/* ReSouris — Design tokens (BPP-10 WP-10.1; v1.2 light-theme flip)
 *
 * Our own design system. Palette is checked against WCAG 2.2 AA
 * contrast ratios from day one (NFR-017).
 *
 * ⚠️ THAT CLAIM WAS NOT TRUE UNTIL 2026-09-03, AND THE REASON IS WORTH
 * KEEPING. This header used to cite an "axe-core gate at WP-10.5" as the
 * thing enforcing it. There is no such gate: tests/ui/test_a11y.py says in
 * its own docstring that axe-core "ships at BPP-11 once a browser harness is
 * wired" and that it deliberately does not pull in axe-core's static port.
 * So that suite checks STRUCTURE -- labels, skip links, accessible names --
 * and has never computed a contrast ratio. The budget below was written by
 * hand and never measured.
 *
 * When it was finally measured (axe-core 4.11 against the running server,
 * 15 screens), --accent was 3.91 on --bg where this file claimed ~5:1, and
 * every primary button, link and sidebar label on every screen failed 1.4.3.
 * The numbers below are now MEASURED, not asserted. If you change a colour
 * here, re-measure -- a hand-written ratio is how this happened.
 *
 * Palette posture: LIGHT theme (v1.2 default). Workforce rostering tool
 * used in office + clinical settings; light surfaces match the rest of
 * the staff member's day (Outlook, EPR, SharePoint) and read better
 * under bright fluorescent lighting.
 *
 * Contrast budget (text vs --bg), measured 2026-09-03:
 *   --text-primary    17.06:1 (AAA)  #0F172A on #F8FAFC
 *   --text-secondary   7.24:1 (AAA)  #475569 on #F8FAFC
 *   --accent           5.67:1 (AA)   #0369A1 on #F8FAFC
 *   --success          7.34:1 (AAA)  #065F46 on #F8FAFC
 *   --warning          5.98:1 (AA)   #9A4A08 on #F8FAFC
 *
 * The previous dark theme tokens are preserved below under
 * `[data-theme="dark"]`; setting `<html data-theme="dark">` flips
 * straight back without code changes.
 */

:root {
  /* ⚠️ **THE PROPERTY, NOT THE MEDIA QUERY.** `prefers-color-scheme` asks what
     the USER wants; `color-scheme` tells the browser what this PAGE IS, and it
     governs every widget the UA paints itself rather than us: scrollbars,
     `select` popups, date and time pickers, checkbox and radio defaults, spin
     buttons and the caret.
     Until 2026-09-30 this was never declared, so a `data-theme="dark"` page
     computed `color-scheme: normal` and the UA painted its LIGHT widgets on it.
     Marcus spotted it as "the scrollbar has a white background". v1.35 §10.4.

     ⚠️ **DO NOT EXPECT THIS TO MOVE THE CONTRAST NUMBERS.** A UA-painted widget
     has no text of ours in it, so a contrast audit cannot see this fix at all —
     measured, both themes, before and after: 36 of 1,521 dark failures, and
     those came from the other edits in the same wave. I first attributed 469
     failures to UA defaults because #A8A9AD and #DDDDDE appear in no file; they
     turned out to be `rgba(255,255,255,0.85)` from `.rg-menu-btn` COMPOSITED
     over two different surfaces. Absence from a grep means "not written
     literally", never "not ours". */
  color-scheme: light;

  /* ---- Surfaces ---- */
  --bg:               #F8FAFC;  /* slate-50; app background */
  --surface:          #FFFFFF;  /* white; cards, panels */
  --surface-raised:   #F1F5F9;  /* slate-100; hovered surfaces */
  /* A TRANSLUCENT surface, for a control floating over coloured content that has
     to keep showing through — the roster grid's per-cell ⋯ menu button. It must
     be a token and not `rgba(255,255,255,0.85)` written in place: that literal
     composited to #DDDDDE over --surface and #A8A9AD over --surface-raised, and
     carried the grid's themed --text-secondary at **1.10:1 — 434 dark failures,
     29% of the product's total, from one button class**. ⚠️ No grep could find
     it: the failing colour is COMPOSITED and appears in no file. v1.35 §10.3. */
  --surface-scrim:      rgba(255, 255, 255, 0.85);
  --surface-scrim-soft: rgba(255, 255, 255, 0.60);  /* over an empty cell */
  --border-subtle:    rgba(15, 23, 42, 0.10);  /* slate-900 @ 10% */
  --border-strong:    rgba(15, 23, 42, 0.22);

  /* ---- Text ---- */
  --text-primary:     #0F172A;  /* slate-900; body + headings */
  --text-secondary:   #475569;  /* slate-600; metadata, captions */
  /* ⚠️ **--text-disabled IS FOR STATES WCAG 2.2 §1.4.3 EXEMPTS — placeholders
     and inactive controls — AND NOTHING ELSE.** At 2.45:1 it is below AA by
     design. v1.35 §9.2 found 21 of its 26 call sites were informational text
     borrowing it as a "faint" colour, which made it the sole cause of every
     light-mode contrast failure on the audited screen. **If the text carries
     meaning, it wants --text-muted, which is the faintest grey that passes.** */
  --text-disabled:    #94A3B8;  /* slate-400; placeholder, disabled state */

  /* ---- v1.35 Cohort C: three pairs, light pinned to the literal in use ----
     ⚠️ The light value IS the hex these replace, so light mode cannot move; only
     the dark counterpart was chosen, and it was picked to preserve the LIGHT
     hierarchy rather than merely clear 4.5:1. Measured on --bg #14161A. */
  --text-secondary-strong: #334155;  /* slate-700; 9.90:1 light. 43 uses */
  --text-tertiary:         #64748B;  /* slate-500; 4.55:1 light. 20 uses */
  /* ⚠️ **AMBER #78350F IS DELIBERATELY NOT TOKENISED — IT CANNOT BE UNTIL #63.**
     It was, and the swap was reverted after measurement: most of its 43 sites
     are amber text on a HARDCODED pale amber tint (#FEF3C7, #FFFBEB) that has no
     dark value, so theming the text alone put light-amber on light-amber at
     1.74:1 — six elements that had been PASSING. The text and its background
     have to move together. v1.35 §9.6. */

  /* ---- v1.35 Cohort A: the `--color-*` scheme, declared at last ---- */
  /* ⚠️ **637 `var()` CALLS ALREADY REFERENCE THESE AND NOTHING DEFINED THEM.**
     A whole naming scheme was designed and never wired. Measured 2026-09-29:
     29 undefined properties, 576 references carrying a light-literal fallback
     and 61 carrying none.

     Proven in Chrome rather than reasoned about:
       var(--undeclared)            -> the PARENT's colour (invalid at
                                       computed-value time, so it inherits)
       var(--undeclared, #6b7280)   -> exactly the fallback
       ...once declared             -> the declared value; the declaration WINS

     So `var(--color-text-muted, #6b7280)` was a HARDCODED LIGHT COLOUR WEARING
     A TOKEN'S CLOTHES: it greps as tokenised and was not themed at all, which
     is why #6B7280 is the most common literal in the product (201x in
     templates) and rendered at 3.75:1 in dark mode.

     ⚠️ **NOT ONE COLOUR HERE IS INVENTED, DELIBERATELY.** Marcus rejected a
     dark palette on look once already (v1.23 §1), so every value below is
     either the literal these call sites ALREADY pass as their fallback (the
     light column, so light mode does not move) or the dark value of an
     existing, already-measured token (the dark column). See
     v1.35 §3a for the derivation and every ratio.

     ⚠️ **SEVEN OF THESE HAD CALL SITES THAT DISAGREED** about the fallback --
     --color-text-muted rendered three different greys depending on where it
     was called. Declaring one value normalises them, which IS a small light-mode
     change at the minority sites. That is a correction (one semantic token, one
     colour) but it is a change, and v1.35 §3a records it rather than burying it. */
  --color-text:        #111827;  /* majority fallback; ~--text-primary */
  --text:              #111827;  /* same, older spelling, 2 refs */
  --color-text-muted:  #6B7280;  /* 4.62:1 on --bg */
  --text-muted:        #6B7280;  /* same, older spelling */
  --muted:             #6B7280;  /* same, 12 refs with NO fallback */
  --color-accent:      #2563EB;  /* 4.94:1 on --bg */
  --color-link:        #2563EB;  /* same; 5 refs, none with a fallback */
  --color-success:     #2E7D32;  /* 4.90:1 on --bg */
  --color-warning:     #B06000;  /* ⚠️ 4.44:1 -- marginally under AA, and
                                    PRE-EXISTING: this is the fallback already
                                    in use. Not worsened here; logged in v1.35. */
  --color-surface:     #FFFFFF;  /* = --surface */
  --color-surface-2:   #F9FAFB;  /* ~--surface-raised */
  /* ✅ #E5E7EB is the light --border-subtle by another name: that rgba
     composites over white to #E7E8EA, within 2/255 per channel. So this is the
     existing border, not a new one. */
  --color-border:      #E5E7EB;
  --border:            #D0D0D0;  /* majority fallback of 18 refs */

  /* ---- Accent + status ---- */
  /* ⚠️ sky-700, NOT sky-600. #0284C7 measured 4.10:1 against white and
     3.91:1 against --bg -- below the 4.5:1 that 1.4.3 requires. Contrast is
     symmetric, so that one value failed in both directions at once: white
     text ON the accent (every primary button, the skip link on all 15
     screens) and accent text on white (links, <summary> toggles). */
  --accent:           #0369A1;  /* sky-700; links, focus, primary actions */
  --accent-on:        #FFFFFF;  /* text colour on accent fills */
  /* Kept in step with --accent by hand, because it is spelled as rgba rather
     than derived: this was rgba(2,132,199) -- the OLD #0284C7 -- and would
     otherwise have left every soft tint keyed to a colour the palette no
     longer contains. */
  --accent-soft:      rgba(3, 105, 161, 0.10);

  /* ⚠️ Both darkened one step 2026-09-03. These are pill text on tinted pill
     backgrounds, and they failed by hairlines rather than by miles --
     #047857 on #DCECE7 measured 4.49:1 against a 4.5:1 requirement. A margin
     that thin is not a pass that happens to be tight; it is a value nobody
     measured, and the next tint tweak would have moved it either way.

     ⚠️ **AND THE SAME JUDGEMENT WAS APPLIED AGAIN 2026-09-30 (v1.35 E4).** 27
     `color:` declarations used `#B45309` (amber-700) and `#15803D` (green-700)
     directly. Both were hairlines in light — **4.58:1 on --surface-raised** —
     where these tokens clear 5.71 and 7.01, so they now point here instead of
     pinning two new tokens to a margin this file already refuses to accept.
     ⚠️ That IS a light-mode change (one step darker) and it is stated rather
     than folded in, per v1.35 §3a.

     ⚠️ **WHY ONLY THOSE TWO OF NINE CANDIDATE LITERALS.** A token swap is
     global, so it is scoped by the sites that currently PASS, not by the ones
     that fail. Measured across 165 screens in dark mode, these two were the
     only literals with **zero** sites sitting on a hardcoded background:

       #B45309  135 sites, 135 themed,   0 literal   -> safe
       #15803D  106 sites, 106 themed,   0 literal   -> safe
       #1D4ED8  257 sites, 250 themed,   7 literal   -> per-site only
       #78350F   90 sites,  46 themed,  44 literal   -> #63, see below
       #047857  132 sites,   4 themed, 128 literal   -> #63

     Only `color:` moved — not `background`, not `border`. v1.35 §10.10. */
  --success:          #065F46;  /* emerald-800 */
  --warning:          #9A4A08;  /* amber-800 */
  --danger:           #B91C1C;  /* red-700 */
  /* ⚠️ **THE FOURTH STATUS COLOUR, MISSING UNTIL 2026-09-30.** The palette had
     three; the UI has four status pills, and `.pill--info` was the only one of
     the four hardcoding its colours while its three siblings used tokens. Its
     siblings were the specification.
     Light is **pinned to `#1D4ED8`, the literal `.pill--info` already rendered**,
     so light mode cannot move; dark `#93C5FD` was already in the codebase as
     `.roster-summary__chip--accent`'s border, so nothing here is invented.
     Measured on its own 14% tint — 5.50 light, 5.92 dark — which sits in family
     with danger 5.08/5.56 and success 6.16/7.78.
     ⚠️ **`--accent` WAS THE OBVIOUS ANSWER AND IT WAS WRONG**: it would have
     given 4.83/5.27, the weakest of the four in both themes AND a light
     regression from what the pill renders today. An existing semantic token is
     not automatically the right one. v1.35 §10.13.1. */
  --info:             #1D4ED8;  /* blue-700 */

  /* ---- Spacing scale (4 px base) ---- */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* ---- Control sizing (v1.92) ----
   *
   * The minimum height of a form control, and the ONLY home for that value.
   *
   * ⚠️ **32px is a deliberate conformance decision, not a taste one.**
   * `docs/accessibility-conformance.md` claims **WCAG 2.2 AA**, whose target
   * criterion is **2.5.8 — Target Size (Minimum), 24×24px**. 44×44 is
   * **2.5.5 — Target Size (Enhanced), level AAA**, which this product neither
   * claims nor tests. Every form row was spending 20px on an unclaimed level;
   * v1.91 measured 167px reclaimed on a single form.
   *
   * ⛔ **DO NOT GO BELOW 24px** — that breaks a documented conformance claim,
   * and buys nothing: measured in v1.91, both 28px and 24px still yield a
   * 39px row because the LABEL becomes the floor.
   *
   * ⛔ **AND DO NOT REPLACE A `var(--control-min-h)` WITH A LITERAL.** The
   * whole point of a token here is that it INHERITS: the coarse-pointer
   * override in screens.css restores 44px for a finger, and it reaches a rule
   * at the bottom of that 5000-line file exactly as well as one at the top.
   * v1.91 shipped the specificity version of this and measured the result —
   * a tablet silently getting a 32px touch target, with every test green and
   * the desktop looking right. A literal re-opens that hole for one rule. */
  --control-min-h: 32px;

  /* The painted size of a checkbox or radio, and the ONLY home for it.
   *
   * ⚠️ **24px IS THE AA FLOOR ITSELF, NOT A COMFORTABLE MARGIN ABOVE IT.**
   * These were 22px at three separate sites — below 2.5.8 on the narrow axis,
   * measured and recorded by v1.91 as a pre-existing defect. ⛔ Any reduction
   * is a conformance regression, not a density choice.
   *
   * ⓘ Deliberately NOT raised to 44px on a coarse pointer, unlike
   * --control-min-h. A checkbox's effective target includes its `<label>`,
   * which is associated and carries `cursor: pointer`, so the finger has far
   * more than 24px to aim at; and the row around it IS raised to 44px. A
   * 44px painted box would be the only control in the product that changes
   * SIZE rather than spacing between pointer types. */
  --control-target-min: 24px;

  /* ---- Type scale ---- */
  --font-stack: system-ui, -apple-system, "Segoe UI", Roboto,
                "Helvetica Neue", Arial, sans-serif;
  --font-mono:  ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --text-xs:   12px;
  --text-sm:   14px;
  --text-base: 16px;
  --text-lg:   18px;
  --text-xl:   22px;
  --text-2xl:  28px;
  --text-3xl:  36px;
  --line-tight:  1.2;
  --line-normal: 1.5;

  /* ---- Radii ---- */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 16px;
  --radius-pill: 999px;  /* v1.4.2 idiom — pill-shaped chips/badges */

  /* ---- Elevation (light theme: softer, narrower spread) ---- */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08);
  --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12);
  --shadow-hover: 0 8px 24px rgba(15, 23, 42, 0.14);  /* v1.4.2 hover lift */

  /* ---- Focus ring (a11y; high contrast on every surface) ---- */
  --focus-ring: 0 0 0 3px rgba(2, 132, 199, 0.45);
  --focus-ring-aria: 0 0 0 3px rgba(2, 132, 199, 0.25),
                     0 8px 18px rgba(2, 132, 199, 0.16);  /* v1.4.2 focus glow */

  /* ---- Motion ---- */
  --motion-fast:   120ms;
  --motion-normal: 200ms;
  --motion-slow:   320ms;
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
}

/* Dark theme. Set `<html data-theme="dark">`, or leave the choice unset and
 * the console follows `prefers-color-scheme`.
 *
 * ⚠️ **NEUTRAL CHARCOAL, NOT SLATE, AND THAT IS THE WHOLE CHANGE.** The previous
 * palette was Tailwind's `slate` family — #0F172A / #1E293B / #38BDF8 — which
 * carries a pronounced blue cast, and it read as exactly that: Marcus,
 * 2026-09-16, *"I'd really like the Dark theme to look more like the one we put
 * into VermontiV2 rather than this 'bluey' one."* These values are Vermonti's,
 * mapped onto this product's token names so nothing downstream changes.
 *
 * ⚠️ **ADOPTED ONLY AFTER MEASURING, BECAUSE THIS FILE HAS CLAIMED A RATIO IT
 * DID NOT HAVE BEFORE.** Contrast against `--surface` #1C1F25, measured
 * 2026-09-16:
 *
 *   --text-primary    #E8EAEF  13.72:1  AAA
 *   --text-secondary  #9AA2B1   6.43:1  AA
 *   --accent          #7FA5F5   6.76:1  AA
 *   --warning         #F0C675  10.25:1  AAA
 *   --success         #6EE7B7  10.83:1  AAA
 *   --danger          #F98A8A   7.10:1  AAA
 *
 * Against `--bg` #14161A every one of them is AAA. The two Vermonti does not
 * define — success and danger — were chosen to sit in the same neutral-friendly
 * register and measured on the same basis rather than picked by eye.
 *
 * ⚠️ `--accent-on` is DARK because this accent is LIGHT: it is the text colour
 * that sits ON an accent fill, and inheriting the light theme's white would put
 * white on a pale periwinkle button.
 */
[data-theme="dark"] {
  /* The other half of the pair declared in `:root` — see the note there. Without
     this line every UA-painted widget on a dark page stays light, and `system`
     mode is covered because `base.html` resolves it to an explicit `data-theme`
     in `<head>` before first paint. */
  color-scheme: dark;

  --bg:               #14161A;
  --surface:          #1C1F25;
  --surface-raised:   #252931;
  /* --surface at the same alphas, so the chip still lets the cell colour through
     but reads as dark. See the note in `:root`. */
  --surface-scrim:      rgba(28, 31, 37, 0.85);
  --surface-scrim-soft: rgba(28, 31, 37, 0.60);
  --border-subtle:    rgba(159, 168, 184, 0.18);
  --border-strong:    rgba(159, 168, 184, 0.42);

  --text-primary:     #E8EAEF;
  --text-secondary:   #9AA2B1;
  /* ⚠️ 3.75:1, and DARKER than its own light value (#94A3B8). That is wrong for
     a dark theme and it is deliberately not "fixed" here: this token means
     "inactive control", which WCAG exempts, and raising it would make disabled
     things look enabled. The fix was to stop informational text using it —
     v1.35 §9.2. Its 5 remaining call sites are all placeholders or [disabled]. */
  --text-disabled:    #6B7280;

  /* ---- v1.35 Cohort C, dark counterparts. Ratios on --bg #14161A ---- */
  --text-secondary-strong: #BFC6D1;  /* 10.53:1 — matches light's 9.90 */
  --text-tertiary:         #9AA2B1;  /*  7.05:1 — ⚠️ deliberately the SAME as
                                        --text-secondary: in light #64748B and
                                        #6B7280 are 4.55 and 4.62, the same grey
                                        to the eye, so a separate dark value
                                        would be a distinction nobody can see.
                                        They stay two tokens so LIGHT stays pinned. */
  /* No --warning-text here: see the light block. #E3B264 measured 9.33:1 on
     --bg and would be correct — on a themed background. Blocked on #63. */

  --accent:           #7FA5F5;
  --accent-on:        #14161A;
  --accent-soft:      rgba(127, 165, 245, 0.12);

  --success:          #6EE7B7;
  --warning:          #F0C675;
  --danger:           #F98A8A;
  /* blue-300; see the note beside the light value. Already present in the
     codebase as a border colour, so this invents nothing. */
  --info:             #93C5FD;

  /* ---- v1.35 Cohort A: the dark half of the `--color-*` scheme ---- */
  /* Every value here is ALREADY IN THE PALETTE ABOVE and already measured —
     nothing new was chosen. Ratios re-measured 2026-09-29 against --bg #14161A
     and --surface #1C1F25 respectively:
         --color-text        15.05 / 13.72 : 1
         --color-text-muted   7.05 /  6.43 : 1
         --color-accent       7.42 /  6.76 : 1
         --color-success     11.88 / 10.83 : 1
         --color-warning     11.25 / 10.25 : 1
     all far above the 4.5:1 AA floor for body text. */
  --color-text:        #E8EAEF;  /* = --text-primary */
  --text:              #E8EAEF;
  --color-text-muted:  #9AA2B1;  /* = --text-secondary */
  --text-muted:        #9AA2B1;
  --muted:             #9AA2B1;
  --color-accent:      #7FA5F5;  /* = --accent */
  --color-link:        #7FA5F5;
  --color-success:     #6EE7B7;  /* = --success */
  --color-warning:     #F0C675;  /* = --warning */
  --color-surface:     #1C1F25;  /* = --surface */
  --color-surface-2:   #252931;  /* = --surface-raised */
  /* ✅ DERIVED, NOT PICKED: this is what --border-subtle rgba(159,168,184,0.18)
     composites to over --surface. The solid form is needed because these call
     sites pass a solid hex fallback, and a border must not become invisible. */
  --color-border:      #34383F;
  --border:            #34383F;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
  --shadow-hover: 0 8px 24px rgba(0, 0, 0, 0.50);

  --focus-ring: 0 0 0 3px rgba(127, 165, 245, 0.55);
  --focus-ring-aria: 0 0 0 3px rgba(127, 165, 245, 0.30),
                     0 8px 18px rgba(127, 165, 245, 0.22);
}

/* Respect operator preference. Reduced motion = instant transitions. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast:   0ms;
    --motion-normal: 0ms;
    --motion-slow:   0ms;
  }
}

/* ---- Service-line identity palette (WP-P49 roster timeline) ----
   Ten saturated fills, ALWAYS white text. Chosen by search rather than
   taste: every entry clears WCAG AA against white (weakest 4.60:1) and the
   closest pair sits dE 18.3 apart in CIE Lab, so they stay distinguishable
   at the 10px the timeline renders them.

   ⚠️ NO red, amber or green. Those three belong to the Trust Admin traffic
   light (`.rg-ta-led`) and to `application/trust_admin.PALETTE`, which uses
   the pale tints of exactly those hues to mean STATE. Identity and state
   must not share a hue family, or the same colour means two things on one
   screen.

   ⚠️ Identical in light and dark. A saturated fill with white text works on
   both grounds, and a service line that changed colour with the theme would
   stop being recognisable — which is the entire job of the palette.

   ⚠️⚠️ **DO NOT ADD A THEMED TOKEN TO THE `:root` BLOCK BELOW.** It comes
   AFTER `[data-theme="dark"]`, and both selectors have specificity (0,1,0) —
   `:root` is a pseudo-class, `[data-theme="dark"]` an attribute selector — so
   **source order decides and the later block wins**. Any token declared in both
   would silently render its LIGHT value in dark mode, with no error anywhere.
   This is safe today only because the two blocks declare disjoint sets: the one
   below is `--sl-*` alone, which the dark theme deliberately does not override
   (see the paragraph above). A themed colour added here would be a theme bug
   that looks like a palette choice. v1.35 §10.13.4. */
:root {
  --sl-1:  #2563EB;  /* blue    */
  --sl-2:  #1E40AF;  /* navy    */
  --sl-3:  #0369A1;  /* steel   */
  --sl-4:  #0E7490;  /* cyan    */
  --sl-5:  #0F766E;  /* teal    */
  --sl-6:  #4F46E5;  /* indigo  */
  --sl-7:  #7E22CE;  /* purple  */
  --sl-8:  #A21CAF;  /* fuchsia */
  --sl-9:  #DB2777;  /* pink    */
  --sl-10: #475569;  /* slate   */
  --sl-ink: #FFFFFF;
}
