/*
 * Lens visual system: tokens (owner: lane V1a).
 *
 * Primitives, semantic aliases with a light and a dark value, data scales, chart tokens, widths,
 * breakpoints and the z-index scale. The ONLY sheet allowed to hold colour literals
 * (VisualSystemNetsTest). Contract: docs/web/visual-system-contract.md §2.
 *
 * Three tiers:
 *   1. primitives (--tz-*): the brand's values plus the dark-theme steps. Only this sheet reads them.
 *   2. semantic aliases (--lens-text, --lens-surface, --lens-good…): what components use. Each has
 *      a light value (on :root) and a dark one (the two dark blocks at the end, identical).
 *   3. data scales (--lens-band-*, --lens-signal-*, --lens-cat-*…): measurements, never UI chrome,
 *      state words or links. Mid-lightness stops that read on both grounds, so most keep one value.
 *
 * Themes: light on :root; dark when the system prefers it and the user did not choose light
 * (data-theme="light"), or when the user chose dark (data-theme="dark", set by the server from the
 * lens-theme cookie; js/lens-theme.js). Both dark blocks are screen-only, so print is always light.
 * VisualSystemContrastTest computes every text and mark pair below in both themes.
 */

/* ------------------------------------------------------------------ 1. primitives */
:root {
  /* brand */
  --tz-primary: #024256;
  --tz-primary-rgb: 2, 66, 86;
  --tz-primary-dark: #02232D;
  --tz-accent: #53BDD0;
  --tz-accent-blue: #0080AA;
  --tz-accent-blue-dark: #03578A;
  --tz-white: #fff;
  --tz-white-rgb: 255, 255, 255;

  /* teal-tinted neutrals — never pure grey (n150 and n850 are the system's in-between steps) */
  --tz-n950: #0B1D24;
  --tz-n900: #122A33;
  --tz-n850: #18343F;
  --tz-n800: #1E3F4C;
  --tz-n700: #2E5565;
  --tz-n600: #436D7D;
  --tz-n500: #5E8794;
  --tz-n400: #82A3AD;
  --tz-n300: #ACC3CA;
  --tz-n200: #D5E1E5;
  --tz-n150: #E2EBEE;
  --tz-n100: #EDF2F4;
  --tz-n50:  #F6F9FA;

  /* semantic triplets: main / bg / fg (the brand's); the -mark steps are darker mains that keep
     3:1 against a light surface, which the brand's mains (2.2–2.5:1) do not */
  --tz-success: #10B981; --tz-success-bg: #D1FAE5; --tz-success-fg: #065F46; --tz-success-mark: #0B8A5F;
  --tz-warning: #F59E0B; --tz-warning-bg: #FEF3C7; --tz-warning-fg: #92400E; --tz-warning-mark: #B86E00;
  --tz-error:   #EF4444; --tz-error-bg:   #FEE2E2; --tz-error-fg:   #991B1B; --tz-error-mark:   #D12E2E;
  --tz-info:    #0080AA; --tz-info-bg:    #E0F4FA; --tz-info-fg:    #03578A;

  /* light-theme interaction tint */
  --tz-selected: #DDEEF3;

  /* dark-theme steps (brand dark-mode guidance: n950 ground, n900 surfaces, light inks) */
  --tz-dk-link: #6CC4E0;
  --tz-dk-link-hover: #9AD8EC;
  --tz-dk-primary: #4FB3C8;
  --tz-dk-primary-hover: #7CCAD9;
  --tz-dk-selected: #134152;
  --tz-dk-good: #34C38F;   --tz-dk-good-ink: #6EE7B7;   --tz-dk-good-bg: #0E3B2E;
  --tz-dk-watch: #F2A93B;  --tz-dk-watch-ink: #FCD34D;  --tz-dk-watch-bg: #3B2C0B;
  --tz-dk-action: #F07171; --tz-dk-action-ink: #FCA5A5; --tz-dk-action-bg: #45181B;
  --tz-dk-info: #4FB3D9;   --tz-dk-info-ink: #7DD3F0;   --tz-dk-info-bg: #0C3646;
  --tz-dk-reviews-fill: #3A3118;

  /* overlay shadows — teal-tinted, never black */
  --tz-shadow-overlay-light: 0 8px 32px rgba(2, 35, 45, .16);
  --tz-shadow-overlay-dark: 0 8px 32px rgba(0, 0, 0, .45);
  --tz-threshold-band-light: rgba(2, 66, 86, .07);
  --tz-threshold-band-dark: rgba(172, 195, 202, .10);
}

/* ------------------------------------------------------------------ 2. semantic aliases (light) */
:root {
  color-scheme: light;

  /* text */
  --lens-text: var(--tz-n800);
  --lens-text-muted: var(--tz-n600);
  --lens-heading: var(--tz-primary-dark);
  --lens-text-inverse: var(--tz-white);

  /* links: one colour everywhere (#0080AA is 4.25:1 on n50, below AA: declared deviation) */
  --lens-link: var(--tz-accent-blue-dark);
  --lens-link-hover: var(--tz-primary);

  /* surfaces */
  --lens-canvas: var(--tz-n50);
  --lens-surface: var(--tz-white);
  --lens-surface-subtle: var(--tz-n100);
  --lens-surface-raised: var(--tz-white);

  /* shell: the midnight-teal top bar and the white second level */
  --lens-shell: var(--tz-primary-dark);
  --lens-shell-2: var(--tz-white);
  --lens-shell-text: var(--tz-white);
  --lens-shell-text-muted: var(--tz-n300);
  --lens-shell-active: var(--tz-primary);

  /* lines */
  --lens-border: var(--tz-n200);
  --lens-divider: var(--tz-n150);
  --lens-border-strong: var(--tz-n500);
  --lens-focus: var(--tz-accent-blue);

  /* interaction */
  --lens-primary: var(--tz-primary);
  --lens-primary-hover: var(--tz-primary-dark);
  --lens-selected: var(--tz-selected);
  --lens-hover: var(--tz-n100);

  /* state (D1): the mark is the dot, -ink the word, -bg only for a box that describes real risk */
  --lens-good: var(--tz-success-mark);
  --lens-good-ink: var(--tz-success-fg);
  --lens-good-bg: var(--tz-success-bg);
  --lens-watch: var(--tz-warning-mark);
  --lens-watch-ink: var(--tz-warning-fg);
  --lens-watch-bg: var(--tz-warning-bg);
  --lens-action: var(--tz-error-mark);
  --lens-action-ink: var(--tz-error-fg);
  --lens-action-bg: var(--tz-error-bg);
  --lens-neutral: var(--tz-n500);
  --lens-neutral-ink: var(--tz-n600);
  --lens-neutral-bg: var(--tz-n100);
  --lens-info: var(--tz-info);
  --lens-info-ink: var(--tz-info-fg);
  --lens-info-bg: var(--tz-info-bg);

  /* elevation: overlays only */
  --lens-shadow-overlay: var(--tz-shadow-overlay-light);
  /* The notice (toast): an inverse surface, so a transient message never reads as page content.
     The state lives in its icon and its words, never in a bar. */
  --lens-toast-bg: var(--tz-primary-dark);
  --lens-toast-text: var(--tz-n50);
  --lens-toast-muted: var(--tz-n300);
  --lens-toast-good: var(--tz-dk-good);
  --lens-toast-watch: var(--tz-dk-watch);
  --lens-toast-action: var(--tz-dk-action);
  --lens-toast-info: var(--tz-dk-info);
}

/* ------------------------------------------------------------------ 3. data scales */
:root {
  /* Coverage bands (S7): diverging at the 80 % bar. Cool and quiet at 80 and above; warm data
     tones below, terracotta to rust, strengthening as coverage falls. Mid-lightness: every band
     keeps 3:1 against the light and the dark grounds, so one set of stops serves both themes.
     -ink is the text that reads on the band (4.5:1). Distinct from the state marks. */
  --lens-band-excellent: #2F7A9E;      /* ≥ 95 % */
  --lens-band-excellent-ink: #FFFFFF;
  --lens-band-good: #449B8E;           /* 80–94 % */
  --lens-band-good-ink: #0B1D24;
  --lens-band-normal: #C47F5E;         /* 70–79 % */
  --lens-band-normal-ink: #0B1D24;
  --lens-band-bad: #C46A4E;            /* 50–69 % */
  --lens-band-bad-ink: #0B1D24;
  --lens-band-very-bad: #B5532A;       /* < 50 % */
  --lens-band-very-bad-ink: #FFFFFF;
  --lens-band-none: #8A9799;           /* too few readings, drawn hatched */
  --lens-band-none-ink: #0B1D24;
  --lens-band-boh: #7A8C84;            /* back of house */
  --lens-band-boh-ink: #0B1D24;
  --lens-hatch: repeating-linear-gradient(45deg, var(--lens-band-none) 0 2px, transparent 2px 7px);

  /* Signal on maps (dBm), strongest first, on the bands' hues */
  --lens-signal-1: var(--lens-band-excellent);
  --lens-signal-2: var(--lens-band-good);
  --lens-signal-3: var(--lens-band-normal);
  --lens-signal-4: var(--lens-band-bad);
  --lens-signal-5: var(--lens-band-very-bad);
  --lens-ramp-signal: linear-gradient(90deg, var(--lens-signal-5), var(--lens-signal-4),
      var(--lens-signal-3), var(--lens-signal-2), var(--lens-signal-1));

  /* Categories (causes, chart series): no violet, none equal to a state or link colour */
  --lens-cat-1: #2B8F9C;  /* teal */
  --lens-cat-2: #A8862A;  /* ochre */
  --lens-cat-3: #5577C0;  /* cornflower */
  --lens-cat-4: #6F8A30;  /* olive */
  --lens-cat-5: #C2527F;  /* rose */
  --lens-cat-6: #8C7A6B;  /* taupe */

  /* Causes, on the categories */
  --lens-cause-bandwidth: var(--lens-cat-1);
  --lens-cause-signal: var(--lens-cat-2);
  --lens-cause-dns: var(--lens-cat-3);
  --lens-cause-loss: var(--lens-cat-5);

  /* Occupancy: a neutral intensity scale, 1 (low) to 5 (high); reversed in the dark theme */
  --lens-occupancy-1: var(--tz-n200);
  --lens-occupancy-2: var(--tz-n300);
  --lens-occupancy-3: var(--tz-n400);
  --lens-occupancy-4: var(--tz-n500);
  --lens-occupancy-5: var(--tz-n700);
  --lens-ramp-occupancy: linear-gradient(90deg, var(--lens-occupancy-1), var(--lens-occupancy-2),
      var(--lens-occupancy-3), var(--lens-occupancy-4), var(--lens-occupancy-5));

  /* Reviews: the ochre category, no violet */
  --lens-reviews: var(--lens-cat-2);
  --lens-reviews-fill: #F2EAD3;

  /* Charts: scripts read these through the chart classes or getComputedStyle, never as literals */
  --lens-chart-axis: var(--tz-n500);
  --lens-chart-grid: var(--tz-n150);
  --lens-chart-label: var(--lens-text-muted);
  --lens-chart-series-1: var(--lens-cat-1);
  --lens-chart-series-2: var(--lens-cat-2);
  --lens-chart-series-3: var(--lens-cat-3);
  --lens-chart-series-4: var(--lens-cat-4);
  --lens-chart-compare: var(--tz-n500);
  --lens-chart-threshold: var(--tz-n700);
  --lens-chart-threshold-band: var(--tz-threshold-band-light);
  --lens-chart-mark: var(--tz-n800);

  /* Maps */
  --lens-map-zone-outline: var(--tz-n700);
  --lens-map-selected: var(--tz-accent-blue);
  --lens-map-tiles-filter: grayscale(1) contrast(.9) brightness(1.05);
}

/* ------------------------------------------------------------------ 4. scales */
:root {
  /* type: Inter for everything, JetBrains Mono only for identifiers, BSSIDs, timestamps and units */
  --lens-font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --lens-font-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Consolas', monospace;
  --lens-fs-meta: 13px;
  /* The one size below 13 px: a shortcut's key cap inside a 14 px button (owner decision K2). */
  --lens-fs-key: 12px;
  --lens-fs-body: 14px;
  --lens-fs-object: 15px;
  --lens-fs-lead: 16px;
  --lens-fs-section: 19px;
  --lens-fs-figure-s: 24px;
  --lens-fs-title: 27px;
  --lens-fs-figure-m: 32px;
  --lens-fs-figure-l: 44px;
  --lens-fw-regular: 400;
  --lens-fw-medium: 500;
  --lens-fw-strong: 600;
  --lens-lh-tight: 1.25;
  --lens-lh-body: 1.5;

  /* space */
  --lens-sp-1: 4px;
  --lens-sp-2: 8px;
  --lens-sp-3: 12px;
  --lens-sp-4: 16px;
  --lens-sp-5: 24px;
  --lens-sp-6: 32px;
  --lens-sp-7: 48px;
  --lens-sp-8: 64px;

  /* radius: pill only for chips, tags and segmented options, never a container */
  --lens-r-s: 4px;
  --lens-r-m: 8px;
  --lens-r-l: 12px;
  --lens-r-pill: 999px;

  /* widths (S2), each page centred at its width. Breakpoints are written as literal px in @media,
     the only place a breakpoint appears: ≤ 640 (phone), ≤ 1024 (tablet), > 1024 */
  --lens-width-wide: 1600px;
  --lens-width-standard: 1280px;
  --lens-width-narrow: 880px;
  --lens-gutter: 24px;

  /* z-index */
  --lens-z-sticky: 100;
  --lens-z-dropdown: 1000;
  --lens-z-overlay: 1100;
  --lens-z-modal: 1200;
  --lens-z-toast: 1300;

  /* motion */
  --lens-ease: cubic-bezier(.2, 0, 0, 1);
  --lens-duration: 150ms;
}

@media (max-width: 640px) {
  :root { --lens-gutter: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  :root { --lens-duration: 0ms; }
}

/* ------------------------------------------------------------------ 5. dark theme
   The same declarations twice: the system's preference (unless the user chose light) and the
   user's choice. Keep them identical (VisualSystemContrastTest compares them). Screen only: print
   keeps the light values. */
@media screen and (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --lens-text: var(--tz-n100);
    --lens-text-muted: var(--tz-n300);
    --lens-heading: var(--tz-n50);
    --lens-text-inverse: var(--tz-n950);
    --lens-link: var(--tz-dk-link);
    --lens-link-hover: var(--tz-dk-link-hover);
    --lens-canvas: var(--tz-n950);
    --lens-surface: var(--tz-n900);
    --lens-surface-subtle: var(--tz-n850);
    --lens-surface-raised: var(--tz-n850);
    --lens-shell: var(--tz-primary-dark);
    --lens-shell-2: var(--tz-n900);
    --lens-shell-text: var(--tz-n50);
    --lens-shell-text-muted: var(--tz-n300);
    --lens-shell-active: var(--tz-dk-primary-hover);
    --lens-border: var(--tz-n800);
    --lens-divider: var(--tz-n850);
    --lens-border-strong: var(--tz-n500);
    --lens-focus: var(--tz-accent);
    --lens-primary: var(--tz-dk-primary);
    --lens-primary-hover: var(--tz-dk-primary-hover);
    --lens-selected: var(--tz-dk-selected);
    --lens-hover: var(--tz-n800);
    --lens-good: var(--tz-dk-good);
    --lens-good-ink: var(--tz-dk-good-ink);
    --lens-good-bg: var(--tz-dk-good-bg);
    --lens-watch: var(--tz-dk-watch);
    --lens-watch-ink: var(--tz-dk-watch-ink);
    --lens-watch-bg: var(--tz-dk-watch-bg);
    --lens-action: var(--tz-dk-action);
    --lens-action-ink: var(--tz-dk-action-ink);
    --lens-action-bg: var(--tz-dk-action-bg);
    --lens-neutral: var(--tz-n400);
    --lens-neutral-ink: var(--tz-n300);
    --lens-neutral-bg: var(--tz-n800);
    --lens-info: var(--tz-dk-info);
    --lens-info-ink: var(--tz-dk-info-ink);
    --lens-info-bg: var(--tz-dk-info-bg);
    --lens-shadow-overlay: var(--tz-shadow-overlay-dark);
    --lens-toast-bg: var(--tz-n50);
    --lens-toast-text: var(--tz-n900);
    --lens-toast-muted: var(--tz-n600);
    --lens-toast-good: var(--tz-success-mark);
    --lens-toast-watch: var(--tz-warning-mark);
    --lens-toast-action: var(--tz-error-mark);
    --lens-toast-info: var(--tz-info-fg);
    --lens-occupancy-1: var(--tz-n800);
    --lens-occupancy-2: var(--tz-n700);
    --lens-occupancy-3: var(--tz-n600);
    --lens-occupancy-4: var(--tz-n500);
    --lens-occupancy-5: var(--tz-n300);
    --lens-reviews-fill: var(--tz-dk-reviews-fill);
    --lens-chart-axis: var(--tz-n500);
    --lens-chart-grid: var(--tz-n800);
    --lens-chart-compare: var(--tz-n400);
    --lens-chart-threshold: var(--tz-n300);
    --lens-chart-threshold-band: var(--tz-threshold-band-dark);
    --lens-chart-mark: var(--tz-n100);
    --lens-map-zone-outline: var(--tz-n300);
    --lens-map-selected: var(--tz-accent);
    --lens-map-tiles-filter: grayscale(1) invert(1) brightness(.85) contrast(.85);
  }
}

@media screen {
  :root[data-theme="dark"] {
    color-scheme: dark;
    --lens-text: var(--tz-n100);
    --lens-text-muted: var(--tz-n300);
    --lens-heading: var(--tz-n50);
    --lens-text-inverse: var(--tz-n950);
    --lens-link: var(--tz-dk-link);
    --lens-link-hover: var(--tz-dk-link-hover);
    --lens-canvas: var(--tz-n950);
    --lens-surface: var(--tz-n900);
    --lens-surface-subtle: var(--tz-n850);
    --lens-surface-raised: var(--tz-n850);
    --lens-shell: var(--tz-primary-dark);
    --lens-shell-2: var(--tz-n900);
    --lens-shell-text: var(--tz-n50);
    --lens-shell-text-muted: var(--tz-n300);
    --lens-shell-active: var(--tz-dk-primary-hover);
    --lens-border: var(--tz-n800);
    --lens-divider: var(--tz-n850);
    --lens-border-strong: var(--tz-n500);
    --lens-focus: var(--tz-accent);
    --lens-primary: var(--tz-dk-primary);
    --lens-primary-hover: var(--tz-dk-primary-hover);
    --lens-selected: var(--tz-dk-selected);
    --lens-hover: var(--tz-n800);
    --lens-good: var(--tz-dk-good);
    --lens-good-ink: var(--tz-dk-good-ink);
    --lens-good-bg: var(--tz-dk-good-bg);
    --lens-watch: var(--tz-dk-watch);
    --lens-watch-ink: var(--tz-dk-watch-ink);
    --lens-watch-bg: var(--tz-dk-watch-bg);
    --lens-action: var(--tz-dk-action);
    --lens-action-ink: var(--tz-dk-action-ink);
    --lens-action-bg: var(--tz-dk-action-bg);
    --lens-neutral: var(--tz-n400);
    --lens-neutral-ink: var(--tz-n300);
    --lens-neutral-bg: var(--tz-n800);
    --lens-info: var(--tz-dk-info);
    --lens-info-ink: var(--tz-dk-info-ink);
    --lens-info-bg: var(--tz-dk-info-bg);
    --lens-shadow-overlay: var(--tz-shadow-overlay-dark);
    --lens-toast-bg: var(--tz-n50);
    --lens-toast-text: var(--tz-n900);
    --lens-toast-muted: var(--tz-n600);
    --lens-toast-good: var(--tz-success-mark);
    --lens-toast-watch: var(--tz-warning-mark);
    --lens-toast-action: var(--tz-error-mark);
    --lens-toast-info: var(--tz-info-fg);
    --lens-occupancy-1: var(--tz-n800);
    --lens-occupancy-2: var(--tz-n700);
    --lens-occupancy-3: var(--tz-n600);
    --lens-occupancy-4: var(--tz-n500);
    --lens-occupancy-5: var(--tz-n300);
    --lens-reviews-fill: var(--tz-dk-reviews-fill);
    --lens-chart-axis: var(--tz-n500);
    --lens-chart-grid: var(--tz-n800);
    --lens-chart-compare: var(--tz-n400);
    --lens-chart-threshold: var(--tz-n300);
    --lens-chart-threshold-band: var(--tz-threshold-band-dark);
    --lens-chart-mark: var(--tz-n100);
    --lens-map-zone-outline: var(--tz-n300);
    --lens-map-selected: var(--tz-accent);
    --lens-map-tiles-filter: grayscale(1) invert(1) brightness(.85) contrast(.85);
  }
}
