/*
 * SimIS CMS - Design tokens and color scheme support
 *
 * Loaded after platform.css and before the theme's inline <style> block.
 *
 * Layer 1  Semantic design tokens (--sc-*) with light-mode values.
 * Layer 2  Dark-mode token overrides.
 * Layer 3  Chrome that consumes the tokens.
 *
 * IMPORTANT - light mode is intentionally left alone. Foundation and
 * platform.css already paint every surface in light mode, so Layer 3 only
 * repaints under [data-theme="dark"]. A site that never opts in renders
 * exactly as it did before this file existed. The handful of rules that do
 * apply in both modes (focus ring, reduced motion) are additive
 * accessibility fixes, called out individually below.
 *
 * Color scheme is selected by the data-theme attribute on <html>:
 *   data-theme="light"  forced light (the default; see theme.ui.mode)
 *   data-theme="dark"   forced dark
 *   data-theme="auto"   follow the operating system preference
 * A missing attribute is treated as light.
 *
 * Contrast: every token pairing below was checked against WCAG 2.2.
 * Text pairings meet 1.4.3 Contrast (Minimum) at 4.5:1. Control borders
 * meet 1.4.11 Non-text Contrast at 3:1. Purely decorative separators are
 * exempt from 1.4.11 and use the lower-contrast --sc-border on purpose.
 */

/* ==========================================================================
   Layer 1 - Semantic tokens (light)
   ========================================================================== */

:root {
  /* Surfaces - "Black Pearl" palette: ink/anthracite/link-blue on frost */
  --sc-surface: #f5f3ef;
  --sc-surface-raised: #ffffff;
  --sc-surface-sunken: #ede9e3;
  --sc-surface-overlay: #ffffff;

  /* Text - contrast vs --sc-surface: text 13.06:1, muted 5.00:1, link 4.99:1.
     Pewter (#979CA4, 2.76:1 on white / 2.53:1 on frost as text) and
     Platinum (#D9DCE1, 1.37:1 as a control border) both fail AA as given --
     --sc-text-muted uses a darkened "pewter-strong" and --sc-border-control
     a darkened "platinum-strong". True Platinum is kept for decorative borders.

     Placeholder text is NOT exempt from SC 1.4.3, contrary to what this note
     used to say. The criterion's exceptions are incidental text -- inactive
     controls, pure decoration, invisible text, text in a picture carrying other
     significant content -- plus logotypes. Placeholder text in an active input
     is none of those, and #1490 already acted on that reading in dark mode. So
     --sc-field-placeholder is a text token and carries a text ratio. */
  --sc-text: #2c2925;
  /* Darkened so it clears the sunken frost surface as well as the white page, not
     only the page: muted on sunken 4.58:1, muted on surface 5.00:1. The previous
     value was derived against white alone and fell short on frost. There is no
     surface-side fix here -- frost is the lighter of the pair, so it would have to
     become white to rescue the old ink, at which point it is not a surface. Light
     tokens never sit on a dark ground, so darkening costs nothing elsewhere.
     Issue 1498. */
  --sc-text-muted: #6c6861;
  /* Sidebar chrome on the dark admin rail (#17191e): 6.37:1. Its own token because
     platform.css was reading --sc-field-placeholder for this, which tied unrelated
     things together -- raising the placeholder to clear SC 1.4.3 on a white field
     would have dragged this token's own consumers below that floor on the rail,
     and broken them silently. */
  --sc-text-subtle: #a09b93;

  /* Admin rail chrome. The rail is not a themed surface -- it is dark in light mode
     and dark in dark mode -- so these are declared once here and deliberately never
     redefined below, the same way --sc-text-subtle above is. Ink and ground move
     together or not at all.

     Pointing rail ink at a themed token is what broke it: --sc-text-inverse flips to
     #17191e in dark while the rail's own background stayed a literal #17191e, so the
     product name was painted in exactly its own background colour. Issue 1574.

     These are the Slate Command values, replacing the Crema warm set. The warm rail was
     not wrong on its own terms -- every pairing passed -- but it sat under a site header
     the admin scoping deliberately does not restyle, so a warm console met a cool header
     and the join read as unfinished. A navy rail belongs to the same family as that
     header, which is the whole reason for the change.

     Still true from the Crema note, and worth keeping: --sc-chrome-raised must not be a
     brand accent pressed into service as a surface. At #53575c it was, and it sat
     barely off the rail, so the active item read as a washed grey slab (issue 1489, the same
     mistake one family over in --sc-surface-raised).

     ink on rail 14.05:1, ink on raised 12.42:1, muted on rail 7.98:1, muted on raised 7.05:1 */
  --sc-chrome: #17202d;
  --sc-chrome-raised: #1f2a39;
  --sc-chrome-ink: #e8eef6;
  --sc-chrome-ink-muted: #aab6c6;

  /* Translucent on purpose, both of them, and taken from the mockup rather than flattened.
     An opaque approximation was the first thing tried here and it is wrong for two
     reasons: the rail is a gradient, so a flat hover patch paints over it and flattens the
     one spot the pointer is on; and a hairline has to sit on whatever it happens to cross.
     Letting the rail show through is the whole point of expressing them as an overlay.

     Two values, not one -- the mockup separates the hover wash (0.06) from the rule it
     draws under the user row (0.09), and using the hover value for the hairline made it
     disappear. */
  --sc-chrome-hover: rgba(232, 238, 246, 0.06);
  --sc-chrome-border: rgba(232, 238, 246, 0.09);

  /* The selected nav item, split out of --sc-chrome-raised because Crema INVERTS it: a
     dove fill carrying dark ink, where every other rail surface carries light ink. One
     token cannot say both, and --sc-chrome-raised was saying it for three unrelated
     things -- the active item, the user chip and a status-update box. Only the first is a
     selection, which is why the chip looked selected too.

     The signal now sits in the marker, not the fill. Crema used a pale dove fill that
     carried the selection on its own; Slate marks the item with a
     3px --sc-chrome-active-marker bar and white ink, and tints the row only faintly.

     That is a deliberate re-base, not an oversight. A fill bright enough to carry the
     non-text floor against a navy rail on its own would need to be around #5a6b80 -- a mid-slate slab,
     which is the washed-out look issue 1489 removed. The marker carries the requirement
     instead, at 5.85:1 on the rail and 4.12:1 across the fill it sits beside, both clear
     of what a non-text indicator needs. The fill is decoration and is stated as such.

     selected ink on selected 11.55:1, ink on selected 9.90:1,
     selected fill vs rail 1.42:1 (decorative -- the marker is the signal) */
  --sc-chrome-selected: #2b3a4e;
  --sc-chrome-ink-selected: #ffffff;

  /* A third ink tier for chrome, issue 1590. The page scale has had three levels since it was
     built -- --sc-text, --sc-text-muted, --sc-text-subtle -- and chrome had two, so the editor
     expressed its quietest text as literals instead: #aaa on the toolbar title and status, #999 on
     the empty preferences state, #888 on a close button. Routing those to --sc-chrome-ink-muted
     would have read as adoption while flattening three deliberate levels into one.

     Not --sc-text-subtle, for the reason the state family cannot be adopted either: that token
     flips between light and dark, and chrome does not. This one is defined here in :root only,
     like the rest of the family.

     Left cool while its siblings went warm: it is the page editor's tier, not the rail's,
     and every warm candidate that reads correctly on the rail lands under 4.5:1 on
     --sc-chrome-control. Warming it needs its own contrast pass, not a colour swap.

     subtle on chrome 5.88:1, subtle on control 4.79:1 */
  --sc-chrome-ink-subtle: #8f9cae;

  /* The page editor's chrome, issue 1590. The editor is theme-invariant dark for the same
     reason the rail is -- it floats over page content whose colour it does not control --
     so it belongs to this family rather than to the themed surfaces. Its 38 navy and blue
     literals read from here now.

     --sc-chrome-control is a level the rail never needed: a control fill sitting ON chrome
     (the editor's inputs, selects, textareas, preset buttons and secondary buttons), with
     --sc-chrome-control-hover as its hover. --sc-chrome-raised cannot do this job -- it is
     light enough to put --sc-border-control under the 3:1 that SC 1.4.11 asks between a
     control and its surroundings, which is the boundary issue 1518 was opened to fix. That
     failure is registered below so it stays true: this level exists because of it.

     The values are picked on this family's own hue ramp against the border token rather
     than matched to the navy they replace, because the navy did not clear the bar either:
     the editor's secondary buttons sat under 1.4.11 on a control boundary at rest and
     further under it hovered. Both clear it on these two levels -- see the claims below.

     control fill: ink 11.45:1, muted 6.50:1, border 3.63:1
     control hover: border 3.32:1
     border on the raised level: 3.94:1

     --sc-chrome-accent is the editor's interactive accent -- selection, focus, the active
     widget, primary actions -- seeded at the blue it has always used, so routing it changed
     no pixels. Whether that accent stays blue or moves to the brand is a live question; it
     is one line here now instead of eighteen sites. --sc-chrome-accent-deep is its pressed
     and hover partner, and absorbs the #003d82 the focus outline used, which differed from
     #004494 by 0.013 luminance. */
  --sc-chrome-control: #243040;
  --sc-chrome-control-hover: #293648;
  --sc-chrome-accent: #0156b2;
  --sc-chrome-accent-deep: #004592;

  /* The 3px bar marking the active rail item. Kept as its own token -- a marker is a
     distinct role from a fill or an ink, and it was the last hardcoded colour in the rail,
     which mattered because a theme could change everything else and leave a stripe behind.

     It was a lightened link-blue while the active item was a full-bleed grey band with the
     marker inset into it. Crema makes the item an inset pill, which puts the marker in the
     list's gutter against the RAIL instead -- so it is brass, the mockup's --brass-on-dark,
     at marker on rail 5.85:1. Laid over the dove fill the same brass would have been close
     enough in luminance to disappear, which is what the intermediate step got wrong.

     The value does not move between light and dark; the rail is dark in both. */
  --sc-chrome-active-marker: #f97316;

  /* Brand. Two roles, deliberately not one token. --sc-brand is a fill that carries white
     ink, which is a property of the fill alone and so needs no per-mode value.
     --sc-brand-text is the brand used AS text on the page, which has to be sized against
     the page and therefore does. The single #ff8c00 this replaces tried to be both and
     cleared neither -- white on it did not come close to the floor, and it was the
     fill behind 33 buttons.
     brand text on surface 5.81:1, on sunken 5.32:1 */
  --sc-brand: #c4441e;
  --sc-brand-hover: #a83918;
  --sc-brand-text: #a83918;

  /* Type scale. Ten steps, derived from what the stylesheets already use rather than
     imposed: 96 font-size declarations across 36 distinct values, of which the great
     majority sat on or within a pixel of these. The near-misses -- 11.5, 12.5, 12.8,
     13.1, 13.5, 14.4, 15.5, 17.5 and 17.6px -- snap to the nearest step, so nothing
     moves by more than a pixel and the drift stops having somewhere to go.

     Anchored at --sc-font-base = 1rem, so the scale follows the reader's own text
     size rather than pinning it. Foundation's fluid heading sizes are deliberately
     left alone: they are responsive behaviour, not steps on this scale. Issue 1575. */
  --sc-font-3xs: 0.625rem;
  --sc-font-2xs: 0.6875rem;
  --sc-font-xs: 0.75rem;
  --sc-font-sm: 0.8125rem;
  --sc-font-md: 0.875rem;
  --sc-font-base: 1rem;
  --sc-font-lg: 1.125rem;
  --sc-font-xl: 1.5rem;
  --sc-font-2xl: 2rem;
  --sc-font-3xl: 2.5rem;

  /* Weights. The stylesheets carried nine distinct values including bold, bolder and
     normal alongside numerics; these are the four that carry meaning here. */
  --sc-weight-regular: 400;
  --sc-weight-medium: 500;
  --sc-weight-semibold: 600;
  --sc-weight-bold: 700;
  --sc-text-inverse: #ffffff;
  /* Same reasoning as --sc-text-muted above, hue preserved: link on sunken
     4.57:1, link on surface 4.99:1. Issue 1498. */
  --sc-link: #246caa;
  --sc-link-hover: #1d5a8d;

  /* Semantic state. Each pair is a strong colour and the tint it sits on: the strong
     value is the button fill, the callout's left border AND the callout's text, so it
     has to clear the AA floor against its own tint, not only against the page. That is the
     binding constraint, and it is why these are darker than the Foundation fills they
     stand beside -- #3adb76 and #ffae00 clear that floor on white with so little headroom
     that any visible tint underneath them fails.

     Distinct from the --sc-fnd-* bridge below, which carries Foundation's own fills for
     Foundation's own components. These are the product's, so a palette change retunes
     them without editing vendored CSS.

     strong on its own tint: info 4.75:1

     The success, warning and danger tints were removed in issue 1590 -- nothing consumed them,
     and Foundation already supplies those colours to the components that need them. --sc-danger
     stays: platform.css uses it as text, never on a tint of its own, so it has no pairing here. */
  --sc-danger: #ba403e;
  --sc-info: #266eac;
  --sc-info-light: #eaf2fa;

  /* Line height. Three steps; the stylesheets carried twelve distinct values including
     raw pixel line-heights, which stop scaling when the reader resizes text. Declared
     once: leading is a rhythm, not a colour, and does not change with the mode. */
  --sc-leading-tight: 1.2;
  --sc-leading-normal: 1.4;
  --sc-leading-relaxed: 1.5;

  /* Lines. --sc-border is decorative (1.4.11 exempt), true Platinum.
     --sc-border-control outlines real controls: 3.32:1 on white (platinum-strong). */
  --sc-border: #ddd8cf;
  /* Clears SC 1.4.11 on the sunken surface, which the previous value missed:
     border on sunken 3.05:1, border on surface 3.32:1. Issue 1498. */
  --sc-border-control: #878581;

  /* Form fields */
  --sc-field-bg: #ffffff;
  --sc-field-text: #1b1914;
  /* Placeholder on the white field below: 4.58:1. The previous value was true
     Pewter, which fails as text on white (see the palette note above), and never
     reached a placeholder in light mode anyway -- Foundation's own #cacaca at
     1.64:1 on white was the declaration actually standing. Same value as
     --sc-text-muted:
     placeholder text is muted text, and holding them together means one
     re-derivation if the light palette ever moves. */
  --sc-field-placeholder: #79756e;
  --sc-field-disabled-bg: #f6f5f3;

  /* Focus ring - Fixed link blue, 4.99:1 on white, well past the 3:1 that
     1.4.11 asks of a focus indicator. */
  --sc-focus-ring: #246caa;
  --sc-focus-ring-width: 2px;
  --sc-focus-ring-offset: 2px;

  /* Elevation - kept deliberately light: thin borders carry most of the
     separation, shadows are a subtle assist rather than a floating-card
     effect. */
  --sc-shadow-md: 0 1px 3px rgba(23, 25, 30, 0.08);
  --sc-shadow-lg: 0 2px 6px rgba(23, 25, 30, 0.10);
  /* One step above -lg, for a card that should read as an object sitting on the workspace
     rather than a panel drawn on it. Two shadows on purpose: a tight contact shadow plus a
     wide soft one -- a single shadow at any radius reads flat, and the pair is what gives the
     edge somewhere to sit. Used by the console's dashboard tiles. */
  --sc-shadow-raised: 0 1px 2px rgba(23, 25, 30, 0.05), 0 6px 16px -8px rgba(23, 25, 30, 0.16);

  /* Radii and spacing - a small scale, so future components stop
     inventing one-off pixel values. Held near 4px sitewide rather than an
     escalating scale, to read as crisp/structured rather than soft. */
  --sc-radius-sm: 4px;
  --sc-radius-md: 4px;
  --sc-radius-pill: 999px;

  --sc-space-1: 0.25rem;
  --sc-space-2: 0.5rem;
  --sc-space-5: 1.5rem;
  --sc-space-6: 2rem;

  /* Motion - referenced so prefers-reduced-motion has a single lever. */
  --sc-motion-fast: 120ms;
  --sc-motion-base: 200ms;
  --sc-motion-ease: cubic-bezier(0.2, 0, 0.2, 1);

  /* Tells the browser to render native widgets (scrollbars, date pickers,
     select popups, form controls) in the matching scheme. */
  color-scheme: light;
}

/* ==========================================================================
   Layer 1b - Foundation's own palette
   ==========================================================================
   Foundation is vendored as compiled CSS with no Sass source, so its palette
   was baked into the shipped file -- which is why most of the product still
   renders in Foundation's factory colours regardless of the site's theme.
   tools/route-foundation-tokens.py rewrites that file's base colours to the
   tokens below, making 285 of its 351 colour declarations addressable at
   runtime.

   These ship with Foundation's OWN values, so nothing changes appearance until
   a theme deliberately overrides them. They are intentionally NOT overridden in
   the dark block yet: doing so would change how the product looks today, which
   belongs in its own reviewable change rather than riding along with the
   plumbing. Naming keeps the -fnd- infix because these describe Foundation's
   palette slots, not semantic roles -- a later pass can point them at the
   semantic tokens once the first-party stylesheets are routed too.
   ========================================================================== */

:root {
  /* $white and $black are split by role. Foundation uses each across both text and
     surfaces, and in a dark theme those move in opposite directions: surfaces go dark
     while text sitting on a coloured button must stay light. A single token cannot
     express that -- one $white token given a dark value turns 32 button captions
     dark-on-dark. */
  --sc-fnd-surface: #fefefe;      /* $white painting a surface (27 uses) */
  --sc-fnd-on-accent: #fefefe;    /* $white as text ON a coloured fill (32 uses) */
  /* Follows the page's own ink rather than Foundation's $black, so a component's text and
     the body text on the same page are the same colour. They were not: an admin page showed
     body text at --sc-text while its callouts, table heads and form controls stayed #0a0a0a,
     which reads as two blacks once the surface around them is warm. Dark mode already made
     this choice (--sc-fnd-ink: var(--sc-text) in both dark blocks); light was left behind. */
  --sc-fnd-ink: var(--sc-text);   /* $black as text (36 uses) */
  --sc-fnd-ink-surface: #0a0a0a;  /* $black painting a surface (12 uses) */

  /* Table chrome, seeded with Foundation's own values so nothing moves until these are
     deliberately changed. Routed because the admin is mostly tables, and on a warm surface
     these cool greys were the last thing in it reading as a different palette. No dark
     values: they have none today either, so light-only keeps the current behaviour exactly
     rather than quietly fixing a second thing. */
  /* Warmed to the palette's own hue and saturation (40deg / 23%, read from --sc-surface
     rather than picked). Each value keeps its Foundation lightness to the decimal --
     97.3, 94.5, 95.3, 97.6 and 92.5 -- so NO contrast ratio moves: every pairing on these
     surfaces keeps exactly the ratio it had, and only the temperature changes. That was
     the complaint: an admin is mostly tables, and cool grey tables on a warm page read as
     two palettes. Subtle on purpose, because Foundation's greys are subtle and matching
     their lightness keeps that; making the tables read as more recessed is a different
     change that would move ratios and need measuring. */
  --sc-fnd-table-head: #faf9f6;
  --sc-fnd-table-stripe: #f4f2ee;
  --sc-fnd-table-head-hover: #f6f4f0;
  --sc-fnd-table-row-hover: #faf9f8;
  --sc-fnd-table-stripe-hover: #f0ede8;
  /* The rule around tbody/tfoot/thead. Foundation spends one colour (#f1f1f1) on both
     this and the stripe fill, which works while everything is pale and comes apart in
     dark mode -- the fill has to go darker than the surface it stripes, the rule has to
     stay light enough to be seen against it. Split out so each can move independently;
     the light value matches --sc-fnd-table-stripe exactly, so light mode is unchanged. */
  --sc-fnd-table-rule: #f4f2ee;

  /* Text on a LIGHT accent fill -- Foundation's warning and success buttons. Defined
     once, here, and deliberately never redefined for dark: those fills keep their
     light values in dark mode, so the text on them has to stay dark or it lands
     light-on-light (1.67:1 on warning, 1.64:1 on success). The mirror of
     --sc-fnd-on-accent, which stays light because its fills stay dark. */
  --sc-fnd-ink-on-accent: #0a0a0a;

  /* Status accents used as INK on a light ground -- Foundation's hollow and clear
     success/warning buttons draw the accent as text on the page rather than as a fill.
     $success and $warning are chosen to sit UNDER dark ink, so read as text on white they
     are 1.799:1 and 1.842:1 (issue 1529). These are hue-preserving darkenings that clear
     the SC 1.4.3 floor, and they double as the border colour, which lifts SC 1.4.11 from
     the same failing ratio to the same passing one:
       --sc-fnd-success-ink on the light surface .... 4.72:1
       --sc-fnd-warning-ink on the light surface .... 4.72:1
     The mirror of --sc-fnd-ink-on-accent above: that one is dark ink for a light fill,
     these are dark accents for a light page. Redefined for dark below, where the accent
     itself is legible and Layer 3b already repaints these variants. */
  --sc-fnd-success-ink: #168442;
  --sc-fnd-warning-ink: #9b6901;

  /* --sc-fnd-white and --sc-fnd-black used to be defined here, aliased to
     --sc-fnd-surface and --sc-fnd-ink, so that stylesheets routed before the role split
     kept working. Every one of those eight references now names the role it means, so
     the aliases are gone rather than deprecated -- they were the last two Foundation
     tokens with no dark value, and their existence invited exactly the mistake the
     split was made to prevent: a name that says "white" reads as safe to use for text
     ON a fill, which inverts the wrong way the moment a theme is applied. */

  --sc-fnd-primary: #2677bc;
  --sc-fnd-secondary: #767676;
  --sc-fnd-success: #3bdb75;
  --sc-fnd-warning: #feaf0a;
  /* Darkened from Foundation's own #cc4b37, which pairs with --sc-fnd-on-accent at
     4.498:1 -- under the 4.5:1 floor of SC 1.4.3 by 0.002, in both modes and for every
     element type (issue 1527). The fill moves rather than the ink because this token
     plays two roles on a light ground and the shortfall is identical in both: a fill
     beneath light ink (.button.alert, .button-group.alert, .label.alert, .badge.alert)
     and ink or a border on that ground (.form-error, .is-invalid-label,
     .is-invalid-input, and the hollow/clear alert variants). Lightening the ink to
     #ffffff would have fixed only the four filled surfaces and left the rest at 4.498:1.
       ink #fefefe on the fill ..... 4.611:1     the colour as text on #fefefe ... 4.611:1
       the colour as text on #ffffff .............................. 4.650:1
     .callout.alert does not share the pair -- it is a tinted #f7e4e1 fill under
     --sc-fnd-ink -- so it is unaffected.

     Deliberately a modest step, not the largest that clears the floor. On the DARK page
     this same token also paints .form-error, where a darker red reads worse: 3.876:1
     before, 3.781:1 after -- failing either way, and a pre-existing gap rather than one
     this creates. The two directions are strictly opposed for a single token: a red that
     clears 4.5:1 on #17191e is at most ~3.3:1 on white. Closing the dark side needs the
     fill and the ink split into separate roles, the way --sc-fnd-on-accent and
     --sc-fnd-ink-on-accent already are; until then this takes just enough headroom to
     clear the floor on the light ground and costs the dark case as little as possible. */
  --sc-fnd-alert: #cb4643;
  --sc-fnd-light-gray: #e7e6e3;
  --sc-fnd-medium-gray: #cdc9c3;
  --sc-fnd-dark-gray: #91897b;
}

/* ==========================================================================
   Layer 2 - Dark token overrides
   ==========================================================================
   Note what is NOT overridden: brand accent colors (theme.button.*,
   theme.utilitybar.*, etc.) -- whatever a site has configured stays as-is
   in dark mode rather than being auto-relit. The fresh-install default is
   Anthracite (#53575c): white text on it is 7.3:1, comfortably past the
   4.5:1 floor, on the light page every site starts on. It is NOT verified
   against the dark *page* background (#241e17) -- a button sitting
   directly on bare dark-mode page (no white card under it) only reaches
   2.27:1 there, short of the 3:1 non-text floor. The old default
   (Foundation's #1779ba) had the same shape of gap, just less severe
   (3.52:1) -- this was never solved for every combination, only judged
   good enough for the common case. Accents are left to the theme.
   ========================================================================== */

:root[data-theme="dark"] {
  /* Warm dark. These were a blue-black ramp (#17191e / #26282e / #101115), which read as
     severe -- a switched-off screen rather than a dim room. The replacement is the Crema
     dark ground from mockup L, carried onto Direction F's layout: same job, warmer hue,
     and materially lighter. #241e17 sits at 0.0137 relative luminance against the old
     #17191e's 0.0096, and its red channel leads rather than its blue.

     Lighter is the point, not a side effect. The previous ramp's darkness was doing the
     work of separating surfaces; here the separation comes from the step between them
     (raised is 1.28:1 over surface) plus --sc-border, which is how this file carries
     elevation anyway. */
  --sc-surface: #241e17;
  --sc-surface-raised: #393025;
  --sc-surface-sunken: #1c1710;
  --sc-surface-overlay: #393025;

  /* Ink and link, warmed to match the ground. The link moves from a blue (#609ace) to the
     teal that carries the informational layer -- a blue link on a warm brown ground reads
     as a leftover from the previous palette, and the teal is the one hue in this scheme
     that is neither the amber (which means "attention") nor the terracotta (which means
     "wrong"), so it can mean "go here" without collision.

     Contrast vs --sc-surface: text 14.91:1, muted 6.31:1, link 6.85:1, link-hover 8.72:1.
     Vs --sc-surface-raised (the value --sc-surface-overlay also carries):
     text 11.69:1, muted 4.95:1, link 5.37:1, link-hover 6.84:1. Raised is chosen so that
     muted, link and link-hover all keep past 4.9:1 on it -- a bound over the three rather
     than three separate targets, since it is the raised surface that moves, not the inks.

     --sc-surface-overlay is held equal to raised deliberately. Lifting it to its own
     lighter value (#4c3e2e was tried) drops --sc-text-muted to 3.94:1 and --sc-link to
     4.28:1 on it -- both under the floor, on the surface dropdowns and tooltips use.
     --sc-field-bg is the one that legitimately differs; its own numbers are recorded
     with it below. */
  --sc-text: #f6f3ef;
  --sc-text-muted: #ad9e89;
  --sc-text-inverse: #241e17;
  --sc-link: #6fb3ac;
  /* dark, brand text on surface 5.50:1 -- the light value is far too dark here. */
  --sc-brand-text: #e8734f;
  --sc-link-hover: #8fc7c1;

  /* State, dark. Same contract: the strong value reads as text on its own tint. The tints
     are warmed to sit on the new ground -- a blue-grey state tint on a brown surface reads
     as a stain rather than a state. Info takes the teal so it does not compete with the
     amber, which this scheme reserves for attention.
     dark, strong on its own tint: info 5.67:1 */
  --sc-danger: #e58881;
  --sc-info: #6fb3ac;
  --sc-info-light: #1f312f;

  --sc-border: rgba(245, 243, 239, 0.13);
  /* Warm platinum. The cool #d9dce1 was calibrated against a blue-black ground; on this one
     it is the only cold edge on the screen. control on field bg 7.90:1. */
  --sc-border-control: #cebba2;

  /* Fields sit one step above the canvas rather than matching the raised surface, so an
     input still reads as an input on a card. field text 13.32:1, placeholder 6.26:1. */
  --sc-field-bg: #2e271e;
  --sc-field-text: #f6f3ef;
  --sc-field-placeholder: #b5a795;
  --sc-field-disabled-bg: #2e271e;

  /* The focus ring is the one place amber is used for something other than attention, and
     that is deliberate: a focus ring IS attention. focus on surface 7.04:1, on raised 5.52:1. */
  --sc-focus-ring: #e09b4a;

  /* Shadows read as noise on a dark page; lean on borders instead. */
  --sc-shadow-md: 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 3px rgba(0, 0, 0, 0.45);
  --sc-shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.5);
  --sc-shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.45), 0 6px 16px -8px rgba(0, 0, 0, 0.6);

  /* ---- Foundation base palette, dark ------------------------------------
     Only the structural tokens move. The five accent colours (primary,
     secondary, success, warning, alert) deliberately keep their light-mode
     values: they are brand-adjacent, Foundation's own defaults already carry
     enough contrast on a dark ground, and restyling them is a design decision
     rather than a mechanical inversion.

     Verified against how Foundation actually pairs these, not in isolation:
       ink on surface ............. 11.69:1     on-accent on primary ... 4.68:1
       ink on the page ............. 14.91:1    menu bars on dark bar .. 16.36:1
       on-accent on ink-surface .... 15.05:1    dark-gray on the page .. 5.44:1  */

  /* Surfaces darken; text drawn ON a coloured fill must not. A dark
     --sc-fnd-on-accent would turn 32 button captions dark-on-dark, which is
     exactly why #1437 split these two roles apart. */
  --sc-fnd-surface: var(--sc-surface-raised);
  --sc-fnd-on-accent: #fefefe;
  --sc-fnd-ink: var(--sc-text);

  /* On a dark page the status accents are legible as text, and the Layer 3b
     hollow/clear rule already repaints those variants to --sc-link. Pointing the ink
     tokens at the same value keeps the two in agreement, so the ink is right whichever
     of the two rules wins the cascade rather than only while Layer 3b outranks
     Layer 3a. No pixel change here -- this is the colour dark already draws. */
  --sc-fnd-success-ink: var(--sc-link);
  --sc-fnd-warning-ink: var(--sc-link);

  /* Stays dark, deliberately. Foundation pairs it with on-accent:
     `.tooltip { background: ink-surface; color: on-accent }`. Inverting it to a
     light chip while on-accent correctly stays light would put white text on a
     white background. A dark tooltip on a dark page is the right reading of that
     pairing, lifted off the page so it still reads as a chip. The one casualty is
     abbr's dotted underline, which shares this token and is faint here --
     decorative, and not worth breaking every tooltip to rescue. */
  --sc-fnd-ink-surface: #2a2520;

  /* The grey ramp inverts by role, not by value: "light" stays the subtlest
     against its ground and "dark" the most prominent, so their actual lightness
     swaps over on a dark page. */
  --sc-fnd-light-gray: #332e27;
  --sc-fnd-medium-gray: #544e46;
  --sc-fnd-dark-gray: #9a938b;

  /* Table chrome. These had no dark values at all, which is why the dark theme carried
     five hand-written table overrides further down this file: each one existed to point
     a Foundation table rule at a semantic token the framework could not reach. The rule
     colour was the one nobody compensated for, so `thead` shipped a near-white #f1f1f1
     border on a dark table.

     Fill and rule move in opposite directions here, which is the whole reason
     --sc-fnd-table-rule was split out of the stripe: the fills sit BELOW the surface
     they stripe (#1c1710 against a #3a3025 body), the rule sits ABOVE it.

     Warmed with the rest of the dark palette. Left cool these were the last cold thing on
     the page, and the admin is mostly tables -- a grey-blue stripe under warm cards reads
     as two palettes, which is the same complaint that produced the warm table chrome in
     light mode. */
  --sc-fnd-table-head: #1c1710;
  --sc-fnd-table-stripe: #1c1710;
  --sc-fnd-table-rule: rgba(245, 243, 239, 0.13);
  /* Hover shades step toward the light rather than away from it, so a row lifts under
     the pointer instead of receding. Text stays --sc-text (#f5f3ef) on both -- measured
     10.05:1 on #453a2d and 14.20:1 on #2a2219, so neither hover state comes near the
     4.5:1 floor.

     Against their own ground the steps are deliberately small (1.16:1 and 1.13:1). A
     hover state is transient and pointer-driven, so it carries no meaning on its own and
     has no 3:1 obligation; the previous value carried the opposite problem, being exactly
     equal to the row beneath it and therefore invisible. */
  --sc-fnd-table-row-hover: #443a2d;
  --sc-fnd-table-stripe-hover: #292219;
  --sc-fnd-table-head-hover: #292219;

  color-scheme: dark;
}

/* Follow the OS only when the site has opted into "auto". An absent
   data-theme stays light, which is what every pre-existing site gets.

   Every value below is a duplicate of the [data-theme="dark"] block above and
   must be changed with it. A token corrected in only one of the two blocks
   leaves every site running theme.ui.mode=auto on the old, broken value. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] {
    /* Mirrors the explicit dark block above, value for value -- see the notes there for why
       each moved. A token warmed in only one of the two blocks leaves every
       theme.ui.mode=auto install on the old blue-black, which is exactly the class of drift
       the parity check in check-token-contrast.py exists to catch. */
    --sc-surface: #241e17;
    --sc-surface-raised: #393025;
    --sc-surface-sunken: #1c1710;
    --sc-surface-overlay: #393025;

    --sc-text: #f6f3ef;
    --sc-text-muted: #ad9e89;
    --sc-text-inverse: #241e17;
    --sc-link: #6fb3ac;
    /* dark, brand text on surface 5.50:1 -- the light value is far too dark here. */
    --sc-brand-text: #e8734f;
    --sc-link-hover: #8fc7c1;
    --sc-danger: #e58881;
    --sc-info: #6fb3ac;
    --sc-info-light: #1f312f;

    --sc-border: rgba(245, 243, 239, 0.13);
    --sc-border-control: #cebba2;

    --sc-field-bg: #2e271e;
    --sc-field-text: #f6f3ef;
    --sc-field-placeholder: #b5a795;
    --sc-field-disabled-bg: #2e271e;

    --sc-focus-ring: #e09b4a;

    --sc-shadow-md: 0 1px 0 rgba(255, 255, 255, 0.05), 0 1px 3px rgba(0, 0, 0, 0.45);
    --sc-shadow-lg: 0 2px 6px rgba(0, 0, 0, 0.5);
    --sc-shadow-raised: 0 1px 2px rgba(0, 0, 0, 0.45), 0 6px 16px -8px rgba(0, 0, 0, 0.6);

    /* ---- Foundation base palette, dark ------------------------------------
       Only the structural tokens move. The five accent colours (primary,
       secondary, success, warning, alert) deliberately keep their light-mode
       values: they are brand-adjacent, Foundation's own defaults already carry
       enough contrast on a dark ground, and restyling them is a design decision
       rather than a mechanical inversion.

       Verified against how Foundation actually pairs these, not in isolation:
         ink on surface ............. 11.69:1     on-accent on primary ... 4.68:1
         ink on the page ............. 14.91:1    menu bars on dark bar .. 16.36:1
         on-accent on ink-surface .... 15.05:1    dark-gray on the page .. 5.44:1  */

    /* Surfaces darken; text drawn ON a coloured fill must not. A dark
       --sc-fnd-on-accent would turn 32 button captions dark-on-dark, which is
       exactly why #1437 split these two roles apart. */
    --sc-fnd-surface: var(--sc-surface-raised);
    --sc-fnd-on-accent: #fefefe;
    --sc-fnd-ink: var(--sc-text);

    /* On a dark page the status accents are legible as text, and the Layer 3b
       hollow/clear rule already repaints those variants to --sc-link. Pointing the ink
       tokens at the same value keeps the two in agreement, so the ink is right whichever
       of the two rules wins the cascade rather than only while Layer 3b outranks
       Layer 3a. No pixel change here -- this is the colour dark already draws. */
    --sc-fnd-success-ink: var(--sc-link);
    --sc-fnd-warning-ink: var(--sc-link);

    /* Stays dark, deliberately. Foundation pairs it with on-accent:
       `.tooltip { background: ink-surface; color: on-accent }`. Inverting it to a
       light chip while on-accent correctly stays light would put white text on a
       white background. A dark tooltip on a dark page is the right reading of that
       pairing, lifted off the page so it still reads as a chip. The one casualty is
       abbr's dotted underline, which shares this token and is faint here --
       decorative, and not worth breaking every tooltip to rescue. */
    --sc-fnd-ink-surface: #2a2520;

    /* The grey ramp inverts by role, not by value: "light" stays the subtlest
       against its ground and "dark" the most prominent, so their actual lightness
       swaps over on a dark page. */
    --sc-fnd-light-gray: #332e27;
    --sc-fnd-medium-gray: #544e46;
    --sc-fnd-dark-gray: #9a938b;

    /* Mirrors the explicit dark block above -- see the note there for why fill and rule
       had to be split, and for the measured hover ratios. */
    --sc-fnd-table-head: #1c1710;
    --sc-fnd-table-stripe: #1c1710;
    --sc-fnd-table-rule: rgba(245, 243, 239, 0.13);
    --sc-fnd-table-row-hover: #443a2d;
    --sc-fnd-table-stripe-hover: #292219;
    --sc-fnd-table-head-hover: #292219;

    color-scheme: dark;
  }
}

/* ==========================================================================
   Layer 3a - Applies in BOTH modes (accessibility fixes, additive)
   ========================================================================== */

/* WCAG 2.2 SC 2.4.11 Focus Not Obscured / 2.4.13 Focus Appearance.
   Foundation's default focus treatment on buttons and links is a faint
   background shift that is easy to lose. :focus-visible keeps mouse users
   from seeing a ring while giving keyboard users a real one.

   input[type] is listed separately and deliberately. Foundation zeroes the
   outline on every text-entry type through an attribute selector --
   [type=text]:focus and its thirteen siblings -- which is specificity
   (0,2,0) and outranks a bare input:focus-visible at (0,1,1). Loading after
   Foundation does not help, since order only breaks ties. The result was
   that every text field in the product had no focus indicator at all (SC
   2.4.7, Level A), while textarea and select kept theirs -- Foundation
   reaches those two at only (0,1,1), so they won on load order.
   input[type]:focus-visible is (0,2,1) and wins on specificity instead. The
   bare input:focus-visible stays for <input> with no type attribute, which
   Foundation's list also misses.

   Intended side effect: text inputs always match :focus-visible even on
   mouse click, per spec, and (0,2,1) also outranks Foundation's
   [data-whatinput=mouse] :focus reset -- so mouse-clicked text fields show
   the ring too, in both modes. That matches what Chrome, Firefox and Safari
   do natively for text inputs. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
input:focus-visible,
input[type]:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: var(--sc-focus-ring-width) solid var(--sc-focus-ring);
  outline-offset: var(--sc-focus-ring-offset);
  border-radius: var(--sc-radius-sm);
}

/* Checkbox/radio fill - native accent-color, not previously themed. Fixed to
   the link-blue accent in both modes rather than tracking --sc-link, since
   this is meant to read as a deliberate constant, not a mode-shifted token. */
input[type="checkbox"],
input[type="radio"] {
  accent-color: #2c79be;
}

/* Modal and callout close buttons. Foundation pins .close-button to #8a8a8a
   at rest and #0a0a0a on hover/focus, neither of which knows what surface it
   landed on. The x character is the control's only visible affordance, so it
   is held to the 4.5:1 SC 1.4.3 asks of text -- and Foundation's own values
   miss that in every one of the 49 places the button renders: 3.42:1 in a
   light .reveal, 3.13:1 in a success callout, 3.45:1 on the newsletter
   overlay. Dark mode is worse, and worse in an unusual way: the hover/focus
   state moves TOWARD the background rather than away from it, so the reveal
   button fails even the 3:1 of 1.4.11 in both states (2.11:1 at rest,
   2.72:1 on hover).

   No fixed color can be right here, because the surface underneath is chosen
   variously -- by Foundation, by the dark token block, by a theme's callout
   colors, or by a site's newsletter overlay properties. What is always paired
   with that surface is the container's own text color, since whoever picked
   the background picked that too. So the button follows it rather than naming
   a color of its own, and needs no dark-mode counterpart.

   The 0.8 preserves Foundation's muted rest state. Measured over http against
   the real cascade, worst case across every surface a close button actually
   renders on is 4.97:1 (the dark .reveal, at rest); every other case is
   10.52:1 or better, in light, dark and auto alike. Lifting to full opacity on
   interaction keeps a visible state change without introducing a second color
   that can drift -- and because :focus is included, the Layer 3a focus ring is
   never drawn through a faded opacity.

   Note the limit: this guarantees contrast wherever the container sets a text
   color to go with its background. A component that repaints a .card-divider
   (or any other wrapper) without also setting color is still on its own. */
.close-button {
  color: inherit;
  opacity: 0.8;
}

.close-button:hover,
.close-button:focus {
  color: inherit;
  opacity: 1;
}

/* Dashboard stat tiles (.callout). Dark mode already recolors the border via
   Layer 3b; light mode had no rule at all and was left on Foundation's
   default translucent-black border. Also gives tiles the ~4px radius used
   sitewide instead of Foundation's square corners. */
.callout {
  border-color: var(--sc-border);
  border-radius: var(--sc-radius-md);
}

/* Foundation's own bare .callout background (a pale yellow, #fffdea) was
   never overridden for light mode -- only the dark-mode background is set,
   in Layer 3b below. Themed variants (primary/success/etc.) keep their
   intentional color in both modes. */
/* Plain .callout, not the themed variants. Stated WITHOUT the :not() chain the dark-mode rules
   below use, and the difference is not cosmetic.

   Each :not() contributes its argument's specificity, so excluding six variants took this rule to
   0-7-0 -- a rule written to be narrower outranking almost everything. It outranked the site's own
   theme.callout.backgroundColor at 0-1-0, so a site could set a callout colour in Theme Settings,
   save it, and have it silently discarded on every page. Measured on a live site: a bare .callout
   rendered the token's #ffffff, not the configured #ffffea (issue 1650).

   At 0-1-0 the exclusions are unnecessary here: Foundation states each variant at 0-2-0
   (.callout.primary and friends) and platform.css states .callout.header the same way, so all of
   them already outrank this. The site theme, also 0-1-0 but emitted after this file, now wins --
   which is the point of a theme setting.

   The dark-mode rules keep their exclusions because the arithmetic is different there: prefixing
   :root[data-theme="dark"] takes them to 0-2-0, which TIES Foundation's variants, and a tie goes to
   source order -- this file loads later, so without the exclusions a dark-mode themed callout would
   lose its colour. Same shape, opposite requirement. */
.callout {
  background-color: var(--sc-surface-raised);
}

/* Hollow and clear status buttons. Foundation draws the status colour as text on
   the page, and its $success/$warning are light accents meant to sit under dark ink,
   so in light mode the caption and border land at 1.799:1 and 1.842:1 (issue 1529).
   Dark mode has been repainting these since Layer 3b; light mode had no rule at all.

   The hue is kept rather than flattened to link blue as dark does -- a green success
   button that turns blue loses the signal the variant exists to carry. These tie
   Foundation's own .button.hollow.success at (0,3,0) and win on source order; the
   dark and auto rules in Layer 3b are (0,4,0) and still outrank them, and the ink
   tokens resolve to the same colour those rules paint, so dark is unchanged either
   way. .hollow.alert / .clear.alert are not listed: they carry the --sc-fnd-alert
   shortfall tracked in issue 1527 and are fixed there. */
.button.hollow.success,
.button.clear.success {
  color: var(--sc-fnd-success-ink);
  border-color: var(--sc-fnd-success-ink);
}

.button.hollow.warning,
.button.clear.warning {
  color: var(--sc-fnd-warning-ink);
  border-color: var(--sc-fnd-warning-ink);
}

/* WCAG 2.2 SC 2.3.3 Animation from Interactions. Foundation, Motion UI and
   animate.css all animate by default; honour the OS setting. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Layer 3b - Dark mode chrome
   ==========================================================================
   Everything below is scoped to the dark selectors so light mode is
   untouched. The two selector groups are kept in sync deliberately;
   :is() would collapse them but Foundation-era browsers in the support
   matrix are not guaranteed to have it.
   ========================================================================== */

:root[data-theme="dark"] body,
:root[data-theme="dark"] .platform-body,
:root[data-theme="dark"] .platform-content,
:root[data-theme="dark"] .platform-content-container {
  background-color: var(--sc-surface);
  color: var(--sc-text);
}

/* Long-form content and headings */
:root[data-theme="dark"] h1,
:root[data-theme="dark"] h2,
:root[data-theme="dark"] h3,
:root[data-theme="dark"] h4,
:root[data-theme="dark"] h5,
:root[data-theme="dark"] h6,
:root[data-theme="dark"] p,
:root[data-theme="dark"] li,
:root[data-theme="dark"] dt,
:root[data-theme="dark"] dd,
:root[data-theme="dark"] blockquote,
:root[data-theme="dark"] label,
:root[data-theme="dark"] legend,
:root[data-theme="dark"] .platform-blog-body {
  color: var(--sc-text);
}

/* Foundation paints .subheader with --sc-fnd-dark-gray, a NEUTRAL token -- the same one its
   borders and rules use. As ink that is subheader neutral on raised 3.46:1, on surface 3.12:1,
   under the 4.5:1 floor of SC 1.4.3, on every subheader in the console (seen on /admin/wikis).
   The dark-mode rule below already routes it to --sc-text-muted; light mode had no counterpart,
   so it fell through to the vendor default.

   Pointing it at the text token rather than darkening the neutral is deliberate: --sc-fnd-dark-gray
   also draws borders, which are held to the 3:1 that SC 1.4.11 asks, and a darker value would
   weight every rule in the product. One token cannot serve both roles well, so the text case takes
   a text token: subheader muted on raised 5.54:1, on surface 5.00:1. */
.subheader {
  color: var(--sc-text-muted, #656970);
}

:root[data-theme="dark"] .help-text,
:root[data-theme="dark"] .platform-activity-date,
:root[data-theme="dark"] .platform-activity-content-date,
:root[data-theme="dark"] .subheader {
  color: var(--sc-text-muted);
}

/* Links. The wrapper scoping is what keeps the site menus out -- they live in
   #platform-menu, outside these containers. Buttons need excluding explicitly:
   an anchor styled as a button sits on an accent fill, and Foundation's own
   ink-on-fill rules are only (0,2,0), which this selector would outrank.
   Issue 1525. Keep :not(.button) on the auto mirror below in step. */
:root[data-theme="dark"] .platform-body a:not(.button),
:root[data-theme="dark"] .platform-content a:not(.button),
:root[data-theme="dark"] .platform-blog-body a:not(.button) {
  color: var(--sc-link);
}

:root[data-theme="dark"] .platform-body a:not(.button):hover,
:root[data-theme="dark"] .platform-content a:not(.button):hover,
:root[data-theme="dark"] .platform-blog-body a:not(.button):hover {
  color: var(--sc-link-hover);
}

/* Buttons keep their theme background; only the unstyled/hollow variants
   need help, because they inherit page text color. */
:root[data-theme="dark"] .button.hollow,
:root[data-theme="dark"] .button.clear {
  color: var(--sc-link);
  border-color: var(--sc-border-control);
  background-color: transparent;
}

/* Cards, panels, wells */
:root[data-theme="dark"] .card,
:root[data-theme="dark"] .card-section,
:root[data-theme="dark"] .card-divider,
:root[data-theme="dark"] .platform-blog-cards-container,
:root[data-theme="dark"] .platform-calendar-details-container,
:root[data-theme="dark"] .platform-toc-container,
:root[data-theme="dark"] .platform-scrollable-view {
  background-color: var(--sc-surface-raised);
  color: var(--sc-text);
  border-color: var(--sc-border);
}

:root[data-theme="dark"] .card-divider {
  background-color: var(--sc-surface-sunken);
}

/* Callouts. Only the neutral default is repainted - primary/success/
   warning/alert are theme colors and stay as the site configured them. */
:root[data-theme="dark"] .callout {
  border-color: var(--sc-border);
}

:root[data-theme="dark"] .callout:not(.primary):not(.secondary):not(.success):not(.warning):not(.alert):not(.header) {
  background-color: var(--sc-surface-raised);
  color: var(--sc-text);
}

/* ...but only the callout BOX was excluded, not its contents. The text rules
   near the top of this layer match on the element, so they reach straight
   past that exclusion into a themed callout: p/li/dt/dd/blockquote/legend and
   h1-h6 get --sc-text, .help-text/.subheader get --sc-text-muted, and links
   get --sc-link -- all of them dark-mode values, painted onto a fill that is
   still deliberately light. Foundation's own ink token flips light here too
   (--sc-fnd-ink: var(--sc-text) in Layer 2), so even the box's own color went
   light on any site that has not set theme.callout.*.text.color.

   Measured on the install defaults, a success flash message rendered
   --sc-text (#f4f5f7) on the success fill (#e1faea): 1.01:1. Invisible.
   page_messages.jspf renders <p> inside .callout.alert/.warning/.success and
   is included by essentially every page, so this hit every flash message on
   every dark-mode page. See issue 1508.

   The fix reads the fill for what it is: inside a themed callout the ground is
   light, so the text tokens point back at their light-mode values for that
   subtree -- the same call Layer 1b already made for --sc-fnd-ink-on-accent,
   which is why the ink here can just borrow it. Nothing here sets `color`, so a
   site's own theme.callout.*.text.color still wins the cascade -- its <style>
   block loads after this file. .header is left out on purpose: its fill is the
   dark top-bar color, so dark-mode text values are already the right ones there.

   Links and muted text take one extra step darker than their plain light-mode
   values, because those were tuned against pure white and these fills are
   tinted. --sc-link #2a74b6 is 4.99:1 on white but only 4.01:1 on the alert
   fill; --sc-text-muted #6c7178 is 5.00:1 on white but 4.01:1 there. So --sc-link
   here is the light ramp's hover value with the hover one step darker again,
   and the muted grey is darkened the same way Layer 1's own "pewter-strong"
   was, far enough to clear the fills while staying a clear step off the ink
   (3.42:1 against it, close to the 3.84:1 separation light mode uses).

   Worst case of each group, measured over the install-default fills:
     text (--sc-text) .......... 16.16:1    muted (--sc-text-muted) ... 4.72:1
     links (--sc-link) ......... 5.36:1     hover (--sc-link-hover) ... 7.52:1 */
:root[data-theme="dark"] .callout.primary,
:root[data-theme="dark"] .callout.secondary,
:root[data-theme="dark"] .callout.success,
:root[data-theme="dark"] .callout.warning,
:root[data-theme="dark"] .callout.alert {
  --sc-text: #17191e;
  --sc-text-muted: #61666d;
  --sc-link: #236098;
  --sc-link-hover: #1a4a75;
  --sc-fnd-ink: var(--sc-fnd-ink-on-accent);
}

/* Re-pointing the tokens fixes the color, but the block-level text rules still
   pin these elements to --sc-text, which would ignore a theme's configured
   callout text color. Inheriting instead lets whatever the box resolved to --
   the theme's color where set, Foundation's ink otherwise -- reach the text.
   Kept in step with the --sc-text element list at the top of this layer.
   Applies to every callout: the neutral one sets --sc-text on the box itself
   just above, so inheriting there lands on the same value it already had. */
:root[data-theme="dark"] .callout h1,
:root[data-theme="dark"] .callout h2,
:root[data-theme="dark"] .callout h3,
:root[data-theme="dark"] .callout h4,
:root[data-theme="dark"] .callout h5,
:root[data-theme="dark"] .callout h6,
:root[data-theme="dark"] .callout p,
:root[data-theme="dark"] .callout li,
:root[data-theme="dark"] .callout dt,
:root[data-theme="dark"] .callout dd,
:root[data-theme="dark"] .callout blockquote,
:root[data-theme="dark"] .callout label,
:root[data-theme="dark"] .callout legend,
:root[data-theme="dark"] .callout .platform-blog-body {
  color: inherit;
}

/* Muted text is a <p> in 275 of its uses, so the rule above would have caught
   it and flattened it to full ink. Put it back on the muted token -- which the
   re-point above has already moved to its light-mode value, so it is muted
   against the fill rather than against a dark page. Kept in step with the
   --sc-text-muted element list at the top of this layer. */
:root[data-theme="dark"] .callout .help-text,
:root[data-theme="dark"] .callout .subheader,
:root[data-theme="dark"] .callout .platform-activity-date,
:root[data-theme="dark"] .callout .platform-activity-content-date {
  color: var(--sc-text-muted);
}

/* Tables: nothing here any more, and that is the point.
   Five rules used to live at this spot, each one reaching past Foundation to point a
   table at a semantic token. They existed because the --sc-fnd-table-* tokens had no
   dark values, so the framework painted tables light and something had to undo it.
   Giving those tokens dark values (see the dark block above) removes the reason, and
   removing the rules fixed two things they were quietly causing:

     - `thead` kept a near-white #f4f2ee border, because the override that corrected
       the rule colour only covered `table tbody`, never thead or tfoot;
     - every `table.unstriped` was striped anyway in dark mode, because
       `[data-theme="dark"] table tbody tr:nth-child(even)` outranks Foundation's
       `table.unstriped tbody tr`. Light mode showed no stripes on the same table.

   Verified against the rendered cascade on /admin/users rather than by reading: row,
   header and cell colours come out identical, and those two defects disappear. */

/* Form fields */
:root[data-theme="dark"] input[type="text"],
:root[data-theme="dark"] input[type="password"],
:root[data-theme="dark"] input[type="date"],
:root[data-theme="dark"] input[type="datetime"],
:root[data-theme="dark"] input[type="datetime-local"],
:root[data-theme="dark"] input[type="month"],
:root[data-theme="dark"] input[type="week"],
:root[data-theme="dark"] input[type="email"],
:root[data-theme="dark"] input[type="number"],
:root[data-theme="dark"] input[type="search"],
:root[data-theme="dark"] input[type="tel"],
:root[data-theme="dark"] input[type="time"],
:root[data-theme="dark"] input[type="url"],
:root[data-theme="dark"] input[type="color"],
:root[data-theme="dark"] textarea,
:root[data-theme="dark"] select {
  background-color: var(--sc-field-bg);
  color: var(--sc-field-text);
  border-color: var(--sc-border-control);
  box-shadow: none;
}

/* The same defect as the placeholder rule below, one property over: in light mode
   nothing applies --sc-border-control to a field, so Foundation's own #cdc9c3 border
   stands on a #fefefe field at 1.63:1 -- under the 3:1 SC 1.4.11 asks of a control
   boundary. The token has existed all along and is applied everywhere else, including
   the status-update textarea's focus ring a few hundred lines up in platform.css.

   Scoped to the admin console, and that is a deliberate departure from the placeholder
   fix (#1506 / PR #1566), which went sitewide. Any compliant value is visibly darker
   than #cdc9c3, so applying it to every form on the public site is a design change as
   well as an accessibility one -- the console is corrected here and the public site is
   left as its own decision. That decision is still open; the failure is still there.

   Only the border is repainted. The field's background and text already clear their
   floors in light mode, so repainting them would be churn with no ratio behind it. */
body.admin-console input[type="text"],
body.admin-console input[type="password"],
body.admin-console input[type="date"],
body.admin-console input[type="datetime"],
body.admin-console input[type="datetime-local"],
body.admin-console input[type="month"],
body.admin-console input[type="week"],
body.admin-console input[type="email"],
body.admin-console input[type="number"],
body.admin-console input[type="search"],
body.admin-console input[type="tel"],
body.admin-console input[type="time"],
body.admin-console input[type="url"],
body.admin-console input[type="color"],
body.admin-console textarea,
body.admin-console select {
  border-color: var(--sc-border-control);
}

/* Light mode needs this rule at all: without it Foundation's own
   `::placeholder { color: var(--sc-fnd-medium-gray, #cdc9c3) }` is the only
   declaration standing, and ships 1.64:1 on a white field. Layer 3 otherwise
   repaints only under [data-theme="dark"], on the principle that light mode is
   already correct -- which held everywhere except here. */
input::placeholder,
textarea::placeholder {
  color: var(--sc-field-placeholder);
  opacity: 1; /* Firefox dims placeholders by default, which undoes the ratio */
}

:root[data-theme="dark"] input::placeholder,
:root[data-theme="dark"] textarea::placeholder {
  color: var(--sc-field-placeholder);
  opacity: 1; /* Firefox dims placeholders by default, which undoes the ratio */
}

:root[data-theme="dark"] input:disabled,
:root[data-theme="dark"] textarea:disabled,
:root[data-theme="dark"] select:disabled,
:root[data-theme="dark"] input[readonly],
:root[data-theme="dark"] textarea[readonly] {
  background-color: var(--sc-field-disabled-bg);
  color: var(--sc-text-muted);
}

/* Foundation's default .help-text uses a negative margin-top to tuck it
   under a plain <input>. That collapses to no visible gap (or worse) after
   an .input-group wrapper (the icon + input used by type="url" fields), so
   help text reads as jammed against the field above it. A small positive
   gap reads correctly after both a plain input and an .input-group. */
.help-text {
  margin-top: var(--sc-space-1);
  /* site-properties-editor.jsp's Value column is a <td nowrap>, which forces
     white-space: nowrap onto every descendant, including this paragraph. A
     help-text longer than a couple of words runs off the right edge instead
     of wrapping, forcing a horizontal scrollbar to read it. The nowrap is
     only meant for the input controls themselves, not their help text. */
  white-space: normal;
  max-width: 60ch;
}

/* Page documentation, as opposed to a field hint.
   ----------------------------------------------------------------------------
   Foundation's .help-text is built for a short hint under one form control: it
   is 13px, and the max-width above caps it at 60ch, which for a 13px font is
   487.5px. Under a control that cap never binds, because the hint is a line or
   two.

   Many admin pages also use .help-text for something structurally different --
   several paragraphs of prose explaining what the whole page does. There the
   two properties combine badly: 13px body copy, capped at 487px, sitting under
   a full-width heading in a 1244px column. The result reads as a narrow ribbon
   with the rest of the page empty beside it, which is what /admin/sitemap
   looked like.

   Note the cap is not the bug on its own -- 13px prose running the full 1244px
   would be ~150 characters a line, which is worse. The mistake is using one
   class for a hint and for body copy. So this does not relax .help-text; it
   gives the documentation case its own size and measure, and .help-text stays
   exactly as it is for the field hints that are the majority of its uses.

   40rem is 640px, which at 15px is ~68 characters a line -- inside the 45-75
   band that makes prose comfortable to read. It is deliberately absolute rather
   than the ch unit used above: ch resolves against each element's own font
   size, so a figure alongside this prose could not be aligned to the same edge
   without re-deriving the number. One value, reused, keeps the column true.

   Applied as a second class (class="help-text page-help") so the colour, the
   dark-mode treatment and the margin above all still come from .help-text, and
   so a page that loses this rule degrades to today's rendering rather than to
   unstyled text. */
.page-help {
  font-size: 0.9375rem;
  line-height: 1.55;
  max-width: 40rem;
}

/* An illustration belonging to a .page-help passage -- an example box, a
   diagram -- sharing its measure so the two line up on both edges. The nested
   .help-text is that figure's caption: it should stay at hint size, but its own
   60ch cap would end it ~130px short of the box it sits in, so inside a figure
   the measure comes from the figure. */
.page-help-figure {
  max-width: 40rem;
}
.page-help-figure .help-text {
  max-width: 100%;
}

/* Foundation renders the select arrow as an embedded SVG data URI in a
   dark ink that disappears on a dark field. */
:root[data-theme="dark"] select {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 24'><polygon points='0,0 32,0 16,24' style='fill: %23a7b0bd'></polygon></svg>");
}

:root[data-theme="dark"] .input-group-label {
  background-color: var(--sc-surface-sunken);
  color: var(--sc-text);
  border-color: var(--sc-border-control);
}

/* Overlays: modals, dropdown panes, tooltips */
:root[data-theme="dark"] .reveal,
:root[data-theme="dark"] .dropdown-pane,
:root[data-theme="dark"] .platform-dialog {
  background-color: var(--sc-surface-overlay);
  color: var(--sc-text);
  border-color: var(--sc-border);
  box-shadow: var(--sc-shadow-lg);
}

:root[data-theme="dark"] .reveal-overlay {
  background-color: rgba(0, 0, 0, 0.7);
}

:root[data-theme="dark"] .tooltip {
  background-color: var(--sc-surface-overlay);
  color: var(--sc-text);
  border: 1px solid var(--sc-border);
}

/* Tabs and accordions */
:root[data-theme="dark"] .tabs,
:root[data-theme="dark"] .tabs-content,
:root[data-theme="dark"] .accordion,
:root[data-theme="dark"] .accordion-content {
  background-color: var(--sc-surface-raised);
  color: var(--sc-text);
  border-color: var(--sc-border);
}

:root[data-theme="dark"] .tabs-title > a,
:root[data-theme="dark"] .accordion-title {
  background-color: var(--sc-surface-raised);
  color: var(--sc-link);
  border-color: var(--sc-border);
}

:root[data-theme="dark"] .tabs-title > a:hover,
:root[data-theme="dark"] .accordion-title:hover {
  background-color: var(--sc-surface-sunken);
}

:root[data-theme="dark"] .tabs-title > a[aria-selected="true"] {
  background-color: var(--sc-surface-sunken);
  color: var(--sc-text);
}

/* Pagination and breadcrumbs */
:root[data-theme="dark"] .pagination a,
:root[data-theme="dark"] .pagination button,
:root[data-theme="dark"] .breadcrumbs a {
  color: var(--sc-link);
}

:root[data-theme="dark"] .pagination .current {
  background-color: var(--sc-surface-sunken);
  color: var(--sc-text);
}

:root[data-theme="dark"] .breadcrumbs li:not(:last-child)::after {
  color: var(--sc-text-muted);
}

/* Code and rules */
:root[data-theme="dark"] code,
:root[data-theme="dark"] pre,
:root[data-theme="dark"] kbd {
  background-color: var(--sc-surface-sunken);
  color: var(--sc-text);
  border-color: var(--sc-border);
}

:root[data-theme="dark"] hr {
  border-color: var(--sc-border);
}

/* Images and media authored for a light page. Full inversion is wrong -
   this only takes the edge off pure-white logo plates. */
:root[data-theme="dark"] img.platform-invert-on-dark {
  filter: invert(1) hue-rotate(180deg);
}

/* --------------------------------------------------------------------------
   Same rules for data-theme="auto" under an OS dark preference.
   Kept as a separate block rather than a shared selector list so that the
   forced-dark rules above stay readable and independently reviewable.
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] body,
  :root[data-theme="auto"] .platform-body,
  :root[data-theme="auto"] .platform-content,
  :root[data-theme="auto"] .platform-content-container {
    background-color: var(--sc-surface);
    color: var(--sc-text);
  }

  :root[data-theme="auto"] h1,
  :root[data-theme="auto"] h2,
  :root[data-theme="auto"] h3,
  :root[data-theme="auto"] h4,
  :root[data-theme="auto"] h5,
  :root[data-theme="auto"] h6,
  :root[data-theme="auto"] p,
  :root[data-theme="auto"] li,
  :root[data-theme="auto"] dt,
  :root[data-theme="auto"] dd,
  :root[data-theme="auto"] blockquote,
  :root[data-theme="auto"] label,
  :root[data-theme="auto"] legend,
  :root[data-theme="auto"] .platform-blog-body {
    color: var(--sc-text);
  }

  :root[data-theme="auto"] .help-text,
  :root[data-theme="auto"] .platform-activity-date,
  :root[data-theme="auto"] .platform-activity-content-date,
  :root[data-theme="auto"] .subheader {
    color: var(--sc-text-muted);
  }

  :root[data-theme="auto"] .platform-body a:not(.button),
  :root[data-theme="auto"] .platform-content a:not(.button),
  :root[data-theme="auto"] .platform-blog-body a:not(.button) {
    color: var(--sc-link);
  }

  :root[data-theme="auto"] .platform-body a:not(.button):hover,
  :root[data-theme="auto"] .platform-content a:not(.button):hover,
  :root[data-theme="auto"] .platform-blog-body a:not(.button):hover {
    color: var(--sc-link-hover);
  }

  :root[data-theme="auto"] .button.hollow,
  :root[data-theme="auto"] .button.clear {
    color: var(--sc-link);
    border-color: var(--sc-border-control);
    background-color: transparent;
  }

  :root[data-theme="auto"] .card,
  :root[data-theme="auto"] .card-section,
  :root[data-theme="auto"] .card-divider,
  :root[data-theme="auto"] .platform-blog-cards-container,
  :root[data-theme="auto"] .platform-calendar-details-container,
  :root[data-theme="auto"] .platform-toc-container,
  :root[data-theme="auto"] .platform-scrollable-view {
    background-color: var(--sc-surface-raised);
    color: var(--sc-text);
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] .card-divider {
    background-color: var(--sc-surface-sunken);
  }

  :root[data-theme="auto"] .callout {
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] .callout:not(.primary):not(.secondary):not(.success):not(.warning):not(.alert):not(.header) {
    background-color: var(--sc-surface-raised);
    color: var(--sc-text);
  }

  /* Mirror of the themed-callout text fix in the dark block; see the comment
     there. Issue 1508. */
  :root[data-theme="auto"] .callout.primary,
  :root[data-theme="auto"] .callout.secondary,
  :root[data-theme="auto"] .callout.success,
  :root[data-theme="auto"] .callout.warning,
  :root[data-theme="auto"] .callout.alert {
    --sc-text: #17191e;
    --sc-text-muted: #61666d;
    --sc-link: #236098;
    --sc-link-hover: #1a4a75;
    --sc-fnd-ink: var(--sc-fnd-ink-on-accent);
  }

  :root[data-theme="auto"] .callout h1,
  :root[data-theme="auto"] .callout h2,
  :root[data-theme="auto"] .callout h3,
  :root[data-theme="auto"] .callout h4,
  :root[data-theme="auto"] .callout h5,
  :root[data-theme="auto"] .callout h6,
  :root[data-theme="auto"] .callout p,
  :root[data-theme="auto"] .callout li,
  :root[data-theme="auto"] .callout dt,
  :root[data-theme="auto"] .callout dd,
  :root[data-theme="auto"] .callout blockquote,
  :root[data-theme="auto"] .callout label,
  :root[data-theme="auto"] .callout legend,
  :root[data-theme="auto"] .callout .platform-blog-body {
    color: inherit;
  }

  :root[data-theme="auto"] .callout .help-text,
  :root[data-theme="auto"] .callout .subheader,
  :root[data-theme="auto"] .callout .platform-activity-date,
  :root[data-theme="auto"] .callout .platform-activity-content-date {
    color: var(--sc-text-muted);
  }

  /* The five table rules that stood here are gone for the same reason as their
     [data-theme="dark"] twins above -- the --sc-fnd-table-* tokens now carry dark
     values, so Foundation paints the table correctly without being overridden. */

  :root[data-theme="auto"] input[type="text"],
  :root[data-theme="auto"] input[type="password"],
  :root[data-theme="auto"] input[type="date"],
  :root[data-theme="auto"] input[type="datetime"],
  :root[data-theme="auto"] input[type="datetime-local"],
  :root[data-theme="auto"] input[type="month"],
  :root[data-theme="auto"] input[type="week"],
  :root[data-theme="auto"] input[type="email"],
  :root[data-theme="auto"] input[type="number"],
  :root[data-theme="auto"] input[type="search"],
  :root[data-theme="auto"] input[type="tel"],
  :root[data-theme="auto"] input[type="time"],
  :root[data-theme="auto"] input[type="url"],
  :root[data-theme="auto"] input[type="color"],
  :root[data-theme="auto"] textarea,
  :root[data-theme="auto"] select {
    background-color: var(--sc-field-bg);
    color: var(--sc-field-text);
    border-color: var(--sc-border-control);
    box-shadow: none;
  }

  :root[data-theme="auto"] input::placeholder,
  :root[data-theme="auto"] textarea::placeholder {
    color: var(--sc-field-placeholder);
    opacity: 1;
  }

  :root[data-theme="auto"] input:disabled,
  :root[data-theme="auto"] textarea:disabled,
  :root[data-theme="auto"] select:disabled,
  :root[data-theme="auto"] input[readonly],
  :root[data-theme="auto"] textarea[readonly] {
    background-color: var(--sc-field-disabled-bg);
    color: var(--sc-text-muted);
  }

  :root[data-theme="auto"] select {
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 24'><polygon points='0,0 32,0 16,24' style='fill: %23a7b0bd'></polygon></svg>");
  }

  :root[data-theme="auto"] .input-group-label {
    background-color: var(--sc-surface-sunken);
    color: var(--sc-text);
    border-color: var(--sc-border-control);
  }

  :root[data-theme="auto"] .reveal,
  :root[data-theme="auto"] .dropdown-pane,
  :root[data-theme="auto"] .platform-dialog {
    background-color: var(--sc-surface-overlay);
    color: var(--sc-text);
    border-color: var(--sc-border);
    box-shadow: var(--sc-shadow-lg);
  }

  :root[data-theme="auto"] .reveal-overlay {
    background-color: rgba(0, 0, 0, 0.7);
  }

  :root[data-theme="auto"] .tooltip {
    background-color: var(--sc-surface-overlay);
    color: var(--sc-text);
    border: 1px solid var(--sc-border);
  }

  :root[data-theme="auto"] .tabs,
  :root[data-theme="auto"] .tabs-content,
  :root[data-theme="auto"] .accordion,
  :root[data-theme="auto"] .accordion-content {
    background-color: var(--sc-surface-raised);
    color: var(--sc-text);
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] .tabs-title > a,
  :root[data-theme="auto"] .accordion-title {
    background-color: var(--sc-surface-raised);
    color: var(--sc-link);
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] .tabs-title > a:hover,
  :root[data-theme="auto"] .accordion-title:hover {
    background-color: var(--sc-surface-sunken);
  }

  :root[data-theme="auto"] .tabs-title > a[aria-selected="true"] {
    background-color: var(--sc-surface-sunken);
    color: var(--sc-text);
  }

  :root[data-theme="auto"] .pagination a,
  :root[data-theme="auto"] .pagination button,
  :root[data-theme="auto"] .breadcrumbs a {
    color: var(--sc-link);
  }

  :root[data-theme="auto"] .pagination .current {
    background-color: var(--sc-surface-sunken);
    color: var(--sc-text);
  }

  :root[data-theme="auto"] .breadcrumbs li:not(:last-child)::after {
    color: var(--sc-text-muted);
  }

  :root[data-theme="auto"] code,
  :root[data-theme="auto"] pre,
  :root[data-theme="auto"] kbd {
    background-color: var(--sc-surface-sunken);
    color: var(--sc-text);
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] hr {
    border-color: var(--sc-border);
  }

  :root[data-theme="auto"] img.platform-invert-on-dark {
    filter: invert(1) hue-rotate(180deg);
  }
}

/* ==========================================================================
   Color scheme toggle control
   ==========================================================================
   Rendered in the utility bar. Inherits the bar's colors so it works
   against whatever the site configured, in either scheme.
   ========================================================================== */

/* Hidden until platform-theme.js marks the document ready. A toggle that
   cannot toggle is worse than no toggle at all (WCAG 2.2 SC 4.1.2 - a
   control that reports itself as a button but does nothing). Deliberately
   NOT keyed off Foundation's .no-js class: Foundation only removes that on
   .foundation() init, which would both delay the button and tie this
   feature to a dependency it does not otherwise need. */
.platform-color-scheme-toggle {
  display: none;
  background: transparent;
  border: 0;
  color: inherit;
  cursor: pointer;
  padding: var(--sc-space-1) var(--sc-space-2);
  margin: 0;
  line-height: 1;
  border-radius: var(--sc-radius-sm);
  align-items: center;
  gap: var(--sc-space-2);
}

:root.platform-color-scheme-ready .platform-color-scheme-toggle {
  display: inline-flex;
}

.platform-color-scheme-toggle:hover {
  background-color: rgba(127, 127, 127, 0.2);
}

.platform-color-scheme-toggle .fa,
.platform-color-scheme-toggle .fas,
.platform-color-scheme-toggle .far {
  color: inherit;
}

/* Only one of the two icons is shown, whichever matches the active scheme.
   Hidden with display so screen readers do not announce the inactive one;
   the accessible name lives on the button's aria-label, which the script
   keeps in sync. */
.platform-color-scheme-toggle .platform-icon-dark {
  display: none;
}

:root[data-theme="dark"] .platform-color-scheme-toggle .platform-icon-light {
  display: none;
}

:root[data-theme="dark"] .platform-color-scheme-toggle .platform-icon-dark {
  display: inline-block;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] .platform-color-scheme-toggle .platform-icon-light {
    display: none;
  }

  :root[data-theme="auto"] .platform-color-scheme-toggle .platform-icon-dark {
    display: inline-block;
  }
}

/* Site logo light/dark swap (cms/logo.jsp). Same toggle idiom as the
   scheme-toggle icons above -- both images are always in the markup, CSS
   picks which one paints. Only rendered as a pair when logo.jsp actually has
   two different sources; a single-source logo has neither class and is
   unaffected by these rules. */
.platform-logo-dark {
  display: none;
}

:root[data-theme="dark"] .platform-logo-light {
  display: none;
}

:root[data-theme="dark"] .platform-logo-dark {
  display: inline-block;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="auto"] .platform-logo-light {
    display: none;
  }

  :root[data-theme="auto"] .platform-logo-dark {
    display: inline-block;
  }
}

