/* =============================================================================
 * Frihat Legal Platform — Design System · 00 · TOKENS
 * =============================================================================
 *
 * PURPOSE
 *   The single source of truth for every value in the Frihat design system:
 *   colour, space, radius, typography, elevation, glass, motion, z-index,
 *   control sizing and layout. This file contains NOTHING but custom property
 *   declarations. It defines no selectors that paint.
 *
 * LAYER POSITION
 *   First file in the bundle. Every other Frihat stylesheet (01-base and up)
 *   and every page-level stylesheet reads from here.
 *
 * DEPENDENCIES
 *   None. This file must never depend on another stylesheet, and must never
 *   contain an at-rule import (the bundler concatenates these files into the
 *   middle of the LeptonX global bundle, where an import is invalid).
 *
 * THE ONE RULE
 *   Components consume SEMANTIC tokens, never primitives.
 *   Primitives carry the prefix fx-p-* and exist only so the semantic layer has
 *   something to point at. If a component references an fx-p-* name, that is a
 *   defect: the missing semantic token should be added here instead.
 *
 * THE SECOND RULE
 *   No layout box carries a fixed pixel width. Sizes are fluid by construction
 *   here, and call sites compose them with min(), max(), clamp(), %, ch and fr.
 *   Viewport height uses dvh or svh, never bare vh.
 *
 * TOKEN GROUPS (in file order)
 *   1) Primitives — green ramp, olive ramp, MINT ramp, neutral ramp, status hues,
 *      fixed brand
 *   2) Semantic colour — LIGHT
 *   3) Semantic colour — DARK
 *   3.9) ACCENT DISCIPLINE — a brand SURFACE and a brand MARK are identity; a
 *        tint is interaction. READ THIS. It supersedes the six-site rule of the
 *        second pass, and it is stated as a derivation, not as a list.
 *   4) Space (fluid) and radius
 *   5) Typography — families, fluid sizes, leading, weight, tracking
 *   6) Elevation, glass
 *   7) Motion
 *   8) Z-index
 *   9) Controls and sizing, including the coarse pointer tier
 *  10) Layout — fluid padding, gutters, container, breakpoint tiers
 *  11) Accessibility overrides — prefers-contrast, forced-colors
 *  12) LEGACY ALIASES — old names kept alive, mapped onto the new semantics
 *  13) PALETTE FAMILIES — petrol, plum, sand, indigo, navy, graphite and violet,
 *      each a full derivation rather than a hue rotation. Read 13.0 before adding
 *      a ninth family. 13.4 restates section 11 and MUST stay last, so 13.5, 13.6,
 *      13.7 and 13.8 are numbered after it and placed before it.
 *
 * THE 2026-08-02 LINEAR RETUNE
 *   The foundation was re-measured against linear.app's shipped CSS on
 *   2026-08-02 (client reference). What changed, in one list:
 *     · four surface levels, adjacent steps compressed to 1.04 to 1.06:1
 *     · FOUR text tiers instead of three — a quaternary was added
 *     · two SEPARATE line families: translucent borders for floating edges,
 *       opaque lines for in-flow separators. Do not collapse them.
 *     · shadows are weak and separate by BLUR, not by darkness
 *     · focus is a 2px outline at 2px offset. Not a glow, not a halo.
 *     · brand colour is spent on six things and nothing else — SUPERSEDED by
 *       the third pass below; see 3.9 for the contract actually in force
 *     · the radius floor is 4px and the default control is a full pill
 *     · motion is 60 to 180ms, with 500ms reserved for a full-height panel
 *   The Frihat green and olive hues are FROZEN and did not move. Only which
 *   ramp step a semantic token points at, and how sparingly it is spent, moved.
 *
 * THE 2026-08-02 SECOND PASS — CLOSING THE GAPS
 *   The six component layers were restyled against the contract above and
 *   reported back. What that surfaced, and what changed here:
 *     · THE SCRIM WAS STRUCTURALLY WRONG. It was one dark ink at two alphas.
 *       A scrim is a different COLOUR per theme — white in light, black in
 *       dark. See 2.1.2, which is the most consequential fix in this pass.
 *     · fx-color-overlay was an opaque alias of level 3, so a busy overlay
 *       HID the region instead of dimming it. It is now the busy veil, and the
 *       opaque meaning moved to fx-color-overlay-solid. Also 2.1.2.
 *     · THE STATUS TRAP IS NOW DOCUMENTED, IN BOTH THEME BLOCKS. The bare
 *       solids are light-only by design and are FILL-UNDER-A-LIGHT-LABEL ONLY;
 *       text and boundaries take -fg. See 2.7 and 3.7. One layer had already
 *       shipped a 2.31:1 dark failure from this.
 *     · 250ms LEFT THE BANNED BAND. fx-dur-slow was 250ms while this file
 *       banned 200 to 400ms; it is now 180ms. See the ruling in section 7.
 *     · MISSING RUNGS FILLED: fx-dur-quick (120ms), fx-space-1-5 (6px),
 *       fx-radius-badge (7px), fx-border-width-mid (1.5px), fx-badge-h-sm
 *       (20px), fx-row-h-spacious, fx-section-label-h, fx-dialog-band-h,
 *       fx-menu-item-pad-x, fx-shadow-bevel, the four fx-color-text-on-*
 *       status inks, and the fx-anchor-w popup convention.
 *     · DEPRECATED TOKENS AUDITED for live consumers and each one marked in
 *       place. Nothing was deleted — section 12's contract holds.
 *
 * THE 2026-08-02 THIRD PASS — PUTTING THE BRAND BACK
 *   The six-site accent rule of the second pass, applied literally across nine
 *   stylesheets, removed the Frihat green from the product. The client's
 *   verdict: the brand colour does not exist now. Section 3.9 is rewritten
 *   around a new contract, and it is the authoritative one:
 *
 *       IDENTITY AND CURRENT POSITION ARE BRAND. INTERACTION IS NEUTRAL.
 *
 *   What that changed here, in one list:
 *     · SECTION 3.9 IS REWRITTEN, not amended. It now sanctions ten sites, of
 *       which five are new, and it carries an equally explicit FORBIDDEN list
 *       so the correction cannot overshoot into a themed Bootstrap panel.
 *       THE COUNT IS SUPERSEDED: the fifth pass took it to thirteen and stopped
 *       counting, because a list that moves three times in a day is not a rule.
 *       The FORBIDDEN half is unchanged and still binds.
 *     · THE FOCUS RING IS BRAND IN LIGHT TOO. It was translucent ink; it is
 *       now green-800, measured at 7.24:1 worst case against level 0 to 3
 *       versus the old ring's 3.47:1. Dark stays green-500 and is re-verified.
 *       See 2.8 and 3.8.
 *     · TWO TOKENS ADDED — fx-color-indicator and fx-color-brand-text, the
 *       semantics the five new position sites point at. They diverge onto
 *       different ramps in dark and that divergence is the reason there are
 *       two of them. See 2.5.1 and 3.5.1.
 *     · Both new tokens promote under prefers-contrast: more, alongside the
 *       ring and the link, in section 11.
 *   Nothing was renamed and nothing was deleted. The green and olive hues are
 *   still FROZEN — this pass moved which ramp step a semantic points at and
 *   WHERE brand is allowed to be spent, never a hue.
 *
 * THE 2026-08-02 FOURTH PASS — THE INTERACTION WASH STOPS BEING GREY
 *   The third pass put the brand back on identity and position but left the
 *   interaction washes as neutral ink at 5 and 8 percent, faithful to the
 *   reference. The client rejected that twice, in these words: not ok with
 *   colors and highlighting grey color, prefer we stick with light green shades
 *   96DD99, A5E1A6, C2E9BF, D7F5D3, B3E5B3. Those five hexes are now a
 *   primitive ramp of their own and they are FROZEN exactly like green and
 *   olive. What that changed here, in one list:
 *     · A MINT RAMP JOINS THE PRIMITIVES — see 1.2.1. Client supplied, frozen,
 *       five rungs, light to deep. An intermediate value comes from color-mix()
 *       of two rungs so the ramp stays the only source of the hue.
 *     · THE LIGHT WASHES ARE OPAQUE MINT. fx-color-hover is mint-100 and
 *       fx-color-active is one step deeper. They are opaque rather than
 *       translucent on purpose: a translucent mint renders as a different hex
 *       on every one of the four planes, and the client asked for THESE five
 *       colours, not for a family of composites derived from them. See 2.8.
 *     · THE DARK WASHES ARE THE SAME RAMP AT LOW ALPHA — mint-500 at 6 and 10
 *       percent, which reproduces the previous greys' lift almost exactly
 *       (1.134 against 1.130, 1.254 against 1.226) while tinting them green.
 *       Five light hexes used as dark FILLS would have inverted the elevation
 *       model. See 3.8.
 *     · THE MINT RAMP SOLVED A STANDING CONSTRAINT. Brand green could not be
 *       TEXT on the dark page — the frozen green ramp tops out at green-700 at
 *       3.24:1 — which is why dark brand text and the dark link were both
 *       forced onto olive. mint-500 measures 8.99 to 10.44:1 across the four
 *       dark planes, so both moved onto it and the dark theme now reads the
 *       client's own green as text. See 3.5.1 and 3.6.
 *     · SECTION 3.9 IS REWORDED, NOT REOPENED. The contract is unchanged:
 *       identity and position are brand, interaction is a TINT. What changed is
 *       that the tint is no longer grey. The FORBIDDEN list is what keeps this
 *       from sliding into a themed panel and it still binds.
 *     · fx-shadow-focus WAS THE WRONG SHAPE. It ringed at zero offset while
 *       every outline in the platform rings at 2px offset — invisible against
 *       the old translucent ink, obvious against the green-800 ring. It is now
 *       a two layer shadow that reproduces the outline geometry. See section 6.
 *   Nothing was renamed and nothing was deleted.
 *
 * THE 2026-08-02 FIFTH PASS — THE RULE IS STATED, NOT THE LIST
 *   A verification pass found that 3.9's closed list of ten sites had fallen
 *   behind the product and contradicted 2.5. Both are reconciled here. No hue
 *   moved, no token was renamed, no token was deleted, and the FORBIDDEN half of
 *   3.9 is untouched. What changed, in one list:
 *     · 3.9 IS RESTATED AS A DERIVATION. Brand appears as a SURFACE (a fill that
 *       replaces the plane under other content and says whose product this is),
 *       as a MARK (a small signal drawn ON a plane that says where you are), or
 *       not at all. Interaction is a tint in every case. A reader can now derive
 *       a site instead of memorising one, which is what the list failed to do
 *       when it had to be extended three times in a single day.
 *     · THREE SURFACES ARE WRITTEN IN, as sites 11, 12 and 13. All three were
 *       already live, all three were asked for by the client on 2026-08-02, and
 *       none of them mapped to a numbered site: the SIDEBAR RAIL and mobile nav
 *       (03-leptonx), the WELCOME BANNER and the QUICK LINK ICON TILE (11-home).
 *       The contract was behind the product; it is not any more.
 *     · THE SURFACE CLAUSE IS NEW AND IT IS THE PRICE OF THE THREE. Every ink,
 *       glyph, line, wash, field and ring on a brand surface is re-derived
 *       against that surface. The rail proved why: fx-color-indicator is the
 *       light rail's own fill and measures 1.95:1 on the dark rail's active row.
 *     · A LIST MARKER IS NO LONGER A BRAND SITE. 2.5 sanctioned one and 3.9
 *       never listed one; the contradiction is resolved against 2.5. A bullet
 *       answers neither question in 3.9 and recurs without bound, so it is a
 *       text tier. See the ruling in 3.9's FORBIDDEN list; 01-base still paints
 *       li::marker from fx-color-accent and is a known follow-up.
 *
 * THE 2026-08-03 SIXTH PASS — THE BRAND MOVES OFF THE RAIL AND ONTO A BAND
 *   The client measured the shell against clio.com and linear.app and reported
 *   that the sidebar was "not even close" to either. Neither product runs a
 *   saturated brand plane behind navigation: Linear's rail has no surface at all
 *   and separates chrome from work by ELEVATING THE CONTENT, and Clio's rail is
 *   a near black with the brand spent on a full bleed header band. He chose
 *   Clio's model. What changed here, in one list:
 *     · ONE TOKEN ADDED — fx-color-rail, in 2.4.1. green-900 mixed 55 percent
 *       toward black, L* 10.9, ONE VALUE IN BOTH THEMES. Derived from the frozen
 *       ramp rather than typed, so the rail keeps the brand hue while reading as
 *       almost black. Its full four tier ladder and its three washes are
 *       measured over the token.
 *     · 3.9 SITE 11 IS REWRITTEN, not amended, and now covers BOTH shell planes
 *       — the brand band and the rail under it. The count of surfaces is still
 *       three. The stale description of the rail as fx-color-primary is gone.
 *     · THE ACTIVE NAV ROW'S BRAND BAR IS WITHDRAWN ON THE RAIL ONLY, on the
 *       arithmetic recorded in site 11. Site 1 still governs an active row on a
 *       page plane and is unchanged.
 *     · NOTHING ELSE MOVED. No ramp, no hue, no rename, no deletion. The FORBIDDEN
 *       halves of 3.9 are untouched, and so is the surface clause they price.
 *
 * THE 2026-08-03 SEVENTH PASS — ONE SURFACE IS RETIRED AND THE BUTTON STOPS
 * BEING A PILL
 *   Two client decisions taken the same day, plus one stale cross reference found
 *   while recording them. No ramp moved, no hue moved, nothing was renamed and
 *   NOTHING WAS DELETED. What changed, in one list:
 *     · 3.9 SITE 12 IS RETIRED, NOT DELETED. The dashboard welcome banner was
 *       sanctioned as a brand SURFACE on 2026-08-02 at the client's request and
 *       REVERSED on 2026-08-03, when the brand moved to a full bleed green top
 *       bar and the two planes measured as the SAME FILL 44px apart. A surface is
 *       a dated client decision, so the reversal is recorded as a decision rather
 *       than as a gap: the original reasoning is kept verbatim and marked
 *       superseded. THE SURFACE COUNT IS NOW TWO, sites 11 and 13.
 *     · THE WARNING ABOVE SITE 11 IS DISCHARGED. It flagged "site 12 and site
 *       11's band resolve to the same fill" as a live question with the client.
 *       He answered it. The note now records the answer instead of the question.
 *     · SITE 13 IS UNTOUCHED. The quick link icon tiles were not part of this
 *       decision and remain the only brand fill on the dashboard. One clause in
 *       that entry compared the tile to the banner and is corrected to name the
 *       band, which is a cross reference repair and not a re-ruling.
 *     · A STALE FIGURE IN 2.5.1 IS CORRECTED. Its prose still said dark brand
 *       TEXT lands on olive-400 at 8.88:1, one pass behind the token, which has
 *       read mint-500 since the fourth pass and is recorded correctly in 3.5.1.
 *       The file was contradicting itself about one token. No declaration moved.
 *     · fx-radius-control LEAVES THE PILL. Client decision, 2026-08-03, measured
 *       on the running app: the stadium button was the only element off the
 *       radius ladder on the sign in screen and it inverted the ladder on two
 *       others. It is now fx-radius-md. fx-radius-pill is UNCHANGED. See the
 *       reasoning recorded over the token in section 4.
 *
 * THE 2026-09-04 SIXTH PASS — THREE FAMILIES JOIN THE SYSTEM
 *   Note on the ordinal, so nobody spends time reconciling it: two entries above
 *   are already dated 2026-08-03 and numbered sixth and seventh, and they are
 *   SHELL passes. This is the sixth pass over the COLOUR SYSTEM. The DATE is the
 *   key in this header, not the count, and no earlier entry is renumbered.
 *
 *   The owner chose three further colour families on 2026-09-04, so the platform
 *   now ships EIGHT THEMES: four families in light and dark. الزيتي is unchanged
 *   and remains the default; الأزرق البترولي (#0F766E), النبيذي (#B03052) and
 *   الرملي الدافئ (#D4B483) join it. What changed, in one list:
 *     · TWO OF THOSE THREE SEEDS ARE THE OWNER'S SECOND CHOICE, taken the same
 *       day on the rendered swatches: «النبيذي يبدو بنفسجي، والرملي الدافئ يبدو بني».
 *       النبيذي was #86198F, which is a fuchsia rather than a wine, and الرملي
 *       was #A16207, whose hue was right and whose lightness and saturation made
 *       it a brown. Only those two families were re-derived; petrol and olive did
 *       not move. THE SAND SEED IS THE FIRST ONE LIGHTER THAN THE MID RAMP and it
 *       lands on rung 300 rather than 700. It was NOT darkened back onto 700 —
 *       that would have reinstated the brown. See the identity clause in 13.0.
 *     · SECTION 13 IS NEW and it is where all of it lives. Six blocks on a new
 *       data-fx-palette attribute, orthogonal to data-bs-theme, plus a restated
 *       prefers-contrast query. The full selector scheme, the specificity math
 *       and the one source order rule that scheme forces are in 13.0.
 *     · A HUE ROTATION WAS NOT ACCEPTABLE AND IS NOT WHAT THIS IS. Each family
 *       carries its OWN neutral ramp, its OWN interaction wash ramp, its OWN
 *       dark chrome, its OWN shadow ink and its OWN status tint backgrounds. The
 *       neutral is the one that decides it: 1.3 tints the greys green so they
 *       never read cold beside the olive, and a green tinted grey under a plum
 *       page is exactly what makes a theme look rotated rather than designed.
 *     · THE MINT RAMP IS NOT EXTENDED, NOT TINTED AND NOT REUSED. 1.2.1 freezes
 *       it for olive and it stays frozen; there is still no sixth rung. Each new
 *       family gets a SEPARATE five rung wash ramp at mint's five luminances, so
 *       the washes land at the identical lift the fourth pass measured.
 *     · THE METHOD IS LUMINANCE PRESERVING HUE TRANSPOSITION. Every derived
 *       value carries the exact relative luminance of the olive value it
 *       replaces, so every ratio this file has measured transfers unchanged.
 *       Verified: 932 pairs across the eight themes, zero failures, worst
 *       divergence from olive 0.25 of a ratio point on a 16.8:1 rail ink. The
 *       ladder's 1.04 to 1.06 steps hold to the third decimal and no adjacent
 *       pair measures 1.000 in any theme.
 *     · 3.9 IS UNTOUCHED AND STILL BINDS IN EVERY FAMILY. A new family is a new
 *       HUE, never a new licence. The FORBIDDEN half is unchanged, the surface
 *       count is still two, and the surface clause is paid: each family records
 *       its band's and its rail's inks, washes and marks measured against those
 *       surfaces' own fills, in both modes.
 *     · THE STATUS HUES DO NOT MOVE. Only the two tint BACKGROUNDS per status
 *       are re-derived, so they sit on the family's neutral; the ruling and the
 *       0.35 cast fraction that keeps a success tint recognisably green are
 *       recorded in each family's 13.x.6.
 *     · FOUR SWATCH TOKENS WERE ADDED IN 2.9, in the DEFAULT block rather than
 *       per family. They are the one deliberate palette independent exception in
 *       the file and the reason is written over them: the picker shows all four
 *       families at once.
 *     · ONE TOKEN ADDED FOR A DEFECT THE COMPONENT LAYER FOUND, in 2.4.3 and
 *       3.4.2. 05-forms measured the selected select2 option and the selected
 *       datepicker day and reported fx-color-primary at 2.94:1 against the
 *       raised plane, short of the 3:1 SC 1.4.11 asks of a state. Re-measured
 *       here it is systemic and slightly worse: 3.24 / 3.09 / 2.94 / 2.79 on
 *       levels 0 to 3, IDENTICAL IN ALL FOUR DARK THEMES, and worst on the
 *       float plane a dropdown actually uses. THE FILL DID NOT MOVE, because
 *       the window between its own two floors is 0.0147 of luminance wide, no
 *       rung lies in it, and every mix that does costs an outright AA failure
 *       on the second ink tier to buy two hundredths of SC 1.4.11 headroom.
 *       fx-color-primary-border is added instead, on the precedent 2.7 already
 *       set for the status trio, and it is the 600 rung at 3.60:1 worst case.
 *       It promotes in section 11 with the other signals.
 *     · ONE DEFECT FIXED OUTSIDE THIS FILE. 13-chat's call disc consumed
 *       fx-p-mint-700, which is a primitive read from a component AND a name
 *       that has never existed, so a hardcoded teal was painting on every theme.
 *       It now reads the status tint pair it always meant.
 *     · RAISED, NOT SILENTLY CORRECTED: the plum brand now sits 20 degrees of
 *       OKLCH hue from the danger red, which is the closest a brand and a status
 *       hue come anywhere in the system. النبيذي is a wine and a wine is red
 *       dominant, so this comes with the colour the owner chose. It is a
 *       recognition question and not a contrast one, the two are 1.36:1 apart in
 *       LIGHTNESS as fills, and the arithmetic and the mitigation are recorded in
 *       13.2. The same entry previously flagged the sand seed at 17 degrees from
 *       the warning amber; the new sand seed measures 28.7 and that flag is
 *       discharged, without the hue being rotated to open the gap.
 *     · THE PLUM ACCENT OFFSET CHANGED SIGN, because the standing rule that the
 *       accent must not collide with a status hue finally bound: a positive
 *       rotation landed 7 degrees from the danger red. See 13.2.
 *   Nothing was renamed, nothing was deleted, and no olive value moved.
 *
 * THE 2026-09-04 SEVENTH PASS — INDIGO AND NAVY
 *   The owner chose two further colour families on 2026-09-04, the same day as
 *   the three above and after seeing them rendered, so the platform now ships
 *   SIX FAMILIES x TWO MODES = TWELVE THEMES. الزيتي is unchanged and remains the
 *   default. النيلي and الكحلي join الأزرق البترولي, النبيذي and الرملي الدافئ.
 *   NOT ONE OLIVE, PETROL, PLUM OR SAND VALUE MOVED, by explicit owner
 *   instruction, and the mirror and cascade checks below prove it rather than
 *   assert it.
 *
 *     · THESE SEEDS CAME AS SIX VALUES, NOT TWO. The owner supplied a triple per
 *       mode — أساسي, خلفية and نص عليها — and they are recorded verbatim:
 *           النيلي  light  #4C5BD4  #EEF0FC  #2C3585
 *           النيلي  dark   #8A93F0  #282D52  #C7CCFA
 *           الكحلي  light  #0B4F9E  #E7F0FA  #083A75
 *           الكحلي  dark   #5B9BE8  #14314F  #BBD7F6
 *       That is more constraint than one hex, not less, and each of the twelve
 *       values is placed against a named token in 13.5 and 13.6 with the OKLab
 *       distance between what he typed and what shipped.
 *     · نص عليها IS NOT fx-color-text-on-primary AND THE DIFFERENCE IS AN AA
 *       FAILURE. Measured, his ink on his own أساسي: 1.92 / 1.79 / 1.40 / 1.94:1
 *       across the four family and mode combinations. On his خلفية the same inks
 *       measure 9.47 / 8.47 / 9.74 / 8.95:1. It is the ink for the SUBTLE GROUND,
 *       so it lands on fx-color-brand-text, fx-color-link and fx-color-indicator,
 *       at rung 900 in light and on the wash ramp in dark. Assigning it to the
 *       ink on the solid fill would have produced two families that look right in
 *       a swatch and fail on every button.
 *     · ONE SUPPLIED VALUE COULD NOT BE HONOURED WHERE IT WAS OFFERED, AND IS
 *       REPORTED RATHER THAN MOVED IN SILENCE. The dark أساسي of both families is
 *       a bright colour built to carry dark ink; this system's dark brand fill
 *       carries white. White on them measures 2.80:1 and 2.88:1 against the 4.5
 *       SC 1.4.3 asks of a button label, where the system's own dark fill measures
 *       5.16:1. Both are honoured at the rung their own OKLab lightness puts them
 *       on, rung 500, which in dark IS fx-color-indicator and fx-color-focus-ring
 *       — the bright brand MARK that 3.5.1 already defines. Nothing was fudged and
 *       no ink forked per palette.
 *     · THE DARK خلفية VALIDATED A FORMULA THIS FILE ALREADY HAD.
 *       fx-color-primary-subtle in dark is the dark fill at 20 percent alpha.
 *       Composited over each family's level 1 card it lands within OKLab dE 0.0053
 *       (النيلي) and 0.0010 (الكحلي) of the value the owner typed. Nothing was
 *       tuned to make that happen; it is evidence that his trio and this file's
 *       trio are the same three roles under different names.
 *     · RAISED LOUDLY, NOT CORRECTED: الكحلي IS THE INFO STATUS HUE. p-blue-600
 *       sits at OKLCH hue 254.2 and this brand at 254.4 — 0.2 of a degree, against
 *       the previous record of 19.9 held by النبيذي and the danger red. It is not
 *       a contrast defect; every info pairing measures within a hundredth of
 *       olive. It is a RECOGNITION problem in two places: as fills the two
 *       separate only by lightness, at 1.28:1, and as pale TINTS they do not
 *       separate at all, at OKLab dE 0.0100. On this family the icon and the label
 *       carry the info meaning, which is what SC 1.4.1 asks for anyway. النيلي is
 *       21.2 degrees from the same hue and is comfortable. THE HUES WERE NOT
 *       ROTATED TO OPEN EITHER GAP; the owner chose these colours.
 *     · THE 0.35 STATUS CAST FRACTION IS NOT UNIVERSAL AFTER ALL, AND THE RULE IS
 *       WHAT SAID SO. It is defined as the LARGEST fraction at which every tint
 *       stays within 30 degrees of the olive tint it replaces. At النيلي's hue the
 *       emerald light tint drifts 37.8 degrees at 0.35, so that family takes 0.30
 *       and measures 26.6 worst case. الكحلي keeps 0.35 at 28.2. The three earlier
 *       families were NOT re-derived; their 0.35 still satisfies the bound.
 *       Luminance is preserved either way, so the fraction costs no contrast.
 *     · THE SIX CHIPS WERE MEASURED AGAINST EACH OTHER, because a picker is the
 *       only place a user meets a family by name. Closest pair النيلي against
 *       الكحلي at OKLab dE 0.141, which is a hair under the four chip set's own
 *       closest pair (الزيتي against الأزرق البترولي, 0.143) and several times a
 *       just noticeable difference. They are only 20.8 degrees apart in hue and
 *       what rescues them is LIGHTNESS: they sit on different rungs, 1.60:1 apart
 *       as fills, which is the second largest lightness gap of any near hue pair
 *       in the set. Two swatch tokens joined 2.9 and both carry the same hairline.
 *     · THE 2.94 QUESTION FROM THE SIXTH PASS IS CLOSED. fx-color-primary against
 *       the raised plane was measured again in all twelve themes and against every
 *       plane the fill can land on: 3.24 / 3.09 / 2.94 / 2.79 on levels 0 to 3,
 *       identical to two decimals in all six families, and the plane a dropdown
 *       panel or a datepicker popup actually floats on is the HIGHEST one, where
 *       it is 2.79 rather than 2.94. Measuring against the true ground made it
 *       worse, not better. fx-color-primary-border, added in 3.4.2 for exactly
 *       this, measures 4.18 / 3.98 / 3.79 / 3.60 in every one of the twelve, so
 *       the boundary clears 3:1 with 0.60 to spare on the worst plane. The fill
 *       did NOT move and the reason is unchanged arithmetic. Recorded as a
 *       measured, deliberate carve-out: the state is carried by the rim and by the
 *       ink, which measures 5.16:1 on the fill, not by the fill alone.
 *     · NOTHING WAS RENAMED, NOTHING WAS DELETED, AND 3.9 IS UNTOUCHED. A new
 *       family is a new HUE, never a new licence. The FORBIDDEN half is unchanged,
 *       the surface count is still two, and the surface clause is paid: each new
 *       family records its band's and its rail's inks, washes and marks measured
 *       against those surfaces' own fills, in both modes.
 *
 * THE 2026-09-05 EIGHTH PASS — GRAPHITE AND VIOLET
 *   The owner chose two further colour families on 2026-09-05, so the platform now
 *   ships EIGHT FAMILIES x TWO MODES = SIXTEEN THEMES. الزيتي is unchanged and
 *   remains the default. الفحمي and البنفسجي join الأزرق البترولي, النبيذي,
 *   الرملي الدافئ, النيلي and الكحلي. NOT ONE VALUE OF ANY OF THE SIX EXISTING
 *   FAMILIES MOVED, by explicit instruction, and the mirror, cascade and divergence
 *   checks below prove it rather than assert it.
 *
 *     · THE SEEDS, RECORDED VERBATIM. Two per family, one per mode, and no more:
 *           الفحمي     light #475569   dark #94A3B8
 *           البنفسجي   light #9333EA   dark #C084FC
 *       Neither family arrived with a خلفية or a نص عليها, so unlike النيلي and
 *       الكحلي these seeds pin only the HUE and the CHROMA SCALE and every other
 *       role is derived by 13.0 rather than by the owner's eye.
 *     · EACH FAMILY ANSWERS A DIFFERENT GAP, AND THE REASONS ARE NOT THE SAME KIND
 *       OF REASON. البنفسجي fills the only clean HUE gap the set had left: measured
 *       on the six shipped chips the CSS hues are 36, 80, 175, 212, 233 and 344, and
 *       of the four openings in that ring three sit on top of a status — a green at
 *       about 140 on the success emerald, a crimson at about 10 on the danger red, a
 *       gold at about 58 on the warning amber. Violet at about 271 collides with
 *       none of them and measures 49.4 degrees of OKLCH hue from the nearest status,
 *       the info blue. الفحمي is not a colour at all. It is the ABSENCE of one, and
 *       it is on the list because in a tool people sit inside for a working day the
 *       neutral theme is the one most often chosen, and because its chip is the
 *       easiest of eight to identify precisely by not being a colour.
 *     · THE GREY FAMILY WAS DERIVED AGAINST A NAMED TRAP AND THE THREE NUMBERS ARE
 *       IN 13.7. A brand fill with no chroma reads as DISABLED, and this file ships
 *       a real fx-color-disabled-bg to be confused with. Measured: the fill sits
 *       OKLab dE 0.0378 (light) and 0.0488 (dark) from an achromatic grey of its own
 *       luminance, which is about two just noticeable differences, so it is a colour
 *       rather than grey paint; it clears its own disabled fill at 7.03:1 in light
 *       and 3.07:1 in dark, and carries its ink at 7.38:1 and 5.16:1 where a
 *       disabled control carries its own at 3.39:1 and 3.50:1.
 *     · RAISED LOUDLY, NOT CORRECTED: الفحمي SITS 2.8 DEGREES OF OKLCH HUE FROM
 *       الكحلي. That is the closest two BRAND hues have come anywhere in this system,
 *       against the previous record of 20.8 held by النيلي and الكحلي. It is not a
 *       contrast defect and it is not a hue that can be moved, because the owner
 *       chose it. WHAT SEPARATES THEM IS CHROMA: 0.0349 against 0.1363, a ratio of
 *       3.91 to 1, so one is a saturated blue and the other is a grey with a blue
 *       cast, which is what the two names say. The consequence reaches two further
 *       places and both are recorded rather than engineered around. The two families
 *       share their NEUTRAL RAMPS almost exactly, three of thirteen rungs byte
 *       identical and the worst of the rest at OKLab dE 0.0050, because at that
 *       chroma 2.8 degrees does not survive an 8 bit round trip. And the two CHIPS
 *       are now the closest pair in the picker.
 *     · THE CHIP SET WAS RE-MEASURED FOR EIGHT, ALL 28 PAIRS. The closest pair is
 *       now الكحلي against الفحمي at OKLab dE 0.102, taking over from النيلي against
 *       الكحلي at 0.141, and it is the first close pair in the set's history that is
 *       NOT rescued by lightness: both seeds land on rung 800, so they measure 1.00:1
 *       against each other as fills. They are rescued by CHROMA alone, at 0.102
 *       against a just noticeable difference of about 0.02, which is five times the
 *       threshold. البنفسجي does not make the set worse: its nearest neighbour is
 *       النيلي at dE 0.146, which is looser than the four tightest pairs already
 *       shipped. Two swatch tokens joined 2.9 and both carry the existing hairline.
 *     · ONE RULE IN 13.0 IS REFINED, FOR THE NEW FAMILIES ONLY, AND IT IS STATED
 *       RATHER THAN SLIPPED IN. The chroma scale relaxes linearly to 1.0 at rung 50
 *       so "the pale end of the ramp cannot go neon". That clause was written for
 *       scales ABOVE 1.0. At الفحمي's 0.395 the same formula runs the other way and
 *       would make the pale rungs two and a half times more saturated than the deep
 *       ones, which is a blue ramp with a grey bottom rather than a grey family. The
 *       relaxation is therefore read as a CAP, min(s, the linear relaxation), which
 *       is IDENTICAL to the shipped formula for every scale above 1.0 — النيلي and
 *       الكحلي re-derive byte for byte under it. الرملي الدافئ, at 0.842, WAS NOT
 *       RE-DERIVED and did not move.
 *     · THE PLACEMENT RULE AND THE OKLab DISTANCE DISAGREED FOR THE FIRST TIME, on
 *       البنفسجي. 13.0 places a seed by OKLab LIGHTNESS, which puts #9333EA on rung
 *       600 at dE 0.0694; by DISTANCE rung 700 would win at dE 0.0273. THE RULE WAS
 *       FOLLOWED AND THE NUMBER REPORTED. Choosing by distance would have raised the
 *       family's chroma scale from 1.830 to 2.025 and made every deep rung more
 *       saturated than the owner's own seed. 0.0694 is the widest seed to rung fit
 *       in the system; the previous widest was النبيذي at 0.0429, and the only place
 *       it is visible is the picker chip.
 *     · THE 0.35 STATUS CAST FRACTION WAS RE-SOLVED PER FAMILY, NOT COPIED. الفحمي
 *       takes 0.35 at a worst tint drift of 22.5 degrees; البنفسجي takes 0.30, at
 *       22.0, because 0.35 drifts the emerald light tint 37.8 degrees past the 30
 *       degree bound — the same failure النيلي hit and for the same reason. No
 *       earlier family was re-derived. Luminance is preserved either way, so the
 *       fraction costs no contrast.
 *     · 13.4 GAINED FOUR BLOCKS AND IS STILL THE LAST THING IN THE FILE. A family
 *       without its prefers-contrast promotions is an accessibility regression with
 *       no visible symptom in the default theme, which is the failure mode the
 *       seventh pass recorded. The two new families are numbered 13.7 and 13.8 and
 *       placed ABOVE 13.4, for the source order reason written at its head.
 *     · 3.9 IS UNTOUCHED AND STILL BINDS. A new family is a new HUE, never a new
 *       licence. The FORBIDDEN half is unchanged, the surface count is still two,
 *       and the surface clause is paid: each new family records its band's and its
 *       rail's inks, washes and marks measured against those surfaces' own fills, in
 *       both modes.
 *     · MEASURED ACROSS ALL SIXTEEN THEMES, 89 pairs per theme and 1424 in total
 *       plus the contrast promoted variants: the largest divergence from olive on
 *       any row either new family produces is 0.10 of a ratio point, on a 16.8:1
 *       rail ink. The ladder's 1.04 to 1.06 steps hold to the third decimal and no
 *       adjacent pair measures 1.000 in any theme.
 *   Nothing was renamed, nothing was deleted, and no olive, petrol, plum, sand,
 *   indigo or navy value moved.
 *
 * THEMING MODEL
 *   Light is the default and lives on html:root. Dark overrides live on
 *   html[data-bs-theme="dark"]:root — the attribute LeptonXLite and Bootstrap
 *   5.3 already use, and that wwwroot/frihat/frihat-theme.js flips.
 *   Custom property substitution is lazy, so every alias declared on the token
 *   layer automatically follows the dark override without being restated.
 *
 * WHY html:root AND NOT html
 *   html:root is specificity 0,1,1; a bare html selector is 0,0,1. A plain
 *   :root selector — the form almost every third party stylesheet reaches for —
 *   is 0,1,0, which BEATS a bare html. Declaring the token layer on html at
 *   0,0,1 would therefore hand our palette to any vendored library or module
 *   sheet that happens to drop a :root block into the bundle, silently and
 *   regardless of load order. Doubling up as html:root costs nothing, is
 *   still trivially overridden by any component class (0,1,0 plus), and puts
 *   the token layer above every :root block we do not control.
 *
 *   The ladder, so the numbers are on the record:
 *       html                             0,0,1
 *       :root                            0,1,0
 *       html:root                        0,1,1   ← the token layer
 *       html[lang^="ar"]:root            0,2,1   ← Arabic scale override
 *       html[data-bs-theme="dark"]:root  0,2,1   ← the dark theme
 *
 *   Every block in this file, including the ones nested inside media queries,
 *   carries the same :root qualification. Anything left at a bare html would
 *   lose to the base blocks above it and its overrides would silently not apply.
 *
 * COMMENT CONVENTION
 *   Token names appear in comments WITHOUT their leading double hyphen
 *   (fx-color-bg, not the declared form) so no tooling can mistake a comment
 *   body for a declaration. Em dashes are used for punctuation.
 *
 * PALETTE
 *   Ala'a Frihat's olive / dark green, carried over verbatim from the legacy
 *   PHP navbar and wwwroot/global-styles.css. The hues are FROZEN.
 * ========================================================================== */


/* ── 1) Primitives ─────────────────────────────────────────────────────────
 * Raw, mode independent. Never referenced by a component.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    /* 1.1 Green ramp — the brand spine. 700/800/900 are the frozen legacy values. */
    --fx-p-green-50:  #eff8f2;
    --fx-p-green-100: #dff2e7;
    --fx-p-green-200: #bfe6cf;
    --fx-p-green-300: #8fd3ac;
    --fx-p-green-400: #5cbd85;
    --fx-p-green-500: #35a862;
    --fx-p-green-600: #26914f;
    --fx-p-green-700: #1e7d43;   /* legacy frihat-green-700 */
    --fx-p-green-800: #145a32;   /* legacy frihat-green-800 — the legacy navbar */
    --fx-p-green-900: #0f3d22;   /* legacy frihat-green-900 */
    --fx-p-green-950: #0a2c18;

    /* 1.2 Olive ramp — الأخضر الزيتي. The decorative / accent family. */
    --fx-p-olive-100: #eaf2d6;
    --fx-p-olive-200: #dbe9b8;
    --fx-p-olive-300: #c3d98a;   /* legacy dark link hover */
    --fx-p-olive-400: #a7c957;   /* legacy dark link */
    --fx-p-olive-500: #85a13d;   /* legacy frihat-olive-2 */
    --fx-p-olive-600: #6b8e23;   /* legacy frihat-olive */
    --fx-p-olive-700: #5b7a1d;
    --fx-p-olive-800: #465e16;

    /* ══ 1.2.1 MINT RAMP — CLIENT SUPPLIED, FROZEN ═════════════════════════
     *
     * Added 2026-08-02 (fourth pass). These five hexes were given verbatim by
     * the client after the neutral interaction washes were rejected twice:
     * "I'm not ok with colors and highlighting grey color … I prefer we stick
     * with light green shades 96DD99, A5E1A6, C2E9BF, D7F5D3, B3E5B3."
     *
     * THEY ARE FROZEN, exactly like the green and olive ramps above. Do not
     * adjust, tint, darken or interpolate them, and do not add a sixth rung. If
     * a semantic needs a value BETWEEN two of them, express it as a color-mix()
     * of two rungs so this ramp stays the only source of the hue — 2.8 does
     * exactly that for fx-color-active and records why.
     *
     * ORDERED LIGHT TO DEEP, so the numbering runs the same direction as every
     * other ramp in this file. Measured relative luminance in brackets:
     *   100  #D7F5D3  (0.845)  lightest — the light theme hover wash
     *   200  #C2E9BF  (0.735)
     *   300  #B3E5B3  (0.689)           — the light theme text selection
     *   400  #A5E1A6  (0.646)
     *   500  #96DD99  (0.605)  deepest  — the dark theme's mint: the low alpha
     *                                     wash tint AND dark brand text
     *
     * WHERE THE RAMP IS SPENT, so a reviewer can grep one comment: the light
     * interaction washes and selection (2.8), the dark interaction washes and
     * selection (3.8), dark brand text (3.5.1), the dark link (3.6) and the
     * dark prefers-contrast promotion (section 11). Nowhere else. It is an
     * INTERACTION and DARK TEXT family; it is not a surface family, and painting
     * a page, a card or a field well with it would flatten the elevation ladder
     * into one hue. */
    --fx-p-mint-100: #d7f5d3;   /* client supplied — lightest */
    --fx-p-mint-200: #c2e9bf;   /* client supplied */
    --fx-p-mint-300: #b3e5b3;   /* client supplied */
    --fx-p-mint-400: #a5e1a6;   /* client supplied */
    --fx-p-mint-500: #96dd99;   /* client supplied — deepest */

    /* 1.3 Neutral ramp — very slightly green tinted so greys never read cold
     * beside the olive. 0 is white, 1000 is the deep page black used in dark. */
    --fx-p-n-0:    #ffffff;
    --fx-p-n-25:   #fbfdfa;
    --fx-p-n-50:   #f4f7f1;   /* legacy light page background */
    --fx-p-n-100:  #e9efe6;
    --fx-p-n-200:  #d8e2d5;
    --fx-p-n-300:  #bfcdbc;
    --fx-p-n-400:  #9bad9d;
    --fx-p-n-500:  #7a8d7f;
    --fx-p-n-600:  #5c6b5f;   /* legacy light dim text */
    --fx-p-n-700:  #45524a;
    --fx-p-n-800:  #2f3a33;
    --fx-p-n-900:  #1c2b20;   /* legacy light text */
    --fx-p-n-950:  #16281c;   /* legacy dark surface */
    --fx-p-n-1000: #10211a;   /* legacy dark page background */

    /* 1.4 Dark chrome surfaces — named separately because they are deliberately
     * green tinted rather than points on the neutral ramp. */
    --fx-p-dark-elevated: #17301f;   /* legacy frihat-elevated */
    --fx-p-dark-sunken:   #12221a;
    --fx-p-dark-well:     #0c1a14;
    --fx-p-dark-ink:      #0f1c12;   /* legacy tabulator accent contrast */

    /* 1.5 Fixed brand constants */
    --fx-p-white:      #ffffff;
    --fx-p-black:      #000000;
    --fx-p-on-primary: #eef4e8;   /* legacy frihat-on-primary */
    --fx-p-success:    #28a745;   /* legacy frihat-success — status dot hue */

    /* 1.6 Status hues, chosen to sit harmoniously beside olive.
     * The 600 grades are the accessible foregrounds on light backgrounds;
     * the 300 grades are the accessible foregrounds on dark backgrounds. */
    --fx-p-emerald-100: #e7f4ec;
    --fx-p-emerald-200: #b6dcc4;
    --fx-p-emerald-300: #5fd48a;
    --fx-p-emerald-600: #146c33;
    --fx-p-emerald-800: #3f8b5c;
    --fx-p-emerald-900: #12301f;

    --fx-p-amber-100: #fdf1e0;
    --fx-p-amber-200: #f0cf9a;
    --fx-p-amber-300: #f0b64a;
    --fx-p-amber-600: #a54c07;
    --fx-p-amber-800: #9c7a2a;
    --fx-p-amber-900: #33260d;

    --fx-p-red-100: #fceceb;
    --fx-p-red-200: #f2c0bc;
    --fx-p-red-300: #f2776b;
    --fx-p-red-500: #d64545;   /* legacy row delete hover */
    --fx-p-red-600: #b42318;
    --fx-p-red-800: #a85348;
    --fx-p-red-900: #341917;

    --fx-p-blue-100: #e8f1fb;
    --fx-p-blue-200: #b9d3ef;
    --fx-p-blue-300: #7cc0f8;
    --fx-p-blue-600: #1d5fa8;
    --fx-p-blue-800: #4a80bb;
    --fx-p-blue-900: #12263a;

    /* 1.7 Breakpoint reference values. A custom property cannot be used inside
     * a media feature, so these exist for container queries, for JavaScript that
     * reads getComputedStyle, and as documentation of the one true ladder:
     * Bootstrap 5.3's 576 / 768 / 992 / 1200 / 1400, min-width only, plus the
     * Frihat ultrawide tier at 1800. Never invent a sixth breakpoint. */
    --fx-bp-sm:    576px;
    --fx-bp-md:    768px;
    --fx-bp-lg:    992px;
    --fx-bp-xl:    1200px;
    --fx-bp-2xl:   1400px;
    --fx-bp-ultra: 1800px;
}


/* ── 2) Semantic colour — LIGHT (default) ──────────────────────────────────
 * Every pairing below was checked for WCAG 2.2 AA. Ratios quoted against the
 * page background fx-color-bg unless stated otherwise.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    /* ══ 2.1 THE ELEVATION LADDER ══════════════════════════════════════════
     *
     * Surfaces are separated by BACKGROUND LEVEL, not by a border and not by a
     * shadow alone. Two adjacent planes read as different planes because they
     * are different colours. The structural idea is taken from linear.app
     * (client reference, 2026-08-02) — the palette stays Frihat.
     *
     *   level-0   the page / app background
     *   level-1   resting surface: cards, panels, the sidebar rail
     *   level-2   raised: field wells, secondary buttons, inset chrome
     *   level-3   overlay: menus, dropdowns, modals, popovers, toasts
     *
     * RETUNED 2026-08-02 — THE LADDER IS NOW MONOTONIC IN BOTH THEMES.
     *
     * The previous light ladder folded back on itself: it stepped UP from the
     * tinted page to pure white at level 1, then back DOWN into the tint at
     * level 2 because white was a ceiling, then up to white again at level 3.
     * That reversal was defensible while level 2 also had to carry HOVER and
     * SELECTION, because in a light interface a deeper tint is what reads as
     * engaged. It is no longer defensible, because hover and selection have
     * moved off the ladder entirely and onto the interaction washes
     * (fx-color-hover and fx-color-active, see 2.8, which are a light green
     * tint since the fourth pass and no longer grey). With that job gone,
     * level 2 is simply the plane above a card, and a plane above a card must
     * be LIGHTER than the card in a light theme exactly as it is in a dark
     * one. Light and dark now behave identically: up is lighter, always.
     *
     * The consequence worth stating: level 1 is no longer pure white. White is
     * reserved for level 3, the floating tier, which is the only tier that has
     * to hold its own over arbitrary content underneath it. A card is a soft
     * off white; a popover over that card is paper white plus a float shadow.
     *
     * THE STEP SIZE IS NOW TINY, ON PURPOSE. Linear's adjacent surfaces differ
     * by roughly 1.04 to 1.06:1, which is below the threshold at which the eye
     * reads a step in isolation. Depth is not carried by the fill on its own —
     * it is carried by the fill PLUS a hairline PLUS a shadow, arriving
     * together. A surface that tries to prove its elevation with fill alone
     * ends up reading as a colour block.
     *
     * MEASURED STEPS (WCAG contrast between adjacent planes):
     *   0 → 1  #edf1ea → #f2f6f0   1.046:1
     *   1 → 2  #f2f6f0 → #f7fbf5   1.045:1
     *   2 → 3  #f7fbf5 → #ffffff   1.046:1  (plus the float shadow)
     *   0 → 3  #edf1ea → #ffffff   1.143:1
     * Note that level 1 lands exactly on the frozen legacy page colour
     * #f4f7f1's neighbourhood and level 0 is one step below it, so the app
     * background is now slightly deeper than the legacy build and the card is
     * where the legacy page colour used to sit.
     *
     * ══ THE LADDER IS FOUR RUNGS AND IT IS CLOSED — 0, 1, 2, 3 ═════════════
     *
     * STATED EXPLICITLY 2026-08-03, because the extent was previously only
     * IMPLIED by which names happened to be declared, and an implied extent is
     * an invitation. THERE IS NO fx-color-level-4, there was never meant to be
     * one, and a fifth rung must not be minted to solve a layering problem.
     *
     * WHY THE CEILING IS REAL RATHER THAN ARBITRARY. In LIGHT, level 3 IS pure
     * white: the ramp has physically run out, and a level 4 could only be white
     * again, i.e. a rung that measures 1.000:1 against the one below it. In DARK
     * the ceiling is a design limit rather than a physical one, but pinning the
     * two themes to the same number of rungs is what lets every component name a
     * LEVEL instead of a theme, which is the whole point of the ladder.
     *
     * WHAT TO REACH FOR INSTEAD, since a fifth rung is always a symptom:
     *   · Something must float ABOVE a level 3 overlay — a popover opened from
     *     inside a modal, a tooltip over a menu. It takes level 3 again PLUS a
     *     heavier fx-shadow-float-*, and z-index in section 8 orders the two.
     *     Depth above the ladder is carried by SHADOW, never by another fill.
     *   · Something must sit BELOW level 0 — a well, an inset region, a code
     *     block. That plane already exists and is called fx-color-surface-sunken
     *     (see 2.1.1). It is deliberately NOT numbered, because it is below the
     *     ladder rather than a rung of it.
     *   · Something needs to separate from a plane it is standing ON. That is a
     *     hairline, a shadow, or the interaction washes in 2.8, and 2.1 above
     *     already records that a fill step alone was never meant to carry it.
     *
     * A REFERENCE TO AN UNDECLARED TOKEN IS NOT A HARMLESS PLACEHOLDER, which is
     * the specific reason this paragraph is worth its lines. `var(fx-color-
     * level-4)` with no fallback is INVALID AT COMPUTED VALUE TIME: the property
     * does not fall back to the previous rule, it falls back to the property's
     * INITIAL value, so a background goes transparent and a colour goes to the
     * inherited ink. 05-forms section 2 carries the scar from exactly this
     * failure with two mis-spelled field tokens, where every hover and focus
     * fill in the form layer silently did nothing. AS OF THIS DATE NO SUCH
     * REFERENCE EXISTS: the twelve Frihat stylesheets were swept for every
     * `var(fx-*)` name and checked against every declaration in this file, and
     * the undeclared set is empty. This note is what keeps it empty.
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-level-0: #edf1ea;            /* page   */
    --fx-color-level-1: #f2f6f0;            /* card   */
    --fx-color-level-2: #f7fbf5;            /* raised */
    --fx-color-level-3: var(--fx-p-n-0);    /* #ffffff + fx-shadow-float-* */

    /* 2.1.1 Ladder aliases. The old surface names are kept alive and mapped
     * onto the ladder so existing component code keeps working unchanged.
     * NEW code should name the LEVEL it means.
     *
     * bg-subtle and surface-sunken are the one plane BELOW the ladder — a well
     * cut into the page rather than a plane above it — so they carry their own
     * value in both themes rather than pointing at a level. One step of the
     * same 1.045 size, downward. */
    --fx-color-bg:              var(--fx-color-level-0);
    --fx-color-bg-subtle:       #e8ece5;                 /* banded / inset regions */
    --fx-color-surface:         var(--fx-color-level-1); /* cards, panels */
    --fx-color-surface-raised:  var(--fx-color-level-3); /* menus, popovers, topbar */
    --fx-color-surface-sunken:  #e8ece5;                 /* wells, code blocks */
    --fx-color-overlay-solid:   var(--fx-color-level-3); /* floating layer FILL */

    /* ══ 2.1.2 THE TWO DIMMERS — A SCRIM IS NOT A VEIL ═════════════════════
     *
     * RETUNED 2026-08-02 (second pass). Both tokens below used to be a
     * different ALPHA of the same dark ink, and fx-color-overlay was not a
     * dimmer at all — it was an opaque alias of level 3. Both are corrected
     * here, and the two are now deliberately different in KIND:
     *
     *   fx-color-scrim        REMOVE THE PAGE FROM CONSIDERATION.
     *                         Behind a modal, an offcanvas, a SweetAlert2
     *                         dialog, a .frihat-dialog, or the Tabulator alert
     *                         panel. The user cannot interact with what is
     *                         under it, so it does not have to stay readable.
     *
     *   fx-color-overlay      THIS REGION IS WORKING. A busy veil over a card,
     *                         a panel or the whole page while data loads. The
     *                         user MUST still be able to see the shape of what
     *                         is loading, otherwise the overlay is
     *                         indistinguishable from an empty state. It is
     *                         therefore always WEAKER than the scrim.
     *
     * THE SCRIM IS A DIFFERENT COLOUR PER THEME, NOT A DIFFERENT ALPHA. This
     * is one of the structural differences that make the reference's dark mode
     * not an inversion of its light mode: a LIGHT page is dimmed with WHITE and
     * a DARK page is dimmed with BLACK. A light interface that goes dark behind
     * a dialog reads as a modal borrowed from a different application — the
     * page appears to switch themes for the duration of the dialog. Dimming
     * light with light keeps the page recognisably itself, merely withdrawn.
     *
     * MEASURED, and the reason a white scrim is safe:
     *   EVERY dialog surface in the system is OPAQUE — .modal is level 3 in
     *   light and level 1 in dark, .frihat-dialog matches it, and the Tabulator
     *   alert panel is level 3. The scrim therefore never composites under
     *   dialog text, and the body copy inside a dialog is unchanged:
     *     light   text #14231a on level 3 #ffffff            16.34:1
     *     dark    text #e7efe6 on level 1 #17251b            13.59:1
     *   What the scrim DOES change is how far the dialog stands off the page
     *   behind it:
     *     light   #ffffff dialog over the scrimmed page #f9faf8   1.047:1
     *     dark    #17251b dialog over the scrimmed page #030504   1.283:1
     *   The light figure is exactly one rung of the elevation ladder (2.1
     *   measures adjacent steps at 1.045 to 1.046), so the dialog separates the
     *   same way every other raised plane in the system does — by fill PLUS
     *   fx-shadow-float-lg. The dark figure is larger than the entire 0 to 3
     *   ladder span (1.162), which is correct: dark carries elevation in the
     *   SHADOW and in the backdrop, because its background steps are tiny.
     *
     * The veil is measured against what actually sits on it — the spinner and
     * its label, which are fx-color-text-muted:
     *     light   #2d3a32 on a 55% white veil over a level 1 card   11.40:1
     *     dark    #c8d6ca on a 70% black veil over a level 1 card   13.13:1
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-scrim:   rgba(255, 255, 255, 0.65);

    /* THE LOADING SCRIM. Heavier than the dialog scrim above, and the reason is
     * that it is the ONLY thing standing between the loading mark and whatever
     * the page happens to be showing.
     *
     * The loading state used to draw a level-3 CARD, which gave the mark and its
     * ring a known backdrop. The owner removed the card on 2026-08-14 — "logo
     * with circular loading are enough without the white window background" —
     * and that removal transferred the whole legibility burden here: the ring
     * now sits over this veil composited over arbitrary content, which on one
     * screen is a pale form and on the next a dense dark grid.
     *
     * SO THE VALUE IS SOLVED FROM THE WORST CASE, NOT CHOSEN BY EYE. The ring is
     * a non-text graphic and owes SC 1.4.11's 3:1. Measured against
     * fx-color-text-subtle over this veil, composited over both extremes:
     *     light theme over a PALE page ......... 5.97:1
     *     light theme over DARK content ........ 3.95:1   <- this sets 0.80
     *     dark  theme over LIGHT content ....... 5.13:1
     *     dark  theme over a DARK page ......... 6.94:1
     * At the 0.65 the dialog scrim uses, the light-over-dark case measures
     * 2.74:1 and FAILS. 0.80 is the lowest step that clears the floor on every
     * backdrop while still leaving the page recognisable underneath, which is
     * the requirement that stopped this being a full-page surface at all.
     *
     * DARK STAYS AT 0.85, matching the dialog scrim: a black veil over a
     * near-black page is already past the floor and lightening it would only
     * cost contrast on the light-content case. */
    --fx-color-scrim-loading: rgba(255, 255, 255, 0.80);
    --fx-color-overlay: rgba(255, 255, 255, 0.55);

    /* ══ 2.2 THE FOUR TEXT TIERS ═══════════════════════════════════════════
     *
     * Retuned 2026-08-02 from three tiers to FOUR. The old muted and subtle
     * grades sat at 5.2:1 and 4.9:1 — six percent apart, which is not a tier,
     * it is a rounding error. Linear runs four clearly separated tiers and
     * expresses ALL hierarchy through them. That is the single most important
     * thing to copy: hierarchy is a COLOUR TIER, never a heavier weight.
     *
     *   fx-color-text         PRIMARY      14 to 19:1
     *                         Headings. Active and selected content. The label
     *                         of a hovered row. Anything being promoted.
     *   fx-color-text-muted   SECONDARY    10 to 14:1
     *                         THE DEFAULT BODY COLOUR — 01-base sets it on
     *                         body. Default menu item labels, table cells,
     *                         paragraph text. Despite the name, this is not a
     *                         dimmed grade; it is the resting state of content.
     *   fx-color-text-subtle  TERTIARY     5 to 6:1
     *                         Icons, section labels, placeholders, inactive
     *                         tabs, timestamps, metadata, table headers.
     *   fx-color-text-faint   QUATERNARY   3.4 to 3.7:1     ← NEW
     *                         Disabled labels, chevrons, decorative glyphs.
     *                         DELIBERATELY BELOW AA. It is not load bearing
     *                         text and must never carry a sentence a user has
     *                         to read. If information lives in it, it is in
     *                         the wrong tier — promote it to subtle.
     *
     * THE BIG JUMP IS SECONDARY TO TERTIARY, roughly 2x. That gap is the line
     * between CONTENT and CHROME, and it is what makes a dense screen read as
     * data with furniture around it rather than as a wall of equal type.
     *
     * THE ICON RULE. An icon sits ONE TIER BELOW the label beside it, and both
     * promote together on hover: a resting menu row is a secondary label with
     * a tertiary icon; hovered, it is a primary label with a secondary icon.
     *
     * MEASURED against fx-color-level-0, the page (the worst case in light,
     * because every higher plane is lighter and therefore kinder):
     *   primary     #14231a   14.30:1   (15.62 on level 2, 16.34 on white)
     *   secondary   #2d3a32   10.42:1   (11.39 / 11.91)
     *   tertiary    #58675e    5.22:1   ( 5.71 /  5.97)
     *   quaternary  #74837a    3.49:1   ( 3.81 /  3.98)
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-text:            #14231a;
    --fx-color-text-muted:      #2d3a32;
    --fx-color-text-subtle:     #58675e;
    --fx-color-text-faint:      #74837a;
    /* ══ 2.2.2 THE PLACEHOLDER TIER — A FIFTH NAME FOR A THIRD-TIER VALUE ═══
     *
     * ADDED 2026-08-03, and it exists for exactly ONE reason: section 11.
     *
     * At rest this is fx-color-text-subtle and nothing else, so no field moves.
     * The name is here so that the prefers-contrast promotion has somewhere to
     * land that is NOT the collapse the other four tiers take. A placeholder is
     * the one piece of dimmed ink in the system that is NOT content: it is a
     * hint that duplicates the field's own label, and the thing it must stay
     * distinguishable from is A VALUE THE USER TYPED. On a legal form, "is this
     * field empty or does it hold a name" is a data-integrity question, and
     * section 11 was answering it identically for both. See 11.
     *
     * A COMPONENT MUST NOT READ fx-color-text-subtle FOR A PLACEHOLDER. It reads
     * this. 05-forms 1 routes fx-ctl-placeholder through it, which is the only
     * consumer that should ever need to know the name. */
    --fx-color-text-placeholder: var(--fx-color-text-subtle);
    --fx-color-text-on-primary: var(--fx-p-on-primary);
    --fx-color-text-inverse:    var(--fx-p-n-50);      /* text on an inverted chip */

    /* ══ 2.2.1 THE SECOND TIER ON A BRAND FILL ═════════════════════════════
     *
     * ADDED 2026-08-02 (fourth pass). 11-home derived this locally after
     * measuring it, and a second brand filled surface is already foreseeable —
     * an empty state, a stat banner, the login panel — so the figure is decided
     * once here rather than re-measured per component.
     *
     * It is the ONLY sanctioned dimmed ink on a brand fill. The four text tiers
     * in 2.2 are measured against the SURFACE LADDER and none of them may be
     * used on fx-color-primary: fx-color-text-muted on the light brand fill
     * measures 1.35:1.
     *
     * THE TWO THEMES CARRY DIFFERENT PERCENTAGES BECAUSE THEY HAVE DIFFERENT
     * ROOM, and this is the part not to "tidy" into one value. The light fill
     * is green-800 under an off white ink and starts at 7.38:1, so a second tier
     * can take a real step down: 80 percent of the ink over the fill measures
     * 5.36:1. The DARK fill is green-700 under white and starts at 5.16:1 — the
     * whole theme has 0.66 of headroom over AA and the ramp is frozen, so a
     * second tier is a whisper or it is a failure. 92 percent measures 4.65:1;
     * 90 percent is the floor at 4.52:1 and 88 percent already fails at 4.38:1.
     *
     * THE RULE THAT FOLLOWS FROM THAT ARITHMETIC: on a brand fill in DARK,
     * hierarchy comes from SIZE, WEIGHT and SPACE, not from a second ink. If a
     * banner needs three levels of emphasis, it does not have three inks. */
    --fx-color-text-on-primary-muted:
        color-mix(in srgb, var(--fx-color-text-on-primary) 80%, var(--fx-color-primary));

    /* ══ 2.3 TWO SEPARATE LINE FAMILIES — DO NOT COLLAPSE THEM ═════════════
     *
     * This is the structural distinction most Linear clones get wrong, and it
     * is why their surfaces look flat. There are two kinds of line and they
     * are not interchangeable:
     *
     *   TRANSLUCENT BORDERS — fx-color-border*
     *     The EDGE of a floating or elevated surface: a popover, a menu, a
     *     modal, a card that genuinely lifts. They are translucent because
     *     such a surface can land on anything, and a translucent edge takes on
     *     whatever is behind it instead of fighting it. Three steps.
     *
     *   OPAQUE LINES — fx-color-divider*
     *     An in-flow separator INSIDE a surface whose colour is already known:
     *     a menu group rule, a section break, a toolbar segment split. They
     *     are opaque because the background is known, so an exact colour is
     *     cheaper to paint and never doubles up where two edges meet. Four
     *     steps, from a visible rule down to a hint.
     *
     * BOTH FAMILIES ARE STRUCTURAL SEPARATION AND ARE THEREFORE ALLOWED TO BE
     * NEARLY INVISIBLE — 1.03:1 to 1.5:1 against their surface, which is
     * Linear's own tier and is below the WCAG SC 1.4.11 floor. That is not a
     * defect: SC 1.4.11 governs the visual information required to IDENTIFY a
     * user interface component, and a card edge or a section rule identifies
     * nothing. An INTERACTIVE CONTROL's boundary is a completely different
     * matter and is governed by fx-shadow-well — see the rule over that token
     * in section 6, and never satisfy a control boundary from this family.
     *
     * MEASURED against level 1 (#f2f6f0):
     *   border-subtle    1.10:1     divider-strong  1.29:1
     *   border           1.16:1     divider         1.13:1
     *   border-emphasis  1.32:1     divider-soft    1.07:1
     *                               divider-faint   1.03:1
     * border-strong is NOT part of the translucent trio. It is the 3:1 capable
     * opaque line that prefers-contrast: more and forced-colors promote to,
     * and it measures 3.09:1 against the page. Leave it alone. */
    --fx-color-border-subtle:   rgba(15, 42, 24, 0.05);
    --fx-color-border:          rgba(15, 42, 24, 0.08);
    --fx-color-border-emphasis: rgba(15, 42, 24, 0.14);
    --fx-color-border-strong:   var(--fx-p-n-500);

    --fx-color-divider-strong:  #d3dcd0;
    --fx-color-divider:         #e2e9df;
    --fx-color-divider-soft:    var(--fx-p-n-100);  /* #e9efe6 */
    --fx-color-divider-faint:   #eef3eb;

    /* 2.3.1 Field wells — the primary identification channel for every control.
     *
     * A borderless input is only findable if its FILL differs from whatever it
     * sits on. With the ladder now monotonic in both themes, both themes agree
     * on the direction as well: a control is LIT ABOVE the surface it sits on,
     * never recessed into it. Rest is level 2, hover is one further step, focus
     * lights the well to the top of the ladder.
     *
     * Rest against a level 1 card is only 1.045:1, which is exactly why
     * fx-shadow-well carries a band that clears 3:1; see the rule written over
     * that token. Fill alone does NOT satisfy SC 1.4.11 here and must never be
     * the only thing distinguishing a control. */
    --fx-color-field-bg:        var(--fx-color-level-2); /* #f7fbf5 */
    --fx-color-field-bg-hover:  #fbfdf9;
    --fx-color-field-bg-focus:  var(--fx-color-level-3); /* #ffffff — lights up */

    /* 2.4 Primary — the deep brand green. See section 3.9 for WHERE this is
     * allowed to be spent; the short answer is almost nowhere.
     *   white over primary        8.27:1
     *   text-on-primary over it   7.38:1
     *   primary fill vs the page  7.25:1 */
    --fx-color-primary:          var(--fx-p-green-800);
    --fx-color-primary-hover:    var(--fx-p-green-900);
    --fx-color-primary-active:   var(--fx-p-green-950);
    --fx-color-primary-subtle:   rgba(20, 90, 50, 0.10);
    --fx-color-primary-contrast: var(--fx-color-text-on-primary);
    --fx-color-primary-rgb:      20, 90, 50;

    /* ══ 2.4.3 THE BRAND FILL'S BOUNDARY — A STATE THAT MUST BE IDENTIFIABLE ══
     *
     * ADDED 2026-09-04. fx-color-primary is the fill under a SELECTED VALUE as
     * well as under a button — the chosen option in a dropdown, the selected day
     * in a datepicker, both sanctioned by 3.9 as a control reporting a value that
     * will be saved. A selected state is "visual information required to identify
     * a state" under SC 1.4.11, so the fill owes 3:1 against the plane it sits on.
     *
     * IN LIGHT IT PAYS THAT OUT OF ITS OWN POCKET, and this token is invisible:
     * the fill measures 7.24 / 7.57 / 7.91 / 8.27:1 against levels 0 to 3, so the
     * border resolves to the fill itself and a component may paint it
     * unconditionally with no visual change at all. IN DARK IT CANNOT, and the
     * dark declaration in 3.4.2 is where the work happens. Read that one.
     *
     * IT IS DECLARED IN BOTH THEMES SO THAT A CALL SITE NEVER HAS TO ASK WHICH
     * THEME IT IS IN. A component writes one rule and the token decides whether
     * that rule draws anything. That is the whole reason this is a token and not
     * a per component border, which is the per screen patch that 3.9 and the
     * project rules both exist to prevent. */
    --fx-color-primary-border:   var(--fx-color-primary);

    /* ══ 2.4.2 THE BAND — PINNED, NOT SPLIT BY THEME ═══════════════════════
     * ADDED 2026-08-04. CLIENT DIRECTION, verbatim: the dark topbar must be
     * "the same colour just like in light mode". Before this, 03-leptonx
     * section 4.0 pointed --fx-band-bg/--fx-band-fg straight at
     * fx-color-primary / fx-color-text-on-primary, which is exactly right for
     * tokens THAT ARE meant to split by theme (buttons, links, focus rings —
     * see 3.4 for why that split is frozen and must not move) and exactly
     * wrong for a single brand surface that must read as one colour. The band
     * gets its own pair instead, held to the value fx-color-primary and
     * fx-color-text-on-primary ALREADY carried in light, so light does not
     * move at all — only dark changes, and it changes to match light exactly.
     *   fx-color-band-fg on fx-color-band   7.38:1   AA (both themes, unchanged
     *                                                 from light's own figure) */
    --fx-color-band:    var(--fx-p-green-800);
    --fx-color-band-fg: var(--fx-p-on-primary);

    /* The band's INTERACTION mark, gold, and the twin of the rail's position
     * mark above — same primitive, so a highlight means the same thing on both
     * brand surfaces. Owner decision 2026-08-04.
     *
     * It exists because LeptonXLite hovers the breadcrumb glyphs to
     * `var(--lpx-brand)`, its own green, at a specificity that beats the band's
     * ink rule. Green on the green band is green on green: the home icon simply
     * DISAPPEARED under the pointer, which is how the owner reported it. A brand
     * colour is the right instinct on a neutral bar and exactly wrong on a brand
     * bar — the mark has to leave the surface's own hue.
     *
     * Gold measures 4.53:1 on the band. The glyph is the entire content of its
     * link, so it is a graphical object under SC 1.4.11 and needs 3:1; it clears
     * that with room, and it is a hover state promoting FROM the 5.36:1 muted
     * ink rather than replacing a resting value. Pinned in both themes for the
     * same reason the fill and ink are. */
    --fx-color-band-mark: var(--fx-p-amber-300);

    /* ══ 2.4.1 THE RAIL PLANE — A NEAR BLACK THAT STILL CARRIES THE HUE ════
     *
     * ADDED 2026-08-03. CLIENT DECISION, same day: the sidebar is "not even
     * close to clio.com or Linear". Research measured both products and found
     * that NEITHER runs a saturated brand plane behind navigation — Linear's
     * rail has no surface at all (transparent, no border, no shadow) and Clio's
     * rail is a near black #001537 that their own help centre calls "the black
     * menu", with the brand blue spent on a full bleed horizontal HEADER BAND
     * instead. The client chose Clio's model: a DARK RAIL plus a BRAND TOP BAR.
     * He keeps more visible brand than the previous build had, and the rail
     * finally gets dark enough to carry a real state model.
     *
     * WHY THE RAIL COULD NOT KEEP A REAL STATE MODEL ON GREEN 800. A state
     * ladder needs room between rest, hover, active and pressed. On the old
     * green 800 rail every wash had to be mixed out of the rail's own light ink
     * at 6 and 10 percent, and the two landed 1.13 and 1.26 above the fill with
     * nowhere left to put a PRESSED step. On this plane the same three steps sit
     * at 1.26, 1.53 and 1.76 and are individually legible. Depth on a near black
     * plane is cheap; on a mid green plane it is not available at all.
     *
     * IT IS NOT A SECOND GREEN, AND THE ARITHMETIC IS WHAT KEEPS IT THAT WAY.
     * L* 10.9, which is inside the L* 8 to 12 band Clio's own rail occupies
     * (#001537 measures L* 8.4). Anything above roughly L* 16 stops reading as
     * "almost black" and starts competing with the brand band above it.
     *
     * DERIVED, NOT PICKED. green-900 mixed 55 percent toward black resolves to
     * #082213 — a value ON the frozen ramp's own line toward black rather than a
     * new hue invented beside it, so the rail cannot drift away from the brand
     * and the ramps stay the only source of green in the system. Do not replace
     * this with a typed hex: the derivation is what guarantees the hue.
     *
     * ══ THE RAIL IS THEME-AWARE SINCE 2026-08-03 — CLIENT DECISION ═════════
     * THIS SECTION USED TO SAY the opposite, verbatim: "ONE VALUE IN BOTH
     * THEMES… there is no reading of 'the black menu' in which it becomes a
     * different black when the page goes dark." That was Clio's model, and the
     * client has since chosen LINEAR'S. The paragraph is deleted rather than
     * qualified, and the measurement that overturned it is short:
     *
     *     dark   rail #082213 vs its canvas  ......  1.06:1
     *     light  rail #082213 vs its canvas  ...... 14.70:1
     *
     * ONE CONSTANT IN A SYSTEM WHERE EVERYTHING ELSE IS A LADDER. In dark the
     * rail and the canvas are effectively one continuous field, so the ONLY
     * edge in the composition is the content card's — which is precisely why
     * the card's curve reads there. In light the identical token becomes a
     * black slab and the composition carries TWO edges, the rail's at 14.7 and
     * the card's at 1.09. The eye takes the louder one and the card stops
     * reading as a card. The client described the symptom exactly: the dark
     * theme shows the curved edges because the sidebar matches the background.
     *
     * SO LIGHT GETS ITS OWN RUNG and dark keeps what it has. The target is that
     * both themes end with the SAME STRUCTURE — one continuous shell field, one
     * raised card, one edge — not the same hex.
     *
     * THE LIGHT VALUE IS green-100, AND IT IS STILL ON THE FROZEN RAMP. The
     * dark value had to be DERIVED (green-900 mixed toward black) because no
     * ramp step sat at L* 10.9. Light needs no derivation: the ramp already has
     * a rung within a hair of the sunken canvas, so naming it is more honest
     * than mixing to reach it. The rule the derivation existed to protect is
     * unchanged — the ramps stay the only source of green in the system, and
     * neither value is a typed hex.
     *
     * ⚠ IT MUST READ AS OLIVE, NOT AS GREY, AND THAT IS A CLIENT CONSTRAINT
     * RATHER THAN A PREFERENCE. A neutral rail was proposed once and rejected
     * outright; a pale GREY rail is that rejected design returning through the
     * back door and it will be read that way. Measured in OKLCH, green-100 is
     * L 0.944 C 0.0248 H 160.5 against the sunken canvas's L 0.926 C 0.0090
     * H 145 — nearly THREE TIMES the chroma of the plane beside it, at the same
     * lightness band. On the raw channels the green excess over the red/blue
     * mean is 15 against the canvas's 6. The hue is visible on screen, not just
     * present in the hex. Do not neutralise it to tidy the ladder.
     *
     * MEASURED — LIGHT (rail green-100 #dff2e7):
     *   rail vs its sunken canvas .................. 1.025:1   below the 1.045
     *          at which a fill step becomes legible on its own, so the rail and
     *          the canvas read as ONE field and the card's 1.094 is the only
     *          edge in the composition. This is the whole point.
     *   rail vs the content card ................... 1.068:1
     *   the brand band above it .................... 7.088:1   a real junction
     *   focus ring (fx-color-focus-ring, green-800) . 7.088:1  SC 1.4.11 — so
     *          light needs NO rail-local ring; the shared token works outright.
     *   position mark (fx-color-indicator, green-800) 7.088:1
     *
     * MEASURED — DARK, and these are the figures 03-leptonx's local ladder is
     * built on.
     * Every foreground on the rail is WHITE mixed toward this plane, so all four
     * tiers carry its green cast rather than reading as flat grey:
     *   white                    100%  ...... 16.82:1   AAA
     *   white mixed 72% .......  #bac1bd ....  9.12:1   AAA
     *   white mixed 55% .......  #909c95 ....  5.91:1   AA
     *   white mixed 38% .......  #66766d ....  3.51:1   SC 1.4.11, disabled only
     * And the three interaction washes, white at alpha OVER the plane:
     *    8%  #1c3426  1.26:1      14%  #2b4134  1.53:1      18%  #344a3d  1.76:1
     * The washes are deliberately stronger than the 1.03 to 1.27 page tint band
     * in 3.9: that band was measured on a plane whose own steps are 1.05, and a
     * near black plane needs more to show a state at all. They remain an order of
     * magnitude below a brand mark, which is the property 3.9 actually protects.
     *
     * WHAT SITS ON IT IS NOT DECIDED HERE. The rail is a brand SURFACE under
     * 3.9 site 11, so the surface clause governs it: 03-leptonx declares the
     * whole fx-rail-* tier set out of this one knob plus one ink, and records the
     * measured ratio at every call site. On the DARK plane nothing on the page
     * ladder is valid — fx-color-text-subtle measures 1.4:1 there. On the LIGHT
     * plane the opposite is now true and that is the point of the change: a rail
     * 1.025:1 from its canvas is the same plane the page tiers were measured
     * against, so the page ink is valid on it. 03-leptonx 7.0 still declares a
     * rail-local ladder in both themes, because the two planes need different
     * mix percentages to reach the same four RATIOS. */
    /* ══ THE SHELL — RULED BY THE CLIENT 2026-08-04 ════════════════════════
     * The rail, the band and the canvas around the content plane are ONE
     * surface and that surface is the brand green. Client instruction, verbatim:
     * «make side bar color and the container color olive green like the top
     * bar». This SUPERSEDES the pale rail described immediately above. That
     * paragraph is kept because it records why the pale rail was correct under
     * the previous brief and what was measured to get there — not because the
     * pale rail is still live. The one line in it that still binds is the
     * client's standing rejection of a NEUTRAL rail; a green shell honours that
     * more strongly than green-100 ever did.
     *
     * ONE KNOB, THREE SURFACES. body, .lpx-content-container and
     * .lpx-footbar-container all paint from this token, and --fx-color-rail
     * points AT it. "The same colour as the top bar" is therefore true by
     * construction rather than by four hexes happening to agree, and a future
     * band retune moves the whole shell with it.
     *
     * IT IS DELIBERATELY NOT --fx-color-surface-sunken. That token has twelve
     * consumers and four of them are FORM CONTROL fills (05-forms 1030, 3066,
     * 3114, 3462), with a fifth the Bootstrap card fallback (07-surfaces 329).
     * Repointing it would have turned every disabled field and every fallback
     * card green. The canvas token keeps its job — recesses INSIDE the content
     * plane — and the shell gets its own knob.
     *
     * MEASURED, light, against #145a32:
     *   white ................. 8.28:1  AAA  the shell's primary ink
     *   white 85% ............. 6.48:1  AA
     *   white 72% ............. 5.15:1  AA   idle rail rows and group headings
     *   white 54% ............. 3.70:1  SC 1.4.11 only — never body text
     *   p-amber-300 (gold) .... 4.53:1  AA   the position mark, below
     *   green-800 on itself ... 1.00:1  which is exactly why
     *          --fx-color-brand-text and --fx-color-indicator may NOT be spent
     *          inside the shell: both resolve to green-800 in light, so a
     *          selected row and the position bar would be invisible. 03-leptonx
     *          overrides both against this plane.
     *
     * DARK IS UNCHANGED BY CONSTRUCTION. The dark rung points the shell at the
     * canvas dark already had, so nothing in dark moves. */
    --fx-color-shell:    var(--fx-p-green-800);
    --fx-color-shell-fg: var(--fx-p-white);

    /* The rail IS the shell. Not a copy of it — the same knob, so the two can
     * never drift apart in a later pass. */
    --fx-color-rail: var(--fx-color-shell);

    /* The position mark. Gold, chosen by the owner on 2026-08-04 from a measured
     * comparison against pale gold, olive-300 and plain white. It marks WHERE
     * YOU ARE and nothing else — 00-tokens 3.9 site 3 — so it is spent on the
     * selected row's bar and never on a label, an icon or a border. The selected
     * row's own ink stays white at 8.28:1, which keeps the selected row the
     * BRIGHTEST thing in the rail; gold as a label would have made it dimmer
     * than the unselected rows around it (4.53:1 against 5.15:1), inverting the
     * hierarchy it is supposed to express.
     *
     * It measures 4.53:1 here and 9.21:1 on the dark rail, so one value serves
     * both themes and the mark means the same thing in each. */
    --fx-color-rail-mark: var(--fx-p-amber-300);

    /* THE RAIL'S PRIMARY INK, promoted to the token layer in the same change.
     * It lived in 03-leptonx as a bare var(--fx-p-white), which was one of that
     * file's four component-level primitive reads; the theme split would have
     * needed a SECOND one for the light ink, and a component may not consume
     * fx-p-*. Naming the pair here retires the existing violation instead of
     * adding to it, and it puts the rail's ink beside the rail's fill where the
     * two can only ever move together — the same shape as
     * fx-color-text-on-primary sitting beside the brand fill.
     *
     * BOTH THEMES NOW TAKE WHITE, and for the same reason: the rail is a dark
     * plane in each. Light is white on the shell green at 8.28:1; dark is white
     * on the near-black plane at 16.82:1, exactly as before. The 2026-08-03
     * arrangement — light taking the PAGE's primary ink because the rail had
     * joined the surface ladder at green-100 — ended with the shell ruling
     * above: page ink measures 2.53:1 on the shell and is no longer valid here. */
    --fx-color-rail-fg: var(--fx-color-shell-fg);

    /* 2.5 Accent — olive. Decorative only, and now spent far more sparingly:
     * it is no longer the focus ring in light, no longer the hover wash and no
     * longer the active wash. What is left is genuine decoration — a mark
     * highlight, a chart series, and the rail's own position bar, which mixes
     * this token toward the rail ink because nothing on the frozen green ramp
     * survives a green plane. Not a text colour on light.
     *
     * ══ A LIST MARKER WAS NAMED HERE AND IS NOT A BRAND SITE ═══════════════
     * RULED 2026-08-02 (fifth pass). This section used to sanction "a list
     * marker" and 3.9 never listed one among its sites while forbidding any
     * addition to that list. The two could not both be right, and the
     * contradiction is resolved AGAINST THIS SECTION for three reasons:
     *
     *   · A bullet answers NEITHER question in 3.9. It does not say who this
     *     product is and it does not say where you are, so Q1 fails; it does not
     *     respond to a pointer or a key, so Q2 fails. 3.9 already rules that an
     *     element answering neither gets weight, space or a text tier — the KPI
     *     tile worked example — and a marker is the purest case of it.
     *   · A bullet is the most GENERIC GLYPH in the system, and 3.9's FORBIDDEN
     *     list sends every generic icon to a text tier one step below its label.
     *     Exempting the one glyph the browser draws for us is arbitrary.
     *   · FREQUENCY. Every sanctioned site in 3.9 is bounded — once per page,
     *     one per region, one per sorted column. A marker recurs once per list
     *     item, without any bound, which makes it the highest volume brand spend
     *     in the product for the least identity returned. That is the "themed
     *     Bootstrap" signal 3.9 exists to prevent, arriving through a footnote.
     *
     * THE SUPERSEDED REASONING, kept because it was not wrong so much as
     * incomplete: a marker is decoration rather than interaction, and this
     * section governs decoration. True, and not sufficient — 3.9 governs whether
     * a thing may be BRAND at all, and it outranks a decoration clause.
     *
     * KNOWN CALL SITE, NOT A LICENCE: 01-base still paints li::marker with
     * fx-color-accent on the strength of the removed clause. It is a follow-up
     * change in that file, to a text tier, and it is recorded here so the next
     * reader does not take the live rule as evidence the clause survived. */
    --fx-color-accent:        var(--fx-p-olive-600);
    --fx-color-accent-hover:  var(--fx-p-olive-700);
    --fx-color-accent-subtle: rgba(107, 142, 35, 0.14);
    --fx-color-accent-rgb:    107, 142, 35;   /* mirrors p-olive-600 */

    /* ══ 2.5.1 IDENTITY MARKS — THE "YOU ARE HERE" BRAND ═══════════════════
     *
     * ADDED 2026-08-02 (third pass), with the corrected accent contract in 3.9.
     * These two exist so that the five POSITION sites named there have a
     * semantic to point at, and so that a reviewer can grep one name and know
     * the brand reference in front of them is sanctioned rather than casual.
     *
     *   fx-color-indicator    A brand MARK that reports position: the active
     *                         sidebar indicator bar, the active tab underline,
     *                         the grid sort arrow. It is a boundary or a glyph,
     *                         never a sentence, so it is governed by
     *                         SC 1.4.11 at 3:1 and not by SC 1.4.3.
     *
     *   fx-color-brand-text   The brand hue that is safe to READ: the active
     *                         sidebar label, the page kicker. Governed by
     *                         SC 1.4.3 at 4.5:1 on every plane, which is a
     *                         stricter bar and is why it is a separate token
     *                         rather than an alias of the one above.
     *
     * THEY ARE NOT INTERCHANGEABLE, and the reason is arithmetic rather than
     * taste. In DARK the two diverge onto different ramps: the mark stays green
     * because a green-500 bar clears 3:1 on every plane, while brand TEXT in
     * dark cannot be the FROZEN GREEN ramp at all — that ramp tops out at
     * green-700, which is 3.24:1 on the page, so reading text takes mint-500 at
     * 10.44:1. This is the same constraint that governs the dark link in 3.6, and
     * both moved onto the client supplied mint ramp in the same pass.
     *
     * CORRECTED 2026-08-03. This paragraph said "olive-400 at 8.88:1" and was one
     * pass stale: fx-color-brand-text moved to mint-500 on 2026-08-02 (fourth
     * pass) and the declaration in 3.5.1 has read var(fx-p-mint-500) ever since,
     * so the file was contradicting itself about one token. The OLIVE reasoning
     * is not lost and must not be reinstated from here — it is recorded, marked
     * superseded and measured against the mint that replaced it, over the dark
     * declaration in 3.5.1. Nothing was declared or re-declared by this fix.
     *
     * fx-color-brand-text carries the same VALUE as fx-color-link in both
     * themes today. That is deliberate and follows the precedent set by the
     * four inks in 2.7.1: the names exist so a call site says WHAT it is
     * colouring, and so that if a kicker ever needs to diverge from a link,
     * exactly one line changes here instead of every consumer being audited.
     * A kicker is not a link and must not be styled through the link token.
     *
     * MEASURED, light, against every plane a mark can land on:
     *   indicator  green-800   level-0 7.24  level-1 7.57  level-2 7.91  level-3 8.27
     *   brand-text green-800   identical figures; the 4.5:1 bar clears by 2.7
     * And on the one composite that actually occurs — the active sidebar row.
     * RE-MEASURED 2026-08-02 (fourth pass): that fill is now the opaque mint
     * wash #c8edc5 rather than an 8 percent ink over the rail, so the figure no
     * longer depends on which plane the rail sits on:
     *   indicator bar 6.45:1 · brand label 6.45:1 · primary text 12.74:1
     * All three are within a tenth of what the grey composite gave (6.52 / 6.52
     * / 12.88), so putting the client's mint under the mark cost nothing.
     * The dark figures are recorded over the same two tokens in 3.5.1. */
    --fx-color-indicator:  var(--fx-p-green-800);
    --fx-color-brand-text: var(--fx-p-green-800);

    /* 2.6 Links — a sanctioned accent site. Moved one ramp step deeper on
     * 2026-08-02: with the page now slightly darker, green-700 fell to 4.51:1,
     * which passes AA with almost no headroom. green-800 restores it.
     *   link on the page   7.25:1      link hover   11.60:1 */
    --fx-color-link:       var(--fx-p-green-800);
    --fx-color-link-hover: var(--fx-p-green-900);

    /* Channel triplets. Bootstrap and LeptonX build translucent variants with
     * rgba(var(--x-rgb), alpha), which cannot read a hex token, so these two
     * must be maintained alongside the colours above. Keep them in step:
     * link-rgb mirrors p-green-800, text-rgb mirrors fx-color-text. */
    --fx-color-link-rgb:   20, 90, 50;
    --fx-color-text-rgb:   20, 35, 26;

    /* ══ 2.7 STATUS — AND THE ONE TRAP IN THIS FILE THAT BITES SILENTLY ════
     *
     * READ THIS BEFORE USING A BARE STATUS TOKEN ANYWHERE.
     *
     * The four BARE solids — fx-color-success / -warning / -danger / -info —
     * are declared HERE, IN THE LIGHT BLOCK, AND ARE DELIBERATELY NOT
     * RE-DECLARED FOR DARK. They therefore carry these light-mode 600-step
     * hues into the dark theme unchanged. That is not an oversight, and it must
     * not be "fixed" — see WHY DARK IS NOT RE-DECLARED below.
     *
     * THE RULE, and it has exactly two halves:
     *
     *   A BARE SOLID IS A FILL UNDER A LIGHT LABEL. NOTHING ELSE.
     *     Paint it as a background with fx-color-text-on-primary (or the
     *     matching fx-color-text-on-* alias below) on top. Measured, in BOTH
     *     themes because the pair is theme independent:
     *         success #146c33 under #eef4e8   5.82:1
     *         warning #a54c07 under #eef4e8   5.16:1
     *         danger  #b42318 under #eef4e8   5.87:1
     *         info    #1d5fa8 under #eef4e8   5.76:1
     *     A solid fill on the DARK page does not itself clear 3:1 against that
     *     page (danger measures 2.55:1), so a filled status chip in dark must
     *     also carry its -border token. That is what the trio is for.
     *
     *   A -fg TOKEN IS FOR TEXT AND FOR BOUNDARIES.
     *     Any status colour that is READ (a label, a helper line, an icon) or
     *     that IDENTIFIES something (a field edge, a row seam, a rail, an
     *     underline) takes fx-color-*-fg, which IS re-declared for dark and
     *     lands on the 300 grades there. Both jobs are governed:
     *     SC 1.4.3 (4.5:1) for text, SC 1.4.11 (3:1) for a boundary.
     *
     * WHAT GOING WRONG LOOKS LIKE. 05-forms hit this during the retune: the
     * invalid-field border was fx-color-danger, which is #b42318, sitting on a
     * dark field #1b291f. That measures 2.31:1 and FAILS SC 1.4.11 outright.
     * It was corrected by moving to fx-color-danger-fg. The failure is silent
     * in light — the same pairing measures 5.74:1 there — so it can only be
     * caught by testing the dark theme or by obeying this rule up front.
     *
     * WHY DARK IS NOT RE-DECLARED, since the instinct is to "fix" it by adding
     * four lines to section 3.7. The ink is fixed and light; brightening a
     * solid for dark would move the fill TOWARD that ink and cost contrast, not
     * gain it. Worked, on the closest analogue in the file: promoting the dark
     * primary from green-700 to green-600 drops white-ink contrast from 4.61:1
     * to 3.57:1. The same arithmetic governs all four status hues. Re-declaring
     * them for dark would break the one job the bare solid actually has.
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-success:        var(--fx-p-emerald-600);
    --fx-color-success-fg:     var(--fx-p-emerald-600);
    --fx-color-success-bg:     var(--fx-p-emerald-100);
    --fx-color-success-border: var(--fx-p-emerald-200);

    --fx-color-warning:        var(--fx-p-amber-600);
    --fx-color-warning-fg:     var(--fx-p-amber-600);
    --fx-color-warning-bg:     var(--fx-p-amber-100);
    --fx-color-warning-border: var(--fx-p-amber-200);

    --fx-color-danger:        var(--fx-p-red-600);
    --fx-color-danger-fg:     var(--fx-p-red-600);
    --fx-color-danger-bg:     var(--fx-p-red-100);
    --fx-color-danger-border: var(--fx-p-red-200);

    --fx-color-info:        var(--fx-p-blue-600);
    --fx-color-info-fg:     var(--fx-p-blue-600);
    --fx-color-info-bg:     var(--fx-p-blue-100);
    --fx-color-info-border: var(--fx-p-blue-200);

    /* 2.7.1 THE INK THAT GOES ON A STATUS FILL. Added 2026-08-02 (second pass)
     * because 04-buttons was deriving all four locally from
     * fx-color-text-on-primary and every other layer that fills with a status
     * hue was reaching for the primary ink by hand, which reads as a mistake
     * even when it is correct.
     *
     * All four resolve to the SAME ink today, and that is the honest state of
     * the system rather than a shortcut: the four solids were chosen in 1.6 to
     * sit at similar apparent lightness precisely so one ink could serve them
     * all, and the measurements above (5.16:1 to 5.87:1) confirm it. The names
     * exist so that a call site says WHICH fill it is inking, and so that if a
     * future status hue ever needs a dark ink — an amber lighter than
     * amber-600 is the realistic case — exactly one line changes here instead
     * of every consumer being audited.
     *
     * They are declared in the LIGHT block only, like the solids they pair
     * with, and follow the theme automatically because the property they point
     * at is itself re-declared in 3.2. */
    --fx-color-text-on-success: var(--fx-color-text-on-primary);
    --fx-color-text-on-warning: var(--fx-color-text-on-primary);
    --fx-color-text-on-danger:  var(--fx-color-text-on-primary);
    --fx-color-text-on-info:    var(--fx-color-text-on-primary);

    /* 2.8 Interaction — A TINT, not brand. See section 3.9.
     *
     * RETUNED 2026-08-02 (fourth pass). These two were olive washes, then
     * neutral ink at 5 and 8 percent. They are now the CLIENT SUPPLIED MINT
     * RAMP from 1.2.1, and the client's instruction is the reason: the greys
     * were rejected twice by name. A hovered row, a selected menu item, a
     * highlighted keyboard target and the FILL behind an active sidebar entry
     * are all painted with these, which makes them the highest traffic surfaces
     * in the product and the ones the client is actually looking at.
     *
     * WHY THEY ARE OPAQUE AND NOT A TRANSLUCENT MINT. A wash at alpha renders
     * as a DIFFERENT HEX on each of the four planes — five requested colours
     * would have become twenty composites, none of them the requested value.
     * Opaque means a hovered row is literally #D7F5D3 wherever it appears. The
     * cost is that the wash no longer inherits the elevation of its host plane,
     * and the mitigation is that it does not need to: mint-100 is DARKER than
     * every light plane, so a hovered row always reads as a step DOWN from its
     * surface and can never be confused with the plane above it. Measured, wash
     * against host plane and against the next plane up:
     *     hover on level-0  1.027 vs level-0, 1.074 vs level-1
     *     hover on level-1  1.074 vs level-1, 1.122 vs level-2
     *     hover on level-2  1.122 vs level-2, 1.174 vs level-3
     *     active            1.122 / 1.173 / 1.226 / 1.282 on levels 0 to 3
     * The old grey wash sat at a flat 1.096 to 1.103 on every plane. On level 0
     * the mint is therefore WEAKER in luminance than the grey it replaces
     * (1.027 against 1.098) and on levels 1 to 3 it is stronger. Level 0 is the
     * page itself and almost never carries a hoverable row — tables, menus,
     * lists and the nav rail all sit on level 1 or above — and the mint carries
     * a large chroma delta that the grey did not, which is what the eye reads
     * first. The hover to active step is 1.093, wider than a full rung of the
     * elevation ladder, so a hovered row and a selected row are never confusable.
     *
     * WHY ACTIVE IS A COLOR-MIX AND NOT mint-200 ON THE NOSE. Pure mint-200 puts
     * the TERTIARY text tier at 4.463:1 — a 0.8 percent miss of the 4.5:1 AA
     * floor, and tertiary carries real text on a selected row (timestamps,
     * metadata, table headers). The ramp has no rung between 100 and 200, and
     * 1.2.1 forbids inventing one, so the intermediate is mixed from the two
     * rungs either side of it. The result is #c8edc5 and tertiary clears at
     * 4.66:1. Everything else about it is mint-200.
     *
     * MEASURED, all four text tiers over the two washes:
     *     hover #D7F5D3    primary 13.92  secondary 10.15  tertiary 5.09  quaternary 3.39
     *     active #c8edc5   primary 12.74  secondary  9.29  tertiary 4.66  quaternary 3.11
     * Quaternary is knowingly sub-AA — it is the disabled and decorative tier
     * and carries no sentence a user has to read (see 2.2). The old greys
     * measured tertiary at 4.76 to 5.42 on hover and 4.49 to 5.12 on active, so
     * the tertiary tier lands inside the band it already occupied.
     *
     * What sits ON the wash in the sidebar — the indicator bar and the label —
     * is brand, and that is a different job; see 2.5.1 and 3.9. The wash must
     * stay clearly WEAKER than a brand mark or the contract in 3.9 collapses:
     * the mark is a saturated green-800 at 7.05:1 against the hover wash, the
     * wash is a pale tint at 1.03 to 1.17 against its own plane. There is no
     * ambiguity between them, and there must not be.
     *
     * THE FOCUS RING IS BRAND IN BOTH THEMES. RETUNED 2026-08-02 (third pass),
     * and this reverses the previous ruling, so read the reason before changing
     * it back. It used to be rgba(15, 42, 24, 0.55) here — translucent ink
     * copied from Linear, whose own #0006 measures 2.85:1 on white and fails
     * SC 1.4.11 outright, which is why ours had been pushed to 55 percent. That
     * ring was defensible while focus counted as INTERACTION. Under the
     * corrected contract in 3.9 focus is a POSITION signal — it is the keyboard
     * user's answer to "where am I" — and every position signal in this system
     * is brand. So light joins dark rather than dark being the exception.
     *
     * The step is green-800, which is the light brand step already in force for
     * fx-color-primary and fx-color-link, so the ring costs no new hue and the
     * three read as one family. MEASURED against every plane a ring can land on
     * (SC 1.4.11 floor is 3:1):
     *     level-0 #edf1ea   7.24:1        level-2 #f7fbf5   7.91:1
     *     level-1 #f2f6f0   7.57:1        level-3 #ffffff   8.27:1
     * The old translucent ink measured 3.47 / 3.53 / 3.59 / 3.63 on the same
     * four planes — passing, but with under 0.6 of headroom on the page and
     * carrying no brand at all. The replacement is over twice as strong on
     * every plane. Dark is unchanged at green-500 and re-verified in 3.8.
     *
     * SELECTION is a sanctioned accent site, but it is a BACKGROUND behind body
     * text, so it is brand in HUE and neutral in WEIGHT: a desaturated green
     * wash, not a saturated one. It moved onto the mint ramp in the fourth pass
     * for the same reason the washes did, and it takes mint-300 — two rungs
     * DEEPER than hover — so that selecting text inside an already hovered or
     * already selected row still reads as a distinct highlight rather than
     * disappearing into it. Measured: 1.211:1 against the hover wash and 1.108:1
     * against the active wash, both of them a real step and the second of them
     * wider than a rung of the elevation ladder.
     *
     * THE TERTIARY TIER IS NOT A CONCERN ON THIS ONE, and the reason is
     * structural rather than lucky: fx-color-selection-fg REPAINTS selected text
     * at the PRIMARY tier, so nothing tertiary is ever rendered over this fill.
     * Primary ink over mint-300 measures 11.50:1, against the old #d5e4d9's
     * 12.40:1 — a deeper, more visibly green selection that still clears AA by a
     * factor of two and a half. */
    --fx-color-focus-ring:   var(--fx-p-green-800);
    --fx-color-selection-bg: var(--fx-p-mint-300);
    --fx-color-selection-fg: var(--fx-color-text);
    --fx-color-hover:        var(--fx-p-mint-100);
    /* #c8edc5 — see the color-mix note above. NOT a sixth ramp rung. */
    --fx-color-active:       color-mix(in srgb, var(--fx-p-mint-200) 70%, var(--fx-p-mint-100));
    --fx-color-disabled-bg:  #e9eee7;
    --fx-color-disabled-fg:  var(--fx-color-text-faint);

    /* ══ 2.9 THE PALETTE SWATCHES — THE ONE DELIBERATE EXCEPTION IN THIS FILE ══
     *
     * ADDED 2026-09-04 (sixth pass). FIVE tokens: one chip per family, plus the
     * one edge all four of them carry.
     *
     * THEY ARE DECLARED HERE, IN THE DEFAULT BLOCK, AND NOWHERE ELSE, AND THAT
     * IS THE POINT RATHER THAN AN OVERSIGHT. Every other family dependent value
     * in this file lives inside its own palette block in section 13, which is
     * exactly right for a value that describes the ACTIVE family. The picker is
     * the one surface in the platform that shows all four families AT ONCE: a
     * user sitting on sand still has to see what plum looks like before they can
     * choose it. Declared per family, three of the four chips would resolve to
     * nothing on every theme. So these are the only tokens in the file that are
     * deliberately palette independent, and they must not be "tidied" into
     * section 13.
     *
     * ══ THE RULE: A CHIP IS ITS FAMILY SEED, AS THE SEED LANDED ON THE LADDER ══
     *
     * RULED 2026-09-04 by the owner. Section 13 places each seed on the frozen
     * luminance ladder at the rung whose OKLab lightness is nearest, and the chip
     * is THAT RUNG. One rule, four families, and the chip is therefore the closest
     * thing in the system to the colour the owner actually chose:
     *   olive  #6b8e23   rung 600, read off the olive ramp the family is named for
     *   petrol #187a73   rung 700
     *   plum   #bf3e5f   rung 700
     *   sand   #dfc08f   rung 300
     * Measured as OKLab delta E between each chip and the seed it stands for:
     *   olive 0.000 · petrol 0.014 · plum 0.043 · sand 0.036
     *
     * ══ THE 600 RUNG RULE THIS REPLACES, AND WHY IT WENT ══
     *
     * KEPT ON THE RECORD BECAUSE IT WAS NOT ABSURD, IT WAS WRONG ABOUT THE JOB.
     * For half a day this section said "the chip is the family hue at its 600
     * rung", which pins every chip to one identification luminance and lets the
     * fill carry its own 3:1 in both modes with no edge at all. Tidy, and it fails
     * the only thing a chip is for.
     *
     * A chip exists so that someone can pick a theme BY LOOKING AT IT. The 600
     * rung rule holds only while a seed sits near 600, and once a seed lands
     * elsewhere the chip stops resembling the family: the sand seed is a pale tan
     * at rung 300 and its 600 rung chip was #a7761a, a mid ochre, delta E 0.190
     * away from it. THE EVIDENCE THAT THIS MATTERS IS NOT HYPOTHETICAL. The owner
     * rejected the PREVIOUS sand seed on 2026-09-04 with one word, «بني», looking
     * at a rendered chip. Shipping a mid ochre chip for a family that is now
     * genuinely pale invites the identical complaint about a family that is
     * correct underneath, and that disagreement is far harder to locate than this
     * one was.
     *
     * ══ THE PRICE, PAID IN FULL: EVERY CHIP CARRIES A HAIRLINE ══
     *
     * A seed rung chip cannot carry its own SC 1.4.11 boundary in both modes,
     * because a family seed is a colour somebody liked and not a value chosen to
     * sit on two opposite grounds. Measured, chip fill against the level 3 float
     * surface it is drawn on, worst case across all four families planes:
     *   olive  #6b8e23   light 3.81:1 pass   dark 3.79:1 pass
     *   petrol #187a73   light 5.16:1 pass   dark 2.79:1 FAIL
     *   plum   #bf3e5f   light 5.16:1 pass   dark 2.79:1 FAIL
     *   sand   #dfc08f   light 1.74:1 FAIL   dark 8.28:1 pass
     * The edge therefore does real work in BOTH modes, on a different pair of
     * chips each time.
     *
     * IT IS ON ALL FOUR, NOT ONLY ON THE FAILING ONES. Four discs where one has
     * an edge and three do not reads as a rendering defect, and the failing SET
     * changes with the mode anyway, so a conditional edge would appear and vanish
     * as the user flips the theme. One rule, four chips, both modes.
     *
     * IT IS AN OBJECT BOUNDARY AND NOT A FOCUS RING, which is why it does not
     * read fx-color-focus-ring. Focus in this platform is a soft glow by owner
     * decision, and a ring drawn permanently around every chip would be a false
     * focus signal on four elements at once. It is a LINE, so it comes from the
     * line families in 2.3 — specifically fx-color-border-strong, the one member
     * of those families built to clear 3:1, and the one that prefers-contrast and
     * forced-colors already promote every other line onto. The translucent trio
     * measures 1.10 to 1.32:1 and would have moved the failure rather than fixed
     * it.
     *
     * THE EDGE IS MEASURED AGAINST THE GROUND, NOT AGAINST THE FILL, and that is
     * the correct target: a boundary is visible when it separates from EITHER
     * neighbour, and the ground is the one thing constant across all four chips.
     * It resolves to the family neutral 500 rung, which is luminance matched
     * across families, so ONE number covers every family in each mode:
     *   edge on the light level 3, white ......... 3.53:1
     *   edge on the dark level 3 ................. 4.08:1
     * Both clear the 3:1 floor for a non text boundary, in all four families, and
     * neither moves under prefers-contrast, because border-strong is already the
     * value that query promotes onto. Against the FILLS the edge runs 1.08:1
     * (olive) to 2.03:1 (sand), which is expected and is not the guarantee.
     *
     * AND THE FOUR ARE DISTINGUISHABLE FROM EACH OTHER, which is a different
     * question again. They no longer share one luminance, so they now separate by
     * lightness AS WELL as by hue: OKLab delta E runs from 0.143 at the closest
     * pair (olive against petrol, 61 degrees of hue) to 0.325 at the farthest
     * (petrol against sand), every one of them several times the just noticeable
     * difference. Under the retired rule the closest pair was 0.107. */
    --fx-color-swatch-olive:  var(--fx-p-olive-600);
    --fx-color-swatch-petrol: #187a73;   /* p-petrol-700, see 13.1.1 */
    --fx-color-swatch-plum:   #bf3e5f;   /* p-plum-700, see 13.2.1   */
    --fx-color-swatch-sand:   #dfc08f;   /* p-sand-300, see 13.3.1   */
    /* ADDED 2026-09-04 (seventh pass). Two more seed rung chips, derived exactly
     * as the four above: each is its family's seed as that seed lands on the
     * ladder, so the picker shows the colour the owner chose rather than a token
     * that happens to be near it.
     *
     * THE TABLE ABOVE IS EXTENDED, NOT REPLACED, and the edge earns its keep on
     * two more chips. Measured, chip fill against the level 3 float surface it is
     * drawn on:
     *   indigo #5660d9   light 5.16:1 pass   dark 2.79:1 FAIL
     *   navy   #014e97   light 8.27:1 pass   dark 1.74:1 FAIL
     * navy is now the worst chip in dark, below sand's light figure of 1.74, so
     * four of the six chips depend on the hairline in dark and two do in light.
     * The edge is on all six for the reason already recorded: a conditional edge
     * would appear and vanish as the user flips the theme.
     *
     * AND THE SIX ARE DISTINGUISHABLE FROM EACH OTHER, which the four chip table
     * above answers for four. Re-measured across all fifteen pairs, OKLab delta E
     * runs from 0.141 at the closest pair to 0.447 at the farthest:
     *   indigo vs navy .... 0.141   hue 20.8   lightness ratio 1.60:1  <- closest
     *   olive vs petrol ... 0.143   hue 61.2   lightness ratio 1.36:1
     *   petrol vs navy .... 0.162   hue 66.7   lightness ratio 1.60:1
     *   sand vs navy ...... 0.447   hue 175.4  lightness ratio 4.76:1  <- farthest
     * THE CLOSEST PAIR DID NOT GET CLOSER when the set grew from four to six: it
     * moved from 0.143 to 0.141, two thousandths, on an axis where a just
     * noticeable difference is about 0.02. THREE OF THE SIX CHIPS ARE BLUE ISH —
     * petrol at hue 187.5, navy at 254.2, indigo at 275.0 — and only the navy to
     * indigo step is tight in hue. What separates that pair is LIGHTNESS: their
     * seeds land on different rungs, 700 and 800, so the chips measure 1.60:1
     * apart as fills where olive and petrol manage only 1.36:1. The lesson the
     * sixth pass recorded, that lightness separation is what rescues a chip set,
     * is what is doing the work here too. */
    --fx-color-swatch-indigo: #5660d9;   /* p-indigo-700, see 13.5.1 */
    --fx-color-swatch-navy:   #014e97;   /* p-navy-800, see 13.6.1   */
    /* ADDED 2026-09-05 (eighth pass). Two more seed rung chips, derived exactly as
     * the six above: each is its family's seed as that seed lands on the ladder.
     *
     * THE TABLE ABOVE IS EXTENDED, NOT REPLACED. Measured, chip fill against the
     * level 3 float surface it is drawn on:
     *   graphite #405061   light 8.27:1 pass   dark 1.74:1 FAIL
     *   violet   #aa4ffd   light 4.00:1 pass   dark 3.60:1 pass
     * البنفسجي is the FIRST CHIP IN THE SET THAT PASSES IN BOTH MODES without the
     * hairline, because its seed lands mid ladder at rung 600 where every other
     * seed but الرملي الدافئ's sits deep. It keeps the edge anyway, for the reason
     * already recorded twice: a conditional edge would appear and vanish as the user
     * flips the theme, and eight discs where seven have an edge reads as a defect.
     *
     * AND THE EIGHT ARE DISTINGUISHABLE FROM EACH OTHER. Re-measured across all 28
     * pairs, OKLab delta E runs from 0.102 at the closest to 0.447 at the farthest:
     *   navy vs graphite ... 0.102   hue   4.0  lightness ratio 1.01:1  <- closest
     *   petrol vs graphite . 0.126   hue  62.7  lightness ratio 1.24:1
     *   indigo vs navy ..... 0.141   hue  20.8  lightness ratio 1.28:1
     *   olive vs petrol .... 0.143   hue  61.2  lightness ratio 1.14:1
     *   indigo vs violet ... 0.146   hue  28.9  lightness ratio 1.14:1
     *   sand vs navy ....... 0.447   hue 175.4  lightness ratio 1.92:1  <- farthest
     * THE CLOSEST PAIR DID GET CLOSER when the set grew from six to eight, from
     * 0.141 to 0.102, and the mechanism changed with it. Every earlier close pair
     * was rescued by LIGHTNESS, sitting on different rungs. الكحلي and الفحمي sit on
     * the SAME rung, so they measure 1.00:1 against each other as fills and are
     * rescued by CHROMA alone: 0.1363 against 0.0349, a factor of 3.91. At five
     * times a just noticeable difference that holds, and it is the difference the
     * two names promise — a blue and a grey. It is recorded rather than fixed
     * because fixing it would mean rotating a hue the owner chose. If it ever needs
     * more room the lever is the graphite chip's RUNG, not its hue: rung 700 would
     * take the pair to dE 0.139 at the cost of the chip no longer being the seed.
     * البنفسجي does not tighten the set at all; its nearest neighbour is النيلي at
     * 0.146, looser than four pairs that already shipped. */
    --fx-color-swatch-graphite: #405061;   /* p-graphite-800, see 13.7.1 */
    --fx-color-swatch-violet:   #aa4ffd;   /* p-violet-600, see 13.8.1   */
    /* The edge every chip carries. Named rather than consumed directly so the
     * picker reads one token that says what it is, and so the 3:1 obligation
     * recorded above sits beside the declaration that owes it. */
    --fx-color-swatch-edge:   var(--fx-color-border-strong);
}


/* ── 3) Semantic colour — DARK ─────────────────────────────────────────────
 * Flipped by html[data-bs-theme="dark"], set by frihat-theme.js. Every value
 * here is a deliberate dark-mode choice, not a mechanical inversion.
 * ────────────────────────────────────────────────────────────────────────── */
html[data-bs-theme="dark"]:root {
    /* ══ 3.1 THE ELEVATION LADDER — DARK ═══════════════════════════════════
     *
     * A true four plane ladder: every step goes UP toward lighter, which on a
     * near black page is unambiguously the raised direction. Level 0 is the
     * frozen legacy page black; levels 1 to 3 are lightness steps on the same
     * hue, no new colour.
     *
     * RETUNED 2026-08-02. The steps used to run 1.079 / 1.092 / 1.236 and to
     * WIDEN as they climbed. They now run at a flat 1.05, which is Linear's
     * band and is deliberately below the threshold at which a step is legible
     * on its own. In dark this matters more than in light: the background step
     * is so small that the SHADOW does nearly all the work of separating a
     * floating surface, which is why the dark shadow alphas RISE with elevation
     * while the light ones fall (see section 6).
     *
     * MEASURED STEPS:
     *   0 → 1  #10211a → #17251b   1.050:1
     *   1 → 2  #17251b → #1b291f   1.051:1
     *   2 → 3  #1b291f → #1f2d23   1.054:1
     *   0 → 3  #10211a → #1f2d23   1.162:1
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-level-0: var(--fx-p-n-1000);        /* #10211a — page   */
    --fx-color-level-1: #17251b;                   /* card   */
    --fx-color-level-2: #1b291f;                   /* raised */
    --fx-color-level-3: #1f2d23;                   /* overlay + float shadow */

    /* 3.1.1 Ladder aliases. bg-subtle and surface-sunken are the one plane
     * BELOW the ladder — a well cut into the page rather than a plane above
     * it — so they keep their own primitives in both themes rather than
     * pointing at a level. */
    --fx-color-bg:             var(--fx-color-level-0);
    --fx-color-bg-subtle:      var(--fx-p-dark-well);
    --fx-color-surface:        var(--fx-color-level-1);
    --fx-color-surface-raised: var(--fx-color-level-2);
    --fx-color-surface-sunken: var(--fx-p-dark-well);
    --fx-color-overlay-solid:  var(--fx-color-level-3);

    /* The two dimmers flip to BLACK here. Read the rule over 2.1.2 — the change
     * of COLOUR between the themes is the point, not the change of alpha. The
     * scrim is heavier in dark than in light (0.85 against 0.65) because a
     * near-black page dimmed gently still reads as an operable page, whereas a
     * near-white one does not. The veil stays weaker than the scrim in both. */
    --fx-color-scrim:   rgba(0, 0, 0, 0.85);

    /* The loading scrim. See the light block for the four measurements that set
     * these two values; in dark it matches the dialog scrim exactly, because a
     * black veil over a near-black page already clears SC 1.4.11 by a wide
     * margin and lightening it would only cost contrast on the case that
     * actually binds — the mark sitting over LIGHT content. */
    --fx-color-scrim-loading: rgba(0, 0, 0, 0.85);
    --fx-color-overlay: rgba(0, 0, 0, 0.70);

    /* 3.2 The four text tiers — read the rule over 2.2, it is the same rule.
     * MEASURED against fx-color-level-0, the page, with the level 3 figure in
     * brackets because in DARK the highest plane is the worst case (every
     * higher plane is lighter and therefore closer to the type):
     *   primary     #e7efe6   14.26:1   (12.27)
     *   secondary   #c8d6ca   11.10:1   ( 9.55)
     *   tertiary    #8b9a8f    5.67:1   ( 4.88)
     *   quaternary  #6b7a71    3.70:1   ( 3.19)
     * Tertiary still clears AA on every plane it is used on. Quaternary is
     * sub-AA on every plane, by design — it is not load bearing text. */
    --fx-color-text:            #e7efe6;
    --fx-color-text-muted:      #c8d6ca;
    --fx-color-text-subtle:     #8b9a8f;
    --fx-color-text-faint:      #6b7a71;
    /* The placeholder tier — see 2.2.2 over the light declaration. Identical to
     * subtle at rest here too; the two only part company under section 11. */
    --fx-color-text-placeholder: var(--fx-color-text-subtle);
    /* PURE WHITE, not the off white fx-p-on-primary the light theme uses, and
     * the ink is the only lever left. Dark fx-color-primary is green-700 and
     * the green ramp is FROZEN, so the fill cannot move: measured against the
     * off white ink #eef4e8, green-600 gives 3.57:1 and green-500 2.71:1, both
     * short of AA, while green-800 fails in the other direction at 2.02:1 as a
     * fill against the dark page and so misses the 3:1 fill vs page floor.
     * green-700 is the unique viable ramp step. Swapping the ink to white takes
     * white on brand from 4.61:1 to 5.16:1, i.e. AA headroom from 0.11 to 0.66,
     * which is what makes the hover ceiling in 04-buttons affordable at all.
     * Light keeps the off white ink: there the fill is dark and does not need
     * the extra half stop. */
    --fx-color-text-on-primary: var(--fx-p-white);
    --fx-color-text-inverse:    var(--fx-p-dark-ink);

    /* The second tier on a brand fill — read the rule over 2.2.1, and read the
     * paragraph about why this theme's percentage is higher before lowering it.
     * 92 percent of white over green-700 measures 4.65:1; 90 is the floor at
     * 4.52 and 88 fails at 4.38. There is no third tier available here. */
    --fx-color-text-on-primary-muted:
        color-mix(in srgb, var(--fx-color-text-on-primary) 92%, var(--fx-color-primary));

    /* 3.3 Two line families — see the rule over 2.3, it is the same rule.
     * The translucent family flips from a green-black ink to a green-white
     * one, because on a dark ground a lighter edge is what reads as an edge.
     * The olive tint they used to carry is gone: a border is not an accent. */
    --fx-color-border-subtle:   rgba(231, 239, 230, 0.05);
    --fx-color-border:          rgba(231, 239, 230, 0.08);
    --fx-color-border-emphasis: rgba(231, 239, 230, 0.14);
    --fx-color-border-strong:   var(--fx-p-n-500);

    --fx-color-divider-strong:  #333d36;
    --fx-color-divider:         #242e27;
    --fx-color-divider-soft:    #1d2721;
    --fx-color-divider-faint:   #192720;

    /* 3.3.1 Field wells — same direction as light now: a control is RAISED
     * out of the page, never recessed into it. Rest is level 2; hover is
     * level 3; focus is one further lightness step on the same hue.
     *
     * Placeholder text is fx-color-text-subtle (the tertiary tier, which is
     * where Linear puts it) and it clears AA on the rest fill: 5.14:1 dark,
     * 5.71:1 light. Under the previous ladder subtle would have failed here,
     * which is why the old note sent placeholders to muted; the compressed
     * ladder removed that constraint. */
    --fx-color-field-bg:       var(--fx-color-level-2); /* #1b291f */
    --fx-color-field-bg-hover: var(--fx-color-level-3); /* #1f2d23 */
    --fx-color-field-bg-focus: #233126;                 /* lights up */

    /* 3.4 Primary — one ramp step brighter than light, so the fill stays
     * visible against the green black page.
     *   white over primary        5.16:1   ← the ink in force, see 3.2
     *   off white #eef4e8 over it 4.61:1   ← the light theme ink, rejected here
     *   primary fill vs the page  3.24:1
     * WHY THE TWO THEMES DO NOT SHARE ONE HEX. Linear picks its brand twice at
     * roughly equal apparent lightness. We cannot: the green ramp is frozen,
     * and only green-700 and darker clear 4.5:1 against white, while only
     * green-700 and lighter clear 3:1 as a fill against the dark page. One hex
     * cannot satisfy both, so the pair is 800 in light and 700 in dark and the
     * lightness parity is the constraint that was dropped. Deliberate. */
    --fx-color-primary:        var(--fx-p-green-700);
    --fx-color-primary-hover:  var(--fx-p-green-800);
    --fx-color-primary-active: var(--fx-p-green-900);
    --fx-color-primary-subtle: rgba(30, 125, 67, 0.20);
    --fx-color-primary-rgb:    30, 125, 67;

    /* ══ 3.4.2 THE BRAND FILL'S BOUNDARY — AND WHY THE FILL DID NOT MOVE ══
     *
     * ADDED 2026-09-04, after 05-forms themed select2 and bootstrap-datepicker,
     * measured the selected option and the selected day, and reported
     * fx-color-primary at 2.94:1 against fx-color-surface-raised. It deferred
     * rather than patching those two call sites. This is the token answer to it.
     *
     * THE FINDING IS SYSTEMIC AND SLIGHTLY WORSE THAN REPORTED. Measured across
     * all four families, the dark brand fill against every plane:
     *     level-0 3.24   level-1 3.09   level-2 2.94   level-3 2.79
     * identical to two decimals in olive, petrol, plum and sand, because every
     * family 700 rung and every family dark ladder carry the same relative
     * luminance by construction. So it is the shape of the dark block and not an
     * olive artefact. And the plane a dropdown panel or a datepicker popup
     * actually floats on is the HIGHEST one, where the figure is 2.79 rather than
     * 2.94 — measuring it against a better ground makes it worse, not better.
     *
     * THE FILL COULD NOT BE MOVED, AND THAT IS ARITHMETIC RATHER THAN A
     * PREFERENCE. A dark brand fill is squeezed between two floors:
     *     it must clear 3:1 against level-3 ...... relative luminance >= 0.1687
     *     white ink on it must clear 4.5:1 ....... relative luminance <= 0.1833
     * That window is 0.0147 wide and NO RAMP RUNG LIES INSIDE IT: rung 700 sits
     * at 0.1535, just below, and rung 600 at 0.2123, well above. Rung 600 was
     * tested and fails the ink at 4.00:1, which is the same result 3.4 already
     * records. A color-mix CAN be placed inside the window, and every value that
     * fits drops fx-color-text-on-primary-muted to 4.09 to 4.30:1, i.e. through
     * the 4.5 floor that 2.2.1 measured at 90 percent and found already failing
     * at 88. The best case buys 3.02:1 against level-3, two hundredths of
     * headroom, and pays for it with a real AA failure on the second ink tier
     * plus 0.38 off the primary ink. That is not a trade. It swaps a marginal
     * SC 1.4.11 miss for an outright SC 1.4.3 one.
     *
     * SO THE BOUNDARY IS ADDED INSTEAD, AND THE FILE ALREADY RULED FOR EXACTLY
     * THIS SHAPE. Section 2.7: a solid fill on the DARK page does not itself
     * clear 3:1 against that page, so a filled status chip in dark must also
     * carry its border token, and that is what the trio is for. Measured, the
     * four status fills against level 1 are 2.43 to 2.76:1 and their border
     * siblings carry 3.03 to 3.97:1. fx-color-primary was the ONLY fill in the
     * system without a border sibling. That was the gap. This closes it in the
     * token layer, once, for every consumer present and future.
     *
     * THE VALUE IS THE 600 RUNG, one step lighter than the fill. Measured, in
     * all four families, against every plane:
     *     level-0 4.18   level-1 3.98   level-2 3.79   level-3 3.60
     * so it clears the 3:1 floor on the worst plane with 0.60 to spare, where
     * the fill missed it by 0.21. Against its own fill it measures 1.29:1, and
     * that is deliberate: it is a RIM that lets the filled shape read against
     * the panel behind it, not a ring drawn around the shape.
     *
     * NOT THE 500 RUNG, though it measures better at 4.75:1. 500 is the dark
     * focus ring and the dark indicator, and 3.5.1 rules that every position
     * signal in dark is one colour. A resting state boundary that borrowed the
     * focus colour would announce focus on every selected row on the screen.
     *
     * AND THE STATE WAS NEVER CARRIED BY THE FILL ALONE, which is why this was a
     * defect worth fixing properly rather than an emergency. A selected option
     * also repaints its ink to fx-color-text-on-primary, measured at 5.16 / 5.16
     * / 5.16 / 5.15:1 on the four families dark fills, comfortably past
     * SC 1.4.3. A user could always READ which option was selected. What was
     * short was the filled shape edge against the panel, and that is what the
     * rim fixes. */
    --fx-color-primary-border: var(--fx-p-green-600);

    /* 3.4.1 THE BAND — SAME FIXED VALUE AS LIGHT, DELIBERATELY NOT THIS
     * BLOCK'S green-700 step. See 2.4.2 for the full rule and the client
     * quote it answers: the band is one brand surface and must read as one
     * colour in both themes, so it does not take the split fx-color-primary
     * takes here. This trades away the fill-vs-page margin dark used to have
     * at green-700 (3.24:1) for green-800's 2.02:1 against the dark page —
     * see the dated decision note over --fx-band-bg in 03-leptonx 4.0, which
     * records why that trade was accepted rather than merely defaulted into. */
    --fx-color-band:    var(--fx-p-green-800);
    --fx-color-band-fg: var(--fx-p-on-primary);

    /* The band's INTERACTION mark, gold, and the twin of the rail's position
     * mark above — same primitive, so a highlight means the same thing on both
     * brand surfaces. Owner decision 2026-08-04.
     *
     * It exists because LeptonXLite hovers the breadcrumb glyphs to
     * `var(--lpx-brand)`, its own green, at a specificity that beats the band's
     * ink rule. Green on the green band is green on green: the home icon simply
     * DISAPPEARED under the pointer, which is how the owner reported it. A brand
     * colour is the right instinct on a neutral bar and exactly wrong on a brand
     * bar — the mark has to leave the surface's own hue.
     *
     * Gold measures 4.53:1 on the band. The glyph is the entire content of its
     * link, so it is a graphical object under SC 1.4.11 and needs 3:1; it clears
     * that with room, and it is a hover state promoting FROM the 5.36:1 muted
     * ink rather than replacing a resting value. Pinned in both themes for the
     * same reason the fill and ink are. */
    --fx-color-band-mark: var(--fx-p-amber-300);

    /* 3.5 Accent */
    --fx-color-accent:        var(--fx-p-olive-500);
    --fx-color-accent-hover:  var(--fx-p-olive-400);
    --fx-color-accent-subtle: rgba(133, 161, 61, 0.18);
    --fx-color-accent-rgb:    133, 161, 61;   /* mirrors p-olive-500 */

    /* ══ 3.5.1 IDENTITY MARKS — DARK ═══════════════════════════════════════
     *
     * Read the rule over 2.5.1; it is the same rule. What changes here is that
     * the two tokens land on DIFFERENT RAMPS, which is the whole reason they
     * are two tokens and not one.
     *
     * fx-color-indicator stays GREEN, at green-500 — the same step as the dark
     * focus ring, so every position signal in dark is one colour. It cannot be
     * green-700, the dark fx-color-primary step, because a bar at green-700
     * measures 2.94:1 on level 2 and 2.79:1 on level 3 and fails SC 1.4.11 on
     * the two planes a tab strip and a grid header most often sit on.
     *
     * fx-color-brand-text WAS OLIVE, at olive-400, and MOVED TO MINT-500 ON
     * 2026-08-02 (fourth pass). Read this before moving it back, because the
     * constraint that put it on olive was real and it is the mint ramp that
     * lifted it. Nothing on the frozen GREEN ramp is simultaneously bright
     * enough to read on the dark page and still recognisably the brand green —
     * green-700 is the top of it and measures 3.24 / 3.09 / 2.94 / 2.79 across
     * the four dark planes, which fails SC 1.4.3 on all four. Olive-400 was the
     * substitute, at 8.88 down to 7.64. The client supplied mint ramp in 1.2.1
     * is the first GREEN in the system that clears that bar: mint-500 measures
     * 10.44 / 9.95 / 9.47 / 8.99, better than olive on every plane. So the dark
     * kicker and the active nav label are now the client's own green rather than
     * a substitute hue, which is what he asked for and what the third pass could
     * not deliver with the ramps it had.
     *
     * WHY THE INDICATOR DID NOT FOLLOW IT ONTO MINT. The mark never had the
     * problem the text had — green-500 clears the 3:1 SC 1.4.11 floor on all
     * four planes with 1.75 of headroom at worst, so there is nothing to fix.
     * Keeping it green-500 also keeps it identical to the dark focus ring, and
     * "every position signal in dark is one colour" is worth more than hue
     * uniformity with the label beside it. The bar and the label are now
     * green-500 and mint-500 — the same hue family two steps apart, which reads
     * as a ramp rather than as the previous green bar against an olive label.
     *
     * MEASURED against every plane, dark:
     *   indicator  green-500  level-0 5.52  level-1 5.26  level-2 5.01  level-3 4.75
     *   brand-text mint-500   level-0 10.44 level-1 9.95  level-2 9.47  level-3 8.99
     *   (was olive-400        level-0 8.88  level-1 8.46  level-2 8.05  level-3 7.64)
     * And on the active sidebar row composite, fx-color-active over the level 1
     * rail, #243728:
     *   indicator bar 4.19:1 · brand label 7.93:1 · primary text 10.83:1
     * The label gained a full point over the olive it replaced (6.81:1). */
    --fx-color-indicator:  var(--fx-p-green-500);
    --fx-color-brand-text: var(--fx-p-mint-500);

    /* ══ THE RAIL, RE-DECLARED FOR DARK — 2026-08-03 ═══════════════════════
     * The light block used to hold the ONLY declaration of fx-color-rail and
     * dark simply inherited it. Since the client chose Linear's model the rail
     * is a theme-aware plane, so dark states its own value here — and that value
     * is BIT FOR BIT the one the single declaration used to produce, because
     * dark was the theme the constant was right for. The full argument, both
     * measurements and the olive constraint on the light rung are recorded over
     * the light declaration in section 2.4; nothing about the near-black plane
     * or the ratios 03-leptonx 7.0 measures against it has changed.
     *
     * MEASURED, dark: rail vs its own sunken canvas 1.064:1 — one rung, which
     * is the relationship light is now built to mirror. Against the OLD level-0
     * canvas it was 1.004; the canvas recess in 03-leptonx 3.0 is what moved it,
     * and one rung is the better number: the two planes still read as a single
     * continuous field (1.064 is under the 1.045-to-be-legible threshold's
     * practical reach at this scale) while the card's 1.122 remains the only
     * edge that reads. */
    --fx-color-rail: color-mix(in srgb, var(--fx-p-green-900) 55%, var(--fx-p-black));

    /* White, at 16.82:1 on that plane. See the light declaration for why the
     * rail's ink is named here rather than read as a primitive inside a
     * component stylesheet. */
    --fx-color-rail-fg: var(--fx-p-white);

    /* ══ THE SHELL IN DARK — POINTED AT WHAT DARK ALREADY HAD ══════════════
     * The 2026-08-04 shell ruling is a LIGHT-THEME change. Dark's chrome was
     * already a dark plane, so the correct dark value for the new knob is the
     * canvas dark was painting before the knob existed. Declaring it here rather
     * than leaving it to inherit is what makes that true: without these two
     * lines the light block's green-800 would fall through and dark would gain a
     * mid-green shell nobody asked for.
     *
     * Note the rail is deliberately NOT re-pointed at the shell in dark. In
     * light the two are one surface by client instruction; in dark the rail
     * keeps its own near-black green, one rung off this canvas, which is the
     * relationship measured immediately above. */
    --fx-color-shell:    var(--fx-color-surface-sunken);
    --fx-color-shell-fg: var(--fx-color-text);

    /* Gold, the same primitive light uses, so the position mark means the same
     * thing in both themes. It measures 9.21:1 on the dark rail plane against
     * 4.53:1 on the light one — both clear AA, and the dark figure clears AAA.
     * This REPLACES the previous dark mark (fx-color-indicator, green-500): a
     * mark that changed hue with the theme was saying two different things. */
    --fx-color-rail-mark: var(--fx-p-amber-300);

    /* 3.6 Links — MINT since 2026-08-02 (fourth pass), olive before that, and
     * never green, which is not a style choice. The frozen green ramp tops out
     * at green-700, which is 3.24:1 on the dark page and cannot carry link TEXT.
     * Olive-400 was the substitute at 8.88:1. The client supplied mint ramp
     * clears the bar with more room — mint-500 is 10.44:1 on the page and 8.99:1
     * on the highest plane — and it is a GREEN, so the dark link is no longer a
     * different hue family from the light link. Hover goes one rung LIGHTER, to
     * mint-400 at 11.10:1, which is the same brighten-on-hover direction the
     * olive pair used.
     *
     * fx-color-brand-text carries the same value, as it did when both were
     * olive; the two tokens exist so a call site says what it is colouring. See
     * 3.5.1. */
    --fx-color-link:       var(--fx-p-mint-500);
    --fx-color-link-hover: var(--fx-p-mint-400);

    /* Channel triplets — dark. link-rgb mirrors p-mint-500 #96dd99,
     * text-rgb mirrors the dark body text #e7efe6. */
    --fx-color-link-rgb:   150, 221, 153;
    --fx-color-text-rgb:   231, 239, 230;

    /* ══ 3.7 STATUS — DARK. THE FOUR BARE SOLIDS ARE ABSENT ON PURPOSE ═════
     *
     * Fills stay identical to light so a component needs one rule, not two; the
     * fg / bg / border trio carries the dark treatment. A solid status fill on
     * the dark page should also carry its border token, because the fill alone
     * does not clear 3:1 against the page.
     *
     * NOTHING NAMED fx-color-success / -warning / -danger / -info APPEARS
     * BELOW, AND NOTHING MAY BE ADDED. Those four inherit their light-mode
     * 600-step hues into this theme, which is correct for the one job they
     * have — a FILL under a light label — and wrong for every other job. The
     * full rule, the measurements and the arithmetic for why brightening them
     * here would make things worse are in section 2.7. Read it before adding a
     * status colour to any dark rule.
     *
     * THE SHORT FORM, for anyone scanning: bare solid = fill under a light
     * label ONLY. Text and boundaries take -fg. A status colour used as a
     * border, a seam, an underline, an icon or a label in dark and NOT routed
     * through -fg is an SC 1.4.3 or SC 1.4.11 failure, and it will look fine in
     * light while it fails.
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-color-success-fg:     var(--fx-p-emerald-300);
    --fx-color-success-bg:     var(--fx-p-emerald-900);
    --fx-color-success-border: var(--fx-p-emerald-800);

    --fx-color-warning-fg:     var(--fx-p-amber-300);
    --fx-color-warning-bg:     var(--fx-p-amber-900);
    --fx-color-warning-border: var(--fx-p-amber-800);

    --fx-color-danger-fg:     var(--fx-p-red-300);
    --fx-color-danger-bg:     var(--fx-p-red-900);
    --fx-color-danger-border: var(--fx-p-red-800);

    --fx-color-info-fg:     var(--fx-p-blue-300);
    --fx-color-info-bg:     var(--fx-p-blue-900);
    --fx-color-info-border: var(--fx-p-blue-800);

    /* 3.8 Interaction — A TINT, not brand, except the ring. See 3.9.
     *
     * RETUNED 2026-08-02 (fourth pass). The washes were a green-white ink at 5
     * and 8 percent. They are now the CLIENT SUPPLIED MINT RAMP from 1.2.1 —
     * mint-500, the deepest rung — at 6 and 10 percent. A selected row in dark
     * is now a slightly lighter row WITH A GREEN CAST, which is the most this
     * theme can honestly do with the instruction.
     *
     * WHY THE RAMP IS USED AT ALPHA HERE AND OPAQUE IN LIGHT, WHICH IS THE ONE
     * THING NOT TO "FIX" INTO SYMMETRY. All five client hexes are LIGHT
     * colours, luminance 0.605 to 0.845. Painted as opaque fills on a near
     * black page they would land far above level 3, so a hovered row would
     * outrank every floating surface in the system and the elevation model
     * would invert. At low alpha the same ramp instead LIFTS the host plane by
     * a fixed proportion, which is exactly what the greys did, and the wash
     * still tracks whichever plane it sits on.
     *
     * WHY 6 AND 10 PERCENT AND NOT THE 5 AND 8 THE GREYS USED. mint-500 is a
     * darker ink than the #e7efe6 it replaces, so the same alpha would have
     * lifted less. These two figures were chosen to reproduce the previous
     * lift almost exactly rather than to intensify it. Measured, wash against
     * its own host plane:
     *     hover   NEW 1.134 / 1.143 / 1.147 / 1.153 on levels 0 to 3
     *             OLD 1.130 / 1.138 / 1.145 / 1.151
     *     active  NEW 1.254 / 1.255 / 1.262 / 1.272
     *             OLD 1.226 / 1.241 / 1.250 / 1.259
     * A hover wash also stays clear of the plane above it — hover on level 0
     * measures 1.080 against level 1, on level 1 1.088 against level 2, on
     * level 2 1.089 against level 3 — so no wash collapses into the next rung.
     *
     * MEASURED, all four text tiers over the washes, worst plane first. The
     * bracketed figure is what the grey wash it replaces measured, so the
     * comparison is on the record:
     *     hover  on level-0   primary 12.58 (12.62)  secondary 9.79 (9.82)
     *                         tertiary 5.00 (5.02)   quaternary 3.27 (3.28)
     *     hover  on level-3   primary 10.64 (10.66)  secondary 8.28 (8.30)
     *                         tertiary 4.23 (4.24)   quaternary 2.76 (2.77)
     *     active on level-0   primary 11.37 (11.63)  secondary 8.86 (9.06)
     *                         tertiary 4.53 (4.63)   quaternary 2.95 (3.02)
     *     active on level-3   primary  9.64 ( 9.74)  secondary 7.51 (7.59)
     *                         tertiary 3.84 ( 3.88)  quaternary 2.51 (2.53)
     * PRIMARY AND SECONDARY CLEAR AA EVERYWHERE, by a factor of two or better.
     * TERTIARY IS THE HONEST CAVEAT and it is INHERITED, not introduced: the
     * tier is already only 4.88:1 on a bare level 3 in this theme, so ANY wash
     * laid over the upper planes pushes it under 4.5 and the greys did so too.
     * The mint figures are within 0.10 of the greys on every cell above. The
     * mitigation is the ICON RULE in 2.2 — a hovered or selected row promotes
     * its content one tier, so nothing tertiary is meant to be sitting on these
     * fills in the first place. A component that leaves a timestamp at tertiary
     * inside a selected dark row is the defect; the wash is not.
     *
     * THE FOCUS RING IS BRAND HERE AND IN LIGHT. It used to be the ONE
     * dark-only accent site, because light ran a translucent ink ring that
     * could not work in dark — a translucent white ring on a near black page is
     * indistinguishable from the hover wash it sits beside. Light has now
     * joined dark on brand (see the retune note over 2.8), so this is no longer
     * an exception; it is the general rule, expressed twice at the ramp step
     * each theme can afford.
     *
     * The dark step is unchanged at green-500 and RE-VERIFIED 2026-08-02 (third
     * pass) against every plane a ring can land on, SC 1.4.11 floor 3:1:
     *     level-0 #10211a   5.52:1        level-2 #1b291f   5.01:1
     *     level-1 #17251b   5.26:1        level-3 #1f2d23   4.75:1
     * Why not the dark brand step green-700, which fx-color-primary uses? It
     * measures 3.24 / 3.09 / 2.94 / 2.79 on the same four planes and FAILS on
     * both of the upper two. green-600 clears at 3.60 worst case but with only
     * 0.6 of headroom on a 2px line. green-500 is the right step and stays.
     *
     * THE RING ALSO HAS TO SURVIVE LANDING ON A WASH, because a focus ring
     * routinely appears on a row that is already hovered or already selected.
     * RE-VERIFIED against the new mint washes, SC 1.4.11 floor 3:1:
     *     over hover   4.87 / 4.60 / 4.37 / 4.12 on levels 0 to 3
     *     over active  4.41 / 4.19 / 3.97 / 3.74
     * Worst case 3.74:1, which is 0.74 of headroom on the hardest combination
     * in the theme. The light ring, green-800, measures 7.05:1 over the light
     * hover wash and 6.45:1 over the light active wash.
     *
     * SELECTION moves onto the mint ramp with everything else, but as an ALPHA
     * rather than as one of the five hexes, for the elevation reason argued at
     * the top of this section. 22 percent is a deliberately heavier alpha than
     * the washes: a text selection has to out-read the row fill underneath it,
     * and at 22 percent it lifts its host plane by 1.71 against the active
     * wash's 1.26. Primary ink over it measures 8.34 down to 7.13 across the
     * four planes, against the old flat #2c3f33's 9.59 — a more visibly green
     * selection that still clears AA by more than half again. */
    --fx-color-focus-ring:   var(--fx-p-green-500);
    /* Expressed as color-mix against transparent rather than as a hand written
     * rgba triplet, so all three follow p-mint-500 automatically and there is
     * no second copy of the channel values to keep in step. Each resolves to
     * rgba(150, 221, 153, alpha). */
    --fx-color-selection-bg: color-mix(in srgb, var(--fx-p-mint-500) 22%, transparent);
    --fx-color-selection-fg: var(--fx-color-text);
    --fx-color-hover:        color-mix(in srgb, var(--fx-p-mint-500)  6%, transparent);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-mint-500) 10%, transparent);
    --fx-color-disabled-bg:  #1a251d;
    --fx-color-disabled-fg:  var(--fx-color-text-faint);
}


/* ── 3.9) ACCENT DISCIPLINE — A BRAND SURFACE, A BRAND MARK, AND A TINT ────
 *
 * THIS IS THE MOST IMPORTANT RULE IN THE FILE AND IT IS NOT A TOKEN.
 *
 * ══ THE RULE, IN ONE LINE ══════════════════════════════════════════════════
 *
 *     IDENTITY AND CURRENT POSITION ARE BRAND. INTERACTION IS A TINT.
 *
 * ══ THE THREE KINDS. THIS IS THE PART TO LEARN; THE LIST BELOW IS EVIDENCE ═
 *
 * RESTATED 2026-08-02 (fifth pass). The contract is unchanged in substance and
 * every earlier ruling in it still stands. What changed is that the rule is now
 * written as a DERIVATION instead of as a closed list, because the list had to
 * be extended three times in a single day. A list that moves that often is not
 * the rule — it is the evidence left behind by one.
 *
 * Brand appears in exactly two kinds of place, and everything else is a tint or
 * is not coloured at all:
 *
 *   A BRAND SURFACE — a FILL IN THE BRAND THAT OTHER CONTENT THEN SITS ON. Its
 *     job is to say WHOSE PRODUCT THIS IS. The shell's header band, an identity
 *     tile. The defining property is not size, it is that
 *     the surface REPLACES THE PLANE beneath its children, which is what makes
 *     it expensive: see THE SURFACE CLAUSE below. A surface is chrome, and
 *     chrome is rare and deliberate or it stops being chrome.
 *
 *   A BRAND MARK — a SMALL SIGNAL DRAWN ON a plane that already exists. Its job
 *     is to say WHERE YOU ARE. The active indicator bar, the tab underline, the
 *     page kicker, the grid sort arrow, the focus ring. It is a boundary, a
 *     glyph or two words. It lands on a surface; it never becomes one, and it
 *     changes nothing beneath it.
 *
 *   A TINT — the pale interaction fill that says THE POINTER OR THE KEYBOARD IS
 *     HERE. fx-color-hover and fx-color-active, and nothing else. NEVER brand,
 *     at any alpha, on any plane, however diluted.
 *
 * The discipline is the GAP between the three, and the gap is measurable. A
 * tint sits at 1.03 to 1.27 against the plane it covers. A mark sits at 3.35 to
 * 8.27 against whatever it lands on, wash included. A surface sits at 3.24 to
 * 7.25 against the page it interrupts. If a tint ever grows strong enough to be
 * mistaken for a mark, or a mark ever weakens enough to be mistaken for a tint,
 * the contract has collapsed, and the fix is to move the TINT back down — never
 * to move the mark up and never to promote a tint into a fill.
 *
 * ══ WHAT "A TINT" MEANS, SINCE IT USED TO SAY "GREY" ═══════════════════════
 *
 * REWORDED 2026-08-02 (fourth pass). Every occurrence of "a grey wash" below
 * now reads "a mint tint", and NOTHING ELSE IN THIS CONTRACT MOVED. The
 * interaction washes are the client supplied light green ramp in 1.2.1 instead
 * of neutral ink, because the greys were rejected twice by name; see 2.8 and
 * 3.8 for the values and the arithmetic.
 *
 * THE DISTINCTION THAT CARRIES THE WHOLE RULE IS STILL TINT VERSUS BRAND, AND
 * IT WAS NEVER GREY VERSUS GREEN. A tint is a pale, low contrast FILL that
 * says "the pointer is here"; a brand mark is a saturated, high contrast
 * GLYPH, BAR or LABEL that says "this is who we are" or "this is where you
 * are". The gap between them is what makes both legible, and it is measurable:
 * an interaction wash sits at 1.03 to 1.27 against the plane it covers, while
 * a brand mark sits at 4.19 to 8.27 against whatever it lands on, wash
 * included. If a wash is ever strong enough to be mistaken for a mark, or a
 * mark ever weak enough to be mistaken for a wash, the contract has collapsed
 * and the fix is to move the wash back down, never to move the mark up.
 *
 * The practical form of that test: A WASH MAY NOT USE A HUE FROM THE BRAND
 * RAMPS. The mint ramp is an interaction family; fx-color-primary,
 * fx-color-indicator, fx-color-brand-text, fx-color-link and fx-color-accent
 * are the brand and identity families. Painting a row hover in green-800 at
 * ten percent is exactly the "themed Bootstrap" failure this section exists to
 * prevent, and it is still forbidden — a diluted brand is not a tint.
 *
 * ══ THE TEST, WHICH IS MECHANICAL ══════════════════════════════════════════
 *
 * Hold the element up and ask, in this order:
 *
 *   Q1. Does this element tell me WHO THIS PRODUCT IS, or WHERE I CURRENTLY
 *       AM?                                                     → BRAND
 *   Q2. Does this element respond to MY POINTER or MY KEYBOARD?  → TINT
 *   Q3. Neither?                                                 → NEITHER.
 *       Reach for weight, size, space and a text tier. MOST OF THE PRODUCT
 *       LIVES HERE and that is the intended state, not a shortfall.
 *
 * Q1 wins ties, and there is exactly one apparent tie worth naming: the FOCUS
 * RING. A ring appears because the keyboard moved, which looks like Q2, but
 * what it communicates is WHERE THE KEYBOARD IS — position, not response. It
 * is brand, in both themes. Everything else that answers Q2 is a tint.
 *
 * IF Q1 ANSWERS, ASK ONE MORE QUESTION BEFORE PAINTING ANYTHING:
 *
 *   Q1a. Am I FILLING a plane that content will then sit on, or DRAWING a
 *        signal on a plane that already exists?
 *          FILLING  → a SURFACE. Read the surface clause; it is not optional
 *                     and it is most of the work.
 *          DRAWING  → a MARK. Point it at fx-color-indicator (a boundary or a
 *                     glyph, SC 1.4.11 at 3:1) or fx-color-brand-text (anything
 *                     read as words, SC 1.4.3 at 4.5:1) and you are finished.
 *
 * The two halves of Q1 line up with the two answers to Q1a almost every time,
 * and that is not a coincidence: WHO THIS PRODUCT IS is a statement large
 * enough to need a plane, and WHERE I AM is a pointer that only needs a mark.
 *
 * ══ WHY THIS SECTION WAS REWRITTEN 2026-08-02 (third pass) ═════════════════
 *
 * The previous contract sanctioned SIX sites and forbade everything else, on
 * the reasoning that Linear spends brand on under two percent of painted
 * pixels. Applied literally across nine stylesheets, that removed the Frihat
 * green from the product. The client's words: the brand colour does not exist
 * now. That is a real failure and it is corrected here rather than argued with.
 *
 * The mistake was importing a conclusion instead of a method. Linear is a
 * NEUTRAL-BRANDED product: its identity lives in its typography, its density
 * and its speed, so it can afford to spend almost no colour. FRIHAT'S IDENTITY
 * IS THE GREEN. The brief was always Linear STRUCTURE while keeping the brand
 * colours, and the two are not in conflict — Linear's actual discipline is not
 * "use less colour", it is "never let colour do a job that shape, weight or
 * position already does". Interaction feedback is that job. Identity is not.
 *
 * So the restraint stays and the target moves. The half of this rule that
 * matters most is still the FORBIDDEN list below: it is what keeps this from
 * sliding back into a themed Bootstrap admin panel, which is the failure mode
 * on the other side and is worse than the one we just corrected.
 *
 * ══ THE SURFACE CLAUSE — WHAT A BRAND PLANE ACTUALLY COSTS ═════════════════
 *
 * ADDED 2026-08-02 (fifth pass), after three surfaces went in and the rail
 * proved the clause the hard way.
 *
 * A surface is not a bigger mark. It changes the ground every child element
 * stands on, so EVERY TEXT TIER, GLYPH, LINE, WASH, FIELD, SCROLLBAR AND RING
 * ON A BRAND SURFACE MUST BE RE-DERIVED AGAINST THAT SURFACE, never inherited
 * from the page. The page tiers in 2.2 / 3.2 and the identity marks in 2.5.1 /
 * 3.5.1 are all measured against the SURFACE LADDER, and not one of them is
 * valid on brand green. Measured, on the surfaces we actually have:
 *
 *   · fx-color-text-muted on the light brand fill .......... 1.35:1  (2.2.1)
 *   · fx-color-indicator IS the light rail's own fill, so a position bar drawn
 *     with it is INVISIBLE; in dark it measures 1.95:1 on the rail's active row
 *   · fx-color-focus-ring is green-800 in light — the rail's own fill again, so
 *     a focused control inside the rail would show no indicator at all
 *   · fx-color-hover and fx-color-active are page treatments: a dark ink wash
 *     vanishes on a dark green plane and a mint wash is indistinguishable from
 *     it. The rail mixes its own washes out of its own ink instead.
 *
 * THE OBLIGATION THAT FOLLOWS. A brand surface declares a LOCAL TIER SET,
 * derived from ONE knob naming the fill and ONE naming the ink, so that the
 * whole surface follows if the fill ever moves and cannot be broken by a
 * page-level retune. The sidebar rail is the worked example and the pattern to
 * copy: fx-rail-bg and fx-rail-fg in 03-leptonx, with every foreground tier,
 * wash, line, field, scrollbar thumb and the focus ring mixed out of those two.
 * A surface that reaches for a page token is a defect even when it happens to
 * measure, because the next person who moves the fill will not know it did.
 *
 * The one ink decided centrally is fx-color-text-on-primary and its single
 * dimmed step fx-color-text-on-primary-muted in 2.2.1. There is no third step
 * and there will not be one: on a brand fill in dark, hierarchy comes from
 * size, weight and space. See the arithmetic recorded over that token.
 *
 * ══ WHEN A NEW SURFACE IS JUSTIFIED — ALL FOUR, OR IT IS NOT ONE ═══════════
 *
 * Chrome is rare or it stops being chrome, so this test is deliberately
 * expensive. It governs CHROME surfaces — the planes that frame the
 * application. It does not reopen the small sanctioned fills at sites 6 and 7
 * or the checked-control carve-out, which report an action or a value rather
 * than an identity and are already settled; those are bound by the ink
 * obligation above and by nothing else here.
 *
 *   S1. IDENTITY, NOT DECORATION. It answers the first half of Q1 — WHO THIS
 *       PRODUCT IS — on its own, with no content on it at all. A card is not
 *       identity. A card is a container for content and it answers Q3.
 *   S2. CHROME, NOT CONTENT. It frames, introduces or navigates. It never
 *       carries the record, the table, the form, the message or the data.
 *   S3. BOUNDED BY THE PAGE, NOT BY THE DATA. The count is authored and fixed,
 *       and it is countable on one hand across the whole product. Anything that
 *       recurs per ROW, per RESULT, per FIELD or per LIST ITEM is disqualified
 *       by frequency alone, whatever else it answers. This is the line that
 *       admits three authored dashboard tiles and refuses a grid row.
 *   S4. ITS LADDER IS RE-DERIVED AND MEASURED. Every foreground on it is
 *       re-measured against the fill, in BOTH themes, and the figures are
 *       recorded at the call site. No figures, no surface.
 *
 * And a fifth condition that is procedural rather than visual: A NEW SURFACE IS
 * A CLIENT DECISION, RECORDED WITH ITS DATE. Every surface this system has ever
 * had was asked for by name — the two that exist and the one that was retired on
 * 2026-08-03. A brand plane is the loudest thing this design system can do, and
 * it is not a move a stylesheet makes on its own initiative.
 *
 * THE CONDITION RUNS BOTH WAYS, which site 12 is the proof of: a surface is
 * WITHDRAWN the same way it was granted, by the client and with a date, and the
 * withdrawal is recorded rather than tidied away. A numbered site that quietly
 * vanishes is indistinguishable from one a reader simply failed to find.
 *
 * ══ SANCTIONED — IDENTITY AND POSITION ═════════════════════════════════════
 *
 * Sites 1 to 10 are MARKS and small sanctioned moments. Sites 11 and 13 are
 * SURFACES and carry the clause above. SITE 12 IS RETIRED and its number is not
 * reused: read its entry before assuming a surface may be added back there.
 *
 * These five were NEW IN THE THIRD PASS. They are what put the green back.
 *
 *   1. The ACTIVE SIDEBAR / NAV ITEM
 *      A brand INDICATOR BAR (fx-color-indicator) plus a brand LABEL
 *      (fx-color-brand-text), sitting on a TINTED fill (fx-color-active).
 *      The fill stays a tint — that part of the old contract was right and is
 *      unchanged; only its hue moved. The bar and the label are the position
 *      signal, and they still out-contrast the fill by four to one.
 *
 *      NOTE FOR THE NEXT READER, SO NOBODY "FIXES" THIS BACK. An accent bar
 *      was REMOVED from the active nav item during the second pass. That
 *      removal was CORRECT under the old contract and is WRONG under this one.
 *      It is being deliberately reinstated. If you are looking at a brand bar
 *      on a nav item and reaching for the six-site rule to delete it, the rule
 *      you are holding is the superseded one.
 *
 *   2. The ACTIVE TAB INDICATOR                    (fx-color-indicator)
 *      KNOWING DEVIATION, RECORDED. Linear paints this with its PRIMARY TEXT
 *      colour, not its brand — the old contract said so, and said it surprises
 *      everybody. We are departing from the reference here on purpose. A tab
 *      strip is the densest concentration of "where am I" in the product, and
 *      under a Q1 test it is unambiguously position. Painting it in ink would
 *      hand the single clearest identity surface back to grey. This is the one
 *      place in the file where we knowingly do not do what the reference does.
 *
 *   3. The PAGE or SECTION KICKER                  (fx-color-brand-text)
 *      The eyebrow label above a page title. It answers "who is this product"
 *      and "which part of it" in the same two words, once per page, at small
 *      size. Cheap in pixels, high in identity — the best value in the system.
 *
 *   4. The GRID SORT INDICATOR                     (fx-color-indicator)
 *      The arrow on the column the grid is CURRENTLY sorted by. Position in a
 *      dataset is still position. The inactive arrows on the other columns are
 *      a text tier and stay grey; only the live one is brand.
 *
 *   5. The FOCUS RING — IN BOTH THEMES             (fx-color-focus-ring)
 *      Was dark-theme-only. Light was translucent ink copied from Linear. See
 *      the retune note over 2.8 for the reasoning and all eight measurements.
 *
 * ══ SANCTIONED — ALREADY IN FORCE, UNCHANGED ═══════════════════════════════
 *
 *   6. The PRIMARY BUTTON fill   (one per screen region; a form has one)
 *   7. A FILLED BADGE            (the status pill that is genuinely a status)
 *   8. LINK TEXT                 (fx-color-link, underlined)
 *   9. The TEXT CARET in a search or command input   (caret-color only)
 *  10. The TEXT SELECTION background
 *      (fx-color-selection-bg — brand in HUE, neutral in WEIGHT)
 *
 * ══ SANCTIONED — BRAND SURFACES. TWO, AND THEY ARE CHROME ══════════════════
 *
 * ADDED 2026-08-02 (fifth pass) as THREE. None of them was new to the PRODUCT —
 * all three shipped that day, on the client's explicit direction, and none of
 * them mapped to a numbered site. The contract had fallen behind and was caught
 * up here. Each is recorded with what it is, why it passes Q1, and the local
 * ladder it therefore owes under the surface clause.
 *
 * SITE 11 WAS REWRITTEN 2026-08-03 and now covers TWO planes rather than one:
 * the brand HEADER BAND and the near black RAIL beneath it. That did not change
 * the count, because they are one client decision and one frame; read the entry
 * before assuming a site has been added.
 *
 * THE COUNT IS TWO AS OF 2026-08-03, and it went DOWN rather than up: SITE 12
 * WAS RETIRED the same day, by the client, in the decision recorded under its
 * number. Sites 11 and 13 are the two that remain. The numbering is not
 * compacted, because a retired site that keeps its number is checkable against
 * every file that ever cited it, and a renumbered list is not.
 *
 * ✓ SETTLED 2026-08-03, AND THIS REPLACES THE WARNING THAT STOOD HERE. That
 * warning read "site 12 and site 11's band now resolve to the same fill, and
 * that is a live question rather than a settled one", and it was correct: both
 * planes read fx-color-primary, and measured on the running app at 1920px they
 * were the SAME FILL in both themes — rgb(20, 90, 50) light and rgb(30, 125, 67)
 * dark, a 60px bar and a 158px banner 44px apart, so the top 260px of the entry
 * screen was one green plane interrupted by a stripe. IT IS NO LONGER A
 * QUESTION. The client answered it on 2026-08-03: THE BAND KEEPS THE BRAND AND
 * THE BANNER GOES. Nothing here is outstanding, and nobody should reopen it as a
 * defect on either file.
 *
 *  11. THE SHELL CHROME — A BRAND HEADER BAND ABOVE A NEAR BLACK RAIL
 *      (fx-band-bg = fx-color-band, and fx-rail-bg = fx-color-rail, both in
 *      03-leptonx; the mobile navbar is the band and the mobile nav overlay is
 *      the rail)
 *
 *      UPDATED 2026-08-04: fx-band-bg used to read fx-color-primary directly,
 *      which is what made the band's fill split by theme along with every
 *      other consumer of that token. It now reads fx-color-band instead — see
 *      2.4.2 — pinned to the SAME value in both theme blocks, because the
 *      client asked for the band to read as one colour regardless of theme.
 *      fx-rail-bg is unaffected and is still fx-color-rail, itself already
 *      pinned to one value per 2.4.1's rail-plane derivation.
 *
 *      REWRITTEN 2026-08-03, AND THE REWRITE IS THE POINT. This site used to
 *      read "the SIDEBAR RAIL, and the MOBILE NAV that is the same rail
 *      (fx-color-primary in light and fx-color-primary-hover in dark, both
 *      resolving to green-800)". That is no longer what the shell is, and a
 *      stale entry HERE is worse than a stale comment anywhere else, because
 *      this list is what a reviewer checks every brand reference in the product
 *      against.
 *
 *      CLIENT DECISION, 2026-08-03, replacing the one taken on 2026-08-02: the
 *      verdict on the green rail was that the sidebar was "not even close to
 *      clio.com or Linear". Both products were measured. Linear's sidebar has NO
 *      SURFACE AT ALL — transparent, no border, no shadow, no brand colour in
 *      its chrome — and separates chrome from work by ELEVATING THE CONTENT into
 *      a rounded card. Clio's rail is a near black #001537 that its own help
 *      centre calls "the black menu", and Clio spends its brand blue on a full
 *      bleed horizontal HEADER BAND. NEITHER PRODUCT RUNS A SATURATED BRAND
 *      PLANE BEHIND NAVIGATION. The client chose Clio's model by name: A DARK
 *      RAIL PLUS A BRAND GREEN TOP BAR. He keeps MORE visible brand than the
 *      green rail gave him, because a header band is read on every screen at eye
 *      level, and the rail finally gets dark enough to carry a real state model.
 *
 *      WHY BOTH PLANES ARE ONE SITE: they were decided in one sentence, they are
 *      the two halves of one frame, and neither is meaningful without the other.
 *      Splitting them into two numbered entries would invite the next reader to
 *      treat one as movable while the other stays.
 *
 *      WHY IT PASSES Q1: the band is the first thing a user sees on every screen
 *      and it carries the product's identity with no content on it at all; the
 *      rail carries nothing but navigation. S1 to S3 pass without argument for
 *      both; together they are the definitional case of chrome in this system.
 *
 *      THE CONSTRAINT THEY CARRY. This pair is what PROVED the surface clause
 *      and it still proves it, in both directions:
 *        · ON THE BAND, fx-color-brand-text and fx-color-focus-ring are both
 *          green-800 in light — the band's own fill — so the current breadcrumb
 *          crumb and every focus ring on it would be invisible. UPDATED
 *          2026-08-04: the band takes fx-color-band-fg now, not
 *          fx-color-text-on-primary — see 2.4.2 — and that ink and its ONE
 *          dimmed step from 2.2.1 measure 7.38:1 and 5.36:1 in BOTH themes,
 *          not the 7.38/5.36 light, 5.16/4.65 dark split recorded here before
 *          the band stopped splitting by theme. It still has no third ink;
 *          its ring is written at each focus rule rather than through a
 *          re-declared token, because a token declared on the band would be
 *          inherited by the dropdown panels the band contains.
 *        · ON THE RAIL, every page tier is a dark ink on a near black plane —
 *          fx-color-text-subtle measures 1.4:1 there. The rail owns a complete
 *          fx-rail-* set: three foregrounds plus a disabled one, three washes, a
 *          line, a field, a scrollbar and its own ring, every one of them mixed
 *          out of fx-rail-bg and fx-rail-fg and measured at the call site
 *          (16.82 / 9.12 / 5.91 / 3.51 against the plane).
 *
 *      AND THE POSITION BAR IS GONE FROM THE ACTIVE NAV ROW. Site 1 names that
 *      bar and warns the next reader not to delete it on a rule reading. This is
 *      not a rule reading: on a near black green-tinted plane every brand-hued
 *      step dark enough to still READ as brand is within a point of the plane it
 *      is drawn on, and every step bright enough to clear 3:1 has been lightened
 *      so far toward white that it has stopped being brand. Position is carried
 *      by the INSET PILL plus two promoted ink tiers, which is what Linear and
 *      Clio both do. 03-leptonx keeps the pseudo element declared and painting
 *      nothing, so prefers-contrast and forced-colors can still put a near-white
 *      mark back where a wash cannot be trusted. Site 1 remains in force
 *      everywhere the active row sits on a PAGE plane rather than on this one.
 *
 *      fx-color-rail IS STILL BRAND. It is green-900 mixed 55 percent toward
 *      black — a value on the frozen ramp's own line, not a hue invented beside
 *      it — so the rail keeps the green cast and the ramps stay the only source
 *      of green in the system. See 2.4.1 for the derivation and the ladder.
 *
 *      THE 2026-08-02 DECISION IS SUPERSEDED, NOT FORGOTTEN, and so is the
 *      neutral-rail decision that preceded it. Both are recorded in 03-leptonx.
 *      Do not restore either from this file.
 *
 *  12. RETIRED — The WELCOME BANNER on the dashboard
 *      SANCTIONED 2026-08-02 · SUPERSEDED 2026-08-03 · NUMBER NOT REUSED
 *
 *      THIS ENTRY IS A RECORD, NOT A PERMISSION. Nothing may be painted under
 *      site 12. It is kept because a brand surface is a DATED CLIENT DECISION
 *      and its withdrawal is that same decision reversed by the same person, so
 *      the reversal belongs on the record as a decision rather than as a gap
 *      where a numbered site used to be. A reader who finds site 12 cited in
 *      another file should land here and read all of it.
 *
 *      THE ORIGINAL ENTRY, VERBATIM AND STILL SOUND ON ITS OWN TERMS. It was not
 *      withdrawn because the reasoning was wrong. It was withdrawn because the
 *      plane it was measured against moved out from under it:
 *
 *        | 12. The WELCOME BANNER on the dashboard
 *        |     (fx-color-primary, .frihat-welcome in 11-home)
 *        |     WHY IT PASSES Q1: it is the product greeting the user by name,
 *        |     once, at the top of the entry screen, above any data. It is an
 *        |     introduction, not a panel of content, which is S2 exactly. One
 *        |     per page, one page — S3.
 *        |     THE CONSTRAINT IT CARRIES: its eyebrow CANNOT be
 *        |     fx-color-brand-text, which is the brand hue drawn on the PAGE and
 *        |     would be the same colour as the fill behind it. Every foreground
 *        |     on it comes from fx-color-text-on-primary and its one dimmed
 *        |     step, measured 7.38:1 in light and 5.16:1 in dark. Note the fill
 *        |     reads the SEMANTIC and not the primitive on purpose: green-800
 *        |     measures 2.02:1 on the dark page and would read as a smudge, so
 *        |     dark resolves to green-700 at 3.24:1.
 *        |     CLIENT DECISION, 2026-08-02: asked for by name — the olive green
 *        |     back for the welcome section.
 *
 *      WHAT REVERSED IT, AND IT WAS MEASURED RATHER THAN ARGUED. On 2026-08-03
 *      the client moved the brand off the sidebar rail and onto a FULL BLEED
 *      GREEN TOP BAR (Clio's model; site 11, built in 03-leptonx). Both planes
 *      resolve to fx-color-primary, so both became the SAME FILL. Taken off the
 *      running application at 1920px wide, in BOTH themes:
 *
 *          light   bar rgb(20, 90, 50)    banner rgb(20, 90, 50)
 *          dark    bar rgb(30, 125, 67)   banner rgb(30, 125, 67)
 *          both    bar 60px tall · banner 158px tall · vertical gap 44px
 *
 *      The top 260px of the entry screen was therefore ONE GREEN PLANE
 *      INTERRUPTED BY A STRIPE, and the banner read as a detached continuation
 *      of the bar rather than as an object of its own. That is not a failure of
 *      S1 to S4 — the banner still passes all four — it is the S4 measurement
 *      being retaken against a page that had changed underneath it, which is
 *      exactly what S4 is for.
 *
 *      WHY THE BANNER AND NOT THE BAR. Three fixes were open and they were not
 *      equivalent: neutralise the BANNER, neutralise the BAR, or keep both and
 *      step one to a different rung of the frozen ramp. THE CLIENT CHOSE THE
 *      FIRST on 2026-08-03. The band is on EVERY screen where the banner was on
 *      ONE, so the product does not lose brand in total, it concentrates it; and
 *      a dashboard with no brand banner under a coloured header is Clio's own
 *      arrangement, which is the reference he had just chosen by name.
 *
 *      WHAT IS LEFT WHERE IT STOOD. .frihat-welcome is DELETED from 11-home —
 *      once the fill goes, what remains IS a page header, and 02-layout section
 *      2 already defines that grammar. Pages/Index.cshtml now uses
 *      .fx-page-header with .fx-page-kicker, so the dashboard's brand reference
 *      is SITE 3, a MARK on the work plane, and no longer a surface at all.
 *      11-home keeps the full retirement record and its re-measured inks under
 *      the heading "THE BANNER THAT USED TO LIVE HERE".
 *
 *      TWO TOKENS DID NOT ORPHAN WITH IT, so do not clean either one up:
 *      fx-color-text-on-primary-muted is the band's dimmed ink through
 *      fx-band-fg-muted in 03-leptonx, and fx-radius-2xl survives on that file's
 *      Bootstrap radius mapping. The banner was a consumer of both, never the
 *      only one.
 *
 *      SITE 13 WAS NOT PART OF THIS DECISION and is untouched below. The three
 *      quick link icon tiles are still brand fills and are now the only brand
 *      on the dashboard's own plane. Do not read this retirement as a trend.
 *
 *  13. The QUICK LINK ICON TILE on the dashboard cards
 *      (fx-color-primary, .frihat-quick-icon in 11-home)
 *      WHY IT PASSES Q1: it is the smallest admissible surface and the one that
 *      shows why Q1a asks about FILLING rather than about SIZE. At 40px it is
 *      mark-sized, but it is a FILL with a glyph on it, so the ink on it has to
 *      be re-derived and the surface clause governs it. It is the identity
 *      carrier on an otherwise neutral card, and it is what keeps the CARD from
 *      needing a brand accent — which remains forbidden below.
 *      THE CONSTRAINT IT CARRIES: the glyph takes fx-color-text-on-primary, not
 *      a text tier and not an icon tier, at 7.38:1 light and 5.16:1 dark. The
 *      tile reads the SEMANTIC fx-color-primary and not a primitive, so it cannot
 *      drift away from the other brand fills in the shell. That clause used to
 *      say "the same semantic as the banner"; the banner retired on 2026-08-03
 *      and the sentence now names the band at site 11, which is the surface the
 *      tile actually has to hold its hue against. CROSS REFERENCE REPAIR ONLY —
 *      this site was not part of that decision and nothing in it is re-ruled.
 *      ON S3, WHICH IS THE ONLY CONDITION WORTH ARGUING HERE: three tiles is an
 *      AUTHORED count on one page, not a count that grows with the data. That is
 *      the whole distinction — three quick links are chrome, a brand tile on
 *      every row of a case list is a themed Bootstrap panel, and the rule that
 *      separates them is "bounded by the page, not by the data".
 *      CLIENT DECISION, 2026-08-02: asked for in the same sentence as the
 *      banner, confirmed as the quick-link cards.
 *
 * ══ FORBIDDEN — STILL A TINT, AND THIS HALF IS LOAD BEARING ════════════════
 *
 * Every one of these answers Q2, or answers nothing at all. Not "a lighter
 * brand", not "brand at 10 percent alpha" — THE TINT, meaning fx-color-hover
 * and fx-color-active and nothing else. This list is the whole difference
 * between a legal instrument and a Bootstrap admin theme with a green swap
 * file, AND NOTHING IN THE SURFACE CLAUSE ABOVE REACHES INTO IT. Adding three
 * surfaces widened where a brand FILL may go by exactly three named planes; it
 * did not widen this list by one entry:
 *
 *   · a ROW HOVER                 → fx-color-hover, a mint tint
 *   · a ROW SELECTION             → fx-color-active, a mint tint
 *   · a MENU-ITEM highlight       → fx-color-hover / fx-color-active
 *   · the COMMAND or KEYBOARD     → fx-color-hover, a mint tint. The cursor in
 *     highlight in a list           a command palette is not a position mark;
 *                                   it moves with the keyboard, so it is Q2.
 *   · a GENERIC ICON              → a text tier, one below its label (see 2.2)
 *   · a LIST MARKER or BULLET     → a text tier. RULED 2026-08-02 (fifth pass),
 *                                   resolving a direct contradiction: 2.5 named
 *                                   a list marker as a decorative accent site
 *                                   and this section never listed one. A bullet
 *                                   answers neither Q1 nor Q2, it is the most
 *                                   generic glyph in the system, and it recurs
 *                                   once per list item without any bound while
 *                                   every sanctioned site above is bounded. The
 *                                   clause in 2.5 is withdrawn; the reasoning is
 *                                   recorded there as superseded rather than
 *                                   deleted. 01-base still paints li::marker
 *                                   with fx-color-accent and is a known
 *                                   follow-up in that file.
 *   · EVERY BORDER and DIVIDER    → the line families in 2.3 / 3.3
 *   · an ALERT or TOAST surface   → the status families in 2.7 / 3.7
 *   · a CARD ACCENT or TOP-BORDER → nothing. A card does not need a brand
 *                                   stripe; it needs a fill and a hairline.
 *   · a PROGRESS BAR              → fx-color-text-subtle, unless the progress
 *                                   itself is the brand moment
 *   · a SPINNER                   → a text tier
 *   · a RANGE THUMB               → a level fill plus fx-shadow-well
 *   · the SURROUND of a checked    → the tint. The wash, ring or row behind a
 *     checkbox, radio or switch      checked control is Q2 and takes
 *                                    fx-color-hover / fx-color-active.
 *
 *     THE ONE CARVE-OUT INSIDE THAT LAST ENTRY: the checked FILL of a
 *     checkbox, radio or switch track IS sanctioned brand. It is not
 *     interaction feedback — it REPORTS A VALUE that will be saved, which is
 *     the same job a filled badge does at site 7. A hovered checkbox is a pale
 *     mint tint; a CHECKED one is the saturated brand green. Those two are not
 *     interchangeable and the gap between them is the point. Do not extend the
 *     brand fill to the row the control sits in.
 *
 * ══ AND FORBIDDEN AS SURFACES. READ THIS BEFORE USING THE SURFACE CLAUSE ═══
 *
 * ADDED 2026-08-02 (fifth pass), in the same change that admitted three
 * surfaces, because the predictable misreading of "a brand surface is allowed"
 * is "so I may brand-fill this". The surface clause is a PRICE LIST, not a
 * permission. These are Q3 or Q2 and remain exactly what they were:
 *
 *   · a CARD, TILE or PANEL BODY  → a level fill and a hairline. It is a
 *                                   container for CONTENT, so it fails S1 and
 *                                   S2 outright. The already forbidden card
 *                                   accent stripe above is the smaller version
 *                                   of this same mistake.
 *   · an ALERT, TOAST or BANNER   → the status families in 2.7 / 3.7. A message
 *     THAT CARRIES A MESSAGE        is content by definition and fails S2. The
 *                                   distinction used to be drawn against site
 *                                   12, a GREETING with no message in it, and it
 *                                   survives that site's retirement intact: the
 *                                   moment a banner carries information the user
 *                                   must read to act, it is not identity. Note
 *                                   that the greeting no longer earns a fill
 *                                   EITHER, so there is now no brand banner of
 *                                   any kind on any page.
 *   · a TABLE or GRID HEADER      → a level fill and the line families. A header
 *                                   is the top of the DATA, it scrolls with the
 *                                   data, and it recurs per grid. The sorted
 *                                   column gets site 4, a MARK, and nothing more.
 *   · a TOOLBAR, FORM, MODAL or   → the surface ladder. All four frame content
 *     SECTION BODY                  but all four also HOLD it, and all four are
 *                                   where the user works. A brand plane behind a
 *                                   form is the themed admin panel, exactly.
 *   · ANY ROW, CELL or REPEATED   → disqualified by S3 before any other question
 *     ELEMENT IN A DATASET          is even asked. If the count comes from the
 *                                   data, it is not chrome.
 *
 * THE ONE-LINE VERSION: two surfaces exist, they were each asked for by the
 * client by name, and the correct response to wanting a third is to run S1 to
 * S4 and then go and ask him — not to notice that the clause exists.
 *
 * AND THE COROLLARY, EARNED ON 2026-08-03: a surface can be TAKEN BACK the same
 * way it was granted. Site 12 was sanctioned and retired within two days, by the
 * same person, on a measurement. If the count can go down, the clause is a real
 * price and not a formality.
 *
 * ══ HOW TO ARGUE WITH THIS RULE ════════════════════════════════════════════
 *
 * REWRITTEN 2026-08-02 (fifth pass). It used to say "you do not add an eleventh
 * site", and then three sites were added in one day, which means the sentence
 * was protecting the list rather than the rule. The list was never the rule. So:
 *
 *   YOU DO NOT ADD A SITE BY PREFERENCE. YOU DERIVE ONE, OR YOU DO NOT PAINT.
 *
 * You run Q1, Q2 and Q3 and accept the answer. If Q1 answers, you run Q1a. If
 * Q1a says you are FILLING, you run S1 to S4 and you bring the client's words
 * and a date, because a surface is chrome and chrome is his decision, not a
 * stylesheet's. A site that survives all of that gets APPENDED HERE WITH ITS
 * REASONING, so the list stays what it has become: a record of decisions that
 * were derived, not a set of permissions to be memorised.
 *
 * The half of this rule that carries the weight is still the FORBIDDEN one. It
 * is what keeps this from sliding back into a themed Bootstrap admin panel,
 * which is the failure mode on the other side and is worse than the one the
 * third pass corrected. Nothing in the surface clause touches it.
 *
 * Worked examples of the ones that come up:
 *
 *   "primary action in a toolbar"    → site 6. It is one button.
 *   "selected filter chip"           → site 7 if it reports STATE that will be
 *                                      applied; a mint tint if it merely shows
 *                                      which chip the pointer landed on.
 *   "the breadcrumb of the open      → Q1, position. Brand text on the LAST
 *    record"                           crumb only; the trail behind it is a
 *                                      text tier.
 *   "our KPI tile looks flat"        → Q3. It answers neither question, so
 *                                      neither brand nor the interaction tint
 *                                      applies. Reach for weight and space.
 *   "the dashboard cards should      → NO, and the banner it wanted to match is
 *    match the welcome banner"         itself gone since 2026-08-03. The card is
 *                                      a container and fails S1 and S2. The
 *                                      identity carrier on that card is its ICON
 *                                      TILE, site 13, and it is already the same
 *                                      green by construction.
 *   "a green strip behind the grid   → NO. Site 4 is a mark on the sorted
 *    header would tie it together"     column. A header is the top of the data.
 *   "the empty state feels bare"     → Possibly a surface. Run S1 to S4 and ask
 *                                      the client. Do not decide it here.
 *
 * Downstream layers (02 and up) are bound by this. A reviewer should be able
 * to open any component file and find that every brand reference in it maps to
 * a numbered site above, by name — and that every brand FILL additionally
 * carries its re-derived ladder and its measurements.
 * ────────────────────────────────────────────────────────────────────────── */


/* ── 4) Space and radius ───────────────────────────────────────────────────
 *
 * A 4px rhythm. Steps 0 to 4 are FIXED: they are the inside of controls, chips,
 * table cells and icon gaps, where a fluid value would make components breathe
 * unevenly against a fixed border width. Steps 5 to 8 are FLUID: they are the
 * gaps BETWEEN blocks, which is where a 13 inch laptop feels cramped and a 32
 * inch 4K feels wasteful.
 *
 * Every fluid value interpolates over the 360px to 1920px viewport band and is
 * clamped flat outside it, so 3840px wide screens do not keep inflating.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-space-0: 0;
    --fx-space-1: 0.25rem;   /*  4px */
    /* THE ONE HALF STEP, added 2026-08-02 (second pass). 6px is not a rhythm
     * value and is never a gap BETWEEN blocks — it is the interior of a small
     * object, where 4px reads as no padding at all and 8px makes a 20 to 24px
     * pill look inflated. Two independent consumers arrived at it during the
     * retune and both had to declare a component local: the tooltip's block
     * padding and the default badge's inline padding. Numbered 1-5 rather than
     * renumbering the ladder, because every step from 1 to 8 is referenced by
     * name across nine stylesheets. Do NOT add a second half step; if a third
     * consumer wants 10px or 14px the answer is a purpose token, not a
     * fractional rhythm. */
    --fx-space-1-5: 0.375rem; /*  6px — small object interiors only */
    --fx-space-2: 0.5rem;    /*  8px */
    --fx-space-3: 0.75rem;   /* 12px */
    --fx-space-4: 1rem;      /* 16px */
    --fx-space-5: clamp(1.25rem, 1.1923rem + 0.2564vw, 1.5rem);   /* 20 → 24px */
    --fx-space-6: clamp(1.5rem,  1.3846rem + 0.5128vw, 2rem);     /* 24 → 32px */
    --fx-space-7: clamp(2rem,    1.7692rem + 1.0256vw, 3rem);     /* 32 → 48px */
    --fx-space-8: clamp(2.5rem,  2.1538rem + 1.5385vw, 4rem);     /* 40 → 64px */

    /* RADIUS — retuned onto the linear.app ladder, 2026-08-02.
     *
     * The measured Linear scale is 4 / 6 / 8 / 10 / 12 / 14 / 9999px. There is
     * NO 2px and NO 3px anywhere in it — 4px is the floor, because below that
     * a corner reads as a rendering artefact rather than as a decision. The
     * previous 2px xs step is therefore gone.
     *
     * THE GOVERNING IDEA: RADIUS GROWS WITH THE SURFACE. A corner is a
     * statement about how big the thing is, so the ladder is read by what the
     * element IS, never by taste:
     *
     *   xs   4px   the smallest inline chrome; a chip nested INSIDE a chip
     *   sm   6px   chips, badges, status pills, menu and list rows
     *   md   8px   THE input radius — text fields, selects, textareas,
     *              popovers, tooltips, modals at dialog size
     *   lg   10px  select popups, cards, panels, the grid shell
     *   xl   12px  large dialogs
     *   2xl  14px  the largest surfaces only — a mega menu, a hero panel
     *   pill only where the shape is DELIBERATELY a pill: avatars, toggles,
     *        switch tracks, scrollbar thumbs
     *
     * NESTING RULE. A chip inside a chip steps DOWN, not sideways: an inner
     * corner must be tighter than the outer one or the gap between them looks
     * uneven. xs is that inner step.
     *
     * fx-radius-control IS THE ONE-LINE REVERSIBLE DECISION, AND ON 2026-08-03
     * IT WAS REVERSED. It reads fx-radius-md. It was 9999px.
     *
     * The token was written so that "every button, segmented control and nav pill
     * in the system reads this single token, so the whole platform can be moved
     * back to a rectangular button by changing one value here and nothing else".
     * That is what happened, and it is worth saying plainly: the token earned its
     * keep. Do not hard code a corner at a call site, and do not route inputs
     * through this token either — an input has its own rung, fx-radius-md, and it
     * reaches it by name.
     *
     * THE SUPERSEDED CONVENTION, KEPT SO NOBODY REDERIVES IT. Linear's default
     * button and nav pill are FULLY PILL, not rounded rectangular, and the
     * stadium was adopted from that reference at the start of the restyle. WHY
     * THE REFERENCE DOES NOT TRANSFER: Linear's stadium reads as "button"
     * because nothing else in its UI is one, and its fields are not 8px
     * rectangles sitting in dense rows beside them. Ours are. Borrowing the
     * shape without borrowing the surrounding density borrowed the cost and not
     * the benefit, which is the same mistake the third pass corrected in 3.9.
     *
     * CLIENT DECISION, 2026-08-03, AND IT WAS MEASURED ON THE RUNNING APP
     * RATHER THAN PREFERRED:
     *
     *   · /Account/Login — the submit button and the field above it are
     *     IDENTICAL 40 by 362 BOXES stacked 40px apart, at 9999px against 8px.
     *     The button was the ONLY element on that entire screen off the radius
     *     ladder: card 8, fields 8, checkbox 4, logo 6, language link 6.
     *   · /Account/Manage — a 32px submit carried a 16px effective corner while
     *     the 40px fields carried 8px. The SMALLER control wore the BIGGER
     *     radius, which inverts this ladder's own premise that RADIUS GROWS WITH
     *     THE SURFACE. That is not a taste disagreement; it is the governing idea
     *     of this section being contradicted by one token.
     *   · /Cases — a button, two selects and a search box, all 32px tall and all
     *     sharing one top edge: 16px against 8, 8 and 8.
     *
     * AND THE ARGUMENT THAT SETTLES IT: THE PILL WAS NEVER EXCLUSIVE TO BUTTONS
     * ANYWAY. The rail toggle, the user chip, the band search wrapper, the band
     * create control, the page header rule, the toolbar divider, the section
     * marker and the scrollbar thumbs are all 9999px. A shape that means six
     * things means none, so the stadium was not carrying "this is actionable"
     * even before it started fighting the fields.
     *
     * TWO THINGS NOT TO UNDO WHILE READING THIS:
     *   · fx-radius-pill IS UNCHANGED and still means FULLY ROUND. It is the
     *     right answer wherever the shape is deliberate rather than conventional,
     *     and .fx-fab-extended was repointed onto it because a floating capsule
     *     is a capsule by nature. Only fx-radius-control moved.
     *   · 03-leptonx mapped bs-border-radius-pill onto fx-radius-CONTROL while
     *     the two happened to share 9999px. Left alone, this change would have
     *     made Bootstrap's own .rounded-pill utility draw 8px rectangles across
     *     the product. It was repointed to fx-radius-PILL in the same change. Do
     *     not point it back. */
    --fx-radius-xs:      4px;
    --fx-radius-sm:      6px;
    --fx-radius-md:      8px;    /* = Linear input / popover */
    --fx-radius-lg:      10px;
    --fx-radius-xl:      12px;
    --fx-radius-2xl:     14px;
    --fx-radius-pill:    999px;
    --fx-radius-circle:  50%;

    /* Retired from 9999px on 2026-08-03. The reasoning, the measurements and the
     * two things not to undo are recorded over the ladder above. */
    --fx-radius-control: var(--fx-radius-md); /* buttons, nav pills, segmented controls */
    --fx-radius-item:    6px;    /* menu rows, list rows, select options */

    /* THE BADGE CORNER IS A PURPOSE TOKEN, NOT A LADDER RUNG. 7px is genuinely
     * the measured reference value for the DEFAULT (24px) badge, and the badge
     * radius set is famously non monotonic — 4px at 20px tall, 7px at 24px,
     * 6px at 28px — because the middle size is the roundest. That sequence
     * cannot be expressed on a ladder whose whole premise is that radius grows
     * with the surface.
     *
     * So 7px does NOT go on the xs / sm / md / lg / xl / 2xl ladder above. That
     * ladder is the measured Linear set, 4 / 6 / 8 / 10 / 12 / 14, with no odd
     * value anywhere in it, and inserting one for a single component would cost
     * the property that makes the ladder legible at a glance. It goes here
     * instead, beside fx-radius-control and fx-radius-item, which are the two
     * other shape decisions in this file that are named for WHAT THEY ARE
     * rather than for how big they are.
     *
     * The 20px and 28px badge sizes stay on the ladder proper — they are
     * fx-radius-xs and fx-radius-sm and need no token of their own. */
    --fx-radius-badge:   0.4375rem; /* 7px — the default (24px) badge only */
}


/* ── 5) Typography ─────────────────────────────────────────────────────────
 *
 * THE FACE — IBM PLEX SUPERFAMILY (adopted 2026-08-02, replacing Cairo + Ubuntu)
 *   IBM Plex Sans Arabic is the Arabic face; IBM Plex Sans is the Latin face;
 *   IBM Plex Mono is the code face. They are ONE superfamily drawn to a shared
 *   brief, which is the whole reason for the change: Cairo and Ubuntu were two
 *   unrelated designs that happened to sit near each other, and every mixed
 *   Arabic and Latin string exposed the seam. Plex Arabic and Plex Sans share
 *   their skeleton, their stroke contrast, their terminal treatment and their
 *   vertical metrics, so a case reference in Latin digits inside an Arabic
 *   sentence now reads as one typeface rather than two.
 *
 *   Each stack still carries the other as its first fallback, so a glyph that
 *   is missing from one face is picked up by its sibling rather than by a
 *   system default.
 *
 *   THE FACES ARE VENDORED LOCALLY under wwwroot/libs/ibm-plex (subsetted
 *   woff2, SIL OFL 1.1), with the at-font-face rules in that folder's own
 *   stylesheet and the link emitted by the BrandFonts layout component
 *   (Components/BrandFonts/Default.cshtml). There is NO external font request
 *   anywhere in the frontend, and none may be introduced: a remote stylesheet
 *   is a third party dependency in the render path, a privacy disclosure, and
 *   a hole in any future content security policy.
 *
 * THE WEIGHT LADDER IS 400 / 500 / 600 / 700, AND ALL FOUR ARE REAL FACES.
 *   The vendored set carries Plex Sans and Plex Sans Arabic at 400, 500, 600
 *   and 700. Nothing is synthesised. There is NO variable axis, so an off-round
 *   weight — Linear's own 510, 590 and 680 — would silently snap to the nearest
 *   static instance and change nothing. Never write a weight that is not on
 *   this ladder.
 *
 *   PLEX MONO IS THE EXCEPTION: only 400 and 500 are vendored. A mono call site
 *   asking for 600 or 700 gets a synthesised smear. Code, kbd, samp and pre all
 *   sit at 400 in 01-base for that reason. If a heavier mono is ever genuinely
 *   needed, the face has to be added to the vendored set first.
 *
 * SCALE
 *   Retuned onto the Linear ladder 2026-08-02: 11 / 12 / 13 / 15 / 16 / 18 /
 *   20 / 24 / 36px at the wide end. The root stays 16px, but the UI BASE IS
 *   15px and dense chrome — table headers, metadata, kbd chips — is 13px.
 *   The old ladder topped out at 31px; the display step is now a real display
 *   step at 36px, because Linear's hierarchy is carried by a large jump at the
 *   top and near-flat steps in the middle, not by an even geometric ramp.
 *   fx-text-2xs (11px) is the ONLY token under 12px and is reserved for non
 *   prose micro labels: tally counters, superscripts, table sort glyph labels.
 *   It must never carry help text, hints, placeholders or any readable sentence.
 *
 * FLUIDITY
 *   Every size is clamp(min, rem intercept + vw slope, max), interpolating over
 *   360px to 1920px. Because both bounds and the intercept are expressed in rem,
 *   browser zoom and a user's root font size still scale the text — the pattern
 *   does not defeat WCAG 1.4.4 the way a bare vw font-size does.
 *
 * ARABIC OPTICAL COMPENSATION — NOW A NO-OP, AND THAT IS THE POINT
 *   fx-font-scale existed because Cairo set noticeably larger than Ubuntu at an
 *   identical px size: taller x-height, wider default advance. It was pinned to
 *   0.96 for Arabic to claw that back. That justification died with Cairo.
 *   IBM Plex Sans and IBM Plex Sans Arabic are metrically harmonised by design
 *   — same 1000 unit em, matched x-height and cap height, matched apparent
 *   colour — so the correct compensation is now NONE and the multiplier sits at
 *   1 in both languages.
 *
 *   The token is deliberately KEPT rather than deleted. It is the single global
 *   dial for the whole type scale, it is visible in devtools, and it is
 *   deterministic in every engine in a way font-size-adjust is not. If a future
 *   face swap reopens the question, this is the one line that answers it.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-font-ar:  "IBM Plex Sans Arabic", "IBM Plex Sans", "Noto Kufi Arabic", "Segoe UI", Tahoma, Arial, sans-serif;
    --fx-font-lat: "IBM Plex Sans", "IBM Plex Sans Arabic", "Segoe UI", system-ui, Roboto, Arial, sans-serif;

    --fx-font-body:    var(--fx-font-ar);
    --fx-font-heading: var(--fx-font-ar);
    --fx-font-mono:    "IBM Plex Mono", ui-monospace, "SF Mono", "Cascadia Code", Menlo, Consolas, monospace;

    /* Numerals. Plex Sans carries a proper tabular figure set, so a numeric
     * column stays in the UI face rather than dropping into the mono face
     * mid-table. Pair it with font-variant-numeric: tabular-nums at the call
     * site — 01-base already does this for number and tel inputs, output, and
     * table cells, and Linear additionally puts tabular figures on badges. */
    /* INHERIT-FIRST, NOT LATIN-FIRST, AND THE REASON IS A MEASURED DOWNLOAD.
     *
     * This led with "IBM Plex Sans", so an Arabic page fetched
     * IBMPlexSans-500-latin.woff2 — 45.7 KB uncached — purely to draw digits.
     * That would be a fair price for better figures. It buys nothing: the two
     * faces were measured in the binaries and in the browser and every ASCII
     * digit is 600/1000 em at every weight in BOTH Plex Sans and Plex Sans
     * Arabic. Identical advances, identical alignment, one fewer request.
     *
     * WHILE HERE, THE TABULAR-NUMERALS QUESTION IS SETTLED, so nobody re-opens
     * it: IBM Plex draws Latin figures TABULAR BY DEFAULT and therefore defines
     * no `tnum` feature — not in the Google subsets and not in IBM's own
     * unsubsetted originals, which were downloaded and dumped to check. Every
     * `font-variant-numeric: tabular-nums` in this system is REDUNDANT rather
     * than broken, and is kept because it documents the intent and costs
     * nothing. An earlier report that the subsetter had stripped the feature was
     * a measurement artifact: `document.fonts.ready` does not wait for a face
     * with a unicode-range that nothing has used yet, so the probe measured the
     * fallback inside the font-display: swap window.
     *
     * ONE GENUINE RESIDUAL, latent and not fixable here: Arabic-Indic digits
     * U+0660 to U+0669 in Plex Sans Arabic ARE proportional, spanning 263 to
     * 630/1000 em, and no tnum exists upstream to correct them. The product
     * renders Western digits throughout today, so nothing misaligns; introducing
     * Arabic-Indic numerals into an aligning column would need a font level fix.
     *
     * IT READS fx-font-body, WHICH IS THE WHOLE POINT. That token is already
     * switched per document language in 01-base, so a numeric column now draws
     * with the same face as the sentence beside it, in either language, with no
     * additional request. A literal stack here cannot do that: it would have to
     * name one language's face first and be wrong on the other page. Note this
     * must NOT be written as the keyword `inherit` — that is a CSS-wide keyword
     * and is only valid as an entire value, never as one entry in a family list.
     * A call site that genuinely wants monospaced figures asks for
     * fx-font-mono by name rather than hoping this token supplies them. */
    --fx-font-numeric: var(--fx-font-body);

    /* Global type scale multiplier. See ARABIC OPTICAL COMPENSATION above.
     * 1 in both languages since the IBM Plex adoption. */
    --fx-font-scale: 1;

    /* Fluid modular scale. The comment after each line is min → max in px. */
    --fx-text-2xs:  calc(clamp(0.65625rem, 0.6490rem + 0.0321vw, 0.6875rem)  * var(--fx-font-scale));  /* 10.5 → 11 */
    --fx-text-xs:   calc(clamp(0.71875rem, 0.7115rem + 0.0321vw, 0.75rem)    * var(--fx-font-scale));  /* 11.5 → 12 */
    --fx-text-sm:   calc(clamp(0.78125rem, 0.7740rem + 0.0321vw, 0.8125rem)  * var(--fx-font-scale));  /* 12.5 → 13 */
    --fx-text-base: calc(clamp(0.875rem,   0.8606rem + 0.0641vw, 0.9375rem)  * var(--fx-font-scale));  /* 14   → 15 */
    --fx-text-lg:   calc(clamp(0.9375rem,  0.9231rem + 0.0641vw, 1rem)       * var(--fx-font-scale));  /* 15   → 16 */
    --fx-text-xl:   calc(clamp(1.03125rem, 1.0096rem + 0.0962vw, 1.125rem)   * var(--fx-font-scale));  /* 16.5 → 18 */
    --fx-text-2xl:  calc(clamp(1.125rem,   1.0962rem + 0.1282vw, 1.25rem)    * var(--fx-font-scale));  /* 18   → 20 */
    --fx-text-3xl:  calc(clamp(1.3125rem,  1.2692rem + 0.1923vw, 1.5rem)     * var(--fx-font-scale));  /* 21   → 24 */
    --fx-text-4xl:  calc(clamp(1.75rem,    1.6346rem + 0.5128vw, 2.25rem)    * var(--fx-font-scale));  /* 28   → 36 */

    /* fx-text-base is the anchor of the whole scale: 15px at 1920px wide, 14px
     * at 360px. fx-text-md is its alias, kept so the ladder can be read as an
     * unbroken 2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl sequence at call sites. */
    --fx-text-md: var(--fx-text-base);

    /* LEADING COLLAPSES AS THE SIZE GROWS. Linear runs body 1.6, title 1.33,
     * display 1.0 to 1.125 — the bigger the type, the tighter the lines, which
     * is what stops a large heading reading as a stack of separate sentences.
     *
     * normal (1.7) and relaxed (1.9) are DELIBERATELY TALLER THAN LINEAR'S 1.6
     * and stay that way. Arabic sets diacritics above the baseline and
     * descenders well below it, and IBM Plex Sans Arabic is no kinder here than
     * Cairo was — a fatha over a kasra in the line above is exactly the
     * collision that 1.6 produces. This is the one place the reference is
     * overruled by the primary script, and it applies to Latin too so a mixed
     * paragraph does not change rhythm mid-sentence.
     *
     * tight and snug moved to Linear's end of the range, because they are only
     * ever used on headings and display type where the collision risk is a
     * single line and the loss of rhythm from tall leading is severe. */
    --fx-leading-tight:   1.15;   /* display — text-4xl */
    --fx-leading-snug:    1.35;   /* titles  — text-xl to text-3xl */
    --fx-leading-normal:  1.7;    /* body — tall for Arabic diacritics */
    --fx-leading-relaxed: 1.9;    /* long prose — taller still */

    /* WEIGHT USAGE — hierarchy is a COLOUR TIER, never a heavier weight.
     *   400 regular   body copy, prose, list text, table cell values
     *   500 medium    THE WORKHORSE UI WEIGHT. Button labels, tabs, nav items,
     *                 section headings, table headers, kbd chips, form labels.
     *                 If a piece of chrome needs to look deliberate, it is 500.
     *   600 semibold  page and dialog TITLES, and filled badges. Nothing else.
     *   700 bold      effectively UNUSED in application chrome. It survives for
     *                 print, for a marketing surface, and for h1 on a document
     *                 page. Reaching for it in the app is a sign the hierarchy
     *                 should have been expressed with fx-color-text instead.
     *   800 extrabold DEPRECATED. BrandFonts loads no 800 instance, so it snaps
     *                 to 700 and does nothing. Kept only so existing call sites
     *                 resolve; never write it in new code. */
    --fx-weight-regular:   400;
    --fx-weight-medium:    500;
    --fx-weight-semibold:  600;
    --fx-weight-bold:      700;
    --fx-weight-extrabold: 800;   /* deprecated — no such face is loaded */

    /* ══ TRACKING — THREE TIERS, LATIN ONLY ════════════════════════════════
     *
     * Negative tracking is Linear's signature and is most of why their type
     * reads engineered rather than merely set. The measured ladder is:
     *   body and UI, 10 to 16px   -0.011em
     *   titles, up to 24px        -0.012em
     *   display, 32px and up      -0.022em
     * Our ramp adds one intermediate step at the 20 to 24px tier so the jump
     * from title to display is not a cliff.
     *
     * EVERY NEGATIVE LETTER-SPACING IN THE ENTIRE SYSTEM MUST FLOW THROUGH ONE
     * OF THESE TOKENS. Never write a negative em value at a call site. The
     * reason is the guard immediately below.
     *
     * ARABIC GUARD: every one of these resolves to 0 under the Arabic block
     * below. Arabic is a cursive, joined script — negative tracking pulls the
     * glyphs apart at the joins and degrades the letterforms. IBM Plex Sans
     * Arabic does not change this; it is still a joined script. This is the one
     * place the Linear reference could actively harm our primary script, so the
     * guard is not optional and must not be removed. ANY NEW TRACKING TOKEN
     * MUST BE ADDED TO THE GUARD IN THE SAME EDIT. */
    --fx-tracking-ui:      -0.011em;   /* body, labels, buttons, tabs, chrome */
    --fx-tracking-tight:   -0.011em;   /* legacy name, aligned to tracking-ui */
    --fx-tracking-normal:  0;
    --fx-tracking-wide:    0.04em;

    --fx-tracking-title:   -0.012em;   /* text-lg / text-xl  — 16 to 18px */
    --fx-tracking-heading: -0.014em;   /* text-2xl / text-3xl — 20 to 24px */
    --fx-tracking-display: -0.022em;   /* text-4xl           — 28 to 36px */
}

/* The Arabic overrides. Declared here rather than in the base layer because
 * they are properties of the scale, not of the reset. */
html[lang^="ar"]:root {
    /* No optical compensation is needed against IBM Plex Sans — the two faces
     * are one superfamily with harmonised metrics. See the header. Kept as an
     * explicit 1 rather than deleted so the dial stays discoverable. */
    --fx-font-scale: 1;

    /* THE ARABIC TRACKING GUARD. Neutralising the ramp here, at the token layer,
     * means every consumer is protected by construction — a component that
     * writes letter-spacing: var(fx-tracking-display) is automatically correct
     * in Arabic without knowing the rule exists. Do not remove, and do not
     * reintroduce a negative letter-spacing anywhere below this line. */
    --fx-tracking-display: 0;
    --fx-tracking-heading: 0;
    --fx-tracking-title:   0;
    --fx-tracking-tight:   0;
    --fx-tracking-ui:      0;
}


/* ── 6) Elevation and glass ────────────────────────────────────────────────
 *
 * THE SYSTEM IS FILL AND ELEVATION DEFINED. Depth does the whole job — a
 * surface is separated from the page because it floats above it, and a control
 * is findable because it sits in a different fill with a well under it.
 *
 * FOCUS IS NOT IN THIS FILE'S GIFT ANY MORE. It was a bloom made of stacked
 * box-shadows; since 2026-08-02 it is a 2px outline at 2px offset and nothing
 * else. See 01-base section 11. The two glow tokens survive here only so old
 * call sites resolve, and both are retuned to render the new model.
 *
 * ══ SHADOWS ARE SCARCE ═════════════════════════════════════════════════════
 *
 * A CARD GETS NO FLOAT SHADOW. It is level 1 on a level 0 page, and it may
 * take fx-shadow-stack for a physical edge — but not fx-shadow-float-*, which
 * says "detached", which a card is not. The same is true of a panel, the
 * sidebar rail, a toolbar, a section header and a table shell. If you find
 * yourself reaching for a float on something that does not leave the document
 * flow, the answer is a LEVEL plus the stack — see 2.1.
 *
 * A shadow means one thing only: this element genuinely floats above the
 * document and can cover arbitrary content. Dropdowns, menus, popovers,
 * modals, toasts, date pickers, autocomplete panels. Those use
 * fx-shadow-float-sm/md/lg, and nothing else should.
 *
 * The generic fx-shadow-xs through fx-shadow-2xl scale is retained because
 * existing call sites and vendored sheets read it, and because the glass
 * treatment still needs it. It is no longer the default answer to "how do I
 * make this stand out". The default answer is a level.
 *
 * This is also what finally settles the ring question: with no shadow on a
 * card there is no ring to soften.
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * ══ RETUNED 2026-08-02 — SHADOWS SEPARATE BY BLUR, NOT BY DARKNESS ════════
 *
 * The measured Linear shadow set is far weaker than anything we had, and its
 * most instructive property is the direction the alpha moves:
 *
 *   LIGHT   0 1px 4px -1px  .09   →   0 3px 12px  .09   →   0 7px 24px  .06
 *                                                            alpha FALLS
 *   DARK    0 2px 4px       .10   →   0 4px 24px  .20   →   0 7px 32px  .35
 *                                                            alpha RISES
 *
 * In LIGHT, elevation is communicated by the shadow getting WIDER and SOFTER,
 * not darker. A high surface casts a large diffuse shadow; a dark one at that
 * size reads as soot. So the alpha comes DOWN as the blur goes up, and NOTHING
 * IN THE LIGHT THEME EXCEEDS 10 PERCENT ALPHA. The single exception is
 * fx-shadow-well, which is exempt because it carries an accessibility
 * guarantee — see the rule below.
 *
 * In DARK the alpha RISES instead, because the background step between two
 * adjacent planes is now only 1.05:1 — almost nothing — so the shadow is
 * doing essentially all of the separation work and has to be allowed to. For
 * the same reason the smallest tier COLLAPSES TO none in dark: a 1px shadow on
 * a near black page is invisible, and Linear simply deletes it.
 *
 * Light shadows keep the brand green tint (15, 42, 24) so nothing reads as grey
 * soot on the olive page. Dark shadows go to pure black, because a green tinted
 * shadow on a green black surface only muddies it and never darkens it.
 *
 * THE PURPOSE BUILT SETS:
 *   fx-shadow-well        the INSET depth of a filled control. Carries the
 *                         accessibility guarantee — see the rule below.
 *   fx-shadow-float-sm/md/lg  the ONLY sanctioned shadows, for things that
 *                         hover over the page: dropdowns, popovers, menus,
 *                         modals, date pickers, autocomplete panels. Pick by
 *                         how far above the page the thing conceptually is.
 *   fx-shadow-stack       the five layer micro stack that gives a card a
 *                         PHYSICAL EDGE. See its own note below.
 *   fx-shadow-press       the flattened / inset state for :active. A pressed
 *                         control LOSES its ambient layer, it does not gain a
 *                         darker one.
 *   fx-shadow-bevel       THE RAISED CONTROL EDGE. A button, a segmented
 *                         control, a select trigger — anything that has to look
 *                         like a physical, pressable object sitting ON a
 *                         surface rather than cut into it. See its own note.
 *   fx-shadow-glow        DEPRECATED as a hover treatment, kept alive and
 *                         retuned down to a plain weak float.
 *                         AUDITED 2026-08-02 (second pass): ZERO CONSUMERS in
 *                         wwwroot. Kept only because section 12's contract says
 *                         names stay alive.
 *   fx-shadow-focus-glow  DEPRECATED as the focus treatment — focus is an
 *                         OUTLINE now, see section 9 and 01-base section 11.
 *                         Retuned to the flat compatibility ring so any call
 *                         site that still reads it renders the new model.
 *                         AUDITED 2026-08-02 (second pass): ZERO CONSUMERS.
 *                         Every reference to the name across 03 to 08 is a
 *                         COMMENT recording that it was removed. Those comments
 *                         are the design record and stay.
 *
 * ══ THE RULE THAT KEEPS A BORDERLESS UI COMPLIANT — DO NOT FLATTEN THIS ══
 *
 * WCAG 2.2 SC 1.4.11 requires 3:1 for the visual information that identifies a
 * control, and the compressed surface ladder makes this HARDER, not easier: a
 * level 2 field on a level 1 card is now 1.045:1 in light and 1.051:1 in dark.
 * Fill alone does not come close.
 *
 * THE SPLIT THAT MAKES THIS COHERENT. Structural separation and control
 * identification are different jobs and are held to different standards:
 *   · STRUCTURAL — card edges, dividers, popover and menu borders, table row
 *     separators, section rules. These identify nothing, so they are allowed
 *     to sit in Linear's near-invisible 1.03 to 1.5:1 tier. See 2.3.
 *   · INTERACTIVE CONTROL BOUNDARIES — text inputs, selects, textareas,
 *     checkboxes, radios, switches, and anything whose boundary is the only
 *     cue that it is operable. These MUST hold 3:1 against the surface they
 *     sit on. There are exactly two conforming ways to do it: the WELL SHADOW
 *     below, or a filled well whose background itself clears 3:1 against the
 *     page. THE PLATFORM USES THE WELL SHADOW, because the fill route would
 *     force a control fill far outside the 1.045 ladder and would undo the
 *     whole surface retune.
 *
 * ══ WHICH STATES OWE THE 3:1 — READONLY DOES, DISABLED DOES NOT ════════════
 *
 * RULED 2026-08-03. The split above says WHICH THINGS owe an identification
 * cue; it never said which STATES of those things do, and the two flattened
 * states were being treated as one. They are not one.
 *
 *   DISABLED is EXEMPT, and the exemption is explicit in SC 1.4.11: an
 *   "inactive user interface component" is out of scope. It is not operable, it
 *   is not in the tab order unless the markup deliberately puts it there, and
 *   there is nothing for a boundary to invite. 05-forms and 01-base both flatten
 *   its well to nothing, and that is CORRECT — losing the depth is the disabled
 *   signal, and an unavailable control should stop looking like a place you can
 *   put something.
 *
 *   READONLY IS NOT EXEMPT, and it was being flattened as if it were. A readonly
 *   field is FOCUSABLE and OPERABLE: it is in the tab order, it takes a caret, a
 *   lawyer tabs into one to read and copy a case reference out of it, and
 *   05-forms section 2 argues that case itself when it deliberately leaves
 *   readonly out of the focus guard. A control the user can put the keyboard
 *   into is an ACTIVE component, so the exemption does not reach it, and it owes
 *   the same 3:1 as the editable field beside it.
 *
 * THE ARITHMETIC THAT MADE THIS URGENT. With the well flattened, a readonly
 * field's ONLY remaining cue is its fill, and the fill is the sunken plane:
 *     light   surface-sunken on a level 2 card ....... 1.143:1
 *     dark    surface-sunken on a level 2 card ....... 1.179:1
 * On a level 1 plane it is weaker still (1.094:1 light, 1.122:1 dark). That is
 * an order of magnitude short of the floor, and it is the ONLY channel, because
 * a readonly field also keeps full strength text and the ordinary cursor by
 * design — the two things that tell it apart from DISABLED are exactly the two
 * things that stop telling it apart from an ordinary FIELD.
 *
 * AND IT WAS WORSE THAN THE RESTING FIGURE SUGGESTS. Until the 01-base layering
 * fix of the same date, a hovered readonly field was PAINTED WITH THE EDITABLE
 * HOVER FILL, because the base layer named that token as a property at 0,3,1 and
 * overpainted the local that said otherwise. So the one cue readonly had was
 * cancelled by the pointer resting on it. That is fixed; the consequence is that
 * the sunken fill is now genuinely load bearing, which is the reason to settle
 * this now rather than later.
 *
 * THE CUE IS THE WELL THE FIELD ALREADY OWNS. No new token, no new value, no
 * stroke: readonly simply STOPS flattening fx-shadow-well. Measured by the
 * canvas method described further down, on the running app, 2026-08-03:
 *     LIGHT   band 1 over the readonly fill #e8ece5 ..... 3.882:1   PASS
 *     DARK    band 1 over the readonly fill #0c1a14 ..... 3.951:1   PASS
 * For comparison the same band over the EDITABLE fill measures 4.119:1 light and
 * 3.629:1 dark on the same instrument. Dark is in fact STRONGER on the readonly
 * plane than on the editable one, because the dark band is a light rim and the
 * readonly fill is the darker of the two.
 *
 * SO READONLY AND EDITABLE STILL READ DIFFERENTLY, and it is worth saying which
 * channel now carries which job, because the point of the ruling is not to make
 * the two look the same: the FILL is what separates readonly from editable (a
 * sunken plane against a raised one), and the WELL is what separates readonly
 * from PROSE. Before the ruling readonly had the first and not the second, so it
 * was identifiable as "not an ordinary field" and not identifiable as a control
 * at all. Disabled keeps neither, which is what makes the three states a ladder.
 *
 * THE RULE THAT PAINTS IT IS NOT IN THIS FILE. 05-forms owns the readonly
 * declaration and must drop its `fx-ctl-shadow: none`. This block is the
 * DECISION and the measurement; that file is the call site.
 *
 * The compliance therefore lives in the WELL SHADOW, and specifically in its
 * strongest band, which is measured against fx-color-field-bg:
 *
 *     LIGHT   inset 0 2px 2px rgba(15, 42, 24, 0.60) over #f7fbf5
 *             UN-BLURRED composite rgb(108, 126, 112)  →  4.16:1
 *             RENDERED   top pixel row rgb(106, 124, 110)  →  4.25:1   PASS
 *     DARK    inset 0 2px 2px rgba(231, 239, 230, 0.50) over #1b291f
 *             UN-BLURRED composite rgb(129, 140, 130)  →  4.34:1
 *             RENDERED   top pixel row rgb(118, 126, 118)  →  3.63:1   PASS
 *
 * THE ALPHAS 0.60 AND 0.50 ARE FROZEN AND MUST NOT BE LOWERED. They are the
 * whole of the identification cue, and the arithmetic is brutal: at 0.06 the
 * light band composites to rgb(233, 238, 231) and measures 1.28:1 rendered,
 * which is no boundary at all. Anyone reading 0.60 as a slipped decimal should
 * read this paragraph first. See the geometry note below for why 0.60 is not
 * the reason the band looks heavy either.
 *
 * ══ THE GEOMETRY WAS THE DEFECT, NOT THE ALPHA. RETUNED 2026-08-03 ═════════
 *
 * The two numbers above used to be quoted from the UN-BLURRED composite alone,
 * with a claim that the alphas carried "roughly 35 percent headroom so blur
 * attenuation cannot push the rendered peak under". That claim was never
 * measured. It was, when the band was rendered to a canvas and the top pixel
 * row read back:
 *
 *     LIGHT   inset 0 2px 4px @ 0.60   rendered 3.008:1   passed by 0.008
 *     DARK    inset 0 1px 3px @ 0.50   rendered 2.231:1   FAILED
 *
 * Every text input, select and textarea on the DARK theme was carrying a 2.23:1
 * identification band while the file recorded 4.34:1. The blur is what ate it:
 * a shadow with blur b approximates a Gaussian of sigma b/2, so the peak that
 * actually lands on the first pixel row is the un-blurred alpha attenuated by
 * how much of the band was smeared out of the box. Dark was worse than light
 * because its offset was SMALLER (1px against 2px) while its blur was nearly as
 * large, so proportionally more of the band fell outside the first row.
 *
 * THE FIX IS TO TIGHTEN THE BLUR, WHICH RAISES THE RATIO AND SHRINKS THE BAND
 * AT THE SAME TIME. Both effects come from the same change and they point the
 * same way, which is why this is a retune and not a trade:
 *
 *     LIGHT   2px/4px  3.008:1   becomes   2px/2px  4.252:1
 *     DARK    1px/3px  2.231:1   becomes   2px/2px  3.626:1
 *
 * Measured by rendering each candidate through an SVG foreignObject onto a
 * canvas and reading the composited pixel column back, on the running app,
 * 2026-08-03. Ten geometries were swept per theme; 2px/2px was the best in both.
 *
 * AND IT ANSWERS THE "IT DOMINATES A CHECKBOX" REPORT WITHOUT WEAKENING
 * ANYTHING. A 2px offset with a 4px blur has visible influence roughly 6px into
 * the box, which on the 16px artwork of a 24px tick box is a third of the
 * control. At 2px/2px it is roughly 3px, which is a lip rather than a bar. The
 * band therefore did NOT need a reduced alpha at the xs rung, and must not be
 * given one: on a selection control the well is one of only two things carrying
 * SC 1.4.11, the other being the padding-box ring 05-forms 12 adds.
 *
 * BAND 2 IS UNCHANGED AND ITS JOB IS NOW ACTUALLY DISTINCT. Band 1 is a tight
 * identification lip; band 2 is the wide soft recess that makes the control read
 * as cut into the surface. Before the retune the two overlapped so heavily that
 * band 1 was doing both jobs, which is the other half of why it read as a bar.
 *
 * Note the DIRECTION FLIP, which is not a stylistic choice but arithmetic: on
 * the dark theme no darker band can ever reach 3:1, because pure black against
 * a #1b291f fill is only 1.39:1. The identification band in dark must therefore
 * be LIGHTER than the fill — a rim light along the top interior, which is also
 * how a real recessed surface catches light.
 *
 * Anyone who lowers those two alphas, widens the blur back out, removes the
 * band, or swaps the dark band for a darker one has made every text input,
 * select and textarea in the platform non-conformant. RE-MEASURE THE RENDERED
 * PIXEL, NOT THE COMPOSITE, after any change here. This is a court-eligibility
 * artefact, not taste.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    /* Last resort only — see the header. Not part of any level below. Now
     * expressed through the translucent border family so a ring and a border
     * can never disagree about what a hairline looks like. */
    --fx-shadow-ring: 0 0 0 var(--fx-border-width) var(--fx-color-border);

    --fx-shadow-xs:  0 1px 2px rgba(15, 42, 24, 0.05);
    --fx-shadow-sm:  0 1px 4px -1px rgba(15, 42, 24, 0.09);
    --fx-shadow-md:  0 3px 12px rgba(15, 42, 24, 0.09);
    --fx-shadow-lg:  0 7px 24px rgba(15, 42, 24, 0.06);
    --fx-shadow-xl:  0 10px 32px rgba(15, 42, 24, 0.07);
    --fx-shadow-2xl: 0 16px 48px rgba(15, 42, 24, 0.08);

    /* Floating layers — the ONLY sanctioned shadows. These are the Linear
     * values verbatim, tinted. Note again that the alpha FALLS as the blur
     * grows: sm and md are both 9 percent and lg drops to 6. */
    --fx-shadow-float-sm: 0 1px 4px -1px rgba(15, 42, 24, 0.09);
    --fx-shadow-float-md: 0 3px 12px rgba(15, 42, 24, 0.09);
    --fx-shadow-float-lg: 0 7px 24px rgba(15, 42, 24, 0.06);

    /* THE PHYSICAL CARD EDGE — five layers, none of them a stroke.
     *
     * This is Linear's low shadow stack and it is the piece that makes a card
     * look MANUFACTURED rather than drawn. Four drop layers stack from 5px down
     * to 0px blur with the alpha rising as the blur shrinks, so the darkest,
     * tightest band sits immediately against the box and reads as the edge of a
     * physical object; one inset layer along the bottom interior finishes it.
     * A single 1px hairline cannot produce this because a hairline has no
     * gradient, and a single soft shadow cannot produce it because a soft
     * shadow has no contact.
     *
     * Use on: SMALL objects at rest on a surface — a kbd chip, a button, a
     * badge, a compact panel, a grid cell shell.
     * Do NOT use on a floating layer — that is what fx-shadow-float-* is for,
     * and stacking both makes the surface look like it is resting on the air.
     *
     * ══ AND DO NOT USE IT ON A LARGE SURFACE IN LIGHT — 2026-08-03 ═════════
     * THE TWO THEMES DECLARE DIFFERENT SHAPES, not merely different alphas, and
     * that asymmetry is deliberate but it is not scale-free:
     *     light   ONE inset band plus four drop layers, and the inset at 10
     *             percent is the STRONGEST layer in the stack
     *     dark    four drop layers only, no inset at all (see the note over the
     *             dark declaration for why an inner light band is wrong there)
     *
     * On a small object the inset is the whole point: it is the bottom lip of a
     * manufactured thing and it is what a kbd chip needs. On a LARGE surface —
     * a page-width card, a full work plane — the same layer becomes a dark rule
     * running along the inside of the element's own border, and a surface with
     * a dark line inside its edge reads as SUNK INTO the plane behind it rather
     * than raised off it. The four drop layers cannot compensate: their largest
     * blur is 5px, which is a contact edge, not an elevation. The practical
     * symptom is that the light theme looks flat while dark looks lifted from
     * the identical rule, which is exactly what was measured on the app shell.
     *
     * A large surface that wants to read as RAISED takes fx-shadow-float-md,
     * which is one ambient drop with the same shape in both themes.
     * 03-leptonx 3.1.2 records that decision and the measurement behind it.
     *
     * ══ WHY THE TOKEN IS NOT RECONCILED, AND WHY THERE IS NO VARIANT ═══════
     * DECIDED 2026-08-03 after enumerating the consumers rather than guessing
     * at them. fx-shadow-stack is read at THIRTY call sites across seven files:
     * 09-tabulator (11), 04-buttons (9), 07-surfaces (5), 05-forms (2),
     * 01-base (1, kbd), 03-leptonx (1, a composed float pair) and 11-home (1).
     *
     * THE CONSUMER PROFILE IS NOT "ALL SMALL", AND THE SENTENCE THAT SAID SO IS
     * CORRECTED HERE — 2026-08-03. Almost every consumer is a small object at
     * rest: a kbd chip, a button, a badge, a menu, a compact panel. TWO ARE
     * LARGE, both of them grid shells, and both are CORRECT:
     *     09-tabulator 2      `.frihat-grid.tabulator`   measured 1462x640
     *     09-tabulator 25.1   `.dt-container`            measured 1464x409
     * Neither is a counter example, because SIZE IS NOT THE TEST and INTENT IS.
     * A grid pinned into the page flow wants a CONTACT EDGE, which is the only
     * thing this token draws, and both shells say exactly that where they spend
     * it. What must never take the stack is a large surface that wants to read
     * as RAISED; that one takes fx-shadow-float-md, per the ruling above. The
     * app shell was the single consumer that asked a contact token for an
     * elevation, and it has moved.
     *
     * So the token is correct as written for the whole of its existing consumer
     * base, and only the one misread consumer was wrong.
     *
     * Reconciling the two shapes — dropping the light inset so both themes are
     * four drops — would silently flatten every button, chip and badge in the
     * platform, in five files this pass does not own and could not verify live.
     * That is a far larger blast radius than the defect.
     *
     * A `fx-shadow-stack-lg` VARIANT WAS CONSIDERED AND DECLINED. It would ship
     * with ZERO call sites: the one consumer that needed it moved to
     * fx-shadow-float-md, which already exists, already has the right shape in
     * both themes, and is the token the elevation model reaches for. Adding an
     * unconsumed token to answer a question an existing token answers is the
     * speculative-token habit this file argues against elsewhere. If a second
     * large surface ever needs a CONTACT edge rather than a float, that is the
     * moment to add it, and this note is the specification for it.
     *
     * The inset band is capped at 10 percent so the light theme's ceiling
     * holds; Linear runs it at 11. The difference is not perceptible and the
     * ceiling is worth more than the one point. */
    --fx-shadow-stack:
        inset 0 -1px 1px 0 rgba(15, 42, 24, 0.10),
        0 5px 2px 0 rgba(15, 42, 24, 0.01),
        0 3px 2px 0 rgba(15, 42, 24, 0.04),
        0 1px 1px 0 rgba(15, 42, 24, 0.07),
        0 0 1px 0 rgba(15, 42, 24, 0.08);

    /* The control well. Band 1 is the accessibility guarantee (4.25:1 as
     * RENDERED, not as composited), band 2 is the recess, band 3 is the light
     * catching the bottom lip so the groove has two sides and reads as depth
     * rather than as a shadow that fell on it.
     * EXEMPT from the 10 percent light ceiling — see the header rule.
     * BAND 1's BLUR IS 2px AND THAT IS LOAD BEARING: at 4px the rendered ratio
     * was 3.008:1 and the band spread 6px into the box. Read the geometry note
     * in the header before widening it. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(15, 42, 24, 0.60),
        inset 0 5px 12px rgba(15, 42, 24, 0.10),
        inset 0 -1px 2px rgba(255, 255, 255, 0.55);

    --fx-shadow-inset: inset 0 1px 2px rgba(15, 42, 24, 0.08);
    --fx-shadow-press: inset 0 1px 3px rgba(15, 42, 24, 0.10);

    /* ══ THE BEVEL — THE RAISED CONTROL EDGE ═══════════════════════════════
     *
     * PROMOTED TO THE TOKEN LAYER 2026-08-02 (second pass). 04-buttons composed
     * this by hand as a component local called fx-btn-bevel, and 05-forms and
     * 07-surfaces both wanted the identical treatment for a select trigger and
     * a segmented control. Three consumers of one recipe is a semantic, not a
     * component detail.
     *
     * IT IS NOT THE WELL, AND THE TWO ARE OPPOSITES. fx-shadow-well cuts a
     * control INTO the surface and carries the SC 1.4.11 identification band; a
     * text field takes it. fx-shadow-bevel lifts a control OUT of the surface;
     * a button takes it. A control must never wear both — a box that is
     * simultaneously recessed and raised has no readable depth at all.
     *
     * THE TWO THEMES ARE DIFFERENT SHAPES, NOT DIFFERENT ALPHAS.
     *   LIGHT collapses to what a light secondary control actually is: one
     *   hairline ring plus the weakest float. There is nothing to simulate — an
     *   off white surface on a near white page is already legible, and inset
     *   light hairlines on it would be invisible at best and dirty at worst.
     *   DARK is the full four layer simulation, because on a near black page a
     *   flat neutral fill has no edge at all: two INSET light hairlines (the top
     *   one catching an imagined overhead light, the surrounding one closing the
     *   box), a 1px ring outside them, and a drop shadow underneath. The
     *   hairlines come from the TRANSLUCENT border family, which inverts with
     *   the theme, so "light hairline" is what they actually paint in dark. In
     *   light the same tokens are dark ink, which is precisely why the light
     *   variant does not use the inset layers.
     * ═══════════════════════════════════════════════════════════════════════ */
    --fx-shadow-bevel:
        0 0 0 var(--fx-border-width) var(--fx-color-border-emphasis),
        var(--fx-shadow-float-sm);

    /* DEPRECATED as a hover treatment. A brand bloom under a button is exactly
     * the "themed Bootstrap" signal the accent rule in 3.9 exists to remove, so
     * a primary button now hovers by changing its fill and nothing else. The
     * token is kept alive and retuned down to a plain weak float so any call
     * site still reading it degrades into the new language instead of shouting. */
    --fx-shadow-glow: var(--fx-shadow-float-md);

    /* ══ fx-shadow-focus — THE COMPATIBILITY RING ══════════════════════════
     *
     * Flat, no blur, for a component that CLIPS ITS OVERFLOW and therefore
     * cannot render a real outline at a positive offset. The known consumers
     * are .input-group (whose overflow: hidden is load bearing — it clips
     * member fills to the assembly's corners and is what makes the RTL corners
     * correct), .fx-segmented, and two grid controls. It is the only sanctioned
     * box-shadow expression of focus. The halo layer it used to carry is gone.
     *
     * RETUNED 2026-08-02 (fourth pass) — IT NOW REPRODUCES THE OUTLINE
     * GEOMETRY, WHICH IT PREVIOUSLY DID NOT. It was a single ring at ZERO
     * offset while every real outline in the platform rings at
     * fx-focus-offset, 2px clear of the box. Against the old translucent ink
     * ring at roughly 3.5:1 that 2px discrepancy was invisible. Against the
     * green-800 ring the third pass installed, at 7.24 to 8.27:1, it is not:
     * an .input-group's ring hugged the control while the plain field beside it
     * floated clear, and two adjacent inputs disagreed about what focus looks
     * like.
     *
     * THE SHAPE, and why it is two layers. A box-shadow cannot express an
     * offset, so the gap has to be PAINTED: layer one is a spread of exactly
     * fx-focus-offset in the colour of whatever the component sits on, layer
     * two is a spread of offset plus width in the ring colour, and because
     * shadows paint outward from the border box in declaration order the second
     * reads as a ring standing off the first. Both spreads are derived from
     * fx-focus-width and fx-focus-offset, so the compatibility ring and the
     * real outline stay in step if either token moves — including under
     * prefers-contrast: more, where fx-focus-width becomes 3px.
     *
     * THE GAP LAYER HAS TO KNOW ITS SURFACE, and one value cannot serve every
     * consumer, so it is a LOCAL WITH A DEFAULT rather than a fixed colour:
     * fx-shadow-focus-surface defaults to fx-color-level-1, which is the card
     * plane that .input-group and .fx-segmented actually sit on. A call site on
     * another plane redeclares the local on itself and the ring follows: a
     * clipping control living inside a popover sets fx-shadow-focus-surface to
     * fx-color-level-3 in its own rule block and needs nothing else.
     *
     * Getting that wrong is cosmetic, not an accessibility failure — the ring
     * itself is unaffected and still clears 3:1; only the 2px gap would be
     * painted in a slightly wrong colour. */
    --fx-shadow-focus:
        0 0 0 var(--fx-focus-offset)
            var(--fx-shadow-focus-surface, var(--fx-color-level-1)),
        0 0 0 calc(var(--fx-focus-offset) + var(--fx-focus-width))
            var(--fx-color-focus-ring);

    /* DEPRECATED. Focus is an OUTLINE now — 2px solid at 2px offset, no blur,
     * no spread halo, no brand bloom. See section 9 and 01-base section 11.
     * Retuned to be identical to fx-shadow-focus so any surviving call site
     * paints the new model rather than the old one. */
    --fx-shadow-focus-glow: var(--fx-shadow-focus);

    /* ══ THE FOCUSED FIELD'S GLOW — MINT, AND NOT A RING ════════════════════
     *
     * OWNER DECISION, 2026-08-29, ARRIVED AT IN TWO STEPS. The original
     * indicator was a 2px ring standing 2px off the field; that was rejected as
     * fencing the control rather than choosing it. The FIRST replacement was a
     * 1px ring hugging the field plus a bloom — and it was rejected too, in the
     * owner's words: "you added a border the same way and changed its colour".
     *
     * HE WAS RIGHT, AND THE REASON IS THE HUE, NOT THE GEOMETRY.
     * fx-color-focus-ring is fx-p-green-800 (#145a32) — a near-black green.
     * ANY shape drawn in it reads as a border, at 1px as much as at 2px.
     * Thinning it was answering the wrong question.
     *
     * SO THE GLOW IS DRAWN IN THE CLIENT'S MINT RAMP INSTEAD, which is what
     * section 3.9 already says interaction colour must come from: brand marks
     * identity and position, interaction is a tint and stays clearly weaker
     * than any brand mark. A mint bloom obeys that rule; a green-800 ring
     * competed with it. The owner's instinct matched the written contract and
     * the earlier implementation did not.
     *
     * TWO LAYERS, AND THE SECOND ONE IS WHY IT READS AS A SHADOW.
     * Layer one is a 3px solid core in the pale mint, layer two a 10px BLURRED
     * bloom in the deepest mint at 55%. The blur is the whole point: a spread
     * with no blur is a ring however pale you make it, and "a thin shadow in
     * light green" was the request.
     *
     * IT DOES NOT REPLACE THE WELL, IT JOINS IT. Every consumer composes this
     * in FRONT of fx-ctl-shadow so the depth that identifies a field under
     * SC 1.4.11 survives being focused.
     *
     * THE ACCESSIBILITY POSITION, STATED PLAINLY. Mint against a white field
     * measures 1.34:1 to 1.60:1, so this indicator does NOT meet the 3:1 that
     * SC 2.4.13 (AAA) asks of a focus indicator; SC 2.4.7 (AA) requires only
     * that focus be visible, which a 13px-wide mint bloom plainly is. This is a
     * recorded owner decision with the shortfall written down, NOT an oversight
     * — see DEVIATIONS D-066. Anyone tempted to "fix" the contrast by darkening
     * the hue is undoing the decision, not improving it.
     *
     * AND THE OUTLINE DOES NOT GO AWAY, IT GOES TRANSPARENT. Forced-colours
     * mode drops every box-shadow in the document, which would leave a focused
     * field with no indicator at all. 05-forms keeps `outline: 2px solid
     * transparent` at the same offset so the geometry survives, and the
     * forced-colours blocks give it back a real system colour — which is also
     * where the 3:1 story is genuinely satisfied, by Highlight. */
    --fx-focus-glow-core: 3px;
    --fx-focus-glow-blur: 10px;

    /* Semantic names over the client ramp: no component may consume fx-p-* . */
    --fx-color-focus-glow:      var(--fx-p-mint-200);
    --fx-color-focus-glow-soft: var(--fx-p-mint-500);

    --fx-shadow-field-focus:
        0 0 0 var(--fx-focus-glow-core) var(--fx-color-focus-glow),
        0 0 var(--fx-focus-glow-blur) 2px
            color-mix(in srgb, var(--fx-color-focus-glow-soft) 55%, transparent);

    /* Frosted panel treatment. Usage:
     *   background: var(fx-glass-bg);
     *   backdrop-filter: blur(var(fx-glass-blur)) saturate(160%);
     *   border: var(fx-border-width) solid var(fx-glass-border);
     *   box-shadow: var(fx-glass-shadow);
     * Always supply an opaque fallback background first, because backdrop-filter
     * is silently ignored where it is unsupported and the panel would then be
     * translucent with no blur behind it. */
    --fx-glass-bg:     rgba(247, 251, 245, 0.72);
    --fx-glass-blur:   14px;

    /* Grain. A large flat brand fill is what reads cheap — the sidebar rail and
     * the login backdrop are both big slabs of one green, and a trace of noise
     * is what stops them looking like painted card. Self contained by
     * construction: an inline SVG turbulence as a data URI, because no external
     * asset can be referenced from a bundled stylesheet. Apply as an overlay
     * layer with pointer-events none, never as the element's own background. */
    --fx-texture-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
    --fx-texture-grain-opacity: 0.035;
    --fx-glass-border: var(--fx-color-border-emphasis);
    --fx-glass-shadow: var(--fx-shadow-float-lg);
}

/* Dark elevation. The alpha RISES with elevation here, the opposite of light,
 * because the background step between adjacent planes is only 1.05:1 and the
 * shadow is therefore carrying nearly all of the separation. fx-shadow-xs
 * COLLAPSES TO none: a 1px shadow on a near black page is invisible and only
 * costs a paint. Note also that the well INVERTS here: its identification band
 * is a rim light, not a shadow. See the header rule. */
html[data-bs-theme="dark"]:root {
    --fx-shadow-ring: 0 0 0 var(--fx-border-width) var(--fx-color-border);

    --fx-shadow-xs:  none;
    --fx-shadow-sm:  0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:  0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:  0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:  0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl: 0 20px 56px rgba(0, 0, 0, 0.55);

    --fx-shadow-float-sm: 0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md: 0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg: 0 7px 32px rgba(0, 0, 0, 0.35);

    /* The inset highlight is dropped in dark — an inner light band on a near
     * black card reads as a scratch, not as an edge. The four drop layers stay
     * and are strengthened, because they are the only edge the card has. */
    --fx-shadow-stack:
        0 5px 2px 0 rgba(0, 0, 0, 0.02),
        0 3px 2px 0 rgba(0, 0, 0, 0.08),
        0 1px 1px 0 rgba(0, 0, 0, 0.14),
        0 0 1px 0 rgba(0, 0, 0, 0.16);

    /* Band 1 is the rim light and carries the guarantee — it is LIGHTER than the
     * fill on purpose, because nothing darker can reach 3:1 here.
     * ITS GEOMETRY WAS THE ONE OUTRIGHT FAILURE THIS FILE HAS RECORDED. At
     * 1px/3px the rendered top row measured 2.231:1 against the 4.34:1 the
     * header claimed, so every dark-theme field on the platform was
     * non-conformant. 2px/2px measures 3.626:1. The alpha is untouched at 0.50;
     * only the offset and the blur moved, and BOTH had to: the offset was too
     * small to hold the peak on the first pixel row and the blur was wide enough
     * to smear the rest of it out of the box. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(231, 239, 230, 0.50),
        inset 0 6px 14px rgba(0, 0, 0, 0.45),
        inset 0 -2px 4px rgba(0, 0, 0, 0.35);

    --fx-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press: inset 0 1px 3px rgba(0, 0, 0, 0.50);

    /* The full four layer bevel — see the rule over the light declaration. The
     * two inset hairlines exist only here, because only in dark does a flat
     * fill need an edge simulated for it. */
    --fx-shadow-bevel:
        inset 0 var(--fx-border-width) 0 0 var(--fx-color-border-emphasis),
        inset 0 0 0 var(--fx-border-width) var(--fx-color-border-subtle),
        0 0 0 var(--fx-border-width) var(--fx-color-border),
        var(--fx-shadow-float-sm);

    /* DEPRECATED — see the light block. Zero consumers as of 2026-08-02. */
    --fx-shadow-glow: var(--fx-shadow-float-md);

    /* Same two layer geometry as light — read the rule over the light
     * declaration. The gap layer's default, fx-color-level-1, is re-declared
     * for this theme in 3.1, so the local picks up the dark card plane without
     * anything being restated here. */
    --fx-shadow-focus:
        0 0 0 var(--fx-focus-offset)
            var(--fx-shadow-focus-surface, var(--fx-color-level-1)),
        0 0 0 calc(var(--fx-focus-offset) + var(--fx-focus-width))
            var(--fx-color-focus-ring);

    /* DEPRECATED — focus is an outline. See the light block. */
    --fx-shadow-focus-glow: var(--fx-shadow-focus);

    /* The field glow on dark. Same two layers and the same mint — read the
     * ruling over the light declaration — but the SOLID CORE IS TRANSLUCENT
     * here. Pale mint at full strength against a near-black field is a bright
     * white-green band that shouts; at 40% it settles into the surface and the
     * blurred bloom does the work, which is the same balance the light theme
     * gets for free from its white background. */
    --fx-color-focus-glow:      color-mix(in srgb, var(--fx-p-mint-400) 40%, transparent);
    --fx-color-focus-glow-soft: var(--fx-p-mint-500);

    --fx-shadow-field-focus:
        0 0 0 var(--fx-focus-glow-core) var(--fx-color-focus-glow),
        0 0 var(--fx-focus-glow-blur) 2px
            color-mix(in srgb, var(--fx-color-focus-glow-soft) 45%, transparent);

    --fx-glass-bg:     rgba(23, 37, 27, 0.72);
    --fx-glass-blur:   16px;
    --fx-glass-border: var(--fx-color-border-emphasis);
    --fx-glass-shadow: var(--fx-shadow-float-lg);
}


/* ── 7) Motion ─────────────────────────────────────────────────────────────
 *
 * Durations are damped to near zero by 01-base under prefers-reduced-motion,
 * so any component that animates through these tokens honours the preference
 * for free. Animating through a hard coded duration bypasses that and is a bug.
 *
 * ══ THE TWO SPEEDS — RETUNED 2026-08-02 ═══════════════════════════════════
 *
 * Linear's timings cluster in two places and NOWHERE IN BETWEEN:
 *   60 to 180ms   anything under the cursor — hover, press, popup, tooltip,
 *                 chevron rotation, a state change on a control
 *   500ms         a full-height side panel, and nothing else
 * The 200 to 400ms band that most design systems live in is precisely the band
 * that makes an application feel slow: long enough to wait for, short enough
 * that waiting feels pointless. Do not put anything there.
 *
 * ══ THE 250ms CONTRADICTION, SETTLED 2026-08-02 (SECOND PASS) ═════════════
 *
 * THE FOUNDATION WAS BREAKING ITS OWN RULE. This section banned the 200 to
 * 400ms band and then declared fx-dur-slow at 250ms, inside it. The stated
 * justification was the sidebar collapse. That justification had already
 * expired: nothing in 02-layout or 03-leptonx reads fx-dur-slow, and a sidebar
 * collapse is a FULL HEIGHT PANEL, which this very section routes to
 * fx-dur-slower (500ms) anyway. The token was a 250ms hole with no owner.
 *
 * The cost of leaving it was not theoretical. Two component layers wrote
 * defensive comments explaining that they refuse to use fx-dur-slow because it
 * lands in the banned band (07-surfaces and 08-feedback both say so in their
 * headers), and 07-surfaces additionally had to justify NOT using it for the
 * Bootstrap collapse. An ambiguity that makes three authors write paragraphs
 * about a token none of them uses is costing more than the token is worth.
 *
 * THE RULING, stated so it can be followed without re-deriving it:
 *
 *   1. THE 200 TO 400ms BAN IS ABSOLUTE FOR TRANSITIONS AND ENTRANCES. There
 *      is no class of motion that earns it. If a duration feels like it wants
 *      to be 250ms, the thing being animated is either smaller than you think
 *      (take fx-dur-base) or it is a full height panel (take fx-dur-slower).
 *
 *   2. fx-dur-slow IS RETUNED FROM 250ms TO 180ms and now means: A SELF
 *      CONTAINED ENTRANCE THE USER IS NOT WAITING ON. A dialog arriving, a
 *      staggered child landing, a region fading in behind the pointer. It is
 *      the TOP of the under-the-cursor band, not a step above it. 180ms is
 *      already this section's own reference timing for a dialog and previously
 *      had no token, so the rung was missing and the banned rung was occupied
 *      — the retune fixes both with one value.
 *
 *   3. THE BAN GOVERNS TRANSITIONS AND ENTRANCES, NOT PERIODS. A looping
 *      indicator (a spinner's rotation, a skeleton sweep, an indeterminate
 *      progress sliver) is a PERIOD, not a duration a user waits through, and
 *      is derived from fx-dur-slower by multiplication. 04, 08 and 09 already
 *      do exactly this and are correct. The toast DWELL (fx-toast-duration) is
 *      likewise not motion at all.
 *
 *   4. A STAGGER IS SCHEDULED, NOT SLOWED. The perceived length of a staggered
 *      entrance is the child duration PLUS the accumulated delay, so the child
 *      duration is the wrong dial to make an entrance feel considered — the
 *      step is. Change fx-stagger-step, never the child duration.
 *
 * REFERENCE TIMINGS, so a component never has to guess. Every one of them now
 * has a token; before this pass, tooltip, chevron and dialog did not:
 *   popup CLOSE            60ms   (fx-dur-exit)
 *   popup OPEN             80ms   (fx-dur-enter)
 *   hover fill            100ms   (fx-dur-fast)
 *   tooltip               120ms   (fx-dur-quick)
 *   chevron rotate        120ms   (fx-dur-quick)
 *   button state change   160ms   (fx-dur-base)
 *   dialog                180ms   (fx-dur-slow)
 *   side panel            500ms   (fx-dur-slower)
 *
 * AN EXIT IS FASTER THAN ITS ENTRANCE. This is not symmetry for its own sake —
 * a menu that takes as long to leave as it took to arrive feels like it is
 * arguing with the click that dismissed it. Enter with fx-dur-enter and
 * fx-ease-standard; leave with fx-dur-exit and fx-ease-in-quad.
 *
 * ENTER ANIMATIONS ARE OPACITY PLUS SCALE, ANCHORED TO THE TRIGGER. Never a
 * slide, never a bare fade. A popover scales from fx-enter-scale up to 1 with
 * its transform-origin set to the edge nearest the control that opened it, so
 * it reads as growing OUT of the trigger. fx-slide-in-inline survives for
 * toasts and offcanvas, where there genuinely is an edge to come from, and its
 * distance was cut hard for the same reason.
 *
 * THE VOCABULARY:
 *   fx-ease-standard  ease-out-quad, the DEFAULT for everything that enters or
 *                     changes state under the cursor.
 *   fx-ease-in-quad   the EXIT curve. Accelerates away. Never used to enter.
 *   fx-ease-spring    a real overshoot. Reserve it for something that must feel
 *                     physical — a toggle knob, a drag drop. Not for menus.
 *                     AUDITED 2026-08-02 (second pass): STILL USED, four call
 *                     sites in two files. Two are legitimately physical (the
 *                     checkbox tick and the switch knob in 05-forms). Two are
 *                     not: 03-leptonx puts it on a dropdown pop and on a
 *                     transform transition, which is precisely the "not for
 *                     menus" case this line already forbids. Flagged, not
 *                     changed — the token is not this file's to enforce.
 *   fx-ease-decel     fast out of the gate, long settle. Staggers, list
 *                     entrances, anything arriving in sequence.
 *   fx-stagger-step   the interval between successive children in an entrance.
 *                     Consumed through the fx-stagger mechanism in 01-base.
 *                     THIS, not the child duration, is the dial for how
 *                     considered an entrance feels — see ruling 4 above.
 *   fx-lift-sm/md     hover translateY distances. Negative: up is out of the
 *                     page. DEPRECATED IN PRACTICE and AUDITED 2026-08-02
 *                     (second pass): ZERO CONSUMERS anywhere in wwwroot. The
 *                     retune removed the last of them, because the reference
 *                     does not lift on hover — it changes fill. Kept alive per
 *                     the section 12 contract. If you are about to use one,
 *                     the thing you are lifting had better be draggable.
 *   fx-lift-focus     DEPRECATED as part of the focus treatment; focus is an
 *                     outline and does not move the control. Token kept alive.
 *                     AUDITED: ZERO CONSUMERS.
 *   fx-press-scale    the :active scale. 0.97 is exactly Linear's value.
 *   fx-enter-scale    the start scale of a popover or dialog entrance.
 *   fx-shine-dur      how long the gloss sweep takes to cross a primary button.
 *                     AUDITED 2026-08-02 (second pass): ZERO CONSUMERS. The
 *                     fx-shine keyframe in 01-base is likewise applied nowhere
 *                     — a gloss sweep across a primary button is the "themed
 *                     Bootstrap" signal the accent rule in 3.9 exists to
 *                     remove. Both are kept declared, neither is live.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-dur-instant: 60ms;
    --fx-dur-fast:    100ms;
    /* 120ms. THE MISSING RUNG, added 2026-08-02 (second pass). This section's
     * own reference table names 120ms twice — tooltip and chevron rotate — and
     * the ladder jumped 100 to 160 with nothing between, so both had to be
     * written as literals or rounded. 05-forms wrote the literal and flagged
     * it; 09-tabulator rounded its three chevrons down to fx-dur-fast to keep
     * them consistent with each other. THE THREE CHEVRONS IN THE SYSTEM — the
     * select trigger, the nav disclosure and the grid tree expander — must all
     * read THIS token. A rotation that differs by 20ms between two chevrons on
     * the same screen is the kind of inconsistency nobody can name and
     * everybody feels. */
    --fx-dur-quick:   120ms;
    --fx-dur-base:    160ms;
    /* RETUNED 250ms → 180ms, 2026-08-02 (second pass). Read the ruling in the
     * header before changing this. In one line: 250ms sat inside the band this
     * section bans, for a sidebar collapse that never consumed it, and 180ms is
     * both the top of the sanctioned band and this section's own reference
     * timing for a dialog. Its meaning is now "a self contained entrance the
     * user is not waiting on". */
    --fx-dur-slow:    180ms;
    --fx-dur-slower:  500ms;   /* full-height panel ONLY */

    /* Popup open and close. Named separately from the ladder above because the
     * asymmetry is the point and a component must not have to remember it. */
    --fx-dur-enter: 80ms;
    --fx-dur-exit:  60ms;

    --fx-ease-standard:   cubic-bezier(0.25, 0.46, 0.45, 0.94);   /* ease-out-quad */
    --fx-ease-in-quad:    cubic-bezier(0.55, 0.085, 0.68, 0.53);  /* EXITS only */
    --fx-ease-out:        cubic-bezier(0, 0, 0.2, 1);
    --fx-ease-in:         cubic-bezier(0.4, 0, 1, 1);
    --fx-ease-emphasized: cubic-bezier(0.05, 0.7, 0.1, 1);
    --fx-ease-spring:     cubic-bezier(0.34, 1.56, 0.64, 1);
    --fx-ease-decel:      cubic-bezier(0.16, 1, 0.3, 1);

    --fx-stagger-step: 40ms;

    --fx-lift-sm:    -1px;
    --fx-lift-md:    -2px;
    --fx-lift-focus: 0;       /* deprecated — focus no longer moves anything */

    --fx-press-scale: 0.97;
    --fx-enter-scale: 0.96;   /* Linear's range is 0.90 to 0.98 */

    --fx-shine-dur: 700ms;

    /* How long a toast stays on screen before it auto dismisses. Overridden per
     * toast from JavaScript by setting the property on the toast element. This
     * is a DWELL time, not an animation, so it is deliberately NOT damped by
     * prefers-reduced-motion: a user who asked for less motion still needs the
     * same amount of time to read the message. */
    --fx-toast-duration: 5s;

    /* ══ THE TWO LOADING SCHEDULE TOKENS ═══════════════════════════════════
     *
     * These are the dials behind every busy indicator in the product, and they
     * are the reason it does not strobe. Both are read from JavaScript by
     * frihat-loading.js through getComputedStyle, so a retune here moves the
     * whole system and no number is typed in script.
     *
     * THEY ARE NOT `fx-dur-*` AND THE PREFIX IS DELIBERATE. Section 7's own
     * rule says every duration added to the ladder must also be added to the
     * damper in 01-base. These must NOT be damped, so they are deliberately
     * NOT on the ladder. They measure HUMAN PERCEPTION, not motion — the same
     * quantity fx-toast-duration measures and for the same reason it is the one
     * time token left undamped. A user who asked for less motion has not asked
     * to be shown a flicker; damping these to 0.01ms would remove the anti
     * flash guarantee for precisely the user least able to tolerate a flash.
     * If you are adding a token here, do not add it to the 01-base list.
     *
     * NEITHER LANDS IN THE BANNED 200 TO 400ms BAND, and the ban does not
     * govern them anyway: a delay is not a transition and a floor is not an
     * entrance. Both are stated inside the sanctioned values regardless, so a
     * reader does not have to re-derive the exemption.
     *
     * ══ THE MODEL WAS INVERTED ON 2026-08-14. READ THIS FIRST. ═════════════
     *
     * These two tokens were written for a system whose first principle was DO
     * NOT PAINT unless the wait is real. That system shipped and was invisible
     * in the browser — correctly, by its own rules, and it was the wrong
     * product. The owner asked for a SIGNATURE: an indicator seen on every
     * action, because the identity comes from the repetition.
     *
     * SO THE BRANDED PATH NO LONGER CONSULTS `fx-load-delay`. It paints at once
     * and is HELD for `fx-load-min-visible`. The roles have swapped: the FLOOR
     * is now the load-bearing token and the DELAY is the situational one.
     *
     * NOTE WHAT DID NOT CHANGE. The anti-flash guarantee is intact, because a
     * strobe is an indicator that appears and vanishes within a few frames and
     * a guaranteed 500ms floor cannot do that. The delay was only ever one of
     * two ways to buy that guarantee; the floor is the other, and it is the one
     * that buys it while being SEEN. Neither token was wrong; the dial moved
     * from "never paint" to "always paint, never briefly".
     *
     * `fx-load-delay` IS KEPT AND STILL BINDS ON THE UNBRANDED PATHS — the
     * CSS-only anti-flash on `.fx-loading-overlay` and `.abp-block-area` in
     * 08-feedback section 6, which have no script to hold them. Do not delete
     * it, and do not reintroduce it on the branded path.
     *
     *   fx-load-delay        160ms. THE SHOW DELAY. Nothing is painted for the
     *                        first 160ms of an UNBRANDED wait; work that
     *                        finishes inside the window never paints at all. It
     *                        is 160ms and
     *                        not the 120ms a generic guide would suggest
     *                        because 160ms is ALREADY the delay shipped in
     *                        08-feedback's CSS anti flash rule (written there
     *                        as fx-dur-base). Two tiers of the same system
     *                        disagreeing by 40ms would be a defect nobody could
     *                        see and everybody would feel — the same argument
     *                        section 7 makes about the three chevrons.
     *
     *   fx-load-min-visible  500ms. THE MINIMUM VISIBLE DURATION, and since the
     *                        inversion above this is THE load-bearing token of
     *                        the pair. Every branded indicator paints at once
     *                        and is held here, so the user sees it on every
     *                        action and it can never strobe. Equal to
     *                        fx-dur-slower by
     *                        value and by intent: 500ms is this system's
     *                        established "long enough to be a deliberate
     *                        event". Written as its own token rather than as
     *                        var(--fx-dur-slower) precisely BECAUSE that token
     *                        is damped and this floor must not be.
     *
     * THE PAIR IS WHAT MAKES IT WORK, not either one alone. The delay removes
     * the indicator that should never have appeared; the floor removes the
     * flicker from the one that had to. */
    --fx-load-delay:       160ms;
    --fx-load-min-visible: 500ms;

    /* The navigation progress bar's thickness. Its own token because it is the
     * one piece of chrome that must stay legible at the very top edge of the
     * viewport, where it is competing with the window frame, and a space step
     * would tie it to a scale that has nothing to do with that.
     *
     * RETUNED 3px → 5px, 2026-08-14, on the owner's verdict that 3px "is too
     * thin for a signature". It is not a hairline reporting a background task;
     * it is the platform's most frequently seen branded surface, and at 3px
     * over a 5px window chrome it was competing with the frame rather than
     * reading as part of the application. */
    --fx-load-bar-size: 5px;
}


/* ── 8) Z-index ────────────────────────────────────────────────────────────
 * Aligned with Bootstrap 5.3 so Frihat layers interleave with modals, offcanvas
 * and tooltips predictably. Never write a raw z-index in a component.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-z-base:     0;
    --fx-z-raised:   10;
    --fx-z-sticky:   1020;
    --fx-z-fixed:    1030;
    --fx-z-backdrop: 1040;
    --fx-z-modal:    1050;
    --fx-z-dropdown: 1060;
    --fx-z-popover:  1070;
    --fx-z-tooltip:  1080;
    --fx-z-toast:    1090;
}


/* ── 9) Controls and sizing ────────────────────────────────────────────────
 *
 * RETUNED 2026-08-02 onto the measured Linear density.
 *
 * THE BUTTON LADDER IS 24 / 32 / 40 / 44px. The middle of that ladder — 32px —
 * is the single most reused height in the entire reference: a menu item, a
 * select item, a nav pill and a table header row are ALL 32px. Our md moved
 * from 36 to 32 to land on it, lg moved from 44 to 40, an xs was added at 24,
 * and 44 survives as xl because that is also the touch comfort target.
 *
 * WCAG 2.2 SC 2.5.8 Target Size (Minimum) is 24 by 24 CSS px. fx-control-h-xs
 * sits exactly on that floor and is therefore the ABSOLUTE MINIMUM: an element
 * at fx-control-h-xs must be a full 24px hit area, not a 24px box with an
 * inset icon. Anything smaller needs padding or an inset pseudo element to
 * reach 24px, and if it cannot, it is not an interactive element.
 *
 * On a coarse pointer the whole ladder steps back up so a primary action is at
 * least 40px tall on touch, and fx-tap-min stays at the 44px comfort target.
 *
 * ROW AND ITEM HEIGHTS are separated from the control ladder because a row is
 * not a control: it is a container that may hold one. Linear runs a 36px table
 * row by default with 32px compact and 40px comfortable variants, a 32px table
 * HEADER row, 32px menu and select items, and a 28px sidebar nav item.
 *
 * WHERE THE COMFORT COMES FROM. The type scale is small and the heights are
 * compact, so comfort is bought with AIR: the surface padding tokens below,
 * and the popover gutter. Heights do not move — padding does.
 *
 * THE POPOVER GUTTER is the small detail that separates a menu that looks
 * BUILT from one that looks stacked: 4px of padding inside the popover, around
 * items that carry a 6px radius. Without the gutter the first and last item
 * touch the container edge and the whole panel reads as a list with a border
 * drawn round it.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-control-h-xs: 24px;   /* mini button, dense icon button, tag */
    --fx-control-h-sm: 28px;   /* small button, sidebar nav item */
    --fx-control-h-md: 32px;   /* THE default — menu item, select item, nav pill */
    --fx-control-h-lg: 40px;   /* large button, primary form action */
    --fx-control-h-xl: 44px;   /* hero action, and the touch comfort target */

    --fx-control-pad-x-xs: 0.625rem;   /* 10px */
    --fx-control-pad-x-sm: 0.75rem;    /* 12px */
    --fx-control-pad-x-md: 1rem;       /* 16px */
    --fx-control-pad-x-lg: 1.25rem;    /* 20px */

    /* Gap between a control's icon and its label. Not derived from the space
     * scale: these are optical values measured off the reference, and the lg
     * step being TIGHTER than sm is correct rather than a typo — at 40px tall
     * the icon and label already have vertical air, so a wide gap makes the
     * pair read as two separate things. */
    --fx-control-gap-xs: 0.25rem;    /* 4px */
    --fx-control-gap-sm: 0.5rem;     /* 8px */
    --fx-control-gap-md: 0.5rem;     /* 8px */
    --fx-control-gap-lg: 0.375rem;   /* 6px */

    /* Rows and list items. A row is a container, not a control — see the note.
     *
     * THE DENSITY LADDER IS FOUR TIERS, NOT THREE (completed 2026-08-02, second
     * pass). 09-tabulator shipped compact / default / comfortable / spacious as
     * classes but only three row tokens existed, so fx-density-spacious had to
     * be documented as an ALIAS of comfortable — a density control with two
     * settings that do the same thing. The fourth rung continues the ladder's
     * own constant 4px step: 32 / 36 / 40 / 44. */
    --fx-row-h-compact:     32px;
    --fx-row-h:             36px;   /* the default table row */
    --fx-row-h-comfortable: 40px;
    --fx-row-h-spacious:    44px;   /* the fourth density tier */
    --fx-row-h-head:        32px;   /* table header row */
    --fx-menu-item-h:       32px;   /* menu row, select option, nav pill */
    --fx-nav-item-h:        28px;   /* sidebar navigation entry */

    /* 14px OF INLINE PADDING ON A MENU ROW. Promoted from a 07-surfaces
     * component local 2026-08-02 (second pass). It is not on the 4px space
     * ladder and not on the control padding ladder above — the nearest are 12px
     * and 16px and both are visibly wrong beside the 4px popover gutter, which
     * is what a menu row's inset is actually measured against.
     *
     * WHY IT IS NOT A FIFTH fx-control-pad-x-* RUNG, since the reference calls
     * 14px its "medium" control padding and 04-buttons hit the same number. A
     * menu row is a 6px-cornered rectangle; a button is a FULL PILL. The pill's
     * curve eats the first and last few pixels of its own padding box, so at
     * equal height a pill needs MORE side padding than a rectangle to look
     * equally inset — which is why 04-buttons resolving its medium tier UP to
     * fx-control-pad-x-md (16px) is correct rather than a rounding error, and
     * why the two numbers should not be unified under one name. Consumers:
     * dropdown items, select options, command rows, list rows. */
    --fx-menu-item-pad-x: 0.875rem;   /* 14px */

    /* THE SECTION LABEL STRIP, 30px. The one height in the sidebar that is
     * neither a nav entry (28px) nor a menu item (32px): it is the label band
     * BETWEEN two groups, and the reference draws it at 30. Promoted from a
     * 03-leptonx literal 2026-08-02 (second pass) because the command menu's
     * group heading is the same object and was about to declare it a second
     * time. Rounding it to either neighbour would move the group rhythm to make
     * a number tidier.
     *
     * IT IS NOT INTERACTIVE, so SC 2.5.8 does not reach it and it does not have
     * to grow to 44px on a coarse pointer — but it does step with its
     * neighbours below, because a label that stayed at 30px between 44px rows
     * would read as a crushed line rather than as a heading. */
    --fx-section-label-h: 30px;

    /* THE DIALOG HEADER AND FOOTER BAND, 56px. Promoted from a 07-surfaces
     * derivation 2026-08-02 (second pass), where it was written out twice — once
     * for .modal and once for .offcanvas — and the .frihat-dialog family needed
     * it a third time. DERIVED, NOT TYPED: the default control plus one space-3
     * of air on each side is exactly 56px today, and it grows correctly on its
     * own when the control ladder steps up for touch (40 + 24 = 64px). A typed
     * 56px would silently crush a 40px action against the band edge on a
     * tablet. */
    --fx-dialog-band-h: calc(var(--fx-control-h-md) + var(--fx-space-3) * 2);

    /* THE NON INTERACTIVE STATUS PILL, 20px. It is deliberately NOT a rung on
     * the fx-control-h-* ladder above, and the distinction is an accessibility
     * one rather than a naming one: fx-control-h-xs (24px) sits exactly on the
     * WCAG 2.2 SC 2.5.8 floor and is the absolute minimum for anything a user
     * can operate. A 20px control would fail that outright. This token is for a
     * badge, a chip or a status pill that is REPORTING state and cannot be
     * clicked. If the thing wearing it gains a click handler, a dismiss cross
     * or a keyboard focus, it stops being eligible for this token and moves to
     * fx-control-h-xs. */
    --fx-badge-h-sm: 1.25rem;   /* 20px — non interactive pills only */

    /* The popover gutter — see the note. Pair with fx-radius-item on the rows
     * inside and fx-radius-md on the container. */
    --fx-popover-pad: 4px;

    /* ══ THE POPUP ANCHOR CONVENTION ═══════════════════════════════════════
     *
     * Added 2026-08-02 (second pass). CSS anchor positioning is not shipping
     * everywhere yet, so a popup that must be at least as wide as the control
     * that opened it has to be told how wide that control is. 05-forms solved
     * it for the select popup with a local (fx-select-anchor-w) written by the
     * opening script and a max() floor typed at the call site. That is the
     * right mechanism; it just needs to be the SAME mechanism everywhere, so a
     * dropdown, a combobox, a date picker and a command palette do not each
     * invent a property name their own script has to know.
     *
     * THE CONVENTION, in one line at the call site:
     *
     *     min-inline-size: max(var(--fx-anchor-w, 0px), var(--fx-popover-min-w));
     *
     * The opening script sets fx-anchor-w ON THE POPUP, in px, from the
     * trigger's offsetWidth. The floor means the popup is correct even if the
     * property is never set at all — which is the state on first paint, on a
     * page with no script, and in any test that renders the markup statically.
     * Never write the floor as a literal; a 160px popup that has to become
     * 180px should be one edit here, not a search across four files.
     *
     * The default is 0px and NOT 0: max() and min() are type checked, and a
     * unitless zero against a px value invalidates the whole declaration. */
    --fx-anchor-w:      0px;
    --fx-popover-min-w: 160px;

    /* Interior padding for SURFACES, the counterpart of the control padding
     * above: card bodies, panel bodies, dropdown menus, modal bodies, empty
     * states, form sections. Fluid over the same 360 to 1920px band as the
     * space and type scales, so a 13 inch laptop is not wasteful and a 32 inch
     * screen is not mean. Never use a raw fx-space-* step for a card body —
     * that is what let the previous build read tight. */
    --fx-surface-pad-sm: clamp(0.875rem, 0.8173rem + 0.2564vw, 1.125rem);  /* 14 → 18px */
    --fx-surface-pad-md: clamp(1.125rem, 1.0096rem + 0.5128vw, 1.625rem);  /* 18 → 26px */
    --fx-surface-pad-lg: clamp(1.5rem,   1.3269rem + 0.7692vw, 2.25rem);   /* 24 → 36px */

    --fx-tap-min: 44px;

    /* Icons. 16px is the DEFAULT everywhere — Linear uses it for menu icons,
     * button icons, table cell icons and toolbar icons alike, and only steps
     * off it for genuinely dense chrome (12 to 14) or a page-level affordance
     * (18). The old 18 / 22 pair read a full step too large beside 15px text. */
    --fx-icon-xs: 12px;
    --fx-icon-sm: 14px;
    --fx-icon-md: 16px;   /* THE default */
    --fx-icon-lg: 18px;

    /* Nothing in the system is thicker than 2px, and 2px is only ever reached
     * by the prefers-contrast promotion and the forced-colors block. At 2dppx
     * and above the hairline drops to a genuine half pixel, which is what makes
     * a border read as an EDGE rather than as a drawn line on a Retina panel.
     * A device pixel ratio below 2 cannot render 0.5px and would round it to 0
     * or 1 unpredictably, which is why this is behind a media query rather than
     * being the base value. */
    --fx-border-width:        1px;
    --fx-border-width-strong: 2px;

    /* 1.5px — THE NO-REFLOW RESERVATION. Added 2026-08-02 (second pass) for the
     * badge family, which carries a TRANSPARENT border on every badge whether or
     * not it is an outline variant, so that switching a badge from filled to
     * bordered at runtime — a status changing, a filter chip being selected —
     * changes a colour and never reflows the row it sits in. Without it every
     * such swap jumps by 3px.
     *
     * ITS SANCTIONED USE IS THAT RESERVATION, AND THE OUTLINE VARIANT THAT
     * PAINTS IT. It is not a general purpose stroke and nothing structural may
     * reach for it: the two line families in 2.3 are drawn at
     * fx-border-width, and 2px remains the system's ceiling.
     *
     * NOTE WHAT IT DOES NOT DO. It is deliberately NOT halved by the 2dppx
     * block below, unlike fx-border-width. The hairline is halved there because
     * a 0.5px line reads as a truer edge on a Retina panel; this value is a
     * LAYOUT reservation whose entire purpose is that the box never changes
     * size, so halving it at one device pixel ratio and not another would
     * reintroduce exactly the reflow it exists to prevent. */
    --fx-border-width-mid:    1.5px;

    /* THE FOCUS GEOMETRY. 2px solid, 2px outside the element. Read the focus
     * note in 01-base section 11 before touching either value. */
    --fx-focus-width:  2px;
    --fx-focus-offset: 2px;

    /* SCROLLBARS. Linear runs a 6px thumb that grows to 10px on hover or drag,
     * with the thumb inset from the gutter edge so it never touches content.
     *
     * IMPLEMENTATION NOTE: the GUTTER stays a constant 10px and the thumb is
     * inset by fx-scrollbar-thumb-inset (2px, giving a 6px thumb) which drops
     * to 0 on hover (giving 10px). Animating the gutter itself would reflow the
     * scroll container on every hover, which is a worse defect than the effect
     * is worth. The visible result is identical. */
    --fx-scrollbar-size:         10px;
    --fx-scrollbar-thumb-inset:  2px;
    --fx-scrollbar-thumb:        rgba(15, 42, 24, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(15, 42, 24, 0.20);
    --fx-scrollbar-thumb-active: rgba(15, 42, 24, 0.30);
}

/* Hairlines on a high density display. See the note above fx-border-width. */
@media (min-resolution: 2dppx) {
    html:root {
        --fx-border-width: 0.5px;
    }
}

html[data-bs-theme="dark"]:root {
    --fx-scrollbar-thumb:        rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active: rgba(255, 255, 255, 0.40);
}

/* Touch and pen. Targets grow, icons grow with them. fx-tap-min (44px) is the
 * governing comfort target and is unchanged; the ladder below simply makes
 * sure the default and large tiers reach it or come close without a component
 * having to test the pointer type itself. */
@media (pointer: coarse) {
    html:root {
        --fx-control-h-xs: 28px;
        --fx-control-h-sm: 32px;
        --fx-control-h-md: 40px;
        --fx-control-h-lg: 44px;
        --fx-control-h-xl: 48px;

        --fx-control-pad-x-xs: 0.75rem;    /* 12px */
        --fx-control-pad-x-sm: 0.875rem;   /* 14px */
        --fx-control-pad-x-md: 1.125rem;   /* 18px */
        --fx-control-pad-x-lg: 1.375rem;   /* 22px */

        --fx-row-h-compact:     40px;
        --fx-row-h:             44px;
        --fx-row-h-comfortable: 48px;
        --fx-row-h-spacious:    52px;
        --fx-row-h-head:        40px;
        --fx-menu-item-h:       44px;
        --fx-nav-item-h:        40px;

        /* The menu row's inset grows with the row, landing on the same 18px the
         * default control padding takes here. */
        --fx-menu-item-pad-x: 1.125rem;   /* 18px */

        /* The label strip steps with its neighbours rather than to a tap
         * target — it is not operable. See the note over the fine value. */
        --fx-section-label-h: 42px;

        /* fx-dialog-band-h and fx-badge-h-sm are NOT restated here on purpose.
         * The band is derived from fx-control-h-md and fx-space-3, so it grows
         * to 64px by itself the moment the control ladder above steps up; the
         * badge is non interactive, so a coarse pointer gives it nothing to
         * hit and inflating it would only cost row height. */

        --fx-icon-xs: 14px;
        --fx-icon-sm: 16px;
        --fx-icon-md: 18px;
        --fx-icon-lg: 20px;

        /* A touch scrollbar is dragged with a thumb, so it does not shrink. */
        --fx-scrollbar-thumb-inset: 0px;
    }
}


/* ── 10) Layout ────────────────────────────────────────────────────────────
 *
 * Page rhythm, fluid over the same 360px to 1920px band as the type and space
 * scales. fx-container-max is written as a min() so it is already responsive
 * before any media query touches it: it can never exceed the available inline
 * size, and it can never exceed the readable cap.
 *
 * fx-measure is the prose cap. Use it on anything that is a column of running
 * text — a legal notice, a case summary, an empty state paragraph — so a 4K
 * monitor never produces an 80 word line. Dashboards and grids use
 * fx-container-max instead.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    --fx-container-max:   min(100%, 1120px);
    --fx-measure:         min(100%, 68ch);
    --fx-page-pad-inline: clamp(1rem, 0.7692rem + 1.0256vw, 2rem);   /* 16 → 32px */
    --fx-page-pad-block:  clamp(1rem, 0.8846rem + 0.5128vw, 1.5rem); /* 16 → 24px */
    --fx-gutter:          clamp(1rem, 0.8846rem + 0.5128vw, 1.5rem); /* 16 → 24px */
    --fx-header-h:        56px;
    --fx-toolbar-h:       44px;

    /* Vertical space reserved at the inline end corner for a floating action
     * button, so a toast stack anchored to the same corner clears it. A page
     * that has no floating action button sets this to 0 on its own root and the
     * toasts drop back to the normal page padding. */
    --fx-fab-clearance: 4.5rem;
}

/* 10.1 Breakpoint tiers — Bootstrap 5.3's ladder, min-width only, plus the
 * Frihat ultrawide tier. Only layout scale changes here; colour, type and
 * motion are already fluid and need no tier. */
@media (min-width: 992px) {
    html:root {
        --fx-container-max: min(100%, 1240px);
    }
}

@media (min-width: 1200px) {
    html:root {
        --fx-container-max: min(100%, 1320px);
    }
}

@media (min-width: 1400px) {
    html:root {
        --fx-container-max: min(100%, 1400px);
        --fx-header-h:      58px;
    }
}

/* 10.2 Ultrawide — 1800px and up. The container stops growing well before the
 * viewport does; the extra pixels become margin, not line length. */
@media (min-width: 1800px) {
    html:root {
        --fx-container-max:   min(100%, 1520px);
        --fx-page-pad-inline: clamp(2rem, 1.5rem + 1vw, 3rem);
        --fx-page-pad-block:  1.75rem;
        --fx-gutter:          1.75rem;
        --fx-header-h:        60px;
        --fx-toolbar-h:       48px;
    }
}


/* ── 11) Accessibility overrides ───────────────────────────────────────────
 *
 * prefers-contrast: more
 *   Promote every decorative line to the 3:1 strong line, collapse the dimmed
 *   text grades onto full strength body text, and thicken the focus ring.
 *   Both the light block and the dark block must be restated: the dark selector
 *   html[data-bs-theme="dark"]:root is specificity 0,2,1 and would otherwise
 *   outrank an html:root override (0,1,1) placed later in the file. Source
 *   order only decides ties, and this is not a tie.
 *
 * ══ THE COLLAPSE DOES NOT REACH THE PLACEHOLDER, AND THAT IS A RULING ══════
 *
 * DECIDED 2026-08-03, after a previous pass measured IDENTICAL INK for a
 * placeholder and a typed value in this tier and filed it as a defect. It is
 * one, and it is the token layer's to fix rather than a component's.
 *
 * The collapse is right for the other four consumers of the dimmed grades.
 * Help text, captions, labels and meta are CONTENT: a user who has asked the
 * operating system for more contrast is asking to be able to READ them, and
 * full strength body ink is the correct answer for every one.
 *
 * A placeholder is not content. It is a hint that duplicates the accessible
 * name of the field it sits in, and its second job — the one nothing else in
 * the system does — is to be visibly UNLIKE a value the user typed. Collapse it
 * onto body ink and an empty field becomes indistinguishable from a filled one.
 * On a legal platform that is a data-integrity defect, not a style regression:
 * a lawyer proof-reading a case form cannot see which fields they have actually
 * answered. The measurement, light theme, on the field fill:
 *
 *     BEFORE   placeholder #14231a   value #14231a   1.00:1   indistinguishable
 *     AFTER    placeholder #2d3a32   value #14231a   1.37:1   distinguishable
 *
 * SO THE PLACEHOLDER PROMOTES ONE RUNG INSTEAD OF COLLAPSING TO ZERO — tertiary
 * to secondary, 5.71:1 to 11.39:1 on the light field fill and 5.14:1 to 9.34:1
 * on the dark one. The preference is honoured (the hint gets substantially more
 * contrast, well past AAA) and the distinction survives (the value is still a
 * full tier darker). That is the general shape for any future tier that is a
 * HINT rather than content: promote it, do not collapse it.
 *
 * The values are written as LITERALS and cannot be `var(fx-color-text-muted)`.
 * Custom property substitution resolves at the point of USE, not at the point of
 * declaration, so naming the muted token inside this block would resolve to the
 * collapsed value three lines above and paint body ink anyway. The literals are
 * the resting secondary tier from 2.2, byte identical; if that tier ever moves,
 * move these with it.
 *
 * 05-forms 16.3 USED TO CARRY A BELT AND BRACES `::placeholder` RULE painting
 * fx-color-text under this query. It was not inert — it sat later in the file
 * than the rule that reads the local, so it won — and it is now removed,
 * because it would have re-flattened exactly what this block is protecting.
 * The same section promotes the SEARCH grade onto this token instead of its own
 * quaternary tier, so a command box's hint rises too without becoming a value.
 *
 * ══ THE SECOND EXEMPTION: DISABLED INK — RULED 2026-08-03 ══════════════════
 *
 * The placeholder ruling above states a general shape and then names only one
 * consumer, so the rest of the collapse was swept for anything with the SAME
 * shape: a grade whose job is to be visibly UNLIKE something else rather than
 * merely to be readable. Exactly one more was found, and it is
 * fx-color-disabled-fg, which points at the quaternary tier and therefore rode
 * the fx-color-text-faint collapse onto full strength body ink.
 *
 * WHY IT IS THE SAME DEFECT. A disabled control's ONLY job, visually, is to say
 * "this is not available to you". Collapse its ink onto body ink and it renders
 * identically to an available one. On a FIELD that is survivable — the disabled
 * fill and the flattened well are two further channels, and neither is touched
 * by this block. On a MENU ITEM, a dropdown link or a list group row it is not
 * survivable: those have no fill of their own, no well, and nothing but the ink
 * tier separating available from unavailable. What is left is `cursor:
 * not-allowed`, which is a POINTER-ONLY cue and says nothing to a keyboard or
 * touch user. So a user who asked the operating system for more contrast was
 * being told LESS about which actions they may take.
 *
 * SC 1.4.3's disabled exemption is not a defence here, and the distinction is
 * worth keeping straight: the exemption says a disabled control need not MEET
 * the contrast minimum. It does not say the platform may DELETE the difference
 * between disabled and enabled. This block was doing the second thing.
 *
 * SO IT PROMOTES ONE RUNG INSTEAD OF COLLAPSING — quaternary to TERTIARY, the
 * same shape as the placeholder and for the same reason. Measured on the
 * disabled fill:
 *     light   rest 3.388:1  →  promoted 5.077:1   enabled ink 13.868:1
 *     dark    rest 3.488:1  →  promoted 5.340:1   enabled ink 13.427:1
 * The preference is honoured — a disabled label gains about 1.5 stops and
 * clears AA outright, which it deliberately does not do at rest — and the
 * distinction survives, because the enabled ink is still some two and a half
 * times stronger. Under the collapse those two columns were the same number.
 *
 * LITERALS, FOR THE REASON GIVEN THREE PARAGRAPHS UP. Naming
 * var(fx-color-text-subtle) here would resolve to the collapse declared above
 * it and paint body ink anyway. The values are the resting TERTIARY tier from
 * 2.2 and 3.2, byte identical; if that tier moves, move these with it.
 *
 * KNOWN GAP, REPORTED RATHER THAN REACHED INTO. Three declarations in files
 * this one does not own route a disabled colour through fx-color-text-faint
 * DIRECTLY instead of through fx-color-disabled-fg, so they still collapse:
 * `bs-dropdown-link-disabled-color` in 03-leptonx and in 07-surfaces, and
 * `bs-list-group-disabled-color` in 07-surfaces. Each should read
 * fx-color-disabled-fg. They are the exact three sites the paragraph above
 * describes as unsurvivable, which is why they are named individually rather
 * than left to a sweep.
 *
 * forced-colors: active  (Windows High Contrast)
 *   NOTE, deliberately not handled here. In forced colours mode the user agent
 *   replaces every colour with a system palette, so overriding tokens is both
 *   ineffective and hostile. The correct response lives in the layers that
 *   paint: keep borders present so component boundaries survive, use the system
 *   keywords (Canvas, CanvasText, ButtonText, Highlight, LinkText) rather than
 *   tokens, and never rely on a box-shadow for a focus indicator because shadows
 *   are dropped entirely. 01-base carries the forced colours focus rule.
 * ────────────────────────────────────────────────────────────────────────── */
@media (prefers-contrast: more) {
    html:root {
        /* Both line families collapse onto the one 3:1 capable line. The
         * near-invisible tier documented in 2.3 is a DEFAULT, not a mandate:
         * a user who has asked the operating system for more contrast has
         * overridden it, and every separation becomes a real rule here. */
        --fx-color-border-subtle:   var(--fx-color-border-strong);
        --fx-color-border:          var(--fx-color-border-strong);
        --fx-color-border-emphasis: var(--fx-color-border-strong);
        --fx-color-divider-strong:  var(--fx-color-border-strong);
        --fx-color-divider:         var(--fx-color-border-strong);
        --fx-color-divider-soft:    var(--fx-color-border-strong);
        --fx-color-divider-faint:   var(--fx-color-border-strong);

        /* All four text tiers collapse onto full strength body text. The
         * quaternary tier is deliberately sub-AA at rest, so it is the one
         * that MOST needs promoting here. */
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        /* THE TWO DIMMED GRADES THAT DO NOT COLLAPSE. Both are literals from
         * 2.2 rather than var() reads, which would resolve to the collapse on
         * the lines above. Read the two rulings in the header.
         *   placeholder → the resting SECONDARY tier: it must stay unlike a
         *                 value the user typed.
         *   disabled    → the resting TERTIARY tier: it must stay unlike an
         *                 available control. */
        --fx-color-text-placeholder: #2d3a32;
        --fx-color-disabled-fg:      #58675e;

        --fx-color-link:        var(--fx-p-green-900);
        --fx-color-focus-ring:  var(--fx-p-green-900);
        /* The two identity marks from 2.5.1 promote alongside the ring, for the
         * same reason: under the corrected contract in 3.9 a position signal is
         * brand, so a user who asked the operating system for more contrast
         * must get a STRONGER brand, not a greyed one. green-900 measures
         * 10.74:1 worst case across level 0 to 3, against green-800's 7.24. */
        --fx-color-indicator:   var(--fx-p-green-900);
        --fx-color-brand-text:  var(--fx-p-green-900);
        --fx-border-width:      2px;
        /* Promoted alongside the hairline. The badge outline variant PAINTS
         * this width, so a user who asked the operating system for more
         * contrast must get a real stroke there too. Its no-reflow property is
         * preserved: it moves in lockstep with fx-border-width, so a filled and
         * a bordered badge still occupy identical boxes in this mode. */
        --fx-border-width-mid:  2px;
        --fx-focus-width:       3px;
    }

    html[data-bs-theme="dark"]:root {
        --fx-color-border-subtle:   var(--fx-color-border-strong);
        --fx-color-border:          var(--fx-color-border-strong);
        --fx-color-border-emphasis: var(--fx-color-border-strong);
        --fx-color-divider-strong:  var(--fx-color-border-strong);
        --fx-color-divider:         var(--fx-color-border-strong);
        --fx-color-divider-soft:    var(--fx-color-border-strong);
        --fx-color-divider-faint:   var(--fx-color-border-strong);

        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        /* The same two exemptions, same reasons, same shape — the resting
         * secondary and tertiary literals from the dark 3.2 block. See the two
         * rulings in the header. */
        --fx-color-text-placeholder: #c8d6ca;
        --fx-color-disabled-fg:      #8b9a8f;

        /* The link and the brand text follow the mint ramp they took at rest in
         * 3.6 and 3.5.1, promoting two rungs lighter — mint-500 to mint-300 —
         * which lifts them from 8.99:1 worst case to 10.13:1. They used to
         * promote onto olive-300 at 9.34:1; the mint promotion is both stronger
         * and, unlike the olive one, does not change hue on a user who turned
         * contrast up. The RING stays on olive-300: it is a 2px line rather than
         * text, it must not become the same colour as the brand text it may
         * surround, and olive at 9.34:1 already far exceeds the 3:1 it is held
         * to. */
        --fx-color-link:        var(--fx-p-mint-300);
        --fx-color-focus-ring:  var(--fx-p-olive-300);
        /* The mark and the brand text still promote onto DIFFERENT ramps here,
         * the same split 3.5.1 makes at rest. The mark stays green and
         * brightens to green-400 (6.22:1 worst case, against green-500's 4.75)
         * so the "you are here" mark does not change hue either. */
        --fx-color-indicator:   var(--fx-p-green-400);
        --fx-color-brand-text:  var(--fx-p-mint-300);
        /* The selected state boundary promotes with the rest. It is already past
         * its 3:1 floor at 3.60:1, but 11 promotes a SIGNAL and not only a
         * failure, the same reasoning that promotes the indicator and the brand
         * text, so a user who asked for more contrast gets a stronger state edge
         * rather than merely a compliant one. The 500 rung measures 4.75:1 on the
         * worst plane, and it does not collide with the focus ring here because
         * the ring has itself promoted onto the accent ramp in this query. */
        --fx-color-primary-border: var(--fx-p-green-500);
        --fx-border-width:      2px;
        --fx-border-width-mid:  2px;
        --fx-focus-width:       3px;
    }
}


/* ── 12) LEGACY ALIASES ────────────────────────────────────────────────────
 *
 * Existing pages, module stylesheets and JavaScript still read the old names.
 * Every one of them is mapped onto a new token here so nothing regresses while
 * call sites are migrated. NEW CODE MUST NOT USE ANY NAME IN THIS SECTION.
 *
 * These are declared once, on the token layer, and follow the dark theme
 * automatically: custom property substitution resolves at the point of use, so
 * an alias pointing at fx-color-primary picks up whichever value won the
 * cascade on the html element in the current theme.
 *
 * SPECIFICITY, for the record. The legacy wwwroot/css/frihat-tabulator.css
 * declares fx-bg, fx-text and friends on a bare :root (0,1,0). This block is
 * html:root (0,1,1) and therefore wins, in both themes, regardless of bundle
 * order — which is the whole reason the token layer is qualified that way.
 * That particular file is being retired during wiring, so the collision is
 * academic; the qualification stays because the NEXT vendored stylesheet to
 * drop a :root block into the bundle will not announce itself. The light values
 * below are byte identical to the legacy ones in any case, so nothing moves
 * visually whichever sheet had won.
 * ────────────────────────────────────────────────────────────────────────── */
html:root {
    /* 12.1 Raw brand ramp — mode independent in the legacy sheet, so these map
     * onto primitives rather than semantics to preserve the exact hue. */
    --frihat-green-900: var(--fx-p-green-900);
    --frihat-green-800: var(--fx-p-green-800);
    --frihat-green-700: var(--fx-p-green-700);
    --frihat-olive:     var(--fx-p-olive-600);
    --frihat-olive-2:   var(--fx-p-olive-500);
    --frihat-success:   var(--fx-p-success);
    --frihat-on-primary: var(--fx-p-on-primary);

    /* 12.2 Legacy semantic names */
    --frihat-primary:        var(--fx-color-primary);
    --frihat-primary-strong: var(--fx-color-primary-hover);
    --frihat-primary-darker: var(--fx-color-primary-hover);
    --frihat-primary-rgb:    var(--fx-color-primary-rgb);
    --frihat-accent:         var(--fx-color-accent);
    --frihat-link:           var(--fx-color-link);
    --frihat-link-hover:     var(--fx-color-link-hover);
    --frihat-bg:             var(--fx-color-bg);
    --frihat-surface:        var(--fx-color-surface);
    --frihat-elevated:       var(--fx-color-surface-raised);
    --frihat-text:           var(--fx-color-text);
    --frihat-text-dim:       var(--fx-color-text-muted);
    --frihat-border:         var(--fx-color-border);
    --frihat-hover:          var(--fx-color-hover);
    --frihat-glass:          var(--fx-glass-bg);

    /* 12.3 Tabulator era names.
     * fx-accent maps to the PRIMARY green rather than to the olive accent: in
     * the legacy sheet fx-accent was the green-800 fill behind fx-accent-ct
     * white text, and remapping it to olive would drop that pairing from 7.4:1
     * to 3.8:1. The olive accent is reached through fx-color-accent. */
    --fx-bg:        var(--fx-color-surface);
    --fx-bg-2:      var(--fx-color-surface-sunken);
    --fx-elev:      var(--fx-color-surface-raised);
    --fx-text:      var(--fx-color-text);
    --fx-text-dim:  var(--fx-color-text-muted);
    --fx-border:    var(--fx-color-border);
    --fx-hover:     var(--fx-color-hover);
    --fx-accent:    var(--fx-color-primary);
    --fx-accent-ct: var(--fx-color-text-on-primary);
    --fx-radius:    var(--fx-radius-lg);
    --fx-shadow:    var(--fx-shadow-float-md);
}


/* ── 13) PALETTE FAMILIES — THE PLATFORM SHIPS SIXTEEN THEMES ──────────────
 *
 * ADDED 2026-09-04 (sixth pass, see the header). Sections 1 to 3 build ONE
 * colour family, الزيتي, in two modes. This section adds three more — الأزرق
 * البترولي, النبيذي and الرملي الدافئ — so the platform ships FOUR FAMILIES x
 * TWO MODES = EIGHT THEMES. Nothing above this line moved. Not one olive value,
 * not one name, not one ruling.
 *
 * EXTENDED 2026-09-04 (seventh pass, same day). النيلي and الكحلي were added as
 * 13.5 and 13.6, taking the count to SIX FAMILIES and TWELVE THEMES. Every rule
 * in this preamble governs them unchanged and each of the two was derived by it
 * rather than beside it. The paragraph above is kept as written because it
 * records what the sixth pass did; the count in the heading is the current one.
 * NOT ONE OLIVE, PETROL, PLUM OR SAND VALUE MOVED in the seventh pass either.
 *
 * EXTENDED AGAIN 2026-09-05 (eighth pass). الفحمي and البنفسجي were added as 13.7
 * and 13.8, taking the count to EIGHT FAMILIES and SIXTEEN THEMES. Every rule in
 * this preamble governs them unchanged, with ONE refinement recorded in the eighth
 * pass header and restated in 13.7: the chroma relaxation toward rung 50 is a CAP
 * and not a target, which changes nothing for any scale above 1.0 and is what keeps
 * a grey family grey at its pale end. NOT ONE VALUE OF ANY EARLIER FAMILY MOVED.
 *
 * WHERE TO FIND THINGS, SINCE THE NUMBERS ARE NO LONGER IN FILE ORDER. 13.4
 * restates section 11 for every non default family and MUST remain the last thing
 * in this file, so the two families added on the seventh pass carry the next free
 * numbers and are placed ABOVE it. File order is 13.1, 13.2, 13.3, 13.5, 13.6,
 * 13.7, 13.8, 13.4. Read the ordinal as an identifier and not as a position.
 *
 * ══ THE SELECTOR SCHEME, AND WHY IT IS ORTHOGONAL ══════════════════════════
 *
 * A second attribute on the html element, data-fx-palette, carrying one of the
 * eight closed slugs olive | petrol | plum | sand | indigo | navy | graphite |
 * violet. It is INDEPENDENT of
 * data-bs-theme, which keeps meaning light or dark and nothing else, so the two
 * axes multiply instead of colliding and a user can change either one without
 * touching the other.
 *
 *   html:root                                                 olive light
 *   html[data-bs-theme="dark"]:root                           olive dark
 *   html[data-fx-palette="petrol"]:root                       petrol light
 *   html[data-fx-palette="petrol"][data-bs-theme="dark"]:root petrol dark
 *   ... and the same pair for plum, sand, indigo, navy, graphite and violet
 *
 * ABSENCE OF THE ATTRIBUTE IS OLIVE. There is deliberately no
 * html[data-fx-palette="olive"] block: olive is what the file already is, and
 * giving the default family a selector of its own would mean two ways to say
 * the same thing and a chance for them to drift. frihat-theme.js validates
 * against the closed set before it writes the attribute, so a junk value
 * selects no palette block and the page falls back to olive rather than to
 * nothing.
 *
 * ══ THE SPECIFICITY MATH, WHICH IS LOAD BEARING ════════════════════════════
 *
 *   html:root                                                  0,1,1
 *   html[data-bs-theme="dark"]:root                            0,2,1
 *   html[data-fx-palette="X"]:root                             0,2,1
 *   html[data-fx-palette="X"][data-bs-theme="dark"]:root       0,3,1
 *
 * A palette LIGHT block beats the token layer at 0,1,1 outright. A palette DARK
 * block beats everything, at 0,3,1. There is NO !important anywhere in this
 * section, and if one is ever needed the scheme is wrong and this comment is
 * the place to start.
 *
 * THE ONE TIE, AND THE RULE IT FORCES. A palette LIGHT block and the olive DARK
 * block are BOTH 0,2,1. A tie is broken by source order, and every block in
 * this section is declared after both existing semantic blocks, so on a page
 * that is petrol AND dark the petrol light block would beat olive's dark block
 * for any token they share. That is why:
 *
 *     EVERY TOKEN A PALETTE LIGHT BLOCK DECLARES IS RESTATED IN THAT PALETTE'S
 *     DARK BLOCK. A token that appears above and is missing below is a defect,
 *     not an economy — it leaks a LIGHT value into a DARK theme.
 *
 * It is the reason the dark blocks below restate values that are byte identical
 * to olive's (the black shadow ink, the white scrollbar thumb). They are not
 * duplication for its own sake; they are the price of the scheme.
 *
 * The converse is safe and is used throughout: a token that NO dark block
 * declares needs no restatement, because a palette light block at 0,2,1 already
 * outranks the 0,1,1 base declaration in both modes. Every primitive ramp below
 * is in that category, which is why the ramps are declared once, in the light
 * block, and are not repeated.
 *
 * SECTION 11 IS RESTATED PER FAMILY FOR THE SAME REASON, at the end of this
 * section. The prefers-contrast query does not add specificity, so its html:root
 * at 0,1,1 would lose to a palette base block at 0,2,1 and every promotion would
 * silently stop applying under the three new families. A family without its
 * promotions is an accessibility regression, not a cosmetic gap.
 *
 * ══ THE METHOD — LUMINANCE PRESERVING HUE TRANSPOSITION ════════════════════
 *
 * A HUE ROTATION IS NOT A THEME, and this section is not one. Every value below
 * was derived, measured and re-measured. The single rule that makes eight themes
 * behave as one system:
 *
 *     EVERY DERIVED VALUE CARRIES THE EXACT RELATIVE LUMINANCE OF THE OLIVE
 *     VALUE IT REPLACES. Only the hue and, where a family asks for it, the
 *     chroma move.
 *
 * WHY THAT RULE AND NOT ANOTHER. WCAG contrast is a function of relative
 * luminance ALONE. Hold luminance rung for rung and every ratio this file has
 * ever measured — the four text tiers, the four surface levels, the washes, the
 * band, the rail, the ring, the status pairs — transfers to the new family
 * unchanged. Measured across all eight themes and 932 pairs, the largest
 * divergence from olive is 0.25 of a ratio point, and that one is a rail ink
 * measurement of 17.07:1 against 16.82:1 — a number already three times past
 * AAA. The elevation ladder's 1.04 to 1.06 steps are preserved to the third
 * decimal, and no adjacent pair anywhere measures 1.000.
 *
 * The derivation is done in OKLab, which is perceptually uniform, so "the same
 * chroma at a different hue" means what it says instead of meaning "much more
 * saturated in green and much less in blue". Where a hue cannot hold the source
 * chroma inside sRGB the chroma is reduced until it fits and the LUMINANCE IS
 * HELD — the ratio is the guarantee, the exact chroma is not.
 *
 * ══ WHAT EACH FAMILY RE-DERIVES, AND WHY EACH ONE IS ON THE LIST ═══════════
 *
 *   THE BRAND RAMP        eleven rungs on the green spine's own luminances.
 *   THE ACCENT RAMP       eight rungs on the olive ramp's luminances, at a
 *                         companion hue. 3.9 still governs where it is spent.
 *   THE WASH RAMP         five rungs at the mint ramp's five luminances. The
 *                         MINT RAMP ITSELF IS CLIENT SUPPLIED AND FROZEN FOR
 *                         OLIVE ONLY (1.2.1) — it is not extended, not tinted,
 *                         not reused, and there is still no sixth mint rung.
 *   THE NEUTRAL RAMP      the most important line in this section. 1.3 tints
 *                         the greys green so they never read cold beside the
 *                         olive; a green tinted grey under a plum page is
 *                         exactly what makes a theme look rotated rather than
 *                         designed, and greys are most of the pixels. Each
 *                         family restates all thirteen rungs at its own hue,
 *                         at the same chroma and the same luminance.
 *   THE DARK CHROME       1.4's four surfaces are hue tinted on purpose, so
 *                         they are re-derived rather than inherited.
 *   THE SHELL, BAND, RAIL the surface clause in 3.9 requires every ink, wash,
 *                         line and mark on a brand surface to be re-derived
 *                         AGAINST THAT SURFACE. Each family's block records the
 *                         four ink tiers, the gold mark and the three washes
 *                         measured over its own fill, in both modes.
 *   THE SHADOW INK        a near black at the family's hue, so a card on a plum
 *                         page does not drop a green shadow. Geometry and alpha
 *                         are untouched.
 *   THE STATUS TINTS      the two TINT BACKGROUNDS only. The status hues do not
 *                         move; see the ruling in each family's 13.x.6.
 *   SECTION 12.1          the legacy raw brand aliases, so a legacy sheet does
 *                         not paint olive green on a petrol page.
 *
 * ══ THE SEED NAMES THE FAMILY'S IDENTITY, NOT ITS INK ══════════════════════
 *
 * STATED EXPLICITLY 2026-09-04, when the owner replaced two seeds and one of the
 * replacements was far lighter than anything the system had seen. A seed does
 * exactly two things: it fixes the family's HUE, and it fixes a CHROMA SCALE by
 * the rung it lands on. It does not decide how dark the family's ink is.
 *
 * A ramp runs 50 to 950 whatever rung the seed occupies, and every rung is a
 * LUMINANCE POSITION on the green spine. So rung 800 carries the same luminance
 * in a family whose seed sat at 300 as in one whose seed sat at 800, and the
 * tokens that must be legible — brand text, the link, the indicator, the focus
 * ring, the band ink — measure what they measure in every other family. A light
 * seed CANNOT push a semantic under AA. It can only make the family less
 * saturated, which is a look and not a failure.
 *
 * THE COROLLARY, WHICH IS THE PART THAT GETS BROKEN: if a semantic ever does
 * fail on a new family, DEEPEN THE RUNG THE SEMANTIC POINTS AT AND SAY SO. Never
 * darken the seed to fix it. Darkening the seed changes the colour the owner
 * chose, in every surface at once, to solve a problem that lives in one token.
 * الرملي الدافئ is the worked example: its seed is a pale tan at rung 300, it was
 * left there, no token needed deepening, and the whole table was re-measured to
 * prove it rather than to assume it.
 *
 * ══ WHAT DOES NOT MOVE, IN ANY FAMILY ══════════════════════════════════════
 *
 *   · SECTION 3.9 IN FULL. Identity and current position are brand, interaction
 *     is a tint, and the FORBIDDEN half is untouched. A new family is a new HUE,
 *     never a new licence: it does not sanction a themed Bootstrap panel, a
 *     brand filled card, a coloured form background or a fourteenth surface.
 *     The surface count is still two and both are dated client decisions.
 *   · THE STATUS HUES. emerald, amber, red and blue mean STATUS. Their 200 /
 *     300 / 600 / 800 grades are identical in all four families.
 *   · The elevation model, the four text tiers, the two line families, the
 *     scrim / veil split, the motion, space, radius, typography and z ladders.
 *   · Every token NAME. Nothing was renamed and nothing was deleted.
 *
 * ══ ADDING A SEVENTH FAMILY ════════════════════════════════════════════════
 *
 * Written when there were four, followed to the letter when the fifth and sixth
 * were added on the seventh pass, and unchanged by that experience except for the
 * three notes at the end. If a family arrives with MORE than one supplied value,
 * read 13.5's role clause first: a supplied ink is almost never the ink on the
 * solid fill, and assigning it there produces a family that looks right in a
 * swatch and fails on every button.
 *
 * Take the seed to OKLab. Place it on the green spine's ladder at the rung whose
 * OKLab LIGHTNESS is nearest — L, not relative luminance, because L is the
 * perceptual coordinate and relative luminance is not. Transpose the accent,
 * wash, neutral, dark
 * chrome, surface, ink, divider, shadow and status tint values at that hue,
 * holding every luminance. Restate section 12.1 and section 11. Then measure
 * the whole table again — do not assume it transferred, prove it. And add the
 * slug to the closed set in frihat-theme.js and to the picker, or the block is
 * dead code.
 *
 * THREE THINGS THE SEVENTH PASS LEARNED, WORTH THE LINES:
 *   · THE 0.35 STATUS CAST FRACTION IS NOT A CONSTANT. It is defined as the
 *     largest fraction at which every tint stays within 30 degrees of the olive
 *     tint it replaces, and that answer depends on the hue. Re-solve it per
 *     family instead of copying 0.35; النيلي needed 0.30. It costs no contrast,
 *     because luminance is preserved at any fraction.
 *   · MEASURE THE NEW CHIP AGAINST EVERY EXISTING CHIP, not just against the
 *     ground. A family is chosen from a picker and nowhere else, so two families
 *     a user cannot tell apart are two families he cannot choose between. Report
 *     OKLab delta E, hue gap AND lightness ratio for all pairs; lightness is what
 *     rescues a near hue pair and hue alone will mislead you.
 *   · CHECK THE NEW BRAND HUE AGAINST THE FOUR STATUS HUES BEFORE DERIVING
 *     ANYTHING. الكحلي landed 0.2 of a degree from the info blue. That is not a
 *     reason to reject a colour the owner chose, but it IS a reason to say so with
 *     numbers, to force the accent offset wider, and to record that on that family
 *     the icon and the label carry the status meaning rather than the hue.
 * ────────────────────────────────────────────────────────────────────────── */

/* ── 13.1) PETROL BLUE — الأزرق البترولي ──
 *
 * SEED #0F766E, chosen by the owner 2026-09-04. Measured: OKLCH L 0.5109
 * C 0.0861 H 186.4, relative luminance 0.14184.
 *
 * WHERE THE SEED LANDS ON THE FROZEN LADDER. Placed by OKLab LIGHTNESS, the
 * perceptual coordinate: the seed sits at L 0.5109 and the green spine's 700 rung
 * at L 0.5216, a difference of 0.0106, and no other rung comes close. So it is the
 * 700 rung of this family and it arrives as #187a73.
 *
 * The RELATIVE luminance moves with it, from the seed's 0.14184 to the rung's
 * 0.15348, and that is the point rather than a cost: pinning every family to the
 * spine's luminance ladder is the whole reason every ratio measured for olive
 * transfers to this family unchanged. Relative luminance is a nonlinear
 * coordinate, so quote the L figure above, not this one, when judging how far
 * the seed actually moved.
 *
 * AND THE SEED NAMES THE FAMILY IDENTITY, NOT ITS INK. A ramp runs 50 to 950
 * whatever rung the seed occupies, so the deep rungs that carry brand text, the
 * link, the indicator and the focus ring are derived from the spine exactly as
 * they are in every other family, and are UNAFFECTED by where the seed sat.
 * This family shows its identity on the band, the rail and the washes; its ink
 * comes from the deep end of its own ramp. Verified rather than assumed: every
 * ink pairing in 13.1.7 and 13.1.8 below is measured against its own plane.
 *
 * CHROMA. s = 0.690, the seed's chroma over the green spine's chroma at that
 * rung. Held flat at and below the seed rung and relaxed linearly to 1.0 at
 * rung 50, so the pale end of the ramp cannot go neon and the deep end keeps
 * the seed's own saturation. Rung 50 lands at s 1.000.
 *
 * ACCENT HUE 213.4, +27 degrees of OKLCH hue from the brand, which reads as
 * a cerulean. The sign and the size are chosen per family so the decorative
 * hue does not collide with a status hue: measured against the four status
 * families it is nearest the info blue at 41 degrees and the success emerald at 64.
 * ─────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="petrol"]:root {
    /* 13.1.1 THE PETROL RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. */
    --fx-p-petrol-50:  #edf8f7;
    --fx-p-petrol-100: #dcf2ef;
    --fx-p-petrol-200: #b8e6e0;
    --fx-p-petrol-300: #85d2ca;
    --fx-p-petrol-400: #4cbbb2;
    --fx-p-petrol-500: #06a69a;
    --fx-p-petrol-600: #098e86;
    --fx-p-petrol-700: #187a73;   /* the owner's seed, on the ladder */
    --fx-p-petrol-800: #135851;
    --fx-p-petrol-900: #113b38;
    --fx-p-petrol-950: #0a2b27;

    /* 13.1.2 THE ACCENT RAMP — a cerulean. The decorative companion, holding the
     * olive ramp's luminance at every rung so 2.5 and 3.5 keep their figures.
     * It is NOT a second brand: 3.9 governs where it may be spent and that
     * contract is unchanged for every family. */
    --fx-p-petrol-accent-100: #daf3f9;
    --fx-p-petrol-accent-200: #c1eaf5;
    --fx-p-petrol-accent-300: #95dbeb;
    --fx-p-petrol-accent-400: #61cbe1;
    --fx-p-petrol-accent-500: #44a3b6;
    --fx-p-petrol-accent-600: #228fa2;
    --fx-p-petrol-accent-700: #1c7b8b;
    --fx-p-petrol-accent-800: #165f6b;

    /* 13.1.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It
     * is not extended, not tinted and not reused here, and there is still no
     * sixth mint rung. This is a SEPARATE ramp that reproduces mint's five
     * relative luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at
     * this family's own hue, so the light opaque washes and the dark low alpha
     * washes land at the identical lift the fourth pass measured (1.134 and
     * 1.254 in dark) and every text tier over a wash keeps its ratio.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.026   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.126  on level 1 1.179  on level 2 1.231 */
    --fx-p-petrol-wash-100: #c3f7f1;
    --fx-p-petrol-wash-200: #a6ece2;
    --fx-p-petrol-wash-300: #90e8dd;
    --fx-p-petrol-wash-400: #7ae4d8;
    --fx-p-petrol-wash-500: #5ce0d5;

    /* 13.1.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES
     * WHETHER THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside
     * the olive. A green tinted grey under a petrol page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels
     * on a legal screen. So the ramp is restated at THIS family's hue, at the
     * SAME OKLCH chroma rung for rung (0.0045 at n 25 up to 0.0330 at n 950)
     * and at the SAME relative luminance rung for rung, which is what keeps the
     * elevation ladder's 1.04 to 1.06 steps identical. n 0 is white in every
     * family and is not restated. Worst luminance drift on this ramp: 0.65 percent.
     */
    --fx-p-n-25:   #fafdfd;
    --fx-p-n-50:   #eff8f6;
    --fx-p-n-100:  #e3f0ed;
    --fx-p-n-200:  #d0e3e1;
    --fx-p-n-300:  #b6ceca;
    --fx-p-n-400:  #92aeaa;
    --fx-p-n-500:  #728e89;
    --fx-p-n-600:  #556c68;
    --fx-p-n-700:  #43524f;
    --fx-p-n-800:  #2d3a38;
    --fx-p-n-900:  #162b2a;
    --fx-p-n-950:  #0f2827;
    --fx-p-n-1000: #0d211f;

    /* 13.1.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they
     * are deliberately hue tinted rather than points on the neutral ramp, so
     * they are re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated: #06312c;
    --fx-p-dark-sunken:   #0e2221;
    --fx-p-dark-well:     #091a19;
    --fx-p-dark-ink:      #091c1b;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white
     * for the same reason; this is the same value at this family's hue.
     * Measured on the brand fill: 7.37:1, against olive's 7.38:1. */
    --fx-p-on-primary: #e6f5f4;

    /* 13.1.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with
     * the palette would stop being a danger red, so the 200 / 300 / 600 / 800
     * grades in 1.6 are untouched in every family and are NOT restated here.
     * What is restated is the two TINT BACKGROUNDS, because a tint sits on this
     * family's neutral and has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and
     * takes the family's neutral cast added at 0.35 of the neutral's own hue
     * shift. The fraction is a ruling, not a taste: at 1.0 the emerald dark tint
     * on the plum neutral loses its hue entirely and measures as a neutral grey,
     * which would make a success panel and an info panel indistinguishable. 0.35
     * is the largest fraction at which all eight tints in all three families stay
     * within 30 degrees of their own status hue. Luminance is preserved exactly,
     * so every status foreground keeps its measured ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.68:1
     *   amber    fg on tint  light 5.18:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.88:1
     */
    --fx-p-emerald-100: #e6f4ef;
    --fx-p-emerald-900: #103022;
    --fx-p-amber-100: #fcf1e3;
    --fx-p-amber-900: #302711;
    --fx-p-red-100: #fbecee;
    --fx-p-red-900: #321a19;
    --fx-p-blue-100: #e7f1fe;
    --fx-p-blue-900: #10263c;

    /* ══ 13.1.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue moved.
     * MEASURED, the ladder: 0 to 1 1.047, 1 to 2 1.045, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.29 / 10.42 / 5.23 / 3.48.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0: #e7f2f1;            /* page   */
    --fx-color-level-1: #edf7f5;            /* card   */
    --fx-color-level-2: #f2fcfa;            /* raised */
    --fx-color-bg-subtle:      #e2edec;
    --fx-color-surface-sunken: #e2edec;

    --fx-color-text:        #102322;
    --fx-color-text-muted:  #2a3a39;
    --fx-color-text-subtle: #556765;
    --fx-color-text-faint:  #718382;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate
     * and that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:   rgba(2, 42, 40, 0.05);
    --fx-color-border:          rgba(2, 42, 40, 0.08);
    --fx-color-border-emphasis: rgba(2, 42, 40, 0.14);
    --fx-color-divider-strong:  #ccddda;
    --fx-color-divider:         #dbeae9;
    --fx-color-divider-faint:   #e8f4f2;
    --fx-color-field-bg-hover:  #f9fdfe;

    /* 2.4. Brand fill #135851, ink on it 7.37:1, white on it 8.26:1,
     * fill against the page 7.23:1. */
    --fx-color-primary:        var(--fx-p-petrol-800);
    --fx-color-primary-hover:  var(--fx-p-petrol-900);
    --fx-color-primary-active: var(--fx-p-petrol-950);
    --fx-color-primary-subtle: rgba(19, 88, 81, 0.10);
    --fx-color-primary-rgb:    19, 88, 81;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.26:1
     *   white 85 percent .......... 6.49:1
     *   white 72 percent .......... 5.14:1   idle rail rows and group headings
     *   white 54 percent .......... 3.62:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.52:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.223 / 1.425 / 1.583
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:  var(--fx-p-petrol-800);
    --fx-color-shell: var(--fx-p-petrol-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:        var(--fx-p-petrol-accent-600);
    --fx-color-accent-hover:  var(--fx-p-petrol-accent-700);
    --fx-color-accent-subtle: rgba(34, 143, 162, 0.14);
    --fx-color-accent-rgb:    34, 143, 162;

    /* 2.5.1 and 2.6. Mark 7.23:1 worst case over levels 0 to 3, brand text and
     * link the same, against a 4.5 bar. */
    --fx-color-indicator:  var(--fx-p-petrol-800);
    --fx-color-brand-text: var(--fx-p-petrol-800);
    --fx-color-link:       var(--fx-p-petrol-800);
    --fx-color-link-hover: var(--fx-p-petrol-900);
    --fx-color-link-rgb:   19, 88, 81;
    --fx-color-text-rgb:   16, 35, 34;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash
     * at alpha renders as a different hex on each of the four planes. Active is
     * mixed from the two rungs either side of it rather than being a sixth rung.
     * The four tiers over hover 13.92 / 10.15 / 5.09 / 3.39 and over active
     * 12.69 / 9.25 / 4.64 / 3.09. The ring over the two washes: 7.04 and 6.42. */
    --fx-color-focus-ring:   var(--fx-p-petrol-800);
    --fx-color-selection-bg: var(--fx-p-petrol-wash-300);
    --fx-color-hover:        var(--fx-p-petrol-wash-100);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-petrol-wash-200) 70%, var(--fx-p-petrol-wash-100));
    --fx-color-disabled-bg:  #e4efec;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a petrol page. Geometry, blur and alpha
     * are untouched — only the three channels moved. */
    --fx-shadow-xs:  0 1px 2px rgba(2, 42, 40, 0.05);
    --fx-shadow-sm:  0 1px 4px -1px rgba(2, 42, 40, 0.09);
    --fx-shadow-md:  0 3px 12px rgba(2, 42, 40, 0.09);
    --fx-shadow-lg:  0 7px 24px rgba(2, 42, 40, 0.06);
    --fx-shadow-xl:  0 10px 32px rgba(2, 42, 40, 0.07);
    --fx-shadow-2xl: 0 16px 48px rgba(2, 42, 40, 0.08);
    --fx-shadow-float-sm: 0 1px 4px -1px rgba(2, 42, 40, 0.09);
    --fx-shadow-float-md: 0 3px 12px rgba(2, 42, 40, 0.09);
    --fx-shadow-float-lg: 0 7px 24px rgba(2, 42, 40, 0.06);
    --fx-shadow-stack:
        inset 0 -1px 1px 0 rgba(2, 42, 40, 0.10),
        0 5px 2px 0 rgba(2, 42, 40, 0.01),
        0 3px 2px 0 rgba(2, 42, 40, 0.04),
        0 1px 1px 0 rgba(2, 42, 40, 0.07),
        0 0 1px 0 rgba(2, 42, 40, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load
     * bearing; read the rule over the olive declaration before touching it. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(2, 42, 40, 0.60),
        inset 0 5px 12px rgba(2, 42, 40, 0.10),
        inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset: inset 0 1px 2px rgba(2, 42, 40, 0.08);
    --fx-shadow-press: inset 0 1px 3px rgba(2, 42, 40, 0.10);
    --fx-color-focus-glow:      var(--fx-p-petrol-wash-200);
    --fx-color-focus-glow-soft: var(--fx-p-petrol-wash-500);
    --fx-glass-bg: rgba(242, 252, 250, 0.72);
    --fx-scrollbar-thumb:        rgba(2, 42, 40, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(2, 42, 40, 0.20);
    --fx-scrollbar-thumb-active: rgba(2, 42, 40, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would
     * paint the olive green on a petrol page. Nothing is renamed. */
    --frihat-green-900: var(--fx-p-petrol-900);
    --frihat-green-800: var(--fx-p-petrol-800);
    --frihat-green-700: var(--fx-p-petrol-700);
    --frihat-olive:     var(--fx-p-petrol-accent-600);
    --frihat-olive-2:   var(--fx-p-petrol-accent-500);
}

/* 13.1.8 PETROL BLUE — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS
 * STRUCTURAL RATHER THAN TIDY. The light palette block is specificity 0,2,1 and
 * sits LATER in the file than the olive dark block, which is also 0,2,1, so on a
 * tie it wins. Every token the light block declares must therefore be restated
 * here at 0,3,1, or it would leak its LIGHT value into this theme. A token that
 * appears above and is missing below is a defect, not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.049, 1 to 2 1.050, 2 to 3 1.053, 0 to 3 1.160.
 * The four text tiers on the page: 14.26 / 11.10 / 5.67 / 3.71, and on level 3
 * 12.29 / 9.57 / 4.89 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="petrol"][data-bs-theme="dark"]:root {
    --fx-color-level-0: var(--fx-p-n-1000);
    --fx-color-level-1: #122524;
    --fx-color-level-2: #162928;
    --fx-color-level-3: #1a2d2c;
    --fx-color-bg-subtle:      var(--fx-p-dark-well);
    --fx-color-surface-sunken: var(--fx-p-dark-well);

    --fx-color-text:        #e1f0ed;
    --fx-color-text-muted:  #c1d7d3;
    --fx-color-text-subtle: #879a99;
    --fx-color-text-faint:  #687a79;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and
     * that ink is this family's own primary text colour. */
    --fx-color-border-subtle:   rgba(225, 240, 237, 0.05);
    --fx-color-border:          rgba(225, 240, 237, 0.08);
    --fx-color-border-emphasis: rgba(225, 240, 237, 0.14);
    --fx-color-divider-strong:  #313d3b;
    --fx-color-divider:         #222e2c;
    --fx-color-divider-soft:    #1b2726;
    --fx-color-divider-faint:   #162726;
    --fx-color-field-bg-hover:  var(--fx-color-level-3);
    --fx-color-field-bg-focus:  #1b322e;

    /* 3.4. One ramp step brighter than light so the fill stays visible against
     * the page: white on it 5.16:1, fill against the page 3.24:1. */
    --fx-color-primary:        var(--fx-p-petrol-700);
    --fx-color-primary-hover:  var(--fx-p-petrol-800);
    --fx-color-primary-active: var(--fx-p-petrol-900);
    --fx-color-primary-subtle: rgba(24, 122, 115, 0.20);
    --fx-color-primary-rgb:    24, 122, 115;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the
     * planes a dropdown or a popup floats on, and it cannot move without
     * breaking its own ink, so it carries a rim instead. This family 600 rung
     * measures 4.18 / 3.98 / 3.79 / 3.60:1 on levels 0 to 3, the same figures
     * as every other family, because a rung is a luminance position. */
    --fx-color-primary-border: var(--fx-p-petrol-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand
     * surface and must read as one colour in both themes, so it stays on 800 and
     * accepts the same 2.03:1 against the dark page that the dated decision in
     * 3.4.1 accepted for olive. Ink on it 7.37:1, gold mark on it 4.52:1. */
    --fx-color-band: var(--fx-p-petrol-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5
     * does for olive: without this line the light block's brand fill would fall
     * through and dark would gain a mid petrol shell nobody asked for. */
    --fx-color-shell: var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.055:1   one rung, as in olive
     *   white on the rail .................. 16.96:1
     *   white 72 / 55 / 38 percent ......... 9.27 / 5.93 / 3.52
     *   gold mark on the rail .............. 9.29:1
     *   washes, white at 8 / 14 / 18 percent 1.254 / 1.521 / 1.752 */
    --fx-color-rail: color-mix(in srgb, var(--fx-p-petrol-900) 55%, var(--fx-p-black));

    --fx-color-accent:        var(--fx-p-petrol-accent-500);
    --fx-color-accent-hover:  var(--fx-p-petrol-accent-400);
    --fx-color-accent-subtle: rgba(68, 163, 182, 0.18);
    --fx-color-accent-rgb:    68, 163, 182;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.76:1 worst case
     * over levels 0 to 3 against a 3.0 bar. Brand TEXT cannot be the brand ramp
     * in dark — rung 700 measures 3.24:1 on the page and fails 4.5 — so it takes
     * the wash ramp's deepest rung, 8.98:1 worst case. Exactly the constraint the
     * mint ramp solved for olive, solved the same way with this family's own
     * wash ramp rather than by borrowing mint. */
    --fx-color-indicator:  var(--fx-p-petrol-500);
    --fx-color-brand-text: var(--fx-p-petrol-wash-500);
    --fx-color-link:       var(--fx-p-petrol-wash-500);
    --fx-color-link-hover: var(--fx-p-petrol-wash-400);
    --fx-color-link-rgb:   92, 224, 213;
    --fx-color-text-rgb:   225, 240, 237;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would
     * invert the elevation model. Measured, wash against its own host plane:
     *   hover  1.132 / 1.138 / 1.144 / 1.150 on levels 0 to 3
     *   active 1.250 / 1.262 / 1.257 / 1.266
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.88 / 4.63 / 4.38 / 4.14
     *   over active 4.42 / 4.17 / 3.99 / 3.76 */
    --fx-color-focus-ring:   var(--fx-p-petrol-500);
    --fx-color-selection-bg: color-mix(in srgb, var(--fx-p-petrol-wash-500) 22%, transparent);
    --fx-color-hover:        color-mix(in srgb, var(--fx-p-petrol-wash-500)  6%, transparent);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-petrol-wash-500) 10%, transparent);
    --fx-color-disabled-bg:  #172524;

    /* Section 6, dark. The shadow ink is pure black in this theme for every
     * family — a hue tinted shadow on a near black page buys nothing — so these
     * are the olive values restated verbatim. They are restated rather than
     * inherited because the light block above declares the same names and would
     * otherwise win the 0,2,1 tie. */
    --fx-shadow-xs:  none;
    --fx-shadow-sm:  0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:  0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:  0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:  0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl: 0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm: 0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md: 0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg: 0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:
        0 5px 2px 0 rgba(0, 0, 0, 0.02),
        0 3px 2px 0 rgba(0, 0, 0, 0.08),
        0 1px 1px 0 rgba(0, 0, 0, 0.14),
        0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the 3.626:1 the olive
     * geometry was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(225, 240, 237, 0.50),
        inset 0 6px 14px rgba(0, 0, 0, 0.45),
        inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press: inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:      color-mix(in srgb, var(--fx-p-petrol-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft: var(--fx-p-petrol-wash-500);
    --fx-glass-bg: rgba(18, 37, 36, 0.72);
    --fx-scrollbar-thumb:        rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active: rgba(255, 255, 255, 0.40);
}

/* ── 13.2) PLUM — النبيذي ──
 *
 * SEED #B03052, chosen by the owner 2026-09-04. Measured: OKLCH L 0.5137
 * C 0.1646 H 9.6, relative luminance 0.11953.
 *
 * WHERE THE SEED LANDS ON THE FROZEN LADDER. Placed by OKLab LIGHTNESS, the
 * perceptual coordinate: the seed sits at L 0.5137 and the green spine's 700 rung
 * at L 0.5216, a difference of 0.0078, and no other rung comes close. So it is the
 * 700 rung of this family and it arrives as #bf3e5f.
 *
 * The RELATIVE luminance moves with it, from the seed's 0.11953 to the rung's
 * 0.15348, and that is the point rather than a cost: pinning every family to the
 * spine's luminance ladder is the whole reason every ratio measured for olive
 * transfers to this family unchanged. Relative luminance is a nonlinear
 * coordinate, so quote the L figure above, not this one, when judging how far
 * the seed actually moved.
 *
 * AND THE SEED NAMES THE FAMILY IDENTITY, NOT ITS INK. A ramp runs 50 to 950
 * whatever rung the seed occupies, so the deep rungs that carry brand text, the
 * link, the indicator and the focus ring are derived from the spine exactly as
 * they are in every other family, and are UNAFFECTED by where the seed sat.
 * This family shows its identity on the band, the rail and the washes; its ink
 * comes from the deep end of its own ramp. Verified rather than assumed: every
 * ink pairing in 13.2.7 and 13.2.8 below is measured against its own plane.
 *
 * CHROMA. s = 1.320, the seed's chroma over the green spine's chroma at that
 * rung. Held flat at and below the seed rung and relaxed linearly to 1.0 at
 * rung 50, so the pale end of the ramp cannot go neon and the deep end keeps
 * the seed's own saturation. Rung 50 lands at s 1.000.
 *
 * ACCENT HUE 342.6, -27 degrees of OKLCH hue from the brand, which reads as
 * a rose. The sign and the size are chosen per family so the decorative
 * hue does not collide with a status hue: measured against the four status
 * families it is nearest the danger red at 47 degrees and the warning amber at 67.
 *
 * THE ACCENT SIGN IS FLIPPED FOR THIS FAMILY, AND THE RULE IS WHAT FLIPPED IT.
 * Every other family offsets its accent by a POSITIVE rotation. A positive 27
 * degrees from a brand at hue 9.6 lands on 36.6, which is 7.1 degrees from the
 * danger red at 29.5 and 12.7 from the warning amber. A decorative hue that close
 * to two status hues is unusable, so the offset is taken in the other direction to
 * 342.6, which is 46.9 clear of the red and 66.7 clear of the amber. The rule in
 * this file has always been that the sign is chosen per family to keep the accent
 * off the status hues; this is the first family in which it binds.
 *
 * KNOWN AND MEASURED: THE PLUM BRAND SITS 20 DEGREES FROM THE DANGER RED.
 * النبيذي is a wine, wine is red dominant, and p-red-600 is at OKLCH hue 29.5
 * against this brand at 9.6. That is now the closest a brand hue and a status hue
 * come anywhere in the system, and it is a consequence of the seed rather than of
 * this derivation: the status hues do not move, and rotating the brand would mean
 * not shipping the colour the owner chose. It is NOT a contrast defect; every red
 * pairing in this family measures within a hundredth of olive.
 *
 * WHAT ACTUALLY SEPARATES THEM IS LIGHTNESS, NOT HUE, AND THERE IS PLENTY OF IT.
 * The brand fill is rung 800 at relative luminance 0.0769 while p-red-600 sits at
 * 0.1097, so a danger foreground measures 1.36:1 against the brand fill and can
 * never be mistaken for it as a fill. Where the two could be confused is a danger
 * label rendered as bare coloured TEXT on a plum page, which 2.7 already rules
 * against: a status that is read takes its fg token and a status chip carries its
 * own tint background and border. Raised for the owner rather than corrected.
 * ─────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="plum"]:root {
    /* 13.2.1 THE PLUM RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. */
    --fx-p-plum-50:  #fff3f4;
    --fx-p-plum-100: #ffe8eb;
    --fx-p-plum-200: #fed2d9;
    --fx-p-plum-300: #ffafba;
    --fx-p-plum-400: #fd869d;
    --fx-p-plum-500: #f36384;
    --fx-p-plum-600: #da4c6f;
    --fx-p-plum-700: #bf3e5f;   /* the owner's seed, on the ladder */
    --fx-p-plum-800: #892e44;
    --fx-p-plum-900: #5e1f2e;
    --fx-p-plum-950: #45161f;

    /* 13.2.2 THE ACCENT RAMP — a rose. The decorative companion, holding the
     * olive ramp's luminance at every rung so 2.5 and 3.5 keep their figures.
     * It is NOT a second brand: 3.9 governs where it may be spent and that
     * contract is unchanged for every family. */
    --fx-p-plum-accent-100: #fee9f4;
    --fx-p-plum-accent-200: #fed9ed;
    --fx-p-plum-accent-300: #febde4;
    --fx-p-plum-accent-400: #fe9edb;
    --fx-p-plum-accent-500: #d27ab2;
    --fx-p-plum-accent-600: #c0639e;
    --fx-p-plum-accent-700: #a65488;
    --fx-p-plum-accent-800: #804168;

    /* 13.2.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It
     * is not extended, not tinted and not reused here, and there is still no
     * sixth mint rung. This is a SEPARATE ramp that reproduces mint's five
     * relative luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at
     * this family's own hue, so the light opaque washes and the dark low alpha
     * washes land at the identical lift the fourth pass measured (1.134 and
     * 1.254 in dark) and every text tier over a wash keeps its ratio.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.028   on level 1 1.075   on level 2 1.122
     *   active on level 0 1.124  on level 1 1.175  on level 2 1.226 */
    --fx-p-plum-wash-100: #ffe7eb;
    --fx-p-plum-wash-200: #ffd4db;
    --fx-p-plum-wash-300: #feccd1;
    --fx-p-plum-wash-400: #ffc3cb;
    --fx-p-plum-wash-500: #ffbac5;

    /* 13.2.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES
     * WHETHER THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside
     * the olive. A green tinted grey under a plum page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels
     * on a legal screen. So the ramp is restated at THIS family's hue, at the
     * SAME OKLCH chroma rung for rung (0.0045 at n 25 up to 0.0330 at n 950)
     * and at the SAME relative luminance rung for rung, which is what keeps the
     * elevation ladder's 1.04 to 1.06 steps identical. n 0 is white in every
     * family and is not restated. Worst luminance drift on this ramp: 0.33 percent.
     */
    --fx-p-n-25:   #fefcfb;
    --fx-p-n-50:   #fdf4f4;
    --fx-p-n-100:  #f8eaeb;
    --fx-p-n-200:  #ecdbde;
    --fx-p-n-300:  #dcc3c7;
    --fx-p-n-400:  #bca2a6;
    --fx-p-n-500:  #9c8285;
    --fx-p-n-600:  #776266;
    --fx-p-n-700:  #5b4b4d;
    --fx-p-n-800:  #423435;
    --fx-p-n-900:  #342326;
    --fx-p-n-950:  #321f22;
    --fx-p-n-1000: #2a191c;

    /* 13.2.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they
     * are deliberately hue tinted rather than points on the neutral ramp, so
     * they are re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated: #3f2326;
    --fx-p-dark-sunken:   #2b1a1e;
    --fx-p-dark-well:     #221317;
    --fx-p-dark-ink:      #241518;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white
     * for the same reason; this is the same value at this family's hue.
     * Measured on the brand fill: 7.38:1, against olive's 7.38:1. */
    --fx-p-on-primary: #ffeef0;

    /* 13.2.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with
     * the palette would stop being a danger red, so the 200 / 300 / 600 / 800
     * grades in 1.6 are untouched in every family and are NOT restated here.
     * What is restated is the two TINT BACKGROUNDS, because a tint sits on this
     * family's neutral and has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and
     * takes the family's neutral cast added at 0.35 of the neutral's own hue
     * shift. The fraction is a ruling, not a taste: at 1.0 the emerald dark tint
     * on the plum neutral loses its hue entirely and measures as a neutral grey,
     * which would make a success panel and an info panel indistinguishable. 0.35
     * is the largest fraction at which all eight tints in all three families stay
     * within 30 degrees of their own status hue. Luminance is preserved exactly,
     * so every status foreground keeps its measured ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.68:1
     *   amber    fg on tint  light 5.18:1   dark 8.08:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.65:1   dark 7.88:1
     */
    --fx-p-emerald-100: #eaf3ee;
    --fx-p-emerald-900: #1e2e21;
    --fx-p-amber-100: #fff0e4;
    --fx-p-amber-900: #3b2211;
    --fx-p-red-100: #feebee;
    --fx-p-red-900: #3c1317;
    --fx-p-blue-100: #ebf0fc;
    --fx-p-blue-900: #1f233c;

    /* ══ 13.2.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue moved.
     * MEASURED, the ladder: 0 to 1 1.045, 1 to 2 1.044, 2 to 3 1.047, 0 to 3 1.142.
     * The four text tiers on the page: 14.29 / 10.42 / 5.23 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0: #f6eeee;            /* page   */
    --fx-color-level-1: #fbf3f3;            /* card   */
    --fx-color-level-2: #fff8fa;            /* raised */
    --fx-color-bg-subtle:      #f1e9e9;
    --fx-color-surface-sunken: #f1e9e9;

    --fx-color-text:        #2d1b1d;
    --fx-color-text-muted:  #433335;
    --fx-color-text-subtle: #715f62;
    --fx-color-text-faint:  #8d7b7e;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate
     * and that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:   rgba(59, 27, 33, 0.05);
    --fx-color-border:          rgba(59, 27, 33, 0.08);
    --fx-color-border-emphasis: rgba(59, 27, 33, 0.14);
    --fx-color-divider-strong:  #e5d6d6;
    --fx-color-divider:         #f1e4e4;
    --fx-color-divider-faint:   #faefef;
    --fx-color-field-bg-hover:  #fefcfb;

    /* 2.4. Brand fill #892e44, ink on it 7.38:1, white on it 8.27:1,
     * fill against the page 7.24:1. */
    --fx-color-primary:        var(--fx-p-plum-800);
    --fx-color-primary-hover:  var(--fx-p-plum-900);
    --fx-color-primary-active: var(--fx-p-plum-950);
    --fx-color-primary-subtle: rgba(137, 46, 68, 0.10);
    --fx-color-primary-rgb:    137, 46, 68;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.27:1
     *   white 85 percent .......... 6.45:1
     *   white 72 percent .......... 5.07:1   idle rail rows and group headings
     *   white 54 percent .......... 3.55:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.205 / 1.396 / 1.542
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:  var(--fx-p-plum-800);
    --fx-color-shell: var(--fx-p-plum-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:        var(--fx-p-plum-accent-600);
    --fx-color-accent-hover:  var(--fx-p-plum-accent-700);
    --fx-color-accent-subtle: rgba(192, 99, 158, 0.14);
    --fx-color-accent-rgb:    192, 99, 158;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and
     * link the same, against a 4.5 bar. */
    --fx-color-indicator:  var(--fx-p-plum-800);
    --fx-color-brand-text: var(--fx-p-plum-800);
    --fx-color-link:       var(--fx-p-plum-800);
    --fx-color-link-hover: var(--fx-p-plum-900);
    --fx-color-link-rgb:   137, 46, 68;
    --fx-color-text-rgb:   45, 27, 29;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash
     * at alpha renders as a different hex on each of the four planes. Active is
     * mixed from the two rungs either side of it rather than being a sixth rung.
     * The four tiers over hover 13.90 / 10.14 / 5.09 / 3.40 and over active
     * 12.72 / 9.27 / 4.65 / 3.11. The ring over the two washes: 7.05 and 6.44. */
    --fx-color-focus-ring:   var(--fx-p-plum-800);
    --fx-color-selection-bg: var(--fx-p-plum-wash-300);
    --fx-color-hover:        var(--fx-p-plum-wash-100);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-plum-wash-200) 70%, var(--fx-p-plum-wash-100));
    --fx-color-disabled-bg:  #f5eaeb;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a plum page. Geometry, blur and alpha
     * are untouched — only the three channels moved. */
    --fx-shadow-xs:  0 1px 2px rgba(59, 27, 33, 0.05);
    --fx-shadow-sm:  0 1px 4px -1px rgba(59, 27, 33, 0.09);
    --fx-shadow-md:  0 3px 12px rgba(59, 27, 33, 0.09);
    --fx-shadow-lg:  0 7px 24px rgba(59, 27, 33, 0.06);
    --fx-shadow-xl:  0 10px 32px rgba(59, 27, 33, 0.07);
    --fx-shadow-2xl: 0 16px 48px rgba(59, 27, 33, 0.08);
    --fx-shadow-float-sm: 0 1px 4px -1px rgba(59, 27, 33, 0.09);
    --fx-shadow-float-md: 0 3px 12px rgba(59, 27, 33, 0.09);
    --fx-shadow-float-lg: 0 7px 24px rgba(59, 27, 33, 0.06);
    --fx-shadow-stack:
        inset 0 -1px 1px 0 rgba(59, 27, 33, 0.10),
        0 5px 2px 0 rgba(59, 27, 33, 0.01),
        0 3px 2px 0 rgba(59, 27, 33, 0.04),
        0 1px 1px 0 rgba(59, 27, 33, 0.07),
        0 0 1px 0 rgba(59, 27, 33, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load
     * bearing; read the rule over the olive declaration before touching it. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(59, 27, 33, 0.60),
        inset 0 5px 12px rgba(59, 27, 33, 0.10),
        inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset: inset 0 1px 2px rgba(59, 27, 33, 0.08);
    --fx-shadow-press: inset 0 1px 3px rgba(59, 27, 33, 0.10);
    --fx-color-focus-glow:      var(--fx-p-plum-wash-200);
    --fx-color-focus-glow-soft: var(--fx-p-plum-wash-500);
    --fx-glass-bg: rgba(255, 248, 250, 0.72);
    --fx-scrollbar-thumb:        rgba(59, 27, 33, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(59, 27, 33, 0.20);
    --fx-scrollbar-thumb-active: rgba(59, 27, 33, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would
     * paint the olive green on a plum page. Nothing is renamed. */
    --frihat-green-900: var(--fx-p-plum-900);
    --frihat-green-800: var(--fx-p-plum-800);
    --frihat-green-700: var(--fx-p-plum-700);
    --frihat-olive:     var(--fx-p-plum-accent-600);
    --frihat-olive-2:   var(--fx-p-plum-accent-500);
}

/* 13.2.8 PLUM — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS
 * STRUCTURAL RATHER THAN TIDY. The light palette block is specificity 0,2,1 and
 * sits LATER in the file than the olive dark block, which is also 0,2,1, so on a
 * tie it wins. Every token the light block declares must therefore be restated
 * here at 0,3,1, or it would leak its LIGHT value into this theme. A token that
 * appears above and is missing below is a defect, not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.050, 1 to 2 1.051, 2 to 3 1.053, 0 to 3 1.162.
 * The four text tiers on the page: 14.26 / 11.11 / 5.67 / 3.70, and on level 3
 * 12.27 / 9.56 / 4.88 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="plum"][data-bs-theme="dark"]:root {
    --fx-color-level-0: var(--fx-p-n-1000);
    --fx-color-level-1: #2d1e1f;
    --fx-color-level-2: #332124;
    --fx-color-level-3: #372528;
    --fx-color-bg-subtle:      var(--fx-p-dark-well);
    --fx-color-surface-sunken: var(--fx-p-dark-well);

    --fx-color-text:        #f6eaeb;
    --fx-color-text-muted:  #e1cecf;
    --fx-color-text-subtle: #a49294;
    --fx-color-text-faint:  #847275;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and
     * that ink is this family's own primary text colour. */
    --fx-color-border-subtle:   rgba(246, 234, 235, 0.05);
    --fx-color-border:          rgba(246, 234, 235, 0.08);
    --fx-color-border-emphasis: rgba(246, 234, 235, 0.14);
    --fx-color-divider-strong:  #433838;
    --fx-color-divider:         #342929;
    --fx-color-divider-soft:    #2d2223;
    --fx-color-divider-faint:   #2f2023;
    --fx-color-field-bg-hover:  var(--fx-color-level-3);
    --fx-color-field-bg-focus:  #3b292c;

    /* 3.4. One ramp step brighter than light so the fill stays visible against
     * the page: white on it 5.16:1, fill against the page 3.24:1. */
    --fx-color-primary:        var(--fx-p-plum-700);
    --fx-color-primary-hover:  var(--fx-p-plum-800);
    --fx-color-primary-active: var(--fx-p-plum-900);
    --fx-color-primary-subtle: rgba(191, 62, 95, 0.20);
    --fx-color-primary-rgb:    191, 62, 95;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the
     * planes a dropdown or a popup floats on, and it cannot move without
     * breaking its own ink, so it carries a rim instead. This family 600 rung
     * measures 4.18 / 3.98 / 3.79 / 3.60:1 on levels 0 to 3, the same figures
     * as every other family, because a rung is a luminance position. */
    --fx-color-primary-border: var(--fx-p-plum-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand
     * surface and must read as one colour in both themes, so it stays on 800 and
     * accepts the same 2.02:1 against the dark page that the dated decision in
     * 3.4.1 accepted for olive. Ink on it 7.38:1, gold mark on it 4.53:1. */
    --fx-color-band: var(--fx-p-plum-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5
     * does for olive: without this line the light block's brand fill would fall
     * through and dark would gain a mid plum shell nobody asked for. */
    --fx-color-shell: var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.057:1   one rung, as in olive
     *   white on the rail .................. 16.93:1
     *   white 72 / 55 / 38 percent ......... 9.15 / 5.86 / 3.44
     *   gold mark on the rail .............. 9.27:1
     *   washes, white at 8 / 14 / 18 percent 1.236 / 1.497 / 1.733 */
    --fx-color-rail: color-mix(in srgb, var(--fx-p-plum-900) 55%, var(--fx-p-black));

    --fx-color-accent:        var(--fx-p-plum-accent-500);
    --fx-color-accent-hover:  var(--fx-p-plum-accent-400);
    --fx-color-accent-subtle: rgba(210, 122, 178, 0.18);
    --fx-color-accent-rgb:    210, 122, 178;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar. Brand TEXT cannot be the brand ramp
     * in dark — rung 700 measures 3.24:1 on the page and fails 4.5 — so it takes
     * the wash ramp's deepest rung, 8.97:1 worst case. Exactly the constraint the
     * mint ramp solved for olive, solved the same way with this family's own
     * wash ramp rather than by borrowing mint. */
    --fx-color-indicator:  var(--fx-p-plum-500);
    --fx-color-brand-text: var(--fx-p-plum-wash-500);
    --fx-color-link:       var(--fx-p-plum-wash-500);
    --fx-color-link-hover: var(--fx-p-plum-wash-400);
    --fx-color-link-rgb:   255, 186, 197;
    --fx-color-text-rgb:   246, 234, 235;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would
     * invert the elevation model. Measured, wash against its own host plane:
     *   hover  1.141 / 1.141 / 1.143 / 1.148 on levels 0 to 3
     *   active 1.249 / 1.264 / 1.258 / 1.267
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.84 / 4.61 / 4.38 / 4.14
     *   over active 4.42 / 4.16 / 3.98 / 3.75 */
    --fx-color-focus-ring:   var(--fx-p-plum-500);
    --fx-color-selection-bg: color-mix(in srgb, var(--fx-p-plum-wash-500) 22%, transparent);
    --fx-color-hover:        color-mix(in srgb, var(--fx-p-plum-wash-500)  6%, transparent);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-plum-wash-500) 10%, transparent);
    --fx-color-disabled-bg:  #2c1f22;

    /* Section 6, dark. The shadow ink is pure black in this theme for every
     * family — a hue tinted shadow on a near black page buys nothing — so these
     * are the olive values restated verbatim. They are restated rather than
     * inherited because the light block above declares the same names and would
     * otherwise win the 0,2,1 tie. */
    --fx-shadow-xs:  none;
    --fx-shadow-sm:  0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:  0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:  0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:  0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl: 0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm: 0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md: 0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg: 0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:
        0 5px 2px 0 rgba(0, 0, 0, 0.02),
        0 3px 2px 0 rgba(0, 0, 0, 0.08),
        0 1px 1px 0 rgba(0, 0, 0, 0.14),
        0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the 3.626:1 the olive
     * geometry was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(246, 234, 235, 0.50),
        inset 0 6px 14px rgba(0, 0, 0, 0.45),
        inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press: inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:      color-mix(in srgb, var(--fx-p-plum-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft: var(--fx-p-plum-wash-500);
    --fx-glass-bg: rgba(45, 30, 31, 0.72);
    --fx-scrollbar-thumb:        rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active: rgba(255, 255, 255, 0.40);
}

/* ── 13.3) WARM SAND — الرملي الدافئ ──
 *
 * SEED #D4B483, chosen by the owner 2026-09-04. Measured: OKLCH L 0.7863
 * C 0.0745 H 78.0, relative luminance 0.48278.
 *
 * WHERE THE SEED LANDS ON THE FROZEN LADDER. Placed by OKLab LIGHTNESS, the
 * perceptual coordinate: the seed sits at L 0.7863 and the green spine's 300 rung
 * at L 0.8107, a difference of 0.0244, and no other rung comes close. So it is the
 * 300 rung of this family and it arrives as #dfc08f.
 *
 * The RELATIVE luminance moves with it, from the seed's 0.48278 to the rung's
 * 0.55407, and that is the point rather than a cost: pinning every family to the
 * spine's luminance ladder is the whole reason every ratio measured for olive
 * transfers to this family unchanged. Relative luminance is a nonlinear
 * coordinate, so quote the L figure above, not this one, when judging how far
 * the seed actually moved.
 *
 * AND THE SEED NAMES THE FAMILY IDENTITY, NOT ITS INK. A ramp runs 50 to 950
 * whatever rung the seed occupies, so the deep rungs that carry brand text, the
 * link, the indicator and the focus ring are derived from the spine exactly as
 * they are in every other family, and are UNAFFECTED by where the seed sat.
 * This family shows its identity on the band, the rail and the washes; its ink
 * comes from the deep end of its own ramp. Verified rather than assumed: every
 * ink pairing in 13.3.7 and 13.3.8 below is measured against its own plane.
 *
 * CHROMA. s = 0.842, the seed's chroma over the green spine's chroma at that
 * rung. Held flat at and below the seed rung and relaxed linearly to 1.0 at
 * rung 50, so the pale end of the ramp cannot go neon and the deep end keeps
 * the seed's own saturation. Rung 50 lands at s 1.000.
 *
 * ACCENT HUE 113.0, +35 degrees of OKLCH hue from the brand, which reads as
 * a dry olive green. The sign and the size are chosen per family so the decorative
 * hue does not collide with a status hue: measured against the four status
 * families it is nearest the success emerald at 37 degrees and the warning amber at 64.
 *
 * THIS SEED LANDS HIGH ON THE LADDER, AT RUNG 300, AND THAT IS ALLOWED.
 * الرملي الدافئ is a pale warm sand. It is the first seed in the system that is
 * lighter than the mid ramp, and the correct response is to let it sit where it
 * belongs rather than to darken it onto rung 700 where the other seeds happen to
 * live. Darkening it would have reproduced exactly the brown the owner rejected on
 * 2026-09-04, so the rung moved and the colour did not.
 *
 * NOTHING DOWNSTREAM DEPENDS ON WHERE THE SEED SAT. Read the identity clause
 * above: the rungs are luminance positions on the frozen spine, so rung 800 is the
 * same luminance in this family as in every other and the light brand fill, the
 * band, the shell, the link, the indicator and the focus ring all measure what
 * they measure elsewhere. The seed set this family hue and its chroma scale, and
 * nothing else. No token needed deepening.
 *
 * AND THE 2026-09-04 AMBER FLAG IS DISCHARGED BY THIS SEED. The previous sand seed
 * sat 17.1 degrees of OKLCH hue from the warning amber, which was recorded here as
 * the closest brand to status approach in the system and as a recognition risk.
 * This seed measures 78.0 against the amber 49.3, so the gap is now 28.7 degrees.
 * The hue was NOT rotated to open it; the owner chose a different colour and the
 * gap came with it. The risk is further reduced by chroma: this family scales the
 * spine chroma by 0.842 while p-amber-600 is a saturated 0.1361, so a warning and
 * a sand surface differ in saturation as well as in hue. The flag moves to the
 * plum family, where the brand now sits 20 degrees from the danger red.
 * ─────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="sand"]:root {
    /* 13.3.1 THE SAND RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. */
    --fx-p-sand-50:  #fbf5ed;
    --fx-p-sand-100: #f7ecdc;
    --fx-p-sand-200: #f0daba;
    --fx-p-sand-300: #dfc08f;   /* the owner's seed, on the ladder */
    --fx-p-sand-400: #d0a35b;
    --fx-p-sand-500: #be8b2f;
    --fx-p-sand-600: #a7761a;
    --fx-p-sand-700: #916514;
    --fx-p-sand-800: #674912;
    --fx-p-sand-900: #47310d;
    --fx-p-sand-950: #33230a;

    /* 13.3.2 THE ACCENT RAMP — a dry olive green. The decorative companion, holding the
     * olive ramp's luminance at every rung so 2.5 and 3.5 keep their figures.
     * It is NOT a second brand: 3.9 governs where it may be spent and that
     * contract is unchanged for every family. */
    --fx-p-sand-accent-100: #edf1d8;
    --fx-p-sand-accent-200: #e1e7bc;
    --fx-p-sand-accent-300: #d0d592;
    --fx-p-sand-accent-400: #bcc362;
    --fx-p-sand-accent-500: #979c47;
    --fx-p-sand-accent-600: #838829;
    --fx-p-sand-accent-700: #6f7524;
    --fx-p-sand-accent-800: #565a1a;

    /* 13.3.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It
     * is not extended, not tinted and not reused here, and there is still no
     * sixth mint rung. This is a SEPARATE ramp that reproduces mint's five
     * relative luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at
     * this family's own hue, so the light opaque washes and the dark low alpha
     * washes land at the identical lift the fourth pass measured (1.134 and
     * 1.254 in dark) and every text tier over a wash keeps its ratio.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.027   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.122  on level 1 1.174  on level 2 1.226 */
    --fx-p-sand-wash-100: #ffeacb;
    --fx-p-sand-wash-200: #fadaad;
    --fx-p-sand-wash-300: #f8d39a;
    --fx-p-sand-wash-400: #f9cb86;
    --fx-p-sand-wash-500: #f7c471;

    /* 13.3.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES
     * WHETHER THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside
     * the olive. A green tinted grey under a sand page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels
     * on a legal screen. So the ramp is restated at THIS family's hue, at the
     * SAME OKLCH chroma rung for rung (0.0045 at n 25 up to 0.0330 at n 950)
     * and at the SAME relative luminance rung for rung, which is what keeps the
     * elevation ladder's 1.04 to 1.06 steps identical. n 0 is white in every
     * family and is not restated. Worst luminance drift on this ramp: 0.19 percent.
     */
    --fx-p-n-25:   #fffcf8;
    --fx-p-n-50:   #f8f6ef;
    --fx-p-n-100:  #f1ede3;
    --fx-p-n-200:  #e7ded0;
    --fx-p-n-300:  #d5c7b6;
    --fx-p-n-400:  #b2a795;
    --fx-p-n-500:  #928775;
    --fx-p-n-600:  #706656;
    --fx-p-n-700:  #554e43;
    --fx-p-n-800:  #3c372c;
    --fx-p-n-900:  #302618;
    --fx-p-n-950:  #2e2212;
    --fx-p-n-1000: #261c0e;

    /* 13.3.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they
     * are deliberately hue tinted rather than points on the neutral ramp, so
     * they are re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated: #382810;
    --fx-p-dark-sunken:   #271d10;
    --fx-p-dark-well:     #1e160a;
    --fx-p-dark-ink:      #201809;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white
     * for the same reason; this is the same value at this family's hue.
     * Measured on the brand fill: 7.38:1, against olive's 7.38:1. */
    --fx-p-on-primary: #f9f1e5;

    /* 13.3.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with
     * the palette would stop being a danger red, so the 200 / 300 / 600 / 800
     * grades in 1.6 are untouched in every family and are NOT restated here.
     * What is restated is the two TINT BACKGROUNDS, because a tint sits on this
     * family's neutral and has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and
     * takes the family's neutral cast added at 0.35 of the neutral's own hue
     * shift. The fraction is a ruling, not a taste: at 1.0 the emerald dark tint
     * on the plum neutral loses its hue entirely and measures as a neutral grey,
     * which would make a success panel and an info panel indistinguishable. 0.35
     * is the largest fraction at which all eight tints in all three families stay
     * within 30 degrees of their own status hue. Luminance is preserved exactly,
     * so every status foreground keeps its measured ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.67:1
     *   amber    fg on tint  light 5.19:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.88:1
     */
    --fx-p-emerald-100: #ebf3eb;
    --fx-p-emerald-900: #1b2f1b;
    --fx-p-amber-100: #fef1df;
    --fx-p-amber-900: #382408;
    --fx-p-red-100: #ffebeb;
    --fx-p-red-900: #391612;
    --fx-p-blue-100: #ecf0fa;
    --fx-p-blue-900: #1b2536;

    /* ══ 13.3.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue moved.
     * MEASURED, the ladder: 0 to 1 1.046, 1 to 2 1.045, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.30 / 10.43 / 5.22 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0: #f4efe9;            /* page   */
    --fx-color-level-1: #f9f4ef;            /* card   */
    --fx-color-level-2: #fef9f4;            /* raised */
    --fx-color-bg-subtle:      #efeae4;
    --fx-color-surface-sunken: #efeae4;

    --fx-color-text:        #281e12;
    --fx-color-text-muted:  #3d362b;
    --fx-color-text-subtle: #6c6255;
    --fx-color-text-faint:  #887e71;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate
     * and that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:   rgba(50, 34, 5, 0.05);
    --fx-color-border:          rgba(50, 34, 5, 0.08);
    --fx-color-border-emphasis: rgba(50, 34, 5, 0.14);
    --fx-color-divider-strong:  #e2d8cb;
    --fx-color-divider:         #ede6dc;
    --fx-color-divider-faint:   #f5f1ea;
    --fx-color-field-bg-hover:  #fffcf7;

    /* 2.4. Brand fill #674912, ink on it 7.38:1, white on it 8.27:1,
     * fill against the page 7.24:1. */
    --fx-color-primary:        var(--fx-p-sand-800);
    --fx-color-primary-hover:  var(--fx-p-sand-900);
    --fx-color-primary-active: var(--fx-p-sand-950);
    --fx-color-primary-subtle: rgba(103, 73, 18, 0.10);
    --fx-color-primary-rgb:    103, 73, 18;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.27:1
     *   white 85 percent .......... 6.52:1
     *   white 72 percent .......... 5.19:1   idle rail rows and group headings
     *   white 54 percent .......... 3.66:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.242 / 1.439 / 1.607
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:  var(--fx-p-sand-800);
    --fx-color-shell: var(--fx-p-sand-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:        var(--fx-p-sand-accent-600);
    --fx-color-accent-hover:  var(--fx-p-sand-accent-700);
    --fx-color-accent-subtle: rgba(131, 136, 41, 0.14);
    --fx-color-accent-rgb:    131, 136, 41;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and
     * link the same, against a 4.5 bar. */
    --fx-color-indicator:  var(--fx-p-sand-800);
    --fx-color-brand-text: var(--fx-p-sand-800);
    --fx-color-link:       var(--fx-p-sand-800);
    --fx-color-link-hover: var(--fx-p-sand-900);
    --fx-color-link-rgb:   103, 73, 18;
    --fx-color-text-rgb:   40, 30, 18;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash
     * at alpha renders as a different hex on each of the four planes. Active is
     * mixed from the two rungs either side of it rather than being a sixth rung.
     * The four tiers over hover 13.92 / 10.16 / 5.09 / 3.39 and over active
     * 12.74 / 9.30 / 4.66 / 3.11. The ring over the two washes: 7.05 and 6.45. */
    --fx-color-focus-ring:   var(--fx-p-sand-800);
    --fx-color-selection-bg: var(--fx-p-sand-wash-300);
    --fx-color-hover:        var(--fx-p-sand-wash-100);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-sand-wash-200) 70%, var(--fx-p-sand-wash-100));
    --fx-color-disabled-bg:  #f0ece6;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a sand page. Geometry, blur and alpha
     * are untouched — only the three channels moved. */
    --fx-shadow-xs:  0 1px 2px rgba(50, 34, 5, 0.05);
    --fx-shadow-sm:  0 1px 4px -1px rgba(50, 34, 5, 0.09);
    --fx-shadow-md:  0 3px 12px rgba(50, 34, 5, 0.09);
    --fx-shadow-lg:  0 7px 24px rgba(50, 34, 5, 0.06);
    --fx-shadow-xl:  0 10px 32px rgba(50, 34, 5, 0.07);
    --fx-shadow-2xl: 0 16px 48px rgba(50, 34, 5, 0.08);
    --fx-shadow-float-sm: 0 1px 4px -1px rgba(50, 34, 5, 0.09);
    --fx-shadow-float-md: 0 3px 12px rgba(50, 34, 5, 0.09);
    --fx-shadow-float-lg: 0 7px 24px rgba(50, 34, 5, 0.06);
    --fx-shadow-stack:
        inset 0 -1px 1px 0 rgba(50, 34, 5, 0.10),
        0 5px 2px 0 rgba(50, 34, 5, 0.01),
        0 3px 2px 0 rgba(50, 34, 5, 0.04),
        0 1px 1px 0 rgba(50, 34, 5, 0.07),
        0 0 1px 0 rgba(50, 34, 5, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load
     * bearing; read the rule over the olive declaration before touching it. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(50, 34, 5, 0.60),
        inset 0 5px 12px rgba(50, 34, 5, 0.10),
        inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset: inset 0 1px 2px rgba(50, 34, 5, 0.08);
    --fx-shadow-press: inset 0 1px 3px rgba(50, 34, 5, 0.10);
    --fx-color-focus-glow:      var(--fx-p-sand-wash-200);
    --fx-color-focus-glow-soft: var(--fx-p-sand-wash-500);
    --fx-glass-bg: rgba(254, 249, 244, 0.72);
    --fx-scrollbar-thumb:        rgba(50, 34, 5, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(50, 34, 5, 0.20);
    --fx-scrollbar-thumb-active: rgba(50, 34, 5, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would
     * paint the olive green on a sand page. Nothing is renamed. */
    --frihat-green-900: var(--fx-p-sand-900);
    --frihat-green-800: var(--fx-p-sand-800);
    --frihat-green-700: var(--fx-p-sand-700);
    --frihat-olive:     var(--fx-p-sand-accent-600);
    --frihat-olive-2:   var(--fx-p-sand-accent-500);
}

/* 13.3.8 WARM SAND — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS
 * STRUCTURAL RATHER THAN TIDY. The light palette block is specificity 0,2,1 and
 * sits LATER in the file than the olive dark block, which is also 0,2,1, so on a
 * tie it wins. Every token the light block declares must therefore be restated
 * here at 0,3,1, or it would leak its LIGHT value into this theme. A token that
 * appears above and is missing below is a defect, not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.050, 1 to 2 1.050, 2 to 3 1.054, 0 to 3 1.162.
 * The four text tiers on the page: 14.25 / 11.09 / 5.67 / 3.70, and on level 3
 * 12.27 / 9.55 / 4.88 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="sand"][data-bs-theme="dark"]:root {
    --fx-color-level-0: var(--fx-p-n-1000);
    --fx-color-level-1: #282113;
    --fx-color-level-2: #2c2516;
    --fx-color-level-3: #30291a;
    --fx-color-bg-subtle:      var(--fx-p-dark-well);
    --fx-color-surface-sunken: var(--fx-p-dark-well);

    --fx-color-text:        #f2ece3;
    --fx-color-text-muted:  #dbd1c3;
    --fx-color-text-subtle: #9f9586;
    --fx-color-text-faint:  #7f7568;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and
     * that ink is this family's own primary text colour. */
    --fx-color-border-subtle:   rgba(242, 236, 227, 0.05);
    --fx-color-border:          rgba(242, 236, 227, 0.08);
    --fx-color-border-emphasis: rgba(242, 236, 227, 0.14);
    --fx-color-divider-strong:  #3f3a31;
    --fx-color-divider:         #302b22;
    --fx-color-divider-soft:    #29241c;
    --fx-color-divider-faint:   #2a2318;
    --fx-color-field-bg-hover:  var(--fx-color-level-3);
    --fx-color-field-bg-focus:  #372c1d;

    /* 3.4. One ramp step brighter than light so the fill stays visible against
     * the page: white on it 5.15:1, fill against the page 3.25:1. */
    --fx-color-primary:        var(--fx-p-sand-700);
    --fx-color-primary-hover:  var(--fx-p-sand-800);
    --fx-color-primary-active: var(--fx-p-sand-900);
    --fx-color-primary-subtle: rgba(145, 101, 20, 0.20);
    --fx-color-primary-rgb:    145, 101, 20;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the
     * planes a dropdown or a popup floats on, and it cannot move without
     * breaking its own ink, so it carries a rim instead. This family 600 rung
     * measures 4.18 / 3.98 / 3.79 / 3.60:1 on levels 0 to 3, the same figures
     * as every other family, because a rung is a luminance position. */
    --fx-color-primary-border: var(--fx-p-sand-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand
     * surface and must read as one colour in both themes, so it stays on 800 and
     * accepts the same 2.02:1 against the dark page that the dated decision in
     * 3.4.1 accepted for olive. Ink on it 7.38:1, gold mark on it 4.53:1. */
    --fx-color-band: var(--fx-p-sand-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5
     * does for olive: without this line the light block's brand fill would fall
     * through and dark would gain a mid sand shell nobody asked for. */
    --fx-color-shell: var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.061:1   one rung, as in olive
     *   white on the rail .................. 16.85:1
     *   white 72 / 55 / 38 percent ......... 9.21 / 5.89 / 3.54
     *   gold mark on the rail .............. 9.22:1
     *   washes, white at 8 / 14 / 18 percent 1.251 / 1.534 / 1.766 */
    --fx-color-rail: color-mix(in srgb, var(--fx-p-sand-900) 55%, var(--fx-p-black));

    --fx-color-accent:        var(--fx-p-sand-accent-500);
    --fx-color-accent-hover:  var(--fx-p-sand-accent-400);
    --fx-color-accent-subtle: rgba(151, 156, 71, 0.18);
    --fx-color-accent-rgb:    151, 156, 71;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar. Brand TEXT cannot be the brand ramp
     * in dark — rung 700 measures 3.25:1 on the page and fails 4.5 — so it takes
     * the wash ramp's deepest rung, 8.98:1 worst case. Exactly the constraint the
     * mint ramp solved for olive, solved the same way with this family's own
     * wash ramp rather than by borrowing mint. */
    --fx-color-indicator:  var(--fx-p-sand-500);
    --fx-color-brand-text: var(--fx-p-sand-wash-500);
    --fx-color-link:       var(--fx-p-sand-wash-500);
    --fx-color-link-hover: var(--fx-p-sand-wash-400);
    --fx-color-link-rgb:   247, 196, 113;
    --fx-color-text-rgb:   242, 236, 227;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would
     * invert the elevation model. Measured, wash against its own host plane:
     *   hover  1.138 / 1.143 / 1.150 / 1.144 on levels 0 to 3
     *   active 1.255 / 1.256 / 1.263 / 1.259
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.85 / 4.60 / 4.35 / 4.15
     *   over active 4.40 / 4.18 / 3.96 / 3.77 */
    --fx-color-focus-ring:   var(--fx-p-sand-500);
    --fx-color-selection-bg: color-mix(in srgb, var(--fx-p-sand-wash-500) 22%, transparent);
    --fx-color-hover:        color-mix(in srgb, var(--fx-p-sand-wash-500)  6%, transparent);
    --fx-color-active:       color-mix(in srgb, var(--fx-p-sand-wash-500) 10%, transparent);
    --fx-color-disabled-bg:  #272216;

    /* Section 6, dark. The shadow ink is pure black in this theme for every
     * family — a hue tinted shadow on a near black page buys nothing — so these
     * are the olive values restated verbatim. They are restated rather than
     * inherited because the light block above declares the same names and would
     * otherwise win the 0,2,1 tie. */
    --fx-shadow-xs:  none;
    --fx-shadow-sm:  0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:  0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:  0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:  0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl: 0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm: 0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md: 0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg: 0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:
        0 5px 2px 0 rgba(0, 0, 0, 0.02),
        0 3px 2px 0 rgba(0, 0, 0, 0.08),
        0 1px 1px 0 rgba(0, 0, 0, 0.14),
        0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the 3.626:1 the olive
     * geometry was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:
        inset 0 2px 2px rgba(242, 236, 227, 0.50),
        inset 0 6px 14px rgba(0, 0, 0, 0.45),
        inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press: inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:      color-mix(in srgb, var(--fx-p-sand-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft: var(--fx-p-sand-wash-500);
    --fx-glass-bg: rgba(40, 33, 19, 0.72);
    --fx-scrollbar-thumb:        rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:  rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active: rgba(255, 255, 255, 0.40);
}

/* ── 13.5) INDIGO — النيلي ──
 *
 * ADDED 2026-09-04 (seventh pass, see the header). NUMBERED AFTER 13.4 BUT
 * PLACED BEFORE IT. 13.4 restates section 11 and has to remain the LAST thing in
 * this file for the reason written at its head, so the two families added on this
 * date take the next free numbers and sit above it. Read the ordinal as an
 * identifier, not as a position.
 *
 * ══ THE OWNER SUPPLIED SIX VALUES FOR THIS FAMILY, NOT ONE ═════════════════
 *
 * Recorded verbatim before anything is derived from them:
 *
 *     light   أساسي #4C5BD4   خلفية #EEF0FC   نص عليها #2C3585
 *     dark    أساسي #8A93F0   خلفية #282D52   نص عليها #C7CCFA
 *
 * That is more constraint than the three earlier families arrived with, and it
 * is a gift rather than a burden: it pins the brand, its subtle ground and the
 * ink for that ground at the same time, so the derivation can be checked against
 * the owner's own eye at six points instead of one.
 *
 * ══ WHAT ROLE EACH SUPPLIED VALUE ACTUALLY FILLS ═══════════════════════════
 *
 * READ THIS BEFORE ASSUMING نص عليها IS fx-color-text-on-primary. It is not, and
 * the difference is an outright AA failure rather than a matter of taste. In this
 * system fx-color-text-on-primary is the ink that sits on the SOLID brand fill.
 * Measured, the owner's نص عليها against the owner's own أساسي:
 *     light  #2C3585 on #4C5BD4 ........ 1.92:1
 *     dark   #C7CCFA on #8A93F0 ........ 1.79:1
 * Against the owner's خلفية the same two inks measure 9.47:1 and 8.47:1. So
 * نص عليها is the ink for the SUBTLE GROUND. The trio is Tailwind shaped — a mid
 * brand, a pale tinted panel, a deep ink for that panel — and this file already
 * spends those three roles under different names:
 *
 *   أساسي      the family SEED. It fixes the hue and the chroma scale, it names
 *              the family in the picker (2.9), and it lands on the ladder at the
 *              rung whose OKLab LIGHTNESS is nearest.
 *   خلفية       the pale end of the ramp, rung 100, and the ground that
 *              fx-color-primary-subtle composites to on a card.
 *   نص عليها    the DEEP BRAND INK that reads on that ground: fx-color-brand-text,
 *              fx-color-link and fx-color-indicator in light. Never the ink on the
 *              solid fill.
 *
 * ══ WHERE EACH SUPPLIED VALUE LANDED, MEASURED RATHER THAN ASSERTED ════════
 *
 *   light أساسي   #4C5BD4  →  rung 700 #5660d9 ................ OKLab dE 0.0204
 *   light خلفية    #EEF0FC  →  rung 100 #e8edff ................ OKLab dE 0.0129
 *   light نص عليها #2C3585  →  rung 900 #282f6b ................ OKLab dE 0.0472
 *   dark  أساسي   #8A93F0  →  rung 500 #7c8afe ................ OKLab dE 0.0395
 *   dark  خلفية    #282D52  →  primary-subtle over a card ....... OKLab dE 0.0053
 *   dark  نص عليها #C7CCFA  →  wash rung 500 #bfcafe ........... OKLab dE 0.0139
 *
 * THE DARK خلفية IS THE STRIKING ONE. fx-color-primary-subtle in dark is the
 * dark brand fill at 20 percent alpha, which is the formula section 3.4 has used
 * since long before this family existed. Composited over this family's level 1
 * card it lands within OKLab dE 0.0053 of the value the owner typed. Nothing was
 * tuned to make that happen. It is the strongest single piece of evidence that
 * the trio he supplied and the trio this file already had are the same three
 * roles wearing different names.
 *
 * THE LIGHT خلفية IS THE LOOSEST FIT OF THE SIX, and honestly so. The same
 * formula at 10 percent composites to #e0e3f1, dE 0.0396 from #EEF0FC, because a
 * translucent tint of a rung 800 fill is darker than a hand picked rung 100. The
 * ramp rung is the closer match at dE 0.0129 and is where the value is recorded.
 * fx-color-primary-subtle was NOT re-specified as an opaque hex to close that
 * gap: 2.4 makes it translucent on purpose so it works on any of the four planes,
 * and trading that for one theme's fidelity to one swatch is a bad trade.
 *
 * ══ THE ONE CONFLICT, RAISED AND NOT SILENTLY RESOLVED ═════════════════════
 *
 * THE DARK أساسي CANNOT BE fx-color-primary IN DARK. #8A93F0 is a bright indigo
 * meant to carry DARK ink; this system's dark brand fill carries a near white one
 * in every family, because 3.4 splits the fill by theme and the dark ink is white.
 * Measured, white on #8A93F0:
 *     2.80:1 — against the 4.5:1 that SC 1.4.3 asks of a button label.
 * The system's dark fill, rung 700 #5660d9, measures 5.16:1 on the same ink.
 * Honouring the value literally would have swapped a legible primary button for
 * an illegible one across the whole dark theme, and it would have done it in two
 * families only, so the dark ink would have had to fork per palette as well.
 *
 * IT IS HONOURED, AT THE RUNG ITS OWN LIGHTNESS PUTS IT ON. #8A93F0 sits nearest
 * rung 500, and rung 500 in dark is fx-color-indicator and fx-color-focus-ring —
 * the bright brand MARK. 3.5.1 already rules that a bright brand colour in a dark
 * theme is a mark and not a fill, so the owner's value lands on exactly the token
 * a bright indigo is for. Measured there: 4.75:1 worst case over levels 0 to 3,
 * against the 3.0 bar a non text mark owes.
 *
 * ══ WHERE THE SEED LANDS ON THE FROZEN LADDER ══════════════════════════════
 *
 * SEED #4C5BD4. Measured: OKLCH L 0.5290 C 0.1850 H 273.0, relative luminance
 * 0.13772. Placed by OKLab LIGHTNESS, the perceptual coordinate: the seed sits at
 * L 0.5290 and the green spine's 700 rung at L 0.5216, a difference of 0.0074,
 * and no other rung comes close. So it is the 700 rung of this family and it
 * arrives as #5660d9.
 *
 * The RELATIVE luminance moves with it, from the seed's 0.13772 to the rung's
 * 0.15348, and that is the point rather than a cost: pinning every family to the
 * spine's luminance ladder is the whole reason every ratio measured for olive
 * transfers to this family unchanged. Relative luminance is a nonlinear
 * coordinate, so quote the L figure above, not this one, when judging how far
 * the seed actually moved.
 *
 * AND THE SEED NAMES THE FAMILY IDENTITY, NOT ITS INK. A ramp runs 50 to 950
 * whatever rung the seed occupies, so the deep rungs that carry brand text, the
 * link, the indicator and the focus ring are derived from the spine exactly as
 * they are in every other family, and are UNAFFECTED by where the seed sat.
 * Verified rather than assumed: every ink pairing in 13.5.7 and 13.5.8 below is
 * measured against its own plane.
 *
 * HUE 275.4, THE CHROMA WEIGHTED MEAN OF ALL SIX SUPPLIED VALUES rather than of
 * the light seed alone. The six anchors span 7.1 degrees of hue, which is the
 * natural spread of a palette a person chose by eye. Weighting each by its own
 * chroma, because the hue of a near neutral is numerically unstable and would
 * otherwise drag the mean around, gives 275.4. Taking the light seed's 273.0 on
 * its own would move the flagship value by OKLab dE 0.008, an order of magnitude
 * below a just noticeable difference, so the mean is used because it honours six
 * anchors instead of one and costs nothing to do so.
 *
 * CHROMA. s = 1.484, the seed's chroma over the green spine's chroma at that
 * rung. Held flat at and below the seed rung and relaxed linearly to 1.0 at
 * rung 50, so the pale end of the ramp cannot go neon and the deep end keeps
 * the seed's own saturation. Rung 50 lands at s 1.000. Where sRGB cannot hold the
 * target chroma at a given luminance the chroma is reduced until it fits and THE
 * LUMINANCE IS HELD, which is the guarantee this whole section rests on. Worst
 * luminance drift on this ramp against the spine: 0.249 percent.
 *
 * ACCENT HUE 320.4, +45.0 degrees of OKLCH hue from the brand, which reads as a
 * magenta orchid. The sign and the size are chosen per family so the decorative
 * hue does not collide with a status hue: measured against the four status
 * families it is nearest the info blue at 66.2 degrees and the danger red at 69.1.
 * A NEGATIVE rotation was not available here and that is worth recording: minus 27
 * degrees lands on 248.4, which is 5.8 degrees from the info blue, so the sign is
 * forced rather than chosen. The size is larger than the other families use for
 * the same reason, since the brand itself already sits near that status hue.
 *
 * ══ KNOWN, MEASURED AND RAISED: THIS BRAND SITS 21 DEGREES FROM THE INFO BLUE ══
 *
 * p-blue-600, the info status foreground, is at OKLCH hue 254.2 and this brand is
 * at 275.4. That is 21.2 degrees, closer than any brand to status approach the
 * system had before 2026-09-04 except this family's sibling below. It is a
 * consequence of the colour the owner chose and NOT of this derivation: the status
 * hues do not move, and rotating the brand would mean not shipping النيلي.
 *
 * IT IS NOT A CONTRAST DEFECT. Every info pairing in this family measures within
 * a hundredth of olive, and the two separate by LIGHTNESS as fills: the brand fill
 * is rung 800 at relative luminance 0.07683 while p-blue-600 sits at 0.11273, so
 * a danger of confusion exists only where a status is rendered as bare coloured
 * TEXT, which 2.7 already rules against. What DOES come close is the pale pair:
 * this family's rung 100 and its info tint background measure OKLab dE 0.0085
 * apart, which is under a just noticeable difference, so an info panel and a brand
 * tinted panel on this page are the same colour. The separation there is the
 * BORDER and the ICON, not the fill, and 2.7 already requires both. Raised for the
 * owner rather than corrected.
 * ─────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="indigo"]:root {
    /* 13.5.1 THE INDIGO RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. */
    --fx-p-indigo-50:             #f2f6fe;
    --fx-p-indigo-100:            #e8edff;
    --fx-p-indigo-200:            #d3dcfe;
    --fx-p-indigo-300:            #b4c2fe;
    --fx-p-indigo-400:            #94a5fe;
    --fx-p-indigo-500:            #7c8afe;
    --fx-p-indigo-600:            #6671f5;
    --fx-p-indigo-700:            #5660d9;
    --fx-p-indigo-800:            #3d459d;
    --fx-p-indigo-900:            #282f6b;
    --fx-p-indigo-950:            #1e214f;

    /* 13.5.2 THE ACCENT RAMP — a magenta orchid. The decorative companion,
     * holding the olive ramp's luminance at every rung so 2.5 and 3.5 keep their
     * figures. It is NOT a second brand: 3.9 governs where it may be spent and
     * that contract is unchanged for every family. Chroma is the olive ramp's own,
     * scaled by min(s, 1.0) and gamut clipped, so a family whose seed is more
     * saturated than the spine does not get a fluorescent companion. Worst
     * luminance drift against the olive ramp: 0.097 percent. */
    --fx-p-indigo-accent-100:     #fae9ff;
    --fx-p-indigo-accent-200:     #f8d9ff;
    --fx-p-indigo-accent-300:     #f3befe;
    --fx-p-indigo-accent-400:     #eca2fc;
    --fx-p-indigo-accent-500:     #c07fcd;
    --fx-p-indigo-accent-600:     #ac6ab9;
    --fx-p-indigo-accent-700:     #955aa0;
    --fx-p-indigo-accent-800:     #73457c;

    /* 13.5.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It
     * is not extended, not tinted and not reused here, and there is still no
     * sixth mint rung. This is a SEPARATE ramp that reproduces mint's five
     * relative luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at
     * this family's own hue, so the light opaque washes and the dark low alpha
     * washes land at the identical lift the fourth pass measured and every text
     * tier over a wash keeps its ratio. Worst drift: 0.049 percent.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.027   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.126  on level 1 1.177  on level 2 1.230 */
    --fx-p-indigo-wash-100:       #e9ecfe;
    --fx-p-indigo-wash-200:       #d5defe;
    --fx-p-indigo-wash-300:       #ced7fe;
    --fx-p-indigo-wash-400:       #c5d1fe;
    --fx-p-indigo-wash-500:       #bfcafe;

    /* 13.5.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES
     * WHETHER THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside
     * the olive. A green tinted grey under an indigo page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels
     * on a legal screen. So the ramp is restated at THIS family's hue, at the
     * SAME OKLCH chroma rung for rung and at the SAME relative luminance rung for
     * rung, which is what keeps the elevation ladder's 1.04 to 1.06 steps
     * identical. n 0 is white in every family and is not restated. Worst
     * luminance drift on this ramp: 0.20 percent. */
    --fx-p-n-25:                  #fdfcfe;
    --fx-p-n-50:                  #f4f6fb;
    --fx-p-n-100:                 #eaedf7;
    --fx-p-n-200:                 #dadfed;
    --fx-p-n-300:                 #c5c8dc;
    --fx-p-n-400:                 #a2a8bb;
    --fx-p-n-500:                 #82889b;
    --fx-p-n-600:                 #626776;
    --fx-p-n-700:                 #4d4e5c;
    --fx-p-n-800:                 #353741;
    --fx-p-n-900:                 #232736;
    --fx-p-n-950:                 #212334;
    --fx-p-n-1000:                #1a1d2b;

    /* 13.5.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they
     * are deliberately hue tinted rather than points on the neutral ramp, so
     * they are re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated:         #262942;
    --fx-p-dark-sunken:           #1c1e2b;
    --fx-p-dark-well:             #131722;
    --fx-p-dark-ink:              #171826;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white
     * for the same reason; this is the same value at this family's hue.
     * Measured on the light brand fill: 7.38:1. In DARK the semantic that reads
     * this primitive is overridden to white by section 3, so the dark band's ink
     * measures 8.28:1 rather than this figure. */
    --fx-p-on-primary:            #f0f1ff;

    /* 13.5.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with
     * the palette would stop being a danger red, so the 200 / 300 / 600 / 800
     * grades in 1.6 are untouched in every family and are NOT restated here.
     * What is restated is the two TINT BACKGROUNDS, because a tint sits on this
     * family's neutral and has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and
     * takes the family's neutral cast added at a fraction of the neutral's own
     * hue shift. Luminance is preserved exactly, so every status foreground keeps
     * its measured ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.67:1
     *   amber    fg on tint  light 5.18:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.88:1
     *
     * THE CAST FRACTION IS 0.30 IN THIS FAMILY AND NOT THE 0.35 THE OTHER FOUR
     * USE, AND THAT IS THE RULE BINDING RATHER THAN AN EXCEPTION TO IT. The
     * ruling recorded for the earlier families states the fraction as the LARGEST
     * at which every tint stays within 30 degrees of the olive tint it replaces,
     * and 0.35 was the answer when the question was asked of three families. It is
     * not the answer for this hue: measured at 0.35 the emerald light tint drifts
     * 37.8 degrees, because a pale tint carries almost no chroma and its hue
     * therefore swings hard for a small shift in OKLab a and b. At 0.30 the worst
     * drift in this family is 26.6 degrees and every tint is back inside the
     * bound. Luminance is preserved either way, so the fraction costs nothing in
     * contrast, and the four foregrounds above measure the same at 0.30 as at
     * 0.35. النبيذي, الرملي الدافئ and الأزرق البترولي were NOT re-derived; their
     * 0.35 still satisfies the bound and not one of their values moved. */
    --fx-p-emerald-100:           #e6f4f0;
    --fx-p-emerald-900:           #162f26;
    --fx-p-amber-100:             #fcf1e3;
    --fx-p-amber-900:             #342518;
    --fx-p-red-100:               #fdebf1;
    --fx-p-red-900:               #36171d;
    --fx-p-blue-100:              #eaf0ff;
    --fx-p-blue-900:              #172441;

    /* ══ 13.5.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue moved.
     * MEASURED, the ladder: 0 to 1 1.046, 1 to 2 1.045, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.30 / 10.42 / 5.23 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0:           #efeff8;
    --fx-color-level-1:           #f2f5fa;
    --fx-color-level-2:           #f7faff;
    --fx-color-bg-subtle:         #eaeaf3;
    --fx-color-surface-sunken:    #eaeaf3;

    --fx-color-text:              #1c1f2e;
    --fx-color-text-muted:        #353644;
    --fx-color-text-subtle:       #606370;
    --fx-color-text-faint:        #7c7f8c;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate
     * and that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:     rgba(32, 35, 59, 0.05);
    --fx-color-border:            rgba(32, 35, 59, 0.08);
    --fx-color-border-emphasis:   rgba(32, 35, 59, 0.14);
    --fx-color-divider-strong:    #d5d9e8;
    --fx-color-divider:           #e5e6f3;
    --fx-color-divider-faint:     #f0f1f9;
    --fx-color-field-bg-hover:    #fdfcfe;

    /* 2.4. Brand fill #3d459d, ink on it 7.38:1, white on it 8.28:1,
     * fill against the page 7.24:1. */
    --fx-color-primary:           var(--fx-p-indigo-800);
    --fx-color-primary-hover:     var(--fx-p-indigo-900);
    --fx-color-primary-active:    var(--fx-p-indigo-950);
    --fx-color-primary-subtle:    rgba(61, 69, 157, 0.10);
    --fx-color-primary-rgb:       61, 69, 157;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.28:1
     *   white 85 percent .......... 6.50:1
     *   white 72 percent .......... 5.18:1   idle rail rows and group headings
     *   white 54 percent .......... 3.64:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.233 / 1.435 / 1.584
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:              var(--fx-p-indigo-800);
    --fx-color-shell:             var(--fx-p-indigo-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:            var(--fx-p-indigo-accent-600);
    --fx-color-accent-hover:      var(--fx-p-indigo-accent-700);
    --fx-color-accent-subtle:     rgba(172, 106, 185, 0.14);
    --fx-color-accent-rgb:        172, 106, 185;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and
     * link the same, against a 4.5 bar. This is also where the owner's light
     * نص عليها is honoured: it lands on rung 900, which is one step deeper than
     * the resting ink here and is exactly what section 11 promotes these three
     * tokens onto when the user asks for more contrast. */
    --fx-color-indicator:         var(--fx-p-indigo-800);
    --fx-color-brand-text:        var(--fx-p-indigo-800);
    --fx-color-link:              var(--fx-p-indigo-800);
    --fx-color-link-hover:        var(--fx-p-indigo-900);
    --fx-color-link-rgb:          61, 69, 157;
    --fx-color-text-rgb:          28, 31, 46;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash
     * at alpha renders as a different hex on each of the four planes. Active is
     * mixed from the two rungs either side of it rather than being a sixth rung.
     * The four tiers over hover 13.93 / 10.15 / 5.09 / 3.39 and over active
     * 12.70 / 9.26 / 4.64 / 3.10. The ring over the two washes: 7.05 and 6.43. */
    --fx-color-focus-ring:        var(--fx-p-indigo-800);
    --fx-color-selection-bg:      var(--fx-p-indigo-wash-300);
    --fx-color-hover:             var(--fx-p-indigo-wash-100);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-indigo-wash-200) 70%, var(--fx-p-indigo-wash-100));
    --fx-color-disabled-bg:       #ebecf5;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on an indigo page. Geometry, blur and
     * alpha are untouched — only the three channels moved. */
    --fx-shadow-xs:               0 1px 2px rgba(32, 35, 59, 0.05);
    --fx-shadow-sm:               0 1px 4px -1px rgba(32, 35, 59, 0.09);
    --fx-shadow-md:               0 3px 12px rgba(32, 35, 59, 0.09);
    --fx-shadow-lg:               0 7px 24px rgba(32, 35, 59, 0.06);
    --fx-shadow-xl:               0 10px 32px rgba(32, 35, 59, 0.07);
    --fx-shadow-2xl:              0 16px 48px rgba(32, 35, 59, 0.08);
    --fx-shadow-float-sm:         0 1px 4px -1px rgba(32, 35, 59, 0.09);
    --fx-shadow-float-md:         0 3px 12px rgba(32, 35, 59, 0.09);
    --fx-shadow-float-lg:         0 7px 24px rgba(32, 35, 59, 0.06);
    --fx-shadow-stack:            inset 0 -1px 1px 0 rgba(32, 35, 59, 0.10), 0 5px 2px 0 rgba(32, 35, 59, 0.01), 0 3px 2px 0 rgba(32, 35, 59, 0.04), 0 1px 1px 0 rgba(32, 35, 59, 0.07), 0 0 1px 0 rgba(32, 35, 59, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load
     * bearing; read the rule over the olive declaration before touching it. */
    --fx-shadow-well:             inset 0 2px 2px rgba(32, 35, 59, 0.60), inset 0 5px 12px rgba(32, 35, 59, 0.10), inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset:            inset 0 1px 2px rgba(32, 35, 59, 0.08);
    --fx-shadow-press:            inset 0 1px 3px rgba(32, 35, 59, 0.10);
    --fx-color-focus-glow:        var(--fx-p-indigo-wash-200);
    --fx-color-focus-glow-soft:   var(--fx-p-indigo-wash-500);
    --fx-glass-bg:                rgba(247, 250, 255, 0.72);
    --fx-scrollbar-thumb:         rgba(32, 35, 59, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(32, 35, 59, 0.20);
    --fx-scrollbar-thumb-active:  rgba(32, 35, 59, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would
     * paint the olive green on an indigo page. Nothing is renamed. */
    --frihat-green-900:           var(--fx-p-indigo-900);
    --frihat-green-800:           var(--fx-p-indigo-800);
    --frihat-green-700:           var(--fx-p-indigo-700);
    --frihat-olive:               var(--fx-p-indigo-accent-600);
    --frihat-olive-2:             var(--fx-p-indigo-accent-500);
}

/* 13.5.8 INDIGO — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS
 * STRUCTURAL RATHER THAN TIDY. The light palette block is specificity 0,2,1 and
 * sits LATER in the file than the olive dark block, which is also 0,2,1, so on a
 * tie it wins. Every token the light block declares that any dark block also
 * declares must therefore be restated here at 0,3,1, or it would leak its LIGHT
 * value into this theme. Fifty seven tokens are in that category and all fifty
 * seven are below; a token that appears above and is missing here is a defect,
 * not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.050, 1 to 2 1.051, 2 to 3 1.054, 0 to 3 1.163.
 * The four text tiers on the page: 14.26 / 11.10 / 5.67 / 3.70, and on level 3
 * 12.26 / 9.55 / 4.88 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="indigo"][data-bs-theme="dark"]:root {
    --fx-color-level-0:           var(--fx-p-n-1000);
    --fx-color-level-1:           #1f212f;
    --fx-color-level-2:           #232533;
    --fx-color-level-3:           #272937;
    --fx-color-bg-subtle:         var(--fx-p-dark-well);
    --fx-color-surface-sunken:    var(--fx-p-dark-well);

    --fx-color-text:              #ebecf8;
    --fx-color-text-muted:        #ced2e1;
    --fx-color-text-subtle:       #9196a6;
    --fx-color-text-faint:        #737683;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and
     * that ink is this family's own primary text colour. */
    --fx-color-border-subtle:     rgba(235, 236, 248, 0.05);
    --fx-color-border:            rgba(235, 236, 248, 0.08);
    --fx-color-border-emphasis:   rgba(235, 236, 248, 0.14);
    --fx-color-divider-strong:    #393a44;
    --fx-color-divider:           #2a2b35;
    --fx-color-divider-soft:      #23242f;
    --fx-color-divider-faint:     #222331;
    --fx-color-field-bg-hover:    var(--fx-color-level-3);
    --fx-color-field-bg-focus:    #2a2d3c;

    /* 3.4. One ramp step brighter than light so the fill stays visible against
     * the page: white on it 5.16:1, fill against the page 3.24:1. */
    --fx-color-primary:           var(--fx-p-indigo-700);
    --fx-color-primary-hover:     var(--fx-p-indigo-800);
    --fx-color-primary-active:    var(--fx-p-indigo-900);
    --fx-color-primary-subtle:    rgba(86, 96, 217, 0.20);
    --fx-color-primary-rgb:       86, 96, 217;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the
     * planes a dropdown or a popup floats on, and it cannot move without
     * breaking its own ink, so it carries a rim instead. This family 600 rung
     * measures 4.18 / 3.98 / 3.79 / 3.60:1 on levels 0 to 3, the same figures
     * as every other family, because a rung is a luminance position. Against its
     * own fill it measures 1.29:1, which is the rim doing what a rim is for. */
    --fx-color-primary-border:    var(--fx-p-indigo-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand
     * surface and must read as one colour in both themes, so it stays on 800 and
     * accepts the same 2.03:1 against the dark page that the dated decision in
     * 3.4.1 accepted for olive. Its ink in dark is white, at 8.28:1, and the gold
     * mark on it 4.53:1. */
    --fx-color-band:              var(--fx-p-indigo-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5
     * does for olive: without this line the light block's brand fill would fall
     * through and dark would gain a mid indigo shell nobody asked for. */
    --fx-color-shell:             var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.061:1   one rung, as in olive
     *   white on the rail .................. 16.87:1
     *   white 72 / 55 / 38 percent ......... 9.22 / 5.90 / 3.52
     *   gold mark on the rail .............. 9.23:1
     *   washes, white at 8 / 14 / 18 percent 1.250 / 1.528 / 1.753 */
    --fx-color-rail:              color-mix(in srgb, var(--fx-p-indigo-900) 55%, var(--fx-p-black));

    --fx-color-accent:            var(--fx-p-indigo-accent-500);
    --fx-color-accent-hover:      var(--fx-p-indigo-accent-400);
    --fx-color-accent-subtle:     rgba(192, 127, 205, 0.18);
    --fx-color-accent-rgb:        192, 127, 205;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar, and that rung is where the owner's
     * dark أساسي #8A93F0 is honoured. Brand TEXT cannot be the brand ramp in
     * dark — rung 700 measures 3.24:1 on the page and fails 4.5 — so it takes the
     * wash ramp's deepest rung, 8.98:1 worst case, which is also where his dark
     * نص عليها #C7CCFA lands. Exactly the constraint the mint ramp solved for
     * olive, solved the same way with this family's own wash ramp rather than by
     * borrowing mint. */
    --fx-color-indicator:         var(--fx-p-indigo-500);
    --fx-color-brand-text:        var(--fx-p-indigo-wash-500);
    --fx-color-link:              var(--fx-p-indigo-wash-500);
    --fx-color-link-hover:        var(--fx-p-indigo-wash-400);
    --fx-color-link-rgb:          191, 202, 254;
    --fx-color-text-rgb:          235, 236, 248;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would
     * invert the elevation model. Measured, wash against its own host plane:
     *   hover  1.134 / 1.141 / 1.146 / 1.152 on levels 0 to 3
     *   active 1.246 / 1.261 / 1.271 / 1.264
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.87 / 4.61 / 4.37 / 4.12
     *   over active 4.43 / 4.17 / 3.94 / 3.76 */
    --fx-color-focus-ring:        var(--fx-p-indigo-500);
    --fx-color-selection-bg:      color-mix(in srgb, var(--fx-p-indigo-wash-500) 22%, transparent);
    --fx-color-hover:             color-mix(in srgb, var(--fx-p-indigo-wash-500) 6%, transparent);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-indigo-wash-500) 10%, transparent);
    --fx-color-disabled-bg:       #1f222e;

    /* Section 6, dark. The shadow ink is pure black in this theme for every
     * family — a hue tinted shadow on a near black page buys nothing — so these
     * are the olive values restated verbatim. They are restated rather than
     * inherited because the light block above declares the same names and would
     * otherwise win the 0,2,1 tie. */
    --fx-shadow-xs:               none;
    --fx-shadow-sm:               0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:               0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:               0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:               0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl:              0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm:         0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md:         0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg:         0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:            0 5px 2px 0 rgba(0, 0, 0, 0.02), 0 3px 2px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the ratio the olive
     * geometry was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:             inset 0 2px 2px rgba(235, 236, 248, 0.50), inset 0 6px 14px rgba(0, 0, 0, 0.45), inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset:            inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press:            inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:        color-mix(in srgb, var(--fx-p-indigo-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft:   var(--fx-p-indigo-wash-500);
    --fx-glass-bg:                rgba(31, 33, 47, 0.72);
    --fx-scrollbar-thumb:         rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active:  rgba(255, 255, 255, 0.40);
}

/* ── 13.6) NAVY — الكحلي ──
 *
 * ADDED 2026-09-04 (seventh pass, see the header). Numbered after 13.4 and placed
 * before it, for the reason recorded at the head of 13.5.
 *
 * ══ THE OWNER SUPPLIED SIX VALUES FOR THIS FAMILY, NOT ONE ═════════════════
 *
 * Recorded verbatim before anything is derived from them:
 *
 *     light   أساسي #0B4F9E   خلفية #E7F0FA   نص عليها #083A75
 *     dark    أساسي #5B9BE8   خلفية #14314F   نص عليها #BBD7F6
 *
 * ══ WHAT ROLE EACH SUPPLIED VALUE ACTUALLY FILLS ═══════════════════════════
 *
 * The same reading as 13.5, and the same measurement backs it. نص عليها is NOT
 * fx-color-text-on-primary, which is the ink on the SOLID brand fill:
 *     light  #083A75 on #0B4F9E ........ 1.40:1
 *     dark   #BBD7F6 on #5B9BE8 ........ 1.94:1
 * Against the owner's خلفية the same two inks measure 9.74:1 and 8.95:1. So the
 * trio is brand, subtle ground, ink for that ground, and this file spends those
 * three roles as the SEED, the pale ramp rung, and the deep brand ink.
 *
 * ══ WHERE EACH SUPPLIED VALUE LANDED, MEASURED RATHER THAN ASSERTED ════════
 *
 *   light أساسي   #0B4F9E  →  rung 800 #014e97 ................ OKLab dE 0.0126
 *   light خلفية    #E7F0FA  →  rung 100 #e1efff ................ OKLab dE 0.0109
 *   light نص عليها #083A75  →  rung 900 #013568 ................ OKLab dE 0.0270
 *   dark  أساسي   #5B9BE8  →  rung 500 #3a95ff ................ OKLab dE 0.0479
 *   dark  خلفية    #14314F  →  primary-subtle over a card ....... OKLab dE 0.0010
 *   dark  نص عليها #BBD7F6  →  wash rung 500 #abcfff ........... OKLab dE 0.0349
 *
 * THIS FAMILY'S LIGHT أساسي IS HONOURED DIRECTLY AS THE BRAND FILL, which no
 * earlier family managed. Its lightness puts it on rung 800, and rung 800 IS
 * fx-color-primary in light in every family, so #0B4F9E arrives as #014e97 and is
 * the fill on the button, the band and the shell. The 0.0126 of OKLab distance
 * between the two is the price of pinning the rung to the spine's luminance, and
 * it is a fifth of a just noticeable difference.
 *
 * THE DARK خلفية IS EVEN CLOSER, at OKLab dE 0.0010. fx-color-primary-subtle in
 * dark is the dark brand fill at 20 percent alpha, a formula older than this
 * family, and composited over this family's level 1 card it is indistinguishable
 * from the value the owner typed. Nothing was tuned to make that happen.
 *
 * THE LIGHT خلفية IS THE LOOSEST FIT OF THE SIX. The same formula at 10 percent
 * composites to #dae4f0, dE 0.0366 from #E7F0FA, because a translucent tint of a
 * rung 800 fill is darker than a hand picked rung 100. The ramp rung is the closer
 * match at dE 0.0109 and is where the value is recorded. fx-color-primary-subtle
 * was NOT re-specified as an opaque hex to close that gap; 2.4 makes it
 * translucent on purpose so it works on any of the four planes.
 *
 * ══ THE ONE CONFLICT, RAISED AND NOT SILENTLY RESOLVED ═════════════════════
 *
 * THE DARK أساسي CANNOT BE fx-color-primary IN DARK. #5B9BE8 is a bright blue
 * meant to carry DARK ink; this system's dark brand fill carries white in every
 * family. Measured, white on #5B9BE8:
 *     2.88:1 — against the 4.5:1 that SC 1.4.3 asks of a button label.
 * The system's dark fill, rung 700 #036dcd, measures 5.16:1 on the same ink.
 *
 * IT IS HONOURED, AT THE RUNG ITS OWN LIGHTNESS PUTS IT ON: rung 500, which in
 * dark is fx-color-indicator and fx-color-focus-ring, the bright brand MARK.
 * 3.5.1 already rules that a bright brand colour in a dark theme is a mark and
 * not a fill. Measured there: 4.75:1 worst case over levels 0 to 3.
 *
 * ══ WHERE THE SEED LANDS ON THE FROZEN LADDER ══════════════════════════════
 *
 * SEED #0B4F9E. Measured: OKLCH L 0.4368 C 0.1431 H 256.4, relative luminance
 * 0.08132. Placed by OKLab LIGHTNESS: the seed sits at L 0.4368 and the green
 * spine's 800 rung at L 0.4145, a difference of 0.0222, and no other rung comes
 * close. So it is the 800 rung of this family and it arrives as #014e97.
 *
 * The RELATIVE luminance moves with it, from the seed's 0.08132 to the rung's
 * 0.07691, which is the smallest such move any family has made and is why this
 * seed lands on the fill itself. Relative luminance is a nonlinear coordinate, so
 * quote the L figure above, not this one, when judging how far the seed moved.
 *
 * AND THE SEED NAMES THE FAMILY IDENTITY, NOT ITS INK, in this family as in every
 * other. That it happens to coincide with the ink rung here is arithmetic, not a
 * new rule, and nothing downstream depends on it. Every ink pairing in 13.6.7 and
 * 13.6.8 below is measured against its own plane.
 *
 * HUE 254.4, THE CHROMA WEIGHTED MEAN OF ALL SIX SUPPLIED VALUES rather than of
 * the light seed alone. The six anchors span 5.6 degrees; weighting each by its
 * own chroma gives 254.4 against the light seed's 256.4 on its own, a move of
 * OKLab dE 0.005 on the flagship value. The mean is used because it honours six
 * anchors instead of one and costs nothing to do so.
 *
 * CHROMA. s = 1.508, the seed's chroma over the green spine's chroma at that
 * rung, the highest scale in the system. Held flat at and below the seed rung and
 * relaxed linearly to 1.0 at rung 50. Where sRGB cannot hold the target chroma at
 * a given luminance the chroma is reduced until it fits and THE LUMINANCE IS
 * HELD. This hue clips hard: several rungs sit against the blue face of the gamut
 * with the red channel at or near zero, which is legal sRGB and is what a
 * saturated navy looks like. Worst luminance drift on this ramp: 0.104 percent.
 *
 * ACCENT HUE 294.4, +40.0 degrees of OKLCH hue from the brand, which reads as a
 * violet periwinkle. Measured against the four status families it is nearest the
 * info blue at 40.2 degrees and the danger red at 95.1. The offset is larger than
 * the +27 the earlier families use, and the reason is the entry below: this brand
 * sits ON the info hue, so anything closer than about 35 degrees in either
 * direction lands on a status.
 *
 * ══ RAISED LOUDLY: THIS BRAND IS THE INFO STATUS HUE, TO A FIFTH OF A DEGREE ══
 *
 * p-blue-600, the info status foreground, is at OKLCH hue 254.2. This brand is at
 * 254.4. That is 0.2 degrees, and it makes this the closest a brand hue and a
 * status hue come anywhere in the system by a wide margin — the previous record
 * was النبيذي at 19.9 degrees from the danger red, which the sixth pass already
 * flagged. الكحلي is a navy and the platform's info status is a blue, so this
 * comes with the colour the owner chose. The status hues do not move, and
 * rotating the brand would mean not shipping الكحلي, so IT WAS NOT ROTATED.
 *
 * IT IS NOT A CONTRAST DEFECT, AND THAT IS WORTH SAYING FIRST. Every info pairing
 * in this family measures within a hundredth of olive. The info foreground on its
 * tint is 5.66:1 in light and 7.89:1 in dark, exactly as everywhere else.
 *
 * WHAT IS AT RISK IS RECOGNITION, AND IT IS AT RISK IN TWO PLACES:
 *   · AS A SOLID FILL the two separate by LIGHTNESS. The brand fill is rung 800 at
 *     relative luminance 0.07690 while p-blue-600 sits at 0.11273, so they measure
 *     1.28:1 apart. That is thin. It is the same shape of separation النبيذي has
 *     against the danger red, at 1.36:1, and the same mitigation applies: 2.7
 *     rules that a status which is READ takes its fg token, and a status chip
 *     carries its own tint background AND its own border.
 *   · AS A PALE TINT they do not separate at all. This family's rung 100 and its
 *     own info tint background measure OKLab dE 0.0100 apart, which is under a
 *     just noticeable difference. An info panel and a brand tinted panel on a navy
 *     page are the same colour, and on this family the INK does not rescue it
 *     either, because the brand ink and p-blue-600 share the hue.
 *
 * SO ON THIS FAMILY THE ICON AND THE LABEL CARRY THE INFO MEANING, NOT THE HUE.
 * That is already how 08-feedback builds an alert and it is what SC 1.4.1 asks for
 * in any case; this family is simply the first one where the colour alone would
 * not have done the job. Raised for the owner rather than corrected, with the
 * numbers, so the decision to keep الكحلي is an informed one.
 * ─────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="navy"]:root {
    /* 13.6.1 THE NAVY RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. */
    --fx-p-navy-50:               #f1f6ff;
    --fx-p-navy-100:              #e1efff;
    --fx-p-navy-200:              #c7dfff;
    --fx-p-navy-300:              #9bc8fe;
    --fx-p-navy-400:              #6dadff;
    --fx-p-navy-500:              #3a95ff;
    --fx-p-navy-600:              #097eef;
    --fx-p-navy-700:              #036dcd;
    --fx-p-navy-800:              #014e97;
    --fx-p-navy-900:              #013568;
    --fx-p-navy-950:              #04264c;

    /* 13.6.2 THE ACCENT RAMP — a violet periwinkle. The decorative companion,
     * holding the olive ramp's luminance at every rung so 2.5 and 3.5 keep their
     * figures. It is NOT a second brand: 3.9 governs where it may be spent and
     * that contract is unchanged for every family. Chroma is the olive ramp's own,
     * scaled by min(s, 1.0) and gamut clipped. Worst luminance drift against the
     * olive ramp: 0.070 percent. */
    --fx-p-navy-accent-100:       #f1ecfe;
    --fx-p-navy-accent-200:       #e6dfff;
    --fx-p-navy-accent-300:       #d5c9fe;
    --fx-p-navy-accent-400:       #c3b2ff;
    --fx-p-navy-accent-500:       #9f89e3;
    --fx-p-navy-accent-600:       #8b74d1;
    --fx-p-navy-accent-700:       #7963b3;
    --fx-p-navy-accent-800:       #5d4c8b;

    /* 13.6.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It
     * is not extended, not tinted and not reused here, and there is still no
     * sixth mint rung. This is a SEPARATE ramp that reproduces mint's five
     * relative luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at
     * this family's own hue. Worst drift: 0.045 percent.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.027   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.125  on level 1 1.177  on level 2 1.229 */
    --fx-p-navy-wash-100:         #e2eefe;
    --fx-p-navy-wash-200:         #c9e1ff;
    --fx-p-navy-wash-300:         #bfdbfe;
    --fx-p-navy-wash-400:         #b5d5ff;
    --fx-p-navy-wash-500:         #abcfff;

    /* 13.6.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES
     * WHETHER THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside
     * the olive. A green tinted grey under a navy page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels
     * on a legal screen. So the ramp is restated at THIS family's hue, at the
     * SAME OKLCH chroma rung for rung and at the SAME relative luminance rung for
     * rung, which is what keeps the elevation ladder's 1.04 to 1.06 steps
     * identical. n 0 is white in every family and is not restated. Worst
     * luminance drift on this ramp: 0.18 percent. */
    --fx-p-n-25:                  #fafdfe;
    --fx-p-n-50:                  #f3f6fd;
    --fx-p-n-100:                 #e7eef6;
    --fx-p-n-200:                 #d6e0ee;
    --fx-p-n-300:                 #becadc;
    --fx-p-n-400:                 #9baabb;
    --fx-p-n-500:                 #7b8a9a;
    --fx-p-n-600:                 #5e6877;
    --fx-p-n-700:                 #46505b;
    --fx-p-n-800:                 #313842;
    --fx-p-n-900:                 #1f2836;
    --fx-p-n-950:                 #182535;
    --fx-p-n-1000:                #161e2b;

    /* 13.6.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they
     * are deliberately hue tinted rather than points on the neutral ramp, so
     * they are re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated:         #1a2c40;
    --fx-p-dark-sunken:           #171f2c;
    --fx-p-dark-well:             #0f1821;
    --fx-p-dark-ink:              #101a24;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white
     * for the same reason; this is the same value at this family's hue.
     * Measured on the light brand fill: 7.38:1. In DARK the semantic that reads
     * this primitive is overridden to white by section 3, so the dark band's ink
     * measures 8.27:1 rather than this figure. */
    --fx-p-on-primary:            #eaf3fd;

    /* 13.6.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with
     * the palette would stop being a danger red, so the 200 / 300 / 600 / 800
     * grades in 1.6 are untouched in every family and are NOT restated here.
     * What is restated is the two TINT BACKGROUNDS, because a tint sits on this
     * family's neutral and has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and
     * takes the family's neutral cast added at 0.35 of the neutral's own hue
     * shift, the same fraction the three families of the sixth pass use. Measured
     * here, the worst drift from the olive tint it replaces is 28.2 degrees, so
     * this family satisfies the 30 degree bound at 0.35 and the fraction did not
     * have to move as it did for النيلي. Luminance is preserved exactly, so every
     * status foreground keeps its measured ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.68:1
     *   amber    fg on tint  light 5.18:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.89:1
     * The info tint is the one to read twice on this family: see the recognition
     * entry in the header above. Its CONTRAST is unchanged; what it no longer has
     * is a hue that distinguishes it from the brand. */
    --fx-p-emerald-100:           #e5f4f2;
    --fx-p-emerald-900:           #142f28;
    --fx-p-amber-100:             #fcf1e3;
    --fx-p-amber-900:             #342518;
    --fx-p-red-100:               #faecf1;
    --fx-p-red-900:               #36171d;
    --fx-p-blue-100:              #e7f1fe;
    --fx-p-blue-900:              #142443;

    /* ══ 13.6.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue moved.
     * MEASURED, the ladder: 0 to 1 1.046, 1 to 2 1.045, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.28 / 10.42 / 5.23 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0:           #ecf0f7;
    --fx-color-level-1:           #f2f5fa;
    --fx-color-level-2:           #f7faff;
    --fx-color-bg-subtle:         #e7ebf2;
    --fx-color-surface-sunken:    #e7ebf2;

    --fx-color-text:              #16212b;
    --fx-color-text-muted:        #2f3841;
    --fx-color-text-subtle:       #5c6471;
    --fx-color-text-faint:        #78808d;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate
     * and that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:     rgba(19, 38, 58, 0.05);
    --fx-color-border:            rgba(19, 38, 58, 0.08);
    --fx-color-border-emphasis:   rgba(19, 38, 58, 0.14);
    --fx-color-divider-strong:    #d2dae7;
    --fx-color-divider:           #dfe8f1;
    --fx-color-divider-faint:     #ecf2fb;
    --fx-color-field-bg-hover:    #fcfcff;

    /* 2.4. Brand fill #014e97 — the owner's own أساسي on the ladder — ink on it
     * 7.38:1, white on it 8.27:1, fill against the page 7.24:1. */
    --fx-color-primary:           var(--fx-p-navy-800);
    --fx-color-primary-hover:     var(--fx-p-navy-900);
    --fx-color-primary-active:    var(--fx-p-navy-950);
    --fx-color-primary-subtle:    rgba(1, 78, 151, 0.10);
    --fx-color-primary-rgb:       1, 78, 151;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.27:1
     *   white 85 percent .......... 6.42:1
     *   white 72 percent .......... 5.07:1   idle rail rows and group headings
     *   white 54 percent .......... 3.56:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.207 / 1.406 / 1.549
     * These are the thinnest shell figures of the six families, because this is
     * the most chromatic fill on the 800 rung, and they still clear every floor:
     * the 54 percent tier is an SC 1.4.11 boundary at a 3.0 bar and measures 3.56.
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:              var(--fx-p-navy-800);
    --fx-color-shell:             var(--fx-p-navy-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:            var(--fx-p-navy-accent-600);
    --fx-color-accent-hover:      var(--fx-p-navy-accent-700);
    --fx-color-accent-subtle:     rgba(139, 116, 209, 0.14);
    --fx-color-accent-rgb:        139, 116, 209;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and
     * link the same, against a 4.5 bar. The owner's light نص عليها lands on rung
     * 900, one step deeper than the resting ink here, which is exactly what
     * section 11 promotes these three tokens onto. */
    --fx-color-indicator:         var(--fx-p-navy-800);
    --fx-color-brand-text:        var(--fx-p-navy-800);
    --fx-color-link:              var(--fx-p-navy-800);
    --fx-color-link-hover:        var(--fx-p-navy-900);
    --fx-color-link-rgb:          1, 78, 151;
    --fx-color-text-rgb:          22, 33, 43;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash
     * at alpha renders as a different hex on each of the four planes. Active is
     * mixed from the two rungs either side of it rather than being a sixth rung.
     * The four tiers over hover 13.91 / 10.15 / 5.09 / 3.40 and over active
     * 12.70 / 9.27 / 4.65 / 3.10. The ring over the two washes: 7.05 and 6.44. */
    --fx-color-focus-ring:        var(--fx-p-navy-800);
    --fx-color-selection-bg:      var(--fx-p-navy-wash-300);
    --fx-color-hover:             var(--fx-p-navy-wash-100);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-navy-wash-200) 70%, var(--fx-p-navy-wash-100));
    --fx-color-disabled-bg:       #e8edf4;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a navy page. Geometry, blur and alpha
     * are untouched — only the three channels moved. */
    --fx-shadow-xs:               0 1px 2px rgba(19, 38, 58, 0.05);
    --fx-shadow-sm:               0 1px 4px -1px rgba(19, 38, 58, 0.09);
    --fx-shadow-md:               0 3px 12px rgba(19, 38, 58, 0.09);
    --fx-shadow-lg:               0 7px 24px rgba(19, 38, 58, 0.06);
    --fx-shadow-xl:               0 10px 32px rgba(19, 38, 58, 0.07);
    --fx-shadow-2xl:              0 16px 48px rgba(19, 38, 58, 0.08);
    --fx-shadow-float-sm:         0 1px 4px -1px rgba(19, 38, 58, 0.09);
    --fx-shadow-float-md:         0 3px 12px rgba(19, 38, 58, 0.09);
    --fx-shadow-float-lg:         0 7px 24px rgba(19, 38, 58, 0.06);
    --fx-shadow-stack:            inset 0 -1px 1px 0 rgba(19, 38, 58, 0.10), 0 5px 2px 0 rgba(19, 38, 58, 0.01), 0 3px 2px 0 rgba(19, 38, 58, 0.04), 0 1px 1px 0 rgba(19, 38, 58, 0.07), 0 0 1px 0 rgba(19, 38, 58, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load
     * bearing; read the rule over the olive declaration before touching it. */
    --fx-shadow-well:             inset 0 2px 2px rgba(19, 38, 58, 0.60), inset 0 5px 12px rgba(19, 38, 58, 0.10), inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset:            inset 0 1px 2px rgba(19, 38, 58, 0.08);
    --fx-shadow-press:            inset 0 1px 3px rgba(19, 38, 58, 0.10);
    --fx-color-focus-glow:        var(--fx-p-navy-wash-200);
    --fx-color-focus-glow-soft:   var(--fx-p-navy-wash-500);
    --fx-glass-bg:                rgba(247, 250, 255, 0.72);
    --fx-scrollbar-thumb:         rgba(19, 38, 58, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(19, 38, 58, 0.20);
    --fx-scrollbar-thumb-active:  rgba(19, 38, 58, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would
     * paint the olive green on a navy page. Nothing is renamed. */
    --frihat-green-900:           var(--fx-p-navy-900);
    --frihat-green-800:           var(--fx-p-navy-800);
    --frihat-green-700:           var(--fx-p-navy-700);
    --frihat-olive:               var(--fx-p-navy-accent-600);
    --frihat-olive-2:             var(--fx-p-navy-accent-500);
}

/* 13.6.8 NAVY — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS
 * STRUCTURAL RATHER THAN TIDY. The light palette block is specificity 0,2,1 and
 * sits LATER in the file than the olive dark block, which is also 0,2,1, so on a
 * tie it wins. Every token the light block declares that any dark block also
 * declares must therefore be restated here at 0,3,1, or it would leak its LIGHT
 * value into this theme. Fifty seven tokens are in that category and all fifty
 * seven are below; a token that appears above and is missing here is a defect,
 * not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.048, 1 to 2 1.051, 2 to 3 1.054, 0 to 3 1.161.
 * The four text tiers on the page: 14.26 / 11.10 / 5.67 / 3.70, and on level 3
 * 12.29 / 9.56 / 4.89 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="navy"][data-bs-theme="dark"]:root {
    --fx-color-level-0:           var(--fx-p-n-1000);
    --fx-color-level-1:           #1a2230;
    --fx-color-level-2:           #1e2634;
    --fx-color-level-3:           #222a38;
    --fx-color-bg-subtle:         var(--fx-p-dark-well);
    --fx-color-surface-sunken:    var(--fx-p-dark-well);

    --fx-color-text:              #e5eef6;
    --fx-color-text-muted:        #cad3e2;
    --fx-color-text-subtle:       #8e97a5;
    --fx-color-text-faint:        #6f7784;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and
     * that ink is this family's own primary text colour. */
    --fx-color-border-subtle:     rgba(229, 238, 246, 0.05);
    --fx-color-border:            rgba(229, 238, 246, 0.08);
    --fx-color-border-emphasis:   rgba(229, 238, 246, 0.14);
    --fx-color-divider-strong:    #353b44;
    --fx-color-divider:           #262c36;
    --fx-color-divider-soft:      #20252d;
    --fx-color-divider-faint:     #1b252f;
    --fx-color-field-bg-hover:    var(--fx-color-level-3);
    --fx-color-field-bg-focus:    #232f3a;

    /* 3.4. One ramp step brighter than light so the fill stays visible against
     * the page: white on it 5.16:1, fill against the page 3.25:1. */
    --fx-color-primary:           var(--fx-p-navy-700);
    --fx-color-primary-hover:     var(--fx-p-navy-800);
    --fx-color-primary-active:    var(--fx-p-navy-900);
    --fx-color-primary-subtle:    rgba(3, 109, 205, 0.20);
    --fx-color-primary-rgb:       3, 109, 205;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the
     * planes a dropdown or a popup floats on, and it cannot move without
     * breaking its own ink, so it carries a rim instead. This family 600 rung
     * measures 4.18 / 3.99 / 3.79 / 3.60:1 on levels 0 to 3, the same figures
     * as every other family, because a rung is a luminance position. Against its
     * own fill it measures 1.29:1, which is the rim doing what a rim is for. */
    --fx-color-primary-border:    var(--fx-p-navy-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand
     * surface and must read as one colour in both themes, so it stays on 800 and
     * accepts the same 2.03:1 against the dark page that the dated decision in
     * 3.4.1 accepted for olive. Its ink in dark is white, at 8.27:1, and the gold
     * mark on it 4.53:1. */
    --fx-color-band:              var(--fx-p-navy-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5
     * does for olive: without this line the light block's brand fill would fall
     * through and dark would gain a mid navy shell nobody asked for. */
    --fx-color-shell:             var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.054:1   one rung, as in olive
     *   white on the rail .................. 16.99:1
     *   white 72 / 55 / 38 percent ......... 9.23 / 5.86 / 3.48
     *   gold mark on the rail .............. 9.30:1
     *   washes, white at 8 / 14 / 18 percent 1.242 / 1.519 / 1.743 */
    --fx-color-rail:              color-mix(in srgb, var(--fx-p-navy-900) 55%, var(--fx-p-black));

    --fx-color-accent:            var(--fx-p-navy-accent-500);
    --fx-color-accent-hover:      var(--fx-p-navy-accent-400);
    --fx-color-accent-subtle:     rgba(159, 137, 227, 0.18);
    --fx-color-accent-rgb:        159, 137, 227;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar, and that rung is where the owner's
     * dark أساسي #5B9BE8 is honoured. Brand TEXT cannot be the brand ramp in
     * dark — rung 700 measures 3.25:1 on the page and fails 4.5 — so it takes the
     * wash ramp's deepest rung, 9.00:1 worst case, which is also where his dark
     * نص عليها #BBD7F6 lands. Exactly the constraint the mint ramp solved for
     * olive, solved the same way with this family's own wash ramp rather than by
     * borrowing mint. */
    --fx-color-indicator:         var(--fx-p-navy-500);
    --fx-color-brand-text:        var(--fx-p-navy-wash-500);
    --fx-color-link:              var(--fx-p-navy-wash-500);
    --fx-color-link-hover:        var(--fx-p-navy-wash-400);
    --fx-color-link-rgb:          171, 207, 255;
    --fx-color-text-rgb:          229, 238, 246;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would
     * invert the elevation model. Measured, wash against its own host plane:
     *   hover  1.142 / 1.138 / 1.143 / 1.149 on levels 0 to 3
     *   active 1.256 / 1.254 / 1.264 / 1.274
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.83 / 4.62 / 4.38 / 4.14
     *   over active 4.39 / 4.20 / 3.96 / 3.73 */
    --fx-color-focus-ring:        var(--fx-p-navy-500);
    --fx-color-selection-bg:      color-mix(in srgb, var(--fx-p-navy-wash-500) 22%, transparent);
    --fx-color-hover:             color-mix(in srgb, var(--fx-p-navy-wash-500) 6%, transparent);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-navy-wash-500) 10%, transparent);
    --fx-color-disabled-bg:       #1c232c;

    /* Section 6, dark. The shadow ink is pure black in this theme for every
     * family — a hue tinted shadow on a near black page buys nothing — so these
     * are the olive values restated verbatim. They are restated rather than
     * inherited because the light block above declares the same names and would
     * otherwise win the 0,2,1 tie. */
    --fx-shadow-xs:               none;
    --fx-shadow-sm:               0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:               0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:               0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:               0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl:              0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm:         0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md:         0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg:         0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:            0 5px 2px 0 rgba(0, 0, 0, 0.02), 0 3px 2px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the ratio the olive
     * geometry was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:             inset 0 2px 2px rgba(229, 238, 246, 0.50), inset 0 6px 14px rgba(0, 0, 0, 0.45), inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset:            inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press:            inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:        color-mix(in srgb, var(--fx-p-navy-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft:   var(--fx-p-navy-wash-500);
    --fx-glass-bg:                rgba(26, 34, 48, 0.72);
    --fx-scrollbar-thumb:         rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active:  rgba(255, 255, 255, 0.40);
}

/* ── 13.7) GRAPHITE — الفحمي ──
 *
 * ADDED 2026-09-05 (eighth pass, see the header). NUMBERED AFTER 13.4 BUT PLACED
 * BEFORE IT, for the reason 13.5 and 13.6 already record: 13.4 restates section 11
 * and has to remain the LAST thing in this file, so every family added after it
 * takes the next free number and sits above it. Read the ordinal as an identifier,
 * not as a position.
 *
 * ══ THIS FAMILY IS NOT A SEVENTH COLOUR. IT IS THE ABSENCE OF ONE ══════════
 *
 * الفحمي is on the list for two reasons that have nothing to do with hue. In a tool
 * people sit inside for a working day the NEUTRAL theme is consistently the one most
 * often chosen, because a saturated chrome that is pleasant for a minute is tiring
 * for six hours. And in a picker that now shows EIGHT discs it is the easiest single
 * chip to identify, precisely because it is the only one that is not a colour.
 *
 * ══ THE TRAP THIS FAMILY WAS DERIVED AGAINST, AND THE THREE NUMBERS ════════
 *
 * A BRAND FILL WITH NO CHROMA READS AS DISABLED. A dead grey solid on a primary
 * button looks like a control that is switched off, and this file ships a real
 * fx-color-disabled-bg and fx-color-disabled-fg pair for exactly that state. So the
 * family had to be measured against three obligations at once rather than styled:
 *
 *   1. IS THE FILL A COLOUR OR IS IT GREY PAINT? Measured against an ACHROMATIC grey
 *      of identical relative luminance, which is the only honest control:
 *          light  fx-color-primary #405061 vs #504e4d ...... OKLab dE 0.0378
 *          dark   fx-color-primary #5a6f89 vs #6e6d6d ...... OKLab dE 0.0488
 *      A just noticeable difference on this axis is about 0.02, so the fill sits
 *      roughly two JND from dead grey in light and two and a half in dark. It is a
 *      colour. It is a quiet one, which is the entire brief.
 *
 *   2. CAN A USER TELL THE BRAND FILL FROM A DISABLED CONTROL? Measured both ways:
 *          light  primary #405061 against disabled bg #e8edf4 .... 7.03:1
 *          dark   primary #5a6f89 against disabled bg #1c232c .... 3.07:1
 *      Both clear the 3:1 an object boundary owes, and the light figure clears it
 *      more than twice over. The two states also separate by INK, which is the part
 *      a ratio between two fills does not capture: a disabled control carries its
 *      disabled ink at 3.39:1 in light and 3.50:1 in dark, while the primary button
 *      carries its on primary ink at 7.38:1 and white at 5.16:1. A disabled control
 *      is dim BY CONSTRUCTION and the brand fill is not, in both directions.
 *
 *   3. IS IT STILL GREY RATHER THAN A SEVENTH BLUE? This is the one that came back
 *      uncomfortable and it is RAISED rather than smoothed over. Measured, OKLCH hue
 *      against the three families already in the blue arc:
 *          vs الأزرق البترولي  hue 187.5 ....... 69.5 degrees
 *          vs النيلي           hue 275.0 ....... 18.0 degrees
 *          vs الكحلي           hue 254.2 ........ 2.8 degrees
 *      TWO POINT EIGHT DEGREES FROM THE NAVY BRAND is the closest two brand hues have
 *      ever come in this system; the previous record was النيلي against الكحلي at
 *      20.8. WHAT SEPARATES THEM IS CHROMA, NOT HUE: this family's seed carries OKLCH
 *      C 0.0349 at its rung where الكحلي carries 0.1363, a ratio of 3.91 to 1, so one
 *      is a saturated blue and the other is a grey with a blue cast. That is the
 *      difference a user actually sees, and it is also the difference the name says.
 *      The hue was NOT rotated to open the gap; the owner chose these colours.
 *
 * ══ THE OWNER SUPPLIED TWO VALUES ══════════════════════════════════════════
 *
 * Recorded verbatim before anything is derived from them:
 *
 *     light  أساسي #475569        dark  أساسي #94A3B8
 *
 * Unlike النيلي and الكحلي this family arrived without a خلفية or a نص عليها, so the
 * two values fix the HUE and the CHROMA SCALE and every other role is derived by the
 * rules in 13.0 rather than pinned by the owner's eye.
 *
 * ══ WHERE THE SEEDS LAND ON THE FROZEN LADDER ══════════════════════════════
 *
 * LIGHT SEED #475569. Measured: OKLCH L 0.4455 C 0.0374 H 257.3, relative luminance
 * 0.08857. Placed by OKLab LIGHTNESS, the perceptual coordinate: the green spine's
 * 800 rung sits at L 0.4145, a difference of 0.0310, and the next nearest rung, 700
 * at L 0.5216, is more than twice as far. So it is the 800 rung of this family and
 * it arrives as #405061, OKLab dE 0.0217 from the value the owner typed.
 *
 * AND RUNG 800 IN LIGHT IS fx-color-primary. That is worth naming, because it is
 * the first family where the seed lands directly on the light brand fill rather than
 * on a relative of it: the colour the owner chose IS the button, to within a fifth of
 * a JND, and no interpretation stands between the two.
 *
 * DARK SEED #94A3B8, OKLCH L 0.7107 C 0.0351 H 256.8, lands on rung 400 at L 0.7245,
 * a difference of 0.0138 against 0.0603 for rung 500, and arrives as #98acc8 at
 * OKLab dE 0.0300. RUNG 400 IN DARK IS NOT A RESTING SEMANTIC. It is the rung
 * section 11 PROMOTES fx-color-indicator onto when the user asks for more contrast;
 * the resting mark is rung 500, one step deeper. Recorded rather than forced: no
 * token was moved to make the dark seed land on a resting role, and the seed still
 * governs the family through the hue and the chroma scale it sets.
 *
 * ══ THE CHROMA DECISION, WHICH IS THE WHOLE FAMILY ═════════════════════════
 *
 * s = 0.395, the light seed's chroma over the green spine's chroma at its rung
 * (0.0374 over 0.0949). It is by a wide margin the lowest scale in the system, where
 * الرملي الدافئ sits at 0.842 and النيلي at 1.484, and it is what makes the family
 * grey. It is the SEED'S OWN, not a number chosen for effect: 13.0 rules that a seed
 * fixes the hue and the chroma scale, and raising the scale to make the fill look
 * more deliberate would have shipped a colour the owner did not pick, on every
 * surface at once, to answer a worry rather than a measurement. The measurements in
 * obligation 1 above say the seed's own chroma already clears the bar.
 *
 * ONE RULE IN 13.0 IS REFINED HERE, AND THE REFINEMENT IS STATED RATHER THAN SLIPPED
 * IN. Every family so far relaxes its chroma scale LINEARLY TO 1.0 AT RUNG 50, so
 * "the pale end of the ramp cannot go neon". That clause was written for scales
 * ABOVE 1.0, where relaxing toward 1.0 REDUCES chroma. At s 0.395 the same formula
 * runs the other way and would make this family's pale rungs two and a half times
 * more saturated than its deep ones, which is a blue ramp with a grey bottom rather
 * than a grey family. So the relaxation is read as a CAP and not as a target:
 *      s at rung i = min(s, the linear relaxation)
 * For every family whose scale is above 1.0 that expression is identical to the
 * formula already shipped, which is why النيلي and الكحلي re-derive byte for byte
 * under it. الرملي الدافئ, whose scale is 0.842, WAS NOT RE-DERIVED and did not move;
 * its pale rungs are left exactly as the sixth pass shipped them.
 *
 * ══ HOW THE SURFACES STAY DISTINGUISHABLE FROM THE BRAND ═══════════════════
 *
 * This is the question every other family answers for free and this one has to
 * answer on purpose, because its neutral ramp and its brand ramp share a hue and sit
 * only a factor of 1.6 apart in chroma. THE ANSWER IS LUMINANCE, AND IT IS
 * STRUCTURAL RATHER THAN LUCKY.
 *
 * The brand fill lives at OKLab L 0.4245 in light and 0.5348 in dark. No surface in
 * either mode is anywhere near it: the light planes run L 0.9532 to 1.0 and the dark
 * planes L 0.2301 to 0.2809. Measured, the fill against every plane it can land on:
 *      light   7.24 / 7.57 / 7.91 / 8.27:1 on levels 0 to 3
 *      dark    3.24 / 3.09 / 2.94 / 2.79:1 on levels 0 to 3
 * Those are the same figures every family measures, because a rung is a luminance
 * position. The dark row is the systemic carve out recorded in 3.4.2 and the fill
 * carries fx-color-primary-border at 4.18 / 3.98 / 3.79 / 3.60:1 for SC 1.4.11.
 *
 * The nearest the two ramps ever come is a comparison no screen actually renders:
 * the brand fill against the NEUTRAL RUNG of the same lightness, n 700 #46505b, at
 * OKLab dE 0.0127. That rung is a divider ink in dark and a text tier nowhere; it is
 * never a plane the brand sits on. Where the two ramps DO meet on screen, which is a
 * brand fill on a page surface, they are seven to eight ratio points apart in light
 * and carry a rim in dark.
 *
 * ══ HUE AND ACCENT ═════════════════════════════════════════════════════════
 *
 * HUE 257.0, the chroma weighted mean of the two supplied values (257.3 and 256.8).
 * The two anchors span half a degree, which is what a two value palette picked by eye
 * from one Tailwind slate column looks like, so the mean is a formality here rather
 * than a reconciliation.
 *
 * ACCENT HUE 297.0, +40.0 degrees of OKLCH hue from the brand, which reads as a
 * lavender grey. Measured against the four status families it is nearest the info
 * blue at 42.9 degrees. A NEGATIVE rotation was rejected on the numbers: minus 27
 * lands on 230.0, only 24.1 degrees from the info blue, and minus 40 lands on 217.0
 * at 37.1, still inside the arc this family's own brand already occupies. The
 * positive sign also flips the TEMPERATURE, which is the property doing the work
 * here: at this chroma the accent cannot separate from the brand by saturation, so
 * it separates by sitting on the other side of neutral.
 *
 * RAISED, MEASURED, NOT CORRECTED: the accent ramp is scaled by min(s, 1.0) like
 * every other family, which at s 0.395 makes it a quiet lavender rather than a
 * colour. The consequence lands in 13.4, where the dark focus ring promotes onto
 * accent 300 and the brand text onto wash 300 specifically so a 2px line never
 * becomes the same colour as the text it may surround. Measured here those two are
 * OKLab dE 0.0400 apart with 46.6 degrees of hue between them, which is two JND and
 * the tightest that pair gets in any family (النيلي manages 0.0774). It holds, and
 * it holds by hue rather than by chroma. If a future pass ever wants more room the
 * honest lever is the accent SCALE, not the accent hue.
 *
 * ══ THE NEUTRAL RAMP IS ALL BUT IDENTICAL TO الكحلي's, AND THAT IS REPORTED ══
 *
 * 13.0 requires each family to restate the neutral ramp at ITS OWN hue. This family's
 * hue is 2.8 degrees from الكحلي's, and at the neutral ramp's chroma of 0.005 to 0.033
 * that difference does not survive an 8 bit round trip: three of the thirteen rungs
 * come out byte identical and the worst of the rest is OKLab dE 0.0050. The two
 * families therefore share their greys, their surfaces and their disabled fills. It
 * is recorded rather than engineered around, for two reasons. A user meets exactly
 * one family at a time, so the two greys are never on screen together. And the thing
 * that distinguishes the families is precisely what the names say it is: one has a
 * blue brand on those greys and the other has a grey one.
 * ────────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="graphite"]:root {
    /* 13.7.1 THE GRAPHITE RAMP. Eleven rungs, the green spine's luminance at
     * every one of them, so a semantic that names a rung keeps its measured
     * contrast when the palette changes. Worst luminance drift against the
     * spine: 0.033 percent. */
    --fx-p-graphite-50:           #f4f6f8;
    --fx-p-graphite-100:          #e8eef6;
    --fx-p-graphite-200:          #d4deea;
    --fx-p-graphite-300:          #b6c6da;
    --fx-p-graphite-400:          #98acc8;
    --fx-p-graphite-500:          #7c96ba;
    --fx-p-graphite-600:          #6a819e;
    --fx-p-graphite-700:          #5a6f89;
    --fx-p-graphite-800:          #405061;   /* the owner's seed, on the ladder */
    --fx-p-graphite-900:          #2c3641;
    --fx-p-graphite-950:          #202633;

    /* 13.7.2 THE ACCENT RAMP — a lavender grey. The decorative companion, holding
     * the olive ramp's luminance at every rung so 2.5 and 3.5 keep their figures.
     * It is NOT a second brand: 3.9 governs where it may be spent and that
     * contract is unchanged for every family. Chroma is the olive ramp's own,
     * scaled by min(s, 1.0) and gamut clipped, which on this family means a
     * companion as quiet as the brand. Worst luminance drift against the olive
     * ramp: 0.026 percent. */
    --fx-p-graphite-accent-100:   #f0edf8;
    --fx-p-graphite-accent-200:   #e6e0f6;
    --fx-p-graphite-accent-300:   #d6cbec;
    --fx-p-graphite-accent-400:   #c4b6e2;
    --fx-p-graphite-accent-500:   #9a92b6;
    --fx-p-graphite-accent-600:   #897da2;
    --fx-p-graphite-accent-700:   #766b8b;
    --fx-p-graphite-accent-800:   #58536d;

    /* 13.7.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It is
     * not extended, not tinted and not reused here, and there is still no sixth
     * mint rung. This is a SEPARATE ramp that reproduces mint's five relative
     * luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at this
     * family's own hue, so the light opaque washes and the dark low alpha washes
     * land at the identical lift the fourth pass measured and every text tier over
     * a wash keeps its ratio. Worst drift: 0.027 percent.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.027   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.126  on level 1 1.177  on level 2 1.230 */
    --fx-p-graphite-wash-100:     #e3eefb;
    --fx-p-graphite-wash-200:     #d3e0f1;
    --fx-p-graphite-wash-300:     #cadaee;
    --fx-p-graphite-wash-400:     #c1d4ee;
    --fx-p-graphite-wash-500:     #b9ceec;

    /* 13.7.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES WHETHER
     * THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside the
     * olive. A green tinted grey under a graphite page is exactly the tell that
     * says a theme was rotated rather than built, and greys are half the pixels on
     * a legal screen. So the ramp is restated at THIS family's hue, at the SAME
     * OKLCH chroma rung for rung and at the SAME relative luminance rung for rung,
     * which is what keeps the elevation ladder's 1.04 to 1.06 steps identical.
     * n 0 is white in every family and is not restated. Worst luminance drift on
     * this ramp: 0.107 percent.
     *
     * READ THE CLAUSE ABOVE ABOUT الكحلي BEFORE COMPARING THE TWO FILES. At this
     * hue and this chroma the ramp is all but byte identical to الكحلي's, which is
     * recorded there as a consequence of the owner's seed and not as a defect. */
    --fx-p-n-25:                  #fdfcfe;
    --fx-p-n-50:                  #f4f6fb;
    --fx-p-n-100:                 #eaedf7;
    --fx-p-n-200:                 #d6e0ee;
    --fx-p-n-300:                 #bfcada;
    --fx-p-n-400:                 #9aaabd;
    --fx-p-n-500:                 #7b8a9a;
    --fx-p-n-600:                 #5f6875;
    --fx-p-n-700:                 #46505b;
    --fx-p-n-800:                 #32383f;
    --fx-p-n-900:                 #1e2838;
    --fx-p-n-950:                 #1a2532;
    --fx-p-n-1000:                #161e2b;

    /* 13.7.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they are
     * deliberately hue tinted rather than points on the neutral ramp, so they are
     * re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated:         #1d2b43;
    --fx-p-dark-sunken:           #191f29;
    --fx-p-dark-well:             #101820;
    --fx-p-dark-ink:              #101a24;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white for
     * the same reason; this is the same value at this family's hue. Measured on the
     * light brand fill: 7.38:1. In DARK the semantic that reads this primitive is
     * overridden to white by section 3, so the dark band's ink measures 8.27:1
     * rather than this figure. */
    --fx-p-on-primary:            #eaf3fd;

    /* 13.7.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with the
     * palette would stop being a danger red, so the 200 / 300 / 600 / 800 grades in
     * 1.6 are untouched in every family and are NOT restated here. What is restated
     * is the two TINT BACKGROUNDS, because a tint sits on this family's neutral and
     * has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and takes
     * the family's neutral cast added at a fraction of the neutral's own hue shift.
     * Luminance is preserved exactly, so every status foreground keeps its measured
     * ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.68:1
     *   amber    fg on tint  light 5.18:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.89:1
     *
     * THE CAST FRACTION IS 0.35 AND IT WAS SOLVED, NOT COPIED. The rule stated in
     * 13.0 is the LARGEST fraction at which every tint stays within 30 degrees of
     * the olive tint it replaces. Solved for this hue: 0.35 gives a worst drift of
     * 22.5 degrees, which is inside the bound, so 0.35 is the answer here as it was
     * for the three sixth pass families. النيلي still takes 0.30 and nothing in any
     * earlier family was re-derived.
     *
     * AND THE INFO PAIR IS THE ONE TO WATCH ON THIS FAMILY, for the same reason
     * 13.6 records: the brand sits 2.9 degrees from p-blue-600. As pale TINTS the
     * brand ground and the info ground do not separate by hue at all, so the ICON
     * and the LABEL carry the info meaning here, which is what SC 1.4.1 asks for
     * anyway, and 2.7 already requires both. */
    --fx-p-emerald-100:           #e6f4ef;
    --fx-p-emerald-900:           #142f29;
    --fx-p-amber-100:             #fbf1e7;
    --fx-p-amber-900:             #342518;
    --fx-p-red-100:               #fbecee;
    --fx-p-red-900:               #341820;
    --fx-p-blue-100:              #eaf0ff;
    --fx-p-blue-900:              #132444;

    /* ══ 13.7.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue and the chroma moved.
     * MEASURED, the ladder: 0 to 1 1.046, 1 to 2 1.045, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.30 / 10.42 / 5.23 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0:           #ecf0f7;
    --fx-color-level-1:           #f2f5fa;
    --fx-color-level-2:           #f7faff;
    --fx-color-bg-subtle:         #e7ebf2;
    --fx-color-surface-sunken:    #e7ebf2;

    --fx-color-text:              #18202e;
    --fx-color-text-muted:        #2e3843;
    --fx-color-text-subtle:       #5c6471;
    --fx-color-text-faint:        #78808d;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate and
     * that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:     rgba(23, 37, 59, 0.05);
    --fx-color-border:            rgba(23, 37, 59, 0.08);
    --fx-color-border-emphasis:   rgba(23, 37, 59, 0.14);
    --fx-color-divider-strong:    #d3dae4;
    --fx-color-divider:           #e3e7f0;
    --fx-color-divider-faint:     #edf2f8;
    --fx-color-field-bg-hover:    #fdfcfd;

    /* 2.4. Brand fill #405061, ink on it 7.38:1, white on it 8.27:1, fill against
     * the page 7.24:1. This is the rung the owner's own #475569 landed on, at
     * OKLab dE 0.0217, so the light primary button IS the value he chose. */
    --fx-color-primary:           var(--fx-p-graphite-800);
    --fx-color-primary-hover:     var(--fx-p-graphite-900);
    --fx-color-primary-active:    var(--fx-p-graphite-950);
    --fx-color-primary-subtle:    rgba(64, 80, 97, 0.10);
    --fx-color-primary-rgb:       64, 80, 97;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.27:1
     *   white 85 percent .......... 6.54:1
     *   white 72 percent .......... 5.23:1   idle rail rows and group headings
     *   white 54 percent .......... 3.69:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.245 / 1.454 / 1.628
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:              var(--fx-p-graphite-800);
    --fx-color-shell:             var(--fx-p-graphite-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:            var(--fx-p-graphite-accent-600);
    --fx-color-accent-hover:      var(--fx-p-graphite-accent-700);
    --fx-color-accent-subtle:     rgba(137, 125, 162, 0.14);
    --fx-color-accent-rgb:        137, 125, 162;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and link
     * the same, against a 4.5 bar. A grey family does not get a weaker signal here:
     * these tokens are luminance positions on the spine and they measure what they
     * measure in every other family. */
    --fx-color-indicator:         var(--fx-p-graphite-800);
    --fx-color-brand-text:        var(--fx-p-graphite-800);
    --fx-color-link:              var(--fx-p-graphite-800);
    --fx-color-link-hover:        var(--fx-p-graphite-900);
    --fx-color-link-rgb:          64, 80, 97;
    --fx-color-text-rgb:          24, 32, 46;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash at
     * alpha renders as a different hex on each of the four planes. Active is mixed
     * from the two rungs either side of it rather than being a sixth rung. The four
     * tiers over hover 13.92 / 10.15 / 5.09 / 3.39 and over active 12.70 / 9.26 /
     * 4.64 / 3.10. The ring over the two washes: 7.05 and 6.43.
     * fx-color-disabled-bg is the pale end of the neutral ramp, and the obligation
     * it carries on THIS family is measured at the head of 13.7: the brand fill
     * clears it by 7.03:1. */
    --fx-color-focus-ring:        var(--fx-p-graphite-800);
    --fx-color-selection-bg:      var(--fx-p-graphite-wash-300);
    --fx-color-hover:             var(--fx-p-graphite-wash-100);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-graphite-wash-200) 70%, var(--fx-p-graphite-wash-100));
    --fx-color-disabled-bg:       #e8edf4;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a graphite page. Geometry, blur and
     * alpha are untouched — only the three channels moved. */
    --fx-shadow-xs:               0 1px 2px rgba(23, 37, 59, 0.05);
    --fx-shadow-sm:               0 1px 4px -1px rgba(23, 37, 59, 0.09);
    --fx-shadow-md:               0 3px 12px rgba(23, 37, 59, 0.09);
    --fx-shadow-lg:               0 7px 24px rgba(23, 37, 59, 0.06);
    --fx-shadow-xl:               0 10px 32px rgba(23, 37, 59, 0.07);
    --fx-shadow-2xl:              0 16px 48px rgba(23, 37, 59, 0.08);
    --fx-shadow-float-sm:         0 1px 4px -1px rgba(23, 37, 59, 0.09);
    --fx-shadow-float-md:         0 3px 12px rgba(23, 37, 59, 0.09);
    --fx-shadow-float-lg:         0 7px 24px rgba(23, 37, 59, 0.06);
    --fx-shadow-stack:            inset 0 -1px 1px 0 rgba(23, 37, 59, 0.10), 0 5px 2px 0 rgba(23, 37, 59, 0.01), 0 3px 2px 0 rgba(23, 37, 59, 0.04), 0 1px 1px 0 rgba(23, 37, 59, 0.07), 0 0 1px 0 rgba(23, 37, 59, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load bearing;
     * read the rule over the olive declaration before touching it. */
    --fx-shadow-well:             inset 0 2px 2px rgba(23, 37, 59, 0.60), inset 0 5px 12px rgba(23, 37, 59, 0.10), inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset:            inset 0 1px 2px rgba(23, 37, 59, 0.08);
    --fx-shadow-press:            inset 0 1px 3px rgba(23, 37, 59, 0.10);
    --fx-color-focus-glow:        var(--fx-p-graphite-wash-200);
    --fx-color-focus-glow-soft:   var(--fx-p-graphite-wash-500);
    --fx-glass-bg:                rgba(247, 250, 255, 0.72);
    --fx-scrollbar-thumb:         rgba(23, 37, 59, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(23, 37, 59, 0.20);
    --fx-scrollbar-thumb-active:  rgba(23, 37, 59, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would paint
     * the olive green on a graphite page. Nothing is renamed. */
    --frihat-green-900:           var(--fx-p-graphite-900);
    --frihat-green-800:           var(--fx-p-graphite-800);
    --frihat-green-700:           var(--fx-p-graphite-700);
    --frihat-olive:               var(--fx-p-graphite-accent-600);
    --frihat-olive-2:             var(--fx-p-graphite-accent-500);
}

/* 13.7.8 GRAPHITE — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS STRUCTURAL
 * RATHER THAN TIDY. The light palette block is specificity 0,2,1 and sits LATER in
 * the file than the olive dark block, which is also 0,2,1, so on a tie it wins.
 * Every token the light block declares that any dark block also declares must
 * therefore be restated here at 0,3,1, or it would leak its LIGHT value into this
 * theme. Fifty seven tokens are in that category and all fifty seven are below; a
 * token that appears above and is missing here is a defect, not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.050, 1 to 2 1.050, 2 to 3 1.054, 0 to 3 1.162.
 * The four text tiers on the page: 14.26 / 11.10 / 5.67 / 3.70, and on level 3
 * 12.27 / 9.55 / 4.88 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="graphite"][data-bs-theme="dark"]:root {
    --fx-color-level-0:           var(--fx-p-n-1000);
    --fx-color-level-1:           #1a2231;
    --fx-color-level-2:           #1f2633;
    --fx-color-level-3:           #232a37;
    --fx-color-bg-subtle:         var(--fx-p-dark-well);
    --fx-color-surface-sunken:    var(--fx-p-dark-well);

    --fx-color-text:              #e8edf7;
    --fx-color-text-muted:        #cad3e2;
    --fx-color-text-subtle:       #8d97a7;
    --fx-color-text-faint:        #6f7784;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and that
     * ink is this family's own primary text colour. */
    --fx-color-border-subtle:     rgba(232, 237, 247, 0.05);
    --fx-color-border:            rgba(232, 237, 247, 0.08);
    --fx-color-border-emphasis:   rgba(232, 237, 247, 0.14);
    --fx-color-divider-strong:    #363b42;
    --fx-color-divider:           #272c33;
    --fx-color-divider-soft:      #20252d;
    --fx-color-divider-faint:     #1b252f;
    --fx-color-field-bg-hover:    var(--fx-color-level-3);
    --fx-color-field-bg-focus:    #252e3e;

    /* 3.4. One ramp step brighter than light so the fill stays visible against the
     * page: white on it 5.16:1, fill against the page 3.24:1. Against the disabled
     * fill in this mode it measures 3.07:1, which is the number the head of 13.7
     * owes and the tighter of the two modes. */
    --fx-color-primary:           var(--fx-p-graphite-700);
    --fx-color-primary-hover:     var(--fx-p-graphite-800);
    --fx-color-primary-active:    var(--fx-p-graphite-900);
    --fx-color-primary-subtle:    rgba(90, 111, 137, 0.20);
    --fx-color-primary-rgb:       90, 111, 137;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the planes a
     * dropdown or a popup floats on, and it cannot move without breaking its own
     * ink, so it carries a rim instead. This family 600 rung measures 4.18 / 3.98 /
     * 3.79 / 3.60:1 on levels 0 to 3, the same figures as every other family,
     * because a rung is a luminance position. Against its own fill it measures
     * 1.29:1, which is the rim doing what a rim is for. */
    --fx-color-primary-border:    var(--fx-p-graphite-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand surface
     * and must read as one colour in both themes, so it stays on 800 and accepts
     * the same 2.02:1 against the dark page that the dated decision in 3.4.1
     * accepted for olive. Its ink in dark is white, at 8.27:1, and the gold mark on
     * it 4.53:1. */
    --fx-color-band:              var(--fx-p-graphite-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5 does
     * for olive: without this line the light block's brand fill would fall through
     * and dark would gain a mid slate shell nobody asked for. */
    --fx-color-shell:             var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.065:1   one rung, as in olive
     *   white on the rail .................. 16.80:1
     *   white 72 / 55 / 38 percent ......... 9.21 / 5.93 / 3.56
     *   gold mark on the rail .............. 9.20:1
     *   washes, white at 8 / 14 / 18 percent 1.260 / 1.551 / 1.767 */
    --fx-color-rail:              color-mix(in srgb, var(--fx-p-graphite-900) 55%, var(--fx-p-black));

    --fx-color-accent:            var(--fx-p-graphite-accent-500);
    --fx-color-accent-hover:      var(--fx-p-graphite-accent-400);
    --fx-color-accent-subtle:     rgba(154, 146, 182, 0.18);
    --fx-color-accent-rgb:        154, 146, 182;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar. Brand TEXT cannot be the brand ramp in
     * dark — rung 700 measures 3.24:1 on the page and fails 4.5 — so it takes the
     * wash ramp's deepest rung, 8.99:1 worst case. Exactly the constraint the mint
     * ramp solved for olive, solved the same way with this family's own wash ramp
     * rather than by borrowing mint. */
    --fx-color-indicator:         var(--fx-p-graphite-500);
    --fx-color-brand-text:        var(--fx-p-graphite-wash-500);
    --fx-color-link:              var(--fx-p-graphite-wash-500);
    --fx-color-link-hover:        var(--fx-p-graphite-wash-400);
    --fx-color-link-rgb:          185, 206, 236;
    --fx-color-text-rgb:          232, 237, 247;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would invert
     * the elevation model. Measured, wash against its own host plane:
     *   hover  1.143 / 1.139 / 1.144 / 1.150 on levels 0 to 3
     *   active 1.255 / 1.257 / 1.266 / 1.260
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.83 / 4.62 / 4.38 / 4.13
     *   over active 4.40 / 4.19 / 3.96 / 3.77 */
    --fx-color-focus-ring:        var(--fx-p-graphite-500);
    --fx-color-selection-bg:      color-mix(in srgb, var(--fx-p-graphite-wash-500) 22%, transparent);
    --fx-color-hover:             color-mix(in srgb, var(--fx-p-graphite-wash-500) 6%, transparent);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-graphite-wash-500) 10%, transparent);
    --fx-color-disabled-bg:       #1c232c;

    /* Section 6, dark. The shadow ink is pure black in this theme for every family
     * — a hue tinted shadow on a near black page buys nothing — so these are the
     * olive values restated verbatim. They are restated rather than inherited
     * because the light block above declares the same names and would otherwise win
     * the 0,2,1 tie. */
    --fx-shadow-xs:               none;
    --fx-shadow-sm:               0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:               0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:               0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:               0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl:              0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm:         0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md:         0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg:         0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:            0 5px 2px 0 rgba(0, 0, 0, 0.02), 0 3px 2px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the ratio the olive geometry
     * was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:             inset 0 2px 2px rgba(232, 237, 247, 0.50), inset 0 6px 14px rgba(0, 0, 0, 0.45), inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset:            inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press:            inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:        color-mix(in srgb, var(--fx-p-graphite-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft:   var(--fx-p-graphite-wash-500);
    --fx-glass-bg:                rgba(26, 34, 49, 0.72);
    --fx-scrollbar-thumb:         rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active:  rgba(255, 255, 255, 0.40);
}

/* ── 13.8) VIOLET — البنفسجي ──
 *
 * ADDED 2026-09-05 (eighth pass, see the header). NUMBERED AFTER 13.4 BUT PLACED
 * BEFORE IT, for the reason recorded at 13.7's head and at 13.4's.
 *
 * ══ WHY THIS HUE AND NOT ANOTHER ═══════════════════════════════════════════
 *
 * البنفسجي FILLS THE ONLY CLEAN HUE GAP THE SET HAD LEFT, and that is a measured
 * claim rather than a preference. The six shipped families sit at 36, 80, 175, 212,
 * 233 and 344 degrees of CSS hue. Three gaps were open in that ring and only one of
 * them is habitable:
 *      about 140 degrees — a green, which lands on the SUCCESS emerald
 *      about  10 degrees — a crimson, which lands on the DANGER red
 *      about  58 degrees — a gold, which lands on the WARNING amber
 *      about 271 degrees — this one, which lands on NOTHING
 * A brand that shares a hue with a status is a recognition problem the system has
 * already met twice, at 20 degrees with النبيذي against the danger red and at 0.2 of
 * a degree with الكحلي against the info blue, and both are still carried as recorded
 * carve outs. This seed sits 49.4 degrees from the nearest status hue in OKLCH, the
 * info blue, and further from all three others. It is the only remaining opening
 * that costs the system nothing.
 *
 * IT ALSO SITS FURTHEST FROM ITS NEIGHBOURS OF ANY CANDIDATE. 38 degrees of CSS hue
 * from النيلي and 72 from النبيذي, which is why the chip matrix in 2.9 grows by two
 * families without its closest pair being one of them.
 *
 * ══ THE OWNER SUPPLIED TWO VALUES ══════════════════════════════════════════
 *
 * Recorded verbatim before anything is derived from them:
 *
 *     light  أساسي #9333EA        dark  أساسي #C084FC
 *
 * As with الفحمي there is no خلفية and no نص عليها, so the pair fixes the hue and
 * the chroma scale and the rest is derived by 13.0.
 *
 * ══ WHERE THE SEEDS LAND ON THE FROZEN LADDER ══════════════════════════════
 *
 * LIGHT SEED #9333EA. Measured: OKLCH L 0.5575 C 0.2525 H 302.3, relative luminance
 * 0.10879. Placed by OKLab LIGHTNESS: the green spine's 600 rung sits at L 0.5812, a
 * difference of 0.0237, against 0.0359 for the 700 rung. So it is the 600 rung of
 * this family and it arrives as #aa4ffd.
 *
 * AND THAT IS THE LOOSEST SEED FIT IN THE SYSTEM, AT OKLab dE 0.0694. It is
 * reported rather than tuned away, and the arithmetic behind it is worth the lines
 * because it looks like a defect and is not. Placement is by L, per 13.0, and by L
 * rung 600 wins. By OKLab DISTANCE rung 700 would win instead, at dE 0.0273, because
 * rung 700 carries less chroma and this seed is very saturated, so the two criteria
 * disagree for the first time. THE RULE WAS FOLLOWED RATHER THAN THE PREFERABLE
 * NUMBER, for the reason 13.0 gives: L is the perceptual lightness coordinate and it
 * is what makes a rung mean the same thing in every family. Choosing by dE instead
 * would have moved this family's chroma scale from 1.830 to 2.025 and made every
 * deep rung more saturated than the owner's own seed. The previous widest fit was
 * النبيذي at dE 0.0429.
 *
 * NOTHING DOWNSTREAM DEPENDS ON WHICH RUNG THE SEED SAT ON. Read the identity clause
 * in 13.0: the rungs are luminance positions on the frozen spine, so rung 800 is the
 * same luminance in this family as in every other and the light brand fill, the band,
 * the shell, the link, the indicator and the focus ring all measure what they measure
 * elsewhere. The seed set this family's hue and its chroma scale, and nothing else.
 * The only place the seed's own rung is visible is the PICKER CHIP in 2.9.
 *
 * DARK SEED #C084FC, OKLCH L 0.7217 C 0.1767 H 305.5, lands on rung 400 at L 0.7245,
 * a difference of 0.0028, which is the tightest lightness fit of any seed in the
 * system. Worth recording: by OKLab distance rungs 400 and 500 are effectively tied,
 * at dE 0.0426 and 0.0419, and rung 500 in dark IS fx-color-indicator and
 * fx-color-focus-ring — the bright brand MARK that 3.5.1 defines. So this family's
 * dark seed is honoured at the resting mark as well as at the rung its lightness
 * picks, and the two are a hundredth of a dE apart. Measured on the mark: 4.75:1
 * worst case over levels 0 to 3, against the 3.0 bar a non text mark owes.
 *
 * ALSO WORTH NAMING, BECAUSE IT IS THE TRAP 13.5 DOCUMENTED: the dark أساسي is a
 * bright violet built to carry DARK ink, and this system's dark brand FILL carries
 * white. White on #C084FC measures 2.28:1 against the 4.5 SC 1.4.3 asks of a button
 * label, where the system's dark fill, rung 700 #9441de, measures 5.16:1. The value
 * is honoured at the rung its own lightness puts it on and NOT at fx-color-primary.
 *
 * ══ HUE, CHROMA AND ACCENT ═════════════════════════════════════════════════
 *
 * HUE 303.6, the chroma weighted mean of the two supplied values (302.3 at C 0.2525
 * and 305.5 at C 0.1767). The two anchors span 3.2 degrees. Weighting by chroma,
 * because the hue of a near neutral is numerically unstable, gives 303.6.
 *
 * CHROMA. s = 1.830, the seed's chroma over the green spine's chroma at its rung.
 * That is the highest scale in the system, above النيلي's 1.484, and it is what makes
 * this the most vivid family shipped. Held flat at and below the seed rung and
 * relaxed linearly toward 1.0 at rung 50, so the pale end of the ramp cannot go neon
 * and the deep end keeps the seed's own saturation. Where sRGB cannot hold the target
 * chroma at a given luminance the chroma is reduced until it fits and THE LUMINANCE
 * IS HELD, which is the guarantee this whole section rests on; on this ramp that
 * clipping bites hardest at rungs 300 and 400, where the target is 0.1251 and 0.1925
 * and the achievable is 0.1017 and 0.1499. Worst luminance drift against the spine:
 * 0.080 percent.
 *
 * ACCENT HUE 330.6, +27.0 degrees of OKLCH hue from the brand, which reads as a
 * magenta rose. The standard offset the earlier families use is available here for
 * once and it is also the best of the candidates: measured against the four status
 * families it is nearest the danger red at 58.9 degrees, the widest status clearance
 * any accent in the system has. A NEGATIVE rotation was not available and the numbers
 * say why: minus 27 lands on 276.6, 22.4 degrees from the info blue and directly on
 * top of النيلي's brand hue.
 *
 * ══ THE STATUS CHECK, RUN BEFORE ANYTHING WAS DERIVED ══════════════════════
 *
 * 13.0 requires the new brand hue to be measured against the four status hues first.
 * Result, in OKLCH degrees: emerald 153.8, amber 105.7, red 85.9, blue 49.4. The
 * nearest approach is 49.4 degrees, which is more than twice النيلي's 21.2 and two
 * orders of magnitude more than الكحلي's 0.2. THIS IS THE FIRST FAMILY SINCE
 * الأزرق البترولي THAT NEEDS NO STATUS CARVE OUT, and that was the point of choosing
 * it. No entry is added to the recognition list for this family, because there is
 * nothing to add.
 * ────────────────────────────────────────────────────────────────────────── */
html[data-fx-palette="violet"]:root {
    /* 13.8.1 THE VIOLET RAMP. Eleven rungs, the green spine's luminance at every
     * one of them, so a semantic that names a rung keeps its measured contrast when
     * the palette changes. */
    --fx-p-violet-50:             #f8f4ff;
    --fx-p-violet-100:            #f0ebfc;
    --fx-p-violet-200:            #e7d6fd;
    --fx-p-violet-300:            #d7b7fd;
    --fx-p-violet-400:            #c296fd;
    --fx-p-violet-500:            #b475ff;
    --fx-p-violet-600:            #aa4ffd;   /* the owner's seed, on the ladder */
    --fx-p-violet-700:            #9441de;
    --fx-p-violet-800:            #6930a1;
    --fx-p-violet-900:            #49206d;
    --fx-p-violet-950:            #34184e;

    /* 13.8.2 THE ACCENT RAMP — a magenta rose. The decorative companion, holding
     * the olive ramp's luminance at every rung so 2.5 and 3.5 keep their figures.
     * It is NOT a second brand: 3.9 governs where it may be spent and that contract
     * is unchanged for every family. Chroma is the olive ramp's own, scaled by
     * min(s, 1.0) and gamut clipped, so a family whose seed is more saturated than
     * the spine does not get a fluorescent companion. Worst luminance drift against
     * the olive ramp: 0.035 percent. */
    --fx-p-violet-accent-100:     #ffe8fa;
    --fx-p-violet-accent-200:     #fdd8f8;
    --fx-p-violet-accent-300:     #fbbcf5;
    --fx-p-violet-accent-400:     #f69ff0;
    --fx-p-violet-accent-500:     #ca7cc1;
    --fx-p-violet-accent-600:     #b865af;
    --fx-p-violet-accent-700:     #9f5696;
    --fx-p-violet-accent-800:     #784473;

    /* 13.8.3 THE INTERACTION WASH RAMP — FIVE RUNGS, THE MINT LUMINANCES.
     *
     * THE MINT RAMP IN 1.2.1 IS CLIENT SUPPLIED AND FROZEN FOR OLIVE ONLY. It is
     * not extended, not tinted and not reused here, and there is still no sixth
     * mint rung. This is a SEPARATE ramp that reproduces mint's five relative
     * luminances exactly — 0.845 / 0.735 / 0.689 / 0.646 / 0.605 — at this
     * family's own hue, so the light opaque washes and the dark low alpha washes
     * land at the identical lift the fourth pass measured and every text tier over
     * a wash keeps its ratio. Worst drift: 0.025 percent.
     *
     * Measured here, wash against the plane it sits on, light theme:
     *   hover on level 0 1.027   on level 1 1.074   on level 2 1.122
     *   active on level 0 1.128  on level 1 1.179  on level 2 1.232 */
    --fx-p-violet-wash-100:       #f0eafd;
    --fx-p-violet-wash-200:       #e9d8fd;
    --fx-p-violet-wash-300:       #e2d1fd;
    --fx-p-violet-wash-400:       #dfc9fe;
    --fx-p-violet-wash-500:       #d9c2fe;

    /* 13.8.4 THE NEUTRAL RAMP, RE-DECLARED. THIS IS THE ONE THAT DECIDES WHETHER
     * THE FAMILY READS AS DESIGNED OR AS HUE ROTATED.
     *
     * 1.3 tints the greys very slightly green so they never read cold beside the
     * olive. A green tinted grey under a violet page is exactly the tell that says a
     * theme was rotated rather than built, and greys are half the pixels on a legal
     * screen. So the ramp is restated at THIS family's hue, at the SAME OKLCH chroma
     * rung for rung and at the SAME relative luminance rung for rung, which is what
     * keeps the elevation ladder's 1.04 to 1.06 steps identical. n 0 is white in
     * every family and is not restated. Worst luminance drift on this ramp: 0.150
     * percent. */
    --fx-p-n-25:                  #fdfcfe;
    --fx-p-n-50:                  #f7f5fc;
    --fx-p-n-100:                 #f1ebf6;
    --fx-p-n-200:                 #e4dced;
    --fx-p-n-300:                 #cdc6d9;
    --fx-p-n-400:                 #ada5b9;
    --fx-p-n-500:                 #8c859b;
    --fx-p-n-600:                 #696576;
    --fx-p-n-700:                 #514d5a;
    --fx-p-n-800:                 #3b3542;
    --fx-p-n-900:                 #2d2435;
    --fx-p-n-950:                 #292130;
    --fx-p-n-1000:                #211b2a;

    /* 13.8.5 Dark chrome surfaces. 1.4 declares these separately BECAUSE they are
     * deliberately hue tinted rather than points on the neutral ramp, so they are
     * re-derived rather than inherited. Same luminance, this hue. */
    --fx-p-dark-elevated:         #332540;
    --fx-p-dark-sunken:           #231c29;
    --fx-p-dark-well:             #18161f;
    --fx-p-dark-ink:              #1c1722;

    /* The ink that goes ON the brand fill. 1.5 carries a green tinted off white for
     * the same reason; this is the same value at this family's hue. Measured on the
     * light brand fill: 7.38:1. In DARK the semantic that reads this primitive is
     * overridden to white by section 3, so the dark band's ink measures 8.27:1
     * rather than this figure. */
    --fx-p-on-primary:            #f4f0fe;

    /* 13.8.6 STATUS TINT BACKGROUNDS ONLY. THE STATUS HUES DO NOT MOVE.
     *
     * emerald, amber, red and blue mean STATUS. A danger red that changed with the
     * palette would stop being a danger red, so the 200 / 300 / 600 / 800 grades in
     * 1.6 are untouched in every family and are NOT restated here. What is restated
     * is the two TINT BACKGROUNDS, because a tint sits on this family's neutral and
     * has to belong to it.
     *
     * DERIVED, NOT PICKED. Each tint keeps its own status vector in OKLab and takes
     * the family's neutral cast added at a fraction of the neutral's own hue shift.
     * Luminance is preserved exactly, so every status foreground keeps its measured
     * ratio:
     *   emerald  fg on tint  light 5.76:1   dark 7.68:1
     *   amber    fg on tint  light 5.18:1   dark 8.07:1
     *   red      fg on tint  light 5.74:1   dark 5.88:1
     *   blue     fg on tint  light 5.66:1   dark 7.88:1
     *
     * THE CAST FRACTION IS 0.30 IN THIS FAMILY AND NOT 0.35, AND THAT IS THE RULE
     * BINDING RATHER THAN AN EXCEPTION TO IT. 13.0 states the fraction as the
     * LARGEST at which every tint stays within 30 degrees of the olive tint it
     * replaces. Solved for this hue: at 0.35 the emerald light tint drifts 37.8
     * degrees, because a pale tint carries almost no chroma and its hue therefore
     * swings hard for a small shift in OKLab a and b. At 0.30 the worst drift is
     * 22.0 degrees and every tint is back inside the bound. النيلي reached the same
     * answer for the same reason; the five families on 0.35 were NOT re-derived and
     * not one of their values moved. Luminance is preserved at any fraction, so the
     * choice costs no contrast and the four foregrounds above are identical at
     * either value. */
    --fx-p-emerald-100:           #eaf3ee;
    --fx-p-emerald-900:           #172f24;
    --fx-p-amber-100:             #fff0e4;
    --fx-p-amber-900:             #372413;
    --fx-p-red-100:               #fbecee;
    --fx-p-red-900:               #36171d;
    --fx-p-blue-100:              #eaf0ff;
    --fx-p-blue-900:              #1c2340;

    /* ══ 13.8.7 SEMANTIC — LIGHT ════════════════════════════════════════
     * Every rule in section 2 still governs. Only the hue and the chroma moved.
     * MEASURED, the ladder: 0 to 1 1.046, 1 to 2 1.044, 2 to 3 1.046, 0 to 3 1.143.
     * The four text tiers on the page: 14.30 / 10.42 / 5.22 / 3.49.
     * Level 3 is white in every family and is not restated. */
    --fx-color-level-0:           #f3eef6;
    --fx-color-level-1:           #f5f4fb;
    --fx-color-level-2:           #fbf9fd;
    --fx-color-bg-subtle:         #eee9f1;
    --fx-color-surface-sunken:    #eee9f1;

    --fx-color-text:              #231d2d;
    --fx-color-text-muted:        #3a3540;
    --fx-color-text-subtle:       #67616f;
    --fx-color-text-faint:        #837d8b;

    /* The translucent trio, re-inked. 2.3 keeps the two line families separate and
     * that separation is untouched; only the ink's hue moved. */
    --fx-color-border-subtle:     rgba(45, 31, 56, 0.05);
    --fx-color-border:            rgba(45, 31, 56, 0.08);
    --fx-color-border-emphasis:   rgba(45, 31, 56, 0.14);
    --fx-color-divider-strong:    #ddd7e4;
    --fx-color-divider:           #e9e5f2;
    --fx-color-divider-faint:     #f3f0fa;
    --fx-color-field-bg-hover:    #fdfcfd;

    /* 2.4. Brand fill #6930a1, ink on it 7.38:1, white on it 8.27:1, fill against
     * the page 7.24:1. */
    --fx-color-primary:           var(--fx-p-violet-800);
    --fx-color-primary-hover:     var(--fx-p-violet-900);
    --fx-color-primary-active:    var(--fx-p-violet-950);
    --fx-color-primary-subtle:    rgba(105, 48, 161, 0.10);
    --fx-color-primary-rgb:       105, 48, 161;

    /* 2.4.2 and the shell ruling in 2.4.1. The band, the rail and the canvas are
     * ONE surface and it is this family's brand fill, so "the same colour as the
     * top bar" stays true by construction. Re-derived AGAINST THAT FILL, which is
     * the surface clause 3.9 prices:
     *   white on the shell ........ 8.27:1
     *   white 85 percent .......... 6.45:1
     *   white 72 percent .......... 5.10:1   idle rail rows and group headings
     *   white 54 percent .......... 3.57:1   SC 1.4.11 only, never body text
     *   gold p-amber-300 .......... 4.53:1   the position mark, unchanged
     *   the three washes, white over the fill at 8 / 14 / 18 percent:
     *     1.216 / 1.403 / 1.546
     * brand-text and indicator still resolve to the fill itself and so still may
     * NOT be spent inside the shell; 03-leptonx overrides both there, and that
     * override reads semantic tokens, so it follows this family unchanged. */
    --fx-color-band:              var(--fx-p-violet-800);
    --fx-color-shell:             var(--fx-p-violet-800);

    /* 2.5. Decoration only, and 3.9's FORBIDDEN list is unchanged. */
    --fx-color-accent:            var(--fx-p-violet-accent-600);
    --fx-color-accent-hover:      var(--fx-p-violet-accent-700);
    --fx-color-accent-subtle:     rgba(184, 101, 175, 0.14);
    --fx-color-accent-rgb:        184, 101, 175;

    /* 2.5.1 and 2.6. Mark 7.24:1 worst case over levels 0 to 3, brand text and link
     * the same, against a 4.5 bar. */
    --fx-color-indicator:         var(--fx-p-violet-800);
    --fx-color-brand-text:        var(--fx-p-violet-800);
    --fx-color-link:              var(--fx-p-violet-800);
    --fx-color-link-hover:        var(--fx-p-violet-900);
    --fx-color-link-rgb:          105, 48, 161;
    --fx-color-text-rgb:          35, 29, 45;

    /* 2.8. The washes are OPAQUE in light for the reason recorded there: a wash at
     * alpha renders as a different hex on each of the four planes. Active is mixed
     * from the two rungs either side of it rather than being a sixth rung. The four
     * tiers over hover 13.92 / 10.15 / 5.09 / 3.39 and over active 12.68 / 9.24 /
     * 4.63 / 3.09. The ring over the two washes: 7.05 and 6.42. */
    --fx-color-focus-ring:        var(--fx-p-violet-800);
    --fx-color-selection-bg:      var(--fx-p-violet-wash-300);
    --fx-color-hover:             var(--fx-p-violet-wash-100);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-violet-wash-200) 70%, var(--fx-p-violet-wash-100));
    --fx-color-disabled-bg:       #efebf3;

    /* Section 6. The shadow ink is a near black at THIS family's hue, so a card
     * edge does not drop a green shadow on a violet page. Geometry, blur and alpha
     * are untouched — only the three channels moved. */
    --fx-shadow-xs:               0 1px 2px rgba(45, 31, 56, 0.05);
    --fx-shadow-sm:               0 1px 4px -1px rgba(45, 31, 56, 0.09);
    --fx-shadow-md:               0 3px 12px rgba(45, 31, 56, 0.09);
    --fx-shadow-lg:               0 7px 24px rgba(45, 31, 56, 0.06);
    --fx-shadow-xl:               0 10px 32px rgba(45, 31, 56, 0.07);
    --fx-shadow-2xl:              0 16px 48px rgba(45, 31, 56, 0.08);
    --fx-shadow-float-sm:         0 1px 4px -1px rgba(45, 31, 56, 0.09);
    --fx-shadow-float-md:         0 3px 12px rgba(45, 31, 56, 0.09);
    --fx-shadow-float-lg:         0 7px 24px rgba(45, 31, 56, 0.06);
    --fx-shadow-stack:            inset 0 -1px 1px 0 rgba(45, 31, 56, 0.10), 0 5px 2px 0 rgba(45, 31, 56, 0.01), 0 3px 2px 0 rgba(45, 31, 56, 0.04), 0 1px 1px 0 rgba(45, 31, 56, 0.07), 0 0 1px 0 rgba(45, 31, 56, 0.08);
    /* Band 1 is the SC 1.4.11 identification band and its 2px blur is load bearing;
     * read the rule over the olive declaration before touching it. */
    --fx-shadow-well:             inset 0 2px 2px rgba(45, 31, 56, 0.60), inset 0 5px 12px rgba(45, 31, 56, 0.10), inset 0 -1px 2px rgba(255, 255, 255, 0.55);
    --fx-shadow-inset:            inset 0 1px 2px rgba(45, 31, 56, 0.08);
    --fx-shadow-press:            inset 0 1px 3px rgba(45, 31, 56, 0.10);
    --fx-color-focus-glow:        var(--fx-p-violet-wash-200);
    --fx-color-focus-glow-soft:   var(--fx-p-violet-wash-500);
    --fx-glass-bg:                rgba(251, 249, 253, 0.72);
    --fx-scrollbar-thumb:         rgba(45, 31, 56, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(45, 31, 56, 0.20);
    --fx-scrollbar-thumb-active:  rgba(45, 31, 56, 0.30);

    /* Section 12.1. The legacy raw brand names are mode independent and map onto
     * primitives to preserve the exact hue, so under this palette they map onto
     * THIS family's primitives. Without these five lines a legacy sheet would paint
     * the olive green on a violet page. Nothing is renamed. */
    --frihat-green-900:           var(--fx-p-violet-900);
    --frihat-green-800:           var(--fx-p-violet-800);
    --frihat-green-700:           var(--fx-p-violet-700);
    --frihat-olive:               var(--fx-p-violet-accent-600);
    --frihat-olive-2:             var(--fx-p-violet-accent-500);
}

/* 13.8.8 VIOLET — DARK. Read section 3; it is the same rule set.
 *
 * THIS BLOCK IS A COMPLETE MIRROR OF THE LIGHT BLOCK ABOVE, AND THAT IS STRUCTURAL
 * RATHER THAN TIDY. The light palette block is specificity 0,2,1 and sits LATER in
 * the file than the olive dark block, which is also 0,2,1, so on a tie it wins.
 * Every token the light block declares that any dark block also declares must
 * therefore be restated here at 0,3,1, or it would leak its LIGHT value into this
 * theme. Fifty seven tokens are in that category and all fifty seven are below; a
 * token that appears above and is missing here is a defect, not an economy.
 *
 * MEASURED, the ladder: 0 to 1 1.049, 1 to 2 1.051, 2 to 3 1.054, 0 to 3 1.162.
 * The four text tiers on the page: 14.25 / 11.10 / 5.67 / 3.70, and on level 3
 * 12.27 / 9.55 / 4.88 / 3.19, which is the worst case in this theme.
 */
html[data-fx-palette="violet"][data-bs-theme="dark"]:root {
    --fx-color-level-0:           var(--fx-p-n-1000);
    --fx-color-level-1:           #24202b;
    --fx-color-level-2:           #28242f;
    --fx-color-level-3:           #2e2735;
    --fx-color-bg-subtle:         var(--fx-p-dark-well);
    --fx-color-surface-sunken:    var(--fx-p-dark-well);

    --fx-color-text:              #efebf6;
    --fx-color-text-muted:        #d5d0e0;
    --fx-color-text-subtle:       #9c93a3;
    --fx-color-text-faint:        #7a7482;

    /* 3.3. The translucent family flips to a light ink on a dark ground, and that
     * ink is this family's own primary text colour. */
    --fx-color-border-subtle:     rgba(239, 235, 246, 0.05);
    --fx-color-border:            rgba(239, 235, 246, 0.08);
    --fx-color-border-emphasis:   rgba(239, 235, 246, 0.14);
    --fx-color-divider-strong:    #3c3944;
    --fx-color-divider:           #2e2a33;
    --fx-color-divider-soft:      #27232d;
    --fx-color-divider-faint:     #26222f;
    --fx-color-field-bg-hover:    var(--fx-color-level-3);
    --fx-color-field-bg-focus:    #312b3b;

    /* 3.4. One ramp step brighter than light so the fill stays visible against the
     * page: white on it 5.16:1, fill against the page 3.24:1. */
    --fx-color-primary:           var(--fx-p-violet-700);
    --fx-color-primary-hover:     var(--fx-p-violet-800);
    --fx-color-primary-active:    var(--fx-p-violet-900);
    --fx-color-primary-subtle:    rgba(148, 65, 222, 0.20);
    --fx-color-primary-rgb:       148, 65, 222;

    /* The fill boundary. Read 3.4.2: the dark fill misses 3:1 against the planes a
     * dropdown or a popup floats on, and it cannot move without breaking its own
     * ink, so it carries a rim instead. This family 600 rung measures 4.18 / 3.98 /
     * 3.79 / 3.60:1 on levels 0 to 3, the same figures as every other family,
     * because a rung is a luminance position. Against its own fill it measures
     * 1.29:1, which is the rim doing what a rim is for. */
    --fx-color-primary-border:    var(--fx-p-violet-600);

    /* 3.4.1. The band does NOT take this block's 700 step. It is one brand surface
     * and must read as one colour in both themes, so it stays on 800 and accepts
     * the same 2.02:1 against the dark page that the dated decision in 3.4.1
     * accepted for olive. Its ink in dark is white, at 8.27:1, and the gold mark on
     * it 4.53:1. */
    --fx-color-band:              var(--fx-p-violet-800);

    /* The shell in dark points at the canvas dark already had, exactly as 3.5 does
     * for olive: without this line the light block's brand fill would fall through
     * and dark would gain a mid violet shell nobody asked for. */
    --fx-color-shell:             var(--fx-color-surface-sunken);

    /* The rail keeps its own near black, derived from the ramp rather than typed,
     * so it carries the family hue while reading as almost black. Measured:
     *   rail vs its own sunken canvas ...... 1.058:1   one rung, as in olive
     *   white on the rail .................. 16.91:1
     *   white 72 / 55 / 38 percent ......... 9.21 / 5.84 / 3.48
     *   gold mark on the rail .............. 9.26:1
     *   washes, white at 8 / 14 / 18 percent 1.242 / 1.507 / 1.743 */
    --fx-color-rail:              color-mix(in srgb, var(--fx-p-violet-900) 55%, var(--fx-p-black));

    --fx-color-accent:            var(--fx-p-violet-accent-500);
    --fx-color-accent-hover:      var(--fx-p-violet-accent-400);
    --fx-color-accent-subtle:     rgba(202, 124, 193, 0.18);
    --fx-color-accent-rgb:        202, 124, 193;

    /* 3.5.1 and 3.6. The two tokens land on DIFFERENT ramps here for the reason
     * recorded there. The mark stays on the brand ramp at 500, 4.75:1 worst case
     * over levels 0 to 3 against a 3.0 bar, and that rung is where the owner's dark
     * أساسي #C084FC is honoured. Brand TEXT cannot be the brand ramp in dark — rung
     * 700 measures 3.24:1 on the page and fails 4.5 — so it takes the wash ramp's
     * deepest rung, 8.99:1 worst case. Exactly the constraint the mint ramp solved
     * for olive, solved the same way with this family's own wash ramp rather than by
     * borrowing mint. */
    --fx-color-indicator:         var(--fx-p-violet-500);
    --fx-color-brand-text:        var(--fx-p-violet-wash-500);
    --fx-color-link:              var(--fx-p-violet-wash-500);
    --fx-color-link-hover:        var(--fx-p-violet-wash-400);
    --fx-color-link-rgb:          217, 194, 254;
    --fx-color-text-rgb:          239, 235, 246;

    /* 3.8. The washes are the SAME ramp at low alpha here, never the five light
     * hexes as fills, because opaque light fills on a near black page would invert
     * the elevation model. Measured, wash against its own host plane:
     *   hover  1.137 / 1.146 / 1.141 / 1.144 on levels 0 to 3
     *   active 1.253 / 1.256 / 1.268 / 1.272
     * The ring over a wash, which is the hardest combination in the theme:
     *   over hover  4.86 / 4.59 / 4.39 / 4.16
     *   over active 4.41 / 4.19 / 3.95 / 3.74 */
    --fx-color-focus-ring:        var(--fx-p-violet-500);
    --fx-color-selection-bg:      color-mix(in srgb, var(--fx-p-violet-wash-500) 22%, transparent);
    --fx-color-hover:             color-mix(in srgb, var(--fx-p-violet-wash-500) 6%, transparent);
    --fx-color-active:            color-mix(in srgb, var(--fx-p-violet-wash-500) 10%, transparent);
    --fx-color-disabled-bg:       #27202a;

    /* Section 6, dark. The shadow ink is pure black in this theme for every family
     * — a hue tinted shadow on a near black page buys nothing — so these are the
     * olive values restated verbatim. They are restated rather than inherited
     * because the light block above declares the same names and would otherwise win
     * the 0,2,1 tie. */
    --fx-shadow-xs:               none;
    --fx-shadow-sm:               0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-md:               0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-lg:               0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-xl:               0 12px 40px rgba(0, 0, 0, 0.45);
    --fx-shadow-2xl:              0 20px 56px rgba(0, 0, 0, 0.55);
    --fx-shadow-float-sm:         0 2px 4px rgba(0, 0, 0, 0.10);
    --fx-shadow-float-md:         0 4px 24px rgba(0, 0, 0, 0.20);
    --fx-shadow-float-lg:         0 7px 32px rgba(0, 0, 0, 0.35);
    --fx-shadow-stack:            0 5px 2px 0 rgba(0, 0, 0, 0.02), 0 3px 2px 0 rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 0 1px 0 rgba(0, 0, 0, 0.16);
    /* Band 1 is the RIM LIGHT and it is the SC 1.4.11 guarantee in dark: it is
     * lighter than the fill because nothing darker can reach 3:1 here, and it is
     * the only layer in this token that is family dependent. It is the family
     * primary dark ink, so the rendered top row keeps the ratio the olive geometry
     * was corrected to. The 2px offset and 2px blur are load bearing. */
    --fx-shadow-well:             inset 0 2px 2px rgba(239, 235, 246, 0.50), inset 0 6px 14px rgba(0, 0, 0, 0.45), inset 0 -2px 4px rgba(0, 0, 0, 0.35);
    --fx-shadow-inset:            inset 0 1px 2px rgba(0, 0, 0, 0.45);
    --fx-shadow-press:            inset 0 1px 3px rgba(0, 0, 0, 0.50);
    --fx-color-focus-glow:        color-mix(in srgb, var(--fx-p-violet-wash-400) 40%, transparent);
    --fx-color-focus-glow-soft:   var(--fx-p-violet-wash-500);
    --fx-glass-bg:                rgba(36, 32, 43, 0.72);
    --fx-scrollbar-thumb:         rgba(255, 255, 255, 0.10);
    --fx-scrollbar-thumb-hover:   rgba(255, 255, 255, 0.20);
    --fx-scrollbar-thumb-active:  rgba(255, 255, 255, 0.40);
}

/* ── 13.4) SECTION 11, RESTATED FOR EVERY NON DEFAULT FAMILY ───────────────
 *
 * WAS "THE THREE NEW FAMILIES" WHEN IT WAS WRITTEN, ON 2026-09-04. The seventh
 * pass the same day took the count to five, so the title names the rule instead
 * of the count and will not go stale again. Nothing else in this section was
 * rewritten; النيلي and الكحلي were appended at the end of the query in the same
 * shape as the three above.
 *
 * THE EIGHTH PASS, 2026-09-05, APPENDED FOUR MORE BLOCKS in the same shape, for
 * الفحمي and البنفسجي, and the count is now seven non default families. The title
 * still names the rule. Nothing above them was rewritten and no earlier family's
 * promotions moved.
 *
 * THIS SECTION MUST REMAIN THE LAST THING IN THE FILE. That is why 13.5 and 13.6
 * are numbered after it and placed before it: source order is what breaks the
 * 0,2,1 tie between a family light block and this query's own family light block,
 * and moving this section above them would silently stop every promotion.
 *
 * Read section 11 first; every ruling in it is in force here unchanged — the
 * line collapse, the four tier collapse, and the two exemptions that PROMOTE
 * one rung instead of collapsing (the placeholder, which must stay unlike a
 * value the user typed, and the disabled ink, which must stay unlike an
 * available control).
 *
 * WHY THESE BLOCKS EXIST AT ALL. A media query adds no specificity. Section
 * 11's html:root is 0,1,1 and a palette base block is 0,2,1, so without these
 * blocks every promotion above would silently stop applying the moment a user
 * picked a family other than olive — the borders would stay hairlines, the
 * dimmed tiers would stay dimmed and the ring would stay at its resting step,
 * for exactly the users who asked the operating system for more contrast. That
 * is an accessibility regression with no visible symptom in the default theme,
 * which is the kind this file exists to prevent.
 *
 * SOURCE ORDER MATTERS INSIDE THIS QUERY. Each family's LIGHT block here is
 * 0,2,1, the same as its base block, so it wins only because it comes LATER in
 * the file. Each family's DARK block is 0,3,1 and beats its own base dark block
 * outright. Do not move this section above the palette blocks.
 *
 * The border widths and the focus width are NOT restated. No palette block
 * declares them, so section 11's own html:root still wins for those three, and
 * restating them here would be a second copy to keep in step for nothing.
 * ────────────────────────────────────────────────────────────────────────── */
@media (prefers-contrast: more) {
    /* PETROL BLUE, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.76:1 worst
     * case over levels 0 to 3, against the resting 7.23:1. */
    html[data-fx-palette="petrol"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #2a3a39;
        --fx-color-disabled-fg:      #556765;
        --fx-color-link:       var(--fx-p-petrol-900);
        --fx-color-focus-ring: var(--fx-p-petrol-900);
        --fx-color-indicator:  var(--fx-p-petrol-900);
        --fx-color-brand-text: var(--fx-p-petrol-900);
    }

    /* PETROL BLUE, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.15:1 worst case, from 8.98), the mark to the brand
     * ramp's 400 (6.22:1, from 4.76), and the RING onto the accent ramp's 300
     * (9.35:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. */
    html[data-fx-palette="petrol"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #c1d7d3;
        --fx-color-disabled-fg:      #879a99;
        --fx-color-link:       var(--fx-p-petrol-wash-300);
        --fx-color-focus-ring: var(--fx-p-petrol-accent-300);
        --fx-color-indicator:  var(--fx-p-petrol-400);
        --fx-color-brand-text: var(--fx-p-petrol-wash-300);
        --fx-color-primary-border: var(--fx-p-petrol-500);
    }

    /* PLUM, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.74:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. */
    html[data-fx-palette="plum"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #433335;
        --fx-color-disabled-fg:      #715f62;
        --fx-color-link:       var(--fx-p-plum-900);
        --fx-color-focus-ring: var(--fx-p-plum-900);
        --fx-color-indicator:  var(--fx-p-plum-900);
        --fx-color-brand-text: var(--fx-p-plum-900);
    }

    /* PLUM, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.13:1 worst case, from 8.97), the mark to the brand
     * ramp's 400 (6.22:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.34:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. */
    html[data-fx-palette="plum"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #e1cecf;
        --fx-color-disabled-fg:      #a49294;
        --fx-color-link:       var(--fx-p-plum-wash-300);
        --fx-color-focus-ring: var(--fx-p-plum-accent-300);
        --fx-color-indicator:  var(--fx-p-plum-400);
        --fx-color-brand-text: var(--fx-p-plum-wash-300);
        --fx-color-primary-border: var(--fx-p-plum-500);
    }

    /* WARM SAND, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.72:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. */
    html[data-fx-palette="sand"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #3d362b;
        --fx-color-disabled-fg:      #6c6255;
        --fx-color-link:       var(--fx-p-sand-900);
        --fx-color-focus-ring: var(--fx-p-sand-900);
        --fx-color-indicator:  var(--fx-p-sand-900);
        --fx-color-brand-text: var(--fx-p-sand-900);
    }

    /* WARM SAND, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.14:1 worst case, from 8.98), the mark to the brand
     * ramp's 400 (6.22:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.34:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. */
    html[data-fx-palette="sand"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #dbd1c3;
        --fx-color-disabled-fg:      #9f9586;
        --fx-color-link:       var(--fx-p-sand-wash-300);
        --fx-color-focus-ring: var(--fx-p-sand-accent-300);
        --fx-color-indicator:  var(--fx-p-sand-400);
        --fx-color-brand-text: var(--fx-p-sand-wash-300);
        --fx-color-primary-border: var(--fx-p-sand-500);
    }

    /* INDIGO, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.75:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. Rung 900 is also where
     * the owner's own light نص عليها #2C3585 landed, so a user who turns contrast
     * up gets the ink he drew rather than a computed one. */
    html[data-fx-palette="indigo"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #353644;
        --fx-color-disabled-fg:      #606370;
        --fx-color-link:       var(--fx-p-indigo-900);
        --fx-color-focus-ring: var(--fx-p-indigo-900);
        --fx-color-indicator:  var(--fx-p-indigo-900);
        --fx-color-brand-text: var(--fx-p-indigo-900);
    }

    /* INDIGO, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.13:1 worst case, from 8.98), the mark to the brand
     * ramp's 400 (6.22:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.33:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. */
    html[data-fx-palette="indigo"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #ced2e1;
        --fx-color-disabled-fg:      #9196a6;
        --fx-color-link:       var(--fx-p-indigo-wash-300);
        --fx-color-focus-ring: var(--fx-p-indigo-accent-300);
        --fx-color-indicator:  var(--fx-p-indigo-400);
        --fx-color-brand-text: var(--fx-p-indigo-wash-300);
        --fx-color-primary-border: var(--fx-p-indigo-500);
    }

    /* NAVY, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.74:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. Rung 900 is also where
     * the owner's own light نص عليها #083A75 landed. */
    html[data-fx-palette="navy"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #2f3841;
        --fx-color-disabled-fg:      #5c6471;
        --fx-color-link:       var(--fx-p-navy-900);
        --fx-color-focus-ring: var(--fx-p-navy-900);
        --fx-color-indicator:  var(--fx-p-navy-900);
        --fx-color-brand-text: var(--fx-p-navy-900);
    }

    /* NAVY, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.15:1 worst case, from 9.00), the mark to the brand
     * ramp's 400 (6.23:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.35:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. The accent ramp is what makes that ring readable AS a ring on
     * this family in particular: a promoted ring on the brand ramp would sit on
     * the info hue, which is the recognition problem recorded in 13.6. */
    html[data-fx-palette="navy"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #cad3e2;
        --fx-color-disabled-fg:      #8e97a5;
        --fx-color-link:       var(--fx-p-navy-wash-300);
        --fx-color-focus-ring: var(--fx-p-navy-accent-300);
        --fx-color-indicator:  var(--fx-p-navy-400);
        --fx-color-brand-text: var(--fx-p-navy-wash-300);
        --fx-color-primary-border: var(--fx-p-navy-500);
    }

    /* GRAPHITE, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.74:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. */
    html[data-fx-palette="graphite"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #2e3843;
        --fx-color-disabled-fg:      #5c6471;
        --fx-color-link:       var(--fx-p-graphite-900);
        --fx-color-focus-ring: var(--fx-p-graphite-900);
        --fx-color-indicator:  var(--fx-p-graphite-900);
        --fx-color-brand-text: var(--fx-p-graphite-900);
    }

    /* GRAPHITE, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.13:1 worst case, from 8.99), the mark to the brand
     * ramp's 400 (6.22:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.34:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. On THIS family that last guarantee is the tightest in the
     * system and it is measured rather than assumed: at s 0.395 the accent is as
     * quiet as the brand, so the promoted ring and the promoted text separate by
     * OKLab dE 0.0400 with 46.6 degrees of hue between them, against النيلي's
     * 0.0774. Two just noticeable differences, carried by hue rather than by
     * chroma. The lever if it ever needs more room is the accent SCALE. */
    html[data-fx-palette="graphite"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #cad3e2;
        --fx-color-disabled-fg:      #8d97a7;
        --fx-color-link:       var(--fx-p-graphite-wash-300);
        --fx-color-focus-ring: var(--fx-p-graphite-accent-300);
        --fx-color-indicator:  var(--fx-p-graphite-400);
        --fx-color-brand-text: var(--fx-p-graphite-wash-300);
        --fx-color-primary-border: var(--fx-p-graphite-500);
    }

    /* VIOLET, light. Restated in full because the family base block above is
     * 0,2,1 and would otherwise beat this query's own html:root at 0,1,1. The
     * two exemptions in the header still hold: the placeholder and the disabled
     * ink PROMOTE one rung instead of collapsing, and both are literals for the
     * reason given there. Promotions measured: link and brand text 10.74:1 worst
     * case over levels 0 to 3, against the resting 7.24:1. */
    html[data-fx-palette="violet"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #3a3540;
        --fx-color-disabled-fg:      #67616f;
        --fx-color-link:       var(--fx-p-violet-900);
        --fx-color-focus-ring: var(--fx-p-violet-900);
        --fx-color-indicator:  var(--fx-p-violet-900);
        --fx-color-brand-text: var(--fx-p-violet-900);
    }

    /* VIOLET, dark. 0,3,1, so it beats both the family base dark block and the
     * light promotion above. The mark and the brand text still promote onto
     * DIFFERENT ramps, the same split section 3 makes at rest, so neither
     * changes hue on a user who turned contrast up: link and brand text to the
     * wash ramp's 300 rung (10.13:1 worst case, from 8.99), the mark to the brand
     * ramp's 400 (6.23:1, from 4.75), and the RING onto the accent ramp's 300
     * (9.34:1) so a 2px line never becomes the same colour as the brand text it
     * may surround. This family has the widest room of the eight for that split,
     * at OKLab dE 0.0581 between the two, because its accent carries the full
     * olive chroma at a hue 27 degrees off the brand. */
    html[data-fx-palette="violet"][data-bs-theme="dark"]:root {
        --fx-color-border-subtle:      var(--fx-color-border-strong);
        --fx-color-border:             var(--fx-color-border-strong);
        --fx-color-border-emphasis:    var(--fx-color-border-strong);
        --fx-color-divider-strong:     var(--fx-color-border-strong);
        --fx-color-divider:            var(--fx-color-border-strong);
        --fx-color-divider-soft:       var(--fx-color-border-strong);
        --fx-color-divider-faint:      var(--fx-color-border-strong);
        --fx-color-text-muted:  var(--fx-color-text);
        --fx-color-text-subtle: var(--fx-color-text);
        --fx-color-text-faint:  var(--fx-color-text);
        --fx-color-text-placeholder: #d5d0e0;
        --fx-color-disabled-fg:      #9c93a3;
        --fx-color-link:       var(--fx-p-violet-wash-300);
        --fx-color-focus-ring: var(--fx-p-violet-accent-300);
        --fx-color-indicator:  var(--fx-p-violet-400);
        --fx-color-brand-text: var(--fx-p-violet-wash-300);
        --fx-color-primary-border: var(--fx-p-violet-500);
    }
}
