/* =============================================================
   walkdeeznust — landing and legal site
   Cherry Ink · Field Edition · v2.0
   -------------------------------------------------------------
   Every token below is copied from the Flutter app, not invented
   here. When the app changes, change it here too:

     lib/globals/constants/app_colors.dart      → §1.1
     lib/globals/constants/app_typography.dart  → §1.2
     lib/globals/constants/app_spacing.dart     → §1.3, §1.4

   Flutter expresses tracking in dp at a fixed size; CSS expresses
   it in em so it survives responsive type. Each value below is
   the app's dp figure divided by the app's size for that step —
   the arithmetic is shown inline so it can be re-checked.

   The three load-bearing rules:
     · One type weight. Size, colour, tracking and case do the work.
     · Cherry marks a live human. On a website there is no live
       human, so cherry appears exactly twice: the presence dot on
       the brand mark's shoulder — where the mark is the person —
       and the wordmark's full stop. Nothing else.
     · Rectangles are the app; circles are people.
   ============================================================= */

/* ---------- 0. FONT ---------- */
/* The app's own face, self-hosted. No third-party font CDN, so the
   CSP in _headers can stay locked to 'self'. */
@font-face {
  font-family: "Fixel Text";
  src: url("/assets/fonts/FixelText-Regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ---------- 1. TOKENS ---------- */
:root {
  /* -- 1.1 Palette · app_colors.dart --------------------------------- */
  --ink:             #1D1B1A;  /* primary   · text, rules, chrome       */
  --paper:           #FAF9F7;  /* background· the ground                */
  --paper-ink:       #FAF9F7;  /* onPrimary · text on ink fills         */
  --surface:         #FFFFFF;  /* surface   · sheets and cards          */
  --bone:            #F0EDE8;  /* surfaceVariant · chips, input fills   */
  --hairline:        #E6E2DC;  /* 1px rules                             */
  --hairline-strong: #CFC9C1;  /* rules on white; input borders         */
  --smoke:           #6E6862;  /* textSecondary · labels, metadata      */
  --ash:             #9A948D;  /* textTertiary · disabled/placeholder   */
  --brick:           #8C2F23;  /* error · the whole safety register     */
  --error-surface:   #F7EDEA;  /* fill behind safety copy               */
  --teal:            #15535C;  /* the `contrast` posture, nothing else  */
  --cherry:          #B3172D;  /* live humans only — see the note above */

  /* Not from app_colors.dart. Added for the waitlist counter only, where
     green is the one convention that reads as "live right now". Used by
     .live__dot and nothing else — do not spread it. */
  --live:            #1B8A4B;

  /* -- 1.2 Type · app_typography.dart -------------------------------- */
  --font: "Fixel Text", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Sizes. The app is a 375–430pt phone; a document site legitimately
     has more width, so display steps interpolate between two real
     tokens rather than inventing a size between them. */
  --t-display2:  clamp(2.5rem, 1.6rem + 3.6vw, 3.25rem); /* 40 → 52 */
  --t-display3:  clamp(2rem,   1.5rem + 2vw,   2.5rem);  /* 32 → 40 */
  --t-title:     1.75rem;    /* 28 */
  --t-headline:  1.375rem;   /* 22 */
  --t-body:      1.0625rem;  /* 17 */
  --t-body-sm:   0.9375rem;  /* 15 */
  --t-caption:   0.8125rem;  /* 13 */
  --t-label:     0.6875rem;  /* 11 */
  --t-micro:     0.625rem;   /* 10 */

  /* Tracking, as dp ÷ size from the app's TextStyles. */
  --ls-display2: -0.0385em;  /* −2.0 / 52 */
  --ls-display3: -0.035em;   /* −1.4 / 40 */
  --ls-title:    -0.0286em;  /* −0.8 / 28 */
  --ls-headline: -0.0182em;  /* −0.4 / 22 */
  --ls-body:      0;
  --ls-caption:   0.0077em;  /*  +0.1 / 13 */
  --ls-label:     0.1455em;  /*  +1.6 / 11 */
  --ls-micro:     0.22em;    /*  +2.2 / 10 */
  --ls-quiet:    -0.015em;   /* the no-italic fallback, §4.3           */

  /* Line heights, verbatim. */
  --lh-display:  1.00;
  --lh-title:    1.10;
  --lh-headline: 1.20;
  --lh-body:     1.45;
  --lh-caption:  1.35;
  --lh-flat:     1.00;

  /* -- 1.3 Space · AppSpacing ---------------------------------------- */
  --s0:  0px;   --s1:  2px;   --s2:  4px;   --s3:  8px;
  --s4:  12px;  --s5:  16px;  --s6:  20px;  --s7:  24px;
  --s8:  32px;  --s9:  44px;  --s10: 64px;

  /* -- 1.4 Radius · AppRadius ---------------------------------------- */
  --r0: 0;      /* everything                                          */
  --r1: 2px;    /* buttons, chips, badges — letterpress softening       */

  /* -- 1.4b Motion · app_motion.dart --------------------------------- */
  --curve-standard: cubic-bezier(0.20, 0, 0, 1);  /* AppCurves.standard   */
  --d-instant: 90ms;                              /* AppDuration.instant  */
  --d-quick:   160ms;
  --d-base:    240ms;

  /* -- 1.5 Layout ---------------------------------------------------- */
  --gutter: var(--s6);          /* the app's 375pt gutter              */
  --container: 1100px;
  --measure: 34em;              /* AppType.bodyMaxMeasureEm            */
  --tap: 44px;                  /* AppSpacing.minTapTarget             */
  --control: 52px;              /* AppSpacing.controlHeight            */
}

/* AppSpacing.gutterOf: s7 once the viewport passes 400. */
@media (min-width: 400px) {
  :root { --gutter: var(--s7); }
}

/* ---------- 2. RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Tabular figures everywhere, as the app enables globally. */
  font-variant-numeric: tabular-nums;
}

/* One weight, one style. Fixel Text ships a 400 and nothing else, so the
   browser must never be allowed to fake the rest — a synthetic bold or a
   sheared oblique is exactly what the scale is built to avoid. */
strong, b, h1, h2, h3, h4, h5, h6, th, summary, optgroup { font-weight: 400; }
* { font-synthesis: none; -webkit-font-synthesis: none; }

img, svg { display: block; max-width: 100%; }
svg { flex: none; }
ul, ol { padding: 0; list-style: none; }

/* `hidden` must win. Several blocks here set `display: flex`, which otherwise
   silently defeats the attribute and renders things meant to be closed. */
[hidden] { display: none !important; }

/* Links are ink. Cherry is not a link colour — see §3.2 of the system. */
a { color: var(--ink); }
a:hover { color: var(--ink); text-decoration-color: currentColor; }

/* Focus rings are ink, never cherry. */
:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
::selection { background: var(--ink); color: var(--paper-ink); }

.page { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; }
.page main { flex: 1; }

/* ---------- 3. PRIMITIVES ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: 760px; }

.skip-link {
  position: absolute; top: var(--s3); left: var(--s3); z-index: 999;
  padding: var(--s3) var(--s4);
  background: var(--ink); color: var(--paper-ink);
  border-radius: var(--r1);
  font-size: var(--t-label); line-height: var(--lh-flat);
  letter-spacing: var(--ls-label);
  text-transform: uppercase; text-decoration: none;
  transform: translateY(-300%);
}
.skip-link:focus { transform: none; color: var(--paper-ink); }

/* The two type registers the whole system is built from. */
.label {
  font-size: var(--t-label); line-height: var(--lh-flat);
  letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--smoke);
}
.micro {
  font-size: var(--t-micro); line-height: 1.3;
  letter-spacing: var(--ls-micro);
  text-transform: uppercase; color: var(--smoke);
}

.t-display  { font-size: var(--t-display2); line-height: 0.94; letter-spacing: var(--ls-display2); }
.t-display3 { font-size: var(--t-display3); line-height: var(--lh-display); letter-spacing: var(--ls-display3); }
.t-title    { font-size: var(--t-title);    line-height: var(--lh-title);    letter-spacing: var(--ls-title); }
.t-headline { font-size: var(--t-headline); line-height: var(--lh-headline); letter-spacing: var(--ls-headline); }

/* Fixel Text has no italic (design system §4.3). The specified fallback is
   display3 in smoke at 90% with tracking loosened — a quieter aside. Never
   a synthetic oblique. */
.t-quiet {
  font-size: calc(var(--t-display3) * 0.9);
  line-height: var(--lh-display);
  letter-spacing: var(--ls-quiet);
  color: var(--smoke);
}

.body    { font-size: var(--t-body);    line-height: var(--lh-body); max-width: var(--measure); text-wrap: pretty; }
.body-sm { font-size: var(--t-body-sm); line-height: var(--lh-body); max-width: var(--measure); text-wrap: pretty; }
.caption { font-size: var(--t-caption); line-height: var(--lh-caption); letter-spacing: var(--ls-caption); color: var(--smoke); text-wrap: pretty; }

/* The cherry full stop — the app's one job, finished. Attaches to the
   wordmark only: never a heading, never body copy, never the letters. */
.stop { color: var(--cherry); }

/* ---------- 4. MASTHEAD (landing) ---------- */
.masthead__banner {
  border-top: 2px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  padding-block: var(--s6) var(--s5);
  text-align: center;
}
.banner {
  display: inline-flex; align-items: center; gap: clamp(8px, 1.6vw, 20px);
  text-decoration: none; color: var(--ink);
  font-size: var(--t-display2);
  line-height: 0.94;
  letter-spacing: var(--ls-display2);
}
.banner__mark { width: clamp(32px, 5vw, 52px); height: clamp(32px, 5vw, 52px); }

.masthead__strip { border-bottom: 1px solid var(--ink); }
.masthead__place { text-align: center; padding-block: var(--s4); }

/* ---------- 5. STATEMENT (landing) ---------- */
.edition { padding-block: clamp(32px, 7vw, 64px); }

/* One centred column. §4.2 reserves centred display type for splash and the
   blocked screen; a landing page is the same situation — a single statement
   with nothing beside it to align against. */
/* No cap here: the bilingual head needs the full container to keep both
   phrases on one line (measured 928px at full size). The narrower measure is
   pushed down to the lines that actually want it. */
.lede { margin-inline: auto; text-align: center; }
.lede__mission, .lede__scope { max-width: 720px; margin-inline: auto; }
.lede__head { max-width: 18ch; margin-inline: auto; text-wrap: balance; }

/* The head carries an Urdu companion line on the same baseline.

   Fixel Text has no Arabic coverage at all — its cmap maps 0 of the 256
   codepoints in the Arabic block, so every glyph in this phrase falls back
   whatever we do. The stack below therefore prefers Nastaliq, which is how
   Urdu is conventionally set, and lets a Naskh system face catch it
   otherwise. Self-hosting Noto Nastaliq Urdu is the only way to make this
   render identically everywhere; see the note in README. */
.lede__head--bilingual {
  max-width: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  column-gap: var(--s8);
  row-gap: var(--s5);
}
.lede__en { max-width: 18ch; }

.lede__ur {
  font-family: "Noto Nastaliq Urdu", "Jameel Noori Nastaleeq", "Awami Nastaliq",
               "Nafees Nastaleeq", "Geeza Pro", "Noto Naskh Arabic", serif;
  font-size: var(--t-display3);
  /* Nastaliq slopes steeply and descends far below the baseline; the Latin
     scale's line-heights clip it. This is the one place that number is not
     taken from app_typography.dart, because it is not that typeface. */
  line-height: 1.7;
  letter-spacing: 0;
  color: var(--smoke);
  /* Isolate the RTL run so it cannot reorder the cherry full stop that
     immediately precedes it. */
  unicode-bidi: isolate;
}
.lede__mission {
  margin-top: var(--s7);
  font-size: var(--t-headline);
  line-height: var(--lh-headline);
  letter-spacing: var(--ls-headline);
  color: var(--smoke);
  text-wrap: pretty;
}
.lede__scope {
  margin-top: var(--s5);
  font-size: var(--t-label);
  line-height: var(--lh-flat);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--ash);
}

/* How it works — printed steps. Rules, not cards. */
.steps {
  margin-top: var(--s10);
  border-top: 1px solid var(--ink);
  text-align: left;
}
.step {
  display: grid;
  grid-template-columns: 2.5em 1fr;
  gap: var(--s5);
  padding-block: var(--s5);
  border-bottom: 1px solid var(--hairline);
}
.step__n {
  font-size: var(--t-label); line-height: var(--lh-body);
  letter-spacing: var(--ls-label);
  text-transform: uppercase; color: var(--smoke);
}
.step__t { font-size: var(--t-body); line-height: var(--lh-body); text-wrap: pretty; }
/* The block below draws its own rule; two hairlines in a row read as a slip. */
.step:last-child { border-bottom: 0; }

/* ---------- 6. STORE NOTICES ---------- */
/* Deliberately not badges. Apple and Google both forbid imitating their
   badge artwork, and neither store requires a download link on the
   marketing site before the listing is live. */
/* Two boxes, one per store, side by side. Each store is its own destination,
   so each gets its own enclosure rather than sharing one. */
.stores {
  max-width: 560px;
  margin: var(--s9) auto 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s5);
}
@media (max-width: 520px) {
  .stores { grid-template-columns: 1fr; }
}

.store-note {
  display: flex; flex-direction: row; align-items: center;
  gap: var(--s4);
  padding: var(--s5);
  border: 1px solid var(--hairline-strong);
  border-radius: 6px;
  background: var(--surface);
  text-align: left;
}
.store-note__logo { width: 26px; height: 26px; }
.store-note__text { display: flex; flex-direction: column; gap: var(--s2); }
.store-note__name { font-size: var(--t-body-sm); line-height: var(--lh-flat); }

/* ---------- 7. BUTTONS ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s3);
  min-height: var(--tap);
  padding: var(--s4) var(--s6);
  background: var(--ink); color: var(--paper-ink);
  border: 1px solid var(--ink);
  border-radius: var(--r1);
  font-size: var(--t-body-sm); line-height: var(--lh-flat);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background 120ms linear, color 120ms linear;
}
.btn:hover { background: var(--paper); color: var(--ink); }
.btn--ghost { background: transparent; color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--paper-ink); }

/* ---------- 8. HEADER / FOOTER (documents) ---------- */
.site-header { border-bottom: 2px solid var(--ink); }
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s6); min-height: 62px; padding-block: var(--s4);
}
.brand {
  display: inline-flex; align-items: center; gap: var(--s4);
  text-decoration: none; color: var(--ink);
  font-size: var(--t-headline); letter-spacing: var(--ls-headline);
}
.brand__mark { width: 28px; height: 28px; }
.site-nav { display: flex; align-items: center; gap: var(--s6); }

.site-footer { border-top: 1px solid var(--ink); padding-block: var(--s6); margin-top: var(--s8); }
.site-footer__row {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: var(--s4) var(--s6);
}
.site-footer__links { display: flex; flex-wrap: wrap; gap: var(--s5) var(--s6); }
.site-footer__links a,
.site-footer__row a { text-decoration: none; }
.site-footer__links a:hover,
.site-footer__row a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ---------- 9. DOCUMENTS ---------- */
.doc { padding-block: var(--s8) var(--s10); }
.doc__header { margin-bottom: var(--s7); padding-bottom: var(--s5); border-bottom: 1px solid var(--ink); }
.doc__title { margin-block: var(--s4) var(--s4); }
.doc__meta {
  font-size: var(--t-micro); letter-spacing: var(--ls-micro);
  text-transform: uppercase; color: var(--smoke); line-height: 1.6;
}

.doc__body { max-width: 68ch; }
.doc__body h2 {
  font-size: var(--t-headline); letter-spacing: var(--ls-headline); line-height: var(--lh-headline);
  margin-block: var(--s9) var(--s5);
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--ink);
  scroll-margin-top: var(--s7);
}
.doc__body h3 {
  font-size: var(--t-body); line-height: var(--lh-body);
  margin-block: var(--s7) var(--s4);
}
.doc__body p { margin-bottom: var(--s5); font-size: var(--t-body-sm); line-height: var(--lh-body); }
.doc__body ul { margin-bottom: var(--s7); }
.doc__body ul li {
  position: relative; padding-left: var(--s7); margin-bottom: var(--s4);
  font-size: var(--t-body-sm); line-height: var(--lh-body);
}
/* A printed dash, not a bullet — the system has no filled decorations. */
.doc__body ul li::before {
  content: ""; position: absolute; left: 0; top: 0.72em;
  width: 10px; height: 1px; background: var(--ink);
}
.doc__body a { text-decoration-color: var(--hairline-strong); text-underline-offset: 3px; }
.doc__body a:hover { text-decoration-color: var(--ink); }

/* There is no bold in this system. Inline emphasis is a hairline rule under
   the phrase — a printed device, no weight, no colour outside the palette. */
.doc__body strong {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--hairline-strong);
  text-underline-offset: 3px;
}

.toc {
  border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink);
  padding-block: var(--s5); margin-bottom: var(--s7);
}
/* The header already closes with a rule; don't strike a second one 20px later. */
.doc__header + .toc { border-top: 0; margin-top: calc(-1 * var(--s4)); }
.toc h2 {
  font-size: var(--t-micro) !important; letter-spacing: var(--ls-micro);
  text-transform: uppercase; color: var(--smoke);
  border: 0 !important; padding: 0 !important; margin: 0 0 var(--s4) !important;
  line-height: var(--lh-flat) !important;
}
.toc ol { counter-reset: toc; columns: 2; column-gap: var(--s9); }
@media (max-width: 620px) { .toc ol { columns: 1; } }
.toc li { counter-increment: toc; margin-bottom: var(--s3); break-inside: avoid; }
.toc a { font-size: var(--t-body-sm); text-decoration: none; }
.toc a::before { content: counter(toc) " · "; color: var(--smoke); }
.toc a:hover { text-decoration: underline; text-underline-offset: 3px; }

.callout {
  border-left: 2px solid var(--ink);
  background: var(--bone);
  padding: var(--s5);
  margin-block: var(--s7);
}
.callout p:last-child { margin-bottom: 0; }
/* The safety register: brick on errorSurface, plain sentences, no wit. */
.callout--safety { border-left-color: var(--brick); background: var(--error-surface); }
.callout--safety strong { text-decoration-color: var(--brick); }

/* Values still awaiting confirmation. Bone, never cherry — a draft is not
   a person. */
.fill {
  padding: 0.1em 0.3em; margin-inline: -0.1em;
  background: var(--bone);
  box-shadow: inset 0 -1px 0 var(--smoke);
}

.data-table { width: 100%; border-collapse: collapse; margin-block: var(--s5) var(--s7); }
.data-table th, .data-table td {
  text-align: left; padding: var(--s4);
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  font-size: var(--t-caption); line-height: var(--lh-body);
}
.data-table thead th {
  font-size: var(--t-micro); letter-spacing: var(--ls-micro);
  text-transform: uppercase; color: var(--smoke);
  border-bottom-color: var(--ink);
  line-height: var(--lh-flat);
}
.data-table td strong { text-decoration: none; }
.table-scroll { overflow-x: auto; }

/* ---------- 9b. WAITLIST ----------
   From the design project's `waitlist.css`, with the literal hex swapped for
   the tokens above as that file instructs. Three substantive changes:

   1. Its `.btn` / `.btn--primary` rules are renamed `.wl-submit`. The site
      already has a `.btn` (the "Back to site" control on every document
      page) and the incoming rules would have silently restyled all of them.
   2. Chip press and button press keep their 0.96 / 0.985 scales — those are
      not off-system decoration, they are written into §7.3 and §7.8.
   3. The aside drops `font-style: italic`. Fixel Text ships no italic and
      `font-synthesis: none` is set globally, so the declaration would do
      nothing; §4.3's documented fallback is smoke at a smaller size, which
      is what it already is.
   ---------------------------------------------------------------- */

/* In the fold band the waitlist is one column of a grid, so it drops the
   separator rule and the top margin it needed as a stacked section. */
/* A panel, not a paragraph. §1.1 calls --surface "sheets and cards", and a
   1dp ink edge is how the app draws anything you act inside. Joining a queue
   should feel like stepping into something, not reading more prose. */
.waitlist {
  max-width: 560px;
  margin-inline: auto;
  margin-top: var(--s10);
  padding: var(--s7) var(--s7) var(--s8);
  border: 1px solid var(--ink);
  border-radius: var(--r1);
  background: var(--surface);
  text-align: center;
}
@media (max-width: 520px) {
  .waitlist { padding: var(--s6) var(--s5) var(--s7); }
}
.waitlist__rule { display: none; }

/* Status bar across the top of the panel: state on the left, live count on
   the right. Reads like a ticket window that is open. */
.waitlist__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  padding-bottom: var(--s5);
  margin-bottom: var(--s6);
  border-bottom: 1px solid var(--hairline);
  text-align: left;
}
.waitlist__tag { color: var(--ink); }

.waitlist__head {
  font-size: var(--t-title);
  line-height: var(--lh-title);
  letter-spacing: var(--ls-title);
  color: var(--ink);
}

.waitlist__lede {
  font-size: var(--t-body-sm);
  line-height: var(--lh-body);
  color: var(--smoke);
  max-width: 46ch;
  margin-inline: auto;
  margin-top: var(--s4);
  text-wrap: pretty;
}

/* ---- form ---- */
.waitlist__form { display: flex; flex-direction: column; margin-top: var(--s7); text-align: left; }

/* Email and submit sit on one line — the whole ask is a single row. Stacks
   below 520px, where a side-by-side button squeezes the input to nothing. */
.field__row { display: flex; gap: var(--s4); align-items: stretch; }
.field__row .field__input { flex: 1 1 auto; min-width: 0; }
.field__row .wl-submit { flex: 0 0 auto; margin-top: 0; white-space: nowrap; }
@media (max-width: 520px) {
  .field__row { flex-direction: column; }
}

/* ============ INPUT TREATMENTS ============
   Three interchangeable looks for the email + button pair. Swap the class on
   the <form> to change it; nothing else needs touching.

     wl-style-fused   one enclosure, button inset inside it
     wl-style-line    hairline underline, quiet inline button
     wl-style-soft    rounded fill, separate pill button

   NOTE: these use radii above --r1 (2px), which §1.4 does not define. The
   app is deliberately square; a marketing form is the one place a softer
   edge earns its keep. Delete this block to fall back to the app's own
   §7.11 field, which is still the default styling below. */

/* Shared: strip the boxy §7.11 field so each variant starts from nothing. */
.wl-style-fused .field__input,
.wl-style-line  .field__input,
.wl-style-soft  .field__input {
  background: transparent;
  border: 0;
  border-radius: 0;
  height: 46px;
  padding: 0;
}
.wl-style-fused .field__input:focus,
.wl-style-line  .field__input:focus,
.wl-style-soft  .field__input:focus {
  background: transparent;
  border: 0;
  padding-bottom: 0;
}

/* ---- 1. fused: input and button share one enclosure ---- */
.wl-style-fused .field__row {
  gap: 0;
  padding: 5px;
  background: var(--bone);
  border: 1px solid var(--hairline-strong);
  border-radius: 8px;
  transition: border-color 160ms var(--curve-standard),
              box-shadow   160ms var(--curve-standard),
              background   160ms var(--curve-standard);
}
.wl-style-fused .field__row:focus-within {
  background: var(--surface);
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(29, 27, 26, 0.07);
}
.wl-style-fused .field__input { padding-inline: var(--s5); }
.wl-style-fused .wl-submit {
  height: 46px;
  border-radius: 6px;
  padding-inline: var(--s6);
}
.wl-style-fused .field--invalid .field__row { border-color: var(--brick); }

/* ---- 2. line: a single rule, nothing else ---- */
.wl-style-line .field__row {
  gap: var(--s4);
  align-items: baseline;
  padding-bottom: var(--s3);
  border-bottom: 1px solid var(--hairline-strong);
  transition: border-color 160ms var(--curve-standard);
}
.wl-style-line .field__row:focus-within { border-bottom-color: var(--ink); }
.wl-style-line .wl-submit {
  height: auto;
  padding: 0 var(--s2);
  background: transparent;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 5px;
  text-decoration-color: var(--hairline-strong);
  transition: text-decoration-color 160ms var(--curve-standard);
}
.wl-style-line .wl-submit:hover { background: transparent; text-decoration-color: var(--ink); }
.wl-style-line .field--invalid .field__row { border-bottom-color: var(--brick); }

/* ---- 3. soft: two pills ---- */
.wl-style-soft .field__row { gap: var(--s4); }
.wl-style-soft .field__input {
  height: 48px;
  padding-inline: var(--s6);
  background: var(--bone);
  border-radius: 999px;
  transition: background 160ms var(--curve-standard),
              box-shadow 160ms var(--curve-standard);
}
.wl-style-soft .field__input:focus {
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--ink);
  padding-inline: var(--s6);
}
.wl-style-soft .wl-submit {
  height: 48px;
  border-radius: 999px;
  padding-inline: var(--s7);
}
.wl-style-soft .field--invalid .field__input { box-shadow: inset 0 0 0 1px var(--brick); }

.field { display: flex; flex-direction: column; border: 0; padding: 0; margin: 0; }
.field + .field { margin-top: var(--s7); }

.field__label { color: var(--smoke); margin-bottom: var(--s3); padding: 0; }

/* §7.11 text field: bone fill, no border at rest, 1dp ink bottom rule. */
.field__input {
  height: var(--control);
  width: 100%;
  background: var(--bone);
  border: 0;
  border-bottom: 1px solid var(--ink);
  border-radius: var(--r0);
  padding: 0 var(--s4);
  font: inherit;
  font-size: var(--t-body);
  color: var(--ink);
  transition: background 120ms var(--curve-standard),
              border-color 120ms var(--curve-standard);
}
.field__input::placeholder { color: var(--ash); }
.field__input:focus {
  outline: none;
  background: var(--surface);
  border-bottom-width: 2px;
  padding-bottom: 1px;              /* hold the 52px box as the rule thickens */
}
/* "focused → label → ink", §7.11. */
.field:focus-within .field__label { color: var(--ink); }

.field__input[aria-invalid="true"] { border-bottom: 2px solid var(--brick); padding-bottom: 1px; }
/* "error → label → brick", §7.11. The label precedes the input in the DOM,
   so this hangs off a class the script toggles on the wrapper. */
.field--invalid .field__label,
.field--invalid:focus-within .field__label { color: var(--brick); }

.field__error {
  font-size: var(--t-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  color: var(--brick);
  margin-top: var(--s3);
}
.field__note {
  font-size: var(--t-caption);
  line-height: var(--lh-caption);
  letter-spacing: var(--ls-caption);
  color: var(--smoke);
  margin-top: var(--s4);
}

/* ---- department chips · §7.3 ---- */
.chips { display: flex; flex-wrap: wrap; gap: var(--s3); }

.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: 34px;                     /* §7.3 — the app's own chip height */
  padding: 0 var(--s3);
  border-radius: var(--r1);
  background: var(--bone);
  border: 1px solid var(--bone);    /* metrics match the selected state exactly */
  color: var(--ink);
  font-size: var(--t-body-sm);
  line-height: var(--lh-flat);
  cursor: pointer;
  transition: background var(--d-instant) var(--curve-standard),
              color var(--d-instant) var(--curve-standard);
}
/* The chip is 34dp to match the app, which is under the 44dp minimum tap
   target. Grow the hit area without moving the ink. */
.chip::after {
  content: "";
  position: absolute;
  inset: -5px 0;
}
.chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.chip:active { transform: scale(0.96); }
.chip:has(input:checked) { background: var(--ink); border-color: var(--ink); color: var(--paper-ink); }
.chip:has(input:focus-visible) { outline: 2px solid var(--ink); outline-offset: 2px; }

/* Dashed = "you wrote this", never "disabled" — §7.4. */
.chip--other { background: var(--surface); border: 1px dashed var(--hairline-strong); }
.chip--other:has(input:checked) { border-style: solid; }

/* ---- submit · §7.8 primary button ---- */
.wl-submit {
  height: var(--control);
  border-radius: var(--r1);
  border: 1px solid transparent;
  background: var(--ink);
  color: var(--paper-ink);
  font: inherit;
  font-size: 0.75rem;               /* AppType.buttonLabel — 12 */
  letter-spacing: 0.1167em;         /* +1.4 / 12 */
  text-transform: uppercase;
  cursor: pointer;
  margin-top: var(--s8);
  transition: background var(--d-instant) var(--curve-standard);
}
.wl-submit:hover { background: #302D2B; }
.wl-submit:active { transform: scale(0.985); }
.wl-submit:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
/* "disabled | bone fill, ash label. Never a faded ink fill." */
.wl-submit[disabled] { background: var(--bone); color: var(--ash); cursor: default; transform: none; }

/* ---- success ---- */
/* Opacity plus 8dp of translation on the standard curve — the only motion
   chrome is allowed, and the only motion on this site. */
.waitlist__done { animation: wl-register var(--d-base) var(--curve-standard) both; }
/* Focused only so screen readers announce it. It is not interactive, so the
   ring would read as a rendering fault rather than a focus affordance. */
.waitlist__done:focus,
.waitlist__done:focus-visible { outline: none; }
@keyframes wl-register {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

.waitlist__tick { width: 28px; height: 28px; color: var(--ink); margin-inline: auto; }

.waitlist__done-head {
  font-size: var(--t-title);
  line-height: var(--lh-title);
  letter-spacing: var(--ls-title);
  color: var(--ink);
  margin-top: var(--s5);
}
.waitlist__done-body {
  font-size: var(--t-body-sm);
  line-height: var(--lh-body);
  color: var(--ink);
  margin-top: var(--s5);
}
.waitlist__echo { border-bottom: 1px solid var(--ink); }

.waitlist__aside {
  font-size: var(--t-caption);
  line-height: var(--lh-body);
  letter-spacing: var(--ls-caption);
  color: var(--smoke);
  border-top: 1px solid var(--hairline);
  margin-top: var(--s8);
  padding-top: var(--s8);
}

/* Three facts about the queue, set as a printed row beneath the panel. No
   rule of its own — the panel edge above already provides the separation. */
.waitlist__meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s4) var(--s7);
  margin-top: var(--s6);
  font-size: var(--t-micro);
  line-height: var(--lh-flat);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--smoke);
}
.waitlist__meta strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* Queue position in the success state. */
.waitlist__place {
  margin-top: var(--s5);
  font-size: var(--t-headline);
  line-height: var(--lh-headline);
  letter-spacing: var(--ls-headline);
  color: var(--smoke);
}
.waitlist__place strong { color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---- live signup count ----
   NOTE: --live is the one colour on this site that is NOT in the app palette
   (§1.1). It was added deliberately for this counter, where green carries the
   universal "live right now" meaning that ink or smoke cannot. It is used
   here and nowhere else. Cherry was not used because §3.2 reserves it for a
   single live human, not an aggregate. */
.live {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--s4);
  border-radius: var(--r1);
  background: color-mix(in srgb, var(--live) 10%, transparent);
  font-size: var(--t-caption);
  line-height: var(--lh-flat);
  letter-spacing: var(--ls-caption);
  color: var(--smoke);
  white-space: nowrap;
}
.live__text strong { color: var(--ink); font-variant-numeric: tabular-nums; }

.live__dot {
  position: relative;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--live);
  flex: none;
}
/* The ring, not the dot, does the pulsing — a dot that changes size nudges
   the text beside it. */
.live__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--live);
  animation: live-ping 2s var(--curve-standard) infinite;
}
@keyframes live-ping {
  0%   { transform: scale(1);   opacity: 0.55; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .live__dot::after { animation: none; }
}



/* ---------- 10. 404 ---------- */
.notfound {
  min-height: 58vh;
  display: grid; place-content: center; justify-items: center;
  text-align: center; gap: var(--s5);
  padding-block: var(--s10);
}

/* ---------- 11. MOTION ---------- */
/* The interface is printed. Only people move — and there is no live person
   on a website, so nothing here animates but a hover fill. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---------- 12. PRINT ---------- */
@media print {
  .site-header, .site-footer, .toc, .skip-link { display: none !important; }
  body { background: #fff; }
  .doc__body { max-width: none; }
  a::after { content: " (" attr(href) ")"; font-size: 0.8em; color: #555; }
}
