/* ==========================================================================
   tokens.css - Shorter Suite
   --------------------------------------------------------------------------
   Every surface loads this first: the static pages in public/, and the
   server-rendered board and gate pages in functions/src/handlers/. It is the
   single source of colour, type, space and motion. Nothing downstream may
   declare a raw hex value.

   Token architecture, the three-state dark mode and the contrast contract are
   adapted from the-monospace-web fork by usualguy (MIT), itself built on
   The Monospace Web by Oskar Wickstrom (MIT). See NOTICE.md. The ramps and
   the type system here are this project's own.

   The world is a travel document: a pale security-tint ground, document
   navy-black ink, and one stamp-pad indigo accent. Radius is 0 because print
   has no radius. Hued ramps are interpolated in OKLab so steps are
   perceptually even; every semantic pairing below is asserted by
   tools/check-contrast.py in BOTH themes.
   ========================================================================== */

/* ==========================================================================
   1  RAW RAMPS - theme-independent, never addressed by a component
   --------------------------------------------------------------------------
   Step index carries a fixed contract in BOTH themes:
     50/100  light-theme tint surfaces      500  NON-TEXT ONLY (rules, borders)
     600     light-theme hued ink           300  dark-theme hued ink
     900/950 dark-theme tint surfaces
   ========================================================================== */

:root {
  /* Neutral runs cool: a faint green-grey cast, so the ground reads as security tint. */
  --n-0:    #ffffff;
  --n-50:   #f5f7f6;
  --n-100:  #eaeeec;
  --n-200:  #d6dcd9;
  --n-300:  #c2cac7;
  --n-400:  #9fa9a6;
  --n-500:  #7d8a86;
  --n-600:  #626e6a;
  --n-700:  #49544f;
  --n-800:  #333d39;
  --n-900:  #1e2724;
  --n-950:  #161e1b;
  --n-1000: #0f1613;

  /* Stamp-pad indigo, deep and muted: bright violet is the SaaS default this world is not. */
  --accent-50:   #f0eff8;
  --accent-100:  #e1e0f1;
  --accent-200:  #c5c2e3;
  --accent-300:  #a9a4d4;
  --accent-400:  #8985c0;
  --accent-500:  #6b66ab;
  --accent-600:  #4f4796;
  --accent-700:  #40397c;
  --accent-800:  #322c62;
  --accent-900:  #241f4a;
  --accent-950:  #1d193f;

  --success-50:   #e9f5ec;
  --success-100:  #d7ecdd;
  --success-200:  #b3dabf;
  --success-300:  #8fc8a2;
  --success-400:  #6fab82;
  --success-500:  #4f8f62;
  --success-600:  #2f7344;
  --success-700:  #265d38;
  --success-800:  #1d492c;
  --success-900:  #153520;

  --warning-50:   #fbf1e3;
  --warning-100:  #f6e5ce;
  --warning-200:  #ebcca2;
  --warning-300:  #e0b476;
  --warning-400:  #c39557;
  --warning-500:  #a67737;
  --warning-600:  #8a5a11;
  --warning-700:  #70490e;
  --warning-800:  #58390b;
  --warning-900:  #402a08;

  --danger-50:   #fceceb;
  --danger-100:  #f9dddb;
  --danger-200:  #f1bebb;
  --danger-300:  #e8a09c;
  --danger-400:  #d27c75;
  --danger-500:  #bb5750;
  --danger-600:  #a32f2a;
  --danger-700:  #842622;
  --danger-800:  #661d1a;
  --danger-900:  #4a1513;
}

/* ==========================================================================
   2  METRICS - theme-independent
   ========================================================================== */

:root {
  /* Archivo carries prose and interface; narrowed on its wdth axis it carries the field labels. */
  /* Martian Mono carries literal machine strings only: codes, slugs, URLs, keys, counts, dates. */
  /* Archivo is variable on wdth 62.5-100, so the condensed cut costs no second request. */
  --font-sans: "Archivo", ui-sans-serif, system-ui, "Helvetica Neue", Arial, sans-serif;
  --font-label: "Archivo", ui-sans-serif, system-ui, "Helvetica Neue", Arial, sans-serif;
  --font-stretch-label: 75%;
  --font-mono: "Martian Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;

  --font-size-2xs:  0.6875rem;
  --font-size-xs:   0.75rem;
  --font-size-sm:   0.8125rem;
  --font-size-base: 0.9375rem;
  --font-size-md:   1.0625rem;
  --font-size-lg:   1.375rem;
  --font-size-xl:   1.75rem;
  --font-size-2xl:  2.25rem;
  --font-size-3xl:  3rem;

  --line-tight: 1.15;
  --line-snug:  1.35;
  --line-base:  1.6;
  --line-loose: 1.75;

  /* Caps tracking makes a 6-letter label legible at 11px; a boxed caption pairs it with an equal text-indent. */
  /* Mono and tight both measured 0 here on purpose: any negative value, even -0.02em, rounds to a
     whole device pixel per letter pair at normal sizes and reliably fuses round letters together
     (the "oo" in a title, "cool" in a slug) since some pairs round to a 0px gap. Positive tracking
     never fully closes a gap the same way, so --tracking-caps is untouched. */
  --tracking-caps:  0.1em;
  --tracking-mono:  0em;
  --tracking-tight: 0em;

  /* Low density is the brief: the scale starts generous and its big steps separate records. */
  --space-3xs: 0.25rem;
  --space-2xs: 0.375rem;
  --space-xs:  0.5rem;
  --space-sm:  0.75rem;
  --space-md:  1rem;
  --space-lg:  1.5rem;
  --space-xl:  2rem;
  --space-2xl: 3rem;
  --space-3xl: 4.5rem;
  --space-4xl: 6rem;

  /* Print has no radius. This is the design language, not an omission. */
  --radius: 0;

  --rule: 1px;
  --rule-strong: 2px;

  /* The only depth here is a dialog lifting off the page: offset plus blur, never a zero-blur block. */
  --shadow-dialog: 0 24px 48px -12px rgb(15 22 19 / 0.28), 0 2px 6px rgb(15 22 19 / 0.12);

  --duration-fast: 90ms;
  --duration-base: 180ms;
  --duration-slow: 320ms;
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-standard: cubic-bezier(0.2, 0, 0, 1);

  --measure: 68ch;

  --z-sticky: 100;
  --z-overlay: 200;
  --z-modal: 300;
  --z-toast: 400;
}

/* ==========================================================================
   3  SEMANTIC ALIASES - LIGHT (the default)
   --------------------------------------------------------------------------
   Components address ONLY these names. Verified >=4.5:1 for text and >=3:1
   for borders, focus rings and other non-text indicators.
   ========================================================================== */

:root {
  --color-bg:         var(--n-50);   /* the security tint, not white */
  --color-bg-raised:  var(--n-0);
  --color-bg-subtle:  var(--n-100);
  --color-bg-inset:   var(--n-100);
  --color-bg-overlay: rgb(15 22 19 / 0.55);

  --color-text:          var(--n-1000);  /* 17.05:1 on bg */
  --color-text-muted:    var(--n-700);   /*  7.33:1 on bg */
  --color-text-subtle:   var(--n-600);
  --color-text-inverse:  var(--n-0);
  --color-text-disabled: var(--n-500);

  --color-rule:        var(--n-300);   /* the hairline that rules a field */
  --color-rule-strong: var(--n-1000);
  --color-border:      var(--n-500);   /* 3:1 minimum: it bounds a control */
  --color-border-strong: var(--n-1000);

  --color-focus:       var(--accent-600);
  --focus-ring-width:  2px;
  --focus-ring-offset: 2px;

  --color-action:        var(--n-1000);
  --color-action-hover:  var(--n-800);
  --color-action-text:   var(--n-0);
  --color-action-ghost-hover: var(--n-100);
  --color-action-ghost-pressed: var(--n-200);

  /* Light-theme rule: hued ink at 600 on a 50 tint; white text on a 600 fill. */
  --color-accent:        var(--accent-600);  /* 7.30:1 on bg */
  --color-accent-hover:  var(--accent-700);
  --color-accent-bg:     var(--accent-50);
  --color-accent-bg-pressed: var(--accent-100);
  --color-accent-border: var(--accent-600);
  --color-accent-text:   var(--n-0);         /* 7.85:1 on the fill */

  --color-success:        var(--success-600);
  --color-success-bg:     var(--success-50);
  --color-success-border: var(--success-600);
  --color-success-text:   var(--n-0);

  --color-warning:        var(--warning-600);
  --color-warning-bg:     var(--warning-50);
  --color-warning-border: var(--warning-600);
  --color-warning-text:   var(--n-0);

  --color-danger:        var(--danger-600);
  --color-danger-hover:  var(--danger-700);
  --color-danger-bg:     var(--danger-50);
  --color-danger-border: var(--danger-600);
  --color-danger-text:   var(--n-0);

  --color-disabled-bg:     var(--n-100);
  --color-disabled-border: var(--n-400);
  --color-disabled-text:   var(--n-600);

  --color-selection-bg: var(--accent-200);
  --color-selection-fg: var(--n-1000);

  color-scheme: light;
}

/* ==========================================================================
   4  SEMANTIC ALIASES - DARK
   --------------------------------------------------------------------------
   Declared twice on purpose:
     (a) under prefers-color-scheme, guarded so an explicit [data-theme=light]
         beats a dark OS setting;
     (b) under [data-theme=dark], so an explicit toggle wins on a light system.
   The two blocks are byte-identical; edit them together.

   The flip is an INVERSION, not a recolour: hued ink moves 600 -> 300, tint
   surfaces move 50 -> 900, and solid hued fills take BLACK text, not white.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg:         var(--n-1000);
    --color-bg-raised:  var(--n-950);
    --color-bg-subtle:  var(--n-900);
    --color-bg-inset:   var(--n-900);
    --color-bg-overlay: rgb(0 0 0 / 0.72);

    --color-text:          var(--n-0);     /* 18.35:1 on bg */
    --color-text-muted:    var(--n-400);   /*  7.60:1 on bg */
    --color-text-subtle:   var(--n-500);
    --color-text-inverse:  var(--n-1000);
    --color-text-disabled: var(--n-600);

    --color-rule:        var(--n-800);
    --color-rule-strong: var(--n-300);
    --color-border:      var(--n-600);
    --color-border-strong: var(--n-300);

    --color-focus:       var(--accent-300);

    --color-action:        var(--n-0);
    --color-action-hover:  var(--n-200);
    --color-action-text:   var(--n-1000);
    --color-action-ghost-hover: var(--n-900);
    --color-action-ghost-pressed: var(--n-800);

    --color-accent:        var(--accent-300);  /* 7.82:1 on bg */
    --color-accent-hover:  var(--accent-200);
    --color-accent-bg:     var(--accent-950);
    --color-accent-bg-pressed: var(--accent-900);
    --color-accent-border: var(--accent-300);
    --color-accent-text:   var(--n-1000);      /* 7.82:1 on the fill */

    --color-success:        var(--success-300);
    --color-success-bg:     var(--success-900);
    --color-success-border: var(--success-300);
    --color-success-text:   var(--n-1000);

    --color-warning:        var(--warning-300);
    --color-warning-bg:     var(--warning-900);
    --color-warning-border: var(--warning-300);
    --color-warning-text:   var(--n-1000);

    --color-danger:        var(--danger-300);
    --color-danger-hover:  var(--danger-200);
    --color-danger-bg:     var(--danger-900);
    --color-danger-border: var(--danger-300);
    --color-danger-text:   var(--n-1000);

    --color-disabled-bg:     var(--n-900);
    --color-disabled-border: var(--n-700);
    --color-disabled-text:   var(--n-500);

    --color-selection-bg: var(--accent-800);
    --color-selection-fg: var(--n-0);

    color-scheme: dark;
  }
}

[data-theme="dark"] {
  --color-bg:         var(--n-1000);
  --color-bg-raised:  var(--n-950);
  --color-bg-subtle:  var(--n-900);
  --color-bg-inset:   var(--n-900);
  --color-bg-overlay: rgb(0 0 0 / 0.72);

  --color-text:          var(--n-0);
  --color-text-muted:    var(--n-400);
  --color-text-subtle:   var(--n-500);
  --color-text-inverse:  var(--n-1000);
  --color-text-disabled: var(--n-600);

  --color-rule:        var(--n-800);
  --color-rule-strong: var(--n-300);
  --color-border:      var(--n-600);
  --color-border-strong: var(--n-300);

  --color-focus:       var(--accent-300);

  --color-action:        var(--n-0);
  --color-action-hover:  var(--n-200);
  --color-action-text:   var(--n-1000);
  --color-action-ghost-hover: var(--n-900);
  --color-action-ghost-pressed: var(--n-800);

  --color-accent:        var(--accent-300);
  --color-accent-hover:  var(--accent-200);
  --color-accent-bg:     var(--accent-950);
  --color-accent-bg-pressed: var(--accent-900);
  --color-accent-border: var(--accent-300);
  --color-accent-text:   var(--n-1000);

  --color-success:        var(--success-300);
  --color-success-bg:     var(--success-900);
  --color-success-border: var(--success-300);
  --color-success-text:   var(--n-1000);

  --color-warning:        var(--warning-300);
  --color-warning-bg:     var(--warning-900);
  --color-warning-border: var(--warning-300);
  --color-warning-text:   var(--n-1000);

  --color-danger:        var(--danger-300);
  --color-danger-hover:  var(--danger-200);
  --color-danger-bg:     var(--danger-900);
  --color-danger-border: var(--danger-300);
  --color-danger-text:   var(--n-1000);

  --color-disabled-bg:     var(--n-900);
  --color-disabled-border: var(--n-700);
  --color-disabled-text:   var(--n-500);

  --color-selection-bg: var(--accent-800);
  --color-selection-fg: var(--n-0);

  color-scheme: dark;
}
