/* Signalens — styles.css
   Dark neon theme. Satoshi, gradient accents (violet → magenta → pink), one radius.
   Verdict status colors are the only colors that carry meaning. */

@import url("https://api.fontshare.com/v2/css?f[]=satoshi@400,500,700,900&display=swap");

/* ---------- Tokens ---------- */
:root {
  --bg: #14141a;
  --bg-raised: #1b1b23;
  --bg-sunken: #101015;
  --bg-deep: #0e0e13;
  --border: #2a2a36;
  --border-soft: #23232e;

  --text: #ffffff;
  --muted: #9a9aab;
  --placeholder: #6a6a7d;

  --accent: #7b61ff;
  --accent-2: #b15cff;
  --accent-3: #ff5ca8;
  --accent-dim: #4a3a8f;
  --accent-wash: #201a34;
  --on-accent: #ffffff;

  --gradient: linear-gradient(120deg, #7b61ff, #b15cff 50%, #ff5ca8);
  --gradient-mark: linear-gradient(140deg, #7b61ff, #b15cff 55%, #ff5ca8);

  /* Verdict statuses */
  --ok: #3ddc97;
  --warn: #b15cff;
  --stop: #ff5ca8;
  --stop-wash: #33203a;

  --sans: "Satoshi", -apple-system, BlinkMacSystemFont, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, monospace;

  --radius: 10px;
  --page: 72rem;    /* marketing sections */
  --measure: 42rem; /* tool screens */
}

/* ---------- Base ---------- */
* { box-sizing: border-box; }

html { background: var(--bg); -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 17px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
}

@media (max-width: 640px) { body { font-size: 16px; } }

/* app.js drives every screen through the hidden attribute, and several
   components below set display on a class. Without this the attribute loses. */
[hidden] { display: none !important; }

::placeholder { color: var(--placeholder); }
::selection { background: var(--accent); color: #ffffff; }

a { color: var(--accent-2); text-decoration: none; border-bottom: 1px solid var(--accent-dim); }
a:hover { color: var(--text); border-bottom-color: var(--accent-3); }

summary { list-style: none; cursor: pointer; }
summary::-webkit-details-marker { display: none; }

h1, h2, h3 { font-family: var(--sans); font-weight: 700; letter-spacing: -0.02em; margin: 0; text-wrap: pretty; }
h1 { font-size: clamp(2.6rem, 5.5vw, 4.2rem); line-height: 1.05; }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.8rem); line-height: 1.15; }
h3 { font-size: 1.6rem; }

/* Gradient headline fragment */
.grad-text {
  background: var(--gradient);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

p { margin: 0 0 1rem; }
.lead { color: var(--muted); font-size: 1.1rem; max-width: 32rem; }
.muted { color: var(--muted); }
.small { font-size: 0.9rem; }

.eyebrow {
  font: 400 12px/1 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent-2);
}
.label {
  font: 400 11px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.label--accent { color: var(--accent-2); }

/* ---------- Layout ---------- */
.wrap { max-width: var(--page); margin: 0 auto; padding: 0 2rem; }
.section { padding: 5rem 0; }
.screen { max-width: var(--measure); margin: 0 auto; padding: 4rem 1.5rem; }

.cols-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(22rem, 1fr));
  gap: 3.5rem;
  align-items: center;
}
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr)); gap: 1.5rem; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem; }

/* Deeper band to separate sections on an already-dark page */
.band-deep { background: var(--bg-deep); }

/* ---------- Header ---------- */
.header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(20, 20, 26, 0.85);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border-soft);
}
.header__inner {
  max-width: var(--page);
  margin: 0 auto;
  padding: 0.9rem 2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}
.wordmark {
  background: none; border: 0; padding: 0; cursor: pointer;
  display: flex; align-items: center; gap: 0.7rem;
}
.wordmark img { width: 2.25rem; height: 2.25rem; object-fit: contain; display: block; }
.wordmark span { font-weight: 700; font-size: 1.15rem; letter-spacing: -0.01em; color: var(--text); }

/* Fallback lettermark when the PNG is not available */
.logo-tile {
  width: 2rem; height: 2rem; border-radius: var(--radius);
  background: var(--gradient-mark);
  display: flex; align-items: center; justify-content: center;
  font-weight: 900; font-size: 1.05rem; color: #ffffff;
}

/* ---------- Buttons ---------- */
.btn-primary, .btn-ghost, .btn-quiet, .btn-invert {
  border-radius: var(--radius);
  font-family: inherit;
  line-height: 1;
  cursor: pointer;
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
  border: 0;
  padding: 1rem 1.7rem;
  font-weight: 700;
  font-size: 1.05rem;
}
.btn-primary--sm { padding: 0.65rem 1.1rem; font-size: 0.95rem; font-weight: 600; }
.btn-primary--grad { background: var(--gradient); }
/* Lighter fill with dark text — for use inside a card that is already dark
   enough that --accent stops reading as the brightest thing on it. */
.btn-primary--light { background: var(--accent-2); color: var(--bg); }
.btn-block { display: block; width: 100%; text-align: center; padding: 1.1rem 1.5rem; }
.btn-primary:disabled,
.btn-primary[aria-disabled="true"] {
  background: var(--accent-dim);
  color: var(--muted);
  cursor: not-allowed;
}

.btn-ghost {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.55rem 0.95rem;
  font-weight: 400;
  font-size: 0.9rem;
}
.btn-ghost:hover { border-color: var(--accent); color: var(--accent-2); }

.btn-quiet {
  background: none; border: 0; padding: 0;
  color: var(--muted); font-weight: 400; font-size: 0.95rem;
  text-decoration: underline; text-underline-offset: 3px;
}
.btn-quiet:hover { color: var(--text); }

.btn-invert { background: #ffffff; color: var(--bg); border: 0; padding: 1rem 1.9rem; font-weight: 700; font-size: 1.05rem; }

/* Anchors styled as buttons must not inherit the link underline. */
a.btn-primary, a.btn-ghost, a.btn-invert {
  display: inline-block; border-bottom: 0; text-decoration: none;
}
a.btn-primary:hover { color: var(--on-accent); }
a.btn-invert, a.btn-invert:hover,
a.btn-primary--light, a.btn-primary--light:hover { color: var(--bg); }
a.btn-block { display: block; }

/* One .btn-primary per screen. Refusals are always .btn-quiet. */

.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1.25rem; margin-top: 2rem; }

/* ---------- Hero ---------- */
/* The headline is display-size, so the default paragraph gap leaves the lead
   sitting on top of it; and next to a 4rem headline the lead reads better a
   step down from the size it takes in the rest of the page. */
.hero h1 { margin-bottom: 1.75rem; }
.hero .lead { font-size: 1rem; }

/* ---------- Cards ---------- */
.card {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
}
/* The hero card is a sample, not a screen: everything inside it is one step
   down from the size the same block takes in the tool. */
.card--float { padding: 1.5rem; box-shadow: 0 30px 90px -40px rgba(123, 97, 255, 0.6); }
.card--float .message, .card--float .reply { padding: 1rem 1.15rem; font-size: 0.95rem; }
.card--float .message { margin-bottom: 1.1rem; }
.card--float > p { font-size: 0.95rem; margin-bottom: 1.1rem; }
/* Full page width, but shallow: three short lines and a button, and the tall
   padding turned the card into an empty field with text floating in it. */
.card--cta {
  position: relative; overflow: hidden;
  background: var(--gradient);
  color: #ffffff; border: 0;
  padding: clamp(2.25rem, 4vw, 3rem) 2rem;
  text-align: center;
}
.card--cta h2 { margin: 0 auto 0.75rem; text-wrap: balance; }
.card--cta p { color: rgba(255, 255, 255, 0.92); margin-bottom: 0; }
.card--cta .note { color: rgba(255, 255, 255, 0.8); font-size: 0.9rem; margin-top: 1rem; }

.sunken { background: var(--bg-sunken); border-radius: var(--radius); padding: 1.4rem; }

.list-item {
  display: grid;
  grid-template-columns: 1.25rem 1fr;
  gap: 0.75rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--border-soft);
}
.list-item::before { content: "→"; color: var(--accent); }
.list-item b { display: block; font-weight: 700; }
.list-item span { color: var(--muted); font-size: 0.95rem; }

/* Numbered steps reuse the card grid; the counter is the only extra. */
.step { counter-increment: step; }
.step__num {
  width: 2rem; height: 2rem; border-radius: var(--radius);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font: 400 12px/1 var(--mono); color: var(--accent-2);
  margin-bottom: 1.1rem;
}

/* ---------- Two features (landing only) ---------- */
/* The pair reads as a pair through depth, not through inversion: one card sits
   a step below the page, the other a step above it. A white card here would be
   the only light surface on the site. */
.features__title { max-width: 20ch; text-wrap: balance; margin-bottom: 3rem; }
/* Two cards, not three steps: they hold a paragraph and a list each, so they
   drop to one column earlier than .cards would on its own. */
.cards--pair { grid-template-columns: repeat(auto-fit, minmax(26rem, 1fr)); }
.feature { display: flex; flex-direction: column; padding: 2.25rem; }
.feature--deep { background: var(--bg-deep); }
.feature__head { display: flex; align-items: center; gap: 0.9rem; margin-bottom: 1.5rem; }
.feature__tile {
  width: 2.5rem; height: 2.5rem; flex: none;
  border-radius: var(--radius);
  background: var(--gradient-mark);
}
.feature__tile--soft {
  background: color-mix(in srgb, var(--accent) 22%, transparent);
  border: 1px solid var(--accent-dim);
}
.feature h3 { margin-bottom: 0.9rem; }
.feature > p { margin-bottom: 1.6rem; }

/* Bulleted, not numbered: these are three things the report shows, in no
   order. The dots take accent tones — the gradient family is decoration, and
   status colours stay on verdicts. */
.feature__list { list-style: none; margin: 0 0 2rem; padding: 0; display: grid; gap: 0.9rem; }
.feature__list li {
  display: grid; grid-template-columns: 0.5rem 1fr; gap: 0.9rem;
  color: var(--muted); font-size: 0.95rem;
}
.feature__list li::before {
  content: "";
  width: 0.5rem; height: 0.5rem;
  border-radius: var(--radius);
  margin-top: 0.55rem;
  background: var(--accent);
}
.feature__list li:nth-child(1)::before { background: var(--accent-3); }
.feature__list li:nth-child(2)::before { background: var(--accent-2); }

/* Pinned to the bottom edge so the button sits on one line across both cards
   however long the copy runs. */
.feature .btn-primary { margin-top: auto; align-self: flex-start; }

/* The two sample requests reuse .message: same sunken block, same label. The
   accent one is the paraphrase — the case people assume a tool won't take.
   (.message--accent itself lives next to .message below: it overrides that
   rule's shorthand and has to come after it.) */
/* One step down from the tool's own .message, the way .card--float is: these
   are two one-line samples, not the request someone actually pasted. */
.feature .message { margin: 0; padding: 0.85rem 1.1rem; font-size: 0.95rem; }
.feature .message__head { margin-bottom: 0.4rem; }
.feature__or {
  font: 400 11px/1 var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--placeholder);
  text-align: center;
  margin: 0.75rem 0;
}

/* ---------- Verdict ---------- */
.verdict__status {
  display: flex; align-items: center; gap: 0.7rem;
  font-weight: 700; font-size: 1.6rem; letter-spacing: -0.02em;
  margin-bottom: 1rem;
}
.verdict__status::before {
  content: "";
  width: 0.6rem; height: 0.6rem;
  border-radius: var(--radius);
  background: currentColor;
  flex: none;
}
.is-in_scope { color: var(--ok); }
.is-unclear { color: var(--warn); }
.is-out_of_scope { color: var(--stop); }

/* Badge form of the status, for the hero card: there the verdict is one beat
   in a three-beat story next to a 4rem headline, not the top of a result
   screen, and at 1.6rem it takes over the whole column. */
.verdict__status--badge {
  display: inline-flex;
  font-size: 0.95rem;
  gap: 0.5rem;
  border-radius: var(--radius);
  padding: 0.45rem 0.85rem;
  background: color-mix(in srgb, currentColor 14%, transparent);
  margin-bottom: 0.9rem;
}
.verdict__status--badge::before { width: 0.5rem; height: 0.5rem; }

.pill {
  display: inline-flex; align-items: center; gap: 0.55rem;
  background: var(--stop-wash); color: var(--stop);
  border-radius: var(--radius); padding: 0.45rem 0.85rem;
  font-weight: 600; font-size: 0.9rem;
}
.pill::before { content: ""; width: 0.5rem; height: 0.5rem; border-radius: var(--radius); background: currentColor; }

.evidence {
  margin: 0 0 1.75rem;
  padding: 0.25rem 0 0.25rem 1.1rem;
  border-left: 3px solid var(--accent-dim);
  font-style: italic;
  color: var(--muted);
}

/* The client's message, above the verdict — the hero card then reads in the
   order the thing actually happens: what arrived, what it is, what to send. */
.message {
  background: var(--bg-sunken);
  border-left: 3px solid var(--border);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  margin-bottom: 1.5rem;
}
.message__head { margin-bottom: 0.7rem; }
.message p { margin: 0; color: var(--muted); }
/* The paraphrased request in the features block — same block, tinted, so the
   pair reads as two ways in rather than two separate samples. */
.message--accent {
  border-left-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 16%, var(--bg-sunken));
}

.reply { background: var(--bg-sunken); border-radius: var(--radius); padding: 1.4rem; }
.reply__head { display: flex; justify-content: space-between; align-items: center; gap: 1rem; margin-bottom: 0.9rem; }
.reply p { margin: 0; white-space: pre-line; }

/* Sits where .evidence sits on the other two verdicts, and so takes the same
   shape: on an `unclear` card there is no quotable line, and a dashed mono box
   in that slot read as a different kind of object rather than the same slot
   holding a different thing. Upright, not italic — a note, not a quotation. */
.low-confidence {
  margin: 0 0 1.75rem;
  padding: 0.25rem 0 0.25rem 1.1rem;
  border-left: 3px solid var(--accent-dim);
  color: var(--muted);
}

.tabs { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.25rem; }
.tabs button {
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 0.55rem 1rem;
  cursor: pointer;
  font: 400 12px/1 var(--mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.tabs button[aria-selected="true"] { background: var(--bg-raised); border-color: var(--border); }
.tabs button[aria-selected="true"].is-in_scope { color: var(--ok); }
.tabs button[aria-selected="true"].is-unclear { color: var(--warn); }
.tabs button[aria-selected="true"].is-out_of_scope { color: var(--stop); }

/* The change order is folded away: it is the next step, not the verdict. */
.change-order { margin-top: 1.5rem; border-top: 1px solid var(--border); padding-top: 1.25rem; }
.change-order summary { display: inline-flex; color: var(--accent-2); font-size: 0.95rem; }
.change-order summary::before { content: "+ "; white-space: pre; }
.change-order[open] summary::before { content: "− "; }
.change-order dl { margin: 1.25rem 0 0; }
.change-order dt { margin-top: 1rem; }
.change-order dt:first-child { margin-top: 0; }
.change-order dd { margin: 0.4rem 0 0; }

/* ---------- Forms ---------- */
textarea, input[type="email"] {
  width: 100%;
  background: var(--bg-sunken);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.1rem 1.2rem;
  font: 400 16px/1.6 var(--sans);
  resize: vertical;
}
textarea:focus, input[type="email"]:focus { border-color: var(--accent); outline: none; }

/* Tall enough to look like it wants a whole agreement, short enough that the
   field and the button under it share one screen — the paste is a scroll either
   way, but a visitor who cannot see "Next" reads the screen as unfinished. */
.field-scope { min-height: 13rem; padding-bottom: 3rem; }
.field-request { min-height: 10rem; }

/* The action row keeps every real button, so the primary action stays close to
   the field it acts on. The foot holds field furniture only: the counter, in
   mono so the line reads as a caption rather than as a second row of actions. */
.field-foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end;
  gap: 1rem; margin: 0.75rem 0 0.5rem;
}
.counter { font: 400 12px/1 var(--mono); color: var(--muted); }
.counter.is-over { color: var(--stop); }

/* The paperclip sits in the field's own bottom-left corner rather than in the
   foot: it acts on the field, and the extra padding-bottom above keeps the
   first lines off it. It is an accent-washed chip, coloured because in the
   corner of an empty dark field a muted grey label reads as a caption, not as
   something to press. It stops short of the right corner so the resize grip
   stays reachable.
   The wash is the only fill on this screen besides the primary button, and it
   sits two steps below it in weight: colour enough to be found, not enough to
   compete with "Next".

   It belongs to the empty field. Once there is text the chip has nothing left
   to offer and starts costing: it lies over a line of the agreement, and an
   opaque box in the middle of a contract reads as damage rather than as
   something to press. So a filled field takes it away, and the padding it had
   reserved goes with it. :placeholder-shown is the test: the placeholder is in
   the markup, and everything that fills the field — typing, a paste, the
   example button, a parsed file — takes it off, so nothing has to be toggled
   from script. */
.field-wrap { position: relative; }
.field-wrap:has(.field-scope:not(:placeholder-shown)) .attach { display: none; }
.field-wrap:has(.field-scope:not(:placeholder-shown)) .field-scope { padding-bottom: 1.1rem; }
.attach {
  position: absolute; left: 0.7rem; bottom: 0.7rem; max-width: calc(100% - 3rem);
  display: flex; align-items: center; gap: 0.75rem; min-width: 0;
  background: var(--accent-wash); border: 1px solid var(--accent-dim);
  border-radius: 8px; padding: 0.4rem 0.6rem;
}
.field-wrap:has(textarea.is-drop) .attach { border-color: var(--accent); }
.attach__btn {
  display: inline-flex; align-items: center; gap: 0.4rem; flex: none;
  background: none; border: 0; padding: 0; cursor: pointer;
  font: 400 12px/1 var(--mono); color: var(--accent-2);
}
.attach__btn:hover { color: var(--text); }
.attach__btn svg { width: 14px; height: 14px; }
/* The file name stays muted: it is what happened, not what to press. */
.attach__name {
  font: 400 12px/1.2 var(--mono); color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Dropping a file on a textarea otherwise navigates the tab to it, taking the
   pasted agreement with it — so the field takes the drop and says it will. */
textarea.is-drop { border-color: var(--accent); background: var(--bg-raised); }

/* The line is reserved whether or not there is an error: a message that pushes
   the button down as it appears moves the target mid-click. */
.error { color: var(--stop); font-size: 0.92rem; line-height: 1.2; margin: 0 0 0.75rem; min-height: 1.2em; }

.scope-recap {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  margin-bottom: 2rem;
}
.scope-recap summary { color: var(--muted); font-size: 0.92rem; }
.scope-recap summary::before { content: "▸ "; }
.scope-recap[open] summary::before { content: "▾ "; }
.scope-recap textarea { margin-top: 1rem; min-height: 14rem; }

/* ---------- Hidden cost ---------- */
/* One argument in one column: the story, then the numbers that back it, then
   the line that says what to do about it. Nothing sits beside the headline.
   The headline is held to two lines: one sentence and one price, where three
   lines read as three separate thoughts. */
.cost h2 { max-width: 30rem; margin-bottom: 3rem; text-wrap: balance; }

/* The rule is the page gradient rather than flat --accent: it is decoration
   here, and flat violet next to the magenta headline read as a fourth colour. */
.story {
  background: var(--gradient) left top / 3px 100% no-repeat;
  padding: 0.25rem 0 0.25rem 1.6rem;
  margin: 0 0 3rem;
  max-width: 52rem;
}
.story blockquote { margin: 0 0 1.5rem; font-size: 1.15rem; font-style: italic; }
.story p { margin: 0; color: var(--muted); }

/* The dividers are the 1px grid gap showing the container's background, not
   borders on the cells: with auto-fit the column count is unknown, and this
   way a wrapped row gets its rule for free and no cell ends with a stray one. */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.stat { background: var(--bg-raised); padding: 2rem; }
/* The figures carry .grad-text in the markup — same gradient as the headline
   and the logo. Colour never means anything here; the verdict statuses are
   still the only place where it does. */
.stat__figure {
  font-weight: 700; letter-spacing: -0.02em;
  font-size: clamp(2.2rem, 4.5vw, 3rem); line-height: 1;
  margin-bottom: 1rem;
}
.stat__body { margin: 0 0 1rem; }
.stat__source {
  display: flex; align-items: center; gap: 0.5rem;
  margin: 0;
  color: var(--placeholder); font-size: 0.85rem; line-height: 1.4;
}

/* A source line people can question without the page having to explain itself
   out loud. Native title tooltip — no JS, and it reads out as an abbreviation. */
.hint {
  flex: none;
  width: 1.05rem; height: 1.05rem;
  border: 1px solid var(--border);
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.7rem; line-height: 1;
  color: var(--muted);
  text-decoration: none;
  cursor: help;
}
.hint:hover { color: var(--text); border-color: var(--accent-dim); }

.cost__close { color: var(--muted); max-width: 34rem; margin: 2.5rem 0 0; }
.cost__close b { color: var(--text); }

/* ---------- Cost calculator ---------- */
/* The card is as tall as its content; nothing here should be vertically
   centred against the column of chips. */
.calc { align-items: start; }
.calc h2 { margin-bottom: 2.5rem; }
.calc__label { color: var(--muted); margin: 0 0 0.8rem; }

.chips { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 2.25rem; }
.chips button {
  background: var(--bg-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.8rem 1.15rem;
  cursor: pointer;
  font-family: inherit;
  font-size: 1rem;
  color: var(--muted);
}
.chips button:hover { color: var(--text); border-color: var(--accent-dim); }
.chips button[aria-pressed="true"] { background: var(--bg-raised); border-color: var(--accent-2); color: var(--text); }

.loss__days {
  font: 400 13px/1.5 var(--mono);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  margin-bottom: 1.5rem;
}
/* One dot per unpaid work day. The dots shrink instead of being capped: a
   truncated grid would stop matching the number printed above it. */
.loss__dots { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 2rem; }
.loss__dots span { width: 1.15rem; height: 1.15rem; border-radius: 50%; background: var(--stop); }
.loss__dots.is-dense span { width: 0.8rem; height: 0.8rem; }
.loss__dots.is-denser { gap: 0.35rem; }
.loss__dots.is-denser span { width: 0.55rem; height: 0.55rem; }

.loss__intro { color: var(--muted); margin-bottom: 0.6rem; }
.loss__figure { font-weight: 700; letter-spacing: -0.02em; font-size: clamp(3rem, 6.5vw, 4.5rem); line-height: 1; color: var(--accent-2); margin-bottom: 1.5rem; }
.loss__row { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-bottom: 2rem; }
.loss__chip { background: var(--border); border-radius: var(--radius); padding: 0.7rem 1.1rem; }
.loss__formula { font: 400 13px/1.5 var(--mono); color: var(--placeholder); margin-bottom: 2rem; }

/* ---------- Waiting screen ---------- */
.waiting { display: flex; flex-direction: column; align-items: center; gap: 2rem; }

.loader {
  position: relative;
  width: min(20rem, 78vw);
  aspect-ratio: 1;
  border-radius: 50%;
  animation: sc-breathe 2.8s ease-in-out infinite;
}
/* Fill: set --p (0–1) from JS; the conic gradient reads it directly. */
.loader__ring {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    #7b61ff 0deg,
    #b15cff calc(var(--p, 0) * 200deg),
    #ff5ca8 calc(var(--p, 0) * 360deg),
    var(--border-soft) calc(var(--p, 0) * 360deg)
  );
}
.loader__hole { position: absolute; inset: 14px; border-radius: 50%; background: var(--bg); }
.loader__arc {
  position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid transparent; border-top-color: var(--accent-dim);
  animation: sc-orbit 2.2s linear infinite;
}
.loader__dash {
  position: absolute; inset: 22px; border-radius: 50%;
  border: 1px dashed var(--border);
  animation: sc-orbit 14s linear infinite reverse;
}
.loader__inner {
  position: absolute; inset: 14px; border-radius: 50%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.9rem; padding: 2.5rem 1.5rem; text-align: center;
}
.loader__percent {
  font-weight: 700; letter-spacing: -0.02em; font-size: 2.6rem; line-height: 1;
  color: var(--accent-2);
  animation: sc-drift 3s ease-in-out infinite;
}
.loader__lines { position: relative; width: 100%; height: 3.6rem; }
.loader__line {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.02rem;
  opacity: 0; transform: translateY(10px);
  transition: opacity 0.45s ease, transform 0.45s ease;
}
.loader__line.is-done { opacity: 0; transform: translateY(-10px); }
.loader__line.is-active { opacity: 1; transform: translateY(0); }

.loader__steps { display: flex; gap: 0.6rem; }
.loader__steps span {
  width: 2.5rem; height: 3px; border-radius: var(--radius);
  background: var(--border); transition: background 0.4s ease;
}
.loader__steps span.is-reached { background: var(--accent); }

@keyframes sc-spin { to { transform: rotate(360deg); } }
@keyframes sc-orbit { to { transform: rotate(360deg); } }
@keyframes sc-fade-up { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes sc-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@keyframes sc-glow { 0%, 100% { opacity: 0.55; } 50% { opacity: 0.9; } }
@keyframes sc-drift { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
@keyframes sc-breathe {
  0%, 100% { box-shadow: 0 0 0 0 rgba(123, 97, 255, 0.25); }
  50% { box-shadow: 0 0 0 22px rgba(123, 97, 255, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .loader, .loader__arc, .loader__dash, .loader__percent { animation: none; }
  .loader__line { transition: none; }
}

/* ---------- Email gate / access form ---------- */
.gate {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(8, 8, 12, 0.72);
  display: flex; align-items: center; justify-content: center;
  padding: 1.5rem;
}
.gate__box {
  width: 100%; max-width: 26rem;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 2rem;
}
.gate__box h3 { font-size: 1.4rem; margin-bottom: 0.6rem; }
.gate__box input[type="email"] { margin-bottom: 0.75rem; }
.gate__box .btn-primary { width: 100%; padding: 0.95rem 1.6rem; font-size: 1rem; margin-bottom: 1rem; }
/* The thank-you state's button is a link into the tool, and a full-width
   inline-block anchor still needs to be told to centre its own text. */
.gate__box a.btn-primary { text-align: center; }
.gate__exit { text-align: center; }

/* ---------- Cookie bar ---------- */
.cookie {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  background: var(--bg-raised);
  border-top: 1px solid var(--border);
}
.cookie__inner {
  max-width: var(--page); margin: 0 auto; padding: 1rem 2rem;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem;
}
.cookie span { color: var(--muted); font-size: 0.9rem; max-width: 26rem; }
.cookie__actions { display: flex; gap: 0.75rem; }

/* ---------- Legal pages ---------- */
.legal { max-width: var(--measure); margin: 0 auto; padding: 4rem 2rem 5rem; }
.legal h1 { font-size: clamp(2rem, 4vw, 2.6rem); margin-bottom: 1.5rem; }
.legal h2 { font-size: 1.3rem; margin: 2.5rem 0 0.75rem; }
.legal ul { padding-left: 1.2rem; color: var(--muted); margin: 0 0 1rem; }
.legal li { margin-bottom: 0.4rem; }
.legal code { font: 400 0.9em/1 var(--mono); color: var(--accent-2); }

/* ---------- Footer ---------- */
.footer {
  max-width: var(--page); margin: 0 auto; padding: 2rem;
  border-top: 1px solid var(--border-soft);
  font: 400 12px/1.8 var(--mono); letter-spacing: 0.06em; color: var(--muted);
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem;
}
.footer nav { display: flex; gap: 1.5rem; }
.footer a { color: var(--muted); border-bottom-color: var(--border); }
.footer a:hover { color: var(--text); }

@media (max-width: 640px) {
  .wrap { padding: 0 1.25rem; }
  .header__inner { padding: 0.8rem 1.25rem; }
  .section { padding: 3.5rem 0; }
  .screen { padding: 2.5rem 1.25rem; }
  .cookie__inner, .footer { padding: 1rem 1.25rem; }
}
