/* Product-only tokens. NOT shared with landing, NOT drift-checked.
   1) Status dots — low-saturation, re-tuned to the paper/ink/blue palette.
      Never render as filled chips or bands.
   2) --overlay / --active — product-only semantics.
   3) Alias bridge (TRANSITIONAL): legacy token names mapped onto brand tokens
      so existing app.css renders unchanged. Remove each alias as the screens
      that use it migrate to canonical names; delete this block when none remain. */

:root {
  --dot-open: var(--ink-faint);
  --dot-planned: var(--blue);
  --dot-building: var(--warn);
  --dot-shipped: var(--good);
  --dot-someday: var(--ink-soft);

  /* Stage-pipeline dots — the Board groups by derived stage, not stored status.
     Aliased onto the brand palette so they track light/dark automatically
     (custom properties resolve at use time).

     These are a RAMP, not four labels: left to right the board goes from
     nothing-decided, through a question still open, to live, to ready. They
     used to be aliased onto the status-dot palette, which made the order read
     orange -> purple -> teal -> green: four hues that carry no direction, and
     names that had stopped meaning anything (--stage-design pointed at
     --dot-building). A reader could not tell from the colour which end of the
     board was further along. */
  --stage-design: var(--ink-faint);     /* nobody has said what we are building */
  --stage-done-when: var(--warn);       /* a question is open */
  --stage-exec:   var(--blue);          /* live */
  --stage-ship:   var(--dot-shipped);   /* ready */

  /* Priority as ONE axis, not five hues: hot -> neutral -> nearly gone. The
     only thing the ramp has to say is that 1 is the most urgent, and a reader
     should get that without learning a legend.

     4 and 5 deliberately share a value. Both mean "not urgent", the digit
     itself carries the exact rank, and inventing a fifth perceptibly-different
     colour would be the board claiming a distinction nobody makes. */
  --prio-1: var(--warn);
  --prio-2: color-mix(in srgb, var(--warn) 50%, var(--ink-faint));
  --prio-3: var(--ink-faint);
  --prio-4: var(--line-strong);
  --prio-5: var(--line-strong);

  /* Boundary of an INTERACTIVE control (input, select, textarea, checkbox).
     Distinct from --line, which is a decorative hairline between surfaces:
     WCAG 1.4.11 requires 3:1 for the former and exempts the latter. --line is
     1.30:1 on paper, so a control drawn with it has no perceivable edge. */

  /* One self-hosted family for Korean, Latin, controls and code. */
  --font-body: "Pretendard Variable", -apple-system, BlinkMacSystemFont, sans-serif;

  /* alias bridge */
  --bg: var(--paper);
  --surface: var(--paper-raised);
  --sidebar: var(--paper-deep);
  --text: var(--ink);
  --muted: var(--ink-faint);
  --border: var(--line);
  --accent: var(--blue);
  --active: var(--paper-deep);

  /* Auth split brand panel — a fixed deep-teal that reads on either shell. */
}

/* --- Density tokens (product-only; high-density baseline) ---
   Single-source knobs for spacing + type. Retune density here, not in app.css.
   Brand rhythm (landing) is unaffected — these live in the product layer. */
:root {
  /* spacing scale (4px grid). Value-based naming: the token name IS the
     pixel value, so adding a size never renumbers an existing one. --space-14,
     --space-18, and --space-24 fill the gaps between 12/16/20 and are in
     active use throughout app.css as the gap values for that grid. */
  --space-2: 2px;   --space-4: 4px;   --space-6: 6px;   --space-8: 8px;
  --space-10: 10px; --space-12: 12px; --space-14: 14px; --space-16: 16px;
  --space-18: 18px; --space-20: 20px; --space-24: 24px;
  /* Ref and continuation notes share a reserved minimum width in pixels. */
  --ref-w: 50px;
  /* semantic shell / rhythm */
  --main-pad-y: 18px;
  --main-pad-x: clamp(16px, 2vw, 28px);
  --main-pad-b: 32px;
  --section-gap: 10px;
  /* type scale — the small end moved up one step (11/12/13 -> 12/13/14).
     A third of every screen was rendering at 11px and the body sat at 13,
     which reads as cramped rather than as dense. --text-md stays 14 and so now
     equals --text-base: that is the intent, not an oversight. base.css holds a
     14px floor for text-entry controls, so body text and the field you type it
     into finally agree; the two names survive because ~80 rules reference them
     and collapsing the names is churn, not design. */
  --text-xs: 12px; --text-sm: 13px; --text-base: 14px; --text-md: 14px;
  --text-lg: 16px; --text-title: 18px; --text-stat: 20px;
  --text-h2: 22px; --text-hero: 24px; --text-h1: 28px;

  /* weight — three, from nine (400 500 560 600 620 650 670 700).
     The variable font makes every weight reachable; each used to get picked
     by eye at the moment it was needed. The gaps were never legible: 620
     against 650 is not a distinction anybody can see, it is just two people
     guessing on different days. */
  --weight-body: 400;
  --weight-em: 600;    /* labels, buttons, anything that leads a row */
  --weight-title: 650; /* headings */

  /* Tracking: tighter large headings, spaced uppercase labels, normal text. */
  --track-title: -0.02em;
  --track-label: 0.07em;
}

/* --- Motion ---------------------------------------------------------------
   The product had 59 :hover rules and almost nothing to carry them: measured
   in the running app, 141 of 154 interactive elements had no transition at
   all, so every hover, every focus and every state change was a single-frame
   cut. The states already existed; only the tween was missing.

   Four steps, chosen to match the durations already in use rather than to
   introduce a new feel — the point is that there is now one place to retune.
   Easing is --ease from the brand layer; do not define another curve here. */

:root {
  --dur-fast: 120ms;    /* colour, background, opacity — the hover default */
  --dur: 180ms;         /* transform, border, anything that moves a little */
  --dur-slow: 280ms;    /* enter/exit, overlays, things that arrive */
  --dur-layout: 450ms;  /* sidebar width — deliberately slow, tracks a drag */
}

/* Flat surfaces: boundaries and contrasting fills carry depth. */
:root {
  --elev-1: none;
  --elev-2: none;
  --elev-3: none;
}

/* --- Focus ----------------------------------------------------------------
   These describe the ring on everything you do NOT type into. A text field
   has no ring at all since TP-401: pulling it inward never did replace the
   field's own border the way the note here used to claim, so a focused field
   drew 1px of grey and 2px of blue and the edge read as three bands. The
   owner asked for it gone rather than merely thinner. base.css is where that
   removal lives, and tests/web/test_accessibility_regressions.py holds the
   line at text entry.

   For what is left, a control pulls the ring INWARD over its own border
   (--focus-inset) so the ring replaces the edge instead of stacking outside
   it; a control with no border of its own pushes it OUT (--focus-outset) so
   it stays clear of the glyphs.

   Solid, at full --blue, and 2px: WCAG 2.4.7 wants an indicator that survives
   not being able to resolve a hue change, so a soft tinted halo is not a
   substitute for it however much better it looks. */
:root {
  --focus-w: 2px;
  --focus-inset: -1px;
  --focus-outset: 2px;
}

/* --- Field primitive ------------------------------------------------------
   ONE vocabulary for every place a person types or picks. Before this, the
   product had thirteen: five backgrounds, three border treatments (1px all
   round / bottom rule only / the browser's own 2px inset), two radii, eight
   paddings and four type sizes — measured in the running app, not estimated.
   Two of those were not even choices: an <input type="number"> on Home that no
   rule reached, and the Area dialog rendering at 11px because it is a
   position:fixed overlay that sits inside the sidebar in the DOM and its input
   asked for `font: inherit`. Fields never inherit their size; it comes from
   here.

   Three sizes and one seamless variant is the entire allowance. A screen that
   wants a different field wants one of these, or wants a token changed here.

   Each size carries its own line-height because the READ state of an editable
   field has to match its EDIT state exactly — a click that changes font-size
   or leading moves every line under the cursor, which is what made the spec
   editor feel like a mode switch rather than a caret landing. */
:root {
  --field-bg: var(--paper-raised);
  --field-bg-hover: var(--paper-solid);
  /* --line-control, never --line: WCAG 1.4.11 wants 3:1 on the boundary of an
     interactive control and exempts a decorative hairline. */
  --field-border: var(--line-control);
  --field-border-quiet: var(--line);
  --field-radius: var(--radius-small);

  /* Default. --text-md, not the 13px body: base.css holds a 14px readability
     floor for text-entry controls, and half the fields here were under it. */
  --field-pad-y: 6px;
  --field-pad-x: 10px;
  --field-size: var(--text-md);
  --field-line: 1.55;
  --field-min-h: 30px;

  /* Small. Inline pickers and the tag input — controls that sit INSIDE a line
     of metadata, where a 14px box would out-shout the row it annotates. The
     floor above is about text you compose; these are things you pick. */
  --field-pad-y-sm: 3px;
  --field-pad-x-sm: 8px;
  /* --text-sm, not --text-base: this has to stay a STEP below the default
     field. It pointed at --text-base back when that was 13px and the step was
     free; raising the body to 14 made "small" and "default" the same size and
     grew every row holding an inline picker. Name the step, not the size. */
  --field-size-sm: var(--text-sm);
  --field-line-sm: 1.5;
  --field-min-h-sm: 24px;

  /* Long-form: spec, constraints, bite body, capture body. Same size as the
     default — a spec and a name field should read alike — but looser leading
     and more room, because this is prose. .spec (the RENDERED half of the same
     field) takes these same three values, which is what makes the read and
     edit states interchangeable. */
  --field-pad-y-lg: 8px;
  --field-pad-x-lg: 10px;
  --field-size-lg: var(--field-size);
  --field-line-lg: 1.6;

  /* Comfortable. The sign-in screens, where one field IS the task. */
  --field-min-h-comfy: 40px;
  --field-pad-x-comfy: 12px;
}

/* Blue-gray product theme (TP-422). Public brand copies remain unchanged. */
:root {
  --paper: #eef1f5;
  --paper-solid: #f3f5f8;
  --paper-raised: #f9fafc;
  --paper-deep: #e4e9f0;
  --ink: #293340;
  --ink-soft: #526174;
  --ink-faint: #59687a;
  --blue: #526882;
  --blue-strong: #3e536d;
  --blue-soft: #d5dfeb;
  --line: #d7dfe8;
  --line-strong: #a0adbd;
  --line-control: #788494;
  --good: #526c57;
  --warn: #926139;
  --overlay: rgba(25, 36, 51, 0.42);
  --texture-opacity: 0;
  --auth-panel-a: var(--paper-deep);
  --auth-panel-b: var(--paper-deep);
  --auth-panel-ink: var(--ink-soft);
  --auth-panel-em: var(--ink);
  --main-pad-y: 24px;
  --section-gap: 16px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
  color-scheme: dark;
  --paper: #191f28;
  --paper-solid: #202835;
  --paper-raised: #252f3c;
  --paper-deep: #151b24;
  --ink: #e7edf5;
  --ink-soft: #b7c4d5;
  --ink-faint: #99a9bd;
  --blue: #a0b9d8;
  --blue-strong: #c0d2e9;
  --blue-soft: #314359;
  --line: #394758;
  --line-strong: #64758b;
  --line-control: #8191a6;
  --good: #a1bda8;
  --warn: #dcb083;
  --overlay: rgba(7, 12, 20, 0.64);
    --texture-opacity: 0;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --paper: #191f28;
  --paper-solid: #202835;
  --paper-raised: #252f3c;
  --paper-deep: #151b24;
  --ink: #e7edf5;
  --ink-soft: #b7c4d5;
  --ink-faint: #99a9bd;
  --blue: #a0b9d8;
  --blue-strong: #c0d2e9;
  --blue-soft: #314359;
  --line: #394758;
  --line-strong: #64758b;
  --line-control: #8191a6;
  --good: #a1bda8;
  --warn: #dcb083;
  --overlay: rgba(7, 12, 20, 0.64);
  --texture-opacity: 0;
}

/* Form composition: shared layout roles for writing and structured forms. */
:root {
  --compose-width: 600px;
  --compose-title-size: 20px;
  --compose-editor-min-h: 128px;
  --compose-editor-max-h: 280px;
  --form-gap: 20px;
  --form-label-weight: 500;
}
