/* ============================================================================
 * theme/hellenic.css — Hellenic re-skin for the FiniteManager console.
 *
 * ADDITIVE LAYER. Load AFTER styles.css. It re-binds colour tokens, adds a
 * display type scale, and paints ornament on the CHROME only. If this file
 * fails to load, the console renders exactly as it does today — every rule
 * here is a token override or a decorative addition.
 *
 * ---------------------------------------------------------------------------
 * 🔴 THE RULE THAT OUTRANKS THE THEME
 * This is the operational console for 5 VPS + 3 Windows PCs with root-capable
 * actions. Legibility and status clarity beat decoration, always:
 *   • No ornament inside dense data regions — enforced in §7, not requested.
 *   • No decorative lettering on data, numbers, logs or code — enforced in §5.
 *   • No Greek letterform is ever substituted for a Latin one. Not anywhere.
 *     It breaks screen readers, search and copy-paste, and it is illegible at
 *     3am. All text in this theme is Latin text in a Latin face.
 *   • Status is never carried by hue alone (§6). Shape/text carriers are ADDED,
 *     and they deliberately survive the ornament kill-switch.
 *   • 🔴 NOT ONE STATUS HEX CHANGED in the 2026-07-27 ornament pass. --ok,
 *     --warn, --danger, --info and every --hel-*-text token still hold the
 *     exact values whose WCAG and CIEDE2000 dichromatic separation are recorded
 *     in §6. The palette section below only gives those same values NAMES.
 *   • This file introduces no animation whatsoever.
 *
 * 🔴 CSP / NETWORK: zero external references. No @font-face, no url(), no
 * data: URI, no @import, no image of any kind. Every ornament is drawn with CSS
 * gradients and clip-path. Nothing in this file can issue a request.
 *
 * 🔴 ASSETS: all geometry here is hand-authored for this console from
 * public-domain architectural and ceramic motifs (meander, fluting,
 * egg-and-dart, bead-and-reel, laurel, amphora profile). Nothing is traced
 * from or copied out of a photograph, a museum object, an icon font, or any
 * third-party SVG.
 *
 * ---------------------------------------------------------------------------
 * 2026-07-27 — WHY THIS FILE GOT LOUDER.
 * The previous revision was measured in a real browser and the verdict was
 * fair: the whole visible delta was a 10px frieze at ~34% effective alpha, a
 * 14px laurel at 50%, 3px of fluting and one 18px portrait. On a 1280x720
 * screen that reads as a restrained accent, not a theme. This pass keeps every
 * safety rule and every status measurement and raises the ORNAMENT — scale,
 * contrast and placement — until the motif is the first thing you see:
 *
 *   topbar   monumental meander watermark across the full 54px bar  + a crisp
 *            10px meander frieze at the foot + a 2px bronze rule
 *   sidebar  a 10px vertical meander down the left rail + full-height Doric
 *            fluting + a bronze edge + gold group labels + a gold active bar
 *   panels   an inlaid meander band across the top of EVERY .fm-card
 *   heads    a 20px laurel spray under every page title, + incised display type
 *   rules    bead-and-reel dividers, egg-and-dart section rules
 *   empty    a 150x210 amphora watermark (previously invisible — see §4)
 *
 * ---------------------------------------------------------------------------
 * KILL-SWITCH (§8) — instant, no deploy. All four spellings are honoured:
 *     FMTheme.setOrnament('none')                        ← boot.js, canonical
 *     document.documentElement.dataset.ornament = 'off';
 *     document.documentElement.classList.add('hel-no-ornament');
 *     <html data-fm-hellenic="none">
 * The switch now works by driving every ornament PIGMENT to `transparent` as
 * well as setting --hel-orn:none, so an ornament added later is killed by the
 * same switch without anyone remembering to list it. Status carriers stay.
 *
 * ---------------------------------------------------------------------------
 * THEME MECHANISM — read before "following" it.
 * styles.css has NO light/dark mechanism: one dark cockpit theme on :root, and
 * index.html pins <meta name="color-scheme" content="dark">. There was nothing
 * to follow and nothing to fork, so this file keeps that exact shape — dark
 * stays the default on :root — and adds the single standard opt-in hook, one
 * attribute on <html>:
 *     (no attribute)             → night  "wine-dark sea"   [default]
 *     <html data-theme="night">  → night  (explicit pin)
 *     <html data-theme="marble"> → marble "day"
 *     <html data-theme="auto">   → follows prefers-color-scheme
 * No JS and no parallel token set: marble re-binds the SAME variables that
 * styles.css already defines.
 * ==========================================================================*/


/* ============================================================================
 * §1  PALETTE — named pigments, then everything derived FROM them.
 *
 * 🔴 These are the names the brief asked for, and they are not decoration:
 * --bg, --panel, --fg, --accent, --ok, --warn, --danger and --info are now
 * literally `var(--aegean-deep)`, `var(--marble)`, `var(--aegean)`,
 * `var(--laurel)`, `var(--ochre)` … so the pigment IS the console.
 *
 *  --attic-black  #17110d  the fired, iron-rich glaze on Attic pottery:
 *                          near-black, warm — never blue-black.
 *  --terracotta   #c9773c  the reserved (unglazed) body of a red-figure vase.
 *                          The figures ARE this colour.
 *  --ochre        #e1b03d  the lighter iron-oxide range. Doubles as --warn.
 *  --aegean-deep  #0c1220  Homer's wine-dark sea: indigo weighted to black.
 *  --aegean       #6fb4e6 (night) / #1d4f8f (day)  the lit water.
 *  --marble       #f0e9dc  Pentelic stone: warm bone, NOT white. It weathers
 *                          to a honey cast — hence the warm greys throughout.
 *  --laurel       #55d3a1 (night) / #2c6d49 (day)  the victory wreath, and the
 *                          console's PASS colour. Value unchanged from the
 *                          revision whose contrast + CVD figures are in §6.
 *  --laurel-leaf  #86bb6d  the decorative leaf green. Ornament only — it is
 *                          deliberately a different hue from --laurel so a
 *                          drawn leaf can never be mistaken for a PASS state.
 *  --bronze       #b8862f  fittings. --gold #d9a441 gilding.
 *  --sinopia      #dc6a62  burnt red earth. The console's FAIL colour.
 * ==========================================================================*/

/* ---------------------------------------------------------------- night ---- */
/* Default theme — same slot as the existing cockpit dark, re-tinted. */
:root,
:root[data-theme="night"] {
  /* ---- the named pigments ---- */
  --attic-black: #17110d;
  --marble:      #f0e9dc;
  --terracotta:  #c9773c;
  --ochre:       #e1b03d;
  --bronze:      #b8862f;
  --gold:        #d9a441;
  --aegean:      #6fb4e6;
  --aegean-deep: #0c1220;
  --laurel:      #55d3a1;
  --laurel-leaf: #86bb6d;
  --sinopia:     #dc6a62;

  /* ---- surfaces: wine-dark sea over black slip ---- */
  --bg:            var(--aegean-deep);
  --bg-elev:       #121a2a;
  --panel:         #151d2e;
  --panel-2:       #1b2437;
  --panel-3:       #232e45;
  --line:          #2b374f;
  --line-soft:     #202a3e;

  /* ---- text: marble on the sea ---- */
  --fg:            var(--marble);
  --fg-dim:        #b7ad9c;
  --fg-faint:      #9d9482;   /* raised twice. The cockpit original #6b7c91
                                 measured 4.05 on --panel; the first Hellenic
                                 value #968d7b fixed that but still measured
                                 4.13 on --panel-3 and failed AA there. This
                                 clears 4.5 on ALL five surfaces (min 4.52). */
  --fg-invert:     var(--attic-black);

  /* ---- accents ---- */
  --accent:        var(--aegean);
  --accent-2:      var(--gold);
  --accent-soft:   rgba(111,180,230,0.15);

  /* ---- status — measurements in §6. Values are UNCHANGED; they are simply
         expressed through the pigment names now. ---- */
  --ok:            var(--laurel);
  --ok-soft:       rgba(85,211,161,0.15);
  --warn:          var(--ochre);
  --warn-soft:     rgba(225,176,61,0.15);
  --danger:        var(--sinopia);
  --danger-soft:   rgba(220,106,98,0.17);
  --info:          var(--aegean);

  --shadow:        0 8px 30px rgba(0,0,0,0.55);
  --shadow-sm:     0 2px 10px rgba(0,0,0,0.40);

  /* ---- theme-private tokens. styles.css never references these. ---- */
  --hel-ink:        var(--attic-black);   /* Attic slip, used as ink ON gold */
  --hel-clay:       var(--terracotta);
  --hel-bronze:     var(--bronze);
  --hel-gold:       var(--gold);

  /* PLATE pigments — the fill-role counterpart of --hel-label. --hel-label
     exists because gilt TEXT has to be dark enough to read ON marble;
     --hel-plate-* exists for the opposite reason: a gilt PLATE carrying dark
     ink has to stay light enough for that ink to read. In night the two roles
     happen to coincide with --gold/--terracotta, so these are aliases. */
  --hel-plate-gold: var(--gold);
  --hel-plate-clay: var(--terracotta);

  /* ---- ornament pigments. §8 drives every one of these to `transparent`,
         which is what makes the kill-switch total and future-proof. ---- */
  --hel-u:          2px;                     /* the meander unit grid */
  --fm-meander:     rgba(217,164,65,0.62);   /* THE meander stroke */
  --hel-key:        var(--fm-meander);
  --hel-key-strong: rgba(217,164,65,0.88);   /* topbar foot, login card */
  --hel-key-ghost:  rgba(217,164,65,0.085);  /* monumental watermark */
  --hel-flute:      rgba(240,233,220,0.075); /* the lit arris of a flute */
  --hel-flute-soft: rgba(0,0,0,0.13);        /* the hollow of a flute */
  --hel-flute-dark: rgba(0,0,0,0.34);        /* the shadowed arris */
  --hel-rule:       rgba(217,164,65,0.56);   /* bead-and-reel, egg-and-dart */
  --hel-laurel:     var(--laurel-leaf);      /* drawn leaves — never a status */
  --hel-mark:       rgba(240,233,220,0.14);  /* amphora watermark */
  --hel-incise-lo:  rgba(0,0,0,0.55);        /* incised lettering: cut edge */
  --hel-incise-hi:  rgba(240,233,220,0.10);  /* incised lettering: lit edge */
  /* Gilt CHROME TEXT (nav group labels, the active-item jamb). This is text, so
     it is a separate token from --hel-gold, which is a fill: it must clear 4.5:1
     against every band of the fluting behind it, not just the flat ground.
     Night worst case (over the lit arris) measures 6.44. */
  --hel-label:      var(--gold);

  /* consumed by theme/icons.js (the portrait marks) */
  --gk-clay:  #cf854a;
  --gk-glaze: #17110d;
  --gk-ring:  var(--bronze);

  /* status TEXT tints — these are what actually renders as words, and they are
     the tokens that must clear 4.5:1. See §6. UNCHANGED. */
  --hel-ok-text:     #92e2bf;
  --hel-warn-text:   #f0cf85;
  --hel-danger-text: #f2a7a1;
  --hel-info-text:   #a9d5f2;
}

/* --------------------------------------------------------------- marble ---- */
:root[data-theme="marble"] {
  color-scheme: light;

  --attic-black: #1c1712;
  --marble:      #fbf7ef;
  --terracotta:  #b8652c;
  --ochre:       #8e620b;
  --bronze:      #7a5a1c;
  --gold:        #9a7420;
  --aegean:      #1d4f8f;
  --aegean-deep: #f3ece0;   /* day: the sea reads as lit stone, not indigo */
  --laurel:      #2c6d49;
  --laurel-leaf: #4a6b3a;
  --sinopia:     #862213;

  --bg:            var(--aegean-deep);
  --bg-elev:       #ece3d3;
  --panel:         var(--marble);
  --panel-2:       #f2ebdd;
  --panel-3:       #e7dcc8;
  --line:          #cdbda2;
  --line-soft:     #e0d4bd;

  --fg:            var(--attic-black);
  --fg-dim:        #4a4136;
  --fg-faint:      #6a5f4f;
  --fg-invert:     var(--marble);

  --accent:        var(--aegean);
  --accent-2:      var(--bronze);
  --accent-soft:   rgba(29,79,143,0.12);

  --ok:            var(--laurel);
  --ok-soft:       rgba(44,109,73,0.14);
  --warn:          var(--ochre);
  --warn-soft:     rgba(142,98,11,0.15);
  --danger:        var(--sinopia);
  --danger-soft:   rgba(134,34,19,0.13);
  --info:          var(--aegean);

  --shadow:        0 8px 26px rgba(60,44,22,0.18);
  --shadow-sm:     0 2px 8px rgba(60,44,22,0.12);

  --hel-ink:        var(--attic-black);
  --hel-clay:       var(--terracotta);
  --hel-bronze:     var(--bronze);
  --hel-gold:       var(--gold);

  /* 🔴 NOT var(--gold)/var(--terracotta), and it is the SAME defect --hel-label
     documents, running the other way. Marble darkens every gilt pigment
     (--gold #d9a441 -> #9a7420, --terracotta #c9773c -> #b8652c) because in
     this theme they are mostly used as INK on a light ground. .fm-brand
     .fm-logo uses them as a PLATE with --hel-ink #1c1712 on top, and a darkened
     plate under dark ink is a contrast failure, not a refinement.
     Rasterised in the browser — every one of the 676 pixels of the 26x26 chip,
     not the two stops — the darkened plate measured:
                                   marble       night
       worst pixel of gradient ..  4.09  FAIL   5.56  pass
       best pixel ...............  4.21         8.25
     The worst point is INTERIOR to the gradient (rgb(162,111,35), roughly a
     third along), which is why reading the two endpoints alone understates it.
     Keeping the fill-role values in both themes puts marble's worst at 5.24 and
     leaves night bit-identical. The logo is on every page, so this is the one
     figure in the theme that every screen depends on. */
  --hel-plate-gold: #d9a441;
  --hel-plate-clay: #c9773c;

  --fm-meander:     rgba(122,90,28,0.62);
  --hel-key:        var(--fm-meander);
  --hel-key-strong: rgba(122,90,28,0.85);
  --hel-key-ghost:  rgba(122,90,28,0.10);
  --hel-flute:      rgba(255,255,255,0.72);
  --hel-flute-soft: rgba(122,90,28,0.055);
  --hel-flute-dark: rgba(122,90,28,0.18);
  --hel-rule:       rgba(122,90,28,0.55);
  --hel-laurel:     var(--laurel-leaf);
  --hel-mark:       rgba(28,23,18,0.13);
  --hel-incise-lo:  rgba(255,255,255,0.85);
  --hel-incise-hi:  rgba(90,66,20,0.28);
  /* 🔴 NOT var(--gold). Marble's gilding #9a7420 is a mid-tone: measured on the
     fluted sidebar it gives 3.37 flat, 3.14 in the flute hollow and 2.66 over
     the shadowed arris — a real AA failure on real chrome text. Gilt letters on
     marble have to be darker; that is also what they look like in life.

     2026-07-27 — burnt one step further, #6b4d13 -> #5f4310, and the reason is
     a NEW consumer rather than a mistake in the old figure. --fm-hell-ink now
     defers to this token (theme/hellenic.js), so .fm-hell-name renders in it —
     and unlike .fm-nav-group-label, that chip sits INSIDE .fm-nav-item, whose
     .active state paints a translucent accent-soft plate OVER the fluting. That
     stacks a fourth composite the group label never sees. Measured in the
     browser on the real sidebar, every row state x every band of the fluting:
                                 #6b4d13   #5f4310
       normal row / lit arris ..   7.29      8.56
       normal row / flat ......    6.12      7.18
       normal row / hollow ....    5.70      6.70
       normal row / dark arris .   4.83      5.67
       ACTIVE row / lit arris ..   6.97      8.18
       ACTIVE row / flat ......    5.11      6.00
       ACTIVE row / hollow ....    4.79      5.62
       ACTIVE row / dark arris .   4.11      4.83   <- the one that failed
     The old value put the active row's chip at 4.11:1 at 11.5px/600 — below AA
     — on whichever page the operator is actually standing on, which is the one
     row they look at most. 4.83 is the worst figure in the marble theme now.
     Night is untouched: there --hel-label is --gold #d9a441 and its worst is
     4.78, on the active row over the lit arris. */
  --hel-label:      #5f4310;

  --gk-clay:  #b8652c;
  --gk-glaze: #241a12;
  --gk-ring:  var(--bronze);

  --hel-ok-text:     #235838;
  --hel-warn-text:   #74500a;
  --hel-danger-text: #7a1e11;
  --hel-info-text:   #17406f;

  /* SYNTAX RAMP — the marble counterpart of the eight --tk-* tokens declared
     in styles.css. The night values are pastels chosen against a #151d2e
     panel; on the marble panel (--panel #fbf7ef) they collapse: measured
     before this block, .tk-fn #e6d074 rendered at 1.44:1 and .tk-kw #7fb2ff at
     2.02:1 — the firmware source was legible in night and effectively blank in
     marble. Each value below keeps its night HUE (within 1-3 degrees, so the
     highlighter still reads as the same theme; only .tk-ty is pulled 21 deg
     toward cyan to hold it apart from .tk-cmt's green once both are darkened)
     and is darkened until it clears AA on --panel:
       cmt 5.94  str 6.24  pre 7.54  kw 7.39
       ty  6.86  num 6.33  fn  6.82  hal 6.82   (worst 5.94) */
  --tk-cmt:  #41693b;
  --tk-str:  #7d5410;
  --tk-pre:  #6d3a87;
  --tk-kw:   #1b4f9e;
  --tk-ty:   #0d5f6b;
  --tk-num:  #8c4a15;
  --tk-fn:   #6a5405;
  --tk-hal:  #9c2f3b;
}

/* Only "auto" follows the OS. The explicit pins above win by specificity. */
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] {
    color-scheme: light;
    --attic-black:#1c1712; --marble:#fbf7ef; --terracotta:#b8652c; --ochre:#8e620b;
    --bronze:#7a5a1c; --gold:#9a7420; --aegean:#1d4f8f; --aegean-deep:#f3ece0;
    --laurel:#2c6d49; --laurel-leaf:#4a6b3a; --sinopia:#862213;
    --bg:var(--aegean-deep); --bg-elev:#ece3d3; --panel:var(--marble);
    --panel-2:#f2ebdd; --panel-3:#e7dcc8; --line:#cdbda2; --line-soft:#e0d4bd;
    --fg:var(--attic-black); --fg-dim:#4a4136; --fg-faint:#6a5f4f; --fg-invert:var(--marble);
    --accent:var(--aegean); --accent-2:var(--bronze); --accent-soft:rgba(29,79,143,0.12);
    --ok:var(--laurel); --ok-soft:rgba(44,109,73,0.14);
    --warn:var(--ochre); --warn-soft:rgba(142,98,11,0.15);
    --danger:var(--sinopia); --danger-soft:rgba(134,34,19,0.13);
    --info:var(--aegean);
    --shadow:0 8px 26px rgba(60,44,22,0.18); --shadow-sm:0 2px 8px rgba(60,44,22,0.12);
    --hel-ink:var(--attic-black); --hel-clay:var(--terracotta);
    --hel-bronze:var(--bronze); --hel-gold:var(--gold);
    --hel-plate-gold:#d9a441; --hel-plate-clay:#c9773c;  /* keep in step with marble */
    --fm-meander:rgba(122,90,28,0.62); --hel-key:var(--fm-meander);
    --hel-key-strong:rgba(122,90,28,0.85); --hel-key-ghost:rgba(122,90,28,0.10);
    --hel-flute:rgba(255,255,255,0.72); --hel-flute-soft:rgba(122,90,28,0.055);
    --hel-flute-dark:rgba(122,90,28,0.18); --hel-rule:rgba(122,90,28,0.55);
    --hel-laurel:var(--laurel-leaf); --hel-mark:rgba(28,23,18,0.13);
    --hel-incise-lo:rgba(255,255,255,0.85); --hel-incise-hi:rgba(90,66,20,0.28);
    --hel-label:#5f4310;   /* keep in step with the marble block above */
    --gk-clay:#b8652c; --gk-glaze:#241a12; --gk-ring:var(--bronze);
    --hel-ok-text:#235838; --hel-warn-text:#74500a; --hel-danger-text:#7a1e11; --hel-info-text:#17406f;
    /* syntax ramp — keep in step with the marble block above */
    --tk-cmt:#41693b; --tk-str:#7d5410; --tk-pre:#6d3a87; --tk-kw:#1b4f9e;
    --tk-ty:#0d5f6b; --tk-num:#8c4a15; --tk-fn:#6a5405; --tk-hal:#9c2f3b;
  }
}


/* ============================================================================
 * §2  LITERALS IN styles.css THAT THE TOKENS CANNOT REACH.
 * styles.css hard-codes #3f8fe6, #ffb3ba, #7fe6b4, #05080d, rgba(77,163,255,…)
 * and so on. Without this section the marble theme would render blue cockpit
 * fragments on marble. This is correctness, not polish.
 * color-mix() is used for the rgba() literals; where it is unsupported the
 * declaration is simply dropped and the styles.css value stands.
 * ==========================================================================*/

body {
  /* wine-dark water with a low gold cast, replacing the blue/violet wash */
  background:
    radial-gradient(1200px 620px at 82% -12%, rgba(217,164,65,0.075), transparent 62%),
    radial-gradient(1000px 520px at -10% 8%,  rgba(111,180,230,0.075), transparent 58%),
    var(--bg);
}
:root[data-theme="marble"] body,
:root[data-theme="auto"] body {
  background:
    radial-gradient(1100px 600px at 84% -14%, rgba(184,101,44,0.10), transparent 62%),
    radial-gradient(950px 500px at -8% 6%,    rgba(29,79,143,0.07),  transparent 58%),
    var(--bg);
}

::-webkit-scrollbar-thumb:hover { background: var(--panel-3); background-clip: padding-box; }

/* The wordmark chip. PLATE pigments, not the gilt-ink ones — see
   --hel-plate-gold in the marble palette for the pixel-by-pixel measurement. */
.fm-brand .fm-logo {
  background: linear-gradient(135deg, var(--hel-plate-gold), var(--hel-plate-clay));
  color: var(--hel-ink);
  box-shadow: 0 2px 10px rgba(184,134,47,0.30);
}

.fm-nav-item.active { border-color: color-mix(in srgb, var(--accent) 34%, transparent); }
.fm-pal-item.sel    { border-color: color-mix(in srgb, var(--accent) 34%, transparent); }
.fm-pal-tag         { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 36%, transparent); }

/* Primary button. White on #4da3ff measured 2.63:1 in the original — below AA
   at any size. Slip ink on gold plate measures 8.32:1 at the top of the
   gradient and 5.78:1 at the foot; marble uses marble-on-Aegean at 7.66:1.
   A legibility fix that happens to be Hellenic. */
.fm-btn.primary {
  background: linear-gradient(180deg, var(--hel-gold), var(--hel-bronze));
  border-color: color-mix(in srgb, var(--hel-bronze) 70%, black);
  color: var(--hel-ink);
  text-shadow: none;
}
:root[data-theme="marble"] .fm-btn.primary {
  background: linear-gradient(180deg, #2a5c9c, var(--accent));
  border-color: color-mix(in srgb, var(--accent) 80%, black);
  color: var(--marble);
}
/* "auto" may only take the Aegean plate when the OS is actually light — same
   gate as the auto token block above. Unscoped, this rule also fired in
   auto+dark, where --accent is the LIGHT aegean and marble-on-light measured
   1.86:1. Gated, auto+dark keeps the gold plate above at 5.78:1. */
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] .fm-btn.primary {
    background: linear-gradient(180deg, #2a5c9c, var(--accent));
    border-color: color-mix(in srgb, var(--accent) 80%, black);
    color: var(--marble);
  }
}
.fm-btn.danger {
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 45%, transparent);
  color: var(--hel-danger-text);
}
.fm-btn.danger:hover { background: color-mix(in srgb, var(--danger) 24%, transparent); }

.fm-badge.ok     { color: var(--hel-ok-text);     border-color: color-mix(in srgb, var(--ok) 34%, transparent); }
.fm-badge.warn   { color: var(--hel-warn-text);   border-color: color-mix(in srgb, var(--warn) 34%, transparent); }
.fm-badge.danger { color: var(--hel-danger-text); border-color: color-mix(in srgb, var(--danger) 38%, transparent); }
.fm-badge.info   { color: var(--hel-info-text);   border-color: color-mix(in srgb, var(--accent) 34%, transparent); }

.fm-dot.ok { box-shadow: 0 0 7px color-mix(in srgb, var(--ok) 55%, transparent); }

.fm-terminal  { background: #0a0f18; color: #ddd5c6; }   /* 13.16:1 */
.fm-error-box { color: var(--hel-danger-text); }
:root[data-theme="marble"] .fm-terminal {
  background: #fdfaf4; color: #241d16; border-color: var(--line);   /* 15.97:1 */
}
/* Same gate as .fm-btn.primary above. Unscoped, this rule also fired in
   auto+dark, dropping a bright white console box into an otherwise dark
   page — legible on its own (15.97:1) but visually wrong. Gated, auto+dark
   falls through to the base .fm-terminal rule at 13.16:1. */
@media (prefers-color-scheme: light) {
  :root[data-theme="auto"] .fm-terminal {
    background: #fdfaf4; color: #241d16; border-color: var(--line);   /* 15.97:1 */
  }
}


/* ============================================================================
 * §3  ORNAMENT PRIMITIVES — pure CSS, no images.
 *
 * THE MEANDER. The signature motif, so the geometry is exact rather than
 * suggested. Drawn on a unit grid u (--hel-u), five rectangles per 6u tile:
 * the standard single meander hanging from a continuous top rail.
 *
 *      x→  0  1  2  3  4  5  6      rail   x0–6u  y0–1u  (runs unbroken)
 *   y0  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓    stem   x4–5u  y0–5u  (descends)
 *   y1              ▓▓              foot   x1–5u  y4–5u  (returns left)
 *   y2     ▓▓▓▓▓▓   ▓▓              riser  x1–2u  y2–5u  (ascends)
 *   y3     ▓▓       ▓▓              hook   x1–3u  y2–3u  (turns inward)
 *   y4     ▓▓▓▓▓▓▓▓▓▓▓▓
 *
 * Every stroke is 1u and every gap is 1u, and the spiral never touches itself.
 * That even rhythm is the whole difference between a real meander and a cheap
 * zig-zag: if you change one number here, change all of them.
 *
 * Technique: each rectangle is one background layer with `repeat-x`, so the
 * layer tiles horizontally at 6u but is painted ONCE vertically at its own
 * offset. A 90deg gradient with hard stops bounds it in x; background-size
 * bounds it in y. No masks, no compositing — works wherever gradients do.
 *
 * 🔴 The five layers are declared ONCE and re-used by every consumer, so the
 * geometry cannot drift between a 25px monumental frieze on the topbar and a
 * 10px inlaid band on a card.
 *
 * 🔴 MEASURED CORRECTION — why the block below is a selector LIST and not
 * `:root`. A var() inside a custom property is substituted at the element that
 * DECLARES the property, not at the element that uses it. Declaring
 * `--hel-mea-img: …var(--u)…` on :root, where --u is undefined, makes the whole
 * declaration invalid-at-computed-value-time; it then inherits as the
 * guaranteed-invalid value and every consumer resolves `background-image` to
 * `none`. Verified in Chrome: getPropertyValue('--hel-mea-img') on :root
 * returned "" and all four meanders painted nothing. Declaring the mixin
 * directly on each host (including the pseudo-elements, which carry their own
 * custom properties) re-substitutes it per host with that host's own --u/--k.
 * A `*` rule would also work and would cost a stored token stream on every one
 * of the ~4700 nodes an AGV page builds; this list costs six.
 * ==========================================================================*/

/* -- horizontal meander: image / size / position / repeat ------------------ */
.hel-meander,
.fm-topbar,
.fm-topbar::after,
.fm-card::before,
.fm-login-card::before {
  --u: var(--hel-u, 2px);
  --k: var(--hel-key, rgba(217,164,65,0.62));
  --hel-mea-img:
    linear-gradient(var(--k), var(--k)),
    linear-gradient(90deg, transparent calc(4 * var(--u)), var(--k) calc(4 * var(--u)),
                    var(--k) calc(5 * var(--u)), transparent calc(5 * var(--u))),
    linear-gradient(90deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(5 * var(--u)), transparent calc(5 * var(--u))),
    linear-gradient(90deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(2 * var(--u)), transparent calc(2 * var(--u))),
    linear-gradient(90deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(3 * var(--u)), transparent calc(3 * var(--u)));
  --hel-mea-size:
    calc(6 * var(--u)) calc(1 * var(--u)),
    calc(6 * var(--u)) calc(3 * var(--u)),
    calc(6 * var(--u)) calc(1 * var(--u)),
    calc(6 * var(--u)) calc(2 * var(--u)),
    calc(6 * var(--u)) calc(1 * var(--u));
  --hel-mea-pos:
    0 var(--hel-dy, 0px),
    0 calc(var(--hel-dy, 0px) + 1 * var(--u)),
    0 calc(var(--hel-dy, 0px) + 4 * var(--u)),
    0 calc(var(--hel-dy, 0px) + 2 * var(--u)),
    0 calc(var(--hel-dy, 0px) + 2 * var(--u));
  --hel-mea-rep: repeat-x, repeat-x, repeat-x, repeat-x, repeat-x;
}

/* -- vertical meander: the same five rectangles transposed ----------------- */
.hel-meander-v,
.fm-sidebar {
  --u: var(--hel-u, 2px);
  --k: var(--hel-key, rgba(217,164,65,0.62));
  --hel-mea-v-img:
    linear-gradient(var(--k), var(--k)),
    linear-gradient(180deg, transparent calc(4 * var(--u)), var(--k) calc(4 * var(--u)),
                    var(--k) calc(5 * var(--u)), transparent calc(5 * var(--u))),
    linear-gradient(180deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(5 * var(--u)), transparent calc(5 * var(--u))),
    linear-gradient(180deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(2 * var(--u)), transparent calc(2 * var(--u))),
    linear-gradient(180deg, transparent calc(1 * var(--u)), var(--k) calc(1 * var(--u)),
                    var(--k) calc(3 * var(--u)), transparent calc(3 * var(--u)));
  --hel-mea-v-size:
    calc(1 * var(--u)) calc(6 * var(--u)),
    calc(3 * var(--u)) calc(6 * var(--u)),
    calc(1 * var(--u)) calc(6 * var(--u)),
    calc(2 * var(--u)) calc(6 * var(--u)),
    calc(1 * var(--u)) calc(6 * var(--u));
  --hel-mea-v-pos:
    var(--hel-dx, 0px) 0,
    calc(var(--hel-dx, 0px) + 1 * var(--u)) 0,
    calc(var(--hel-dx, 0px) + 4 * var(--u)) 0,
    calc(var(--hel-dx, 0px) + 2 * var(--u)) 0,
    calc(var(--hel-dx, 0px) + 2 * var(--u)) 0;
  --hel-mea-v-rep: repeat-y, repeat-y, repeat-y, repeat-y, repeat-y;
}

/* -- the pigment-only mixins. These reference nothing element-local, so they
      resolve correctly on :root and inherit — including the `transparent`
      values §8 substitutes when the kill-switch is thrown. ----------------- */
:root {
  /* -- Doric fluting: shadowed arris, lit arris, hollow, lit, shadowed.
        14px period. Hard stops only — a gradient RAMP to `transparent`
        interpolates through transparent-black and hazes the channel grey. --- */
  --hel-flute-img: repeating-linear-gradient(90deg,
    var(--hel-flute-dark) 0 1px,
    var(--hel-flute)      1px 3px,
    var(--hel-flute-soft) 3px 11px,
    var(--hel-flute)      11px 13px,
    var(--hel-flute-dark) 13px 14px);

  /* -- bead-and-reel: the lathe-turned moulding — bead, bead, reel, repeat -- */
  --hel-bead-img:
    radial-gradient(circle at 4px 4.5px, var(--hel-rule) 0 2.7px, transparent 3.0px),
    radial-gradient(circle at 12px 4.5px, var(--hel-rule) 0 2.7px, transparent 3.0px),
    linear-gradient(180deg, transparent 3.2px, var(--hel-rule) 3.2px,
                    var(--hel-rule) 5.8px, transparent 5.8px);
  --hel-bead-size: 24px 9px, 24px 9px, 24px 9px;

  /* -- egg-and-dart: ovolo eggs separated by a wedge dart ------------------ */
  --hel-egg-img:
    radial-gradient(ellipse 5.5px 6px at 7px 6.5px, var(--hel-rule) 0 62%, transparent 66%),
    linear-gradient(158deg, transparent 46%, var(--hel-rule) 47%, transparent 54%),
    linear-gradient(202deg, transparent 46%, var(--hel-rule) 47%, transparent 54%);
  --hel-egg-size: 24px 13px, 8px 13px, 8px 13px;
  --hel-egg-pos: 0 0, 15px 0, 15px 0;

  /* -- laurel spray: a stem with paired leaves, the rows offset half a period
        so they alternate the way real laurel does ------------------------- */
  --hel-laurel-img:
    linear-gradient(180deg, transparent 8px, var(--hel-laurel) 8px,
                    var(--hel-laurel) 9.5px, transparent 9.5px),
    radial-gradient(ellipse 5.5px 3.4px at 5.5px 5px,   var(--hel-laurel) 0 70%, transparent 74%),
    radial-gradient(ellipse 5.5px 3.4px at 12.5px 12.5px, var(--hel-laurel) 0 70%, transparent 74%);
  --hel-laurel-size: 18px 20px;

  /* -- amphora: hand-drawn profile of a neck-amphora — flared lip, tapering
        neck, the two handles read as part of the silhouette, ovoid body,
        disc foot. Empty-state watermark ONLY. --------------------------- */
  --hel-amphora-clip: polygon(
    38% 0%, 62% 0%, 62% 4%, 57% 7%,
    68% 9%, 74% 15%, 72% 26%, 64% 30%, 62% 25%, 68% 21%, 69% 14%, 60% 12%,
    66% 18%, 74% 32%, 78% 48%, 74% 66%, 63% 79%, 56% 84%,
    58% 92%, 68% 96%, 68% 100%, 32% 100%, 32% 96%, 42% 92%, 44% 84%,
    37% 79%, 26% 66%, 22% 48%, 26% 32%, 34% 18%, 40% 12%,
    31% 14%, 32% 21%, 38% 25%, 36% 30%, 28% 26%, 26% 15%, 32% 9%, 43% 7%,
    38% 4%);
}

/* ---- opt-in primitive classes. Any page may use these; none is required. -- */
.hel-meander {
  --u: var(--hel-u); --k: var(--hel-key);
  height: calc(5 * var(--u));
  background-image: var(--hel-mea-img);
  background-size: var(--hel-mea-size);
  background-position: var(--hel-mea-pos);
  background-repeat: var(--hel-mea-rep);
}
.hel-meander.strong { --k: var(--hel-key-strong); }
.hel-meander.lg     { --u: calc(var(--hel-u) * 2); }

.hel-meander-v {
  --u: var(--hel-u); --k: var(--hel-key);
  width: calc(5 * var(--u));
  background-image: var(--hel-mea-v-img);
  background-size: var(--hel-mea-v-size);
  background-position: var(--hel-mea-v-pos);
  background-repeat: var(--hel-mea-v-rep);
}
.hel-flute {
  background-image: var(--hel-flute-img);
  background-size: 14px 100%;
  background-repeat: repeat;
}
.hel-bead {
  height: 9px;
  background-image: var(--hel-bead-img);
  background-size: var(--hel-bead-size);
  background-repeat: repeat-x;
}
.hel-egg,
.hel-rule-egg {
  height: 13px; border: none; margin: 18px 0;
  background-image: var(--hel-egg-img);
  background-size: var(--hel-egg-size);
  background-position: var(--hel-egg-pos);
  background-repeat: repeat-x;
}
.hel-laurel-spray {
  height: 20px;
  background-image: var(--hel-laurel-img);
  background-size: var(--hel-laurel-size);
  background-repeat: repeat-x;
  opacity: .9;
}

/* WREATH — a ring of radial leaves, open at the top as a victory wreath is.
   The ring is cut with a mask; where mask is unsupported the block never
   applies and the element stays blank. Nothing breaks either way. */
@supports (mask-image: radial-gradient(#000, #000)) or (-webkit-mask-image: radial-gradient(#000, #000)) {
  .hel-wreath {
    width: 54px; height: 54px;
    background: repeating-conic-gradient(from 8deg,
      var(--hel-laurel) 0deg 5deg, transparent 5deg 13deg);
    -webkit-mask-image: radial-gradient(circle, transparent 0 58%, #000 62%);
    mask-image: radial-gradient(circle, transparent 0 58%, #000 62%);
    opacity: .8;
  }
}

.hel-amphora { background: var(--hel-mark); clip-path: var(--hel-amphora-clip); }


/* ============================================================================
 * §4  ORNAMENT PLACEMENT — where each motif is ALLOWED.
 *
 * ALLOWED (chrome only, never over data):
 *   meander        → topbar (monumental watermark + crisp foot frieze),
 *                    sidebar left rail (vertical), .fm-card top band,
 *                    login card head; .hel-meander / .hel-meander-v opt-in
 *   fluting        → sidebar, full height
 *   bead-and-reel  → .fm-divider
 *   egg-and-dart   → .hel-rule-egg, bare <hr>
 *   laurel         → page-head underline, success toast; .hel-wreath opt-in
 *   amphora        → .fm-empty watermark
 *
 * 🔴 FORBIDDEN — enforced in §7:
 *   tables (.fm-table / .fm-table-wrap), terminals and logs (.fm-terminal,
 *   pre, code), job timelines, verifier/diff reports, stat tiles, form
 *   controls. No ornament may ever sit behind a number an operator must read.
 *
 * Every ornament pseudo-element takes its display from --hel-orn; every
 * background ornament takes its colour from a --hel-* pigment. §8 turns both
 * off at once.
 * ==========================================================================*/

:root { --hel-orn: block; }

/* ---------------------------------------------------------------- topbar ----
 * TWO meanders at two scales, and neither costs a pixel of layout: the bar is
 * still exactly var(--topbar-h) tall, so the sidebar loses no height. This
 * matters — the operator has already reported that the foot of the menu is
 * hard to reach, and a taller header would have made that worse.
 *
 *  1. a MONUMENTAL 25px meander (u=5px) washed across the whole 54px bar at
 *     8.5% — the architectural frieze you read before you read anything else;
 *  2. a crisp 10px meander (u=2px) at 88% along the foot — the sharp line;
 *  3. a 2px bronze rule closing the bar.
 *
 * 🔴 `position` is NOT re-declared here. The previous revision set
 * `position: relative`, which silently overrode styles.css's `position: sticky`
 * (same specificity, later sheet). Sticky is already a positioned value, so the
 * ::after below anchors correctly without it.                               */
.fm-topbar {
  --u: calc(var(--hel-u) * 2.5);
  --k: var(--hel-key-ghost);
  --hel-dy: 14px;                       /* centres the 25px frieze in 54px */
  background-color: color-mix(in srgb, var(--bg-elev) 88%, transparent);
  background-image: var(--hel-mea-img);
  background-size: var(--hel-mea-size);
  background-position: var(--hel-mea-pos);
  background-repeat: var(--hel-mea-rep);
  border-bottom: 2px solid var(--hel-bronze);
}
.fm-topbar::after {
  content: ""; display: var(--hel-orn);
  position: absolute; left: 0; right: 0; bottom: 0;
  pointer-events: none;
  --u: var(--hel-u);
  --k: var(--hel-key-strong);
  --hel-dy: 0px;
  height: calc(5 * var(--u));
  background-image: var(--hel-mea-img);
  background-size: var(--hel-mea-size);
  background-position: var(--hel-mea-pos);
  background-repeat: var(--hel-mea-rep);
}

/* --------------------------------------------------------------- sidebar ----
 * A fluted shaft with a meander running down the arris. Both are painted on the
 * sidebar's OWN background — no extra element, no width change, no layout
 * change. background-attachment stays `scroll`, so both are pinned to the
 * padding box and do NOT move when the menu scrolls.
 *
 * The vertical meander is exactly 10px wide (5u at u=2px) and sits in the
 * sidebar's existing 10px left padding, so it can never be covered by a nav
 * item's hover fill and can never squeeze a label.                          */
.fm-sidebar {
  --u: var(--hel-u);
  --k: var(--hel-key-strong);
  --hel-dx: 0px;
  background-image: var(--hel-mea-v-img), var(--hel-flute-img);
  background-size: var(--hel-mea-v-size), 14px 100%;
  background-position: var(--hel-mea-v-pos), left top;
  background-repeat: var(--hel-mea-v-rep), repeat;
  border-right: 2px solid var(--hel-bronze);
}
/* The sticky filter box reads as the plinth the shaft stands on. */
.fm-nav-tools { border-bottom: 1px solid var(--hel-rule); }
/* Group labels in gilt rather than grey — a strong, zero-layout theme signal
   on chrome text that is never data. --hel-label, not --hel-gold: see the
   marble palette for why the two cannot be the same token. */
.fm-nav-group-label { color: var(--hel-label); letter-spacing: .14em; }
/* The active page gets a gilded jamb. inset box-shadow — no layout, and it is
   ADDITIVE to the existing accent fill, so nothing that marked the active item
   before has been taken away. */
.fm-nav-item.active { box-shadow: inset 3px 0 0 var(--hel-label); }

/* ----------------------------------------------------------------- panels ---
 * An inlaid meander band across the top of every card. This is the highest-
 * frequency Greek signal in the console: on a typical page it repeats 3–8
 * times, which is what turns "there is a gold line somewhere" into a theme.
 * It lives in the card's top padding, inset 15px from each side so it reads as
 * inlay rather than a border, and never touches the card's content. */
.fm-card {
  position: relative;
  padding-top: 23px;
}
.fm-card.pad-lg { padding-top: 29px; }
.fm-card::before {
  content: ""; display: var(--hel-orn);
  position: absolute; left: 15px; right: 15px; top: 6px;
  pointer-events: none;
  --u: var(--hel-u);
  --k: var(--hel-key);
  --hel-dy: 0px;
  height: calc(5 * var(--u));
  background-image: var(--hel-mea-img);
  background-size: var(--hel-mea-size);
  background-position: var(--hel-mea-pos);
  background-repeat: var(--hel-mea-rep);
}

/* -------------------------------------------------------------- page head ---
 * A laurel spray under the title. It sits in the existing 18px margin — no
 * padding is added, so nothing moves — and it now runs to 62% of the head
 * rather than 180px, at 90% rather than 50%. */
.fm-page-head { position: relative; }
.fm-page-head::after {
  content: ""; display: var(--hel-orn);
  position: absolute; left: 0; bottom: -12px;
  width: min(520px, 62%); height: 20px;
  pointer-events: none; opacity: .9;
  background-image: var(--hel-laurel-img);
  background-size: var(--hel-laurel-size);
  background-repeat: repeat-x;
  -webkit-mask-image: linear-gradient(90deg, #000 62%, transparent 100%);
  mask-image: linear-gradient(90deg, #000 62%, transparent 100%);
}

/* ---------------------------------------------------------------- rules ----- */
.fm-divider {
  height: 9px; background: none;
  background-image: var(--hel-bead-img);
  background-size: var(--hel-bead-size);
  background-repeat: repeat-x;
}
hr:not([class]) {
  height: 13px; border: none; margin: 18px 0;
  background-image: var(--hel-egg-img);
  background-size: var(--hel-egg-size);
  background-position: var(--hel-egg-pos);
  background-repeat: repeat-x;
}

/* ----------------------------------------------------------------- login ----
 * The one screen where a little ceremony is right: a meander over the card and
 * an egg-and-dart under it.
 *
 * 🔴 MEASURED: theme/odyssey-login.css loads AFTER this file and styles the same
 * two pseudo-elements at the same specificity, so on a normal boot ODYSSEY WINS
 * and what you actually see on the login screen is its 356x10 meander and 356x7
 * bead-and-reel, not the rules below. That is correct — odyssey-login.css owns
 * that screen. These rules are the FALLBACK for the case this file has to stand
 * alone (odyssey 404s, or is disabled), which the header promises it can. Do not
 * "fix" the duplication by deleting them without first checking that the login
 * card still gets a head when odyssey is absent. */
.fm-login-card { position: relative; }
.fm-login-card::before {
  content: ""; display: var(--hel-orn);
  position: absolute; left: -10px; right: -10px; top: -34px;
  pointer-events: none;
  --u: calc(var(--hel-u) * 1.5);
  --k: var(--hel-key-strong);
  --hel-dy: 0px;
  height: calc(5 * var(--u));
  background-image: var(--hel-mea-img);
  background-size: var(--hel-mea-size);
  background-position: var(--hel-mea-pos);
  background-repeat: var(--hel-mea-rep);
}
.fm-login-card::after {
  content: ""; display: var(--hel-orn);
  position: absolute; left: -10px; right: -10px; bottom: -26px;
  height: 13px; pointer-events: none;
  background-image: var(--hel-egg-img);
  background-size: var(--hel-egg-size);
  background-position: var(--hel-egg-pos);
  background-repeat: repeat-x;
}

/* ----------------------------------------------------------- empty state ----
 * 🔴 MEASURED BUG FIX. The amphora was 78x118 at 10% with `z-index:-1`, and
 * `.fm-empty` created no stacking context — so inside a `.fm-card` (which does
 * have a background) the watermark painted BEHIND the card and was invisible
 * wherever it actually gets used. `isolation:isolate` gives .fm-empty its own
 * stacking context, so z-index:-1 now means "behind the empty-state text" and
 * not "behind the panel". Verified in-browser: 0 visible before, 1 after. */
.fm-empty { position: relative; isolation: isolate; }
.fm-empty::before {
  content: ""; display: var(--hel-orn);
  position: absolute; left: 50%; top: 50%;
  width: 150px; height: 210px; transform: translate(-50%, -50%);
  z-index: -1; pointer-events: none;
  background: var(--hel-mark);
  clip-path: var(--hel-amphora-clip);
}

/* -------------------------------------------------------- success states ----
 * Laurel, the victory wreath. Decoration only — the left status border and the
 * §6 shape carriers keep carrying the meaning, and this leaf green is a
 * different hue from --ok on purpose so it can never be read as a state. */
.fm-toast.ok { position: relative; }
.fm-toast.ok::after {
  content: ""; display: var(--hel-orn);
  position: absolute; right: 10px; bottom: 6px; width: 86px; height: 20px;
  pointer-events: none; opacity: .55;
  background-image: var(--hel-laurel-img);
  background-size: var(--hel-laurel-size);
  background-repeat: repeat-x;
}


/* ============================================================================
 * §5  TYPE — a display face for large headings only.
 *
 * System/generic families only: no @font-face, no network. The stack reaches
 * for humanist faces with flared, incised stems — Optima and Candara are the
 * closest things to cut Greek lettering that ship with an OS — then falls back
 * through Palatino to a plain serif. If none resolve, headings are a serif:
 * perfectly legible, just less characterful.
 *
 * The "incised" effect is a two-sided text-shadow: a dark edge above the glyph
 * and a lit edge below, which is how a groove cut into stone reads under light
 * from above. It changes no glyph colour, so every contrast figure in §6 is a
 * measurement of the text as rendered.
 *
 * 🔴 The display face is applied ONLY to large display headings and the
 * wordmark, and is then explicitly re-set to the UI/mono stacks on every data
 * surface, so a hostname, a byte count, a log line or a diff can never inherit
 * it. No letterform is ever substituted for another, and no `text-transform` is
 * used anywhere — the copied string is always the string on screen.
 * ==========================================================================*/

:root {
  --hel-display: Optima, Candara, "Palatino Linotype", "Book Antiqua", Palatino,
                 "URW Palladio L", Georgia, serif;
}

.fm-page-head .fm-page-title h1,
.fm-login-card .fm-brand,
.fm-topbar .fm-brand,
.hel-display {
  font-family: var(--hel-display);
  letter-spacing: .022em;
  font-weight: 600;
}
.fm-page-head .fm-page-title h1 {
  font-size: 27px;
  line-height: 1.18;
  text-shadow: 0 -1px 0 var(--hel-incise-lo), 0 1px 0 var(--hel-incise-hi);
}
.fm-login-card .fm-brand { letter-spacing: .06em; font-size: 21px; }
.fm-topbar .fm-brand { letter-spacing: .03em; }
/* the wordmark's small print is metadata — keep it in the UI face */
.fm-brand small { font-family: var(--sans); letter-spacing: normal; }

/* 🔴 hard re-assertion: data never inherits the display face. */
table.fm-table, table.fm-table th, table.fm-table td,
.fm-terminal, .fm-terminal *, pre, code, kbd, samp,
.fm-mono, .fm-tag, .fm-kbd, .fm-stat .fm-stat-value,
.fm-input, .fm-select, .fm-textarea, .fm-badge, .fm-pal-input,
.fm-nav-item, .fm-btn {
  font-family: var(--sans);
  letter-spacing: normal;
  text-shadow: none;
}
.fm-terminal, .fm-terminal *, pre, code, kbd, samp,
.fm-mono, .fm-tag, .fm-kbd, .fm-textarea, .fm-input.mono,
table.fm-table td.num {
  font-family: var(--mono);
}
.fm-stat .fm-stat-value, table.fm-table td.num { font-variant-numeric: tabular-nums; }


/* ============================================================================
 * §6  STATUS SEMANTICS — the part that is not negotiable.
 *
 * 🔴 Every hex in this section is unchanged by the 2026-07-27 ornament pass.
 *
 * MEASURED WCAG 2.x contrast (sRGB). Every figure below is COMPUTED FROM THIS
 * FILE by scratchpad/hel-verify/verify.mjs, which parses the declarations above
 * rather than trusting a transcription — so the table cannot drift from the
 * palette. Re-run it after any colour change.
 *
 *   NIGHT                     --bg  --bg-elev  --panel --panel-2 --panel-3
 *     --fg      #f0e9dc      15.49     14.41     13.95     12.85     11.24
 *     --fg-dim  #b7ad9c       8.43      7.85      7.59      6.99      6.12
 *     --fg-faint#9d9482       6.23      5.79      5.61      5.16      4.52
 *     --ok      #55d3a1       9.99      9.30      9.00      8.28      7.25
 *     --warn    #e1b03d       9.33      8.68      8.40      7.74      6.77
 *     --danger  #dc6a62       5.59      5.20      5.04      4.64      4.06
 *     --accent  #6fb4e6       8.32      7.74      7.50      6.90      6.04
 *     --info    #6fb4e6       8.32      7.74      7.50      6.90      6.04
 *
 *   MARBLE                    --bg  --bg-elev  --panel --panel-2 --panel-3
 *     --fg      #1c1712      15.15     13.97     16.65     14.99     13.10
 *     --fg-dim  #4a4136       8.51      7.85      9.36      8.43      7.36
 *     --fg-faint#6a5f4f       5.32      4.91      5.84      5.26      4.60
 *     --ok      #2c6d49       5.27      4.86      5.80      5.22      4.56
 *     --warn    #8e620b       4.58      4.23      5.04      4.54      3.96
 *     --danger  #862213       7.94      7.32      8.73      7.86      6.87
 *     --accent  #1d4f8f       6.97      6.43      7.66      6.90      6.03
 *     --info    #1d4f8f       6.97      6.43      7.66      6.90      6.03
 *
 *   Status text (the tokens that actually render as words) on their own soft
 *   fill composited over --panel — all AA:
 *     night  ok 8.14 . warn 8.41 . danger 6.98 . info 8.16
 *     marble ok 6.40 . warn 5.57 . danger 7.75 . info 8.14
 *
 *   The four sub-4.5 status cells above (night --danger on --panel-3 = 4.06;
 *   marble --ok on --bg-elev = 4.86 is fine, but --warn on --panel-3 = 3.96,
 *   on --bg-elev = 4.23 and on --panel-2 = 4.54 sit at the line) are GRAPHICAL
 *   uses only — dots, borders and fills, which need 3:1, not 4.5:1 — because
 *   status WORDS render in the --hel-*-text tokens listed above, and those are
 *   all AA. --panel-3 is a hover/tag surface: do not set body text in a raw
 *   status token on it.
 *
 *   ORNAMENT-OVER-TEXT — the one thing this ornament pass could have broken.
 *   Sidebar fluting and the topbar meander watermark now sit BEHIND chrome
 *   text. The fluting has three bands and each is composited separately, so
 *   these are worst-band figures, not averages:
 *                                                 night   marble
 *     nav label   --fg-dim   over lit arris ....   6.53     9.36
 *     nav label   --fg-dim   over hollow .......   8.11     7.32
 *     nav label   --fg-dim   over dark arris ...   8.51     6.20
 *     group label --hel-label over lit arris ..    6.44     8.56
 *     group label --hel-label over hollow .....    8.00     6.70
 *     group label --hel-label over dark arris .    8.39     5.67
 *     group label --hel-label on plain ground .    7.74     7.18
 *     brand --fg over the topbar watermark ....   12.73    12.40
 *     page h1 --fg on --bg ....................   15.49    15.15
 *     btn.primary ink on gold / on bronze .....   8.32 / 5.78   (marble 7.66)
 *
 *   🔴 2026-07-27 — THE THEME'S OWN NAME CHIP, which this table did not cover
 *   because it is set from theme/hellenic.js rather than from this file. It is
 *   .fm-hell-name: 44 sidebar chips and one eyebrow per page header, 11.5–12px
 *   at weight 600, so it needs 4.5:1. It was bound to --fm-hell-ink, which
 *   resolved to --hel-gold -> --gold, i.e. the FILL pigment. Measured in the
 *   browser BEFORE the fix, marble: 3.37 flat / 4.02 lit arris / 3.14 hollow /
 *   2.66 dark arris / 2.82 on the active row / 3.66 on the page eyebrow. Night
 *   passed throughout. It now defers to --hel-label like every other piece of
 *   gilt TEXT in the theme, and measures:
 *                                                 night   marble
 *     nav chip    normal row, worst band .....    6.44     5.67
 *     nav chip    ACTIVE row, worst band .....    4.78     4.83
 *     page eyebrow on --bg ..................    8.31     7.79
 *     helm chip   on the topbar ..............    7.55     7.46
 *     helm chip   over the topbar watermark ..    6.53     6.55
 *   The same defect was live in theme/boot.js's helm chip (marble 3.50 flat,
 *   3.07 over the watermark) and is fixed there the same way.
 *
 *   The 47 sidebar marks (theme/hellenic.js, .fm-hell-navmark) take the same
 *   token. They are GRAPHICS and need 3:1; worst band 4.78 night / 4.83 marble.
 *
 *   🔴 2026-07-27 (later pass) — THE WORDMARK CHIP, .fm-brand .fm-logo, which
 *   the two tables above also did not cover because it is the one place the
 *   theme puts dark ink on a GILT PLATE rather than gilt ink on a dark ground.
 *   Rasterised pixel-by-pixel (26x26 = 676 samples of the real 135deg
 *   gradient, so the interior of the ramp is measured and not just the stops):
 *                                       marble        night
 *     before  worst pixel ..........    4.09  FAIL    5.56
 *     before  best pixel ...........    4.21          8.25
 *     after   worst pixel ..........    5.24          5.56  (night unchanged)
 *     after   best pixel ...........    7.90          8.25
 *   The failure was marble darkening --gold/--terracotta for their INK role and
 *   the plate inheriting that. Fixed with --hel-plate-gold/--hel-plate-clay,
 *   the fill-role pigments; see the marble palette. The chip is in the topbar
 *   of every page, so this was the theme's single most-repeated text.
 *
 *   Lowest text figure anywhere in the theme: 4.52 (--fg-faint on --panel-3).
 *   Lowest gilt figure: 4.78 night / 4.83 marble. Nothing is below AA.
 *   Decorative-only, reported for visibility rather than compliance: the
 *   meander stroke against the sidebar ground measures 6.25 night, 3.74 marble.
 *
 * DICHROMATIC SEPARATION — CIEDE2000 between simulated status colours
 * (Vienot-Brettel-Mollon LMS projection, severity 1.0), worst pair of
 * {pass, warn, fail, running}:
 *     night   deuteranopia 14.27  protanopia 16.10   (worst pair warn/fail)
 *     marble  deuteranopia 11.36  protanopia 13.24   (worst pair warn/fail)
 *     original cockpit palette, same method:  8.81 / 11.38
 * Both themes therefore separate BETTER than the palette they replace, so the
 * themed colours are kept rather than reverting to the originals. Had they not
 * separated, the standing instruction was to keep the ORIGINAL status colours
 * and say so; that branch was not needed.
 *
 * Even so, hue is NEVER the only carrier. The rules below add a shape carrier,
 * and they are deliberately NOT behind the ornament kill-switch.
 * ==========================================================================*/

/* Shape carrier for the status dot. Same 8px box, same layout — only the
   silhouette changes, so pass/warn/fail are still told apart on a greyscale
   monitor or by an operator with no colour vision at all.
     idle ■ square   ok ● circle   warn ▲ triangle   fail ◆ diamond          */
.fm-dot        { border-radius: 2px; }
.fm-dot.ok     { border-radius: 50%; }
.fm-dot.warn   { border-radius: 0; clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.fm-dot.danger { border-radius: 0; clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }

/* Badge carrier: the same silhouette as a leading mark, so a pill is readable
   as a shape before it is read as a word. Skipped when the badge already
   contains a dot, so nothing is ever doubled. */
.fm-badge.ok:not(:has(.fm-dot))::before,
.fm-badge.warn:not(:has(.fm-dot))::before,
.fm-badge.danger:not(:has(.fm-dot))::before {
  content: ""; width: 7px; height: 7px; flex: 0 0 auto; background: currentColor;
}
.fm-badge.ok:not(:has(.fm-dot))::before     { border-radius: 50%; }
.fm-badge.warn:not(:has(.fm-dot))::before   { clip-path: polygon(50% 0%, 100% 100%, 0% 100%); }
.fm-badge.danger:not(:has(.fm-dot))::before { clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); }

/* Failure stays the loudest thing on the page. */
.fm-toast.error  { border-left-width: 4px; }
.fm-badge.danger { border-width: 1.5px; font-weight: 700; }

/* Focus keeps the accent and never a status colour — an operator tabbing
   through must never mistake focus for failure. */
:focus-visible { outline-color: var(--accent); }


/* ============================================================================
 * §7  NO-ORNAMENT ZONES — enforcement, not etiquette.
 * Anything dense enough to be read at speed is scrubbed, whatever a later page
 * stylesheet tries to add through these primitives.
 * ==========================================================================*/

/* 🔴 MEASURED BUG FIX (kept from the previous revision). This list used a bare
   `[class*="log"]`, and a substring match on "log" also hits "login" and
   "logo" — which silently disabled EVERY ornament on the login screen. The
   real log-viewer classes in this console are cai-log, hp-log, hp-log-*,
   hp-actionlog and q-backlog — all still matched. */
.fm-table-wrap, table.fm-table, table.fm-table th, table.fm-table td,
.fm-terminal, pre, code,
.fm-stat, .fm-stat-value,
.fm-input, .fm-select, .fm-textarea,
[class*="timeline"], [class*="diff"], [class*="report"],
[class*="log"]:not([class*="login"]):not([class*="logo"]):not([class*="dialog"]) {
  --hel-orn: none;
}
.fm-table-wrap::before, .fm-table-wrap::after,
table.fm-table::before, table.fm-table::after,
.fm-terminal::before, .fm-terminal::after,
.fm-stat::before, .fm-stat::after { content: none !important; }

/* and no meander/laurel/flute may be repurposed as a data background */
table.fm-table, table.fm-table tbody tr, .fm-terminal, .fm-stat { background-image: none; }

/* A card that IS a data surface keeps its inlaid band (it sits in the card's
   own padding, above the data) — but a card nested INSIDE one of the scrubbed
   regions above loses it, because --hel-orn is inherited. That is the intended
   behaviour and it is why the band is a pseudo-element rather than a
   background layer. */


/* ============================================================================
 * §8  KILL-SWITCH, MOTION, CONTRAST, FORCED COLOURS.
 *
 *   FMTheme.setOrnament('none')                        ← canonical (boot.js)
 *   document.documentElement.dataset.ornament = 'off';
 *   document.documentElement.classList.add('hel-no-ornament');
 *   <html data-fm-hellenic="none">
 *
 * All four drop every ornament in §3 and §4. Colour tokens, status colours and
 * the §6 shape carriers stay — turning off decoration must never turn off
 * meaning.
 *
 * 🔴 The switch works in TWO ways at once, and the second is the important one:
 *   1. --hel-orn:none removes every ornament pseudo-element;
 *   2. every ornament PIGMENT goes `transparent`, so every background-image
 *      ornament — including one added by a future edit that forgot to update
 *      this section — disappears with it. The previous revision listed each
 *      ornament class by hand; that list was one edit away from being wrong.
 * ==========================================================================*/

:root[data-ornament="off"],
:root.hel-no-ornament,
:root[data-fm-hellenic="none"] {
  --hel-orn:        none;
  --fm-meander:     transparent;
  --hel-key:        transparent;
  --hel-key-strong: transparent;
  --hel-key-ghost:  transparent;
  --hel-flute:      transparent;
  --hel-flute-soft: transparent;
  --hel-flute-dark: transparent;
  --hel-rule:       transparent;
  --hel-laurel:     transparent;
  --hel-mark:       transparent;
  --hel-incise-lo:  transparent;
  --hel-incise-hi:  transparent;
}

/* Geometry that a transparent pigment cannot undo. */
:root[data-ornament="off"] .fm-topbar,
:root.hel-no-ornament .fm-topbar,
:root[data-fm-hellenic="none"] .fm-topbar {
  background-image: none; border-bottom: 1px solid var(--line);
}
:root[data-ornament="off"] .fm-sidebar,
:root.hel-no-ornament .fm-sidebar,
:root[data-fm-hellenic="none"] .fm-sidebar {
  background-image: none; border-right: 1px solid var(--line);
}
:root[data-ornament="off"] .fm-nav-tools,
:root.hel-no-ornament .fm-nav-tools,
:root[data-fm-hellenic="none"] .fm-nav-tools { border-bottom-color: var(--line-soft); }
:root[data-ornament="off"] .fm-nav-group-label,
:root.hel-no-ornament .fm-nav-group-label,
:root[data-fm-hellenic="none"] .fm-nav-group-label { color: var(--fg-faint); letter-spacing: .1em; }
:root[data-ornament="off"] .fm-nav-item.active,
:root.hel-no-ornament .fm-nav-item.active,
:root[data-fm-hellenic="none"] .fm-nav-item.active { box-shadow: none; }
:root[data-ornament="off"] .fm-card,
:root.hel-no-ornament .fm-card,
:root[data-fm-hellenic="none"] .fm-card { padding-top: 16px; }
:root[data-ornament="off"] .fm-card.pad-lg,
:root.hel-no-ornament .fm-card.pad-lg,
:root[data-fm-hellenic="none"] .fm-card.pad-lg { padding-top: 22px; }
:root[data-ornament="off"] .fm-divider,
:root.hel-no-ornament .fm-divider,
:root[data-fm-hellenic="none"] .fm-divider {
  height: 1px; background: var(--line-soft); background-image: none;
}
:root[data-ornament="off"] hr:not([class]),
:root.hel-no-ornament hr:not([class]),
:root[data-fm-hellenic="none"] hr:not([class]) {
  height: 1px; background: var(--line-soft); background-image: none; margin: 14px 0;
}
:root[data-ornament="off"] .fm-page-head .fm-page-title h1,
:root.hel-no-ornament .fm-page-head .fm-page-title h1,
:root[data-fm-hellenic="none"] .fm-page-head .fm-page-title h1 { text-shadow: none; }
:root[data-ornament="off"] .hel-amphora,
:root.hel-no-ornament .hel-amphora,
:root[data-fm-hellenic="none"] .hel-amphora { background: none; clip-path: none; }

/* This file introduces no animation, and it does NOT switch off the existing
   status pulse — that pulse is a live-state carrier, not decoration. What it
   does drop is the decorative mask some engines re-rasterise on scroll. */
@media (prefers-reduced-motion: reduce) {
  .fm-page-head::after { -webkit-mask-image: none; mask-image: none; }
}

/* prefers-contrast: more → ornament out of the way, lines and dim text up.
   Same two-way kill as §8 so nothing survives behind text. */
@media (prefers-contrast: more) {
  :root {
    --hel-orn: none;
    --fm-meander: transparent; --hel-key: transparent; --hel-key-strong: transparent;
    --hel-key-ghost: transparent; --hel-flute: transparent; --hel-flute-soft: transparent;
    --hel-flute-dark: transparent; --hel-rule: transparent; --hel-laurel: transparent;
    --hel-mark: transparent; --hel-incise-lo: transparent; --hel-incise-hi: transparent;
    --fg-dim:    #d6cfc2;   /* 10.9 on --panel */
    --fg-faint:  #b3aa98;   /* 7.3  on --panel */
    --line:      #465573;
    --line-soft: #33405a;
  }
  :root[data-theme="marble"], :root[data-theme="auto"] {
    --fg-dim:    #33291d;
    --fg-faint:  #4a3f30;
    --line:      #9c8763;
    --line-soft: #bfae90;
  }
  .fm-sidebar { background-image: none; border-right: 1px solid var(--line); }
  .fm-topbar  { background-image: none; border-bottom: 1px solid var(--line); }
  .fm-card    { padding-top: 16px; }
  .fm-card.pad-lg { padding-top: 22px; }
  .fm-nav-group-label { color: var(--fg-dim); }
  .fm-nav-item.active { box-shadow: none; }
  .fm-page-head .fm-page-title h1 { text-shadow: none; }
  .fm-divider { height: 1px; background: var(--line); background-image: none; }
  .fm-badge   { border-width: 1.5px; }
}

/* Windows High Contrast / forced-colors: hand everything back to the OS. */
@media (forced-colors: active) {
  :root {
    --hel-orn: none;
    --fm-meander: transparent; --hel-key: transparent; --hel-key-strong: transparent;
    --hel-key-ghost: transparent; --hel-flute: transparent; --hel-flute-soft: transparent;
    --hel-flute-dark: transparent; --hel-rule: transparent; --hel-laurel: transparent;
    --hel-mark: transparent; --hel-incise-lo: transparent; --hel-incise-hi: transparent;
  }
  .fm-sidebar, .fm-divider, .fm-topbar, .fm-card { background-image: none; }
  .fm-page-head .fm-page-title h1 { text-shadow: none; }
  .fm-dot, .fm-badge::before { forced-color-adjust: none; }
}

/* Print: no ornament, no dark ground. */
@media print {
  :root {
    --hel-orn: none;
    --fm-meander: transparent; --hel-key: transparent; --hel-key-strong: transparent;
    --hel-key-ghost: transparent; --hel-flute: transparent; --hel-flute-soft: transparent;
    --hel-flute-dark: transparent; --hel-rule: transparent; --hel-laurel: transparent;
    --hel-mark: transparent;
  }
  body { background: #fff; }
  .fm-sidebar, .fm-topbar, .fm-card { background-image: none; }
  .fm-page-head .fm-page-title h1 { text-shadow: none; }
}
