/* =====================================================================
   Edgewood Technology — Brand Stylesheet (single source of truth)
   Path when deployed: https://technology.edgewoodhs.org/branding/brand.css
   ---------------------------------------------------------------------
   Drop this into any Edgewood app to inherit the shared brand:
     <link rel="stylesheet"
           href="https://technology.edgewoodhs.org/branding/brand.css" />
   ...or copy the :root tokens into your Tailwind config.
   Tokens reconcile every app on the server (landing, chromebook,
   onboarding, purchaseorders, maintenance, scheduler, ...).
   ===================================================================== */

/* ---- Fonts -------------------------------------------------------- */
/* Apps should also add the Google Fonts <link> in <head>:
   family=Source+Sans+3:wght@300;400;600;700;900
   family=JetBrains+Mono:wght@500;700
   (EB Garamond retired 2026-07 — Source Sans 3 now carries headings too.) */

:root {
  /* =================================================================
     OFFICIAL BRAND COLORS — exact spec values. Do not alter these.
     ================================================================= */
  --ehs-maroon:          #681a31;  /* Edgewood Maroon · PMS 7421 C */
  --ehs-gold:            #d0b786;  /* Edgewood Gold   · PMS 7502 C */
  --ehs-legacy-gold:     #daa900;  /* Legacy Gold     · PMS 110 C  */
  --ehs-crusader-maroon: #550119;  /* Crusader Maroon · PMS 504 C  */
  --ehs-crusader-gold:   #ceb888;  /* Crusader Gold   · PMS 4515 C */
  --ehs-grey:            #ebebeb;  /* Light Grey      · PMS 663    */
  --ehs-black:           #231f20;  /* Dominican Black · PMS Black  */

  /* =================================================================
     DERIVED SHADES — tints/shades of the official colors only, for
     hovers, borders, and pale fills. (Tints/shades of brand colors
     are allowed; no new hues are introduced.)
     ================================================================= */
  /* Maroon: Crusader Maroon doubles as the darker/pressed maroon. */
  --ehs-maroon-deep:   var(--ehs-crusader-maroon);
  --ehs-maroon-light:  #7d2740;                    /* +lightness of Edgewood Maroon */
  /* Gold */
  --ehs-gold-deep:     #a8895a;                     /* shade of Edgewood Gold  */
  --ehs-gold-pale:     #f3ead6;                     /* tint  of Edgewood Gold  */
  --ehs-on-goldpale:   var(--ehs-maroon-deep);      /* readable text on gold-pale (dark-mode override below) */
  --ehs-on-maroonpale: var(--ehs-maroon);           /* readable text on a maroon-tinted fill (dark override below) */
  /* The brand accent used as TEXT on the page ground. Maroon reads at ~2:1 on the dark
     ground however far it is lightened while still being maroon (measured across the kit,
     2026-07-30), so on dark the accent becomes GOLD — which is already what the appbar
     service name, the sidebar's active link and the action toggle do. FILLS and BORDERS
     keep using --ehs-maroon; this token is only for glyphs. */
  --ehs-accent-text: var(--ehs-maroon);

  /* Neutrals (greys built around official Light Grey + Dominican Black) */
  --ehs-ink:           var(--ehs-black);
  --ehs-muted:         #6b6257;
  --ehs-paper:         #ffffff;
  --ehs-cream:         #faf7f1;   /* warm off-white ground */
  --ehs-rule:          var(--ehs-grey);
  --ehs-rule-strong:   #c8bfb5;
  /* RGB triples (space-separated) so alpha compositing works on themed colors —
     Tailwind opacity modifiers (bg-gold/20 -> rgb(var(--ehs-gold-rgb)/.2)) and color-mix. */
  --ehs-maroon-rgb: 104 26 49;   --ehs-maroon-deep-rgb: 85 1 25;   --ehs-maroon-light-rgb: 125 39 64;
  --ehs-gold-rgb: 208 183 134;   --ehs-gold-deep-rgb: 168 137 90;  --ehs-gold-pale-rgb: 243 234 214;
  --ehs-ink-rgb: 35 31 32;       --ehs-muted-rgb: 107 98 87;
  --ehs-paper-rgb: 255 255 255;  --ehs-cream-rgb: 250 247 241;     --ehs-rule-rgb: 235 235 235;

  /* =================================================================
     SYSTEM STATUS — functional only, OUTSIDE the core brand palette.
     Used strictly for state (success/caution/error/info). Warn + error
     borrow the brand's gold/maroon families to stay in family.
     ================================================================= */
  /* Each status has: solid (icon/accent), pale (fill), border, text-on-pale.
     Tuned to sit beside BOTH the primary (Edgewood) and secondary (Crusader)
     palettes — they only ever render on paper/cream, never on maroon. The
     amber warn is deliberately more saturated than Edgewood Gold so "caution"
     never reads as "brand gold". */
  --ehs-ok:   #2f7d4f; --ehs-ok-pale:   #e6f1e9; --ehs-ok-border:   #b7d6bf; --ehs-ok-text:   #245c37;
  --ehs-warn: #c0891e; --ehs-warn-pale: #f8efd3; --ehs-warn-border: #e6cf95; --ehs-warn-text: #7a591a;
  --ehs-bad:  #b23a2e; --ehs-bad-pale:  #f7e4e1; --ehs-bad-border:  #e2b3ab; --ehs-bad-text:  #7d281d;
  --ehs-info: #2f6f8f; --ehs-info-pale: #e2eef3; --ehs-info-border: #aecfdc; --ehs-info-text: #245266;

  /* Focus ring (gold reads on both maroon fills and light grounds) */
  --ehs-focus:         var(--ehs-legacy-gold);

  /* Code block surface (dark in both themes) + syntax colors */
  --ehs-code-bg:  #2b2224; --ehs-code-fg:  #f2e6d8;
  --ehs-code-tag: #d9b876; --ehs-code-attr:#c99aa6; --ehs-code-str: #cdb58a; --ehs-code-punct:#9d8e85;   /* was #8f8078 = 4.07:1 on --ehs-code-bg; now 4.9 */

  /* Type — Garamond retired; Source Sans 3 carries display + body, JetBrains Mono for code. */
  --ehs-font-display: 'Source Sans 3', system-ui, 'Gill Sans', sans-serif;
  --ehs-font-body:    'Source Sans 3', system-ui, 'Gill Sans', sans-serif;
  --ehs-font-mono:    'JetBrains Mono', 'Courier New', monospace;

  /* Radius */
  --ehs-r-sm: 6px;
  --ehs-r-md: 10px;
  --ehs-r-lg: 14px;
  --ehs-r-pill: 999px;

  /* =================================================================
     WIDTH CONTRACT (unified-shell Phase 0) — one gutter + one page cap
     for the whole suite, so every app's left edge and content column
     line up. Full desktop width is the DEFAULT; narrow is opt-in.
       --ehs-gutter    horizontal padding shared by appbar/footer/content
       --ehs-page-max  global content cap (decision 3: one value, 1440)
       measures        .ehs-content--reading | --wide | --full
     ================================================================= */
  --ehs-gutter:   clamp(16px, 4vw, 40px);
  --ehs-page-max: 1440px;
  --ehs-measure-reading: 720px;   /* forms, prose, single-column reading */
  --ehs-measure-wide:    1100px;  /* dashboards, detail views */
  /* --full = edge-to-edge within the gutter (no cap) */
  /* Geometry (Phase 0b shell): appbar height is load-bearing — sticky offsets +
     the mobile drawer top edge reference it. Deep/workspace apps use the sidebar. */
  --ehs-appbar-h:  55px;          /* padding 8+8 + wordmark 36 + 3px gold border */
  --ehs-sidebar-w: 216px;
  --ehs-subnav-h:  46px;          /* Tier-2 within-section tab strip (sticky under appbar) */
  --ehs-detail-w:  380px;         /* master-detail drawer panel width */

  /* Elevation */
  --ehs-shadow-sm: 0 1px 2px rgba(35,31,32,.06);
  --ehs-shadow-md: 0 4px 14px rgba(104,26,49,.08);
  --ehs-shadow-lg: 0 12px 34px rgba(104,26,49,.12);

  /* Sunken surface (segmented track, neutral chips, wells) */
  --ehs-sunken:        #efe9df;

  /* Spacing scale (4px base) */
  --ehs-s1: 4px;  --ehs-s2: 8px;  --ehs-s3: 12px; --ehs-s4: 16px;
  --ehs-s5: 24px; --ehs-s6: 32px; --ehs-s7: 48px; --ehs-s8: 64px;
}

/* =====================================================================
   DARK THEME
   ---------------------------------------------------------------------
   Same brand, dark surfaces. Neutrals flip; maroon + gold are kept but
   accents lean on the lighter tints so they read on a dark ground.
   Dark is OPT-IN via the toggle (data-theme="dark"); the default is LIGHT
   regardless of the OS setting. (Changed 2026-07-29 — families on dark-mode
   devices were landing on a dark site by surprise, esp. in incognito.)
   ===================================================================== */
:root[data-theme="dark"],
:root[data-theme="dark"] * { color-scheme: dark; }

@media (prefers-color-scheme: dark) {
  :root[data-theme="dark"] {
    --ehs-paper:        #241c1e;   /* card / surface (warm maroon-black) */
    --ehs-cream:        #16110f;   /* page background       */
    --ehs-sunken:       #0e0a0b;   /* wells, segmented track */
    --ehs-ink:          #f4ede3;   /* primary text (warm off-white) */
    --ehs-muted:        #b3a89c;   /* secondary text        */
    --ehs-rule:         #3a2e30;   /* hairline borders      */
    --ehs-rule-strong:  #57474d;   /* stronger borders      */
    --ehs-maroon-rgb: 143 43 69;  --ehs-maroon-light-rgb: 165 59 87;
    --ehs-gold-rgb: 220 196 145;  --ehs-gold-deep-rgb: 215 189 136;  --ehs-gold-pale-rgb: 58 48 28;
    --ehs-ink-rgb: 244 237 227;   --ehs-muted-rgb: 179 168 156;
    --ehs-paper-rgb: 36 28 30;    --ehs-cream-rgb: 22 17 15;         --ehs-rule-rgb: 58 46 48;
    /* Brand accents lifted for contrast on dark */
    --ehs-maroon:       #8f2b45;   /* Edgewood Maroon, lightened for dark fills */
    --ehs-maroon-light: #a53b57;
    --ehs-gold:         #dcc491;   /* gold, slightly brighter */
    --ehs-gold-deep:    #d7bd88;
    --ehs-gold-pale:    #3a301c;
    --ehs-on-goldpale:  #e6d2a0;
    --ehs-on-maroonpale: #e2a9b8;  /* maroon fills go near-black on dark; text must lift */
    --ehs-accent-text: var(--ehs-gold);
    /* Status — brighter solids, deep pales, mid borders, light text */
    --ehs-ok:   #63b079; --ehs-ok-pale:   #16261a; --ehs-ok-border:   #2f5038; --ehs-ok-text:   #a6d6b2;
    --ehs-warn: #d8a63a; --ehs-warn-pale: #2b2310; --ehs-warn-border: #574710; --ehs-warn-text: #e6c877;
    --ehs-bad:  #d76a5c; --ehs-bad-pale:  #2e1714; --ehs-bad-border:  #5a2b26; --ehs-bad-text:  #e6a89f;
    --ehs-info: #61a4c1; --ehs-info-pale: #12232b; --ehs-info-border: #2a4d5c; --ehs-info-text: #a9d0de;
    --ehs-shadow-sm: 0 1px 2px rgba(0,0,0,.5);
    --ehs-shadow-md: 0 4px 14px rgba(0,0,0,.55);
    --ehs-shadow-lg: 0 12px 34px rgba(0,0,0,.6);
  }
}
:root[data-theme="dark"] {
  --ehs-paper:        #241c1e;
  --ehs-cream:        #16110f;
  --ehs-sunken:       #0e0a0b;
  --ehs-ink:          #f4ede3;
  --ehs-muted:        #b3a89c;
  --ehs-rule:         #3a2e30;
  --ehs-rule-strong:  #57474d;
  --ehs-maroon-rgb: 143 43 69;  --ehs-maroon-light-rgb: 165 59 87;
  --ehs-gold-rgb: 220 196 145;  --ehs-gold-deep-rgb: 215 189 136;  --ehs-gold-pale-rgb: 58 48 28;
  --ehs-ink-rgb: 244 237 227;   --ehs-muted-rgb: 179 168 156;
  --ehs-paper-rgb: 36 28 30;    --ehs-cream-rgb: 22 17 15;         --ehs-rule-rgb: 58 46 48;
  --ehs-maroon:       #8f2b45;
  --ehs-maroon-light: #a53b57;
  --ehs-gold:         #dcc491;
  --ehs-gold-deep:    #d7bd88;
  --ehs-gold-pale:    #3a301c;
  /* Must mirror the prefers-color-scheme block: --ehs-gold-pale flips dark here
     but --ehs-on-goldpale was omitted, so it stayed var(--ehs-maroon-deep) and
     every gold surface (badge--gold, chip, banner--gold, calendar__event) went
     dark-maroon-on-dark-brown (~1.15:1) for anyone using the explicit theme
     TOGGLE. OS-level dark was fine, which is why it hid for so long. */
  --ehs-on-goldpale:  #e6d2a0;
  --ehs-on-maroonpale: #e2a9b8;
  --ehs-accent-text: var(--ehs-gold);
  --ehs-ok:   #63b079; --ehs-ok-pale:   #16261a; --ehs-ok-border:   #2f5038; --ehs-ok-text:   #a6d6b2;
  --ehs-warn: #d8a63a; --ehs-warn-pale: #2b2310; --ehs-warn-border: #574710; --ehs-warn-text: #e6c877;
  --ehs-bad:  #d76a5c; --ehs-bad-pale:  #2e1714; --ehs-bad-border:  #5a2b26; --ehs-bad-text:  #e6a89f;
  --ehs-info: #61a4c1; --ehs-info-pale: #12232b; --ehs-info-border: #2a4d5c; --ehs-info-text: #a9d0de;
  --ehs-shadow-sm: 0 1px 2px rgba(0,0,0,.5);
  --ehs-shadow-md: 0 4px 14px rgba(0,0,0,.55);
  --ehs-shadow-lg: 0 12px 34px rgba(0,0,0,.6);
}

/* =====================================================================
   Base document defaults (unified-shell) — any app that loads brand.css
   gets a themed, flush-edge body WITHOUT restating it. The shared full-width
   sticky .ehs-appbar assumes no UA body margin, and dark mode needs an
   EXPLICIT body color/bg (relying on color-scheme alone left some apps
   dark-on-dark). Single-element specificity, emitted before the component
   classes, so ANY app's own `body { … }` rule overrides these.
   ===================================================================== */
body {
  margin: 0;
  background: var(--ehs-cream);
  color: var(--ehs-ink);
  font-family: var(--ehs-font-body);
  -webkit-font-smoothing: antialiased;
  /* SUITE RULE #1 — sticky footer: the body is a full-viewport flex column so the
     shared footer sits at the bottom of the viewport OR just below the content
     (whichever is lower). `margin-top:auto` on the footer absorbs any leftover
     space when content is short; when content is tall the footer just flows after
     it. Apps that set their own body `display` override this (their rule wins). */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
/* Push the shared footer to the bottom of the body flex column (sticky-footer). */
#ehs-chrome-footer { margin-top: auto; }

/* The UA's [hidden] rule is display:none at the lowest possible weight, so ANY
   component class that sets display (.ehs-field, .ehs-modal-backdrop, .ehs-row…)
   silently defeats it — markup that toggles the `hidden` attribute then never
   hides, which has bitten a modal-on-load and a form field here already.
   !important is the conventional fix (normalize.css / HTML5 Boilerplate do the
   same): an element carrying `hidden` is meant to be gone, full stop. */
[hidden] { display: none !important; }

/* Secondary text. `--ehs-muted` existed as a token from the start, and apps
   (incl. the create-ehs-app scaffold) had been writing class="ehs-muted"
   expecting the obvious companion class — which silently did nothing until it
   was added here. Dark-flips with the token. */
.ehs-muted { color: var(--ehs-muted); }

/* =====================================================================
   Base component classes — prefix .ehs- to avoid clashing with
   app-local styles. Everything below is optional; use what you need.
   ===================================================================== */

/* ---- Buttons ------------------------------------------------------ */
.ehs-btn {
  font-family: var(--ehs-font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1;
  padding: 10px 18px;
  border-radius: var(--ehs-r-sm);
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background .15s ease, border-color .15s ease,
              color .15s ease, box-shadow .15s ease, transform .05s ease;
  text-decoration: none;
  white-space: nowrap;
}
.ehs-btn:active { transform: translateY(1px); }
.ehs-btn:focus-visible {
  outline: 2px solid var(--ehs-focus);
  outline-offset: 2px;
}
.ehs-btn:disabled, .ehs-btn[aria-disabled='true'] {
  opacity: .5; cursor: not-allowed; transform: none;
}

.ehs-btn--primary {
  background: var(--ehs-maroon);
  color: #fff;
}
.ehs-btn--primary:hover { background: var(--ehs-maroon-deep); }

.ehs-btn--secondary {
  background: var(--ehs-paper);
  color: var(--ehs-accent-text);
  border-color: var(--ehs-rule-strong);
}
.ehs-btn--secondary:hover {
  border-color: var(--ehs-maroon);
  background: var(--ehs-cream);
}

.ehs-btn--gold {
  background: var(--ehs-gold);
  color: var(--ehs-maroon-deep);
}
.ehs-btn--gold:hover { background: var(--ehs-gold-deep); }

.ehs-btn--ghost {
  background: transparent;
  color: var(--ehs-ink);
}
.ehs-btn--ghost:hover { background: rgba(35,31,32,.06); }

.ehs-btn--danger {
  background: var(--ehs-bad);
  color: #fff;
}
.ehs-btn--danger:hover { filter: brightness(.92); }

.ehs-btn--sm { padding: 6px 12px; font-size: 12px; }
.ehs-btn--lg { padding: 13px 24px; font-size: 16px; }

/* ---- Badges / pills ---------------------------------------------- */
.ehs-badge {
  font-family: var(--ehs-font-body);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--ehs-r-pill);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.ehs-badge--gold { color: var(--ehs-on-goldpale); background: var(--ehs-gold-pale); }
.ehs-badge--maroon { color: #fff; background: var(--ehs-maroon); }
.ehs-badge--ok   { color: var(--ehs-ok-text);   background: var(--ehs-ok-pale); }
.ehs-badge--warn { color: var(--ehs-warn-text); background: var(--ehs-warn-pale); }
.ehs-badge--bad  { color: var(--ehs-bad-text);  background: var(--ehs-bad-pale); }
.ehs-badge--info { color: var(--ehs-info-text); background: var(--ehs-info-pale); }
.ehs-badge--neutral { color: var(--ehs-muted); background: var(--ehs-sunken); }

/* ---- Form controls ----------------------------------------------- */
.ehs-field { display: flex; flex-direction: column; gap: 6px; }
.ehs-label {
  font-family: var(--ehs-font-body);
  font-size: 13px;
  font-weight: 600;
  color: var(--ehs-ink);
}
.ehs-hint { font-size: 12px; color: var(--ehs-muted); }
.ehs-input, .ehs-select, .ehs-textarea {
  /* border-box: width:100% must mean "fill the container", borders + padding
     included — under the content-box default these fields overflow any flex/
     grid cell by their padding (worst with .ehs-search's 36px icon inset).
     Found via kitchenmanager UI verify 2026-07-18. */
  box-sizing: border-box;
  font-family: var(--ehs-font-body);
  font-size: 14px;
  color: var(--ehs-ink);
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule-strong);
  border-radius: var(--ehs-r-sm);
  padding: 9px 12px;
  transition: border-color .15s ease, box-shadow .15s ease;
  width: 100%;
}
.ehs-input:focus, .ehs-select:focus, .ehs-textarea:focus {
  outline: none;
  border-color: var(--ehs-maroon);
  box-shadow: 0 0 0 3px rgba(104,26,49,.12);
}
.ehs-input::placeholder, .ehs-textarea::placeholder { color: #a89f92; }
.ehs-input--error { border-color: var(--ehs-bad); }
.ehs-input--error:focus { box-shadow: 0 0 0 3px rgba(163,60,46,.15); }
.ehs-textarea { resize: vertical; min-height: 84px; }

/* Checkbox / radio (accent) */
.ehs-check, .ehs-radio { accent-color: var(--ehs-maroon); width: 16px; height: 16px; }

/* Toggle */
.ehs-toggle { position: relative; display: inline-block; width: 42px; height: 24px; }
.ehs-toggle input { opacity: 0; width: 0; height: 0; }
.ehs-toggle .ehs-track {
  position: absolute; inset: 0; background: var(--ehs-rule-strong);
  border-radius: var(--ehs-r-pill); transition: background .18s ease;
}
.ehs-toggle .ehs-track::before {
  content: ''; position: absolute; height: 18px; width: 18px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: transform .18s ease;
  box-shadow: var(--ehs-shadow-sm);
}
.ehs-toggle input:checked + .ehs-track { background: var(--ehs-maroon); }
.ehs-toggle input:checked + .ehs-track::before { transform: translateX(18px); }

/* ---- Card --------------------------------------------------------- */
.ehs-card {
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-md);
  padding: 20px 22px;
  box-shadow: var(--ehs-shadow-sm);
}
.ehs-card__title {
  font-family: var(--ehs-font-display);
  font-size: 20px; font-weight: 700; color: var(--ehs-ink);
  margin-bottom: 6px;
}
.ehs-card__desc { font-size: 14px; color: var(--ehs-muted); line-height: 1.55; }

/* ---- Tile (service-hub style) ------------------------------------ */
.ehs-tile {
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-lg);
  padding: 22px 24px 18px;
  display: flex; flex-direction: column; gap: 10px;
  position: relative; overflow: hidden;
  transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.ehs-tile::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--ehs-maroon); transform: translateX(-4px);
  transition: transform .18s ease;
}
.ehs-tile:hover {
  border-color: var(--ehs-maroon); transform: translateY(-2px);
  box-shadow: var(--ehs-shadow-md);
}
.ehs-tile:hover::before { transform: translateX(0); }
.ehs-tile__title {
  font-family: var(--ehs-font-display);
  font-size: 22px; font-weight: 700; color: var(--ehs-ink); line-height: 1.2;
}
.ehs-tile__desc { font-size: 14px; color: var(--ehs-muted); line-height: 1.55; flex: 1; }

/* ---- Alerts / callouts ------------------------------------------- */
.ehs-alert {
  border-radius: var(--ehs-r-sm);
  padding: 12px 14px;
  font-size: 14px;
  line-height: 1.5;
  border: 1px solid;
  display: flex; gap: 10px; align-items: flex-start;
}
.ehs-alert__icon { flex: none; font-weight: 700; }
.ehs-alert--ok   { background: var(--ehs-ok-pale);   border-color: var(--ehs-ok-border);   color: var(--ehs-ok-text); }
.ehs-alert--warn { background: var(--ehs-warn-pale); border-color: var(--ehs-warn-border); color: var(--ehs-warn-text); }
.ehs-alert--bad  { background: var(--ehs-bad-pale);  border-color: var(--ehs-bad-border);  color: var(--ehs-bad-text); }
.ehs-alert--info { background: var(--ehs-info-pale); border-color: var(--ehs-info-border); color: var(--ehs-info-text); }
.ehs-alert--ok .ehs-alert__icon   { color: var(--ehs-ok); }
.ehs-alert--warn .ehs-alert__icon { color: var(--ehs-warn); }
.ehs-alert--bad .ehs-alert__icon  { color: var(--ehs-bad); }
.ehs-alert--info .ehs-alert__icon { color: var(--ehs-info); }

/* ---- Table -------------------------------------------------------- */
.ehs-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.ehs-table th {
  text-align: left;
  font-family: var(--ehs-font-body);
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ehs-muted);
  padding: 10px 14px;
  border-bottom: 2px solid var(--ehs-rule-strong);
  background: var(--ehs-cream);
}
.ehs-table td { padding: 11px 14px; border-bottom: 1px solid var(--ehs-rule); color: var(--ehs-ink); }
.ehs-table tbody tr:hover { background: var(--ehs-cream); }

/* ---- Tabs --------------------------------------------------------- */
.ehs-tabs { display: flex; gap: 4px; border-bottom: 2px solid var(--ehs-rule); }
.ehs-tab {
  font-family: var(--ehs-font-body);
  font-size: 14px; font-weight: 600; color: var(--ehs-muted);
  padding: 10px 16px; cursor: pointer; background: none; border: none;
  border-bottom: 2px solid transparent; margin-bottom: -2px;
  transition: color .15s ease, border-color .15s ease;
}
.ehs-tab:hover { color: var(--ehs-ink); }
.ehs-tab--active { color: var(--ehs-accent-text); border-bottom-color: var(--ehs-maroon); }

/* ---- Progress ----------------------------------------------------- */
.ehs-progress { height: 8px; background: var(--ehs-rule); border-radius: var(--ehs-r-pill); overflow: hidden; }
.ehs-progress__bar { height: 100%; background: var(--ehs-maroon); border-radius: inherit; }

/* ---- Avatar ------------------------------------------------------- */
.ehs-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--ehs-gold); color: var(--ehs-maroon-deep);
  font-family: var(--ehs-font-display); font-weight: 700; font-size: 16px;
  display: inline-flex; align-items: center; justify-content: center;
}

/* ---- Divider / gold rule ----------------------------------------- */
.ehs-gold-rule { width: 64px; height: 3px; background: var(--ehs-gold); border: 0; }

/* ---- Shield mark (CSS fallback if no PNG) ------------------------ */
.ehs-shield {
  width: 38px; height: 38px; background: var(--ehs-gold);
  border-radius: 50% 50% 40% 40%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--ehs-font-display); font-weight: 700; font-size: 18px;
  color: var(--ehs-maroon);
}

/* =====================================================================
   Extended component library — the full "visual dictionary" set.
   ===================================================================== */

/* ---- Avatar: photo-first --------------------------------------------
   DEFAULT is the account profile picture. Put an <img> inside .ehs-avatar;
   the initials text under it shows only if the image is missing/broken
   (set onerror to hide the img). Presence dot via .ehs-avatar--dot.     */
/* overflow stays VISIBLE so the presence dot isn't clipped by the circle mask;
   the photo clips itself via border-radius: inherit instead. */
.ehs-avatar { position: relative; overflow: visible; }
/* Photo covers the whole avatar; the initials sit behind as fallback and
   are only revealed if the <img> is hidden (set onerror="this.style.display='none'"). */
.ehs-avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }
.ehs-avatar--sm { width: 28px; height: 28px; font-size: 12px; }
/* Photo avatar: the <img> itself carries .ehs-avatar (SSO/Google profile pic). */
.ehs-avatar--photo { object-fit: cover; background: none; }
.ehs-avatar--lg { width: 56px; height: 56px; font-size: 22px; }
.ehs-avatar--square { border-radius: var(--ehs-r-sm); }
.ehs-avatar--dot::after {
  content: ''; position: absolute; right: -1px; bottom: -1px;
  width: 11px; height: 11px; border-radius: 50%; background: var(--ehs-ok);
  border: 2px solid var(--ehs-paper); overflow: visible;
}
.ehs-avatar--away::after  { background: var(--ehs-warn); }
.ehs-avatar--busy::after  { background: var(--ehs-bad); }
.ehs-avatar--off::after   { background: var(--ehs-rule-strong); }
.ehs-avatar-group { display: inline-flex; }
.ehs-avatar-group .ehs-avatar { border: 2px solid var(--ehs-paper); margin-left: -10px; }
.ehs-avatar-group .ehs-avatar:first-child { margin-left: 0; }

/* ---- Icons (line set; use via <svg class="ehs-ico"><use href="#i-name"/>) */
.ehs-ico {
  width: 1.15em; height: 1.15em; display: inline-block; vertical-align: -0.18em;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; flex: none;
}
.ehs-ico--fill { fill: currentColor; stroke: none; }
.ehs-ico-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- Icon button / button group / split / FAB --------------------- */
.ehs-icon-btn {
  width: 38px; height: 38px; border-radius: var(--ehs-r-sm);
  border: 1px solid var(--ehs-rule-strong); background: var(--ehs-paper);
  color: var(--ehs-ink); cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center; font-size: 16px;
  transition: border-color .15s, background .15s;
}
.ehs-icon-btn:hover { border-color: var(--ehs-maroon); background: var(--ehs-cream); }
.ehs-btn-group { display: inline-flex; }
.ehs-btn-group > .ehs-btn { border-radius: 0; border-color: var(--ehs-rule-strong); }
.ehs-btn-group > .ehs-btn:first-child { border-radius: var(--ehs-r-sm) 0 0 var(--ehs-r-sm); }
.ehs-btn-group > .ehs-btn:last-child  { border-radius: 0 var(--ehs-r-sm) var(--ehs-r-sm) 0; }
.ehs-btn-group > .ehs-btn + .ehs-btn { margin-left: -1px; }

/* Split button — a primary action + a divided dropdown toggle. The toggle
   segment gets a visible divider and a darker hover so it never blends into
   the main button. */
.ehs-split { display: inline-flex; border-radius: var(--ehs-r-sm); }
.ehs-split > .ehs-btn { border-radius: 0; }
.ehs-split > .ehs-split__main   { border-radius: var(--ehs-r-sm) 0 0 var(--ehs-r-sm); }
.ehs-split > .ehs-split__toggle {
  border-radius: 0 var(--ehs-r-sm) var(--ehs-r-sm) 0;
  padding-inline: 11px; gap: 0;
  border-left: 1px solid rgba(255,255,255,.45);   /* divider on filled variants */
}
.ehs-split__toggle:hover { background: var(--ehs-maroon-deep); }
/* Divider color for light (secondary/ghost) split variants */
.ehs-split .ehs-btn--secondary.ehs-split__toggle,
.ehs-split .ehs-btn--gold.ehs-split__toggle { border-left-color: rgba(35,31,32,.18); }
.ehs-fab {
  width: 54px; height: 54px; border-radius: 50%; border: none;
  background: var(--ehs-maroon); color: #fff; font-size: 24px; cursor: pointer;
  box-shadow: var(--ehs-shadow-lg); display: inline-flex; align-items: center; justify-content: center;
}
.ehs-fab:hover { background: var(--ehs-maroon-deep); }

/* ---- Segmented control -------------------------------------------- */
.ehs-segmented {
  /* border-box for the same reason as .ehs-choice-card: the 3px track padding put
     a width:100% segmented control 6px past its container. */
  box-sizing: border-box;
  display: inline-flex; background: var(--ehs-sunken); border-radius: var(--ehs-r-sm); padding: 3px;
}
.ehs-segmented__opt {
  border: none; background: none; cursor: pointer; padding: 6px 14px;
  font-family: var(--ehs-font-body); font-size: 13px; font-weight: 600; color: var(--ehs-muted);
  border-radius: 5px; transition: background .15s, color .15s;
}
.ehs-segmented__opt--active { background: var(--ehs-paper); color: var(--ehs-accent-text); box-shadow: var(--ehs-shadow-sm); }

/* ---- Dropdown / context menu -------------------------------------- */
.ehs-menu {
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-lg); padding: 6px; min-width: 200px;
}
.ehs-menu__item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 10px; border: none; background: none; cursor: pointer; border-radius: var(--ehs-r-sm);
  font-family: var(--ehs-font-body); font-size: 14px; color: var(--ehs-ink);
}
.ehs-menu__item:hover { background: var(--ehs-cream); }
.ehs-menu__item--danger { color: var(--ehs-bad); }
.ehs-menu__item .key { margin-left: auto; font-family: var(--ehs-font-mono); font-size: 11px; color: var(--ehs-muted); }
.ehs-menu__sep { height: 1px; background: var(--ehs-rule); margin: 6px 4px; }

/* ---- Tooltip (CSS hover) ------------------------------------------ */
.ehs-tt { position: relative; display: inline-flex; }
/* Tooltip is a fixed dark chip in BOTH themes (never inverts to unreadable). */
.ehs-tt__bubble {
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%) translateY(4px);
  background: var(--ehs-code-bg); color: var(--ehs-code-fg); font-size: 12px; padding: 6px 10px; border-radius: 6px;
  white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .15s, transform .15s;
  border: 1px solid rgba(255,255,255,.1);
}
.ehs-tt__bubble::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border: 5px solid transparent; border-top-color: var(--ehs-code-bg); }
.ehs-tt:hover .ehs-tt__bubble { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ---- Popover / hover card ----------------------------------------- */
.ehs-popover {
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-lg); padding: 16px; max-width: 280px;
}

/* ---- Slider (range) ----------------------------------------------- */
.ehs-slider { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: var(--ehs-r-pill); background: var(--ehs-rule); outline: none; }
.ehs-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%; background: var(--ehs-maroon); cursor: pointer; box-shadow: var(--ehs-shadow-sm); }
.ehs-slider::-moz-range-thumb { width: 18px; height: 18px; border: none; border-radius: 50%; background: var(--ehs-maroon); cursor: pointer; }

/* ---- Stepper (number +/-) ----------------------------------------- */
.ehs-stepper { display: inline-flex; align-items: center; border: 1px solid var(--ehs-rule-strong); border-radius: var(--ehs-r-sm); overflow: hidden; }
.ehs-stepper button { width: 34px; height: 34px; border: none; background: var(--ehs-paper); cursor: pointer; font-size: 18px; color: var(--ehs-accent-text); }
.ehs-stepper button:hover { background: var(--ehs-cream); }
.ehs-stepper input { width: 46px; text-align: center; border: none; border-inline: 1px solid var(--ehs-rule); font-family: var(--ehs-font-body); font-size: 14px; }

/* ---- Search / input group ----------------------------------------- */
.ehs-input-group { display: flex; align-items: stretch; }
.ehs-input-group .ehs-input { border-radius: 0; }
.ehs-input-group > :first-child { border-radius: var(--ehs-r-sm) 0 0 var(--ehs-r-sm); }
.ehs-input-group > :last-child { border-radius: 0 var(--ehs-r-sm) var(--ehs-r-sm) 0; }
.ehs-input-group > * + * { margin-left: -1px; }
.ehs-addon {
  display: inline-flex; align-items: center; padding: 0 12px; background: var(--ehs-cream);
  border: 1px solid var(--ehs-rule-strong); color: var(--ehs-muted); font-size: 14px; white-space: nowrap;
}
.ehs-search { position: relative; }
.ehs-search .ehs-input { padding-left: 36px; }
.ehs-search__icon { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--ehs-muted); font-size: 15px; pointer-events: none; }

/* ---- Combobox / autocomplete suggestions --------------------------
   Any .ehs-combobox with an <input data-suggest="a,b,c"> gets a live
   filtered dropdown (wired by the shared brand.js behavior). The list
   also works for command palettes via data-filter on a container.      */
.ehs-combobox { position: relative; }
.ehs-suggest {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 40;
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-md); box-shadow: var(--ehs-shadow-lg);
  padding: 6px; max-height: 240px; overflow-y: auto; display: none;
}
.ehs-suggest.open { display: block; }
.ehs-suggest__item {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 8px 10px; border: none; background: none; cursor: pointer;
  border-radius: var(--ehs-r-sm); font-family: var(--ehs-font-body);
  font-size: 14px; color: var(--ehs-ink);
}
.ehs-suggest__item:hover, .ehs-suggest__item--active { background: var(--ehs-cream); }
.ehs-suggest__item mark { background: var(--ehs-gold-pale); color: inherit; border-radius: 3px; padding: 0 1px; }
.ehs-suggest__empty { padding: 10px; color: var(--ehs-muted); font-size: 13px; text-align: center; }

/* ---- Chip / tag (removable) --------------------------------------- */
.ehs-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 11px;
  background: var(--ehs-gold-pale); color: var(--ehs-on-goldpale); border-radius: var(--ehs-r-pill);
  font-size: 13px; font-weight: 600;
}
.ehs-chip__x { width: 16px; height: 16px; border-radius: 50%; background: color-mix(in srgb, currentColor 22%, transparent); border: none; cursor: pointer; color: inherit; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.ehs-chip__x:hover { background: color-mix(in srgb, currentColor 40%, transparent); }

/* ---- Rating (stars) ----------------------------------------------- */
.ehs-rating { display: inline-flex; gap: 2px; font-size: 20px; color: var(--ehs-rule-strong); }
.ehs-rating .on { color: var(--ehs-gold-deep); }

/* ---- Spinner / dots / top-bar ------------------------------------- */
.ehs-spinner { width: 26px; height: 26px; border-radius: 50%; border: 3px solid var(--ehs-rule); border-top-color: var(--ehs-maroon); animation: ehs-spin .7s linear infinite; }
@keyframes ehs-spin { to { transform: rotate(360deg); } }
.ehs-dots { display: inline-flex; gap: 5px; }
.ehs-dots span { width: 8px; height: 8px; border-radius: 50%; background: var(--ehs-maroon); animation: ehs-bounce 1s infinite; }
.ehs-dots span:nth-child(2) { animation-delay: .15s; }
.ehs-dots span:nth-child(3) { animation-delay: .3s; }
@keyframes ehs-bounce { 0%,80%,100%{ transform: scale(.5); opacity:.4 } 40%{ transform: scale(1); opacity:1 } }
.ehs-loadbar { height: 3px; background: var(--ehs-rule); overflow: hidden; border-radius: var(--ehs-r-pill); }
.ehs-loadbar::after { content: ''; display: block; height: 100%; width: 40%; background: var(--ehs-maroon); animation: ehs-load 1.2s ease-in-out infinite; }
@keyframes ehs-load { 0%{ transform: translateX(-100%) } 100%{ transform: translateX(320%) } }

/* ---- Banner (page-level) ------------------------------------------ */
.ehs-banner {
  display: flex; align-items: center; gap: 12px; padding: 12px 18px;
  background: var(--ehs-maroon); color: #fff; font-size: 14px;
}
.ehs-banner--gold { background: var(--ehs-gold-pale); color: var(--ehs-on-goldpale); }
.ehs-banner__close { margin-left: auto; background: none; border: none; color: inherit; cursor: pointer; font-size: 18px; opacity: .8; }

/* ---- Empty state -------------------------------------------------- */
.ehs-empty { text-align: center; padding: 40px 20px; color: var(--ehs-muted); }
.ehs-empty__icon { font-size: 40px; opacity: .5; }
.ehs-empty__title { font-family: var(--ehs-font-display); font-size: 20px; color: var(--ehs-ink); margin: 10px 0 4px; }

/* ---- Steps / wizard ----------------------------------------------- */
.ehs-steps { display: flex; align-items: center; }
.ehs-step { display: flex; align-items: center; gap: 8px; color: var(--ehs-muted); font-size: 13px; font-weight: 600; }
.ehs-step__num { width: 26px; height: 26px; border-radius: 50%; border: 2px solid var(--ehs-rule-strong); display: inline-flex; align-items: center; justify-content: center; font-size: 12px; background: var(--ehs-paper); }
.ehs-step--done .ehs-step__num { background: var(--ehs-maroon); border-color: var(--ehs-maroon); color: #fff; }
.ehs-step--active { color: var(--ehs-accent-text); }
.ehs-step--active .ehs-step__num { border-color: var(--ehs-maroon); color: var(--ehs-accent-text); }
.ehs-step__line { width: 40px; height: 2px; background: var(--ehs-rule-strong); margin: 0 10px; }

/* ---- Timeline ----------------------------------------------------- */
.ehs-timeline { list-style: none; padding-left: 6px; }
.ehs-tl-item { position: relative; padding: 0 0 20px 24px; border-left: 2px solid var(--ehs-rule); }
.ehs-tl-item:last-child { border-left-color: transparent; }
.ehs-tl-item::before { content: ''; position: absolute; left: -7px; top: 2px; width: 12px; height: 12px; border-radius: 50%; background: var(--ehs-gold); border: 2px solid var(--ehs-paper); box-shadow: 0 0 0 2px var(--ehs-gold-deep); }
.ehs-tl-item .when { font-family: var(--ehs-font-mono); font-size: 11px; color: var(--ehs-muted); }

/* ---- List / description list -------------------------------------- */
.ehs-list { list-style: none; border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-list__item { display: flex; align-items: center; gap: 12px; padding: 12px 16px; }
.ehs-list__item + .ehs-list__item { border-top: 1px solid var(--ehs-rule); }
.ehs-list__item:hover { background: var(--ehs-cream); }
.ehs-dl { display: grid; grid-template-columns: max-content 1fr; gap: 8px 22px; font-size: 14px; }
.ehs-dl dt { color: var(--ehs-muted); font-weight: 600; }
.ehs-dl dd { color: var(--ehs-ink); }

/* ---- Tree --------------------------------------------------------- */
.ehs-tree { font-size: 14px; }
.ehs-tree__node { padding: 4px 0 4px 20px; position: relative; }
.ehs-tree__node::before { content: '▸'; position: absolute; left: 4px; color: var(--ehs-muted); font-size: 11px; }
.ehs-tree__node--open::before { content: '▾'; }
.ehs-tree__children { padding-left: 16px; border-left: 1px dashed var(--ehs-rule-strong); margin-left: 8px; }

/* ---- Drawer / sheet ----------------------------------------------- */
.ehs-drawer { background: var(--ehs-paper); border-left: 1px solid var(--ehs-rule); box-shadow: var(--ehs-shadow-lg); width: 300px; height: 100%; padding: 20px; }

/* ---- Command palette ---------------------------------------------- */
.ehs-cmdk { background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-lg); box-shadow: var(--ehs-shadow-lg); width: 100%; max-width: 460px; overflow: hidden; }
.ehs-cmdk__input { width: 100%; border: none; border-bottom: 1px solid var(--ehs-rule); padding: 15px 18px; font-family: var(--ehs-font-body); font-size: 15px; outline: none; }
.ehs-cmdk__list { padding: 8px; }

/* ---- Sidebar nav / vertical tabs ---------------------------------- */
.ehs-side { background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); padding: 8px; width: 210px; }
.ehs-side__link { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: var(--ehs-r-sm); color: var(--ehs-ink); font-size: 14px; text-decoration: none; cursor: pointer; }
.ehs-side__link:hover { background: var(--ehs-cream); }
.ehs-side__link--active { background: var(--ehs-maroon); color: #fff; font-weight: 600; }

/* ---- Bottom nav / tab bar ----------------------------------------- */
.ehs-bottomnav { display: flex; background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; }
.ehs-bottomnav__item { flex: 1; text-align: center; padding: 10px 4px; font-size: 11px; color: var(--ehs-muted); cursor: pointer; }
.ehs-bottomnav__item .ico { font-size: 19px; display: block; }
.ehs-bottomnav__item--active { color: var(--ehs-accent-text); }

/* ---- Toolbar ------------------------------------------------------ */
.ehs-toolbar { display: flex; align-items: center; gap: 6px; padding: 8px; background: var(--ehs-cream); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); }
.ehs-toolbar__sep { width: 1px; height: 22px; background: var(--ehs-rule-strong); margin: 0 4px; }

/* ---- Stat / KPI --------------------------------------------------- */
.ehs-stat { background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); padding: 16px 18px; }
.ehs-stat__label { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--ehs-muted); font-weight: 700; }
.ehs-stat__value { font-family: var(--ehs-font-display); font-size: 34px; font-weight: 700; color: var(--ehs-ink); line-height: 1.1; }
.ehs-stat__delta { font-size: 12px; font-weight: 600; }
.ehs-stat__delta.up { color: var(--ehs-ok); }
.ehs-stat__delta.down { color: var(--ehs-bad); }

/* ---- Meter -------------------------------------------------------- */
.ehs-meter { height: 10px; border-radius: var(--ehs-r-pill); background: var(--ehs-rule); overflow: hidden; display: flex; }
.ehs-meter span { height: 100%; }

/* ---- Kbd / code / quote ------------------------------------------- */
.ehs-kbd { font-family: var(--ehs-font-mono); font-size: 12px; background: var(--ehs-paper); border: 1px solid var(--ehs-rule-strong); border-bottom-width: 2px; border-radius: 5px; padding: 2px 7px; color: var(--ehs-ink); }
.ehs-code { font-family: var(--ehs-font-mono); font-size: 13px; background: var(--ehs-code-bg); color: var(--ehs-code-fg); border-radius: var(--ehs-r-md); padding: 14px 16px; overflow-x: auto; }
/* Syntax token colors — used by highlighted code blocks (light + dark). */
.t-tag   { color: var(--ehs-code-tag); }
.t-attr  { color: var(--ehs-code-attr); }
.t-str   { color: var(--ehs-code-str); }
.t-punct { color: var(--ehs-code-punct); }
.ehs-code--inline { display: inline; padding: 2px 6px; font-size: .9em; }
.ehs-quote { border-left: 4px solid var(--ehs-gold); background: var(--ehs-cream); padding: 12px 18px; font-family: var(--ehs-font-display); font-size: 18px; color: var(--ehs-ink); border-radius: 0 var(--ehs-r-sm) var(--ehs-r-sm) 0; }

/* ---- File dropzone ------------------------------------------------ */
.ehs-dropzone { border: 2px dashed var(--ehs-rule-strong); border-radius: var(--ehs-r-md); padding: 30px; text-align: center; color: var(--ehs-muted); background: var(--ehs-cream); cursor: pointer; transition: border-color .15s, background .15s; }
.ehs-dropzone:hover { border-color: var(--ehs-maroon); background: var(--ehs-paper); }

/* ---- Choice card (radio/checkbox card) ---------------------------- */
/* box-sizing: width:100% plus side padding and a border is 34px wider than the
   column under the content-box default, so a stack of choice cards hung out past
   every input above it. Found on the public form fill page 2026-07-25. */
.ehs-choice-card { box-sizing: border-box; display: flex; gap: 12px; align-items: flex-start; border: 1px solid var(--ehs-rule-strong); border-radius: var(--ehs-r-md); padding: 14px 16px; cursor: pointer; transition: border-color .15s, box-shadow .15s; background: none; color: var(--ehs-ink); font-family: var(--ehs-font-body); text-align: left; width: 100%; }
.ehs-choice-card:hover { border-color: var(--ehs-maroon); }
.ehs-choice-card--active { border-color: var(--ehs-maroon); box-shadow: 0 0 0 3px rgba(104,26,49,.12); }

/* ---- Calendar (mini) ---------------------------------------------- */
.ehs-cal { background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); padding: 14px; width: 260px; }
.ehs-cal__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.ehs-cal__dow { font-size: 10px; color: var(--ehs-muted); font-weight: 700; padding: 4px 0; }
.ehs-cal__day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; font-size: 13px; border-radius: var(--ehs-r-sm); cursor: pointer; }
.ehs-cal__day:hover { background: var(--ehs-cream); }
.ehs-cal__day--today { border: 1px solid var(--ehs-gold-deep); }
.ehs-cal__day--sel { background: var(--ehs-maroon); color: #fff; }
.ehs-cal__day--mute { color: var(--ehs-muted); } /* rule-strong is a border token; unreadable as text on dark */

/* ---- Presence / notification badge -------------------------------- */
.ehs-presence { width: 10px; height: 10px; border-radius: 50%; display: inline-block; background: var(--ehs-ok); }
.ehs-notif { position: relative; display: inline-flex; }
.ehs-notif__count { position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px; border-radius: var(--ehs-r-pill); background: var(--ehs-bad); color: #fff; font-size: 10px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; border: 2px solid var(--ehs-paper); }

/* ---- Carousel (dots) ---------------------------------------------- */
/* =====================================================================
   ACCORDION (promoted 2026-07-25) — expand/collapse rows for FAQs, settings
   groups, and long forms. The kit's component index has advertised an
   "Accordion" since the first import, but the only implementation lived in
   the gallery page's own <style> as `.acc`, so any app that copied the row
   got an unstyled div. Same markup, real class. Panel open state is a class
   the app toggles (`.ehs-accordion__panel--open`); like .ehs-modal there is
   no shared JS.
   ===================================================================== */
.ehs-accordion {
  border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md);
  overflow: hidden; background: var(--ehs-paper); width: 100%;
}
.ehs-accordion__item + .ehs-accordion__item { border-top: 1px solid var(--ehs-rule); }
.ehs-accordion__btn {
  width: 100%; text-align: left; padding: 14px 16px;
  font-family: var(--ehs-font-body); font-size: 15px; font-weight: 600;
  background: none; border: none; cursor: pointer;
  display: flex; justify-content: space-between; align-items: center;
  color: var(--ehs-ink);
}
.ehs-accordion__btn:hover { background: var(--ehs-cream); }
.ehs-accordion__btn:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: -2px; }
.ehs-accordion__panel {
  padding: 0 16px; max-height: 0; overflow: hidden;
  transition: max-height .22s ease, padding .22s ease;
  color: var(--ehs-muted); font-size: 14px;
}
.ehs-accordion__panel--open { max-height: 60vh; padding: 12px 16px 16px; }
@media (prefers-reduced-motion: reduce) { .ehs-accordion__panel { transition: none; } }

.ehs-carousel__dots { display: flex; gap: 7px; justify-content: center; }
.ehs-carousel__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ehs-rule-strong); border: none; cursor: pointer; }
.ehs-carousel__dot--active { background: var(--ehs-maroon); width: 22px; border-radius: var(--ehs-r-pill); }

/* ---- Divider variants --------------------------------------------- */
.ehs-divider { height: 1px; background: var(--ehs-rule); border: 0; }
.ehs-divider--text { display: flex; align-items: center; gap: 14px; color: var(--ehs-muted); font-size: 12px; text-transform: uppercase; letter-spacing: .1em; }
.ehs-divider--text::before, .ehs-divider--text::after { content: ''; flex: 1; height: 1px; background: var(--ehs-rule); }

/* =====================================================================
   High-reuse patterns (added from the cross-app UI inventory).
   ===================================================================== */

/* ---- Loading button ------------------------------------------------ */
.ehs-btn--loading { position: relative; color: transparent !important; pointer-events: none; }
.ehs-btn--loading::after {
  content: ''; position: absolute; left: 50%; top: 50%; width: 15px; height: 15px;
  margin: -7.5px 0 0 -7.5px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.45); border-top-color: #fff;
  animation: ehs-spin .6s linear infinite;
}
.ehs-btn--secondary.ehs-btn--loading::after,
.ehs-btn--ghost.ehs-btn--loading::after { border-color: rgba(104,26,49,.35); border-top-color: var(--ehs-maroon); }

/* ---- Toast / snackbar system -------------------------------------- */
.ehs-toasts {
  position: fixed; bottom: 22px; right: 22px; z-index: 1000;
  display: flex; flex-direction: column; gap: 10px; max-width: 350px;
}
.ehs-toast {
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--ehs-code-bg); color: var(--ehs-code-fg);
  padding: 12px 14px 12px 13px; border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-lg); border-left: 4px solid var(--ehs-gold);
  font-size: 14px; line-height: 1.4; animation: ehs-toast-in .22s ease;
}
.ehs-toast--ok   { border-left-color: var(--ehs-ok); }
.ehs-toast--warn { border-left-color: var(--ehs-warn); }
.ehs-toast--bad  { border-left-color: var(--ehs-bad); }
.ehs-toast--info { border-left-color: var(--ehs-info); }
.ehs-toast.hide  { animation: ehs-toast-out .2s ease forwards; }
.ehs-toast__icon { flex: none; font-weight: 700; }
.ehs-toast__close { margin-left: auto; background: none; border: none; color: inherit; opacity: .6; cursor: pointer; font-size: 15px; }
.ehs-toast__close:hover { opacity: 1; }
@keyframes ehs-toast-in  { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: none; } }
@keyframes ehs-toast-out { to { opacity: 0; transform: translateX(20px); } }

/* ---- Stat strip (KPI header row) ---------------------------------- */
.ehs-statstrip {
  display: flex; flex-wrap: wrap;
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-md); overflow: hidden;
}
.ehs-statstrip > .ehs-statstrip__item {
  flex: 1; min-width: 150px; padding: 16px 20px;
  border-left: 1px solid var(--ehs-rule);
}
.ehs-statstrip > .ehs-statstrip__item:first-child { border-left: 0; }

/* ---- Data table: toolbar, sortable, selectable -------------------- */
.ehs-table-wrap { border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-table-toolbar { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--ehs-rule); flex-wrap: wrap; }
.ehs-table-toolbar .ehs-search { flex: 1; min-width: 180px; }
.ehs-table-wrap .ehs-table th.ehs-th-sort { cursor: pointer; user-select: none; }
.ehs-table-wrap .ehs-table th.ehs-th-sort:hover { color: var(--ehs-ink); }
.ehs-th-sort .caret { opacity: .4; font-size: 10px; margin-left: 3px; }
.ehs-th-sort[aria-sort="ascending"] .caret,
.ehs-th-sort[aria-sort="descending"] .caret { opacity: 1; color: var(--ehs-accent-text); }
.ehs-table tr.is-selected td { background: var(--ehs-gold-pale); }
/* Zebra striping for long, dense tables. */
.ehs-table--striped tbody tr:nth-child(even) td { background: color-mix(in srgb, var(--ehs-cream) 60%, var(--ehs-paper)); }
.ehs-table--striped tbody tr:hover td { background: var(--ehs-cream); }
.ehs-table--striped tbody tr.is-selected td { background: var(--ehs-gold-pale); }

/* ---- Lightbox / image viewer -------------------------------------- */
.ehs-thumbs { display: flex; flex-wrap: wrap; gap: 10px; }
.ehs-thumb { width: 90px; height: 68px; border-radius: var(--ehs-r-sm); overflow: hidden; cursor: pointer; border: 1px solid var(--ehs-rule); background: var(--ehs-sunken); }
/* contain + neutral bars so non-square images aren't cropped in the grid */
.ehs-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; transition: transform .2s ease; }
.ehs-thumb:hover img { transform: scale(1.06); }
.ehs-lightbox { position: fixed; inset: 0; background: rgba(20,12,14,.9); z-index: 1100; display: none; align-items: center; justify-content: center; padding: 40px; }
.ehs-lightbox.open { display: flex; }
.ehs-lightbox img { max-width: 92vw; max-height: 86vh; border-radius: var(--ehs-r-md); box-shadow: var(--ehs-shadow-lg); }
.ehs-lightbox__btn { position: absolute; top: 50%; transform: translateY(-50%); width: 46px; height: 46px; border-radius: 50%; border: none; background: rgba(255,255,255,.14); color: #fff; font-size: 22px; cursor: pointer; }
.ehs-lightbox__btn:hover { background: rgba(255,255,255,.26); }
.ehs-lightbox__prev { left: 22px; } .ehs-lightbox__next { right: 22px; }
.ehs-lightbox__close { position: absolute; top: 20px; right: 22px; width: 40px; height: 40px; border-radius: 50%; border: none; background: rgba(255,255,255,.14); color: #fff; font-size: 20px; cursor: pointer; }
.ehs-lightbox__close:hover { background: rgba(255,255,255,.26); }

/* ---- Rich-text editor / composer ---------------------------------- */
.ehs-editor { border: 1px solid var(--ehs-rule-strong); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-editor:focus-within { border-color: var(--ehs-maroon); box-shadow: 0 0 0 3px rgba(104,26,49,.12); }
.ehs-editor__bar { display: flex; align-items: center; gap: 2px; padding: 6px 8px; border-bottom: 1px solid var(--ehs-rule); background: var(--ehs-cream); flex-wrap: wrap; }
.ehs-editor__bar .ehs-icon-btn { width: 30px; height: 30px; border: none; background: none; font-size: 14px; }
.ehs-editor__bar .ehs-icon-btn:hover { background: var(--ehs-sunken); }
.ehs-editor__bar .sep { width: 1px; height: 18px; background: var(--ehs-rule-strong); margin: 0 4px; }
.ehs-editor__area { padding: 12px 14px; min-height: 92px; font-size: 14px; color: var(--ehs-ink); outline: none; line-height: 1.5; }
.ehs-editor__area:empty::before { content: attr(data-placeholder); color: #a89f92; }
.ehs-editor__foot { display: flex; justify-content: flex-end; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--ehs-rule); }

/* =====================================================================
   Niche / app-specific components (from the cross-app inventory).
   ===================================================================== */

/* ---- QR / barcode scanner viewfinder ------------------------------ */
.ehs-scanner { position: relative; width: 260px; aspect-ratio: 1; border-radius: var(--ehs-r-md); overflow: hidden; background: #0e0a0b; display: flex; align-items: center; justify-content: center; }
.ehs-scanner video, .ehs-scanner__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ehs-scanner__bg { background: repeating-linear-gradient(135deg, #1a1416, #1a1416 12px, #161012 12px, #161012 24px); }
.ehs-scanner__frame { position: absolute; inset: 20%; }
.ehs-scanner__frame::before, .ehs-scanner__frame::after,
.ehs-scanner__frame > i::before, .ehs-scanner__frame > i::after {
  content: ''; position: absolute; width: 26px; height: 26px; border: 3px solid var(--ehs-gold);
}
.ehs-scanner__frame::before { top: 0; left: 0; border-right: 0; border-bottom: 0; border-radius: 6px 0 0 0; }
.ehs-scanner__frame::after  { top: 0; right: 0; border-left: 0; border-bottom: 0; border-radius: 0 6px 0 0; }
.ehs-scanner__frame > i::before { bottom: 0; left: 0; border-right: 0; border-top: 0; border-radius: 0 0 0 6px; }
.ehs-scanner__frame > i::after  { bottom: 0; right: 0; border-left: 0; border-top: 0; border-radius: 0 0 6px 0; }
.ehs-scanner__line { position: absolute; left: 22%; right: 22%; height: 2px; background: var(--ehs-gold); box-shadow: 0 0 10px 1px var(--ehs-gold); top: 22%; animation: ehs-scan 2.2s ease-in-out infinite; }
@keyframes ehs-scan { 0%,100% { top: 22%; } 50% { top: 78%; } }
.ehs-scanner__hint { position: absolute; bottom: 10px; left: 0; right: 0; text-align: center; color: rgba(255,255,255,.8); font-size: 12px; }

/* ---- Signature pad ------------------------------------------------ */
.ehs-sigpad { border: 1px solid var(--ehs-rule-strong); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); width: 100%; max-width: 420px; }
.ehs-sigpad__canvas { display: block; width: 100%; height: 160px; touch-action: none; cursor: crosshair; background:
  linear-gradient(var(--ehs-paper), var(--ehs-paper)) ; }
.ehs-sigpad__line { position: relative; }
.ehs-sigpad__line::after { content: ''; position: absolute; left: 18px; right: 18px; bottom: 40px; border-top: 1px dashed var(--ehs-rule-strong); pointer-events: none; }
.ehs-sigpad__bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--ehs-rule); background: var(--ehs-cream); }
.ehs-sigpad__label { font-size: 12px; color: var(--ehs-muted); }

/* ---- Kanban board ------------------------------------------------- */
.ehs-kanban { display: flex; gap: 14px; overflow-x: auto; padding-bottom: 6px; }
.ehs-kanban__col { flex: 1; min-width: 190px; background: var(--ehs-cream); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.ehs-kanban__col.is-drop { outline: 2px dashed var(--ehs-maroon); outline-offset: -3px; }
.ehs-kanban__col-head { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ehs-muted); padding: 2px 4px 4px; }
.ehs-kanban__col-head .n { margin-left: auto; background: var(--ehs-sunken); color: var(--ehs-muted); border-radius: var(--ehs-r-pill); padding: 1px 8px; font-size: 11px; }
.ehs-kanban__card { background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-left: 3px solid var(--ehs-gold); border-radius: var(--ehs-r-sm); padding: 10px 12px; font-size: 13.5px; cursor: grab; box-shadow: var(--ehs-shadow-sm); }
.ehs-kanban__card:active { cursor: grabbing; }
.ehs-kanban__card.dragging { opacity: .4; }
.ehs-kanban__card--maroon { border-left-color: var(--ehs-maroon); }
.ehs-kanban__card--bad { border-left-color: var(--ehs-bad); }
.ehs-kanban__card .meta { display: flex; align-items: center; gap: 6px; margin-top: 8px; font-size: 11px; color: var(--ehs-muted); }

/* ---- PIN pad ------------------------------------------------------ */
.ehs-pinpad { width: 236px; }
.ehs-pinpad__dots { display: flex; justify-content: center; gap: 12px; margin-bottom: 18px; }
.ehs-pinpad__dot { width: 13px; height: 13px; border-radius: 50%; border: 2px solid var(--ehs-rule-strong); }
.ehs-pinpad__dot.on { background: var(--ehs-maroon); border-color: var(--ehs-maroon); }
.ehs-pinpad__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.ehs-pin-key { height: 60px; border-radius: var(--ehs-r-md); border: 1px solid var(--ehs-rule); background: var(--ehs-paper); font-family: var(--ehs-font-body); font-size: 22px; font-weight: 600; color: var(--ehs-ink); cursor: pointer; transition: background .1s, border-color .1s; }
.ehs-pin-key:hover { background: var(--ehs-cream); border-color: var(--ehs-rule-strong); }
.ehs-pin-key:active { background: var(--ehs-gold-pale); }
.ehs-pin-key--muted { background: none; border-color: transparent; color: var(--ehs-muted); font-size: 15px; }
.ehs-pin-key--muted:hover { background: var(--ehs-cream); }

/* ---- Full month calendar ------------------------------------------ */
.ehs-calendar { border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-calendar__head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--ehs-rule); }
.ehs-calendar__title { font-family: var(--ehs-font-display); font-size: 18px; font-weight: 700; }
.ehs-calendar__nav { margin-left: auto; display: flex; gap: 6px; }
.ehs-calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.ehs-calendar__dow { text-align: center; font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ehs-muted); padding: 8px 0; border-bottom: 1px solid var(--ehs-rule); }
.ehs-calendar__cell { min-height: 78px; border-right: 1px solid var(--ehs-rule); border-bottom: 1px solid var(--ehs-rule); padding: 6px 7px; display: flex; flex-direction: column; gap: 3px; }
.ehs-calendar__cell:nth-child(7n) { border-right: 0; }
.ehs-calendar__date { font-size: 12.5px; color: var(--ehs-ink); align-self: flex-start; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; }
.ehs-calendar__cell--mute .ehs-calendar__date { color: var(--ehs-muted); }
.ehs-calendar__cell--today .ehs-calendar__date { background: var(--ehs-maroon); color: #fff; font-weight: 700; }
.ehs-calendar__event { font-size: 10.5px; padding: 2px 6px; border-radius: 4px; background: var(--ehs-gold-pale); color: var(--ehs-on-goldpale); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ehs-calendar__event--maroon { background: color-mix(in srgb, var(--ehs-maroon) 16%, var(--ehs-paper)); color: var(--ehs-on-maroonpale); }
.ehs-calendar__event--ok { background: var(--ehs-ok-pale); color: var(--ehs-ok-text); }
/* Remaining status families, so a calendar can carry a full categorical set
   (6 distinct day types) without an app hand-rolling its own swatches. Each
   pair dark-flips on both surface and text. */
.ehs-calendar__event--info { background: var(--ehs-info-pale); color: var(--ehs-info-text); }
.ehs-calendar__event--warn { background: var(--ehs-warn-pale); color: var(--ehs-warn-text); }
.ehs-calendar__event--bad { background: var(--ehs-bad-pale); color: var(--ehs-bad-text); }
.ehs-calendar__event--muted { background: var(--ehs-sunken); color: var(--ehs-muted); }
/* Ink-tinted neutral — a 7th distinct chip for categorical sets that outgrow
   the brand + status families, carrying no status meaning. Both sides derive
   from --ehs-ink/--ehs-paper, so it inverts with the theme automatically. */
.ehs-calendar__event--neutral { background: color-mix(in srgb, var(--ehs-ink) 12%, var(--ehs-paper)); color: var(--ehs-ink); }

/* ---- Calendar: classify variant ----------------------------------- */
/* For calendars where each day carries ONE categorical value — the day's
   *type*, not a list of things happening on it (bell schedule, duty roster,
   staffing tier). Cells are interactive: clicking a day opens the app's own
   editor (typically an .ehs-modal) for that day.
   Markup — cells are real <button>s so keyboard + AT get them for free:
     <div class="ehs-calendar ehs-calendar--classify">
       <div class="ehs-calendar__head">…</div>
       <div class="ehs-calendar__grid">
         <div class="ehs-calendar__dow">Sun</div>  … ×7 (required: the 7n
                                                   border rule counts on them)
         <button class="ehs-calendar__cell ehs-calendar__cell--today">
           <span class="ehs-calendar__date">17</span>
           <span class="ehs-calendar__event ehs-calendar__event--ok">Regular</span>
         </button>
       </div>
     </div>
   Use __cell--empty for a day with no value, and __cell--mute for padding
   days outside the month. */
/* A day with no value reads as a well. Stated before the button rules and
   repeated at button specificity below — a bare `.ehs-calendar__cell--empty`
   (0,1,0) cannot beat `--classify button.ehs-calendar__cell` (0,2,1), so the
   read-only <div> and interactive <button> cases each need their own reach. */
.ehs-calendar__cell--empty { background: var(--ehs-sunken); }
/* Interactivity keys off the cell actually being a <button>, so a read-only
   calendar can use the same variant (same colours, same one-value-per-day
   layout) without advertising clicks it does not handle. */
.ehs-calendar--classify button.ehs-calendar__cell {
  font: inherit; color: var(--ehs-ink); text-align: left; width: 100%;
  background: var(--ehs-paper); cursor: pointer;
  border: 0; border-right: 1px solid var(--ehs-rule); border-bottom: 1px solid var(--ehs-rule);
  transition: background .12s, box-shadow .12s;
}
.ehs-calendar--classify button.ehs-calendar__cell:nth-child(7n) { border-right: 0; }
.ehs-calendar--classify button.ehs-calendar__cell--empty { background: var(--ehs-sunken); }
.ehs-calendar--classify button.ehs-calendar__cell:hover,
.ehs-calendar--classify button.ehs-calendar__cell--empty:hover { background: var(--ehs-cream); }
.ehs-calendar--classify button.ehs-calendar__cell:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: -2px; z-index: 1; }
/* The event is the day's value, so it fills the cell and may wrap — unlike the
   ellipsised one-of-many events in the default calendar. */
.ehs-calendar--classify .ehs-calendar__event { white-space: normal; font-weight: 600; margin-top: auto; }
.ehs-calendar--classify .ehs-calendar__note { font-size: 9.5px; color: var(--ehs-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* =====================================================================
   IMPORTED — adapted from Uiverse.io (MIT), recolored to the brand.
   Each effect reimplemented with --ehs-* tokens.
   ===================================================================== */

/* ---- Glow card (frosted glass + maroon->gold glow, expands on hover) */
.ehs-glow-card { position: relative; width: 220px; height: 300px; display: flex; align-items: center; justify-content: center; transition: .5s; }
.ehs-glow-card::before, .ehs-glow-card::after {
  content: ''; position: absolute; top: 0; left: 42px; width: 55%; height: 100%; border-radius: var(--ehs-r-md);
  background: linear-gradient(315deg, var(--ehs-gold), var(--ehs-maroon)); transform: skewX(15deg); transition: .5s;
}
.ehs-glow-card::after { filter: blur(30px); }
.ehs-glow-card:hover::before, .ehs-glow-card:hover::after { transform: skewX(0deg) scaleX(1.25); }
.ehs-glow-card__body {
  position: relative; z-index: 1; width: 190px; height: 254px; padding: 20px; border-radius: var(--ehs-r-md);
  background: rgba(255,255,255,.08); backdrop-filter: blur(10px); box-shadow: var(--ehs-shadow-md);
  color: #fff; display: flex; align-items: center; justify-content: center; text-align: center; font-family: var(--ehs-font-display); font-weight: 700; font-size: 20px;
}

/* ---- Flip card (3D, maroon front / gold back) --------------------- */
.ehs-flip { width: 300px; height: 190px; perspective: 1000px; }
.ehs-flip__inner { position: relative; width: 100%; height: 100%; transition: transform .8s; transform-style: preserve-3d; }
.ehs-flip:hover .ehs-flip__inner { transform: rotateY(180deg); }
.ehs-flip__front, .ehs-flip__back {
  position: absolute; inset: 0; backface-visibility: hidden; border-radius: var(--ehs-r-md);
  display: flex; align-items: center; justify-content: center; text-align: center; padding: 20px;
  font-family: var(--ehs-font-display); font-weight: 700; font-size: 22px; box-shadow: var(--ehs-shadow-md);
}
.ehs-flip__front { background: var(--ehs-maroon); color: #fff; }
.ehs-flip__back { background: var(--ehs-gold); color: var(--ehs-maroon-deep); transform: rotateY(180deg); }

/* Info Card — the non-flip version of the flip card: same gold-edge look,
   all content on one static face, maroon border on hover. */
.ehs-infocard { position: relative; display: flex; flex-direction: column; overflow: hidden;
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md);
  padding: 18px 20px; box-shadow: var(--ehs-shadow-sm); transition: border-color .15s ease, transform .15s ease; }
.ehs-infocard::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--ehs-gold); }
.ehs-infocard:hover { border-color: var(--ehs-maroon); }
.ehs-infocard__title { font-family: var(--ehs-font-display); font-weight: 800; font-size: 20px; color: var(--ehs-ink); line-height: 1.15; }
.ehs-infocard__sub { font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--ehs-gold-deep); margin-top: 2px; }
.ehs-infocard__body { margin-top: 10px; font-size: 14px; color: var(--ehs-muted); line-height: 1.55; }
.ehs-infocard__foot { margin-top: auto; padding-top: 14px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* ---- Reveal button (color wipe + underline + arrow) --------------- */
.ehs-btn-reveal { position: relative; display: inline-flex; align-items: center; gap: .5rem; background: none; border: none; cursor: pointer; font-family: var(--ehs-font-body); font-weight: 700; font-size: 18px; color: var(--ehs-ink); }
.ehs-btn-reveal__t { position: relative; }
.ehs-btn-reveal__t::before { content: attr(data-text); position: absolute; inset: 0; width: 0; overflow: hidden; color: var(--ehs-accent-text); transition: width .3s ease-out; }
.ehs-btn-reveal::after { content: ''; position: absolute; left: 0; bottom: -6px; height: 2px; width: 0; background: var(--ehs-gold); transition: width .3s ease-out; }
.ehs-btn-reveal:hover::after { width: 100%; }
.ehs-btn-reveal:hover .ehs-btn-reveal__t::before { width: 100%; }
.ehs-btn-reveal svg { width: 15px; height: 15px; transition: transform .2s .2s, color .2s; }
.ehs-btn-reveal:hover svg { transform: translateX(4px); color: var(--ehs-accent-text); }

/* ---- Download button (text slides up to icon + tooltip) ----------- */
.ehs-btn-dl { --w: 116px; --h: 38px; position: relative; width: var(--w); height: var(--h); background: var(--ehs-maroon); border-radius: var(--ehs-r-sm); text-align: center; transition: background .3s; cursor: pointer; }
.ehs-btn-dl:hover { background: var(--ehs-maroon-deep); }
/* Clip wrapper so exactly ONE of text/icon is visible — no bleed. */
.ehs-btn-dl__slide { position: absolute; inset: 0; overflow: hidden; border-radius: inherit; }
.ehs-btn-dl__t, .ehs-btn-dl__i { position: absolute; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #fff; transition: top .45s ease; }
.ehs-btn-dl__t { top: 0; font-weight: 700; font-size: 13px; letter-spacing: .04em; text-transform: uppercase; }
.ehs-btn-dl__i { top: 100%; }
.ehs-btn-dl:hover .ehs-btn-dl__t { top: -100%; }
.ehs-btn-dl:hover .ehs-btn-dl__i { top: 0; }
.ehs-btn-dl::before { content: attr(data-tip); position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(100% + 12px); background: var(--ehs-paper); color: var(--ehs-ink); border: 1px solid var(--ehs-rule); font-size: 12px; padding: 5px 10px; border-radius: var(--ehs-r-sm); white-space: nowrap; box-shadow: var(--ehs-shadow-md); opacity: 0; visibility: hidden; transition: all .3s; }
.ehs-btn-dl:hover::before { opacity: 1; visibility: visible; bottom: calc(100% + 8px); }

/* ---- Scan loader (text with sweeping brand line + clip cut) ------- */
.ehs-loader-scan { position: relative; display: inline-block; font-family: var(--ehs-font-display); font-weight: 700; font-style: italic; font-size: 42px; color: var(--ehs-ink); }
.ehs-loader-scan span { display: inline-block; animation: ehs-cut 2s infinite; }
.ehs-loader-scan::before { content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 4px; border-radius: 4px; background: var(--ehs-maroon); animation: ehs-scan 2s infinite; z-index: 1; }
.ehs-loader-scan::after { content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 6px; border-radius: 4px; background: var(--ehs-gold); filter: blur(8px); animation: ehs-scan 2s infinite; }
@keyframes ehs-scan { 0%{top:0} 25%{top:44px} 50%{top:0} 75%{top:44px} }
@keyframes ehs-cut { 0%{clip-path:inset(0 0 0 0)} 25%{clip-path:inset(100% 0 0 0)} 50%{clip-path:inset(0 0 100% 0)} 75%{clip-path:inset(0 0 0 0)} }

/* ---- Honeycomb loader (7 gold hexes pulsing) --------------------- */
.ehs-honeycomb { position: relative; height: 24px; width: 24px; }
.ehs-honeycomb div { position: absolute; width: 24px; height: 12px; margin-top: 6px; background: var(--ehs-gold); animation: ehs-honey 2.1s infinite backwards; }
.ehs-honeycomb div::before, .ehs-honeycomb div::after { content: ''; position: absolute; left: 0; right: 0; border-left: 12px solid transparent; border-right: 12px solid transparent; }
.ehs-honeycomb div::before { bottom: -6px; border-top: 6px solid var(--ehs-gold); }
.ehs-honeycomb div::after { top: -6px; border-bottom: 6px solid var(--ehs-gold); }
.ehs-honeycomb div:nth-child(1){ left:-28px; top:0; animation-delay:0s; }
.ehs-honeycomb div:nth-child(2){ left:-14px; top:22px; animation-delay:.1s; }
.ehs-honeycomb div:nth-child(3){ left:14px; top:22px; animation-delay:.2s; }
.ehs-honeycomb div:nth-child(4){ left:28px; top:0; animation-delay:.3s; }
.ehs-honeycomb div:nth-child(5){ left:14px; top:-22px; animation-delay:.4s; }
.ehs-honeycomb div:nth-child(6){ left:-14px; top:-22px; animation-delay:.5s; }
.ehs-honeycomb div:nth-child(7){ left:0; top:0; animation-delay:.6s; }
@keyframes ehs-honey { 0%,20%,80%,100%{opacity:0;transform:scale(0)} 30%,70%{opacity:1;transform:scale(1)} }

/* ---- Globe loader (spinning, maroon water + gold land) ----------- */
/* Globe stays true blue/green so it reads as an actual planet. */
.ehs-globe { --water: #2a6fb0; --land: #4aa05a; width: 7em; height: 7em; border-radius: 50%; background: var(--water); position: relative; overflow: hidden; border: solid .15em #eef4f8; box-shadow: inset 0 .5em rgba(255,255,255,.22), inset 0 -.5em rgba(0,0,0,.3); }
.ehs-globe span { position: absolute; width: 2.4em; height: 1.6em; background: var(--land); border-radius: 45%; opacity: .95; animation: ehs-globe 5s infinite linear; }
.ehs-globe span:nth-child(1){ top: 1em; animation-delay: 0s; }
.ehs-globe span:nth-child(2){ top: 3em; animation-delay: -1.6s; height: 2em; width: 3em; }
.ehs-globe span:nth-child(3){ top: 4.6em; animation-delay: -3.2s; }
@keyframes ehs-globe { from{ left: 7.5em; } to{ left: -4em; } }

/* ---- Day/Night switch — doubles as the light/dark toggle ---------- */
.ehs-daynight { position: relative; display: inline-block; width: 74px; height: 34px; flex: none; }
.ehs-daynight input { opacity: 0; width: 0; height: 0; }
.ehs-daynight .track {
  position: absolute; inset: 0; cursor: pointer; border-radius: 34px; overflow: hidden;
  background: linear-gradient(#6db3e6, #bfe0f5); transition: background .4s; box-shadow: inset 0 1px 3px rgba(0,0,0,.25);
}
/* DAY: gold sun with glow. NIGHT: pale crescent moon. */
.ehs-daynight .orb {
  position: absolute; height: 26px; width: 26px; left: 4px; top: 4px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #ffe07a, var(--ehs-legacy-gold));
  box-shadow: 0 0 10px 3px rgba(255,209,64,.7); transition: transform .45s cubic-bezier(.4,1.4,.5,1), background .4s, box-shadow .4s; z-index: 3;
}
.ehs-daynight input:checked + .track { background: linear-gradient(#0b1430, #1d2b52); }
.ehs-daynight input:checked + .track .orb {
  transform: translateX(40px);
  background: #e7e3d6; box-shadow: inset -7px -3px 0 0 #c9c3b2, 0 0 8px 2px rgba(0,0,0,.35);
}
/* Stars (night) + day clouds */
.ehs-daynight .star { position: absolute; border-radius: 50%; background: #fff; opacity: 0; transform: scale(.4); transition: opacity .4s, transform .4s; }
.ehs-daynight .star:nth-of-type(1){ width:4px;height:4px; top:7px; left:10px; }
.ehs-daynight .star:nth-of-type(2){ width:3px;height:3px; top:17px; left:18px; }
.ehs-daynight .star:nth-of-type(3){ width:2px;height:2px; top:9px; left:24px; }
.ehs-daynight .star:nth-of-type(4){ width:3px;height:3px; top:21px; left:28px; }
.ehs-daynight input:checked + .track .star { opacity: .95; transform: scale(1); transition-delay: .2s; }
.ehs-daynight .cloud { position: absolute; height: 7px; width: 18px; border-radius: 7px; background: rgba(255,255,255,.85); right: 8px; bottom: 8px; transition: opacity .4s, transform .4s; }
.ehs-daynight .cloud::before { content:''; position:absolute; width:10px; height:10px; border-radius:50%; background:inherit; top:-4px; left:3px; }
.ehs-daynight input:checked + .track .cloud { opacity: 0; transform: translateX(14px); }

/* ---- ID card (3D flip; EHS-themed, maroon/gold) ------------------- */
.ehs-idcard { width: 250px; height: 158px; perspective: 1000px; color: #fff; font-family: var(--ehs-font-body); }
.ehs-idcard__inner { position: relative; width: 100%; height: 100%; transition: transform .8s; transform-style: preserve-3d; }
.ehs-idcard:hover .ehs-idcard__inner { transform: rotateY(180deg); }
.ehs-idcard__front, .ehs-idcard__back { position: absolute; inset: 0; backface-visibility: hidden; border-radius: 12px; box-shadow: var(--ehs-shadow-lg); overflow: hidden; }
.ehs-idcard__front { background: linear-gradient(135deg, var(--ehs-maroon), var(--ehs-maroon-deep)); padding: 14px 16px; }
.ehs-idcard__front::after { content: ''; position: absolute; right: -30px; top: -30px; width: 120px; height: 120px; border-radius: 50%; background: radial-gradient(circle, rgba(208,183,134,.28), transparent 70%); }
.ehs-idcard__org { font-size: 10px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ehs-gold); }
.ehs-idcard__chip { width: 34px; height: 26px; border-radius: 5px; margin: 14px 0 12px; background: linear-gradient(135deg, #e7cf95, var(--ehs-gold-deep)); position: relative; }
.ehs-idcard__chip::before { content: ''; position: absolute; inset: 4px 6px; border: 1px solid rgba(83,15,33,.4); border-radius: 2px; }
.ehs-idcard__num { font-family: var(--ehs-font-mono); font-size: 13px; letter-spacing: .12em; }
.ehs-idcard__row { display: flex; justify-content: space-between; align-items: flex-end; margin-top: 8px; }
.ehs-idcard__label { font-size: 7px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.65); }
.ehs-idcard__name { font-size: 13px; font-weight: 700; letter-spacing: .04em; }
.ehs-idcard__shield { position: absolute; right: 14px; bottom: 12px; height: 30px; }
.ehs-idcard__back { background: linear-gradient(135deg, var(--ehs-maroon-deep), #3a0e1c); transform: rotateY(180deg); }
.ehs-idcard__strip { height: 34px; background: #1a1214; margin-top: 18px; }
.ehs-idcard__sig { margin: 12px 16px; height: 22px; border-radius: 3px; background: repeating-linear-gradient(45deg, #efe7d8, #efe7d8 6px, #e2d8c4 6px, #e2d8c4 12px); display: flex; align-items: center; justify-content: flex-end; padding-right: 8px; color: var(--ehs-maroon-deep); font-family: var(--ehs-font-mono); font-size: 11px; font-weight: 700; }
.ehs-idcard__note { font-size: 8px; color: rgba(255,255,255,.5); margin: 0 16px; }

/* ---- Folder button (folder opens + pencil writes on hover) -------- */
.ehs-btn-folder {
  --left: var(--ehs-maroon-deep); --folder: var(--ehs-gold); --folder-in: var(--ehs-gold-deep);
  --paper: #fff; --paper-line: #cbb9be; --paper-back: #e7d9dd;
  position: relative; border: none; cursor: pointer; border-radius: var(--ehs-r-sm);
  padding: 15px 26px 15px 66px; font-family: var(--ehs-font-body); font-size: 14px; font-weight: 700;
  letter-spacing: .03em; color: #fff; background: var(--ehs-maroon); transition: background .3s; overflow: hidden;
}
.ehs-btn-folder:hover { background: var(--ehs-maroon-deep); }
.ehs-btn-folder > .fx { position: absolute; left: 0; top: 0; bottom: 0; width: 50px; border-radius: var(--ehs-r-sm) 0 0 var(--ehs-r-sm); background: var(--left); overflow: hidden; }
.ehs-btn-folder .folder { position: absolute; left: 14px; top: 13px; width: 22px; height: 26px; }
.ehs-btn-folder .folder .paper { position: absolute; left: 1px; top: 2px; width: 20px; height: 22px; border-radius: 1px; background: var(--paper); transform: translateY(0); transition: transform .4s ease .1s; }
.ehs-btn-folder .folder .paper::before, .ehs-btn-folder .folder .paper::after { content: ''; position: absolute; left: 3px; width: 12px; height: 2px; border-radius: 1px; background: var(--paper-line); box-shadow: 0 5px 0 var(--paper-line), 0 10px 0 var(--paper-line); top: 4px; }
.ehs-btn-folder .folder .front { position: absolute; inset: 0; background: var(--folder); border-radius: 1px 3px 3px 3px; transform-origin: 50% 100%; transition: transform .4s ease; z-index: 2; }
.ehs-btn-folder .folder .front::before { content: ''; position: absolute; top: -4px; left: 0; width: 10px; height: 5px; border-radius: 2px 2px 0 0; background: var(--folder); }
.ehs-btn-folder .pencil { position: absolute; right: -14px; top: 8px; width: 4px; height: 18px; border-radius: 2px 2px 0 0; background: linear-gradient(var(--ehs-gold) 60%, #fff 60%); transform: rotate(38deg); transition: right .4s ease .05s; z-index: 3; }
.ehs-btn-folder .pencil::after { content: ''; position: absolute; bottom: -4px; left: 0; border-left: 2px solid transparent; border-right: 2px solid transparent; border-top: 4px solid var(--ehs-maroon-deep); }
.ehs-btn-folder:hover .folder .front { transform: perspective(120px) rotateX(-58deg); }
.ehs-btn-folder:hover .folder .paper { transform: translateY(-6px); }
.ehs-btn-folder:hover .pencil { right: 8px; }

/* ---- Branded scrollbar --------------------------------------------
   Add .ehs-scroll to any scrollable element (or .ehs-scroll-page on
   <html> to brand the whole page).
   Note: the standard scrollbar-width/-color and the ::-webkit-scrollbar
   pseudo-elements are mutually exclusive in Chromium (if the standard
   props are set, Chromium ignores the webkit rules). So we give Firefox
   the standard thin colored bar, then RESET those props inside
   @supports selector(::-webkit-scrollbar) so the fuller webkit bar wins
   in Chromium/Safari. */
/* Firefox (and anything WITHOUT ::-webkit-scrollbar): thin colored bar.
   Scoped with `@supports not` so Chromium never enters standard-scrollbar
   mode — otherwise it ignores the webkit rules below. */
@supports not selector(::-webkit-scrollbar) {
  .ehs-scroll, .ehs-scroll-page { scrollbar-width: thin; scrollbar-color: var(--ehs-maroon) var(--ehs-sunken); }
  .ehs-scroll--gold { scrollbar-color: var(--ehs-gold-deep) var(--ehs-sunken); }
}

@supports selector(::-webkit-scrollbar) {
  .ehs-scroll::-webkit-scrollbar, .ehs-scroll-page::-webkit-scrollbar { width: 12px; height: 12px; }
  .ehs-scroll::-webkit-scrollbar-track, .ehs-scroll-page::-webkit-scrollbar-track { background: var(--ehs-sunken); border-radius: var(--ehs-r-pill); }
  .ehs-scroll::-webkit-scrollbar-thumb, .ehs-scroll-page::-webkit-scrollbar-thumb {
    background: var(--ehs-maroon); border-radius: var(--ehs-r-pill);
    border: 3px solid var(--ehs-sunken); background-clip: padding-box;
  }
  .ehs-scroll::-webkit-scrollbar-thumb:hover, .ehs-scroll-page::-webkit-scrollbar-thumb:hover { background: var(--ehs-maroon-deep); }
  .ehs-scroll::-webkit-scrollbar-corner, .ehs-scroll-page::-webkit-scrollbar-corner { background: var(--ehs-sunken); }
  .ehs-scroll--gold::-webkit-scrollbar-thumb { background: var(--ehs-gold-deep); }
  .ehs-scroll--gold::-webkit-scrollbar-thumb:hover { background: var(--ehs-gold); }
  .ehs-scroll--thin::-webkit-scrollbar { width: 8px; height: 8px; }
  .ehs-scroll--thin::-webkit-scrollbar-thumb { border-width: 2px; }
}

/* =====================================================================
   FINALSITE — mirrors the live public site (edgewoodhs.org).
   Deliberately SEPARATE from the official brand: deeper maroon (#500000),
   different gold (#ae9142), Barlow / Barlow Condensed / EB Garamond,
   flat sharp-cornered components. Everything is scoped under .fs so it
   never leaks into the --ehs-* system.
   ===================================================================== */
.fs {
  --fs-maroon: #500000; --fs-gold: #ae9142; --fs-cream: #fbf7e6;
  --fs-ink: #373737; --fs-ink-strong: #131313; --fs-rule: #cfcfcf; --fs-bg: #f8f8f8;
  --fs-body: 'Barlow', system-ui, sans-serif;
  --fs-cond: 'Barlow Condensed', 'Barlow', sans-serif;
  --fs-serif: 'EB Garamond', Georgia, serif;
  font-family: var(--fs-body); color: var(--fs-ink);
}
.fs h1, .fs h3 { font-family: var(--fs-cond); color: var(--fs-maroon); font-weight: 600; line-height: 1.15; }
.fs h1 { font-size: 40px; } .fs h3 { font-size: 28px; font-weight: 500; }
.fs h2, .fs h4, .fs h5 { font-family: var(--fs-serif); color: var(--fs-ink-strong); }
.fs h4 { font-size: 24px; font-weight: 500; } .fs h5 { font-size: 16px; color: var(--fs-maroon); }

/* Buttons — condensed, uppercase, 2px radius, sharp */
.fs-btn {
  display: inline-flex; align-items: center; gap: 8px; font-family: var(--fs-cond);
  font-size: 20px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px;
  padding: 11px 38px; border-radius: 2px; border: 1px solid transparent; cursor: pointer; text-decoration: none;
  transition: background .15s, color .15s, border-color .15s;
}
.fs-btn--solid { background: var(--fs-maroon); color: #fff; border-color: var(--fs-maroon); }
.fs-btn--solid:hover { background: #3a0000; }
.fs-btn--gold { background: var(--fs-gold); color: var(--fs-maroon); border-color: var(--fs-gold); }
.fs-btn--gold:hover { background: #977c34; }
.fs-btn--hollow { background: transparent; color: var(--fs-maroon); border-color: var(--fs-maroon); }
.fs-btn--hollow:hover { background: var(--fs-maroon); color: #fff; }
.fs-btn--hollow-gold { background: transparent; color: var(--fs-gold); border-color: var(--fs-gold); }
.fs-btn--hollow-gold:hover { background: var(--fs-gold); color: var(--fs-maroon); }
.fs-btn--expand { width: 100%; justify-content: center; }

/* Tags / badges (.fsTag) — sharp maroon outline */
.fs-tag { display: inline-block; background: transparent; border: 1px solid var(--fs-maroon); color: var(--fs-maroon);
  font-family: var(--fs-body); font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .04em; padding: 6px 8px; }

/* Styled link with leading icon */
.fs-link { display: inline-flex; align-items: center; gap: 8px; font-family: var(--fs-cond); font-size: 18px;
  font-weight: 600; text-transform: uppercase; letter-spacing: .06em; color: var(--fs-maroon); text-decoration: none; }
.fs-link:hover { color: var(--fs-gold); }

/* Cards — flat rectangles, no radius, no shadow */
.fs-card { padding: 22px 24px; border-radius: 0; }
.fs-card h4, .fs-card h3 { margin-bottom: 6px; }
.fs-card--light { background: var(--fs-bg); color: var(--fs-maroon); }
.fs-card--dark { background: var(--fs-ink-strong); color: #fff; }
.fs-card--dark h3, .fs-card--dark h4 { color: #fff; }
.fs-card--primary { background: var(--fs-maroon); color: #fff; }
.fs-card--primary h3, .fs-card--primary h4 { color: #fff; }
.fs-card--secondary { background: var(--fs-gold); color: var(--fs-maroon); }
.fs-card--secondary h3, .fs-card--secondary h4 { color: var(--fs-maroon); }
.fs-card--yellow { background: var(--fs-cream); color: var(--fs-maroon); }
.fs-card--border { border: 1px solid var(--fs-rule); }

/* Table — maroon header, flat */
.fs-table { width: 100%; border-collapse: collapse; font-family: var(--fs-body); font-size: 16px; }
.fs-table th { background: var(--fs-maroon); color: #fff; font-weight: 500; text-align: left; padding: 16px 20px; }
.fs-table td { background: #fff; color: var(--fs-ink); padding: 13px 20px; border-bottom: 1px solid var(--fs-rule); }

/* Blockquote + callout (EB Garamond) */
.fs-quote { font-family: var(--fs-serif); font-size: 18px; color: var(--fs-ink-strong); }
.fs-callout { font-family: var(--fs-serif); font-size: 18px; color: var(--fs-ink-strong);
  padding: 12px 18px; box-shadow: inset 4px 0 0 0 var(--fs-gold); background: var(--fs-bg); }

/* =====================================================================
   DASHBOARD & DATA-VIZ (adapted from the personal kit, brand-native).
   ===================================================================== */

/* ---- Sparkline (inline SVG; maroon line, gold end dot) ------------ */
/* The line/area stretch to fill width (preserveAspectRatio: none). The end
   datapoint is a separate HTML dot so it stays a perfect circle instead of
   being squashed into an ellipse by the non-uniform SVG scale. Position it
   with left = x/viewBoxW %, top = y/viewBoxH %. */
.ehs-sparkline-wrap { position: relative; }
.ehs-sparkline { display: block; width: 100%; height: 100%; overflow: visible; }
.ehs-sparkline .line { fill: none; stroke: var(--ehs-maroon); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.ehs-sparkline .area { fill: color-mix(in srgb, var(--ehs-maroon) 12%, transparent); stroke: none; }
.ehs-sparkline__dot { position: absolute; width: 9px; height: 9px; border-radius: 50%; background: var(--ehs-gold-deep); transform: translate(-50%, -50%); box-shadow: 0 0 0 2px var(--ehs-paper); }

/* ---- CSS-only bar chart ------------------------------------------- */
.ehs-bars { display: flex; align-items: flex-end; gap: 10px; height: 140px; padding-top: 8px; border-bottom: 1px solid var(--ehs-rule); }
.ehs-bars__col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.ehs-bars__bar { width: 100%; max-width: 34px; background: linear-gradient(var(--ehs-maroon), var(--ehs-maroon-deep)); border-radius: var(--ehs-r-sm) var(--ehs-r-sm) 0 0; transition: filter .15s; }
.ehs-bars__col:hover .ehs-bars__bar { filter: brightness(1.12); }
.ehs-bars__bar--gold { background: linear-gradient(var(--ehs-gold), var(--ehs-gold-deep)); }
.ehs-bars__label { font-size: 11px; color: var(--ehs-muted); font-weight: 600; }

/* ---- Pomodoro / focus timer --------------------------------------- */
.ehs-timer { display: inline-flex; flex-direction: column; align-items: center; gap: 12px; }
.ehs-timer__ring { position: relative; width: 150px; height: 150px; }
.ehs-timer__ring svg { transform: rotate(-90deg); }
.ehs-timer__track { fill: none; stroke: var(--ehs-rule); stroke-width: 9; }
.ehs-timer__prog  { fill: none; stroke: var(--ehs-maroon); stroke-width: 9; stroke-linecap: round; transition: stroke-dashoffset .5s linear; }
.ehs-timer.is-break .ehs-timer__prog { stroke: var(--ehs-ok); }
.ehs-timer__time { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.ehs-timer__num { font-family: var(--ehs-font-mono); font-size: 34px; font-weight: 700; color: var(--ehs-ink); }
.ehs-timer__phase { font-size: 11px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ehs-muted); }
.ehs-timer__dots { display: flex; gap: 6px; }
.ehs-timer__dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--ehs-rule-strong); }
.ehs-timer__dots i.on { background: var(--ehs-maroon); }

/* ---- Leaderboard -------------------------------------------------- */
.ehs-leaderboard { border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-lb__row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; }
.ehs-lb__row + .ehs-lb__row { border-top: 1px solid var(--ehs-rule); }
.ehs-lb__rank { width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 13px; background: var(--ehs-sunken); color: var(--ehs-muted); flex: none; }
.ehs-lb__row--1 .ehs-lb__rank { background: var(--ehs-gold); color: var(--ehs-maroon-deep); }
.ehs-lb__row--2 .ehs-lb__rank { background: #cfc7bb; color: var(--ehs-black); } /* pinned chip needs pinned text */
.ehs-lb__row--3 .ehs-lb__rank { background: #d8b892; color: var(--ehs-maroon-deep); }
.ehs-lb__name { font-weight: 600; flex: 1; }
.ehs-lb__val { font-family: var(--ehs-font-mono); font-weight: 700; color: var(--ehs-accent-text); }

/* ---- Player bar --------------------------------------------------- */
/* --ehs-black, not --ehs-ink: ink is the TEXT token and flips to cream on dark, which
   left white text on a cream bar (1.1:1). The player bar is dark chrome in BOTH themes
   by design, like every media player, so it wants the neutral that does not flip. */
.ehs-playerbar { display: flex; align-items: center; gap: 14px; background: var(--ehs-black); color: #fff; padding: 10px 16px; border-radius: var(--ehs-r-md); }
.ehs-playerbar__art { width: 44px; height: 44px; border-radius: var(--ehs-r-sm); background: linear-gradient(135deg, var(--ehs-maroon), var(--ehs-gold-deep)); flex: none; }
.ehs-playerbar__meta { min-width: 0; }
.ehs-playerbar__title { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ehs-playerbar__sub { font-size: 12px; color: rgba(255,255,255,.6); }
.ehs-playerbar__controls { display: flex; align-items: center; gap: 6px; }
.ehs-playerbar__btn { width: 34px; height: 34px; border-radius: 50%; border: none; background: rgba(255,255,255,.1); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.ehs-playerbar__btn:hover { background: rgba(255,255,255,.2); }
.ehs-playerbar__btn--play { background: var(--ehs-gold); color: var(--ehs-maroon-deep); }
.ehs-playerbar__prog { flex: 1; display: flex; align-items: center; gap: 8px; }
.ehs-playerbar__time { font-family: var(--ehs-font-mono); font-size: 11px; color: rgba(255,255,255,.6); }
.ehs-playerbar__track { flex: 1; height: 4px; border-radius: var(--ehs-r-pill); background: rgba(255,255,255,.18); overflow: hidden; }
.ehs-playerbar__fill { height: 100%; background: var(--ehs-gold); }

/* ---- Glass stat block (signage / TV) ------------------------------ */
.ehs-glass-stage { display: flex; gap: 16px; flex-wrap: wrap; padding: 26px; border-radius: var(--ehs-r-md);
  background: radial-gradient(120% 140% at 20% 0%, var(--ehs-maroon), var(--ehs-maroon-deep) 70%, #2b0a15); }
.ehs-glass-stat { flex: 1; min-width: 150px; padding: 20px 22px; border-radius: var(--ehs-r-md);
  background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16); backdrop-filter: blur(8px); color: #fff; }
.ehs-glass-stat__value { font-family: var(--ehs-font-display); font-size: 40px; font-weight: 800; line-height: 1; }
.ehs-glass-stat__label { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.72); margin-top: 8px; }
.ehs-glass-stat__value .u { color: var(--ehs-gold); }

/* =====================================================================
   EDITORIAL / LANDING (adapted from the personal kit, brand-native).
   ===================================================================== */

/* ---- HUD corner brackets ------------------------------------------ */
.ehs-hud { position: relative; padding: 26px 28px; }
.ehs-hud::before, .ehs-hud::after,
.ehs-hud > .ehs-hud__c::before, .ehs-hud > .ehs-hud__c::after {
  content: ''; position: absolute; width: 18px; height: 18px; border: 2px solid var(--ehs-gold-deep);
}
.ehs-hud::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.ehs-hud::after  { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.ehs-hud > .ehs-hud__c::before { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.ehs-hud > .ehs-hud__c::after  { bottom: 0; right: 0; border-left: 0; border-top: 0; }

/* ---- Status lamp (pulsing) ---------------------------------------- */
.ehs-lamp { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ehs-muted); }
.ehs-lamp::before { content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--ehs-ok); box-shadow: 0 0 0 0 color-mix(in srgb, var(--ehs-ok) 60%, transparent); animation: ehs-lamp 1.8s infinite; }
.ehs-lamp--warn::before { background: var(--ehs-warn); box-shadow: 0 0 0 0 color-mix(in srgb, var(--ehs-warn) 60%, transparent); }
.ehs-lamp--bad::before  { background: var(--ehs-bad);  box-shadow: 0 0 0 0 color-mix(in srgb, var(--ehs-bad) 60%, transparent); }
@keyframes ehs-lamp { 0%{ box-shadow: 0 0 0 0 currentColor; } 70%{ box-shadow: 0 0 0 7px transparent; } 100%{ box-shadow: 0 0 0 0 transparent; } }

/* ---- Wave divider -------------------------------------------------- */
.ehs-wave { display: block; width: 100%; height: 36px; }
.ehs-wave path { fill: none; stroke: var(--ehs-gold-deep); stroke-width: 2; }

/* ---- Readout terminal panel --------------------------------------- */
.ehs-readout { position: relative; background: var(--ehs-code-bg); color: var(--ehs-gold); font-family: var(--ehs-font-mono); font-size: 13px; line-height: 1.7; padding: 16px 18px; border-radius: var(--ehs-r-md); border: 1px solid rgba(208,183,134,.2); overflow: hidden; }
.ehs-readout::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: repeating-linear-gradient(transparent 0 3px, rgba(255,255,255,.03) 3px 4px); }
.ehs-readout b { color: #fff; }

/* ---- Ghost numeral ------------------------------------------------ */
.ehs-ghost { position: relative; padding: 18px 22px; overflow: hidden; }
.ehs-ghost__n { position: absolute; right: 6px; top: -18px; font-family: var(--ehs-font-display); font-weight: 800; font-size: 120px; line-height: 1; color: var(--ehs-accent-text); opacity: .07; pointer-events: none; }
.ehs-ghost > * { position: relative; }

/* ---- Tag + tick micro-label --------------------------------------- */
.ehs-tick { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--ehs-gold-deep); }
.ehs-tick::before { content: ''; width: 14px; height: 14px; border-radius: 3px; background: var(--ehs-gold); flex: none;
  -webkit-mask: no-repeat center/10px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12 9 17 20 6'/%3E%3C/svg%3E");
          mask: no-repeat center/10px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12 9 17 20 6'/%3E%3C/svg%3E"); }

/* Branded scrollbar on scrollable dropdowns (search suggestions, menus). */
@supports not selector(::-webkit-scrollbar) {
  .ehs-suggest, .ehs-menu, .ehs-cmdk__list { scrollbar-width: thin; scrollbar-color: var(--ehs-maroon) var(--ehs-sunken); }
}
@supports selector(::-webkit-scrollbar) {
  .ehs-suggest::-webkit-scrollbar, .ehs-menu::-webkit-scrollbar, .ehs-cmdk__list::-webkit-scrollbar { width: 10px; }
  .ehs-suggest::-webkit-scrollbar-track, .ehs-menu::-webkit-scrollbar-track, .ehs-cmdk__list::-webkit-scrollbar-track { background: transparent; }
  .ehs-suggest::-webkit-scrollbar-thumb, .ehs-menu::-webkit-scrollbar-thumb, .ehs-cmdk__list::-webkit-scrollbar-thumb {
    background: var(--ehs-maroon); border-radius: var(--ehs-r-pill); border: 3px solid var(--ehs-paper); background-clip: padding-box;
  }
  .ehs-suggest::-webkit-scrollbar-thumb:hover, .ehs-menu::-webkit-scrollbar-thumb:hover, .ehs-cmdk__list::-webkit-scrollbar-thumb:hover { background: var(--ehs-maroon-deep); }
}

/* =====================================================================
   APP SHELL / CHAT (adapted from the personal kit, brand-native).
   ===================================================================== */

/* ---- Chat bubbles ------------------------------------------------- */
.ehs-chat { display: flex; flex-direction: column; gap: 8px; }
.ehs-bubble { max-width: 76%; padding: 9px 13px; border-radius: 14px; font-size: 14px; line-height: 1.42; }
.ehs-bubble--in  { align-self: flex-start; background: var(--ehs-sunken); color: var(--ehs-ink); border-bottom-left-radius: 4px; }
.ehs-bubble--out { align-self: flex-end; background: var(--ehs-maroon); color: #fff; border-bottom-right-radius: 4px; }
.ehs-bubble__time { display: block; font-size: 10px; opacity: .6; margin-top: 3px; text-align: right; }

/* ---- Task rows ---------------------------------------------------- */
.ehs-tasks { border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); }
.ehs-task { display: flex; align-items: center; gap: 11px; padding: 11px 14px; }
.ehs-task + .ehs-task { border-top: 1px solid var(--ehs-rule); }
.ehs-task__title { flex: 1; font-size: 14px; }
.ehs-task__meta { font-size: 12px; color: var(--ehs-muted); }
.ehs-task--done .ehs-task__title { text-decoration: line-through; color: var(--ehs-muted); }

/* =====================================================================
   TEAM & CAMPAIGNS (adapted from the personal kit, brand-native).
   ===================================================================== */

/* ---- Announcement ticker (marquee) -------------------------------- */
.ehs-ticker { overflow: hidden; background: var(--ehs-maroon); color: #fff; border-radius: var(--ehs-r-sm); padding: 9px 0; white-space: nowrap; }
.ehs-ticker__track { display: inline-flex; gap: 48px; padding-left: 48px; will-change: transform; animation: ehs-marquee 22s linear infinite; }
.ehs-ticker:hover .ehs-ticker__track { animation-play-state: paused; }
.ehs-ticker__item { display: inline-flex; align-items: center; gap: 10px; font-weight: 600; font-size: 14px; }
.ehs-ticker__item::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: var(--ehs-gold); flex: none; }
@keyframes ehs-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .ehs-ticker__track { animation: none; } }

/* ---- Live badge --------------------------------------------------- */
.ehs-live { display: inline-flex; align-items: center; gap: 6px; background: var(--ehs-bad); color: #fff; font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; padding: 3px 9px 3px 8px; border-radius: var(--ehs-r-pill); }
.ehs-live::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: #fff; animation: ehs-lamp 1.4s infinite; }

/* ---- Roster / player card ----------------------------------------- */
.ehs-roster { width: 180px; border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); overflow: hidden; background: var(--ehs-paper); text-align: center; transition: transform .15s, box-shadow .15s; }
.ehs-roster:hover { transform: translateY(-2px); box-shadow: var(--ehs-shadow-md); }
.ehs-roster__photo { position: relative; height: 150px; background: linear-gradient(160deg, var(--ehs-maroon), var(--ehs-maroon-deep)); display: flex; align-items: flex-end; justify-content: center; overflow: hidden; }
.ehs-roster__num { position: absolute; top: 6px; right: 12px; font-family: var(--ehs-font-display); font-size: 40px; font-weight: 800; color: rgba(255,255,255,.16); line-height: 1; }
.ehs-roster__photo img { height: 138px; width: auto; object-fit: contain; }
.ehs-roster__body { padding: 12px 12px 14px; }
.ehs-roster__name { font-family: var(--ehs-font-display); font-weight: 700; font-size: 17px; }
.ehs-roster__role { font-size: 11px; color: var(--ehs-muted); text-transform: uppercase; letter-spacing: .08em; margin-top: 2px; }

/* ---- Fundraiser / goal banner ------------------------------------- */
.ehs-fundraiser { border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); padding: 18px 20px; background: var(--ehs-paper); }
.ehs-fundraiser__head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 10px; }
.ehs-fundraiser__goal { font-family: var(--ehs-font-display); font-size: 20px; font-weight: 800; }
.ehs-fundraiser__pct { color: var(--ehs-accent-text); font-weight: 700; font-family: var(--ehs-font-mono); }
.ehs-fundraiser__bar { height: 12px; background: var(--ehs-sunken); border-radius: var(--ehs-r-pill); overflow: hidden; }
.ehs-fundraiser__fill { height: 100%; background: linear-gradient(90deg, var(--ehs-maroon), var(--ehs-gold-deep)); border-radius: inherit; }
.ehs-fundraiser__meta { display: flex; justify-content: space-between; font-size: 13px; color: var(--ehs-muted); margin-top: 8px; }
.ehs-fundraiser__meta b { color: var(--ehs-ink); }

/* ---- Calendar hover-expand overlay (ported from the scheduler) -----
   Cells that overflow show a fixed-position card on hover. CSS toggles
   visibility; JS positions it (measure off-screen, clamp to viewport,
   flip left past the right edge / up past the bottom). Cell must go
   overflow:visible so the card isn't clipped. */
.ehs-calendar__cell.has-expand { overflow: visible; }
.ehs-cal-more { display: block; width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  color: var(--ehs-accent-text); font-weight: 700; font-size: 11px; padding: 1px 4px; margin-top: 2px; }
.ehs-cal-expand {
  display: none; position: fixed; top: 0; left: 0; z-index: 200; width: 280px;
  background: var(--ehs-paper); border: 1px solid var(--ehs-maroon); border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-lg); padding: 8px 10px; pointer-events: none;
}
.ehs-calendar__cell.has-expand:hover .ehs-cal-expand { display: block; pointer-events: auto; }
.ehs-cal-expand__head { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ehs-accent-text); margin-bottom: 6px; padding-bottom: 6px; border-bottom: 1px solid var(--ehs-rule); }
.ehs-cal-expand .ehs-calendar__event { display: block; margin-bottom: 3px; white-space: normal; }

/* =====================================================================
   UNIVERSAL APP HEADER + FOOTER (drop into any Edgewood app).
   Header: modern wordmark (links home) · service name · actions
   (theme switch + user/login widget). Footer: school line + links.
   ===================================================================== */
/* The chrome mounts the appbar INSIDE the #ehs-chrome-header wrapper div. A sticky
   element only travels within its parent, and an unstyled wrapper is exactly appbar-
   height — zero travel — so `position: sticky` below silently never stuck anywhere.
   display:contents makes the wrapper layout-transparent, so the appbar's sticky
   containing block becomes the page and the declared behavior (and every element
   authored against --ehs-appbar-h: .ehs-subnav, .ehs-sidebar, app doc-headers)
   finally works. Operator-approved 2026-07-19; pure addition, the id had no rules. */
#ehs-chrome-header { display: contents; }
.ehs-appbar {
  display: flex; align-items: center; gap: 14px;
  background: var(--ehs-paper); border-bottom: 3px solid var(--ehs-gold);
  padding: 8px var(--ehs-gutter); position: sticky; top: 0; z-index: 50;
}
.ehs-appbar__brand { display: inline-flex; align-items: center; flex: none; text-decoration: none; border-radius: 5px; }
.ehs-appbar__brand:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: 2px; }
/* wordmark sits on a white chip so the black-on-white modern wordmark reads on any (incl. dark) bar */
.ehs-appbar__wordmark { height: 36px; width: auto; display: block; background: #fff; border-radius: 5px; padding: 3px 7px; }
.ehs-appbar__divider { width: 1px; height: 28px; background: var(--ehs-rule-strong); flex: none; }
.ehs-appbar__service { font-family: var(--ehs-font-display); font-weight: 800; font-size: 18px; letter-spacing: -0.01em; color: var(--ehs-accent-text); white-space: nowrap; }
/* Gold in dark mode — maroon text goes dim on the dark bar. */
:root[data-theme="dark"] .ehs-appbar__service { color: var(--ehs-gold); }
@media (prefers-color-scheme: dark) { :root[data-theme="dark"] .ehs-appbar__service { color: var(--ehs-gold); } }
.ehs-appbar__spacer { flex: 1 1 auto; }
/* Center nav slot in the appbar — app sections/links/controls (search, palette, help). */
.ehs-appbar__nav { display: flex; align-items: center; gap: 2px; margin-left: 10px; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.ehs-appbar__nav::-webkit-scrollbar { display: none; }
.ehs-appbar__navlink { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: var(--ehs-r-sm); color: var(--ehs-muted); font-family: var(--ehs-font-body); font-size: 14px; font-weight: 600; text-decoration: none; background: none; border: none; cursor: pointer; white-space: nowrap; }
.ehs-appbar__navlink:hover { background: var(--ehs-cream); color: var(--ehs-ink); }
.ehs-appbar__navlink--active { color: var(--ehs-maroon); background: var(--ehs-gold-pale); }
:root[data-theme="dark"] .ehs-appbar__navlink--active { color: var(--ehs-gold); }
@media (prefers-color-scheme: dark) { :root[data-theme="dark"] .ehs-appbar__navlink--active { color: var(--ehs-gold); } }
.ehs-appbar__actions { display: flex; align-items: center; gap: 12px; flex: none; }

/* User / login widget */
.ehs-usermenu { position: relative; }
.ehs-usermenu__btn { display: inline-flex; align-items: center; gap: 8px; background: none; border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-pill); padding: 3px 12px 3px 3px; cursor: pointer; font-family: var(--ehs-font-body); color: var(--ehs-ink); }
.ehs-usermenu__btn:hover { border-color: var(--ehs-rule-strong); background: var(--ehs-cream); }
.ehs-usermenu__name { font-size: 13px; font-weight: 600; }
.ehs-usermenu__caret { color: var(--ehs-muted); display: inline-flex; }
.ehs-usermenu__pop { position: absolute; right: 0; top: calc(100% + 8px); min-width: 200px; background: var(--ehs-paper); border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md); box-shadow: var(--ehs-shadow-lg); padding: 6px; display: none; z-index: 60; }
.ehs-usermenu.open .ehs-usermenu__pop { display: block; }
.ehs-usermenu__head { padding: 8px 10px 10px; border-bottom: 1px solid var(--ehs-rule); margin-bottom: 4px; }
.ehs-usermenu__who { font-weight: 700; font-size: 14px; }
.ehs-usermenu__email { font-size: 12px; color: var(--ehs-muted); }

/* Footer */
.ehs-appfooter { position: relative; z-index: 20; /* above decorative fixed layers (.ehs-polaroid-wing z1) */
  border-top: 1px solid var(--ehs-rule); background: var(--ehs-paper); padding: 16px var(--ehs-gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13px; color: var(--ehs-muted); }
.ehs-appfooter a { color: var(--ehs-accent-text); font-weight: 600; text-decoration: none; }
.ehs-appfooter a:hover { text-decoration: underline; }
.ehs-appfooter__brand { display: flex; align-items: center; gap: 8px; }
.ehs-appfooter a.ehs-appfooter__school { font-family: var(--ehs-font-display); font-weight: 700; color: var(--ehs-ink); text-decoration: none; }
.ehs-appfooter a.ehs-appfooter__school:hover { text-decoration: underline; }
.ehs-appfooter__sep { color: var(--ehs-rule-strong); }
@media (max-width: 640px) { .ehs-appbar__service { font-size: 15px; } .ehs-appbar__wordmark { height: 30px; } .ehs-appbar__divider { display: none; } }

/* =====================================================================
   NARROW APPBAR COLLAPSE (added 2026-07-18) — mobile responsive breakpoint.
   ---------------------------------------------------------------------
   PROBLEM: the appbar is a single non-wrapping flex row whose fixed segments
   (brand ~121 + service ~93 + actions ~213 = ~508px min, nav collapsed to 0)
   never fit a phone, so EVERY app scrolled horizontally below ~508px and the
   nav links + user menu became unreachable (trapped in the 0-width nav
   scroller / pushed off-screen).
   FIX: below 640px (same threshold the rule above already uses to shrink the
   wordmark/service and hide the divider) let the row WRAP. Natural DOM order is
   preserved, so nothing reorders: brand + service stay on row 1; the center nav
   slot, the spacer, and the actions (theme toggle + user menu) flow onto row 2,
   where the nav scrolls within its remaining width and the spacer keeps the
   actions pinned right. Above 640px NONE of this applies — desktop is untouched
   (verified pixel-identical at 1440). Sticky behavior + dark mode are inherited
   unchanged. This block is PURELY ADDITIVE; it edits no existing selector.
   The width-contract note (~L107) flags --ehs-appbar-h as load-bearing (sticky
   subnav/sidebar offsets + the mobile drawer top reference it), so it is bumped
   here to the real 2-row height measured at ≤640px.
   ===================================================================== */
/* The service label + center nav are wrapped by brand-chrome.js in
   .ehs-appbar__center. display:contents makes that wrapper INVISIBLE to layout
   here, so on desktop the service + nav lay out as direct appbar flex children
   exactly as before (pixel-identical). Below the breakpoint the media block
   turns it into a real flex box that forms the appbar's second row. */
.ehs-appbar__center { display: contents; }
@media (max-width: 640px) {
  :root { --ehs-appbar-h: 96px; }                 /* real 2-row appbar height at ≤640 (measured) */
  /* Row 1 stays brand (left) + spacer + actions (theme toggle + user menu, right).
     Row 2 is the .ehs-appbar__center box, forced full-width so it always wraps. */
  .ehs-appbar { flex-wrap: wrap; row-gap: 8px; column-gap: 8px; }  /* tighter gaps so row 1 (brand+actions) stays one line down to 320 */
  .ehs-appbar__actions { gap: 8px; }
  .ehs-appbar__center {
    display: flex; align-items: center; gap: 10px;
    order: 1; flex-basis: 100%; min-width: 0;      /* becomes the full-width 2nd row */
  }
  /* Long multi-word service names truncate with an ellipsis instead of forcing
     horizontal scroll (nowrap is already set on .ehs-appbar__service above). */
  .ehs-appbar__service { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  /* Nav takes the rest of row 2 and scrolls within it (overflow-x already set);
     drop the desktop 10px inset since the center box owns the row's left edge. */
  .ehs-appbar__nav { margin-left: 0; flex: 1 1 auto; min-width: 0; }
  /* Compact the user chip to avatar + caret so the actions fit a phone; the full
     name still shows inside the open menu (.ehs-usermenu__who). */
  .ehs-usermenu__name { display: none; }
}

/* =====================================================================
   CONTENT COLUMN (unified-shell Phase 0) — the shared page column every
   app wraps its body in. Full desktop width by default (capped at the one
   global --ehs-page-max), gutter matches the appbar so left edges line up.
   Narrow is opt-in via a modifier — forms/prose use --reading regardless
   of the app (decision 3: one global cap, no per-app override).
   ===================================================================== */
.ehs-content {
  width: 100%;
  max-width: var(--ehs-page-max);
  margin-inline: auto;
  padding-inline: var(--ehs-gutter);
  box-sizing: border-box;
}
.ehs-content--reading { max-width: var(--ehs-measure-reading); }
.ehs-content--wide    { max-width: var(--ehs-measure-wide); }
.ehs-content--full    { max-width: none; }
/* Flush variant: column width/cap without the gutter (for apps that already
   pad their own body or need edge-to-edge panels inside the column). */
.ehs-content--flush   { padding-inline: 0; }

/* =====================================================================
   PAGE HEADER (unified-shell Phase 3) — the one standard back/eyebrow/
   title/subtitle/actions row. Shared here so every app renders the same
   markup and stops hand-rolling its own header (BEM: __back/__breadcrumb/
   __row/__text/__eyebrow/__title/__subtitle/__actions).
   ===================================================================== */
.ehs-page-header { margin-bottom: 28px; }
.ehs-page-header__back {
  display: inline-block; font-size: 13px;
  color: var(--ehs-muted); text-decoration: none; margin-bottom: 6px;
  font-family: var(--ehs-font-body);
}
.ehs-page-header__back:hover { color: var(--ehs-accent-text); }
.ehs-page-header__breadcrumb {
  display: flex; gap: 8px; align-items: center; font-size: 12px; color: var(--ehs-muted);
  font-family: var(--ehs-font-mono); letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 8px;
}
.ehs-page-header__breadcrumb a { color: var(--ehs-muted); text-decoration: none; }
.ehs-page-header__breadcrumb a:hover { color: var(--ehs-accent-text); }
.ehs-page-header__breadcrumb .sep { color: var(--ehs-rule-strong); }
.ehs-page-header__row {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 16px;
}
.ehs-page-header__text { min-width: 0; }
.ehs-page-header__title { margin: 0; }
.ehs-page-header__eyebrow {
  font-family: var(--ehs-font-mono); font-size: 11px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--ehs-accent-text);
  margin-bottom: 6px;
}
.ehs-page-header__subtitle {
  margin-top: 8px; color: var(--ehs-muted); font-size: 14px;
  font-family: var(--ehs-font-mono); letter-spacing: 0.04em;
}
.ehs-page-header__actions { display: flex; gap: 10px; align-items: center; flex-shrink: 0; }
@media (max-width: 640px) {
  .ehs-page-header__row { flex-direction: column; align-items: flex-start; }
}

/* =====================================================================
   SUBNAV (unified-shell Phase 4) — Tier-2 within-section tabs / view
   toggles / filters. Sticky just under the appbar; scrolls horizontally on
   overflow rather than wrapping. z below the appbar (50) and menus (60).
   ===================================================================== */
.ehs-subnav {
  position: sticky; top: var(--ehs-appbar-h); z-index: 40;
  display: flex; align-items: center; gap: 4px;
  min-height: var(--ehs-subnav-h);
  padding: 0 var(--ehs-gutter);
  background: var(--ehs-paper); border-bottom: 1px solid var(--ehs-rule);
  overflow-x: auto; scrollbar-width: thin;
}
.ehs-subnav__link {
  display: inline-flex; align-items: center; white-space: nowrap;
  padding: 12px 12px 10px; border-bottom: 2px solid transparent;
  font-family: var(--ehs-font-body); font-size: 14px; color: var(--ehs-muted);
  text-decoration: none; cursor: pointer; background: none; border-top: 0; border-left: 0; border-right: 0;
}
.ehs-subnav__link:hover { color: var(--ehs-ink); }
.ehs-subnav__link--active { color: var(--ehs-accent-text); border-bottom-color: var(--ehs-maroon); font-weight: 600; }
.ehs-subnav__actions { margin-left: auto; display: flex; align-items: center; gap: 8px; flex: none; }

/* =====================================================================
   DETAIL (unified-shell Phase 5) — master-detail side panel. Inline on
   desktop; apps make it an overlay drawer under 1024 (reusing the modal tier).
   ===================================================================== */
.ehs-detail {
  flex: none; width: var(--ehs-detail-w); min-width: 0;
  border-left: 1px solid var(--ehs-rule); background: var(--ehs-paper);
  overflow-y: auto;
}

/* Density-compact — tighter cell padding for dense data-admin tables. */
.ehs-density-compact.ehs-table th,
.ehs-density-compact.ehs-table td,
.ehs-density-compact .ehs-table th,
.ehs-density-compact .ehs-table td { padding-top: 6px; padding-bottom: 6px; }

/* =====================================================================
   SHELL + SIDEBAR (unified-shell Phase 0b) — deep/workspace apps (many
   sections) move their Tier-1 nav into a left rail instead of the top
   center-nav. Reuses the app's existing full-height flex model: the shell
   is a flex row (sidebar + main), both full height. On mobile the rail
   becomes an off-canvas drawer toggled by an app-set `.ehs-shell-open`
   class (+ a `.ehs-drawer-backdrop` scrim). Framework-agnostic: any app
   (React/Astro/vanilla) renders this markup with these classes.
   ===================================================================== */
.ehs-shell { display: flex; align-items: stretch; min-height: 0; height: 100%; }
/* Fill mode (unified-shell Phase 6): the ONE sanctioned full-height mode.
   The shell owns the viewport below the appbar; .ehs-main is the scroller —
   apps must stop mutating <body> to 100vh (that fights the shell). */
.ehs-shell--fill { height: calc(100dvh - var(--ehs-appbar-h)); }
.ehs-shell--fill .ehs-main { overflow: auto; }
.ehs-sidebar {
  flex: none; width: var(--ehs-sidebar-w);
  background: var(--ehs-paper); border-right: 1px solid var(--ehs-rule);
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 10px;
}
.ehs-sidebar__group { display: flex; flex-direction: column; gap: 1px; margin-bottom: 10px; }
.ehs-sidebar__group-label {
  font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--ehs-muted); padding: 8px 10px 4px;
}
.ehs-sidebar__link {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 11px; border-radius: var(--ehs-r-sm);
  color: var(--ehs-ink); text-decoration: none;
  font-family: var(--ehs-font-body); font-size: 14px; font-weight: 600;
  background: none; border: none; cursor: pointer; text-align: left; width: 100%;
}
.ehs-sidebar__link:hover { background: var(--ehs-cream); }
.ehs-sidebar__link--active { background: var(--ehs-gold-pale); color: var(--ehs-maroon); }
:root[data-theme="dark"] .ehs-sidebar__link--active { color: var(--ehs-gold); }
@media (prefers-color-scheme: dark) { :root[data-theme="dark"] .ehs-sidebar__link--active { color: var(--ehs-gold); } }
.ehs-main { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; }

/* Mobile-only menu bar (holds the drawer toggle under the appbar) + toggle button. */
.ehs-navbar-mobile { display: none; }
.ehs-nav-toggle {
  display: inline-flex; align-items: center; gap: 8px;
  background: none; border: none; cursor: pointer;
  font-family: var(--ehs-font-body); font-size: 14px; font-weight: 700; color: var(--ehs-ink);
  padding: 10px 14px;
}
.ehs-drawer-backdrop { display: none; }

/* Rail → off-canvas drawer below the rail↔drawer breakpoint (900). */
@media (max-width: 900px) {
  .ehs-navbar-mobile {
    display: flex; align-items: center; gap: 10px;
    border-bottom: 1px solid var(--ehs-rule); background: var(--ehs-paper);
    /* top was 0, which tucked this bar UNDER the (now genuinely sticky, z-50) appbar on
       scroll. Stick beneath it instead. --ehs-appbar-h is kept pixel-true at runtime by
       brand-chrome.js (it measures the mounted bar), so this tracks the real height at
       every width, including the 2-row ≤640 collapse. Operator-approved 2026-07-19. */
    position: sticky; top: var(--ehs-appbar-h); z-index: 40;
  }
  /* …but sticky offsets are measured from the SCROLLPORT, not the viewport, and
     in fill mode the scrollport is .ehs-main — which already begins below the
     appbar. The offset above then double-counts and parks the bar an appbar's
     height down, showing a strip of content above it. Measured on the kit at
     420px (2026-07-25): bar at y=168 in a scrollport starting at y=84.
     Affects any .ehs-shell--fill app with the mobile bar (charliework today). */
  .ehs-shell--fill .ehs-navbar-mobile { top: 0; }
  .ehs-sidebar {
    position: fixed; top: var(--ehs-appbar-h); left: 0; bottom: 0;
    width: min(82vw, var(--ehs-sidebar-w)); z-index: 200;
    transform: translateX(-100%); transition: transform .2s ease;
    box-shadow: var(--ehs-shadow-lg);
  }
  .ehs-shell-open .ehs-sidebar { transform: translateX(0); }
  .ehs-drawer-backdrop {
    position: fixed; inset: 0; z-index: 190;
    background: color-mix(in srgb, var(--ehs-ink) 45%, transparent);
  }
  .ehs-shell-open .ehs-drawer-backdrop { display: block; }
}
@media (prefers-reduced-motion: reduce) { .ehs-sidebar { transition: none; } }

/* Flip program card (Card Hover 2 applied to content cards) --------- */
.ehs-flipcard { perspective: 1200px; }
.ehs-flipcard__inner { position: relative; transition: transform .7s cubic-bezier(.4,.2,.2,1); transform-style: preserve-3d; }
.ehs-flipcard:hover .ehs-flipcard__inner, .ehs-flipcard.flipped .ehs-flipcard__inner { transform: rotateY(180deg); }
.ehs-flipcard__front, .ehs-flipcard__back { backface-visibility: hidden; -webkit-backface-visibility: hidden; }
.ehs-flipcard__back { position: absolute; inset: 0; transform: rotateY(180deg); }

/* =====================================================================
   MODAL / DIALOG — centered, scrimmed dialog with header/body/footer.
   Markup:
     <div class="ehs-modal-backdrop">
       <div class="ehs-modal" role="dialog" aria-modal="true">
         <header class="ehs-modal__header">
           <h2 class="ehs-modal__title">Title</h2>
           <button class="ehs-modal__close" aria-label="Close">…</button>
         </header>
         <div class="ehs-modal__body"> … </div>
         <footer class="ehs-modal__foot"> …buttons… </footer>
       </div>
     </div>
   Sizes: --sm (460) · --narrow (560) · default (860). Header/footer optional.
   ===================================================================== */
.ehs-modal-backdrop {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: color-mix(in srgb, var(--ehs-ink) 50%, transparent);
  animation: ehs-backdrop-in .15s ease;
}
/* Toggling the `hidden` attribute on the backdrop is a supported way to show and
   hide a modal — the global [hidden] rule in the base block makes it stick even
   though `display:flex` above would otherwise win. */
:root[data-theme="dark"] .ehs-modal-backdrop { background: color-mix(in srgb, var(--ehs-ink) 66%, transparent); }
@media (prefers-color-scheme: dark) { :root[data-theme="dark"] .ehs-modal-backdrop { background: color-mix(in srgb, var(--ehs-ink) 66%, transparent); } }
.ehs-modal {
  display: flex; flex-direction: column; width: 100%; max-width: 860px; max-height: 88vh;
  background: var(--ehs-paper); border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-lg); box-shadow: var(--ehs-shadow-lg);
  overflow: hidden; animation: ehs-modal-in .18s ease;
}
.ehs-modal--sm { max-width: 460px; }
.ehs-modal--narrow { max-width: 560px; }
.ehs-modal__header {
  display: flex; align-items: center; gap: 12px; flex-shrink: 0;
  padding: 18px 22px 14px; border-bottom: 1px solid var(--ehs-rule);
}
.ehs-modal__title {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--ehs-font-display); font-size: 20px; font-weight: 700;
  color: var(--ehs-ink); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ehs-modal__close {
  flex: none; width: 32px; height: 32px; border-radius: var(--ehs-r-sm);
  border: 1px solid transparent; background: none; color: var(--ehs-muted);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1; transition: background .12s, color .12s, border-color .12s;
}
.ehs-modal__close:hover { background: var(--ehs-cream); color: var(--ehs-ink); }
.ehs-modal__close:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: 2px; }
.ehs-modal__body { padding: 20px 22px; overflow-y: auto; flex: 1 1 auto; }
.ehs-modal__foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 10px; flex-shrink: 0;
  padding: 14px 22px; border-top: 1px solid var(--ehs-rule); background: var(--ehs-cream);
}
@keyframes ehs-backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes ehs-modal-in { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .ehs-modal-backdrop, .ehs-modal { animation: none; }
}

/* =====================================================================
   DIFF VIEWER — compact field-level "from → to" change list. For audit
   trails, edit history, config diffs. Removed value reads in the error
   (bad) family; the new value in the success (ok) family.
   Markup:
     <ul class="ehs-diff">
       <li class="ehs-diff__row">
         <span class="ehs-diff__field">status</span>
         <span class="ehs-diff__from">open</span>
         <span class="ehs-diff__arrow">→</span>
         <span class="ehs-diff__to">done</span>
       </li>
     </ul>
   ===================================================================== */
.ehs-diff { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.ehs-diff__row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 5px; font-size: 13px; line-height: 1.5; }
.ehs-diff__field { font-family: var(--ehs-font-mono); font-size: 11.5px; font-weight: 700; color: var(--ehs-ink); flex-shrink: 0; }
.ehs-diff__field::after { content: ':'; color: var(--ehs-muted); }
.ehs-diff__from, .ehs-diff__to {
  font-family: var(--ehs-font-mono); font-size: 11.5px;
  border-radius: var(--ehs-r-sm); padding: 1px 5px; word-break: break-word;
}
.ehs-diff__from { color: var(--ehs-bad-text); background: var(--ehs-bad-pale); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--ehs-bad) 55%, transparent); }
.ehs-diff__arrow { color: var(--ehs-muted); flex-shrink: 0; font-size: 12px; }
.ehs-diff__to { color: var(--ehs-ok-text); background: var(--ehs-ok-pale); }
/* When a value was added (no prior) or cleared (no new), omit the missing side. */
.ehs-diff__empty { color: var(--ehs-muted); font-style: italic; font-family: var(--ehs-font-body); }

/* =====================================================================
   ACTION TOGGLE — an icon (or short-label) button that carries an on/off
   state, for row actions like pin / flag / star / claim. Off = quiet;
   on = tinted. Add .is-on when active. Tone modifiers pick the on-color:
   default (maroon), --warn, --info, --ok. --pill gives a labeled soft pill.
   Markup: <button class="ehs-toggle-btn is-on" aria-pressed="true">★</button>
   ===================================================================== */
.ehs-toggle-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 30px; height: 30px; padding: 0;
  border: 1px solid transparent; border-radius: var(--ehs-r-sm);
  background: none; color: var(--ehs-muted); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.ehs-toggle-btn:hover { background: var(--ehs-cream); color: var(--ehs-ink); }
.ehs-toggle-btn:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: 2px; }
.ehs-toggle-btn:disabled { opacity: .5; cursor: not-allowed; }
.ehs-toggle-btn.is-on { color: var(--ehs-maroon); background: var(--ehs-gold-pale); }
.ehs-toggle-btn--warn.is-on { color: var(--ehs-warn-text); background: var(--ehs-warn-pale); }
.ehs-toggle-btn--info.is-on { color: var(--ehs-info-text); background: var(--ehs-info-pale); }
.ehs-toggle-btn--ok.is-on   { color: var(--ehs-ok-text);   background: var(--ehs-ok-pale); }
/* Labeled soft pill (e.g. a "Claim" action). */
.ehs-toggle-btn--pill {
  width: auto; height: 24px; padding: 0 12px; border-radius: var(--ehs-r-pill);
  font-family: var(--ehs-font-body); font-size: 12px; font-weight: 600;
  background: var(--ehs-gold-pale); color: var(--ehs-maroon-deep);
}
.ehs-toggle-btn--pill:hover { background: var(--ehs-gold); color: var(--ehs-maroon-deep); }
/* Dark: maroon on-color reads dim on the dark ground — lift to warm ink / gold. */
:root[data-theme="dark"] .ehs-toggle-btn.is-on { color: var(--ehs-gold); }
:root[data-theme="dark"] .ehs-toggle-btn--pill { color: var(--ehs-ink); }
@media (prefers-color-scheme: dark) {
  :root[data-theme="dark"] .ehs-toggle-btn.is-on { color: var(--ehs-gold); }
  :root[data-theme="dark"] .ehs-toggle-btn--pill { color: var(--ehs-ink); }
}

/* ============================================================================
   EHS SHIELD LOADER  ·  .ehs-loader
   Full-screen "the shield draws itself on" loading experience.
   Markup is generated by /branding/loader.js (window.ehsLoader). This file
   owns the layer styling, the design tokens, and every @keyframes.

   Design handoff: /bastion/docs/design-handoffs/ehs-loader/
   Main cycle = --ehs-loader-dur (4.4s). See README for the full timeline.

   TOKENS — the handoff's design tokens are mapped onto the suite --ehs-*
   tokens where an equivalent exists, so the loader dark-flips with the rest
   of the brand suite. Loader-only tokens (--ehs-loader-*) cover the rest.
     handoff --ehs-bg      -> var(--ehs-cream)     (page ground)
     handoff --ehs-ink     -> var(--ehs-maroon)    (fill maroon)  = --ehs-loader-fill
     handoff --ehs-gold    -> var(--ehs-gold)      (shimmer / flow / runner)
     handoff --ehs-base    -> --ehs-loader-base    (deep-maroon trace stroke)
     handoff --ehs-shield  -> --ehs-loader-shield  (shield fill; reverses on dark)
     handoff --ehs-diamond -> --ehs-loader-diamond (diamond fill)
     handoff --ehs-veil    -> --ehs-loader-veil    (radial veil RGB triplet)
   ========================================================================== */
.ehs-loader {
  /* speed: raise --ehs-loader-speed (0.5–2) to run faster; dur derives from it */
  --ehs-loader-speed: 1;
  --ehs-loader-dur: calc(4.4s / var(--ehs-loader-speed));
  --ehs-loader-bg:      var(--ehs-cream);                 /* page ground        */
  --ehs-loader-base:    #530f21;                          /* trace stroke       */
  --ehs-loader-fill:    var(--ehs-maroon);                /* ink / fill maroon  */
  --ehs-loader-gold:    var(--ehs-gold);                  /* shimmer + flow     */
  --ehs-loader-shield:  var(--ehs-black);                 /* shield body        */
  --ehs-loader-diamond: #ffffff;                          /* diamond behind     */
  --ehs-loader-veil:    250,246,238;                      /* veil RGB triplet   */
  --ehs-loader-sketch-op: 0.17;
  --ehs-loader-sketch-filter: sepia(0.55) contrast(0.85);
  --ehs-loader-track:   rgb(var(--ehs-maroon-rgb) / 0.16);/* progress track     */
  --ehs-loader-progress: 0%;                              /* determinate width  */

  position: fixed; inset: 0; z-index: 2147483000;
  background: var(--ehs-loader-bg);
  font-family: var(--ehs-font-body);
}
.ehs-loader, .ehs-loader * { box-sizing: border-box; }

/* Layer 1: pencil sketch of the school */
.ehs-loader__sketch {
  position: absolute; inset: 0;
  background: url('/branding/edgewood-sketch.png') center 28% / cover no-repeat;
  opacity: var(--ehs-loader-sketch-op);
  filter: var(--ehs-loader-sketch-filter);
}
/* Layer 2: radial veil — faintest behind the shield so the mark stays dominant */
.ehs-loader__veil {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 46%,
    rgba(var(--ehs-loader-veil),0.82) 0%,
    rgba(var(--ehs-loader-veil),0.38) 42%,
    rgba(var(--ehs-loader-veil),0.05) 78%,
    rgba(var(--ehs-loader-veil),0)   100%);
}
/* Layer 3: centered shield + reserved bar row */
.ehs-loader__stage {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 36px;
}
.ehs-loader__shield {
  width: min(38vh, 60vw);
  animation: ehs-loader-breathe var(--ehs-loader-dur) ease-in-out infinite;
}
.ehs-loader__svg { width: 100%; display: block; overflow: visible; }
.ehs-loader__svg--hold { display: none; }
.ehs-loader--extended .ehs-loader__svg--anim { display: none; }
.ehs-loader--extended .ehs-loader__svg--hold { display: block; }

/* --- animated-cycle layers (the "draw-on") --- */
.ehs-loader__diamond,
.ehs-loader__shieldfill { animation: ehs-loader-sfill var(--ehs-loader-dur) ease-in-out infinite; }
.ehs-loader__strace { animation: ehs-loader-sdraw var(--ehs-loader-dur) cubic-bezier(0.5,0,0.4,1) infinite; }
.ehs-loader__itrace { animation: ehs-loader-idraw var(--ehs-loader-dur) cubic-bezier(0.5,0,0.4,1) infinite; }
.ehs-loader__drop   { animation: ehs-loader-drop  var(--ehs-loader-dur) cubic-bezier(0.3,0.55,0.35,1) infinite; }
.ehs-loader__flow   { animation: ehs-loader-flow  var(--ehs-loader-dur) linear infinite; }
.ehs-loader__shimmer{ mix-blend-mode: screen; animation: ehs-loader-shimmer var(--ehs-loader-dur) cubic-bezier(0.4,0,0.5,1) infinite; }

/* --- extended / held-shield layers --- */
.ehs-loader__holdflow { animation: ehs-loader-holdflow 3.2s ease-in-out infinite; }

/* --- progress bar (extended-load state) --- */
.ehs-loader__barrow {
  height: 20px;                          /* fixed row so the shield never shifts */
  display: flex; align-items: center; justify-content: center;
}
.ehs-loader__bar {
  width: min(220px, 40vw); height: 4px; border-radius: 2px;
  overflow: hidden; background: var(--ehs-loader-track);
  opacity: 0;
}
.ehs-loader--extended .ehs-loader__bar { opacity: 1; animation: ehs-loader-fadein 0.6s ease-out both; }
.ehs-loader__runner {
  width: 38%; height: 100%; border-radius: 2px;
  background: linear-gradient(90deg, var(--ehs-loader-fill), var(--ehs-loader-gold));
  animation: ehs-loader-bar 1.4s cubic-bezier(0.4,0.1,0.6,0.9) infinite;
}
/* determinate: runner width is driven by JS via --ehs-loader-progress */
.ehs-loader--determinate .ehs-loader__runner {
  width: var(--ehs-loader-progress, 0%);
  animation: none; transition: width 0.3s ease;
}

/* --- small variant (88px section mark): thicken strokes, drop gold flow + turbulence --- */
.ehs-loader--small .ehs-loader__shield { width: 88px; }
.ehs-loader--small .ehs-loader__strace { stroke-width: 18; }
.ehs-loader--small .ehs-loader__itrace { stroke-width: 22; }
.ehs-loader--small .ehs-loader__flow,
.ehs-loader--small .ehs-loader__shimmer { display: none; }
.ehs-loader--small .ehs-loader__inkgroup { filter: none !important; }

/* --- exit: fade the whole overlay out (used by hide() from the held state) --- */
.ehs-loader--exit { animation: ehs-loader-fadeout 0.4s ease-out both; }

/* --- quick mode (DEFAULT, ~2s): trace + fill + inlay + ink-flood, then fade.
       No gold shimmer sweep, no hold. Re-times the layers via the q-* keyframes
       and shortens the cycle. Extended-load + reduced-motion are unaffected. --- */
.ehs-loader--quick { --ehs-loader-dur: calc(2s / var(--ehs-loader-speed)); }
.ehs-loader--quick .ehs-loader__diamond,
.ehs-loader--quick .ehs-loader__shieldfill { animation-name: ehs-loader-q-sfill; }
.ehs-loader--quick .ehs-loader__strace { animation-name: ehs-loader-q-sdraw; }
.ehs-loader--quick .ehs-loader__itrace { animation-name: ehs-loader-q-idraw; }
.ehs-loader--quick .ehs-loader__drop   { animation-name: ehs-loader-q-drop; }
.ehs-loader--quick .ehs-loader__flow   { animation-name: ehs-loader-q-flow; }
.ehs-loader--quick .ehs-loader__shimmer { display: none; }        /* no sweep in quick */

/* --- dark: reverse the shield, darken diamond + veil, invert the sketch --- */
:root[data-theme="dark"] .ehs-loader {
  /* The MARK DOES NOT FLIP. Inverting it produced a cream shield on a near-black field:
     legible, but no longer the logo — the black shape that carries the identity had
     become the light one. Keeping the print colours costs the silhouette its edge on a
     dark ground, so --ehs-*-rim draws that edge back on the OUTLINE ONLY. No fill
     changes. Treatments compared in the 2026-07-30 dark-mode shield study. */
  /* ALL GOLD on dark. The mark is not inverted and it is not the light-mode mark
     either — it is one colour throughout, with the field dropped to the page ground
     so it reads as negative space. Chosen 2026-07-30 over keeping Dominican black
     with a gold edge; the black silhouette needed rescuing on a dark ground, gold
     does not. --ehs-loader-gold lifts above the body gold so the shimmer and the
     ink-flow still read against it. */
  --ehs-loader-shield:  var(--ehs-gold);
  --ehs-loader-diamond: var(--ehs-cream);
  --ehs-loader-fill:    var(--ehs-gold);
  --ehs-loader-base:    var(--ehs-gold);
  --ehs-loader-gold:    #f0dcae;
  --ehs-loader-veil:    26,16,20;
  --ehs-loader-sketch-op: 0.12;
  --ehs-loader-sketch-filter: invert(1) sepia(0.3);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="dark"] .ehs-loader {
    /* The MARK DOES NOT FLIP. Inverting it produced a cream shield on a near-black field:
       legible, but no longer the logo — the black shape that carries the identity had
       become the light one. Keeping the print colours costs the silhouette its edge on a
       dark ground, so --ehs-*-rim draws that edge back on the OUTLINE ONLY. No fill
       changes. Treatments compared in the 2026-07-30 dark-mode shield study. */
    /* ALL GOLD on dark. The mark is not inverted and it is not the light-mode mark
       either — it is one colour throughout, with the field dropped to the page ground
       so it reads as negative space. Chosen 2026-07-30 over keeping Dominican black
       with a gold edge; the black silhouette needed rescuing on a dark ground, gold
       does not. --ehs-loader-gold lifts above the body gold so the shimmer and the
       ink-flow still read against it. */
    --ehs-loader-shield:  var(--ehs-gold);
    --ehs-loader-diamond: var(--ehs-cream);
    --ehs-loader-fill:    var(--ehs-gold);
    --ehs-loader-base:    var(--ehs-gold);
    --ehs-loader-gold:    #f0dcae;
    --ehs-loader-veil:    26,16,20;
    --ehs-loader-sketch-op: 0.12;
    --ehs-loader-sketch-filter: invert(1) sepia(0.3);
  }
}

/* --- reduced motion: static filled shield + static bar, no draw-on, no sweep --- */
@media (prefers-reduced-motion: reduce) {
  .ehs-loader__shield { animation: none; }
  .ehs-loader__holdflow { animation: none; opacity: 0; }
  .ehs-loader__bar { opacity: 1; animation: none; }
  .ehs-loader__runner { animation: none; }
}

/* ---- keyframes (percentages of --ehs-loader-dur; see README timeline) ---- */
@keyframes ehs-loader-sdraw {
  0%   { stroke-dashoffset: 1; opacity: 1; }
  28%  { stroke-dashoffset: 0; opacity: 1; }
  94%  { stroke-dashoffset: 0; opacity: 1; }
  98%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ehs-loader-sfill {
  0%, 24% { opacity: 0; }
  36%     { opacity: 1; }
  94%     { opacity: 1; }
  98%, 100% { opacity: 0; }
}
@keyframes ehs-loader-idraw {
  0%, 22% { stroke-dashoffset: 1; opacity: 1; }
  52%     { stroke-dashoffset: 0; opacity: 1; }
  94%     { stroke-dashoffset: 0; opacity: 1; }
  98%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ehs-loader-drop {
  0%, 46% { transform: scale(0); opacity: 0.95; }
  70%     { transform: scale(1); opacity: 1; }
  94%     { transform: scale(1); opacity: 1; }
  98%, 100% { transform: scale(1); opacity: 0; }
}
@keyframes ehs-loader-flow {
  0%, 48% { stroke-dashoffset: 0; opacity: 0; }
  54%     { opacity: 0.9; }
  72%     { opacity: 0.9; stroke-dashoffset: -0.18; }
  78%, 100% { opacity: 0; stroke-dashoffset: -0.22; }
}
@keyframes ehs-loader-shimmer {
  0%, 80% { transform: translateX(-980px); opacity: 1; }
  93%     { transform: translateX(2050px); opacity: 1; }
  94%, 100% { transform: translateX(2050px); opacity: 0; }
}
@keyframes ehs-loader-breathe {
  0%, 100% { transform: scale(0.988); }
  70%      { transform: scale(1.014); }
}
@keyframes ehs-loader-holdflow {
  0%   { stroke-dashoffset: 0; opacity: 0; }
  22%  { opacity: 0.85; }
  60%  { opacity: 0.85; }
  100% { stroke-dashoffset: -0.12; opacity: 0; }
}
@keyframes ehs-loader-bar {
  0%   { transform: translateX(-110%); }
  100% { transform: translateX(280%); }
}
@keyframes ehs-loader-fadein  { from { opacity: 0; } to { opacity: 1; } }
@keyframes ehs-loader-fadeout { from { opacity: 1; } to { opacity: 0; } }

/* ---- quick-mode keyframes (~2s cycle): trace + fill + inlay + ink-flood, then
        a short fade. No shimmer, no hold pause. Percentages of the 2s cycle. ---- */
@keyframes ehs-loader-q-sdraw {
  0%   { stroke-dashoffset: 1; opacity: 1; }
  30%  { stroke-dashoffset: 0; opacity: 1; }
  90%  { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ehs-loader-q-sfill {
  0%, 26% { opacity: 0; }
  40%     { opacity: 1; }
  90%     { opacity: 1; }
  97%, 100% { opacity: 0; }
}
@keyframes ehs-loader-q-idraw {
  0%, 24% { stroke-dashoffset: 1; opacity: 1; }
  58%     { stroke-dashoffset: 0; opacity: 1; }
  90%     { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes ehs-loader-q-drop {
  0%, 52% { transform: scale(0); opacity: 0.95; }
  84%     { transform: scale(1); opacity: 1; }
  90%     { transform: scale(1); opacity: 1; }
  97%, 100% { transform: scale(1); opacity: 0; }
}
@keyframes ehs-loader-q-flow {
  0%, 54% { stroke-dashoffset: 0; opacity: 0; }
  60%     { opacity: 0.9; }
  82%     { opacity: 0.9; stroke-dashoffset: -0.14; }
  88%, 100% { opacity: 0; stroke-dashoffset: -0.17; }
}

/* ============================================================================
   EHS STATUS PAGES  ·  .ehs-status
   The universal Blocked / Unavailable / In Development / 404 page — the same
   shield, sketch ground and veil as the loader, holding a message instead of
   an animation. Markup is generated by /branding/status.js (window.ehsStatus);
   this file owns every layer, token and @keyframes. Ready-made pages live at
   /branding/status/{blocked,unavailable,dev,404}.html (public, ungated — a
   signed-out visitor has to be able to see them).

   Design handoff: /bastion/docs/design-handoffs/ehs-status/

   STATE = a modifier only: .ehs-status--blocked | --unavailable | --dev |
   --notfound. All four render identically by design (one calm brand surface,
   different words); the modifier is a styling hook for an app that needs to
   tint one, and the state name is also on [data-ehs-status] for JS/analytics.
   Layout modifiers: --overlay (fixed over a running app) · --embedded (inside
   a card or a region, no full-viewport height).

   TOKENS — mapped onto the suite --ehs-* tokens wherever an equivalent exists
   so the page dark-flips with the rest of the brand. Status-only tokens
   (--ehs-status-*) cover the rest.
     handoff #faf6ee -> var(--ehs-cream)   (page ground)
     handoff #681a31 -> var(--ehs-maroon)  (inlay + primary button)
     handoff #d0b786 -> var(--ehs-gold)    (eyebrow pips)
     handoff #231f20 -> var(--ehs-ink)     (headline + shield body)
     handoff #8a6a74 -> --ehs-status-eyebrow (muted maroon kicker)
   TYPE — the handoff set the headline in Source Serif 4. The suite retired its
   serif in 2026-07 (Source Sans 3 carries display), so the headline uses
   var(--ehs-font-display) by default. To go back to the handoff's serif on a
   given page, set --ehs-status-title-font (and load the font).
   ========================================================================== */
.ehs-status {
  --ehs-status-bg:      var(--ehs-cream);
  --ehs-status-veil:    250,246,238;                        /* veil RGB triplet   */
  --ehs-status-shield:  var(--ehs-ink);                     /* shield body        */
  --ehs-status-diamond: #ffffff;                            /* diamond behind     */
  --ehs-status-inlay:   var(--ehs-maroon);                  /* inlay fill         */
  --ehs-status-eyebrow: #8a6a74;                            /* mono kicker        */
  --ehs-status-title:   var(--ehs-ink);
  --ehs-status-msg:     #5c5450;
  --ehs-status-foot:    #8a7a6a;
  --ehs-status-rule:    rgb(var(--ehs-maroon-rgb) / 0.18);
  --ehs-status-sketch-op: 0.16;
  --ehs-status-sketch-filter: sepia(0.55) contrast(0.85);
  --ehs-status-title-font: var(--ehs-font-display);
  --ehs-status-mark-w: clamp(56px, 7cqw, 72px);

  position: relative;
  container-type: inline-size;
  overflow: hidden;
  min-height: 100dvh;
  background: var(--ehs-status-bg);
  font-family: var(--ehs-font-body);
  color: var(--ehs-status-title);
}
.ehs-status, .ehs-status * { box-sizing: border-box; }

/* Layer 1: the same pencil sketch of the school the loader uses */
.ehs-status__sketch {
  position: absolute; inset: 0;
  background: url('/branding/edgewood-sketch.png') center 24% / cover no-repeat;
  opacity: var(--ehs-status-sketch-op);
  filter: var(--ehs-status-sketch-filter);
}
/* Layer 2: radial veil — brightest behind the message so the copy stays legible */
.ehs-status__veil {
  position: absolute; inset: 0;
  background: radial-gradient(circle at 50% 42%,
    rgba(var(--ehs-status-veil),0.94) 0%,
    rgba(var(--ehs-status-veil),0.72) 40%,
    rgba(var(--ehs-status-veil),0.28) 74%,
    rgba(var(--ehs-status-veil),0.05) 100%);
}
/* Layer 3: top/bottom fade so the sketch never fights the mark or the footer */
.ehs-status__fade {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(var(--ehs-status-veil),0.60) 0%,
    rgba(var(--ehs-status-veil),0)    30%,
    rgba(var(--ehs-status-veil),0)    70%,
    rgba(var(--ehs-status-veil),0.85) 100%);
}

/* Layer 4: content — mark, message block, school line pinned to the bottom */
.ehs-status__inner {
  position: relative;
  min-height: 100dvh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: clamp(28px, 4vh, 44px);
  padding: clamp(72px, 7cqw, 88px) clamp(24px, 7cqw, 72px) clamp(28px, 4vh, 44px);
  text-align: center;
}
.ehs-status__mark {
  width: var(--ehs-status-mark-w);
  animation: ehs-status-in 0.7s cubic-bezier(0.2,0.8,0.3,1) both;
}
.ehs-status__mark svg { width: 100%; display: block; }
.ehs-status__diamond { fill: var(--ehs-status-diamond); }
.ehs-status__shield  { fill: var(--ehs-status-shield); }
.ehs-status__inlay   { fill: var(--ehs-status-inlay); }

.ehs-status__block {
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(14px, 2vh, 20px);
  max-width: 34rem;
  animation: ehs-status-in 0.7s cubic-bezier(0.2,0.8,0.3,1) 0.08s both;
}
.ehs-status__eyebrow {
  margin: 0;
  display: flex; align-items: center; gap: 10px;
  font-family: var(--ehs-font-mono);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ehs-status-eyebrow);
}
.ehs-status__pip {
  width: 6px; height: 6px; flex: none;
  background: var(--ehs-gold); transform: rotate(45deg);
}
.ehs-status__title {
  margin: 0;
  font-family: var(--ehs-status-title-font);
  font-weight: 400;
  font-size: clamp(30px, 8.5cqw, 52px);
  line-height: 1.08;
  color: var(--ehs-status-title);
  text-wrap: pretty;
}
.ehs-status__msg {
  margin: 0;
  max-width: 30rem;
  font-size: clamp(16px, 1.75cqw, 19px);
  line-height: 1.62;
  color: var(--ehs-status-msg);
  text-wrap: pretty;
}
.ehs-status__actions {
  margin-top: 6px;
  display: flex; flex-wrap: wrap; justify-content: center; gap: 14px;
}
.ehs-status__actions .ehs-btn { min-height: 46px; }
/* The quiet way out (Blocked page): a text link for someone who is not part of
   Edgewood at all, deliberately not a third button competing with the two actions. */
.ehs-status__aside {
  margin: 2px 0 0;
  font-size: 14px;
  color: var(--ehs-status-msg);
}
.ehs-status__aside a { color: var(--ehs-accent-text); text-underline-offset: 3px; }
:root[data-theme="dark"] .ehs-status__aside a { color: var(--ehs-gold); }
@media (prefers-color-scheme: dark) {
  :root[data-theme="dark"] .ehs-status__aside a { color: var(--ehs-gold); }
}
.ehs-status__detail {
  margin: 2px 0 0;
  font-family: var(--ehs-font-mono);
  font-size: 11px; letter-spacing: 0.06em;
  color: var(--ehs-status-foot);
  word-break: break-word;
}
.ehs-status__footer {
  margin-top: auto;
  padding-top: clamp(24px, 4vh, 40px);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-family: var(--ehs-status-title-font);
  font-size: 13px; letter-spacing: 0.02em;
  color: var(--ehs-status-foot);
}
.ehs-status__rule { width: 40px; height: 1px; background: var(--ehs-status-rule); }

/* --- overlay: the same page thrown over a running app (lost access mid-session) --- */
.ehs-status--overlay { position: fixed; inset: 0; z-index: 2147482000; }  /* under .ehs-loader */

/* --- embedded: a region/card inside an app (a blocked tab, a not-built-yet panel) --- */
.ehs-status--embedded { min-height: 0; border-radius: var(--ehs-r-lg); }
.ehs-status--embedded .ehs-status__inner {
  min-height: 0;
  gap: clamp(20px, 3vh, 30px);
  padding: clamp(36px, 6cqw, 56px) clamp(20px, 6cqw, 48px);
}
.ehs-status--embedded .ehs-status__footer { display: none; }
.ehs-status--embedded { --ehs-status-mark-w: clamp(44px, 6cqw, 58px); }

/* --- dark: reverse the shield, darken diamond + veil, invert the sketch (as loader) --- */
:root[data-theme="dark"] .ehs-status {
  --ehs-status-bg:      #1a1014;
  --ehs-status-veil:    26,16,20;
  /* The MARK DOES NOT FLIP. Inverting it produced a cream shield on a near-black field:
     legible, but no longer the logo — the black shape that carries the identity had
     become the light one. Keeping the print colours costs the silhouette its edge on a
     dark ground, so --ehs-*-rim draws that edge back on the OUTLINE ONLY. No fill
     changes. Treatments compared in the 2026-07-30 dark-mode shield study. */
  --ehs-status-shield:  var(--ehs-gold);
  --ehs-status-diamond: var(--ehs-cream);
  --ehs-status-inlay:   var(--ehs-gold);
  --ehs-status-eyebrow: #c9a3af;
  --ehs-status-msg:     #cbbfb6;
  --ehs-status-foot:    #a2928a;
  --ehs-status-rule:    rgb(var(--ehs-gold-rgb) / 0.28);
  --ehs-status-sketch-op: 0.12;
  --ehs-status-sketch-filter: invert(1) sepia(0.3);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="dark"] .ehs-status {
    --ehs-status-bg:      #1a1014;
    --ehs-status-veil:    26,16,20;
    /* The MARK DOES NOT FLIP. Inverting it produced a cream shield on a near-black field:
       legible, but no longer the logo — the black shape that carries the identity had
       become the light one. Keeping the print colours costs the silhouette its edge on a
       dark ground, so --ehs-*-rim draws that edge back on the OUTLINE ONLY. No fill
       changes. Treatments compared in the 2026-07-30 dark-mode shield study. */
    --ehs-status-shield:  var(--ehs-gold);
    --ehs-status-diamond: var(--ehs-cream);
    --ehs-status-inlay:   var(--ehs-gold);
    --ehs-status-eyebrow: #c9a3af;
    --ehs-status-msg:     #cbbfb6;
    --ehs-status-foot:    #a2928a;
    --ehs-status-rule:    rgb(var(--ehs-gold-rgb) / 0.28);
    --ehs-status-sketch-op: 0.12;
    --ehs-status-sketch-filter: invert(1) sepia(0.3);
  }
}

/* --- reduced motion: no rise-in, just the page --- */
@media (prefers-reduced-motion: reduce) {
  .ehs-status__mark, .ehs-status__block { animation: none; }
}

@keyframes ehs-status-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}


/* =====================================================================
   S1 — .ehs-filecard : generated-file / download result card
   -------------------------------------------------------------------
   A utilitarian file row for the "here is your produced document" moment:
   a type glyph, filename, a meta line, and an action cluster of existing
   .ehs-btn elements. Built entirely on --ehs-* tokens so it flips in dark
   mode. Modifier --locked adds a 4px --ehs-gold left rail (same device as
   .ehs-infocard::before) + a lock overlay on the glyph, for a confidential
   companion (e.g. an answer key) paired with .ehs-badge--gold.
   Cross-app: Docusuite rows, PO PDFs, Maintenance docs, Scheduler SOP
   exports, Onboarding forms, Chromebook exports.
   ===================================================================== */
.ehs-filecard {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--ehs-s3);
  padding: var(--ehs-s3);
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-sm);
}
.ehs-filecard__icon {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--ehs-r-sm);
  background: color-mix(in srgb, var(--ehs-maroon) 12%, var(--ehs-paper));
  color: var(--ehs-accent-text);
}
.ehs-filecard__icon svg { width: 22px; height: 22px; display: block; }
.ehs-filecard__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ehs-filecard__name {
  font-family: var(--ehs-font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--ehs-ink);
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.ehs-filecard__meta {
  font-size: 12px;
  color: var(--ehs-muted);
  line-height: 1.4;
}
.ehs-filecard__actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--ehs-s2);
  flex-wrap: wrap;
}
/* --locked : gold rail + lock overlay for a confidential companion file */
.ehs-filecard--locked { border-color: var(--ehs-gold-deep); }
.ehs-filecard--locked::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 4px;
  border-radius: var(--ehs-r-md) 0 0 var(--ehs-r-md);
  background: var(--ehs-gold);
}
.ehs-filecard--locked .ehs-filecard__icon {
  background: var(--ehs-gold-pale);
  color: var(--ehs-gold-deep);
}
.ehs-filecard--locked .ehs-filecard__icon::after {
  content: '';
  position: absolute;
  right: -3px;
  bottom: -3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ehs-gold);
  /* padlock glyph, masked so it inherits the token color path */
  -webkit-mask: no-repeat center / 10px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23231f20' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='11' width='16' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E");
          mask: no-repeat center / 10px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23231f20' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='11' width='16' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E");
  background-color: var(--ehs-maroon-deep);
}
@media (max-width: 560px) {
  .ehs-filecard { flex-wrap: wrap; }
  .ehs-filecard__actions { width: 100%; margin-left: 52px; }
}

/* =====================================================================
   S2 — .ehs-tokenfield : chip multi-select wrapper (kills <select multiple>)
   -------------------------------------------------------------------
   A field wrapper that unifies removable .ehs-chip tokens + a text input
   into one bordered, input-shaped control. Compose with .ehs-combobox for
   the live-suggest dropdown; the removable chips are the existing .ehs-chip
   / .ehs-chip__x, and the dropdown is the existing .ehs-suggest — this
   block styles ONLY the wrapper and its bare inner input, nothing else.
   Reads as an .ehs-input: --ehs-rule-strong border, --ehs-r-sm, --ehs-paper,
   with the established focus ring on :focus-within.
   Cross-app: SharesModal staff grants, Blueprint bank draw, Maintenance
   tags & assignees, PO account selection, Chromebook multi-device, Signage
   screen groups.
   ===================================================================== */
.ehs-tokenfield {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ehs-s2);
  padding: 5px var(--ehs-s2);
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule-strong);
  border-radius: var(--ehs-r-sm);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ehs-tokenfield:focus-within {
  border-color: var(--ehs-maroon);
  box-shadow: 0 0 0 3px rgba(104,26,49,.12);
}
.ehs-tokenfield__input {
  flex: 1 1 90px;
  min-width: 90px;
  border: 0;
  outline: none;
  padding: 4px 2px;
  margin: 0;
  background: transparent;
  color: var(--ehs-ink);
  font-family: var(--ehs-font-body);
  font-size: 14px;
}
.ehs-tokenfield__input::placeholder { color: #a89f92; }

/* =====================================================================
   INSTRUCTIONALS "THE SHEET" VARIANTS  (additive — 2026-07-17)
   Five approved variants for the Instructionals refresh (the
   "Google-Docs-for-tests" language). All colours/radii/shadows are
   --ehs-* tokens, so light/dark is a pure token flip — no per-theme
   rules. Paper-white (--ehs-paper) is reserved for surfaces that
   represent a real document (the doctile thumbnail + the canvas sheet);
   everything else sits on --ehs-cream. Introduced for `instructionals`;
   the sheet/tally/folio idioms are reusable by any document-authoring app.
   ===================================================================== */

/* --- 1 · .ehs-folio — mono dot-separated document metadata line ------ */
.ehs-folio {
  font-family: var(--ehs-font-mono);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ehs-muted);
  white-space: nowrap;
}

/* --- 2 · .ehs-doctile — portrait 8.5:11 paper thumbnail -------------- */
.ehs-doctile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
.ehs-doctile__paper {
  position: relative;
  aspect-ratio: 8.5 / 11;
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-sm);
  overflow: hidden;
  transition: box-shadow .15s, transform .12s;
  padding: 14px 13px 0;
}
.ehs-doctile:hover .ehs-doctile__paper {
  box-shadow: var(--ehs-shadow-md);
  transform: translateY(-2px);
}
.ehs-doctile:focus-visible { outline: none; }
.ehs-doctile:focus-visible .ehs-doctile__paper {
  outline: 2px solid var(--ehs-legacy-gold);
  outline-offset: 2px;
}
/* faux mini-document preview inside the thumbnail */
.ehs-doctile__mast {
  height: 14px;
  border-radius: 2px;
  background: var(--ehs-gold-pale);
  margin-bottom: 9px;
}
.ehs-doctile__line {
  height: 4px;
  border-radius: 2px;
  background: var(--ehs-rule);
  margin: 0 0 6px;
}
.ehs-doctile__line--q {
  background: var(--ehs-rule-strong);
  width: 38%;
  height: 5px;
  margin-top: 11px;
}
.ehs-doctile__line--s { width: 88%; }
.ehs-doctile__line--m { width: 70%; }
.ehs-doctile__line--l { width: 96%; }
.ehs-doctile__break {
  position: absolute;
  left: 0;
  right: 0;
  top: 63%;
  border-top: 1.5px dashed var(--ehs-maroon);
  opacity: .55;
}
/* --shared · gold companion tab in the corner of a shared doc */
.ehs-doctile--shared .ehs-doctile__paper::after {
  content: "";
  position: absolute;
  top: 0;
  right: 16px;
  width: 18px;
  height: 24px;
  background: var(--ehs-gold);
  border-radius: 0 0 4px 4px;
  box-shadow: var(--ehs-shadow-sm);
}
.ehs-doctile__cap {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.ehs-doctile__title {
  font-family: var(--ehs-font-display);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.25;
}
.ehs-doctile__folio {
  font-family: var(--ehs-font-mono);
  font-size: 10.5px;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ehs-muted);
}

/* --- 3 · .ehs-sheet / .ehs-mast / .ehs-pagebreak — the canvas paper -- */
.ehs-sheet {
  position: relative;
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-lg);
  box-shadow: var(--ehs-shadow-lg);
  padding: 0 34px 44px 58px;
}
/* mono Q-number binding ruler down the left edge */
.ehs-sheet__ruler {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 40px;
  border-right: 1px solid var(--ehs-rule);
  display: flex;
  flex-direction: column;
  padding-top: 150px;
}
.ehs-sheet__tick {
  position: relative;
  font-family: var(--ehs-font-mono);
  font-size: 10px;
  color: var(--ehs-muted);
  text-align: right;
  padding-right: 8px;
}
.ehs-sheet__tick--active {
  color: var(--ehs-accent-text);
  font-weight: 700;
}
/* gold-pale NAME / DATE / MOD masthead band */
.ehs-mast {
  background: var(--ehs-gold-pale);
  border: 1px solid var(--ehs-gold-deep);
  border-radius: var(--ehs-r-sm);
  margin: 34px 0 26px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ehs-mast__ttl {
  font-family: var(--ehs-font-display);
  font-weight: 800;
  font-size: 20px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ehs-on-goldpale);
}
.ehs-mast__row {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
}
.ehs-mast__field {
  flex: 1 1 auto;
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: var(--ehs-on-goldpale);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.ehs-mast__field--slug { flex: 0 0 auto; }
.ehs-mast__rule {
  flex: 1;
  border-bottom: 1.5px solid var(--ehs-gold-deep);
  min-width: 40px;
  height: 0;
  transform: translateY(-3px);
}
.ehs-mast__p {
  font-family: var(--ehs-font-mono);
  letter-spacing: 0;
}
/* the signature live page-break rule that flows where printed pages split */
.ehs-pagebreak {
  position: relative;
  border-top: 2px dashed var(--ehs-maroon);
  margin: 30px 0 26px;
  opacity: .9;
}
.ehs-pagebreak__tag {
  position: absolute;
  top: -10px;
  right: 0;
  background: var(--ehs-cream);
  padding: 0 8px;
  font-family: var(--ehs-font-mono);
  font-size: 10px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ehs-accent-text);
  font-weight: 600;
}
.ehs-pagebreak__tag::before {
  content: "\2310 ";
  opacity: .6;
}

/* --- 4 · .ehs-qblock — authoring question block --------------------- */
.ehs-qblock {
  position: relative;
  border-left: 3px solid var(--ehs-rule);
  padding: 6px 4px 6px 16px;
  margin: 0 0 22px;
}
.ehs-qblock--active { border-left-color: var(--ehs-maroon); }
.ehs-qblock__spec {
  position: absolute;
  top: -9px;
  right: 0;
  font-family: var(--ehs-font-mono);
  font-size: 9.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ehs-muted);
  background: var(--ehs-gold-pale);
  border-radius: var(--ehs-r-pill);
  padding: 2px 8px;
}
.ehs-qblock__stem {
  font-size: 15px;
  line-height: 1.5;
  margin: 0 0 12px;
  font-weight: 500;
}
.ehs-qblock__num {
  font-family: var(--ehs-font-mono);
  font-weight: 600;
  color: var(--ehs-accent-text);
  margin-right: 8px;
}

/* --- 5 · .ehs-tally — blueprint completeness gauge ------------------ */
.ehs-tally {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.ehs-tally__track {
  display: flex;
  gap: 3px;
}
.ehs-tally__seg {
  width: 15px;
  height: 9px;
  border-radius: 2px;
  background: var(--ehs-gold-pale);
  border: 1px solid var(--ehs-gold-deep);
}
.ehs-tally__seg--filled {
  background: var(--ehs-gold);
  border-color: var(--ehs-gold-deep);
}
.ehs-tally__seg--over {
  background: var(--ehs-warn-pale);
  border-color: var(--ehs-warn);
}
.ehs-tally__read {
  font-family: var(--ehs-font-mono);
  font-size: 11px;
  color: var(--ehs-muted);
  letter-spacing: .02em;
}
.ehs-tally__read b {
  color: var(--ehs-ink);
  font-weight: 600;
}

/* =====================================================================
   .ehs-doctile PER-TYPE VARIANTS  (additive — 2026-07-18)
   Six doctype modifiers for Instructionals' library. The faux preview
   inside each tile's paper is a literal miniature of that template's
   printout — the layout IS the identification; no new hues, no badges.
   Greys (--ehs-rule / --ehs-rule-strong) draw the miniature; gold-pale
   marks header zones; maroon appears only where it means something:
   the answer-sheet page break (test) and the scissor cut line
   (mini cards, exit ticket). Everything is tokens, so dark mode is the
   usual flip — no per-theme rules.
   New elements: __row __bubbles __rules __grid __cell __slip __cut
   __para __type. New modifiers: --test --quiz --worksheet --minicard
   --exitticket --studyguide. Nothing existing is redefined.
   ===================================================================== */

/* --- shared miniature vocabulary ------------------------------------- */
/* one answered question: bubble cluster + stem line */
.ehs-doctile__row {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 7px;
}
/* four 5px answer bubbles, drawn with one repeated radial gradient */
.ehs-doctile__bubbles {
  flex: none;
  width: 30px;
  height: 6px;
  background: radial-gradient(circle 2.5px at 3px 3px,
              var(--ehs-rule-strong) 97%, transparent) 0 0 / 8px 6px repeat-x;
}
.ehs-doctile__line--stem { flex: 1; margin: 0; }
/* dashed maroon cut line — "scissors here" (cf. __break = page break) */
.ehs-doctile__cut {
  border-top: 1.5px dashed var(--ehs-maroon);
  opacity: .55;
  margin: 0 -13px;             /* run to the paper edge */
}
/* glyph + template name as the first folio segment */
.ehs-doctile__type {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  vertical-align: top;
}
.ehs-doctile__type svg {
  width: 11px;
  height: 11px;
  flex: none;
  stroke: currentColor;
}

/* --- test · sectioned rows of bubbled questions ---------------------- */
/* (composition only: mast, __line--q section heads, __row × n, __break
   for the separate answer sheet — no extra rules needed) */
.ehs-doctile--test .ehs-doctile__line--q { margin-top: 9px; }

/* --- quiz · a short stack, bottom half deliberately empty ------------ */
.ehs-doctile--quiz .ehs-doctile__mast { height: 10px; width: 62%; }
.ehs-doctile--quiz .ehs-doctile__row  { margin-bottom: 9px; }

/* --- worksheet · one prompt, then ruled room to work ----------------- */
.ehs-doctile--worksheet .ehs-doctile__paper {
  display: flex;
  flex-direction: column;
}
.ehs-doctile__rules {
  flex: 1;
  margin-top: 6px;
  background: repeating-linear-gradient(to bottom,
              transparent 0 12px, var(--ehs-rule) 12px 13px);
}

/* --- minicard · the 8-up cut-apart sheet ----------------------------- */
.ehs-doctile__grid {
  position: absolute;
  inset: 12px 11px;
  display: grid;
  grid-template: repeat(4, 1fr) / repeat(2, 1fr);
  gap: 6px;
}
.ehs-doctile__cell {
  border: 1px solid var(--ehs-rule-strong);
  border-radius: 2px;
  background: linear-gradient(to bottom, var(--ehs-gold-pale) 0 4px,
              transparent 4px);
}

/* --- exit ticket · a small slip on the paper, cut off below ---------- */
.ehs-doctile__slip {
  border: 1px solid var(--ehs-rule-strong);
  border-radius: 3px;
  background: linear-gradient(to bottom, var(--ehs-gold-pale) 0 6px,
              transparent 6px);
  padding: 12px 8px 9px;
  margin: 2px 0 10px;
}
.ehs-doctile__slip .ehs-doctile__line:last-child { margin-bottom: 0; }

/* --- study guide · dense reading, paragraph blocks ------------------- */
/* a paragraph of tight 3px text lines, one repeated gradient */
.ehs-doctile__para {
  height: 24px;
  margin: 0 0 9px;
  background: repeating-linear-gradient(to bottom,
              var(--ehs-rule-strong) 0 3px, transparent 3px 8px);
  opacity: .75;
}
.ehs-doctile__para--s { width: 86%; height: 16px; }
.ehs-doctile--studyguide .ehs-doctile__mast { margin-bottom: 7px; }
.ehs-doctile--studyguide .ehs-doctile__line--q { margin-top: 7px; }

/* =====================================================================
   .ehs-polaroid — polaroid-framed photos + edge-stacked fly-in wings
   Added 2026-07-17 (first used by crusadersidekick landing).
   ---------------------------------------------------------------------
   Decorative photo piles fixed to the viewport edges. At rest every
   polaroid peeks ~15% into the page at a messy angle; hovering a target
   element slides that target's polaroids fully in. Pair with
   /branding/ehs-polaroid.js:

     EhsPolaroid.init({
       hoverSelector: '.program-card',
       placeholderSrc: '/path/shield.png',   // for targets without a photo
       perSide: 2,
     });

   Hover targets carry data-polaroid-src / data-polaroid-caption; JS
   builds the wings. Wings render only for fine pointers >=1240px wide
   and never intercept clicks. Reduced-motion falls back to a fade.
   ===================================================================== */
.ehs-polaroid {
  --polaroid-w: 212px;
  margin: 0;
  width: var(--polaroid-w);
  padding: 9px 9px 38px;
  background: #fdfdfb;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 2px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28), 0 1px 3px rgba(0, 0, 0, 0.15);
}
.ehs-polaroid img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  background: #e9e4da;
}
.ehs-polaroid--placeholder img {
  object-fit: contain;
  padding: 18%;
  box-sizing: border-box;
}
.ehs-polaroid figcaption {
  margin-top: 9px;
  text-align: center;
  font-family: var(--ehs-font-body);
  font-style: italic;
  font-size: 13px;
  letter-spacing: 0.02em;
  color: #4a4234;
}
.ehs-polaroid-wing {
  position: fixed;
  top: 0;
  bottom: 0;
  width: var(--polaroid-w, 212px);
  display: none;
  z-index: 1; /* under shared chrome: appbar is z50, .ehs-appfooter z20 */
  pointer-events: none;
}
.ehs-polaroid-wing--left  { left: 0; }
.ehs-polaroid-wing--right { right: 0; }
@media (hover: hover) and (pointer: fine) and (min-width: 1240px) {
  .ehs-polaroid-wing { display: block; }
}
.ehs-polaroid-wing .ehs-polaroid {
  position: absolute;
  top: var(--peek-top, 40%);
  rotate: var(--tilt, -5deg);
  transition:
    translate 560ms cubic-bezier(0.30, 1.25, 0.40, 1),
    rotate    560ms cubic-bezier(0.30, 1.25, 0.40, 1),
    top       560ms cubic-bezier(0.30, 1.25, 0.40, 1),
    box-shadow 560ms ease;
  transition-delay: var(--delay, 0ms);
  will-change: translate, rotate, top;
}
/* --peek = how far off-screen a photo rests (set per-fig by JS for variance) */
.ehs-polaroid-wing--left  .ehs-polaroid { left: 0;  translate: calc(var(--peek, 65%) * -1) 0; }
.ehs-polaroid-wing--right .ehs-polaroid { right: 0; translate: var(--peek, 65%) 0; }
/* Slid-in photos move to dedicated slots (--in-top, set by JS) so a
   target's polaroids fan out down the rail instead of piling up */
.ehs-polaroid-wing--left  .ehs-polaroid.is-in { translate: 18% 0; }
.ehs-polaroid-wing--right .ehs-polaroid.is-in { translate: -18% 0; }
.ehs-polaroid-wing .ehs-polaroid.is-in {
  top: var(--in-top, var(--peek-top, 40%));
  rotate: calc(var(--tilt, -5deg) * 0.55);
  z-index: 10;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.35), 0 2px 6px rgba(0, 0, 0, 0.18);
}
@media (prefers-reduced-motion: reduce) {
  .ehs-polaroid-wing .ehs-polaroid {
    transition: opacity 200ms ease-out;
    opacity: 0;
  }
  .ehs-polaroid-wing .ehs-polaroid.is-in { opacity: 1; }
}

/* Inline variant — a small tilted polaroid INSIDE content (e.g. a program
   card) for the viewports the wings don't serve: touch devices and narrow
   screens. Complement of the wing gate above, so exactly one of the two
   presentations is ever visible. Float-right so text wraps around it. */
.ehs-polaroid--inline {
  display: none;
  --polaroid-w: 108px;
  float: right;
  padding: 6px 6px 20px;
  margin: 0 0 6px 12px;
  rotate: 4deg;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.22), 0 1px 2px rgba(0, 0, 0, 0.12);
}
/* Alternate tilt when the CONTAINING element is even (one polaroid per card) */
*:nth-child(even) > .ehs-polaroid--inline { rotate: -4deg; }
@media (hover: none), (pointer: coarse), (max-width: 1239.98px) {
  .ehs-polaroid--inline { display: block; }
}

/* Strip variant — a row of ~4 small overlapping polaroids inside content
   (e.g. across a program card) for the same viewports as --inline. Children
   are plain .ehs-polaroid figures; the strip sizes and tilts them. */
.ehs-polaroid-strip {
  display: none;
  justify-content: center;
  align-items: flex-start;
  padding: 4px 2px;
}
.ehs-polaroid-strip .ehs-polaroid {
  --polaroid-w: auto;
  width: 26%;
  min-width: 62px;
  padding: 5px 5px 16px;
  margin: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.20), 0 1px 2px rgba(0, 0, 0, 0.10);
}
.ehs-polaroid-strip { gap: 10px; }
.ehs-polaroid-strip .ehs-polaroid { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.ehs-polaroid-strip .ehs-polaroid:nth-child(odd)  { rotate: -5deg; }
.ehs-polaroid-strip .ehs-polaroid:nth-child(even) { rotate: 4deg; translate: 0 7px; }
.ehs-polaroid-strip .ehs-polaroid:nth-child(3)    { rotate: 6deg; translate: 0 -2px; }

/* Scatter variant — polaroids interleaved through content, floated on
   alternating sides so text wraps around them and the photos cascade down
   the whole section instead of clustering in one row. Same viewports as
   the strip. Tap-to-zoom applies (ehs-polaroid.js). Give the containing
   block a clearfix (::after { clear: both }). */
figure.ehs-polaroid--scatter {
  display: none;
  --polaroid-w: 116px;
  width: var(--polaroid-w);
  padding: 6px 6px 18px;
  margin: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.20), 0 1px 2px rgba(0, 0, 0, 0.10);
}
figure.ehs-polaroid--scatter:nth-of-type(4n + 1) { float: right; rotate: 5deg;  margin: -2px -6px 8px 14px; }
figure.ehs-polaroid--scatter:nth-of-type(4n + 2) { float: left;  clear: right; rotate: -6deg; margin: 4px 14px 8px -6px; }
figure.ehs-polaroid--scatter:nth-of-type(4n + 3) { float: right; clear: both;  rotate: 4deg;  margin: 4px -4px 8px 14px; width: calc(var(--polaroid-w) * 0.9); }
figure.ehs-polaroid--scatter:nth-of-type(4n)     { float: left;  clear: both;  rotate: -4deg; margin: 4px 14px 2px -2px; width: calc(var(--polaroid-w) * 0.95); }
@media (hover: none), (pointer: coarse), (max-width: 1239.98px) {
  figure.ehs-polaroid--scatter { display: block; }
}

/* Tap-to-zoom viewer — a polaroid lightbox. Built by ehs-polaroid.js when a
   strip polaroid is tapped; tapping anywhere (or Esc) closes it. */
.ehs-polaroid-viewer {
  position: fixed;
  inset: 0;
  z-index: 1300; /* above app chrome + sticky bars, below system toasts */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  background: rgba(35, 31, 32, 0.74); /* dominican black scrim */
  opacity: 0;
  transition: opacity 240ms ease-out;
  cursor: pointer;
}
.ehs-polaroid-viewer.is-open { opacity: 1; }
.ehs-polaroid-viewer .ehs-polaroid {
  --polaroid-w: min(78vw, 420px);
  width: var(--polaroid-w);
  padding: 12px 12px 52px;
  margin: 0;
  rotate: -9deg;
  scale: 0.35;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.5), 0 4px 12px rgba(0, 0, 0, 0.3);
  transition:
    scale 420ms cubic-bezier(0.30, 1.25, 0.40, 1),
    rotate 420ms cubic-bezier(0.30, 1.25, 0.40, 1);
}
.ehs-polaroid-viewer.is-open .ehs-polaroid { scale: 1; rotate: -1.5deg; }
.ehs-polaroid-viewer figcaption { font-size: 17px; margin-top: 14px; }
@media (prefers-reduced-motion: reduce) {
  .ehs-polaroid-viewer .ehs-polaroid { transition: none; scale: 1; rotate: -1.5deg; }
}
@media (hover: none), (pointer: coarse), (max-width: 1239.98px) {
  .ehs-polaroid-strip { display: flex; }
}

/* =====================================================================
   DASHBOARD WIDGETS — the .ehs-dash-* family (per-user dashboard backbone)
   ---------------------------------------------------------------------
   A small, composable widget kit for the gated /dashboard preview and any
   future app dashboard: a responsive grid, a widget card shell (header /
   body / footer), a grid-sized stat tile, a list widget, and empty +
   skeleton (degraded / loading) states. Additive — new class names only,
   tokens only (both themes flip via --ehs-*), no hardcoded hex.

   Width: .ehs-dash-grid is width:100% and lives INSIDE the shared page
   column (.ehs-content), so it inherits — "respects" — the one global
   --ehs-page-max cap + --ehs-gutter without re-capping (avoids a double
   gutter). Internal gap is --ehs-s4.
   ===================================================================== */

/* ---- Responsive grid (3-col desktop → 2 → 1) ---------------------- */
.ehs-dash-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--ehs-s4);
  width: 100%;
  align-items: stretch;   /* equal-height cells per row */
}
.ehs-dash-grid__item { min-width: 0; }          /* let long content shrink, never overflow */
.ehs-dash-grid__item--span-2 { grid-column: span 2; }
.ehs-dash-grid__item--span-3 { grid-column: span 3; }
/* span-4 is meaningful only when a page widens the grid to 4 columns (the
   dashboard's desktop fit mode); on the default 3-col grid it clamps to 3. */
.ehs-dash-grid__item--span-4 { grid-column: span 3; }
@media (min-width: 1280px) {
  .ehs-dash-grid__item--span-4 { grid-column: span 4; }
}
@media (max-width: 900px) {
  .ehs-dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ehs-dash-grid__item--span-2,
  .ehs-dash-grid__item--span-3,
  .ehs-dash-grid__item--span-4 { grid-column: span 2; }
}
@media (max-width: 600px) {
  .ehs-dash-grid { grid-template-columns: minmax(0, 1fr); }
  .ehs-dash-grid__item--span-2,
  .ehs-dash-grid__item--span-3,
  .ehs-dash-grid__item--span-4 { grid-column: span 1; }
}

/* ---- Widget card shell (header / body / footer) ------------------- */
.ehs-dash-card {
  display: flex;
  flex-direction: column;
  height: 100%;                 /* fill the equal-height grid cell */
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule);
  border-radius: var(--ehs-r-lg);
  box-shadow: var(--ehs-shadow-sm);
  overflow: hidden;
}
.ehs-dash-card__header {
  display: flex; align-items: center; gap: var(--ehs-s3);
  padding: var(--ehs-s3) var(--ehs-s4);
  border-bottom: 1px solid var(--ehs-rule);
}
.ehs-dash-card__title {
  margin: 0;
  font-family: var(--ehs-font-display);
  font-size: 15px; font-weight: 700; line-height: 1.25;
  color: var(--ehs-ink);
}
.ehs-dash-card__actions {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: var(--ehs-s1);
}
.ehs-dash-card__body { flex: 1; padding: var(--ehs-s4); }
.ehs-dash-card__footer {
  display: flex; align-items: center; gap: var(--ehs-s2);
  padding: var(--ehs-s3) var(--ehs-s4);
  border-top: 1px solid var(--ehs-rule);
  font-size: 13px; color: var(--ehs-muted);
}

/* ---- Stat tile (grid-sized; visually consistent with .ehs-stat) --- */
.ehs-dash-stat { display: flex; flex-direction: column; gap: 2px; }
.ehs-dash-stat__value {
  font-family: var(--ehs-font-display);
  font-size: 30px; font-weight: 700; line-height: 1.1;
  color: var(--ehs-ink);
}
.ehs-dash-stat__label {
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  font-weight: 700; color: var(--ehs-muted);
}
.ehs-dash-stat__delta { font-size: 12px; font-weight: 600; color: var(--ehs-muted); }
.ehs-dash-stat__delta--up   { color: var(--ehs-ok); }
.ehs-dash-stat__delta--down { color: var(--ehs-bad); }

/* ---- List widget (events, links) --------------------------------- */
.ehs-dash-list { list-style: none; margin: 0; padding: 0; }
.ehs-dash-list__item {
  display: flex; align-items: center; gap: var(--ehs-s3);
  padding: var(--ehs-s3) 0;
}
.ehs-dash-list__item:first-child { padding-top: 0; }
.ehs-dash-list__item:last-child  { padding-bottom: 0; }
.ehs-dash-list__item + .ehs-dash-list__item { border-top: 1px solid var(--ehs-rule); }
.ehs-dash-list__primary {
  flex: 1; min-width: 0;
  font-size: 14px; font-weight: 600; color: var(--ehs-ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ehs-dash-list__meta {
  flex-shrink: 0;
  font-size: 12px; color: var(--ehs-muted); font-family: var(--ehs-font-mono);
}
/* Link rows (e.g. Quick Links) — anchor variant, hover lifts the label. */
a.ehs-dash-list__item { text-decoration: none; color: inherit; }
a.ehs-dash-list__item:hover .ehs-dash-list__primary { color: var(--ehs-accent-text); }

/* ---- Empty / degraded state ("No data right now") ---------------- */
.ehs-dash-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--ehs-s2); min-height: 120px;
  padding: var(--ehs-s6) var(--ehs-s4);
  text-align: center; color: var(--ehs-muted);
}
.ehs-dash-empty__icon { font-size: 30px; line-height: 1; opacity: .55; }
.ehs-dash-empty__msg { font-size: 13px; color: var(--ehs-muted); max-width: 34ch; }

/* ---- Skeleton (loading) state ------------------------------------ */
.ehs-dash-skeleton { display: flex; flex-direction: column; gap: var(--ehs-s3); }
.ehs-dash-skeleton__line {
  height: 12px; border-radius: var(--ehs-r-sm);
  background: var(--ehs-rule);
}
.ehs-dash-skeleton__line--sm { width: 40%; }
.ehs-dash-skeleton__line--md { width: 65%; }
.ehs-dash-skeleton__line--lg { width: 90%; }
/* --pulse: shimmer sweep. Motion-off users get a static placeholder. */
.ehs-dash-skeleton--pulse .ehs-dash-skeleton__line {
  background: linear-gradient(90deg, var(--ehs-rule) 25%, var(--ehs-cream) 50%, var(--ehs-rule) 75%);
  background-size: 200% 100%;
  animation: ehs-dash-shimmer 1.3s ease-in-out infinite;
}
@keyframes ehs-dash-shimmer { to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) {
  .ehs-dash-skeleton--pulse .ehs-dash-skeleton__line { animation: none; }
}

/* =====================================================================
   TABGROUP — grouped dropdown-tabs (additive, 2026-07-25)
   A horizontal bar where each item is EITHER a single link/tab OR a
   disclosure that reveals a menu of sub-links, e.g.
       [ Box office ] [ Sell ▾ ] [ Money ▾ ] [ Setup ▾ ] [ Will-call ]

   Mechanism is CSS-only and JS-optional: dropdowns are native
   <details>/<summary> disclosures, so open/close works with zero
   JavaScript and zero additions to the shared chrome loader. Give every
   <details> in one bar the SAME `name=""` and the browser makes them an
   exclusive group (opening one closes the others) — again, no JS.

   Visual language matches .ehs-tabs (muted text, maroon active tab with a
   maroon bottom-border indicator) and the dropdown panel matches .ehs-menu
   (paper surface, rule border, shadow-lg). All colours are --ehs-* tokens,
   so light/dark flip automatically — no hardcoded hex.

   Escape-to-close and outside-click-close are NOT native to <details>;
   they are an OPTIONAL ~12-line progressive-enhancement snippet documented
   in the demo + README. The component is fully usable (closed → open →
   closed) without it. Do not add that snippet to the shared loader.

   State hook is the native [open] attribute (mirrored by an optional
   .ehs-tabgroup__group--open class for JS-driven callers).
   z-index 60 = the shared "menu" tier (above appbar 50 / subnav 40).
   ===================================================================== */
.ehs-tabgroup {
  display: flex; align-items: stretch; gap: 4px; flex-wrap: wrap;
  border-bottom: 2px solid var(--ehs-rule);
  font-family: var(--ehs-font-body);
}

/* A dropdown item wraps its trigger + menu; single tabs need no wrapper. */
.ehs-tabgroup__group { position: relative; display: inline-flex; }

/* Shared tab look for BOTH the plain <a> tabs and the <summary> triggers. */
.ehs-tabgroup__tab {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  font-size: 14px; font-weight: 600; color: var(--ehs-muted);
  padding: 10px 16px; cursor: pointer;
  background: none; border: none; border-bottom: 2px solid transparent;
  margin-bottom: -2px; text-decoration: none;
  transition: color .15s ease, border-color .15s ease;
}
.ehs-tabgroup__tab:hover { color: var(--ehs-ink); }
.ehs-tabgroup__tab--active { color: var(--ehs-accent-text); border-bottom-color: var(--ehs-maroon); }
.ehs-tabgroup__tab:focus-visible {
  outline: 2px solid var(--ehs-focus); outline-offset: -2px;
  border-radius: var(--ehs-r-sm);
}

/* <summary> as a trigger: kill the native disclosure marker + list bullet. */
summary.ehs-tabgroup__tab { list-style: none; -webkit-user-select: none; user-select: none; }
summary.ehs-tabgroup__tab::-webkit-details-marker { display: none; }
summary.ehs-tabgroup__tab::marker { content: ""; }

/* Caret flips when the disclosure is open. */
.ehs-tabgroup__caret {
  width: 12px; height: 12px; flex: none; color: currentColor; opacity: .7;
  transition: transform .15s ease;
}
.ehs-tabgroup__group[open] > .ehs-tabgroup__tab,
.ehs-tabgroup__group--open > .ehs-tabgroup__tab { color: var(--ehs-ink); }
.ehs-tabgroup__group[open] .ehs-tabgroup__caret,
.ehs-tabgroup__group--open .ehs-tabgroup__caret { transform: rotate(180deg); }

/* Dropdown panel — mirrors .ehs-menu; hidden by the UA when <details> is
   closed, shown (and absolutely positioned) when open. */
.ehs-tabgroup__menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 60;
  min-width: 200px; padding: 6px;
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule); border-radius: var(--ehs-r-md);
  box-shadow: var(--ehs-shadow-lg);
}
.ehs-tabgroup__menu--right { left: auto; right: 0; }
/* Explicit hide so JS-driven --open callers (no [open] attr) behave too. */
.ehs-tabgroup__group:not([open]):not(.ehs-tabgroup__group--open) .ehs-tabgroup__menu { display: none; }

.ehs-tabgroup__item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  text-align: left; white-space: nowrap;
  padding: 8px 10px; border: none; background: none; cursor: pointer;
  border-radius: var(--ehs-r-sm);
  font-family: var(--ehs-font-body); font-size: 14px;
  color: var(--ehs-ink); text-decoration: none;
}
.ehs-tabgroup__item:hover { background: var(--ehs-cream); }
.ehs-tabgroup__item:focus-visible { outline: 2px solid var(--ehs-focus); outline-offset: -2px; }
.ehs-tabgroup__item--active { color: var(--ehs-accent-text); font-weight: 600; }
.ehs-tabgroup__item--danger { color: var(--ehs-bad); }
.ehs-tabgroup__item .key { margin-left: auto; font-family: var(--ehs-font-mono); font-size: 11px; color: var(--ehs-muted); }
.ehs-tabgroup__sep { height: 1px; border: 0; background: var(--ehs-rule); margin: 6px 4px; }

/* Push trailing tabs to the right edge (e.g. a final [ Will-call ] action). */
.ehs-tabgroup__spacer { margin-left: auto; }

@media (prefers-reduced-motion: reduce) {
  .ehs-tabgroup__tab, .ehs-tabgroup__caret { transition: none; }
}

/* ---- Segmented control: radio variant ------------------------------
   The button-based .ehs-segmented above is for view switching (JS reads the
   click). Inside a form the same shape has to carry a real <input type=radio>
   so it submits, tabs, and announces as a single-choice group. Markup:

     <div class="ehs-segmented ehs-segmented--radio" role="radiogroup">
       <label class="ehs-segmented__opt"><input type="radio" name="x"> All day</label>
       ...
     </div>

   The input is transparent and stretched over its own label, so the whole
   segment is the hit target and focus stays on a real control. Checked state
   is driven by :has(); callers that also toggle .ehs-segmented__opt--active
   (belt and braces on older engines) get the identical result. */
.ehs-segmented--radio { display: flex; width: 100%; }
.ehs-segmented--radio .ehs-segmented__opt {
  flex: 1 1 0;
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  min-height: 38px;
  text-align: center;
  line-height: 1.25;
}
.ehs-segmented--radio .ehs-segmented__opt input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.ehs-segmented--radio .ehs-segmented__opt--active,
.ehs-segmented--radio .ehs-segmented__opt:has(input:checked) {
  background: var(--ehs-paper); color: var(--ehs-accent-text); box-shadow: var(--ehs-shadow-sm);
}
.ehs-segmented--radio .ehs-segmented__opt:has(input:focus-visible) {
  outline: 2px solid var(--ehs-focus); outline-offset: -1px;
}
/* Three long labels do not fit a phone's width. Stack instead of shrinking the
   text, so the tap targets stay full-width. */
@media (max-width: 520px) {
  .ehs-segmented--radio { flex-direction: column; }
}

/* ---- Day picker ----------------------------------------------------
   One card per calendar day for "which days are you here, and for how much of
   the day". Built for multi-day events (bootcamps, retreats, tournaments)
   where three separate radios — attending / arriving late / leaving early —
   let a respondent give a self-contradicting answer. Here the day is the unit,
   so partial attendance is a state of that day and the times belong to it.

     <div class="ehs-daypick">
       <div class="ehs-daypick__day">
         <div class="ehs-daypick__when">
           <span class="ehs-daypick__label">Saturday, August 1</span>
           <span class="ehs-daypick__window">8:00 AM – 4:00 PM</span>
         </div>
         <div class="ehs-segmented ehs-segmented--radio">…</div>
         <div class="ehs-daypick__times">        <!-- add `hidden` when full-day -->
           <label class="ehs-field"><span class="ehs-label">I arrive</span>
             <input class="ehs-input" type="time"></label>
           <label class="ehs-field"><span class="ehs-label">I leave</span>
             <input class="ehs-input" type="time"></label>
         </div>
       </div>
     </div> */
.ehs-daypick { display: flex; flex-direction: column; gap: var(--ehs-s2); }
.ehs-daypick__day {
  display: flex; flex-direction: column; gap: var(--ehs-s2);
  background: var(--ehs-paper);
  border: 1px solid var(--ehs-rule-strong);
  border-radius: var(--ehs-r-md);
  padding: 14px var(--ehs-s4);   /* matches .ehs-choice-card so the two card types agree */
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ehs-daypick__day--answered { border-color: var(--ehs-gold-deep); }
.ehs-daypick__day--bad { border-color: var(--ehs-bad); box-shadow: 0 0 0 3px rgba(178,58,46,.12); }
/* Declined day: still legible, visibly out of play. */
.ehs-daypick__day--off { background: var(--ehs-sunken); }
.ehs-daypick__day--off .ehs-daypick__label { color: var(--ehs-muted); }

.ehs-daypick__when { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ehs-s1) var(--ehs-s3); }
.ehs-daypick__label { font-size: 15px; font-weight: 700; color: var(--ehs-ink); }
.ehs-daypick__window { font-family: var(--ehs-font-mono); font-size: 12px; color: var(--ehs-muted); }

.ehs-daypick__times {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--ehs-s3);
  padding-top: var(--ehs-s2);
  border-top: 1px dashed var(--ehs-rule-strong);
}
.ehs-daypick__note { font-size: 12px; color: var(--ehs-muted); grid-column: 1 / -1; }
