/* =============================================================================
   CacheGenie NOC - design tokens
   The first stylesheet loaded, before noc.css (and before docs_body.css, which the
   TinyMCE editor loads with this file and nothing else). Nothing here but
   custom properties, so a theme is a re-mapping of values and never a rule change.

   The rule the whole panel is built on: COLOUR IS RESERVED FOR STATE. A page where
   nothing is wrong is ink, muted ink and hairlines. --noc-accent (teal) means one of
   three things and nothing else - focus, hover, current item. --noc-indigo annotates.
   Everything else that carries colour is saying a thing is up, degraded, down, paused
   or busy, through the --st-* set below.

   Depth is hairlines and two tones, never a shadow and never a gradient. Where a card
   has to read as raised, its body sits on --noc-surface-2 and its action foot on
   --noc-surface above a hairline.

   THEMES. Light is the default and the only thing a document gets without asking.
   Dark applies under :root[data-theme="dark"] and nowhere else.

   There is deliberately NO @media (prefers-color-scheme: dark) block here, guarded or
   otherwise. A media query cannot be scoped to one document, and two other documents
   load this file: the TinyMCE editor iframe (admin/docs.php content_css) and the
   standalone article preview page (admin/docs.php), each with its own <html> carrying
   no data-theme. A media query would turn both dark while the page around them stayed
   light. An attribute cannot leak that way, so the OS preference is resolved once, in
   the small synchronous script index.php puts at the top of the NOC's <head>, which
   writes the attribute before the first frame. index.php pins every public host to
   "light" server side, so a shared link never opens dark unasked.
   ============================================================================= */

:root {
    color-scheme: light;

    /* --- Brand constants: the same value in both themes ------------------- */
    --cg-navy: #1a1c34;
    --cg-indigo: #464b9f;
    --cg-teal: #2dbdba;

    /* --- Surfaces --------------------------------------------------------- */
    --noc-page: #1a1c34;          /* the field the sheet floats on */
    --noc-chrome: #1a1c34;        /* top bar and phone tab bar */
    --noc-chrome-line: rgba(255, 255, 255, 0.10);
    --noc-chrome-ink: #cfd2e6;          /* an idle link on the chrome */
    --noc-chrome-ink-strong: #ffffff;   /* the current one, and white on any dark fill */
    --noc-surface: #ffffff;       /* the sheet, and every box on it */
    --noc-surface-2: #f6f7fa;     /* inset ground: the two-tone card body, read-only fields */
    --noc-surface-3: #eef0f7;     /* tint: chips, inline code, a highlight */
    --noc-inverse: #1a1c34;       /* a panel that inverts: code blocks, the PIN, the node log */
    --noc-inverse-ink: #e6e7f0;
    --noc-inverse-line: rgba(255, 255, 255, 0.16);
    --noc-inverse-wash: rgba(255, 255, 255, 0.08);
    --noc-inverse-wash-2: rgba(255, 255, 255, 0.16);
    --noc-inverse-line-2: rgba(255, 255, 255, 0.50);

    /* --- Ink -------------------------------------------------------------- */
    --noc-ink: #1a1c34;           /* headings, names, figures. The brand navy, not a neutral black */
    --noc-ink-2: #40456a;         /* body copy and values */
    --noc-ink-muted: #6b7090;     /* sub-lines, labels, helper text */
    --noc-ink-faint: #9a9dbb;     /* placeholder, disabled, a value that is not there */

    /* --- Lines ------------------------------------------------------------ */
    --noc-line: #dcdfec;          /* every hairline between rows and around boxes */
    --noc-line-2: #cbcfe0;        /* a border that has to read as an edge: inputs, controls */

    /* --- Action ----------------------------------------------------------- */
    --noc-chrome-raised: #262a4d;
    --noc-btn-bg: #1a1c34;
    --noc-btn-bg-hover: #262a4d;
    --noc-btn-ink: #ffffff;
    /* A control that is on: a switch's track and a ticked box. On the light sheet it is the primary colour (16.67:1).
       In the dark theme the primary button's indigo measured 2.42:1 against the sheet, under the 3:1 a control's
       state needs, so there it is a lifted indigo: 3.46:1 on the sheet, 3.10:1 on the inset tone, and the white knob
       on it 4.82:1. The primary buttons keep theirs, which carry white words rather than a state. */
    --noc-control-on: var(--noc-btn-bg);
    --noc-accent: #2dbdba;        /* focus, hover, current. Never decoration */
    --noc-accent-ring: rgba(45, 189, 186, 0.22);
    /* The accent as text on a light surface. #1d8583 was written here as "4.5:1" and measured 4.435:1 against
       white, which nothing caught because no rule used the token until the certificate link's hover did on
       20 September 2026. Measured in the browser, not calculated: 5.06:1 on the white sheet and 4.60:1 on
       --noc-surface-2, so it passes AA on either. */
    --noc-accent-ink: #1a7b79;
    --noc-indigo: #464b9f;        /* the annotation rule, and "maintenance" */
    --noc-indigo-ink: #464b9f;

    /* Legacy names, kept as aliases so a rule that still spells a colour rather than
       its job keeps working and still follows the theme. Prefer the semantic name. */
    --noc-navy: var(--noc-chrome);
    --noc-navy-raised: var(--noc-chrome-raised);
    --noc-teal: var(--noc-accent);

    /* --- Overlay ---------------------------------------------------------- */
    --noc-scrim: rgba(26, 28, 52, 0.45);

    /* --- Service state ----------------------------------------------------
       The first five are spoken by the public status page and GET /v1/status, so
       their light values are fixed. The last four promote colours that were bare
       hexes repeated fifteen times across the two stylesheets. */
    --st-up: #21ce61;
    --st-degraded: #f3c600;
    --st-down: #d63a3a;
    --st-maint: #464b9f;
    --st-pending: #9a9dbb;
    /* A place we mean to serve from and have not built yet. Deliberately the quietest state there
       is: it is not a fault, not work in progress and not something a reader should act on. */
    --st-planned: #a6a9c0;
    --st-ok: #26704a;             /* a run finished, a GET, a thing that is fine.
                                     Darker than it looks it needs to be: the chip puts it
                                     on its own tint, which lifts the ground under it. */
    --st-error: #c8473d;          /* a run failed, a node offline, a DELETE */
    --st-warn: #8f5500;           /* attention, not failure: updates waiting, out of service.
                                     Dark enough to stay legible on its own tint. */
    --st-info: #b8860b;           /* PUT / PATCH, and a neutral notice */
    /* The ink a saturated state fill needs. These do NOT flip with the theme: a red
       pill is red in both, so white stays readable on it and the yellow one still
       needs dark text. */
    --st-ink-on-fill: #ffffff;
    --st-ink-on-warm: #1a1c34;
    /* Tints of the above, for a chip fill or a dot halo */
    --st-ok-soft: rgba(38, 112, 74, 0.12);
    --st-up-soft: rgba(33, 206, 97, 0.18);
    --st-degraded-soft: rgba(243, 198, 0, 0.22);
    --st-down-soft: rgba(214, 58, 58, 0.20);
    --st-maint-soft: rgba(70, 75, 159, 0.14);
    --st-pending-soft: rgba(154, 157, 187, 0.20);
    --st-planned-soft: rgba(166, 169, 192, 0.18);
    --st-error-soft: rgba(200, 71, 61, 0.12);
    --st-warn-soft: rgba(143, 85, 0, 0.12);
    --st-warn-bg: #f2ebe0;        /* the soft tint laid on the white surface, opaque: for a band that sits on
                                     the navy page rather than on the sheet (the overdue banner), where the
                                     translucent tint went navy underneath and the amber text measured 2.75:1 */
    --noc-indigo-bg: #e5e6f2;     /* the indigo at 14% laid on white, opaque for the same reason: the band that
                                     says staff are viewing a customer's account sits on the navy page too */

    /* --- Geometry --------------------------------------------------------- */
    --noc-top-height: 64px;
    --noc-tab-height: 60px;
    --noc-gutter: 24px;
    --noc-max: 1200px;
    --noc-radius: 6px;            /* boxes, buttons, inputs, modals */
    --noc-radius-sm: 4px;         /* pills, chips, tags, code */
    --noc-gap: 16px;              /* between boxes */
    --noc-pad-box: 18px;          /* inside a box, and a list row's side padding */
    /* The spacing ladder. Nothing outside it. */
    --sp-1: 4px;
    --sp-2: 8px;
    --sp-3: 12px;
    --sp-4: 16px;
    --sp-5: 18px;
    --sp-6: 24px;

    /* --- Type -------------------------------------------------------------
       Eight steps replacing nineteen ad-hoc sizes. Written as `font:` shorthands on
       purpose: one declaration sets family, size, weight and leading AND resets them
       together, so an inherited bold cannot leak into a child, and the seventy-six
       `font-weight: bold` keywords the panel used to carry are deleted rather than
       restated. Maven Pro ships 400-900; there is NO 300 face, and asking for one
       makes the browser synthesise a thin. */
    --t-figure:  900 32px/1.05 'Maven Pro', sans-serif;   /* the one stat per tile */
    --t-display: 900 30px/1.15 'Maven Pro', sans-serif;   /* the status page hero */
    --t-h1:      700 24px/1.2  'Maven Pro', sans-serif;   /* page title */
    --t-h2:      700 17px/1.3  'Maven Pro', sans-serif;   /* section heading */
    --t-h3:      700 15px/1.45 'Maven Pro', sans-serif;   /* box title */
    --t-strong:  700 15px/1.45 'Maven Pro', sans-serif;   /* a name in a list */
    --t-body:    400 15px/1.5  'Maven Pro', sans-serif;
    --t-sub:     400 13px/1.5  'Maven Pro', sans-serif;   /* sub-lines and help text */
    --t-micro:   500 12px/1.4  'Maven Pro', sans-serif;   /* labels, pills, stacked-row labels */
    --t-mono:    400 13px/1.55 var(--doc-mono);
    --measure-help: 62ch;   /* help text stops before it becomes a wall */

    /* --- Documentation reading palette ------------------------------------
       Deliberately its own small set: the docs body is prose, not chrome. */
    --doc-body: 16px;
    --doc-measure: 74ch;
    --doc-code-bg: var(--noc-inverse);
    --doc-code-ink: var(--noc-inverse-ink);
    --doc-inline-bg: var(--noc-surface-3);
    --doc-mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;

    /* --- Charts -----------------------------------------------------------
       noc_charts.js reads these off :root rather than carrying its own hexes, so a
       chart follows the theme. The series palette is ordered for distinguishability,
       not by brand rank. */
    --chart-grid: #eceef6;
    --chart-tick: var(--noc-ink-muted);
    --chart-tooltip-bg: #ffffff;
    --chart-tooltip-ink: var(--noc-ink);
    --chart-tooltip-line: var(--noc-line-2);
    --chart-1: #1a1c34;
    --chart-2: #2dbdba;
    --chart-3: #6a52c8;
    --chart-4: #d9a441;
    --chart-5: #c8473d;
    --chart-6: #3f7fb8;
    --chart-7: #4f9d6b;
    --chart-8: #8a8da3;
}

/* -----------------------------------------------------------------------------
   Dark. The sheet becomes the brand navy and the field goes deeper beneath it, so
   content still floats rather than merging into the page. The primary button moves
   to a lifted indigo rather than the teal, or a focused primary button would be a
   teal ring on a teal fill.
   The two selectors carry one list: the media query for "no choice made", the
   attribute for "chose dark".
   -------------------------------------------------------------------------- */

:root[data-theme="dark"] {
    color-scheme: dark;

    --noc-page: #0e1020;
    --noc-chrome: #14162a;
    --noc-chrome-line: rgba(255, 255, 255, 0.09);
    --noc-chrome-ink: #b9bdd6;
    --noc-chrome-ink-strong: #ffffff;
    --noc-surface: #1a1c34;
    --noc-surface-2: #22253f;
    --noc-surface-3: #2a2e4d;
    --noc-inverse: #0b0d18;
    --noc-inverse-ink: #e6e7f0;
    --noc-inverse-line: rgba(255, 255, 255, 0.14);
    --noc-inverse-wash: rgba(255, 255, 255, 0.07);
    --noc-inverse-wash-2: rgba(255, 255, 255, 0.14);
    --noc-inverse-line-2: rgba(255, 255, 255, 0.45);

    --noc-ink: #f0f1f7;
    --noc-ink-2: #c3c6dc;
    --noc-ink-muted: #9095b5;
    --noc-ink-faint: #8288a8;

    --noc-line: #33375a;
    --noc-line-2: #474c78;

    --noc-chrome-raised: #22263f;
    --noc-btn-bg: #4a50ad;
    --noc-btn-bg-hover: #5a60c4;
    --noc-btn-ink: #ffffff;
    --noc-control-on: #6168cc;
    --noc-accent: #3ad4d0;
    --noc-accent-ring: rgba(58, 212, 208, 0.26);
    --noc-accent-ink: #3ad4d0;
    --noc-indigo: #7f86e8;
    --noc-indigo-ink: #9aa0f0;

    --noc-scrim: rgba(5, 7, 16, 0.62);

    --st-up: #34d97a;
    --st-degraded: #f5cf2e;
    --st-down: #d63a3a;   /* a fill under white text, so it is not lifted for dark */
    --st-maint: #5a61c4;  /* likewise a fill; --noc-indigo-ink is the text form */
    --st-pending: #8c90b0;
    --st-planned: #7e82a2;
    --st-ok: #4cc98a;
    --st-error: #e8675c;
    --st-warn: #e0a33a;
    --st-info: #d9b44a;
    --st-ok-soft: rgba(76, 201, 138, 0.16);
    --st-up-soft: rgba(52, 217, 122, 0.20);
    --st-degraded-soft: rgba(245, 207, 46, 0.22);
    --st-down-soft: rgba(214, 58, 58, 0.30);
    --st-maint-soft: rgba(127, 134, 232, 0.22);
    --st-pending-soft: rgba(140, 144, 176, 0.22);
    --st-planned-soft: rgba(126, 130, 162, 0.22);
    --st-error-soft: rgba(232, 103, 92, 0.18);
    --st-warn-soft: rgba(224, 163, 58, 0.18);
    --st-warn-bg: #3b3536;
    --noc-indigo-bg: #30335c;

    --chart-grid: #2c3054;
    --chart-tooltip-bg: #22253f;
    --chart-tooltip-line: #474c78;
    --chart-1: #8f96f0;
    --chart-2: #3ad4d0;
    --chart-3: #b39af5;
    --chart-4: #e8b55c;
    --chart-5: #f4776f;
    --chart-6: #6fb3e8;
    --chart-7: #6ed19a;
    --chart-8: #a7abc4;
}

/* Responsive geometry. The gutter is the only token a breakpoint changes. */
@media (max-width: 1200px) { :root { --noc-gutter: 16px; } }
@media (max-width: 640px)  { :root { --noc-gutter: 12px; --noc-top-height: 56px; } }
