/* ==========================================================================
   KECA U.S.A. — SHARED DESIGN TOKENS (single source of truth)
   --------------------------------------------------------------------------
   Source: the :root block of kecausa.com/assets/css/site.css, as supplied in
   the project brief. This is a LOCAL COPY inside the standalone specifier app.
   The live site is never read from at runtime and is never modified.

   WHO LOADS THIS FILE (checked against the files on disk, not assumed):
       app/index.html          <link href="./assets/css/keca-tokens.css">
       app/viewer.html         <link href="./assets/css/keca-tokens.css">
       app/viewer-states.html  <link href="./assets/css/keca-tokens.css">
       app/plan.html           <link href="assets/css/keca-tokens.css">
       app/tearsheet.html      <link href="./assets/css/keca-tokens.css">
       app/dev/test.html       <link href="../assets/css/keca-tokens.css">
   ...and nothing else.

   MERGE NOTE — 2026-08-31
   Two agents built the app in parallel and produced two token files:
   app/assets/css/keca-tokens.css (site namespace: --bg, --paper, --line …)
   and app/css/tokens.css (--keca-* namespace). They were checked value by
   value, found to AGREE everywhere they overlapped, and merged into this one
   file. app/css/tokens.css has been deleted. Both namespaces are declared
   below and both are complete; nothing was dropped and no value was changed.

   Namespace map, for anyone wondering which name to reach for:
       --bg / --paper / --line / --surface / --tint / --accent / --green …
           the site-native names. app/assets/css/viewer.css consumes these.
       --keca-n-* / --keca-bg / --keca-text / --keca-s-* / --keca-stroke-* …
           the ramp + scale namespace. app/assets/css/plan.css consumes these
           (via its own --pl-* aliases) and app/dev/test.html uses them inline.
   New work should not add a third namespace. Extend whichever of the two the
   consuming stylesheet already speaks.

   The element-level base rules (body, headings, .btn, .wrap …) that used to
   live at the bottom of this file are now in app/assets/css/keca-base.css.
   They are page furniture, not tokens, and only the two viewer pages have ever
   applied them — linking them onto plan.html and dev/test.html as a side
   effect of this merge would have silently restyled both pages. viewer.html
   and viewer-states.html link keca-base.css directly, in the same cascade
   position the rules previously occupied, so nothing about their rendering
   changed.

   Values marked VERIFIED are exactly as given in the brief.
   Values marked DERIVED are computed from a verified token (documented inline).
   Values marked ALIAS point at a verified token because the live site's own
   value was not supplied; they are deliberately NOT invented hex codes. If the
   real value is later read off site.css, replace the alias with it.
   Values marked UNMAPPED have no counterpart on the live site and keep their
   original provisional value rather than an invented one; nothing references
   them, so no rendered pixel depends on an unverified colour.

   Monochrome discipline: there is no hue in this palette beyond the single
   reserved green pair. Any state that must be distinguished (a clearance
   failure, a selected piece) is distinguished by WEIGHT, DASH PATTERN, HATCH
   FILL and TEXT — never by color alone. That is both the house style and a
   WCAG 1.4.1 requirement.
   ========================================================================== */

:root {

  /* ========================================================================
     PART 1 — SITE NAMESPACE
     Consumed by app/assets/css/viewer.css.
     ===================================================================== */

  /* --- surfaces ---------------------------------------------------------- */
  --bg:          #f7f5f2;              /* VERIFIED — page ground             */
  --bg-step:     #ece8e3;              /* VERIFIED — alternating band        */
  --surface:     #ffffff;              /* VERIFIED — card / panel face       */
  --tint:        #efece7;              /* VERIFIED — soft fill               */

  /* --- ink --------------------------------------------------------------- */
  --paper:       #1c1b1b;              /* VERIFIED — primary text            */
  --paper-soft:  rgba(28, 27, 27, .78);/* DERIVED  — --paper at 78% alpha    */
  --paper-muted: #6a6a6a;              /* VERIFIED — secondary text          */

  /* --- lines ------------------------------------------------------------- */
  --line:        #d6d4d2;              /* VERIFIED — rules and dividers      */
  --card-line:   #e2dfda;              /* VERIFIED — card border             */

  /* --- card ink (ALIAS: live-site values not supplied) -------------------- */
  --card-ink:    var(--paper);         /* ALIAS                              */
  --card-muted:  var(--paper-muted);   /* ALIAS                              */

  /* --- accent (monochrome by design — do not introduce a new hue) -------- */
  --accent:       #1c1b1b;             /* VERIFIED                           */
  --accent-hover: #000000;             /* VERIFIED (per approved plan)       */

  /* --- the one non-neutral pair, reserved for a PASS/verified state ------- */
  --green:    #3E7C55;                 /* VERIFIED                           */
  --green-bg: #E7F0E4;                 /* VERIFIED                           */

  /* --- geometry ---------------------------------------------------------- */
  --radius:      0px;                  /* VERIFIED — square corners, always  */
  --shadow-rest: none;                 /* VERIFIED — no resting shadow       */
  --wrap:        1240px;               /* VERIFIED — max content width       */

  /* --- type -------------------------------------------------------------- */
  --head-font: "Montserrat", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --body-font: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;


  /* ========================================================================
     PART 2 — --keca-* NAMESPACE
     Consumed by app/assets/css/plan.css (through its --pl-* aliases) and by
     the inline <style> block in app/dev/test.html.

     IF YOU EDIT THIS BLOCK: keep the SEMANTIC ALIAS NAMES (--keca-bg,
     --keca-text, --keca-rule, ...). plan.css maps them into its own --pl-*
     namespace with fallbacks, so a missing alias degrades to a readable
     default rather than an unstyled page — but matching names is what keeps
     the plan page and the viewer page visually identical.
     ===================================================================== */

  /* --- NEUTRAL RAMP -----------------------------------------------------
     Steps marked VERIFIED map 1:1 onto a real site token — and, since the
     merge, onto the literal PART 1 declaration a few lines above. Steps
     marked UNMAPPED have no counterpart on the live site: the site's palette
     has four ink/line values, not an eleven-step ramp. Nothing in the
     SEMANTIC block below references an UNMAPPED step.

     These are written as literals rather than as var(--surface) etc. so that
     the ramp stays readable as a ramp and so that a partial copy of this file
     cannot produce a half-resolved chain. The literals were diffed against
     PART 1 at merge time and agree exactly.
     -------------------------------------------------------------------- */
  --keca-n-000: #ffffff;  /* VERIFIED  --surface   */
  --keca-n-050: #f7f5f2;  /* VERIFIED  --bg        */
  --keca-n-100: #efece7;  /* VERIFIED  --tint      */
  --keca-n-150: #ece8e3;  /* VERIFIED  --bg-step   */
  --keca-n-200: #e2dfda;  /* VERIFIED  --card-line */
  --keca-n-300: #d6d4d2;  /* VERIFIED  --line      */
  --keca-n-400: #a6a6a1;  /* UNMAPPED — unreferenced */
  --keca-n-500: #7d7d78;  /* UNMAPPED — unreferenced */
  --keca-n-600: #6a6a6a;  /* VERIFIED  --paper-muted */
  --keca-n-700: #3d3d3a;  /* UNMAPPED — unreferenced */
  --keca-n-800: #262624;  /* UNMAPPED — unreferenced */
  --keca-n-900: #1c1b1b;  /* VERIFIED  --paper     */

  /* --- SEMANTIC ALIASES — names preserved exactly, values authoritative -- */
  --keca-bg:            var(--keca-n-050);
  --keca-surface:       var(--keca-n-000);
  --keca-surface-alt:   var(--keca-n-100);
  --keca-surface-sunk:  var(--keca-n-150);

  --keca-text:          var(--keca-n-900);
  --keca-text-muted:    var(--keca-n-600);
  /* The live site defines only two ink levels (--paper, --paper-muted). Rather
     than invent a third, "faint" is --paper at reduced opacity over the page
     ground. This is a DERIVED value, not one of the VERIFIED site colours.
     It was .55, which composites to ~#828282: 3.8:1 on white and 3.5:1 on the
     page ground, below the WCAG 1.4.7 / 1.4.3 AA minimum of 4.5:1 for normal
     text. That matters here more than usual, because --keca-text-faint is what
     paints `.is-pending` — the em dash that tells a specifier a value was never
     supplied — and the inch column in the spec table. Both are real
     information, not decoration, so they must be legible. .72 composites to
     ~6.3:1 on white and ~6.1:1 on the page ground while staying clearly
     subordinate to --keca-text-muted.
     Note: this is intentionally NOT the same value as --paper-soft (.78) in
     PART 1. Different consumers, different contrast targets; neither overrides
     the other because the names differ. */
  --keca-text-faint:    rgba(28, 27, 27, .72);
  --keca-text-invert:   var(--keca-n-000);

  --keca-rule:          var(--keca-n-300);
  --keca-rule-strong:   var(--keca-n-900);
  --keca-rule-faint:    var(--keca-n-200);

  --keca-focus:         var(--keca-n-900);
  --keca-focus-halo:    var(--keca-n-000);

  /* Monochrome "alert" tones. Deliberately not red — the tool signals state
     with hatch, dash and words. These only carry emphasis weight. */
  --keca-alert:         var(--keca-n-900);
  --keca-warn:          var(--keca-n-600);

  /* --- TYPE ------------------------------------------------------------- */
  /* These deliberately differ from --head-font / --body-font in PART 1 by one
     fallback each ("Segoe UI" for the plan tool's dense UI chrome). Both
     stacks lead with the same two webfonts, so the rendered result is the same
     wherever the fonts load. Left as-is: changing either would be a visual
     change, and this merge is structural only. */
  --keca-font-display: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  --keca-font-body: "Nunito Sans", "Segoe UI", Helvetica, Arial, sans-serif;
  --keca-font-mono: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace;

  --keca-fs-micro: 0.6875rem;  /* 11px */
  --keca-fs-small: 0.75rem;    /* 12px */
  --keca-fs-base:  0.875rem;   /* 14px */
  --keca-fs-body:  1rem;       /* 16px */
  --keca-fs-lead:  1.125rem;   /* 18px */
  --keca-fs-h3:    1rem;
  --keca-fs-h2:    1.25rem;
  --keca-fs-h1:    1.5rem;

  --keca-tracking-display: 0.14em;
  --keca-tracking-label: 0.09em;
  --keca-lh-tight: 1.2;
  --keca-lh-body: 1.55;

  /* --- SPACE (4px base) -------------------------------------------------- */
  --keca-s-1: 0.25rem;
  --keca-s-2: 0.5rem;
  --keca-s-3: 0.75rem;
  --keca-s-4: 1rem;
  --keca-s-5: 1.5rem;
  --keca-s-6: 2rem;
  --keca-s-7: 3rem;

  /* --- STROKE WEIGHTS (screen px; SVG uses non-scaling-stroke) ----------- */
  --keca-stroke-hair: 0.5px;
  --keca-stroke-thin: 1px;
  --keca-stroke-med: 1.5px;
  --keca-stroke-heavy: 2px;
  --keca-stroke-wall: 3px;

  /* --- GEOMETRY ---------------------------------------------------------- */
  --keca-radius: 0;            /* square corners, everywhere, always */
  --keca-focus-width: 2px;
  --keca-focus-offset: 2px;
  --keca-tap-min: 44px;        /* minimum touch target */
}
