/* ══════════════════════════════════════════════════════════════════════
   The page every start page is built from: layout, cards, fields, the
   link box, Get in touch. No colour of its own - those are the skin's,
   as custom properties on :root (wow/start.css is one).
   ══════════════════════════════════════════════════════════════════════ */

/* The typeface of the support button. Served from here like the other
   fonts. */
@font-face {
  font-family: 'Quicksand';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/quicksand-latin-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+2000-206F, U+20AC, U+2122, U+2212,
                 U+FEFF, U+FFFD;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  background-image: var(--glow);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  padding-block: 40px 28px;
  padding-left: 18px;
  padding-right: 18px;
}
/* A film grain over the whole page, at a strength you feel rather than
   see. It gives the flat dark surfaces some texture. */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
}
.wrap { max-width: 1140px; margin: 0 auto; }

/* ════════ The pitch ════════
   The words that used to sit centred above the page, now simply the first
   cell of the grid. They never describe what the scene beside them already
   shows, and that scene is the real overlay rather than a screenshot, so
   it cannot go stale the way the old product images did. */
.eyebrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  font-family: var(--serif);
  font-size: 12.5px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--gold-dim);
  /* Bigger than the gap under the headline itself (22px). The eyebrow
     names the product; the headline says what it does. Set closer than
     this the two read as one four-line block of serif. */
  margin-bottom: 38px;
}
/* The dot belongs to the phrase that follows it rather than to the gap
   between two phrases. As a flex item of its own it was left stranded at
   the end of the line whenever the eyebrow wrapped, which it does on a
   phone and at the 1060px breakpoint. */
.eyebrow .bit::before {
  content: '\00B7';
  color: var(--line-lit);
  margin-right: 10px;
}
/* The gem: a rotated square, which is as much ornament as the game itself
   uses on a heading. It stands in for an icon everywhere on the page. */
.gem {
  display: inline-block; width: 9px; height: 9px; flex-shrink: 0;
  background: var(--gold);
  transform: rotate(45deg);
  box-shadow: 0 0 10px rgba(var(--gold-rgb), 0.65);
}
h1 {
  font-family: var(--serif);
  font-weight: normal;
  /* Sized by the column it sits in rather than by the window. The long
     line is "World of Warcraft look." and what it has to fit inside is
     this column, which at the 1060px breakpoint is 469px while the window
     is over twice that. A vw size has to be tuned for that worst case and
     is then too small everywhere else - it was, and it left the ONE
     column layout at 900px with a smaller headline (36px) than the two
     column one at 1180px (46px), in a column nearly twice as wide.
     9cqw holds the long line at about 95% of the column at every width:
     it never wraps, and no width is left unused. */
  font-size: clamp(24px, 9cqw, 54px);
  line-height: 1.07;
  /* Display sizes only. Marcellus is drawn for headings and sets a touch
     loose once it is this large. */
  letter-spacing: -0.01em;
  color: var(--title);
  text-wrap: balance;
}
h1 .hl {
  display: block;
  background: linear-gradient(180deg, var(--gold-hi) 0%, var(--gold) 52%, var(--gold-lo) 100%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.lead {
  margin-top: 26px; max-width: 46ch;
  /* The width is in ch, so this keeps the two sentences one per line. */
  font-size: 17.5px; line-height: 1.6; color: var(--text);
}
.cta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px 22px;
  margin-top: 34px;
}
.btn-quiet {
  color: var(--gold-dim); text-decoration: none;
  border-bottom: 1px solid var(--line-lit);
  padding-bottom: 1px; font-size: 14.5px;
}
.btn-quiet:hover { color: var(--gold); border-color: var(--gold-dim); }
.facts {
  list-style: none;
  margin-top: 42px; padding-top: 26px;
  border-top: 1px solid var(--line);
  display: grid; gap: 10px;
  font-size: 14px; line-height: 1.5; color: var(--muted);
}
.facts li { position: relative; padding-left: 20px; }
.facts li::before {
  content: ''; position: absolute; left: 2px; top: 7px;
  width: 6px; height: 6px;
  background: var(--gold-dim);
  transform: rotate(45deg);
}
.facts b { color: var(--text); font-weight: 600; }
.facts a {
  color: var(--gold-dim); text-decoration: none;
  border-bottom: 1px solid rgba(var(--gold-dim-rgb), 0.5);
}
.facts a:hover { color: var(--gold); border-color: var(--gold-dim); }

/* The stream stand-in. 16:9 like a canvas; taller on a phone, where a
   16:9 box gets too flat to hold the overlay at a readable size. */
/* Stacked under the copy, the scene is held at about the width it has
   beside it: a canvas the full width of a tablet is mostly empty space. */
.scene-wrap { margin: 0 auto; min-width: 0; width: 100%; max-width: 640px; }
@media (min-width: 1060px) { .scene-wrap { max-width: none; } }
/* Narrow, the stage has to get taller rather than wider or the even
   margin eats the overlay: centring costs the same air top and bottom,
   where the old bottom-left corner only paid once. */
@media (max-width: 719px) { .scene { aspect-ratio: 3 / 2; } }
.scene {
  position: relative; overflow: hidden;
  /* What is centred in here is the chat window, not the browser source
     that contains it - see fitScene(). At the default settings that is
     187px inside the 522px column, which 16:9 surrounds with an even 53px
     and leaves the two labels well clear. Taller and the stage starts
     dwarfing the thing it is showing. */
  aspect-ratio: 16 / 9;
  border-radius: 10px;
  background: var(--scene);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.65),
    0 24px 60px rgba(0, 0, 0, 0.6),
    0 0 90px rgba(var(--gold-rgb), 0.05);
}
/* One shaft of light and a vignette, so the scene has depth without
   needing a picture of anything. */
.scene::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(112deg, transparent 38%, rgba(255, 232, 160, 0.07) 50%, transparent 62%),
    radial-gradient(120% 100% at 50% 40%, transparent 50%, rgba(0, 0, 0, 0.55) 100%);
}
.hud {
  position: absolute; top: 12px; z-index: 2;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.58);
  border: 1px solid rgba(255, 255, 255, 0.09);
  font-size: 11px; letter-spacing: 1.2px; text-transform: uppercase;
  white-space: nowrap;
}
/* Two labels, one per corner, and between them they say what the box is:
   a preview, of something you get to change. */
.prv-tag { left: 12px;  color: var(--muted); }
.src-tag { right: 12px; color: var(--gold); border-color: rgba(var(--gold-rgb), 0.35); }
/* Centred on the stage. It used to sit in the bottom left corner, where a
   chat sits on a real stream, inside a dashed frame that named it as the
   browser source. Both went: the frame was a second edge inside a picture
   that already has one, and off-centre it read as a screenshot of a scene
   rather than as a preview of the overlay. Centred it is what it is.

   It is laid out at its true size and shrunk with a transform, never
   through a smaller scale= parameter, so what is on screen is what OBS
   renders. */
.scene-ov {
  position: absolute; left: 50%; top: 50%;
  /* Both written by fitScene(). The width is the browser source's, but the
     HEIGHT is only the part of it the overlay actually draws on, so that
     centring this box centres what a viewer sees. The frame inside keeps
     its full height and hangs out of the bottom; there is nothing on it
     down there, and the stage clips it anyway. */
  width: 450px; height: 187px;
  transform: translate(-50%, -50%) scale(var(--k, 1));
}
/* pointer-events off: the scene is something to look at, and a stray click
   must not drop focus into a chat nobody can type in. */
#preview { display: block; border: 0; pointer-events: none; }
.scene-wrap figcaption {
  margin-top: 12px; text-align: center;
  font-size: 12.5px; color: var(--muted);
}

/* ════════ Section title ════════
   A rule on either side with a gem at each end: the divider the game draws
   under a panel heading, reduced to a line. */
/* The divider is what tells a reader the selling is over and the work
   starts, so it needs room on the side it is dividing away from as much as
   on the other. */
.sec { position: relative; text-align: center; margin: 16px 0 24px; scroll-margin-top: 20px; }
.sec-title {
  display: flex; align-items: center; gap: 18px;
  font-family: var(--serif); font-weight: normal;
  font-size: 21px; letter-spacing: 1.2px;
  color: var(--gold);
}
.sec-title .rule {
  position: relative; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, var(--line-lit));
}
.sec-title .rule:last-child { background: linear-gradient(90deg, var(--line-lit), transparent); }
.sec-title .rule::after {
  content: ''; position: absolute; top: -3px; right: -1px;
  width: 6px; height: 6px;
  background: var(--gold-dim);
  transform: rotate(45deg);
}
.sec-title .rule:last-child::after { right: auto; left: -1px; }
.sec-note { margin-top: 8px; font-size: 14px; color: var(--muted); }
/* Back to the defaults. There only while a setting differs from what a
   first visit starts with, and that can begin under a slider that is being
   dragged: so it hangs in the room between the note and the first card
   instead of taking a row of its own, and nothing moves when it comes or
   goes. Its looks are the download line's, further down. */
#reset {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  margin-top: 6px;
  white-space: nowrap;
}

/* ════════ One grid: words and controls left, the stream right ════════
   The hero used to be a grid of its own above this one. That put a chat
   window in the picture at the top and a second, identical chat window in
   a preview card directly beneath it - the same thing twice inside one
   screen, and the lower one showed nothing the upper one had not. There is
   one overlay on this page now, in the scene, and it is both things at
   once: the picture that says what this is, and the live preview that
   follows every setting.

   Every track is minmax(0, …): a plain 1fr or auto track takes min-content as
   its floor, and the 450px preview frame would then push the column wider
   than the page instead of scrolling inside its own box. */
.layout, .col-main, .below {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px;
}
/* Nothing should start against the top edge of the window. */
.layout { padding-top: 14px; }
.col-main { align-content: start; }
/* The container the headline sizes itself against - see h1. */
.hero-copy { min-width: 0; container-type: inline-size; }

/* 522px = the 450px overlay plus the padding around it, so the preview is
   never cut off at its natural size */
@media (min-width: 1060px) {
  .layout, .below { grid-template-columns: minmax(0, 1fr) 522px; }
  .layout { align-items: start; padding-top: 24px; }
  /* Three rows, and "Set up your overlay" is the middle one: the pitch and
     the picture sit above it, the settings and the link below it. That
     divider is the one thing on the page that says where being sold to
     ends and configuring begins, and a link card reaching up past it put
     a piece of the form in the half that is still an advertisement. So
     the scene and the link card are separate cells, on either side of it,
     rather than one block in the margin.

     The scene spans all three rows. That is only about sticky: an element
     can be carried no further than its own grid area, and the area has to
     last as long as the settings do. It still renders at the top of that
     area, beside the pitch, because the grid is start-aligned.

     Its margin moves only where it STARTS. A sticky box takes its resting
     place from normal flow but pins to the viewport, so the scene begins
     level with the headline, the way the hero picture used to sit, and
     comes to rest 20px under the top edge once it is being carried along.
     Flush with the page top it looked dropped rather than placed. */
  /* The pitch is a band, not the first item in a list, so it is given
     room to end in before the divider underneath it. Only this column
     needs it: the picture beside it spans every row and is placed by its
     own margin. */
  .hero-copy  { grid-column: 1; grid-row: 1; padding-bottom: 30px; }
  .sec        { grid-column: 1; grid-row: 2; }
  .col-main   { grid-column: 1; grid-row: 3; }
  .scene-wrap {
    grid-column: 2; grid-row: 1 / span 3;
    /* Level with the headline, which means level with the top of the Y
       beside it and not with the top of its box: half the leading plus the
       gap between Marcellus' ascender and its cap height sit above the
       first painted pixel, and at this size that is 17px of nothing. Lined
       up on the box the picture read as floating between the eyebrow and
       the headline, tied to neither. */
    margin-top: 74px;
    /* Room kept below for the link card, written by fitScene(). A sticky
       box may not leave its containing block, margin included, so this is
       what makes the two stop travelling at the same moment: without it
       the link card ran out of room first at the foot of the settings and
       slid up behind the picture. The variable is read here and nowhere
       else, so one column never sees the gap. */
    margin-bottom: var(--clear, 0px);
    position: sticky; top: 20px;
  }
  /* Sticky too, so the "copy it again" warning cannot raise itself off
     screen - that warning is the whole reason the link travels along. The
     offset comes in through a variable and is applied only here, because
     every .card is position:relative for the sake of its popover: set as a
     plain inline `top` it moved the card down the page in one column too,
     straight through the section below it. */
  #link-card {
    grid-column: 2; grid-row: 3;
    position: sticky; top: var(--stick, 20px);
  }
}

/* position:relative because the info popovers are placed against the CARD
   and not against their own field: a field in the grid gets narrow, and a
   popover anchored to one would hang off the edge of the page. */
.card {
  position: relative;
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 20px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.04), 0 6px 22px rgba(0,0,0,0.45);
}
.card > h2 {
  font-family: var(--serif);
  font-size: 13px;
  font-weight: normal;
  color: var(--gold);
  letter-spacing: 1.8px;
  text-transform: uppercase;
}
.card > h2 {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 10px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
/* The step number. Only the three cards you fill in are numbered - the
   preview is not a step, it is what the steps do. */
.step {
  display: inline-flex; align-items: center; justify-content: center;
  width: 21px; height: 21px; flex-shrink: 0;
  margin: 3px 5px 3px 3px;
  border: 1px solid var(--gold-dim); border-radius: 3px;
  background: rgba(var(--gold-rgb), 0.07);
  transform: rotate(45deg);
  font-size: 11.5px; letter-spacing: 0; color: var(--gold);
}
.step > span { transform: rotate(-45deg); }

/* ════════ Form fields ════════ */
/* The minimum is what decides how many columns a card gets, and 176px is
   picked against the narrowest thing that has to fit on one line: the three
   emote ticks (BTTV FFZ 7TV) need 180px side by side. At 154px a desktop
   card fitted THREE columns, which squeezed that field to 175px and broke
   7TV onto its own line - and auto-fit could not collapse the spare track,
   because the .wide fields below span every column and so keep it alive. */
.fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); gap: 16px; }
.wide { grid-column: 1 / -1; }
.field { display: block; min-width: 0; }
.field + .field { margin-top: 16px; }
.fields .field + .field { margin-top: 0; }
.lbl {
  display: block; font-size: 11px; letter-spacing: 1.1px;
  text-transform: uppercase; color: var(--muted);
}
.lbl-row { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
input[type=text], input[type=number], select {
  width: 100%;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 4px;
  color: var(--text);
  padding: 10px 11px;
  font-size: 15px;
  font-family: inherit;
}
input[type=range] { width: 100%; accent-color: var(--gold-dim); cursor: pointer; }
/* What the two ends of a slider mean, when the number alone does not say it */
.ends {
  display: flex; justify-content: space-between;
  font-size: 12px; color: var(--muted); margin-top: 3px;
}
.lbl .val { color: var(--text); letter-spacing: 0.4px; }
input:focus, select:focus, button:focus-visible {
  outline: 2px solid var(--gold-dim); outline-offset: -1px;
}
input::placeholder { color: var(--faint); }

/* One line under the field, in plain words. Anything that needs a paragraph
   lives behind the ⓘ next to the label instead. It used to be four stacked
   paragraphs at the bottom of the card, explaining four fields at once and
   leaving the reader to work out which was which. */
.note { font-size: 12.5px; color: var(--muted); margin-top: 6px; }
/* A typed name the link will not carry: amber, the page's warning colour,
   not red (see --danger-text). */
.note .ignored { color: var(--warn); }
.note b { color: var(--text); font-weight: 600; }
/* Opens a second block inside a card, so two lists do not read as one */
.note.sep { margin-top: 20px; padding-top: 16px; border-top: 1px solid rgba(var(--line-rgb), 0.55); }

/* ════════ The ⓘ and its popover ════════ */
button.info {
  width: 17px; height: 17px; padding: 0; flex-shrink: 0;
  border: 1px solid var(--line-lit); border-radius: 50%;
  background: transparent; color: var(--muted);
  font-family: Georgia, serif; font-size: 11px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
button.info:hover:not(:disabled), button.info[aria-expanded="true"] {
  color: var(--gold); border-color: var(--gold-dim); filter: none;
}
/* left/right against the card, top set in JS: inside the card at every
   width, so it can never push a horizontal scrollbar onto a phone */
.pop {
  position: absolute; z-index: 6;
  left: 14px; right: 14px;
  background: var(--raised);
  border: 1px solid var(--line-lit);
  border-radius: 6px;
  padding: 12px 14px;
  font-size: 12.5px; line-height: 1.55; color: var(--text);
  text-transform: none; letter-spacing: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  box-shadow: 0 12px 30px rgba(0,0,0,0.65);
}
.pop b { color: var(--gold); font-weight: 600; }
.pop p + p { margin-top: 8px; }

/* Platform picker. Deliberately built from the existing button style rather
   than a new control, so nothing new enters the visual language. */
.seg { display: flex; gap: 8px; flex-wrap: wrap; }
.seg button { flex: 1 1 0; min-width: 94px; padding: 11px 10px; letter-spacing: 0.4px; }
.seg button[aria-pressed="true"] {
  background: var(--pressed);
  border-color: var(--gold);
  box-shadow: inset 0 0 0 1px rgba(var(--gold-rgb), 0.25);
}
.seg button[aria-pressed="false"] { color: var(--muted); }
/* The platform toggles say "on" rather than "chosen", in green. */
#platform button[aria-pressed="true"] {
  background: var(--on-bg);
  border-color: var(--on);
  box-shadow: inset 0 0 0 1px rgba(var(--on-rgb), 0.3);
  color: var(--on-text);
}

/* Fields that belong to only one platform choice. Asking about a marker
   when there is only one chat would be asking about nothing. */
.only { display: none; }
.only.show { display: block; }

.checks { display: flex; gap: 16px; flex-wrap: wrap; padding-top: 6px; }
.checks label { display: flex; align-items: center; gap: 7px; cursor: pointer; white-space: nowrap; }
/* nowrap suits the short provider names; one long label has to be allowed
   to break, or it pushes the narrow layout into a horizontal scroll. */
.checks.long label { white-space: normal; align-items: baseline; }
.checks input { accent-color: var(--gold-dim); cursor: pointer; width: 15px; height: 15px; }

/* The raid tick and its threshold share a line: the number belongs to the
   tick and can only be edited while the tick is set. */
.raids { display: flex; align-items: center; gap: 8px 16px; flex-wrap: wrap; padding-top: 6px; }
.raids label { display: flex; align-items: center; gap: 7px; cursor: pointer; white-space: nowrap; }
.raids input[type=checkbox] { accent-color: var(--gold-dim); cursor: pointer; width: 15px; height: 15px; }
.raids input[type=number] { width: 6.5em; padding: 6px 8px; }
.raids input:disabled { opacity: 0.45; cursor: not-allowed; }
.raids label:has(input:disabled) { color: var(--muted); cursor: default; }

/* Marks a setting that has just shipped. It sits inside its own label, so
   clicking it does what clicking the label does.

   It is red on a page where red otherwise means "something is wrong", which
   is exactly why it works and also why it is temporary: the badge is worth
   the exception only while the thing behind it is actually new. Take it off
   again and the rule above --danger-text goes back to being whole. */
.badge-new {
  margin-left: 8px;
  color: var(--danger-text);
  font-size: 10px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase;
  vertical-align: 1px;
}

/* A platform still in testing, in the warning colour. */
.badge-beta {
  margin-left: 6px;
  color: var(--warn);
  font-size: 10px; font-weight: 700; letter-spacing: 1px;
  text-transform: uppercase;
  vertical-align: 1px;
}

/* ════════ A fold inside a field: the one-time setup ════════ */
.setup { margin-top: 10px; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.setup summary {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none; color: var(--text);
}
.setup summary::-webkit-details-marker { display: none; }
.setup summary .w { border-bottom: 1px solid rgba(var(--gold-dim-rgb), 0.5); padding-bottom: 1px; }
.setup summary:hover { color: var(--gold); }
.setup .chev {
  width: 6px; height: 6px; margin: -3px 0 0 1px;
  border: solid currentColor; border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
.setup[open] .chev { transform: rotate(-135deg); margin-top: 3px; }
.setup ol { margin: 8px 0 0; padding-left: 20px; }
.setup li + li { margin-top: 4px; }
.setup b { color: var(--text); font-weight: 600; }
.setup a { color: var(--gold-dim); }
.setup a:hover { color: var(--gold); }
/* The port line at the foot of the fold. */
.setup .port { display: flex; align-items: center; gap: 8px; margin: 10px 0 0; }
.setup .port input[type=number] { width: 6em; padding: 6px 8px; }

/* ════════ Option cards: how the two chats are told apart ════════
   This was one flat dropdown of five entries that mixed two questions -
   WHICH kind of marker, and WHICH platform gets it. The options carried
   their own examples as text ("Bob-Twitch, Bob-Kick"), which is exactly
   the thing a sample line can simply show. */
.opts { display: grid; grid-template-columns: repeat(auto-fit, minmax(172px, 1fr)); gap: 10px; }
/* The follow-up question under the cards keeps the distance fields keep
   from each other; it is nested, so `.field + .field` does not reach it. */
.opts + .field { margin-top: 16px; }
.opt { display: block; cursor: pointer; min-width: 0; }
/* The radio stays in the DOM and keeps the keyboard behaviour; the box next
   to it is what gets drawn. No :has() needed that way. */
.opt > input { position: absolute; opacity: 0; width: 0; height: 0; }
.opt-box {
  display: block; height: 100%;
  background: var(--sunken);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 11px 12px 12px;
}
.opt:hover .opt-box { border-color: var(--line-lit); }
.opt > input:checked ~ .opt-box {
  border-color: var(--gold);
  background: var(--chosen);
}
.opt > input:focus-visible ~ .opt-box { outline: 2px solid var(--gold-dim); outline-offset: 1px; }
.opt-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 12.5px; color: var(--text); margin-bottom: 8px;
}
.dot {
  width: 13px; height: 13px; flex-shrink: 0;
  border: 1px solid var(--line-lit); border-radius: 50%;
}
.opt > input:checked ~ .opt-box .dot {
  background: var(--gold); border-color: var(--gold);
  box-shadow: inset 0 0 0 2.5px var(--sunken);
}

/* ════════ The generated link ════════ */
#out {
  display: block;
  background: var(--sunken);
  border: 1px solid var(--line-lit);
  border-radius: 4px;
  color: var(--gold);
  padding: 11px 12px;
  font-family: ui-monospace, "Cascadia Code", Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  word-break: break-all;
  min-height: 62px;
}
#out.empty { color: var(--muted); font-family: inherit; font-size: 14px; }

button {
  background: var(--button);
  border: 1px solid var(--gold-dim);
  color: var(--gold);
  border-radius: 4px;
  padding: 12px 22px;
  font-size: 14.5px;
  font-family: inherit;
  letter-spacing: 0.6px;
  cursor: pointer;
  transition: filter 0.1s;
}
button:hover:not(:disabled) { filter: brightness(1.4); }
button:disabled { opacity: 0.35; cursor: not-allowed; }
/* The one action the whole page leads to, so it is the one filled button:
   "Build your link" at the top and "Copy link" where the link is are the
   same button, because they are the same action seen from two places. */
.btn-primary, #copy {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary);
  color: var(--on-primary);
  text-decoration: none;
  border: 1px solid var(--gold-hi);
  border-radius: 5px;
  padding: 13px 26px;
  font-size: 15px; font-weight: 600; letter-spacing: 0.3px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 8px 24px rgba(var(--gold-rgb), 0.16),
    0 2px 6px rgba(0, 0, 0, 0.5);
  transition: filter 0.12s, transform 0.12s;
}
.btn-primary:hover, #copy:hover:not(:disabled) { filter: brightness(1.07); transform: translateY(-1px); }
#copy { width: 100%; margin-top: 10px; }

/* The file, one line under the gold button and deliberately quieter: the
   link is the way in, the file is the way out for somebody who would
   rather not depend on this site. The button wears .btn-quiet's clothes
   rather than a button's, so the line reads as a sentence with a link in
   it and not as a second action competing with the first. */
.alt {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px;
  margin-top: 12px;
  font-size: 13px; color: var(--muted);
}
#download, #reset {
  background: none; border: 0; border-radius: 0; padding: 0 0 1px;
  border-bottom: 1px solid var(--line-lit);
  color: var(--gold-dim); font-size: 13px; letter-spacing: 0;
  transition: none;
}
#download:hover:not(:disabled), #reset:hover { color: var(--gold); border-color: var(--gold-dim); filter: none; }
#download:disabled { opacity: 0.45; }
#dl-note { margin-top: 10px; }

/* ── The tip line ──
   One short line under the download line. A first visit does not see
   it: it appears once the link was copied or the file saved, and is
   there from the start on a device that has copied a link before. Until
   then the link card holds nothing but the link (above 1060px the card
   is sticky). It leads to the support block further down, where every
   way to support stands together. It wears the link style of the facts
   under the hero, not the gold of Copy link. */
#tip-note { margin-top: 10px; }
#tip-note a {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--gold-dim); text-decoration: none;
}
/* The rule runs under the words only: the cup is a picture, and a line
   under a picture reads as a caption. The emoji is the one thing on
   this page that a font decides the colour of, so it is kept small and
   left to render as the platform wants. */
#tip-note .cup { font-size: 13px; line-height: 1; }
#tip-note .w { border-bottom: 1px solid rgba(var(--gold-dim-rgb), 0.5); padding-bottom: 1px; }
#tip-note a:hover { color: var(--gold); }
#tip-note a:hover .w { border-color: var(--gold-dim); }

/* ════════ Browser source size ════════
   Given its own block rather than a line of small print: getting this wrong
   is what makes the overlay look blurry or cut off in OBS. */
.sizebox {
  margin-top: 14px;
  border: 1px solid var(--line-lit);
  border-radius: 6px;
  background: var(--sunken);
  padding: 12px 14px;
}
.sizebox .lbl { margin-bottom: 4px; }
.sizenum {
  font-size: 23px; color: var(--gold);
  font-family: Georgia, "Times New Roman", serif;
  line-height: 1.25;
}
.sizenum .x { color: var(--gold-dim); font-size: 17px; margin: 0 3px; }
.sizebox .sub { display: block; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
/* The one line in this box that is advice instead of a number, so it is the
   one line that is not grey. Shown only while the size is the one a first
   visit is given: that is when 900 x 374 is a number nobody chose and might
   read as a mistake. */
.sizebox .tip {
  display: none;
  color: var(--gold-dim);
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line-lit);
}
.sizebox .tip.show { display: block; }

/* Shown only once the copied link no longer matches the settings */
#stale {
  display: none;
  margin-top: 12px;
  border: 1px solid rgba(var(--warn-rgb), 0.45);
  background: rgba(var(--warn-rgb), 0.08);
  border-radius: 4px;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--warn);
}
#stale.show { display: block; }

/* ════════ The two reference sections at the bottom ════════ */
.below { margin-top: 26px; }
/* Each is as tall as its own content; the shorter one does not stretch to
   match the taller one next to it. Both are jump targets from further up,
   hence the margin: landing with the heading flush against the top edge
   reads as a cut-off page rather than an arrival. */
.below .card { align-self: start; scroll-margin-top: 20px; }
/* The orientation line on the right of a heading: how long this is going to
   take, before you start reading it. */
.h2-note {
  margin-left: auto; text-transform: none; letter-spacing: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  font-size: 12.5px; color: var(--muted);
}

ol.steps { padding-left: 21px; }
ol.steps li { margin-bottom: 9px; }
ol.steps li:last-child { margin-bottom: 0; }
code {
  background: var(--sunken); border: 1px solid var(--line); border-radius: 3px;
  padding: 1px 6px; font-family: ui-monospace, Consolas, monospace;
  font-size: 13px; color: var(--gold);
}

/* ════════ Screenshot of the real OBS window ════════ */
.shot { margin-top: 16px; }
.shot img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: 5px;
}
.shot figcaption { font-size: 12.5px; color: var(--muted); margin-top: 8px; }
.shot figcaption b { color: var(--text); font-weight: 600; }

/* ════════ Chat colour legend ════════ */
.legend { list-style: none; }
.legend li {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; padding: 6px 0;
  border-bottom: 1px solid rgba(var(--line-rgb), 0.55);
}
.legend li:last-child { border-bottom: none; }
.legend .who { font-size: 13.5px; color: var(--muted); }

/* ════════ Get in touch ════════
   The last block before the footer, and the only one on the page that
   asks for something back. It is a card like the two above it and not a
   bubble in the corner: a floating chat button is the look of a support
   widget, which is the one thing a page promising "no account" cannot
   afford to look like - and at full width it would come
   to rest on top of the copy button, which is what the page is for.
   Full width because the two cards beside it are a 1fr + 522px pair and a
   third one would have queued up under the taller of them. */
@media (min-width: 1060px) { #contact { grid-column: 1 / -1; } }
/* The only card on the page that runs the full width, so its one
   paragraph is the only text here that would otherwise set 150 characters
   to the line. */
#contact .note { max-width: 88ch; }
#contact .note + .note { margin-top: 10px; }
.contacts { list-style: none; margin-top: 16px; display: grid; gap: 16px; }
@media (min-width: 560px) { .contacts { grid-template-columns: 1fr 1fr; gap: 18px 26px; } }
.contacts .line { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
/* Two controls per row, because they do two different things: the
   platform name is a link that may or may not land where it should, and
   the handle beside it is a button that puts the name on your clipboard,
   which is what works either way. */
.contacts .where {
  font-family: var(--serif);
  font-size: 12.5px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--gold); text-decoration: none;
  border-bottom: 1px solid rgba(var(--gold-dim-rgb), 0.5);
  padding-bottom: 1px;
}
.contacts .where:hover { border-color: var(--gold); }
.handle {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--sunken);
  border: 1px solid var(--line-lit);
  border-radius: 5px;
  padding: 5px 11px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 13px; letter-spacing: 0; color: var(--text);
}
.handle:hover { border-color: var(--gold-dim); }
.handle .tag {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  font-size: 11px; letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--gold-dim);
}
.contacts .how { display: block; margin-top: 8px; font-size: 12.5px; color: var(--muted); }
/* Own-project line: a block of its own under the contacts, set like the support sentence */
#contact .project { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); }
#contact .project .note { margin-top: 0; font-size: 13.5px; color: var(--text); }

/* ── The support block ──
   After the contacts and not among them, and quieter than Copy link on
   purpose: that button is what the page is for, this block is optional.

   It is a plain link and never an embedded widget: an embed would make a
   request to a third party on every page load, for every visitor. A link
   sends nothing until somebody clicks it. */
#contact .give {
  margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--line);
}
/* The rule runs the full width of the card, the sentence under it does
   not: at 88ch it stops where every other paragraph in this card stops,
   and a divider that stopped there with it would read as a mistake. */
#contact .give > p:first-child {
  max-width: 88ch; font-size: 13.5px; color: var(--text);
}
/* The support button stands open under the sentence, with its label
   above it and a note below. */
#contact .give .way { margin-top: 16px; }
#contact .give .way .lbl { font-weight: normal; margin-bottom: 9px; }
#contact .give .note { margin-top: 11px; }

/* The addresses sit behind one fold under the button. A <details>
   because that is exactly what it is - it opens with the keyboard,
   announces its state and works before the script has run. Its summary
   is a short question with the page's link rule under it, so it reads
   as the quieter of the two. */
#contact .give .ways { margin-top: 18px; }
#contact .give summary {
  display: inline-flex; align-items: center; gap: 8px;
  list-style: none; cursor: pointer;
  font-size: 12.5px; color: var(--gold-dim);
}
#contact .give summary::-webkit-details-marker { display: none; }
#contact .give summary .w { border-bottom: 1px solid rgba(var(--gold-dim-rgb), 0.5); padding-bottom: 1px; }
#contact .give summary:hover,
#contact .give details[open] > summary { color: var(--gold); }
#contact .give summary:hover .w { border-color: var(--gold-dim); }
#contact .give .chev {
  width: 6px; height: 6px; margin: -3px 0 0 1px;
  border: solid currentColor; border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
#contact .give details[open] .chev { transform: rotate(-135deg); margin-top: 3px; }
#contact .give .ways-body {
  margin-top: 14px;
  animation: ways-in 0.2s ease-out;
}
#contact .give .ways-body > .note:first-child { margin-top: 0; }
@keyframes ways-in { from { opacity: 0; transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { #contact .give .ways-body { animation: none; } }

/* The rows are set one size under the rest of the card. Only one: the
   addresses still have to be read and compared character by character. */
.crypto .coins { margin-top: 10px; gap: 9px 12px; }
.crypto .coins .coin { font-size: 11.5px; letter-spacing: 1.4px; }
.crypto .coins code { font-size: 12px; padding: 5px 10px; }
.crypto .coins button { padding: 0 10px; }
.crypto .coins .tag { font-size: 10.5px; }

/* The support button. A plain link styled here, not an embedded widget:
   the icon and the font are served from this site, so nothing is
   requested from a third party until the button is clicked. */
#contact .give .kofi {
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 150px; justify-content: center;
  padding: 2px 14px; line-height: 36px;
  background: #72a4f2; border-radius: 7px;
  box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.2);
  font-family: 'Quicksand', Helvetica, 'Century Gothic', sans-serif;
  font-weight: 700; font-size: 14px; letter-spacing: -0.15px;
  color: #fff; text-decoration: none;
}
#contact .give .kofi:hover { opacity: 0.85; }
#contact .give .kofi img {
  width: 20px; height: 16px; object-fit: contain;
  animation: kofi-wiggle 3s infinite;
}
/* Still for most of the three seconds, then a brief shake of the cup. */
@keyframes kofi-wiggle {
  0%, 60% { transform: rotate(0) scale(1); }
  75% { transform: rotate(0) scale(1.12); }
  80% { transform: rotate(0) scale(1.1); }
  84%, 92% { transform: rotate(-10deg) scale(1.1); }
  88%, 96% { transform: rotate(10deg) scale(1.1); }
  100% { transform: rotate(0) scale(1); }
}
@media (prefers-reduced-motion: reduce) { #contact .give .kofi img { animation: none; } }

/* The last word in the block is a thank-you, and signed - it is the one
   sentence on the page that is from a person rather than about a tool. */
#contact .give .thanks {
  margin-top: 20px;
  padding-top: 16px; border-top: 1px solid var(--line);
}
#contact .give .thanks > p:first-child { max-width: 88ch; font-size: 13.5px; color: var(--text); }
#contact .give .sig {
  margin-top: 8px;
  font-family: var(--serif);
  font-size: 12.5px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--gold-dim);
}
#contact .give .sig::before { content: "\2014\00a0"; }

/* One row per coin: the network, the address, a copy button. The address
   is always shown IN FULL and never shortened to 0xFDe8…7242 - the whole
   point of a checkable address is being checkable, and clipboard malware
   that swaps addresses keeps the first and last few characters alike.
   The name column is a subgrid so the three addresses line up under one
   another; below 560px the name goes above its address instead. */
.coins { list-style: none; display: grid; gap: 12px 14px; grid-template-columns: minmax(0, 1fr); }
.coins li { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; gap: 5px 14px; align-items: center; }
@media (min-width: 560px) { .coins { grid-template-columns: max-content minmax(0, max-content); } }
.coins .coin {
  font-family: var(--serif);
  font-size: 12.5px; letter-spacing: 1.6px; text-transform: uppercase;
  color: var(--gold-dim);
}
/* The handle's box, split in two: the address is selectable text and
   selects whole on one click, the button beside it only copies. */
.coins .addr {
  display: flex; align-items: stretch; min-width: 0;
  background: var(--sunken);
  border: 1px solid var(--line-lit);
  border-radius: 5px;
}
.coins .addr:hover { border-color: var(--gold-dim); }
.coins code {
  flex: 1; min-width: 0;
  padding: 6px 11px;
  font-family: ui-monospace, Consolas, monospace;
  font-size: 13px; color: var(--text);
  overflow-wrap: anywhere;
  user-select: all; -webkit-user-select: all;
}
.coins button {
  flex-shrink: 0;
  background: none; border: 0; border-left: 1px solid var(--line);
  border-radius: 0 5px 5px 0;
  padding: 0 11px; cursor: pointer;
}
.coins .tag {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  font-size: 11px; letter-spacing: 0.5px; text-transform: uppercase;
  color: var(--gold-dim); white-space: nowrap;
}
.coins button:hover .tag { color: var(--gold); }

/* ════════ The signpost to Get in touch ════════
   The card at the foot of the page is the only one that asks for anything
   back, and on a page this long most people never scroll to it.

   Measured against the copy button: at every width from 390px to 1400px
   the signpost grazes that button at one to three scroll positions out of
   eighty to a hundred and twenty, by at most 42px, while passing.

   What makes a chat widget read as a chat widget is sitting in the corner
   from the first paint and never leaving. So this one is **absent on
   arrival and absent at the bottom** - it fades in after a screen of
   scrolling and out again the moment the contact card is up. */
#jump {
  position: fixed; right: 20px; bottom: 20px; z-index: 40;
  display: inline-flex; align-items: center;
  background: var(--panel);
  border: 1px solid var(--line-lit);
  border-radius: 999px;
  padding: 0; height: 52px;
  color: var(--gold);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.55);
  /* visibility, not just opacity: an invisible button must not be
     reachable by tab either. */
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity 0.25s, transform 0.25s, visibility 0.25s,
              border-color 0.15s;
}
#jump.show { opacity: 1; visibility: visible; transform: none; }
#jump:hover, #jump:focus-visible { border-color: var(--gold); }

/* The quest marker is an original drawing, a path of its own in the
   style of the game's marker - the same approach as Marcellus standing
   in for the game's typeface.

   It is the "?" and not the "!" on purpose. In the game "!" marks a
   quest an NPC is handing out and "?" marks one you are bringing back.
   Here the visitor is the one carrying something, so "?" is the one that
   means what this button does. */
#jump .quest {
  width: 52px; height: 52px; flex-shrink: 0;
  display: grid; place-items: center;
}
#jump .quest svg {
  width: 19px; height: 27px; display: block;
  filter: drop-shadow(0 0 7px rgba(var(--gold-rgb), 0.45));
}

/* Closed it is a 52px circle, which is what "too wide" was about. The
   word is what the icon cannot say on its own, so it is spent only on a
   pointer that has already come to rest on the button. A touch screen
   never hovers and never sees it - there the icon and the aria-label
   carry it, and nothing is lost, because tapping does the same thing. */
#jump .word {
  font-family: var(--serif);
  color: var(--gold);
  font-size: 12.5px; letter-spacing: 1.4px; text-transform: uppercase;
  white-space: nowrap; overflow: hidden;
  max-width: 0; opacity: 0; padding-right: 0;
  transition: max-width 0.25s, opacity 0.2s, padding-right 0.25s;
}
#jump:hover .word, #jump:focus-visible .word {
  max-width: 160px; opacity: 1; padding-right: 21px;
}
@media (max-width: 559px) { #jump { right: 13px; bottom: 13px; } }
@media (prefers-reduced-motion: reduce) {
  #jump, #jump .word { transition: none; }
}

footer {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  margin-top: 44px; padding-top: 22px;
  border-top: 1px solid var(--line);
  color: var(--muted); font-size: 12.5px; text-align: center;
}
footer .brand {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--serif); font-size: 13px; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--gold-dim);
  margin-bottom: 4px;
}
/* Same measure as the contact card's paragraphs */
footer > span { max-width: 88ch; }
footer a { color: var(--gold-dim); }
