  /* Google Fonts live in the page <head> as <link rel="stylesheet"> (Sep 16 2026 Core Web Vitals pass):
     a <link> is discovered and fetched IN PARALLEL with this file, where an `@import` here had to wait
     for the stylesheet to download and parse before the font request could even start. The URL keeps
     `&display=swap` (font-display: swap), so text paints in the fallback face immediately instead of
     flashing invisible. CSP already allows both hosts at deploy (style-src https://fonts.googleapis.com,
     font-src https://fonts.gstatic.com — see src/deploy/headers.*.conf). */
  :root {
    --header-h: 66.375px;
    --tab-h: 2.8125rem;
    --tabbar-gap: 0.6875rem;
    --font-primary: 'Oswald', 'Arial Narrow', sans-serif;
    --font-secondary: 'Roboto', 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    --primary: #6699CC;
    --primary-light: #85B5DD;
    --primary-dark: #4A7AAF;
  /* AA text variant of the brand blue (Sep 16 2026 a11y pass): #6699CC is 3.0:1 on white, so it can't
     carry normal-size text — #45729E is 5.06:1 on white. Use --primary for graphics/large type and
     --primary-text for small text on light backgrounds. */
  --primary-text: #45729E;
    --card-accent: rgba(102,153,204,0.35);
    --chip-bg: rgba(102,153,204,0.22);
    --chip-gray: #6E7480;
    --chip-gray-dark: #5D6470;
    --secondary: #00204E;
    --secondary-dark: #001433;
    --ws-bg: #EFF2F6;
    --ws-line: #C9CDD3;
    --ws-ink: #2F5284;
    --ws-ink-2: #274570;
    --ws-muted: #64748B;
    --ws-hover: #F2F4F7;
    --ws-danger: #DC2626;
    /* "Pay My Bill" urgency (src/BILLING-SCOPE.md → "The button's states"). A SEMANTIC ALIAS rather
       than the danger token used directly: red here means "money is owed now", not "destructive", and
       the two meanings should be free to diverge later without a hunt. */
    --pay-due: #DC2626;
    --pay-due-dark: #B91C1C;
    --secondary-light: #013a7a;
    --light-gray: #E8EAED;
    --gray: #8A8F98;
    --dark-gray: #2D2D2D;
    --gray-text: #555;
    --white: #FFFFFF;
  }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  [hidden] { display: none !important; }
  html {
    overflow-x: clip;
    scrollbar-gutter: stable;
    font-size: clamp(16px, 1.434vw, 18px);
  }
  body {
    font-family: var(--font-secondary);
    color: var(--dark-gray);
    text-align: left;
    background: var(--white);
    line-height: 1.6;
    position: relative;
    overflow-x: clip;
  }
  h1, h2, h3, h4, h5, h6,
  .nav-links a, .nav-cta, .hamburger,
  .btn-primary, .btn-outline, .btn-outline-dark, .btn-outline-white, .modal-btn,
  .pt-eyebrow, .program-eyebrow, .tab, .tab-btn, .roster-table th,
  .footer-col h5, .dash-stat-value {
    font-family: var(--font-primary);
  }
  .section.dark, .hero, .cta-band, .rosters-hero {
    position: relative;
  }
  .section.dark > *, .hero > *, .cta-band > *, .rosters-hero > * {
    position: relative;
    z-index: 1;
  }

  /* ---------- Header ---------- */
  header {
    background: var(--white);
    border-bottom: 2.25px solid var(--secondary);
    position: sticky;
    top: 0;
    z-index: 100;
  }
  .nav-scrim {
    position: fixed;
    inset: 0;
    background: rgba(8,20,42,0.85);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.08s ease;
    z-index: 90;
  }
  .nav-scrim.visible { opacity: 1; pointer-events: auto; }
  .nav-wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4.5625px clamp(1.5rem, 3vw, 4.5rem);
    position: relative;
    z-index: 2;
    transform: translateZ(0);
  }
  .logo {
    display: flex;
    align-items: center;
    gap: 11.25px;
    font-size: 29.25px;
    font-weight: 800;
    color: var(--secondary);
    letter-spacing: 0.5634px;
    text-decoration: none;
    transition: opacity 0.3s ease, filter 0.3s ease;
    flex-shrink: 0;
  }
  .logo > span {
    font-family: 'Bitter', Georgia, serif;
    font-weight: 800;
    letter-spacing: 2.25px;
    text-transform: uppercase;
  }
  .logo .logo-stack {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 0.95;
  }
  .logo .logo-top {
    font-family: 'Bitter', Georgia, serif;
    font-weight: 800;
    font-size: 33.75px;
    letter-spacing: 2.25px;
    text-transform: uppercase;
    line-height: 0.95;
    transform: translateY(1.5px);
  }
  .logo .logo-bottom {
    font-family: 'Bitter', Georgia, serif;
    font-weight: 700;
    font-size: 17.64px;
    letter-spacing: 1.125px;
    text-transform: uppercase;
    color: var(--primary);
    line-height: 0.95;
    transform: translateY(-1.5px);
  }
  .logo-icon {
    width: 55px; height: 55px;
    background: var(--secondary);
    border-radius: 50%;
    overflow: hidden;
    display: flex; align-items: center; justify-content: center;
    color: var(--white); font-size: 20.625px;
    flex-shrink: 0;
  }
  .logo-icon .logo-img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: cover;
    display: block;
    transform: translateY(-1px);
  }
  nav {
    flex: 1;
    display: flex;
    justify-content: center;
  }
  .nav-links {
    display: flex; gap: 40.5px; list-style: none;
    position: fixed;
    left: 50%;
    top: calc(var(--header-h) / 2);
    transform: translate(-50%, -50%);
    z-index: 5;
    width: max-content;
  }
  #drawerLogout, #drawerMyDashboard { display: none; }
  .nav-panel-title { display: none; }
  .nav-panel-footer { display: none; }
  .nav-links a {
    text-decoration: none;
    color: var(--dark-gray);
    font-weight: 600;
    font-size: 19.125px;
    letter-spacing: 0.5634px;
    line-height: 1;
    transition: color 0.2s;
    position: relative;
  }
  .nav-links a:hover { color: var(--primary); }
  .nav-links a::after {
    content: "";
    position: absolute;
    bottom: -5.625px; left: 15%; right: 15%;
    height: 2.25px;
    background: var(--primary);
    border-radius: 2.25px;
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .nav-links a:hover::after { transform: scaleX(1); }
  .nav-cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6.75px;
    background: transparent;
    color: var(--secondary) !important;
    border: 2.25px solid var(--secondary);
    padding: 7.875px 20.25px;
    border-radius: 6.75px;
    font-weight: 700;
    font-size: 15.75px;
    text-decoration: none;
    transition: background 0.2s, color 0.2s;
    flex-shrink: 0;
  }
  .nav-cta .nav-cta-text {
    font-family: var(--font-primary);
    font-size: 15.75px;
    font-weight: 700;
  }
  .nav-cta .nav-cta-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    vertical-align: middle;
    font-size: 24.75px;
  }
  .nav-cta .nav-cta-icon svg {
    width: 1em;
    height: 1em;
    display: block;
  }
  @media (min-width: 981px) {
    .nav-cta { padding: 7.875px 18px; }
  }
  .nav-portal.is-logged-in .nav-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 51.75px;
    height: 51.75px;
    padding: 0;
    border-radius: 9px;
    font-size: 22.5px;
  }
  .nav-portal.is-logged-in .nav-cta .nav-cta-text { display: none; }
  .nav-portal.is-logged-in .nav-cta-icon { line-height: 1; font-size: 29.25px; transform: none; }
  .nav-cta:hover { background: var(--secondary); color: var(--white) !important; }
  .nav-actions {
    display: flex;
    align-items: center;
    flex-shrink: 0;
  }
  .nav-portal { position: relative; flex-shrink: 0; display: flex; align-items: center; gap: 13.5px; }
  .nav-portal .nav-user[hidden] { display: none !important; }
  .nav-user {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    flex-shrink: 0;
    line-height: 1.2;
  }
  .nav-user-name {
    font-family: var(--font-primary);
    font-weight: 600;
    font-size: 18px;
    letter-spacing: 0.5634px;
    color: var(--secondary);
    text-decoration: none;
    white-space: nowrap;
    max-width: 202.5px;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .nav-user-name:hover { color: var(--primary); }
  .nav-user-logout {
    font-family: var(--font-primary);
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: 0.9px;
    text-transform: uppercase;
    color: var(--gray-text);
    text-decoration: none;
    border-bottom: 1.125px solid rgba(0,32,78,0.3);
    line-height: 1.3;
  }
  .nav-user-logout:hover { color: var(--primary); border-bottom-color: var(--primary); }
  .hamburger {
    display: none;
    align-items: center;
    justify-content: center;
    position: relative;
    width: 51.75px;
    height: 51.75px;
    border: 2.25px solid var(--secondary);
    border-radius: 9px;
    background: var(--secondary);
    color: var(--white) !important;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.2s, color 0.2s, transform 0.15s;
  }
  .hamburger:hover { background: var(--secondary-light); border-color: var(--secondary-light); }
  .hamburger.open { background: transparent; color: var(--secondary) !important; }
  .hamburger.open:hover { background: var(--secondary); border-color: var(--secondary); color: var(--white) !important; }
  .hamburger:active { transform: scale(0.95); }
  .hamburger .ham-line {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 24.75px;
    height: 2.7px;
    border-radius: 1123.875px;
    background: currentColor;
    transform: translate(-50%, -50%);
    transition: transform 0.2s ease, opacity 0.2s ease;
  }
  .hamburger .ham-line:nth-child(1) { transform: translate(-50%, calc(-50% - 6.1884px)); }
  .hamburger .ham-line:nth-child(3) { transform: translate(-50%, calc(-50% + 6.1884px)); }
  .hamburger.open .ham-line:nth-child(1) { transform: translate(-50%, -50%) rotate(45deg); }
  .hamburger.open .ham-line:nth-child(2) { opacity: 0; }
  .hamburger.open .ham-line:nth-child(3) { transform: translate(-50%, -50%) rotate(-45deg); }

  /* ---------- Hero ---------- */
  .hero {
    background: var(--secondary);
    color: var(--white);
    min-height: min(calc(100vh - var(--header-h)), 38rem);
    padding: 0 1.5rem;
    text-align: center;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    container-type: size;
  }
  .hero > * { position: relative; z-index: 2; }
  /* Content-driven (Sep 2026): headlines are stored in normal case and uppercased
     here, so an admin-typed headline always renders all-caps. Sizing uses the
     hero as a size container (cqw = width, cqh = height): the cqh bound keeps
     short-landscape phones from overflowing while desktop widths all settle at
     the same 5.5rem cap — a fixed, consistent look at every desktop size. */
  .hero h1 {
    font-size: clamp(2.25rem, min(15vw, 14vh), 5.5rem);
    font-size: clamp(2.25rem, min(15cqw, 16cqh), 5.5rem);
    font-weight: 900;
    margin: 0 0 clamp(1rem, 3vh, 1.75rem);
    letter-spacing: -0.0312rem;
    line-height: 1.1;
    text-transform: uppercase;
  }
  .hero p {
    font-size: clamp(1.125rem, min(3vw, 6vh), 1.5rem);
    font-size: clamp(1.125rem, min(3cqw, 6cqh), 1.5rem);
    max-width: min(38rem, 80vw);
    margin: 0 auto clamp(1.75rem, 5vh, 3rem);
    opacity: 0.92;
  }
  #heroSlides {
    position: absolute;
    inset: 0;
  }
  .hero-slide {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: clamp(1.5rem, 4vh, 3rem) clamp(1.25rem, 4vw, 2rem);
    /* Image comes from the slide's inline --img custom property (landscape is
       the default; a --portrait-img variant swaps in on portrait phones below). */
    background-image: var(--img, none);
    background-size: cover;
    background-position: center;
    opacity: 0;
    visibility: hidden;
    transform: translateY(1.125rem);
    animation: heroCycle 40s linear infinite;
  }
  
  .hero-slide::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%);
  }
  .hero-slide > * { position: relative; z-index: 1; width: 100%; max-width: 68.75rem; }
  /* Portrait variant content (JAMIE, Sep 2026): each slide carries TWO inners —
     landscape (default, shown everywhere) and a portrait override shown only on
     portrait phones (and the admin portrait preview), via the has-portrait
     media swaps further down. Blank portrait fields fall back to landscape at
     render time, so the portrait inner may equal the landscape inner. */
  .hero-slide-inner { width: 100%; max-width: 68.75rem; }
  .hero-slide-inner-portrait { display: none; }
  /* Desktop-variant inner (JAMIE, Sep 2026): shown only on the desktop layout
     (fine-pointer screens ≥1280px, plus the admin Desktop preview). A slide
     with desktop content carries BOTH the landscape inner and this one; the
     desktop media query below swaps them, and blank desktop fields fall back
     to landscape at render time. */
  .hero-slide-inner-desktop { display: none; }
  /* Tablet-variant inner (JAMIE, Oct 2026 — Global model): a slide with custom
     tablet copy carries this THIRD inner; the tablet band below (and the admin
     Tab-LG / Tab-SM previews) swaps it in, exactly like the portrait/desktop
     inners. Blank tablet fields fall back to the global copy at render time. */
  .hero-slide-inner-tablet { display: none; }
  /* Content Position (JAMIE, Sep 2026): per-slide horizontal anchoring of the
     whole content block (headline/sub/buttons), set from the Hero Slides
     editor — Auto (no class) / Force Left / Force Center. These BASE rules are
     the landscape layout — which covers Tab-LG AND Tab-SM, since those two
     tablet tabs edit this one shared value (JAMIE, Sep 2026). Portrait phones
     and the desktop layout each get their own cp-*-p / cp-*-d rules further
     down, so a context-specific value always outranks the inherited one
     (equal specificity → later in source wins).
     The scrim travels with the content: Force Left gets the desktop-style left
     gradient, Force Center the centered radial. Those ::before rules use
     :where() so they stay at ONE class of specificity — every explicit Overlay
     (ov-*, 2+ classes) still wins wherever it's set. An explicitly-set button
     row (bh-* / bph-* / dbv-…) also still wins: those rules are 3+ classes, these
     are 2. */
  .hero:not(.is-mini) .hero-slide.cp-left { align-items: flex-start; text-align: left; }
  .hero:not(.is-mini) .hero-slide.cp-left p { margin-left: 0; margin-right: auto; }
  .hero:not(.is-mini) .hero-slide.cp-center { align-items: center; text-align: center; }
  .hero:not(.is-mini) .hero-slide.cp-center p { margin-left: auto; margin-right: auto; }
  .hero:not(.is-mini) .cp-left .hero-btns { justify-content: flex-start; }
  .hero-slide:where(.cp-left)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  /* Overlay control (JAMIE, Sep 2026): per-slide strength of the default
     darkening scrim. These class rules out-specify the base ::before above AND
     the desktop left-scrim further down (2 classes > 1), so each level wins on
     every viewport. 'none' kills the scrim entirely (e.g. the shop slide). */
  .hero:not(.is-mini) .hero-slide.ov-none::before { background: none; }
  .hero:not(.is-mini) .hero-slide.ov-low::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.42) 0%, rgba(0,20,51,0.28) 60%, rgba(0,20,51,0.15) 100%); }
  .hero:not(.is-mini) .hero-slide.ov-high::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.85) 0%, rgba(0,20,51,0.66) 60%, rgba(0,20,51,0.48) 100%); }
  /* Desktop overlays mirror the left scrim shape at low/high strength. */
  @media (min-width: 1280px) and (hover: hover) and (pointer: fine) {
    .hero:not(.is-mini) .hero-slide.ov-low::before { background: linear-gradient(to right, rgba(0,20,51,0.5) 0%, rgba(0,20,51,0.32) 36%, rgba(0,20,51,0.1) 60%, rgba(0,20,51,0.02) 78%, rgba(0,20,51,0) 100%); }
    .hero:not(.is-mini) .hero-slide.ov-high::before { background: linear-gradient(to right, rgba(0,20,51,0.9) 0%, rgba(0,20,51,0.7) 36%, rgba(0,20,51,0.4) 60%, rgba(0,20,51,0.12) 78%, rgba(0,20,51,0) 100%); }
    /* Per-variant desktop overlay (JAMIE, Sep 2026): when a slide has its own
       desktop_overlay_level, it wins over the landscape overlay on desktop —
       scoped to the live hero so the admin mini-preview keeps its own rules. */
    .hero:not(.is-mini) .hero-slide.ov-d-none::before { background: none; }
    .hero:not(.is-mini) .hero-slide.ov-d-low::before { background: linear-gradient(to right, rgba(0,20,51,0.5) 0%, rgba(0,20,51,0.32) 36%, rgba(0,20,51,0.1) 60%, rgba(0,20,51,0.02) 78%, rgba(0,20,51,0) 100%); }
    .hero:not(.is-mini) .hero-slide.ov-d-high::before { background: linear-gradient(to right, rgba(0,20,51,0.9) 0%, rgba(0,20,51,0.7) 36%, rgba(0,20,51,0.4) 60%, rgba(0,20,51,0.12) 78%, rgba(0,20,51,0) 100%); }
  }
  @keyframes heroCycle {
    0%     { opacity: 0; visibility: hidden; transform: translateY(1.125rem); }
    1.5%   { opacity: 1; visibility: visible; transform: translateY(0); }
    21%    { opacity: 1; visibility: visible; transform: translateY(0); }
    25%    { opacity: 0; visibility: visible; transform: translateY(-1.125rem); }
    25.01% { visibility: hidden; }
    100%   { opacity: 0; visibility: hidden; transform: translateY(-1.125rem); }
  }
  @media (prefers-reduced-motion: reduce) {
    .hero-slide { animation: none; opacity: 1; visibility: visible; transform: none; }
    .hero-slide:not(:first-child) { opacity: 0; visibility: hidden; }
  }
  .hero-btns {
    display: flex; gap: clamp(0.75rem, 2vw, 1.25rem); justify-content: center; flex-wrap: wrap;
  }
  /* Manual CTA position (JAMIE, Sep 2026): when a vertical position is set the
     button row leaves the flow and is pinned to a spot on the slide; the
     horizontal setting aligns the buttons within the slide's content width.
     'auto' (no class) keeps the default flow layout (buttons follow the
     headline/subheading). Class names are full words: bv-top/middle/bottom +
     bh-left/center/right (landscape), bpv-* / bph-* (portrait). Portrait classes
     apply only where the portrait image actually shows (portrait phones below,
     admin portrait preview further down); everywhere else the landscape
     classes are in effect. */
  .hero-slide.bv-top .hero-btns,
  .hero-slide.bv-middle .hero-btns,
  .hero-slide.bv-bottom .hero-btns {
    position: absolute;
    z-index: 2;
    width: auto;
    max-width: none;
    left: clamp(1.25rem, 4vw, 2rem);
    right: clamp(1.25rem, 4vw, 2rem);
  }
  .hero-slide.bv-top .hero-btns { top: calc(clamp(1.5rem, 4vh, 3rem) - var(--cta-off-y, 0px)); }
  .hero-slide.bv-middle .hero-btns { top: calc(50% - var(--cta-off-y, 0px)); }
  .hero-slide.bv-bottom .hero-btns { bottom: calc(clamp(1.5rem, 4vh, 3rem) + var(--cta-off-y, 0px)); }
  /* Horizontal offset convention: + is ALWAYS right, - is ALWAYS left (matches
     vertical's "+ = up"). Implemented with transform:translateX so both
     directions work for every alignment (padding can't move a right-aligned row
     right). translateX on the button row is safe — its children are static, so
     no containing-block side effects. */
  .hero-slide.bh-left .hero-btns { justify-content: flex-start; transform: translateX(var(--cta-off-x, 0px)); }
  .hero-slide.bh-center .hero-btns { justify-content: center; transform: translateX(var(--cta-off-x, 0px)); }
  .hero-slide.bh-right .hero-btns { justify-content: flex-end; transform: translateX(var(--cta-off-x, 0px)); }
  /* Middle vertical centering uses translateY(-50%); when a horizontal offset is
     also set the two must combine. This rule comes AFTER the bh-* rules so it
     wins when both are present (equal specificity, later in source). */
  .hero-slide.bv-middle .hero-btns { transform: translate(var(--cta-off-x, 0px), -50%); }
  /* Tab-SM offset overrides (JAMIE, Sep 2026): the two tablet sizes now have
     their OWN nudge offsets — Tab-LG (≥1150px-wide coarse tablets) keeps the
     base --cta-off-x/-y above; the smaller Tab-SM band (<1150px) uses its own
     --cta-off-x-tsm/-y-tsm (emitted per-slide by apex-hero.js). Scoped to
     .hero:not(.is-mini) so the admin mini-preview (variant-controlled via its
     own data-variant rules below) is never hijacked when the editor window
     itself is a narrow coarse screen. Blank _tsm = 0 (no extra nudge), exactly
     like the _p portrait offsets. */
  @media (min-width: 900px) and (min-height: 500px) and (orientation: landscape) and (pointer: coarse) and (max-width: 1149px) {
    .hero:not(.is-mini) .hero-slide.bv-top .hero-btns { top: calc(clamp(1.5rem, 4vh, 3rem) - var(--cta-off-y-tsm, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.bv-middle .hero-btns { top: calc(50% - var(--cta-off-y-tsm, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.bv-bottom .hero-btns { bottom: calc(clamp(1.5rem, 4vh, 3rem) + var(--cta-off-y-tsm, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.bh-left .hero-btns { justify-content: flex-start; transform: translateX(var(--cta-off-x-tsm, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.bh-center .hero-btns { justify-content: center; transform: translateX(var(--cta-off-x-tsm, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.bh-right .hero-btns { justify-content: flex-end; transform: translateX(var(--cta-off-x-tsm, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.bv-middle .hero-btns { transform: translate(var(--cta-off-x-tsm, var(--cta-off-x, 0px)), -50%); }
    /* NO Content Position rules belong in this band: Tab-LG and Tab-SM are ONE
       setting (JAMIE, Sep 2026), so the base cp-* rules above already lay out
       the Tab-SM band and the cp-*-tsm class no longer exists. */
  }
  /* Manual CTA position — containing-block fix (JAMIE, Sep 2026): the pinned
     button row is position:absolute, so the SLIDE must be its containing block.
     But .hero-slide > * gives the inner position:relative, which becomes the
     containing block instead — pinning the buttons to the INNER's box (for an
     image-only slide that inner is ~0-height, so the button landed mid-slide).
     Making the inner static for manual-position slides fixes that; the text
     children then need their own z-index to stay above the scrim. */
  .hero-slide.bv-top .hero-slide-inner, .hero-slide.bv-top .hero-slide-inner-portrait,
  .hero-slide.bv-middle .hero-slide-inner, .hero-slide.bv-middle .hero-slide-inner-portrait,
  .hero-slide.bv-bottom .hero-slide-inner, .hero-slide.bv-bottom .hero-slide-inner-portrait,
  .hero-slide.bpv-top .hero-slide-inner, .hero-slide.bpv-top .hero-slide-inner-portrait,
  .hero-slide.bpv-middle .hero-slide-inner, .hero-slide.bpv-middle .hero-slide-inner-portrait,
  .hero-slide.bpv-bottom .hero-slide-inner, .hero-slide.bpv-bottom .hero-slide-inner-portrait,
  .hero-slide.dbv-top .hero-slide-inner, .hero-slide.dbv-top .hero-slide-inner-portrait, .hero-slide.dbv-top .hero-slide-inner-desktop,
  .hero-slide.dbv-middle .hero-slide-inner, .hero-slide.dbv-middle .hero-slide-inner-portrait, .hero-slide.dbv-middle .hero-slide-inner-desktop,
  .hero-slide.dbv-bottom .hero-slide-inner, .hero-slide.dbv-bottom .hero-slide-inner-portrait, .hero-slide.dbv-bottom .hero-slide-inner-desktop { position: static; }
  .hero-slide.bv-top .hero-slide-inner h1, .hero-slide.bv-top .hero-slide-inner p,
  .hero-slide.bv-middle .hero-slide-inner h1, .hero-slide.bv-middle .hero-slide-inner p,
  .hero-slide.bv-bottom .hero-slide-inner h1, .hero-slide.bv-bottom .hero-slide-inner p,
  .hero-slide.bv-top .hero-slide-inner-portrait h1, .hero-slide.bv-top .hero-slide-inner-portrait p,
  .hero-slide.bv-middle .hero-slide-inner-portrait h1, .hero-slide.bv-middle .hero-slide-inner-portrait p,
  .hero-slide.bv-bottom .hero-slide-inner-portrait h1, .hero-slide.bv-bottom .hero-slide-inner-portrait p,
  .hero-slide.bpv-top .hero-slide-inner h1, .hero-slide.bpv-top .hero-slide-inner p,
  .hero-slide.bpv-middle .hero-slide-inner h1, .hero-slide.bpv-middle .hero-slide-inner p,
  .hero-slide.bpv-bottom .hero-slide-inner h1, .hero-slide.bpv-bottom .hero-slide-inner p,
  .hero-slide.bpv-top .hero-slide-inner-portrait h1, .hero-slide.bpv-top .hero-slide-inner-portrait p,
  .hero-slide.bpv-middle .hero-slide-inner-portrait h1, .hero-slide.bpv-middle .hero-slide-inner-portrait p,
  .hero-slide.bpv-bottom .hero-slide-inner-portrait h1, .hero-slide.bpv-bottom .hero-slide-inner-portrait p,
  .hero-slide.dbv-top .hero-slide-inner h1, .hero-slide.dbv-top .hero-slide-inner p,
  .hero-slide.dbv-middle .hero-slide-inner h1, .hero-slide.dbv-middle .hero-slide-inner p,
  .hero-slide.dbv-bottom .hero-slide-inner h1, .hero-slide.dbv-bottom .hero-slide-inner p,
  .hero-slide.dbv-top .hero-slide-inner-portrait h1, .hero-slide.dbv-top .hero-slide-inner-portrait p,
  .hero-slide.dbv-middle .hero-slide-inner-portrait h1, .hero-slide.dbv-middle .hero-slide-inner-portrait p,
  .hero-slide.dbv-bottom .hero-slide-inner-portrait h1, .hero-slide.dbv-bottom .hero-slide-inner-portrait p,
  .hero-slide.dbv-top .hero-slide-inner-desktop h1, .hero-slide.dbv-top .hero-slide-inner-desktop p,
  .hero-slide.dbv-middle .hero-slide-inner-desktop h1, .hero-slide.dbv-middle .hero-slide-inner-desktop p,
  .hero-slide.dbv-bottom .hero-slide-inner-desktop h1, .hero-slide.dbv-bottom .hero-slide-inner-desktop p { position: relative; z-index: 1; }
  @media (min-width: 1280px) and (hover: hover) and (pointer: fine) {
    .hero:not(.is-mini) .hero-slide.bv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.bv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.bv-bottom .hero-btns { left: 7rem; right: 2rem; }
  }
  @media (max-width: 767px) and (orientation: portrait) {
    /* Scoped to .hero:not(.is-mini): the admin mini-preview is variant-controlled
       by its Landscape/Portrait tabs (see .hero.is-mini below) and must not be
       hijacked by this live-page media query when the admin's own window is a
       narrow portrait phone. */
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-bottom .hero-btns {
      position: absolute;
      z-index: 2;
      width: auto;
      max-width: none;
      left: clamp(1.25rem, 4vw, 2rem);
      right: clamp(1.25rem, 4vw, 2rem);
    }
    /* bpv-* wins on portrait phones: clear any top/bottom left by the base
       landscape bv-* rules (slides carry both class sets) or the button row
       stretches between two edges instead of pinning to one spot. */
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-bottom .hero-btns { top: auto; bottom: auto; }
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-top .hero-btns { top: calc(clamp(1.5rem, 4vh, 3rem) - var(--cta-off-y-p, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-middle .hero-btns { top: calc(50% - var(--cta-off-y-p, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-bottom .hero-btns { bottom: calc(clamp(1.5rem, 4vh, 3rem) + var(--cta-off-y-p, var(--cta-off-y, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bph-left .hero-btns { justify-content: flex-start; transform: translateX(var(--cta-off-x-p, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bph-center .hero-btns { justify-content: center; transform: translateX(var(--cta-off-x-p, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bph-right .hero-btns { justify-content: flex-end; transform: translateX(var(--cta-off-x-p, var(--cta-off-x, 0px))); }
    .hero:not(.is-mini) .hero-slide.has-portrait.bpv-middle .hero-btns { transform: translate(var(--cta-off-x-p, var(--cta-off-x, 0px)), -50%); }
  }
  /* Landscape viewports: centered cover crops the photo's top, which would cut off slide 1's head — anchor it to the top instead */
  @media (orientation: landscape) {
    .hero-slide.coach-top { background-position: center top; }
  }
  /* Portrait image swap (JAMIE, Sep 2026): a slide may specify a separate
     portrait_image_url for phones. Landscape is kept everywhere it makes sense —
     all landscape viewports (incl. phones held sideways) and tablets/desktops in
     portrait — and only narrow PORTRAIT phones get the portrait variant.
     Tune the 767px breakpoint to taste. Only the displayed image is fetched. */
  @media (max-width: 767px) and (orientation: portrait) {
    /* Same .hero:not(.is-mini) scope as the button-position block above — the
       admin mini-preview swaps content only via its own data-variant rules. */
    .hero:not(.is-mini) .hero-slide.has-portrait { background-image: var(--portrait-img); }
    /* Portrait variant content: swap the text/buttons to the portrait inner. */
    .hero:not(.is-mini) .hero-slide.has-portrait .hero-slide-inner { display: none; }
    .hero:not(.is-mini) .hero-slide.has-portrait .hero-slide-inner-portrait { display: block; }
    /* A slide carrying BOTH portrait and tablet copy: the portrait phone shows
       the portrait inner, never the tablet one. */
    .hero:not(.is-mini) .hero-slide.has-portrait .hero-slide-inner-tablet { display: none; }
    /* Portrait image anchored to the top when the portrait art wants it. */
    .hero:not(.is-mini) .hero-slide.has-portrait.coach-top-p { background-position: center top; }
    /* Per-variant portrait overlay (JAMIE, Sep 2026): when a slide has its own
       portrait_overlay_level, it wins over the landscape overlay on portrait
       phones — .hero:not(.is-mini) + ov-p-* (4 classes) beats both the base
       ::before (1) and the landscape ov-* rules (2). */
    .hero:not(.is-mini) .hero-slide.ov-p-none::before { background: none; }
    .hero:not(.is-mini) .hero-slide.ov-p-low::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.42) 0%, rgba(0,20,51,0.28) 60%, rgba(0,20,51,0.15) 100%); }
    .hero:not(.is-mini) .hero-slide.ov-p-high::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.85) 0%, rgba(0,20,51,0.66) 60%, rgba(0,20,51,0.48) 100%); }
    /* Content Position on portrait phones (JAMIE, Sep 2026): the phone's own
       value (cp-*-p) outranks the inherited one. Force Left keeps the text
       left-anchored, but the scrim is a LEFT-BIASED RADIAL rather than the
       desktop's left-to-right band — a linear gradient across a ~390px-wide
       portrait phone reads as a hard vertical seam, while the biased radial
       darkens behind the content and still opens up on the right. */
    .hero:not(.is-mini) .hero-slide.cp-left-p { align-items: flex-start; text-align: left; }
    .hero:not(.is-mini) .hero-slide.cp-left-p p { margin-left: 0; margin-right: auto; }
    .hero:not(.is-mini) .hero-slide.cp-center-p { align-items: center; text-align: center; }
    .hero:not(.is-mini) .hero-slide.cp-center-p p { margin-left: auto; margin-right: auto; }
    .hero:not(.is-mini) .cp-left-p .hero-btns { justify-content: flex-start; }
    .hero:not(.is-mini) .cp-center-p .hero-btns { justify-content: center; }
    .hero-slide:where(.cp-left-p)::before { background: radial-gradient(ellipse 95% 75% at 24% 45%, rgba(0,20,51,0.8) 0%, rgba(0,20,51,0.52) 62%, rgba(0,20,51,0.3) 100%); }
    .hero-slide:where(.cp-center-p)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  }
  /* Tablet variant content (JAMIE, Oct 2026 — Global model): a slide with
     custom tablet copy swaps its text/buttons to the tablet inner on tablet
     screens — coarse-pointer landscape tablets ≥900px wide, and portrait
     screens in the 768–1279px tablet band. Phones (portrait ≤767px) and the
     desktop layout (fine-pointer ≥1280px) are untouched: their own swaps
     below re-hide the tablet inner whenever has-desktop / has-portrait fires
     on those screens, so the precedence is always desktop/portrait > tablet. */
  @media (min-width: 900px) and (min-height: 500px) and (orientation: landscape) and (pointer: coarse),
         (min-width: 768px) and (orientation: portrait) and (max-width: 1279px) {
    .hero:not(.is-mini) .hero-slide.has-tablet .hero-slide-inner { display: none; }
    .hero:not(.is-mini) .hero-slide.has-tablet .hero-slide-inner-tablet { display: block; }
  }
  /* Short viewports (landscape phones/tablets): tighten the vertical rhythm so the
     headline + sub + CTA fit without clipping the slide's top edge. Tiers:
     ≤480px trims margins; ≤400px also shrinks the type itself. */
  @media (max-height: 480px) {
    .hero-slide { padding-top: 1rem; padding-bottom: 1rem; }
    .hero h1 { margin-bottom: 0.625rem; }
    .hero p { margin-bottom: 0.875rem; }
  }
  @media (max-height: 400px) {
    .hero-slide { padding-top: 0.625rem; padding-bottom: 0.625rem; }
    .hero h1 { font-size: clamp(1.75rem, min(13cqw, 13cqh), 5.5rem); }
    .hero p { font-size: clamp(0.875rem, min(2.5cqw, 4.5cqh), 1.125rem); }
  }
  /* Tablet landscape (wide touch tablets keep the centered layout because the
     desktop variant is gated to fine pointers): the base clamp's 5.5rem cap
     reads too big on a ~900px-tall screen, so scale the type down for this band. */
  @media (min-width: 900px) and (min-height: 500px) and (orientation: landscape) and (pointer: coarse) {
    .hero h1 { font-size: clamp(2.25rem, min(10cqw, 11cqh), 4rem); text-wrap: pretty; text-wrap: balance; }
    .hero p { font-size: clamp(1rem, min(2.2cqw, 4.5cqh), 1.25rem); }
  }
  /* Desktop variant: content anchored to the left over a left-side scrim. Gated on hover+fine pointer so tablets/phones (even landscape) keep the centered layout.
     Scoped to .hero:not(.is-mini) like every other per-variant hero block (Tab-SM,
     Portrait, ov-d-*, Tab-LG): the admin's Hero Slides mini-preview models ONE device
     at a time through its own data-variant rules, but the admin's EDITOR window can
     itself satisfy this media query — unscoped, its left anchoring + left scrim +
     desktop image/copy swap (and the dbv-/dbh- rails) leaked into the Tab-LG /
     Tab-SM / Portrait previews, so a slide with Content Position = Auto rendered
     left-aligned in every preview except the Desktop one (JAMIE, Sep 2026). The base
     ov-* rules above are scoped for the same reason: they and these desktop ones are
     the two halves of the "an explicit Overlay always beats the cp-driven default
     scrim" precedence chain, so they must move together. */
  @media (min-width: 1280px) and (hover: hover) and (pointer: fine) {
    .hero:not(.is-mini) { min-height: calc(100vh - var(--header-h)); }
    .hero:not(.is-mini) .hero-slide {
      align-items: flex-start;
      text-align: left;
      /* Fixed left rail (7rem) — NOT a percentage — so the layout is pixel-identical at every desktop width. */
      padding-left: 7rem;
      padding-right: 2rem;
    }
    .hero:not(.is-mini) .hero-slide::before {
      background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%);
    }
    .hero:not(.is-mini) p { max-width: min(30rem, 40vw); margin-left: 0; margin-right: auto; }
    .hero:not(.is-mini) h1 {
      /* Cap the measure so long headlines break to a second line instead of running
         across the viewport, and let the browser balance the break onto even,
         word-boundary lines (falls back to pretty/orphan-safe wrapping). */
      max-width: 62rem;
      text-wrap: pretty;
      text-wrap: balance;
    }
    .hero:not(.is-mini) .hero-btns { justify-content: flex-start; }
    /* Landscape bv-* buttons shift to the 7rem rail on desktop too (matches
       the admin Desktop preview): the button row is pinned across the rail,
       not the full-width clamp it gets below 1280px. */
    .hero:not(.is-mini) .hero-slide.bv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.bv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.bv-bottom .hero-btns { left: 7rem; right: 2rem; }
    .hero:not(.is-mini) .hero-slide.has-desktop { background-image: var(--desktop-img, var(--img)); }
    .hero:not(.is-mini) .hero-slide.has-desktop .hero-slide-inner { display: none; }
    .hero:not(.is-mini) .hero-slide.has-desktop .hero-slide-inner-desktop { display: block; }
    /* A slide carrying BOTH desktop and tablet copy: the desktop layout shows
       the desktop inner, never the tablet one. */
    .hero:not(.is-mini) .hero-slide.has-desktop .hero-slide-inner-tablet { display: none; }
    .hero:not(.is-mini) .hero-slide.coach-top-d { background-position: center top; }
    .hero:not(.is-mini) .hero-slide.dbv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.dbv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.dbv-bottom .hero-btns { position: absolute; z-index: 2; width: auto; max-width: none; left: 7rem; right: 2rem; }
    .hero:not(.is-mini) .hero-slide.dbv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.dbv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.dbv-bottom .hero-btns { top: auto; bottom: auto; }
    .hero:not(.is-mini) .hero-slide.dbv-top .hero-btns { top: calc(clamp(1.5rem, 4vh, 3rem) - var(--cta-off-y-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbv-middle .hero-btns { top: calc(50% - var(--cta-off-y-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbv-bottom .hero-btns { bottom: calc(clamp(1.5rem, 4vh, 3rem) + var(--cta-off-y-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbh-left .hero-btns { justify-content: flex-start; transform: translateX(var(--cta-off-x-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbh-center .hero-btns { justify-content: center; transform: translateX(var(--cta-off-x-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbh-right .hero-btns { justify-content: flex-end; transform: translateX(var(--cta-off-x-d, 0px)); }
    .hero:not(.is-mini) .hero-slide.dbv-middle .hero-btns { transform: translate(var(--cta-off-x-d, 0px), -50%); }
    /* Content Position on the desktop layout (JAMIE, Sep 2026): Force Center
       drops the fixed 7rem left rail (the content is centered on the full
       slide, so there's no rail to clear) and restores the centered radial
       scrim; Force Left is the layout's own look, so it only re-asserts it for
       a slide whose desktop value differs from its landscape one. The ::before
       rules stay :where()-narrow (1 class) AND come after this block's own
       left-scrim rule, so they win over the default but still lose to every
       explicit Overlay. */
    .hero:not(.is-mini) .hero-slide.cp-center-d, .hero:not(.is-mini) .hero-slide.cp-center { padding-left: 2rem; }
    .hero:not(.is-mini) .hero-slide.cp-center-d { align-items: center; text-align: center; }
    .hero:not(.is-mini) .hero-slide.cp-center-d p { max-width: min(30rem, 40vw); margin-left: auto; margin-right: auto; }
    .hero:not(.is-mini) .hero-slide.cp-left-d { align-items: flex-start; text-align: left; }
    .hero:not(.is-mini) .hero-slide.cp-left-d p { max-width: min(30rem, 40vw); margin-left: 0; margin-right: auto; }
    .hero:not(.is-mini) .cp-center-d .hero-btns { justify-content: center; }
    .hero:not(.is-mini) .cp-left-d .hero-btns { justify-content: flex-start; }
    /* A centered slide's pinned button row spans the slide symmetrically (the
       7rem rail applies only to the left-anchored layout). */
    .hero:not(.is-mini) .hero-slide.cp-center-d.bv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.cp-center-d.bv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.cp-center-d.bv-bottom .hero-btns,
    .hero:not(.is-mini) .hero-slide.cp-center-d.dbv-top .hero-btns,
    .hero:not(.is-mini) .hero-slide.cp-center-d.dbv-middle .hero-btns,
    .hero:not(.is-mini) .hero-slide.cp-center-d.dbv-bottom .hero-btns { left: 2rem; right: 2rem; }
    .hero:not(.is-mini) .hero-slide:where(.cp-center-d)::before,
    .hero:not(.is-mini) .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
    .hero:not(.is-mini) .hero-slide:where(.cp-left-d)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
    /* Image position: an explicit desktop Center wins over the landscape
       coach-top rule (which is still in effect on a landscape viewport). */
    .hero:not(.is-mini) .hero-slide.coach-center-d { background-position: center; }
  }
  /* Admin mini-preview (Hero Slides tab): a static, compact frame that reuses
     the real slide styles so what the admin sees is what ships. The frame's
     aspect-ratio matches the slide's own image (set dynamically), and the
     four variant tabs model the real hero box at the most common screen sizes
     (JAMIE, Sep 2026): Desktop = a 1920x1080 full-height hero; Tab-LG = a
     1280x800 Android tablet (root 18px → 684px hero); Tab-SM = a 1024x768
     iPad 10.2" (root 16px → 608px hero); Portrait = a 390x844 phone (root
     16px → 608px hero). --mini-s (computed in fitMiniPreview, apex-hero.js) =
     frameWidth / realScreenWidth, and every value below is the live slide's
     own value — its clamp evaluated at the real screen size — uniformly scaled
     by --mini-s, so the button/headline/subheading appear at the same FRACTION
     of the preview that they do of the real screen. */
  .hero.is-mini {
    min-height: 0;
    container-type: size;
    width: 100%;
    padding: 0;
    border-radius: 0.5rem;
    overflow: hidden;
    margin: 0.75rem auto 0.25rem;
    /* The mini preview models a REAL 1920x1080 desktop (JAMIE, Sep 2026):
       font-size 18px = the desktop root font, and --m-vw/--m-vh are the
       modeled viewport, so every 4vh/4vw clamp below evaluates exactly as it
       does on a 1080p desktop, then --mini-s scales it down. (Previously the
       vh/vw measured the tiny preview iframe, so the button sat at the wrong
       spot/size.) */
    font-size: 18px;
    /* --m-root = the modeled device's root font size (rem would resolve
       against the EDITOR's root, not this modeled root). Landscape/desktop
       model the 18px desktop root; the portrait variant below overrides to
       16px. */
    --m-root: 18px;
    --m-vw: 1920px;
    --m-vh: 1080px;
    /* Crop overlay vars (see applyCropOverlay in apex-hero.js): the bands a
       real screen crops off the slide image (as % for the overlay bars and as
       REAL px for the insets below). Zeroed until the shown image's real crop
       is computed; landscape crops top+bottom, portrait crops left+right. */
    --crop-top: 0%; --crop-bottom: 0%; --crop-left: 0%; --crop-right: 0%;
    --crop-top-px: 0px; --crop-bottom-px: 0px; --crop-left-px: 0px; --crop-right-px: 0px;
    /* aspect-ratio is set dynamically from the slide's own image so the whole
       slide displays naturally (no forced 16:9 / 9:16 crop) — see updatePreview. */
  }
  .hero.is-mini .hero-slide {
    position: absolute;
    inset: 0;
    min-height: 0;
    /* Content is anchored to the VISIBLE band, not the image edges: the crop
       bands (--crop-*-px, set by applyCropOverlay) are added to the pad, so
       flow content sits where it does on the real screen — on a 1080p desktop
       the bottom ~14% of a landscape slide is cropped, so the content is inset
       from the visible-band edges exactly as live. Zero crop = unchanged. */
    padding:
      calc((var(--crop-top-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em)) * var(--mini-s, 1))
      calc((var(--crop-left-px, 0px) + clamp(1.25em, calc(var(--m-vw, 1920px) * 0.04), 2em)) * var(--mini-s, 1))
      calc((var(--crop-bottom-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em)) * var(--mini-s, 1))
      calc((var(--crop-right-px, 0px) + clamp(1.25em, calc(var(--m-vw, 1920px) * 0.04), 2em)) * var(--mini-s, 1));
    animation: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
  }
  .hero.is-mini .hero-slide h1 {
    font-size: calc(clamp(2.25em, calc(min(15cqw, 16cqh) / var(--mini-s, 1)), 5.5em) * var(--mini-s, 1));
    margin: 0 0 calc(clamp(1em, calc(var(--m-vh, 1080px) * 0.03), 1.75em) * var(--mini-s, 1));
  }
  .hero.is-mini .hero-slide p {
    font-size: calc(clamp(1.125em, calc(min(3cqw, 6cqh) / var(--mini-s, 1)), 1.5em) * var(--mini-s, 1));
    margin: 0 auto calc(clamp(1.75em, calc(var(--m-vh, 1080px) * 0.05), 3em) * var(--mini-s, 1));
    /* The subheading width cap must model the REAL screen (--m-vw + the
       modeled root --m-root), then scale by --mini-s like the font does —
       otherwise the box is effectively ~3x too wide and text that wraps on a
       real device stays on one line in the preview (JAMIE, Sep 8 2026). */
    max-width: calc(min(38 * var(--m-root), var(--m-vw) * 0.8) * var(--mini-s, 1));
  }
  .hero.is-mini .hero-btns { justify-content: center; gap: calc(clamp(0.75em, calc(var(--m-vw, 1920px) * 0.02), 1.25em) * var(--mini-s, 1)); }
  /* Mini preview should mirror manual horizontal placement too (later rules
     would otherwise force center). */
  .hero.is-mini .hero-slide.bh-left .hero-btns { justify-content: flex-start; }
  .hero.is-mini .hero-slide.bh-center .hero-btns { justify-content: center; }
  .hero.is-mini .hero-slide.bh-right .hero-btns { justify-content: flex-end; }
  /* Landscape CTA insets inside the mini: the live slide's own clamp values
     evaluated against the modeled 1920x1080 viewport (--m-vw/--m-vh), then
     scaled with --mini-s — so the button sits exactly where it does on a real
     1080p desktop. */
  .hero.is-mini .hero-slide.bv-top .hero-btns,
  .hero.is-mini .hero-slide.bv-middle .hero-btns,
  .hero.is-mini .hero-slide.bv-bottom .hero-btns { left: calc(clamp(1.25em, calc(var(--m-vw, 1920px) * 0.04), 2em) * var(--mini-s, 1)); right: calc(clamp(1.25em, calc(var(--m-vw, 1920px) * 0.04), 2em) * var(--mini-s, 1)); }
  /* Manual-position buttons anchor to the VISIBLE band too (JAMIE, Sep 9):
     adding the crop band (--crop-*-px) matches how the live hero measures the
     inset from the screen edge — which is the visible-band edge, not the
     image's — so the button appears exactly where it does on a real screen. */
  .hero.is-mini .hero-slide.bv-top .hero-btns { top: calc((var(--crop-top-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) - var(--cta-off-y, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini .hero-slide.bv-middle .hero-btns { top: calc(50% - var(--cta-off-y, 0px) * var(--mini-s, 1)); }
  .hero.is-mini .hero-slide.bv-bottom .hero-btns { bottom: calc((var(--crop-bottom-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) + var(--cta-off-y, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini .hero-slide.bh-left .hero-btns,
  .hero.is-mini .hero-slide.bh-center .hero-btns,
  .hero.is-mini .hero-slide.bh-right .hero-btns { transform: translateX(calc(var(--cta-off-x, 0px) * var(--mini-s, 1))); }
  .hero.is-mini .hero-slide.bv-middle .hero-btns { transform: translate(calc(var(--cta-off-x, 0px) * var(--mini-s, 1)), -50%); }
  .hero.is-mini .btn-primary,
  .hero.is-mini .btn-outline { padding: 0.875em 2em; font-size: calc(1em * var(--mini-s, 1)); border-width: 0.125em; }
  /* Crop "safe zone" bars (JAMIE, Sep 9): preview-only divs injected by
     ensureCropBars (apex-hero.js) that dim the parts of the slide image a real
     screen crops away, so the bright band = what end users actually see and
     the dashed edge = the cut line. Sized by --crop-* (computed from the shown
     image's real cover crop). Painted above the scrim, below the buttons. */
  .hero.is-mini .hs-crop {
    position: absolute;
    z-index: 1;
    max-width: none;
    background: rgba(10, 16, 30, 0.55);
    pointer-events: none;
  }
  .hero.is-mini .hs-crop-top { top: 0; left: 0; right: 0; height: var(--crop-top, 0%); border-bottom: 0.125rem dashed rgba(255, 255, 255, 0.5); }
  .hero.is-mini .hs-crop-bottom { bottom: 0; left: 0; right: 0; height: var(--crop-bottom, 0%); border-top: 0.125rem dashed rgba(255, 255, 255, 0.5); }
  .hero.is-mini .hs-crop-left { left: 0; top: 0; bottom: 0; width: var(--crop-left, 0%); border-right: 0.125rem dashed rgba(255, 255, 255, 0.5); }
  .hero.is-mini .hs-crop-right { right: 0; top: 0; bottom: 0; width: var(--crop-right, 0%); border-left: 0.125rem dashed rgba(255, 255, 255, 0.5); }
  /* Admin mini-preview TABLET variants (JAMIE, Sep 2026): Tab-LG models a
     Galaxy-Tab-style 1280×800 Android tablet (root 18px → hero 684 tall) and
     Tab-SM an iPad-10.2"-style 1024×768 tablet (root 16px → hero 608 tall).
     Both keep the centered landscape layout (they share the landscape fields)
     and apply the live site's coarse-pointer tablet type clamps below, so the
     headline/subheading render at their real tablet size instead of desktop
     size. The base .hero.is-mini block is the 1920×1080 desktop model; these
     only retarget --m-vw/--m-vh (and the root font for Tab-SM, whose 1024px
     width puts it under the 1115px root-font ramp). */
  .hero.is-mini[data-variant="tab-lg"] {
    --m-vw: 1280px;
    --m-vh: 800px;
  }
  .hero.is-mini[data-variant="tab-sm"] {
    font-size: 16px;
    --m-root: 16px;
    --m-vw: 1024px;
    --m-vh: 768px;
  }
  /* Coarse-pointer tablet type clamps — mirrors the live tablet-landscape MQ
     (min-width 900px, coarse pointer): the base clamp's 5.5rem cap reads too
     big on a ~800px-tall tablet, so scale it down for both tablet variants. */
  .hero.is-mini[data-variant="tab-lg"] .hero-slide h1,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide h1 {
    font-size: calc(clamp(2.25em, calc(min(10cqw, 11cqh) / var(--mini-s, 1)), 4em) * var(--mini-s, 1));
    text-wrap: pretty;
    text-wrap: balance;
  }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide p,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide p {
    font-size: calc(clamp(1em, calc(min(2.2cqw, 4.5cqh) / var(--mini-s, 1)), 1.25em) * var(--mini-s, 1));
  }
  /* Tablet-variant content inside the admin tablet previews: swap the
     text/buttons to the tablet inner (mirrors the live tablet band above). A
     slide carrying BOTH tablet and portrait copy still previews its tablet
     copy here — the portrait inner belongs to the Portrait tab. */
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.has-tablet .hero-slide-inner,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.has-tablet .hero-slide-inner { display: none; }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.has-tablet .hero-slide-inner-tablet,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.has-tablet .hero-slide-inner-tablet { display: block; }
  /* Tab-SM mini-preview offsets (JAMIE, Sep 2026): the smaller tablet model
     uses its OWN _tsm nudge offsets; the Tab-LG/landscape model keeps the base
     --cta-off-x/-y rules above. Same 8 rules, higher specificity via
     data-variant, so they win for the Tab-SM preview only. */
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bv-top .hero-btns { top: calc((var(--crop-top-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) - var(--cta-off-y-tsm, var(--cta-off-y, 0px))) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bv-middle .hero-btns { top: calc(50% - var(--cta-off-y-tsm, var(--cta-off-y, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bv-bottom .hero-btns { bottom: calc((var(--crop-bottom-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) + var(--cta-off-y-tsm, var(--cta-off-y, 0px))) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bh-left .hero-btns { justify-content: flex-start; transform: translateX(calc(var(--cta-off-x-tsm, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bh-center .hero-btns { justify-content: center; transform: translateX(calc(var(--cta-off-x-tsm, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bh-right .hero-btns { justify-content: flex-end; transform: translateX(calc(var(--cta-off-x-tsm, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.bv-middle .hero-btns { transform: translate(calc(var(--cta-off-x-tsm, var(--cta-off-x, 0px)) * var(--mini-s, 1)), -50%); }
  /* Admin mini-preview portrait variant: a 9:16 frame (1080x1920 — the most
     common phone resolution) so the admin sees the actual portrait crop. The
     frame falls back to showing the landscape image (shaded) if no portrait
     URL is set — same as the live site. */
  .hero.is-mini[data-variant="portrait"] {
    /* JAMIE (Sep 2026): the full-column-width portrait frame was too tall for
       the editor — halve it. Because the frame height follows the image's
       aspect-ratio, width:50% halves both dimensions. It also lets --mini-s
       (frameWidth/390, recomputed in fitMiniPreview) bind at ~0.55 instead of
       the old 1.0 fit-cap, so the type/buttons now render at their true
       phone-proportional size. */
    width: 50%;
    max-height: none;
    margin-left: auto;
    margin-right: auto;
    /* Portrait models a real phone (390x844 CSS px — e.g. iPhone 12/13/14, the
       most common layout size; NOT its 1080x1920 physical resolution). The
       phone root font is 16px (not the desktop 18px), so em below resolves to
       phone sizes. */
    font-size: 16px;
    --m-root: 16px;
    --m-vw: 390px;
    --m-vh: 844px;
  }
  /* Portrait model default (JAMIE, Sep 22 2026): with Content Position on Auto the portrait
     composition is CENTERED. It does NOT inherit the landscape / Tab-LG value, and — because
     this rule is more specific than a bare `.hero-slide` rule — no window-size (or leaked
     desktop) rule can pull the portrait preview's content left. An explicit `.cp-left-p`
     (Force Left on the Portrait tab) is one class more specific and still wins. */
  .hero.is-mini[data-variant="portrait"] .hero-slide {
    align-items: center;
    text-align: center;
  }
  .hero.is-mini[data-variant="portrait"] .hero-slide .hero-slide-inner {
    align-items: center;
  }
  /* Portrait variant inside the admin portrait preview: swap the image AND the
     text/buttons to the portrait inner (mirrors the live portrait-phone swap). */
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait { background-image: var(--portrait-img, none); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait .hero-slide-inner { display: none; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait .hero-slide-inner-portrait { display: block; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait .hero-slide-inner-tablet { display: none; }
  /* Per-variant portrait overlay inside the admin portrait preview — mirrors
     the live portrait-phone rules (radial scrims). */
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-p-none::before { background: none; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-p-low::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.42) 0%, rgba(0,20,51,0.28) 60%, rgba(0,20,51,0.15) 100%); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-p-high::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.85) 0%, rgba(0,20,51,0.66) 60%, rgba(0,20,51,0.48) 100%); }
  /* Portrait-position classes inside the admin portrait preview — mirrors the
     live portrait-phone media query above (insets use the live slide's own
     clamps, scaled with --mini-s). Offsets honor the _p nudge vars. */
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-top .hero-btns,
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-middle .hero-btns,
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-bottom .hero-btns {
    position: absolute;
    z-index: 2;
    width: auto;
    max-width: none;
    /* On a phone the portrait image is cropped on the SIDES, so the button's
       left/right inset is measured from the visible-band edge (+ crop px). */
    left: calc((var(--crop-left-px, 0px) + clamp(1.25em, calc(var(--m-vw, 390px) * 0.04), 2em)) * var(--mini-s, 1));
    right: calc((var(--crop-right-px, 0px) + clamp(1.25em, calc(var(--m-vw, 390px) * 0.04), 2em)) * var(--mini-s, 1));
  }
  /* bpv-* wins inside the portrait mini too: clear the landscape bv-* top/bottom
     (the slide carries both class sets) so the row pins to ONE edge/spot. */
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-top .hero-btns,
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-middle .hero-btns,
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-bottom .hero-btns { top: auto; bottom: auto; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-top .hero-btns { top: calc((clamp(1.5em, calc(var(--m-vh, 1920px) * 0.04), 3em) - var(--cta-off-y-p, var(--cta-off-y, 0px))) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-middle .hero-btns { top: calc(50% - var(--cta-off-y-p, var(--cta-off-y, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-bottom .hero-btns { bottom: calc((clamp(1.5em, calc(var(--m-vh, 1920px) * 0.04), 3em) + var(--cta-off-y-p, var(--cta-off-y, 0px))) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bph-left .hero-btns { justify-content: flex-start; transform: translateX(calc(var(--cta-off-x-p, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bph-center .hero-btns { justify-content: center; transform: translateX(calc(var(--cta-off-x-p, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bph-right .hero-btns { justify-content: flex-end; transform: translateX(calc(var(--cta-off-x-p, var(--cta-off-x, 0px)) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.bpv-middle .hero-btns { transform: translate(calc(var(--cta-off-x-p, var(--cta-off-x, 0px)) * var(--mini-s, 1)), -50%); }
  /* Admin mini-preview DESKTOP variant (JAMIE, Sep 2026): forces the big-screen
     desktop layout — content anchored to the left over the left scrim — no
     matter the admin's own viewport, so what the admin sees is exactly the
     desktop hero. Same 18px root + 1920x1080 model as the Landscape tab, but
     the desktop hero is FULL screen height (1013.6px on a 1080p desktop), so
     the crop overlay models that box, not the 38rem-capped centered one. */
  .hero.is-mini[data-variant="desktop"] .hero-slide {
    align-items: flex-start;
    text-align: left;
    padding:
      calc((var(--crop-top-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em)) * var(--mini-s, 1))
      calc((var(--crop-right-px, 0px) + 2rem) * var(--mini-s, 1))
      calc((var(--crop-bottom-px, 0px) + clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em)) * var(--mini-s, 1))
      calc((var(--crop-left-px, 0px) + 7rem) * var(--mini-s, 1));
  }
  .hero.is-mini[data-variant="desktop"] .hero-slide h1 { max-width: calc(62 * var(--m-root) * var(--mini-s, 1)); text-wrap: pretty; text-wrap: balance; }
  .hero.is-mini[data-variant="desktop"] .hero-slide p { max-width: calc(min(30 * var(--m-root), var(--m-vw) * 0.4) * var(--mini-s, 1)); margin-left: 0; margin-right: auto; }
  .hero.is-mini[data-variant="desktop"] .hero-btns { justify-content: flex-start; }
  /* Desktop left scrim — mirrors the live desktop media query. */
  .hero.is-mini[data-variant="desktop"] .hero-slide::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-low::before { background: linear-gradient(to right, rgba(0,20,51,0.5) 0%, rgba(0,20,51,0.32) 36%, rgba(0,20,51,0.1) 60%, rgba(0,20,51,0.02) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-high::before { background: linear-gradient(to right, rgba(0,20,51,0.9) 0%, rgba(0,20,51,0.7) 36%, rgba(0,20,51,0.4) 60%, rgba(0,20,51,0.12) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-none::before { background: none; }
  /* Per-variant desktop overlay inside the admin desktop preview — mirrors the
     live desktop rules (left linear scrims). */
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-d-none::before { background: none; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-d-low::before { background: linear-gradient(to right, rgba(0,20,51,0.5) 0%, rgba(0,20,51,0.32) 36%, rgba(0,20,51,0.1) 60%, rgba(0,20,51,0.02) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.ov-d-high::before { background: linear-gradient(to right, rgba(0,20,51,0.9) 0%, rgba(0,20,51,0.7) 36%, rgba(0,20,51,0.4) 60%, rgba(0,20,51,0.12) 78%, rgba(0,20,51,0) 100%); }
  /* Desktop-variant content inside the desktop mini — swap to the desktop inner
     (mirrors the live desktop media query). */
  .hero.is-mini[data-variant="desktop"] .hero-slide.has-desktop { background-image: var(--desktop-img, var(--img)); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.has-desktop .hero-slide-inner { display: none; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.has-desktop .hero-slide-inner-desktop { display: block; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.has-desktop .hero-slide-inner-tablet { display: none; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.coach-top-d { background-position: center top; }
  /* Landscape bv-* buttons shift to the 7rem rail on desktop (mirrors live). */
  .hero.is-mini[data-variant="desktop"] .hero-slide.bv-top .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.bv-middle .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.bv-bottom .hero-btns { left: calc((var(--crop-left-px, 0px) + 7rem) * var(--mini-s, 1)); right: calc((var(--crop-right-px, 0px) + 2rem) * var(--mini-s, 1)); }
  /* Desktop button position override inside the desktop mini — mirrors the live
     desktop dbv-* / dbh-* rules, scaled with --mini-s. */
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-top .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-middle .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-bottom .hero-btns { position: absolute; z-index: 2; width: auto; max-width: none; left: calc((var(--crop-left-px, 0px) + 7rem) * var(--mini-s, 1)); right: calc((var(--crop-right-px, 0px) + 2rem) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-top .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-middle .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-bottom .hero-btns { top: auto; bottom: auto; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-top .hero-btns { top: calc((clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) - var(--cta-off-y-d, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-middle .hero-btns { top: calc(50% - var(--cta-off-y-d, 0px) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-bottom .hero-btns { bottom: calc((clamp(1.5em, calc(var(--m-vh, 1080px) * 0.04), 3em) + var(--cta-off-y-d, 0px)) * var(--mini-s, 1)); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbh-left .hero-btns { justify-content: flex-start; transform: translateX(calc(var(--cta-off-x-d, 0px) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbh-center .hero-btns { justify-content: center; transform: translateX(calc(var(--cta-off-x-d, 0px) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbh-right .hero-btns { justify-content: flex-end; transform: translateX(calc(var(--cta-off-x-d, 0px) * var(--mini-s, 1))); }
  .hero.is-mini[data-variant="desktop"] .hero-slide.dbv-middle .hero-btns { transform: translate(calc(var(--cta-off-x-d, 0px) * var(--mini-s, 1)), -50%); }
  /* IMAGE POSITION inside the mini preview must be governed by the MODELED
     variant only. The live TABLET/PORTRAIT media queries can still match the
     admin's own editor window (a narrow portrait window satisfies the portrait
     query), so the context classes a real slide carries for OTHER devices —
     coach-top-d on a tablet preview, coach-center-d on a portrait one — would
     otherwise re-anchor the previewed image. Normalize per variant, then
     re-apply the landscape anchor where the landscape column actually says
     'top' (JAMIE, Sep 2026). The desktop query no longer needs normalizing
     here: it is scoped to .hero:not(.is-mini) at its source (see the desktop
     layout block), so it can't reach the preview at all. */
  .hero.is-mini[data-variant="tab-lg"] .hero-slide,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide,
  .hero.is-mini[data-variant="portrait"] .hero-slide { background-position: center; }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.coach-top,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.coach-top { background-position: center top; }
  /* Mini-preview IMAGE POSITION for the portrait variant (JAMIE, Sep 2026): the
     portrait phone rules had no background-position rule at all in the preview,
     so a forced Top (or an explicit Center) on a phone was invisible here.
     Mirrors the live portrait-phone rules. */
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.coach-top-p { background-position: center top; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.has-portrait.coach-center-p { background-position: center; }
  /* Same for the desktop mini: an explicit Center must beat the landscape
     coach-top rule, exactly as the live desktop scrim/layout rules do. */
  .hero.is-mini[data-variant="desktop"] .hero-slide.coach-center-d { background-position: center; }
  /* Content Position inside the admin mini-preview (JAMIE, Sep 2026): mirrors
     the live cp-* rules per variant, with the same "a context-specific value
     outranks the inherited one" ordering (base → Portrait → Desktop; the base
     rules carry the landscape layout AND both tablet tabs, which share one
     Content Position setting — JAMIE, Sep 2026).
     Every length uses the mini's own modeled + --mini-s-scaled formula, never a
     live rem/percent value (rem would resolve against the editor's root font,
     not the modeled device's). Button alignment uses :not() guards so an
     explicitly-set button row (bh-* / bph-* / dbh-*) still wins, exactly as live.
     Ordering note: the BUTTON rules must come AFTER the minis' own bh-* / bph-* /
     dbh-* rules above for the guard-free alignment to be predictable. */
  .hero.is-mini .hero-slide.cp-left { align-items: flex-start; text-align: left; }
  .hero.is-mini .hero-slide.cp-left p { margin-left: 0; margin-right: auto; }
  .hero.is-mini .hero-slide.cp-center { align-items: center; text-align: center; }
  .hero.is-mini .hero-slide.cp-center p { margin-left: auto; margin-right: auto; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-left-p { align-items: flex-start; text-align: left; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-left-p p { margin-left: 0; margin-right: auto; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-center-p { align-items: center; text-align: center; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-center-p p { margin-left: auto; margin-right: auto; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d {
    align-items: center;
    text-align: center;
    /* Force Center has no left rail to clear — symmetric insets, exactly like
       the live desktop rule. */
    padding-left: calc((var(--crop-left-px, 0px) + 2rem) * var(--mini-s, 1));
    padding-right: calc((var(--crop-right-px, 0px) + 2rem) * var(--mini-s, 1));
  }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d p { max-width: calc(min(30 * var(--m-root), var(--m-vw) * 0.4) * var(--mini-s, 1)); margin-left: auto; margin-right: auto; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-left-d { align-items: flex-start; text-align: left; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-left-d p { margin-left: 0; margin-right: auto; }
  .hero.is-mini .hero-slide.cp-left:not(.bh-left):not(.bh-center):not(.bh-right) .hero-btns { justify-content: flex-start; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-left-p:not(.bph-left):not(.bph-center):not(.bph-right) .hero-btns { justify-content: flex-start; }
  .hero.is-mini[data-variant="portrait"] .hero-slide.cp-center-p:not(.bph-left):not(.bph-center):not(.bph-right) .hero-btns { justify-content: center; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-left-d:not(.dbh-left):not(.dbh-center):not(.dbh-right):not(.bh-left):not(.bh-center):not(.bh-right) .hero-btns { justify-content: flex-start; }
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d:not(.dbh-left):not(.dbh-center):not(.dbh-right):not(.bh-left):not(.bh-center):not(.bh-right) .hero-btns { justify-content: center; }
  /* A centered slide's pinned button row spans symmetrically in the desktop
     preview too (mirrors the live rule above). */
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.bv-top .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.bv-middle .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.bv-bottom .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.dbv-top .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.dbv-middle .hero-btns,
  .hero.is-mini[data-variant="desktop"] .hero-slide.cp-center-d.dbv-bottom .hero-btns { left: calc((var(--crop-left-px, 0px) + 2rem) * var(--mini-s, 1)); right: calc((var(--crop-right-px, 0px) + 2rem) * var(--mini-s, 1)); }
  /* cp-driven default scrim per mini variant — same "context beats base"
     ordering as the alignment rules, and the same scrim shapes as live. */
  .hero.is-mini[data-variant="tab-lg"] .hero-slide:where(.cp-left)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide:where(.cp-left)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="tab-sm"] .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  .hero.is-mini[data-variant="portrait"] .hero-slide:where(.cp-left)::before { background: radial-gradient(ellipse 95% 75% at 24% 45%, rgba(0,20,51,0.8) 0%, rgba(0,20,51,0.52) 62%, rgba(0,20,51,0.3) 100%); }
  .hero.is-mini[data-variant="portrait"] .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  .hero.is-mini[data-variant="portrait"] .hero-slide:where(.cp-left-p)::before { background: radial-gradient(ellipse 95% 75% at 24% 45%, rgba(0,20,51,0.8) 0%, rgba(0,20,51,0.52) 62%, rgba(0,20,51,0.3) 100%); }
  .hero.is-mini[data-variant="portrait"] .hero-slide:where(.cp-center-p)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide:where(.cp-left)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide:where(.cp-center)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide:where(.cp-left-d)::before { background: linear-gradient(to right, rgba(0,20,51,0.82) 0%, rgba(0,20,51,0.58) 36%, rgba(0,20,51,0.24) 60%, rgba(0,20,51,0.06) 78%, rgba(0,20,51,0) 100%); }
  .hero.is-mini[data-variant="desktop"] .hero-slide:where(.cp-center-d)::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.72) 0%, rgba(0,20,51,0.5) 60%, rgba(0,20,51,0.34) 100%); }
  /* An explicitly-set Overlay level always beats the cp-driven default scrim, in
     every mini variant (mirrors live precedence). Scoped to the Tab-LG / Tab-SM /
     Portrait models: those are the radial ("centered layout") scrims, while the
     Desktop model's own rules above give it the live desktop layout's LEFT linear
     rail scrim for ov-low / ov-high / ov-none (JAMIE, Sep 2026 — a desktop-mini
     ov-low used to fall through to the radial fallback here, which out-specifies
     those rules, so the Desktop preview disagreed with what ships). */
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.ov-none::before,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.ov-none::before,
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-none::before { background: none; }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.ov-low::before,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.ov-low::before,
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-low::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.42) 0%, rgba(0,20,51,0.28) 60%, rgba(0,20,51,0.15) 100%); }
  .hero.is-mini[data-variant="tab-lg"] .hero-slide.ov-high::before,
  .hero.is-mini[data-variant="tab-sm"] .hero-slide.ov-high::before,
  .hero.is-mini[data-variant="portrait"] .hero-slide.ov-high::before { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.85) 0%, rgba(0,20,51,0.66) 60%, rgba(0,20,51,0.48) 100%); }
  .hs-preview-caption {
    font-size: 0.75rem;
    color: var(--ws-muted, #5B6B7C);
    text-align: center;
    margin: 0.25rem auto 0.5rem;
  }
  /* Global-model editing tabs (JAMIE, Oct 2026): Global holds the words + both
     required photos; Desktop / Tablet / Portrait adjust the words only (Use
     global or Customize), and the Tablet tab previews at either bracketing
     tablet width via the Preview-width switch. Whichever tab you're editing is
     the one you're previewing. The editor opens on Global. */
  .hs-variant-tabs {
    display: inline-flex;
    border: 0.0625rem solid var(--light-gray, #D7DEE7);
    border-radius: 999px;
    overflow: hidden;
    margin: 0.875rem 0 0.625rem;
  }
  .hs-vtab {
    border: 0;
    background: transparent;
    padding: 0.375rem 0.875rem;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--ws-muted, #5B6B7C);
    cursor: pointer;
  }
  .hs-vtab.active { background: var(--primary, #6699CC); color: #fff; }
  /* Global-model copy controls (JAMIE, Oct 2026): on the Desktop / Tablet /
     Portrait tabs each copy field carries a two-state Use-global / Customize
     switch. The active choice reads as a filled pill; the "Shows:" note names
     the inherited global value while the field follows it. */
  .hs-mode-row { display: flex; align-items: center; flex-wrap: wrap; gap: 0.375rem; margin-top: 0.375rem; }
  .hs-mode-btn {
    border: 0.0625rem solid var(--light-gray, #D7DEE7);
    background: transparent;
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ws-muted, #5B6B7C);
    cursor: pointer;
  }
  .hs-mode-btn.on { background: var(--primary, #6699CC); border-color: var(--primary, #6699CC); color: #fff; }
  /* Tablet preview-width switch: the single Tablet content tab previews at
     either bracketing tablet width (Large = 1280×800, Small = 1024×768). */
  .hs-tabsize-row { display: flex; align-items: center; justify-content: center; gap: 0.375rem; margin: 0.375rem 0 0.25rem; }
  .hs-tabsize-label { font-size: 0.75rem; font-weight: 700; color: var(--ws-muted, #5B6B7C); margin-right: 0.25rem; }
  /* Info / warning note for the variant editing panes (e.g. the Desktop tab's
     "blank = Landscape" reminder and the database-migration warning). */
  .hs-vtab-note {
    font-size: 0.8125rem;
    line-height: 1.45;
    color: var(--ws-muted, #5B6B7C);
    background: rgba(102, 153, 204, 0.08);
    border-left: 0.1875rem solid var(--primary, #6699CC);
    border-radius: 0.25rem;
    padding: 0.625rem 0.75rem;
    margin-bottom: 0.75rem;
  }
  .hs-vtab-note.warn {
    background: rgba(217, 119, 6, 0.1);
    border-left-color: #D97706;
    color: #92400E;
  }
  /* Collapsed single-field slide editor (JAMIE, Sep 2026): one set of fields
     that tracks the active variant. The mini preview is capped so it stays a
     preview window (item 17) — width = min(100%, 640px, and whatever keeps the
     box under 400px tall given the slide's own image aspect --ar), so landscape
     slides render ~640×360 and portrait ones shrink to fit 400px tall, always
     keeping the image's natural aspect ratio (no forced crop). */
  #heroSlidePreview {
    width: min(100%, 640px, calc(400px * var(--ar, 1.78)));
  }
  .hs-variant-tabs-wrap { text-align: center; margin: 0.25rem 0 0.5rem; }
  .hs-variant-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ws-muted, #5B6B7C);
    margin-bottom: 0.5rem;
  }
  .hs-variant-tabs { margin: 0 0 0.25rem; }
  .hs-editor-lower { margin-top: 1.125rem; }
  .hs-btn-section { margin-top: 1.25rem; }
  .hs-btn-section-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
  }
  .hs-btn-section-title {
    font-size: 0.8125rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ws-muted, #5B6B7C);
    white-space: nowrap;
  }
  .hs-btn-section-line { flex: 1 1 auto; height: 1px; background: var(--light-gray, #D7DEE7); }
  .hs-editor-lower .hs-vtab-note.warn { margin-top: 1rem; }
  /* Narrow screens (JAMIE, Sep 2026): the variant tabs don't fit on one row
     inside the editor box, so the pill wraps them into a 2×2 segmented
     control that stays inside the box. */
  @media (max-width: 450px) {
    .hs-variant-tabs {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      width: 100%;
      border-radius: 0.75rem;
    }
    .hs-vtab { padding: 0.375rem 0.5rem; }
  }
  .btn-primary {
    display: inline-block;
    background: var(--primary);
    color: var(--white);
    border: 0;
    padding: 0.875rem 2rem;
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 1rem;
    box-shadow: 0 0.25rem 0.875rem rgba(102,153,204,0.35);
    transition: transform 0.15s, box-shadow 0.15s, background 0.2s;
  }
  .btn-primary:hover { transform: translateY(-0.125rem); box-shadow: 0 0.5rem 1.5rem rgba(102,153,204,0.5); background: var(--primary-dark); }
  .btn-primary:disabled { opacity: 0.55; cursor: default; transform: none; box-shadow: none; }
  .btn-primary:disabled:hover { transform: none; box-shadow: none; background: var(--primary); }
  .btn-secondary {
    display: inline-block;
    background: transparent;
    color: var(--secondary);
    padding: 0.875rem 1.75rem;
    border: 0.125rem solid var(--primary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 0.9375rem;
    cursor: pointer;
    transition: transform 0.15s, background 0.2s, color 0.2s;
  }
  .btn-secondary:hover { background: var(--secondary); color: var(--white); transform: translateY(-0.125rem); }
  /* Hero ghost button (JAMIE, Sep 2026): JAMIE liked the glass scrim — a plain
     half-transparent white border vanished against bright slide photos, so the
     _hero_ outline CTA sits on a light navy glass scrim with a stronger border.
     Scrim/border only: the label size and padding stay at their original values
     (JAMIE didn't want the CTAs made bigger). */
  .btn-outline {
    background: rgba(0,32,78,0.3);
    color: var(--white);
    padding: 0.875rem 2rem;
    border: 0.125rem solid rgba(255,255,255,0.72);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 1rem;
    box-shadow: 0 0.25rem 0.875rem rgba(0,0,0,0.25);
    transition: border-color 0.2s, background 0.2s;
  }
  .btn-outline:hover { border-color: var(--white); background: rgba(0,32,78,0.45); box-shadow: 0 0.375rem 1.25rem rgba(0,0,0,0.35); }
  /* Press + touch feedback (JAMIE, Sep 2026): the button family only had :hover,
     so a tap on a touch device gave no feedback at all. :active is the press state
     and MUST come after the :hover rules (equal specificity, source order wins) so
     pressing replaces the hover lift rather than stacking on it. touch-action and
     tap-highlight drop the browser's own tap flash/delay in favor of this. */
  .btn-primary, .btn-outline, .btn-outline-dark, .btn-outline-white, .btn-secondary,
  .nav-cta, .modal-btn, .ws-btn {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }
  .btn-primary:active, .btn-outline:active, .btn-outline-dark:active, .btn-outline-white:active,
  .btn-secondary:active, .nav-cta:active, .modal-btn:active, .ws-btn:active {
    transform: translateY(0) scale(0.98);
    transition-duration: 0.06s;
  }
  .btn-primary:active { box-shadow: 0 0.125rem 0.375rem rgba(102,153,204,0.35); }
  /* Devices with no real hover (JAMIE's tablet): the desktop lift would otherwise
     stick to a button after a tap. Cancel it there. */
  @media (hover: none) {
    .btn-primary:hover, .btn-outline:hover, .btn-outline-dark:hover,
    .btn-outline-white:hover, .btn-secondary:hover { transform: none; }
  }

  /* ---------- Sections ---------- */
  .section {
    max-width: 68.75rem;
    margin: 0 auto;
    padding: 5rem 1.5rem;
  }
  .section.dark { background: var(--secondary); max-width: none; color: var(--white); }
  .section.dark .section-head h2 { color: var(--white); }
  .section.dark .section-head p { color: rgba(255,255,255,0.7); }
  .section.light { background: var(--light-gray); max-width: none; }
  .section.light .section-head h2 { color: var(--dark-gray); }
  .section.light .section-head p { color: var(--gray-text); }
  .section.dark > *,
  .section.light > *,
  .cta-band > * {
    max-width: 68.75rem;
    margin-left: auto;
    margin-right: auto;
  }
  .section-inner { max-width: 68.75rem; margin: 0 auto; }
  .section-head { text-align: center; margin-bottom: 3.125rem; }
  .section-head .pt-eyebrow {
    display: block;
    font-size: 0.8125rem; font-weight: 800; letter-spacing: 0.125rem; text-transform: uppercase;
    color: var(--primary); margin-bottom: 0.5rem;
  }
  .section.dark .section-head .pt-eyebrow { color: var(--primary-light); }
  .section-head h2 {
    font-size: clamp(1.625rem, 3.5vw, 2.375rem);
    font-weight: 900;
    color: var(--dark-gray);
    margin-bottom: 0.75rem;
    position: relative;
  }
  .section-head h2::after {
    content: "";
    display: block;
    width: 3.75rem; height: 0.25rem;
    background: var(--primary);
    border-radius: 0.125rem;
    margin: 0.875rem auto 0;
  }
  .section-head p { color: var(--gray-text); font-size: 1.0625rem; max-width: 35rem; margin: 0 auto; }
  .section-head p + p { margin-top: 1rem; }
  #page-about .section-head strong { color: var(--secondary); }

  /* ---------- Program Cards ---------- */
  .card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16.25rem, 1fr));
    gap: 1.625rem;
  }
  #page-about .card-grid {
    grid-template-columns: repeat(auto-fit, minmax(16.25rem, 1fr));
  }
  .card {
    background: var(--white);
    border-radius: 0.75rem;
    padding: 2.125rem 1.75rem;
    border: 0.0625rem solid var(--light-gray);
    border-top: 0.25rem solid var(--card-accent);
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
    transition: transform 0.2s, box-shadow 0.2s;
  }
  .section.dark .card {
    background: rgba(255,255,255,0.08);
    border: 0.0625rem solid rgba(255,255,255,0.15);
  }
  .section.light .card {
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
  }
  .section.light .card h3 { color: var(--secondary); }
  .section.light .card p { color: var(--gray-text); }
  .card:hover { transform: translateY(-0.25rem); box-shadow: 0 0.75rem 2.25rem rgba(0,32,78,0.15); }
  .card-icon {
    width: 3.5rem; height: 3.5rem;
    background: var(--chip-bg);
    border-radius: 0.75rem;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.625rem; margin-bottom: 1.125rem;
  }
  .card h3 { font-size: 1.25rem; font-weight: 800; margin-bottom: 0.625rem; color: var(--secondary); }
  .section.dark .card h3 { color: var(--white); }
  .card p { color: var(--gray-text); font-size: 0.9375rem; }
  .section.dark .card p { color: rgba(255,255,255,0.7); }

  /* ---------- Home coaches: the photo plates (JAMIE, Sep 2026) ---------- */
  /* The home band is no longer three "avatar circle + name + stacked roles" cards. It is three
     photo plates: the headshot fills a 288x310 frame graded to navy, the name with the specialties
     stacked under it at the bottom-left of the frame over a scrim, and the qualifying line set as a
     chip hung on the frame's top edge (JAMIE, Sep 2026: it started inside the frame's top-left, moved
     out under the frame, sat centered above it, and now straddles the edge itself, half on the navy
     and half across the photo, with the frame's hairline running out of either side of it). JAMIE
     chose this size from the raster mockups
     (318 beat 265 and the full-width poster plates) — see the 0.9.6 note in
     src/CHANGELOG.md — and then asked for it a little smaller (Sep 2026: *"Make the coaches photos on the homepage a little smaller."*), so the whole plate is the approved mock scaled to 0.906: 16rem IS that mock's 318px scaled: the desktop root is 18px (html { font-size:
     clamp(16px, 1.434vw, 18px) }), so 288 / 18 = 16 — the plates measure
     mock at 288x310 and scale with the root below it. The caption type, the chip's padding, the caption inset and the corner radius all came down with the frame, so the internals keep the mock's ratios instead of growing inside a smaller plate. The block is centered, so it reads narrower
     than the 77.375rem section head, which is the proportion the mock approved. The plates are not
     links, so there is no hover state.
     The grade is painted by the browser, not baked into the files: the plate fills with a deep navy and
     the photo screen-blends over it, so the shadows land on the base and the highlights stay white.
     That base WAS the section's own #00204e (--secondary) — the mock's curve, navy at black, 131/146/169
     at mid gray — and is now the site's deeper #001433 (--secondary-dark): JAMIE dropped it Sep 2026
     (*"drop the plate's base"*) after the band read washed out, because a screen blend can never show
     anything darker than its base and the brightest of the three uploads has no dark end of its own.
     Highlights are unaffected (screen keeps white white); the mid gray moves to ~128/138/153, which is
     the price of the deeper black, and the shadows now match the caption scrim's own navy. grayscale(0.72)
     leaves 25% of the original color, which is the mock's 25% original mix. The square _hs headshots are unchanged: cover-cropping a square into
     a 0.93 plate takes ~7% off the left/right edges and nothing vertically, so no cap clips (the
     reason those files are square — see the COACH_IMG_NAMES note in src/deploy-build.js). */
  .plate-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 16rem));
    justify-content: center;
    /* The chip is out of the flow (see below), so a cell is nothing but its frame and all three are
       the same height already — end-alignment is kept only as a belt-and-braces measure. */
    align-items: end;
    gap: 1.25rem;
  }
  /* The grid cell: the frame, with the chip hung off it. `container-type: inline-size` makes the cell
     the measuring stick for the chip, which has to size against the FRAME rather than the viewport
     (the frame is 288px wide on a desktop and 288px stacked, and the chip has to keep clear of the
     corners at both — see the kicker below). */
  .coach-plate-item {
    position: relative;
    container-type: inline-size;
    display: flex; flex-direction: column;
    margin: 0;
  }
  /* The label, hung on the frame's top edge as an outlined chip (JAMIE's pick, Sep 2026 — he rejected
     the plain label, the two flanking rules, and then the chip floating free above the frame). Its
     midpoint sits ON the edge: the top half reads against the section navy, the bottom half bites into
     the photo, and the frame's own hairline (the .coach-plate border, same color and width) runs out
     of either side of it, so the chip reads as a break in the plate's outline. Three things make that
     work: the chip is hung on the CELL, not the frame (the frame clips with overflow:hidden and would
     cut the overhanging half off); its fill is OPAQUE (the translucent fill it used to carry would
     show the photo through the lower half, and the frame's hairline through the middle); and it sits
     at z-index 2 so its own hairline is the one that wins where the two meet. It keeps the section
     eyebrow's treatment (.pt-eyebrow): caps, weight 800, wide tracking, --primary-light on dark.
     The type is set in cqw against the cell, not in rem: the chip must stay comfortably inside the
     frame's corners at 288px on a desktop, at 288px stacked, and at the squeezed widths between them, so it is
     sized off the frame it sits on; the tracking is in em for the same reason, so the label keeps its
     proportions instead of crowding the frame as it narrows.
     Keep in step with the critical-CSS copy in index.html. */
  .coach-plate-kicker {
    position: absolute;
    z-index: 2;
    top: 0; left: 50%;
    transform: translate(-50%, -50%);
    display: block;
    padding: 0.23rem 0.45rem;
    border: 1.5px solid rgba(133,181,221,0.45);
    border-radius: 0.34rem;
    /* Opaque, but the exact color the old rgba(133,181,221,0.10) fill composited to over the navy,
       so the chip looks the same as when it sat above the frame — it just can't be seen through.
       The fill and the type each keep that old value as a cascade fallback: a browser that predates
       color-mix or container queries gets the chip as it was approved (a translucent chip at
       0.8125rem — still clear of the frame's corners at every width this grid can produce) rather
       than a see-through chip at body size. */
    background: rgba(133,181,221,0.10);
    background: color-mix(in srgb, var(--primary-light) 10%, var(--secondary));
    color: var(--primary-light);
    font-size: 0.735rem;
    font-size: clamp(0.62rem, 4.4cqw, 0.735rem);
    font-weight: 800;
    letter-spacing: 0.15em; text-transform: uppercase; line-height: 1.2;
    /* The label never wraps; the 50rem stack breakpoint exists so it never has to. */
    white-space: nowrap;
  }
  .coach-plate {
    position: relative;
    isolation: isolate;
    /* The hairline the chip breaks into: same color and width as the chip's border, so the two read
       as one outline with the label sitting in it. In px, like the site's other borders (the
       2.25px nav rules), because it is a hairline weight rather than a type-relative measure — JAMIE
       asked for it a touch thicker (Sep 2026: *"slightly thicker outline 1.5px?"*), up from the 1px the
       hairline started at. */
    border: 1.5px solid rgba(133,181,221,0.45);
    /* Soft corners, matching the site's card language (JAMIE asked for squircles, Sep 2026). The
       photo, the grade and the scrim are all clipped by the same radius. The border is inside the
       288x310 (box-sizing: border-box), so the frame's outer size is unchanged. */
    border-radius: 0.68rem;
    aspect-ratio: 318 / 342;
    overflow: hidden;
    /* The black point the screen blend hands to the plate. JAMIE dropped it here (Sep 2026) from the
       section's own --secondary after the band read washed out: a screen blend can never show anything
       darker than its base, and the brightest upload has no dark end of its own. Highlights are
       untouched by the change (screen keeps white white); the shadows deepen from #00204e to #001433
       and the mid gray loses a little of its blue cast. It is already the color the caption scrim used. */
    background: var(--secondary-dark);
  }
  /* --coach-plate-filter is the per-coach hook: Ben's studio upload is blown out and low-contrast (mean
     luma 0.64, against 0.36 and 0.35 for the other two), so index.html hands his img a pulled-down grade
     — since Sep 2026 grayscale(0.72) contrast(1.4) brightness(0.62), which is the family's own color mix
     rather than a grayer one, and which lands his shadow floor level with the other two plates (33 -> 18,
     mean 136 -> 118). No saturate() anywhere in the set: JAMIE's rule is don't oversaturate. */
  .coach-plate-photo {
    display: block;
    width: 100%; height: 100%;
    object-fit: cover;
    filter: var(--coach-plate-filter, grayscale(0.72) contrast(1.12) brightness(1.03));
    mix-blend-mode: screen;
  }
  /* One scrim now, carrying the name and specialties at the foot of the frame. (The short top scrim
     the mock had belonged to the kicker, and the kicker now hangs on the frame's own top edge, so
     nothing up there needs a scrim.) */
  .coach-plate::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(to top, rgba(0,20,51,0.94), rgba(0,20,51,0) 60%);
    pointer-events: none;
  }
  .coach-plate-caption {
    position: absolute; z-index: 1;
    left: 0; right: 0; bottom: 0.85rem;
    padding: 0 0.85rem;
    display: flex; flex-direction: column; align-items: flex-start;
    text-align: left;
  }
  /* The name scales with the viewport because three plates get narrow before the grid stacks; at
     full width the cap wins, so the desktop name is the mock's 31px scaled with the plate to 28.1px (1.56rem). */
  .coach-plate-name {
    display: block;
    color: var(--white);
    font-family: var(--font-primary);
    /* The floor is 1.36rem rather than the old 1.15rem: between the 50rem stack breakpoint and the
       ~1100px where the viewport term takes over, the frame is 215-272px wide and the name has to
       hold "Anthony Torreullas" on one line at a legible size. */
    font-size: clamp(1.36rem, 1.95vw, 1.56rem);
    font-weight: 700; line-height: 1.08; letter-spacing: 0.01em;
  }
  .coach-plate-roles {
    margin-top: 0.17rem;
    color: rgba(255,255,255,0.78);
    font-size: 0.79rem; font-weight: 500;
    letter-spacing: 0.02em; line-height: 1.3;
    /* One line, always (JAMIE, Sep 2026): the wording is kept short enough to clear the narrowest
       plate the layout reaches, so nowrap is safe and the line never wraps inside the frame. */
    white-space: nowrap;
  }
  /* One plate per row below 50rem — held at the desktop plate width and centered instead of stretched
     full-bleed, with a wide row gap so each coach reads as its own block (JAMIE, Sep 2026: the
     full-width stack was "way too large" and the rows had no separation between them).
     This is also the width below which three columns would be too narrow for the longest label
     ("Strength & Conditioning"), so it is the only breakpoint this grid needs. */
  @media (max-width: 50rem) {
    .plate-grid {
      grid-template-columns: minmax(0, 18rem);
      gap: 2rem 0;
    }
    /* STACKED FRAME = 18rem (JAMIE, Sep 2026: "when coach cards are stacked in 1 column the photos
       can be a little bigger"). At a 390px viewport the band's container is 342px wide, so the old
       16rem frame — 256px at the phone root of 16px — left ~86px of the width unused; 18rem
       renders 288px, the same pixel width as a desktop plate, and still clears the container with
       54px to spare. The caption was left alone: the screen is narrow, so the caption is already set
       a step larger than the desktop ratio rather than a step smaller (at this size the caption has
       to carry the photo — JAMIE, Sep 2026), 1.63rem on the name is the largest that still keeps
       "Anthony Torreullas" on one line inside the frame, and a wider frame only gives it more room.
       The chip is deliberately NOT stepped up either: it is sized in cqw against the frame, so it
       holds the same proportions at every width and grew with the frame on its own. */
    .coach-plate-name { font-size: 1.63rem; }
    .coach-plate-roles { font-size: 0.91rem; }
  }
  #home-coaches { container-type: inline-size; }
  .coaches-more { text-align: center; margin-top: 2.125rem; }
  /* The coaches-page profile role line. (Its old home-band twin — the stacked <span> cards — is
     gone; the home band's roles now live in .coach-plate-roles.) The two pages share this class
     name, which is why the bare rule and the #page-coaches override below both still exist. */
  .coach-role { color: var(--primary-light); font-weight: 500; font-size: 0.875rem; margin-bottom: 0.5rem; letter-spacing: 0.0313rem; }

  /* ---------- Coaches page: expandable staff roster (redesign, Sep 2026) ---------- */
  /* Each coach is ONE box. Collapsed it is a compact horizontal mini-bar (thumbnail + role +
     name + one-line hook); clicking it expands that box, in place, into the full editorial
     profile (portrait beside bio, quote, credentials and CTA). One coach open at a time; Ben
     (Apex Founder) is open on load; coaches.html#coach-<id> deep-links open a specific coach.
     The old one-full-width-profile-per-row layout and the centered "Jump to" pills are gone, and
     the credential facts live in ONE place per coach (chips = short tags, highlights = detail) so
     the page no longer prints the same achievement twice. */

  #page-coaches #coachesBody { padding-top: 2.5rem; padding-bottom: 3.5rem; }
  /* Coaches hero matches the standard height (Oct 5 2026, Jamie) — the old shorter-hero padding trim
     is gone, so this page's band lines up with facilities/about. */
  #page-coaches #coachesBody .section-head { margin-bottom: 2rem; }
  #page-coaches #coachesBody .section-head h2::after { margin-top: 0.625rem; }
  #page-coaches .cta-band { padding: 2.75rem 1.5rem; }
  /* Same 56.25rem rail the rosters/about/facilities pages use, so the content columns line up
     across pages. The hero and closing CTA band keep the wide 68.75rem page rail, like every page. */
  #page-coaches #coachesBody > *,
  #page-coaches #coach-system > * {
    max-width: 56.25rem;
  }

  .coach-roster { display: grid; gap: 1rem; }

  .coach-item {
    /* LIGHT-CARD VARIANT (JAMIE: "Gray instead of white" → "Can go deeper gray for closed... Use
       the current gray for open cards"). Cool-gray cards on the navy band: closed = a deeper
       #DBDFE5, the open profile lifts to the near-white #EFF2F6 so its photo reads crisp. The bar +
       detail content is authored for a dark surface, so everything inside is recolored by the
       "#page-coaches .coach-item" override block below. The accent text is `#35608F` (not
       `--primary-dark`) because the deeper gray drops the lighter steel-blue under 4.5:1. To go back
       to WHITE cards, set both surfaces to `var(--white)`; to go back to the TINTED-GLASS cards,
       restore `background: rgba(102,153,204,0.16)` / border `rgba(133,181,221,0.30)` / stripe
       `var(--primary-light)` (open fill `rgba(102,153,204,0.24)`, open border `0.42`), put the old
       box-shadows back, and delete the override block.

       ACCENT BAR: a 6px (`0.375rem`) left bar, and per JAMIE ("That side accent can be primary dark for both
       accordion states") it is `--primary-dark` (#4A7AAF) in BOTH states — resting rows and the open profile
       alike (previously the brand `--primary` #6699CC in both states, per the earlier "Full blue in both
       states (not navy)" call). `--primary-dark` measures ~3.34:1 on the light cards (a clear edge, not a
       glare); brand `--primary` was the softer 2.24:1 / 2.68:1 option. (A flat color: a `border-left` can't
       take a gradient — that needs a pseudo-element or `border-image`, both of which fight the card's
       `border-radius`.) */
    background: #DBDFE5;
    border: 0.0625rem solid rgba(0,32,78,0.10);
    border-left: 0.375rem solid var(--primary-dark);
    border-radius: 1rem;
    overflow: hidden;
    box-shadow: 0 1rem 2rem rgba(0,0,0,0.28);
    scroll-margin-top: calc(var(--header-h) + 1.25rem);
    transition: background 0.2s, border-color 0.2s, box-shadow 0.2s;
  }
  .coach-item.is-open {
    background: #EFF2F6;
    border-color: rgba(0,32,78,0.16);
    border-left-color: var(--primary-dark);
    box-shadow: 0 1.375rem 2.75rem rgba(0,0,0,0.34);
  }
  /* Recolor the roster's whole front-end for the light card. Scoped to #page-coaches so the HOME
     page's dark `.coach-role` / `.coach-card` type (which shares the `.coach-role` class) is
     untouched. Delete this whole block to go back to the tinted-glass cards. */
  #page-coaches .coach-item .coach-bar:hover { background: rgba(0,32,78,0.05); }
  #page-coaches .coach-item .coach-bar:focus-visible { outline-color: var(--primary); }
  #page-coaches .coach-item .coach-thumb { border-color: rgba(0,32,78,0.12); }
  #page-coaches .coach-item .coach-bar-role,
  #page-coaches .coach-item .coach-role,
  #page-coaches .coach-item .coach-bar-more,
  #page-coaches .coach-item .coach-quote cite { color: #35608F; }
  #page-coaches .coach-item .coach-bar-name,
  #page-coaches .coach-item .coach-name { color: var(--secondary); }
  #page-coaches .coach-item .coach-bar-hook { color: var(--gray-text); }
  #page-coaches .coach-item .coach-collapse {
    background: rgba(0,32,78,0.05); color: var(--secondary);
    border-color: rgba(0,32,78,0.18);
  }
  #page-coaches .coach-item .coach-collapse:hover {
    background: var(--primary); border-color: var(--primary); color: var(--white);
  }
  #page-coaches .coach-item .coach-bio,
  #page-coaches .coach-item .coach-highlights li { color: var(--gray-text); }
  #page-coaches .coach-item .coach-quote { color: var(--secondary); }
  #page-coaches .coach-item .coach-chip {
    color: var(--secondary); background: rgba(102,153,204,0.14);
    border-color: rgba(102,153,204,0.42);
  }
  #page-coaches .coach-item .coach-needs {
    color: #8A5A0B; background: rgba(242,200,121,0.22);
    border-color: rgba(199,146,32,0.6);
  }
  #page-coaches .coach-item .coach-detail-media .coach-photo { box-shadow: 0 0.75rem 1.75rem rgba(0,32,78,0.18); }

  .coach-bar {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center; gap: 1.125rem;
    width: 100%; text-align: left;
    font: inherit; color: inherit;
    background: none; border: 0; padding: 1.25rem 1.25rem;
    cursor: pointer;
    transition: background 0.18s;
  }
  .coach-bar:hover { background: rgba(255,255,255,0.05); }
  .coach-bar:focus-visible { outline: 0.125rem solid var(--primary-light); outline-offset: -0.125rem; }
  .coach-item.is-open .coach-bar { display: none; }
  .coach-bar-media { display: block; }
  .coach-thumb {
    display: block; width: 4.5rem; height: 4.5rem;
    object-fit: cover; object-position: var(--coach-thumb-pos, center top);
    border-radius: 0.625rem;
    border: 0.0625rem solid rgba(255,255,255,0.18);
  }
  .coach-bar-text {
    min-width: 0;
    display: grid;
    /* Fixed identity column width so the hook/blurb always starts at the same x on every bar.
       Sized to the longest role line (Anthony's three-discipline line, ~347px) so the blurb
       sits as far left as the bars allow without the role wrapping. */
    grid-template-columns: 20rem minmax(0, 1fr);
    align-items: center;
    gap: clamp(1.25rem, 3vw, 2.5rem);
  }
  .coach-bar-id { min-width: 0; }
  .coach-bar-role {
    display: block; font-family: var(--font-primary); font-size: 0.6875rem; font-weight: 700;
    letter-spacing: 0.14em; text-transform: uppercase; color: var(--primary-light);
  }
  .coach-bar-name {
    display: block; font-family: var(--font-primary);
    font-size: 1.375rem; font-weight: 800; line-height: 1.15; color: var(--white);
    margin-top: 0.1875rem;
  }
  .coach-bar-hook {
    display: block; font-size: 0.875rem; line-height: 1.45;
    color: rgba(255,255,255,0.62);
  }
  .coach-bar-more {
    display: inline-flex; align-items: center; gap: 0.5rem;
    font-family: var(--font-primary); font-size: 0.75rem; font-weight: 700;
    letter-spacing: 0.1em; text-transform: uppercase; color: var(--primary-light);
    white-space: nowrap;
  }
  .coach-chev { width: 1.125rem; height: 1.125rem; flex: 0 0 auto; }

  .coach-detail { padding: 0.5rem 1.25rem 1.5rem; animation: coachDetailIn 0.24s ease; }
  html.lite .coach-detail { animation: none; }
  @keyframes coachDetailIn {
    from { opacity: 0; transform: translateY(-0.25rem); }
    to { opacity: 1; transform: none; }
  }
  .coach-detail-grid {
    display: grid; grid-template-columns: 0.82fr 1fr;
    gap: clamp(1.5rem, 3vw, 2.75rem); align-items: start;
  }
  .coach-detail-media { min-width: 0; }
  #page-coaches .coach-detail-media .coach-photo {
    display: block; width: 100%; height: auto;
    aspect-ratio: 4 / 5;
    object-fit: cover;
    object-position: var(--coach-photo-pos, center top);
    border-radius: 0.75rem;
    box-shadow: 0 1.125rem 2.5rem rgba(0,0,0,0.35);
  }
  .coach-detail-body { min-width: 0; }
  .coach-detail-top {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 1rem; margin-bottom: 1rem;
  }
  /* Scoped to #page-coaches: this rule's class is shared with the HOME page's coach cards, and as a
     bare `.coach-role` it came later in the sheet than the home rule, so its uppercase + 0.75rem +
     0.13em tracking leaked onto the home cards. Scoping it lets the home cards fall back to their
     own `.coach-role` rule above (0.875rem, weight 500, no caps). Same class, two pages. */
  #page-coaches .coach-role {
    font-family: var(--font-primary); font-size: 0.75rem; font-weight: 600;
    letter-spacing: 0.13em; text-transform: uppercase;
    color: var(--primary-light); margin-bottom: 0.375rem;
  }
  .coach-name {
    font-family: var(--font-primary);
    font-size: clamp(1.75rem, 3.2vw, 2.375rem);
    font-weight: 900; line-height: 1.08; color: var(--white);
  }
  .coach-collapse {
    flex: 0 0 auto; width: 2.25rem; height: 2.25rem;
    display: inline-flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.06); color: var(--white);
    border: 0.0625rem solid rgba(255,255,255,0.22); border-radius: 62.4375rem;
    cursor: pointer; transition: background 0.18s, border-color 0.18s;
  }
  .coach-collapse:hover { background: var(--primary); border-color: var(--primary); }
  .coach-collapse:focus-visible { outline: 0.125rem solid var(--primary-light); outline-offset: 0.125rem; }
  .coach-collapse svg { width: 1.125rem; height: 1.125rem; display: block; }

  .coach-bio {
    font-size: 1rem; line-height: 1.65;
    color: rgba(255,255,255,0.78);
    max-width: 48ch; margin-bottom: 1.125rem;
  }
  .coach-quote {
    margin: 0 0 1.25rem; padding: 0.125rem 0 0.125rem 1.125rem;
    border-left: 0.1875rem solid var(--primary);
    font-style: italic; font-size: 1.0625rem; line-height: 1.55;
    color: rgba(255,255,255,0.92);
  }
  .coach-quote cite {
    display: block; margin-top: 0.5rem;
    font-family: var(--font-primary); font-style: normal;
    font-size: 0.75rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--primary-light);
  }
  .coach-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 1.25rem; }
  .coach-chip {
    font-family: var(--font-primary); font-size: 0.75rem; font-weight: 600;
    letter-spacing: 0.05em; color: var(--white);
    background: var(--chip-bg);
    border: 0.0625rem solid rgba(102,153,204,0.45);
    padding: 0.3125rem 0.6875rem; border-radius: 62.4375rem;
  }
  .coach-highlights { list-style: none; display: grid; gap: 0.5rem; margin-bottom: 1.5rem; }
  .coach-highlights li {
    position: relative; padding-left: 1.375rem;
    font-size: 0.9375rem; line-height: 1.55; color: rgba(255,255,255,0.72);
  }
  .coach-highlights li::before {
    content: ""; position: absolute; left: 0.0625rem; top: 0.4375rem;
    width: 0.5rem; height: 0.3125rem;
    border-left: 0.125rem solid var(--primary);
    border-bottom: 0.125rem solid var(--primary);
    transform: rotate(-45deg);
  }
  .coach-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; }
  .coach-actions .btn-primary { font-size: 0.875rem; }
  .coach-needs {
    display: inline-block;
    font-family: var(--font-primary); font-style: normal;
    font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
    color: #F2C879;
    background: rgba(242,200,121,0.12);
    border: 0.0625rem dashed rgba(242,200,121,0.65);
    padding: 0.1875rem 0.5rem; border-radius: 0.3125rem;
  }
  .coach-pillar-lead {
    margin-top: 0.875rem;
    font-family: var(--font-primary); font-size: 0.8125rem; font-weight: 700;
    letter-spacing: 0.1em; text-transform: uppercase; color: var(--primary);
  }

  #coach-system { padding-top: 3rem; padding-bottom: 3.25rem; }
  #coach-system .section-head { margin-bottom: 2rem; }
  /* The pillars are a light supporting section — they should read quieter than the roster above,
     not compete with it, so the cards lose their shadow/weight and the type steps down a size. */
  #coach-system .card { padding: 1.5rem 1.5rem 1.625rem; box-shadow: none; border-top-width: 0.1875rem; }
  #coach-system .card-icon { width: 2.75rem; height: 2.75rem; margin-bottom: 0.75rem; }
  #coach-system .card-icon svg { width: 1.75rem; height: 1.75rem; }
  #coach-system .card h3 { font-size: 1.125rem; margin-bottom: 0.4375rem; }
  #coach-system .card p { font-size: 0.875rem; line-height: 1.6; }
  #coach-system .coach-pillar-lead { margin-top: 0.6875rem; }
  /* Three pillars, always 3-up until they stack. The shared auto-fit left the third card orphaned
     on its own row between roughly 601-828px — an iPad portrait width. */
  #coach-system .card-grid { grid-template-columns: repeat(3, 1fr); }

  @media (max-width: 999px) {
    .coach-bar-text { grid-template-columns: 1fr; gap: 0; }
    .coach-bar-hook { margin-top: 0.25rem; }
  }
  @media (max-width: 860px) {
    .coach-detail-grid { grid-template-columns: 1fr; }
    .coach-detail-media { width: 100%; max-width: 24rem; margin-inline: auto; }
    #page-coaches .coach-detail-media .coach-photo { aspect-ratio: 4 / 5; }
    #coach-system .card-grid { grid-template-columns: 1fr; }
  }
  @media (max-width: 560px) {
    .coach-bar { gap: 0.875rem; padding: 1rem 0.875rem; }
    /* On phones the bar drops the hook, so the "Profile" control is the whole affordance — give it
       a filled pill so it reads as a button instead of a stray chevron. */
    .coach-bar-more {
      gap: 0.3125rem; padding: 0.4375rem 0.6875rem;
      background: var(--primary); color: var(--white);
      border-radius: 62.4375rem; font-size: 0.6875rem; letter-spacing: 0.08em;
    }
    /* Keep the phone "Profile" pill's white label: the white-card override block gives
       .coach-bar-more a dark-blue color, which would sit on this filled pill. */
    #page-coaches .coach-item .coach-bar-more { color: var(--white); }
    .coach-bar-role { font-size: 0.625rem; letter-spacing: 0.08em; }
    .coach-thumb { width: 3.75rem; height: 3.75rem; }
    .coach-bar-name { font-size: 1.1875rem; }
    .coach-bar-hook { display: none; }
    .coach-detail { padding: 0.375rem 0.875rem 1.25rem; }
    .coach-name { font-size: 1.625rem; }
    .coach-bio { font-size: 0.9375rem; }
    .coach-highlights li { font-size: 0.875rem; }
    .coach-quote { font-size: 1rem; }
    .coach-chip { font-size: 0.6875rem; }
  }
  /* ---------- Testimonials ---------- */
  .testimonial-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(17.5rem, 1fr));
    gap: 1.625rem;
  }
  .testimonial-card {
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-top: 0.25rem solid var(--card-accent);
    border-radius: 0.75rem;
    padding: 2rem 1.75rem;
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
    display: flex;
    flex-direction: column;
    transition: transform 0.2s, box-shadow 0.2s;
  }
  .testimonial-card:hover { transform: translateY(-0.25rem); box-shadow: 0 0.75rem 2.25rem rgba(0,32,78,0.12); }
  .testimonial-quote-mark {
    font-family: 'Oswald', sans-serif;
    font-size: 3.5rem;
    line-height: 1;
    color: var(--primary);
    opacity: 0.4;
    margin-bottom: 0.375rem;
    user-select: none;
  }
  .testimonial-quote {
    flex: 1;
    font-size: 0.9375rem;
    color: var(--dark-gray);
    line-height: 1.7;
    margin-bottom: 1.25rem;
    font-style: italic;
  }
  .testimonial-author {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    border-top: 0.0625rem solid var(--light-gray);
    padding-top: 1rem;
  }
  .testimonial-avatar {
    width: 2.75rem; height: 2.75rem;
    border-radius: 50%;
    background: var(--secondary);
    color: var(--white);
    font-family: var(--font-primary);
    font-weight: 700;
    font-size: 0.9375rem;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
  }
  .testimonial-name { font-size: 0.9375rem; font-weight: 700; color: var(--secondary); }
  .testimonial-role { font-size: 0.8125rem; color: var(--gray-text); }
  #testimonials { container-type: inline-size; }
  @container (min-width: 36.625rem) and (max-width: 55.7494rem) {
    .testimonial-card:last-child:nth-child(odd) {
      grid-column: 1 / -1;
      justify-self: center;
      width: calc((100% - 1.625rem) / 2);
    }
  }
  @container (max-width: 36.6244rem) {
    .testimonial-grid .testimonial-card { max-width: 23.75rem; margin: 0 auto; aspect-ratio: auto; }
  }

  /* ---------- Schedule / CTA ---------- */
  .cta-band {
    background: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-dark) 100%);
    color: var(--white);
    text-align: center;
    padding: 3.25rem 1.5rem;
    position: relative;
    overflow: hidden;
  }
  .cta-band h2 { font-size: clamp(1.625rem, 3.75vw, 2.375rem); font-weight: 900; margin-bottom: 0.75rem; position: relative; z-index: 1; }
  #schedule h2 { margin-bottom: 1.75rem; }
  .cta-band p { font-size: 1.0625rem; opacity: 0.92; margin-bottom: 1.75rem; position: relative; z-index: 1; }
  .cta-band .btn-primary { position: relative; z-index: 1; }
  .cta-break { display: none; }
  @media (min-width: 641px) {
    .cta-break { display: inline; }
  }
  .br-above-440 { display: none; }
  @media (min-width: 441px) {
    .br-above-440 { display: inline; }
  }

  /* ---------- Program Sections ---------- */
  /* ---------- Program Tabs ---------- */
  .program-tabs { background: var(--light-gray); padding: 5rem 1.5rem 1.75rem; }
  .tab-bar { scroll-margin-top: calc(var(--header-h) + var(--tabbar-gap)); }
  .program-tabs-inner { max-width: 68.75rem; margin: 0 auto; }
  .program-tabs-head { text-align: center; margin-bottom: 0.75rem; }
  .program-tabs-head .pt-eyebrow {
    display: block;
    font-size: 0.8125rem; font-weight: 800; letter-spacing: 0.125rem; text-transform: uppercase;
    color: var(--primary); margin-bottom: 0.5rem;
  }
  .program-tabs-head h2 { font-size: clamp(1.5rem, 3vw, 2.125rem); font-weight: 900; color: var(--secondary); margin-bottom: 0.25rem; }
  .program-tabs-head p { color: var(--gray-text); font-size: 0.9375rem; max-width: 35rem; margin: 0 auto; text-wrap: balance; }
  .tab-bar {
    display: flex;
    gap: 0.375rem;
    padding: 0.625rem 0.875rem 0;
    background: #D7DBE1;
    border-bottom: 0.125rem solid #C2C8D0;
    border-radius: 0.875rem 0.875rem 0 0;
    overflow-x: auto;
    overflow-y: hidden;
  }
  .tab {
    background: #C2C8D0;
    border: none;
    border-radius: 0.5625rem 0.5625rem 0 0;
    border-bottom: 0.125rem solid transparent;
    margin-bottom: -0.125rem;
    padding: 0.5rem 1.125rem;
    font: 700 0.875rem 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
    color: var(--secondary);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s;
  }
  .tab:hover { background: #CDD3DA; }
  .tab.active { background: var(--white); color: var(--secondary); border-bottom-color: var(--white); }
  .program-panels {
    background: var(--white);
    border-radius: 0 0 0.875rem 0.875rem;
    box-shadow: 0 0.375rem 1.5rem rgba(0,32,78,0.08);
  }
  .program-panel { display: none; padding: 1.25rem 2.5rem; overflow-y: auto; min-height: calc(100vh - var(--header-h) - var(--tab-h) - var(--tabbar-gap) - 1.75rem); max-height: calc(100vh - var(--header-h) - var(--tab-h) - var(--tabbar-gap) - 1.75rem); }
  @media (min-width: 1281px) and (min-height: 721px) {
    .program-panel { min-height: calc(min(100vh - var(--header-h) - var(--tab-h) - var(--tabbar-gap) - 1.75rem, 30rem)); max-height: calc(min(100vh - var(--header-h) - var(--tab-h) - var(--tabbar-gap) - 1.75rem, 30rem)); }
  }
  .program-panel.active { display: flex; }
  .program-panel .program-grid { grid-template-columns: 1fr 1fr; gap: 2.5rem; align-items: stretch; width: 100%; margin-top: auto; margin-bottom: auto; }
  .program-panel .program-card { display: flex; flex-direction: column; align-items: flex-start; }
  .program-panel .program-card dl { flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; width: 100%; padding-left: 0.5rem; }
  .program-panel .program-card .d-row { display: flex; flex-direction: column; }
  .program-panel .program-card .coaches {
    display: grid;
    grid-template-columns: auto 0.0625rem 1fr;
    gap: 0.75rem;
    align-items: stretch;
    margin-top: 0.5rem;
  }
  .program-panel .program-card .coach-names,
  .program-panel .program-card .coach-specs {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    font-size: 0.8125rem;
    line-height: 1.3;
  }
  .program-panel .program-card .coach-rule {
    width: 0.0625rem;
    align-self: stretch;
    background: var(--gray);
    opacity: 0.6;
  }
  .program-panel .program-eyebrow { margin-bottom: 0.5rem; }
  .program-panel .program-copy h2 { font-size: clamp(1.375rem, 3vw, 1.875rem); margin-bottom: 0.625rem; }
  .program-panel .program-copy p { font-size: 0.9375rem; margin-bottom: 0.875rem; }
  .program-panel .program-copy .btn-primary { margin-top: 0.625rem; }
  .program-panel .program-list { margin-bottom: 1.125rem; }
  .program-panel .program-list li { font-size: 0.875rem; margin-bottom: 0.375rem; }
  .program-panel .program-card { padding: 1.25rem 1.5rem; }
  .program-panel .program-card .card-icon { width: 2.375rem; height: 2.375rem; font-size: 1.125rem; margin-bottom: 0.5rem; }
  .program-panel .program-card h3 { font-size: 1.125rem; margin-bottom: 0.25rem; }
  .program-panel .program-card dd { font-size: 0.875rem; margin: 0.125rem 0 0; }
  .program-panel .btn-outline-dark, .program-panel .btn-outline-white { margin-top: 1rem; padding: 0.6875rem 1.625rem; }

  /* ---------- Photo Bands ---------- */
  .photo-band {
    position: relative;
    background-size: cover;
    background-position: center;
    height: clamp(12.5rem, 26vw, 18.75rem);
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
  }
  .photo-band::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(rgba(0,32,78,0.45), rgba(0,20,51,0.78));
  }
  .photo-band p {
    position: relative;
    z-index: 1;
    color: var(--white);
    font-size: clamp(1.25rem, 3vw, 1.875rem);
    font-weight: 800;
    letter-spacing: 0.0625rem;
    max-width: 40rem;
    margin: 0 1.5rem;
  }
  @media (min-width: 901px) {
    .photo-band { background-attachment: fixed; }
  }

  .program-section { padding: 3rem 1.5rem; }
  .program-section.alt { background: var(--light-gray); }
  .program-section .section-inner { max-width: 68.75rem; margin: 0 auto; }
  .program-grid {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 3.5rem;
    align-items: center;
  }
  .program-grid.flip .program-card { order: -1; }
  .program-eyebrow {
    display: inline-block;
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.125rem;
    text-transform: uppercase;
    color: var(--primary);
    margin-bottom: 0.75rem;
  }
  .program-copy h2 {
    font-size: clamp(1.625rem, 3.5vw, 2.375rem);
    font-weight: 900;
    color: var(--secondary);
    margin-bottom: 0.875rem;
    line-height: 1.15;
  }
  .program-copy p { color: var(--gray-text); font-size: 1.0625rem; max-width: 33.75rem; margin-bottom: 1rem; }
  .program-list { list-style: none; margin-bottom: 1.25rem; }
  .program-list li {
    display: flex; gap: 0.625rem; align-items: flex-start;
    color: var(--dark-gray); font-size: 0.9375rem; margin-bottom: 0.5rem;
  }
  .program-list li::before { content: "✓"; color: var(--primary); font-weight: 900; flex-shrink: 0; }
  .program-card {
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-top: 0.25rem solid var(--card-accent);
    border-radius: 0.875rem;
    padding: 1.625rem 1.625rem;
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
  }
  .program-card .card-icon { width: 2.875rem; height: 2.875rem; font-size: 1.375rem; margin-bottom: 0.75rem; }
  .card-title-row { display: flex; align-items: center; gap: 0.75rem; }
  .program-card .card-title-row { margin-bottom: 0.75rem; }
  .program-card .card-title-row .card-icon { margin-bottom: 0; }
  .program-panel .program-card .card-title-row .card-icon { margin-bottom: 0; }
  .program-panel .program-card .card-title-row { margin-bottom: 0.5rem; }
  .program-card h3 { font-size: 1.125rem; font-weight: 800; color: var(--secondary); margin-bottom: 0.25rem; }
  .program-card dl { margin: 0; }
  .program-card dt {
    font-size: 0.6875rem; font-weight: 800; text-transform: uppercase;
    letter-spacing: 0.0625rem; color: var(--primary); margin-top: 0.5625rem;
  }
  .program-card dd { font-size: 0.875rem; color: var(--dark-gray); margin: 0.125rem 0 0; }
  .btn-outline-dark {
    display: inline-block;
    margin-top: 1rem;
    padding: 0.625rem 1.375rem;
    border: 0.125rem solid var(--secondary);
    color: var(--secondary);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 0.875rem;
    box-shadow: 0 0.25rem 0.875rem rgba(0,32,78,0.14);
    transition: background 0.2s, color 0.2s, box-shadow 0.2s;
  }
  .btn-outline-dark:hover { background: var(--secondary); color: var(--white); box-shadow: 0 0.375rem 1.25rem rgba(0,32,78,0.25); }
  .program-section.dark { position: relative; background: var(--secondary); color: var(--white); }
  .program-section.dark .section-inner { position: relative; z-index: 1; }
  .program-section.dark .program-eyebrow { color: var(--primary-light); }
  .program-section.dark .program-copy h2 { color: var(--white); }
  .program-section.dark .program-copy p { color: rgba(255,255,255,0.72); }
  .program-section.dark .program-list li { color: rgba(255,255,255,0.9); }
  .program-section.dark .program-list li::before { color: var(--primary-light); }
  .program-section.dark .program-card {
    background: rgba(255,255,255,0.08);
    border: 0.0625rem solid rgba(255,255,255,0.15);
    border-top: 0.25rem solid var(--primary);
    box-shadow: 0 0.5rem 1.75rem rgba(0,0,0,0.25);
  }
  .program-section.dark .program-card h3 { color: var(--white); }
  .program-section.dark .program-card dt { color: var(--primary-light); }
  .program-section.dark .program-card dd { color: rgba(255,255,255,0.85); }
  .btn-outline-white {
    display: inline-block;
    margin-top: 1rem;
    padding: 0.625rem 1.375rem;
    border: 0.125rem solid rgba(255,255,255,0.6);
    color: var(--white);
    border-radius: 0.5rem;
    text-decoration: none;
    font-weight: 700;
    font-size: 0.875rem;
    transition: background 0.2s, color 0.2s, border-color 0.2s;
  }
  .btn-outline-white:hover { background: var(--white); color: var(--secondary); border-color: var(--white); }


  /* ---------- Follow / Social ---------- */
  #follow { padding: 3.5rem 1.5rem 4rem; }
  #follow .section-head { margin-bottom: 2.125rem; }
  .social-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2.5rem;
    max-width: 48.75rem;
    margin: 0 auto;
  }
  /* The cards are switched on or off from the Social Tiles admin tab, so the
     number actually showing decides the grid — one or two cards stay centered
     instead of hugging the left of a three-column track. */
  .social-grid[data-visible="1"] { grid-template-columns: minmax(0, 20rem); justify-content: center; }
  .social-grid[data-visible="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 32.5rem; }
  .social-card {
    position: relative;
    min-width: 0;
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.875rem;
    padding: 1.125rem 0.875rem 3.75rem;
    text-align: center;
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
    transition: transform 0.2s, box-shadow 0.2s;
    display: flex;
    flex-direction: column;
  }
  .yt-card { overflow: clip; }
  .social-card::before {
    content: "";
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 0.25rem;
    border-radius: 0.875rem 0.875rem 0 0;
  }
  .social-card.ig-card::before { background: linear-gradient(45deg, #F77737, #E1306C, #833AB4); }
  .social-card.fb-card::before { background: #1877F2; }
  .social-card.yt-card::before { background: #FF0000; }
  .social-card:hover { transform: translateY(-0.25rem); box-shadow: 0 0.75rem 1.875rem rgba(0,32,78,0.1); }
  .social-icon { width: 2.125rem; height: 2.125rem; margin: 0 auto 0.5rem; display: block; }
  .social-card h3 { font-size: 0.9375rem; font-weight: 800; color: var(--secondary); }
  .social-handle { font-size: 0.75rem; color: var(--gray); margin-bottom: 0.625rem; overflow-wrap: anywhere; }
  .social-tile-grid { flex: 1; display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; gap: 0.3125rem; margin-bottom: 0.625rem; width: 100%; }
  .social-tile { border-radius: 0.3125rem; background-size: cover; background-position: center; }
  .social-video {
    position: relative;
    aspect-ratio: 16/9;
    border-radius: 0.3125rem;
    background-size: cover;
    background-color: rgba(0, 32, 78, 0.06);
    background-position: center;
    margin-bottom: 0.5rem;
    flex: none;
    width: 100%;
  }
  .social-video::after {
    content: "▶";
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 1.125rem;
    background: rgba(0,0,0,0.25);
    border-radius: 0.3125rem;
  }
  .social-caption {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--dark-gray);
    line-height: 1.35;
    min-height: 2.7em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
    text-decoration: none;
    margin-bottom: 0.625rem;
  }
  .social-caption[href]:hover { color: var(--secondary); text-decoration: underline; }
  .social-follow {
    position: absolute;
    left: 50%;
    bottom: 0.875rem;
    transform: translateX(-50%);
    padding: 0.4375rem 0.875rem;
    border-radius: 0.375rem;
    font-weight: 700;
    font-size: 0.75rem;
    text-decoration: none;
    color: var(--white);
    white-space: nowrap;
    transition: transform 0.15s, box-shadow 0.15s, opacity 0.2s;
  }
  .social-follow:hover { transform: translateX(-50%) translateY(-0.125rem); box-shadow: 0 0.375rem 1.125rem rgba(0,0,0,0.2); opacity: 0.92; }
  .social-follow.ig { background: linear-gradient(45deg, #F77737, #E1306C, #833AB4); }
  .social-follow.fb { background: #1877F2; }
  .social-follow.yt { background: #FF0000; }

  /* ---------- Footer ---------- */
  footer {
    background: var(--white);
    border-top: 0.1875rem solid var(--secondary);
    padding: 3.125rem max(1.5rem, calc((100vw - 68.75rem) / 2)) 1.75rem;
  }
  .footer-wrap {
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 2.25rem;
    max-width: 68.75rem; margin: 0 auto;
  }
  .footer-links { flex: 1 1 0; min-width: 9.375rem; }
  .footer-brand { flex: 1.5 1 0; }
  .footer-col h5 {
    font-size: 0.875rem; font-weight: 800; color: var(--secondary);
    text-transform: uppercase; letter-spacing: 0.0625rem; margin-bottom: 0.875rem;
  }
  .footer-col:not(.footer-brand) h5 {
    font-size: 1rem;
  }
  .footer-col a {
    display: flex; align-items: center; gap: 0.5rem; text-decoration: none; color: var(--gray-text);
    font-size: 0.875rem; margin-bottom: 0.5625rem; transition: color 0.2s;
  }
  .footer-col a:hover { color: var(--primary); }
  .footer-col a svg { width: 1.125rem; height: 1.125rem; flex-shrink: 0; transition: transform 0.2s; }
  .footer-col a:hover svg { transform: scale(1.12); }
  .footer-col a.footer-sub { padding-left: 1.125rem; font-size: 0.8125rem; }
  .footer-col a.footer-sub::before { content: "•"; color: var(--gray-text); }
  .social-row { display: contents; }
  .footer-brand .logo { margin-bottom: 0.75rem; color: var(--secondary); }
  .footer-brand p { color: var(--gray-text); font-size: 0.9375rem; max-width: 15rem; }
  .footer-tagline-row {
    margin: 2rem auto 0;
    max-width: 68.75rem;
    text-align: right;
  }
  .footer-tagline { font-style: italic; color: var(--primary-text); }
  .footer-bottom {
    position: relative;
    margin: 0.75rem auto 0;
    max-width: 68.75rem;
    border-top: 0.0625rem solid var(--light-gray);
    padding-top: 1.25rem;
    text-align: center;
    color: var(--gray-text); font-size: 0.8125rem;
  }
  .footer-privacy, .footer-terms {
    display: inline-block;
    margin-top: 0.375rem;
    color: var(--gray-text);
    font-size: 0.8125rem;
    text-decoration: underline;
    text-underline-offset: 0.15em;
  }
  /* Footer separator (Sep 16 2026, JAMIE: "put a bullet between Privacy Policy and Terms of Service links"):
     the two legal links are separated by a middle dot rather than by a gap, so the pair reads as one
     list. It's a plain span (aria-hidden), not a ::before on the Privacy link, so the bullet is not
     part of either link's click target and screen readers skip it. Margins sit on the span, so the
     spacing stays even on both sides. */
  .footer-sep {
    display: inline-block;
    margin: 0.375rem 0.5rem 0;
    color: var(--gray);
    font-size: 0.8125rem;
  }
  .footer-privacy:hover, .footer-privacy:focus-visible,
  .footer-terms:hover, .footer-terms:focus-visible { color: var(--primary-dark); }
  /* Build badge (Sep 15 2026, JAMIE): the build number (stamped at build time from src/CHANGELOG.md —
     "v0.9.5" as of Sep 16 2026), bottom-left of the footer on
     every page in every environment. It rides the Privacy Policy line (same row, far left) rather
     than sitting on a line of its own, so the footer keeps its centered rhythm instead of sprouting
     a lone left-aligned string. Deliberately tiny and gray so it's easy to miss; the number is
     stamped from src/CHANGELOG.md by src/deploy-build.js (the dev ground shows index.html's copy). */
  .footer-build {
    position: absolute;
    left: 0;
    bottom: 0;
    text-align: left;
    color: var(--gray);
    font-size: 0.6875rem;
    letter-spacing: 0.03125rem;
    opacity: 0.7;
  }
  /* Phone widths (Sep 16 2026, JAMIE: "Move the version number to its own line at phone widths.
     Smaller version number text"): on a narrow footer the far-left stamp crowds the legal links, so
     below 640px it drops its absolute position and becomes its own centered line under them, one
     notch smaller again. */
  @media (max-width: 640px) {
    .footer-build {
      position: static;
      display: block;
      margin-top: 0.375rem;
      text-align: center;
      font-size: 0.625rem;
    }
  }
  @media (min-width: 981px) {
    .footer-brand { transform: translateX(3.125rem); }
  }

  /* Keyboard focus ring (Sep 16 2026 a11y pass): one consistent, visible focus indicator for links,
     buttons and every focusable control that doesn't already style its own. :focus-visible means a mouse
     click paints nothing (so the design is unchanged for pointer users) while keyboard/AT focus always
     shows. Components with a bespoke ring (e.g. .coach-bar, .coach-collapse, the form inputs) win on
     specificity and keep their own treatment. */
  a:focus-visible,
  button:focus-visible,
  select:focus-visible,
  textarea:focus-visible,
  summary:focus-visible,
  input:focus-visible,
  [tabindex]:focus-visible,
  [role="button"]:focus-visible,
  [role="tab"]:focus-visible {
    outline: 0.125rem solid var(--primary);
    outline-offset: 0.125rem;
  }

  /* ---------- Rosters Page ---------- */
  .rosters-hero {
    background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,20,51,0.78) 0%, rgba(0,20,51,0.56) 60%, rgba(0,20,51,0.38) 100%), var(--hero-img, none) center / cover no-repeat;
    color: var(--white);
    text-align: center;
    padding: 4.375rem 1.5rem;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
  .rosters-hero > * {
    width: 100%;
    max-width: 68.75rem;
    margin-left: auto;
    margin-right: auto;
  }
  .rosters-hero h1 {
    font-size: clamp(1.875rem, 4.5vw, 3rem);
    font-weight: 900;
    margin: 0 0 0.625rem;
    position: relative; z-index: 1;
  }
  .br-hero { display: none; }
  @media (max-width: 640px) {
    .br-hero { display: inline; }
  }
  .rosters-hero p { font-size: 1.0625rem; opacity: 0.92; position: relative; z-index: 1; }
  /* About hero art (Sep 18 2026): three crops of the same photograph — one per band of screen
     width — picked up from the --hero-lg / --hero-md / --hero-sm custom properties the markup sets
     INLINE on the About hero (this rule maps the width-appropriate one into the single --hero-img
     slot the band paints). The vars stay inline and the choice is made here because an inline
     declaration beats a stylesheet one for the same property name: an inline --hero-img could never
     be swapped by a media query, so the markup no longer sets --hero-img at all.
     At laptop width and up the band takes the shape of JAMIE's own 4.085:1 crop, so `cover` shows
     that crop whole. Below that the band is TALLER than the photo and the wide crop could only be
     sliced at the sides — losing whichever coach fell outside the middle strip — so each narrower
     band uses its own crop of the original, framed around the coaches' band of the photo, and the
     vertical value keeps their heads out of the trim as the box grows taller on the way down. */
  #page-about .rosters-hero { --hero-img: var(--hero-lg); }
  @media (max-width: 1023px) {
    #page-about .rosters-hero {
      --hero-img: var(--hero-md);
      background-position: center, 50% 25%;
    }
  }
  @media (max-width: 640px) {
    #page-about .rosters-hero {
      --hero-img: var(--hero-sm);
      background-position: center, 50% 10%;
    }
  }
  @media (min-width: 1024px) {
    #page-about .rosters-hero {
      aspect-ratio: 4085 / 1000;
      width: 100%;
    }
  }
  /* News hero (Oct 2026): the Maryland Little League Champions banner itself, crowning the Summer
     of Glove article. Textless by design — the article carries its own headline — so the band is pure
     banner. Full-bleed, cropped close: the band's 1654:590 shape shows the middle ~71% of the face
     (keeps 14%–86% — the 2026 starts at ~17%, the logo ends at ~82%), so the border trims but no
     text or logo is ever touched. A slight wash + vignette so the white field sits softer. */
  #page-news .rosters-hero {
    --hero-img: var(--hero-lg);
    background: linear-gradient(rgba(0,20,51,0.20), rgba(0,20,51,0.20)), radial-gradient(ellipse 90% 90% at 50% 45%, rgba(0,20,51,0) 55%, rgba(0,20,51,0.35) 100%), var(--hero-img, none) center / cover no-repeat;
    padding: 0;
    aspect-ratio: 1654 / 590;
    width: 100%;
  }
  .rosters-body {
    max-width: 56.25rem;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 5rem;
  }
  /* Rosters + facilities heroes (Oct 2026, Jamie): 250px tall on desktop like the
     coaches band, content vertically centered, framing kept (scorebook on the book,
     gym tight). The scorebook ships two crops from Jamie's wide photo (Oct 8 2026):
     full-width desktop + a closer phone cut, swapped below 1024px like the About tiers. */
  #page-rosters .rosters-hero { --hero-img: var(--hero-lg); }
  @media (max-width: 1023px) {
    #page-rosters .rosters-hero {
      --hero-img: var(--hero-phone);
      background-position: center, center 40%;
    }
  }
  @media (min-width: 1024px) {
    #page-rosters .rosters-hero {
      height: 250px;
      min-height: 0;
      width: 100%;
      padding: 0 1.5rem;
      background-position: center, center 60%;
    }
    #page-facilities div.rosters-hero {
      height: 250px;
      min-height: 0;
      padding: 0 1.5rem;
      background-position: center 68%;
    }
  }
  /* Facilities hero: cropped tight on the gym — banners and plates fill the frame.
     Phone cut (Oct 8 2026, Jamie): the full-width shot left phones staring at the
     doors, so below 1024px a left-shifted crop leads with the plate racks. */
  #page-facilities .rosters-hero { --hero-img: var(--hero-lg); background-position: center 20%; }
  @media (max-width: 1023px) {
    #page-facilities .rosters-hero {
      --hero-img: var(--hero-phone);
      background-position: center, center 40%;
    }
  }
  #page-coaches .rosters-hero { background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.35) 60%, rgba(0,0,0,0.22) 100%), var(--hero-img) center / contain no-repeat; background-color: #2D2D2D; }
  /* Coaches hero width lock (Oct 2026, Jamie): `contain` fits the whole 1920x312
     board inside the band, so the fit axis flips with the box shape — at 1920
     the art fills the band height, at 1280 it shrinks to fit the width and the
     icons render smaller with gray bars top/bottom. At desktop widths the band
     is therefore height-locked (250px) with the art sized by height (1538x250):
     icon size is identical at every covered width; narrower boxes just narrow
     the gray side gutters instead of shrinking the marks. Measured ink edges:
     leftmost ink ~270px (Evansville script), rightmost ink ~1675px (Sky Sox),
     so the right side binds — art may narrow to 1440-2*0.75*(1920-1675)=1073px
     before ink clips, and the lock runs down to 1120px for margin. Below 1120
     the strips reflow (480–1119), then restack for the smallest phones (480 and below, winning the 1px overlap). */
  @media (min-width: 1120px) {
    #page-coaches .rosters-hero { height: 250px; min-height: 0; padding: 0 1.5rem; background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.35) 60%, rgba(0,0,0,0.22) 100%), var(--hero-img) center / auto 250px no-repeat; background-color: #2D2D2D; }
  }
  /* Coaches hero reflow tier (Oct 2026, Jamie): below 1120px the baked board
     would clip ink, so the board's four logo strips (slices of coaches-logos.jpg itself —
     same pixels, same scale, baked halo included) ride in a flex row with fluid gaps: the
     outer stacks glide inward as the band narrows, icon size untouched and identical to the
     board above 1120. One font-size knob scales the whole row: full size to ~892px, 90% to
     ~803px, 80% toward 720px, then 70/60/50% steps carry the same row to the 480px
     floor (760 looks like 761 — same row, one step smaller). The stacked query runs to
     481px so the two tiers overlap across 480–481 and the later stacked rules win any
     shared viewport — no fractional width can fall through to the base board. */
  .hero-logo-chips { display: none; }
  @media (min-width: 480px) and (max-width: 1119px) {
    #page-coaches .rosters-hero { container-type: inline-size; height: 250px; min-height: 0; padding: 0; background: #2D2D2D; }
    .hero-logo-chips { display: flex; align-items: center; justify-content: center; gap: clamp(0.6em, calc((100cqw - 85em - 2.4em) / 3), 4em); position: absolute; inset: 0; width: 100%; max-width: none; margin: 0; padding: 0 1.2em; font-size: 10px; pointer-events: none; }
    /* Strips are slices of the baked board itself (same pixels, same scale), so sizes below
       1120 match above by construction — only positions reflow. Plain rects: no trim boxes,
       no offsets, no drop-shadow (the baked halo rides inside each slice). */
    .hero-logo-chips img { flex: none; height: 25em; width: auto; display: block; }
    /* Sole scrim of the tier: the hero behind is flat gray, so this overlay dims band and
       strips exactly once each — like the board's top scrim layer above 1120. Under the
       title (h1/p are z-index:1 siblings). */
    .hero-logo-chips::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.35) 60%, rgba(0,0,0,0.22) 100%); }
  }
  @media (min-width: 481px) and (max-width: 892px) {
    .hero-logo-chips { font-size: 9px; }
  }
  @media (min-width: 481px) and (max-width: 803px) {
    .hero-logo-chips { font-size: 8px; }
  }
  @media (min-width: 481px) and (max-width: 719px) {
    .hero-logo-chips { font-size: 7px; }
  }
  @media (min-width: 481px) and (max-width: 639px) {
    .hero-logo-chips { font-size: 6px; }
  }
  @media (min-width: 481px) and (max-width: 559px) {
    .hero-logo-chips { font-size: 5px; }
  }
  /* Coaches hero stacked tier (Oct 2026, Jamie: 480 and below — the row can't stay
     legible, so ESU/SAGU take a large top row and the minor stacks sit side by side
     underneath, reading as a 2x2 with each mark clearly smaller than the majors).
     Same language as above: flat gray hero, the chips ::after as the single full-hero
     scrim (chips are static, so the overlay's containing block is the hero itself),
     and the title wrapped in .coaches-hero-text so it overlays the art bed centered —
     exactly where it sits at every wider tier. At 480–481 both tiers match and these
     later stacked rules win, so no fractional viewport falls through to the base. */
  @media (max-width: 481px) {
    #page-coaches .rosters-hero { height: auto; min-height: 0; padding: 1.5rem 1rem 1.75rem; background: #2D2D2D; }
    #page-coaches .coaches-hero-text { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; max-width: none; margin: 0; padding: 0 1rem; text-align: center; pointer-events: none; }
    #page-coaches .rosters-hero h1 { margin-bottom: 0.375rem; }
    #page-coaches .rosters-hero p { margin-bottom: 0; }
    .hero-logo-chips { display: grid; grid-template-columns: 1fr 1fr; grid-template-areas: "esu sagu" "left right"; justify-items: center; align-items: center; column-gap: 0.5rem; row-gap: 0.75rem; position: static; width: 100%; max-width: none; margin: 0; padding: 0; pointer-events: none; }
    .hero-logo-chips img { display: block; height: auto; }
    .hero-logo-chips .hlc-esu { grid-area: esu; height: clamp(7.5rem, 37vw, 10.75rem); width: auto; }
    .hero-logo-chips .hlc-sagu { grid-area: sagu; height: clamp(7.5rem, 37vw, 10.75rem); width: auto; }
    .hero-logo-chips .hlc-left { grid-area: left; height: clamp(6.25rem, 34vw, 8.75rem); width: auto; }
    .hero-logo-chips .hlc-right { grid-area: right; height: clamp(6.25rem, 34vw, 8.75rem); width: auto; }
    .hero-logo-chips::after { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 85% 90% at 50% 45%, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.35) 60%, rgba(0,0,0,0.22) 100%); pointer-events: none; }
  }
  /* ---------- News article ---------- */
  .news-article .news-kicker {
    font-size: 0.75rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.125rem;
    color: var(--primary-text);
    margin: 0 0 0.5rem;
  }
  .news-article .news-title {
    font-family: var(--font-primary);
    font-size: 2rem;
    font-weight: 700;
    color: var(--secondary);
    line-height: 1.2;
    letter-spacing: 0.01em;
    margin: 0 0 0.375rem;
  }
  .news-article .news-byline {
    font-size: 0.9375rem;
    font-weight: 700;
    color: var(--secondary);
    margin: 0 0 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 0.1875rem solid var(--secondary);
  }
  .news-article .news-byline-date { font-weight: 400; }
  .news-article .news-byline-date::before { content: "· "; }
  .news-subhead {
    font-size: 0.875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.1875rem;
    color: var(--secondary);
    margin: 2.5rem 0 0;
  }
  .news-pullquote {
    margin: 2rem auto;
    max-width: 36rem;
    text-align: center;
    border-top: 0.1875rem solid var(--secondary);
    border-bottom: 0.0625rem solid var(--light-gray);
    padding: 1.25rem 1rem;
  }
  .news-article .news-pullquote p {
    font-family: var(--font-primary);
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--secondary);
    margin: 0;
  }
  .news-article .news-lede {
    font-size: 1.125rem;
    line-height: 1.7;
    color: var(--dark-gray);
  }
  .news-figure { margin: 2rem 0; }
  /* Narrow (portrait) figures run centered at a capped width so a near-square photo doesn't tower
     over the text column at full 900px width. */
  .news-figure--narrow { max-width: 28rem; margin-left: auto; margin-right: auto; }
  /* Desktop floated figure (Oct 2026): the landscape story photo drops into the text column with the
     words running down its right side — magazine style. Narrow figure and phones keep the stacked
     full-width treatment. */
  @media (min-width: 56.25rem) {
    .news-article .news-figure:not(.news-figure--narrow) {
      float: left;
      width: 22rem;
      margin: 0.5rem 1.5rem 1rem 0;
    }
    /* Snake: the portrait lede photo floats right at a slimmer width, text down its left. */
    .news-article .news-figure--narrow {
      float: right;
      width: 18rem;
      margin: 0.5rem 0 1rem 1.5rem;
    }
  }
  .news-figure img {
    width: 100%;
    height: auto;
    display: block;
    border-radius: 0.5rem;
  }
  .news-figure figcaption {
    font-size: 0.8125rem;
    line-height: 1.6;
    color: var(--gray-text);
    padding-top: 0.625rem;
    border-bottom: 0.0625rem solid var(--light-gray);
    padding-bottom: 0.625rem;
  }
  /* Tournament-run strip (Oct 2026): the whole summer as a scoreboard — grouped by round, Berlin
     score first, W/L pills. Sits at the foot of the article as the recap. */
  .news-results {
    margin: 2rem auto 0;
    max-width: 36rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    overflow: hidden;
  }
  .news-results-title {
    font-family: var(--font-primary);
    font-size: 1.25rem;
    font-weight: 700;
    color: #fff;
    background: var(--secondary);
    margin: 0;
    padding: 0.75rem 1.25rem;
  }
  .news-results-group {
    font-size: 0.75rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.125rem;
    color: var(--primary-text);
    margin: 0;
    padding: 1rem 1.25rem 0.25rem;
  }
  .news-results-list { list-style: none; margin: 0; padding: 0 1.25rem 0.75rem; }
  .news-results-list li {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.375rem 0;
    border-bottom: 0.0625rem solid var(--light-gray);
    font-size: 0.9375rem;
  }
  .news-results-list li:last-child { border-bottom: 0; }
  .news-results-list .nr-date { color: var(--gray-text); min-width: 3.5rem; }
  .news-results-list .nr-match { flex: 1; }
  .news-results-list .nr-score { font-weight: 700; font-variant-numeric: tabular-nums; }
  .news-results-list .nr-verdict {
    font-size: 0.75rem;
    font-weight: 800;
    min-width: 1.5rem;
    text-align: center;
    border-radius: 0.25rem;
    padding: 0.125rem 0;
  }
  .news-results-list .nr-w { background: var(--secondary); color: #fff; }
  .news-results-list .nr-l { background: var(--light-gray); color: var(--dark-gray); }
  .news-results-list .nr-recap { font-size: 0.8125rem; font-weight: 700; }
  .news-results-list .nr-trophy { width: 0.9375rem; height: 0.9375rem; flex: none; align-self: center; color: #b8912f; }
  .news-strip-rule {
    border: 0;
    border-top: 0.0625rem solid var(--light-gray);
    margin: 2.5rem auto 0;
    max-width: 36rem;
  }
  .news-results-champs {
    margin: 0 1.25rem;
    padding: 0.625rem 0 1rem;
    text-align: center;
    font-size: 0.8125rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.125rem;
    color: var(--secondary);
  }
  /* ---------- Legal (Privacy Policy) Page ---------- */
  .legal-body {
    max-width: 42rem;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 5rem;
    text-align: left;
    color: var(--gray-text);
  }
  .legal-body p { margin: 0 0 0.9375rem; font-size: 0.9688rem; line-height: 1.75; }
  .legal-body h2 {
    font-family: var(--font-primary);
    font-size: 1.1875rem;
    font-weight: 600;
    color: var(--secondary);
    letter-spacing: 0.01em;
    margin: 2.25rem 0 0.625rem;
  }
  .legal-body ul { margin: 0 0 1.125rem; padding-left: 1.25rem; }
  .legal-body li { margin-bottom: 0.3125rem; font-size: 0.9688rem; line-height: 1.75; }
  .legal-body strong { color: var(--dark-gray); font-weight: 700; }
  .legal-body a { color: var(--primary-dark); text-decoration: underline; text-underline-offset: 0.15em; }
  .legal-body a:hover, .legal-body a:focus-visible { color: var(--secondary); }
  .legal-body p.legal-updated {    margin: 0 0 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 0.0625rem solid var(--light-gray);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--gray-text);
  }
  /* ---------- 404 page (JAMIE, Sep 16 2026) ----------
     Not navigable: Cloudflare Pages serves 404.html with a 404 status for any unmatched path, so
     the page is built, noindexed and never linked. A navy full-bleed panel in the
     .cta-band/.rosters-hero family (same gradient, same white type) so a mistyped URL still lands
     on something that reads as Apex rather than a platform error page. 62vh rather than a full
     viewport keeps the footer's top edge in view on a desktop and a phone alike. */
  .notfound-wrap {
    min-height: 62vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 4rem 1.5rem 5rem;
    background: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-dark) 100%);
    color: var(--white);
  }
  .notfound-code {
    font-family: var(--font-primary);
    font-size: clamp(4rem, 15vw, 8.5rem);
    font-weight: 900;
    line-height: 0.9;
    letter-spacing: 0.02em;
    color: var(--primary);
    margin-bottom: 0.5rem;
  }
  .notfound-wrap h1 {
    font-size: clamp(1.75rem, 4.5vw, 2.75rem);
    font-weight: 900;
    margin-bottom: 0.875rem;
  }
  .notfound-copy {
    font-size: 1.0625rem;
    opacity: 0.92;
    max-width: 34rem;
    margin: 0 auto 2rem;
  }
  .notfound-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; }
  /* ---------- Forgot-password page (Oct 2026, Jamie) ----------
     Dedicated reset page, reached only from the emailed link: header + footer stay shared, the page
     itself is a navy full-bleed panel in the .notfound-wrap family with a centered white card holding
     the two password fields. Reuses .form-group / .form-msg / .btn-primary / .notfound-actions. */
  .reset-wrap {
    min-height: 62vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 4rem 1.5rem 5rem;
    background: linear-gradient(135deg, var(--secondary) 0%, var(--secondary-dark) 100%);
    color: var(--white);
  }
  .reset-card {
    width: 100%;
    max-width: 26rem;
    background: var(--white);
    color: var(--dark-gray);
    border-radius: 0.75rem;
    padding: 2rem 1.75rem;
    box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.28);
  }
  .reset-card .form-group { margin-bottom: 1rem; text-align: left; }
  .reset-card .btn-primary { display: block; margin-left: auto; margin-right: auto; color: var(--white) !important; }
  @media (max-width: 640px) {
    .reset-card .btn-primary { width: 100%; }
  }
  .reset-copy { margin: 0 0 1rem; font-size: 0.9688rem; line-height: 1.6; }
  .reset-checking { margin: 0; font-size: 0.9688rem; }
  .reset-card .notfound-actions { margin-top: 1.5rem; }
  .reset-wrap h1 {
    font-size: clamp(1.75rem, 4.5vw, 2.75rem);
    font-weight: 900;
    margin: 0 0 0.5rem;
    text-align: center;
  }
  .reset-sub { margin: 0 0 2rem; font-size: 1.0625rem; opacity: 0.92; text-align: center; }
  /* Password peek toggles (reset form only): the eye button rides inside the field wrapper — which
     doubles as markInvalid's .field-wrap, so error badges wrap input + toggle together. When the
     red badge appears it takes the right slot and the eye slides left, same as the select rule. */
  #resetForm .pw-peek-wrap input { padding-right: 2.75rem; }
  #resetForm .pw-peek {
    position: absolute;
    right: 0.625rem;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    padding: 0.25rem;
    background: none;
    border: 0;
    cursor: pointer;
    color: var(--gray);
  }
  #resetForm .pw-peek[aria-pressed="true"] { color: var(--secondary); }
  #resetForm .pw-peek:focus-visible { outline: 2px solid var(--secondary); outline-offset: 2px; }
  #resetForm .pw-peek svg { width: 1.25rem; height: 1.25rem; display: block; }
  #resetForm .pw-peek svg[hidden] { display: none; }
  #resetForm .field-wrap.field-invalid .pw-peek { right: 1.875rem; }
  #resetForm .field-wrap.field-invalid input { padding-right: 3.75rem; }
  /* ---------- Facilities Page helpers ---------- */
  #page-facilities .facility-body { max-width: 50rem; }
  #page-facilities .facility-head { margin-bottom: 1.75rem; }
  #page-facilities .facility-head--spaced { margin-top: 3.5rem; }
  #page-facilities .facility-head p { max-width: 96%; }
  #page-facilities .facility-grid { grid-template-columns: repeat(3, 1fr); }
  #page-facilities .facility-field-strip {
    height: clamp(13.75rem, 30vw, 21.25rem);
    background-size: cover;
    background-position: center;
    border-radius: 0.75rem;
    margin-bottom: 1.75rem;
  }
  /* The Home Field strip's navy wash (Sep 2026, with the placeholder photo). The band is a wide cover-crop of a
     drone shot whose sky, white roofs and pickleball glare all outshine the field, so the edges are taken down
     toward the page navy while the middle — where the field sits — is left nearly clear, with a light veil over
     the whole band to cool the vivid real-estate processing. Nothing is baked into the file: this is a scrim on
     the box, the same non-destructive treatment the coach plates use, and it is keyed to the modifier class so a
     future photo can opt out by dropping the class. Tune the alphas, not the photo. */
  #page-facilities .facility-field-strip--scrim { position: relative; }
  #page-facilities .facility-field-strip--scrim::after {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    pointer-events: none;
    background:
      radial-gradient(ellipse 76% 118% at 50% 62%, rgba(0,20,51,0.06) 0%, rgba(0,20,51,0.34) 62%, rgba(0,20,51,0.66) 100%),
      linear-gradient(to bottom, rgba(0,20,51,0.32), rgba(0,20,51,0) 34%, rgba(0,20,51,0) 66%, rgba(0,20,51,0.40));
  }
  #page-facilities .facility-photo {
    width: 100%;
    height: auto;
    border-radius: 0.75rem;
    box-shadow: 0 0.25rem 1.5rem rgba(0,32,78,0.15);
    margin-bottom: 2rem;
  }
  .team-tabs {
    display: flex;
    gap: 0.75rem;
    margin-bottom: 0.875rem;
    flex-wrap: wrap;
    position: sticky;
    top: var(--header-h);
    z-index: 50;
    background: var(--white);
    padding: 0.75rem 0;
    border-bottom: 0.0625rem solid rgba(0,32,78,0.1);
  }
  .team-meta {
    margin-bottom: 1.5rem;
    font-size: 0.9375rem;
    color: #000;
  }
  .team-meta-coach, .team-meta-assist { font-weight: 400; color: #000; }
  .team-meta-assist { margin-top: 0.1875rem; }
  .roster-empty {
    background: var(--white);
    border: 0.125rem dashed var(--light-gray);
    border-radius: 0.75rem;
    padding: 2.75rem 1.25rem;
    text-align: center;
    color: var(--dark-gray);
    font-size: 1rem;
    font-weight: 600;
  }
  .site-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    width: 60%;
    min-width: max-content;
    max-width: 100%;
    min-height: 3.75rem;
    margin: 0.25rem auto 0;
    padding: 0 1.5rem;
    background: rgba(0,32,78,0.05);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    font-size: 0.875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.09375rem;
    color: var(--secondary);
  }
  .tab-btn {
    background: var(--white);
    border: 0.125rem solid var(--light-gray);
    color: var(--dark-gray);
    padding: 0.625rem 1.375rem;
    border-radius: 0.5rem;
    font-weight: 700;
    font-size: 0.9375rem;
    cursor: pointer;
    transition: all 0.2s;
  }
  .tab-btn:hover { border-color: var(--primary); color: var(--primary); }
  .tab-btn.active {
    background: var(--secondary);
    border-color: var(--secondary);
    color: var(--white);
  }
  .tab-btn[data-team*="blue"].active, .tab-btn.team-blue.active {
    background: var(--primary);
    border-color: var(--primary);
  }
  .roster-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--white);
    border-radius: 0.75rem;
    overflow: hidden;
    box-shadow: 0 0.125rem 1rem rgba(0,32,78,0.08);
  }
  .roster-table th {
    background: var(--secondary);
    color: var(--white);
    padding: 0.875rem 1rem;
    text-align: left;
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.0625rem;
  }
  .roster-table.roster-blue th { background: var(--primary); }
  .roster-table td {
    padding: 0.8125rem 1rem;
    border-bottom: 0.0625rem solid var(--light-gray);
    font-size: 0.9375rem;
  }
  .roster-table tbody tr:nth-child(even) { background: rgba(0,32,78,0.035); }
  .roster-table tbody tr:hover { background: rgba(102,153,204,0.12); }
  .roster-table .player-name { font-weight: 700; color: var(--secondary); }
  .roster-cards { display: none; }
  @media (max-width: 640px) {
    .roster-cards { display: block; }
    .roster-table { display: none; }
    .roster-card {
      display: flex;
      align-items: center;
      gap: 0.75rem;
      background: #F4F6F9;
      border: 0.0625rem solid rgba(0,32,78,0.12);
      border-radius: 0.625rem;
      padding: 0.75rem 0.875rem;
      margin-bottom: 0.5rem;
      box-shadow: 0 0.125rem 0.5rem rgba(0,32,78,0.08);
    }
    .rc-num {
      flex: 0 0 auto;
      width: 2.125rem;
      height: 2.125rem;
      border-radius: 50%;
      background: var(--secondary);
      color: var(--white);
      font-weight: 800;
      font-size: 0.875rem;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .rc-main { flex: 1 1 auto; min-width: 0; }
    .rc-name { font-weight: 700; color: var(--secondary); font-size: 0.9375rem; }
    .rc-pos { font-size: 0.8125rem; color: var(--primary); font-weight: 700; }
    .rc-stats {
      flex: 0 0 auto;
      display: flex;
      gap: 0.75rem;
      text-align: center;
    }
    .rc-stat { display: flex; flex-direction: column; align-items: center; }
    .rc-stat-label {
      font-size: 0.625rem;
      text-transform: uppercase;
      letter-spacing: 0.05rem;
      font-weight: 700;
      color: rgba(0,32,78,0.55);
    }
    .rc-stat-val { font-size: 0.8438rem; font-weight: 700; color: var(--secondary); margin-top: 0.0625rem; }
    .roster-card--blue .rc-num { background: var(--primary); }
  }
  .active-link { color: var(--secondary) !important; }
  .nav-links a.active-link::after { transform: scaleX(1); background: var(--primary); }

  /* ---------- Player Portal ---------- */
  .dashboard-hero {
    background:
      repeating-linear-gradient(-45deg, rgba(255,255,255,0.03) 0 1.375rem, transparent 1.375rem 2.75rem),
      linear-gradient(135deg, var(--secondary) 0%, var(--secondary-dark) 100%);
    color: var(--white);
    padding: 2.5rem 1.5rem 1.875rem;
    position: relative;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
    --pill-left-pad: 1rem;
    --num-width: 2rem;
    --pill-height: 1.5625rem;
    --hero-gap: 1rem;
    --hero-top-gap: 1.25rem;
    --stat-row: 4.875rem;
    --stat-gap: 0.625rem;
    --photo-h: calc(var(--stat-row) * 2 + var(--stat-gap) + var(--pill-height) + var(--hero-gap));
    --photo-w: calc(var(--photo-h) * 0.875);
  }
  .hero-main {
    position: relative;
    width: 100%;
    max-width: 80rem;
    margin: 0 auto;
  }
  .hero-top {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    column-gap: var(--hero-top-gap);
    row-gap: var(--hero-gap);
    margin-bottom: 0;
  }
  .dash-stats {
    order: 2;
    flex: 1;
    min-width: 0;
    max-width: calc(100% - (var(--pill-left-pad) + var(--num-width)) * 2 - var(--photo-w) - var(--hero-top-gap));
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.625rem;
  }
  .dash-stat {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    min-height: 3rem;
    background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.05) 100%);
    border: 0.0625rem solid rgba(255,255,255,0.26);
    border-radius: 0.5rem;
    padding: 0.25rem 0.75rem 0.25rem 0.875rem;
    position: relative;
    overflow: hidden;
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.26);
    -webkit-backdrop-filter: blur(0.5rem);
    backdrop-filter: blur(0.5rem);
  }
  .dash-stat::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 0.1875rem;
    background: var(--primary);
  }
  .apex-tooltip {
    position: fixed;
    max-width: 16rem;
    width: max-content;
    padding: 0.5rem 0.625rem;
    background: rgba(0,20,51,0.96);
    color: #eaf3ff;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
    border-radius: 0.375rem;
    border: 0.0625rem solid rgba(255,255,255,0.18);
    box-shadow: 0 0.375rem 1rem rgba(0,10,26,0.35);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    left: 0;
    top: 0;
    z-index: 9999;
    transition: opacity 0.12s ease;
  }
  .apex-tooltip.show {
    opacity: 1;
    visibility: visible;
  }
  .dash-stats.is-empty {
    height: calc(var(--stat-row) * 2 + var(--stat-gap));
  }
  .dash-no-stats {
    grid-column: 1 / -1;
    align-self: center;
    justify-self: center;
    width: 60%;
    min-width: max-content;
    max-width: 100%;
    min-height: 3.75rem;
    padding: 0 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.05) 100%);
    border: 0.0625rem solid rgba(255,255,255,0.26);
    border-radius: 0.5rem;
    font-size: 0.875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.09375rem;
    color: #C9E2FC;
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.26);
    -webkit-backdrop-filter: blur(0.5rem);
    backdrop-filter: blur(0.5rem);
  }
  /* THE DASHBOARD HERO'S GLASS IS DESKTOP-ONLY (Sep 26 2026). The hero's tiles
     (.dash-stat, and .dash-no-stats in their place) each carry a 0.5rem backdrop
     blur. Every one of those is a live compositor surface that has to re-sample
     and re-blur whatever sits behind it, and the hero repaints as a unit — so the
     moment the parent ledger inside this screen does its big DOM build, the GPU
     re-blurs all of them at once. That is what makes the ledger screen too heavy
     for a tablet. The blur is over a flat-ish dark gradient, so on the devices
     that choke on it the glass buys almost nothing: touch/coarse-pointer gets the
     same tiles with a plain translucent fill, desktop keeps the blur. */
  @media (hover: none), (pointer: coarse) {
    .dash-stat,
    .dash-no-stats {
      -webkit-backdrop-filter: none;
      backdrop-filter: none;
    }
  }
  .dash-stats.is-loading {
    height: calc(var(--stat-row) * 2 + var(--stat-gap));
    align-content: center;
  }
  .dash-loading {
    grid-column: 1 / -1;
    align-self: center;
    justify-self: center;
    width: 60%;
    min-width: max-content;
    max-width: 100%;
    min-height: 3.75rem;
    padding: 0 1.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    background: linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.05) 100%);
    border: 0.0625rem solid rgba(255,255,255,0.26);
    border-radius: 0.5rem;
    font-size: 0.875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.09375rem;
    color: #C9E2FC;
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.26);
  }
  .dash-loading-dots span {
    display: inline-block;
    transform: translateZ(0);
    will-change: opacity;
    animation: dash-dot 1.5s steps(1) infinite;
  }
  .portal-panel[data-panel="viewstats"] .dash-loading {
    color: var(--secondary);
    background: rgba(0, 32, 78, 0.05);
    border-color: var(--light-gray);
    box-shadow: none;
    margin-left: auto;
    margin-right: auto;
  }
  .dash-loading-dots span:nth-child(2) { animation-delay: 0.375s; }
  .dash-loading-dots span:nth-child(3) { animation-delay: 0.75s; }
  @keyframes dash-dot { 50% { opacity: 0; } }
  .lite .dash-loading-dots span { animation: none; }
  .lite .hero-pill,
  .lite .hero-pill::after,
  .lite .hero-photo,
  .lite .dash-stat {
    box-shadow: none;
  }
  .lite .hero-pill {
    box-shadow: inset 0 0.0625rem 0.1875rem rgba(0,0,0,0.25);
    will-change: auto;
    transform: none;
  }
  .lite .dash-stats.is-6 { will-change: auto; }
  .lite body.apex-design-blue .hero-pill,
  .lite body.apex-design-blue .hero-pill::after,
  .lite body.apex-design-blue .hero-photo {
    box-shadow: none;
  }
  .lite body.apex-design-blue .hero-pill {
    box-shadow: inset 0 0.0625rem 0.1875rem rgba(0,20,51,0.18);
  }
  .lite .hero-pill h1,
  .lite body.apex-design-blue .hero-pill h1,
  .lite body.apex-design-blue .hero-pill-num,
  .lite .hero-stat,
  .lite body.apex-design-blue .hero-stat,
  .lite body.apex-design-blue .stat-label,
  .lite body.apex-design-blue .dash-stat-value {
    text-shadow: none;
  }
  .lite body.apex-design-blue .dash-stat {
    box-shadow: none;
  }
  @media (prefers-reduced-motion: reduce) {
    .dash-loading-dots span { animation: none; }
    .hero-slide { animation: none !important; }
  }
  .dash-player-switcher {
    width: 100%;
    max-width: 80rem;
    margin: 1.5rem auto 0;
    display: flex;
    justify-content: center;
  }
  .dash-player-chips {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.25rem;
    justify-content: center;
    background: rgba(0,20,51,0.30);
    border: 0.0625rem solid rgba(255,255,255,0.14);
    border-radius: 999px;
    box-shadow: inset 0 0.125rem 0.375rem rgba(0,10,30,0.35);
    padding: 0.25rem 0.75rem;
  }
  button.dash-player-chip {
    font-family: var(--font-primary);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.58);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.5);
    background: none;
    border: 0;
    border-radius: 999px;
    padding: 0.3125rem 0.75rem;
    position: relative;
    z-index: 1;
    cursor: pointer;
    line-height: 1;
    transition: color 0.2s ease, background-color 0.2s ease;
  }
  .dash-player-num {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    opacity: 0.7;
    margin-right: 0.375rem;
  }
  .dash-player-chip:hover:not(.active) {
    color: #fff;
    background: rgba(255,255,255,0.10);
  }
  .dash-player-chip.active {
    color: #fff;
    font-weight: 700;
  }
  .dash-player-chip:focus-visible {
    outline: 0.125rem solid var(--primary);
    outline-offset: 0.25rem;
  }
  body.apex-design-blue .dash-player-chips {
    background: rgba(198,216,236,0.58);
    border-color: rgba(0,32,78,0.16);
    box-shadow: inset 0 0.0625rem 0.25rem rgba(0,32,78,0.08);
  }
  body.apex-design-blue .dash-player-chip {
    color: var(--secondary-light);
    text-shadow: none;
  }
  body.apex-design-blue .dash-player-num { opacity: 1; }
  body.apex-design-blue .dash-player-chip:hover:not(.active) {
    color: var(--secondary-light);
    background: rgba(0,32,78,0.10);
  }
  body.apex-design-blue .dash-player-chip.active {
    color: var(--white);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.35);
  }
  body.apex-design-blue .dash-player-chip:focus-visible { outline-color: var(--secondary); }
  .dash-player-carriage {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    border-radius: 999px;
    background: rgba(102,153,204,0.30);
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.14), 0 0.125rem 0.375rem rgba(0,10,30,0.30);
    pointer-events: none;
    z-index: 0;
  }
  body.apex-design-blue .dash-player-carriage {
    background: rgba(0,32,78,0.55);
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.10), 0 0.125rem 0.375rem rgba(0,32,78,0.22);
  }
  .dash-player-carriage.is-ready {
    transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1), top 0.28s cubic-bezier(0.4, 0, 0.2, 1), width 0.28s cubic-bezier(0.4, 0, 0.2, 1), height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
  }
  .lite .dash-player-carriage { transition: none; }
  @media (prefers-reduced-motion: reduce) {
    .dash-player-carriage { transition: none; }
  }
  .dash-stat-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.625rem;
  }
  .dash-stat-label {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.09375rem;
    color: #C9E2FC;
    white-space: nowrap;
  }
  .dash-stat-cat {
    position: absolute;
    left: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.4rem;
    color: var(--primary);
    writing-mode: vertical-rl;
    text-orientation: mixed;
  }
  .dash-stat-value {
    font-family: var(--font-primary);
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--white);
    line-height: 1.05;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,8,26,0.45);
  }
  .dash-stat-rank {
    font-size: 0.6875rem;
    font-weight: 700;
    color: rgba(255,255,255,0.9);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: right;
  }
  .dash-stats.is-6 .dash-stat {
    min-height: 4.375rem;
    padding: 0.375rem 0.875rem 0.375rem 1.5rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto auto auto;
    column-gap: 0.875rem;
    align-items: center;
  }
  .dash-stats.is-6 {
    grid-auto-rows: var(--stat-row);
    grid-template-columns: repeat(3, minmax(0, 1fr));
    transform: translateZ(0);
    will-change: transform;
  }
  .dash-stats.is-6 .dash-stat-cat {
    position: absolute;
    left: 0.5rem;
    top: 50%;
    transform: translateY(calc(-50% + 2px));
    font-size: 0.6875rem;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.4rem;
    color: var(--primary);
    writing-mode: vertical-rl;
    text-orientation: mixed;
  }
  .dash-stats.is-6 .dash-stat-label {
    grid-column: 1;
    grid-row: 1;
    text-align: center;
    margin-top: 0.165rem;
    font-size: 0.75rem;
  }
  .dash-stats.is-6 .dash-stat-value {
    grid-column: 1;
    grid-row: 2;
    font-size: 1.625rem;
    text-align: center;
    align-self: center;
    margin-top: -0.1875rem;
  }
  .dash-stats.is-6 .dash-stat-ranks {
    grid-column: 2;
    grid-row: 1 / -1;
    align-self: center;
    transform: none;
    margin-right: 0.875rem;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    align-items: flex-end;
  }
  .dash-stats.is-6 .dash-stat-rank {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.25rem;
    font-size: 0.875rem;
    font-weight: 600;
    color: rgba(255,255,255,0.75);
    text-align: right;
  }
  .dash-stats.is-6 .dash-stat-rank b {
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--white);
  }
  .dash-stats.is-6 .dash-stat-rank .rank-lbl span {
    display: inline;
  }
  .dash-stats.is-6 .dash-stat-rank .rank-lbl span + span::before {
    content: "\00a0";
  }
  .dash-stats.is-6 .dash-stat-rank .rank-lbl span + span::after {
    content: ":";
  }
  .dash-stats.is-6 .dash-stat-ranks.is-single {
    grid-row: 1 / -1;
    align-self: center;
    transform: none;
  }
  .dash-stats.is-6 .dash-stat-rank.is-stacked {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.0625rem;
    text-align: center;
  }
  .dash-stats.is-6 .dash-stat-rank.is-stacked .rank-lbl span + span::after {
    content: "";
  }
  @media (max-width: 960px) {
    .dash-stats.is-6 {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .dash-stats.is-6 .dash-stat.hide-on-narrow {
      display: none;
    }
  }
  .hero-pill {
    order: 3;
    flex-basis: 100%;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.875rem;
    position: relative;
    z-index: 1;
    will-change: transform;
    transform: translateZ(0);
    background:
      linear-gradient(180deg, rgba(255,255,255,0.10) 0%, rgba(255,255,255,0.02) 14%, rgba(0,0,0,0) 24%),
      linear-gradient(180deg, #1e54a0 0%, #0b2c5e 60%, #0d2c58 100%);
    border: 0.0625rem solid rgba(255,255,255,0.5);
    border-top-color: rgba(255,255,255,0.65);
    border-bottom-color: rgba(255,255,255,0.5);
    box-shadow:
      inset 0 0.0625rem 0.1875rem rgba(255,255,255,0.22),
      inset 0 0.0625rem 0 rgba(255,255,255,0.4),
      inset 0 -0.5rem 1.25rem rgba(0,0,0,0.1),
      inset 0.625rem 0 0.875rem -0.625rem rgba(0,10,26,0.5),
      inset -0.625rem 0 0.875rem -0.625rem rgba(0,10,26,0.5),
      0 0.1875rem 0.5rem rgba(0,8,26,0.6),
      0 1rem 1.875rem rgba(0,8,26,0.55);
    border-radius: 62.4375rem;
    width: 100%;
    height: var(--pill-height);
    padding: 0 45px 0 var(--pill-left-pad);
  }
  .hero-pill::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background:
      linear-gradient(180deg, rgba(0,10,26,0) 0%, rgba(0,10,26,0.28) 6%, rgba(0,10,26,0) 12%),
      linear-gradient(180deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.04) 12%, rgba(255,255,255,0) 22%),
      linear-gradient(115deg, transparent 33%, rgba(255,255,255,0.78) 42%, rgba(255,255,255,0.12) 50%, transparent 58%);
    pointer-events: none;
  }
  .hero-pill-num {
    font-family: 'Oswald', sans-serif;
    font-size: clamp(0.8125rem, 1.2vw, 0.9375rem);
    font-weight: 700;
    color: var(--white);
    line-height: 1;
    width: var(--num-width);
    text-align: center;
    flex-shrink: 0;
    padding-right: 0.75rem;
    border-right: 0.125rem solid rgba(255,255,255,0.22);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.8);
    z-index: 1;
  }
  .hero-photo {
    order: 1;
    flex-shrink: 0;
    position: relative;
    z-index: 0;
    margin-left: calc(var(--pill-left-pad) + var(--num-width));
    margin-bottom: calc(-1 * (var(--pill-height) + var(--hero-gap)));
    width: var(--photo-w);
    height: var(--photo-h);
    border-radius: 0.9375rem;
    border: 0.125rem solid rgba(255,255,255,0.4);
    box-shadow: 0 0.875rem 1.625rem rgba(0,8,26,0.5);
    overflow: hidden;
    background: linear-gradient(180deg, #0f2b52 0%, #0a1c38 100%);
  }
  .photo-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    color: rgba(255,255,255,0.7);
  }
  .photo-placeholder svg {
    width: 2.875rem;
    height: 2.875rem;
    opacity: 0.95;
  }
  .photo-placeholder img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .photo-placeholder span {
    font-size: 0.75rem;
    letter-spacing: 0.125rem;
    text-transform: uppercase;
    color: rgba(255,255,255,0.75);
  }
  .hero-pill-stats {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding-left: 1.625rem;
    position: relative;
    top: 0.0625rem;
    z-index: 1;
  }
  #dashTeam { transform: translateY(-1.5px); display: inline-block; }
  .hero-pill-num { order: 1; }
  .hero-pill-spacer { order: 2; }
  .hero-pill-stats-left { order: 3; margin-left: 0; }
  .hero-pill-stats-right { order: 4; margin-left: 0; padding-left: 0; }
  .hero-caption, .hero-sep { display: none; }
  .dashboard-hero.is-title-mode .hero-caption,
  .dashboard-hero.is-title-mode .hero-sep { display: none !important; }
  .hero-stat {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    font-size: clamp(0.6875rem, 1.1vw, 0.875rem);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.075rem;
    color: #EAF3FB;
    line-height: 1;
    white-space: nowrap;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.8);
  }
  .stat-label {
    color: var(--primary-light);
    font-weight: 600;
    margin-right: 0.125rem;
  }
  .stat-divider {
    color: var(--primary-light);
    font-size: 1.1em;
    line-height: 0;
  }
  .hero-pill h1 {
    font-family: 'Oswald', sans-serif;
    font-size: clamp(0.8125rem, 1.3vw, 1rem);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.0625rem;
    line-height: 1.05;
    margin: 0;
    color: var(--white);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.8), 0 -0.0625rem 0 rgba(255,255,255,0.12);
    position: absolute;
    left: calc(var(--pill-left-pad) + var(--num-width) - 0.0625rem);
    top: 50%;
    transform: translateY(-50%);
    width: var(--photo-w);
    text-align: center;
    z-index: 2;
  }
  .hero-pill-spacer {
    flex: 1;
    min-width: 0;
  }
  .hero-pill.is-stacked h1 {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
  }
  .hero-pill.is-stacked .hero-pill-num {
    font-size: clamp(1rem, 1.5vw, 1.1875rem);
  }
  .hero-pill.is-stacked .hero-stat {
    font-size: clamp(0.8125rem, 1.3vw, 1rem);
  }
  .hero-title {
    font-family: 'Oswald', sans-serif;
    font-size: clamp(1.875rem, 4.5vw, 3rem);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    line-height: 1.15;
    margin: 0 auto;
    white-space: pre-line;
    color: var(--white);
    text-shadow: 0 0.125rem 0.625rem rgba(0,10,30,0.55);
    text-align: center;
    z-index: 1;
  }
  .hero-title-sub {
    margin: 0.875rem auto 0;
    font-family: var(--font-secondary);
    font-size: clamp(0.9375rem, 1.5vw, 1.125rem);
    font-weight: 500;
    letter-spacing: 0.03em;
    color: #B9D3EC;
  }
  .hero-title-rule {
    width: 4.5rem;
    height: 0.1875rem;
    margin: 1.125rem auto 0;
    background: var(--primary);
    border-radius: 0.09375rem;
  }
  .hero-teams {
    margin: 1.125rem auto 0;
    max-width: 40rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.625rem;
  }
  .hero-team-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.4375rem 0.9375rem;
    border: 0.0625rem solid rgba(255,255,255,0.35);
    border-radius: 2rem;
    background: rgba(255,255,255,0.10);
    color: var(--white);
    font-family: 'Oswald', 'Arial Narrow', sans-serif;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.6);
  }
  .hero-teams.is-empty {
    display: block;
    font-style: italic;
    font-size: 0.8125rem;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: rgba(255,255,255,0.65);
  }
  body.apex-design-blue .hero-team-chip {
    background: rgba(255,255,255,0.22);
    border-color: rgba(255,255,255,0.6);
    color: var(--white);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,10,30,0.6);
  }
  body.apex-design-blue .hero-teams.is-empty { color: rgba(0,32,78,0.75); }
  .dashboard-hero.is-title-mode {
    display: block;
    text-align: center;
    padding: 4.625rem 1.5rem 4rem;
  }
  .portal-tab[hidden] { display: none; }
  .portal-layout {
    max-width: 66.25rem;
    margin: 0 auto;
    padding: 3rem 1.5rem 5.625rem;
    display: grid;
    grid-template-columns: 12.5rem 1fr;
    gap: 2rem;
    align-items: start;
  }
  .portal-nav {
    display: block;
    background: var(--light-gray);
    border: 0.0625rem solid #D7DAE0;
    border-radius: 0.75rem;
    padding: 0.375rem;
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
    position: sticky;
    top: calc(var(--header-h) + 1rem);
  }
  .portal-tab {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    padding: 0.5rem 0.875rem;
    border-radius: 0.4375rem;
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 700;
    color: var(--dark-gray);
    cursor: pointer;
    transition: background 0.2s, color 0.2s;
  }
  .portal-tab:hover { background: #DDE2E7; }
  .portal-tab .tab-roles {
    font-family: var(--font-primary);
    font-size: 0.625rem;
    font-weight: 500;
    letter-spacing: 0.0625rem;
    color: var(--gray-text);
    margin-left: 0.3125rem;
  }
  .portal-tab.active {
    background: var(--secondary);
    color: var(--white);
  }
  .portal-more {
    display: none;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--dark-gray);
    background: none;
    border: none;
    border-radius: 0.3125rem;
    padding: 0.25rem 0.375rem;
    cursor: pointer;
    transition: color 0.15s, background 0.15s;
  }
  .portal-more:hover { color: var(--ws-ink); background: #DDE2E7; }
  .portal-more .more-lbl { line-height: 1; }
  .portal-more .more-arrow { font-size: 0.9375rem; line-height: 1; }
  .portal-panel {
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.75rem;
    padding: 2.25rem;
    box-shadow: 0 0.125rem 0.75rem rgba(0,32,78,0.06);
    container-type: inline-size;
  }
  .portal-panel .btn-primary { color: var(--white) !important; }
  .portal-panel .btn-secondary { color: var(--secondary) !important; }
  .portal-panel .btn-secondary:hover { color: var(--white) !important; }
  .portal-panel h2 {
    font-size: 1.5rem; font-weight: 900; color: var(--secondary);
    margin-bottom: 0.5rem;
  }
  .portal-sub {
    color: var(--gray-text);
    font-size: 0.9375rem;
    margin-bottom: 1.75rem;
    max-width: 32.5rem;
  }
  .portal-sub.portal-note {
    font-size: 0.8125rem;
    color: var(--ws-muted);
    margin-top: -1.1rem;
    margin-bottom: 1.75rem;
  }
  .portal-sub-list {
    list-style: none;
    margin: -1rem 0 1.75rem 1.5rem;
    padding: 0;
    text-align: left;
    font-size: 0.9375rem;
    color: var(--gray-text);
  }
  .portal-sub-list li {
    margin: 0.1875rem 0;
  }
  .portal-sub-list li::before {
    content: "\2022";
    display: inline-block;
    width: 1rem;
    color: var(--secondary);
    font-weight: 700;
  }
  .ledger-empty {
    border: 0.0625rem dashed var(--light-gray);
    border-radius: 0.75rem;
    padding: 3rem 1.5rem;
    text-align: center;
    background: #F7FAFD;
  }
  .ledger-empty-icon {
    width: 2.625rem;
    height: 2.625rem;
    color: var(--primary);
    opacity: 0.85;
    margin-bottom: 0.875rem;
  }
  .ledger-empty-title {
    font-family: var(--font-primary);
    font-weight: 700;
    font-size: 1.0625rem;
    color: var(--secondary);
    margin-bottom: 0.375rem;
  }
  .ledger-empty-note {
    color: var(--gray-text);
    font-size: 0.875rem;
    max-width: 22.5rem;
    margin: 0 auto;
  }
  .vs-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.625rem;
  }
  .vs-control {
    font-family: var(--font-primary);
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--secondary);
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    padding: 0.5rem 0.875rem;
    max-width: 100%;
  }
  .vs-season-label {
    white-space: nowrap;
    margin-left: auto;
    /* The season TEXT is right-aligned to the INNER stats box, not to the outer section card
       (JAMIE, Sep 22 2026: "line up the right edge of the season text with the right edge of the
       interior box ... not the offensive statistics box, but the hitting line box inside of it",
       for all roles). That edge is the .vs-subgroup card's outer right edge, inset from the row by
       the section's 1px border + the .vs-body padding-right, so this inset tracks the .vs-body
       padding at both bands — see the @container (max-width: 600px) rule below. */
    margin-right: calc(1rem + 0.0625rem);
    background: none;
    border: 0;
    padding: 0;
    font-weight: 700;
  }
  .vs-player-wrap {
    display: flex;
    justify-content: center;
    margin: 0.75rem 0 0.25rem;
  }
  .vs-selector-row {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    align-items: center;
    gap: 0.625rem;
    margin: 0.75rem 0 0.625rem;
  }
  .vs-sel-left { justify-self: start; }
  .vs-sel-center { justify-self: center; }
  .vs-sel-right { justify-self: end; display: flex; align-items: center; gap: 0.625rem; }
  .vs-stats { margin-top: 0.25rem; }
  body.apex-design-blue .vs-control { color: var(--secondary); border-color: rgba(0,32,78,0.35); }
  body.apex-design-blue .vs-section.is-open .vs-section-head { background: #9CC2E4; }
  body.apex-design-blue .vs-section.is-open .vs-section-title { color: var(--white); }
  body.apex-design-blue .vs-section.is-open .vs-section-count { background: rgba(255,255,255,0.22); color: var(--white); }
  body.apex-design-blue .vs-section.is-open .vs-chev { border-top-color: var(--white); }
  body.apex-design-blue .vs-subgroup { border-left-color: #9CC2E4; }
  body.apex-design-blue .vs-subgroup-head { background: rgba(156, 194, 228, 0.3); }
  @container (max-width: 560px) {
    .vs-selector-row { grid-template-columns: 1fr 1fr; gap: 0.5rem; }
    .vs-sel-left { grid-column: 1; grid-row: 1; justify-self: stretch; }
    .vs-sel-center { grid-column: 2; grid-row: 1; justify-self: stretch; }
    .vs-sel-right { grid-column: 1 / -1; grid-row: 2; justify-self: stretch; }
    .vs-sel-left select.vs-control,
    .vs-sel-right select.vs-control,
    .vs-sel-center select.vs-control { width: 100%; }
    /* TWO-SELECTOR ROWS KEEP BOTH CONTROLS ON ONE LINE (JAMIE, Sep 22 2026): "the parent View Stats
       panel ... is currently following CSS rules for admins who have 3 selectors. Parent accounts only
       have two selectors, so they can remain on the same line." When there is no team selector the JS
       moves the player select into .vs-sel-left and leaves .vs-sel-center EMPTY, so the row only has two
       controls — the player and the season. Below 560px those two share row 1 instead of the player
       spanning it and the season dropping to row 2 the way the three-selector (admin / multi-team coach)
       row still does. The single-control case is the one exception: with the player select
       hidden (one kid, or a Player's own stats) there is nothing to pair it with, so the season keeps
       the full width. The label's right inset is the .vs-body padding (see `.vs-season-label` above),
       so the season TEXT lands on the inner stats box whatever the row's shape. The hidden test names
       the PLAYER select (`.vs-player-sel`) because the left group also holds the hidden team select in
       this flow — a bare `[hidden]` there would match every parent row and undo the whole point. */
    .vs-selector-row:has(.vs-sel-center:empty) .vs-sel-left { grid-column: 1; grid-row: 1; }
    .vs-selector-row:has(.vs-sel-center:empty) .vs-sel-right { grid-column: 2; grid-row: 1; justify-self: stretch; }
    .vs-selector-row:has(.vs-sel-center:empty):has(.vs-sel-left select.vs-player-sel[hidden]) .vs-sel-right { grid-column: 1 / -1; }
  }
  .vs-stats {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    margin-top: 0.75rem;
  }
  .vs-section {
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.625rem;
    overflow: hidden;
    background: var(--white);
  }
  .vs-section-head {
    width: 100%;
    display: flex;
    align-items: center;
    gap: 0.625rem;
    border: none;
    background: #EFF2F6;
    padding: 0.625rem 0.875rem;
    cursor: pointer;
    font-family: var(--font-primary);
    text-align: left;
    scroll-margin-top: calc(var(--header-h) + 0.5rem);
  }
  .vs-section.is-open .vs-section-head { background: var(--secondary); }
  .vs-section.is-open .vs-section-title { color: var(--white); }
  .vs-section-title {
    font-weight: 800;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--secondary);
    margin-right: 0.625rem;
  }
  .vs-section-count {
    font-size: 0.6875rem;
    font-weight: 700;
    color: var(--gray-text);
    background: rgba(0,0,0,0.07);
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
  }
  .vs-section.is-open .vs-section-count { background: rgba(255,255,255,0.22); color: var(--white); }
  .vs-chev {
    width: 0; height: 0;
    margin-left: auto;
    border-left: 0.3rem solid transparent;
    border-right: 0.3rem solid transparent;
    border-top: 0.35rem solid var(--gray-text);
    transform: rotate(90deg);
    transition: transform 0.15s;
  }
  .vs-section.is-open .vs-chev { transform: rotate(0deg); border-top-color: var(--white); }
  .vs-section .vs-body { display: none; }
  .vs-section.is-open .vs-body { display: block; }
  .vs-pair {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1.5rem;
    align-items: start;
  }
  @container (max-width: 1000px) { .vs-pair { grid-template-columns: 1fr; } }
  .vs-group {
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.75rem;
    overflow: hidden;
    min-width: 0;
  }
  .vs-group-title {
    font-family: var(--font-primary);
    font-weight: 800;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    color: var(--white);
    background: var(--secondary);
    padding: 0.625rem 1.25rem;
    text-align: center;
  }
  .vs-table {
    width: 100%;
    border-collapse: collapse;
  }
  .vs-table thead th {
    font-family: var(--font-primary);
    font-size: 0.6875rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--gray-text);
    font-weight: 700;
    text-align: left;
    padding: 0.625rem 1.25rem;
    border-bottom: 0.0625rem solid var(--light-gray);
    background: #EFF2F6;
  }
  .vs-table thead th.vs-col-stat { width: 6rem; min-width: 6rem; }
  .vs-table thead th.vs-col-value { width: 4.25rem; min-width: 4.25rem; }
  .vs-table thead th.vs-col-rank { width: 3.25rem; min-width: 3.25rem; }
  .vs-table thead th.vs-col-value,
  .vs-table thead th.vs-col-rank { text-align: right; }
  .vs-table tbody td {
    padding: 0.4375rem 1.25rem;
    font-size: 0.875rem;
    border-bottom: 0.0625rem solid var(--light-gray);
  }
  .vs-table tbody tr:last-child td { border-bottom: none; }
  .vs-table td.vs-stat {
    font-weight: 600;
    color: var(--secondary);
    text-align: left;
    white-space: nowrap;
  }
  .vs-stat .vs-stat-def {
    color: var(--gray-text);
    font-size: 0.75rem;
    line-height: 1.35;
    min-width: 9rem;
    white-space: normal;
    font-weight: 400;
  }
  .vs-table td.vs-value {
    font-weight: 800;
    color: var(--secondary);
    text-align: right;
    font-variant-numeric: tabular-nums;
  }
  .vs-table td.vs-rank-cell {
    text-align: right;
    font-size: 0.75rem;
    color: var(--gray-text);
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  .vs-dash { color: var(--gray-text); }
  .vs-body { padding: 0.875rem 1rem 1rem; }
  .vs-subgroup {
    border: 0.0625rem solid #E1E7EF;
    border-left: 0.25rem solid var(--secondary);
    border-radius: 0.625rem;
    overflow: hidden;
    margin-top: 0.875rem;
  }
  .vs-subgroup:first-child { margin-top: 0; }
  .vs-subgroup-head {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    padding: 0.625rem 0.875rem 0.5rem;
    background: rgba(0, 32, 78, 0.2);
    border-bottom: 0.0625rem solid #E1E7EF;
  }
  .vs-subgroup-name {
    font-family: var(--font-primary);
    font-weight: 800;
    font-size: 0.75rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--secondary);
  }
  .vs-subgroup-desc {
    font-size: 0.75rem;
    color: var(--gray-text);
    line-height: 1.4;
    margin-top: 0.125rem;
    max-width: 44rem;
  }
  .nr { font-style: italic; }
  .rk-rank.nr { background: transparent; color: var(--ws-muted); box-shadow: none; }
  @container (max-width: 600px) {
    .vs-body { padding: 0.625rem 0.625rem 0.875rem; }
    /* The season text tracks the narrower .vs-body padding at this band, so its right edge keeps
       landing on the inner stats box (the .vs-subgroup card) at every width — JAMIE, Sep 22 2026. */
    .vs-season-label { margin-right: calc(0.625rem + 0.0625rem); }
    .vs-subgroup-head { padding: 0.5rem 0.625rem 0.4375rem; }
    .vs-table thead th, .vs-table tbody td { padding: 0.4375rem 0.5rem; }
    .vs-stat .vs-stat-def { min-width: 0; }
    .vs-subgroup { overflow-x: auto; }
    .vs-table thead th.vs-col-stat { width: 44%; min-width: 5.5rem; }
    .vs-table thead th.vs-col-value { width: 24%; min-width: 3.5rem; }
    .vs-table thead th.vs-col-rank { width: 16%; min-width: 3rem; }
  }


  /* Billing Summary: the heading that owns the money (JAMIE, Sep 26 2026: "Let's put the billing options
     outside of the freshbooks box in a billing summary box." — Oct 1 2026: one box too many, so the
     wrapper box is gone and the heading stands alone). The per-player amounts and the pay-ahead
     checkboxes sit ABOVE the two method cards, one per-player block inside #payPlayers. The method cards
     below are dashed and tinted because they are offers to choose between. The heading mirrors
     .pay-card h3 so the two levels (panel h2 → heading) read as one system. */
  .pay-summary-h {
    font-family: var(--font-primary);
    font-weight: 700;
    font-size: 1.0625rem;
    color: var(--secondary);
    margin: 0 0 0.5rem;
  }
  [data-panel="payment"] > h2 + .pay-summary-h { margin-top: 1.5rem; }
  .pay-summary-h.pay-options-h { margin-top: 1.5rem; }
  .pay-players { margin-bottom: 1.25rem; }
  .pay-methods {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }
  .pay-card {
    border: 0.0625rem dashed var(--light-gray);
    border-radius: 0.75rem;
    padding: 1.75rem 1.5rem;
    background: #F7FAFD;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.625rem;
  }
  .pay-icon {
    width: 2.625rem;
    height: 2.625rem;
    color: var(--primary);
    opacity: 0.85;
    margin-bottom: 0.125rem;
  }
  .pay-card h3 {
    font-family: var(--font-primary);
    font-weight: 700;
    font-size: 1.0625rem;
    color: var(--secondary);
    margin-bottom: 0.125rem;
  }
  .pay-card p {
    color: var(--gray-text);
    font-size: 0.9375rem;
    line-height: 1.55;
    margin: 0;
  }
  .pay-card .pay-addr {
    font-weight: 600;
    color: var(--secondary);
    line-height: 1.6;
  }
  .pay-card .pay-privacy { font-size: 0.75rem; font-style: italic; }
  .pay-card .btn-primary { margin-top: 0.375rem; }
  /* Payment panel: the processor's mark sits inline in the card's own heading — the same unaltered
     FreshBooks logotype the ledger's pay box uses, never recolored, filtered or redrawn. */
  .pay-mark { display: inline-block; height: 1.5rem; width: auto; vertical-align: -0.3125rem; }
  .pay-mark-inline { display: inline-block; height: 1.25em; width: auto; vertical-align: -0.2em; }
  /* One box per linked player, each listing its own pills. */
  .pay-players { display: flex; flex-direction: column; gap: 0.75rem; width: 100%; margin-top: 0.25rem; }
  .pay-player {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 0.875rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.625rem;
    background: #fff;
  }
  .pay-player-name { font-weight: 700; font-size: 0.875rem; color: var(--secondary); }
  /* Locked pay rows (online payment in flight while the checkout tab is open): the box
     disables natively, the text dims, and the reason rides inline under the row — a
     greyed control with no explanation reads as broken (BILLING-SCOPE §13). */
  .pay-opt-row.is-locked { cursor: default; }
  .pay-opt-row.is-locked .pay-opt-info, .pay-opt-row.is-locked .pay-opt-amt { opacity: 0.55; }
  .pay-opt-row.is-locked input { cursor: default; }
  .pay-progress-tag { display: block; font-size: 0.6875rem; font-weight: 700; color: #1D4ED8; }
  .pay-opt-row.is-paid { cursor: default; }
  .pay-opt-row.is-paid .pay-opt-info, .pay-opt-row.is-paid .pay-opt-amt { opacity: 0.55; }
  .pay-opt-row.is-paid input { cursor: default; }
  .pay-paid-tag { display: block; font-size: 0.6875rem; font-weight: 700; color: #1A7F37; }
  .pay-opt-row.is-pending { cursor: default; }
  .pay-opt-row.is-pending .pay-opt-info, .pay-opt-row.is-pending .pay-opt-amt { opacity: 0.55; }
  .pay-opt-row.is-pending input { cursor: default; }
  .pay-pending-tag { display: block; font-size: 0.6875rem; font-weight: 700; color: #8A5A00; }
  .pay-declined-tag { display: block; font-size: 0.6875rem; font-weight: 700; color: #B91C1C; }
  .pay-status.is-settling { color: #8A5A00; font-weight: 700; font-size: 0.8125rem; background: #FEF3DC; border: 0.0625rem solid #D99A00; border-radius: 0.5rem; padding: 0.625rem 0.875rem; }
  .pay-due-tag.is-paid-tag { background: #1A7F37; color: #fff; }
  .pay-due-tag.is-pending-tag { background: #8A5A00; color: #fff; }
  .pay-min-note { margin: 0.5rem 0 0; font-size: 0.8125rem; font-weight: 700; color: #B91C1C; }
  .pay-min-note[hidden] { display: none; }
  /* Selected-total line between the player cards and the method boxes: big, right-aligned,
     unmissable. Updated by syncPayNow alongside the Pay Now label. */
  .pay-total-line { display: flex; align-items: baseline; justify-content: flex-end; gap: 0.5rem; margin: 0.75rem 0; padding-bottom: 0.75rem; border-bottom: 0.0625rem solid var(--light-gray); font-size: 1rem; font-weight: 600; color: var(--ws-ink-2); }
  .pay-total-line strong { font-size: 1.375rem; font-weight: 800; color: var(--secondary); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
  /* "Payment Options" header above the method boxes: same voice as Billing Summary, with a
     blank line of air above it. Left-aligned by default. */
  .pay-options-h { margin-top: 1.25rem; }
  /* Pay-link status line under Pay Now ("Creating…", "Confirming…", honest errors). Same caption
     voice as the rest of the panel; hidden until it has something true to say. */
  .pay-status { margin: 0.5rem 0 0; font-size: 0.8125rem; color: var(--gray-text); }
  .pay-status.is-received { color: #1A7F37; font-weight: 700; font-size: 0.8125rem; background: #E6F4EA; border: 0.0625rem solid #1A7F37; border-radius: 0.5rem; padding: 0.625rem 0.875rem; }
  .pay-status.is-error { color: #B91C1C; font-weight: 700; font-size: 0.8125rem; }
  .pay-status.is-received .pay-still-due { display: block; margin-top: 0.25rem; }
  .pay-still-due-box { margin: 0.5rem 0 0; width: 100%; align-self: stretch; font-size: 0.8125rem; font-weight: 700; color: #8A5A00; background: #FEF3DC; border: 0.0625rem solid #D99A00; border-radius: 0.5rem; padding: 0.625rem 0.875rem; }
  .pay-still-due-box .pay-still-due-list { margin: 0.25rem 0 0; padding-left: 2.5rem; list-style: disc; }
  .pay-still-due-box .pay-still-due { display: list-item; }
  .pay-still-due-box .pay-pending-line { display: block; }
  .pay-still-due-box .pay-warn-icon { vertical-align: -0.15em; margin-right: 0.375rem; }
  @media (max-width: 640px) {
    .pay-still-due-box .pay-still-due-list { padding-left: 1.25rem; }
  }
  .pay-status[hidden] { display: none; }
  /* Pre-checkout confirm modal: the covered items and the FreshBooks fee table. Amount
     leads big; items ride quiet under it; fees read as method/fee rows on hairlines. */
  #payConfirmModal .btn-primary { color: var(--white) !important; }
  /* Continue button carries the full-color FreshBooks lockup (badge + black wordmark), so it
     sits on white — the trademark file ships unaltered, never filtered. Buttons wrap on tiny
     screens instead of squeezing. */
  #payConfirmModal .modal-btn-row { flex-wrap: wrap; }
  #payConfirmModal .modal-btn-row .ws-btn { flex: 1 1 6rem; padding-top: 0.45rem; padding-bottom: 0.45rem; font-size: 0.875rem; }
  #payConfirmModal .pay-continue { flex: 1 1 12rem; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 0; padding-top: 0.45rem; padding-bottom: 0.45rem; font-size: 0.875rem; line-height: 1.35; }
  #payConfirmModal .pay-confirm-amt { margin: 0 0 0.375rem; font-size: 1.375rem; font-weight: 800; color: var(--secondary); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; line-height: 1.2; }
  #payConfirmModal .pay-confirm-items { margin: 0 0 0.875rem; padding-left: 2.5rem; list-style: disc; font-size: 0.8125rem; color: var(--gray-text); }
  #payConfirmModal .pay-confirm-items li { margin: 0; padding: 0.125rem 0 0.125rem 0.5rem; font-variant-numeric: tabular-nums; }
  #payConfirmModal .pay-confirm-note { margin: 0 0 0.5rem; font-size: 0.875rem; line-height: 1.55; color: var(--secondary); text-align: center; }
  .pay-card .pay-fee-note { margin: 1.5rem 0 0.25rem; font-size: 0.75rem; line-height: 1.5; color: var(--gray-text); }
  .pay-fee-list { margin: 0; padding: 0; list-style: none; font-size: 0.75rem; }
  .pay-fee-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; margin: 0; padding: 0.25rem 0; border-top: 0.0625rem solid var(--light-gray); }
  .pay-fee-list li:last-child { border-bottom: 0.0625rem solid var(--light-gray); }
  .pay-fee-list span { color: var(--gray-text); }
  .pay-fee-list strong { flex: none; color: var(--secondary); font-variant-numeric: tabular-nums; }
  /* The owed amount leads as a stated fact; every row's box stays enabled — past-due lines default
     ticked (BILLING-SCOPE §13) and unticking takes one deliberate click. */
  .pay-due-line { display: flex; align-items: center; gap: 0.375rem; margin: 0; }
  .pay-due-amt { font-size: 1.375rem; font-weight: 800; color: var(--ws-ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
  .pay-due-tag { display: inline; background: none; border: none; padding: 0; white-space: nowrap; }
  .pay-due-tag.is-paid-tag { background: none; border: none; }
  .pay-due-tag.is-pending-tag { background: none; border: none; }
  .pay-due-chip { font-size: 0.5625rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; line-height: 1; padding: 0.25rem 0.4375rem; border-radius: 0.9375rem; white-space: nowrap; background: #fff; border: 0.0625rem solid #FECACA; color: #B91C1C; position: relative; top: -2px; }
  .pay-due-tag.is-paid-tag .pay-due-chip { background: #fff; border-color: rgba(22, 163, 74, 0.6); color: #15803D; }
  .pay-due-tag.is-pending-tag .pay-due-chip { background: #fff; border-color: rgba(180, 120, 0, 0.65); color: #8A5A00; }
  .pay-due-sub { display: flex; align-items: center; gap: 0.375rem; margin: -0.125rem 0 0; }
  .pay-due-sub-amt { font-size: 1.375rem; font-weight: 500; color: var(--ws-ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; text-align: right; }
  .pay-due-sub-tag { font-size: 0.5625rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em; line-height: 1; color: #8A5A00; background: #fff; border: 0.0625rem solid rgba(180, 120, 0, 0.65); border-radius: 0.9375rem; padding: 0.25rem 0.4375rem; white-space: nowrap; }
  .pay-due-note { margin: 0; font-size: 0.8125rem; color: var(--gray-text); }
  .pay-due-note.pay-due-warn { color: var(--pay-due); font-weight: 700; }
  .pay-due-alarm { color: var(--pay-due); font-weight: 700; }
  .pay-nothing { margin: 0; font-size: 0.8125rem; color: var(--gray-text); }
  /* JAMIE: "Put a separator line above Optional Pay Ahead when that is showing." The rule rides on the
     caption itself, so it can only ever appear when the caption does — a player with nothing optional
     ahead shows no orphan line — and the caption's own margin comes off so the rule sits at the box's
     normal 0.5rem rhythm rather than a gap-plus-margin above it. */
  .pay-opt-label {
    margin: 0;
    padding-top: 0.375rem;
    border-top: 0.0625rem solid var(--light-gray);
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #5A6B7C;
  }
  /* A pay row reads [checkbox] · description · "(Due <date>)" · amount (JAMIE, Sep 26 2026: "Change the
     format so it reads: [Checkbox] (indent) (description) Due (date) then the (total) on the right").
     Three columns — the box, the text, the money — so the amount always lands on the row's right edge
     whatever the description does, and the text column (`minmax(0, 1fr)`, which may shrink below its
     content) takes the spare width and wraps INSIDE itself instead of squeezing the amount. */
  .pay-opt-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    cursor: pointer;
  }
  .pay-opt-row input { width: 1rem; height: 1rem; margin: 0; accent-color: var(--primary); cursor: pointer; }
  /* The indent JAMIE asked for — the description starts a step in from the box rather than flush
     against it. The row's smallest text now lives in this cell, so the ink styles hang off it. */
  .pay-opt-info { min-width: 0; padding-left: 0.375rem; font-size: 0.8125rem; display: flex; flex-wrap: wrap; align-items: baseline; column-gap: 0.375rem; }
  /* The description names WHAT is being paid — an installment's own number ("Tuition/Peak Installment
     2 of 4") or a Peak/Mo month in the ledger's own words ("PK/mo · Peak: 9/1-9/30", the ledger's name
     cell beside its period) — and carries the ledger's name styling (JAMIE, Sep 26 2026). */
  .pay-opt-name { font-weight: 800; color: var(--ws-ink); overflow-wrap: anywhere; }
  /* At phone-narrow widths the nowrap name ("Peak Installment 1 of 4") plus its date and amount
     cannot share one row's budget, so the panel sheds padding and a step of type instead of breaking
     the name apart (Oct 1 2026). The wrap point stays BETWEEN the name and its "(Due …)" aside. */
  @media (max-width: 22.5rem) {
    .portal-panel[data-panel="payment"] { padding: 1rem; }
    .pay-player { padding: 0.75rem 0.625rem; }
    .pay-opt-row { gap: 0.375rem; }
    .pay-opt-info { font-size: 0.75rem; }
    .pay-opt-amt { font-size: 0.75rem; }
  }
  /* The date closes the description as a parenthetical aside — "(Due 10/1/26)" — a step smaller than the
     row's other text (JAMIE, Sep 26 2026: "Put Due (date) in parentheses and use a smaller font") and in
     the ledger's own muted period styling. nowrap so a date can never be split across two lines, with a
     small lead-in so the aside is not glued to the tail of a long description. */
  .pay-opt-due { font-size: 0.75rem; color: var(--ws-ink-2); white-space: nowrap; }
  .pay-opt-amt { font-size: 0.8125rem; font-weight: 700; color: var(--ws-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
  .pay-empty { color: var(--gray-text); font-size: 0.9375rem; margin: 0; }
  /* Pay Now is the ledger screen's own Make a Payment button, one panel over (JAMIE, Sep 26 2026:
     "Smaller pay now button (similar size as Make A Payment button on ledgers screen)"): the same
     0.875rem/700 label, the same 0.5625rem x 1.25rem padding, the same 0.3125rem radius and palette as
     .parent-pay-btn, so the two CTAs read as one control. It keeps its INTRINSIC width in a way the
     ledger button deliberately does not — that one stretches to match the processor note beneath it,
     and there is no note here. Inert state copies the ledger's own: the line colour fills, the label
     drops to muted, nothing vanishes — a $0 or unticked panel still shows the button it cannot press. */
  .pay-now {
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 700;
    line-height: 1.2;
    padding: 0.5625rem 1.25rem;
    border: none;
    border-radius: 0.3125rem;
    background: var(--primary);
    color: var(--white) !important;
    cursor: pointer;
    transition: background 0.15s ease;
  }
  .pay-now:hover { background: var(--primary-dark); }
  .pay-now:disabled { background: var(--ws-line); color: var(--ws-muted); cursor: default; }
  .pay-blurb { margin-bottom: 0.25rem !important; }
  .pay-action { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-top: 0.25rem; }
  .pay-powered { font-size: 0.75rem; color: var(--gray-text); white-space: nowrap; }
  .pay-mark-sm { height: 1.1rem; }
  .photo-url-row { display: flex; align-items: center; gap: 0.5rem; }
  .photo-url-row .ws-input { flex: 1 1 auto; min-width: 0; }
  #pPhotoWrap {
    border: 1px dashed var(--primary);
    border-radius: 0.5rem;
    padding: 0.75rem;
    background: rgba(102, 153, 204, 0.06);
  }
  .photo-helper { margin: 0 0 0.5rem; font-size: 0.8125rem; color: var(--secondary); }
  .photo-upload-row { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.5rem; }
  .photo-upload-msg { font-size: 0.8125rem; color: var(--secondary); }
  .photo-upload-msg.error { color: #BE123C; }
  .photo-upload-msg.success { color: #047857; }
  .photo-url-preview {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
    border-radius: 0.375rem;
    object-fit: cover;
    background: #f3f4f6;
    border: 1px solid rgba(0,0,0,0.08);
  }
  /* The two payment cards STACK at every width (JAMIE, Sep 26 2026). The base grid was
     already single-column; a `min-width: 40rem` rule used to split it into two side-by-side
     cards and is deliberately gone, so nobody "restores" the side-by-side pass. */
  .ledger-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.9375rem;
    margin-top: 0.25rem;
  }
  .ledger-table th {
    text-align: left;
    font-family: var(--font-primary);
    font-weight: 700;
    font-size: 0.8438rem;
    text-transform: uppercase;
    letter-spacing: 0.0312rem;
    color: var(--secondary);
    padding: 0.625rem 0.75rem;
    border-bottom: 0.125rem solid var(--primary);
  }
  .ledger-table td {
    padding: 0.625rem 0.75rem;
    border-bottom: 0.0625rem solid var(--light-gray);
  }
  .ledger-table .num { text-align: right; font-variant-numeric: tabular-nums; }
  .pw-fields {
    margin-top: 1.25rem;
    border-top: 0.0625rem solid var(--light-gray);
    padding-top: 1.5rem;
  }
  .pw-fields .btn-primary {
    margin-top: 0.75rem;
    color: var(--white) !important;
  }
  .form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 1.125rem;
    margin-bottom: 0.5rem;
  }
  .form-grid .form-grid-full { grid-column: 1 / -1; }
  .form-grid-3 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 0 1.125rem;
  }
  @media (max-width: 760px) {
    .portal-layout { display: block; padding-top: 0; }
    .portal-nav {
      position: sticky;
      top: var(--header-h);
      z-index: 50;
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.03125rem;
      margin: 0 -1.5rem 1.25rem;
      padding: 0.03125rem;
      background: #D4D9E0;
      border: none;
      /* Ledge where the band meets the hero above it. Each design draws a line that reads
         against its own hero: light blue on the navy design, navy on the light-blue design. */
      border-top: 0.125rem solid var(--nav-ledge, var(--primary));
      border-radius: 0;
      box-shadow: 0 0.1875rem 0.625rem rgba(0,32,78,0.12);
    }
    /* Docked, the band sits under the header rather than against the hero, so the ledge goes away.
       COLOR only (never width), so the band never shifts by a pixel as it docks. */
    .portal-nav.portal-nav-docked { border-top-color: transparent; }
    .portal-tab {
      width: 100%;
      text-align: center;
      background: var(--light-gray);
      border: none;
      border-radius: 0;
      padding: 0.3125rem 0.5rem;
      font-size: 0.875rem;
      font-weight: 700;
      color: var(--dark-gray);
      box-shadow: inset 0 0 0 0.03125rem rgba(0,32,78,0.10);
    }
    .portal-tab .tab-roles { display: inline; margin-left: 0.25rem; margin-top: 0; color: var(--gray-text); }
    .portal-tab:hover { background: #DDE2E7; color: var(--dark-gray); }
    .portal-tab.active { background: var(--secondary); color: var(--white); }
    .portal-tab.active .tab-roles { color: rgba(255, 255, 255, 0.75); }
    .portal-nav.portal-nav-few { grid-template-columns: 1fr; }
    .portal-nav .portal-tab.portal-tab-last-full { grid-column: 1 / -1; }
    .portal-nav.portal-nav-many > .portal-tab.portal-nav-rest { display: none; }
    .portal-nav.portal-nav-many .portal-more {
      position: absolute;
      left: 50%;
      bottom: 0;
      transform: translateX(-50%) translateY(50%);
      clip-path: inset(50% 0 0 0);
      display: inline-flex;
      align-items: center;
      justify-content: center;
      gap: 0.25rem;
      padding: 1.1875rem 1rem 0.125rem;
      white-space: nowrap;
      border: 0.0625rem solid #D4D9E0;
      border-radius: 999px;
      background: var(--light-gray);
      box-shadow: 0 0.125rem 0.375rem rgba(0,32,78,0.08);
      color: var(--dark-gray);
      font-size: 0.75rem;
    }
    .portal-nav.portal-nav-many .portal-more:hover { background: #DDE2E7; color: var(--dark-gray); }
    .portal-nav.portal-nav-many.portal-nav-more-open .portal-more { color: var(--secondary); }
    .form-grid { grid-template-columns: 1fr; }
    .form-grid-3 { grid-template-columns: 1fr; }
    #pPhysWrap { grid-template-columns: 1fr 1fr; }
    #pDobRow { grid-template-columns: 1fr 1fr; }
    #tNameRow { grid-template-columns: 1fr 1fr; }
    #tCoachRow { grid-template-columns: 1fr 1fr; }
    .hero-top { flex-direction: column; align-items: center; }
    .hero-caption { order: 1; display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-bottom: -0.375rem; }
    .hero-caption .stat-label { display: none; }
    .hero-caption .hero-stat { font-size: 1rem; gap: 0.25rem; }
    .dash-stats { order: 5; width: 100%; max-width: none; }
    .dashboard-hero { --stat-row: 3.375rem; --pill-height: 2.375rem; }
    .dashboard-hero { padding-top: 1.875rem; padding-bottom: 1.875rem; }
    .dash-stats.is-6 .dash-stat { padding: 0.25rem 0.5rem 0.25rem 1.125rem; min-height: 0; }
    .dash-stats.is-6 .dash-stat-cat { left: 0.1875rem; font-size: 0.59375rem; letter-spacing: 0.3125rem; }
    .dash-stats.is-6 .dash-stat-label { transform: none; font-size: 0.625rem; margin-top: 0; }
    .dash-stats.is-6 .dash-stat-value { font-size: 1.125rem; align-self: flex-start; margin-top: 0.125rem; }
    .dash-stats.is-6 .dash-stat-ranks { grid-row: 1 / -1; align-self: center; transform: none; margin-right: 0.375rem; margin-top: -0.125rem; gap: 0.1875rem; }
    .dash-stats.is-6 .dash-stat-rank { align-items: baseline; gap: 0.25rem; font-size: 0.75rem; line-height: 1.1; }
    .dash-stats.is-6 .dash-stat-rank b { font-size: 0.75rem; }
    .dash-stats.is-6 .dash-stat-rank .rank-lbl { display: inline; }
    .hero-photo { order: 2; margin-left: auto; margin-right: auto; width: min(calc(100% - 2 * (var(--pill-left-pad) + var(--num-width))), 16rem); aspect-ratio: 7 / 8; height: auto; border-width: 0.0625rem; }
    .dashboard-hero.is-stacked-3 .hero-photo { margin-bottom: calc(-1 * (var(--hero-gap) + var(--pill-height) / 2)); }
    .hero-pill { order: 3; flex-basis: auto; width: 100%; padding: 0 0.875rem 0 var(--pill-left-pad); gap: 0.625rem; border-bottom-color: rgba(255,255,255,0.5); box-shadow: inset 0 0.0625rem 0.1875rem rgba(255,255,255,0.22), inset 0 0.0625rem 0 rgba(255,255,255,0.4), inset 0 -0.5rem 1.25rem rgba(0,0,0,0.1), inset 0.625rem 0 0.875rem -0.625rem rgba(0,10,26,0.5), inset -0.625rem 0 0.875rem -0.625rem rgba(0,10,26,0.5), 0 0 0.875rem rgba(142,201,255,0.16), 0 0 2.25rem rgba(142,201,255,0.10); }
    .hero-pill h1 { left: 50%; transform: translate(-50%, -50%); width: calc(100% - 2 * (var(--pill-left-pad) + var(--num-width))); font-size: 1.125rem; }
    .hero-pill-num { font-size: 1rem; padding-right: 0.625rem; }
    .hero-sep { order: 4; display: block; width: 4.5rem; height: 0.1875rem; background: var(--primary); border-radius: 0.1875rem; margin: 0.375rem 0 0; }
    .hero-pill-stats { display: none; }
  }
  @media (min-width: 460.5px) and (max-width: 760px) {
    .hero-caption { display: none; }
    .hero-pill-stats { display: flex; }
    #dashTeam { transform: translateY(-1.5px); display: inline-block; }
    .hero-pill-stats-right { order: 2; margin-left: 0; padding-left: 0; }
    .hero-pill-spacer { order: 3; }
    .hero-pill-stats-left { order: 4; margin-left: 0; padding-left: 0; }
    .hero-pill-stats-left .stat-divider { display: none; }
    .hero-pill-stats .stat-label::after { content: ":"; }
    .hero-pill.is-stacked .hero-pill-stats .stat-label::after { content: ""; }
    .hero-pill h1 { width: calc(100% - 22.375rem); }
    .hero-pill.is-stacked h1 { overflow-wrap: anywhere; width: calc(100% - 17.75rem); }
    .hero-pill-stats .hero-stat { gap: 0.1875rem; }
    .hero-pill.is-stacked .hero-stat { flex-direction: column; align-items: flex-start; gap: 0.125rem; }
  }
  @media (min-width: 599.5px) and (max-width: 760px) {
    .dash-stats.is-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .dash-stats.is-6 .dash-stat.hide-on-narrow { display: grid; }
  }
  @media (max-width: 360.5px) {
    .dash-stats.is-6 .dash-stat-rank { font-size: 0.6875rem; line-height: 1.1; }
    .dash-stats.is-6 .dash-stat-rank b { font-size: 0.6875rem; }
    .dash-stats.is-6 .dash-stat-ranks { margin-top: 0; }
    .dash-stats.is-6 .dash-stat-rank .rank-lbl span + span { display: none; }
    .dash-stats.is-6 .dash-stat-rank .rank-lbl::after { content: " Rk:"; }
  }
  @media (max-width: 420.5px) {
    .dashboard-hero .dash-stat-value,
    .dashboard-hero .dash-stats.is-6 .dash-stat-value { font-size: 1rem; }
    .dashboard-hero .dash-stats.is-6 .dash-stat-label,
    .dashboard-hero .dash-stats.is-6 .dash-stat-value { position: relative; left: 0.25rem; }
  }

  /* ---------- Player Portal Modal ---------- */
  .modal-overlay {
    position: fixed; inset: 0;
    background: rgba(0,20,51,0.6);
    backdrop-filter: blur(0.25rem);
    display: flex;
    overflow-y: auto;
    z-index: 1000;
    padding: 1.25rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
  }
  .modal-overlay.open {
    opacity: 1;
    pointer-events: auto;
  }
  .modal {
    background: var(--white);
    border-radius: 1rem;
    box-shadow: 0 1.25rem 3.75rem rgba(0,20,51,0.3);
    width: 100%;
    max-width: 25rem;
    padding: 2.25rem 2rem;
    margin: auto;
    position: relative;
    transform: translateY(1.25rem);
    transition: transform 0.3s ease;
  }
  .modal-overlay.open .modal {
    transform: translateY(0);
  }
  .modal-close {
    position: absolute;
    top: 0.875rem; right: 0.875rem;
    z-index: 2;
    background: none; border: none;
    font-size: 1.375rem;
    cursor: pointer;
    color: var(--gray);
    width: 2rem; height: 2rem;
    border-radius: 0.5rem;
    display: flex; align-items: center; justify-content: center;
    transition: background 0.2s, color 0.2s;
  }
  .modal-close:hover { background: var(--light-gray); color: var(--dark-gray); }
  .modal-logo {
    width: 3.25rem; height: 3.25rem;
    background: var(--secondary);
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    margin: 0 auto 1.125rem;
  }
  .modal h2 {
    font-size: 1.5rem; font-weight: 900;
    color: var(--secondary);
    text-align: center;
    margin-bottom: 0.25rem;
  }
  .modal-sub {
    text-align: center;
    color: var(--gray-text);
    font-size: 0.875rem;
    margin-bottom: 1.5rem;
  }
  #portalModal .modal-head {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.125rem;
  }
  #portalModal .modal-logo {
    margin: 0;
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 3.625rem;
    height: 3.625rem;
    /* The real brand logo (JAMIE, Sep 2026): the official round badge, exactly as the header and the
       footer render it. overflow:hidden is what makes it round here — the asset is a SQUARE navy card
       whose corners must be clipped to the circle (the header's .logo-icon clips it the same way). */
    overflow: hidden;
  }
  #portalModal .modal-logo .logo-img {
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: cover;
    display: block;
    transform: translateY(-1px);
  }
  /* Login-modal field outlines (JAMIE, Sep 2026): the shared .form-group line (--light-gray #E8EAED)
     all but disappears against the modal's white card, so the portal modal's inputs take a slightly
     darker one. The focus rule repeats at the same ID specificity on purpose — otherwise this
     border-color would out-specify .form-group input:focus and kill the blue focus ring. */
  #portalModal .form-group input {
    border-color: #C9CDD3;
  }
  #portalModal .form-group input:focus {
    border-color: var(--primary);
  }
  #portalModal .modal-head h2 {
    margin: 0;
    text-align: center;
    font-size: 1.625rem;
  }
  #portalModal .modal-sub {
    margin-top: calc(0.5rem + 29px);
    font-weight: 500;
  }
  #portalModal .modal-close {
    width: 2.625rem;
    height: 2.625rem;
    font-size: 1.875rem;
  }
  #portalModal .modal {
    padding-top: 1.5rem;
    /* The watermark below bleeds past the card on purpose, so the card has to clip it — this is what
       turns an oversized logo into a background shape instead of a stray image hanging off the box. */
    overflow: hidden;
  }
  /* Login-modal brand watermark (JAMIE, Sep 2026: "Can you creatively display this logo as the
     background of the login modal (perhaps intentionally too large)?"). The official A mark (its
     transparent-background raster, apex-logo-mark.png — the badge's vector master as a PNG) is scaled
     to 200% of the card, pushed off the bottom-right corner and rotated, so the card shows only part
     of it: the goal is a brand shape the form sits ON, not a logo pasted into a box. It is faint
     (opacity) and masked, brightest at the bottom-right where the card is empty (below the button,
     beside the "Forgot Password?" link) and gone by the time it reaches the headline and the fields —
     the labels and outlines stay crisp. Every real child of the card is lifted to z-index 1 so the
     watermark can only ever be a backdrop (the close button keeps its own absolute positioning). */
  #portalModal .modal-bg {
    position: absolute; inset: 0;
    pointer-events: none;
    z-index: 0;
    overflow: hidden;
    /* The fade lives on the CARD-SIZED layer, not on the artwork, so the watermarked region stays put
       in card coordinates no matter how far the logo is scaled up inside it. */
    /* 0.28 tuned Sep 2026 (JAMIE: "what if the mark were slightly more visible?"): at 0.22 the mark
       barely read as a logo at all, and by 0.34 the shapes start hazing the space behind the Sign In
       button and the Forgot Password link — 0.28 is the last step that is legible-but-calm. */
    opacity: 0.28;
    -webkit-mask-image: radial-gradient(130% 118% at 84% 106%, #000 0%, rgba(0,0,0,0.62) 44%, rgba(0,0,0,0) 76%);
    mask-image: radial-gradient(130% 118% at 84% 106%, #000 0%, rgba(0,0,0,0.62) 44%, rgba(0,0,0,0) 76%);
  }
  #portalModal .modal-bg-mark {
    position: absolute;
    right: -52%;
    bottom: -28%;
    width: 200%;
    height: auto;
    transform: rotate(-7deg);
    user-select: none;
    -webkit-user-drag: none;
    /* Do NOT darken this with a filter to try to "bring back" its lighter tones — tried Sep 2026 and
       reverted: brightness() flattens every tone, white shapes included, into an even gray wash. The
       white shapes are load-bearing — white-on-white is what keeps the badge's internal contrast. */
  }
  #portalModal .modal > *:not(.modal-bg):not(.modal-close) {
    position: relative;
    z-index: 1;
  }
  /* Phones (JAMIE, Sep 2026): the same watermark on a ~350px card covers a far bigger share of the
     surface, where a sliced logo starts to read as clutter instead of a background. So on narrow
     screens it drops to a whisper AND slides further off the corner — the visible part becomes a soft
     brand sweep behind the empty bottom-right of the card, and the form keeps its whitespace.
     The 460px trigger is the point where the CARD itself starts shrinking: it is
     min(100% - 2.5rem, 25rem), so above ~460px every screen (phone in landscape included) gets the
     full-size 400px card and the desktop-strength watermark, and below it the card is genuinely
     narrow and the card-relative scale needs calming. */
  @media (max-width: 460px) {
    #portalModal .modal-bg { opacity: 0.15; }
    #portalModal .modal-bg-mark { right: -64%; bottom: -32%; width: 235%; }
  }

  /* ---------- Workspace modals (teams) — scoped, does not affect the login modal ---------- */
  .workspace-modal .modal {
    border-radius: 0.5rem;
    box-shadow: 0 0.875rem 2.5rem rgba(0,20,51,0.25);
    max-width: min(22.5rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    padding: 1.25rem 1.25rem 1.125rem;
  }
  .workspace-modal .modal-close {
    top: 1.25rem; right: 0.625rem;
    color: var(--ws-muted);
    width: 2rem; height: 2rem;
    margin-top: -0.25rem;
  }
  .workspace-modal .modal-close svg { width: 1rem; height: 1rem; display: block; }
  .workspace-modal .modal-close:hover { background: var(--ws-hover); color: var(--ws-ink); }
  .workspace-modal .modal-logo {
    width: 2.75rem; height: 2.75rem;
    margin: 0 auto 0.75rem;
  }
  .workspace-modal .modal h2 {
    font-size: 1.25rem; font-weight: 800;
    text-transform: uppercase; letter-spacing: 0.02em;
    color: var(--secondary);
    text-align: left;
    padding-right: 2.5rem;
    margin-bottom: 0.375rem;
    line-height: 1.1;
  }
  .workspace-modal .modal-sub {
    text-align: left;
    color: var(--secondary);
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.55;
    margin-bottom: 1rem;
  }
  .workspace-modal .modal-sub b { color: var(--dark-gray); }
  .workspace-modal .modal-sub .urgent { color: #B91C1C; font-weight: 800; }
  .form-group { margin-bottom: 1rem; }
  .form-section-break {
    margin: 0.25rem 0 1.25rem;
    padding-top: 1.25rem;
  }
  .form-section-title {
    font-size: 1.125rem;
    font-weight: 800;
    color: var(--secondary);
    margin: 0;
  }
  .form-group label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--dark-gray);
    margin-bottom: 0.375rem;
  }
  .form-group label .req {
    color: #D64541;
  }
  .form-group input {
    width: 100%;
    padding: 0.6875rem 0.875rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    font-size: 0.9375rem;
    font-family: inherit;
    transition: border-color 0.2s;
  }
  .form-group input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.15);
  }
  .form-group input[readonly] {
    background: #F4F6F9;
    color: var(--ws-muted);
    cursor: default;
    border-color: #DCE3EB;
  }
  .form-group select,
  .form-group textarea {
    width: 100%;
    padding: 0.6875rem 0.875rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    font-size: 0.9375rem;
    font-family: inherit;
    transition: border-color 0.2s;
  }
  .money-input {
    display: flex;
    align-items: center;
  }
  .money-symbol {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--ws-muted);
    padding: 0 0.5rem 0 0.125rem;
    user-select: none;
  }
  .money-input input {
    width: 100%;
  }
  .workspace-modal .form-group { margin-bottom: 0.5625rem; }
  .ws-check-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 1.5rem;
  }
  .ws-check-row .form-group { margin-bottom: 0.375rem; }
  .workspace-modal .form-group label { margin-bottom: 0.25rem; }
  .workspace-modal .form-group input,
  .workspace-modal .form-group select,
  .workspace-modal .form-group textarea {
    padding: 0.5625rem 0.75rem;
    font-size: 0.875rem;
  }
  .workspace-modal .form-group input[readonly] {
    background: #F4F6F9;
    color: var(--ws-muted);
    cursor: default;
    border-color: #DCE3EB;
  }
  .form-group input[readonly]#pAgeGroup,
  .form-group input[readonly]#tmDivision {
    background: rgba(46,111,180,0.10);
    color: #1E3A8A;
    font-weight: 800;
    border: 0.0625rem solid rgba(46,111,180,0.28);
    border-radius: 0.5rem;
    text-align: center;
    letter-spacing: 0.04em;
  }
  .form-group select:focus,
  .form-group textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.15);
  }
  .field-error {
    font-size: 0.8125rem;
    color: #EF4444;
    margin-top: 0.3125rem;
    min-height: 0;
    display: none;
    white-space: pre-line;
  }
  .field-error.show { display: block; }
  .field-hint {
    font-size: 0.75rem;
    color: var(--ws-muted);
    margin: 0.3125rem 0 0;
  }
  /* The contact form's live character counter, fed from the field's own maxlength, so the cap has
     exactly one home. It turns red the moment the field is full. */
  .field-hint.contact-count {
    text-align: right;
  }
  .field-hint.contact-count-full {
    color: #EF4444;
    font-weight: 700;
  }
  .field-wrap { position: relative; }
  .field-badge {
    position: absolute;
    right: 0.625rem;
    top: 50%;
    transform: translateY(-50%);
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: #EF4444;
    color: var(--white);
    font-size: 0.6875rem;
    font-weight: 800;
    line-height: 1rem;
    text-align: center;
    display: none;
    pointer-events: none;
  }
  .field-wrap.field-invalid .field-badge { display: block; }
  .field-wrap.field-invalid input,
  .field-wrap.field-invalid textarea,
  .field-wrap.field-invalid select {
    border-color: #EF4444;
  }
  .field-wrap.field-invalid input:focus,
  .field-wrap.field-invalid textarea:focus,
  .field-wrap.field-invalid select:focus {
    border-color: #EF4444;
    box-shadow: 0 0 0 0.1875rem rgba(239,68,68,0.12);
  }
  .account-form .field-wrap input {
    padding-right: 2.375rem;
  }
  .field-wrap.field-invalid input,
  .field-wrap.field-invalid select,
  .field-wrap.field-invalid textarea {
    padding-right: 2.375rem;
  }
  .field-wrap.field-invalid select ~ .field-badge { right: 2rem; }
  .contact-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.875rem;
    align-items: start;
  }
  .contact-block {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    margin-bottom: 1.625rem;
  }
  .contact-icon {
    flex: 0 0 auto;
    width: 2.875rem;
    height: 2.875rem;
    border-radius: 0.75rem;
    background: var(--light-gray);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
  }
  .contact-block h3 { margin: 0 0 0.25rem; font-size: 1.0625rem; }
  .contact-block p { margin: 0; color: var(--dark-gray); font-size: 0.9063rem; line-height: 1.6; }
  .contact-link { color: var(--secondary); font-weight: 700; text-decoration: none; }
  .contact-link:hover { text-decoration: underline; }
  #contact-section { scroll-margin-top: calc(var(--header-h) + 0.875rem); }
  .contact-form {
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.875rem;
    box-shadow: 0 0.25rem 1.5rem rgba(0,32,78,0.08);
    padding: 1.75rem 1.625rem;
  }
  .contact-form h3 {
    margin: 0 0 1.125rem;
    font-size: 1.25rem;
    color: var(--secondary);
  }
  /* Standing notice shown while the contact backend is unwired (#contactNotice). Hidden by
     app.js's applyWiring() the moment APEX_CONTACT_WIRED is true, so the form cannot look
     available while it cannot deliver. */
  .form-note {
    margin: 0 0 1.125rem;
    padding: 0.75rem 0.875rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    background: var(--light-gray);
    color: var(--dark-gray);
    font-size: 0.8438rem;
    line-height: 1.55;
    text-align: left;
  }
  .contact-form.contact-offline .form-group { opacity: 0.55; }
  .contact-submit {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    border: none;
    cursor: pointer;
    margin-top: 0.25rem;
    color: var(--white) !important;
  }
  .contact-submit:disabled { opacity: 0.7; cursor: default; transform: none; }
  .contact-submit .spinner {
    width: 0.9375rem;
    height: 0.9375rem;
    border: 0.125rem solid rgba(255,255,255,0.4);
    border-top-color: var(--white);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
    display: none;
  }
  .contact-submit.loading .spinner { display: inline-block; }
  @keyframes spin { to { transform: rotate(360deg); } }
  .hp-field {
    position: absolute;
    left: -624.9375rem;
    width: 0.0625rem;
    height: 0.0625rem;
    opacity: 0;
  }
  /* 760px is already a breakpoint in this file (the portal bands above), so the Get in
     Touch section switches there too instead of at its old one-off 720px. In both bands the
     Hours and Direct Message options come first and the Send Message card sits under them
     (source order, no reordering), so the options are always above the card. At 760px and
     above the two options sit side by side in the same 34rem column as the card, so the
     clock icon lines up with the card's left edge and the form never stretches to the full
     .rosters-body measure. */
  @media (max-width: 760px) {
    .contact-grid { grid-template-columns: 1fr; gap: 2.125rem; }
    .contact-grid .contact-info {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 0.75rem;
    }
    .contact-grid .contact-block { margin-bottom: 0; }
  }
  /* Both bands meet at exactly 760px, so the selectors in the block below are the same as
     the ones above on purpose: equal specificity + later source order means the row layout
     is what a 760px-wide viewport gets. */
  @media (min-width: 760px) {
    .contact-grid { grid-template-columns: 1fr; gap: 1.875rem; max-width: 34rem; margin: 0 auto; }
    .contact-grid .contact-info {
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 2rem;
      align-items: start;
    }
    .contact-grid .contact-form { width: 100%; margin: 0 auto; }
    .contact-grid .contact-block { margin-bottom: 0; }
  }
  .modal-btn {
    width: 100%;
    background: var(--secondary);
    color: var(--white) !important;
    border: none;
    padding: 0.8125rem;
    border-radius: 0.5rem;
    font-size: 1rem;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.2s;
    margin-top: 0.375rem;
  }
  .modal-btn:hover { background: var(--secondary-dark); }
  .modal-toggle {
    text-align: center;
    margin-top: 1.125rem;
    font-size: 0.875rem;
    color: var(--gray-text);
  }
  .modal-toggle a {
    color: var(--primary);
    font-weight: 700;
    text-decoration: none;
    cursor: pointer;
  }
  .modal-toggle a:hover { text-decoration: underline; }
  .form-msg {
    text-align: center;
    font-size: 0.875rem;
    margin-top: 0.75rem;
    padding: 0;
    opacity: 0;
    transition: opacity 0.2s;
  }
  .form-msg:empty { margin: 0; }
  .form-msg.show { opacity: 1; }
  .form-msg.error { color: #EF4444; }
  .form-msg.success { color: #1E8449; background: #E6F7ED; border-radius: 0.5rem; padding: 0.625rem 0.875rem; }
  #accountForm .form-grid:has(+ .form-submit-wrap), #pwForm .form-grid:has(+ .form-submit-wrap) { margin-bottom: 0; }
  #accountForm .form-grid:has(+ .form-submit-wrap) .form-group, #pwForm .form-grid:has(+ .form-submit-wrap) .form-group { margin-bottom: 0; }
  #accountForm > .form-group:has(+ .form-grid:has(.form-group[hidden])) { margin-bottom: 0; }
  .form-submit-wrap { position: relative; display: block; width: fit-content; padding-top: 31px; }
  .form-submit-wrap .form-msg { position: absolute; top: 7px; left: 50%; transform: translateX(-50%); margin: 0; text-align: center; line-height: 1.0625rem; white-space: nowrap; }
  #accountForm .form-submit-wrap, #pwForm .form-submit-wrap { display: flex; align-items: center; gap: 0.75rem; width: auto; padding-top: 0; }
  #accountForm.role-admin .form-submit-wrap { margin-top: 20px; }
  #pwForm .form-submit-wrap { margin-top: 20px; }
  #pwForm .form-submit-wrap { flex-direction: column; align-items: flex-start; }
  #pwForm .form-submit-wrap button[type="submit"] { order: 1; }
  #pwForm .form-submit-wrap .form-msg { order: 2; }
  #pwForm .form-submit-wrap .form-msg.success { background: none; padding: 0; }
  #accountForm .form-submit-wrap .form-msg, #pwForm .form-submit-wrap .form-msg { position: static; transform: none; text-align: left; white-space: normal; }
  #accountForm .form-submit-wrap .form-msg:empty { display: none; }
  .test-hint {
    text-align: center;
    margin-top: 1rem;
    padding: 0.75rem 1rem;
    background: var(--light-gray);
    border-radius: 0.5rem;
    font-size: 0.8125rem;
    color: var(--gray-text);
    line-height: 1.5;
  }
  .test-hint-label {
    display: block;
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.0625rem;
    color: var(--primary);
    margin-bottom: 0.25rem;
  }
  .test-hint strong { color: var(--dark-gray); }

  /* ---------- Teams Management (admin data entry) ---------- */
  .ws-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    background: var(--ws-ink) !important;
    color: var(--white) !important;
    border: 0.0625rem solid transparent;
    border-radius: 0.3125rem;
    padding: 0.5rem 1rem;
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.2;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s, border-color 0.15s;
  }
  .ws-btn:hover { background: var(--ws-ink-2) !important; }
  .ws-btn:disabled { opacity: 0.55; cursor: default; }
  .ws-btn-danger { background: var(--ws-danger) !important; }
  .ws-btn-danger:hover { background: #B91C1C !important; }
  .ws-btn-green { background: #1A7F37 !important; }
  .ws-btn-green:hover { background: #166C2F !important; }
  .pp-row { display: flex; gap: 0.625rem; align-items: flex-start; padding: 0.625rem 0.8125rem; border-top: 0.0625rem solid #E2E8F0; font-size: 0.8125rem; }
  .pp-row input[type="checkbox"] { margin-top: 0.2rem; flex: 0 0 auto; }
  .pp-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
  .pp-head { font-weight: 700; color: var(--ws-ink); }
  .pp-sub, .pp-rec { color: var(--ws-ink-2); }
  .pp-rec a { color: var(--ws-primary, #2E6FB4); }
  .pp-actions { flex: 0 0 auto; display: flex; gap: 0.375rem; align-items: center; flex-wrap: wrap; justify-content: flex-end; max-width: 14rem; }
  .pp-actions select { max-width: 12rem; }
  .pp-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; table-layout: fixed; }
  .pp-table th { text-align: left; font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.05em; color: #5A6B7C; padding: 0.375rem 0.5rem; border-bottom: 0.0625rem solid #CBD5E1; white-space: nowrap; }
  .pp-table td { padding: 0.5rem; border-top: 0.0625rem solid #E2E8F0; vertical-align: top; overflow-wrap: anywhere; }
  .pp-table th:first-child, .pp-table td:first-child { width: 1.75rem; padding-left: 0.25rem; padding-right: 0; }
  .pp-table td.pp-amt, .pp-table td.pp-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
  .pp-table td.pp-date { width: 4.4rem; }
  .pp-table td.pp-amt { width: 4.2rem; font-weight: 700; }
  .pp-table td.pp-act { width: 6.5rem; }
  .pp-table td.pp-act .ws-btn { padding: 0.25rem 0.5rem; font-size: 0.75rem; margin: 0 0.25rem 0.25rem 0; }
  .pp-table td.pp-act select { max-width: 100%; font-size: 0.75rem; }
  .pp-clamp { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  .pp-card { border-top: 0.0625rem solid #CBD5E1; padding: 0.5rem 0.25rem; font-size: 0.8125rem; }
  .pp-top { display: grid; grid-template-columns: 1fr 1fr; gap: 0.25rem 1rem; align-items: center; }
  .pp-top .pp-status { justify-self: end; }
  .pp-namerow { display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem; }
  .pp-top .pp-amt { justify-self: end; font-weight: 700; font-variant-numeric: tabular-nums; }
  .pp-val { color: #15803D; }
  .pp-linkrow { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
  .pp-card-act .ws-btn { padding: 0.25rem 0.5rem; font-size: 0.75rem; margin-left: 0.25rem; }
  .pp-card-act select { max-width: 100%; font-size: 0.75rem; }
  .pp-note { color: #000; }
  .pp-note-dark, .pp-note-dark b { color: #000; }
  .pp-top .pp-refund { justify-self: end; }
  .pp-refval { color: #BE123C; font-weight: 700; }
  .pp-assignrow { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
  .pp-emailrow { overflow-wrap: anywhere; }
  .pp-applyrow { margin-top: 0.5rem; display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
  .pp-applyrow .pp-apply { margin-left: auto; }
  .pp-applyrow .pp-assign { flex: 1 1 100%; }
  .pp-applyrow.pp-actionrow { background: #FFFBEB; border: 0.0625rem solid #F0D9A8; border-left: 0.25rem solid #D97706; border-radius: 0.5rem; padding: 0.5rem 0.625rem; }
  .pp-applyrow.pp-actionrow .pp-note { flex: 1 1 12rem; min-width: 0; }
  .pp-note.pp-noterow { background: #F1F5F9; border: 0.0625rem solid #CBD5E1; border-left: 0.25rem solid #1E3A5F; border-radius: 0.5rem; padding: 0.5rem 0.625rem; color: #1E3A5F; margin-top: 1rem; }
  .pp-note.pp-noterow b { color: #1E3A5F; }
  .pp-note.pp-noterow.pp-withbtn { display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; }
  .pp-note.pp-noterow.pp-withbtn .pp-notetxt { flex: 1 1 12rem; min-width: 0; }
  .pp-note.pp-noterow.pp-withbtn .pp-apply { margin-left: auto; }
  .pp-note.pp-noterow.pp-spent { background: #FDFCF8; border-color: #E7E0CE; border-left-color: #1E3A5F; }
  .pp-note.pp-noterow.pp-armed { background: #FFFBEB; border-color: #F0D9A8; border-left-color: #D97706; }
  .pp-assignbox { flex: 0 0 auto; }
  .pp-assigned div { line-height: 1.5; }
  .pp-assign .ws-input { flex: 0 0 auto; width: 12rem; max-width: 100%; box-sizing: border-box; }
  .pp-assign { display: inline-flex; gap: 0.375rem; align-items: center; }
  .pp-assignbox { position: relative; display: inline-flex; }
  .pp-suggest { position: absolute; top: 100%; left: 0; right: 0; z-index: 30; background: #fff; border: 0.0625rem solid #CBD5E1; border-radius: 0.375rem; box-shadow: 0 0.25rem 0.75rem rgba(15, 42, 67, 0.18); }
  .pp-suggest-item { padding: 0.375rem 0.625rem; font-size: 0.8125rem; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .pp-suggest-item:hover { background: #EAF1F8; }
  .ws-msg.pp-loading { animation: pp-pulse 1.1s ease-in-out infinite; }
  @keyframes pp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
  .workspace-modal .ws-btn { width: 100%; margin-top: 0.375rem; }
  .workspace-modal .modal-btn-row { display: flex; gap: 0.5rem; margin-top: 0.75rem; }
  .workspace-modal .modal-btn-row .ws-btn { width: auto; flex: 1 1 0; margin-top: 0; }
  .ws-btn-ghost {
    background: #E9F1F9 !important;
    color: var(--ws-ink-2) !important;
    border-color: #C5D9EC;
  }
  .ws-btn-ghost:hover { background: #DCE9F6 !important; }
  #teamDeleteModal .modal-head, #bugDeleteModal .modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.625rem;
  }
  #teamDeleteModal h2, #bugDeleteModal h2 {
    margin-bottom: 0;
    padding-right: 0;
  }
  #teamDeleteModal .modal-close, #bugDeleteModal .modal-close {
    position: static;
    width: 2rem;
    height: 2rem;
    font-size: 1.25rem;
  }
  .teams-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: nowrap;
    margin-bottom: 0.875rem;
  }
  .teams-toolbar-left {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: nowrap;
    flex: 1 1 auto;
    min-width: 0;
  }
  .team-actions { display: flex; gap: 0.5rem; flex-shrink: 0; }
  #fetchLedgerBtn { flex: 0 0 auto; width: auto; max-width: 7.5rem; }
  /* Manage Ledgers: stick the toolbar under the site header so its buttons stay reachable while scrolling */
  #ledgerToolbar {
    position: sticky;
    top: var(--header-h);
    z-index: 40;
    background: var(--white);
    padding: 0.75rem 0 0.875rem;
    margin-bottom: 0;
    border-bottom: 0.0625rem solid rgba(0,32,78,0.1);
  }
  #ledgerList .roster-editor {
    margin-left: 0;
    margin-right: 0;
  }
  @media (max-width: 980px) {
    .teams-toolbar { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .portal-panel[data-panel="teams"] .teams-toolbar { grid-template-columns: repeat(3, minmax(0, 1fr)); align-items: stretch; }
    .teams-toolbar-left { display: contents; }
    .team-actions { display: contents; }
    .team-actions[hidden] { display: none; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar { display: flex; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left { display: flex; }
    .portal-panel[data-panel="ledgers"] .team-actions { display: flex; }
    
    .portal-panel[data-panel="bugtracker"] .teams-toolbar { display: flex; }
    .portal-panel[data-panel="bugtracker"] .teams-toolbar-left { display: flex; }
    .portal-panel[data-panel="bugtracker"] #bugSearchInput { flex: 1 1 auto; min-width: 0; }
    
    #teamSearch, #playerSearch, #accountSearch { grid-column: 1 / -1; order: 4; }
    .portal-panel[data-panel="teams"] .teams-toolbar .ws-btn { width: 100%; max-width: none; justify-self: stretch; }
  }
  /* Ledgers toolbar 680–760px gap (Oct 16 2026, Jamie): five controls can't share one
     row here — the search drops to its own line, the buttons keep the first. */
  @media (max-width: 760px) and (min-width: 681px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left { flex-wrap: wrap; }
    .portal-panel[data-panel="ledgers"] #ledgerSearch { flex: 1 1 100%; order: 5; min-width: 0; }
  }
  @media (max-width: 450px) {
    .plus-hide-sm { display: none; }
  }
  @media (max-width: 760px) {
    .portal-panel[data-panel="teams"] h2,
    .portal-panel[data-panel="players"] h2,
    .portal-panel[data-panel="accounts"] h2,
    .portal-panel[data-panel="teams"] .portal-sub,
    .portal-panel[data-panel="players"] .portal-sub,
    .portal-panel[data-panel="accounts"] .portal-sub {
      text-align: center;
    }
    .portal-panel[data-panel="teams"] .portal-sub,
    .portal-panel[data-panel="players"] .portal-sub,
    .portal-panel[data-panel="accounts"] .portal-sub {
      margin-left: auto;
      margin-right: auto;
    }
    .portal-panel[data-panel="teams"] .teams-toolbar,
    .portal-panel[data-panel="players"] .teams-toolbar,
    .portal-panel[data-panel="accounts"] .teams-toolbar {
      justify-content: center;
    }
    
    .portal-panel[data-panel="bugtracker"] .teams-toolbar { display: grid; grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto); align-items: center; gap: 0.5rem; }
    .portal-panel[data-panel="bugtracker"] .teams-toolbar-left { display: contents; }
    .portal-panel[data-panel="bugtracker"] #bugNewBtn { grid-column: 1; grid-row: 1; }
    .portal-panel[data-panel="bugtracker"] #bugSearchInput { grid-column: 2; grid-row: 1; }
    .portal-panel[data-panel="bugtracker"] #bugMyIssuesBtn { grid-column: 3; grid-row: 1; }
    @media (max-width: 525px) {
      .portal-panel[data-panel="bugtracker"] .teams-toolbar { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: auto auto; }
      .portal-panel[data-panel="bugtracker"] #bugNewBtn { grid-column: 1; grid-row: 1; width: 100%; max-width: none; justify-self: stretch; }
      .portal-panel[data-panel="bugtracker"] #bugSearchInput { grid-column: 1 / -1; grid-row: 2; }
      .portal-panel[data-panel="bugtracker"] #bugMyIssuesBtn { grid-column: 2; grid-row: 1; width: 100%; max-width: none; justify-self: stretch; }
    }
    
  }
  .teams-toolbar .ws-btn { white-space: normal; flex-shrink: 0; }
  /* Manage Accounts: once results are fetched, lay all 5 controls out in one left-aligned row */
  #accountToolbar.stacked { justify-content: flex-start; flex-wrap: nowrap; }
  #accountToolbar.stacked .teams-toolbar-left { flex: 1 1 auto; flex-wrap: nowrap; }

  /* 1000px and below, once results loaded: New/Edit/Delete on top row, Search + Fetch on bottom (accounts & players) */
  @media (max-width: 1000px) {
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked,
    .portal-panel[data-panel="players"] #playerToolbar.stacked {
      display: grid;
      grid-template-columns: repeat(3, minmax(0, 1fr));
      align-items: stretch;
      gap: 0.5rem;
    }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked .teams-toolbar-left,
    .portal-panel[data-panel="players"] #playerToolbar.stacked .teams-toolbar-left { display: contents; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked .team-actions,
    .portal-panel[data-panel="players"] #playerToolbar.stacked .team-actions { display: contents; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked .team-actions[hidden],
    .portal-panel[data-panel="players"] #playerToolbar.stacked .team-actions[hidden] { display: none; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked #addAccountBtn,
    .portal-panel[data-panel="players"] #playerToolbar.stacked #addPlayerBtn { grid-column: 1; grid-row: 1; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked #editAccountBtn,
    .portal-panel[data-panel="players"] #playerToolbar.stacked #editPlayerBtn { grid-column: 2; grid-row: 1; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked #deleteAccountBtn,
    .portal-panel[data-panel="players"] #playerToolbar.stacked #deletePlayerBtn { grid-column: 3; grid-row: 1; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked #accountSearch,
    .portal-panel[data-panel="players"] #playerToolbar.stacked #playerSearch { grid-column: 1 / 3; grid-row: 2; }
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked #fetchAccountsBtn,
    .portal-panel[data-panel="players"] #playerToolbar.stacked #fetchPlayersBtn { grid-column: 3 / 4; grid-row: 2; }
  }
  /* Pre-fetch (no results loaded yet) on accounts/players: keep New + Search + Fetch in
     one row with the search flexing in the middle between the two buttons, all the way down
     to the 525px stack (JAMIE, Sep 3 — the search no longer drops to its own row at 640px). */
  @media (max-width: 980px) {
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked),
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) {
      display: grid;
      grid-template-columns: auto 1fr auto;
      align-items: center;
      gap: 0.75rem;
    }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) .teams-toolbar-left,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) .teams-toolbar-left {
      display: contents;
    }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #addAccountBtn,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #addPlayerBtn { grid-column: 1; grid-row: 1; }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #accountSearch,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #playerSearch { grid-column: 2; grid-row: 1; }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #fetchAccountsBtn,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #fetchPlayersBtn { grid-column: 3; grid-row: 1; }
  }
  /* Pre-fetch on accounts/players at 525px and below: stack New on top of Fetch
     (both full-width), Search on its own full-width row below (JAMIE, Sep 3). */
  @media (max-width: 525px) {
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked),
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) {
      grid-template-columns: 1fr;
    }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #addAccountBtn,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #addPlayerBtn { grid-column: 1; grid-row: 1; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #fetchAccountsBtn,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #fetchPlayersBtn { grid-column: 1; grid-row: 2; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="accounts"] .teams-toolbar:not(.stacked) #accountSearch,
    .portal-panel[data-panel="players"] .teams-toolbar:not(.stacked) #playerSearch { grid-column: 1; grid-row: 3; width: 100%; box-sizing: border-box; }
  }
  /* Manage Ledgers toolbar: Peak Report + Team Ledgers buttons, the search and the
     Fetch Ledgers button. Wide: all four on ONE row (search flexing in the middle,
     never crushing below its basis). When the PANEL is too narrow for the search at
     its minimum width the three buttons share one row with the search on a
     full-width row below; on very narrow panels Fetch drops under the two report
     buttons. Container-based on the panel itself (the panel is already an
     inline-size container), so wide desktops keep the single row and narrow panels
     stack. */
  #ledgerSearch { flex: 1 1 10rem; min-width: 10rem; }
  @container (max-width: 560px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 0.5rem;
      flex: 1 1 100%;
      width: 100%;
    }
    .portal-panel[data-panel="ledgers"] #peakReportBtn { grid-column: 1; grid-row: 1; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="ledgers"] #pendingPayBtn { grid-column: 2; grid-row: 1; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="ledgers"] #teamLedgerBtn { grid-column: 1; grid-row: 2; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="ledgers"] #fetchLedgerBtn { grid-column: 2; grid-row: 2; width: 100%; max-width: none; justify-self: stretch; }
    .portal-panel[data-panel="ledgers"] #ledgerSearch { grid-column: 1 / -1; grid-row: 3; width: 100%; box-sizing: border-box; }
    /* Pre-fetch / pre-selection only (both report buttons hidden): the two buttons
       share the top row with the search full-width beneath them. */
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) #pendingPayBtn {
      grid-column: 1;
      grid-row: 1;
      width: 100%;
      max-width: none;
    }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) #fetchLedgerBtn {
      grid-column: 2;
      grid-row: 1;
      width: 100%;
      max-width: none;
    }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) #ledgerSearch {
      grid-column: 1 / -1;
      grid-row: 2;
    }
  }
  /* Post-fetch at mid widths (Jamie, Oct 21 2026): 561–760px panels get the same
     2x2 + search-under grid the phones use — four squeezed buttons in one row reads
     terribly here. Pre-fetch keeps its one row above. */
  @container (min-width: 561px) and (max-width: 760px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) {
      display: grid;
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 0.5rem;
      flex: 1 1 100%;
      width: 100%;
    }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #peakReportBtn { grid-column: 1; grid-row: 1; width: 100%; max-width: none; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #pendingPayBtn { grid-column: 2; grid-row: 1; width: 100%; max-width: none; margin-right: 0; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #teamLedgerBtn { grid-column: 1; grid-row: 2; width: 100%; max-width: none; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #fetchLedgerBtn { grid-column: 2; grid-row: 2; width: 100%; max-width: none; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #ledgerSearch { grid-column: 1 / -1; grid-row: 3; width: 100%; box-sizing: border-box; }
  }
  /* Post-fetch at desktop (Jamie, Oct 21 2026): Peak | Pending | Team | Fetch share one
     row with the search full-width beneath — DOM order is Peak, Team, Pending, so the
     middle two are explicitly ordered. Pre-fetch keeps its one row above. */
  @media (min-width: 1200px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) { flex-wrap: wrap; justify-content: flex-start; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #peakReportBtn { order: 1; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #pendingPayBtn { order: 2; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #teamLedgerBtn { order: 3; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #fetchLedgerBtn { order: 4; }
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left:not(:has(#peakReportBtn[hidden])) #ledgerSearch { flex: 1 1 100%; order: 5; min-width: 0; }
  }
  @media (max-width: 560px) {
    .portal-panel[data-panel="ledgers"] #pendingPayPanel { margin-left: 0; margin-right: 0; }
  }
  /* Very narrow panels: the two report buttons share the top row and Fetch spans
     the width beneath them, so no label ever wraps into an unreadable stack. */
  @container (max-width: 430px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar-left {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }
    .portal-panel[data-panel="ledgers"] #peakReportBtn { grid-column: 1; grid-row: 1; }
    .portal-panel[data-panel="ledgers"] #pendingPayBtn { grid-column: 2; grid-row: 1; }
    .portal-panel[data-panel="ledgers"] #teamLedgerBtn { grid-column: 1; grid-row: 2; }
    .portal-panel[data-panel="ledgers"] #fetchLedgerBtn { grid-column: 2; grid-row: 2; }
    .portal-panel[data-panel="ledgers"] #ledgerSearch { grid-column: 1 / -1; grid-row: 3; }
  }
  /* The generic narrow-toolbar squeeze (max-width 5.5rem) would crush these labels
     once they sit in grid cells — let the ledgers buttons fill their cells instead. */
  @container (max-width: 400px) {
    .portal-panel[data-panel="ledgers"] .teams-toolbar .ws-btn { max-width: none; justify-self: stretch; }
  }
  .portal-panel[data-panel="ledgers"] .team-actions { display: none; }
  .portal-panel[data-panel="ledgers"] .teams-toolbar-left { justify-content: flex-end; }
  /* Peak Report is the primary action of this toolbar (Jamie, Oct 21 2026) — same
     primary blue as Pay Now / Make a Payment. */
  .portal-panel[data-panel="ledgers"] #peakReportBtn { background: var(--primary) !important; }
  .portal-panel[data-panel="ledgers"] #peakReportBtn:hover { background: var(--primary-dark) !important; }
  /* Pre-fetch state (Jamie, Oct 21 2026): the Pending Payments button pins left while
     the search + Fetch stay right. */
  .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) #pendingPayBtn { margin-right: auto; }
  /* Same state (Jamie, Oct 21 2026): Pending | Search | Fetch share one row — the
     search shrinks instead of wrapping (grid layouts below override display anyway). */
  .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) { flex-wrap: nowrap; }
  /* Same state: undo the 681–760px gap rule's search-last ordering — DOM order is
     already Pending | Search | Fetch. */
  .portal-panel[data-panel="ledgers"] .teams-toolbar-left:has(#peakReportBtn[hidden]) #ledgerSearch { order: 0; }
  @container (max-width: 400px) {
    .teams-toolbar .ws-btn {
      width: 100%;
      max-width: 5.5rem;
      justify-self: center;
    }
  }
  /* Manage Teams: on very narrow containers drop the 3-button row to 2 rows (New Team full-width, Edit + Delete split) so labels never wrap */
  @container (max-width: 430px) {
    .portal-panel[data-panel="teams"] .teams-toolbar {
      grid-template-columns: 1fr 1fr;
    }
    .portal-panel[data-panel="teams"] .teams-toolbar #addTeamBtn {
      grid-column: 1 / -1;
    }
  }
  /* Stacked accounts/players: let the action-row buttons fill their grid cells so they span the row and reach the right edge of the table below */
  @media (max-width: 1000px) {
    .portal-panel[data-panel="accounts"] #accountToolbar.stacked .ws-btn,
    .portal-panel[data-panel="players"] #playerToolbar.stacked .ws-btn {
      width: 100%;
      max-width: none;
      justify-self: stretch;
    }
  }
  .ws-input {
    padding: 0.4375rem 0.75rem;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.3125rem;
    background: var(--white);
    font-family: inherit;
    font-size: 0.8125rem;
    color: var(--ws-ink-2);
    flex: 1 1 10rem;
    min-width: 0;
    transition: border-color 0.15s;
  }
  .ws-input::placeholder { color: var(--ws-muted); }
  .ws-input:focus { outline: none; border-color: var(--ws-ink); box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.12); }
  .ws-invalid { border-color: #EF4444 !important; }
  .workspace-modal select,
  .workspace-modal .form-group select,
  select.ws-input {
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237A8AA0' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M6 9l6 6 6-6'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.625rem center;
    background-size: 0.75rem 0.75rem;
    padding-right: 1.875rem;
    cursor: pointer;
  }
  .workspace-modal select,
  .workspace-modal .form-group select {
    width: 100%;
    padding: 0.4375rem 1.875rem 0.4375rem 0.75rem;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.3125rem;
    background-color: var(--white);
    font-size: 0.8125rem;
    color: var(--ws-ink-2);
  }
  .workspace-modal select:hover,
  .workspace-modal .form-group select:hover { border-color: #B4BDC8; }
  .workspace-modal select:focus,
  .workspace-modal .form-group select:focus {
    outline: none;
    border-color: var(--ws-ink);
    box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.12);
  }
  .ws-msg {
    display: block;
    width: fit-content;
    font-size: 0.8125rem;
    font-weight: 700;
    color: #EF4444;
    background: rgba(239, 68, 68, 0.12);
    box-shadow: inset 0 0 0 0.0625rem rgba(239, 68, 68, 0.25);
    border-radius: 0.1875rem;
    padding: 0.1875rem 0.5rem;
    margin: 0 auto 0.75rem;
    text-align: center;
  }
  .ws-msg.success {
    color: #1A7F37;
    background: rgba(26, 127, 55, 0.12);
    box-shadow: inset 0 0 0 0.0625rem rgba(26, 127, 55, 0.25);
  }
  .ws-msg.info {
    color: #1D4F9C;
    background: rgba(102, 153, 204, 0.14);
    box-shadow: inset 0 0 0 0.0625rem rgba(102, 153, 204, 0.35);
  }
  .team-row.selected {
    background: #E9F1F9 !important;
    box-shadow: inset 0 0 0 0.125rem var(--primary) !important;
  }
  .team-row.selected .tc-team,
  .team-row.selected .tc-age,
  .team-row.selected .tc-div,
  .team-row.selected .tc-coach { color: #2F3640; }
  .teams-table {
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    overflow: hidden;
    container-type: inline-size;
  }
  .teams-table-head,
  .team-row {
    display: grid;
    grid-template-columns: 0.6fr 0.9fr 0.8fr 1.7fr 4.5rem;
    gap: 0.875rem;
    align-items: center;
    padding: 0.625rem 1rem;
  }
  .teams-table-head {
    background: #B9C0CA;
    border-bottom: 0.0625rem solid #9CA5B1;
  }
  .teams-table-head span {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #2F3640;
  }
  .teams-table-head .tc-coach { padding-left: 1.5rem; }
  .team-row {
    width: 100%;
    background: var(--white);
    border: none;
    border-bottom: 0.0625rem solid #DCE1E8;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: background 0.15s;
  }
  .team-row:last-child { border-bottom: none; }
  .team-row:hover { background: #F4F6F9; }
  .tc-team { font-size: 0.875rem; font-weight: 800; color: var(--secondary); }
  .tc-age, .tc-div { font-size: 0.8125rem; color: #3F4A5A; }
  .tc-coach { display: flex; align-items: center; gap: 0.375rem; font-size: 0.8125rem; color: #3F4A5A; min-width: 0; }
  .tc-coach > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tc-coach > .tc-coach-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.35; white-space: normal; overflow: visible; }
  .tc-coach-text > .tc-coach-name { display: block; min-width: 0; font-size: 0.8125rem; font-weight: 400; color: #3F4A5A; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .tc-asst-wrap { position: relative; display: inline-block; align-self: flex-start; }
  .tc-asst-link.tc-asst-link { padding: 0; background: none !important; border: none; font-family: inherit; font-size: 0.6875rem; font-weight: 700; line-height: inherit; color: #00204E; cursor: pointer; white-space: nowrap; }
  .tc-asst-link:hover { text-decoration: underline; }
  .tc-asst-tip { display: none; position: absolute; bottom: calc(100% + 0.3125rem); left: 0; z-index: 60; width: max-content; max-width: 12rem; padding: 0.375rem 0.5625rem; font-family: inherit; font-size: 0.75rem; font-weight: 400; line-height: 1.45; color: #fff; background: #2F3640; border-radius: 0.375rem; box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.25); white-space: pre-line; }
  .tc-asst-wrap:hover .tc-asst-tip, .tc-asst-wrap:focus-within .tc-asst-tip, .tc-asst-tip.show { display: block; }
  .team-coach-edit-btn { flex-shrink: 0; }
  .tc-coach b { color: var(--dark-gray); font-weight: 700; }
  .tc-roster { display: flex; justify-content: center; text-align: center; }
  .team-roster-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    min-height: 1.75rem;
    padding: 0.25rem 0.75rem;
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--white) !important;
    background: var(--ws-ink) !important;
    border: 0.0625rem solid transparent;
    border-radius: 0.3125rem;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s;
  }
  .team-roster-btn:hover { background: var(--ws-ink-2) !important; }
  .team-roster-btn { width: 100%; }
  .team-roster-btn svg { width: 0.875rem; height: 0.875rem; flex-shrink: 0; display: none; }
  .team-coach-edit-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: transparent !important;
    border: none;
    cursor: pointer;
  }
  .team-coach-edit-btn:hover svg { transform: scale(1.15); }
  .team-coach-edit-btn svg { width: 1.125rem; height: 1.125rem; display: block; transition: transform 0.15s; }
  @container (max-width: 480px) {
    .teams-table-head, .team-row {
      grid-template-columns: 0.6fr 0.9fr 0.8fr 1.7fr 2rem;
      gap: 0.5rem;
      padding: 0.5rem 0.625rem;
    }
    .team-roster-btn { padding: 0.25rem; }
    .team-roster-btn svg { display: block; width: 1.375rem; height: 1.375rem; }
    .team-roster-btn .trb-label { display: none; }
    .team-roster-btn svg path:not(:first-child),
    .team-roster-btn svg rect { display: none; }
    .team-roster-btn svg path { stroke: #fff; stroke-width: 1.5; }
  }
  @container (max-width: 20.5rem) {
    .teams-table-head { display: none; }
    .team-row {
      grid-template-columns: auto auto auto 1fr;
      grid-template-areas:
        "age name type roster"
        "coach coach coach roster";
      gap: 0.5rem 0.375rem;
      padding: 0.75rem;
    }
    .team-row .tc-age {
      grid-area: age;
      font-size: 0.75rem;
      font-weight: 800;
      color: var(--ws-muted);
      align-self: center;
    }
    .team-row .tc-team { grid-area: name; font-size: 0.9375rem; align-self: center; }
    .team-row .tc-div {
      grid-area: type;
      font-size: 0;
      align-self: center;
    }
    .team-row .tc-div:not([data-letter=""])::after {
      content: "(" attr(data-letter) ")";
      font-size: 0.8125rem;
      font-weight: 800;
      color: var(--ws-muted);
      line-height: 1;
    }
    .team-row .tc-coach { grid-area: coach; }
    .team-row .tc-roster { grid-area: roster; grid-row: 1 / -1; align-self: center; justify-content: flex-end; }
    .team-roster-btn { height: 2.25rem; width: 2.25rem; }
  }
  .teams-empty {
    border: 0.0625rem dashed var(--light-gray);
    border-radius: 0.5rem;
    padding: 2rem 1.5rem;
    text-align: center;
    color: var(--gray-text);
    background: #F7FAFD;
  }
  .teams-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 0.625rem 1rem;
    border-top: 0.0625rem solid #DCE1E8;
    background: #FBFCFE;
  }
  .teams-pager-left { display: flex; align-items: center; gap: 0.5rem; }
  .teams-pager-right { display: flex; align-items: center; gap: 0.375rem; }
  .teams-pager-label { font-size: 0.75rem; color: var(--ws-muted); font-weight: 700; }
  .teams-pager-select { min-width: 0; width: 4rem; flex: 0 0 auto; padding: 0.3125rem 0.5rem; font-size: 0.75rem; }
  .teams-pager-info { font-size: 0.75rem; color: var(--ws-muted); }
  .teams-pager-nav { display: flex; gap: 0.375rem; }
  .teams-pager-btn { padding: 0.3125rem 0.625rem; font-size: 0.75rem; }
  .teams-pager-btn:disabled { opacity: 0.45; cursor: default; }
  @media (max-width: 400px) {
    .teams-pager-left { flex: 1 1 100%; }
    .teams-pager-right { flex: 1 1 100%; flex-wrap: wrap; justify-content: center; }
    .teams-pager-right .teams-pager-label { flex-basis: 100%; text-align: center; }
  }
  .players-table-head,
  .player-row {
    display: grid;
    grid-template-columns: 1.5fr 0.55fr 3rem 0.7fr 0.7fr 0.7fr;
    grid-template-areas: "name age team ht wt bt";
    gap: 0.875rem;
    align-items: center;
    padding: 0.625rem 1rem;
  }
  .pc-line { display: contents; }
  .player-row .pc-name { grid-area: name; }
  .player-row .pc-age { grid-area: age; }
  .player-row .pc-team { grid-area: team; }
  .player-row .pc-ht { grid-area: ht; }
  .player-row .pc-wt { grid-area: wt; }
  .player-row .pc-bt { grid-area: bt; }
  .players-table-head {
    background: #B9C0CA;
    border-bottom: 0.0625rem solid #9CA5B1;
  }
  .players-table-head span {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #2F3640;
  }
  .player-row {
    width: 100%;
    background: var(--white);
    border: none;
    border-bottom: 0.0625rem solid #DCE1E8;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: 0.8125rem;
    transition: background 0.15s;
  }
  .player-row:last-child { border-bottom: none; }
  .player-row:hover { background: #F4F6F9; }
  .player-row.selected {
    background: #E9F1F9 !important;
    box-shadow: inset 0 0 0 0.125rem var(--primary) !important;
  }
  .player-row .pc-name { font-weight: 700; color: var(--secondary); }
  .player-row .pc-age,
  .player-row .pc-ht,
  .player-row .pc-wt,
  .player-row .pc-bt { color: var(--ws-ink-2); }
  .players-table-head .pc-ht,
  .players-table-head .pc-wt,
  .players-table-head .pc-bt,
  .player-row .pc-ht,
  .player-row .pc-wt,
  .player-row .pc-bt { text-align: center; }
  .player-row .pc-team {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
  }
  .player-row .pc-team-tag {
    display: inline-block;
    padding: 0.0625rem 0.4375rem;
    border-radius: 0.25rem;
    font-size: 0.6875rem;
    font-weight: 700;
    white-space: nowrap;
  }
  @container (max-width: 480px) {
    .players-table-head, .player-row {
      grid-template-columns: 1.4fr 0.55fr 3rem 0.6fr 0.6fr 0.6fr;
      gap: 0.5rem;
      padding: 0.5rem 0.625rem;
    }
  }
  @container (max-width: 380px) {
    .players-table-head { display: none; }
    .player-row {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
      gap: 0.25rem;
      padding: 0.75rem;
    }
    .player-row .pc-line {
      display: flex;
      align-items: center;
      column-gap: 0.375rem;
      max-width: 100%;
      min-width: 0;
    }
    .player-row .pc-name {
      font-size: 0.9375rem;
      min-width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .player-row .pc-bt {
      font-size: 0.75rem;
      font-weight: 600;
      color: var(--ws-muted);
    }
    .player-row .pc-bt::before { content: "("; }
    .player-row .pc-bt::after { content: ")"; }
    .player-row .pc-age,
    .player-row .pc-ht,
    .player-row .pc-wt {
      font-size: 0.75rem;
      font-weight: 600;
      color: var(--ws-muted);
    }
    .player-row .pc-ht::before {
      content: "\00b7";
      margin: 0 0.9375rem 0 0.375rem;
      color: #77828E;
    }
    .player-row .pc-wt::before {
      content: "/";
      margin: 0 0.5625rem 0 0.1875rem;
      color: #77828E;
    }
    .player-row .pc-wt::after { content: "lbs"; }
    .player-row .pc-team {
      display: inline-flex;
      align-items: center;
      min-width: 3rem;
    }
  }
  .accounts-table-head,
  .account-row {
    display: grid;
    grid-template-columns: minmax(0, 1.7fr) minmax(0, 1.3fr) minmax(0, 0.5fr);
    gap: 0.875rem;
    align-items: center;
    padding: 0.625rem 1rem;
  }
  .accounts-table-head {
    background: #B9C0CA;
    border-bottom: 0.0625rem solid #9CA5B1;
  }
  .accounts-table-head span {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #2F3640;
  }
  .accounts-table-head span:last-child {
    justify-self: center;
    text-align: center;
  }
  .account-row {
    width: 100%;
    background: var(--white);
    border: none;
    border-bottom: 0.0625rem solid #DCE1E8;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    font-size: 0.8125rem;
    transition: background 0.15s;
  }
  .account-row:last-child { border-bottom: none; }
  .account-row:hover { background: #F4F6F9; }
  .account-row.selected {
    background: #E9F1F9 !important;
    box-shadow: inset 0 0 0 0.125rem var(--primary) !important;
  }
  .account-row .ac-account,
  .account-row .ac-links {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
  }
  .account-row .ac-name {
    font-weight: 700;
    color: var(--secondary);
  }
  .account-row .ac-lp {
    color: var(--ws-ink-2);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.125rem;
    min-width: 0;
    --ac-lp-pencil-w: 0.8125rem;
  }
  .account-row .ac-lp .ac-lp-line {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    max-width: 100%;
    min-width: 0;
  }
  .account-row .ac-lp .ac-lp-line .ac-pencil { margin-right: 0; }
  .account-row .ac-lp > .ac-lp-name,
  .account-row .ac-lp > .ac-lp-more {
    padding-left: calc(var(--ac-lp-pencil-w) + 0.3rem);
  }
  .account-row .ac-lp .ac-lp-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .account-row .ac-lp .ac-lp-more {
    font-size: 0.6875rem;
    font-weight: 700;
    color: var(--ws-muted);
  }
  .account-row .ac-role {
    display: inline-block;
    justify-self: center;
    padding: 0.0625rem 0.375rem;
    border-radius: 0.1875rem;
    font-size: 0.625rem;
    font-weight: 800;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: #241773;
    background: rgba(36, 23, 115, 0.12);
    box-shadow: inset 0 0 0 0.0625rem rgba(36, 23, 115, 0.25);
  }
  .account-row.role-Admin .ac-role { color: #B91C1C; background: rgba(185, 28, 28, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(185, 28, 28, 0.25); }
  .account-row.role-Coach .ac-role { color: #004C54; background: rgba(0, 76, 84, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(0, 76, 84, 0.25); }
  .account-row.role-Player .ac-role { color: #2E6FB4; background: rgba(46, 111, 180, 0.15); box-shadow: inset 0 0 0 0.0625rem rgba(46, 111, 180, 0.35); }
  .account-row .ac-role.is-coach { color: #004C54; background: rgba(0, 76, 84, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(0, 76, 84, 0.25); }
  .account-row .ac-lp .ac-pencil,
  .account-row .ac-lk .ac-pencil {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    margin-right: 0.3rem;
    vertical-align: -0.125em;
    padding: 0;
    border: 0;
    background: none !important;
    color: inherit;
    cursor: pointer;
    line-height: 0;
  }
  .account-row .ac-lp .ac-pencil svg,
  .account-row .ac-lk .ac-pencil svg {
    width: 0.8125rem;
    height: 0.8125rem;
    display: block;
  }
  .account-row .ac-lp .ac-pencil:hover svg,
  .account-row .ac-lk .ac-pencil:hover svg { transform: scale(1.12); }
  .account-row .ac-nolink {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ws-danger);
  }
  .account-row .ac-mail,
  .account-row .ac-lk {
    font-size: 0.75rem;
    color: var(--ws-muted);
  }
  .account-row .ac-mail,
  .account-row .ac-name,
  .account-row .ac-lp,
  .account-row .ac-lk {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .account-row .ac-link-btn {
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    font-family: inherit;
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--white) !important;
    background: var(--ws-ink) !important;
    border: 0.0625rem solid transparent;
    border-radius: 0.3125rem;
    padding: 0.25rem 0.625rem;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.15s;
  }
  .account-row .ac-link-btn:hover { background: var(--ws-ink-2) !important; }
  .account-row .ac-na {
    font-size: 0.75rem;
    color: var(--ws-muted);
    font-style: italic;
  }
  .account-editor .ws-input:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background: #F2F5F8;
  }
  .account-editor.ac-link-mode .form-grid,
  .account-editor.ac-link-mode .form-group { display: none; }
  .account-editor.ac-link-mode #acPlayerWrap:not([hidden]) { display: block; }
  .cb { position: relative; }
  .cb .cb-input { width: 100%; padding-right: 2.25rem; }
  .cb-chips { display: flex; flex-wrap: wrap; gap: 0.25rem; margin-bottom: 0.375rem; }
  .cb-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.125rem 0.375rem;
    font-size: 0.6875rem;
    font-weight: 700;
    color: #fff;
    background: var(--ws-ink);
    border-radius: 0.1875rem;
    max-width: 100%;
  }
  .cb-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .cb-chip-x {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.3);
    color: #fff;
    font-size: 0.75rem;
    line-height: 1;
    cursor: pointer;
  }
  .cb-chip-x:hover { background: rgba(255, 255, 255, 0.5); }
  .cb-opt.cb-on { font-weight: 800; }
  .cb-clear {
    position: absolute;
    top: 50%;
    right: 0.375rem;
    transform: translateY(-50%);
    display: none;
    align-items: center;
    justify-content: center;
    width: 1.25rem;
    height: 1.25rem;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none !important;
    color: var(--ws-muted);
    font-family: inherit;
    font-size: 0.6875rem;
    line-height: 1;
    cursor: pointer;
  }
  .cb-clear:hover { color: var(--ws-ink-2); background: #E3E8EE !important; }
  .cb-clear:not([hidden]) { display: inline-flex; }
  .cb-list {
    position: absolute;
    top: calc(100% + 0.1875rem);
    left: 0;
    right: 0;
    z-index: 60;
    max-height: 15rem;
    overflow-y: auto;
    background: var(--white);
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.375rem;
    box-shadow: 0 0.5rem 1.25rem rgba(0,32,78,0.12);
    padding: 0.25rem;
    display: none;
  }
  .cb-list:not([hidden]) { display: block; }
  .cb-opt {
    display: block;
    width: 100%;
    text-align: left;
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--ws-ink-2) !important;
    background: none !important;
    border: 0;
    border-radius: 0.3125rem;
    padding: 0.4375rem 0.625rem;
    cursor: pointer;
  }
  .cb-opt.hl { background: #EAF1F9 !important; }
  .cb-opt:disabled {
    color: var(--ws-muted) !important;
    font-weight: 500;
    cursor: default;
    opacity: 0.7;
  }
  .cb-opt:disabled.hl { background: none !important; }
  .pw-row { display: flex; gap: 0.5rem; align-items: center; }
  .pw-row .ws-input { flex: 1 1 auto; min-width: 0; }
  .pw-row .ws-btn { flex: 0 0 auto; margin-top: 0; }
  @media (max-width: 720px) {
    .accounts-table-head, .account-row {
      grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.2fr) minmax(0, 0.5fr);
      gap: 0.5rem;
      padding: 0.5rem 0.625rem;
    }
  }
  @media (max-width: 580px) {
    .accounts-table-head { display: none; }
    .account-row {
      grid-template-columns: minmax(0, 1fr) auto;
      grid-template-areas:
        "account role"
        "links role";
      gap: 0.375rem 0.75rem;
      padding: 0.75rem;
    }
    .account-row .ac-account {
      grid-area: account;
      font-size: 0.9375rem;
    }
    .account-row .ac-links {
      grid-area: links;
      font-size: 0.8125rem;
    }
    .account-row .ac-role {
      grid-area: role;
      justify-self: end;
      align-self: center;
    }
    .account-row .ac-lp::before { content: "Player: "; font-weight: 700; color: var(--ws-ink-2); }
    .account-row .ac-lk::before { content: "Parent: "; font-weight: 700; color: var(--ws-ink-2); }
    .account-row .ac-lp > .ac-lp-name,
    .account-row .ac-lp > .ac-lp-more { padding-left: 0; }
    .account-row .ac-links-na { display: none; }
    .account-row .ac-lp .ac-pencil,
    .account-row .ac-lk .ac-pencil { display: none; }
  }
  .workspace-modal .form-group input.ws-input {
    width: 100%;
    padding: 0.4375rem 0.75rem;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.3125rem;
    background-color: var(--white);
    font-size: 0.8125rem;
    color: var(--ws-ink-2);
  }
  .workspace-modal .form-group input.ws-input:focus {
    outline: none;
    border-color: var(--ws-ink);
    box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.12);
  }
  .roster-list {
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    margin-bottom: 0.75rem;
  }
  #statsPreviewEditor .roster-list {
    max-height: none;
    overflow-y: visible;
  }
  .roster-head {
    display: grid;
    grid-template-columns: 3.5rem 1fr 6rem auto;
    gap: 0.625rem;
    align-items: center;
    padding: 0.375rem 0.75rem;
    border-bottom: 0.0625rem solid #E3E7ED;
    font-size: 0.6875rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--ws-muted);
  }
  .roster-head span:first-child { text-align: center; }
  .roster-head span:last-child {
    visibility: hidden;
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.6875rem;
    font-weight: 700;
    padding: 0.3125rem 0.5rem;
    border: 0.0625rem solid transparent;
    border-radius: 0.3125rem;
    white-space: nowrap;
  }
  .roster-row {
    display: grid;
    grid-template-columns: 3.5rem 1fr 6rem auto;
    gap: 0.625rem;
    align-items: center;
    padding: 0.5rem 0.75rem;
    border-bottom: 0.0625rem solid #E3E7ED;
    font-size: 0.8125rem;
  }
  .roster-row:last-child { border-bottom: none; }
  .roster-num {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    min-width: 0;
  }
  .roster-num-hash {
    flex: 0 0 auto;
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ws-muted);
  }
  .roster-num .roster-num-input { flex: 1 1 auto; min-width: 0; }
  .roster-num-input {
    width: 100%;
    min-width: 0;
    text-align: center;
    padding: 0.3125rem 0.25rem;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.3125rem;
    background: var(--white);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--ws-ink-2);
  }
  .roster-num-input:focus { outline: none; border-color: var(--ws-ink); box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.12); }
  .roster-pos-input {
    width: 100%;
    min-width: 0;
    padding: 0.3125rem 0.5rem;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.3125rem;
    background: var(--white);
    font-family: inherit;
    font-size: 0.75rem;
    color: var(--ws-ink-2);
  }
  .roster-pos-input:focus { outline: none; border-color: var(--ws-ink); box-shadow: 0 0 0 0.1875rem rgba(102,153,204,0.12); }
  .roster-remove-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: #DC2626 !important;
    font-size: 0.7rem;
    line-height: 1;
    padding: 0.125rem 0.25rem;
    border-radius: 0.1875rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .roster-remove-btn:hover { background: #FEE2E2; }
  .roster-row > .roster-remove-btn { grid-column: 4; justify-self: end; align-self: center; }
  .roster-name { min-width: 0; overflow-wrap: anywhere; font-weight: 700; color: var(--dark-gray); }
  .roster-empty {
    padding: 1.5rem 1rem;
    text-align: center;
    color: var(--ws-muted);
    font-size: 0.8125rem;
  }
  .roster-add { display: flex; gap: 0.5rem; margin-bottom: 0.75rem; border-top: 0.0625rem solid var(--ws-line); padding-top: 0.75rem; }
  .roster-add #rosterAgeSel { flex: 0 0 4.75rem; min-width: 0; }
  .roster-add #rosterAddSel { flex: 1; min-width: 0; }
  .roster-add .ws-btn { width: auto; margin-top: 0; flex: 0 0 auto; }
  .roster-msg {
    display: block;
    width: fit-content;
    font-size: 0.8125rem;
    font-weight: 700;
    color: #EF4444;
    background: rgba(239, 68, 68, 0.12);
    box-shadow: inset 0 0 0 0.0625rem rgba(239, 68, 68, 0.25);
    border-radius: 0.1875rem;
    padding: 0.1875rem 0.5rem;
    margin: 0 auto 0.75rem;
    text-align: center;
  }
  .roster-msg:empty { display: none; }
  .roster-msg.hint { color: var(--ws-muted); background: rgba(100, 116, 139, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(100, 116, 139, 0.25); font-weight: 600; }
  .roster-msg.ok { color: #1A7F37; background: rgba(26, 127, 55, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(26, 127, 55, 0.25); }
  .roster-msg.pending { color: var(--ws-ink); background: rgba(51, 65, 85, 0.12); box-shadow: inset 0 0 0 0.0625rem rgba(51, 65, 85, 0.25); }
  .roster-editor {
    margin: 0.75rem 1.25rem 0.875rem;
    padding: 1rem 1.125rem 1.125rem;
    background: #F6F9FC;
    border: 0.0625rem solid #D5DDE6;
    border-radius: 0.5rem;
  }
  .roster-editor-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    margin-bottom: 0.625rem;
  }
  .roster-editor-head h3 {
    margin: 0;
    font-family: var(--font-primary);
    font-size: 0.9375rem;
    font-weight: 800;
    color: var(--ws-ink);
  }
  .roster-editor-head p {
    margin: 0.125rem 0 0;
    font-size: 0.75rem;
    color: var(--ws-muted);
  }
  .roster-editor-close {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent !important;
    color: var(--ws-muted) !important;
    border: 0.0625rem solid transparent;
    border-radius: 0.3125rem;
    cursor: pointer;
  }
  .roster-editor-close svg { width: 0.875rem; height: 0.875rem; }
  .roster-editor-close:hover { background: #E9F1F9 !important; color: var(--ws-ink-2) !important; }
  .roster-editor-actions { display: flex; justify-content: space-between; gap: 0.5rem; margin-top: 0.75rem; }
  .roster-editor-actions .ws-btn { flex: 0 0 auto; margin-top: 0; }
  .roster-editor-actions .ws-btn-ghost { width: 116px; }
  @media (max-width: 450px) {
    .account-editor .roster-editor-actions,
    #teamEditor .roster-editor-actions,
    #rosterEditor .roster-editor-actions,
    #playerEditor .roster-editor-actions,
    #bugEditor .roster-editor-actions,
    #heroSlideEditor .roster-editor-actions,
    .danger-card .roster-editor-actions { flex-direction: column; align-items: stretch; }
    .account-editor .roster-editor-actions .ws-btn,
    #teamEditor .roster-editor-actions .ws-btn,
    #rosterEditor .roster-editor-actions .ws-btn,
    #playerEditor .roster-editor-actions .ws-btn,
    #bugEditor .roster-editor-actions .ws-btn,
    #heroSlideEditor .roster-editor-actions .ws-btn,
    .danger-card .roster-editor-actions .ws-btn { flex: 1 1 0; width: 100%; }
  }
  .rollover-preview {
    background: #FFF;
    border: 0.0625rem solid #D5DDE6;
    border-radius: 0.5rem;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
  }
  .rollover-preview ul { margin: 0.375rem 0 0.625rem 1.25rem; padding: 0; font-size: 0.8125rem; color: var(--ws-ink-2); }
  .rollover-preview li { margin: 0.125rem 0; }
  .rollover-stat { font-size: 0.8125rem; color: var(--ws-ink); margin: 0.375rem 0; }
  .rollover-stat strong { color: var(--ws-ink); }
  .rollover-stat-warn { color: #C0392B; font-weight: 700; }
  .rollover-ok-box {
    background: rgba(26, 127, 55, 0.08);
    border: 0.0625rem solid rgba(26, 127, 55, 0.3);
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    font-size: 0.8125rem;
    color: #1A7F37;
    font-weight: 700;
    margin-bottom: 0.75rem;
  }
  .rollover-warn-box {
    background: rgba(192, 57, 43, 0.07);
    border: 0.0625rem solid rgba(192, 57, 43, 0.28);
    border-radius: 0.5rem;
    padding: 0.625rem 0.75rem;
    font-size: 0.75rem;
    color: #C0392B;
    margin-bottom: 0.75rem;
  }
  .rollover-meta { font-size: 0.75rem; color: var(--ws-muted); margin: 0.125rem 0 0.75rem; }
  .danger-cards {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    margin-bottom: 1rem;
  }
  .danger-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    background: #FFF9F9;
    border: 0.0625rem solid #F0C9C9;
    border-radius: 0.5rem;
    padding: 1rem 1.125rem 1.125rem;
  }
  .danger-card h3 {
    margin: 0;
    font-family: var(--font-primary);
    font-size: 0.9375rem;
    font-weight: 800;
    color: var(--ws-danger);
  }
  .danger-card > p {
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: var(--ws-ink-2);
  }
  .danger-card .roster-editor {
    margin: 0;
    background: #FFF;
    border-color: #F0C9C9;
  }
  .danger-card .roster-editor .roster-editor-actions { margin-top: 0; }
  .danger-card-actions {
    margin-top: auto;
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
  }
  .danger-card-actions .ws-btn { flex-shrink: 0; }
  .danger-card-foot {
    margin-top: auto;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
  }
  .danger-card-foot .danger-card-actions { margin-top: 0; }
  .danger-card-year {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
  }
  .danger-card-year-label {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ws-muted);
  }
  .danger-card-year-value {
    font-size: 0.8125rem;
    font-weight: 800;
    color: var(--ws-ink);
    font-variant-numeric: tabular-nums;
  }
  @media (max-width: 420px) {
    .danger-card-foot { flex-direction: column; align-items: stretch; }
    .danger-card-actions { justify-content: stretch; }
    .danger-card-actions .ws-btn { flex: 1 1 0; width: 100%; }
  }
  .roster-editor .form-grid { margin-bottom: 0.75rem; }
  .roster-editor .form-group { margin-bottom: 0.75rem; }
  .roster-editor .form-group label { margin-bottom: 0.25rem; }
  .account-editor .form-grid { margin-bottom: 0.75rem; }
  .account-editor .form-group { margin-bottom: 0.75rem; }
  .account-editor .form-group label { margin-bottom: 0.25rem; }
  .account-editor .form-group input[readonly] {
    background: #F4F6F9;
    color: var(--ws-muted);
    cursor: default;
    border-color: #DCE3EB;
  }
  .coach-teams-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr));
    gap: 0.75rem;
    margin-bottom: 0.75rem;
  }
  .coach-team-card {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
    padding: 0.875rem;
    background: var(--white);
    border: 0.0625rem solid var(--ws-line);
    border-top: 0.1875rem solid var(--taccent, var(--secondary));
    border-radius: 0.5rem;
    box-shadow: 0 0.125rem 0.5rem rgba(0,32,78,0.06);
  }
  .ctc-head { display: flex; align-items: center; gap: 0.625rem; min-width: 0; }
  .ctc-medal {
    flex: 0 0 auto;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.625rem;
    background: var(--taccent, var(--secondary));
    color: #fff;
    font-weight: 800;
    font-size: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    text-transform: uppercase;
  }
  .ctc-titles { min-width: 0; }
  .ctc-name { font-size: 0.9375rem; font-weight: 800; color: var(--secondary); line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ctc-age { font-size: 0.75rem; color: var(--ws-muted); margin-top: 0.0625rem; }
  .ctc-pos { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.125rem 0.375rem; margin-top: 0.125rem; min-height: 2.5rem; font-size: 0.75rem; font-weight: 600; color: #7E8EA4; }
  .ctc-pos-item { white-space: nowrap; display: inline-flex; align-items: baseline; }
  .ctc-pos-lbl { display: inline-block; min-width: 2.5ch; text-align: right; }
  .ctc-pos-count { margin-left: 0.25em; color: var(--secondary); }
  .ctc-pos-zero { color: #EF4444; }
  .ctc-pos-none { display: block; font-weight: 600; }
  .ctc-btn { margin-top: auto; }
  .ctc-actions { margin-top: auto; display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: stretch; }
  .ctc-actions .ctc-btn { margin-top: 0; flex: 1 1 auto; }
  .coach-teams-list > #coachRosterEditor { grid-column: 1 / -1; }
  #coachTeamsList > * { min-width: 0; }
  .coach-team-card.editing { box-shadow: 0 0.125rem 0.5rem rgba(0,32,78,0.06), 0 0 0 0.125rem var(--taccent, var(--secondary)); }
  @media (max-width: 420px) {
    .coach-teams-list { grid-template-columns: 1fr; }
  }
  #coachRosterEditor .roster-head,
  #coachRosterEditor .roster-row {
    grid-template-columns: 2.75rem 1fr 6rem;
  }
  #coachRosterEditor .roster-head span:last-child {
    visibility: visible;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    font-size: 0.6875rem;
    padding: 0;
    border: none;
    border-radius: 0;
    white-space: normal;
  }

  /* ---------- Team Leaders (coach) ---------- */
  .coach-teams-list > #coachRankingsPanel { grid-column: 1 / -1; }
  .coach-teams-list > #coachInsightsPanel { grid-column: 1 / -1; }
  .rankings-toolbar { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.75rem; }
  .rankings-sel-label { font-size: 0.8125rem; font-weight: 700; color: var(--ws-ink-2); }
  .rankings-toolbar .vs-control { max-width: 20rem; }
  .rankings-toolbar .ws-btn { margin-top: 0; }
  .rk-section { margin-bottom: 1rem; }
  .rk-section-title {
    margin: 0 0 0.5rem;
    font-family: var(--font-primary);
    font-size: 0.8125rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--ws-muted);
  }
  .rk-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr)); gap: 0.75rem; }
  .rk-card { background: #FFF; border: 0.0625rem solid #D5DDE6; border-radius: 0.5rem; padding: 0.625rem 0.75rem; }
  .rk-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.375rem; }
  .rk-card-label { font-family: var(--font-primary); font-size: 0.9375rem; font-weight: 800; color: var(--ws-ink); }
  .rk-card-hint { font-size: 0.6875rem; color: var(--ws-muted); text-transform: uppercase; letter-spacing: 0.04em; font-weight: 700; }
  .rk-list { list-style: none; margin: 0; padding: 0; }
  .rk-list li { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0; font-size: 0.8125rem; border-top: 0.0625rem solid #EEF2F6; }
  .rk-list li:first-child { border-top: 0; }
  .rk-rank {
    flex: 0 0 1.25rem;
    height: 1.25rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.3125rem;
    background: #E8EEF5;
    color: var(--ws-ink-2);
    font-weight: 800;
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
  }
  .rk-list li.rk-top .rk-rank { background: var(--primary); color: #FFF; }
  .rk-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ws-ink); font-weight: 600; }
  .rk-val { flex: 0 0 auto; font-weight: 800; color: var(--ws-ink); font-variant-numeric: tabular-nums; }
  .rk-empty { color: var(--ws-muted); font-style: italic; }
  .rk-single { background: #FFF; border: 0.0625rem solid #D5DDE6; border-radius: 0.5rem; padding: 0.875rem 1rem; max-width: 34rem; }
  .rk-single-head { display: flex; align-items: baseline; gap: 0.625rem; margin-bottom: 0.25rem; flex-wrap: wrap; }
  .rk-single-label { font-family: var(--font-primary); font-size: 1.0625rem; font-weight: 800; color: var(--ws-ink); }
  .rk-single-dir { font-size: 0.75rem; color: var(--ws-muted); font-weight: 600; }
  .rk-single-sub { margin: 0 0 0.5rem; font-size: 0.75rem; color: var(--ws-muted); }
  .rk-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
  .rk-table th { text-align: left; font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ws-muted); font-weight: 700; padding: 0.25rem 0.5rem; border-bottom: 0.0625rem solid #D5DDE6; }
  .rk-table th.rk-num, .rk-table td.rk-num { text-align: center; width: 3rem; }
  .rk-table th.rk-val, .rk-table td.rk-val { text-align: right; width: 5.5rem; }
  .rk-table td { padding: 0.375rem 0.5rem; border-bottom: 0.0625rem solid #EEF2F6; color: var(--ws-ink); }
  .rk-table tr:last-child td { border-bottom: 0; }
  .rk-table td.rk-num { color: var(--ws-ink-2); font-weight: 700; font-variant-numeric: tabular-nums; }
  .rk-table td.rk-val { font-weight: 800; font-variant-numeric: tabular-nums; }

  /* ---------- Team Insights (coach) ---------- */
  .ins-card { background: #FFF; border: 0.0625rem solid #D5DDE6; border-radius: 0.5rem; padding: 0.875rem 1rem; margin-bottom: 0.75rem; }
  .ins-card:last-child { margin-bottom: 0; }
  .ins-card-head { display: flex; align-items: baseline; gap: 0.625rem; flex-wrap: wrap; margin-bottom: 0.375rem; }
  .ins-card-title { margin: 0; font-family: var(--font-primary); font-size: 1rem; font-weight: 800; color: var(--ws-ink); }
  .ins-card-sub { font-size: 0.75rem; color: var(--ws-muted); font-weight: 600; }
  .ins-card-body { display: flex; flex-direction: column; gap: 0.375rem; }
  .ins-line { margin: 0; font-size: 0.8125rem; color: var(--ws-ink); line-height: 1.45; }
  .ins-note { margin: 0; font-size: 0.8125rem; color: var(--ws-muted); font-style: italic; }
  .ins-statline { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; padding: 0.3125rem 0; }
  .ins-statline-label { flex: 0 0 auto; min-width: 4.5rem; font-size: 0.6875rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ws-muted); }
  .ins-statline-cell { display: inline-flex; flex-direction: column; align-items: center; background: #F3F6FA; border-radius: 0.375rem; padding: 0.25rem 0.5rem; min-width: 3.25rem; }
  .ins-statline-key { font-size: 0.625rem; font-weight: 700; color: var(--ws-muted); text-transform: uppercase; letter-spacing: 0.04em; }
  .ins-statline-val { font-size: 0.875rem; font-weight: 800; color: var(--ws-ink); font-variant-numeric: tabular-nums; }
  .ins-workload { display: flex; flex-direction: column; }
  .ins-workload-row { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; padding: 0.3125rem 0; border-top: 0.0625rem solid #EEF2F6; font-size: 0.8125rem; }
  .ins-workload-row:first-child { border-top: 0; }
  .ins-workload-name { font-weight: 700; color: var(--ws-ink); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ins-workload-meta { flex: 0 0 auto; color: var(--ws-muted); font-size: 0.75rem; font-weight: 600; }

  /* ---------- Roster editors: small screens ---------- */
  @media (max-width: 500px) {
    .portal-panel[data-panel="myteams"],
    .portal-panel[data-panel="teams"],
    .portal-panel[data-panel="viewstats"] {
      margin-left: -1.5rem;
      margin-right: -1.5rem;
      padding: 1.25rem 1rem;
      border-radius: 0.5rem;
    }
    #coachRosterEditor,
    #rosterEditor,
    #coachRankingsPanel,
    #coachInsightsPanel {
      margin: 0.625rem 0 0.75rem;
      padding: 0.875rem 0.75rem;
    }
    .roster-head,
    .roster-row {
      gap: 0.375rem;
      padding-left: 0.5rem;
      padding-right: 0.5rem;
    }
    #coachRosterEditor .roster-head,
    #coachRosterEditor .roster-row {
      grid-template-columns: 2.75rem 1fr 4.25rem;
    }
    .roster-head,
    .roster-row {
      grid-template-columns: 2.75rem 1fr 4.25rem auto;
    }
    .roster-add #rosterAgeSel { flex: 0 0 4rem; }
  }

  /* ---------- Responsive ---------- */
  @media (max-width: 980px) {
    .nav-links {
      display: flex;
      visibility: hidden;
      opacity: 0;
      transform: translate3d(100%, 0, 0);
      transition: transform 0.2s ease, opacity 0.2s ease, visibility 0s;
      flex-direction: column;
      position: fixed;
      top: var(--header-h);
      left: 0;
      right: 0;
      bottom: 0;
      width: auto;
      background: var(--secondary);
      padding: 1.625rem 1.25rem 2.5rem;
      gap: 0;
      box-shadow: 0 1.125rem 2.75rem rgba(0,0,0,0.45);
      overflow-y: auto;
      overflow-x: hidden;
    }
    .nav-links.open {
      visibility: visible;
      opacity: 1;
      transform: translate3d(0, 0, 0);
    }
    .nav-links li { list-style: none; }
    .nav-panel-title {
      display: block;
      color: var(--primary-light);
      font-size: 0.75rem;
      font-weight: 800;
      text-transform: uppercase;
      letter-spacing: 0.125rem;
      padding: 0.25rem 1rem 0.5rem;
      border-bottom: 0.0625rem solid rgba(255,255,255,0.28);
      margin-bottom: 0.25rem;
    }
    .nav-panel-footer {
      display: block;
      margin-top: 0.875rem;
      padding: 0.625rem 1rem 0.25rem;
      border-top: 0.0625rem solid rgba(255,255,255,0.28);
      color: rgba(255,255,255,0.65);
      font-size: 0.8125rem;
      line-height: 1.6;
    }
    .nav-panel-footer .npf-handle { font-size: 0.875rem; }
    .nav-panel-footer .npf-social {
      display: flex;
      align-items: center;
      flex-wrap: wrap;
      gap: 0.5rem;
      color: var(--primary-light);
      font-weight: 600;
      font-size: 0.7813rem;
      margin-top: 0.375rem;
    }
    .npf-social .npf-icons { display: inline-flex; align-items: center; gap: 0.375rem; }
    .npf-social .npf-ico {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: 1.375rem;
      height: 1.375rem;
      padding: 0;
      border-radius: 50%;
      overflow: hidden;
      box-shadow: 0 0 0 0.0625rem rgba(255,255,255,0.25);
      transition: transform 0.2s ease, opacity 0.2s ease;
    }
    .npf-social .npf-ico::before,
    .npf-social .npf-ico::after { content: none; }
    .npf-social .npf-ico:hover { background: none; transform: translateY(-0.0625rem); opacity: 0.9; }
    .npf-social .npf-ico svg { width: 100%; height: 100%; display: block; }
    .nav-links a {
      display: flex;
      align-items: center;
      position: relative;
      padding: 1rem 2.75rem 1rem 1.5rem;
      font-size: 1.375rem;
      font-weight: 700;
      color: var(--white);
      letter-spacing: 0.0188rem;
      border-radius: 0.75rem;
      transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
    }
    .nav-links a::before {
      content: "";
      position: absolute;
      left: 0;
      top: 50%;
      width: 0.25rem;
      height: 55%;
      border-radius: 62.4375rem;
      background: var(--primary-light);
      transform: translateY(-50%) scaleY(0);
      transform-origin: center;
      transition: transform 0.22s ease;
    }
    .nav-links a::after {
      content: "›";
      position: absolute;
      left: auto;
      right: 1.125rem;
      top: 50%;
      bottom: auto;
      width: auto;
      height: auto;
      background: none;
      font-size: 1.625rem;
      font-weight: 700;
      line-height: 1;
      color: var(--primary-light);
      opacity: 0;
      transform: translateY(-50%) translateX(-0.375rem);
      transition: opacity 0.2s ease, transform 0.2s ease;
    }
    .nav-links a:hover {
      color: var(--white);
      background: rgba(255,255,255,0.08);
      transform: translateX(0.25rem);
    }
    .nav-links a:hover::before {
      transform: translateY(-50%) scaleY(1);
    }
    .nav-links a.active-link::before {
      transform: translateY(-50%) scaleY(0);
    }
    .nav-links a:hover::after {
      opacity: 1;
      transform: translateY(-50%) translateX(0);
    }
    .nav-links a.active-link {
      background: var(--primary);
      color: var(--white);
    }
    .nav-links a.active-link:hover { background: var(--primary); color: var(--white); }
    @media (prefers-reduced-motion: reduce) {
      .nav-links, .nav-links.open { animation: none; transition: none; }
      .nav-links a::before, .nav-links a::after { transition: none; }
      .hamburger .ham-line { transition: none; }
    }
    .hamburger { display: flex; margin-left: 0.75rem; }
    .nav-user-name { max-width: 7.5rem; }
    .nav-cta {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 2.875rem;
      height: 2.875rem;
      padding: 0;
      border-radius: 0.5rem;
      font-size: 1.25rem;
    }
    .nav-cta .nav-cta-text { display: none; }
    .nav-cta .nav-cta-icon { line-height: 1; font-size: 1.625rem; }
    .nav-portal.is-logged-in .nav-cta { display: none; }
    #drawerLogout { display: list-item; }
    #drawerLogout[hidden] { display: none; }
    #drawerMyDashboard { display: list-item; }
    #drawerMyDashboard[hidden] { display: none; }
    .nav-panel-logout {
      margin-top: 0.875rem;
      border-top: 0.0625rem solid rgba(255,255,255,0.28);
      padding: 0.875rem 0;
    }
    .nav-panel-logout a { padding-top: 0; padding-bottom: 0; }
    #drawerMyDashboard a { padding-top: 0.875rem; padding-bottom: 0.875rem; }
    #drawerLogout { margin-top: 0; border-top: 0; padding-top: 0.25rem; }
    .program-grid { grid-template-columns: 1fr; gap: 1.875rem; }
    .program-grid.flip .program-card { order: 0; }
    .program-tabs { padding: 5rem 1rem 4rem; }
    .program-panel {
      min-height: 0;
      max-height: none;
      overflow: visible;
      padding: 2.5rem 1.5rem;
    }
    .social-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; }
    .social-grid[data-visible="1"] { grid-template-columns: minmax(0, 20rem); justify-content: center; }
    .social-grid .ig-card, .social-grid .fb-card { aspect-ratio: 1; }
    .social-grid .yt-card { grid-column: 1 / -1; }
    .social-grid .yt-card .social-video { max-width: 23.75rem; margin-left: auto; margin-right: auto; }
    .social-tile-grid { grid-auto-rows: auto; align-content: center; }
    .social-tile { aspect-ratio: 1 / 1; }
    .social-tile:nth-child(n+3) { display: none; }
    .social-card { padding: 0.875rem 0.75rem 3.125rem; }
    .social-icon { width: 1.75rem; height: 1.75rem; margin-bottom: 0.375rem; }
    .social-handle { font-size: clamp(0.5rem, 2.55vw, 0.6875rem); margin-bottom: 0.375rem; }
    .social-caption { font-size: clamp(0.625rem, 2.55vw, 0.75rem); }
    .social-tile-grid { margin-bottom: 0.5rem; }
    .social-follow { padding: 0.375rem 0.75rem; font-size: 0.6875rem; bottom: 0.75rem; }
    .testimonial-card { padding: 1.375rem 1.125rem; }
    .testimonial-quote-mark { font-size: 2.125rem; margin-bottom: 0.125rem; }
    .testimonial-quote { flex: none; font-size: 0.8125rem; margin-bottom: 0.875rem; }
    .footer-wrap {
      display: grid;
      grid-template-columns: minmax(0, 1fr) auto;
      gap: 2rem 2.25rem;
      width: 88%;
      max-width: 32.5rem;
      margin: 0 auto;
    }
    .footer-links { min-width: 0; }
    .footer-brand { grid-column: 1; grid-row: 1; }
    .footer-programs { grid-column: 1; grid-row: 2; }
    .footer-explore { grid-column: 2; grid-row: 2; }
    .footer-contact { grid-column: 2; grid-row: 1; display: flex; flex-direction: column; justify-content: center; }
    .footer-brand p.footer-mission { font-size: clamp(0.7rem, 2.8vw, 0.9375rem); }
    .footer-tagline-row, .footer-bottom { max-width: 32.5rem; }
    .footer-tagline-row { text-align: center; margin: 2rem auto 0; }
  }

  /* ---------- Compact header under 1000px: pull logo/buttons to the edges, halve top/bottom padding ---------- */
  @media (max-width: 1000px) {
    .nav-wrap { padding: 4.5625px clamp(0.75rem, 2vw, 1.5rem); }
  }

  /* ---------- Tablet: compact right-aligned menu panel ---------- */
  @media (min-width: 481px) and (max-width: 980px) {
    .nav-links {
      left: auto;
      right: 1rem;
      width: min(23.75rem, 85vw);
      top: var(--header-h);
      bottom: auto;
      height: auto;
      transition: transform 0.15s ease, visibility 0s;
      padding: 0.625rem 0.875rem 0.875rem;
    }
  }
  /* Short tablet screens (landscape phones): cap the panel at the viewport so it never clips */
  @media (min-width: 481px) and (max-width: 980px) and (max-height: 600px) {
    .nav-links {
      max-height: calc(100vh - var(--header-h));
      overflow-y: auto;
      overflow-x: hidden;
    }
  }

  /* ---------- Program Tabs: Mobile Portrait Redesign ---------- */
  @media (max-width: 640px) {
    .tab-bar {
      position: sticky;
      top: var(--header-h);
      z-index: 50;
      gap: 0.5rem;
      margin: 0 -1rem;
      padding: 0.625rem 1rem;
      background: var(--light-gray);
      border-bottom: 0.0625rem solid rgba(0,32,78,0.1);
      border-radius: 0;
      flex-wrap: wrap;
      justify-content: center;
      container-type: inline-size;
      overflow-y: hidden;
    }
    .tab {
      flex: 0 0 auto;
      border: none;
      border-radius: 62.4375rem;
      margin: 0;
      padding: 0.5625rem 0.9375rem;
      font-size: 0.8438rem;
      background: var(--white);
      color: var(--secondary);
      box-shadow: inset 0 0 0 0.0625rem rgba(0,32,78,0.14);
    }
    .tab:hover { background: var(--white); color: var(--primary); }
    .tab.active { background: var(--secondary); color: var(--white); }
    .tab.active:hover { background: var(--secondary); color: var(--white); }
    @container (max-width: 40rem) {
      .tab {
        flex: 1 1 calc(50% - 0.25rem);
        white-space: normal;
      }
    }
    .program-panels { border-radius: 0.875rem; margin-top: 0.75rem; }
    .program-panel {
      display: none;
      min-height: 0;
      max-height: none;
      overflow: visible;
      padding: 2rem 1.5rem;
    }
    .program-panel.active { display: block; }
    .program-panel .program-grid {
      grid-template-columns: 1fr;
      gap: 1.75rem;
      margin-top: 0;
      margin-bottom: 0;
    }
    .program-panel .program-card dl { flex: none; justify-content: flex-start; }
    .program-panel .program-card {
      background: transparent;
      border: none;
      border-radius: 0;
      box-shadow: none;
      padding: 0;
    }
    .program-panel .program-card::before {
      content: "";
      display: block;
      width: 100%;
      height: 0.1875rem;
      margin-bottom: 1.25rem;
      border-radius: 62.4375rem;
      background: var(--card-accent);
    }
  }

  /* ---------- Hero: mobile sizing ---------- */
  @media (max-width: 640px) {
    footer { padding: 2.25rem 1.25rem 1.625rem; }
    .footer-wrap { gap: 1.75rem 2.25rem; }
    .footer-col a { padding: 0.5625rem 0; margin-bottom: 0; }
    .footer-tagline-row { text-align: center; }
  }
  @media (max-width: 400px) {
    .rosters-hero h1 .h-phrase { display: block; }
  }
  /* ---------- Short landscape screens (landscape phones): fit content to the viewport ---------- */
  @media (max-height: 520px) {
    :root { --header-h: 58.5px; }
    .nav-wrap { padding: 5.625px clamp(0.75rem, 2vw, 1.5rem); }
    .logo-icon { width: 45px; height: 45px; font-size: 18px; }
    .hamburger { width: 45px; height: 45px; }
    .nav-portal.is-logged-in .nav-cta { width: 45px; height: 45px; }
    .nav-portal.is-logged-in .nav-cta-icon { font-size: 24.75px; }
    .logo { font-size: 24.75px; gap: 9px; }
    .logo .logo-top { font-size: 29.25px; }
    .logo .logo-bottom { font-size: 15.3px; }
    .section { padding: 2.5rem 1.5rem; }
    .program-tabs { padding: 2.5rem 1.5rem 1.25rem; }
    .cta-band { padding: 1.75rem 1.5rem; }
    .program-panel { min-height: 0; max-height: none; overflow: visible; padding: 1.25rem 1.5rem; }
    .program-tabs-head { margin-bottom: 0.5rem; }
    .program-tabs-head h2 { font-size: 1.375rem; margin-bottom: 0.125rem; }
    .program-tabs-head p { font-size: 0.8438rem; }
    .tab-bar {
      position: sticky;
      top: var(--header-h);
      z-index: 50;
      gap: 0.4375rem;
      padding: 0.375rem 0.875rem;
      margin: 0;
      background: #D7DBE1;
      border-bottom: 0.125rem solid #C2C8D0;
      border-radius: 0;
      flex-wrap: nowrap;
      overflow-x: auto;
      overflow-y: hidden;
      justify-content: flex-start;
    }
    .tab {
      flex: 0 0 auto;
      border: none;
      border-radius: 62.4375rem;
      margin: 0;
      padding: 0.4375rem 1rem;
      font-size: 0.8438rem;
      background: #C2C8D0;
      color: var(--secondary);
    }
    .tab:hover { background: #CDD3DA; color: var(--secondary); }
    .tab.active { background: var(--secondary); color: var(--white); }
    .tab.active:hover { background: var(--secondary); color: var(--white); }
    .program-panel .program-grid { gap: 1.75rem; }
    .program-panel .program-eyebrow { font-size: 0.6875rem; margin-bottom: 0.25rem; }
    .program-panel .program-copy h2 { font-size: clamp(1.125rem, 2.6vw, 1.5rem); margin-bottom: 0.375rem; }
    .program-panel .program-copy p { font-size: 0.875rem; margin-bottom: 0.625rem; }
    .program-panel .program-copy .btn-primary { margin-top: 0.375rem; padding: 0.625rem 1.375rem; font-size: 0.875rem; }
    .program-panel .program-list { margin-bottom: 0.75rem; }
    .program-panel .program-list li { font-size: 0.8438rem; margin-bottom: 0.25rem; }
    .program-panel .program-card { padding: 0.875rem 1.125rem; }
    .program-panel .program-card .card-icon { width: 2rem; height: 2rem; margin-bottom: 0.375rem; }
    .program-panel .program-card h3 { font-size: 1rem; }
    .program-panel .program-card dd { font-size: 0.8125rem; }
    .rosters-hero { padding: 1.875rem 1.5rem; }
    .rosters-hero h1 { font-size: clamp(1.5rem, 4vw, 2.25rem); margin-bottom: 0.5rem; }
    .rosters-hero p { font-size: 0.9063rem; }
    .rosters-body { padding: 1.75rem 1.5rem 3rem; }
    .legal-body { padding: 1.75rem 1.5rem 3rem; }
    #page-coaches #coachesBody { padding-top: 1.125rem; padding-bottom: 1.5rem; }
    .card { padding: 1.125rem 1rem; }
    .card-icon { width: 2.5rem; height: 2.5rem; font-size: 1.25rem; margin-bottom: 0.625rem; }
    .card h3 { font-size: 1.0625rem; margin-bottom: 0.375rem; }
    .card p { font-size: 0.8438rem; }
    .photo-band { height: clamp(6.875rem, 22vw, 10.625rem); }
    .section-head { margin-bottom: 1.5rem; }
    .section-head h2 { font-size: clamp(1.375rem, 3vw, 1.875rem); margin-bottom: 0.5rem; }
    .section-head p { font-size: 0.9375rem; }
    #page-facilities .facility-head { margin-bottom: 0.875rem; }
    #page-facilities .facility-head--spaced { margin-top: 1.375rem; }
    #page-facilities .facility-photo { margin-bottom: 0.875rem; }
    #page-facilities .facility-grid { gap: 0.875rem; }
    #page-facilities .facility-field-strip { height: clamp(6.875rem, 20vw, 10.625rem); margin-bottom: 0.875rem; }
    .team-tabs { padding: 0.5rem 0; gap: 0.5rem; margin-bottom: 0.625rem; }
    .tab-btn { padding: 0.5rem 1rem; font-size: 0.875rem; }
    .team-meta { margin-bottom: 0.75rem; font-size: 0.875rem; }
    .roster-table th { padding: 0.625rem 0.75rem; }
    .roster-table td { padding: 0.5625rem 0.75rem; font-size: 0.875rem; }
    #page-about .section-head { margin-bottom: 1rem !important; }
    #page-about .card-grid { margin-bottom: 1.375rem !important; gap: 0.875rem; }
    #page-about .contact-grid { gap: 1.375rem; }
    #page-about .contact-block { margin-bottom: 0.875rem; }
    #page-about .contact-icon { width: 2.375rem; height: 2.375rem; }
    #page-about .contact-form { padding: 1.25rem 1.125rem; }
    #page-about .contact-form h3 { margin: 0 0 0.75rem; font-size: 1.125rem; }
    .modal-overlay { padding: 0.75rem; }
    .modal { padding: 1.125rem 1.5rem; max-width: 23.75rem; max-height: calc(100vh - 1.5rem); overflow-y: auto; }
    .modal-logo { display: none; }
    .modal h2 { font-size: 1.25rem; margin-bottom: 0.125rem; }
    .modal-sub { font-size: 0.8125rem; margin-bottom: 0.625rem; }
    .form-group { margin-bottom: 0.5rem; }
    .form-group label { font-size: 0.7813rem; margin-bottom: 0.25rem; }
    .form-group input { padding: 0.4375rem 0.6875rem; font-size: 0.875rem; }
    .modal-btn { padding: 0.5625rem; font-size: 0.9375rem; margin-top: 0.25rem; }
    .modal-toggle { margin-top: 0.625rem; font-size: 0.8125rem; }
    .test-hint { margin-top: 0.5rem; padding: 0.375rem 0.75rem; font-size: 0.7813rem; }
    .test-hint { margin-top: 0.375rem; padding: 0.3125rem 0.625rem; }
  }
  @media (max-height: 520px) and (max-width: 980px) {
    .nav-cta { width: 2.5rem; height: 2.5rem; }
    .nav-cta .nav-cta-icon { font-size: 1.375rem; }
  }
  @media (max-width: 400px) {
    #page-facilities .facility-grid .card-icon { display: none; }
  }
  @media (max-width: 640px) {
    #page-facilities .facility-grid {
      grid-template-columns: 1fr;
      width: 96%;
      margin-left: auto;
      margin-right: auto;
    }
  }
  @media (max-width: 360.5px) {
    :root { --header-h: 58.5px; }
    .nav-wrap { padding: 5.625px 12px; }
    .logo { gap: 9px; font-size: 24.75px; }
    .logo .logo-top { font-size: 29.25px; }
    .logo .logo-bottom { font-size: 15.3px; }
    .logo-icon { width: 45px; height: 45px; font-size: 18px; }
    .nav-portal { gap: 9px; }
    .nav-user-name { font-size: 15.75px; max-width: 99px; }
    .nav-user-logout { font-size: 12.375px; }
    .hamburger { width: 45px; height: 45px; margin-left: 9px; }
  }

  /* ---------- Dashboard Style (portal tab: Default Team Color / Always Navy / Always Light Blue) ---------- */
  .theme-radio {
    display: flex; align-items: flex-start; gap: 0.75rem;
    padding: 0.875rem 1.125rem;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.625rem;
    background: #fff; cursor: pointer;
  }
  .theme-radio + .theme-radio { margin-top: 0.625rem; }
  .theme-radio input { margin-top: 0.28125rem; accent-color: var(--primary); }
  .theme-radio-txt strong {
    display: block;
    font-family: 'Oswald', 'Arial Narrow', sans-serif;
    font-size: 1rem; font-weight: 700; letter-spacing: 0.03125rem;
    color: var(--secondary);
  }
  .theme-radio-sub { display: block; margin-top: 0.1875rem; color: var(--gray-text); font-size: 0.8125rem; line-height: 1.45; }
  .theme-radio:has(input:checked) {
    border-color: var(--primary);
    background: rgba(102,153,204,0.07);
    box-shadow: 0 0 0 0.0625rem rgba(102,153,204,0.35);
  }


  /* ---------- Light Blue dashboard design (body.apex-design-blue) ---------- */
  body.apex-design-blue .dashboard-hero {
    background:
      repeating-linear-gradient(-45deg, rgba(255,255,255,0.05) 0 1.375rem, transparent 1.375rem 2.75rem),
      linear-gradient(135deg, #7FAED8 0%, var(--primary) 45%, var(--primary-dark) 100%);
  }
  body.apex-design-blue .hero-pill {
    background:
      linear-gradient(180deg, rgba(255,255,255,0.12) 0%, rgba(255,255,255,0.02) 18%, rgba(0,0,0,0) 30%),
      linear-gradient(180deg, #9CC2E4 0%, var(--primary) 50%, var(--primary-dark) 100%);
    border-color: rgba(255,255,255,0.55);
    border-top-color: rgba(255,255,255,0.7);
    border-bottom-color: rgba(255,255,255,0.5);
    box-shadow:
      inset 0 0.0625rem 0.1875rem rgba(255,255,255,0.28),
      inset 0 0.0625rem 0 rgba(255,255,255,0.4),
      inset 0 -0.5rem 1.25rem rgba(0,32,78,0.22),
      inset 0.625rem 0 0.875rem -0.625rem rgba(0,32,78,0.4),
      inset -0.625rem 0 0.875rem -0.625rem rgba(0,32,78,0.4),
      0 0.1875rem 0.5rem rgba(0,20,51,0.5),
      0 1rem 1.875rem rgba(0,20,51,0.45);
  }
  body.apex-design-blue .hero-pill::after {
    background:
      linear-gradient(180deg, rgba(0,10,26,0) 0%, rgba(0,10,26,0.08) 9%, rgba(0,10,26,0) 19%),
      linear-gradient(180deg, rgba(255,255,255,0.15) 0%, rgba(255,255,255,0.04) 10%, rgba(255,255,255,0) 20%),
      linear-gradient(115deg, transparent 33%, rgba(255,255,255,0.78) 42%, rgba(255,255,255,0.12) 50%, transparent 58%);
  }
  body.apex-design-blue .hero-pill-num {
    color: #ffffff;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.45);
  }
  body.apex-design-blue .hero-pill h1 {
    color: #ffffff;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.5), 0 -0.0625rem 0 rgba(255,255,255,0.25);
  }
  body.apex-design-blue .hero-stat {
    color: #ffffff;
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.5);
  }
  body.apex-design-blue .stat-label,
  body.apex-design-blue .stat-divider {
    color: var(--secondary);
    text-shadow: 0 0.0625rem 0.125rem rgba(255,255,255,0.4);
  }
  body.apex-design-blue .hero-sep { background: var(--secondary); }
  body.apex-design-blue .hero-photo {
    background: linear-gradient(180deg, #7FAED8 0%, var(--primary-dark) 100%);
    border-color: rgba(255,255,255,0.55);
    box-shadow: 0 0.875rem 1.625rem rgba(0,20,51,0.5);
  }
  body.apex-design-blue .dash-stat {
    background: linear-gradient(180deg, rgba(255,255,255,0.25) 0%, rgba(255,255,255,0.10) 100%);
    border: 0.0625rem solid rgba(255,255,255,0.5);
    box-shadow: inset 0 0.0625rem 0 rgba(255,255,255,0.25), 0 0.1875rem 0.5rem rgba(0,20,51,0.18);
  }
  body.apex-design-blue .dash-stat::before { background: #00204E; }
  body.apex-design-blue .dash-stat-label { color: #00204E; }
  body.apex-design-blue .dash-stat-cat { color: #00204E !important; }
  body.apex-design-blue .dash-stat-value {
    color: var(--white);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.55);
  }
  body.apex-design-blue .dash-stat-rank { color: rgba(255,255,255,0.92); text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.55); }
  body.apex-design-blue .dash-no-stats {
    color: #ffffff;
    border-color: rgba(0,32,78,0.55);
  }
  body.apex-design-blue .dash-stats.is-6 .dash-stat-rank { color: rgba(255,255,255,0.8); text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.55); }
  body.apex-design-blue .dash-stats.is-6 .dash-stat-rank b { color: var(--white); }
  body.apex-design-blue .portal-tab.active { background: var(--primary); }
  body.apex-design-blue .portal-tab.active .tab-roles { color: var(--secondary); }
  body.apex-design-blue .portal-nav { --nav-ledge: rgba(0,32,78,0.30); }
  body.apex-design-blue .vs-group-title {
    background: linear-gradient(180deg, #9CC2E4 0%, var(--primary) 55%, var(--primary-dark) 100%);
    text-shadow: 0 0.0625rem 0.125rem rgba(0,20,51,0.35);
  }

  /* ---------- Company Ledger grid ---------- */
  .ledger-table-head,
  .ledger-row {
    display: grid;
    grid-template-columns: 1.5fr 1.2fr 1fr 1.1fr;
    gap: 0.875rem;
    align-items: center;
    padding: 0.625rem 1rem;
  }
  .ledger-table-head {
    background: #B9C0CA;
    border-bottom: 0.0625rem solid #9CA5B1;
  }
  .ledger-table-head span {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #2F3640;
  }
  .ledger-row {
    width: 100%;
    position: relative;
    background: var(--white);
    border: none;
    border-bottom: 0.0625rem solid #DCE1E8;
    cursor: pointer;
    text-align: left;
    font-family: inherit;
    transition: background 0.15s;
  }
  .ledger-row:last-child { border-bottom: none; }
  .ledger-row:hover { background: #F4F6F9; }
  .ledger-row.selected { background: #E9F1F9; box-shadow: inset 0 0 0 0.125rem var(--primary); }
  .ldg-name { display: inline-flex; align-items: center; gap: 0.375rem; min-width: 0; font-size: 0.8125rem; font-weight: 700; color: var(--ws-ink); }
  .ldg-chev {
    position: absolute;
    right: 0.625rem;
    top: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    color: var(--ws-muted);
    font-size: 1rem;
    line-height: 1;
    flex-shrink: 0;
    transition: transform 0.15s ease, color 0.15s ease;
  }
  .ldg-chev::before { content: "\25C2"; }
  .ledger-row.is-open .ldg-chev { transform: rotate(-90deg); color: var(--primary); }
  .ldg-parent { font-size: 0.75rem; color: var(--ws-ink-2); }
  .ldg-parent-sub { font-size: 0.75rem; color: var(--ws-muted); }
  .ldg-team { font-size: 0.75rem; color: var(--ws-ink-2); }
  .ldg-team-tag {
    display: inline-block;
    padding: 0 0.3125rem;
    border-radius: 0.25rem;
    font-size: 0.625rem;
    font-weight: 700;
    white-space: nowrap;
  }
  .ldg-rem { font-size: 0.8125rem; font-weight: 800; font-variant-numeric: tabular-nums; }
  .ldg-rem-owed { color: #C0392B; }
  .ldg-rem-paid { color: #1A7F37; }
  /* Company Ledger: below 550px collapse the 4-column grid into stacked cards with a badge for the remaining amount */
  @media (max-width: 550px) {
    .ledger-table-head { display: none; }
    .ledger-row {
      display: grid;
      grid-template-columns: 1fr auto;
      gap: 0.375rem 0.875rem;
      align-items: center;
      padding: 0.625rem 0.875rem;
      margin-bottom: 0.5rem;
      border: 0.0625rem solid #DCE1E8;
      border-radius: 0.5rem;
      background: var(--white);
      box-shadow: 0 0.0625rem 0.1875rem rgba(16,24,40,0.06);
    }
    .ledger-row:last-child { margin-bottom: 0; }
    .ldg-name { grid-column: 1; grid-row: 1; font-size: 0.875rem; }
    .ldg-chev { position: static; }
    .ldg-rem {
      grid-column: 2; grid-row: 1;
      justify-self: end;
      padding: 0.1875rem 0.625rem;
      border-radius: 999px;
      background: #EFF2F6;
      font-size: 0.75rem;
    }
    .ldg-rem-owed { background: #FBE9E7; color: #C0392B; }
    .ldg-rem-paid { background: #E6F4EA; color: #1A7F37; }
    .ldg-parent { grid-column: 1 / -1; grid-row: 2; font-size: 0.75rem; color: var(--ws-ink-2); }
    .ldg-parent::before { content: "Parent: "; color: var(--ws-muted); }
    .ldg-team { grid-column: 1 / -1; grid-row: 3; justify-self: end; }
    .ldg-team-tag { font-size: 0.6875rem; }
  }
  .ledger-modal-player {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--ws-ink);
    padding: 0.375rem 0.625rem;
    background: #E2E8F0;
    border: 0.0625rem solid #D3DBE4;
    border-radius: 0.3125rem;
    margin-bottom: 1.25rem;
  }
  .ledger-sec-title {
    font-size: 0.75rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #5A6B7C;
    margin: 0.875rem 0 0.5rem;
  }
  .ledger-sec-title:first-of-type { margin-top: 0.25rem; }
  .ledger-inst-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr;
    gap: 0.625rem;
    align-items: end;
    margin-bottom: 0.625rem;
  }
  .ledger-inst-label {
    font-size: 0.8125rem;
    font-weight: 800;
    color: var(--ws-ink-2);
    align-self: center;
  }
  .ws-check {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.8125rem;
    color: var(--ws-ink-2);
    cursor: pointer;
  }
  .ledger-flags {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
    margin-bottom: 0.25rem;
  }
  .ledger-flags .ws-check { cursor: pointer; color: var(--ws-ink-2); font-weight: 700; }
  .ledger-flags .ws-check input { accent-color: var(--primary); }
  .ledger-flag-group {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.875rem;
    padding: 0.25rem 0.625rem;
    border: 0.0625rem solid #C5D9EC;
    border-radius: 0.3125rem;
    background: #F4F8FC;
  }
  
  .ledger-bk-empty {
    color: var(--ws-muted);
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-align: center;
    padding: 1.25rem 0.8125rem;
    border: 0.0625rem dashed #D7DAE0;
    border-radius: 0.4375rem;
  }
  .ledger-bk-head {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    padding: 0 0.8125rem 0.25rem;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #5A6B7C;
  }
  .ledger-bk-head + .ledger-bk-head-amt,
  .ledger-bk-head-amt { text-align: right; }
  .ledger-bk-row {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    align-items: baseline;
    padding: 0.25rem 0.8125rem;
    font-size: 0.8125rem;
  }
  /* Ledger Editor: charge rows (Tuition/Peak/PK-mo) get the same light separator
     as payments/adjustments, so there's a line between EVERY line item (JAMIE, Sep 3). */
  .ledger-editor .ledger-bk-row { border-top: 0.0625rem solid #E2E8F0; }
  .ledger-bk-name { font-weight: 800; color: var(--ws-ink); }
  .ledger-bk-date { color: var(--ws-ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 0.75rem; }
  .ledger-bk-head-desc { text-align: left; padding-left: 1.5rem; }
  .ledger-bk-desc { color: var(--ws-ink-2); padding-left: 1.5rem; text-align: left; }
  .ledger-bk-amt { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ws-ink); text-align: right; }
  .ledger-bk-head-x { text-align: left; padding-left: 0.75rem; }
  .ledger-bk-del {
    background: none;
    border: none;
    cursor: pointer;
    color: #DC2626 !important;
    font-size: 0.7rem;
    line-height: 1;
    padding: 0.125rem 0.25rem;
    border-radius: 0.1875rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .ledger-bk-del:hover { background: #FEE2E2; }
  .ledger-bk-total {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    align-items: baseline;
    padding: 0.5rem 0.8125rem;
    border-top: 0.125rem solid #475569;
    font-size: 0.8125rem;
  }
  .ledger-bk-total-label { grid-column: 2; font-weight: 800; color: var(--ws-ink); }
  .ledger-bk-total-amt { grid-column: 4; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ws-ink); text-align: right; }
  .ledger-editor .ledger-bk-sched { margin-left: -0.4375rem; margin-right: -0.4375rem; }
  .ledger-editor-actions { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-top: 0.75rem; flex-wrap: wrap; }
  .ledger-editor-actions-left { display: flex; align-items: center; gap: 0.5rem; }
  .ledger-editor-actions-right { display: flex; align-items: center; gap: 0.5rem; }
  .ledger-bk-pay {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    align-items: baseline;
    padding: 0.25rem 0.8125rem;
    font-size: 0.8125rem;
    border-top: 0.0625rem solid #E2E8F0;
  }
  .ledger-bk-pay-amt { font-weight: 700; font-variant-numeric: tabular-nums; color: #15803D; text-align: right; }
  .ledger-bk-sched {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem 0.5rem;
    margin-top: 0.5rem;
    padding: 0.5rem 0.8125rem;
    border: 0.0625rem solid #D3DBE4;
    border-radius: 0.3125rem;
    background: #F8FAFC;
    font-size: 0.75rem;
    color: #64748B;
  }
  .ledger-bk-sched-label {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.75rem;
    color: #5A6B7C;
    flex-basis: 100%;
    margin-top: 0.375rem;
    padding-left: 0.75rem;
  }
  .ledger-bk-sched-label:first-child { margin-top: 0; }
  .ledger-bk-sched-label strong { font-weight: 900; color: #22303C; }
  .ledger-bk-sched-rest {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem 0.375rem;
    flex-basis: 100%;
  }
  @media (max-width: 375px) {
    .ledger-bk-sched-label-due { display: block; }
  }
  .ledger-bk-sched-item {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex: 0 0 11.875rem;
    width: 11.875rem;
    max-width: 11.875rem;
    box-sizing: border-box;
    padding: 0.125rem 0.4375rem;
    border-radius: 0.5625rem;
    border: 0.0625rem solid rgba(100, 116, 139, 0.25);
    background: #EEF2F6;
    color: #475569;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
  }
  .ledger-bk-sched-item.is-next {
    background: #C9DCF1;
    border-color: rgba(46, 92, 138, 0.35);
    color: #1E3A5F;
    font-weight: 700;
  }
  .ledger-bk-sched-next {
    background: #fff;
    color: #1E3A5F;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1;
    padding: 0.25rem 0.4375rem;
    border-radius: 0.9375rem;
    box-shadow: inset 0 0 0 0.0625rem rgba(46, 92, 138, 0.25);
  }
  .ledger-bk-sched-item.is-due {
    background: #FFF5F5;
    border-color: rgba(220, 38, 38, 0.4);
    color: #B91C1C;
    font-weight: 700;
  }
  .ledger-bk-sched-item.is-overdue {
    background: #FECACA;
    border-color: rgba(220, 38, 38, 0.6);
    color: #B91C1C;
    font-weight: 700;
  }
  .ledger-bk-sched-due {
    background: #fff;
    color: #DC2626;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1;
    padding: 0.25rem 0.4375rem;
    border-radius: 0.9375rem;
    box-shadow: inset 0 0 0 0.0625rem rgba(220, 38, 38, 0.45);
  }
  .ledger-bk-sched-overdue {
    background: #DC2626;
    color: #fff;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1;
    padding: 0.25rem 0.4375rem;
    border-radius: 0.9375rem;
  }
  .ledger-bk-sched-item.is-paid {
    background: #DCFCE7;
    border-color: rgba(22, 163, 74, 0.35);
    color: #15803D;
    font-weight: 700;
  }
  .ledger-bk-sched-paid {
    background: #fff;
    color: #15803D;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1;
    padding: 0.25rem 0.4375rem;
    border-radius: 0.9375rem;
    box-shadow: inset 0 0 0 0.0625rem rgba(22, 163, 74, 0.3);
  }
  .ledger-bk-sched-next, .ledger-bk-sched-due, .ledger-bk-sched-overdue, .ledger-bk-sched-paid {
    min-width: 2.6rem;
    flex: 0 0 auto;
    white-space: nowrap;
    text-align: center;
    padding: 0.1875rem 0.4375rem;
  }
  .ledger-bk-sched-date { white-space: nowrap; display: inline-block; min-width: 6.5ch; text-align: right; }
  .ledger-bk-sched-amt { font-weight: 700; font-variant-numeric: tabular-nums; display: inline-block; min-width: 8ch; text-align: center; flex: 1 1 auto; }
  .ledger-bk-sched-pay {
    display: inline-flex;
    align-items: center;
    gap: 0.1875rem;
    padding: 0.0625rem 0.5rem;
    border-radius: 0.9375rem;
    background: var(--primary);
    color: #fff !important;
    font-size: 0.6875rem;
    font-weight: 700;
    text-decoration: none;
    line-height: 1.4;
  }
  .ledger-bk-sched-pay:hover { filter: brightness(1.06); }
  .ledger-bk-plan {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem 1.25rem;
    flex-basis: 100%;
    margin: 0.5rem 0 0.5rem;
    padding: 0.375rem 0.625rem;
    background: #E2E8F0;
    border-radius: 0.25rem;
    font-size: 0.8125rem;
    color: #64748B;
  }
  .ledger-bk-plan-label {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.8125rem;
    color: #5A6B7C;
  }
  .ledger-bk-plan .ws-check { cursor: pointer; color: var(--ws-ink-2); font-weight: 700; }
  .ledger-bk-plan .ws-check input { accent-color: var(--primary); }
  .ledger-bk-mcount {
    font-size: 0.75rem;
    color: #5A6B7C;
    font-weight: 600;
    white-space: nowrap;
  }
  .ledger-bk-adj {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    align-items: baseline;
    padding: 0.25rem 0.8125rem;
    font-size: 0.8125rem;
    border-top: 0.0625rem solid #E2E8F0;
  }
  .ledger-bk-adj-amt { font-weight: 700; font-variant-numeric: tabular-nums; color: #B45309; text-align: right; }
  .ledger-bk-spill {
    display: grid;
    grid-template-columns: 4.5rem minmax(4.5rem, auto) 1fr 5.5rem 1.25rem;
    gap: 0.375rem;
    align-items: baseline;
    padding: 0.25rem 0.8125rem;
    font-size: 0.8125rem;
    border-top: 0.0625rem solid #E2E8F0;
    background: #EFF6FF;
  }
  .ledger-bk-spill-amt { font-weight: 700; font-variant-numeric: tabular-nums; color: #2563EB; text-align: right; }
  /* Parent/Coach "My Ledger" tab: one read-only summary card per linked player.
     Reuses the ledger-bk-* breakdown classes so it matches the admin editor view. */
  /* My Ledger → the Make a Payment entry point. Label AND color come from the ledger's own
     schedule (client-side, same source the pills use): red "Pay My Bill" when something is due or
     overdue, blue "Make a Payment" when nothing is due but money can still be paid ahead, and present
     but DISABLED at a $0 balance — it never disappears. Spec: src/BILLING-SCOPE.md.
     Sized to the house portal action button (.ws-btn: 13px / 0.5rem 1rem / radius 0.3125rem); the old
     `font: inherit` dragged in body's 16px/1.6, which is what made it 172x46. `color` carries
     !important like every other filled button in the portal (cf. .portal-panel .btn-primary) — a
     portal-scoped selector outranks a bare class selector, so plain `color` silently lost.
     The button is CENTERED at the END of the panel, below the last per-kid card, inside its own boxed
     section, with the processor note STACKED UNDER IT (JAMIE, Sep 25 2026, asked "under the button or
     leave it?" — under wins: the note is a caption to the CTA, the button stays the box's one focal point,
     and the row version already collapsed into a stack below ~500px anyway). The button is also exactly as
     WIDE as that note (JAMIE, Sep 25 2026) — align-self: stretch takes the note's own width, so the two edges
     line up with no fixed px to keep in sync if the note's wording or mark ever changes. The note is the processor's
     OFFICIAL MARK plus the words "online with" — a third-party trademark, so never recolor, filter or
     re-draw it; its durable bytes and its bundled /assets/img/logos/ path are wired in src/deploy-build.js.
     Keep this button a SIBLING of the dev time-travel row's div, never a child of it: production deletes
     that whole balanced div (stripBalancedDiv in src/deploy-build.js), so a child would be deleted with it.
     NOTE TO FUTURE EDITORS: never write that dev row's class name (or its button's id) anywhere in THIS
     file outside its own strip markers — the production build scans the shipped CSS for those tokens and
     fails the build, which is exactly what a comment here did on Sep 25 2026. */
  /* The button stands alone, no box and no processor line (Oct 1 2026 — was a bordered box with an
     "online with FreshBooks" lockup; the FreshBooks mark still lives on the Make a Payment tab's
     online card). The wrapper div stays because loadLedger toggles it hidden. */
  .parent-pay-box {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    width: fit-content; max-width: 100%; margin: 0.5rem auto 0;
    text-align: center;
  }
  .parent-pay-box[hidden] { display: none; }
  .parent-pay-btn {
    transform: translateY(10px);
    flex: none; align-self: stretch; margin: 0 -0.5px;
    display: inline-flex; align-items: center; justify-content: center; gap: 0.375rem;
    font-family: inherit; font-size: 0.875rem; font-weight: 700; line-height: 1.2;
    padding: 0.5625rem 1.25rem; border: none; border-radius: 0.3125rem;
    background: var(--primary); color: var(--white) !important; cursor: pointer;
    transition: background 0.15s ease;
  }
  .parent-pay-btn:hover { background: var(--primary-dark); }
  .parent-pay-btn.is-due { background: var(--pay-due); }
  .parent-pay-btn.is-due:hover { background: var(--pay-due-dark); }
  .parent-pay-btn:disabled,
  .parent-pay-btn.is-due:disabled { background: var(--ws-line); color: var(--ws-muted) !important; cursor: default; }
  .parent-ledger-card {
    background: #fff;
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.625rem;
    box-shadow: 0 0.0625rem 0.25rem rgba(0,32,78,0.06);
    margin-bottom: 1.25rem;
    overflow: hidden;
  }
  .parent-ledger-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    padding: 0.75rem 0.875rem;
    background: #F8FAFC;
    border-bottom: 0.0625rem solid var(--light-gray);
  }
  .parent-ledger-title { display: flex; flex-direction: column; gap: 0.125rem; min-width: 0; }
  .parent-ledger-name { font-weight: 800; color: var(--ws-ink); font-size: 1rem; }
  .parent-ledger-sub { color: var(--ws-ink-2); font-size: 0.75rem; display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; min-width: 0; }
  .parent-ledger-sub-sep { color: #8A97A6; }
  .parent-ledger-bal { display: flex; flex-direction: column; align-items: flex-end; gap: 0.25rem; text-align: right; margin-left: auto; }
  .parent-ledger-bal-label { display: block; font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.06em; color: #5A6B7C; }
  .parent-ledger-bal-row { display: inline-flex; align-items: center; gap: 0.375rem; }
  .parent-ledger-bal-amt { font-weight: 800; font-size: 1.125rem; color: var(--ws-ink); font-variant-numeric: tabular-nums; }
  .parent-ledger-bal-amt.is-owed { color: var(--ws-ink); }
  /* The color is what tells the two $0.00s apart (JAMIE, Sep 25 2026): navy when there are no charges
     at all, green once charges have been paid. */
  .parent-ledger-bal-amt.is-unbilled { color: var(--ws-ink); }
  .parent-ledger-bal-amt.is-paid { color: #1A7F37; }
  .parent-ledger-paid-box {
    display: inline-flex;
    align-items: center;
    background: #DCFCE7;
    border: 0.0625rem solid rgba(22, 163, 74, 0.35);
    border-radius: 999px;
    padding: 0.125rem;
  }
  .parent-ledger-paid-badge {
    background: #fff;
    color: #15803D;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    line-height: 1;
    padding: 0.25rem 0.4375rem;
    border-radius: 999px;
    box-shadow: inset 0 0 0 0.0625rem rgba(22, 163, 74, 0.3);
    white-space: nowrap;
  }
  .parent-ledger-toggle {
    flex: 0 0 auto;
    width: 1.875rem;
    height: 1.875rem;
    border-radius: 999px;
    border: 0.0625rem solid #C9D6E2;
    background: #fff;
    color: #5A6B7C;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
  }
  .parent-ledger-toggle:hover { background: #F1F5F9; color: #1E293B; border-color: #94A3B8; }
  .parent-ledger-toggle svg { width: 1rem; height: 1rem; display: block; transition: transform 0.18s ease; }
  .parent-ledger-toggle.is-open svg { transform: rotate(180deg); }
  @media (max-width: 360px) {
    .parent-ledger-head { padding: 0.625rem 0.75rem; }
    .parent-ledger-bal { gap: 0.1875rem; }
    .parent-ledger-bal-amt { font-size: 1rem; }
    .parent-ledger-paid-badge { padding: 0.1875rem 0.375rem; font-size: 0.5625rem; }
  }
  /* Narrow panels: the toggle drops to its own spot on EVERY card at the same panel
     width, so one card never wraps while its neighbor does (all drop together) — but
     it stays a circle and hangs centered, half over the head's bottom line (which is
     the card's bottom edge when collapsed). Card overflow opens so the hanging half
     stays visible; the head/body radii keep the rounded corners the clipping used to. */
  @container (max-width: 19rem) {
    .parent-ledger-card { overflow: visible; }
    .parent-ledger-head { position: relative; border-radius: 0.5625rem 0.5625rem 0 0; padding-bottom: 1.25rem; }
    .parent-ledger-card:has(.parent-ledger-body[hidden]) .parent-ledger-head { border-radius: 0.5625rem; }
    .parent-ledger-body { border-radius: 0 0 0.5625rem 0.5625rem; overflow: hidden; padding-top: 1.25rem; }
    .parent-ledger-toggle { position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 50%); z-index: 1; }
  }
  .parent-ledger-body { padding: 0.75rem 0.875rem 0.875rem; }
  .parent-ledger-body .ledger-bk-head { padding-left: 0; padding-right: 0; }
  .parent-ledger-body .ledger-bk-row,
  .parent-ledger-body .ledger-bk-total,
  .parent-ledger-body .ledger-bk-pay,
  .parent-ledger-body .ledger-bk-adj,
  .parent-ledger-body .ledger-bk-spill { padding-left: 0; padding-right: 0; }
  .parent-ledger-body .ledger-bk-sched { margin-left: -0.1875rem; margin-right: -0.1875rem; }
  .parent-ledger-empty-note { color: var(--ws-ink-2); font-size: 0.875rem; padding: 0.25rem 0; }
  .parent-ledger-loading { color: var(--ws-ink-2); padding: 1.25rem 0; text-align: center; }
  .parent-ledger-plan-val { font-weight: 700; color: var(--ws-ink); }
  .ledger-bk-plan-desc { flex-basis: 100%; color: #5A6B7C; font-size: 0.8125rem; }
  .parent-ledger-none { text-align: center; padding: 2rem 0.5rem; }
  .parent-ledger-none-title { font-weight: 700; color: var(--ws-ink); margin: 0 0 0.25rem; }
  .parent-ledger-none-note { color: var(--ws-ink-2); font-size: 0.875rem; margin: 0; }
  .ledger-editor-actions .ws-btn { flex: 0 0 auto; margin-top: 0; white-space: nowrap; }
  /* Stack the 4 action buttons into two full-width rows (Payments|Adjustments,
     Cancel|Save Changes) when the ledger panel itself is too narrow for all four
     side by side — container-relative, so it tracks the panel, not the viewport. */
  @container (max-width: 480px) {
    /* Stacked 2x2 grid: row1 = Payments | Adjustments, row2 = Cancel | Save Changes,
       matching the DOM/natural order (JAMIE, Sep 3 — swapped from the previous
       Payments|Cancel / Adjustments|Save arrangement). display:contents lets the four
       buttons become direct grid items of .ledger-editor-actions. */
    .ledger-editor-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
    .ledger-editor-actions-left { display: contents; }
    .ledger-editor-actions-right { display: contents; }
    .ledger-editor-actions .ws-btn { width: 100%; min-width: 0; }
    #addPaymentBtn { grid-column: 1; grid-row: 1; }
    #adjustmentBtn { grid-column: 2; grid-row: 1; }
    #ledgerCancelBtn { grid-column: 1; grid-row: 2; }
    #ledgerSaveBtn { grid-column: 2; grid-row: 2; }
  }
  .team-ledger-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.8125rem;
    border-top: 0.0625rem solid #E2E8F0;
    font-size: 0.8125rem;
  }
  .team-ledger-row:first-child { border-top: none; }
  .team-ledger-row-name { flex: 0 0 6.5rem; display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
  .team-ledger-row-first { font-weight: 600; color: #5A6B7C; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .team-ledger-row-last { font-weight: 800; color: var(--ws-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .team-ledger-row-main { flex: 1 1 auto; min-width: 0; }
  .team-ledger-row-main .team-ledger-progress-track { height: 0.4375rem; display: block; }
  .team-ledger-row-main .team-ledger-progress-fill { display: block; }
  .team-ledger-row-meta { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-top: 0.3125rem; flex-wrap: wrap; row-gap: 0.25rem; }
  .team-ledger-row-progress { font-size: 0.6875rem; color: #64748B; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .team-ledger-row-next { display: inline-flex; align-items: center; }
  .team-ledger-row-next-none { color: #94A3B8; }
  .team-ledger-progress {
    margin-top: 0.75rem;
    padding: 0.625rem 0.8125rem;
    background: #F8FAFC;
    border: 0.0625rem solid #E2E8F0;
    border-radius: 0.3125rem;
  }
  .team-ledger-progress-head { display: flex; justify-content: space-between; align-items: baseline; gap: 0.75rem; margin-bottom: 0.375rem; }
  .team-ledger-progress-label { font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.6875rem; color: #5A6B7C; }
  .team-ledger-progress-pct { font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ws-ink); font-size: 0.875rem; }
  .team-ledger-progress-track { position: relative; height: 0.625rem; background: #CBD5E1; border-radius: 0.9375rem; overflow: hidden; box-shadow: inset 0 0 0 0.0625rem rgba(15, 23, 42, 0.08); }
  .team-ledger-progress-track::before,
  .team-ledger-progress-track::after { content: ""; position: absolute; left: 0; right: 0; pointer-events: none; background-image: linear-gradient(90deg, transparent 0 calc(25% - 0.5px), rgba(15, 23, 42, 0.4) calc(25% - 0.5px) calc(25% + 0.5px), transparent calc(25% + 0.5px) calc(50% - 0.5px), rgba(15, 23, 42, 0.4) calc(50% - 0.5px) calc(50% + 0.5px), transparent calc(50% + 0.5px) calc(75% - 0.5px), rgba(15, 23, 42, 0.4) calc(75% - 0.5px) calc(75% + 0.5px), transparent calc(75% + 0.5px) 100%); }
  .team-ledger-progress-track::before { bottom: 0; height: 20%; }
  .team-ledger-progress-track::after { top: 0; height: 20%; }
  .team-ledger-progress-fill { height: 100%; width: 0; background: var(--primary); border-radius: 0.9375rem; transition: width 0.4s ease; }
  .team-ledger-progress-note { margin: 0.5rem 0 0; font-size: 0.75rem; color: #64748B; }
  .team-ledger-head { display: flex; align-items: center; gap: 0.75rem; min-width: 0; }
  .team-ledger-head > div:last-child { min-width: 0; }
  .team-ledger-head .ws-btn { flex-shrink: 0; margin-top: 0; }
  .team-ledger-subrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
  }
  .team-ledger-subrow > .ws-btn:not([hidden]) { margin-bottom: 0.5rem; }
  
  .team-ledger-summary-row { cursor: pointer; padding: 0.75rem 0.8125rem; }
  .team-ledger-summary-row:hover { background: #F1F5F9; }
  .team-ledger-summary-row .team-ledger-row-name { justify-content: center; font-weight: 800; color: var(--ws-ink); }
  .team-ledger-summary-row .team-ledger-row-next { color: #64748B; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .team-ledger-summary-row .team-ledger-progress-track { height: 0.5625rem; }
  .team-ledger-all {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.75rem 0.8125rem;
    margin-bottom: 0;
    background: #F0F7FF;
    border: 0.0625rem solid #C7DCF2;
    border-radius: 0.375rem;
  }
  .team-ledger-sep {
    height: 0.125rem;
    background: #ADC7E4;
    border-radius: 0.0625rem;
    margin: 0.75rem 0 1rem;
  }
  .team-ledger-all .team-ledger-row-name {
    flex: 0 0 6.5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    line-height: 1.15;
    min-width: 0;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    font-size: 0.75rem;
    color: var(--secondary);
  }
  .team-ledger-all .team-ledger-progress-track { height: 1.125rem; }
  .team-ledger-all .team-ledger-row-meta { margin-top: 0.375rem; }
  .team-ledger-all .team-ledger-row-progress { font-size: 0.75rem; font-weight: 600; color: var(--secondary); }
  .team-ledger-all .team-ledger-row-next { color: #64748B; font-variant-numeric: tabular-nums; white-space: nowrap; }
  #teamLedgerList .ledger-bk-sched-item {
    font-size: 0.6875rem;
    padding: 0.0625rem 0.3125rem;
    gap: 0.1875rem;
  }
  #teamLedgerList .ledger-bk-sched-date { min-width: 5ch; margin-right: 0.125rem; }
  #teamLedgerList .ledger-bk-sched-amt { min-width: 6ch; }
  #teamLedgerList .ledger-bk-sched-next,
  #teamLedgerList .ledger-bk-sched-due,
  #teamLedgerList .ledger-bk-sched-overdue,
  #teamLedgerList .ledger-bk-sched-paid {
    font-size: 0.5625rem;
    padding: 0.125rem 0.3125rem;
    min-width: 2.1rem;
  }
  .ws-check input { width: auto; margin: 0; accent-color: var(--primary); }
  /* Ledger breakdown shrinks with the portal-panel container, so it stays readable
     between ~916px viewports and the 760px mobile flip (where the panel widens again). */
  @container (max-width: 34rem) {
    .ledger-bk-head,
    .ledger-bk-row,
    .ledger-bk-total,
    .ledger-bk-pay,
    .ledger-bk-adj,
    .ledger-bk-spill {
      grid-template-columns: 4.25rem minmax(5rem, auto) 1fr 5rem 1.25rem;
      gap: 0.25rem;
      padding-left: 0.625rem;
      padding-right: 0.625rem;
    }
    .ledger-bk-head-desc,
    .ledger-bk-desc { padding-left: 0.75rem; }
  }
  @container (max-width: 30rem) {
    .ledger-bk-sched { gap: 0.25rem 0.375rem; }
    .ledger-bk-plan { gap: 0.25rem 0.75rem; }
    .ledger-bk-plan-label { flex-basis: 100%; }
    .ledger-bk-sched-item { padding: 0.09375rem 0.375rem; font-size: 0.75rem; }
    .ledger-bk-row,
    .ledger-bk-pay,
    .ledger-bk-adj,
    .ledger-bk-spill {
      grid-template-columns: 4.25rem minmax(5rem, auto) 1fr 5rem 1.25rem;
      gap: 0.1875rem 0.25rem;
      align-items: baseline;
    }
    .ledger-bk-date { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
    .ledger-bk-name { grid-column: 2; grid-row: 1; }
    .ledger-bk-pay-amt, .ledger-bk-adj-amt, .ledger-bk-amt, .ledger-bk-spill-amt { grid-column: 4; grid-row: 1; }
    .ledger-bk-desc { grid-column: 2 / 5; grid-row: 2; padding-left: 0; }
    .ledger-bk-del { grid-column: 5; grid-row: 1; align-self: center; }
    .ledger-bk-head-desc { display: none; }
    .ledger-bk-head-date { grid-column: 1; }
    .ledger-bk-head-name { grid-column: 2; }
    .ledger-bk-head-amt { grid-column: 4; }
    .ledger-bk-head-x { grid-column: 5; }
  }
  /* At 500px and below the ledger panel goes full-bleed (nearly full screen) and the
     breakdown keeps the Date as its OWN column (JAMIE, Sep 3 — previously it was merged
     under the Name; now the dedicated Date column is retained, with Name + Description
     sharing the middle and Amount + delete on the right). */
  @media (max-width: 500px) {
    .parent-ledger-bal-row { flex-direction: column-reverse; align-items: flex-end; gap: 0.25rem; }
    .portal-panel[data-panel="ledger"] { padding: 1.25rem 1rem; }
    .parent-ledger-body { padding: 0.75rem 0.625rem 0.875rem; }
    .parent-ledger-body .ledger-bk-sched { padding-left: 0.5rem; padding-right: 0.5rem; }
    /* Parent rows carry no delete buttons, so the fourth track is dead width — drop it and trim the
       fixed tracks, or the name column collapses to zero below ~400px (Oct 1 2026). */
    .parent-ledger-body .ledger-bk-head,
    .parent-ledger-body .ledger-bk-row,
    .parent-ledger-body .ledger-bk-total,
    .parent-ledger-body .ledger-bk-pay,
    .parent-ledger-body .ledger-bk-adj,
    .parent-ledger-body .ledger-bk-spill {
      grid-template-columns: 3.25rem minmax(0, 1fr) 5rem 0;
    }
    .portal-panel[data-panel="ledgers"] {      margin-left: -1.5rem;
      margin-right: -1.5rem;
      padding: 1.25rem 1rem;
      border-radius: 0.5rem;
    }
    .ledger-bk-head {
      grid-template-columns: 3.75rem minmax(0, 1fr) 5.5rem 1.25rem;
      gap: 0.125rem 0.25rem;
      padding: 0 0.375rem 0.25rem;
    }
    .ledger-bk-head-desc { display: none; }
    .ledger-bk-head-date { grid-column: 1; }
    .ledger-bk-head-name { grid-column: 2; }
    .ledger-bk-head-amt { grid-column: 3; }
    .ledger-bk-head-x { grid-column: 4; }
    .ledger-bk-row,
    .ledger-bk-pay,
    .ledger-bk-adj,
    .ledger-bk-spill {
      grid-template-columns: 3.75rem minmax(0, 1fr) 5.5rem 1.25rem;
      gap: 0.125rem 0.25rem;
      padding: 0.375rem;
      align-items: baseline;
    }
    .ledger-bk-name { grid-column: 2; grid-row: 1; font-size: 0.875rem; min-width: 0; }
    .ledger-bk-date { grid-column: 1; grid-row: 1 / span 2; align-self: center; font-size: 0.75rem; white-space: nowrap; }
    .ledger-bk-pay-amt, .ledger-bk-adj-amt, .ledger-bk-amt, .ledger-bk-spill-amt {
      grid-column: 3; grid-row: 1; font-size: 0.8125rem; white-space: nowrap; text-align: right;
    }
    .ledger-bk-desc { grid-column: 2 / -1; grid-row: 2; font-size: 0.8125rem; padding-left: 0; min-width: 0; }
    .ledger-bk-del { grid-column: 4; grid-row: 1; justify-self: end; align-self: center; }
    /* Balance row: label under the Name column, value right-aligned under the Amount
       column so it lines up with the amounts above (JAMIE, Sep 3). */
    .ledger-bk-total { grid-template-columns: 3.75rem minmax(0, 1fr) 5.5rem 1.25rem; gap: 0.125rem 0.25rem; padding: 0.5rem 0.375rem; align-items: baseline; }
    .ledger-bk-total-label { grid-column: 2; font-size: 0.8125rem; }
    .ledger-bk-total-amt { grid-column: 3; font-size: 0.8125rem; }
  }

  /* ---------- Peak Report (Manage Ledgers): who is up to date on Peak ---------- */
  .peak-report-summary {
    margin: 0 0 0.5rem;
    font-size: 0.8125rem;
    color: var(--ws-ink-2);
    line-height: 1.5;
  }
  .peak-report-summary-owed { color: #B45309; font-weight: 800; }
  .peak-report-summary-ok { color: #15803D; font-weight: 800; }
  /* Legend (between the summary and the grid) plus the one-line billing note. */
  .peak-report-note {
    display: flex;
    flex-direction: column;
    gap: 0.3125rem;
    margin: 0 0 0.625rem;
    font-size: 0.6875rem;
    color: #94A3B8;
    line-height: 1.4;
    text-align: left;
  }
  .peak-report-legend {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem 0.875rem;
    color: #64748B;
  }
  .peak-report-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 0.3125rem;
    font-weight: 600;
  }
  .peak-report-legend-item .peak-report-none { font-size: 0.9375rem; line-height: 1; font-weight: 700; }
  .peak-report-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    border: 0.0625rem solid #E2E8F0;
    border-radius: 0.375rem;
    background: var(--white);
  }
  .peak-report-table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.75rem;
    text-align: center;
  }
  .peak-report-table th,
  .peak-report-table td {
    padding: 0.375rem 0.1875rem;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  .peak-report-table thead th {
    background: #F1F5F9;
    color: #5A6B7C;
    font-size: 0.625rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-bottom: 0.0625rem solid #DCE1E8;
  }
  .peak-report-table tbody tr { border-bottom: 0.0625rem solid #EEF2F7; }
  .peak-report-table tbody tr:last-child { border-bottom: none; }
  .peak-report-table tbody tr:hover td,
  .peak-report-table tbody tr:hover th { background: #F8FAFC; }
  /* The Member column stays put while the month columns scroll sideways. */
  .peak-report-member {
    position: sticky;
    left: 0;
    z-index: 2;
    text-align: left;
    background: var(--white);
    min-width: 5.75rem;
    max-width: 13rem;
    box-shadow: inset -0.0625rem 0 0 #E2E8F0;
  }
  .peak-report-table thead .peak-report-member { z-index: 3; background: #F1F5F9; }
  .peak-report-name {
    display: block;
    font-weight: 800;
    color: var(--ws-ink);
    font-size: 0.75rem;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .peak-report-meta {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-wrap: wrap;
    margin-top: 0.125rem;
  }
  .peak-report-kind { font-size: 0.625rem; font-weight: 700; color: #64748B; }
  .peak-report-month { min-width: 1.75rem; }
  /* The dense grid columns keep the tight horizontal padding, so the 14-column table
     fits its panel without a scrollbar at desktop and tablet-landscape widths. The
     Paid column keeps a proper right pad so its amounts never sit flush on the edge. */
  .peak-report-table .peak-report-month { padding-left: 0.125rem; padding-right: 0.125rem; }
  .peak-report-table .peak-report-paid { padding-left: 0.25rem; padding-right: 0.5rem; }
  /* Month cells are states, not numbers: check = paid, X = billed but unpaid, dash = not billed yet. */
  .peak-report-mark { width: 0.8125rem; height: 0.8125rem; display: inline-block; vertical-align: middle; }
  .peak-report-yes { color: #15803D; }
  .peak-report-no { color: #DC2626; }
  .peak-report-none { color: #CBD5E1; }
  .peak-report-paid {
    min-width: 3.125rem;
    text-align: right;
    color: var(--ws-ink);
  }
  .peak-report-paid-amt { font-weight: 800; }
  .peak-report-paid-zero { color: #CBD5E1; }
  .peak-report-empty {
    text-align: center;
    color: var(--ws-ink-2);
    padding: 1.5rem 0.75rem;
    font-size: 0.8125rem;
  }
  /* Month headers: "Sep" when there's room, "S" when there isn't. The three-letter
     label is the widest part of these columns, so at narrow panels the abbreviations
     are what buys the table its fit — the full month stays in the header's tooltip.
     (Breakpoint measured against the grid's own min-content at the current root size:
     the three-letter grid bottoms out at ~485px, and the panel's content box runs
     ~79px wider than the scroll wrapper — so 3-letter mode is only safe once the panel
     content box clears ~564px. Below that the single letters fit down to a ~381px
     table / ~460px content box; past that the wrapper scrolls with the member pinned.) */
  .peak-report-mo-abbr { display: none; }
  @container (max-width: 565px) {
    .peak-report-mo-full { display: none; }
    .peak-report-mo-abbr { display: inline; }
    .peak-report-month { min-width: 1.25rem; }
    .peak-report-member { min-width: 5rem; }
  }


  
  /* ---------- Bug Tracker tab (admin-only; TestAdmin edits priority/severity) ---------- */
  #bugList { min-height: 0; }
  #bugTrackerToolbar { scroll-margin-top: calc(var(--header-h) + 4.5rem); outline: none; }
  .bug-row {
    background: var(--white);
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.5rem;
    padding: 0.4375rem 0.75rem;
    margin: 0.5rem 0;
    text-align: left;
  }
  .bug-row-head {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
    cursor: pointer;
    user-select: none;
    border-radius: 0.375rem;
  }
  .bug-row-head:hover { background: #F8FAFC; }
  .bug-row-head:focus-visible { outline: 2px solid var(--ws-ink); outline-offset: 2px; }
  .bug-chev {
    font-size: 1.5rem;
    line-height: 1;
    color: var(--ws-muted);
    transition: transform 0.15s ease;
  }
  .bug-chev::before { content: "\25C2"; }
  .bug-row.bug-open .bug-chev { transform: rotate(-90deg); }
  .bug-pin {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.625rem;
    height: 1.625rem;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--ws-muted);
    cursor: pointer;
    border-radius: 0.375rem;
    flex: 0 0 auto;
  }
  .bug-pin:hover { background: #EEF1F6; color: var(--ws-ink); }
  .bug-pin.is-pinned { color: #B5721E; }
  .bug-pin.is-pinned:hover { background: #FBF3E7; color: #8F5A14; }
  .bug-pin:disabled { opacity: 0.5; cursor: wait; }
  .bug-row-detail { margin-top: 0.625rem; padding-top: 0.625rem; border-top: 1px dashed var(--ws-line); }
  .bug-row:not(.bug-open) .bug-row-detail { display: none; }
  .bug-title {
    flex: 1 1 0%;
    min-width: 0;
    font-family: var(--font-primary);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.4px;
    color: var(--secondary);
  }
  .bug-no {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.4px;
    color: #33415C;
    background: #EEF2F7;
    border: 1px solid #D9E2EC;
    border-radius: 0.375rem;
    padding: 0.125rem 0.4375rem;
    white-space: nowrap;
  }
  .bug-sev {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    padding: 0.0625rem 0.375rem;
    border-radius: 999px;
  }
  .bug-sev-minor { background: #E3F2FD; color: #1565C0; }
  .bug-sev-major { background: #FFF8E1; color: #F57F17; }
  .bug-sev-critical { background: #FFF3E0; color: #E65100; }
  .bug-sev-blocker { background: #FFEBEE; color: #C62828; }
  .bug-page, .bug-browser {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 0.0625rem 0.375rem;
    border-radius: 999px;
    background: #F3F4F6;
    color: #4B5563;
    border: 1px solid #E5E7EB;
    white-space: nowrap;
  }
  .bug-prio {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    padding: 0.0625rem 0.375rem;
    border-radius: 999px;
  }
  .bug-prio-low { background: #E8F5E9; color: #2E7D32; }
  .bug-prio-normal { background: #E3F2FD; color: #1565C0; }
  .bug-prio-high { background: #FFF3E0; color: #E65100; }
  .bug-prio-urgent { background: #FFEBEE; color: #C62828; }
  .bug-prio-new { background: #EDE9FE; color: #6D28D9; border: 1px solid #DDD6FE; }
  .bug-status-chip {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    padding: 0.0625rem 0.375rem;
    border-radius: 999px;
  }
  .bug-status-open { background: #E3F2FD; color: #1565C0; }
  .bug-status-in_progress { background: #FFF8E1; color: #B26A00; }
  .bug-status-resolved { background: #E8F5E9; color: #2E7D32; }
  .bug-status-wontfix { background: #F3F4F6; color: #6B7280; }
  .bug-date { font-size: 0.75rem; color: var(--ws-muted); white-space: nowrap; margin-left: auto; }
  .bug-pill-updated {
    font-size: 0.5rem;
    font-weight: 700;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: #fff;
    background: #D64545;
    padding: 0.0625rem 0.3125rem;
    border-radius: 999px;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    line-height: 1.4;
    vertical-align: middle;
  }
  .bug-row.bug-row-new { background: #FFF7F6; border-color: #F0BFC0; }
  .bug-row.bug-row-new .bug-title { color: #8E2E2E; }
  .bug-pills {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
  }
  .bug-desc {
    margin: 0.5rem 0 0;
    font-size: 0.84375rem;
    line-height: 1.5;
    color: #374151;
    white-space: pre-wrap;
  }
  .bug-reported {
    margin: 0.625rem 0 0;
    font-size: 0.75rem;
    color: var(--ws-muted);
  }
  .bug-meta {
    margin: 0.375rem 0 0;
    font-size: 0.75rem;
    color: var(--ws-muted);
  }
  .bug-row-actions {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-top: 1.125rem;
    flex-wrap: wrap;
  }
  .bug-toolbar-fields {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.625rem;
    flex: 1 1 auto;
    min-width: 0;
  }
  .bug-cluster {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-left: auto;
    flex-shrink: 0;
  }
  .bug-label {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    font-size: 0.78125rem;
    color: #33415C;
  }
  .bug-status, .bug-prio-sel, .bug-sev-sel, .bug-page-sel, .bug-browser-sel { width: auto; padding: 0.3125rem 0.5rem; }
  .bug-del { padding: 0.4rem 0.875rem; }
  .bug-toolbar-save { padding: 0.4rem 0.875rem; }
  #bugMyIssuesBtn.is-active { background: var(--secondary); color: var(--white); border-color: var(--secondary); }
  #bugMyIssuesBtn.is-active:hover { background: var(--secondary); }
  .bug-shots { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.625rem; }
  .bug-shot { display: block; }
  .bug-shot img {
    max-height: 5.5rem;
    max-width: 9rem;
    object-fit: cover;
    border: 1px solid var(--ws-line);
    border-radius: 0.375rem;
    display: block;
  }
  /* Issue comments (JAMIE, Sep 1): read in the expanded row, added from the editor. */
  .bug-row-comments { margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px dashed var(--ws-line); }
  .bug-row-comments-title, .bug-comments-title {
    margin: 0 0 0.5rem;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: #33415C;
  }
  .bug-comment-loading { margin: 0; font-size: 0.75rem; color: var(--ws-muted); }
  .bug-comment {
    padding: 0.5rem 0.625rem;
    background: #F8FAFC;
    border: 1px solid #E5E7EB;
    border-radius: 0.375rem;
    margin-bottom: 0.5rem;
  }
  .bug-comment-meta { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; font-size: 0.6875rem; color: var(--ws-muted); margin-bottom: 0.25rem; }
  .bug-comment-body { font-size: 0.84375rem; line-height: 1.5; color: #374151; white-space: pre-wrap; }
  .bug-comment-actions { display: inline-flex; gap: 0.125rem; flex: 0 0 auto; }
  .bug-comment-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--ws-muted);
    cursor: pointer;
    border-radius: 0.375rem;
    flex: 0 0 auto;
  }
  .bug-comment-icon:hover { background: #EEF1F6; color: var(--ws-ink); }
  .bug-comment-icon.armed { color: #D64545; }
  .bug-comment-icon.armed:hover { background: #FFEDEB; color: #B02828; }
  .bug-comment-mini {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.25rem 0.5rem;
    border: none;
    background: transparent;
    color: var(--ws-muted);
    cursor: pointer;
    border-radius: 0.375rem;
    font-size: 0.75rem;
    font-weight: 600;
    flex: 0 0 auto;
  }
  .bug-comment-mini:hover { background: #EEF1F6; color: var(--ws-ink); }
  .bug-comment-mini.is-danger:hover { background: #FFEDEB; color: #B02828; }
  .bug-comment-confirm {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.375rem;
    margin-top: 0.375rem;
    padding-top: 0.375rem;
    border-top: 1px dashed #E5E7EB;
    font-size: 0.75rem;
    color: #B02828;
    font-weight: 600;
  }
  .bug-comment-edit-box { margin-top: 0.375rem; }
  .bug-comment-edit-box .ws-input { height: auto; width: 100%; }
  .bug-comment-edit-actions { display: flex; justify-content: flex-end; gap: 0.375rem; margin-top: 0.375rem; }
  .bug-comment { scroll-margin-top: calc(var(--header-h) + 1rem); }
  .bug-comment-new { animation: bugCommentFlash 3s ease-out 1; }
  @keyframes bugCommentFlash {
    0% { background: #FFEDEB; border-color: #F2B8B5; box-shadow: 0 0 0 3px rgba(214, 69, 69, 0.15); }
    100% { background: #F8FAFC; border-color: #E5E7EB; box-shadow: none; }
  }
  .bug-comments { margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--ws-line); }
  .bug-comment-list { max-height: 18rem; overflow-y: auto; }
  .bug-comment-add { display: flex; flex-direction: column; gap: 0.5rem; margin-top: 0.625rem; }
  .bug-comment-add .ws-input { flex: 0 0 auto; height: auto; }
  .bug-comment-add .ws-btn { align-self: flex-end; }
  @media (max-width: 480px) {
    .bug-comment-add .ws-btn { align-self: stretch; width: 100%; }
  }
  .bug-comment-note { margin: 0.5rem 0 0; font-size: 0.75rem; color: var(--ws-muted); }
  /* Pagination (JAMIE, Sep 1): default 15/page, options 25/50. Compact footer bar. */
  .bug-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem 0.75rem;
    margin: 0.75rem 0 0.25rem;
    padding-top: 0.625rem;
    border-top: 1px solid var(--ws-line);
  }
  .bug-pager-info { font-size: 0.75rem; color: var(--ws-muted); white-space: nowrap; }
  .bug-pager-nav { display: flex; align-items: center; gap: 0.375rem; margin-left: auto; }
  .bug-pager-size { display: inline-flex; align-items: center; gap: 0.3125rem; font-size: 0.75rem; color: var(--ws-muted); }
  .bug-pager-size select.ws-input { width: auto; min-width: 3.25rem; padding: 0.1875rem 0.3125rem; flex: none; }
  .bug-pager-num { min-width: 5.5rem; text-align: center; font-size: 0.8125rem; color: #33415C; white-space: nowrap; }
  .bug-pager-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; padding: 0;
    background: #E9F1F9 !important; color: var(--ws-ink-2) !important;
    border: 0.0625rem solid #C5D9EC; border-radius: 0.3125rem;
    font-size: 1.125rem; line-height: 1; cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
  }
  .bug-pager-btn:hover:not(:disabled) { background: #DCE9F6 !important; }
  .bug-pager-btn:disabled { opacity: 0.45; cursor: default; }
  /* Narrow container: stack the info over a centered nav; on phones drop the "Per page" text label. */
  @container (max-width: 540px) {
    .bug-pager { flex-direction: column; align-items: center; gap: 0.375rem; }
    .bug-pager-nav { margin-left: 0; }
  }
  @container (max-width: 400px) {
    .bug-pager-size span { display: none; }
    .bug-pager-size select.ws-input { min-width: 2.75rem; }
  }
  .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid > #btTitleRow,
  .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid > #btDescRow,
  .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid > #btShotsGroup,
  .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid > #btShotExistingGroup { grid-column: 1 / -1; }
  .portal-panel[data-panel="bugtracker"] .roster-editor-head h3.bug-editor-title { font-size: 1.125rem; }
  .portal-panel[data-panel="bugtracker"] textarea.ws-input { resize: vertical; }
  .portal-panel[data-panel="bugtracker"] #btDesc { font-size: 0.8125rem; line-height: 1.55; }
  #btShots { padding: 0.375rem; }
  .bug-shot-preview { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.625rem; }
  .bug-shot-preview.is-empty { display: none; }
  .bug-shot-preview figure { margin: 0; position: relative; }
  .bug-shot-preview img { max-height: 5rem; border: 1px solid var(--ws-line); border-radius: 0.375rem; display: block; }
  .shot-remove {
    position: absolute;
    top: -0.375rem;
    right: -0.375rem;
    width: 1.25rem;
    height: 1.25rem;
    border: 0;
    border-radius: 50%;
    background: #C62828;
    color: #fff;
    font-size: 0.875rem;
    line-height: 1.1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .bug-shot-note { margin: 0.5rem 0 0; font-size: 0.75rem; color: var(--ws-muted); }
  @media (max-width: 640px) {
    .portal-panel[data-panel="bugtracker"] #bugEditor .form-grid { grid-template-columns: 1fr; }
  }
  

  /* ---------- Hero Slides tab (admin; real production feature — NOT stripped) ---------- */
  #heroSlidesList { min-height: 0; }
  #heroSlidesToolbar { scroll-margin-top: calc(var(--header-h) + 4.5rem); outline: none; }
  #heroNewBtn { white-space: nowrap; }
  .hs-row {
    background: var(--white);
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.5rem;
    padding: 0.4375rem 0.75rem;
    margin: 0.5rem 0;
    text-align: left;
  }
  .hs-row-head {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
  }
  .hs-row-actions { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.4375rem; }
  .hs-row-move { display: flex; gap: 0.375rem; width: 5.125rem; justify-content: flex-end; }
  .hs-move { min-width: 2.375rem; padding: 0.3125rem 0.375rem; font-size: 1rem; line-height: 1.1; }
  .hs-move:disabled { opacity: 0.35; cursor: default; }
  .hs-row-btns { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-left: auto; }
  .hs-title { font-weight: 700; font-size: 0.9375rem; }
  .hs-date { margin-left: auto; font-size: 0.75rem; color: var(--ws-muted, #5B6B7C); }
  .hs-pos {
    min-width: 1.75rem;
    height: 1.75rem;
    padding: 0 0.375rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--ws-ink, #00204E);
    color: #fff;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.8125rem;
  }
  .hs-thumb {
    width: 3.25rem;
    height: 2.125rem;
    border-radius: 0.25rem;
    overflow: hidden;
    background: #E8EDF4;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
  }
  .hs-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
  .hs-sub { width: 100%; color: var(--ws-muted, #5B6B7C); font-size: 0.8125rem; }
  .hs-sub-none { font-style: italic; opacity: 0.65; }
  .hs-badge {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 0.1875rem 0.5rem;
    border-radius: 999px;
  }
  .hs-badge-on { background: #E3F4E8; color: #1B7A3D; }
  .hs-badge-off { background: #F2E7E7; color: #9A3B3B; }
  .hs-badge-portrait { background: #E8F0FB; color: #2C5F9E; }
  .hs-badge-tablet { background: #EFE8FB; color: #5B3E9E; }
  .hs-opt { color: var(--ws-muted, #5B6B7C); font-weight: 400; }
  .portal-panel[data-panel="heroslides"] #heroSlideEditor .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .portal-panel[data-panel="heroslides"] #heroSlideEditor .form-grid > .form-grid-full { grid-column: 1 / -1; }
  .portal-panel[data-panel="heroslides"] .roster-editor-head h3.hs-editor-title { font-size: 1.125rem; }
  .portal-panel[data-panel="heroslides"] textarea.ws-input { resize: vertical; }
  #hsPosition { max-width: 6rem; }
  .hs-check-group { display: flex; align-items: center; min-height: 2.375rem; }
  .hs-check-group .ws-check { margin: 0; }
  .hs-btn-grid { grid-column: 1 / -1; }
  .hs-btn-grid .hs-btn-col { margin-top: 0.75rem; }
  .hs-btn-grid .hs-btn-col:first-child { margin-top: 0; }
  @media (min-width: 641px) {
    .hs-btn-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 1.125rem; }
    .hs-btn-grid .hs-btn-col { margin-top: 0; }
  }
  .hs-hint { margin: 0 0 0.25rem; font-size: 0.75rem; color: var(--ws-muted, #5B6B7C); }
  @media (max-width: 640px) {
    .portal-panel[data-panel="heroslides"] #heroSlideEditor .form-grid { grid-template-columns: 1fr; }
  }

  /* Hero Slides — narrow screens: keep the layout intact down to 320px.
     The 3 action buttons move to their own full-width line and share it
     evenly; arrows stay left. */
  @media (max-width: 500px) {
    .portal-panel[data-panel="heroslides"] { padding: 1.5rem 1rem; }
    .hs-row { padding: 0.4375rem 0.5625rem; }
    .hs-row-actions { flex-wrap: wrap; }
    .hs-row-move { justify-content: flex-start; }
    .hs-row-btns { flex: 1 1 100%; margin-left: 0; }
    .hs-row-btns .ws-btn { flex: 1 1 0; min-width: 0; padding-left: 0.375rem; padding-right: 0.375rem; white-space: nowrap; }
    #heroSlidesToolbar { display: flex; }
    #heroSlidesToolbar .teams-toolbar-left { display: flex; flex: 1 1 auto; }
    #heroNewBtn { flex: 1 1 auto; width: 100%; max-width: none; justify-self: stretch; }
  }

  /* ---------- Social Tiles tab (admin; real production feature — NOT stripped) ----------
     The tile rows reuse the hero-slides list classes (.hs-row, .hs-pos, .hs-thumb,
     .hs-badge, .hs-move, .hs-title, .hs-sub, .hs-row-*, including their <=500px
     wrap behavior) so both admin lists look and behave identically. Only the
     per-account grouping, the photo picker and the caption preview are new. */
  #socialTilesLists { min-height: 0; }
  #socialTilesMsg { scroll-margin-top: calc(var(--header-h) + 4.5rem); outline: none; }
  .st-group {
    background: rgba(0, 32, 78, 0.03);
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.625rem;
    padding: 0.625rem 0.75rem 0.75rem;
    margin: 0.875rem 0;
    text-align: left;
  }
  .st-group-head { display: flex; align-items: center; gap: 0.625rem; flex-wrap: wrap; }
  .st-group-head h3 { margin: 0; font-size: 1rem; font-weight: 800; color: var(--ws-ink, #00204E); }
  .st-count { font-size: 0.75rem; font-weight: 700; color: var(--ws-muted, #5B6B7C); }
  /* The Hide Tile switch in each group head. A hidden card dims its rows so the
     state is obvious without reading the checkbox. */
  .st-card-toggle { font-size: 0.75rem; font-weight: 700; color: var(--ws-muted, #5B6B7C); }
  .st-group.is-hidden .st-group-list { opacity: 0.55; }
  .st-group.is-hidden .st-count { opacity: 0.6; }
  .st-new { margin: 0 0 0 auto; }
  .st-new:disabled { opacity: 0.5; cursor: default; }
  .st-empty { margin: 0.625rem 0 0.125rem; font-size: 0.8125rem; font-style: italic; color: var(--ws-muted, #5B6B7C); }
  .st-uploading { margin: 0.5rem 0 0; font-size: 0.8125rem; font-weight: 700; color: var(--ws-ink, #00204E); display: flex; align-items: center; gap: 0.375rem; }
  .st-photo-row { display: flex; align-items: center; gap: 0.625rem; flex-wrap: wrap; }
  .st-photo-row .st-file { flex: 1 1 13rem; min-width: 0; max-width: 100%; }
  .st-photo-preview {
    width: 4.5rem;
    height: 4.5rem;
    flex: 0 0 auto;
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.375rem;
    background: #E8EDF4 center/cover no-repeat;
  }
  .st-spin {
    width: 1rem;
    height: 1rem;
    flex: 0 0 auto;
    border: 0.125rem solid rgba(0, 32, 78, 0.22);
    border-top-color: var(--ws-ink, #00204E);
    border-radius: 50%;
    animation: spin 0.7s linear infinite;
  }
  .lite .st-spin { animation-duration: 1.8s; }
  .st-preview-wrap { margin: 0.875rem 0 0; }
  .st-preview-label {
    display: block;
    margin-bottom: 0.375rem;
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ws-muted, #5B6B7C);
  }
  .st-preview-card {
    width: 15.5rem;
    max-width: 100%;
    padding: 0.5rem 0.75rem;
    background: var(--white);
    border: 0.0625rem solid var(--ws-line);
    border-radius: 0.5rem;
  }
  .st-preview-card .social-caption { margin-bottom: 0; }
  .portal-panel[data-panel="social"] #socialTileEditor .form-grid { grid-template-columns: 1fr; }
  .portal-panel[data-panel="social"] .roster-editor-head h3.st-editor-title { font-size: 1.125rem; }
  .portal-panel[data-panel="social"] textarea.ws-input { resize: vertical; }
  @media (max-width: 500px) {
    .portal-panel[data-panel="social"] { padding: 1.5rem 1rem; }
    .st-group { padding: 0.5625rem 0.5625rem 0.625rem; }
    .st-new { margin-left: 0; flex: 1 1 100%; }
    .st-photo-preview { width: 3.75rem; height: 3.75rem; }
  }

/* ---------- Admin Tools submenu (Sep 20 2026, JAMIE) ----------
   The nav shows one level at a time. .portal-nav-subs is set by window.apexNavSync (src/app.js)
   whenever the admin sections are the level on screen: the .portal-back row takes the Admin Tools
   slot and every .portal-sub tab (the administrative sections) appears, while the top-level tabs
   are hidden. Kept at the END of the file on purpose — these rules have to beat the mobile grid's
   own .portal-tab rules and the #010 rest-mark collapse, which are declared earlier. */
/* The arrows are inline SVG, NOT glyphs: the nav's webfonts have no U+2190/U+25B8, so the browser
   falls back to a font whose line box is nearly twice a tab's height — the Back row measured 60px
   against the other tabs' 32px on a 390px phone, and no line-height on the (atomic) icon box could
   bring it back. An SVG icon has no font metrics at all, so the row height is the row height. */
.portal-tab .nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: -0.125em;
  line-height: 1;
}
.portal-tab .nav-icon svg {
  display: block;
  width: 0.875rem;
  height: 0.875rem;
}
.portal-tab .nav-arrow {
  margin-left: 0.3125rem;
  color: var(--gray-text);
}
.portal-tab .back-arrow {
  margin-right: 0.3125rem;
}
.portal-nav.portal-nav-parent-active > .portal-tab.portal-nav-parent { background: var(--secondary); color: var(--white); }
.portal-nav.portal-nav-parent-active > .portal-tab.portal-nav-parent .nav-arrow { color: rgba(255, 255, 255, 0.75); }
body.apex-design-blue .portal-nav.portal-nav-parent-active > .portal-tab.portal-nav-parent { background: var(--primary); color: var(--white); }
body.apex-design-blue .portal-nav.portal-nav-parent-active > .portal-tab.portal-nav-parent .nav-arrow { color: var(--secondary); }
.portal-nav:not(.portal-nav-subs) > .portal-back { display: none; }
.portal-nav.portal-nav-subs > .portal-back { display: block; }
/* The two level rules are both conditional on Admin Tools EXISTING for this role (:has), so a role
   whose allowed-tab list has no admintools — e.g. before the get_my_dashboard re-run ships it, or a
   non-admin who never gets it — keeps the flat one-level nav it has today. The child marker is
   .portal-nav-sub and NOT .portal-sub, which is already the panels' subtitle-paragraph class: reusing
   that name gave every administrative tab its 1.75rem margin-bottom, which stretched the shared grid
   row and made the (margin-less) Back row render at twice the height of the tabs beside it. */
.portal-nav:has(> .portal-tab[data-tab="admintools"]):not(.portal-nav-subs) > .portal-tab.portal-nav-sub { display: none; }
.portal-nav.portal-nav-subs > .portal-tab:not(.portal-nav-sub):not(.portal-back) { display: none; }

  /* ---- Form Inquiries (Admin Tools → Form Inquiries, Sep 21 2026, JAMIE) ------
     Every message sent through the About page's Contact Us form, newest first.
     The list is a grid "table" — a head row plus one .inq-row per inquiry — that
     collapses on CONTAINER width (the same technique as the Manage Teams table),
     because the panel is narrow on a phone and wide on a desktop and the message
     column is the one that needs the room. Five columns: Name (with the received
     time stacked under it, mail-client style, so the message keeps the width),
     Email, Topic, Message, Delete. A reason to keep it tight: the panel's own
     column is only ~795px on a 1920 desktop (the portal layout caps at 66.25rem),
     so a sixth timestamp column would squeeze the message to nothing. */
  [data-panel="forminquiries"] .inq-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-bottom: 0.875rem;
  }
  [data-panel="forminquiries"] .inq-count {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--ws-muted);
  }
  [data-panel="forminquiries"] .inq-loading {
    padding: 2.25rem 1rem;
    text-align: center;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--ws-muted);
    animation: inqPulse 1.2s ease-in-out infinite;
  }
  @keyframes inqPulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
  [data-panel="forminquiries"] .inq-table {
    border: 0.0625rem solid var(--light-gray);
    border-radius: 0.5rem;
    overflow: hidden;
    container-type: inline-size;
  }
  [data-panel="forminquiries"] .inq-table-head,
  [data-panel="forminquiries"] .inq-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr) minmax(0, 0.7fr) minmax(0, 2.4fr) 5rem;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
  }
  [data-panel="forminquiries"] .inq-table-head {
    align-items: center;
    background: #B9C0CA;
    border-bottom: 0.0625rem solid #9CA5B1;
  }
  [data-panel="forminquiries"] .inq-table-head span {
    font-size: 0.6875rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: #2F3640;
  }
  [data-panel="forminquiries"] .inq-table-head .inq-col-act { text-align: right; }
  [data-panel="forminquiries"] .inq-row {
    align-items: start;
    background: var(--white);
    border-bottom: 0.0625rem solid #DCE1E8;
    font-size: 0.8125rem;
    color: #3F4A5A;
  }
  [data-panel="forminquiries"] .inq-row:last-child { border-bottom: none; }
  [data-panel="forminquiries"] .inq-row:hover { background: #F4F6F9; }
  [data-panel="forminquiries"] .iq-name { min-width: 0; overflow-wrap: anywhere; }
  [data-panel="forminquiries"] .iq-from { font-weight: 800; color: var(--secondary); }
  [data-panel="forminquiries"] .iq-when { display: block; margin-top: 0.125rem; font-size: 0.75rem; font-weight: 400; color: var(--ws-muted); }
  /* break-word (not anywhere) here: the email carries <wbr> hints after "@" and ".", and
     break-word prefers those over splitting a local-part in half. */
  [data-panel="forminquiries"] .iq-email { min-width: 0; overflow-wrap: break-word; }
  [data-panel="forminquiries"] .iq-email a { color: var(--primary); text-decoration: none; }
  [data-panel="forminquiries"] .iq-email a:hover { text-decoration: underline; }
  /* The message keeps its own line breaks (pre-wrap) — a parent who wrote three
     paragraphs gets three paragraphs — and long unbroken strings wrap rather than
     widening the table. */
  [data-panel="forminquiries"] .iq-msg { min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ws-ink); }
  [data-panel="forminquiries"] .inq-actions { display: flex; justify-content: flex-end; }
  [data-panel="forminquiries"] .inq-actions .ws-btn { width: 100%; max-width: 5rem; }
  /* Below ~720px of table the columns stop being readable side by side, so the head
     row goes and the row becomes a stacked card: name + time, email / topic, the
     message, then Delete. */
  @container (max-width: 720px) {
    [data-panel="forminquiries"] .inq-table-head { display: none; }
    [data-panel="forminquiries"] .inq-row {
      grid-template-columns: minmax(0, 1fr) auto;
      grid-template-areas:
        "name  name"
        "email topic"
        "msg   msg"
        "act   act";
      gap: 0.375rem 0.75rem;
      padding: 0.875rem 1rem;
    }
    [data-panel="forminquiries"] .iq-name { grid-area: name; }
    [data-panel="forminquiries"] .iq-email { grid-area: email; }
    [data-panel="forminquiries"] .iq-topic { grid-area: topic; text-align: right; }
    [data-panel="forminquiries"] .iq-msg { grid-area: msg; margin-top: 0.125rem; }
    [data-panel="forminquiries"] .inq-actions { grid-area: act; }
    [data-panel="forminquiries"] .inq-actions .ws-btn { width: auto; max-width: none; }
    [data-panel="forminquiries"] .iq-email::before,
    [data-panel="forminquiries"] .iq-topic::before {
      content: attr(data-label) ": ";
      font-size: 0.6875rem;
      font-weight: 800;
      text-transform: uppercase;
      letter-spacing: 0.05em;
      color: var(--ws-muted);
    }
  }
  /* Phone-width panels: one field per line. */
  @container (max-width: 420px) {
    [data-panel="forminquiries"] .inq-row {
      grid-template-columns: minmax(0, 1fr);
      grid-template-areas: "name" "email" "topic" "msg" "act";
    }
    [data-panel="forminquiries"] .iq-topic { text-align: left; }
  }
