/* ============================================================================
   Rosetta Dynamics — design tokens v0.1
   Industrial predictive-maintenance / instrumentation register.

   Every text pairing below was checked programmatically against WCAG 2.1.
   Ratios are noted inline. Don't hand-edit a value without re-checking it.

   Usage:  <link rel="stylesheet" href="tokens.css">
   Theme:  follows the OS by default; force with <html data-theme="light|dark">
   ============================================================================ */

/* ---------------------------------------------------------------- primitives
   Raw ramps. Refer to these ONLY when defining semantic tokens below —
   never in component CSS. That indirection is what lets a sub-brand
   ("wing") re-map the palette without touching a single component. */

:root {
  /* Neutrals — very slightly cool, to sit with teal without reading "blue tech" */
  --n-0:    #FFFFFF;
  --n-25:   #FAFBFB;
  --n-50:   #F4F6F7;
  --n-100:  #E8ECEE;
  --n-200:  #D2D9DC;
  --n-300:  #B3BDC2;
  --n-400:  #8B979D;
  --n-500:  #6B777D;
  --n-600:  #525C61;
  --n-700:  #3D4649;
  --n-800:  #2A3134;
  --n-900:  #1B2023;
  --n-950:  #111517;
  --n-1000: #0A0C0D;

  /* Brand accent — deep teal. Deliberately occupies NO alarm hue. */
  --a-50:  #EAF3F4;
  --a-100: #CBE3E6;
  --a-200: #9CCBD1;
  --a-300: #66ADB6;
  --a-400: #3D8F9B;
  --a-500: #1F7580;
  --a-600: #155E68;
  --a-700: #124B54;
  --a-800: #123C43;
  --a-900: #102F35;

  /* ------------------------------------------------------------ typography */

  /* IBM Plex is free, open source, and built for this technical register.
     Self-host it — do not rely on system fonts, or a large share of visitors
     get Arial at weight 400 and your type discipline evaporates. */
  --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system,
               "Segoe UI", Roboto, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo,
               Consolas, monospace;
  --font-condensed: "IBM Plex Sans Condensed", var(--font-sans);

  /* Type scale — 1.200 (minor third). Tight enough for dense tables,
     with enough range for marketing. */
  --text-2xs:  0.694rem;   /* 11.1px — dense table meta, avoid for prose */
  --text-xs:   0.833rem;   /* 13.3px — table body, labels */
  --text-sm:   0.9375rem;  /* 15px   — secondary UI text */
  --text-base: 1rem;       /* 16px   — body */
  --text-lg:   1.2rem;     /* 19.2px */
  --text-xl:   1.44rem;    /* 23px   — card titles */
  --text-2xl:  1.728rem;   /* 27.6px — section heads */
  --text-3xl:  2.074rem;   /* 33.2px */
  --text-4xl:  2.488rem;   /* 39.8px — page titles */
  --text-5xl:  2.986rem;   /* 47.8px — marketing hero */

  --leading-tight:  1.2;   /* headings */
  --leading-snug:   1.35;  /* dense tables */
  --leading-normal: 1.55;  /* body prose */

  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;

  --tracking-tight: -0.011em;  /* large headings */
  --tracking-wide:   0.06em;   /* small caps labels */

  /* Live-updating numerics MUST be tabular or digits jitter as they change. */
  --numeric-tabular: tabular-nums lining-nums;

  /* ---------------------------------------------------------------- space
     4px base. Sticking to the scale is what keeps density consistent
     once twelve people are writing components. */
  --space-1:  0.25rem;
  --space-2:  0.5rem;
  --space-3:  0.75rem;
  --space-4:  1rem;
  --space-5:  1.5rem;
  --space-6:  2rem;
  --space-7:  3rem;
  --space-8:  4rem;
  --space-9:  6rem;

  /* --------------------------------------------------------------- shape */
  --radius-sm: 3px;
  --radius-md: 5px;
  --radius-lg: 8px;
  --radius-full: 999px;

  --border-width: 1px;
  --border-width-emphasis: 2px;

  /* Touch targets. 44px is the floor for gloved hands on a plant floor —
     treat this as a hard minimum, not a suggestion. */
  --target-min: 44px;

  /* --------------------------------------------------------------- motion
     Motion conveys state change only. Never decorative — in an ops tool,
     movement trains the eye, and spending it on flourish dulls the signal. */
  --motion-fast:   120ms;
  --motion-normal: 200ms;
  --motion-slow:   320ms;
  --ease-out: cubic-bezier(0.2, 0, 0, 1);
}

/* ==========================================================================
   SEMANTIC TOKENS — light (default)
   ========================================================================== */

:root,
[data-theme="light"] {
  --surface-page:    var(--n-0);
  --surface-raised:  var(--n-50);
  --surface-sunken:  var(--n-100);
  --surface-overlay: var(--n-0);
  --surface-inverse: var(--n-950);

  --text-primary:   var(--n-900);   /* 16.4:1 on page */
  --text-secondary: var(--n-800);   /* 13.2:1 */
  --text-muted:     var(--n-600);   /*  6.9:1 on page, 6.3:1 on raised */
  --text-inverse:   var(--n-0);
  --text-accent:    var(--a-600);   /*  7.4:1 */
  --text-on-accent: var(--n-0);     /*  7.4:1 on accent-solid */

  /* Two border weights. Subtle is decorative (exempt from contrast rules);
     strong is for interactive control outlines and MUST clear 3:1. */
  --border-subtle: var(--n-200);
  --border-strong: var(--n-500);    /* 4.6:1 — clears the 3:1 UI minimum */
  --border-accent: var(--a-500);

  --accent-solid:       var(--a-600);
  --accent-solid-hover: var(--a-700);
  --accent-wash:        var(--a-50);

  /* Status — all clear 4.5:1 on the page surface.
     See the CVD warning near the bottom of this file. */
  --status-nominal:  #15703F;   /* 6.14:1 */
  --status-watch:    #826716;   /* 5.38:1 */
  --status-warning:  #AE5313;   /* 5.19:1 */
  --status-critical: #B3261E;   /* 6.54:1 */
  --status-offline:  #525C61;   /* 6.86:1 */

  /* Washes for chip/row backgrounds. Text on these uses the solid above. */
  --status-nominal-wash:  #E7F3EC;
  --status-watch-wash:    #F7F0DC;
  --status-warning-wash:  #FBEDE3;
  --status-critical-wash: #FAE9E7;
  --status-offline-wash:  var(--n-100);

  --focus-ring: var(--a-500);
  --shadow-sm: 0 1px 2px rgba(17, 21, 23, 0.06);
  --shadow-md: 0 2px 8px rgba(17, 21, 23, 0.08);
  --shadow-lg: 0 8px 24px rgba(17, 21, 23, 0.10);

  color-scheme: light;
}

/* ==========================================================================
   SEMANTIC TOKENS — dark
   Functional, not stylistic: control rooms and night shifts need it.
   Keep MARKETING pages light — dark marketing plus dark product is what
   tips an instrumentation brand back into consumer-AI territory.
   ========================================================================== */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --surface-page:    var(--n-950);
    --surface-raised:  var(--n-900);
    --surface-sunken:  var(--n-1000);
    --surface-overlay: var(--n-800);
    --surface-inverse: var(--n-0);

    --text-primary:   var(--n-100);   /* 15.5:1 */
    --text-secondary: var(--n-200);   /* 12.9:1 */
    --text-muted:     var(--n-400);   /*  6.1:1 on page, 5.5:1 on raised */
    --text-inverse:   var(--n-950);
    --text-accent:    var(--a-300);   /*  7.2:1 */
    --text-on-accent: var(--n-1000);

    --border-subtle: var(--n-800);
    --border-strong: var(--n-500);    /* 4.0:1 */
    --border-accent: var(--a-400);

    --accent-solid:       var(--a-400);
    --accent-solid-hover: var(--a-300);
    --accent-wash:        var(--a-900);

    --status-nominal:  #5FD98D;   /* 10.32:1 */
    --status-watch:    #EBC24C;   /* 10.80:1 */
    --status-warning:  #FF9A4D;   /*  8.73:1 */
    --status-critical: #FF6B63;   /*  6.59:1 */
    --status-offline:  #93A0A6;   /*  6.84:1 */

    --status-nominal-wash:  #12291D;
    --status-watch-wash:    #2B2410;
    --status-warning-wash:  #2E1D10;
    --status-critical-wash: #2E1614;
    --status-offline-wash:  var(--n-800);

    --focus-ring: var(--a-300);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.6);

    color-scheme: dark;
  }
}

/* Explicit override, for a user toggle that beats the OS setting. */
[data-theme="dark"] {
  --surface-page:    var(--n-950);
  --surface-raised:  var(--n-900);
  --surface-sunken:  var(--n-1000);
  --surface-overlay: var(--n-800);
  --surface-inverse: var(--n-0);

  --text-primary:   var(--n-100);
  --text-secondary: var(--n-200);
  --text-muted:     var(--n-400);
  --text-inverse:   var(--n-950);
  --text-accent:    var(--a-300);
  --text-on-accent: var(--n-1000);

  --border-subtle: var(--n-800);
  --border-strong: var(--n-500);
  --border-accent: var(--a-400);

  --accent-solid:       var(--a-400);
  --accent-solid-hover: var(--a-300);
  --accent-wash:        var(--a-900);

  --status-nominal:  #5FD98D;
  --status-watch:    #EBC24C;
  --status-warning:  #FF9A4D;
  --status-critical: #FF6B63;
  --status-offline:  #93A0A6;

  --status-nominal-wash:  #12291D;
  --status-watch-wash:    #2B2410;
  --status-warning-wash:  #2E1D10;
  --status-critical-wash: #2E1614;
  --status-offline-wash:  var(--n-800);

  --focus-ring: var(--a-300);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.6);

  color-scheme: dark;
}

/* ==========================================================================
   COLOUR-BLINDNESS: READ THIS BEFORE BUILDING ANY STATUS UI

   These status colours were simulated for deuteranopia and protanopia.
   Measured result:

     light  deuteranopia   warning vs critical   dE = 5.7
     light  protanopia     warning vs critical   dE = 3.6
     dark   deuteranopia   warning vs critical   dE = 2.7
     dark   protanopia     watch   vs critical   dE = 5.4

   dE below ~10 is not reliably distinguishable. Warning and critical
   converge, and no hue choice fixes it — red and orange collapse onto the
   same axis for red-green CVD, which affects roughly 8% of men in a
   male-dominated field. Optimising the palette purely for separation
   produced colours no one would read as "critical".

   So the rule is not negotiable, and it matches ISA-101 control-room
   practice: COLOUR IS THE SECONDARY CHANNEL. Every status must also carry
   a distinct icon SHAPE and a text label.

     nominal   circle           "Nominal"
     watch     diamond          "Watch"
     warning   triangle         "Warning"
     critical  octagon / hex    "Critical"
     offline   slashed circle   "Offline"

   Shape and text survive CVD, greyscale printing, bad monitors, and
   sunlight on a tablet. Colour is reinforcement, never the carrier.
   ========================================================================== */

/* ------------------------------------------------------------------ motion */

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-normal: 0ms;
    --motion-slow: 0ms;
  }
}
