/* ===========================================================================
   BLACKTOP

   Backlog T2. A black ground, amber and orange, chrome highlights, heavy slab
   lettering and worn metal — the American-highway-at-night vernacular.

   THE NAME IS PART OF THE BRIEF, NOT A LABEL PUT ON AFTERWARDS. This was asked
   for as a theme named after a motorcycle manufacturer and was renamed the same
   day, by the maintainer, on purpose: that name is a live trademark and its
   badge is not ours to reproduce. So nothing here copies a mark — no shield, no
   wing, no engraved script, no corporate orange sampled off a tank. What is
   copied is the VERNACULAR, which belongs to nobody: enamel, chrome, sodium
   light, an instrument cluster and a slab-serif sign. `blacktop` is a common
   noun for asphalt paving, it names the palette rather than a manufacturer, and
   it is one evocative word like Matrix, Cyberpunk and Halloween. A registered
   charity's internal tool is not a place to be casual about a mark.

   WHAT THE THEME ACTUALLY IS, which is the whole design:

   CHROME IS NOT A COLOUR, IT IS A TRANSITION. Nothing else in this directory
   does that. A chromed edge is a specular ROLL — the road reflected below, a
   narrow white source above centre, a warm bounce off the lamp just under it —
   because chrome is a mirror and what it mirrors is a bright source and a black
   road at once. That roll is this theme's signature: the beading down the
   sidebar, the strip under the topbar, the bevel on every raised edge, and the
   brushed grain that scatters along one axis the way a brushed panel does. It
   is all painted once, and NONE of it crosses the reading path.

   THE LIGHT IS SODIUM, AND IT IS THE ONE THING THAT MOVES. A forecourt lamp
   over the chrome trim, breathing on an irregular cycle the way an old
   discharge lamp does, so the metal under it catches more and less. It is one
   element, one animated property, and it is in the chrome — see "THE FORECOURT
   LAMP" near the bottom of this file for the four limits it answers and for
   what was rejected before it.

   THE TWO VARIANTS ARE TWO LIGHTING CONDITIONS ON THE SAME MATERIAL, not two
   palettes. Dark is the road at night. Light is the same machine on the shop
   floor at noon: the ground becomes poured CONCRETE (a warm grey with the
   cement cast), not paper, and the amber stops being text and becomes a fill
   with near-black on it — because amber on a pale ground measures about 1.6:1
   and no amount of taste fixes that. The chrome band is declared ONCE and is
   identical in both, which is the point: metal does not change colour, only
   what is around it does.

   THE DISCIPLINE: THE CHROME IS METAL AND THE READING PATH IS PAPER. No table
   cell has a gradient, no body text has a shadow. Nobody reads 394 rows on a
   page where everything gleams.

   WHAT WAS CUT, recorded because in this repo an absence is not a decision:

     * NO ROAD MARKINGS. A dashed amber rule under a heading was drawn and
       thrown away: at every weight it reads as `border-bottom: dashed`, which
       is the same failure Electricity's lamp marquee had twice.
     * NO FLAMES. A flame is a gradient wash used as decoration, which is a
       default rather than a choice, and it cannot be done at 2px.
     * NO SHINE SWEEP ACROSS THE PAGE. The first build had no ambient motion at
       all, on the argument that the obvious move — a highlight travelling the
       width of the chrome band — is the most generic thing this brief could
       produce AND would sit above the table somebody is reading. The maintainer
       asked for motion, and the second half of that argument turned out to be
       the useful half: it does not say don't, it says WHERE. The lamp below is
       in the chrome and never crosses a row. The first half stands on its own —
       there is still no sweep, because a lamp that breathes is the thing that
       actually happens on a forecourt at night and a sweeping glint is not.

   Structure lives in chrome.css; this file is colour, material and type. The
   contract is themes/README.md and it is a contract, not a style guide.
   =========================================================================== */

/* ===========================================================================
   LIGHT — the shop floor at noon. Concrete, black enamel, chrome, amber.
   This block also carries every token that does NOT change with the variant:
   the chrome ramp, the sidebar (dark in both), the faces, and the sound.
   =========================================================================== */
:root[data-palette="blacktop"] {
  /* ---- Poured concrete. Warm grey with the cement cast — deliberately not a
     cream, which is the base theme's ground and is also the commonest tell in
     generated design. ---- */
  --bt-ground:     #e4e1da;   /* the page */
  --bt-surface:    #f1efe9;   /* cards, panels */
  --bt-surface-2:  #eceae3;   /* sectioning */
  --bt-ink:        #16120e;
  --bt-ink-2:      #3b352e;
  --bt-ink-3:      #5c554c;   /* muted */
  --bt-rule:       #cbc5bb;
  --bt-rule-firm:  #a8a196;
  --bt-field-edge: #7f7970;  /* the edge of a form field: 3:1 against the page at least (WCAG 1.4.11; the UI audit of 2026-11-05, backlog S232 — the line colour it used was 1.96:1) */

  /* ---- CHROME. Declared once, never overridden: a chromed part does not
     change colour between night and noon, only its surroundings do. The band
     is a real specular ramp — dark steel, a white core, dark steel — which is
     what makes it read as metal rather than as a light grey line. Slightly
     COOL on purpose: it is reflecting sky, and the cool against the warm black
     and the amber is most of why it reads as chrome at all. ---- */
  --bt-chrome-hi:  #ffffff;
  --bt-chrome:     #c3c8ce;
  --bt-chrome-lo:  #454b52;

  /* THE SPECULAR ROLL. Rewritten 2026-09-18 when the maintainer asked for the
     metal to be pushed further, and the change is not "more stops" — it is
     three things a flat ramp does not have, which are what separate a polished
     curved surface from a grey gradient:

       1. THE HIGHLIGHT IS NARROW AND OFF-CENTRE. A mirror-finished cylinder
          returns the light source as a thin band, not a soft middle, and it sits
          above centre because the source is above. A wide central highlight is
          what a "silver" gradient looks like, and it reads as plastic.
       2. IT HAS A DARK SIDE, and the dark side is DARKER than the surroundings.
          Chrome is a mirror: below the highlight it reflects the road, which is
          black. That near-black stop at the bottom is doing more work than the
          white one.
       3. THE BOUNCE IS WARM. This metal is under a sodium lamp, so the light it
          throws back is not neutral — #fdf2df immediately under the core is the
          lamp in the reflection, and it is the single stop that stops the band
          reading as cold steel on a warm page. */
  --bt-chrome-band: linear-gradient(
    to bottom,
    #14181b 0%,     /* the road, reflected */
    #3d434a 10%,
    #78808a 26%,
    #c8d0d8 38%,
    #ffffff 43%,    /* the source: narrow, above centre */
    #fdf2df 47%,    /* the sodium lamp in the reflection */
    #a2aab3 55%,
    #4c535b 70%,
    #23282d 86%,
    #0e1113 100%    /* the dark side, darker than anything around it */
  );
  /* The same roll for the vertical beading down the sidebar's outer edge. Read
     across its 3px width rather than down its length: a chromed strip catches
     one line of light along the whole edge, which is why this runs `to right`
     and the band above runs `to bottom`. */
  --bt-chrome-beading: linear-gradient(
    to right,
    #0e1113 0%,
    #454c54 22%,
    #aab3bc 46%,
    #ffffff 58%,
    #fdf2df 66%,
    #6d757e 82%,
    #1a1e21 100%
  );

  /* BEVEL. A polished edge has BOTH a bright top and a dark underside, and the
     pair is what makes an element look raised rather than merely outlined —
     one without the other reads as a border somebody forgot to finish. The
     bounce is the warm one again: the underside of a chromed edge picks up the
     lamp, not the sky. */
  --bt-bevel-hi:  rgba(255, 255, 255, 0.62);
  --bt-bevel-lo:  rgba(0, 0, 0, 0.34);
  --bt-bounce:    rgba(255, 176, 90, 0.16);

  /* BRUSHED, NOT NOISY. Brushed metal scatters along ONE axis, which is the
     whole difference between a surface and a texture: the grain runs with the
     panel and the light smears across it. Two superimposed pitches, 3px and
     7px, at different alphas — a single pitch reads as a screen-door moiré and
     is the reason the first version looked like dither rather than like metal.
     Painted once, never animated. */
  --bt-brush:
    repeating-linear-gradient(90deg, rgba(255, 248, 236, 0.020) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.16) 0 1px, transparent 1px 7px);

  /* The forecourt lamp's own bloom, which is what the chrome catches. Declared
     per variant below: at night it is the lamp, at noon it is barely there. */
  --bt-lamp-bloom: rgba(255, 167, 38, 0.10);
  --bt-lamp-catch: rgba(255, 248, 232, 0.42);

  /* ---- AMBER is the lamp; ORANGE is heat. The split is by JOB, which is what
     keeps a two-accent palette from reading as one smear: amber says "here",
     orange says "hot". On concrete, amber cannot be small text (about 1.6:1),
     so it becomes the FILL with near-black on it — which is the more
     recognisable half of roadside signage anyway. Link ink drops to the burnt
     end of the same hue so the family still holds. ---- */
  --bt-amber:      #ffa726;   /* the lamp — fills, edges, never small text here */
  --bt-amber-hot:  #ffc25c;
  --bt-amber-deep: #e07f00;
  --bt-orange:     #ff6a2b;   /* heat: hover, hot metal */
  --bt-on-amber:   #170f02;   /* near-black on the lamp: 9.9:1 */
  --bt-glow:       rgba(255, 167, 38, 0.34);
  --bt-glow-soft:  rgba(255, 167, 38, 0.16);

  /* LINKS ARE CHROME, NOT AMBER — changed 2026-09-18 on the maintainer's
     reading of the first build: *"let's pull back a little and use chrome as
     well."* He was right, and the reason is arithmetic rather than taste. Every
     asset name and every holder name in every list is a link, so on a long page
     the link colour is most of the coloured pixels — with amber links beside
     amber "checked out" pills the night list came out uniformly golden, and
     amber stopped meaning anything because everything was it. Amber now earns
     its place in two jobs only: the status pills and the primary action.

     THE RISK IN THE SWAP, and how it is answered. A grey link beside grey-white
     body text can stop reading as a link — similar lightness, and the eye
     needs some difference to catch. There are three here and only one of them
     is lightness: this palette's ink is WARM (#f3ede3 / #16120e) and its chrome
     is COOL, so a cool link against warm text is a different thing even where
     the luminance is close (CIELAB dE 24.5 in dark, 27.5 in light, both far
     past the ~10 that reads as another colour); Pico's underline is left on and
     carries it on its own; and the ratios below are well clear of AA anyway. */
  --bt-link:       #3d4a55;   /* cool steel: 6.96:1 on concrete, 6.14:1 on a striped row */
  --bt-link-hot:   #222d36;

  /* FOCUS. Two rings, because one colour cannot survive both variants: a ring
     in the theme's own hue, plus a chrome hairline OUTSIDE it that is the
     opposite lightness to the ring. On concrete the dark ring carries it and
     the white hairline separates it from dark furniture; in the dark block
     below the pair inverts. Keyboard focus staying visible is a rule in this
     directory's README, not a nicety. */
  --bt-focus:      #7a2c04;
  --bt-focus-edge: rgba(255, 255, 255, 0.92);
  --bt-focus-halo: rgba(255, 167, 38, 0.40);

  /* ---- TYPE. Zilla Slab, self-hosted, headings only.
     WHY A SLAB AT ALL: the brief says heavy slab lettering, and it is right —
     the blunt, flat, barely-bracketed slab is the letterform of a route
     shield, a roadhouse sign and an enamel tank badge, and it is the one
     typographic gesture that places this theme without copying anybody's mark.
     WHY THIS SLAB: Zilla Slab is Clarendon-descended, which is exactly the
     register the registry's own note rejected for Electricity — "a Clarendon
     slab says 1890s trade catalogue" — and that is a reason to reject it
     THERE and to choose it HERE. Sturdy at 700, plain at 600, and its
     lowercase is the good part, so nothing below is set in all caps.
     Body stays Karla. 394 rows of inventory is not the place for character. */
  --heading-font-family: "Zilla Slab", Rockwell, "Roboto Slab", Georgia, serif;
  --bt-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ---- Pico surface + ink ---- */
  --pico-background-color: var(--bt-ground);
  --pico-color: var(--bt-ink);
  --pico-h1-color: var(--bt-ink);
  --pico-h2-color: var(--bt-ink);
  --pico-h3-color: var(--bt-ink);
  --pico-h4-color: var(--bt-ink);
  --pico-h5-color: var(--bt-ink);
  --pico-h6-color: var(--bt-ink);
  --pico-muted-color: var(--bt-ink-3);
  --pico-muted-border-color: var(--bt-rule);
  --pico-border-color: var(--bt-rule-firm);
  --pico-table-border-color: var(--bt-rule);
  --pico-card-background-color: var(--bt-surface);
  --pico-card-border-color: var(--bt-rule);
  --pico-card-sectioning-background-color: var(--bt-surface-2);
  --pico-code-background-color: #dcd8cf;
  --pico-code-color: var(--bt-ink-2);
  --pico-blockquote-border-color: var(--bt-amber);
  /* Stamped metal and baked enamel have hard edges. 0.2rem, not the base's
     0.5rem — enough to look machined rather than laser-cut. */
  --pico-border-radius: 0.2rem;

  /* ---- Amber is the action colour ---- */
  --pico-primary: var(--bt-link);
  --pico-primary-background: var(--bt-amber);
  --pico-primary-hover: var(--bt-link-hot);
  --pico-primary-hover-background: var(--bt-amber-hot);
  --pico-primary-underline: rgba(61, 74, 85, 0.50);
  --pico-primary-focus: var(--bt-focus-halo);
  /* Declared here and NOT in the dark blocks on purpose: the ink on an amber
     lamp is near-black whatever time of day it is. 9.9:1. */
  --pico-primary-inverse: var(--bt-on-amber);

  --pico-secondary: #4a443c;
  --pico-secondary-background: #4a443c;
  --pico-secondary-hover: #2e2a25;
  --pico-secondary-hover-background: #2e2a25;
  --pico-secondary-focus: rgba(74, 68, 60, 0.25);
  --pico-secondary-inverse: #ffffff;

  /* <mark> carries the overdue count on an assignee page and the
     terminated-holder warning on a check-out — the same "this needs you" job
     the caution tier does, so it takes the caution amber rather than a quieter
     tint. The README's rule for this family is that it must not read QUIETER
     than the text around it; 9.1:1 here, against body text's 14.3:1. */
  --pico-mark-background-color: #ffd98a;
  --pico-mark-color: #4a3200;

  /* ---- Forms ---- */
  --pico-form-element-background-color: var(--bt-surface);
  --pico-form-element-border-color: var(--bt-field-edge);
  --pico-form-element-color: var(--bt-ink);
  --pico-form-element-placeholder-color: var(--bt-ink-3);
  --pico-form-element-active-background-color: #ffffff;
  --pico-form-element-active-border-color: var(--bt-amber-deep);
  --pico-form-element-focus-color: var(--bt-focus);
  --pico-form-element-selected-background-color: var(--bt-glow-soft);
  --pico-switch-background-color: var(--bt-rule-firm);
  --pico-switch-checked-background-color: var(--bt-amber);
  --pico-range-thumb-color: var(--bt-amber-deep);

  --pico-dropdown-background-color: var(--bt-surface);
  --pico-dropdown-border-color: var(--bt-rule);
  --pico-dropdown-hover-background-color: #e7e4dc;

  --scroll-shadow-color: rgba(22, 18, 14, 0.30);

  /* ---- THE SIDEBAR IS BLACK ENAMEL IN BOTH VARIANTS, like the base theme's
     own rail and most sidebar-nav apps. Declared once here and never
     overridden below: this is the tank, and it is the same object at noon and
     at midnight. Slightly lighter than the night ground (#121110 against
     #0b0a09) so it reads as a panel bolted on rather than a hole. ---- */
  --sidebar-bg: #121110;
  --sidebar-ink: #f1ebe1;
  --sidebar-muted: #9d9284;
  --sidebar-link: #c9bfb2;
  --sidebar-link-active: #ffffff;
  --sidebar-hover-bg: #201c18;
  --sidebar-active-bg: #3a2508;

  /* ---- SOUND. `console` — triangle and square tones with a sharp attack and a
     short tail, machine noise rather than an instrument. It is the nearest
     existing voice to stamped metal and a relay click, and it is REUSED rather
     than extended: this theme would really want a sixth voice built out of
     solenoids, and building one is separate creative work with its own brief
     (that is how `terminal` and `hollow` were added), not something to bolt
     onto a palette. See uiSound.js. ---- */
  --theme-sound: 1;
  --theme-voice: engine;

  /* AMBIENT MOTION — the forecourt lamp. See the animation block near the
     bottom of this file for what it is and why it is where it is. Declared
     ONCE, unscoped by variant, because the lamp is on in both: the Motion
     control in the Appearance panel is revealed by this token, and a control
     that appeared in dark and vanished in light would be a control that lies
     half the time. */
  --theme-motion: 1;

  /* ---- THE INSTRUMENT CLUSTER — the semantic tiers -----------------------
     Every idiot light on every machine in this vernacular follows one
     convention: GREEN is running normally, AMBER is take note, RED is a fault.
     That is not a metaphor laid over a palette; it is where the convention
     comes from, and it is why this theme is allowed a green when nothing else
     in the brief is green. Without it, good/caution/bad would be three warm
     tones on a warm page and would converge, which is the one thing this
     directory's README forbids outright.

     Measured from these hex values, per the three rules in that README:
       1. Distinguishable from each other, as CIELAB dE76 between the fills —
          the metric that matches the rule, since these differ in hue more than
          in lightness. LIGHT: good/caution 20.2, caution/bad 14.2,
          good/bad 18.6. DARK: 25.4 / 18.6 / 40.9. Over ~10 reads as a
          different colour.
       2. Direction preserved: green pilot, amber caution, red fault, and alarm
          one step hotter than bad.
       3. Every label clears 4.5:1 ON ITS OWN FILL, which is the surface that
          decides it because every one of these fills is opaque — so the table
          row underneath, striped or not, cannot reach the text. LIGHT: 7.49 /
          7.02 / 6.33 (alarm 6.89, neutral 8.46, inactive 7.01, archived 8.92).
          DARK: 8.36 / 8.60 / 7.26 (alarm 5.48, neutral 7.70, inactive 7.69,
          archived 5.20). Lowest anywhere: 5.20.
     The three greys are separated by TEMPERATURE as well as lightness, so
     "cancelled", "not working" and "donated" are three states rather than
     three greys: dE 13.4 and 9.9 in light, 12.4 and 8.9 in dark. -------- */
  --sem-good-bg: #d7ead9;      --sem-good-fg: #1c5026;
  --sem-caution-bg: #fbe6bb;   --sem-caution-fg: #684503;
  --sem-bad-bg: #fbdccc;       --sem-bad-fg: #8a3310;
  --sem-alarm-bg: #f4bda9;     --sem-alarm-fg: #6d1e0d;
  --sem-neutral-bg: #d8dadc;   --sem-neutral-fg: #33383c;
  --sem-inactive-bg: #e9dfc9;  --sem-inactive-fg: #54452a;
  --sem-archived-bg: #c6c2bb;  --sem-archived-fg: #25221f;

  /* Derived, not chosen: 28% of the ink mixed into the fill lands between the
     two in the tier's own hue, so re-pitching a tier never also means picking
     three border colours by hand. */
  --sem-good-border: color-mix(in srgb, var(--sem-good-fg) 28%, var(--sem-good-bg));
  --sem-caution-border: color-mix(in srgb, var(--sem-caution-fg) 28%, var(--sem-caution-bg));
  --sem-bad-border: color-mix(in srgb, var(--sem-bad-fg) 28%, var(--sem-bad-bg));

  /* THE ERROR FAMILY STAYS ON THE BAD TIER HERE, unlike Electricity. On an
     instrument cluster a fault lamp and a failure are the same red, and this
     palette has no calm colour to move "in maintenance" onto without importing
     a hue the brief does not have. Stated rather than left to the default,
     because the default is what nobody checked. */
  --sem-error-bg: var(--sem-bad-bg);
  --sem-error-fg: var(--sem-bad-fg);
  --sem-error-border: var(--sem-bad-border);
  --sem-bad-accent: #8a3310;

  /* The filter chips. The lit lamp is the theme's amber with near-black on it;
     the alerting one is the fault red. */
  --sem-chip-fill: var(--bt-amber);
  --sem-chip-ink: var(--bt-on-amber);
  --sem-chip-alert-ink: #fff1ea;
  --sem-chip-alert-fill: #8a3310;
  --sem-chip-alert-outline: #8a3310;

  /* The zebra is an OVERLAY, so it is one alpha rather than a light value and
     a dark one. Graphite, not the base's warm brown: a brown wash over a grey
     concrete ground is the exact defect this token exists to let a theme fix,
     and it is visible across 394 rows. */
  --zebra-stripe: rgba(58, 54, 48, 0.075);

  /* The dashboard's eight conductors. Same cluster order as the chips: the
     three lamps, then the greys, with `category` on the theme's own amber
     because it is a count and not a state. The boundary these need against
     the track is carried by --chart-bar-edge, which chrome.css declares as a
     flat overlay for every theme. */
  --chart-bar-available: #2f7d43;
  --chart-bar-category: #b5670a;
  --chart-bar-checked_out: #c98a06;
  --chart-bar-in_maintenance: #c1521f;
  --chart-bar-not_working: #8a6a3e;
  --chart-bar-lost: #9c2c14;
  --chart-bar-disposed: #6b6f73;
  --chart-bar-donated: #4a4d50;
}

/* ===========================================================================
   DARK — the road at night, and the variant this theme is designed around.
   Sodium light on black enamel; the chrome is the only thing that is not warm.
   =========================================================================== */
:root[data-palette="blacktop"][data-theme="dark"] {
  --bt-ground:     #0b0a09;   /* asphalt: a true black with a bituminous cast */
  --bt-surface:    #17140f;
  --bt-surface-2:  #1c1813;
  --bt-ink:        #f3ede3;   /* the warm white of a painted road line */
  --bt-ink-2:      #cfc5b6;
  --bt-ink-3:      #a49a8b;
  --bt-rule:       #2b2520;
  --bt-rule-firm:  #4a4139;
  --bt-field-edge: #6c635b;  /* the edge of a form field: 3:1 against the page at least (WCAG 1.4.11; the UI audit of 2026-11-05, backlog S232 — the line colour it used was 1.98:1) */

  /* Links are cool chrome here too — see the light block for why amber was
     pulled back off them. In the dark the chrome runs light rather than dark,
     which is the same inversion the rest of the metal makes: 9.57:1 on the
     ground, 8.93:1 on a striped row, and CIELAB dE 24.5 from the warm body ink
     beside it. */
  --bt-link:       #a9b6c2;
  --bt-link-hot:   #dfe5ea;
  --bt-glow:       rgba(255, 167, 38, 0.42);
  --bt-glow-soft:  rgba(255, 167, 38, 0.20);
  /* The lamp is ON at night, and this is the only place the theme's motion is
     visible. See the animation block for the four limits it answers. */
  --bt-lamp-bloom: rgba(255, 167, 38, 0.30);
  --bt-lamp-catch: rgba(255, 244, 222, 0.85);

  /* The focus pair inverts: a bright ring with a dark hairline outside it. */
  --bt-focus:      #ffb454;
  --bt-focus-edge: rgba(0, 0, 0, 0.85);
  --bt-focus-halo: rgba(255, 167, 38, 0.32);

  --pico-primary: var(--bt-link);
  --pico-primary-hover: var(--bt-link-hot);
  --pico-primary-underline: rgba(169, 182, 194, 0.55);
  --pico-code-background-color: #1c1813;
  --pico-form-element-active-background-color: #1d1913;
  --pico-form-element-active-border-color: var(--bt-amber);
  --pico-form-element-focus-color: var(--bt-focus);
  --pico-secondary: var(--bt-ink-2);
  --pico-secondary-background: #332c26;
  --pico-secondary-hover: var(--bt-ink);
  --pico-secondary-hover-background: #413931;
  --pico-dropdown-hover-background-color: #201c16;
  --pico-mark-background-color: #4a3200;
  --pico-mark-color: #ffd98a;
  --scroll-shadow-color: rgba(0, 0, 0, 0.70);

  /* ---- THE INSTRUMENT CLUSTER, dark. See the light block for the measured
     separations and ratios; the same three rules were applied to these. ---- */
  --sem-good-bg: #10301a;      --sem-good-fg: #7cd992;
  --sem-caution-bg: #3b2a07;   --sem-caution-fg: #ffc24d;
  --sem-bad-bg: #4a1a0d;       --sem-bad-fg: #ffa06b;
  --sem-alarm-bg: #6b0d10;     --sem-alarm-fg: #ff8a8a;
  --sem-neutral-bg: #2a2d30;   --sem-neutral-fg: #bcc2c7;
  --sem-inactive-bg: #342a1e;  --sem-inactive-fg: #d6bc97;
  --sem-archived-bg: #211e1a;  --sem-archived-fg: #968f87;

  --sem-good-border: color-mix(in srgb, var(--sem-good-fg) 28%, var(--sem-good-bg));
  --sem-caution-border: color-mix(in srgb, var(--sem-caution-fg) 28%, var(--sem-caution-bg));
  --sem-bad-border: color-mix(in srgb, var(--sem-bad-fg) 28%, var(--sem-bad-bg));

  --sem-error-bg: var(--sem-bad-bg);
  --sem-error-fg: var(--sem-bad-fg);
  --sem-error-border: var(--sem-bad-border);
  --sem-bad-accent: #ffa06b;

  --sem-chip-fill: var(--bt-amber);
  --sem-chip-ink: var(--bt-on-amber);
  --sem-chip-alert-ink: #ffeee8;
  --sem-chip-alert-fill: #7a2611;
  --sem-chip-alert-outline: #ff8a6b;

  --zebra-stripe: rgba(255, 176, 90, 0.055);

  --chart-bar-available: #6fc98a;
  --chart-bar-category: #ffa726;
  --chart-bar-checked_out: #ffc24d;
  --chart-bar-in_maintenance: #ff8f5c;
  --chart-bar-not_working: #c9ae85;
  --chart-bar-lost: #ff6f5e;
  --chart-bar-disposed: #9aa0a6;
  --chart-bar-donated: #6f757b;
}

@media (prefers-color-scheme: dark) {
  /* The same design stated for the OS preference. Kept token-for-token
     identical to the block above — the two routes to dark are two selectors
     for one design, and this package's darkVariantParity test exists because
     keeping them in step by hand has failed twice. */
  :root[data-palette="blacktop"]:not([data-theme="light"]) {
    --bt-ground:     #0b0a09;
    --bt-surface:    #17140f;
    --bt-surface-2:  #1c1813;
    --bt-ink:        #f3ede3;
    --bt-ink-2:      #cfc5b6;
    --bt-ink-3:      #a49a8b;
    --bt-rule:       #2b2520;
    --bt-rule-firm:  #4a4139;
    --bt-field-edge: #6c635b;  /* the edge of a form field: 3:1 against the page at least (WCAG 1.4.11; the UI audit of 2026-11-05, backlog S232 — the line colour it used was 1.98:1) */

    --bt-link:       #a9b6c2;
    --bt-link-hot:   #dfe5ea;
    --bt-glow:       rgba(255, 167, 38, 0.42);
    --bt-glow-soft:  rgba(255, 167, 38, 0.20);
    --bt-lamp-bloom: rgba(255, 167, 38, 0.30);
    --bt-lamp-catch: rgba(255, 244, 222, 0.85);

    --bt-focus:      #ffb454;
    --bt-focus-edge: rgba(0, 0, 0, 0.85);
    --bt-focus-halo: rgba(255, 167, 38, 0.32);

    --pico-primary: var(--bt-link);
    --pico-primary-hover: var(--bt-link-hot);
    --pico-primary-underline: rgba(169, 182, 194, 0.55);
    --pico-code-background-color: #1c1813;
    --pico-form-element-active-background-color: #1d1913;
    --pico-form-element-active-border-color: var(--bt-amber);
    --pico-form-element-focus-color: var(--bt-focus);
    --pico-secondary: var(--bt-ink-2);
    --pico-secondary-background: #332c26;
    --pico-secondary-hover: var(--bt-ink);
    --pico-secondary-hover-background: #413931;
    --pico-dropdown-hover-background-color: #201c16;
    --pico-mark-background-color: #4a3200;
    --pico-mark-color: #ffd98a;
    --scroll-shadow-color: rgba(0, 0, 0, 0.70);

    --sem-good-bg: #10301a;      --sem-good-fg: #7cd992;
    --sem-caution-bg: #3b2a07;   --sem-caution-fg: #ffc24d;
    --sem-bad-bg: #4a1a0d;       --sem-bad-fg: #ffa06b;
    --sem-alarm-bg: #6b0d10;     --sem-alarm-fg: #ff8a8a;
    --sem-neutral-bg: #2a2d30;   --sem-neutral-fg: #bcc2c7;
    --sem-inactive-bg: #342a1e;  --sem-inactive-fg: #d6bc97;
    --sem-archived-bg: #211e1a;  --sem-archived-fg: #968f87;

    --sem-good-border: color-mix(in srgb, var(--sem-good-fg) 28%, var(--sem-good-bg));
    --sem-caution-border: color-mix(in srgb, var(--sem-caution-fg) 28%, var(--sem-caution-bg));
    --sem-bad-border: color-mix(in srgb, var(--sem-bad-fg) 28%, var(--sem-bad-bg));

    --sem-error-bg: var(--sem-bad-bg);
    --sem-error-fg: var(--sem-bad-fg);
    --sem-error-border: var(--sem-bad-border);
    --sem-bad-accent: #ffa06b;

    --sem-chip-fill: var(--bt-amber);
    --sem-chip-ink: var(--bt-on-amber);
    --sem-chip-alert-ink: #ffeee8;
    --sem-chip-alert-fill: #7a2611;
    --sem-chip-alert-outline: #ff8a6b;

    --zebra-stripe: rgba(255, 176, 90, 0.055);

    --chart-bar-available: #6fc98a;
    --chart-bar-category: #ffa726;
    --chart-bar-checked_out: #ffc24d;
    --chart-bar-in_maintenance: #ff8f5c;
    --chart-bar-not_working: #c9ae85;
    --chart-bar-lost: #ff6f5e;
    --chart-bar-disposed: #9aa0a6;
    --chart-bar-donated: #6f757b;
  }
}

/* ===========================================================================
   THE CHROME BAND — the one thing this theme is for.

   Two 2px strips, both drawn from the same specular ramp, both pure
   background-image so they cost one paint and never reflow: one under the
   topbar, one down the sidebar's outer edge. Together they read as trim
   running around the panel, which is what chrome does on the object this
   vernacular comes from. They are the loudest thing here and they are 2px.
   =========================================================================== */
:root[data-palette="blacktop"] .topbar {
  background-image: var(--bt-chrome-band);
  background-repeat: no-repeat;
  background-size: 100% 3px;
  background-position: left bottom;
}

/* ===========================================================================
   THE FORECOURT LAMP — the theme's one ambient motion, and the only animation
   in this file.

   WHAT IT IS. A sodium lamp over the trim, and the trim catching it. One
   pseudo-element on `.topbar` carrying two things at once — a warm bloom
   rising off the bottom edge, and a brightener sitting exactly on the chrome
   band — so when the lamp swells the metal under it lights up. That pairing is
   the whole point: the motion is not decoration laid over the chrome, it is
   what the chrome is FOR.

   WHY IT BREATHES INSTEAD OF SWEEPING. A gas-discharge lamp does not hold a
   steady output; an old one visibly wanders and dips. The keyframes below are
   deliberately IRREGULAR — seven stops at uneven intervals over 13 seconds —
   because evenly spaced stops read as a CSS pulse and uneven ones read as a
   lamp. It is the same reasoning uiSound.js's `chatter` gives for jittering
   its ticks, and for the same reason: regularity is the tell.

   THE FOUR LIMITS IN themes/README.md, answered one at a time:

     OUT OF THE READING PATH. It is inside `.topbar` — the row that holds the
       search box and the account menu — and it is the bottom 22px of it, under
       the controls and over nothing. It cannot reach a table, a form field or
       a figure, because it is not in the same element as any of them.
     REDUCED MOTION. Turned OFF, not slowed, in the media query at the foot of
       this file, and turned off again by the Appearance panel's Motion control
       via [data-motion="off"]. Two levers, and neither can force it on.
     CHEAP. One element, ~1400x22px, one animated property, and that property is
       `opacity` — compositor-only, so it does not lay out, does not repaint the
       page and costs nothing extra while 479 rows scroll past underneath. No
       gradient stop is animated anywhere in this file; the gradients are
       painted once.
     NOT THE FIRST THING THE EYE LANDS ON. The swing is 0.78 to 1.0 of a layer
       whose own peak alpha is 0.30 in dark and 0.10 in light, so the amplitude
       is a few percent of a translucent band at the very top of the chrome. You
       notice it after a minute, which is the correct amount.

   WHY `.topbar` AND NOT THE SIDEBAR. Reach. `.topbar` is rendered by BOTH apps
   (`apps/hub/views/partials/header.ejs` and the Asset Manager's own), so the
   Hub's pages get the theme's atmosphere too; `.sidebar` exists only in the
   Asset Manager, and a theme whose one moving part is missing from half the
   product is the "one look, two behaviours" gap this package's CLAUDE.md was
   written about.

   TWO REAL TRAPS HERE, both checked rather than assumed:

     1. THE HUB'S `.topbar` IS `position: sticky` (hub.css) AND THE ASSET
        MANAGER'S IS STATIC. A blanket `position: relative` from this file would
        overwrite the Hub's sticky and unstick its topbar. Sticky is already a
        positioned value, so the Hub needs nothing; only the Asset Manager's
        does, and it is reached by `.app-main .topbar`, which the Hub has no
        element matching.
     2. THE APPEARANCE PANEL LIVES INSIDE `.topbar` ON THE HUB and is
        `position: fixed`. So this file must never give `.topbar` `overflow`,
        `transform`, `filter`, `backdrop-filter`, `contain` or `will-change` —
        the first clips the panel away in WebKit, the rest make the topbar its
        containing block in every engine, and both look identical to the user:
        the trigger opens and no panel appears. That is why the glow is sized
        and positioned exactly rather than drawn large and clipped, and why
        there is no `will-change` on it despite the animation.
   =========================================================================== */
:root[data-palette="blacktop"] .app-main .topbar {
  position: relative;
}
:root[data-palette="blacktop"] .topbar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 22px;
  pointer-events: none;
  background-image:
    linear-gradient(to top, var(--bt-lamp-bloom) 0%, transparent 100%),
    linear-gradient(to bottom, transparent 0 19px, var(--bt-lamp-catch) 19px 100%);
  animation: bt-lamp 13s ease-in-out infinite;
}

@keyframes bt-lamp {
  0%   { opacity: 0.92; }
  17%  { opacity: 1; }
  29%  { opacity: 0.78; }
  34%  { opacity: 0.97; }
  52%  { opacity: 0.86; }
  61%  { opacity: 1; }
  79%  { opacity: 0.81; }
  100% { opacity: 0.92; }
}

/* The Appearance panel's Motion control. Only "off" is honoured — there is
   deliberately no value that forces it on, because the OS preference below must
   not be overridable by an app switch. */
:root[data-palette="blacktop"][data-motion="off"] .topbar::after {
  animation: none;
}

/* The sidebar is the enamelled panel: a brushed vertical grain so it reads as
   a surface rather than a hole, the chrome beading down its outer edge, and
   one sodium fall from the top where the light comes in. All three are under
   the threshold where they would compete with the nav — which is the README's
   fourth limit, and the one an atmospheric theme actually fails. */
/* FOUR LAYERS, and the order is the material from the outside in: the chromed
   beading on the outer edge, the sodium falling down the panel from the lamp,
   then the two brush pitches. `var(--bt-brush)` expands to TWO layers, so the
   four background-* lists below have four entries each — miscounting them is
   how a background list silently stops lining up. All painted once; none of
   this animates. */
:root[data-palette="blacktop"] .sidebar {
  background-image:
    var(--bt-chrome-beading),
    /* The fall from the lamp. A LITERAL and not `--bt-glow-soft`, which is the
       hover/active token and is twice this strength: rendered at that value the
       sidebar's top third went visibly brown and became the first thing the eye
       landed on when the page opened, which is the README's fourth limit and
       the one an atmospheric theme actually fails. Measured back down by
       looking. */
    linear-gradient(to bottom, rgba(255, 167, 38, 0.11) 0, transparent 240px),
    var(--bt-brush);
  background-repeat: no-repeat, no-repeat, repeat, repeat;
  background-size: 3px 100%, 100% 240px, auto, auto;
  background-position: right top, left top, left top, left top;
  /* The bevel where the enamel meets the beading: a warm bounce off the chrome
     back onto the panel, and a dark seam at the top where it meets the lid. */
  box-shadow:
    inset -4px 0 6px -5px var(--bt-bounce),
    inset 0 1px 0 rgba(255, 255, 255, 0.05);
}

/* ===========================================================================
   THE LAMP. The nav is a dark rail with every page hung off it, and the page
   you are on is the one drawing current: an amber filament down its left edge,
   its light spilling onto the panel. This is how you know where you are, which
   is a job the theme did not invent — it is just wearing it in the theme's own
   material.
   =========================================================================== */
:root[data-palette="blacktop"] .sidebar-nav a {
  box-shadow: inset 2px 0 0 rgba(255, 246, 232, 0.07);
  transition: box-shadow 130ms ease-out;
}
:root[data-palette="blacktop"] .sidebar-nav a:hover {
  box-shadow: inset 2px 0 0 var(--bt-chrome);
}
:root[data-palette="blacktop"] .sidebar-nav a.active {
  background-image: linear-gradient(to right, var(--bt-glow-soft) 0%, transparent 70%);
  box-shadow:
    inset 3px 0 0 var(--bt-amber),
    inset 0 0 22px -8px var(--bt-glow);
}

/* The name of the thing, in the lamp colour, at the top of the rail where the
   eye starts. One line of amber in the whole chrome. */
:root[data-palette="blacktop"] .sidebar-brand-subtitle {
  color: var(--bt-amber);
  font-weight: 700;
}

/* ===========================================================================
   SODIUM. One wash entering from above, fixed so it does not travel with the
   scroll, at a level nobody would notice until it was removed. It is behind
   the page rather than on it: `background-attachment: fixed` on the body
   paints once and never repaints while a 394-row table scrolls past.
   =========================================================================== */
:root[data-palette="blacktop"][data-theme="dark"] body {
  background-image: radial-gradient(150% 80% at 50% -24%, rgba(255, 167, 38, 0.07) 0%, transparent 62%);
  background-attachment: fixed;
}
@media (prefers-color-scheme: dark) {
  :root[data-palette="blacktop"]:not([data-theme="light"]) body {
    background-image: radial-gradient(150% 80% at 50% -24%, rgba(255, 167, 38, 0.07) 0%, transparent 62%);
    background-attachment: fixed;
  }
}

/* ===========================================================================
   METALFLAKE — the theme's signature ambient layer, and the thing that answers
   "give it what Matrix has".

   The first build's ambient motion was the forecourt lamp below. Measured over
   its whole cycle, the only pixels that changed on the page were a 3px line
   moving 41/255, with a whole-page mean delta of 0.23/255. That is not subtle,
   it is absent — and it was the wrong SUBJECT besides: a forecourt lamp is
   scenery seen from the road, and this theme was asked for as a motorcycle.

   Aluminium flake suspended in black lacquer is the custom tank's surface. It
   is why black paint on a bike looks expensive instead of flat, it belongs to
   no manufacturer, and it is a PARTICLE FIELD — the same class of effect as the
   digital rain, made of a different substance, which is how it matches that
   theme's ambition without copying its idea.

   THE MARKUP IS blacktopFlake.js's, per the contract in its header:

       <canvas class="bt-flake" aria-hidden="true"></canvas>

   as a direct child of <body>, created only while the palette is blacktop and
   removed when it changes, its loop stopped while the tab is hidden and never
   started under prefers-reduced-motion or data-motion="off". Everything below
   — position, stacking, opacity, and whether it exists in the light variant —
   is this stylesheet's to decide, so that script needs no variant branch.
   =========================================================================== */

/* WHY A z-index: -1 CANVAS IS VISIBLE AT ALL, which is worth writing down
   because it is somebody else's decision that this layer depends on.

   Such a canvas paints ABOVE <html>'s background and BELOW <body>'s, so an
   opaque body would hide the field completely — and it would look exactly like
   an effect that was never written. It does not happen here because PICO
   ALREADY PAINTS THE GROUND ON <html> AND LEAVES <body> TRANSPARENT, in every
   theme: measured across all eight palettes in both variants, body is
   rgba(0,0,0,0) and html carries the colour, with nothing in this file involved.

   This block briefly carried two rules moving the ground to <html> itself, with
   a comment claiming they fixed that bug. They fixed nothing — the condition was
   already true — and a rule that documents a problem it did not solve is worse
   than no rule, so they are gone. What remains is the dependency: if Pico ever
   moves the ground onto <body>, this field goes silently invisible and the fix
   is here, not in the script.

   `.app-shell` and `.content` declare no background either, so the flake reads
   across the whole page ground while the table's own opaque cells sit over it. */
:root[data-palette="blacktop"] {
  --bt-flake-display: block;
  --bt-flake-opacity: 1;
}

/* THE LIGHT VARIANT HAS NO FLAKE, and that is a decision rather than an
   oversight. A white glint on warm concrete is invisible at any opacity worth
   painting, and the honest alternative — dark facets on a pale ground — is a
   different effect wearing this one's name. Shop floor at noon is lit flat.
   The dark variant is where the paint lives. */
:root[data-palette="blacktop"][data-theme="light"] {
  --bt-flake-display: none;
}

:root[data-palette="blacktop"] .bt-flake {
  display: var(--bt-flake-display);
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
  pointer-events: none;
  opacity: var(--bt-flake-opacity);
}

/* OFF, not slower. The element selector takes these to (0,2,1) so they beat the
   (0,2,0) rule above on specificity rather than on source order — the
   equal-specificity trap this directory has been bitten by before. The script
   stops its own loop as well; this only stops it being seen. */
:root[data-palette="blacktop"][data-motion="off"] canvas.bt-flake {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  :root[data-palette="blacktop"] canvas.bt-flake {
    display: none;
  }
}

/* ===========================================================================
   FOCUS — a chrome ring with an amber halo. Two rings in opposite lightness so
   it survives both variants and both the concrete page and the black rail:
   whichever one the surface swallows, the other one shows.
   =========================================================================== */
:root[data-palette="blacktop"] :focus-visible {
  outline: 2px solid var(--bt-focus);
  outline-offset: 2px;
  box-shadow:
    0 0 0 5px var(--bt-focus-edge),
    0 0 0 7px var(--bt-focus-halo);
  transition: box-shadow 110ms ease-out;
}

/* ===========================================================================
   ENAMEL AND CHROME — the primary button.

   Baked amber enamel with a chromed top edge and a dark shadow under it: three
   stops of the enamel, a hard white catch where the chrome trim sits, a dark
   lip at the bottom. It gets hotter when you touch it.

   THE EXCLUSION LIST IS LOAD-BEARING AND IS NOT OPTIONAL. Pico styles every
   bare `button` as a primary action, so `button:not(.secondary):not(.outline)`
   reads as "a real button" and is not: five controls in these apps are
   `<button>` elements deliberately stripped back to look like something else
   (the client-sort column headers, the narrow-screen hamburger, the waffle,
   the avatar and "Sign out"), and a rule of this shape is (0,4,1) against
   resets of (0,1,1), so it wins and turns each of them into an amber block.
   Electricity shipped exactly that on 2026-09-05 and broke all five; the
   exclusion has to be on the rule itself because the natural undo is (0,3,2)
   and would lose silently. test/themeButtonScope.test.js pins the list.
   The Asset Manager's destructive confirm (.app-dialog-ok-danger) is on it
   too since 2026-10-06 (backlog S204): it wears the danger red, and the lamp
   painted it amber under its light ink.
   =========================================================================== */
:root[data-palette="blacktop"] button:not(.secondary):not(.outline):not(.th-sort):not(.sidebar-toggle):not(.hubmenu-icon-button):not(.hubmenu-avatar-button):not(.hubmenu-item-button):not(.theme-choice):not(.app-dialog-ok-danger),
:root[data-palette="blacktop"] [role="button"]:not(.secondary):not(.outline),
:root[data-palette="blacktop"] input[type="submit"] {
  /* Baked enamel over a curved panel: the roll is narrow and high, the body is
     the lamp colour, and it darkens to a lip at the bottom — the same three
     ideas as the chrome ramp, in amber instead of steel. The ink on it is
     near-black at every stop (9.9:1 on the body, higher at both ends), so the
     gradient buys depth and costs no contrast. */
  background-image: linear-gradient(
    to bottom,
    #ffd486 0%,
    var(--bt-amber-hot) 16%,
    var(--bt-amber) 44%,
    #f59412 64%,
    var(--bt-amber-deep) 88%,
    #b86600 100%
  );
  box-shadow:
    inset 0 1px 0 var(--bt-bevel-hi),
    inset 0 -1px 0 var(--bt-bevel-lo),
    0 1px 0 rgba(0, 0, 0, 0.34);
  transition: box-shadow 130ms ease-out, background-image 130ms ease-out;
}
:root[data-palette="blacktop"] button:not(.secondary):not(.outline):not(.th-sort):not(.sidebar-toggle):not(.hubmenu-icon-button):not(.hubmenu-avatar-button):not(.hubmenu-item-button):not(.theme-choice):not(.app-dialog-ok-danger):hover,
:root[data-palette="blacktop"] [role="button"]:not(.secondary):not(.outline):hover,
:root[data-palette="blacktop"] input[type="submit"]:hover {
  background-image: linear-gradient(to bottom, #ffd27f 0%, var(--bt-amber-hot) 50%, var(--bt-orange) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.72),
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    0 2px 14px -6px var(--bt-glow);
}

/* ===========================================================================
   PANEL HARDWARE — type, plates and figures.
   =========================================================================== */
:root[data-palette="blacktop"] h1,
:root[data-palette="blacktop"] h2,
:root[data-palette="blacktop"] h3 {
  font-family: var(--heading-font-family);
  font-weight: 700;
  letter-spacing: -0.004em;
}

/* Column headers are the plate above the gauge: the slab at its plain weight,
   small, faintly tracked. Sentence case is kept from the base — a tracked-out
   all-caps eyebrow is the commonest tell in generated design and this app
   deliberately removed its own in backlog X11. */
:root[data-palette="blacktop"] table thead th {
  font-family: var(--heading-font-family);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  color: var(--bt-ink-2);
  border-bottom: 2px solid var(--bt-rule-firm);
}

/* Figures are a meter reading. A column of counts that does not line up is the
   one place character costs the reader something. */
:root[data-palette="blacktop"] td.num,
:root[data-palette="blacktop"] .money,
:root[data-palette="blacktop"] .stat-tile-value {
  font-family: var(--bt-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.015em;
}

/* Status badges and filter chips are stamped plates, not pills: squared off,
   ringed in their own ink. The ring is what gives the pale light-mode chips an
   edge against the row — the fills themselves sit at 1.04-1.21 against it,
   which is a fill you can read text on and not a shape you can see. */
:root[data-palette="blacktop"] .status-badge,
:root[data-palette="blacktop"] .filter-chip {
  border-radius: 0.12rem;
  border: 1px solid currentColor;
  font-weight: 600;
  /* A stamped plate has a lit top edge and a shadowed bottom one. ONE PIXEL
     each, and that is a contrast decision rather than a taste one: an inset
     shadow does not change `background-color`, so every ratio measured for
     these chips is arithmetically unaffected — but it does repaint the top and
     bottom pixel rows, so it is kept to the rows no glyph reaches. Anything
     with a blur radius would have crept under the text. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.13),
    inset 0 -1px 0 rgba(0, 0, 0, 0.22);
}

/* The FILLED chips only. The rule above rings every chip in currentColor at
   (0,2,0), which outranks the base rule's (0,1,0) border-color — so a filled
   chip would come out ringed in its own INK rather than its fill, which reads
   as a halo around a solid block. The OUTLINE alert chip is deliberately left
   alone: ringing that one in its own ink is the plate treatment. */
:root[data-palette="blacktop"] .filter-chip-active {
  border-color: var(--sem-chip-fill);
}
:root[data-palette="blacktop"] .filter-chip-alert.filter-chip-active {
  border-color: var(--sem-chip-alert-fill);
}

/* ===========================================================================
   THE ATTENTION TILES — four enamelled panels with a chrome catch along the
   top edge, which is where a lit panel actually catches.

   RE-PITCHED, all four. The base grounds are SCP brand teal, mustard, salmon
   and stone, and on a black-and-amber page the teal one would be the only cool
   thing present and would read as a foreign object — which is exactly the A4
   finding that put halloween's tiles three weeks unnoticed. They move onto the
   same instrument cluster as the chips: green running, amber take note, red
   fault, gunmetal inert.

   They stay DARK in both variants, like Electricity's. `.stat-tile` carries a
   fixed `color: #fff` in the app's own stylesheet for the figure, the label
   and the caveat, so a pale tile in light mode would need three ink repairs to
   undo one — and a repair like that is what survived onto matrix's transparent
   tiles and measured 1.13:1. White on these: 11.09 / 9.89 / 11.87 / 11.54.
   =========================================================================== */
/* The bevel is the SAME pair as the chips and for the same reason: one lit pixel
   at the top, one shadowed at the bottom, no blur, nothing under the figure or
   the caveat. The ratios in the manifest are untouched by it. */
:root[data-palette="blacktop"] .stat-tile {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.30),
    inset 0 -1px 0 rgba(0, 0, 0, 0.42);
}
:root[data-palette="blacktop"] .stat-tile-teal   { background: #16442a; }
:root[data-palette="blacktop"] .stat-tile-amber  { background: #5c3d00; }
:root[data-palette="blacktop"] .stat-tile-salmon { background: #6a1a12; }
:root[data-palette="blacktop"] .stat-tile-grey   { background: #333a40; }

/* ===========================================================================
   THE APPEARANCE PANEL — material only. Its structure (where it sits, how big
   it is) belongs to chrome.css and a test fails on a theme that puts any of it
   back; what is left, and all this theme wants, is that the panel is a chromed
   plate rather than a card.
   =========================================================================== */
:root[data-palette="blacktop"] .appearance-panel {
  border: 1px solid var(--bt-rule-firm);
  border-radius: 0.2rem;
  background-image: var(--bt-brush);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.30),
    inset 0 -1px 0 rgba(0, 0, 0, 0.30),
    0 10px 28px -12px rgba(0, 0, 0, 0.65);
}

/* Cards are panels too: the same bevel, the same brushed face, and the chrome
   band along the top edge where a lid would be screwed down. `article` is
   Pico's card; this is the widest surface in the app after the page itself, so
   the grain is the low-alpha pair rather than anything stronger. */
:root[data-palette="blacktop"] article {
  background-image:
    var(--bt-chrome-band),
    var(--bt-brush);
  background-repeat: no-repeat, repeat, repeat;
  background-size: 100% 2px, auto, auto;
  background-position: left top, left top, left top;
  box-shadow:
    inset 0 -1px 0 rgba(0, 0, 0, 0.26),
    inset 0 -8px 10px -12px var(--bt-bounce);
}

/* ===========================================================================
   REDUCED MOTION. This theme has ONE ambient animation — the forecourt lamp on
   the topbar's chrome band — so it declares `--theme-motion: 1` and the
   Appearance panel's Motion control applies to it (`[data-motion="off"]` is
   handled beside the animation itself, further up). This block is the OS
   preference, which is honoured independently of that control: somebody who
   asked for less movement gets none, not a subtler version of it. The first
   build genuinely had no ambient motion and said so here; the maintainer asked
   for motion on 2026-09-18 and this paragraph was the half that did not move.
   =========================================================================== */
@media (prefers-reduced-motion: reduce) {
  /* THE LAMP STOPS. Off, not slowed — somebody with vestibular sensitivity is
     not asking for a gentler flicker. The band stays exactly where it is at
     full strength; only the animation goes, so nothing about the page's
     appearance or contrast depends on whether this query matched. */
  :root[data-palette="blacktop"] .topbar::after {
    animation: none;
  }
  :root[data-palette="blacktop"] :focus-visible,
  :root[data-palette="blacktop"] .sidebar-nav a,
  :root[data-palette="blacktop"] button:not(.secondary):not(.outline):not(.th-sort):not(.sidebar-toggle):not(.hubmenu-icon-button):not(.hubmenu-avatar-button):not(.hubmenu-item-button):not(.theme-choice):not(.app-dialog-ok-danger),
  :root[data-palette="blacktop"] [role="button"]:not(.secondary):not(.outline),
  :root[data-palette="blacktop"] input[type="submit"] {
    transition: none;
  }
}

/* Paper has no chrome and no lamp. Colour on paper belongs to print.css, which
   loads after every theme and forces dark ink for all of them — nothing here
   sets a colour, only turns off the material. */
@media print {
  :root[data-palette="blacktop"] .stat-tile,
  :root[data-palette="blacktop"] article,
  :root[data-palette="blacktop"] .status-badge,
  :root[data-palette="blacktop"] .filter-chip,
  :root[data-palette="blacktop"] .sidebar-nav a.active {
    box-shadow: none;
  }
}

/* ===========================================================================
   APP GLYPHS — a CAST BADGE. The plate is the lamp's amber, graded hot at the
   top to deep at the foot, with the bevel this theme puts on its metal (a
   light top edge, a dark bottom edge); the glyph is the near-black ink,
   EMBOSSED by a one-pixel highlight above and shade below, so it reads as
   stamped into the plate rather than printed on it. Motion is the SHEEN: on
   hover a band of lamp-catch light sweeps across the badge once, left to right,
   the way a headlamp crosses a fuel-tank emblem. It rides the plate's inert
   ::after from chrome.css (structure there, the light here). One-shot, so it
   adds nothing to this theme's --theme-motion (the lamp is already ambient);
   it yields to prefers-reduced-motion and the Motion switch.
   =========================================================================== */
:root[data-palette="blacktop"] .app-glyph-plate {
  background: linear-gradient(165deg, var(--bt-amber-hot) 0%, var(--bt-amber) 45%, var(--bt-amber-deep) 100%);
  color: var(--bt-on-amber);
  border-radius: 0.5rem;
  box-shadow: inset 0 1px 0 var(--bt-bevel-hi), inset 0 -1px 0 var(--bt-bevel-lo), 0 1px 3px rgba(0, 0, 0, 0.42);
}
:root[data-palette="blacktop"] .app-glyph-layer { filter: drop-shadow(0 1px 0 var(--bt-bevel-hi)) drop-shadow(0 -0.6px 0 var(--bt-bevel-lo)); }
:root[data-palette="blacktop"] .app-glyph-plate::after {
  background: linear-gradient(115deg, transparent 38%, var(--bt-lamp-catch) 50%, transparent 62%);
  transform: translateX(-120%);
}
@keyframes bt-glyph-sheen {
  0%   { transform: translateX(-120%); opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateX(120%); opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  :root[data-palette="blacktop"]:not([data-motion="off"]) :is(.home-card, .hub-app-tile):is(:hover, :focus-visible) .app-glyph-plate::after { animation: bt-glyph-sheen 0.85s ease-out 1; }
}

/* THE LOGO, THEMED (optional; Appearance → Logo, 2026-09-20): the mark in the
   lamp's amber with a faint bloom, like the badge. The original stays the default. */
:root[data-palette="blacktop"] { --logo-themed: 1; --logo-tint: var(--bt-amber); --logo-glow: drop-shadow(0 0 6px var(--bt-glow-soft)); }

/* ===========================================================================
   BADGES — a sticker on the ASPHALT (2026-10-02, S182): the lamp's amber hex
   with the near-black ink, the deep amber for the accent, a warm paper, and a
   die-cut edge of the bright chrome this theme puts on everything, catching
   the sodium lamp's glow from below. The same sticker in both modes.
   =========================================================================== */
:root[data-palette="blacktop"] .badge-medal {
  --badge-disc: var(--bt-amber);
  --badge-glyph: var(--bt-on-amber);
  --badge-rim: var(--bt-amber-deep);
  --badge-paper: #fff1d6;
  --badge-backing: #f4f4f4;
  --badge-locked-line: var(--pico-muted-color);
}
:root[data-palette="blacktop"] .badge-medal:not(.is-locked):not(.is-hidden) > svg { filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.35)) drop-shadow(0 0 6px var(--bt-glow-soft)); }

/* ---------------------------------------------------------------------------
   THE 404 EASTER EGG (DOCKET 107, 2026-11-02; views/chrome/notFound.ejs).
   A road-closed barricade, its lamp still going.
   chrome.css hides all eight jokes; this file shows its own, sets the
   drawing's four colours and adds one short flourish, never for anybody who
   has asked for less motion.
   --------------------------------------------------------------------------- */
:root[data-palette="blacktop"] .nf-joke[data-nf-for="blacktop"] { display: grid; }
:root[data-palette="blacktop"] .nf {
  --nf-ink: var(--bt-ink);
  --nf-soft: #1a1612;
  --nf-accent: var(--bt-amber);
  --nf-accent-2: var(--bt-ink-2);
}
:root[data-palette="blacktop"] .nf-art .nf-lamp { filter: drop-shadow(0 0 5px var(--bt-glow)); }
:root[data-palette="blacktop"] .nf-code { color: var(--bt-ink); text-shadow: 0 0 0.4em var(--bt-glow); }
@media (prefers-reduced-motion: no-preference) {
  :root[data-palette="blacktop"]:not([data-motion="off"]) .nf-joke[data-nf-for="blacktop"] .nf-lamp { animation: nf-blacktop-lamp 0.8s steps(1) 0.2s 3 both; }
}
@keyframes nf-blacktop-lamp {
  0% { opacity: 1; } 50% { opacity: 0.25; }
}

/* ---------------------------------------------------------------------------
   THE LOST-COMPUTER MAP'S COLOURS (Device Manager, backlog S221, 2026-11-02).
   Asphalt, and the highways lit amber like sodium lamps. chrome.css derives every --map-* token from the page's colours; these
   give this theme's map its own. Colour only; each follows light and dark
   because the theme's own tokens do.
   --------------------------------------------------------------------------- */
:root[data-palette="blacktop"] {
  --map-road: color-mix(in srgb, var(--bt-ink) 18%, var(--pico-background-color));
  --map-road-major: color-mix(in srgb, var(--bt-amber) 46%, var(--pico-background-color));
  --map-label: var(--bt-ink-2);
  /* The ring is amber pulled toward the ink, so it stands out from the amber roads in both modes. */
  --map-accent: color-mix(in srgb, var(--bt-amber) 62%, var(--bt-ink));
  --map-trail: var(--bt-ink-2);
}
