/* ===========================================================================
   LIMS Lite signup — design system
   ---------------------------------------------------------------------------
   HODO brand: primary #0078BF, secondary #F04E98 (matched to limslite.com's
   Figma redesign, 9 Nov 2026 — see the theme note below).

   Accessibility is not a layer on top of this stylesheet, it is the reason
   for several of its rules:
     · :focus-visible gets a 3px high-contrast ring on EVERY interactive
       element, in both colour schemes. Nothing sets outline:none without a
       replacement.
     · every scrollable region is overflow-y:auto with a real max-height, so
       PageUp/PageDown/Home/End work inside it.
     · nothing depends on hover to be discoverable or operable.
     · prefers-reduced-motion removes every transition and animation.
   ========================================================================= */

@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@400;500;600;700;800&family=Inter:wght@400;500;600&display=swap');

/* ---------------------------------------------------------------------------
   Theme: limslite.com apex (Figma "limslite", 9 Nov 2026).
   The values below are lifted from the apex site's css/limslite.css so the
   brochure page and this signup flow read as one product. The VARIABLE NAMES
   are this stylesheet's own and deliberately unchanged — ~1300 lines of
   component rules already reference them, so retuning the palette here
   re-skins the whole app (signup, approve, dashboard) without touching those
   rules and risking a regression in a flow that provisions live tenants.
   ------------------------------------------------------------------------- */
:root {
  --blue: #0078bf;          /* apex --blue        */
  --blue-dark: #0a5e93;     /* apex --blue-700    */
  --blue-wash: #eaf4fb;     /* apex --blue-50     */
  --blue-wash-2: #d6ecf8;   /* apex --blue-100    */
  --pink: #f04e98;          /* apex --pink        */
  --pink-wash: #fdedf4;     /* apex --pink-50     */
  --green: #059669;         /* apex --green       */
  --green-wash: #ecfdf5;
  --amber: #d97706;
  --amber-wash: #fffbeb;
  /* Apex rule, carried over verbatim: validation errors are red, never pink —
     pink is a brand accent, not a failure state. */
  --red: #d92d20;           /* apex --error       */
  --red-wash: #fef3f2;
  --red-ring: rgba(217, 45, 32, 0.16);
  --blue-ring: rgba(0, 120, 191, 0.14);

  /* Semantic colours used as TEXT rather than as a fill.
     In light mode they are the brand colours unchanged. In dark mode they are
     lightened, because the brand greens/blues/reds are dark hues: #047857
     text on the dark green wash is 2.7:1, which fails WCAG AA for small text.
     Fills keep using --green/--blue/--red so a white glyph on a solid chip
     stays legible — the two jobs need different values.

     Light mode is not simply the brand hue either: #0078bf as 11–13px text on
     the pale blue wash is 4.30:1 and #d97706 on the amber wash is 3.07:1, both
     short of AA. --blue-ink is therefore the brand's own --blue-dark (6.08:1)
     and --amber-ink is one stop darker (4.84:1). Fills are untouched, so the
     buttons and chips keep the exact brand primary. */
  --green-ink: #047857;
  --blue-ink: #0a5e93;
  --amber-ink: #b45309;
  --red-ink: #b42318;
  /* Brand pink as 11px bold text on white is 3.0:1 — short of AA, same
     problem as blue/amber above. Darker clears it at 4.79:1. The apex site
     uses the raw --pink for its eyebrow; here it is reserved for FILLS and
     rules, and text takes this value instead. */
  --pink-ink: #c42d7a;

  --ink: #0c2230;           /* apex --ink    */
  --ink-2: #46606d;         /* apex --body   */
  /* apex --muted is #64748B; one stop darker, because 13px text on the
     --sheet-2 wash measures 4.49:1 there and AA wants 4.5:1. */
  --ink-3: #616f85;
  /* Placeholder grey only, and placeholders only ever sit on --sheet,
     where this is 4.75:1. Apex's #94A3B8 is 2.56:1 and is not used. */
  --faint: #667488;
  --line: #e2e8f0;          /* apex --line   */
  --line-2: #cbd5e1;
  --line-soft: #eef3f7;     /* apex --line-soft */
  --line-card: #e4effc;     /* apex --line-card */
  --bg: #f4f9fc;            /* apex --wash   */
  --sheet: #ffffff;
  --sheet-2: #f4f9fc;

  --radius: 20px;           /* apex --radius-lg, used on the step sheets  */
  --radius-sm: 10px;        /* apex field radius                          */
  --radius-md: 12px;        /* apex plan-tile radius                      */
  --radius-pill: 999px;     /* apex buttons are fully rounded             */
  --header-h: 76px;
  --shadow: 0 8px 24px -14px rgba(8, 52, 80, 0.3);  /* apex --shadow-card */
  --shadow-lg: 0 14px 40px rgba(12, 34, 48, 0.1);
  --focus: var(--blue);
  --mono: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e5e7eb;
    --ink-2: #cbd5e1;
    --ink-3: #94a3b8;
    --faint: #8295ab;
    --line: #1f2a44;
    --line-2: #2d3b5a;
    --line-soft: #1a2437;
    --line-card: #24375a;
    --bg: #0b1220;
    --sheet: #111a2c;
    --sheet-2: #16213a;
    --blue-wash: #112a3f;
    --blue-wash-2: #163a57;
    --pink-wash: #33182a;
    --green-wash: #0d2a22;
    --amber-wash: #2e2410;
    --red-wash: #2d1513;
    --red-ring: rgba(252, 165, 165, 0.22);
    --blue-ring: rgba(108, 197, 255, 0.22);
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.45);
    --shadow-lg: 0 18px 44px rgba(0, 0, 0, 0.5);
    /* A lighter ring reads better on the dark sheet. */
    --focus: #6cc5ff;
    /* Text-weight variants, lightened to clear 4.5:1 on the dark sheet and
       on every wash. Measured against --sheet (#111a2c): 8.9, 9.1, 10.4 and
       9.0:1 respectively, versus 2.6–3.6:1 for the unlightened brand hues. */
    --green-ink: #34d399;
    --blue-ink: #6cc5ff;
    --amber-ink: #fbbf24;
    --red-ink: #fca5a5;
    --pink-ink: #f472b6;
  }
}

* { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  /* The masthead is sticky, so an anchor jump must stop clear of it rather
     than underneath it. Smooth scrolling is removed again by the
     prefers-reduced-motion block further down. */
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 16px/1.6 'Raleway', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ── skip link ───────────────────────────────────────────────────────────── */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--sheet);
  color: var(--ink);
  padding: 12px 18px;
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 700;
}
.skip:focus { left: 0; }

/* ── focus ring: one rule, every element ─────────────────────────────────── */
:focus { outline: none; }
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 6px;
}
/* Keyboard users who land on a card get the same affordance. */
[tabindex='-1']:focus-visible { outline-offset: 4px; }

/* ── layout ──────────────────────────────────────────────────────────────── */
.shell {
  max-width: 1080px;
  margin: 0 auto;
  padding: 28px 20px 64px;
}

/* Sticky brand band, matching the apex header: a full-bleed 76px rule with a
   translucent white fill, its contents constrained to the same column as the
   page body by .masthead-inner. The <header> therefore sits OUTSIDE .shell —
   a band that stopped at the shell's 1080px would not read as a header. */
.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--sheet) 92%, transparent);
  border-bottom: 1px solid var(--line-soft);
}
.masthead-inner {
  max-width: 1080px;
  margin: 0 auto;
  padding: 10px 20px;
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
@supports (backdrop-filter: blur(12px)) or (-webkit-backdrop-filter: blur(12px)) {
  .masthead {
    -webkit-backdrop-filter: saturate(180%) blur(12px);
    backdrop-filter: saturate(180%) blur(12px);
  }
}
/* color-mix is recent; without it the band must still be opaque, or the
   content scrolling underneath shows through. */
@supports not (background: color-mix(in srgb, #fff 92%, transparent)) {
  .masthead { background: var(--sheet); }
}

.brand {
  display: flex;
  align-items: center;
  gap: 13px;
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-decoration: none;
}
.brand img {
  height: 38px;
  width: auto;
  display: block;
  flex: none;
}
/* The HODO lockup is a dark-navy wordmark, so on the dark scheme it all but
   disappears. The brand guidelines forbid recolouring it and require a
   containing shape instead — so it gets a white plate rather than a filter. */
@media (prefers-color-scheme: dark) {
  .brand img {
    background: #fff;
    border-radius: 8px;
    padding: 5px 8px;
    box-sizing: content-box;
  }
}
.brand span { display: block; }
.brand small {
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pink-ink);
}

.masthead-aside {
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-2);
  margin: 0;
}
.masthead-aside a { color: var(--blue-ink); font-weight: 600; }

/* ── hero copy ───────────────────────────────────────────────────────────── */
.hero { padding-bottom: 30px; max-width: 760px; }

/* The trial offer, restyled to the apex eyebrow: a pink rule followed by the
   terms. A statement of terms, not a sales flash — no animation, no shouting,
   and it reads correctly when the colour is not perceived. */
.badge {
  display: flex;
  /* flex-start, not center: on a narrow screen the text wraps to two lines
     and a centred rule would float beside the gap between them. */
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 14px;
  padding: 0;
  border: 0;
  background: none;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink-2);
}
.badge strong { color: var(--pink-ink); font-weight: 800; }
.badge-dot {
  width: 18px;
  height: 2px;
  margin-top: 10px;   /* centres the rule on the FIRST line (14px × 1.6) */
  border-radius: 2px;
  background: var(--pink);
  flex: none;
}
.hero h1 {
  margin: 0 0 14px;
  font-size: clamp(30px, 4.6vw, 46px);
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.18;
  color: var(--blue);
}
/* Apex treatment: the closing phrase drops to a new line in brand pink. */
.hero h1 .accent { color: var(--pink-ink); display: block; }
.hero p { margin: 0; color: var(--ink-2); font-size: 18.5px; line-height: 1.55; }
.hero .trust {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  padding-top: 20px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-2);
}
/* Direct children only: the chips now contain a nested <span> carrying the
   trial length, and a descendant selector would give that one its own bullet
   too — "• •10-day free trial". */
/* The chip lays its own contents out as inline flow, NOT as a flex row. A
   chip now wraps a <span> carrying the trial length, and as a flex item that
   token is blockified and separated by the row gap — "10 -day free trial".
   (Blockification is a used-value rule, so `display: inline` on the token
   cannot override it; the container has to stop being flex.) Inline flow also
   lets a long chip wrap across lines like ordinary text. */
.hero .trust > span { display: block; }
/* Apex treatment: a pink tick rather than a bullet. Decorative — the chip's
   own words carry the meaning, so nothing is lost if the glyph is dropped. */
.hero .trust > span::before {
  content: '✓';
  display: inline-block;
  margin-right: 8px;
  vertical-align: baseline;
  font-size: 14px;
  font-weight: 800;
  color: var(--pink-ink);
}

/* ── stepper ─────────────────────────────────────────────────────────────── */
/* Ported from the apex modal's step rail: bare numbered pips, no chips. The
   current step is pink, a finished one is a solid pink pip with a tick. The
   state is carried by data-state (set by signup.js), never by colour alone —
   the current panel's heading says the same thing. */
.stepper {
  display: flex;
  gap: 10px 22px;
  align-items: center;
  list-style: none;
  margin: 0 0 24px;
  padding: 0 0 22px;
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.stepper li {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-3);
}
.stepper li .n {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--sheet-2);
  color: var(--ink-3);
  display: grid;
  place-items: center;
  font-size: 13px;
  font-weight: 700;
  flex: none;
  border: 1px solid var(--line);
}
.stepper li[data-state='current'] { color: var(--pink-ink); font-weight: 700; }
.stepper li[data-state='current'] .n {
  background: var(--pink-wash);
  color: var(--pink-ink);
  border-color: var(--pink);
}
.stepper li[data-state='done'] { color: var(--ink); font-weight: 700; }
.stepper li[data-state='done'] .n {
  background: var(--pink);
  color: #fff;
  border-color: var(--pink);
  /* The step number is replaced by a tick, exactly as on the apex rail. */
  font-size: 0;
}
.stepper li[data-state='done'] .n::after {
  content: '✓';
  font-size: 14px;
  line-height: 1;
  font-weight: 700;
}

/* ── sheet / card ────────────────────────────────────────────────────────── */
.sheet {
  position: relative;
  background: var(--sheet);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
/* Apex modal accent: a blue/pink rule across the top of the card. Purely
   decorative, so it is a pseudo-element rather than markup. */
.sheet::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 4px;
  background: linear-gradient(90deg, var(--blue) 0 52%, var(--pink) 52% 100%);
}
.sheet-head {
  padding: 26px 30px 0;
}
.sheet-head h2 {
  margin: 0 0 8px;
  font-size: clamp(21px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -0.025em;
}
.sheet-head p { margin: 0; color: var(--ink-2); font-size: 15.5px; font-weight: 500; }
.sheet-body { padding: 24px 30px 30px; }
.sheet-foot {
  padding: 18px 30px;
  border-top: 1px solid var(--line-soft);
  background: var(--sheet-2);
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}
.sheet-foot .spacer { flex: 1 1 auto; }

/* ── form ────────────────────────────────────────────────────────────────── */
.grid { display: grid; gap: 18px; grid-template-columns: 1fr 1fr; }
.grid .full { grid-column: 1 / -1; }
@media (max-width: 680px) { .grid { grid-template-columns: 1fr; } }

.field label {
  display: block;
  font-size: 15px;
  font-weight: 700;
  padding-bottom: 8px;
  color: var(--ink);
}
.field label .req { color: var(--pink); margin-left: 3px; }

input[type='text'],
input[type='email'],
input[type='tel'],
textarea,
select {
  width: 100%;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--sheet);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
/* Auto-grow to a sensible ceiling, then scroll inside — so PageUp/PageDown,
   Home/End and the wheel all work on a long set of call notes instead of the
   box swallowing the page. */
textarea {
  display: block;
  resize: vertical;
  min-height: 92px;
  max-height: 40vh;
  overflow-y: auto;
  line-height: 1.55;
}
input::placeholder, textarea::placeholder { color: var(--faint); opacity: 1; }
input:hover:not(:disabled), textarea:hover:not(:disabled), select:hover:not(:disabled) { border-color: var(--line-card); }
/* The apex field adds a soft brand halo on focus. The 3px :focus-visible
   outline from the single rule near the top of this file is NOT replaced by
   it — both are present, so keyboard focus stays unmistakable. */
input:focus, textarea:focus, select:focus {
  border-color: var(--blue);
  box-shadow: 0 0 0 3px var(--blue-ring);
}
input:disabled { background: var(--sheet-2); color: var(--ink-3); cursor: not-allowed; }

.hint { font-size: 13px; color: var(--ink-3); padding-top: 8px; line-height: 1.45; }
.hint code {
  font-family: var(--mono);
  font-size: 12px;
  background: var(--sheet-2);
  padding: 1px 5px;
  border-radius: 4px;
}

.err {
  font-size: 13px;
  font-weight: 600;
  color: var(--red-ink);
  padding-top: 8px;
  line-height: 1.45;
}
.err:empty { display: none; }
.field[data-invalid='true'] input { border-color: var(--red); }
.field[data-invalid='true'] input:focus { box-shadow: 0 0 0 3px var(--red-ring); }

/* ── checkbox field ──────────────────────────────────────────────────────────
   A real <input type=checkbox>, sized up to a comfortable touch target and
   wrapped in its own label so the whole line toggles it — by click, by tap,
   and by Space when focused. */
.field.check { padding-top: 20px; }
.field.check label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border: 1.5px solid var(--line-2);
  border-radius: var(--radius-sm);
  background: var(--sheet-2);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.5;
  cursor: pointer;
}
.field.check label:hover { border-color: var(--ink-3); }
.field.check input[type='checkbox'] {
  width: 22px;
  height: 22px;
  margin: 0;
  flex: none;
  accent-color: var(--blue);
  cursor: pointer;
}
.field.check input[type='checkbox']:checked ~ span { color: var(--blue-ink); }

/* Inline disclosure inside a sheet, instead of a dialog box. */
.sheet-body.bordered {
  border-top: 1px solid var(--line);
  background: var(--sheet-2);
  padding: 20px 28px 22px;
}

/* ── call-out: one thing the reader must act on ──────────────────────────── */
.callout {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 0 20px;
  padding: 16px 18px;
  border: 1.5px solid var(--blue);
  background: var(--blue-wash);
  border-radius: var(--radius-sm);
}
.callout-k {
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--blue-ink);
}
.callout-v {
  font-size: 19px;
  font-weight: 800;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.01em;
}
.callout-v:hover { text-decoration: underline; }
.callout-s { font-size: 12.5px; color: var(--ink-3); }

/* instance name: input + fixed domain suffix */
.addr {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--sheet);
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.addr:hover { border-color: var(--line-card); }
.addr:focus-within { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-ring); }
.addr input {
  border: 0;
  border-radius: 0;
  flex: 1 1 auto;
  min-width: 0;
  /* Left-aligned on purpose: a right-aligned editable field makes the
     browser rescroll its visible window on every keystroke once the text
     overflows the box (narrow/mobile widths hit this almost immediately,
     since this box is short by design). That rescroll is what made typing
     here feel broken — characters landing in the wrong place, letters
     dropped or doubled while the view caught up. Left-align is how every
     "yourname.domain" input does it, and it's the one alignment where the
     caret position is exactly where it visually should be at every length. */
  text-align: left;
  font-family: var(--mono);
  font-size: 15px;
}
.addr input:focus-visible { outline: none; }
.addr .suffix {
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 500;
  color: var(--ink-2);
  background: var(--sheet-2);
  border-left: 1px solid var(--line);
  white-space: nowrap;
}
/* The whole control gets the ring, not the bare input inside it. */
.addr:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }

.addr-status {
  font-size: 12.5px;
  font-weight: 700;
  padding-top: 7px;
  display: flex;
  align-items: center;
  gap: 7px;
  min-height: 19px;
}
.addr-status[data-state='ok'] { color: var(--green-ink); }
.addr-status[data-state='bad'] { color: var(--red-ink); }
.addr-status[data-state='busy'] { color: var(--ink-3); }

/* ── billing plan cards ──────────────────────────────────────────────────────
   Free Trial is informational only (every signup gets it automatically);
   Monthly and Annual are a role="radio" pair — selection is display/record
   only, nothing here charges anyone. 300px floor settles 3-up on a form-width
   column and collapses to 1-up on narrow screens, same rule as .feature-grid. */
.plan-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
  margin-top: 4px;
}
.plan-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  text-align: left;
  font: inherit;
  padding: 16px 16px 18px;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-md);
  background: var(--sheet);
  color: inherit;
}
button.plan-card {
  cursor: pointer;
  transition: border-color 0.16s ease, background-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}
button.plan-card:hover { border-color: var(--line-card); transform: translateY(-1px); }
button.plan-card:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
button.plan-card[aria-checked='true'] {
  border-color: var(--blue);
  background: var(--blue-wash);
  box-shadow: inset 0 0 0 1px var(--blue);
}
.plan-tag {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.plan-tag-best { color: var(--pink-ink); }
.plan-card strong { font-size: 16px; font-weight: 700; color: var(--ink); line-height: 1.25; }
.plan-price { font-size: 21px; font-weight: 800; color: var(--blue-ink); letter-spacing: -0.02em; }
.plan-price small { font-size: 12.5px; font-weight: 600; color: var(--ink-3); }
.plan-note { font-size: 13px; line-height: 1.45; color: var(--ink-2); }
.plan-card-trial { background: var(--sheet-2); border-style: dashed; }

/* ── buttons ─────────────────────────────────────────────────────────────── */
/* Apex buttons are fully rounded. The lift on hover is suppressed by the
   reduced-motion block, and never carries meaning on its own. */
.btn {
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  border-radius: var(--radius-pill);
  padding: 15px 28px;
  border: 1.5px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  text-decoration: none;
  transition: background-color 0.16s ease, border-color 0.16s ease, color 0.16s ease,
              box-shadow 0.16s ease, transform 0.16s ease;
}
.btn:hover:not(:disabled) { transform: translateY(-1px); }
.btn:active:not(:disabled) { transform: translateY(0); }
.btn-primary { background: var(--blue); color: #fff; box-shadow: 0 6px 16px rgba(0, 120, 191, 0.24); }
.btn-primary:hover:not(:disabled) { background: #0268a6; }
.btn-ghost { background: var(--sheet); color: var(--blue-ink); border-color: var(--blue); }
.btn-ghost:hover:not(:disabled) { background: var(--blue-wash); color: var(--blue-dark); }
.btn-link {
  background: none;
  border: 0;
  color: var(--blue);
  font-weight: 700;
  font-size: 14px;
  padding: 6px 4px;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.btn:disabled, .btn-link:disabled { opacity: 0.55; cursor: not-allowed; }

.btn .spin {
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 999px;
  animation: spin 0.7s linear infinite;
  display: none;
}
.btn[aria-busy='true'] .spin { display: block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── one-time code ───────────────────────────────────────────────────────── */
.otp-wrap { max-width: 330px; }
input.otp {
  font-family: var(--mono);
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 0.32em;
  text-align: center;
  padding: 14px 10px 14px 20px;
}
.otp-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding-top: 14px;
  font-size: 13px;
  color: var(--ink-3);
}

/* ── notice blocks (replace alert dialogs entirely) ──────────────────────── */
.notice {
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-size: 14px;
  line-height: 1.6;
  border: 1px solid transparent;
  margin-bottom: 18px;
}
.notice:empty { display: none; }
.notice strong { font-weight: 800; }
.notice-info { background: var(--blue-wash); border-color: var(--blue); color: var(--ink); }
.notice-ok { background: var(--green-wash); border-color: var(--green); color: var(--ink); }
.notice-warn { background: var(--amber-wash); border-color: var(--amber); color: var(--ink); }
.notice-err { background: var(--red-wash); border-color: var(--red); color: var(--ink); }

/* ── progress list ───────────────────────────────────────────────────────── */
.steps { list-style: none; margin: 0; padding: 0; }
.steps li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14.5px;
}
.steps li:last-child { border-bottom: 0; }
.steps .icon {
  width: 24px;
  height: 24px;
  border-radius: 999px;
  flex: none;
  display: grid;
  place-items: center;
  font-size: 12px;
  font-weight: 800;
  background: var(--line);
  color: var(--ink-3);
  margin-top: 1px;
}
.steps li[data-state='active'] .icon { background: var(--blue); color: #fff; }
.steps li[data-state='active'] .icon::after {
  content: '';
  width: 9px;
  height: 9px;
  border: 2px solid #fff;
  border-right-color: transparent;
  border-radius: 999px;
  animation: spin 0.7s linear infinite;
}
.steps li[data-state='done'] .icon { background: var(--green); color: #fff; }
/* The ` / ''` is the alternative text for this generated content: these
   markers are decoration beside a label that already says the same thing,
   and without it a screen reader announces a bare "tick" — Chromium reads
   pseudo-element content even inside an aria-hidden, display:none panel. */
.steps li[data-state='done'] .icon::after { content: '\2713' / ''; }
.steps li[data-state='failed'] .icon { background: var(--red); color: #fff; }
.steps li[data-state='failed'] .icon::after { content: '!' / ''; }
/* A static list of instructions, not a progress indicator. Three spinning
   icons on the confirmation page would claim that work is already under way —
   the exact opposite of what that page is telling the reader. Numbered,
   motionless markers instead. */
.steps.guide { counter-reset: guide; }
.steps.guide li { counter-increment: guide; }
.steps.guide li .icon { background: var(--blue); color: #fff; }
.steps.guide li .icon::after {
  content: counter(guide) / '';
  width: auto;
  height: auto;
  border: 0;
  animation: none;
}

.steps .label { font-weight: 700; }
.steps .detail { font-size: 13px; color: var(--ink-3); padding-top: 2px; }
.steps li[data-state='pending'] .label { color: var(--ink-3); font-weight: 600; }

.log {
  margin-top: 20px;
  max-height: 220px;
  overflow-y: auto;
  background: var(--sheet-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.7;
  color: var(--ink-2);
}
.log p { margin: 0; }
.log .t { color: var(--ink-3); }

/* ── credentials ─────────────────────────────────────────────────────────── */
.creds {
  background: var(--blue-wash);
  border: 1px solid var(--blue);
  border-radius: var(--radius-sm);
  padding: 4px 18px;
  margin-bottom: 20px;
}
.cred {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 0;
  border-bottom: 1px solid rgba(0, 120, 191, 0.22);
  flex-wrap: wrap;
}
.cred:last-child { border-bottom: 0; }
.cred .k {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue);
  width: 112px;
  flex: none;
}
.cred .v {
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  word-break: break-all;
  flex: 1 1 180px;
  min-width: 0;
}
.cred .v a { color: var(--ink); }

/* ── table ───────────────────────────────────────────────────────────────── */
.table-wrap { overflow-x: auto; overflow-y: auto; max-height: 62vh; }
table.data { width: 100%; border-collapse: collapse; font-size: 14px; }
table.data th,
table.data td {
  text-align: left;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
table.data th {
  position: sticky;
  top: 0;
  background: var(--sheet-2);
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
  z-index: 1;
}
table.data tbody tr:hover { background: var(--sheet-2); }
table.data tbody tr:focus-within { background: var(--blue-wash); }
table.data td.wrap { white-space: normal; min-width: 180px; }

/* The last column is always a row action (Open / Review) — pin it to the
   right edge of the scroll container so it's never the thing a wide row
   scrolls out of view. Without this, a row with enough columns to overflow
   .table-wrap hides its own "Open" button behind a horizontal scrollbar a
   user has no visual cue to reach — confirmed twice as "where's the restart
   option" confusion on the Failed row, whose action was simply off-screen. */
table.data th:last-child,
table.data td:last-child {
  position: sticky;
  right: 0;
  background: var(--sheet);
  box-shadow: -6px 0 6px -6px rgb(0 0 0 / 0.12);
}
table.data th:last-child { background: var(--sheet-2); z-index: 2; }
table.data tbody tr:hover td:last-child { background: var(--sheet-2); }
table.data tbody tr:focus-within td:last-child { background: var(--blue-wash); }

.pill {
  display: inline-block;
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid transparent;
}
.pill-live { background: var(--green-wash); color: var(--green-ink); border-color: var(--green); }
.pill-failed { background: var(--red-wash); color: var(--red-ink); border-color: var(--red); }
.pill-queued, .pill-provisioning { background: var(--amber-wash); color: var(--amber-ink); border-color: var(--amber); }
/* Awaiting a sales call is an action for us, not a neutral state — it reads
   as blue (ours to do) rather than grey (nothing to do). */
.pill-awaiting_approval { background: var(--blue-wash); color: var(--blue-ink); border-color: var(--blue); }
.pill-started, .pill-email_verified, .pill-mobile_verified, .pill-abandoned, .pill-declined {
  background: var(--sheet-2); color: var(--ink-3); border-color: var(--line-2);
}
/* Overdue in the waiting queue. */
.pill-overdue { background: var(--red-wash); color: var(--red-ink); border-color: var(--red); }

/* ── stat tiles ──────────────────────────────────────────────────────────── */
.tiles {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(166px, 1fr));
  padding-bottom: 22px;
}
.tile {
  background: var(--sheet);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 16px 18px;
}
.tile .k {
  font-size: 11.5px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.tile .v {
  font-size: 27px;
  font-weight: 800;
  letter-spacing: -0.02em;
  padding-top: 5px;
  line-height: 1.1;
}
.tile .s { font-size: 12.5px; color: var(--ink-3); padding-top: 3px; }

/* ── 30-day bar chart ────────────────────────────────────────────────────── */
.chart {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 92px;
  padding-top: 8px;
}
.chart .bar {
  flex: 1 1 0;
  min-width: 3px;
  background: var(--line-2);
  border-radius: 3px 3px 0 0;
  position: relative;
}
.chart .bar .live {
  position: absolute;
  inset: auto 0 0 0;
  background: var(--blue);
  border-radius: 3px 3px 0 0;
}

/* ── detail panel ────────────────────────────────────────────────────────── */
.panel { display: grid; gap: 22px; grid-template-columns: 1fr 1fr; }
@media (max-width: 860px) { .panel { grid-template-columns: 1fr; } }
dl.kv { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: 9px 16px; font-size: 14px; }
dl.kv dt { color: var(--ink-3); font-weight: 600; white-space: nowrap; }
dl.kv dd { margin: 0; font-weight: 600; word-break: break-word; }
dl.kv dd.mono { font-family: var(--mono); font-size: 13px; }

/* ── keyboard help ───────────────────────────────────────────────────────── */
.keys {
  margin-top: 24px;
  font-size: 13px;
  color: var(--ink-3);
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
}
kbd {
  font-family: var(--mono);
  font-size: 11.5px;
  font-weight: 700;
  background: var(--sheet);
  border: 1px solid var(--line-2);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 2px 6px;
  color: var(--ink-2);
}

/* ── what LIMS Lite does (marketing content, below the form) ─────────────── */
/* Separated from the wizard by a rule rather than a card, so it reads as page
   content and never competes with the sheet the visitor is filling in. */
.features {
  margin-top: 48px;
  padding-top: 36px;
  border-top: 1px solid var(--line);
}
.features h2 {
  margin: 0 0 8px;
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.features h2#h-included { margin-top: 38px; }
.features-lede {
  margin: 0 0 22px;
  max-width: 640px;
  color: var(--ink-2);
  font-size: 15px;
  line-height: 1.65;
}

.feature-grid {
  display: grid;
  /* 300px rather than a smaller floor: six cards over a ~1040px content column
     settle into 3 + 3 instead of 4 + 2 orphans, and the body copy gets a
     comfortable measure. Still collapses to 2-up and 1-up on narrow screens. */
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.feature-grid > li {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--sheet);
}
.feature-grid h3 {
  margin: 0 0 6px;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink);
}
.feature-grid p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-2);
}

.included {
  margin: 0;
  padding: 0;
  list-style: none;
  max-width: 680px;
}
.included > li {
  position: relative;
  padding: 7px 0 7px 26px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-2);
}
/* Decorative tick drawn from two borders rather than a ✓ character, so there is
   no generated text for a screen reader to announce in the first place. */
.included > li::before {
  content: '';
  position: absolute;
  left: 2px;
  top: 13px;
  width: 11px;
  height: 6px;
  border-left: 2px solid var(--green);
  border-bottom: 2px solid var(--green);
  transform: rotate(-45deg);
}
.included strong { color: var(--ink); font-weight: 700; }
.included code {
  font-family: var(--mono);
  font-size: 12.5px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--sheet-2);
  border: 1px solid var(--line);
}

.features-foot {
  margin: 26px 0 0;
  font-size: 14px;
  line-height: 1.65;
  color: var(--ink-2);
}
.features-foot a { color: var(--blue-ink); font-weight: 600; }

/* ── footer ──────────────────────────────────────────────────────────────── */
.foot {
  margin-top: 44px;
  padding-top: 26px;
  border-top: 1px solid var(--line-soft);
  font-size: 13px;
  color: var(--ink-3);
  line-height: 1.7;
}
.foot a { color: var(--ink-3); text-decoration: underline; text-underline-offset: 3px; }
.foot a:hover { color: var(--blue-ink); }

/* ── utility ─────────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
[hidden] { display: none !important; }
.honeypot {
  position: absolute !important;
  left: -9999px !important;
  width: 1px; height: 1px;
  opacity: 0;
}

/* ===========================================================================
   The confirmation call
   ---------------------------------------------------------------------------
   Two surfaces share these components: the sales page, where the call is
   recorded, and the applicant's wait screen, where the shared half of it
   appears as it is typed.

   The sales page is used one-handed, on a phone, while talking. That drives
   three decisions: the action bar is sticky so the decision is never more
   than a thumb away, every option is a chip big enough to hit without
   looking, and nothing that matters is behind a hover.
   ========================================================================= */

/* ── information buttons (the "i") ───────────────────────────────────────── */
.i {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  border: 1.5px solid var(--line-2);
  background: var(--sheet);
  color: var(--ink-3);
  font-size: 11.5px;
  font-weight: 800;
  font-family: var(--mono);
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease;
}
.i:hover { border-color: var(--blue); color: var(--blue-ink); }
.i[aria-expanded='true'] { border-color: var(--blue); background: var(--blue-wash); color: var(--blue-ink); }

/* ── disclosures ─────────────────────────────────────────────────────────── */
.disc {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 10px 0;
  font: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--blue-ink);
  cursor: pointer;
}
.disc-i {
  width: 0;
  height: 0;
  border-left: 6px solid currentColor;
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
  transition: transform 0.14s ease;
}
.disc[aria-expanded='true'] .disc-i { transform: rotate(90deg) translateX(1px); }
.disc-body { padding: 4px 0 12px; }

/* ── pre-call checks ─────────────────────────────────────────────────────── */
.checks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}
.chip {
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--sheet-2);
  padding: 10px 12px;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2px 8px;
  align-items: start;
}
.chip-k {
  grid-column: 1;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.chip .i { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
.chip-v { grid-column: 1; font-size: 13.5px; font-weight: 700; color: var(--ink); word-break: break-word; }
.chip-why {
  grid-column: 1 / -1;
  margin: 6px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink-2);
  border-top: 1px solid var(--line);
  padding-top: 7px;
}
.chip[data-tone='ok'] { border-color: #bbf7d0; background: var(--green-wash); }
.chip[data-tone='ok'] .chip-v { color: var(--green-ink); }
.chip[data-tone='warn'] { border-color: #fde68a; background: var(--amber-wash); }
.chip[data-tone='warn'] .chip-v { color: var(--amber-ink); }
.chip[data-tone='info'] { border-color: #bfdbfe; background: var(--blue-wash); }
.chip[data-tone='info'] .chip-v { color: var(--blue-ink); }

.look-up { margin: 0 0 18px; font-size: 13px; color: var(--ink-3); }
.look-up-k { font-weight: 700; }
.look-up a { color: var(--blue-ink); font-weight: 600; }

/* ── the previous call ───────────────────────────────────────────────────── */
.prev {
  border: 1.5px solid var(--line);
  border-left: 4px solid var(--amber);
  border-radius: var(--radius-sm);
  padding: 2px 14px;
  margin: 18px 0;
  background: var(--sheet-2);
}
.prev-reason { margin: 0 0 8px; font-size: 13.5px; font-weight: 700; color: var(--amber-ink); }
.prev-mom {
  margin: 0 0 12px;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-2);
  white-space: pre-wrap;
}

/* ── the script ──────────────────────────────────────────────────────────── */
.block { margin: 22px 0 0; }
.block-head { border-bottom: 2px solid var(--line); padding-bottom: 8px; margin-bottom: 4px; }
.block-head h3 {
  margin: 0;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.block-head p { margin: 3px 0 0; font-size: 12.5px; color: var(--ink-3); line-height: 1.5; }

.q { padding: 15px 0 13px; border-bottom: 1px solid var(--line); }
.q:last-child { border-bottom: 0; }
.q-head { display: flex; align-items: center; gap: 9px; padding-bottom: 8px; }
.q-head label { padding: 0; margin: 0; flex: 1 1 auto; font-size: 14px; font-weight: 700; color: var(--ink); }
.q-ask { display: inline; }
.q-head .req { color: var(--pink); }
.q-why {
  margin: 0 0 9px;
  padding: 9px 11px;
  border-radius: 8px;
  background: var(--blue-wash);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--ink-2);
}
.q textarea { min-height: 64px; }
.q-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding-top: 8px; }
.q-foot .spacer { flex: 1 1 auto; }
.q-clear { font-size: 12.5px; }

/* The gate's outstanding items, marked where they actually are. */
.q[data-wanted='true'], .field[data-wanted='true'] {
  background: var(--amber-wash);
  box-shadow: -14px 0 0 var(--amber-wash), 14px 0 0 var(--amber-wash);
  border-radius: 2px;
}
.q[data-wanted='true'] .q-head label::after,
.field[data-wanted='true'] > label::after {
  content: ' · needed';
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--amber-ink);
}

/* ── option chips (radio groups) ─────────────────────────────────────────── */
.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip-opt { position: relative; display: inline-flex; }
.chip-opt input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.chip-opt span {
  display: inline-block;
  padding: 8px 13px;
  border: 1.5px solid var(--line-2);
  border-radius: 999px;
  background: var(--sheet);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink-2);
  transition: border-color 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.chip-opt input:hover + span { border-color: var(--ink-3); }
/* The ring goes on the visible chip, since the real radio is transparent. */
.chip-opt input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }
.chip-opt input:checked + span {
  border-color: var(--blue);
  background: var(--blue);
  color: #fff;
}
.chips.tri .chip-opt span { padding: 6px 11px; font-size: 12.5px; }
.chips.tri .chip-confirmed input:checked + span { border-color: var(--green); background: var(--green); }
/* The brand amber carries white text at only 3.19:1, so the selected
   "Not sure" chip uses the text-weight amber as its fill (5.02:1). Every
   other chip keeps its exact brand hue — only this one cannot. */
.chips.tri .chip-unsure input:checked + span { border-color: var(--amber-ink); background: var(--amber-ink); }
.chips.tri .chip-failed input:checked + span { border-color: var(--red); background: var(--red); }

fieldset.field { border: 0; margin: 0; padding: 0; }
fieldset.field legend {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  padding: 0 0 9px;
}
fieldset.field legend .req { color: var(--pink); }

/* ── save state ──────────────────────────────────────────────────────────── */
.save-state { font-size: 11.5px; font-weight: 700; color: var(--ink-3); }
.save-state[data-kind='ok'] { color: var(--green-ink); }
.save-state[data-kind='saving'] { color: var(--blue-ink); }
.save-state[data-kind='error'] { color: var(--red-ink); }
.save-state[data-kind='dirty'] { color: var(--amber-ink); }

/* ── the action bar ──────────────────────────────────────────────────────── */
.sheet-foot.actions {
  position: sticky;
  bottom: 0;
  z-index: 5;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  background: var(--sheet);
  border-top: 1.5px solid var(--line);
  box-shadow: 0 -8px 24px rgba(17, 24, 39, 0.06);
}
.action-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.action-row .spacer { flex: 1 1 auto; }
.gate {
  margin: 0;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.5;
  color: var(--ink-3);
}
.gate[data-tone='ok'] { color: var(--green-ink); }
.gate[data-tone='warn'] { color: var(--amber-ink); }
.gate[data-tone='info'] { color: var(--blue-ink); }

/* ===========================================================================
   The applicant's live profile
   ---------------------------------------------------------------------------
   The same answers, on the other side of the phone call. Deliberately quiet:
   it is a record filling in, not an activity feed demanding attention.
   ========================================================================= */
.mirror {
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--sheet-2);
  padding: 16px 18px;
  margin: 18px 0;
}
.mirror-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.mirror-head h3 { margin: 0; font-size: 15px; font-weight: 800; color: var(--ink); }
.mirror-count {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--ink-3);
}
.mirror-count[data-live='true'] {
  color: var(--green-ink);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mirror-count[data-live='true']::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--green);
  animation: pulse 1.8s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.mirror-sub { margin: 6px 0 14px; font-size: 13px; color: var(--ink-3); line-height: 1.55; }
.mirror-rows { font-size: 13.5px; }
.mirror-rows dd { white-space: pre-wrap; }
.mirror-rows dt[data-empty='true'], .mirror-rows dd[data-empty='true'] {
  color: var(--ink-3);
  font-weight: 500;
}
/* A line that just arrived gets a brief highlight — enough to draw the eye
   to what changed, gone before it becomes decoration. */
.mirror-rows dd[data-fresh='true'] {
  animation: arrived 2.4s ease-out 1;
  border-radius: 4px;
}
@keyframes arrived {
  0% { background: #bfdbfe; box-shadow: 0 0 0 4px #bfdbfe; }
  100% { background: transparent; box-shadow: 0 0 0 4px transparent; }
}

@media (max-width: 620px) {
  .checks { grid-template-columns: 1fr; }
  .action-row .btn { flex: 1 1 auto; justify-content: center; }
}

/* ── dark mode for everything above ──────────────────────────────────────── */
@media (prefers-color-scheme: dark) {
  .i { background: var(--sheet); border-color: var(--line-2); }
  .chip { background: var(--sheet-2); border-color: var(--line); }
  .chip[data-tone='ok'] { border-color: #065f46; }
  .chip[data-tone='warn'] { border-color: #92400e; }
  .chip[data-tone='info'] { border-color: #1e40af; }
  .chip-opt span { background: var(--sheet); }
  .chip-opt input:checked + span { color: #fff; }
  /* --amber-ink is a pale yellow in dark mode, so the fill that works in
     light mode would put white on near-white here. Go the other way. */
  .chips.tri .chip-unsure input:checked + span {
    border-color: #92400e;
    background: #92400e;
  }
  .prev, .mirror { background: var(--sheet-2); }
  .sheet-foot.actions { box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.4); }
  @keyframes arrived {
    0% { background: #1e3a8a; box-shadow: 0 0 0 4px #1e3a8a; }
    100% { background: transparent; box-shadow: 0 0 0 4px transparent; }
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
