/* ---- brand/dpt.v1.css ---- */
/* dpt.v1.css: brand palette and the user-toggled theme layer. Values were first copied from the public website palette and have since drifted
   (the --c-* names in the trailing notes are the old site names). Change a value here, never in an app, then run sync.mjs;
   a breaking change is a new dpt.vN.css. */

/* Self-hosted variable fonts (Oswald OFL-1.1, Roboto Apache-2.0), Google "latin" subset;
   swap so text shows at once on slow gym wifi. */
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 200 700;
  font-display: swap;
  src: url('/static/brand/fonts/oswald.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/static/brand/fonts/roboto.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* App palette. The --c-* names in the notes are old website token names, not a promise the site still uses these values. */
  --dp-brand:        #FFC72C;   /* --c-brand       older gold, no longer the site's main button */
  --dp-brand-dark:   #D69E06;   /* --c-brand-dark  older darker gold step */
  --dp-green:        #00753C;   /* --c-green       green that is safe as text */
  --dp-green-brand:  #00A651;   /* --c-green-brand older bright green */
  --dp-green-hover:  #008C47;   /* --c-green-hover */
  --dp-ink:          #141A21;   /* --c-ink */
  --dp-ink-deep:     #0D1117;   /* --c-ink-deep    app chrome */
  --dp-slate:        #55606B;   /* --c-slate       muted text */
  --dp-paper:        #F4F4F4;   /* --c-paper */
  --dp-mint:         #E6F6EE;   /* --c-mint */
  --dp-border:       #D7DBD4;   /* --c-border */
  --dp-field-border: #92968F;   /* --c-field-border */
  --dp-field-hover:  #7A7F78;   /* --c-field-border-hover */
  --dp-white:        #FFFFFF;
  --dp-error:        #C43D3D;   /* --c-error       form validation */

  /* App-only status set: a vivid mark step for rails and fills, and a text-safe step per status
     (ratios in README.md). */
  --dp-good:         #00753C;
  --dp-good-wash:    #E6F6EE;
  --dp-warn:         #96540A;
  --dp-warn-wash:    #FBEFD8;
  --dp-crit:         #D92D20;   /* mark only — 4.1:1 on its wash, fails as text */
  --dp-crit-ink:     #C42115;   /* text step — 5.1:1 */
  --dp-crit-wash:    #FDECEA;
  --dp-raised-dark:  #283442;

  /* AMENDMENT 36: white label on the deep-green fill (5.82:1); hover goes brighter (#00854A, 4.71:1).
     #00A651 keeps the no-text jobs: goal bars, streak fills, top rules, glow. */
  --dp-action:       #00753C;
  --dp-action-ink:   #FFFFFF;
  --dp-action-hover: #00854A;

  /* Gold is never text on light (#D69E06 on white is 2.40:1): a fill, pill or rail with ink on it. */
  --dp-attention:     #FFC72C;
  --dp-attention-ink: #141A21;

  --dp-font-heading: 'Oswald', 'Roboto Condensed', 'Arial Narrow', sans-serif;
  --dp-font-body:    'Roboto', -apple-system, 'Segoe UI', Arial, sans-serif;
  --dp-fs-display: clamp(2.75rem, 1.5rem + 5vw, 4.5rem);
  --dp-fs-h1:      clamp(2.25rem, 1.4rem + 3.6vw, 3.5rem);
  --dp-fs-h2:      clamp(1.75rem, 1.3rem + 2vw, 2.5rem);
  --dp-fs-h3:      clamp(1.25rem, 1.1rem + .8vw, 1.5rem);
  --dp-fs-lead:    clamp(1.0625rem, 1rem + .5vw, 1.25rem);
  --dp-fs-body:    1rem;
  --dp-fs-small:   0.875rem;

  --dp-sp-1: 4px;  --dp-sp-2: 8px;  --dp-sp-3: 16px;
  --dp-sp-4: 24px; --dp-sp-5: 48px; --dp-sp-6: 96px;
  --dp-radius:    8px;
  --dp-radius-lg: 16px;
  --dp-btn-h:     48px;   /* standalone, per the site */
  --dp-btn-h-sm:  44px;   /* in-card, and the phone minimum */
  --dp-btn-h-desk: 40px;  /* app-only: dense tables. See README Deltas. */
  --dp-shadow:    0 4px 18px rgba(13,17,23,.14);
  --dp-shadow-lg: 0 12px 32px rgba(13,17,23,.18);
  --dp-measure:   65ch;
}

/* Theme: color-scheme follows data-theme (set before paint by theme.js) or the OS.
   Tokens below are declared twice on purpose: the plain light value, then light-dark(). Safari < 17.5
   drops the second and keeps light. Do not "clean up" the duplicates. The raw palette above never
   flips; apps alias these semantic names. */
:root                    { color-scheme: light dark; }
:root[data-theme="light"]{ color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

/* Reserve the scrollbar gutter so centred fixed pills and columns do not jump sideways when a page
   starts to overflow. */
:root { scrollbar-gutter: stable; }

/* react-remove-scroll injects body margin-right !important on lock; the stable gutter already
   reserves that space. A page opting out with scrollbar-gutter:auto must also set
   --dp-scroll-lock-compensation:initial to restore the library's measured gap. */
@supports (scrollbar-gutter: stable) {
  :root { --dp-scroll-lock-compensation: 0px; }
  html body[data-scroll-locked] {
    margin-right: var(--dp-scroll-lock-compensation, var(--removed-body-scroll-bar-size, 0px)) !important;
  }
}

:root {
  --dp-surface:        #F4F4F4;
  --dp-surface:        light-dark(#F4F4F4, #0B0F14);   /* the page */
  /* AMENDMENTS 25/26: automatic dark uses the same page/card poles as the dark role (1.52:1). */
  --dp-surface-raised: #FFFFFF;
  --dp-surface-raised: light-dark(#FFFFFF, #283442);   /* cards, modals */
  --dp-surface-sunken: #ECEEF0;
  --dp-surface-sunken: light-dark(#ECEEF0, #080B0F);   /* wells, table heads */

  /* Chrome is dark in both themes. */
  --dp-chrome:     #0D1117;
  --dp-chrome:     light-dark(#0D1117, #06090D);
  --dp-chrome-ink: #FFFFFF;
  --dp-chrome-ink: light-dark(#FFFFFF, #E8EBEE);

  /* Not light-dark(): the chrome bar is dark in both themes, so green text, rules or focus on it
     needs the bright step (10.86:1 on the light-mode bar, 11.45:1 on the dark one). */
  --dp-chrome-green: #2BE07B;

  --dp-text:       #141A21;
  --dp-text:       light-dark(#141A21, #E8EBEE);       /* 15.8:1 on surface */
  --dp-text-muted: #55606B;
  --dp-text-muted: light-dark(#55606B, #A2ADB6);       /* 8.3:1 on surface */
  /* Dark line: 2.41:1 on the page, 1.81:1 on the card. Text on a --line fill needs --dp-text
     (muted lands at 3.4:1). */
  --dp-line:       #D7DBD4;
  --dp-line:       light-dark(#D7DBD4, #465468);

  /* BREAK 3: on ink the green brightens to #2BE07B (10.9:1); the label stays dark in both themes. */
  --dp-action-t:      #00A651;
  --dp-action-t:      light-dark(#00A651, #2BE07B);
  --dp-action-t-ink:  #0D1117;
  --dp-action-t-ink:  light-dark(#0D1117, #06120B);
  --dp-action-t-hover:#00B357;
  --dp-action-t-hover:light-dark(#00B357, #5CE99A);

  /* Green as words: deep step on light, bright step on dark. */
  --dp-green-text: #00753C;
  --dp-green-text: light-dark(#00753C, #2BE07B);

  /* Status. Gold needs no dark variant (12.1:1 on the dark surface). */
  --dp-good-t:      #00753C;
  --dp-good-t:      light-dark(#00753C, #2BE07B);
  --dp-good-wash-t: #E6F6EE;
  --dp-good-wash-t: light-dark(#E6F6EE, #0E2A1C);
  --dp-warn-t:      #96540A;
  --dp-warn-t:      light-dark(#96540A, #F0B45A);
  --dp-warn-wash-t: #FBEFD8;
  --dp-warn-wash-t: light-dark(#FBEFD8, #2A2413);
  --dp-crit-t:      #C42115;
  --dp-crit-t:      light-dark(#C42115, #FF8078);
  --dp-crit-wash-t: #FDECEA;
  --dp-crit-wash-t: light-dark(#FDECEA, #2B1614);

  /* light-dark() sits at the colour position only: wrapping the whole shadow is invalid and
     computes to none (AMENDMENT 10). */
  --dp-shadow-t:    0 4px 18px rgba(13,17,23,.14);
  --dp-shadow-t:    0 4px 18px light-dark(rgba(13,17,23,.14), rgba(0,0,0,.5));
}

/* Theme toggle; inherits the text colour so it works on dark bars and light surfaces. */
.dp-theme-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; padding: 0;
  border: 1px solid currentColor; border-radius: 8px;
  background: transparent; color: inherit; cursor: pointer;
  opacity: .75; transition: opacity .12s;
}
.dp-theme-btn:hover { opacity: 1; }
/* No label beside it to widen the hit area, so it takes the touch minimum. */
@media (pointer: coarse) {
  .dp-theme-btn { width: var(--dp-btn-h-sm); height: var(--dp-btn-h-sm); }
}
.dp-theme-btn svg { display: block; width: 17px; height: 17px; }
/* Only one of the two icons is ever shown. */
:root[data-theme="dark"] .dp-theme-btn .dp-i-moon,
:root:not([data-theme="dark"]) .dp-theme-btn .dp-i-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .dp-theme-btn .dp-i-moon { display: none; }
  :root:not([data-theme]) .dp-theme-btn .dp-i-sun  { display: block; }
}

/* Accessibility floor, scoped to plain elements so adopting this file cannot restyle app components. */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none; /* AMENDMENT 36: no outer ring; the control's own border turns green */
}
/* AMENDMENT 50.1: never inside a v5 root (.dpt-v5), where the kit's 1.5px inset line is the only focus mark
   (A49) and a green border beside it would be a second line. Still (0,1,0): :where() adds nothing. */
:where(a, button, input, select, textarea, summary, [tabindex]):where(:not(.dpt-v5 *)):focus-visible {
  border-color: var(--dp-green-brand);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Opt-in so it cannot silently resize existing controls. */
.dp-tap { min-height: var(--dp-btn-h-sm); min-width: var(--dp-btn-h-sm); }

/* Screen-reader-only text, for icon-only controls that need a name. */
.dp-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Wide content must scroll inside its own box, never the page body. */
.dp-scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.dp-num { font-variant-numeric: tabular-nums; }

/* ---- brand/dpt.v2.css ---- */
/* dpt.v2.css: additive "Scoreboard, floating" layer; loads after dpt.v1.css.
   Tokens are declared twice (plain light value, then light-dark()), as in v1; do not "clean up" the
   duplicates. light-dark() is a colour function: in a border or shadow it sits at the colour position,
   never around the whole value. */
:root {
  --dp2-page:          #F4F4F4;
  --dp2-page:          light-dark(#F4F4F4, #0B0D10);
  --dp2-card:          #FFFFFF;
  --dp2-card:          light-dark(#FFFFFF, #283442); /* AMENDMENTS 15/25: one dark card */
  --dp2-well:          #ECEEF0;
  --dp2-well:          light-dark(#ECEEF0, #0B0D10);   /* nested inside a card */
  --dp2-glass:         #FFFFFF;
  --dp2-glass:         light-dark(#FFFFFF, rgba(255,255,255,.045));
  --dp2-hairline:      #D7DBD4;
  --dp2-hairline:      light-dark(#D7DBD4, #242B33);
  --dp2-hairline-soft: #E3E6E4;
  --dp2-hairline-soft: light-dark(#E3E6E4, #1B222B);
  /* Light only; a colour token, used as border: 1px solid var(--dp2-card-border-c). */
  --dp2-card-border-c: #D7DBD4;
  --dp2-card-border-c: light-dark(#D7DBD4, transparent);

  --dp2-text:          #141A21;
  --dp2-text:          light-dark(#141A21, #EDF1F4);
  --dp2-text-2:        #55606B;
  --dp2-text-2:        light-dark(#55606B, #93A0AB);
  --dp2-label:         #55606B;
  --dp2-label:         light-dark(#55606B, #7A8794);   /* 10px micro-labels */

  --dp2-good:          #00753C;
  --dp2-good:          light-dark(#00753C, #2BE07B);
  --dp2-warn:          #96540A;
  --dp2-warn:          light-dark(#96540A, #F0B45A);   /* rails/marks; as light TEXT prefer slate + gold mark */
  --dp2-crit:          #C42115;
  --dp2-crit:          light-dark(#C42115, #FF8078);
  --dp2-crit-chip-bg:  #FDECEA;
  --dp2-crit-chip-bg:  light-dark(#FDECEA, #3A1E1C);

  /* Gold never moves and is never text on light. */
  --dp2-gold:          #FFC72C;
  --dp2-gold-ink:      #141A21;
  /* Accent text is green on both grounds: gold is a fill or rail with ink on it, never a text colour,
     because gold means "press this". */
  --dp2-accent-text:   #00753C;
  --dp2-accent-text:   light-dark(#00753C, #2BE07B);

  /* AMENDMENT 4: white label on the deep-green fill (5.82:1); hover #005E30 (7.94:1) gets more legible,
     matching the site's button. #00A651 keeps the no-text jobs (glow, streaks, progress bars).
     As a control boundary: 5.82 light card, 5.29 light page, 3.06 dark card, 3.34 dark page. */
  --dp2-action:        #00753C;
  --dp2-action-ink:    #FFFFFF;
  --dp2-action-hover:  #005E30;
  --dp2-action-glow:   0 10px 30px rgba(0,166,81,.3);
  --dp2-action-glow:   0 10px 30px light-dark(rgba(0,166,81,.3), rgba(0,166,81,.25));
  --dp2-fab-shadow:    0 8px 24px rgba(0,166,81,.4);

  --dp2-nav-bg:        rgba(255,255,255,.94);
  --dp2-nav-bg:        light-dark(rgba(255,255,255,.94), rgba(23,27,33,.9));
  --dp2-nav-border:    #D7DBD4;
  --dp2-nav-border:    light-dark(#D7DBD4, rgba(255,255,255,.06));
  --dp2-nav-item:      #55606B;
  --dp2-nav-item:      light-dark(#55606B, #7A8794);
  /* The active tab is a state, and states are green. */
  --dp2-nav-active:    #00753C;
  --dp2-nav-active:    light-dark(#00753C, #2BE07B);
  /* No shadow on dark: light-dark() can only swap the colour, so it goes transparent. */
  --dp2-nav-shadow:    0 10px 30px rgba(13,17,23,.12);
  --dp2-nav-shadow:    0 10px 30px light-dark(rgba(13,17,23,.12), rgba(0,0,0,0));

  --dp2-r-hero: 14px;
  --dp2-r-card: 12px;
  --dp2-r-stat: 10px;
  --dp2-r-inner: 9px;
  --dp2-r-pill: 99px;
  --dp2-rail: 3px;          /* border-left status rail width */

  --dp2-fs-title: 19px;     /* Oswald 700, ls .06em, uppercase */
  --dp2-fs-sub: 10px;       /* 700, ls .22em, --dp2-accent-text */
  --dp2-fs-label: 10px;     /* 700, ls .12em, uppercase, --dp2-label */
  --dp2-fs-section: 12px;   /* Oswald 700, ls .12em */
  --dp2-fs-nav: 11px;       /* Oswald, ls .14em, uppercase */
  --dp2-fs-num-stat: 32px;  /* Oswald 700 */
  --dp2-fs-num-hero: 58px;  /* Oswald 700 */

  /* A token, not a [data-theme="dark"] rule: auto-dark sets no attribute. */
  --dp2-streak-on:     #00A651;
  --dp2-streak-on:     light-dark(#00A651, #2BE07B);
}

/* Opt-in components; never restyle app internals. */

/* Floating pill nav. Add padding-bottom:96px (+ safe area) to the page. */
.dp2-nav {
  position: fixed; bottom: calc(18px + env(safe-area-inset-bottom));
  left: 18px; right: 18px; z-index: 40;
  display: flex; justify-content: space-around; align-items: center;
  padding: 15px 8px; border-radius: var(--dp2-r-pill);
  background: var(--dp2-nav-bg); border: 1px solid var(--dp2-nav-border);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--dp2-nav-shadow);
}
.dp2-nav.has-fab { right: 88px; }
/* Desktop: the pill hugs its content, centred; phones keep the full-width bar for thumb reach. */
@media (min-width: 720px) {
  .dp2-nav {
    left: 50%; right: auto; transform: translateX(-50%);
    /* 100% not 100vw: vw includes the scrollbar. */
    width: max-content; max-width: calc(100% - 36px);
    justify-content: center; gap: 34px; padding: 15px 34px;
  }
  .dp2-nav.has-fab { right: auto; }
}
.dp2-nav a, .dp2-nav button {
  font-family: var(--dp-font-heading); font-size: var(--dp2-fs-nav);
  letter-spacing: .14em; text-transform: uppercase; text-decoration: none;
  color: var(--dp2-nav-item); background: none; border: 0; cursor: pointer;
  padding: 8px 6px; /* keeps the 44px target with the bar's own padding */
}
.dp2-nav .is-active { color: var(--dp2-nav-active); font-weight: 700; }

.dp2-fab {
  position: fixed; right: 18px; bottom: calc(14px + env(safe-area-inset-bottom));
  width: 54px; height: 54px; border-radius: 50%; border: 0; z-index: 41;
  background: var(--dp2-action); color: var(--dp2-action-ink);
  font-size: 26px; line-height: 1; cursor: pointer; box-shadow: var(--dp2-fab-shadow);
}
.dp2-fab:hover { background: var(--dp2-action-hover); }

/* Chrome never prints, and neither does a fixed pill floating over a sheet. */
@media print {
  .dp2-nav, .dp2-fab { display: none !important; }
}

/* Primary button — white on green, bold, never below 11px. */
.dp2-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--dp2-action); color: var(--dp2-action-ink);
  font-family: var(--dp-font-heading); font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  border: 0; border-radius: var(--dp2-r-inner); padding: 11px 16px; cursor: pointer;
}
.dp2-btn:hover { background: var(--dp2-action-hover); }

.dp2-hero {
  background: var(--dp2-action); color: var(--dp2-action-ink);
  border-radius: var(--dp2-r-hero); padding: 16px 18px;
  box-shadow: var(--dp2-action-glow);
}

.dp2-stat {
  background: var(--dp2-card); border: 1px solid var(--dp2-card-border-c);
  border-left: var(--dp2-rail) solid var(--dp2-good);
  border-radius: var(--dp2-r-stat); padding: 12px 14px;
}
.dp2-stat.is-warn { border-left-color: var(--dp2-gold); }
.dp2-stat.is-crit { border-left-color: var(--dp2-crit); }

.dp2-streak { display: grid; grid-template-columns: repeat(14, 1fr); gap: 3px; }
.dp2-streak > i { height: 8px; border-radius: 2px; background: var(--dp2-hairline-soft); }
.dp2-streak > i.on { background: var(--dp2-streak-on); }

/* Entrance motion: add .dp-enter to a view's direct children on initial mount only, never on
   re-render (list views guard with a data-entered flag). Portal and roster stagger, ops the hero
   card only, staff dashboard none. */
@keyframes dp-enter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.dp-enter { animation: dp-enter .24s cubic-bezier(.2,.7,.3,1) both; }
.dp-enter:nth-child(2) { animation-delay: 35ms; }
.dp-enter:nth-child(3) { animation-delay: 70ms; }
.dp-enter:nth-child(4) { animation-delay: 105ms; }
.dp-enter:nth-child(5) { animation-delay: 140ms; }
.dp-enter:nth-child(n+6) { animation-delay: 175ms; }
@media (prefers-reduced-motion: reduce) { .dp-enter { animation: none; } }

/* ---- brand/dpt.v3.css ---- */
/* dpt.v3.css: the App Brand Kit layer; loads after dpt.v1.css and dpt.v2.css.
   v1/v2 flip with the user's theme; v3 flips with the surface's role. Put .dpt-dark or .dpt-light on
   <html>, not <body> (AMENDMENT 11): the role pins every v1/v2 token to a plain value and sets
   color-scheme, so app aliases declared on :root resolve without light-dark(). Never alias a --dp3-*
   token on :root; mode tokens exist only inside the role blocks.

   ROLE MAP  .dpt-dark   portal stats/testing/progress, staff dashboard, roster, ops, testing app
             .dpt-light  /book/, checkout, forms, account and billing, wp-admin hubs

   RULES
     1. Components consume semantic tokens; never a raw hex in an app rule.
     2. --dp3-electric is dark surfaces only: hero numerals, rings, active indicators, primary fills.
        Never on light, never as body text.
     3. One glowing element per screen at most; glow is dark-only.
     4. Status and score always ship a dot or icon plus a word, never colour alone.
     5. Spacing is --dp3-sp-*: the WordPress theme's --sp-* uses different values on :root.
     6. Changes land as numbered amendments in README.md's single ledger.

   check-contrast.mjs re-measures every pair (AMENDMENTS 23-25); run it before moving any surface.
   An older "AMENDMENT 22" about the club-hub dark palette means 25; 22 is --dp3-r-field. */

/* Hanken Grotesk (OFL-1.1), self-hosted variable 400-800, same latin subset as v1's fonts. */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/static/brand/fonts/hanken.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Oswald for display, Hanken for app UI text; --dp-font-body is untouched, so nothing moves
     without opting in. */
  --dp3-font-display: 'Oswald', 'Roboto Condensed', 'Arial Narrow', sans-serif;
  --dp3-font-ui: 'Hanken Grotesk', -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;

  /* Fixed px for app chrome (a viewport scale makes dense tables wrap); only the hero numeral clamps. */
  --dp3-t-score-hero: clamp(56px, 14vw, 88px);  /* Oswald 600, line-height 1 */
  --dp3-t-score: 40px;                          /* Oswald 600, stat tiles */
  --dp3-t-h1: clamp(26px, 5vw, 32px);           /* Oswald 700, uppercase */
  --dp3-t-h2: 22px;                             /* Oswald 600 */
  --dp3-t-h3: 17px;                             /* Hanken 700 */
  --dp3-t-body: 16px;                           /* Hanken 400, 1.55 */
  --dp3-t-sub: 14px;                            /* Hanken 400-500 */
  --dp3-t-micro: 11px;                          /* Hanken 700 CAPS, +.08em */

  /* App radius scale; v1's --dp-radius stays for non-kit surfaces. */
  --dp3-r-sm: 8px;      /* inline elements, small tags */
  --dp3-r-md: 12px;     /* list rows, slot chips */
  --dp3-r-lg: 16px;     /* cards */
  --dp3-r-xl: 20px;     /* hero cards, sheets, modals */
  --dp3-r-pill: 999px;  /* buttons, chips, segmented controls */
  /* AMENDMENT 22: fields get their own 8px step (8 -> 16 -> pill); list rows and slots stay on r-md. */
  --dp3-r-field: 8px;   /* text inputs, selects, textareas */

  /* RULE 5: prefixed to avoid the WordPress theme's --sp-*. */
  --dp3-sp-1: 4px;  --dp3-sp-2: 8px;  --dp3-sp-3: 12px; --dp3-sp-4: 16px;
  --dp3-sp-5: 24px; --dp3-sp-6: 32px; --dp3-sp-7: 40px; --dp3-sp-8: 48px;

  /* Field height; button heights come from v1 (--dp-btn-h / -sm / -desk, BREAK 2). */
  --dp3-field-h: 48px;

  /* Focus line thickness, matching the child theme's --dpt-focus-w; --dp3- prefix because /book/
     loads both. */
  --dp3-focus-w: 1.5px;

  --dp3-ease: cubic-bezier(.2, .7, .3, 1);
  --dp3-t-fast: 150ms;  /* hover, press, chip toggle */
  --dp3-t-med: 220ms;   /* card, reveal */
  --dp3-t-slow: 320ms;  /* sheet, panel, count-up */

  /* Never flips (RULE 2). A solid electric fill carries ink, never white (white on #00E676 is 1.67:1). */
  --dp3-electric: #00E676;
  --dp3-electric-ink: #06120B;
  --dp3-accent-hot-hover: #5CE99A; /* AMENDMENT 33: named hover for the electric fill */

  /* Glow. Dark surfaces only, one element per screen. */
  --dp3-glow-text: 0 0 18px rgba(0, 230, 118, .40);
  --dp3-glow-ring: drop-shadow(0 0 10px rgba(0, 230, 118, .45));
  --dp3-glow-dot: 0 0 8px rgba(0, 230, 118, .60);
}

/* ROLE: DARK. Pins v1 + v2 to their dark pole with plain values. */
.dpt-dark {
  color-scheme: dark;

  /* v1 */
  --dp-surface: #0B0F14;         /* AMENDMENT 26: follows --dp3-bg */
  --dp-surface-raised: #283442;  /* AMENDMENT 26: follows --dp3-card */
  --dp-surface-sunken: #080B0F;
  --dp-chrome: #06090D;
  --dp-chrome-ink: #E8EBEE;
  --dp-text: #E8EBEE;
  --dp-text-muted: #A2ADB6;
  --dp-line: #465468;
  --dp-action-t: #2BE07B;
  --dp-action-t-ink: #06120B;
  --dp-action-t-hover: #5CE99A;
  --dp-green-text: #2BE07B;
  --dp-good-t: #2BE07B;      --dp-good-wash-t: #0E2A1C;
  --dp-warn-t: #F0B45A;      --dp-warn-wash-t: #2A2413;
  --dp-crit-t: #FF8078;      --dp-crit-wash-t: #2B1614;
  --dp-shadow-t: 0 4px 18px rgba(0, 0, 0, .5);

  /* v2 */
  --dp2-page: #0B0D10;
  /* AMENDMENT 15/24: aliases the one dark card; move --dp3-card, --dp3-card-2 and this together or a
     v2/v3 seam appears. */
  --dp2-card: #283442;
  --dp2-well: #0B0D10;
  --dp2-glass: rgba(255, 255, 255, .045);
  --dp2-hairline: #242B33;
  --dp2-hairline-soft: #1B222B;
  --dp2-card-border-c: transparent;
  --dp2-text: #EDF1F4;
  --dp2-text-2: #93A0AB;
  /* AMENDMENT 23: absorbs the portal's PORTAL-LOCAL override; 5.16:1 on the card for 10px labels. */
  --dp2-label: #9AA7B4;
  --dp2-good: #2BE07B;
  --dp2-warn: #F0B45A;
  --dp2-crit: #FF8078;
  --dp2-crit-chip-bg: #3A1E1C;
  --dp2-accent-text: #2BE07B;
  /* AMENDMENT 23: the action pair is pinned so the primary never depends on v2's :root or on
     color-scheme. White on #00753C 5.82:1, hover 7.94:1. */
  --dp2-action: #00753C;
  --dp2-action-ink: #FFFFFF;
  --dp2-action-hover: #005E30;
  /* Painted as .btn's inset ring: the fill alone is under 3:1 on the dark card; the edge (3.68:1)
     carries 1.4.11. */
  --dp2-action-edge: #2E9D62;
  --dp2-action-glow: 0 10px 30px rgba(0, 166, 81, .25);
  --dp2-nav-bg: rgba(23, 27, 33, .9);
  --dp2-nav-border: rgba(255, 255, 255, .06);
  --dp2-nav-item: #9AA7B4; /* AMENDMENT 33: same value as --dp2-label */
  --dp2-nav-active: #2BE07B;
  --dp2-nav-shadow: 0 10px 30px rgba(0, 0, 0, 0);
  --dp2-streak-on: #2BE07B;

  /* v3 */
  /* AMENDMENT 25: darker page so the lifted card reads as a card (1.52:1). */
  --dp3-bg: #0B0F14;
  /* AMENDMENT 15: ONE dark card; --dp3-card-2 and --dp2-card alias it, so move all three.
     On it: text 11.55, text-2 6.41, text-3 4.74, line-strong 3.99. */
  --dp3-card: #283442;
  /* Alias of the card (a separate step collapsed to 1.009:1); the seg inset ring carries selection. */
  --dp3-card-2: #283442;
  --dp3-line: rgba(255, 255, 255, .14);
  --dp3-card-edge: rgba(255, 255, 255, .14);
  /* AMENDMENT 13: every use is a control boundary (3:1 floor). 3.99:1 on the card, 4.68:1 on the page. */
  --dp3-line-strong: rgba(255, 255, 255, .46);
  --dp3-text: #F2F5F7;
  --dp3-text-2: #AEBAC6;   /* AMENDMENT 25: 6.41:1 on card */
  --dp3-text-3: #93A0AC;   /* AMENDMENT 25: 4.74:1 on card */
  --dp3-accent: #00A651;            /* structural brand accent */
  --dp3-accent-hot: var(--dp3-electric);
  --dp3-accent-hot-ink: var(--dp3-electric-ink);
  /* AMENDMENT 36: filled green controls carry white on the deep green in both roles. Separate from
     accent-hot, which stays the bright step for lines, text and strokes. */
  --dp3-action: #00753C;
  --dp3-action-ink: #FFFFFF;
  --dp3-action-hover: #00854A;   /* brighter than rest and still 4.71:1 */
  /* No rim: the 5.82:1 label identifies the control. Never add a line around a green button for
     accessibility without a design decision; #00A651 is the edge if one is requested on dark. */
  --dp3-action-rim: var(--dp3-action);
  --dp3-link: #4ADE80;
  --dp3-link-hover: #86EFAC;
  --dp3-focus: #4ADE80;
  /* AMENDMENT 35: neutral control pair for white-label surfaces, never a semantic. Label on fill
     15.99:1, on hover 17.51:1; fill vs card 11.55:1, vs page 17.55:1. */
  --dp3-neutral: #F2F5F7;
  --dp3-neutral-ink: #141A21;
  --dp3-neutral-hover: #C9D3DA;
  --dp3-ok: #4ADE80;      --dp3-ok-tint: rgba(74, 222, 128, .14);
  --dp3-warn: #FFA94D;    --dp3-warn-tint: rgba(255, 169, 77, .14);
  /* AMENDMENT 24: a badge paints its ink on a TINT of the card, so ink-on-tint is the binding pair.
     Danger and info inks are the -300 steps (5.04 / 5.17:1 on their own tints). A darker ink fails
     on the tint, and a darker tint erases the borderless badge. Do not re-darken an ink without
     re-deriving its tint. */
  --dp3-danger: #FCA5A5;  --dp3-danger-tint: rgba(252, 165, 165, .14);
  --dp3-info: #93C5FD;    --dp3-info-tint: rgba(147, 197, 253, .14);
  --dp3-score-optimal: var(--dp3-electric);
  --dp3-score-fair: #FFA94D;
  /* AMENDMENT 24: tracks --dp3-danger; 12px caps on the danger tint, 5.04:1. */
  --dp3-score-low: #FCA5A5;
  --dp3-score-none: #93A0AC;   /* AMENDMENT 25: tracks text-3; 12px caps, 4.74:1 */
  --dp3-shadow-card: none;
  --dp3-shadow-float: 0 12px 32px rgba(0, 0, 0, .45);

  /* Charts: categorical, fixed order, CVD-safe, measured on the card (not the page) against the 3:1
     mark floor. A 6th series folds into chart-other ("Other"); never cycle hues. Before changing a value
     re-run the dataviz validator, check-contrast.mjs and a CVD separation check. If the card lightens
     again, chart-3 and chart-5 cross 3:1 near #333F4D. */
  --dp3-chart-1: #00B25C;   /* green 4.53:1, DPT is always first */
  --dp3-chart-2: #4C8DFF;   /* blue 3.95:1 */
  --dp3-chart-3: #EA580C;   /* orange 3.55:1, thinnest margin */
  /* AMENDMENT 24: violet-300. violet-500 failed 3:1 on this card and sat dE 8 from blue under
     deuteranopia; it is the palest series because luminance carries separation when hue collapses. */
  --dp3-chart-4: #C4B5FD;   /* violet 6.85:1 */
  --dp3-chart-5: #EC4899;   /* pink 3.59:1, thin margin */
  --dp3-chart-other: #93A0AC;  /* AMENDMENT 25: tracks text-3, 4.74:1 */
  --dp3-chart-grid: rgba(255, 255, 255, .08);
  --dp3-chart-axis: #AEBAC6;   /* AMENDMENT 25: tracks text-2, 6.41:1 */
  /* Sequential ramp: monotonic lightness. */
  --dp3-seq-1: #12301F; --dp3-seq-2: #0F5230; --dp3-seq-3: #008C47;
  --dp3-seq-4: #00B25C; --dp3-seq-5: #3ADF8A;
  /* Diverging: improved vs declined */
  --dp3-div-pos: #00B25C; --dp3-div-mid: #8B97A1; --dp3-div-neg: #FF6B6B;
}

/* ROLE: LIGHT. Money, forms, parent admin. */
.dpt-light {
  color-scheme: light;

  /* v1 */
  --dp-surface: #F4F4F4;
  --dp-surface-raised: #FFFFFF;
  --dp-surface-sunken: #ECEEF0;
  --dp-chrome: #0D1117;
  --dp-chrome-ink: #FFFFFF;
  --dp-text: #161208;            /* AMENDMENT 21: warm ink */
  --dp-text-muted: #55606B;
  --dp-line: #D7DBD4;
  --dp-action-t: #00A651;
  --dp-action-t-ink: #0D1117;
  --dp-action-t-hover: #00B357;
  --dp-green-text: #00753C;
  --dp-good-t: #00753C;      --dp-good-wash-t: #E6F6EE;
  --dp-warn-t: #96540A;      --dp-warn-wash-t: #FBEFD8;
  --dp-crit-t: #C42115;      --dp-crit-wash-t: #FDECEA;
  --dp-shadow-t: 0 4px 18px rgba(13, 17, 23, .14);

  /* v2 */
  --dp2-page: #F4F4F4;
  --dp2-card: #FFFFFF;
  --dp2-well: #ECEEF0;
  --dp2-glass: #FFFFFF;
  --dp2-hairline: #D7DBD4;
  --dp2-hairline-soft: #E3E6E4;
  --dp2-card-border-c: #D7DBD4;
  --dp2-text: #161208;           /* AMENDMENT 21 */
  --dp2-text-2: #55606B;
  --dp2-label: #55606B;
  --dp2-good: #00753C;
  --dp2-warn: #96540A;
  --dp2-crit: #C42115;
  --dp2-crit-chip-bg: #FDECEA;
  --dp2-accent-text: #00753C;
  /* AMENDMENT 23 - the action pair, pinned. See the .dpt-dark block note. */
  --dp2-action: #00753C;
  --dp2-action-ink: #FFFFFF;
  --dp2-action-hover: #005E30;
  /* Same as the fill: 5.82:1 on the light card needs no ring. */
  --dp2-action-edge: #00753C;
  --dp2-action-glow: 0 10px 30px rgba(0, 166, 81, .3);
  --dp2-nav-bg: rgba(255, 255, 255, .94);
  --dp2-nav-border: #D7DBD4;
  --dp2-nav-item: #55606B;
  --dp2-nav-active: #00753C;
  --dp2-nav-shadow: 0 10px 30px rgba(13, 17, 23, .12);
  --dp2-streak-on: #00A651;

  /* v3. --dp3-accent-hot is the deep green here (RULE 2), aliased so components write it once. */
  --dp3-bg: #F4F4F4;
  --dp3-card: #FFFFFF;
  --dp3-card-2: #FAFBFB;
  --dp3-line: #E4E7EA;
  --dp3-card-edge: #D5D9DD; /* AMENDMENT 38: visible light card edge, 1.29:1 on page */
  /* AMENDMENT 13: control boundary, 3:1 floor. 3.46 card, 3.15 page, 3.34 card-2. */
  --dp3-line-strong: #828B94;
  --dp3-text: #161208;           /* AMENDMENT 21: warm ink */
  --dp3-text-2: #55606B;
  /* AMENDMENT 23: painted as 10.5px text; 5.05 card, 4.87 card-2, 4.59 page (binding). Also the
     program builder's dot grid. */
  --dp3-text-3: #667079;
  --dp3-accent: #00753C;
  --dp3-accent-hot: #00753C;
  --dp3-accent-hot-ink: #FFFFFF;
  /* AMENDMENT 36: same pair as dark; the hover keeps the site's deeper step (7.94:1). */
  --dp3-action: #00753C;
  --dp3-action-ink: #FFFFFF;
  --dp3-action-hover: #005E30;
  --dp3-action-rim: var(--dp3-action);
  --dp3-link: #00753C;
  --dp3-link-hover: #005E30;
  --dp3-focus: #00753C;
  /* AMENDMENT 35, light: label on fill 13.48:1, on hover 18.68:1; fill vs card 13.48:1, vs page 12.25:1. */
  --dp3-neutral: #2A2F36;
  --dp3-neutral-ink: #FFFFFF;
  --dp3-neutral-hover: #161208;
  /* AMENDMENT 12: warn and danger are v1's audited text steps (5.17 / 5.14:1 on their tints); the
     spec's #B45309 / #DC2626 fail as words. */
  --dp3-ok: #00753C;      --dp3-ok-tint: #E6F6EE;
  --dp3-warn: #96540A;    --dp3-warn-tint: #FBEFD8;
  --dp3-danger: #C42115;  --dp3-danger-tint: #FDECEA;
  --dp3-info: #1D4ED8;    --dp3-info-tint: #EAF0FD;
  --dp3-score-optimal: #00753C;
  --dp3-score-fair: #96540A;
  --dp3-score-low: #C42115;
  --dp3-score-none: #667079;   /* tracks text-3; painted as 12px CAPS */
  --dp3-shadow-card: 0 2px 6px rgba(13, 17, 23, .08); /* AMENDMENT 38 */
  --dp3-shadow-float: 0 8px 24px rgba(13, 17, 23, .12);

  /* Charts — validated against #FFFFFF */
  --dp3-chart-1: #00753C;
  --dp3-chart-2: #2563EB;
  --dp3-chart-3: #C2570B;
  --dp3-chart-4: #7C3AED;
  --dp3-chart-5: #DB2777;
  --dp3-chart-other: #667079;  /* tracks text-3; only needs 3:1 as a mark */
  --dp3-chart-grid: #ECEFF1;
  --dp3-chart-axis: #55606B;
  --dp3-seq-1: #E6F6EE; --dp3-seq-2: #9FDFBE; --dp3-seq-3: #4CBF87;
  --dp3-seq-4: #00A651; --dp3-seq-5: #00753C;
  --dp3-div-pos: #00753C; --dp3-div-mid: #8B97A1; --dp3-div-neg: #DC2626;
}

/* Both roles paint their own ground, so a nested island (a light sheet over a dark page) does not
   inherit through. */
.dpt-dark, .dpt-light {
  background: var(--dp3-bg);
  color: var(--dp3-text);
  font-family: var(--dp3-font-ui);
  font-size: var(--dp3-t-body);
  line-height: 1.55;
}

/* AMENDMENT 36: no ring outside a control. Focus recolours the control's own border; the inset line
   covers borderless controls and green-on-green fills, and filled controls take their own ink as the
   line. Filled-control rules need (0,4,0) to beat the (0,3,1) control rule. Never set border-radius
   here: at this specificity it overrides app field shapes mid-interaction. */
.dpt-dark :focus-visible, .dpt-light :focus-visible { outline: none; }
.dpt-dark :is(input, select, textarea, button, a.dp3-btn, .dp3-btn):focus-visible,
.dpt-light :is(input, select, textarea, button, a.dp3-btn, .dp3-btn):focus-visible {
  box-shadow: inset 0 0 0 1px var(--dp3-focus);
}
/* AMENDMENT 50.1: the border recolour (and the two BR-12 rules below) skip anything inside a v5 root. There
   the kit's 1.5px inset line is the only focus mark (A49), and a recoloured border beside it drew a second
   line: a white rim round the green action. :where() adds nothing, so outside v5 this stays (0,3,1). */
.dpt-dark :is(input, select, textarea, button, a.dp3-btn, .dp3-btn):where(:not(.dpt-v5 *)):focus-visible,
.dpt-light :is(input, select, textarea, button, a.dp3-btn, .dp3-btn):where(:not(.dpt-v5 *)):focus-visible {
  border-color: var(--dp3-focus);
}
.dpt-dark :is(.dp3-btn--primary, .dp3-chip.is-on, .dp3-slot.is-sel):focus-visible,
.dpt-light :is(.dp3-btn--primary, .dp3-chip.is-on, .dp3-slot.is-sel):focus-visible {
  box-shadow: inset 0 0 0 2px var(--dp3-action-ink);
}
/* AMENDMENT 36: the white inset is the focus cue; no bright green rim on a green fill. */
.dpt-dark .dp3-chip.is-on:where(:not(.dpt-v5 *)):focus-visible,
.dpt-dark .dp3-slot.is-sel:where(:not(.dpt-v5 *)):focus-visible,
.dpt-dark .dp3-btn.dp3-btn--primary:where(:not(.dpt-v5 *)):focus-visible { border-color: var(--dp3-action); }
.dpt-dark .dp3-btn.dp3-btn--primary:where(:not(.dpt-v5 *)):hover:focus-visible { border-color: var(--dp3-action-hover); }
.dpt-dark :is(.dp3-btn--gold, .dp3-btn.dp3-btn--gold):focus-visible,
.dpt-light :is(.dp3-btn--gold, .dp3-btn.dp3-btn--gold):focus-visible { box-shadow: inset 0 0 0 2px #161208; }
.dpt-dark :is(.dp3-btn--neutral, .dp3-btn.dp3-btn--neutral):focus-visible,
.dpt-light :is(.dp3-btn--neutral, .dp3-btn.dp3-btn--neutral):focus-visible { box-shadow: inset 0 0 0 2px var(--dp3-neutral-ink); }

/* COMPONENTS: opt-in classes; no raw hex below except where a comment says why. */

.dp3-h1 {
  font-family: var(--dp3-font-display); font-weight: 700;
  font-size: var(--dp3-t-h1); line-height: 1.1;
  text-transform: uppercase; letter-spacing: .02em;
}
.dp3-h2 {
  font-family: var(--dp3-font-display); font-weight: 600;
  font-size: var(--dp3-t-h2); line-height: 1.2;
}
.dp3-h3 { font-weight: 700; font-size: var(--dp3-t-h3); line-height: 1.3; }
.dp3-micro {
  font-size: var(--dp3-t-micro); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--dp3-text-2);
}
/* Tabular figures so a column of times does not jitter. */
.dp3-num { font-variant-numeric: tabular-nums; }

/* Buttons. --primary is the action pair in both roles; --gold is the money CTA, at most one per view
   (BREAK 1, AMENDMENT 28). */
.dp3-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--dp-btn-h-desk, 40px); padding: 0 18px;
  border-radius: var(--dp3-r-pill);
  font-family: var(--dp3-font-ui); font-size: 14px; font-weight: 700;
  border: 1.5px solid transparent; cursor: pointer;
  white-space: nowrap; text-decoration: none;
  transition: background var(--dp3-t-fast) var(--dp3-ease),
              border-color var(--dp3-t-fast) var(--dp3-ease);
}
/* AMENDMENT 36: the site's chassis, 40px desktop and 44px on coarse pointers (a pointer query, so
   tablets get 44). --lg keeps 48px. */
@media (pointer: coarse) { .dp3-btn { min-height: var(--dp-btn-h-sm, 44px); } }
.dp3-btn--sm { min-height: 34px; padding: 0 14px; font-size: 13px; }
/* --sm is 44px on touch too, matching the controls beside it. */
@media (pointer: coarse) { .dp3-btn--sm { min-height: var(--dp-btn-h-sm, 44px); } }
.dp3-btn--lg { min-height: var(--dp-btn-h, 48px); padding: 0 26px; font-size: 15px; }
/* The rim token equals the fill; .dp3-btn reserves 1.5px of border so nothing reflows. */
.dp3-btn--primary {
  background: var(--dp3-action); color: var(--dp3-action-ink);
  border-color: var(--dp3-action-rim);
}
/* The rim stays put on hover: it is the boundary, not the state. */
.dp3-btn--primary:hover { background: var(--dp3-action-hover); }
/* Gold never flips: #FFC72C under warm ink, 11.97:1 (AMENDMENT 21). AMENDMENT 23: on light the fill
   is 1.56:1 on the card, so a 1.5px bronze rim carries the boundary (5.88:1). Hover #D69E06 keeps
   7.79:1; its darker-on-hover direction is a look decision left open. */
.dp3-btn--gold { background: #FFC72C; color: #161208; }
.dp3-btn--gold:hover { background: #D69E06; }
.dpt-light .dp3-btn--gold { border-color: var(--dp3-warn); }
.dp3-btn--ghost { background: transparent; border-color: var(--dp3-line-strong); color: var(--dp3-text); }
/* AMENDMENT 35: white-label primary, used instead of --primary on tenant-branded surfaces. Hover is a
   discrete step, not opacity (opacity bleeds the surface through and drops the label). */
.dp3-btn--neutral { background: var(--dp3-neutral); color: var(--dp3-neutral-ink); }
.dp3-btn--neutral:hover { background: var(--dp3-neutral-hover); color: var(--dp3-neutral-ink); }
.dpt-dark .dp3-btn--ghost { background: rgba(255, 255, 255, .06); border-color: var(--dp3-line-strong); } /* AMENDMENT 33: .28 was 2.40:1 on the lifted card */
.dp3-btn--danger { background: transparent; border-color: var(--dp3-danger); color: var(--dp3-danger); }
.dp3-btn[disabled], .dp3-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.dp3-link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--dp3-link); font-weight: 700; font-size: 15px; text-decoration: none;
}
.dp3-link:hover { color: var(--dp3-link-hover); text-decoration: underline; }

/* Ring + hero numeral: the screen's one glowing element (RULE 3); glow on the arc and numeral,
   never the track. */
.dp3-ring { position: relative; display: inline-block; }
.dp3-ring svg { transform: rotate(-90deg); display: block; }
.dp3-ring .dp3-ring-track { fill: none; stroke: var(--dp3-line); stroke-width: 10; }
.dp3-ring .dp3-ring-prog {
  fill: none; stroke: var(--dp3-accent-hot); stroke-width: 10;
  stroke-linecap: round; filter: var(--dp3-glow-ring);
}
.dpt-light .dp3-ring .dp3-ring-prog { filter: none; }  /* RULE 3: dark only */
.dp3-ring .dp3-ring-center {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; text-align: center;
}
.dp3-ring .dp3-ring-num {
  font-family: var(--dp3-font-display); font-weight: 600; line-height: 1;
  font-size: var(--dp3-t-score-hero); color: var(--dp3-text);
  font-variant-numeric: tabular-nums; text-shadow: var(--dp3-glow-text);
}
.dpt-light .dp3-ring .dp3-ring-num { text-shadow: none; }
.dp3-ring .dp3-ring-label {
  font-size: var(--dp3-t-micro); font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--dp3-text-2);
}

/* RULE 4: the dot is the colour-blind channel; never ship the chip without its word. */
.dp3-scorechip {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--dp3-r-pill); padding: 4px 12px;
  font-size: 12px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.dp3-scorechip .dp3-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.dp3-scorechip--optimal { color: var(--dp3-score-optimal); background: var(--dp3-ok-tint); }
.dp3-scorechip--fair { color: var(--dp3-score-fair); background: var(--dp3-warn-tint); }
.dp3-scorechip--low { color: var(--dp3-score-low); background: var(--dp3-danger-tint); }
.dp3-scorechip--none { color: var(--dp3-score-none); background: var(--dp3-card-2); }

.dp3-tile {
  background: var(--dp3-card); border: 1px solid var(--dp3-card-edge);
  border-radius: var(--dp3-r-lg); padding: var(--dp3-sp-4);
  box-shadow: var(--dp3-shadow-card);
  display: flex; flex-direction: column; gap: var(--dp3-sp-1); min-width: 0;
}
.dp3-tile .dp3-tile-val {
  font-family: var(--dp3-font-display); font-weight: 600;
  font-size: var(--dp3-t-score); line-height: 1.05;
  color: var(--dp3-text); font-variant-numeric: tabular-nums;
}
.dp3-tile .dp3-tile-val small { font-size: 16px; font-weight: 500; color: var(--dp3-text-2); margin-left: 2px; }
.dp3-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; font-weight: 700; }
.dp3-delta--up { color: var(--dp3-ok); }
.dp3-delta--down { color: var(--dp3-danger); }
.dp3-delta--flat { color: var(--dp3-text-2); }

.dp3-card {
  background: var(--dp3-card); border: 1px solid var(--dp3-card-edge);
  border-radius: var(--dp3-r-lg); padding: var(--dp3-sp-4);
  box-shadow: var(--dp3-shadow-card);
}
.dp3-card--hero { border-radius: var(--dp3-r-xl); padding: var(--dp3-sp-5); }
.dp3-row {
  display: flex; align-items: center; gap: var(--dp3-sp-3);
  min-height: 52px; padding: var(--dp3-sp-2) 0;
  border-bottom: 1px solid var(--dp3-line);
}
.dp3-row:last-child { border-bottom: 0; }
.dp3-row .dp3-row-grow { flex: 1; min-width: 0; }
.dp3-row .dp3-row-t { font-weight: 600; color: var(--dp3-text); font-size: 15px; }
.dp3-row .dp3-row-s { font-size: 13px; color: var(--dp3-text-2); }
.dp3-row .dp3-row-v { font-weight: 700; color: var(--dp3-text); font-variant-numeric: tabular-nums; }

/* Week strip: today is an outline, not a fill, so a future day never reads as missed. */
.dp3-week { display: flex; gap: 9px; align-items: center; }
.dp3-week .dp3-week-day {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  font-size: 10.5px; font-weight: 600; color: var(--dp3-text-3);
}
.dp3-week .dp3-week-mark {
  width: 30px; height: 30px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--dp3-line-strong); color: transparent;
  font-size: 13px; font-weight: 700;
}
/* AMENDMENT 23/36: the done mark uses the filled action pair, never white on #00A651 (3.19:1). */
.dp3-week .is-done {
  background: var(--dp3-action); border-color: var(--dp3-action-rim);
  color: var(--dp3-action-ink);
}
.dp3-week .is-today { border-color: var(--dp3-accent-hot); color: var(--dp3-accent-hot); }

.dp3-chip {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--dp-btn-h-sm, 44px); padding: 0 15px; border-radius: var(--dp3-r-pill);
  border: 1.5px solid var(--dp3-line-strong); background: transparent;
  color: var(--dp3-text); font-family: var(--dp3-font-ui);
  font-size: 13.5px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.dp3-chip.is-on {
  background: var(--dp3-action); border-color: var(--dp3-action-rim);
  color: var(--dp3-action-ink);
}
.dp3-seg {
  display: inline-flex; background: var(--dp3-card); border: 1px solid var(--dp3-line);
  border-radius: var(--dp3-r-pill); padding: 4px; gap: 2px;
}
.dpt-light .dp3-seg { background: #EDF0F2; border-color: transparent; }
.dp3-seg > * {
  min-height: var(--dp-btn-h-sm, 44px); padding: 0 16px; border-radius: var(--dp3-r-pill);
  color: var(--dp3-text-2); font-weight: 600; font-size: 13.5px;
  display: inline-flex; align-items: center; border: 0; background: transparent; cursor: pointer;
}
/* AMENDMENT 23: card-2 aliases card in dark, so selection needs the line-strong inset ring
   (3:1 state floor); the light shadow only lifts. */
.dp3-seg > .is-on {
  background: var(--dp3-card-2); color: var(--dp3-text);
  box-shadow: inset 0 0 0 1.5px var(--dp3-line-strong);
}
.dpt-light .dp3-seg > .is-on {
  background: #FFFFFF;
  box-shadow: inset 0 0 0 1.5px var(--dp3-line-strong), 0 1px 2px rgba(13, 17, 23, .08);
}
.dp3-slots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--dp3-sp-2); }
.dp3-slot {
  min-height: var(--dp-btn-h-sm, 44px); border-radius: var(--dp3-r-md);
  border: 1.5px solid var(--dp3-line-strong); background: var(--dp3-card);
  color: var(--dp3-text); font-weight: 600; font-size: 14px;
  display: flex; align-items: center; justify-content: center;
  font-variant-numeric: tabular-nums; cursor: pointer;
}
.dp3-slot.is-sel { background: var(--dp3-action); border-color: var(--dp3-action-rim); color: var(--dp3-action-ink); }
.dp3-slot.is-off {
  color: var(--dp3-text-3); background: var(--dp3-card-2);
  border-color: var(--dp3-line); text-decoration: line-through; cursor: not-allowed;
}

/* RULE 4: dot or icon, plus a word. */
.dp3-badge {
  display: inline-flex; align-items: center; gap: 6px;
  border-radius: var(--dp3-r-pill); padding: 3px 10px;
  font-size: 12px; font-weight: 700; white-space: nowrap;
}
.dp3-badge .dp3-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.dp3-badge--ok { color: var(--dp3-ok); background: var(--dp3-ok-tint); }
.dp3-badge--warn { color: var(--dp3-warn); background: var(--dp3-warn-tint); }
.dp3-badge--danger { color: var(--dp3-danger); background: var(--dp3-danger-tint); }
.dp3-badge--info { color: var(--dp3-info); background: var(--dp3-info-tint); }
.dp3-badge--neutral { color: var(--dp3-text-2); background: var(--dp3-card-2); }
.dpt-light .dp3-badge--neutral { background: #EDF0F2; }
.dp3-alert {
  display: flex; gap: var(--dp3-sp-3); align-items: flex-start;
  border-radius: var(--dp3-r-md); padding: 13px 15px;
  font-size: 13.5px; border: 1px solid; color: var(--dp3-text);
}
/* AMENDMENT 23: icon ink is a token that flips with the nearest role (dark ink on dark-mode pastels,
   white on light-mode fills), so a light island over a dark page gets the right ink. */
.dp3-alert .dp3-alert-ic {
  flex: 0 0 auto; width: 21px; height: 21px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 800;
  color: var(--dp3-accent-hot-ink);
}
.dp3-alert b { display: block; margin-bottom: 1px; }
.dp3-alert--warn { background: var(--dp3-warn-tint); border-color: var(--dp3-warn); }
.dp3-alert--warn .dp3-alert-ic { background: var(--dp3-warn); }
.dp3-alert--info { background: var(--dp3-info-tint); border-color: var(--dp3-info); }
.dp3-alert--info .dp3-alert-ic { background: var(--dp3-info); }
.dp3-alert--danger { background: var(--dp3-danger-tint); border-color: var(--dp3-danger); }
.dp3-alert--danger .dp3-alert-ic { background: var(--dp3-danger); }

/* Initials only, at most two characters. */
.dp3-avatar {
  width: 38px; height: 38px; border-radius: 50%; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  background: var(--dp3-ok-tint); color: var(--dp3-accent);
  font-weight: 700; font-size: 14px;
}
.dpt-dark .dp3-avatar { color: var(--dp3-link); }
.dp3-avatar--coach { box-shadow: 0 0 0 2px var(--dp3-accent); }

.dp3-field { display: flex; flex-direction: column; gap: 6px; }
.dp3-field label { font-size: var(--dp3-t-sub); font-weight: 600; color: var(--dp3-text); }
.dp3-field input, .dp3-field select, .dp3-field textarea {
  min-height: var(--dp3-field-h, 48px); border-radius: var(--dp3-r-field, 8px); /* AMENDMENT 22 */
  border: 1.5px solid var(--dp3-line-strong); background: var(--dp3-card);
  color: var(--dp3-text); font: inherit; padding: 0 14px; width: 100%;
}
.dp3-field textarea { padding: 12px 14px; min-height: 96px; }
.dp3-field .dp3-field-err { font-size: 13px; font-weight: 600; color: var(--dp3-danger); }

/* AMENDMENT 27: the open picker is part of the control. Single selects only; browsers without
   ::picker() keep their native sheet.
   AMENDMENT 37: picker at --dp3-r-field, options concentric, labels centred, checkmark trails. */
@supports (appearance: base-select) {
  select:not([multiple]), select:not([multiple])::picker(select) { appearance: base-select; }
  select:not([multiple]) { align-items: center; }
  select:not([multiple])::picker(select) {
    background: var(--dp3-card, Canvas);
    color: var(--dp3-text, CanvasText);
    border: 1.5px solid var(--dp3-line-strong, GrayText);
    border-radius: var(--dp3-r-field);
    padding: 4px;
    margin-top: 4px;
    box-shadow: var(--dp3-shadow-float);
  }
  select:not([multiple]) option {
    border-radius: calc(var(--dp3-r-field) - 4px); /* concentric: field radius minus picker padding */
    min-height: 40px;
    display: flex;
    align-items: center;
    padding: 6px 12px;
    font-size: 16px;
    color: var(--dp3-text);
    background: transparent;
  }
  select:not([multiple]) option:is(:hover, :focus-visible) { background: var(--dp3-ok-tint); color: var(--dp3-link); }
  select:not([multiple]) option:checked { background: var(--dp3-ok-tint); color: var(--dp3-text); }
  select:not([multiple]) option::checkmark { color: var(--dp3-ok); margin-left: auto; order: 1; }
  select:not([multiple])::picker-icon { color: var(--dp3-text-2); }
  @media (pointer: coarse) { select:not([multiple]) option { min-height: 44px; } }
}

.dp3-appbar { display: flex; align-items: center; gap: var(--dp3-sp-3); min-height: 52px; }
.dp3-appbar .dp3-appbar-title {
  font-family: var(--dp3-font-display); font-weight: 600; font-size: 18px;
  text-transform: uppercase; letter-spacing: .04em; flex: 1; text-align: center;
}
.dp3-iconbtn {
  width: var(--dp-btn-h-sm, 44px); height: var(--dp-btn-h-sm, 44px);
  border-radius: 50%; border: 0; background: var(--dp3-card);
  color: var(--dp3-text); display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.dp3-tabbar {
  display: flex; justify-content: space-around;
  background: var(--dp3-card); border-top: 1px solid var(--dp3-line);
  padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 12px));
}
.dp3-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-height: var(--dp-btn-h-sm, 44px); padding-top: 7px;
  color: var(--dp3-text-3); font-size: 10.5px; font-weight: 600;
  position: relative; text-decoration: none;
}
.dp3-tab svg { width: 22px; height: 22px; }
/* No glow on the tab indicator: persistent chrome never glows (RULE 3). A screen whose hero is
   chrome opts in with .dp3-glow. */
.dp3-tab.is-on { color: var(--dp3-accent-hot); }
.dp3-tab.is-on::after {
  content: ""; position: absolute; top: 0;
  width: 16px; height: 3px; border-radius: 2px;
  background: var(--dp3-accent-hot);
}
.dpt-dark .dp3-glow { box-shadow: var(--dp3-glow-dot); }

/* Paint series with style="fill:var(--dp3-chart-1)", not the fill= attribute: presentation
   attributes are the lowest cascade layer and var() support there is uneven. */
.dp3-chart svg { width: 100%; height: auto; display: block; }
.dp3-chart text { font-family: var(--dp3-font-ui); font-size: 11px; fill: var(--dp3-chart-axis); }
.dp3-chart .dp3-chart-grid { stroke: var(--dp3-chart-grid); stroke-width: 1; }
.dp3-chart .dp3-chart-label { font-weight: 700; font-size: 12px; fill: var(--dp3-text); }

/* Reduced motion for v3; a count-up must render its final value. */
@media (prefers-reduced-motion: reduce) {
  .dpt-dark *, .dpt-light * {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}


/* ---- brand/dpt.v4.css ---- */
/* dpt.v4.css: the App Direction layer (AMENDMENT 39). Loads after dpt.v3.css. OPT-IN:
   put .dpt-app on <html> together with .dpt-dark. Nothing here changes an app that does not opt in.
   Black canvas, near-black cards with a hairline, one big numeral per card with a coloured status
   word, caps micro labels, dark rows with chevrons, pill segments, a 5-tab bar.
   RULES (these override v1-v3 where they disagree, for .dpt-app surfaces only)
     1. One neutral sans (Inter) for everything, numerals included. Oswald and Roboto stay on the website.
     2. Primary button = white pill with ink text. Gold pill only when money moves. Everything else is
        a text link. No uppercase buttons. Radius: cards 22, fields 16, buttons and chips pill.
     3. Cards are --dp4-card on a --dp4-bg canvas with a 1px --dp4-line hairline. Slate is retired.
     4. One brand wash (.dp4-wash) is allowed behind a screen header. No halo or glow on any element.
     5. Text links are --dp4-link (green). On the sign-in screen only, the secondary link may be
        --dp4-text-2 (grey).
     6. The PR badge is exempt from "gold once per view". Gold BUTTONS stay once per view.
     7. Status colour always ships with a word (v3 RULE 4 still applies). No outer focus ring (AMENDMENT 36).
     8. No lift, no transform, no entrance animation on any control or card. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/brand/fonts/inter.woff2') format('woff2');
}

:root.dpt-app {
  --dp4-font: 'Inter', -apple-system, 'SF Pro Text', 'Segoe UI', system-ui, sans-serif;

  /* canvas and surfaces */
  --dp4-bg: #000000;
  --dp4-card: #212226;
  --dp4-card-2: #2C2D32;
  --dp4-line: #3B3C42;
  --dp4-field: #1C1D21;
  --dp4-field-line: #34353B;
  --dp4-tabbar: #0A0A0B;

  /* text */
  --dp4-text: #F5F5F7;
  --dp4-text-2: #B8BBC2;
  --dp4-text-3: #8E9199;
  --dp4-placeholder: #8E9199;

  /* status: always with a word */
  --dp4-good: #31D07B;      --dp4-good-bg: rgba(49, 208, 123, .14);
  --dp4-watch: #F0B45A;     --dp4-watch-bg: rgba(240, 180, 90, .14);
  --dp4-bad: #FF7A70;       --dp4-bad-bg: rgba(255, 122, 112, .14);
  --dp4-link: #4ADE80;
  --dp4-link-hover: #86EFAC;

  /* brand */
  --dp4-green: #00A651;                 /* lines, the wash, sparklines */
  --dp4-gold: #FFC72C;  --dp4-gold-ink: #161208;   /* PR badge, money button */

  /* controls */
  --dp4-primary: #F5F5F7;  --dp4-primary-ink: #000000;  --dp4-primary-hover: #E4E4E8;
  --dp4-btn-h: 56px;       --dp4-btn-h-sm: 44px;
  --dp4-field-h: 66px;

  /* geometry */
  --dp4-r-card: 22px;  --dp4-r-field: 16px;  --dp4-r-pill: 999px;  --dp4-r-badge: 6px;

  /* type scale (px) */
  --dp4-t-num-hero: 44px;   /* card headline numeral, weight 500, tracking -.02em, tabular */
  --dp4-t-num-row: 28px;    /* row value */
  --dp4-t-title: 22px;      /* screen section title, weight 600 */
  --dp4-t-h1: 30px;         /* sign-in "Welcome back", weight 500 */
  --dp4-t-body: 17px;       /* row title / card label, weight 500 */
  --dp4-t-sub: 14px;        /* row sub-line, --dp4-text-2 */
  --dp4-t-micro: 11px;      /* caps eyebrow, weight 600, tracking .18em, --dp4-text-2 */

  /* v1-v3 aliases so kit components inherit the direction without a rewrite */
  --dp3-font-ui: var(--dp4-font);
  --dp3-font-display: var(--dp4-font);
  --dp3-bg: var(--dp4-bg);
  --dp3-card: var(--dp4-card);
  --dp3-card-2: var(--dp4-card-2);
  --dp3-line: var(--dp4-line);
  --dp3-line-strong: #3A3B40;
  --dp3-text: var(--dp4-text);
  --dp3-text-2: var(--dp4-text-2);
  --dp3-text-3: var(--dp4-text-3);
  --dp3-link: var(--dp4-link);
  --dp3-link-hover: var(--dp4-link-hover);
  --dp3-focus: var(--dp4-good);
  --dp3-r-lg: var(--dp4-r-card);
  --dp3-r-xl: var(--dp4-r-card);
  --dp3-r-field: var(--dp4-r-field);
  --dp3-shadow-card: none;
  --dp3-glow: none;
  --dp2-page: var(--dp4-bg);
  --dp2-card: var(--dp4-card);
  --dp2-action-glow: none;
  --dp-surface: var(--dp4-bg);
  --dp-surface-raised: var(--dp4-card);
  --dp-text: var(--dp4-text);
  --dp-text-muted: var(--dp4-text-2);
  --dp-line: var(--dp4-line);
  color-scheme: dark;
}

/* ---- components (opt-in classes) ---- */
.dpt-app body { background: var(--dp4-bg); color: var(--dp4-text); font: 17px/1.45 var(--dp4-font); -webkit-font-smoothing: antialiased; }

.dp4-card {
  background: var(--dp4-card); border: 1px solid var(--dp4-line); border-radius: var(--dp4-r-card);
  padding: 20px; box-shadow: none;
}
.dp4-eyebrow { font-size: var(--dp4-t-micro); font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--dp4-text-2); }
.dp4-num { font-size: var(--dp4-t-num-hero); font-weight: 500; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.dp4-num small { font-size: 18px; font-weight: 500; color: var(--dp4-text-2); margin-left: 4px; letter-spacing: 0; }
.dp4-label { font-size: var(--dp4-t-body); color: var(--dp4-text-2); margin-top: 6px; }
.dp4-title { font-size: var(--dp4-t-title); font-weight: 600; }

.dp4-row { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 16px 0; border-top: 1px solid var(--dp4-line); }
.dp4-row:first-child { border-top: 0; }
.dp4-row__t { font-size: var(--dp4-t-body); font-weight: 500; }
.dp4-row__s { font-size: var(--dp4-t-sub); color: var(--dp4-text-2); margin-top: 2px; }
.dp4-row__v { font-size: var(--dp4-t-num-row); font-weight: 500; letter-spacing: -.02em; font-variant-numeric: tabular-nums; text-align: right; }
.dp4-row__v small { font-size: 13px; color: var(--dp4-text-2); margin-left: 3px; }
.dp4-row__d { font-size: 13px; font-weight: 600; text-align: right; margin-top: 2px; color: var(--dp4-good); }
.dp4-row__d.is-flat { color: var(--dp4-text-2); }
.dp4-row__d.is-watch { color: var(--dp4-watch); }
.dp4-chev { color: var(--dp4-text-3); font-size: 20px; line-height: 1; }

/* Status pill: colour + word, never colour alone. */
.dp4-pill { display: inline-block; font-size: 13px; font-weight: 600; padding: 3px 8px; border-radius: var(--dp4-r-badge); }
.dp4-pill--good { color: var(--dp4-good); background: var(--dp4-good-bg); }
.dp4-pill--watch { color: var(--dp4-watch); background: var(--dp4-watch-bg); }
.dp4-pill--bad { color: var(--dp4-bad); background: var(--dp4-bad-bg); }
.dp4-pr { display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: .04em; padding: 3px 8px; border-radius: var(--dp4-r-badge); background: var(--dp4-gold); color: var(--dp4-gold-ink); }

/* Buttons: white pill primary, gold pill for money, text link for the rest. No uppercase, no ring, no lift. */
.dp4-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
  min-height: var(--dp4-btn-h); padding: 0 24px; border: 0; border-radius: var(--dp4-r-pill);
  background: var(--dp4-primary); color: var(--dp4-primary-ink);
  font: 600 18px/1 var(--dp4-font); cursor: pointer; text-decoration: none; transform: none; box-shadow: none;
}
.dp4-btn:hover { background: var(--dp4-primary-hover); color: var(--dp4-primary-ink); text-decoration: none; }
.dp4-btn:focus-visible { outline: 0; box-shadow: inset 0 0 0 2px var(--dp4-primary-ink); }
.dp4-btn--money { background: var(--dp4-gold); color: var(--dp4-gold-ink); }
.dp4-btn--money:hover { background: #F2B91F; color: var(--dp4-gold-ink); }
.dp4-btn--sm { width: auto; min-height: var(--dp4-btn-h-sm); padding: 0 18px; font-size: 15px; }
.dp4-btn--ghost { background: var(--dp4-card-2); color: var(--dp4-text); border: 1px solid var(--dp4-line); }
.dp4-btn--ghost:hover { background: #1F2023; color: var(--dp4-text); }
.dp4-btn:disabled { opacity: .45; cursor: not-allowed; }
.dp4-link { background: none; border: 0; padding: 0; font: 600 15px/1.3 var(--dp4-font); color: var(--dp4-link); cursor: pointer; text-decoration: none; }
.dp4-link:hover { color: var(--dp4-link-hover); text-decoration: underline; }
.dp4-link--quiet { color: var(--dp4-text-2); font-weight: 500; }   /* sign-in secondary link only (RULE 5) */

/* Fields: dark, tall, no ring; focus = the field edge turns green (AMENDMENT 36). */
.dp4-field {
  display: block; width: 100%; min-height: var(--dp4-field-h); padding: 0 22px;
  background: var(--dp4-field); border: 1px solid var(--dp4-field-line); border-radius: var(--dp4-r-field);
  color: var(--dp4-text); font: 400 18px/1.2 var(--dp4-font); box-shadow: none;
}
.dp4-field::placeholder { color: var(--dp4-placeholder); opacity: 1; }
.dp4-field:focus, .dp4-field:focus-visible { outline: 0; border-color: var(--dp4-good); }
.dp4-field-wrap { position: relative; }
.dp4-field-wrap .dp4-field-aux { position: absolute; right: 22px; top: 50%; transform: translateY(-50%); background: none; border: 0; padding: 0; color: var(--dp4-text-2); font: 500 16px/1 var(--dp4-font); cursor: pointer; }

/* Segmented control (D W M): pill track, ink-on-light active. */
.dp4-seg { display: inline-flex; padding: 4px; gap: 2px; background: var(--dp4-card-2); border-radius: var(--dp4-r-pill); }
.dp4-seg button { background: none; border: 0; border-radius: var(--dp4-r-pill); min-height: 36px; padding: 0 16px; color: var(--dp4-text-2); font: 600 14px/1 var(--dp4-font); cursor: pointer; }
.dp4-seg button.is-on { background: #2C2C2E; color: var(--dp4-text); }
.dp4-seg button:focus-visible { outline: 0; box-shadow: inset 0 0 0 1px var(--dp4-good); }

/* The one allowed wash: brand green behind a screen header (RULE 4). */
.dp4-wash { position: absolute; left: 0; right: 0; top: 0; height: 380px; pointer-events: none;
  background: radial-gradient(120% 90% at 50% 0%, rgba(0, 166, 81, .55), rgba(0, 166, 81, .08) 55%, transparent 75%); }

/* Bars: current white, others dim. No halo. */
.dp4-bars { display: flex; align-items: flex-end; justify-content: center; gap: 10px; }
.dp4-bar { width: 44px; border-radius: 8px; background: #2B2D31; display: flex; justify-content: center; align-items: flex-start; padding-top: 8px; font: 600 14px/1 var(--dp4-font); color: #D9D9DE; }
.dp4-bar.is-on { background: var(--dp4-primary); color: var(--dp4-primary-ink); box-shadow: none; }

/* 5-tab bar: icon over 10px caps label, active white. */
.dp4-tabs { display: flex; justify-content: space-around; align-items: flex-start; height: 84px; padding-top: 10px; background: var(--dp4-tabbar); border-top: 1px solid #1B1C1F; }
.dp4-tab { display: flex; flex-direction: column; align-items: center; gap: 6px; font: 600 10px/1 var(--dp4-font); letter-spacing: .08em; text-transform: uppercase; color: var(--dp4-text-3); text-decoration: none; min-width: 56px; }
.dp4-tab svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.dp4-tab.is-on, .dp4-tab[aria-current="page"] { color: var(--dp4-text); }
.dp4-tab:focus-visible { outline: 0; color: var(--dp4-text); }

@media (prefers-reduced-motion: reduce) { .dpt-app * { transition: none !important; animation: none !important; } }

/* ---- brand/dpt.v5.css ---- */
/* dpt.v5.css: App Kit v5 (AMENDMENT 40). Loads LAST, after dpt.v3.css and
   dpt.v4.css. OPT-IN: put .dpt-v5 on <html> next to .dpt-dark. Family apps (athlete portal,
   health-hub) also keep .dpt-app, which switches the geometry to the rounded family. Nothing
   here changes an app that does not opt in. The written rules and the history of every
   older value are in brand/README.md.

   RULES (override v1-v4 where they disagree, for .dpt-v5 surfaces only). AMENDMENT 50 (look C)
   rewrote 1, 2, 3, 6 and 7; brand/README.md keeps the history of every older value.
     1. Navy, white and two greens. Canvas #080C16 is the frame (nav rail, tab bar, outer page),
        surface #0C1322 the working panel, raised #141D30 a tile (cards, fields, chips). Green
        #00D68F is the brand: accents, links, active marks, deltas, and the ONE action button
        (navy text). Deep green #007A52 is green on light surfaces and the light action fill
        (white text). Gold, every older green and every charcoal grey are gone from app surfaces.
     2. ONE filled button per screen, the action: .dp5-btn--primary and .dp5-btn--money paint
        --dp5-action (bright green, navy ink, on dark). --dp5-primary is the WHITE SLAB and paints
        SELECTED things (segments, picked chips, tabs, toasts), never the main button. Secondary
        and ghost buttons are plain text (#D5DCE6, hover white): no fill, no outline. Danger is a
        red word; a red fill only on a confirm sheet.
     3. Two radius families. Tool (staff apps): one corner shape, 8 (controls, fields, cards,
        sheets) and 6 (chips, badges), no pills. Family (.dpt-app): buttons and chips pill,
        fields 16, cards 22, sheets 24.
     4. Focus is an inset 1.5px line in the text colour, never green (AMENDMENT 49). Nothing
        outside the edge (AMENDMENT 36).
     5. Inter for everything, tabular numerals, sentence case everywhere. Caps only on the 11px
        micro label.
     6. A card is a tile: raised fill plus a 1px white-30% edge (--dp5-line-card), no shadow, no
        grain. Buttons, chips, rows and fields never lift: no transform, no glow. The sheet/dialog
        keeps its own deeper shadow. Hover and selected fills sit one rung up the navy ladder
        (raised-hover, raised-press) so they still read inside a tile.
     7. Status is a coloured dot plus a word, never a tinted fill. Class-type colours are an 8px
        dot plus the word.
     8. Every token here is --dp5-*. The alias block re-points --dp4-*, --dp3-*, --dp2-* and
        --dp-* so kit components inherit v5 without a rewrite. Apps consume tokens, never hex. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/brand/fonts/inter.woff2') format('woff2');
}

/* ============================================================ TOKENS */
/* Also asserted on any descendant that carries a v3 role class (body.dpt-dark, .sheet.dpt-light): dpt.v3.css
   re-declares ~80 tokens on .dpt-dark / .dpt-light, and for inheritance the closer element wins regardless of
   where :root sits. Without this, a printed form kept an older green. */
:root.dpt-v5, .dpt-v5 :is(.dpt-dark, .dpt-light) {
  color-scheme: dark;

  /* AMENDMENT 50 (look C): the navy ladder Ops and DPT Hub shipped, now the kit default.
     Same token NAMES (they are an API); the values are look C. Canvas is the frame (nav rail, tab bar, outer
     page), surface the working panel, raised a tile (card, field, chip). Hover and selected fills step one
     rung up (raised-hover, raised-press), so a row still reads inside a tile. The card is drawn by its edge:
     --dp5-line-card over the tile is #5B616E, 3.13:1 on the canvas. The A45-A49 greys (#171717 canvas,
     #232323 surface, #3A3A3A raised and every hairline between) are retired; the README ledger keeps why
     each one was picked. A test pins these values and bans the charcoals. */
  --dp5-canvas: #080C16;
  --dp5-surface: #0C1322;
  --dp5-raised: #141D30;
  --dp5-raised-hover: #1C2740;
  --dp5-raised-press: #243652;
  /* One quiet divider for rows and rails; the white-30% line is every edge that must read (card, field,
     control). The divider is deliberately under 1.5:1 on a fill: A43's step rules swap it for line-strong
     the moment a row fills, so it never has to carry a boundary on its own. */
  --dp5-line: #1F2A40;
  --dp5-line-canvas: #1F2A40;
  --dp5-line-strong: rgba(255, 255, 255, .30);
  --dp5-line-card: rgba(255, 255, 255, .30);
  --dp5-skel: #1C2740;
  --dp5-tabbar: #080C16;
  --dp5-scrim: rgba(8, 12, 22, .72);
  --dp5-shadow-card: none;   /* A50: the 1px white-30% edge does the work (A45's lifted shadow is retired) */
  --dp5-shadow-sheet: 0 16px 48px rgba(0, 0, 0, .6);

  /* text: secondary text clears 8:1 on the panel AND on a tile (A47's floor, re-measured for navy):
     text-2 13.44 / 12.19, text-3 8.85 / 8.02. The placeholder is text-3 (A49 left it open for A50). */
  --dp5-text: #FFFFFF;
  --dp5-text-2: #D5DCE6;
  --dp5-text-3: #A9B4C4;
  --dp5-text-off: #7E8B9E;       /* disabled only: WCAG 1.4.3 exempts inactive controls */
  --dp5-text-missing: #7E8B9E;   /* a missing value said in words (Not set, No team): readable text, not a disabled control. Same ink as off here; a theme may lift it on its own */
  --dp5-placeholder: #A9B4C4;
  --dp5-ink: #0C1322;            /* text ON a light or green fill: the panel navy */

  /* the two greens */
  --dp5-green: #00D68F;
  --dp5-green-hover: #4DE3AC;
  --dp5-green-tint: rgba(0, 214, 143, .14);
  --dp5-green-deep: #007A52;
  --dp5-green-deep-hover: #00845A;   /* white text 4.7:1; #00895C was 4.4 */
  --dp5-green-deep-press: #005C3E;
  --dp5-wash: rgba(0, 214, 143, .16);
  --dp5-grain: 0;                /* A50: look C has no grain (AMENDMENT 41's layer stays, switched off) */

  /* controls */
  /* A50: the ACTION is the one filled button per screen. Bright green with navy ink on dark (9.73:1; hover
     11.40, press 7.74), deep green with white ink on light. .dp5-btn--primary and .dp5-btn--money both paint it. */
  --dp5-action: #00D68F;  --dp5-action-ink: #0C1322;  --dp5-action-hover: #4DE3AC;  --dp5-action-press: #00BF80;
  /* --dp5-primary is the WHITE SLAB: selected segments, picked chips, tabs, toasts. Never the main button. */
  --dp5-primary: #FFFFFF;  --dp5-primary-ink: #0C1322;  --dp5-primary-hover: #E6EAF0;  --dp5-primary-press: #D5DCE6;
  /* A50 supersedes A44's outline and the older grey slab: secondary and ghost are PLAIN TEXT, no fill, no
     line, no hover wash (Ops and Hub have none). Hover is the ink stepping from text-2 to white. The wash
     tokens stay declared (an API) and are transparent. */
  --dp5-secondary: transparent;  --dp5-secondary-ink: var(--dp5-text-2);  --dp5-secondary-ink-hover: var(--dp5-text);
  --dp5-secondary-line: transparent;
  --dp5-secondary-wash: transparent;
  --dp5-secondary-wash-press: transparent;
  /* Money IS the action on dark (look C). Kept as its own names so .dp5-btn--money and v3/v4 money buttons
     keep working; on light it resolves to the deep green with white ink. */
  --dp5-money: var(--dp5-action);  --dp5-money-ink: var(--dp5-action-ink);
  --dp5-money-hover: var(--dp5-action-hover);  --dp5-money-press: var(--dp5-action-press);
  /* Focus is a thin 1.5px inset line in the text colour, never a thick green border. On light surfaces --dp5-text is ink, so the line follows the text colour there too. */
  --dp5-focus: inset 0 0 0 1.5px var(--dp5-text);
  /* The focus line must contrast the fill it sits on. A white, green or deep-green control that is NOT a kit
     class sets the variable on itself instead of restating box-shadow:  .mine { --dp5-focus: var(--dp5-focus-ink); }
     (otherwise an app-named white control paints green on white at 1.9:1). An app's own
     action button takes --dp5-focus-action (navy on the bright green, white on the deep green). */
  --dp5-focus-ink: inset 0 0 0 1.5px var(--dp5-primary-ink);
  --dp5-focus-money: inset 0 0 0 1.5px var(--dp5-money-ink);
  --dp5-focus-action: inset 0 0 0 1.5px var(--dp5-action-ink);

  /* status: always a word, and on a v5 badge a dot and a word with NO fill (A50). The tints stay for the v3/v4
     aliases and are OPAQUE, mixed 14% over the navy canvas #080C16, so nothing
     tinted is charcoal-based. White text on each clears 15:1, the status colour itself 6:1. */
  --dp5-good: var(--dp5-green);   --dp5-good-tint: #072827;
  --dp5-warn: #FFB224;            --dp5-warn-tint: #2B2318;
  --dp5-bad: #FF7A7A;             --dp5-bad-tint: #2B1B24;   --dp5-bad-deep: #C42115;   /* #FF5F5F failed 4.5 on raised rows */
  --dp5-info: #5B9DFF;            --dp5-info-tint: #142037;

  /* class-type dots: dot + word, never a fill or text colour */
  --dp5-cat-performance: var(--dp5-green);
  --dp5-cat-semi: #5B9DFF;
  --dp5-cat-power: #FFB224;
  --dp5-cat-volleyball: #A78BFA;

  /* charts: one series in green, a second in grey */
  --dp5-chart: var(--dp5-green);
  --dp5-chart-fill: rgba(0, 214, 143, .18);
  --dp5-chart-other: var(--dp5-text-2);
  --dp5-chart-axis: var(--dp5-text-3);
  --dp5-chart-base: var(--dp5-line);
  --dp5-chart-point: var(--dp5-text);

  /* type */
  --dp5-font: 'Inter', -apple-system, 'Segoe UI', system-ui, sans-serif;
  --dp5-t-hero: 56px;   /* hero numeral, 600, -.02em */
  --dp5-t-stat: 28px;   /* stat and page title, 600, -.01em */
  --dp5-t-h2: 20px;     /* section, 600 */
  --dp5-t-row: 16px;    /* row title, 500 */
  --dp5-t-body: 14px;
  --dp5-t-dense: 13px;  /* staff body */
  --dp5-t-meta: 12px;   /* text 3 */
  --dp5-t-micro: 11px;  /* caps, 600, .08em */

  /* spacing */
  --dp5-sp-1: 4px; --dp5-sp-2: 8px; --dp5-sp-3: 12px; --dp5-sp-4: 16px;
  --dp5-sp-5: 24px; --dp5-sp-6: 32px; --dp5-sp-7: 40px; --dp5-sp-8: 48px;

  /* motion: one curve, colour 100, reveal 180, sheet 240, screen 320 */
  --dp5-ease: cubic-bezier(.2, .8, .2, 1);
  --dp5-t-fast: 100ms; --dp5-t-base: 180ms; --dp5-t-sheet: 240ms; --dp5-t-page: 320ms;

  /* geometry, TOOL family (staff apps). .dpt-app overrides below. A50: one corner shape, 8 and 6 (Ops and Hub). */
  --dp5-r-ctl: 8px; --dp5-r-chip: 6px; --dp5-r-badge: 6px; --dp5-r-field: 8px;
  --dp5-r-card: 8px; --dp5-r-sheet: 8px;
  --dp5-h-ctl: 36px; --dp5-h-ctl-lg: 40px; --dp5-h-field: 40px; --dp5-h-row: 40px;
  --dp5-fs-ctl: 13px; --dp5-fs-field: 13px; --dp5-h-chip: 24px;
  --dp5-pad-card: 16px; --dp5-side-w: 220px; --dp5-content-max: 1180px;

  /* ---- aliases: v4 ---- */
  --dp4-font: var(--dp5-font);
  --dp4-bg: var(--dp5-canvas); --dp4-card: var(--dp5-surface); --dp4-card-2: var(--dp5-raised);
  --dp4-line: var(--dp5-line); --dp4-field: var(--dp5-raised); --dp4-field-line: var(--dp5-raised);
  --dp4-tabbar: var(--dp5-tabbar);
  --dp4-text: var(--dp5-text); --dp4-text-2: var(--dp5-text-2); --dp4-text-3: var(--dp5-text-3);
  --dp4-placeholder: var(--dp5-placeholder);
  --dp4-good: var(--dp5-good); --dp4-good-bg: var(--dp5-good-tint);
  --dp4-watch: var(--dp5-warn); --dp4-watch-bg: var(--dp5-warn-tint);
  --dp4-bad: var(--dp5-bad); --dp4-bad-bg: var(--dp5-bad-tint);
  --dp4-link: var(--dp5-green); --dp4-link-hover: var(--dp5-green-hover);
  --dp4-green: var(--dp5-green);
  --dp4-gold: var(--dp5-primary); --dp4-gold-ink: var(--dp5-primary-ink);   /* gold is out: the PR badge goes white */
  --dp4-primary: var(--dp5-primary); --dp4-primary-ink: var(--dp5-primary-ink); --dp4-primary-hover: var(--dp5-primary-hover);
  --dp4-btn-h: var(--dp5-h-ctl-lg); --dp4-btn-h-sm: var(--dp5-h-ctl); --dp4-field-h: var(--dp5-h-field);
  --dp4-r-card: var(--dp5-r-card); --dp4-r-field: var(--dp5-r-field); --dp4-r-pill: var(--dp5-r-ctl); --dp4-r-badge: var(--dp5-r-badge);
  --dp4-t-num-hero: var(--dp5-t-hero); --dp4-t-num-row: var(--dp5-t-stat); --dp4-t-title: var(--dp5-t-h2); --dp4-t-h1: var(--dp5-t-stat);
  --dp4-t-body: var(--dp5-t-row); --dp4-t-sub: var(--dp5-t-meta); --dp4-t-micro: var(--dp5-t-micro);   /* v4 defined these only under .dpt-app */

  /* ---- aliases: v3 ---- */
  --dp3-font-ui: var(--dp5-font); --dp3-font-display: var(--dp5-font);
  --dp3-bg: var(--dp5-canvas); --dp3-card: var(--dp5-surface); --dp3-card-2: var(--dp5-raised);
  --dp3-card-edge: var(--dp5-line); --dp3-line: var(--dp5-line); --dp3-line-strong: var(--dp5-line-strong);
  --dp3-text: var(--dp5-text); --dp3-text-2: var(--dp5-text-2); --dp3-text-3: var(--dp5-text-3);
  --dp3-accent: var(--dp5-green);
  --dp3-accent-hot: var(--dp5-green); --dp3-accent-hot-hover: var(--dp5-green-hover); --dp3-accent-hot-ink: var(--dp5-ink);
  --dp3-electric: var(--dp5-green); --dp3-electric-ink: var(--dp5-ink);
  --dp3-action: var(--dp5-primary); --dp3-action-ink: var(--dp5-primary-ink); --dp3-action-hover: var(--dp5-primary-hover);
  --dp3-action-rim: transparent;
  --dp3-neutral: var(--dp5-primary); --dp3-neutral-ink: var(--dp5-primary-ink); --dp3-neutral-hover: var(--dp5-primary-hover);
  --dp3-link: var(--dp5-green); --dp3-link-hover: var(--dp5-green-hover);
  --dp3-focus: var(--dp5-text); --dp3-focus-w: 1.5px;   /* AMENDMENT 49: v3 alias follows the text-colour line */
  --dp3-ok: var(--dp5-good); --dp3-warn: var(--dp5-warn); --dp3-danger: var(--dp5-bad); --dp3-info: var(--dp5-info);
  --dp3-ok-tint: var(--dp5-good-tint); --dp3-warn-tint: var(--dp5-warn-tint); --dp3-danger-tint: var(--dp5-bad-tint); --dp3-info-tint: var(--dp5-info-tint);
  --dp3-div-mid: var(--dp5-text-3); --dp3-div-neg: var(--dp5-bad);
  --dp3-seq-2: rgba(0, 214, 143, .35); --dp3-seq-3: rgba(0, 214, 143, .6); --dp3-seq-5: var(--dp5-green-hover);
  --dp3-score-optimal: var(--dp5-good); --dp3-score-fair: var(--dp5-warn); --dp3-score-low: var(--dp5-bad); --dp3-score-none: var(--dp5-text-3);
  --dp3-chart-1: var(--dp5-chart); --dp3-chart-2: var(--dp5-chart-other); --dp3-chart-3: var(--dp5-text-3);
  --dp3-chart-4: var(--dp5-chart-other); --dp3-chart-5: var(--dp5-chart-other);   /* category colours are dots only */
  --dp3-chart-axis: var(--dp5-chart-axis); --dp3-chart-grid: var(--dp5-chart-base); --dp3-chart-other: var(--dp5-chart-other);
  --dp3-div-pos: var(--dp5-good);
  --dp3-seq-1: var(--dp5-green-tint); --dp3-seq-4: var(--dp5-green);
  --dp3-glow-dot: none; --dp3-glow-ring: none; --dp3-glow-text: none;
  --dp3-shadow-card: var(--dp5-shadow-card); --dp3-shadow-float: var(--dp5-shadow-sheet);
  --dp3-r-sm: var(--dp5-r-badge); --dp3-r-md: var(--dp5-r-ctl); --dp3-r-lg: var(--dp5-r-card);
  --dp3-r-xl: var(--dp5-r-sheet); --dp3-r-pill: var(--dp5-r-ctl); --dp3-r-field: var(--dp5-r-field);
  --dp3-field-h: var(--dp5-h-field);
  --dp3-ease: var(--dp5-ease); --dp3-t-fast: var(--dp5-t-fast); --dp3-t-med: var(--dp5-t-base); --dp3-t-slow: var(--dp5-t-page);
  --dp3-t-score-hero: var(--dp5-t-hero); --dp3-t-score: var(--dp5-t-stat); --dp3-t-h1: var(--dp5-t-stat); --dp3-t-h2: var(--dp5-t-h2);
  --dp3-t-h3: var(--dp5-t-row); --dp3-t-body: var(--dp5-t-body); --dp3-t-sub: var(--dp5-t-meta); --dp3-t-micro: var(--dp5-t-micro);
  --dp3-sp-1: var(--dp5-sp-1); --dp3-sp-2: var(--dp5-sp-2); --dp3-sp-3: var(--dp5-sp-3); --dp3-sp-4: var(--dp5-sp-4); --dp3-sp-5: var(--dp5-sp-5);

  /* ---- aliases: v2 ---- */
  --dp2-page: var(--dp5-canvas); --dp2-card: var(--dp5-surface); --dp2-well: var(--dp5-canvas); --dp2-glass: var(--dp5-raised);
  --dp2-hairline: var(--dp5-line); --dp2-hairline-soft: var(--dp5-line-canvas); --dp2-card-border-c: transparent;
  --dp2-text: var(--dp5-text); --dp2-text-2: var(--dp5-text-2); --dp2-label: var(--dp5-text-3);
  --dp2-good: var(--dp5-good); --dp2-warn: var(--dp5-warn); --dp2-crit: var(--dp5-bad); --dp2-crit-chip-bg: var(--dp5-bad-tint);
  --dp2-gold: var(--dp5-primary); --dp2-gold-ink: var(--dp5-primary-ink);
  --dp2-accent-text: var(--dp5-green);
  --dp2-action: var(--dp5-primary); --dp2-action-ink: var(--dp5-primary-ink); --dp2-action-hover: var(--dp5-primary-hover);
  --dp2-action-glow: none; --dp2-fab-shadow: none; --dp2-nav-shadow: none; --dp2-action-edge: transparent;
  --dp2-nav-item: var(--dp5-text-3); --dp2-nav-active: var(--dp5-green); --dp2-nav-border: var(--dp5-line-canvas); --dp2-nav-bg: var(--dp5-tabbar);
  --dp2-streak-on: var(--dp5-green);
  --dp2-r-hero: var(--dp5-r-card); --dp2-r-card: var(--dp5-r-card); --dp2-r-stat: var(--dp5-r-card);
  --dp2-r-inner: var(--dp5-r-ctl); --dp2-r-pill: var(--dp5-r-ctl); --dp2-fs-nav: var(--dp5-t-meta);

  /* ---- aliases: v1 ---- */
  --dp-font-heading: var(--dp5-font); --dp-font-body: var(--dp5-font);
  --dp-brand: var(--dp5-green-deep); --dp-brand-dark: var(--dp5-green-deep-press);   /* the money colour; gold is gone */
  --dp-green: var(--dp5-green-deep); --dp-green-brand: var(--dp5-green); --dp-green-hover: var(--dp5-green-hover); --dp-green-text: var(--dp5-green);
  --dp-ink: var(--dp5-ink); --dp-ink-deep: var(--dp5-canvas); --dp-slate: var(--dp5-text-3);
  --dp-paper: var(--dp5-surface); --dp-mint: var(--dp5-green-tint); --dp-white: var(--dp5-text);
  --dp-border: var(--dp5-line); --dp-field-border: var(--dp5-line); --dp-field-hover: var(--dp5-line-strong);
  --dp-error: var(--dp5-bad);
  --dp-good: var(--dp5-good); --dp-good-wash: var(--dp5-good-tint); --dp-good-t: var(--dp5-good); --dp-good-wash-t: var(--dp5-good-tint);
  --dp-warn: var(--dp5-warn); --dp-warn-wash: var(--dp5-warn-tint); --dp-warn-t: var(--dp5-warn); --dp-warn-wash-t: var(--dp5-warn-tint);
  --dp-crit: var(--dp5-bad); --dp-crit-ink: var(--dp5-bad); --dp-crit-wash: var(--dp5-bad-tint); --dp-crit-t: var(--dp5-bad); --dp-crit-wash-t: var(--dp5-bad-tint);
  --dp-action: var(--dp5-primary); --dp-action-ink: var(--dp5-primary-ink); --dp-action-hover: var(--dp5-primary-hover);
  --dp-action-t: var(--dp5-green); --dp-action-t-ink: var(--dp5-ink); --dp-action-t-hover: var(--dp5-green-hover);
  --dp-attention: var(--dp5-warn); --dp-attention-ink: var(--dp5-ink);
  --dp-raised-dark: var(--dp5-raised);
  --dp-surface: var(--dp5-canvas); --dp-surface-raised: var(--dp5-surface); --dp-surface-sunken: var(--dp5-canvas);
  --dp-text: var(--dp5-text); --dp-text-muted: var(--dp5-text-2); --dp-line: var(--dp5-line);
  --dp-radius: var(--dp5-r-ctl); --dp-radius-lg: var(--dp5-r-card);
  --dp-btn-h: var(--dp5-h-ctl-lg); --dp-btn-h-sm: var(--dp5-h-ctl); --dp-btn-h-desk: var(--dp5-h-ctl);
  --dp-chrome: var(--dp5-canvas); --dp-chrome-green: var(--dp5-green); --dp-chrome-ink: var(--dp5-text);
  --dp-shadow: none; --dp-shadow-lg: none; --dp-shadow-t: none;
}

/* FAMILY geometry (athlete portal, health-hub): rounded, taller, bigger type. */
:root.dpt-v5.dpt-app, :root.dpt-v5.dpt-app :is(.dpt-dark, .dpt-light) {
  --dp5-r-ctl: 999px; --dp5-r-chip: 999px; --dp5-r-badge: 6px; --dp5-r-field: 16px;
  --dp5-r-card: 22px; --dp5-r-sheet: 24px;
  --dp5-h-ctl: 44px; --dp5-h-ctl-lg: 56px; --dp5-h-field: 56px; --dp5-h-row: 56px;
  --dp5-fs-ctl: 15px; --dp5-fs-field: 16px; --dp5-h-chip: 32px;
  --dp5-pad-card: 18px; --dp5-content-max: 720px;
}
/* A50: the FAMILY page is the website's dark section, not the staff frame. Page #0C1322, cards (tiles) #141D30
   with the white-30% edge, footer and tab bar #080C16 (--dp5-tabbar). Screen only and never on a light root or
   island: this rule is (0,4,0) on body, so outside @media screen it would beat the print and light canvases. */
@media screen {
  :root.dpt-v5.dpt-app:not(.dpt-light), :root.dpt-v5.dpt-app .dpt-dark { --dp5-canvas: #0C1322; }
}

/* TOOL family on a phone OR any coarse pointer (a tablet held on the gym floor): touch targets. */
@media (max-width: 768px), (pointer: coarse) {
  :root.dpt-v5:not(.dpt-app), :root.dpt-v5:not(.dpt-app) :is(.dpt-dark, .dpt-light) { --dp5-h-ctl: 44px; --dp5-h-ctl-lg: 48px; --dp5-h-field: 44px; --dp5-h-row: 48px; --dp5-fs-ctl: 14px; --dp5-fs-field: 16px; --dp5-h-chip: 32px; }
}

/* LIGHT surfaces: print, PDF, email only. Apps are dark-only; no toggle. A .dpt-light element inside a dark app
   (a print sheet) gets these too; it must come after the dark block so it wins the equal-specificity tie. */
:root.dpt-v5.dpt-light, .dpt-v5 .dpt-light {
  color-scheme: light;
  /* A50: look C light. Page #F5F7FA, cards and panels white, one cool line #DDE3EA, navy text, one cool grey
     #3D4757 for text-2 and text-3 (8.75:1 on the page, 9.39:1 on a card). Action and money are the deep green
     with WHITE ink; the selected slab is navy with white ink. Secondary stays plain text (the dark block's
     transparent tokens resolve here too), which prints as well as a fill does. */
  --dp5-canvas: #F5F7FA; --dp5-surface: #FFFFFF; --dp5-raised: #FFFFFF; --dp5-raised-hover: #EEF1F5; --dp5-raised-press: #E6EAF0;
  --dp5-line: #DDE3EA; --dp5-line-canvas: #DDE3EA; --dp5-line-strong: #7D8898; --dp5-skel: #EEF1F5; --dp5-tabbar: #FFFFFF; --dp5-grain: 0;
  --dp5-line-card: #DDE3EA; --dp5-shadow-card: none;
  --dp5-text: #0C1322; --dp5-text-2: #3D4757; --dp5-text-3: #3D4757; --dp5-text-off: #A0A9B6; --dp5-text-missing: #A0A9B6; --dp5-placeholder: #5E6978;
  --dp5-green: #007A52; --dp5-green-hover: #005C3E; --dp5-green-tint: rgba(0, 122, 82, .12); --dp5-wash: rgba(0, 122, 82, .08);
  --dp5-action: #007A52; --dp5-action-ink: #FFFFFF; --dp5-action-hover: #00845A; --dp5-action-press: #005C3E;
  --dp5-primary: #0C1322; --dp5-primary-ink: #FFFFFF; --dp5-primary-hover: #1C2740; --dp5-primary-press: #243652;
  --dp5-good-tint: #E0EFEA; --dp5-warn: #96540A; --dp5-warn-tint: #F2EBE2;
  --dp5-bad: #C42115; --dp5-bad-deep: #C42115; --dp5-bad-tint: #F9E9E8;
  --dp5-info: #1D4ED8; --dp5-info-tint: #E8EDFB;
  --dp5-chart-fill: rgba(0, 122, 82, .14);
  --dp5-scrim: rgba(12, 19, 34, .4);
}
@media print {
  :root.dpt-v5, .dpt-v5 :is(.dpt-dark, .dpt-light) {
    /* paper stays white; everything else is look C light */
    --dp5-canvas: #FFFFFF; --dp5-surface: #FFFFFF; --dp5-raised: #FFFFFF; --dp5-line: #DDE3EA; --dp5-line-canvas: #DDE3EA;
    --dp5-line-card: #DDE3EA; --dp5-shadow-card: none;
    --dp5-text: #0C1322; --dp5-text-2: #3D4757; --dp5-text-3: #3D4757;
    --dp5-green: #007A52; --dp5-green-tint: rgba(0, 122, 82, .12);
    --dp5-primary: #0C1322; --dp5-primary-ink: #FFFFFF;
    --dp5-action: #007A52; --dp5-action-ink: #FFFFFF; --dp5-action-hover: #00845A; --dp5-action-press: #005C3E;
    --dp5-warn: #96540A; --dp5-bad: #C42115;
  }
}

/* ============================================================ BASE */
html.dpt-v5 { background: var(--dp5-canvas); }
.dpt-v5 body {
  /* background-color, not the shorthand: body.dp5-washed keeps its wash image. */
  margin: 0; background-color: var(--dp5-canvas); color: var(--dp5-text);
  font: var(--dp5-t-body)/1.4 var(--dp5-font);
  -webkit-font-smoothing: antialiased; font-feature-settings: "tnum" 1;
  -webkit-tap-highlight-color: transparent;
}
/* Zero-specificity base so a class on the element always wins (anchor buttons, nav links, app headings). */
:where(.dpt-v5 a) { color: var(--dp5-green); text-decoration: none; }
:where(.dpt-v5 a:hover) { color: var(--dp5-green-hover); }
:where(.dpt-v5 p a, .dpt-v5 li a, .dpt-v5 td a, .dpt-v5 .dp5-sub a) { text-decoration: underline; text-underline-offset: 2px; }   /* links inside copy need more than colour */
.dpt-v5 :is(button, input, select, textarea, h1, h2, h3, h4, h5, h6) { font-family: var(--dp5-font); }
:where(.dpt-v5 h1, .dpt-v5 h2, .dpt-v5 h3, .dpt-v5 h4) { margin: 0; font-weight: 600; letter-spacing: -.01em; }
:where(.dpt-v5 h1) { font-size: var(--dp5-t-stat); }
:where(.dpt-v5 h2) { font-size: var(--dp5-t-h2); }
:where(.dpt-v5 h3) { font-size: var(--dp5-t-row); font-weight: 500; letter-spacing: 0; }
/* Components size themselves border-box; apps that never set it would otherwise overflow 100%-width fields by their padding. */
.dpt-v5 [class*="dp5-"], .dpt-v5 [class*="dp5-"] *, .dpt-v5 [class*="dp5-"]::before, .dpt-v5 [class*="dp5-"]::after { box-sizing: border-box; }

/* Focus: the inset line, everywhere, never outside the edge. Text links underline instead. */
/* Focus rules carry a triple .dpt-v5 (0,3,0 scope) on purpose: dpt.v3.css's own
   `.dpt-dark :is(input, select, textarea, button, a.dp3-btn, .dp3-btn):focus-visible` is (0,3,1) and
   otherwise beats every focus colour here (a 1px green line showed on the deep-green
   money button). The bump is invisible to users and keeps the per-button inks winning.
   AMENDMENT 50.1: that v3 rule (and dpt.v1.css's) also recoloured a focused control's own BORDER, a second
   line beside this one (a white rim round the green action). Both border rules now skip anything inside
   .dpt-v5, so here the inset line is the only focus mark and a control keeps its resting edge. */
/* :where() keeps this base rule at (0,2,0); with :is() it was (0,4,0) and beat every per-button focus
   colour below (money buttons took green on deep green, 2.8:1). */
.dpt-v5.dpt-v5.dpt-v5 :where(button, [role="button"], input, select, textarea, summary, [tabindex]:not([tabindex="-1"]), a.dp5-btn):focus-visible {
  outline: 0; box-shadow: var(--dp5-focus);
}
:where(.dpt-v5 a:not(.dp5-btn)):focus-visible { outline: 0; text-decoration: underline; text-decoration-thickness: 2px; color: var(--dp5-green); }
/* On a filled control the text-colour line has no contrast: the line takes the control's own ink instead.
   A50: the primary BUTTON is the action (navy line on the bright green, white on the light deep green); the
   white slab (picked chip, PR flag) and the red confirm keep the slab ink. */
.dpt-v5.dpt-v5.dpt-v5 .dp5-btn--primary:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-action-ink); }
.dpt-v5.dpt-v5.dpt-v5 :is(.dp5-chip.is-on, .dp5-pr, .dp5-badge--pr, .dp5-btn--danger-fill):focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-primary-ink); }
.dpt-v5.dpt-v5.dpt-v5 .dp5-btn--money:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-money-ink); }
.dpt-v5.dpt-v5.dpt-v5 .dp5-check:checked:focus-visible, .dpt-v5.dpt-v5.dpt-v5 .dp5-check:indeterminate:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-ink); }
@media (forced-colors: active) {
  .dpt-v5 :where(a, button, input, select, textarea, summary, [role="button"], [tabindex]:not([tabindex="-1"])):focus-visible { outline: 2px solid; outline-offset: -2px; box-shadow: none; }
  .dpt-v5 :is(.dp5-check, .dp5-switch, .dp5-radio) { appearance: auto; forced-color-adjust: auto; }
  .dpt-v5 :is(.dp5-check, .dp5-switch, .dp5-radio)::after { content: none; }
}

/* ============================================================ TYPE */
.dp5-eyebrow { font-size: var(--dp5-t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--dp5-green); }
.dp5-eyebrow--quiet { color: var(--dp5-text-3); }
.dp5-title { font-size: var(--dp5-t-stat); font-weight: 600; letter-spacing: -.01em; line-height: 1.15; }
.dp5-h2 { font-size: var(--dp5-t-h2); font-weight: 600; }
.dp5-sub { color: var(--dp5-text-2); }
.dp5-meta { font-size: var(--dp5-t-meta); color: var(--dp5-text-3); }
.dp5-num { font-size: var(--dp5-t-hero); font-weight: 600; letter-spacing: -.02em; line-height: 1; font-variant-numeric: tabular-nums; }
.dp5-num small, .dp5-unit { font-size: .36em; font-weight: 500; color: var(--dp5-text-2); letter-spacing: 0; margin-left: .12em; }
.dp5-stat { font-size: var(--dp5-t-stat); font-weight: 600; letter-spacing: -.01em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.dp5-delta { font-size: var(--dp5-t-dense); font-weight: 600; color: var(--dp5-good); }
.dp5-delta--flat { color: var(--dp5-text-3); }
.dp5-delta--down { color: var(--dp5-bad); }

/* ============================================================ BUTTONS */
.dp5-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: var(--dp5-h-ctl); padding: 0 16px; border-radius: var(--dp5-r-ctl);
  /* Every variant carries the same 1.5px box so the geometry never moves. The border colour is
     transparent unless a variant sets it. box-sizing is border-box here, so the control stays 40px / 44px. */
  border: 1.5px solid var(--dp5-secondary-line);
  background: var(--dp5-secondary); color: var(--dp5-secondary-ink);
  font: 600 var(--dp5-fs-ctl)/1 var(--dp5-font); white-space: nowrap; cursor: pointer;
  text-decoration: none; transform: none; box-shadow: none;
  transition: background var(--dp5-t-fast) var(--dp5-ease), color var(--dp5-t-fast) var(--dp5-ease);
}
/* A50: the primary button is the ACTION (bright green, navy ink); --dp5-primary is the selected slab, not this. */
.dp5-btn--primary { background: var(--dp5-action); color: var(--dp5-action-ink); border-color: transparent; }
.dp5-btn--money { background: var(--dp5-money); color: var(--dp5-money-ink); border-color: transparent; }   /* A42: NO EDGE ON A MONEY BUTTON, EVER. */
.dp5-btn--ghost { background: transparent; color: var(--dp5-secondary-ink); border-color: transparent; }
.dp5-btn--link { background: transparent; color: var(--dp5-green); padding: 0 4px; border-color: transparent; }
.dp5-btn--danger { background: transparent; color: var(--dp5-bad); border-color: transparent; }
.dp5-btn--danger-fill { background: var(--dp5-bad); color: var(--dp5-primary-ink); border-color: transparent; }   /* confirm sheets only */
.dp5-btn--lg { height: var(--dp5-h-ctl-lg); padding: 0 20px; font-size: calc(var(--dp5-fs-ctl) + 1px); }
.dp5-btn--block { width: 100%; }
.dp5-btn--icon { width: var(--dp5-h-ctl); padding: 0; }
/* A50: a disabled text button stays text; only a disabled FILLED button keeps a (raised) fill so its shape holds. */
.dp5-btn:disabled, .dp5-btn[aria-disabled="true"] { background: transparent; color: var(--dp5-text-off); border-color: transparent; cursor: default; }
.dp5-btn:is(.dp5-btn--primary, .dp5-btn--money, .dp5-btn--danger-fill):is(:disabled, [aria-disabled="true"]) { background: var(--dp5-raised-hover); }
.dp5-btn.is-loading { pointer-events: none; }   /* label keeps its colour; the spinner is the state */
.dp5-btn svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
@media (hover: hover) {
  .dp5-btn:hover { background: var(--dp5-secondary-wash); color: var(--dp5-secondary-ink-hover); }
  .dp5-btn--primary:hover { background: var(--dp5-action-hover); color: var(--dp5-action-ink); }
  .dp5-btn--money:hover { background: var(--dp5-money-hover); color: var(--dp5-money-ink); }
  .dp5-btn--ghost:hover { background: transparent; color: var(--dp5-secondary-ink-hover); }
  .dp5-btn--link:hover { background: transparent; color: var(--dp5-green-hover); }
  .dp5-btn--danger:hover { background: transparent; color: var(--dp5-bad); }   /* A50: danger is a word; no tint on hover */
  .dp5-btn--danger-fill:hover { background: #FF7A7A; color: var(--dp5-ink); }
  .dp5-btn:disabled:hover { background: transparent; color: var(--dp5-text-off); }
}
/* Pressed states sit AFTER the hover block so a mouse press shows on desktop (equal specificity, later wins). */
.dp5-btn:active { background: var(--dp5-secondary-wash-press); color: var(--dp5-secondary-ink-hover); }
.dp5-btn--primary:active { background: var(--dp5-action-press); color: var(--dp5-action-ink); }
.dp5-btn--money:active { background: var(--dp5-money-press); color: var(--dp5-money-ink); }
.dp5-btn--ghost:active { background: transparent; color: var(--dp5-secondary-ink-hover); }
.dp5-btn--link:active { background: transparent; color: var(--dp5-green); }
.dp5-btn--danger:active { background: transparent; color: var(--dp5-bad); }
.dp5-btn--danger-fill:active { background: var(--dp5-bad); color: var(--dp5-primary-ink); }
.dp5-btn:is(:disabled, [aria-disabled="true"]):is(:hover, :active) { background: transparent; color: var(--dp5-text-off); }
.dp5-btn:is(.dp5-btn--primary, .dp5-btn--money, .dp5-btn--danger-fill):is(:disabled, [aria-disabled="true"]):is(:hover, :active) { background: var(--dp5-raised-hover); }
.dp5-btn, .dp5-btn:is(:hover, :active) { transform: none; filter: none; text-shadow: none; }   /* a host theme's button:hover never lifts us */
.dp5-btn--link, .dp5-link { min-width: 24px; min-height: 24px; }
.dp5-spin { width: 14px; height: 14px; border: 2px solid rgba(169, 180, 196, .4); border-top-color: currentColor; border-radius: 50%; animation: dp5-spin .8s linear infinite; }
@keyframes dp5-spin { to { transform: rotate(360deg); } }
.dp5-link { background: none; border: 0; padding: 0; color: var(--dp5-green); font: inherit; font-weight: 500; cursor: pointer; }
.dp5-link--quiet { color: var(--dp5-text-2); }   /* sign-in secondary link only */

/* ============================================================ FIELDS */
.dp5-label { display: block; font-size: var(--dp5-t-meta); color: var(--dp5-text-2); margin: 0 0 6px; }
.dp5-field {
  display: block; width: 100%; height: var(--dp5-h-field); padding: 0 14px;
  background: var(--dp5-raised); color: var(--dp5-text); border: 0; border-radius: var(--dp5-r-field);
  font: 400 var(--dp5-fs-field)/1.2 var(--dp5-font); box-shadow: inset 0 0 0 1px var(--dp5-line-strong); appearance: none; -webkit-appearance: none;
}
/* AMENDMENT 48: a field shows its edge. A borderless fill barely separates from the card or the canvas,
   so a field was found by its placeholder. The edge is inset (no layout change) in line-strong,
   and it steps aside for the focus and error lines, which set their own box-shadow. The default
   below gives every text field inside the kit the same edge; :where() keeps it at zero specificity, so an app rule
   that styles its own field (a search wrapper, a keypad buffer) keeps the last word. Never an alias token on :root:
   a var() read here re-resolves inside a light island, an alias would not (AMENDMENT 11). */
:where(.dpt-v5) :where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"], [type="file"], [type="color"], [type="submit"], [type="button"], [type="reset"], [type="image"]), textarea, select) {
  box-shadow: inset 0 0 0 1px var(--dp5-line-strong);
}
.dp5-field::placeholder { color: var(--dp5-placeholder); opacity: 1; }
.dp5-field[readonly] { background: var(--dp5-canvas); box-shadow: inset 0 0 0 1px var(--dp5-line); }
.dp5-field:is(:disabled, [aria-disabled="true"]) { color: var(--dp5-text-off); }
.dp5-field:focus, .dp5-field:focus-visible { outline: 0; box-shadow: var(--dp5-focus); }
.dp5-field[aria-invalid="true"], .dp5-field.is-error { box-shadow: inset 0 0 0 2px var(--dp5-bad); }
textarea.dp5-field { height: auto; min-height: calc(var(--dp5-h-field) * 2); padding: 12px 14px; line-height: 1.4; resize: vertical; }
select.dp5-field { padding-inline-end: 36px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23A9B4C4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 12px center; }
.dp5-error { display: block; font-size: var(--dp5-t-meta); color: var(--dp5-bad); margin-top: 6px; }
.dp5-help { display: block; font-size: var(--dp5-t-meta); color: var(--dp5-text-3); margin-top: 6px; }
.dp5-field-wrap { position: relative; --dp5-aux-w: 4rem; }
.dp5-field-wrap:has(.dp5-field-aux) > .dp5-field { padding-inline-end: calc(var(--dp5-aux-w) + 20px); }   /* typed text never runs under Show */
.dp5-field-wrap .dp5-field-aux { position: absolute; inset-inline-end: 6px; top: 50%; transform: translateY(-50%); min-width: var(--dp5-aux-w); min-height: 24px; background: none; border: 0; padding: 0 8px; color: var(--dp5-text-2); font: 500 var(--dp5-t-dense)/1 var(--dp5-font); cursor: pointer; }
@supports (appearance: base-select) {
  select.dp5-field:not([multiple]) { appearance: base-select; background-image: none; padding-inline-end: 14px; }
  select.dp5-field::picker-icon { color: var(--dp5-text-2); }
  select.dp5-field::picker(select) { background: var(--dp5-surface); color: var(--dp5-text); border: 0; border-radius: var(--dp5-r-sheet); box-shadow: var(--dp5-shadow-sheet); }
}
.dp5-radio { appearance: none; width: 24px; height: 24px; margin: 0; border: 0; border-radius: 50%; background: var(--dp5-raised); box-shadow: inset 0 0 0 1.5px var(--dp5-text-3); cursor: pointer; }   /* A50: a tile is raised too, so the edge (A48's checkbox recipe) is what finds it */
.dp5-radio:checked { background: radial-gradient(circle, var(--dp5-green) 0 6px, var(--dp5-raised) 7px); box-shadow: inset 0 0 0 1.5px var(--dp5-green); }
.dp5-fieldset { min-width: 0; margin: 0; padding: 0; border: 0; }
.dp5-fieldset > legend { padding: 0; margin-bottom: 8px; font-size: var(--dp5-t-meta); color: var(--dp5-text-2); }
.dp5-input-group { display: flex; gap: 8px; min-width: 0; }
.dp5-input-group > .dp5-field { flex: 1; min-width: 0; width: 0; }
.dp5-label.is-required::after { content: " *"; color: var(--dp5-bad); }
.dp5-switch { appearance: none; width: 40px; height: 24px; border-radius: 12px; /* the one capsule: a switch reads as a switch */ background: var(--dp5-raised-press); position: relative; cursor: pointer; border: 0; margin: 0; }
.dp5-switch::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--dp5-text-2); transition: transform var(--dp5-t-fast) var(--dp5-ease), background var(--dp5-t-fast) var(--dp5-ease); }
.dp5-switch:is(:checked, [aria-checked="true"]) { background: var(--dp5-green-deep); }
.dp5-switch:is(:checked, [aria-checked="true"])::after { transform: translateX(16px); background: #FFFFFF; }
.dp5-check { appearance: none; width: 24px; height: 24px; border-radius: 4px; background: var(--dp5-raised); border: 0; margin: 0; cursor: pointer; display: inline-grid; place-items: center; }
.dp5-check:checked { background: var(--dp5-green); }
.dp5-check:checked::after { content: ""; width: 11px; height: 6px; border: 2px solid var(--dp5-ink); border-top: 0; border-right: 0; transform: translateY(-1px) rotate(-45deg); }
.dp5-check:indeterminate { background: var(--dp5-green); }
.dp5-check:indeterminate::after { content: ""; width: 11px; height: 2px; background: var(--dp5-ink); }
/* AMENDMENT 48: an unticked box shows its edge in text-3. The native box had none (raised on raised); the component
   box (dpt.v5.components.css) drew line-strong, which is too faint on a hovered or selected row and on the
   table header, which is where a row checkbox lives. text-3 clears 3:1 on the card, a raised row and the canvas.
   The component rule is (0,1,0) and loads later, so this is (0,3,0). */
input.dp5-check:not(:checked):not(:indeterminate) { box-shadow: inset 0 0 0 1.5px var(--dp5-text-3); }
.dp5-check:not(input):not(.is-on):not(.is-mixed) { border-color: var(--dp5-text-3); }
.dp5-check:is(:disabled, [aria-disabled="true"]), .dp5-switch:is(:disabled, [aria-disabled="true"]), .dp5-radio:is(:disabled, [aria-disabled="true"]) { opacity: .45; cursor: default; }

/* ============================================================ SURFACES */
/* AMENDMENT 50: a card is a TILE, raised #141D30 with the white-30% edge and no shadow
   (--dp5-shadow-card is none). The edge over the tile is #5B616E, 3.13:1 on the canvas. Rows, table heads and
   chips inside it step one rung up (raised-hover to hover, raised-press to select) so they still read.
   Cards only: rows, fields, chips and buttons never lift. Light surfaces (print, email) reset the edge below. */
.dp5-card { background: var(--dp5-raised); border-radius: var(--dp5-r-card); border: 1px solid var(--dp5-line-card); box-shadow: var(--dp5-shadow-card); }
.dp5-card__body { padding: var(--dp5-pad-card); }
.dp5-card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: var(--dp5-pad-card) var(--dp5-pad-card) 0; }
.dp5-row { display: flex; align-items: center; gap: 12px; min-height: var(--dp5-h-row); padding: 10px var(--dp5-pad-card); border-top: 1px solid var(--dp5-line); color: inherit; text-decoration: none; }
.dp5-row:first-child { border-top: 0; }
.dp5-row__main { flex: 1; min-width: 0; }
.dp5-row__t { font-size: var(--dp5-t-row); font-weight: 500; line-height: 1.25; }
.dp5-row__s { font-size: var(--dp5-t-meta); color: var(--dp5-text-3); margin-top: 2px; }
.dp5-row__v { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dp5-row__v small { font-size: .8em; font-weight: 500; color: var(--dp5-text-2); margin-left: 3px; }
.dp5-row__d { font-size: var(--dp5-t-meta); font-weight: 600; color: var(--dp5-good); text-align: right; }
.dp5-chev { color: var(--dp5-text-3); flex: none; width: 16px; height: 16px; }
a.dp5-row, button.dp5-row { width: 100%; text-align: left; background: none; border-top: 1px solid var(--dp5-line); border-left: 0; border-right: 0; border-bottom: 0; font: inherit; cursor: pointer; }
@media (hover: hover) { a.dp5-row:hover, button.dp5-row:hover, .dp5-row.is-hover { background: var(--dp5-raised-hover); } }
.dp5-row.is-selected, .dp5-row[aria-selected="true"] { background: var(--dp5-raised-press); }
.dp5-row:is(.is-hover, .is-selected, [aria-selected="true"]) :is(.dp5-row__s, .dp5-meta, .dp5-delta--flat) { color: var(--dp5-text-2); }   /* the quiet text-3 is too faint on a filled row */
@media (hover: hover) { a.dp5-row:hover :is(.dp5-row__s, .dp5-meta), button.dp5-row:hover :is(.dp5-row__s, .dp5-meta) { color: var(--dp5-text-2); } }
.dp5-row__t, .dp5-row__main { min-width: 0; overflow-wrap: anywhere; }
.dp5-card__head { flex-wrap: wrap; }
.dp5-card__head > * { min-width: 0; }
:root.dpt-v5:not(.dpt-app) .dp5-row__t { font-size: var(--dp5-t-body); }
.dp5-divider { height: 1px; background: var(--dp5-line); border: 0; margin: 0; }
.dp5-avatar { width: 36px; height: 36px; border-radius: 50%; flex: none; background: var(--dp5-raised-hover); color: var(--dp5-text); display: inline-flex; align-items: center; justify-content: center; font-size: var(--dp5-t-meta); font-weight: 600; overflow: hidden; }
.dp5-avatar img { width: 100%; height: 100%; object-fit: cover; }
.dp5-avatar--lg { width: 48px; height: 48px; font-size: var(--dp5-t-body); }
.dp5-prog { height: 6px; background: var(--dp5-raised); border-radius: 3px; overflow: hidden; }
.dp5-prog > i, .dp5-prog__fill { display: block; height: 100%; background: var(--dp5-green); border-radius: 3px; }

/* tables (staff apps) */
.dp5-table { width: 100%; border-collapse: collapse; font-size: var(--dp5-t-dense); }
/* AMENDMENT 41: the head sits one step lighter than the card, with a text-2 label. The rule: the head is never
   the card fill it sits in, or it vanishes against the card. */
.dp5-table th { position: sticky; top: 0; background: var(--dp5-raised-hover); text-align: left; font-size: var(--dp5-t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--dp5-text-2); padding: 8px 12px; border-bottom: 1px solid var(--dp5-line); }
.dp5-table td { padding: 0 12px; height: var(--dp5-h-row); border-bottom: 1px solid var(--dp5-line); vertical-align: middle; }
.dp5-table :is(th, td).is-num { text-align: right; font-variant-numeric: tabular-nums; }
@media (hover: hover) { .dp5-table tbody tr:hover td { background: var(--dp5-raised-hover); } .dp5-table tbody tr:hover .dp5-meta { color: var(--dp5-text-2); } }
.dp5-table tr:is(.is-selected, [aria-selected="true"]) td { background: var(--dp5-raised-press); }
.dp5-table tr:is(.is-selected, [aria-selected="true"]) .dp5-meta { color: var(--dp5-text-2); }

/* AMENDMENT 43: an edge never paints in the fill that is about to cover it. --dp5-line and
   --dp5-raised were once the same colour, so a hairline on a hovered or selected row vanished - the
   edge did not fade, it ceased to exist. Nothing at rest moves: the edge steps to the strong line
   exactly while the element is filled, and the element ABOVE it steps too, because that hairline is
   the hovered row's own top edge. Moving the FILL to another step was tried and does not separate the line enough.
   The :has() rules are kept SEPARATE from the rest: an unsupported selector kills a whole rule, and
   the floor tablets are iPadOS 15, where :has() only arrived in 15.4. There the step simply does not
   happen and hover looks as it did before. */
.dp5-row:is(.is-hover, .is-selected, [aria-selected="true"]),
.dp5-row:is(.is-hover, .is-selected, [aria-selected="true"]) + .dp5-row { border-top-color: var(--dp5-line-strong); }
.dp5-table tbody tr:is(.is-selected, [aria-selected="true"]) td { border-bottom-color: var(--dp5-line-strong); }
.dp5-table tbody tr:has(+ tr:is(.is-selected, [aria-selected="true"])) td { border-bottom-color: var(--dp5-line-strong); }
.dp5-table:has(tbody tr:first-child:is(.is-selected, [aria-selected="true"])) thead th { border-bottom-color: var(--dp5-line-strong); }
@media (hover: hover) {
  a.dp5-row:hover, button.dp5-row:hover,
  a.dp5-row:hover + .dp5-row, button.dp5-row:hover + .dp5-row { border-top-color: var(--dp5-line-strong); }
  .dp5-table tbody tr:hover td { border-bottom-color: var(--dp5-line-strong); }
  .dp5-table tbody tr:has(+ tr:hover) td { border-bottom-color: var(--dp5-line-strong); }
  .dp5-table:has(tbody tr:first-child:hover) thead th { border-bottom-color: var(--dp5-line-strong); }
}

/* ============================================================ BADGES, CHIPS, DOTS */
.dp5-badge { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: var(--dp5-r-badge); font-size: var(--dp5-t-meta); font-weight: 600; line-height: 1; white-space: nowrap; background: var(--dp5-raised-hover); color: var(--dp5-text-2); }
/* AMENDMENT 50: a status badge is the dot and the word, no fill, no padding, so the
   word lines up with the text beside it. The word is never green on a green ground: text on green is white or black. */
:is(.dp5-badge--good, .dp5-badge--warn, .dp5-badge--bad, .dp5-badge--info) { background: transparent; color: var(--dp5-text); padding: 0; }
:is(.dp5-badge--good, .dp5-badge--warn, .dp5-badge--bad, .dp5-badge--info)::before { content: ""; width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dp5-badge--good::before { background: var(--dp5-good); }
.dp5-badge--warn::before { background: var(--dp5-warn); }
.dp5-badge--bad::before { background: var(--dp5-bad); }
.dp5-badge--info::before { background: var(--dp5-info); }
.dp5-badge--pr, .dp5-pr { background: var(--dp5-primary); color: var(--dp5-primary-ink); letter-spacing: .04em; }
.dp5-badge { max-width: 100%; }
/* A50: a choice chip is a tile with the white-30% edge (Ops' sheet chips); picked is the white slab, no edge. */
.dp5-chip { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px; border: 0; border-radius: var(--dp5-r-chip); background: var(--dp5-raised); box-shadow: inset 0 0 0 1px var(--dp5-line-card); color: var(--dp5-text-2); font: 500 var(--dp5-t-dense)/1 var(--dp5-font); cursor: pointer; white-space: nowrap; }
@media (hover: hover) { .dp5-chip:not(.is-on):not([aria-pressed="true"]):not([aria-selected="true"]):not(:disabled):hover { background: var(--dp5-raised-hover); color: var(--dp5-text); } }
.dp5-chip { height: var(--dp5-h-chip); }
:root.dpt-v5:not(.dpt-app) .dp5-chip { font-size: var(--dp5-t-meta); }
.dp5-chip:is(:disabled, [aria-disabled="true"]) { background: var(--dp5-raised); color: var(--dp5-text-off); cursor: default; }
/* A50.1: a SEGMENT's options (.dp5-seg > .dp5-chip) are words, not tiles: no fill, no edge, text-2 turning white.
   The picked one is the white slab (the next rule, declared after this one so it wins). A lone choice chip keeps
   Ops' tile + edge above. */
.dp5-seg > .dp5-chip { background: transparent; box-shadow: none; }
@media (hover: hover) { .dp5-seg > .dp5-chip:not(.is-on):not([aria-pressed="true"]):not([aria-selected="true"]):not(:disabled):hover { background: transparent; } }
.dp5-chip.is-on, .dp5-chip[aria-pressed="true"], .dp5-chip[aria-selected="true"] { background: var(--dp5-primary); color: var(--dp5-primary-ink); font-weight: 600; box-shadow: none; }
.dp5-seg { display: inline-flex; gap: 6px; }
.dp5-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--dp5-text-3); flex: none; }
.dp5-dot--performance { background: var(--dp5-cat-performance); }
.dp5-dot--semi { background: var(--dp5-cat-semi); }
.dp5-dot--power { background: var(--dp5-cat-power); }
.dp5-dot--volleyball { background: var(--dp5-cat-volleyball); }
.dp5-dot--good { background: var(--dp5-good); } .dp5-dot--warn { background: var(--dp5-warn); } .dp5-dot--bad { background: var(--dp5-bad); }

/* ============================================================ NAVIGATION */
.dp5-lockup { display: flex; align-items: center; gap: 10px; padding: 6px 8px 16px; color: var(--dp5-text); text-decoration: none; }
.dp5-lockup svg, .dp5-lockup img { height: 22px; width: auto; display: block; }
.dp5-lockup b { font-weight: 700; letter-spacing: .02em; font-size: 15px; }
.dp5-lockup span { font-size: var(--dp5-t-micro); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--dp5-text-3); margin-inline-start: 2px; }
/* AMENDMENT 41: the sidebar is its own plane (the tab-bar tone), and the active item carries a 2px
   green rail. Green on navigation is the active marker only, never a fill. */
.dp5-side { width: var(--dp5-side-w); flex: none; background: var(--dp5-tabbar); padding: 14px 10px; border-right: 1px solid var(--dp5-line-canvas); display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.dp5-side__label { font-size: var(--dp5-t-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--dp5-text-3); padding: 12px 10px 6px; }
.dp5-side__item { position: relative; display: flex; align-items: center; gap: 10px; min-height: 32px; padding: 0 10px; border-radius: var(--dp5-r-card); color: var(--dp5-text-2); font-size: var(--dp5-t-dense); font-weight: 500; text-decoration: none; background: none; border: 0; width: 100%; cursor: pointer; text-align: left; }
.dp5-side__item.is-on::before, .dp5-side__item[aria-current="page"]::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 2px; border-radius: 1px; background: var(--dp5-green); }
.dp5-side__item svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.dp5-side__item.is-on, .dp5-side__item[aria-current="page"] { background: var(--dp5-raised); color: var(--dp5-text); }   /* A50: the open screen is a tile on the frame (Ops) */
@media (hover: hover) { .dp5-side__item:hover { background: var(--dp5-raised); color: var(--dp5-text); } }
/* AMENDMENT 43, the rail: an active or hovered item is a filled tile, and the rail's own right-hand line
   could blend into that fill, so the rail disappeared exactly where the eye was. The step below makes the
   line stronger at the active item: there the rail has to READ, not merely differ. */
.dp5-side:has(.dp5-side__item:is(.is-on, [aria-current="page"])) { border-right-color: var(--dp5-line-strong); }
@media (hover: hover) { .dp5-side:has(.dp5-side__item:hover) { border-right-color: var(--dp5-line-strong); } }
.dp5-side__user { margin-top: auto; display: flex; align-items: center; gap: 10px; padding: 10px; font-size: var(--dp5-t-meta); color: var(--dp5-text-2); }
.dp5-side__user b { display: block; color: var(--dp5-text); font-weight: 500; }
.dp5-side__user > * { min-width: 0; overflow-wrap: anywhere; }
.dp5-crumb { font-size: var(--dp5-t-meta); color: var(--dp5-text-3); }
.dp5-crumb a { color: var(--dp5-text-3); }
.dp5-tabbar { position: sticky; bottom: 0; z-index: 30; display: flex; justify-content: space-around; align-items: flex-start; background: var(--dp5-tabbar); border-top: 1px solid var(--dp5-line-canvas); padding: 10px 8px calc(10px + env(safe-area-inset-bottom, 0px)); }
.dp5-tab { display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 56px; min-height: 44px; font-size: 10px; font-weight: 600; letter-spacing: .04em; color: var(--dp5-text-3); text-decoration: none; background: none; border: 0; cursor: pointer; }
.dp5-tab svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
.dp5-tab.is-on, .dp5-tab[aria-current="page"] { color: var(--dp5-green); }
.dp5-rail { width: 48px; }   /* icon rail 769-1023 on staff apps: the app hides labels at that width */
.dp5-wash { position: fixed; left: 0; right: 0; top: 0; height: 320px; pointer-events: none; z-index: 0; background: radial-gradient(120% 80% at 50% 0%, var(--dp5-wash), transparent 70%); }
.dp5-wash--static { position: absolute; }
/* AMENDMENT 41: the same wash as a background on the content column, so it needs no stacking
   context. Policy: the wash is a STATIC plane at the top of the column (it does not scroll with the
   content). A sticky header inside the column is opaque, so give it .dp5-washed too: it sits at the
   column's top at rest and when stuck, so the two slices line up. Put it on the column, not <body>. */
.dp5-washed { background-image: radial-gradient(120% 80% at 50% 0%, var(--dp5-wash), transparent 70%); background-repeat: no-repeat; background-size: 100% 320px; background-position: top center; }
/* AMENDMENT 41: optional grain. A fixed, click-through noise layer at --dp5-grain opacity over the whole
   canvas; it removes the flat-vector look and hides gradient banding. Off in print and on light roles.
   z-index 45: above canvas chrome (sticky heads, rails, tab bars), BELOW every overlay (toasts, menus,
   slide-overs, div dialogs); native <dialog> via showModal() is in the top layer regardless. Normal
   blending at low opacity on purpose: mix-blend-mode on a large fixed layer hits WebKit bug 250828
   (fixed only in Safari 18.4) and the floor tablets run iPadOS 15. Off per app with --dp5-grain: 0.
   Known limit: a light island (a print sheet shown on screen) inside a dark app is still under it. */
.dp5-grain { position: fixed; inset: 0; z-index: 45; pointer-events: none; opacity: var(--dp5-grain, .045); background-size: 160px 160px; background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>"); }

/* ============================================================ STATES */
.dp5-boot { position: fixed; inset: 0; z-index: 100; background: var(--dp5-canvas); display: flex; align-items: center; justify-content: center; }
.dp5-boot__bar { position: absolute; top: 0; left: 0; height: 2px; width: 38%; background: var(--dp5-green); border-radius: 0 2px 2px 0; animation: dp5-boot 1.2s var(--dp5-ease) infinite; }
@keyframes dp5-boot { 0% { transform: translateX(-100%); } 100% { transform: translateX(265%); } }
.dp5-boot svg, .dp5-boot img { height: 50px; width: auto; }
.dp5-skel { background: var(--dp5-skel); border-radius: var(--dp5-r-badge); position: relative; overflow: hidden; color: transparent; pointer-events: none; }
:root.dpt-v5.dpt-app .dp5-skel { border-radius: 8px; }
:root.dpt-v5.dpt-app .dp5-skel--avatar { border-radius: 50%; }
:root.dpt-v5.dpt-app .dp5-skel--row { border-radius: 0; }
.dp5-skel::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .05), transparent); transform: translateX(-100%); animation: dp5-shimmer 1.4s linear infinite; }
@keyframes dp5-shimmer { to { transform: translateX(100%); } }
.dp5-skel--text { height: 12px; }
.dp5-skel--title { height: 16px; }
.dp5-skel--avatar { width: 36px; height: 36px; border-radius: 50%; }
.dp5-skel--row { height: var(--dp5-h-row); border-radius: 0; }
.dp5-skel-only { display: none; }
[aria-busy="true"] > .dp5-skel-only { display: block; }
.dp5-empty { text-align: center; padding: 28px 18px; }
.dp5-empty svg { width: 28px; height: 28px; stroke: var(--dp5-text-3); fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.dp5-empty b, .dp5-empty__title { display: block; font-size: 15px; font-weight: 600; margin: 10px 0 2px; }
.dp5-empty span, .dp5-empty__body { display: block; color: var(--dp5-text-2); font-size: var(--dp5-t-dense); margin-bottom: 14px; }
.dp5-empty--error svg { stroke: var(--dp5-bad); }
.dp5-toasts { position: fixed; z-index: 90; left: 0; right: 0; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; align-items: center; gap: 8px; pointer-events: none; }
@media (min-width: 769px) { .dp5-toasts { left: auto; right: 24px; bottom: 24px; align-items: flex-end; } }
.dp5-toast { pointer-events: auto; display: inline-flex; align-items: center; flex-wrap: wrap; gap: 12px; min-height: 44px; max-width: calc(100vw - 32px); padding-block: 8px; padding: 0 14px; border-radius: var(--dp5-r-ctl); background: var(--dp5-primary); color: var(--dp5-primary-ink); font-size: var(--dp5-t-dense); font-weight: 500; box-shadow: none; }
:root.dpt-v5:not(.dpt-app) .dp5-toast { border-radius: var(--dp5-r-ctl); }
.dp5-toast__mark { font-weight: 700; }
.dp5-toast--error .dp5-toast__mark { color: var(--dp5-bad-deep); }   /* the toast is white: the bright red is 2.7:1 there */
.dp5-toast__action { background: none; border: 0; padding: 0 6px; min-width: 24px; min-height: 24px; font: 600 var(--dp5-t-dense)/1 var(--dp5-font); color: var(--dp5-green-deep); cursor: pointer; }
.dp5-offline { font-size: var(--dp5-t-meta); color: var(--dp5-text-3); text-align: center; padding: 4px 0; }

/* ============================================================ SHEETS AND DIALOGS */
.dp5-scrim { position: fixed; inset: 0; z-index: 80; background: var(--dp5-scrim); display: flex; align-items: flex-end; justify-content: center; }
.dp5-sheet { width: 100%; max-width: 560px; max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow: auto; overscroll-behavior: contain; background: var(--dp5-surface); border-radius: var(--dp5-r-sheet) var(--dp5-r-sheet) 0 0; padding: 14px 18px calc(22px + env(safe-area-inset-bottom, 0px)); box-shadow: var(--dp5-shadow-sheet); animation: dp5-sheet-in var(--dp5-t-sheet) var(--dp5-ease); }
.dp5-sheet__handle { width: 36px; height: 4px; border-radius: 2px; background: var(--dp5-raised); margin: 0 auto 14px; }
.dp5-sheet__title { font-size: var(--dp5-t-h2); font-weight: 600; margin-bottom: 4px; }
.dp5-sheet__body { color: var(--dp5-text-2); margin-bottom: 18px; }
.dp5-sheet__actions { display: flex; gap: 8px; }
:root.dpt-v5.dpt-app .dp5-sheet__actions { flex-direction: column; }
@keyframes dp5-sheet-in { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (min-width: 769px) {
  .dp5-scrim { align-items: center; }
  .dp5-sheet { max-width: 480px; border-radius: var(--dp5-r-sheet); padding: 20px 22px 22px; animation: dp5-dialog-in var(--dp5-t-base) var(--dp5-ease); }
  .dp5-sheet__handle { display: none; }
  .dp5-sheet__actions { justify-content: flex-end; flex-direction: row; }
  :root.dpt-v5.dpt-app .dp5-sheet__actions { flex-direction: row; }
}
@keyframes dp5-dialog-in { from { opacity: 0; } to { opacity: 1; } }
dialog.dp5-dialog { background: var(--dp5-surface); color: var(--dp5-text); border: 0; border-radius: var(--dp5-r-sheet); padding: 20px 22px 22px; max-width: 480px; width: calc(100% - 32px); max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow: auto; box-shadow: var(--dp5-shadow-sheet); }
.dp5-sheet__actions { flex-wrap: wrap; }
dialog.dp5-dialog::backdrop { background: var(--dp5-scrim); }

/* ============================================================ OVERRIDES for v4 / v3 / v2 components that hard-code a colour */
.dpt-v5 .dp4-wash { background: radial-gradient(120% 90% at 50% 0%, var(--dp5-wash), transparent 70%); }
.dpt-v5 .dp4-bar { background: var(--dp5-raised); color: var(--dp5-text-2); }
.dpt-v5 .dp4-bar.is-on { background: var(--dp5-primary); color: var(--dp5-primary-ink); }
.dpt-v5 .dp4-btn { transition: background var(--dp5-t-fast) var(--dp5-ease); }
.dpt-v5.dpt-v5.dpt-v5 .dp4-btn:focus-visible { outline: 0; box-shadow: var(--dp5-focus); }
.dpt-v5 .dp4-btn--money { background: var(--dp5-money); color: var(--dp5-money-ink); }
.dpt-v5 .dp4-btn--money:hover { background: var(--dp5-money-hover); color: var(--dp5-money-ink); }
.dpt-v5 .dp4-btn--money:active { background: var(--dp5-money-press); color: var(--dp5-money-ink); }
.dpt-v5 .dp4-btn--ghost { background: transparent; color: var(--dp5-secondary-ink); border: 0; }   /* A50: plain text */
.dpt-v5 .dp4-btn--ghost:hover { background: transparent; color: var(--dp5-secondary-ink-hover); }
.dpt-v5 .dp4-btn:disabled { opacity: 1; background: var(--dp5-raised); color: var(--dp5-text-off); }
.dpt-v5 .dp4-pr { background: var(--dp5-primary); color: var(--dp5-primary-ink); }
.dpt-v5 .dp4-eyebrow { color: var(--dp5-green); letter-spacing: .08em; }
.dpt-v5 .dp4-card { border: 0; }
.dpt-v5 .dp4-seg { background: var(--dp5-raised); }
.dpt-v5 .dp4-seg button.is-on { background: var(--dp5-primary); color: var(--dp5-primary-ink); }
.dpt-v5.dpt-v5.dpt-v5 .dp4-seg button:focus-visible { outline: 0; box-shadow: var(--dp5-focus); }
.dpt-v5 .dp4-field { background: var(--dp5-raised); border: 0; }
.dpt-v5.dpt-v5.dpt-v5 .dp4-field:focus, .dpt-v5.dpt-v5.dpt-v5 .dp4-field:focus-visible { outline: 0; box-shadow: var(--dp5-focus); }
.dpt-v5 .dp4-tabs { border-top-color: var(--dp5-line-canvas); }
.dpt-v5 .dp4-tab { text-transform: none; letter-spacing: .04em; }
.dpt-v5 .dp4-tab.is-on, .dpt-v5 .dp4-tab[aria-current="page"] { color: var(--dp5-green); }
.dpt-v5 .dp4-link--quiet { color: var(--dp5-text-2); }
.dpt-v5 :is(.dp4-field, .dp3-field, .dp2-field)::placeholder { color: var(--dp5-placeholder); }
.dpt-v5 .dp3-btn--gold, .dpt-v5 .dp3-btn--gold:hover { background: var(--dp5-money); color: var(--dp5-money-ink); }   /* v3's gold = money */
/* A50: legacy status chips agree with .dp5-badge: the word (and the dot where the markup has one), never a tint. */
.dpt-v5 :is(.dp3-badge--ok, .dp3-badge--warn, .dp3-badge--danger, .dp3-badge--info, .dp3-scorechip--optimal, .dp3-scorechip--fair, .dp3-scorechip--low, .dp4-pill--good, .dp4-pill--watch, .dp4-pill--bad) { background: transparent; padding-inline: 0; }
.dpt-v5 .dp3-avatar--coach { box-shadow: none; }
.dpt-v5 .dp3-seg > .is-on { background: var(--dp5-primary); color: var(--dp5-primary-ink); box-shadow: none; }
.dpt-v5 :is(.dp3-badge, .dp3-scorechip) { border-radius: var(--dp5-r-badge); }
.dpt-v5 .dp3-card--hero { border-radius: var(--dp5-r-card); }
.dpt-v5 .dp2-stat.is-warn { border-inline-start-color: var(--dp5-warn); }
.dpt-v5 :is(.dp3-h1, .dp3-appbar-title, .dp3-scorechip, .dp2-btn, .dp2-nav a, .dp2-nav button) { text-transform: none; letter-spacing: normal; }
.dpt-v5 :is(.dp4-btn, .dp3-btn, .dp2-btn):is(:hover, :active) { transform: none; filter: none; text-shadow: none; }
.dpt-v5.dpt-v5.dpt-v5 :is(.dp4-btn, .dp3-btn, .dp2-btn):not(:focus-visible) { box-shadow: none; }
.dpt-v5.dpt-v5.dpt-v5 .dp4-btn--money:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-money-ink); }
.dpt-v5.dpt-v5.dpt-v5 .dp4-btn:not(.dp4-btn--money):not(.dp4-btn--ghost):focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-primary-ink); }
.dpt-v5 .dp5-chart__baseline { stroke: var(--dp5-text-3); }
.dpt-v5 .dp5-chart__other { stroke: var(--dp5-chart-other); stroke-dasharray: 6 4; }

/* ============================================================ TOUCH */
@media (max-width: 768px), (pointer: coarse) {
  .dpt-v5 :is(.dp5-chip, .dp5-field-aux, .dp5-toast__action, .dp5-side__item, .dp5-btn--link, .dp5-link, .dp4-field-aux, .dp4-link, .dp4-seg button) { min-height: 44px; }
  .dpt-v5 :is(.dp5-check, .dp5-radio) { width: 28px; height: 28px; }
}

/* ============================================================ PRINT */
@media print {
  :root.dpt-v5, .dpt-v5 :is(.dpt-dark, .dpt-light) { color-scheme: light; print-color-adjust: exact; -webkit-print-color-adjust: exact; --dp5-tabbar: #FFFFFF; --dp5-skel: #EEF1F5; --dp5-text-3: #3D4757; --dp5-placeholder: #5E6978; --dp5-text-off: #A0A9B6; --dp5-text-missing: #A0A9B6; --dp5-line-strong: #7D8898; --dp5-green-hover: #007A52; --dp5-info: #1D4ED8; --dp5-wash: transparent; --dp5-shadow-sheet: none; --dp5-good-tint: #E0EFEA; --dp5-warn-tint: #F2EBE2; --dp5-bad-tint: #F9E9E8; --dp5-info-tint: #E8EDFB; --dp5-chart-fill: rgba(0, 122, 82, .14); }
  .dpt-v5 :is(.dp5-side, .dp5-tabbar, .dp4-tabs, .dp2-nav, .dp5-toasts, .dp5-scrim, .dp5-boot, .dp5-wash, .dp4-wash, .dp5-grain) { display: none !important; }
  .dpt-v5 .dp5-washed { background-image: none; }
  .dpt-v5 .dp5-card { box-shadow: none; }
  .dpt-v5 :is(.dp5-card, .dp4-card, .dp3-card, .dp5-row, tr) { break-inside: avoid; }
  .dpt-v5 :is(h1, h2, h3) { break-after: avoid; }
  .dpt-v5 .dp5-table th { position: static; }
  .dpt-v5 thead { display: table-header-group; }
  .dpt-v5 .dp5-dot { border: 1px solid var(--dp5-text); }
}
:root.dpt-v5.dpt-light .dp5-dot { border: 1px solid var(--dp5-text); }

/* ============================================================ MOTION */
@media (prefers-reduced-motion: reduce) {
  :root.dpt-v5, :root.dpt-v5::before, :root.dpt-v5::after, :root.dpt-v5 *, :root.dpt-v5 *::before, :root.dpt-v5 *::after { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
  :root.dpt-v5 .dp5-skel::after { content: none; }
}

/* ---- styles.css ---- */
/* App aliases, declared on the role classes and NOT :root: --dp3-* exist only inside a role block, and a :root
   declaration computes once and would leak the dark page's values into nested light islands. */
.dpt-dark, .dpt-light {
  --navy:        var(--dp3-text);
  --navy-2:      var(--dp3-link);
  --ink:         var(--dp3-text);
  --chrome:      var(--dp-chrome);       /* dark in both roles */
  --chrome-fg:   var(--dp-chrome-ink);
  --bg:          var(--dp3-bg);
  --card:        var(--dp3-card);
  --well:        var(--dp2-well);
  /* --line is also every input border; the hairline --dp3-line vanishes on a field. */
  --line:        var(--dp3-line-strong);
  --muted:       var(--dp3-text-2);
  --good:        var(--dp3-ok);
  --good-bg:     var(--dp3-ok-tint);
  /* The danger and warn tokens fail AA as text. */
  --bad:         var(--dp-crit-t);
  --bad-bg:      var(--dp-crit-wash-t);
  --warn:        var(--dp-warn-t);
  --warn-bg:     var(--dp-warn-wash-t);
  --gold:        var(--dp-brand-dark);
  --gold-bright: var(--dp-brand);
  /* Not --dp3-accent-hot: electric green is for hero numerals, rings and indicators only. */
  --green:       var(--dp-action-t);
  --green-hover: var(--dp-action-t-hover);
  --good-line:   color-mix(in srgb, var(--dp3-ok) 38%, transparent);
  --bad-line:    color-mix(in srgb, var(--dp-crit-t) 38%, transparent);
}

/* Beats dpt.v1.css :root[data-theme] (0,2,0), which a leftover data-theme would otherwise win. */
:root.dpt-light { color-scheme: light; }
:root.dpt-dark  { color-scheme: dark; }
* { box-sizing: border-box; }
.skip-link {
  position: absolute; left: 8px; top: 8px; z-index: 100;
  padding: 8px 12px; background: var(--card); color: var(--navy-2);
  border-radius: var(--dp3-r-sm); font-weight: 700;
  clip: rect(0 0 0 0); width: 1px; height: 1px; overflow: hidden;
}
.skip-link:focus {
  clip: auto; width: auto; height: auto; overflow: visible;
  box-shadow: var(--dp5-focus);
}
body {
  margin: 0; background: var(--bg); color: var(--ink);
  /* --dp3-font-ui resolves to Inter on a .dpt-v5 surface. */
  font: 15px/1.5 var(--dp3-font-ui);
}
/* Clears the floating pill nav and the home indicator. */
main { max-width: 1060px; margin: 0 auto; padding: 12px 16px calc(110px + env(safe-area-inset-bottom)); }
h1, h2 { font-family: var(--dp3-font-display); }
h1 { font-size: 24px; margin: 18px 0 10px; color: var(--navy); text-transform: uppercase; letter-spacing: .03em; }
h2 { font-size: 17px; margin: 0 0 8px; color: var(--navy); letter-spacing: .02em; }
a { color: var(--navy-2); text-decoration: none; }
a:hover { text-decoration: underline; }
small, .small { font-size: 12.5px; }
.muted { color: var(--muted); }

/* Keeps the .topbar class: print rules hide the header by it. */
.topbar {
  display: flex; align-items: center; gap: 12px;
  max-width: 1060px; margin: 0 auto; padding: 14px 16px 4px;
}
.brand { display: block; min-width: 0; }
.footer { text-align: center; color: var(--muted); font-size: 12px; padding: 18px 18px calc(96px + env(safe-area-inset-bottom)); }
.footer span { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 10px; }
.footer span > * { white-space: nowrap; }

.card {
  background: var(--card); border: 1px solid var(--dp2-card-border-c); border-radius: var(--dp3-r-lg);
  padding: 16px 18px; margin: 12px 0; box-shadow: var(--dp3-shadow-card);
}
.card.narrow { max-width: 430px; margin: 40px auto; }
.center { text-align: center; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; }
input, textarea, select { max-width: 100%; }

.unread {
  display: inline-block; background: var(--dp2-action); color: var(--dp2-action-ink); font-size: 11px;
  font-weight: 800; border-radius: var(--dp3-r-pill); padding: 2px 9px; vertical-align: 3px;
  letter-spacing: .02em; font-family: var(--dp3-font-ui);
}
.inactive { opacity: .55; }

/* White on a bright green is unreadable, and the fill never brightens in dark mode. */
.btn {
  font-family: inherit;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--dp2-action); color: var(--dp2-action-ink); border: 0;
  /* 40px on desktop; the coarse-pointer 44px bump lives in one block at the foot. */
  min-height: var(--dp-btn-h-desk, 40px);
  padding: 0 18px; border-radius: var(--dp4-r-pill); font-weight: 700; font-size: 14px; cursor: pointer;
  /* WCAG 1.4.11: the fill is under 3:1 on the dark card, so an inset ring in --dp2-action-edge delineates it
     (the light role pins it to the fill). */
  box-shadow: inset 0 0 0 1px var(--dp2-action-edge, var(--dp2-action));
}
.btn:hover { background: var(--dp2-action-hover); text-decoration: none; }
/* A42: inactive is the raised grey with muted text, never a dimmed copy of the live colour. */
.btn:disabled, .btn[aria-busy="true"] {
  background: var(--dp5-raised); color: var(--dp5-text-off);
  box-shadow: none; opacity: 1; cursor: not-allowed; pointer-events: none;
}
/* The money button is bright green with navy text on the family app, and deep green with white text only
   on a light or printed page. At most one per screen, and only where a card is charged or a pack is used. */
.btn.big { font-size: 15px; padding: 0 26px; background: var(--dp5-money); color: var(--dp5-money-ink); box-shadow: none; }
.btn.big:hover { background: var(--dp5-green-deep-hover); color: var(--dp5-money-ink); }
.btn.gold { background: var(--dp5-money); color: var(--dp5-money-ink); box-shadow: none; }
.btn.gold:hover { background: var(--dp5-green-deep-hover); color: var(--dp5-money-ink); }
.btn.secondary {
  background: transparent; color: var(--navy-2);
  box-shadow: inset 0 0 0 1.5px currentColor;
}
.btn.secondary:hover { background: transparent; color: var(--dp5-text); }
.btn.small { padding: 0 14px; font-size: 13px; min-height: 34px; }
/* An inner line in the button's own ink. The :is(.dpt-dark, .dpt-light) prefix matches the
   kit's focus rule weight, and these must follow every .btn variant (.gold and .big set box-shadow: none). */
:is(.dpt-dark, .dpt-light) :is(a, button).btn:focus-visible {
  box-shadow: inset 0 0 0 1.5px var(--dp2-action-ink);
}
:is(.dpt-dark, .dpt-light) :is(a, button).btn:is(.big, .gold):focus-visible {
  box-shadow: inset 0 0 0 1.5px var(--dp5-money-ink);
}
:is(.dpt-dark, .dpt-light) :is(a, button).btn.secondary:focus-visible {
  box-shadow: inset 0 0 0 1.5px var(--dp5-text);
}
/* Author display beats the UA [hidden] rule; push.js hides this button. */
.btn[hidden] { display: none; }
.btnrow { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
/* Same [hidden] fix as .btn[hidden]. */
.btnrow[hidden] { display: none; }
@media (max-width: 480px) {
  #push-card .btnrow .btn { width: 100%; }
}
.linklike { background: none; border: 0; color: var(--dp3-link); cursor: pointer; font: inherit; padding: 0; }
main .linklike { color: var(--navy-2); }
.linklike:hover { color: var(--navy-2); text-decoration: underline; }
.linklike.danger { color: var(--bad); font-size: 12px; }
.linklike.danger:hover { color: var(--bad); }
.inline { display: inline; }
.stack { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.stack .linklike { align-self: flex-start; }
/* Explicit colours: UA input styling is grey-on-grey in dark mode. */
input, textarea, select {
  font: inherit; padding: 9px 10px; width: 100%;
  min-height: var(--dp3-field-h);
  border: 1.5px solid var(--line); border-radius: var(--dp3-r-field);
  background: var(--card); color: var(--ink);
}
::placeholder { color: var(--muted); opacity: 1; }
input:disabled, textarea:disabled, select:disabled {
  opacity: .55; cursor: not-allowed;
}
/* Chromium's autofill wash ignores the field token; an inset shadow wins. */
input:autofill, input:-webkit-autofill,
textarea:autofill, textarea:-webkit-autofill,
select:autofill, select:-webkit-autofill {
  box-shadow: 0 0 0 1000px var(--card) inset;
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  border-color: var(--line);
}

/* The open dropdown is part of the control. base-select opts in; other browsers keep the native sheet.
   Picker on the field radius, options concentric (must match the kit select block). */
@supports (appearance: base-select) {
  select:not([multiple]),
  ::picker(select) {
    appearance: base-select;
  }
  select:not([multiple])::picker(select) {
    background: var(--card);
    border: 1.5px solid var(--line);
    border-radius: var(--dp3-r-field);
    padding: 4px;
    margin-top: 4px;
    box-shadow: var(--dp3-shadow-float);
    color: var(--ink);
  }
  select:not([multiple]) option {
    border-radius: calc(var(--dp3-r-field) - 4px);
    min-height: var(--dp-btn-h-sm);
    display: flex;
    align-items: center;
    padding: 6px 12px;
    font-size: 16px;
    color: var(--ink);
    background: transparent;
  }
  select:not([multiple]) option:is(:hover, :focus-visible) {
    background: var(--good-bg);
    color: var(--navy-2);
  }
  select:not([multiple]) option:checked {
    background: var(--good-bg);
    color: var(--ink);
  }
  select:not([multiple]) option::checkmark {
    order: 1;
    color: var(--navy-2);
    margin-left: auto;
  }
  select:not([multiple])::picker-icon { color: var(--muted); }
}

.notice {
  background: var(--good-bg); border: 1px solid var(--good-line); color: var(--good);
  border-radius: var(--dp3-r-md); padding: 10px 14px; margin: 10px 0;
}
.error-notice { background: var(--bad-bg); border-color: var(--bad-line); color: var(--bad); }

.highlights { display: flex; gap: 12px; flex-wrap: wrap; margin: 12px 0; }
.hl { border-radius: var(--dp3-r-md); padding: 10px 16px; min-width: 220px; }
.hl small { display: block; text-transform: uppercase; letter-spacing: .06em; font-size: 10.5px; }
.hl.good { background: var(--good-bg); color: var(--good); }

table.report { width: 100%; border-collapse: collapse; min-width: 560px; }
@media (max-width: 640px) {
  table.report { min-width: 0; }
  table.report th, table.report td { padding: 7px 6px; }
}
table.report th {
  text-align: left; font-size: 11.5px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--chrome-fg); background: var(--chrome); padding: 7px 9px;
}
table.report th:first-child { border-radius: var(--dp3-r-sm) 0 0 var(--dp3-r-sm); }
table.report th:last-child { border-radius: 0 var(--dp3-r-sm) var(--dp3-r-sm) 0; }
table.report td { padding: 8px 9px; border-bottom: 1px solid var(--line); vertical-align: middle; }
table.report td small { display: block; }
td.good { color: var(--good); background: var(--good-bg); font-weight: 700; }
td.bad { color: var(--bad); background: var(--bad-bg); font-weight: 700; }
.pr {
  background: var(--dp2-action); color: var(--dp2-action-ink); font-size: 11px; font-weight: 800;
  border-radius: var(--dp3-r-sm); padding: 2px 7px; letter-spacing: .04em;
}

.spark { min-width: 84px; }
.spark svg { display: block; width: 100%; max-width: 120px; height: auto; }
.printpage .spark svg { width: 120px; }

.thread { display: flex; flex-direction: column; margin: 10px 0; }

details summary { cursor: pointer; color: var(--navy-2); font-size: 12.5px; }

.printpage { background: var(--dp3-card); color: var(--dp3-text); color-scheme: light; }
.printpage table.report { color: var(--dp3-text); }
.legend { margin-top: 14px; }

@media print {
  .noprint { display: none !important; }
  @page { margin: 14mm; }
  table.report tr, .highlights, .hl { break-inside: avoid; }
  td.good { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  td.bad, .pr, .hl, table.report th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}


.hb-streak { background: var(--dp2-action); color: var(--dp2-action-ink); font-weight: 800; font-size: 13px; border-radius: var(--dp3-r-pill); padding: 4px 12px; white-space: nowrap; }
/* paintProgress() hides this by attribute; keep [hidden] winning. */
.hb-streak[hidden] { display: none; }
.hb-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; margin: 14px 0 0; }
.hb-daywrap { display: flex; flex-direction: column; align-items: center; gap: 5px; min-width: 0; }
.hb-dow { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; color: var(--muted); }
/* No text in the mark: public/habits.js rewrites className wholesale, so the tick and cross come from CSS. */
.hb-day { width: 30px; height: 30px; border-radius: 50%; font-size: 13px; font-weight: 800; display: inline-flex; align-items: center; justify-content: center; background: var(--well); color: var(--muted); border: 1px solid var(--line); }
.hb-day.hb-perfect { background: var(--dp2-action); color: var(--dp2-action-ink); border-color: var(--dp2-action); }
.hb-day.hb-perfect::after { content: '✓'; }
.hb-day.hb-partial { background: var(--good-bg); color: var(--good); border-color: var(--good-line); }
.hb-day.hb-missed { background: var(--bad-bg); color: var(--bad); border-color: var(--bad-line); }
.hb-day.hb-missed::after { content: '×'; }
.hb-day.hb-pending { background: transparent; border-style: dashed; border-color: var(--line); }
.hb-day.hb-none { background: transparent; border-color: var(--line); opacity: .35; }
/* Today is an outline, never a fill: the one electric element on this screen. */
.hb-day.is-today { border: 2px solid var(--dp3-electric); }
.hb-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.hb-row { background: var(--card); border: 1px solid var(--line); border-radius: var(--dp3-r-md); padding: 8px 12px; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 6px 10px; min-height: 64px; }
.hb-row.is-finished { opacity: .6; }
.hb-row.hb-busy { opacity: .5; pointer-events: none; }
.hb-main { display: block; width: 100%; min-height: 48px; padding: 6px 0; background: none; border: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; }
/* No ring of its own: the kit's :focus-visible line already draws inside it. */
.hb-main:focus-visible { outline: none; border-radius: var(--dp3-r-sm); }
.hb-name { font-size: 15px; font-weight: 700; }
.hb-sub { display: block; font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.hb-act { display: flex; align-items: center; gap: 10px; pointer-events: none; }
.hb-chev { color: var(--muted); font-size: 20px; line-height: 1; }
.hb-badge { font-weight: 800; font-size: 11px; border-radius: var(--dp3-r-pill); padding: 3px 10px; white-space: nowrap; }
.hb-badge.hb-done { background: var(--good-bg); color: var(--good); }
.hb-badge.hb-hit { background: var(--dp2-action); color: var(--dp2-action-ink); }
.hb-err { grid-column: 1 / -1; color: var(--bad); font-size: 12.5px; }

.hb-card { max-width: 430px; margin: 14px auto; }
.hb-card-h { margin: 0 0 4px; }
.hb-card-note { margin: 0 0 6px; }
.hb-assigns .dp3-row .dp3-row-t, .hb-card .dp3-row .dp3-row-t { display: block; }
.hb-card .dp3-row .dp3-row-s { display: block; margin-top: 1px; }
.hb-save { width: 100%; margin-top: 14px; }
.hb-time { max-width: 150px; min-height: 48px; }

/* CSS over the real checkbox: same name, value and POST with styles off. */
.hb-switch { position: relative; flex: 0 0 auto; width: 52px; height: 32px; }
.hb-switch input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.hb-switch-track { position: absolute; inset: 0; border-radius: var(--dp3-r-pill); background: var(--well); border: 1px solid var(--line); transition: background var(--dp3-t-fast, 160ms) var(--dp3-ease); }
.hb-switch-track::after { content: ''; position: absolute; top: 4px; left: 4px; width: 22px; height: 22px; border-radius: 50%; background: var(--muted); transition: transform var(--dp3-t-fast, 160ms) var(--dp3-ease), background var(--dp3-t-fast, 160ms) var(--dp3-ease); }
.hb-switch input:checked + .hb-switch-track { background: var(--dp2-action); border-color: var(--dp2-action); }
.hb-switch input:checked + .hb-switch-track::after { transform: translateX(20px); background: var(--dp2-action-ink); }
.hb-switch input:focus-visible + .hb-switch-track { border-color: var(--dp5-text); }
.hb-switch input:checked:focus-visible + .hb-switch-track { box-shadow: inset 0 0 0 1.5px var(--dp2-action-ink); }
@media (prefers-reduced-motion: reduce) { .hb-switch-track, .hb-switch-track::after { transition: none; } }

/* <dialog> as a bottom sheet: the UA background, border, centring and fit-content width all have to go. */
.hb-sheet {
  position: fixed; inset: auto 0 0 0; margin: 0 auto; z-index: 60;
  width: 100%; max-width: 560px; max-height: 88vh; overflow-y: auto;
  /* iOS lays the keyboard OVER a fixed sheet, which hid "Type a number" and Save. The shared
     helper publishes the keyboard's height and the height still on show; the sheet sits on the first and is never
     taller than the second. Both fall back to today's values (0 and the full screen) when no keyboard is up. */
  bottom: var(--dpm-kb, 0px); max-height: min(88vh, var(--dpm-vvh, 100dvh));
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-bottom: 0;
  border-radius: var(--dp3-r-xl) var(--dp3-r-xl) 0 0;
  box-shadow: var(--dp3-shadow-float);
  padding: 10px 18px calc(20px + env(safe-area-inset-bottom, 0px));
}
.hb-sheet::backdrop { background: color-mix(in srgb, var(--bg) 55%, transparent); }
/* The fallback path (no showModal) gets its scrim from the body instead. */
body.hb-sheet-on::after { content: ''; position: fixed; inset: 0; background: color-mix(in srgb, var(--bg) 55%, transparent); z-index: 55; }
.hb-sheet[open] { display: block; animation: hb-sheet-up var(--dp3-t-slow) var(--dp3-ease); }
@keyframes hb-sheet-up { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
.hb-sheet-grip { width: 40px; height: 4px; border-radius: 2px; background: var(--line); margin: 0 auto 12px; }
.hb-sheet-title { font-size: 19px; margin: 0 0 14px; }
.hb-sheet-body { display: flex; flex-direction: column; gap: 14px; }
.hb-sheet-err { color: var(--bad); font-size: 13px; margin: 10px 0 0; }
.hb-sheet-err[hidden] { display: none; }
.hb-sheet-close { display: block; margin: 14px auto 0; }
.hb-sheet-undo { align-self: center; }

.hb-sheet-num { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hb-step {
  flex: 0 0 auto; width: var(--dp-btn-h-desk, 40px); height: var(--dp-btn-h-desk, 40px); border-radius: 50%;
  border: 1.5px solid var(--line); background: var(--well); color: var(--ink);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.hb-step:hover { border-color: var(--green); color: var(--green); }
.hb-step:focus-visible { border-color: var(--dp3-focus); box-shadow: var(--dp5-focus); }
.hb-bignum { display: flex; align-items: baseline; gap: 6px; justify-content: center; flex: 1 1 auto; min-width: 0; }
.hb-bignum-v { font-family: var(--dp3-font-display); font-size: 46px; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; }
.hb-bignum-u { font-size: 15px; color: var(--muted); }
.hb-sheet-goal { text-align: center; color: var(--muted); font-size: 13px; margin: 0; }
.hb-sheet-goal[hidden] { display: none; }
.hb-sheet-exact { display: flex; flex-direction: column; gap: 5px; }
.hb-sheet-exact input { width: 100%; }
.hb-sheet-save { width: 100%; }
.hb-sheet-scale { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.hb-scale-btn { min-height: var(--dp-btn-h-desk, 40px); border-radius: var(--dp3-r-md); border: 1px solid var(--line); background: var(--well); color: var(--ink); font-size: 18px; cursor: pointer; }
.hb-scale-btn:hover { border-color: var(--green); background: var(--good-bg); }
.hb-scale-btn:focus-visible { border-color: var(--dp3-focus); box-shadow: var(--dp5-focus); }
@media (prefers-reduced-motion: reduce) { .hb-sheet[open] { animation: none; } }
@media print { .hb-sheet, body.hb-sheet-on::after { display: none !important; } }

/* Geometry comes from lib/habit-rings.js; lighting a notch is a class flip only.
   --dp2-streak-on, not --dp2-action: only it brightens on dark. */
.hb-ring { --ring-size: 46px; position: relative; display: inline-block; width: var(--ring-size); height: var(--ring-size); flex: 0 0 auto; }
.hb-ring-svg { display: block; width: 100%; height: 100%; }
.hb-seg { fill: none; stroke: var(--dp2-hairline-soft); stroke-width: 9; }
.hb-seg.is-on { stroke: var(--dp2-streak-on); }
/* A dashed circle starts at 3 o'clock; turn it to the top. */
.hb-seg-arc { transform: rotate(-90deg); transform-origin: 50% 50%; stroke-linecap: round; }
.hb-ring.is-missed .hb-seg { stroke: var(--bad-line); }

.hb-ring-mid { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; pointer-events: none; }
.hb-ring-num { font-family: var(--dp3-font-display); font-size: 14px; font-weight: 700; color: var(--ink); }
.hb-ring-den { font-size: 8px; font-style: normal; font-weight: 700; color: var(--muted); margin-top: 2px; letter-spacing: .02em; }

.hb-ring-check { fill: none; stroke: var(--dp2-streak-on); stroke-width: 9; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.hb-ring-bool.is-full .hb-ring-check { stroke-dashoffset: 0; transition: stroke-dashoffset .32s cubic-bezier(.2,.7,.3,1); }
.hb-ring-bool.is-full .hb-ring-mid { display: none; }

@keyframes hb-ring-pop { 0% { transform: scale(1); } 45% { transform: scale(1.09); } 100% { transform: scale(1); } }
.hb-ring.is-popping { animation: hb-ring-pop .34s cubic-bezier(.2,.7,.3,1); }

.hb-ringbtn { -webkit-appearance: none; appearance: none; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; display: inline-flex; border-radius: 50%; }
.hb-ringbtn:focus-visible { box-shadow: var(--dp5-focus); }
@media (pointer: coarse) { .hb-ring { --ring-size: 52px; } }

.hb-today { display: flex; flex-direction: column; padding: 16px; margin-bottom: 12px; }
.hb-today .hb-ring-day { --ring-size: 118px; }
.hb-today .hb-ring-day .hb-ring-num { font-size: 36px; }
.hb-today .hb-ring-day .hb-ring-den { font-size: 11px; margin-top: 4px; }
.hb-today-line { font-family: var(--dp3-font-display); font-size: 22px; font-weight: 600; line-height: 1.1; letter-spacing: .02em; text-transform: uppercase; margin: 0; }
@media (max-width: 430px) {
  .hb-today { padding: 14px; }
  .hb-today .hb-ring-day { --ring-size: 96px; }
  .hb-today .hb-ring-day .hb-ring-num { font-size: 29px; }
  .hb-today-line { font-size: 19px; }
  .hb-day { width: 28px; height: 28px; font-size: 12px; }
  .hb-week { gap: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .hb-ring.is-popping { animation: none; }
  .hb-ring-bool.is-full .hb-ring-check { transition: none; }
}

.hb-trend-sub { margin: 0; }
.dp3-seg a { text-decoration: none; }
.hb-table { margin-top: 8px; }
.hb-table summary { font-size: 12.5px; color: var(--muted); cursor: pointer; min-height: 24px; }
.hb-table table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 6px; }
.hb-table th { text-align: left; color: var(--muted); font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em; padding: 4px 8px 4px 0; }
.hb-table td { padding: 4px 8px 4px 0; border-top: 1px solid var(--line); }
.hb-table .hb-miss { color: var(--bad); }

/* Print: dpt.v3.css pins .dpt-dark to plain values that ignore color-scheme, so re-point the role tokens
   or a habits page prints black. */
.printonly { display: none; }
@media print {
  :root, :root[data-theme="dark"] { color-scheme: light !important; }
  :root.dpt-dark {
    color-scheme: light;
    --dp3-bg: var(--dp-white);          --dp3-card: var(--dp-white);
    --dp3-card-2: var(--dp-paper);      --dp3-shadow-card: none;
    --dp3-text: var(--dp-ink);          --dp3-text-2: var(--dp-slate);
    --dp3-text-3: var(--dp-slate);      --dp3-line: var(--dp-border);
    --dp3-line-strong: var(--dp-border);
    --dp3-link: var(--dp-green);        --dp3-accent: var(--dp-green);
    --dp3-ok: var(--dp-good);           --dp3-ok-tint: var(--dp-good-wash);
    /* v1 dark status steps print at 2-3:1 on white. */
    --dp-action-t: var(--dp-green-brand);
    --dp-crit-t: var(--dp-crit-ink);    --dp-crit-wash-t: var(--dp-crit-wash);
    --dp-warn-t: var(--dp-warn);        --dp-warn-wash-t: var(--dp-warn-wash);
    --dp2-well: var(--dp-paper);           --dp2-page: var(--dp-white);
    --dp2-card: var(--dp-white);           --dp2-card-border-c: var(--dp-border);
    --dp2-hairline: var(--dp-border);      --dp2-hairline-soft: var(--dp-border);
    --dp2-streak-on: var(--dp-green-brand);
    --dp2-text: var(--dp-ink);             --dp2-text-2: var(--dp-slate);
    --dp2-label: var(--dp-slate);          --dp2-accent-text: var(--dp-green);
    --dp2-good: var(--dp-good);            --dp2-warn: var(--dp-warn);
    --dp2-crit: var(--dp-crit-ink);
  }
  .printonly { display: inline; }
  header.topbar, footer.footer, .notice, .noprint { display: none !important; }
  main { max-width: none; padding: 0; }
  @page { margin: 14mm; }
  .hb-streak { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  /* Without this a ring prints as an empty circle — the notches are the data. */
  .hb-ring, .hb-seg, .hb-ring-check { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .hb-ringbtn { display: inline-flex !important; }
  /* A Numbers table prints only if it was open on screen. */
  details.hb-table:not([open]) { display: none; }
  .hb-table summary { list-style: none; }
  .hb-table summary::-webkit-details-marker { display: none; }
  .hb-table tr { break-inside: avoid; }
}

.install-card { position: relative; padding-right: 40px; }
.install-close {
  position: absolute; top: 8px; right: 8px; width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--dp3-r-sm); background: none; color: var(--muted);
  font-size: 20px; line-height: 1; cursor: pointer;
}
.install-close:hover { background: var(--good-bg); color: var(--navy-2); }
@media (pointer: coarse) { .install-close { width: var(--dp-btn-h-sm); height: var(--dp-btn-h-sm); } }
.install-steps { list-style: none; margin: 10px 0 2px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.install-steps li { display: flex; align-items: center; gap: 10px; font-size: 14px; }
.install-icon {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; border-radius: var(--dp3-r-sm); background: var(--well); color: var(--navy-2);
}
.install-icon svg { width: 18px; height: 18px; }

.p1-microlabel {
  font-size: var(--dp2-fs-label); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--dp2-label);
}

.p1-empty { padding: 22px 18px; }
/* Sentence case: this heading does not follow the uppercase titles. */
.p1-empty-h {
  font-family: var(--dp5-font);
  font-size: 15px; font-weight: 600; letter-spacing: 0; text-transform: none;
  line-height: 1.2; color: var(--dp5-text); margin: 0 0 4px;
}
.p1-empty p { margin: 0; }
.p1-empty p + p { margin-top: 8px; }
.p1-empty .btn, .p1-empty .dp2-btn { margin-top: 12px; }

.p1-streakcard { padding: 14px 16px; }
.p1-streakcount {
  font-family: var(--dp3-font-display);
  font-size: 18px; font-weight: 700; letter-spacing: .04em; color: var(--dp2-accent-text);
}

.sess-h { margin-top: 20px; }
.sess-h:first-of-type { margin-top: 8px; }
.sess-chip {
  flex: none; background: var(--dp2-action); color: var(--dp2-action-ink);
  font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  border-radius: var(--dp3-r-pill); padding: 3px 9px; white-space: nowrap;
}
.sess-chip.is-pending { background: var(--dp2-warn); color: var(--dp-attention-ink); }
.sess-chip.is-off { background: var(--well); color: var(--muted); }
/* Waitlist is an outline, never the pending amber. */
.sess-chip.is-wait { background: transparent; color: var(--dp2-good); box-shadow: inset 0 0 0 1.5px var(--dp2-good); }
.p1-empty .btnrow { margin-top: 12px; }
.p1-empty .btnrow .btn { margin-top: 0; flex: 1 1 12rem; }
.nv-block { display: block; }
.sess-mhead {
  font-family: var(--dp3-font-display);
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--muted); margin: 16px 0 8px;
}
.sess-pastcard { padding: 4px 15px; }
.sess-past {
  display: grid; grid-template-columns: 128px 1fr auto auto; gap: 4px 12px; align-items: baseline;
  padding: 9px 0; border-bottom: 1px solid var(--dp2-hairline-soft); font-size: 13px;
}
.sess-past:last-child { border-bottom: 0; }
@media (max-width: 560px) {
  /* One row: a stacked date read as a duplicate session. */
  .sess-past { grid-template-columns: auto 1fr auto; }
}

/* Same [hidden] fix: a failed fetch otherwise painted the skeleton, empty and error cards at once. */
.p1-empty[hidden],
[data-credits-skel][hidden],
[data-credits-slot][hidden] { display: none; }

/* Skeleton markup must ship hidden and be revealed by the script that starts the fetch, or a no-JS load
   shimmers forever. */
@keyframes dp-skel { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.skel {
  display: block; background-color: var(--dp5-skel);
  background-image: linear-gradient(90deg,
    transparent 0%, rgba(255, 255, 255, .05) 50%, transparent 100%);
  background-size: 200% 100%; background-repeat: no-repeat;
  border-radius: 8px;
  animation: dp-skel 1.4s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

.lockup { display: block; height: 38px; width: auto; max-width: 100%; }

.ath-switch {
  display: flex; gap: 8px; max-width: 1060px; margin: 0 auto;
  padding: 4px 16px 0; overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.ath-switch a {
  flex: 0 0 auto; font-family: var(--dp3-font-display);
  font-size: 12px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); background: var(--card); border: 1px solid var(--dp2-card-border-c);
  border-radius: var(--dp3-r-pill); padding: 7px 14px; text-decoration: none;
}
.ath-switch a:hover { text-decoration: none; border-color: var(--dp2-good); color: var(--navy-2); }
.ath-switch a.is-on { background: var(--dp2-action); color: var(--dp2-action-ink); border-color: transparent; }
@media (pointer: coarse) { .ath-switch a { min-height: var(--dp-btn-h-sm); display: inline-flex; align-items: center; } }

.ath-avatar {
  flex: none; border-radius: 50%; object-fit: cover; background: var(--well);
  display: grid; place-items: center; overflow: hidden;
}
.ath-avatar.is-mono {
  font-family: var(--dp3-font-display); font-weight: 700;
  color: var(--dp2-action-ink); background: var(--dp2-action); letter-spacing: .02em;
}
.ath-avatar--sm { width: 40px; height: 40px; font-size: 15px; }

.share-out { margin-top: 12px; }
.share-preview {
  display: block; width: 100%; max-width: 320px; height: auto;
  border-radius: var(--dp3-r-lg); border: 1px solid var(--dp2-hairline);
}

.sess-count { margin: 0 0 10px; font-size: 13.5px; color: var(--muted); }
.sess-count b {
  font-family: var(--dp3-font-display);
  font-size: 17px; color: var(--navy); letter-spacing: .02em;
}

.dp2-nav { padding: 6px 6px; overflow-x: auto; }
/* Six 52px columns fill a 360px phone; a seventh scrolls rather than overlapping labels. */
.dp2-nav a, .dp2-nav button { flex-shrink: 0; }
.dp2-nav a, .dp2-nav button {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; min-height: 48px; min-width: 52px; padding: 5px 8px;
  border-radius: var(--dp2-r-inner);
}
.dp2-nav a:hover, .dp2-nav button:hover { color: var(--dp2-nav-active); text-decoration: none; }
.dp2-nav svg { width: 20px; height: 20px; display: block; }
.dp2-navicon { position: relative; display: block; }
.dp2-navbadge {
  position: absolute; top: -5px; right: -11px;
  background: var(--dp2-action); color: var(--dp2-action-ink);
  font-family: var(--dp3-font-ui); font-size: 9.5px; font-weight: 800;
  line-height: 1; letter-spacing: 0; padding: 3px 5px; border-radius: 99px;
}
@media (max-width: 719px) {
  .dp2-nav a, .dp2-nav button { min-width: 44px; padding-inline: 4px; }
}
@media (min-width: 720px) {
  .dp2-nav { padding: 6px 18px; gap: 18px; }
  .dp2-nav a, .dp2-nav button { padding: 5px 10px; }
}

.sess-pastcard.hide-off .sess-past.is-canceled { display: none; }
.sess-showoff {
  display: block; margin-top: 8px; font-size: 12.5px; color: var(--muted);
  background: none; border: 0; cursor: pointer; padding: 6px 0; font-weight: 600;
  min-height: var(--dp-btn-h-sm);
}
.sess-showoff:hover { color: var(--navy-2); }

/* Touch: no UA tap highlight or sticky focus ring; the keyboard keeps :focus-visible. */
.dp2-nav a, .dp2-nav button, .dp2-sheetx {
  -webkit-tap-highlight-color: transparent; touch-action: manipulation;
}
.dp2-nav a:focus, .dp2-nav button:focus { outline: none; }
/* Focus is the inset line in the text colour. No outline, nothing outside the edge. */
.dp2-nav a:focus-visible, .dp2-nav button:focus-visible {
  outline: 0; box-shadow: var(--dp5-focus);
}
.dp2-nav a:active, .dp2-nav button:active { color: var(--dp2-nav-active); }
.dp2-sheetwrap { position: fixed; inset: 0; z-index: 60; }
/* During the close fade the wrap still covers the nav; never let it eat taps. */
.dp2-sheetwrap:not(.is-open) { pointer-events: none; }
.dp2-sheetback { position: absolute; inset: 0; background: color-mix(in srgb, var(--bg) 55%, transparent); opacity: 0; transition: opacity .18s ease; }
.dp2-sheet {
  position: absolute; left: 50%; bottom: 0; transform: translate(-50%, 12px);
  width: min(440px, calc(100vw - 16px));
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-bottom: 0;
  /* The 44px top padding is the header line the out-of-flow grip and X sit in. */
  border-radius: var(--dp3-r-xl) var(--dp3-r-xl) 0 0; padding: 44px 20px calc(20px + env(safe-area-inset-bottom, 0px));
  opacity: 0; transition: transform .18s ease, opacity .18s ease;
  box-shadow: var(--dp2-nav-shadow);
  /* Swipe-to-dismiss (footer.ejs): pinch-zoom keeps two-finger zoom but leaves the one-finger vertical drag to the
     script; pan-y would hand it to the browser. none is the fallback for UAs without pinch-zoom. */
  touch-action: none;
  touch-action: pinch-zoom;
}
.dp2-sheet input, .dp2-sheet select, .dp2-sheet textarea { touch-action: auto; }
.dp2-sheetwrap.is-open .dp2-sheetback { opacity: 1; }
.dp2-sheetwrap.is-open .dp2-sheet { transform: translate(-50%, 0); opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .dp2-sheetback, .dp2-sheet { transition: none; }
}
.dp2-sheetgrip {
  position: absolute; top: 19.5px; left: 50%; margin-left: -20px;
  width: 40px; height: 5px; border-radius: 99px; background: var(--line);
}
.dp2-sheetx {
  position: absolute; top: 0; right: 0;
  width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--muted); border-radius: var(--dp3-r-sm);
}
.dp2-sheetx svg { width: 18px; height: 18px; display: block; }
.dp2-sheetx:hover { color: var(--navy-2); }
.dp2-sheetx:focus-visible { color: var(--dp5-text); outline: 0; box-shadow: var(--dp5-focus); }
/* The panel takes focus on open but is not a control: no ring. */
.dp2-sheet:focus, .dp2-sheet:focus-visible { outline: none; }

.dp2-swtoast {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 50;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--dp-btn-h-sm); min-width: 44px;
  max-width: calc(100vw - 32px);
  padding: 12px 18px; border: 0; border-radius: var(--dp3-r-md);
  background: var(--dp2-action); color: var(--dp2-action-ink);
  font-family: var(--dp3-font-ui); font-size: 15px; font-weight: 600; line-height: 1.3;
  cursor: pointer; box-shadow: var(--dp2-nav-shadow);
}
.dp2-swtoast[hidden] { display: none; }
.dp2-swtoast-wrap {
  position: fixed; left: 50%; transform: translateX(-50%);
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 50; display: inline-flex; align-items: center; gap: 6px;
  /* max-content: a fixed box at left: 50% only gets HALF the screen to shrink into, which squeezed
     Update ready. Tap to reload. onto three lines on a phone. */
  width: max-content; max-width: calc(100vw - 32px);
}
.dp2-swtoast-wrap[hidden] { display: none; }
.dp2-swtoast-wrap .dp2-swtoast { position: static; transform: none; bottom: auto; }
body:has(.dp2-nav) .dp2-swtoast-wrap {
  bottom: calc(96px + env(safe-area-inset-bottom, 0px));
}
.dp2-swtoast-x {
  min-width: 44px; min-height: var(--dp-btn-h-sm); border: 0; border-radius: var(--dp3-r-md);
  background: var(--card); color: var(--ink); font-size: 22px; line-height: 1; cursor: pointer;
  box-shadow: var(--dp2-nav-shadow);
}
.dp2-swtoast-x:hover { color: var(--navy-2); }
/* Kit weight (see .btn:focus-visible), keeping the float shadow. */
:is(.dpt-dark, .dpt-light) button.dp2-swtoast-x:focus-visible { box-shadow: inset 0 0 0 1px var(--dp3-focus), var(--dp2-nav-shadow); }
.dp2-srlive { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.dp2-swtoast:hover { background: var(--dp2-action-hover); }
:is(.dpt-dark, .dpt-light) button.dp2-swtoast:focus-visible {
  box-shadow: inset 0 0 0 1.5px var(--dp2-action-ink), var(--dp2-nav-shadow);
}
@media (prefers-reduced-motion: reduce) { .dp2-swtoast { transition: none; } }

/* 16px inputs: anything smaller and iOS Safari zooms on focus. */
input, select, textarea { font-size: 16px; }
/* Undo the generic input rule for checkboxes and radios; WebKit painted a radio as a giant disc. */
input[type="checkbox"],
input[type="radio"] {
  width: 20px; height: 20px; min-height: 0; padding: 0; border: 0;
  accent-color: var(--dp2-action); flex: 0 0 auto;
  -webkit-appearance: auto; appearance: auto;
}
.checkrow {
  display: flex; align-items: center; gap: var(--dp3-sp-2);
  min-height: var(--dp-btn-h-sm);
}

.crd-big { display: flex; align-items: baseline; gap: 8px; margin: 6px 0 0; }
.crd-big b {
  font-family: var(--dp3-font-display); font-size: 40px; line-height: 1;
  color: var(--green); font-variant-numeric: tabular-nums;
}
.crd-big span { font-size: 15px; font-weight: 600; }
.crd-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  padding: 8px 0 0; font-size: 14.5px;
}
.crd-name { font-weight: 600; }
.crd-val { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.crd-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.sess-sheeth { margin: 4px 2px 6px; font-size: 22px; }
#cancel-sheet .muted { margin: 0 2px 4px; }
#cancel-sheet-late { margin: 0 2px 10px; }
#cancel-sheet .btnrow { padding: 8px 2px 4px; }

/* Belt: Sessions tab is also omitted in footer.ejs for role athlete. */
html.is-athlete .dp2-nav a[href="/sessions"] { display: none; }
.rsv-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: var(--dp-btn-h-sm);
  padding: 8px 12px; margin: 0 0 6px;
  background: var(--card); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--dp3-r-md);
  font: inherit; text-align: left; cursor: pointer;
}
.rsv-row:hover, .rsv-row:focus-visible {
  border-color: var(--dp2-action);
  background: color-mix(in srgb, var(--dp2-action) 12%, var(--card));
}
.rsv-name { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.rsv-spots { color: var(--muted); white-space: nowrap; font-size: 13px; }
.rsv-row.is-full .rsv-spots { color: var(--dp2-warn); }
.rsv-cap { margin: 8px 2px 4px; font-weight: 600; }
.rsv-who { border: 0; padding: 8px 0 4px; margin: 0; }
.rsv-who legend { padding: 0; }
.rsv-who .checkrow {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: var(--dp-btn-h-sm);
  padding: 10px 12px; margin: 0 0 8px;
  background: var(--well); border: 1.5px solid var(--line);
  border-radius: var(--dp3-r-md); cursor: pointer;
}
.rsv-who .checkrow span { font-weight: 600; min-width: 0; }
.rsv-who .checkrow:hover { border-color: var(--dp2-action); }
.rsv-who .checkrow:has(input:checked) {
  border-color: var(--dp2-action);
  box-shadow: inset 0 0 0 1px var(--dp2-action);
}
#rsv-sheet .muted { margin: 0 2px 4px; }
#rsv-sheet .btnrow { padding: 8px 2px 4px; }
.rsched-lead { margin: 14px 0 4px; }
.rsched-dayh {
  margin: 18px 0 8px;
  font-family: var(--dp3-font-display);
  font-size: 13px; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted);
}
.rsched-slots { display: flex; flex-direction: column; gap: 8px; }
.rsched-slot { margin: 0; }
.rsched-slot .btn { width: 100%; min-height: var(--dp-btn-h-desk, 40px); }
.rsched-keep {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  margin-top: 18px;
}
.rsched-keep .linklike { min-height: var(--dp-btn-h-sm); display: inline-flex; align-items: center; }

.card-viz { display: flex; align-items: flex-start; gap: 12px; }
.card-viz-ico {
  flex: none; width: 40px; height: 40px; border-radius: var(--dp3-r-md);
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--dp2-action) 18%, var(--card));
  color: var(--dp2-accent-text);
}
.card-viz-ico svg { width: 20px; height: 20px; display: block; }
.card-viz-body { min-width: 0; flex: 1; }
.p1-empty-ico {
  width: 28px; height: 28px; border-radius: 0;
  display: grid; place-items: center; margin: 0 0 10px;
  background: none;
  color: var(--dp5-text-3);
}
.p1-empty-ico svg { width: 28px; height: 28px; display: block; stroke-width: 1.6; }

/* Rules that could also match the other habits markup go under body.hb2. */

.hb-badge.hb-yours {
  background: transparent; color: var(--good);
  border: 1px solid var(--good); font-weight: 700;
}
/* Data hook for habit-builder.js goalFor(); never shown. */
.hb-goal { display: none; }

.hb-lock {
  display: inline-block; position: relative; width: 8px; height: 7px;
  margin-left: 5px; vertical-align: -1px; border-radius: 1.5px;
  background: currentColor; opacity: .8;
}
.hb-lock::before {
  content: ''; position: absolute; left: 1px; bottom: 5px;
  width: 6px; height: 4px; border: 1.5px solid currentColor;
  border-bottom: 0; border-radius: 3px 3px 0 0;
}
.hb-lock--coach { color: var(--muted); opacity: .65; }

.hb-add {
  width: 100%; min-height: var(--dp-btn-h-desk, 40px); justify-content: center;
  display: inline-flex; align-items: center;
}
.hb-add:hover { border-color: var(--good); color: var(--good); text-decoration: none; }
.hb-add:focus-visible { border-color: var(--dp3-focus); box-shadow: var(--dp5-focus); }
.hb-add-cap { margin: 2px 0 0; text-align: center; min-height: 44px; padding: 12px 8px 0; }
.hb-add-cap a { color: var(--muted); text-decoration: underline; }
.hb-add-cap a:hover { color: var(--ink); }

.hb-banner, .hb-firstrun { padding: 14px 16px; margin-bottom: 10px; }
.hb-banner-h {
  font-family: var(--dp3-font-display); font-size: 19px; font-weight: 600;
  line-height: 1.15; letter-spacing: .01em; margin: 4px 0 10px;
}
.hb-firstrun-line { margin: 4px 0 12px; font-size: 14.5px; line-height: 1.45; }
.hb-banner-rows { list-style: none; margin: 0 0 12px; padding: 0; }
.hb-banner-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 5px 0; font-size: 14px; border-top: 1px solid var(--line);
}
.hb-banner-row:first-child { border-top: 0; }
.hb-banner-name { font-weight: 700; }
.hb-banner-move { color: var(--muted); font-variant-numeric: tabular-nums; }
/* A text control, still a 44px target. */
.hb-banner-only {
  margin-left: auto; background: none; border: 0; padding: 0 0 0 4px; cursor: pointer;
  display: inline-flex; align-items: center; min-height: 44px;
  font: inherit; font-size: 12.5px; color: var(--muted); text-decoration: none;
}
.hb-banner-only:hover { color: var(--ink); text-decoration: underline; }
.hb-banner-only:focus-visible { box-shadow: var(--dp5-focus); }
.hb-banner-btns { display: flex; gap: 10px; flex-wrap: wrap; }
.hb-banner-btn { min-height: var(--dp-btn-h-desk, 40px); flex: 1 1 140px; justify-content: center; }
.hb-firstrun-btn { min-height: var(--dp-btn-h-desk, 40px); }

.hb-builder { display: flex; flex-direction: column; gap: 18px; }
.hb-builder input, .hb-builder select, .hb-profile input, .hb-goal-edit input,
.hb-target-form input {
  /* 16px: anything smaller and iOS zooms the whole page on focus. */
  font-size: 16px;
}
.hb-builder-err {
  margin: 0; padding: 10px 14px; border-radius: var(--dp3-r-md);
  background: var(--bad-bg); border: 1px solid var(--bad-line); color: var(--bad);
  font-size: 13.5px;
}
.hb-builder-sec { border: 0; padding: 0; margin: 0; min-width: 0; }
.hb-builder-sec[hidden] { display: none; }
.hb-builder-sec legend, .hb-builder-name > .p1-microlabel { padding: 0; margin-bottom: 8px; }
.hb-builder-name { display: block; }
.hb-builder-name input { max-width: 420px; }
.hb-builder-opt { color: var(--muted); font-weight: 600; letter-spacing: 0; text-transform: none; }
.hb-builder-hint { margin: 8px 0 0; color: var(--muted); font-size: 13px; }
.hb-builder-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; min-height: 44px; margin-top: 10px;
}
.hb-builder-row[hidden] { display: none; }
.hb-builder-lab { font-size: 14px; font-weight: 600; }
.hb-builder-num { max-width: 150px; }
.hb-builder-foot { margin: 0; text-align: center; }
.hb-builder-seen { margin: 0; text-align: center; }
.hb-builder-head { display: flex; align-items: center; min-height: 44px; margin-bottom: 4px; }
.hb-builder-sheet .hb-sheet-title { margin-bottom: 2px; }
.hb-builder-head { gap: 16px; }
.hb-builder-head .hb-builder-cancel,
body.hb2 .hb-sheet .hb-builder-head a.hb-builder-cancel:not(.btn):not(.dp3-btn) {
  /* margin: 0 undoes the shared .hb-sheet-close centring. */
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 2px; margin: 0;
  font-size: 14px; font-weight: 700; color: var(--muted); text-decoration: none;
}
.hb-builder-head .hb-builder-cancel:hover,
body.hb2 .hb-sheet .hb-builder-head a.hb-builder-cancel:not(.btn):not(.dp3-btn):hover { color: var(--ink); text-decoration: underline; }
.hb-builder-head .hb-builder-cancel:focus-visible {
  box-shadow: var(--dp5-focus);
  border-radius: var(--dp3-r-sm);
}

.hb-seg2 {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--well); border: 1px solid var(--line);
  border-radius: var(--dp3-r-pill); padding: 4px;
}
.hb-seg2-opt { position: relative; }
.hb-seg2-opt input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.hb-seg2-opt span {
  display: flex; align-items: center; justify-content: center;
  min-height: var(--dp-btn-h-desk, 40px); border-radius: var(--dp3-r-pill);
  font-size: 14.5px; font-weight: 700; color: var(--muted);
}
.hb-seg2-opt input:checked + span {
  background: var(--card); color: var(--good); box-shadow: inset 0 0 0 1px var(--good);
}
/* 2px: the chosen segment already wears a 1px green line. */
.hb-seg2-opt input:focus-visible + span {
  box-shadow: inset 0 0 0 1.5px var(--dp5-text);
}
.hb-seg2.is-off { opacity: .5; }

.hb-more { margin-top: 14px; }
.hb-more > summary {
  list-style: none; cursor: pointer;
  min-height: 52px; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 0 14px; margin-top: 2px;
  background: var(--well); border: 1px solid var(--line); border-radius: var(--dp3-r-md);
  color: var(--ink); font-weight: 700; font-size: 14.5px;
}
.hb-more > summary::-webkit-details-marker { display: none; }
.hb-more > summary:hover { border-color: var(--good); }
.hb-more > summary:focus-visible { border-color: var(--dp3-focus); box-shadow: var(--dp5-focus); }
.hb-more-chev { color: var(--muted); font-size: 20px; line-height: 1; flex: 0 0 auto; }
.hb-more[open] > summary .hb-more-chev { transform: rotate(90deg); }
.hb-more-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.hb-more-row, .hb-more-hit {
  position: relative; display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 8px 12px;
  background: var(--well); border: 1px solid var(--line);
  border-radius: var(--dp3-r-md); cursor: pointer;
}
.hb-more-row--scale { display: block; padding: 0; cursor: default; }
.hb-more-hit { border: 0; background: none; border-radius: var(--dp3-r-md) var(--dp3-r-md) 0 0; }
.hb-more-row input[type="radio"], .hb-more-hit input[type="radio"] {
  position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer;
}
.hb-more-ico {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: var(--dp3-r-sm);
  display: grid; place-items: center; font-size: 15px; font-weight: 800;
  background: color-mix(in srgb, var(--dp2-action) 18%, var(--card));
  color: var(--dp2-accent-text);
}
.hb-more-txt { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1 1 auto; }
.hb-more-txt b { font-size: 14.5px; }
.hb-more-txt i { font-style: normal; font-size: 12.5px; color: var(--muted); }
.hb-more-row:has(input:checked) { border-color: var(--good); }
.hb-more-row:has(input:focus-visible) { border-color: var(--dp3-focus); box-shadow: var(--dp5-focus); }
.hb-more-sub {
  display: flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 12px 8px 56px;
  font-size: 12.5px; color: var(--muted); cursor: pointer;
}
.hb-more-sub input { width: 18px; height: 18px; margin: 0; accent-color: var(--dp2-action); }
.hb-more-sub:hover { color: var(--ink); }

.hb-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.hb-chips[hidden] { display: none; }
.hb-chip {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 15px; border-radius: var(--dp3-r-pill);
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  font-size: 14px; font-weight: 600; white-space: nowrap; cursor: pointer;
}
.hb-chip input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.hb-chip:hover { border-color: var(--good); }
.hb-chip:has(input:checked), .hb-chip.is-on {
  background: var(--well); border-color: var(--good); color: var(--good);
  box-shadow: inset 0 0 0 1px var(--good);
}
/* 2px: a chosen chip already wears a 1px ring. */
.hb-chip:has(input:focus-visible) {
  border-color: var(--dp3-focus); box-shadow: inset 0 0 0 1.5px var(--dp5-text);
}
:is(.dpt-dark, .dpt-light) button.hb-chip-btn:focus-visible {
  border-color: var(--dp3-focus); box-shadow: inset 0 0 0 1.5px var(--dp5-text);
}
.hb-chips--week { display: flex; flex-wrap: wrap; gap: 8px; }
.hb-chip--day { min-width: 44px; min-height: 44px; padding: 0 10px; font-size: 13px; }

.hb-profile .hb-builder-sec { margin-top: 16px; }
.hb-profile-row { border-top: 1px solid var(--line); padding-top: 12px; }
.hb-profile-num { display: flex; align-items: center; gap: 8px; }
.hb-profile-num input { max-width: 130px; min-height: 44px; text-align: right; }
.hb-profile-num i { font-style: normal; color: var(--muted); font-size: 14px; }
.hb-target-row { align-items: center; }
.hb-target-val { display: inline-flex; align-items: baseline; gap: 4px; white-space: nowrap; }
.hb-target-val b {
  font-family: var(--dp3-font-display); font-size: 22px; font-weight: 600;
  color: var(--dp2-accent-text); font-variant-numeric: tabular-nums;
}
.hb-target-val i { font-style: normal; font-size: 12.5px; color: var(--muted); }
.hb-target-edit > summary, .hb-archive > summary {
  min-height: 44px; display: flex; align-items: center;
  color: var(--muted); font-weight: 700; font-size: 13.5px; cursor: pointer;
}
.hb-target-edit > summary:hover, .hb-archive > summary:hover {
  color: var(--ink); text-decoration: underline;
}
.hb-target-edit > summary:focus-visible, .hb-archive > summary:focus-visible {
  box-shadow: var(--dp5-focus);
}
.hb-target-form, .hb-archive form { padding: 0 0 14px; }
.hb-target-form .btn, .hb-archive-go { margin-top: 10px; }
.hb-target-pending {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 0 10px; font-size: 13px;
}
.hb-target-pending-l { color: var(--muted); flex: 1 1 auto; }
.hb-target-pending-b { display: flex; gap: 8px; flex: 0 0 auto; }
/* 44px on phones comes from the coarse block at the foot. */
.hb-target-pending-b .btn, .hb-target-pending-b .dp3-btn { min-height: var(--dp-btn-h-desk, 40px); }

.hb-sheet-seg {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  background: var(--well); border: 1px solid var(--line);
  border-radius: var(--dp3-r-pill); padding: 4px;
}
.hb-seg-btn {
  min-height: var(--dp-btn-h-desk, 40px); border: 0; border-radius: var(--dp3-r-pill);
  background: none; color: var(--muted); font: inherit; font-weight: 700;
  font-size: 14.5px; cursor: pointer;
}
.hb-seg-btn.is-on { background: var(--card); color: var(--ink); box-shadow: inset 0 0 0 1px var(--good); }
:is(.dpt-dark, .dpt-light) button.hb-seg-btn:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-text); }
/* Every author display beats UA [hidden], and each log body child sets one. */
body.hb2 .hb-sheet-body > [hidden] { display: none !important; }
.hb-goal-edit { display: flex; flex-direction: column; gap: 10px; }
.hb-goal-edit .btn { width: 100%; }
.hb-goal-step { display: flex; align-items: center; gap: 12px; }
.hb-goal-step .hb-goal-num {
  flex: 1 1 auto; min-width: 0; text-align: center;
  font-family: var(--dp3-font-display); font-size: 38px; font-weight: 600;
  font-variant-numeric: tabular-nums; border: 0; background: none;
}
.hb-goal-step .hb-step { width: 48px; height: 48px; font-size: 22px; flex: 0 0 auto; }

body.hb2 .hb-list .linklike, body.hb2 .hb-sheet .linklike, body.hb2 .hb-card .linklike,
body.hb2 .hb-sheet-undo, body.hb2 .hb-sheet-close {
  color: var(--muted);
}
body.hb2 .hb-list .linklike:hover, body.hb2 .hb-sheet .linklike:hover,
body.hb2 .hb-card .linklike:hover,
body.hb2 .hb-sheet-undo:hover, body.hb2 .hb-sheet-close:hover {
  color: var(--ink); text-decoration: underline;
}
/* In-screen links are text; buttons wearing <a> keep their colours. */
body.hb2 .hb-list a:not(.btn):not(.dp3-btn),
body.hb2 .hb-card a:not(.btn):not(.dp3-btn),
body.hb2 .hb-sheet a:not(.btn):not(.dp3-btn) {
  color: var(--muted); text-decoration: underline;
}
body.hb2 .hb-list a:not(.btn):not(.dp3-btn):hover,
body.hb2 .hb-card a:not(.btn):not(.dp3-btn):hover,
body.hb2 .hb-sheet a:not(.btn):not(.dp3-btn):hover { color: var(--ink); }

/* A submit button styled as the reminder switch, because the page has no script. */
body.hb2 .hb-athrow { margin: 0; }
body.hb2 .hb-athsw {
  position: relative; flex: 0 0 auto;
  width: 52px; height: 44px;                 /* 44px thumb target, 32px paint */
  padding: 6px 0; margin: 0;
  background: none; border: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
body.hb2 .hb-athsw-track {
  display: block; position: relative; width: 52px; height: 32px;
  border-radius: var(--dp3-r-pill); background: var(--well);
  border: 1px solid var(--line);
  transition: background var(--dp3-t-fast, 160ms) var(--dp3-ease);
}
body.hb2 .hb-athsw-track::after {
  content: ''; position: absolute; top: 4px; left: 4px; width: 22px; height: 22px;
  border-radius: 50%; background: var(--muted);
  transition: transform var(--dp3-t-fast, 160ms) var(--dp3-ease),
              background var(--dp3-t-fast, 160ms) var(--dp3-ease);
}
body.hb2 .hb-athsw[aria-checked="true"] .hb-athsw-track {
  background: var(--dp2-action); border-color: var(--dp2-action);
}
body.hb2 .hb-athsw[aria-checked="true"] .hb-athsw-track::after {
  transform: translateX(20px); background: var(--dp2-action-ink);
}
/* The focus mark goes on the 32px track, not the 44px button; box-shadow: none cancels the kit's button line. */
body.hb2 .hb-athsw:focus-visible { outline: none; box-shadow: none; }
body.hb2 .hb-athsw:focus-visible .hb-athsw-track { border-color: var(--dp3-focus); }
body.hb2 .hb-athsw[aria-checked="true"]:focus-visible .hb-athsw-track {
  box-shadow: inset 0 0 0 1.5px var(--dp2-action-ink);
}
@media (prefers-reduced-motion: reduce) {
  body.hb2 .hb-athsw-track, body.hb2 .hb-athsw-track::after { transition: none; }
}

@media (min-width: 700px) {
  body.hb2 main:has(.hb-builder-card) .hb-card { max-width: none; }
  body.hb2 .hb-week { max-width: 340px; }
}
@media (min-width: 1100px) {
  body.hb2 .hb-cols { column-count: 2; column-gap: 28px; }
  body.hb2 .hb-cols > * { break-inside: avoid; }
  body.hb2 .hb-cols .hb-card { max-width: none; margin: 0 0 16px; }
}

body.hb2 .footer a { white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  .hb-builder-sheet[open] { animation: none; }
}

.hb-sheet, .ath-switch, .dp2-nav {
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

/* Coarse-pointer bump, in ONE block at the foot: two-class selectors (.rsched-slot .btn etc.)
   outrank any earlier .btn bump. */
@media (pointer: coarse) {
  .linklike, summary, .footer a {
    min-height: var(--dp-btn-h-sm);
    display: inline-flex; align-items: center;
  }
  .linklike { min-width: var(--dp-btn-h-sm); }
  summary { display: flex; width: 100%; }
  .btn, .btn.small, .dp2-btn {
    min-height: var(--dp-btn-h-sm);
    display: inline-flex; align-items: center; justify-content: center;
  }
  .hb-scale-btn,
  .hb-add,
  .hb-banner-btn,
  .hb-firstrun-btn,
  .hb-seg2-opt span,
  .hb-seg-btn,
  .rsched-slot .btn,
  .hb-target-pending-b .btn,
  .hb-target-pending-b .dp3-btn {
    min-height: var(--dp-btn-h-sm);
  }
  .hb-step { width: var(--dp-btn-h-sm); height: var(--dp-btn-h-sm); }
}

/* Keep More's navigation tap target below every sheet action; 15vh keeps the sheet inside a 768x480 landscape phone. */
#more-sheet .dp2-sheet { padding-bottom: calc(96px + env(safe-area-inset-bottom, 0px)); padding-bottom: calc(min(96px, 15vh) + env(safe-area-inset-bottom, 0px)); max-height: 100dvh; overflow-y: auto; }
/* X sticks (a scrolled sheet would carry an absolute X away): it floats at the content top and the first row keeps the 44px header line. */
#more-sheet .dp2-sheet { padding-top: 0; }
#more-sheet .dp2-sheetx { position: sticky; top: 0; right: auto; float: right; margin: 0 -20px -44px 0; background: var(--card); border-top-right-radius: calc(var(--dp3-r-xl) - 1px); z-index: 1; }
.sess-showoff, .install-close { font-family: inherit; }
a[href^="tel:"] { white-space: nowrap; }
main:has(.card.narrow) .install-card { max-width: 430px; margin-inline: auto; }
@media (max-width: 480px) {
  .hb-row .hb-ring-num { font-size: 11px; }
  .hb-row .hb-ring-unit { display: none; }
}


/* ---- shell.css ---- */
/* shell.css: portal chrome on the v5 kit, look C.
   Loads after styles.css and overrides its chrome and generic controls. Per-screen rules live in
   the screen stylesheets (header.ejs `screenCss`).
   The family app matches the website's dark section: navy-black page (the kit's family canvas),
   tiles with a faint light edge and no shadow, tab bar and top bar one step darker. One filled
   button per screen: bright green with navy text (--dp5-action / --dp5-money). Everything else is
   plain text. Selected things are the white slab with navy text. Status is a coloured dot plus a
   word, never a tinted fill. Corners stay 12px on controls and 16px on cards. The green header
   wash stays.
   Colour comes from --dp5-* tokens, never raw hex. No charcoal grey. */

.dpt-dark, .dpt-light {
  --bg: var(--dp4-bg); --card: var(--dp4-card); --well: var(--dp4-card-2);
  --line: var(--dp4-line); --line-field: var(--dp4-field-line);
  --ink: var(--dp4-text); --navy: var(--dp4-text); --navy-2: var(--dp4-link);
  --muted: var(--dp4-text-2);
  --green: var(--dp4-link); --green-hover: var(--dp4-link-hover); --green-brand: var(--dp4-green);
  /* Look C: no tinted fills. Every legacy status background (select option hover, td.good, .hl, builder
     errors, install x hover) is the neutral one-rung-up navy; the status colour stays on the word. */
  --good: var(--dp4-good); --good-bg: var(--dp5-raised-hover);
  --warn: var(--dp4-watch); --warn-bg: var(--dp5-raised-hover);
  --bad: var(--dp4-bad); --bad-bg: var(--dp5-raised-hover);
  /* The legacy --gold* names carry the money colour. */
  --gold: var(--dp5-money); --gold-bright: var(--dp5-money); --gold-ink: var(--dp5-money-ink);
  --dp2-action: var(--dp4-primary); --dp2-action-ink: var(--dp4-primary-ink); --dp2-action-hover: var(--dp4-primary-hover);
  --dp2-action-edge: var(--dp4-primary); --dp2-action-glow: none;
  --dp2-good: var(--dp4-good); --dp2-accent-text: var(--dp4-good); --dp2-label: var(--dp4-text-2);
  --dp2-card-border-c: var(--dp4-line); --dp2-hairline: var(--dp4-line); --dp2-hairline-soft: var(--dp4-line);
  --dp2-well: var(--dp4-card-2); --dp2-streak-on: var(--dp4-good);
  --dp3-shadow-card: none; --dp3-focus: var(--dp5-text); --dp3-focus-w: 1.5px;
  --shell-max: 720px; --nav-h: 60px;
}
/* Signed-in pages share one outer width, including their existing 16px gutters. */
body:has(.topbar--app) { --shell-max: var(--dp5-content-max, 720px); }

/* The kit's --dp4-card is the page itself here, so the card alias points at --dp5-raised. A fill that used the tile colour would vanish into the card, so it steps one rung up.
   Custom properties inherit as computed values, so each alias is re-declared inside the tile, not only --dp5-raised. */
:root.dpt-v5.dpt-app, :root.dpt-v5.dpt-app :is(.dpt-dark, .dpt-light) {
  --dp4-card: var(--dp5-raised);
}
:root.dpt-v5.dpt-app :is(.card, .dp4-card, .dp2-sheet, .hb-card, .hb-banner, .hb-firstrun, .hb-builder-card, .hb-sheet, .rsv-pick, .install-card) {
  --dp5-raised: var(--dp5-raised-hover);
  --dp4-card-2: var(--dp5-raised-hover);
  --dp4-field: var(--dp5-raised-hover);
  --dp4-field-line: var(--dp5-raised-hover);
  --dp3-card-2: var(--dp5-raised-hover);
  --dp2-well: var(--dp5-raised-hover);
  --well: var(--dp5-raised-hover);
}

/* ---------- shared phone helper (public/vendor/dp-mobile.css: a byte copy, never edited here) ----------
   Its pull-to-refresh disc is a small tile: the tile fill, the tile's own edge, the text colours. Never
   green (green is a value or the main action). Skeleton bones keep the helper's default. */
:root.dpt-v5.dpt-app {
  --dpm-surface: var(--dp5-raised);
  --dpm-line: var(--dp5-line-card);
  --dpm-ink: var(--dp5-text);
  --dpm-ink-2: var(--dp5-text-2);
  --dpm-radius: var(--dp5-r-card);
}

html { background: var(--dp4-bg); }
body { margin: 0; background: var(--dp4-bg); color: var(--dp4-text); font: 17px/1.45 var(--dp4-font); -webkit-font-smoothing: antialiased; }
main { max-width: var(--shell-max); margin: 0 auto; padding: 8px 16px 48px; position: relative; }
/* The phone tab bar is the icons and labels (about 52px) plus the home-indicator inset, never a fixed 84px. --tabbar-h is that height; main clears it by 16px so a last button is never under the bar. */
@media (max-width: 768px) {
  :root.dpt-v5.dpt-app, :root.dpt-v5.dpt-app :is(.dpt-dark, .dpt-light) { --tabbar-h: calc(58px + max(6px, env(safe-area-inset-bottom, 0px))); }
  main { padding-bottom: calc(var(--tabbar-h) + 16px); }
}
/* On a phone the screen is the content and the tabs. Signed-in screens have no top bar and no footer. */
@media (max-width: 768px) { main { padding-top: 12px; } }
body:has(.dp2-nav) .footer { display: none; }
h1, h2, h3 { color: var(--dp4-text); font-family: var(--dp4-font); letter-spacing: 0; text-transform: none; }
h1 { font-size: var(--dp4-t-title); font-weight: 600; margin: 10px 4px 12px; }
/* One title-row recipe: the first thing in main on every signed-in screen. */
.pg-title { font-size: var(--dp4-t-title); font-weight: 600; margin: 8px 4px 14px; }
body:has(.topbar--app) main h1 { margin-inline: 0; }
body:has(.topbar--app) main .pg-title { margin-inline: 0; }
h2 { font-size: 19px; font-weight: 600; margin: 0 0 10px; }
h3 { font-size: 15px; font-weight: 600; margin: 0 0 6px; }
p { margin: 0 0 8px; }
a { color: var(--dp4-link); text-decoration: none; }
a:hover { color: var(--dp4-link-hover); text-decoration: underline; }
/* Links inside a screen are quiet text; green stays on the filled button and the status dot. Danger words are red. */
main .dp4-link { color: var(--dp5-text-2); }
main .dp4-link:hover { color: var(--dp5-text); }
main .dp4-link.dp4-link--danger, main .dp4-link--danger:hover { color: var(--dp5-bad); }
small, .small { font-size: 14px; }
.muted { color: var(--dp4-text-2); }
.dp-num { font-variant-numeric: tabular-nums; }
/* Kit .dp5-unit: a unit rides the baseline of the numeral it belongs to. Left to itself the
   <small> centres on the cap height and "in" floats above the middle of a 44px figure. */
.dpt-v5 :is(.dp4-num, .dp4-row__v, .hm-nvwhen, .rc-big) > small { vertical-align: baseline; line-height: 1; }
.dp-enter { animation: none !important; opacity: 1 !important; transform: none !important; }

.topbar { position: sticky; top: 0; z-index: 40; background: var(--dp5-tabbar); border-bottom: 1px solid var(--dp5-line-canvas); display: block; max-width: none; margin: 0; padding: 0; }
.topbar-in { max-width: var(--shell-max); margin: 0 auto; padding: 0 16px; min-height: var(--nav-h); display: flex; align-items: center; gap: 24px; }
.brand { display: inline-flex; align-items: center; gap: 10px; flex: none; min-width: 0; color: var(--dp5-text); text-decoration: none; }
.brand:focus-visible { outline: 0; box-shadow: var(--dp5-focus); border-radius: 8px; }
.brand:hover { color: var(--dp5-text); text-decoration: none; }
/* The name here is the installed name from site.webmanifest. */
.brand .dmark { display: block; width: 30px; height: 30px; flex: none; }
.brand .brand-name { font: 600 15px/1 var(--dp5-font); letter-spacing: 0; white-space: nowrap; }

.dp2-nav { position: static; transform: none; width: auto; max-width: none; display: flex; align-items: stretch; gap: 2px; margin-left: auto; padding: 0; overflow: visible; background: none; border: 0; border-radius: 0; box-shadow: none; }
.dp2-nav a, .dp2-nav button { display: inline-flex; align-items: center; min-height: var(--nav-h); padding: 0 14px; border: 0; background: none; cursor: pointer; font: 600 15px/1 var(--dp4-font); letter-spacing: 0; text-transform: none; color: var(--dp4-text-2); text-decoration: none; position: relative; border-radius: 0; gap: 0; min-width: 0; }
.dp2-nav a svg, .dp2-nav button svg { display: none; }
.dp2-nav a, .dp2-nav button { color: var(--dp5-text-3); }
.dp2-nav a:hover, .dp2-nav button:hover { color: var(--dp5-text); text-decoration: none; }
.dp2-nav a.is-active, .dp2-nav button.is-active { color: var(--dp5-text); background: var(--dp5-raised); }
.dp2-nav a.is-active::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: var(--dp5-green); }
/* The kit nav stacks the label and the count; this keeps them on one line. */
.dp2-nav a, .dp2-nav button { flex-direction: row; }
.dp2-nav .dp2-navicon { position: relative; display: inline-flex; order: 2; margin-left: 6px; }
/* A number after a green dot, not a filled chip: the one fill is the action. */
.dp2-nav .dp2-navbadge { position: static; display: inline-flex; align-items: center; gap: 4px; margin-left: 0; background: none; color: var(--dp5-text); font-size: 13px; font-weight: 600; line-height: 1; padding: 0; border-radius: 0; }
.dp2-nav .dp2-navbadge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--dp5-green); }
.dp2-nav a:focus-visible, .dp2-nav button:focus-visible { outline: 0; color: var(--dp4-text); }
/* Pressing a tab never flashes green (styles.css paints --dp2-nav-active on :active). */
.dp2-nav a:active, .dp2-nav button:active { color: var(--dp5-text); }

@media (max-width: 768px) {
  .dp2-nav { position: fixed; left: 0; right: 0; bottom: 0; z-index: 50; margin: 0; padding: 8px 4px max(6px, env(safe-area-inset-bottom, 0px)); background: var(--dp5-tabbar); border-top: 1px solid var(--dp5-line-canvas); display: flex; justify-content: space-around; align-items: flex-start; min-height: 0; }
  .dp2-nav a, .dp2-nav button { flex: 1 1 0; flex-direction: column; justify-content: flex-start; gap: 6px; min-height: 44px; padding: 0 2px; font: 600 10px/1 var(--dp5-font); letter-spacing: .04em; text-transform: none; color: var(--dp5-text-3); }
  .dp2-nav a svg, .dp2-nav button svg { display: block; width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; }
  .dp2-nav a.is-active::after { display: block; left: 18%; right: 18%; }
  .dp2-nav a.is-active, .dp2-nav button.is-active { color: var(--dp5-text); background: none; }
  .dp2-nav .dp2-navicon { order: 0; margin-left: 0; }
  /* On a phone the badge is a dot, so it stays round. */
  .dp2-nav .dp2-navbadge { position: absolute; top: -2px; right: -6px; margin: 0; padding: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--dp5-green); font-size: 0; line-height: 0; overflow: hidden; }
  .dp2-nav .dp2-navbadge::before { content: none; }
}
@media (min-width: 769px) { #more-sheet.dp2-sheetwrap { display: none !important; } }

/* Shown only after 200ms with no next page. Under the tab bar (50), the desktop top bar (40) and the update notice (50), over everything in <main>. */
.nav-wait { position: fixed; left: 0; right: 0; bottom: 0; z-index: 35; overflow: hidden; background-color: var(--dp4-bg); }
.nav-wait__col { max-width: var(--shell-max); margin: 0 auto; padding: 8px 16px 0; }
.nav-wait__card { margin: 0 0 12px; }
.nav-wait__card .dpm-skel--line + .dpm-skel--line { margin-top: 8px; }
@media print { .nav-wait { display: none; } }
.dp2-sheet { background: var(--dp4-card); border: 1px solid var(--dp5-line-card); border-bottom: 0; box-shadow: none; }
.dp2-sheetgrip { background: var(--dp5-raised); }
body:has(.dp2-nav) .dp2-swtoast-wrap { bottom: calc(var(--tabbar-h, 84px) + 12px); }
@media (min-width: 769px) { body:has(.dp2-nav) .dp2-swtoast-wrap { bottom: 24px; } }

/* Athlete switcher chips: pill segment. */
/* It sits inside <main> now, which already carries the column width and the gutters. */
.ath-switch { margin: 0; padding: 0 0 4px; gap: 8px; }
/* Look C chip: a tile with the white-30% edge drawn inside it (kit A50 chip recipe); picked = the white slab. */
.ath-switch a { font: 600 14px/1 var(--dp4-font); letter-spacing: 0; text-transform: none; color: var(--dp4-text-2); background: var(--dp5-raised); border: 1px solid transparent; box-shadow: inset 0 0 0 1px var(--dp5-line-card); border-radius: var(--dp5-r-chip); padding: 0 16px; min-height: var(--dp5-h-ctl); display: inline-flex; align-items: center; }
.ath-switch a:hover { color: var(--dp4-text); text-decoration: none; }
.ath-switch a.is-on { background: var(--dp5-primary); color: var(--dp5-primary-ink); box-shadow: none; }

/* An in-flow card is a tile. --dp5-shadow-card is none, so the edge does the work. Not on nav, rows, fields, chips or toasts. */
.card { background: var(--dp4-card); border: 1px solid var(--dp5-line-card); border-radius: var(--dp4-r-card); padding: 20px; margin: 0 0 12px; box-shadow: var(--dp5-shadow-card); }
.card.narrow { max-width: 480px; margin: 24px auto; }
/* The kit's `.dpt-v5 .dp4-card { border: 0 }` is the same specificity; shell.css loads after it. */
.dpt-v5 .dp4-card { border: 1px solid var(--dp5-line-card); box-shadow: var(--dp5-shadow-card); }
/* Look C: a notice is a tile with a white sentence and a status dot, never a tinted fill. */
.notice { background: var(--dp5-raised); border: 0; box-shadow: inset 0 0 0 1px var(--dp5-line-card); color: var(--dp5-text); border-radius: var(--dp5-r-ctl); padding: 12px 16px; margin: 0 0 12px; font-weight: 500; }
.notice::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; background: var(--dp5-good); vertical-align: 1px; }
.error-notice { background: var(--dp5-raised); color: var(--dp5-text); }
.error-notice::before { background: var(--dp5-bad); }
.footer { color: var(--dp4-text-3); font-size: 13px; text-align: center; padding: 24px 16px 32px; border-top: 1px solid var(--dp4-line); max-width: var(--shell-max); margin: 24px auto 0; }
/* align-items: on touch the links are 44px tall boxes, so without it "Questions?" and the dots float above them. */
.footer span { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 4px 12px; }
.footer span > * { white-space: nowrap; }
@media (max-width: 768px) { .footer { padding-bottom: calc(100px + env(safe-area-inset-bottom, 0px)); border-top: 0; } }
.footer a { color: var(--dp4-text-2); }

.btn, .dp3-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: var(--dp4-btn-h-sm); padding: 0 20px; box-sizing: border-box; border: 1.5px solid transparent; border-radius: var(--dp4-r-pill); background: var(--dp5-action); color: var(--dp5-action-ink); font: 600 15px/1 var(--dp4-font); cursor: pointer; text-decoration: none; box-shadow: none; transform: none; }
.btn:hover, .dp3-btn:hover { background: var(--dp5-action-hover); color: var(--dp5-action-ink); text-decoration: none; }
.btn:active, .dp3-btn:active { background: var(--dp5-action-press); color: var(--dp5-action-ink); }
/* Secondary and ghost are plain text: no fill, no outline. */
.btn.secondary, .dp3-btn--ghost { background: transparent; color: var(--dp5-secondary-ink); border-color: transparent; box-shadow: none; }
.btn.secondary:hover, .dp3-btn--ghost:hover { background: transparent; color: var(--dp5-secondary-ink-hover); }
.btn.secondary:active, .dp3-btn--ghost:active { background: transparent; color: var(--dp5-secondary-ink-hover); }
/* No edge on a money button. */
.btn.gold, .btn.big, .dp4-btn--money { background: var(--dp5-money); color: var(--dp5-money-ink); border-color: transparent; }
.btn.gold:hover, .btn.big:hover, .dp4-btn--money:hover { background: var(--dp5-money-hover); color: var(--dp5-money-ink); }
.btn.gold:active, .btn.big:active, .dp4-btn--money:active { background: var(--dp5-money-press); color: var(--dp5-money-ink); }
.btn.small, .dp3-btn--sm { min-height: 36px; padding: 0 14px; font-size: 14px; }
/* Danger is a red word (kit A50), never a tinted fill. */
.btn.danger { background: transparent; color: var(--dp5-bad); border-color: transparent; }
.btn:disabled, .btn[aria-busy="true"] { opacity: .45; cursor: not-allowed; }
/* This selector ties styles.css:150-158 and won by load order, painting the green line on every .btn: 1.9:1 on the white primary and 2.8:1 on the money fill.
   .gold/.big are the money fill and take white, like .dp4-btn--money. Secondary keeps the green line. */
:is(.dpt-dark, .dpt-light) :is(a, button).btn:is(.big, .gold):focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-money-ink); }
:is(.dpt-dark, .dpt-light) :is(a, button).btn.secondary:focus-visible { box-shadow: inset 0 0 0 1.5px var(--dp5-text); }
/* The kit's base focus rule is triple-scoped (`.dpt-v5.dpt-v5.dpt-v5 :where(...)` is (0,4,0)) and outranks styles.css:150 at (0,3,1), leaving the green line on a white fill at 1.9:1.
   The four excluded modifiers sit on dark fills or carry their own ink, so they keep the kit's green line. */
:is(.dpt-dark, .dpt-light) :is(a, button).btn:not(.secondary, .gold, .big, .danger):focus-visible { box-shadow: var(--dp5-focus-action); }
:is(.dpt-dark, .dpt-light) :is(a, button).btn.danger:focus-visible { box-shadow: var(--dp5-focus); }

.btnrow { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
.linklike, main .linklike { background: none; border: 0; padding: 0; color: var(--dp4-link); font: 600 15px/1.3 var(--dp4-font); cursor: pointer; }
.linklike:hover { color: var(--dp4-link-hover); text-decoration: underline; }
.linklike.danger { color: var(--dp4-bad); font-size: 14px; }

label { display: block; font: 500 14px/1.3 var(--dp4-font); color: var(--dp4-text-2); margin: 0 0 8px; }
/* A field shows its edge. The alias paints this border in the fill colour
   (--dp4-field-line is --dp5-raised) and this rule's box-shadow: none keeps the kit's inset edge out, so the edge is
   this existing 1px border in line-strong: nothing moves. Every focus rule recolours the same border, so focus wins. */
input, textarea, select { font: 400 18px/1.2 var(--dp4-font); width: 100%; min-height: var(--dp4-field-h); padding: 0 22px; background: var(--dp4-field); border: 1px solid var(--dp5-line-strong); border-radius: var(--dp4-r-field); color: var(--dp4-text); box-shadow: none; }
/* The sign-in fields (.dp4-field) have no border at all under the kit's bridge (`.dpt-v5 .dp4-field { border: 0 }`),
   so they take the inset edge instead. (0,2,0) beats `box-shadow: none` above; the kit's (0,5,0) focus line beats this.
   Autofill paints its fill as a 1000px inset shadow: the edge goes first so the fill cannot cover it. */
.dpt-v5 .dp4-field { box-shadow: inset 0 0 0 1px var(--dp5-line-strong); }
.dpt-v5 .dp4-field:is(:autofill, :-webkit-autofill) { box-shadow: inset 0 0 0 1px var(--dp5-line-strong), 0 0 0 1000px var(--dp4-field) inset; }
textarea { padding: 18px 22px; line-height: 1.4; }
/* Inset line inside the edge. Never an outer ring. */
input:focus, textarea:focus, select:focus, input:focus-visible, textarea:focus-visible, select:focus-visible { outline: 0; border-color: transparent; box-shadow: var(--dp5-focus); }
::placeholder { color: var(--dp4-placeholder); opacity: 1; }
input:autofill, input:-webkit-autofill { box-shadow: 0 0 0 1000px var(--dp4-field) inset; -webkit-text-fill-color: var(--dp4-text); caret-color: var(--dp4-text); border-color: var(--dp5-line-strong); }
/* Nothing selected is green: a ticked box or picked radio takes the text colour. */
input[type="checkbox"], input[type="radio"] { width: 20px; height: 20px; min-height: 0; padding: 0; accent-color: var(--dp5-text); }
.checkrow { display: flex; align-items: center; gap: 12px; font-weight: 500; }
.stack { display: flex; flex-direction: column; gap: 12px; margin-top: 0; }
.field-error { color: var(--dp4-bad); font: 500 14px/1.3 var(--dp4-font); margin: 8px 0 0 6px; }

/* A coloured dot plus the word: no fill, no side padding. */
.sess-chip { display: inline-flex; align-items: center; gap: 6px; font: 600 13px/1 var(--dp4-font); letter-spacing: 0; text-transform: none; border-radius: 0; padding: 4px 0; background: none; color: var(--dp5-text); box-shadow: none; }
.sess-chip::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--dp5-good); }
.sess-chip.is-pending { background: none; color: var(--dp5-text); }
.sess-chip.is-pending::before { background: var(--dp5-warn); }
.sess-chip.is-wait, .sess-chip.is-off { background: none; color: var(--dp5-text-2); box-shadow: none; }
.sess-chip.is-wait::before, .sess-chip.is-off::before { background: var(--dp5-text-3); }
/* Kit v4 status pills: the kit already drops the tint; status words that stand alone get the dot too. */
.dpt-v5 .dp4-pill { background: none; padding-inline: 0; }
.dpt-v5 :is(.hm-rows, .ibx-row, .hm-saved) .dp4-pill, .dpt-v5 .dp4-pill.acc-say { display: inline-flex; align-items: center; gap: 6px; color: var(--dp5-text); }
.dpt-v5 :is(.hm-rows, .ibx-row, .hm-saved) .dp4-pill::before, .dpt-v5 .dp4-pill.acc-say::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--dp5-good); }
.dpt-v5 .dp4-pill--watch.acc-say::before { background: var(--dp5-warn); }
.dp2-nav a.is-active .dp2-navbadge { display: none; }

.p1-microlabel { font: 600 11px/1.3 var(--dp4-font); letter-spacing: .18em; text-transform: uppercase; color: var(--dp4-text-2); }
/* PR is a white badge with ink text; gold is out of the apps. */
.pr { background: var(--dp5-primary); color: var(--dp5-primary-ink); border-radius: var(--dp5-r-badge); font: 700 12px/1 var(--dp5-font); letter-spacing: .04em; padding: 3px 8px; }

/* The head sits one rung up inside a tile, with a text-2 label. */
table.report th { background: var(--dp5-raised); color: var(--dp5-text-2); font: 600 11px/1.3 var(--dp4-font); letter-spacing: .12em; text-transform: uppercase; padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--dp4-line); }
table.report td { padding: 14px 12px; border-bottom: 1px solid var(--dp4-line); vertical-align: middle; background: none; }
table.report tr:last-child td { border-bottom: 0; }
table.report td.good, table.report .good { color: var(--dp4-good); background: none; }
table.report td.bad, table.report .bad { color: var(--dp4-text-2); background: none; }

.dp-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Placed last so it beats the .topbar block above. */
@media (max-width: 768px) {
  .topbar, .topbar--app { position: static; background: none; border: 0; min-height: 0; }
  .topbar-in { min-height: 0; padding: 0; }
  .brand { display: none !important; }
}

.dp2-swtoast { background: var(--dp5-primary); color: var(--dp5-primary-ink); border-radius: var(--dp5-r-ctl); font: 600 15px/1.3 var(--dp5-font); box-shadow: none; }
.dp2-swtoast:hover { background: var(--dp5-primary-hover); }
.dp2-swtoast-x { background: var(--dp5-primary); color: var(--dp5-primary-ink); border-radius: var(--dp5-r-ctl); box-shadow: none; }
.dp2-swtoast-x:hover { color: var(--dp5-primary-ink); background: var(--dp5-primary-hover); }

/* the wash is a static plane on the content column (`main.dp5-washed`, kit utility).
   Report already paints .dp4-wash; do not double-paint that screen. The old body::before / fixed
   .dp4-wash plane is gone — never background-attachment: local, never pinned to the viewport.
   No opaque sticky header sits inside <main>, so the topbar does not carry .dp5-washed. */
main.dp5-washed:has(.dp4-wash) { background-image: none; }
/* On the 720px column the kit's wash is wider than the column and shows a vertical edge; this one is gone before the edge. */
@media (min-width: 769px) {
  .dpt-v5 main.dp5-washed { background-image: radial-gradient(60% 80% at 50% 0%, var(--dp5-wash), transparent 70%); }
  /* Report paints the kit's own 720px wash plane inside the column; same narrower gradient so it fades before the column edge. */
  .dpt-v5 main > .dp4-wash { background: radial-gradient(60% 80% at 50% 0%, var(--dp5-wash), transparent 70%); }
}
/* Look C: file tiles are one neutral step up inside the card (no tint: colour carries meaning only). */
.ibx-tile { background: var(--dp4-card-2); color: var(--dp5-text-2); }
/* A byline is not one of green's jobs; the green rail on the card already says it is the coach. */
.ibx-msg.is-coach .ibx-who { color: var(--dp5-text); }

/* Class type is an 8px dot plus the word, with no fill and no coloured text, so the time and the
   class name stay in the normal text colour. */
.dpt-app { --k-sp: var(--dp5-cat-performance); --k-semi: var(--dp5-cat-semi); --k-power: var(--dp5-cat-power); --k-vb: var(--dp5-cat-volleyball); --k-other: var(--dp5-text-3); }
.kdot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; vertical-align: 0; background: var(--k-other); }
.k-sp .kdot { background: var(--k-sp); }
.k-semi .kdot { background: var(--k-semi); }
.k-power .kdot { background: var(--k-power); }
.k-vb .kdot { background: var(--k-vb); }
.rsv-row.is-full .kdot, .rsv-row.is-in .kdot { opacity: .45; }

.dp2-sheet { padding-bottom: calc(36px + env(safe-area-inset-bottom, 0px)); }
#rsv-sheet, #cancel-sheet { padding-bottom: calc(44px + env(safe-area-inset-bottom, 0px)); }
#more-sheet .card-viz-ico { width: 36px; height: 36px; border-radius: var(--dp5-r-ctl); background: var(--dp4-card-2); color: var(--dp5-text-2); }
#more-sheet .card-viz-ico svg { width: 18px; height: 18px; }

#more-sheet .dp2-sheet { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }

/* .dpt-v5 scope on purpose: the kit paints .dp4-eyebrow green at (0,2,0), so a bare class here
   loses and every label stayed green. */
.dpt-v5 .dp4-eyebrow--quiet {
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--dp5-text-2);
}
/* Text on the green wash is white or grey, and it is never green. */
.dpt-v5 .dp5-washed .dp4-eyebrow:not(.dp4-eyebrow--quiet) {
  color: var(--dp5-text-2);
  text-transform: none;
  letter-spacing: 0;
  font-size: 13px;
  font-weight: 600;
}

/* Print flattens the lift the way the kit flattens .dp5-card. */
@media print {
  .dpt-v5 :is(.card, .dp4-card) { box-shadow: none; }
}

/* The shared kit still ships 56px heights and fully round corners. These rules match that selector and load after it, so the column stays 720px while cards, buttons and fields use these sizes.
   Leave the charcoal page and panel colours alone: they apply as shipped. */
:root.dpt-v5.dpt-app, :root.dpt-v5.dpt-app :is(.dpt-dark, .dpt-light) {
  --dp5-r-ctl: 12px;
  --dp5-r-chip: 12px;
  --dp5-r-card: 16px;
  --dp5-h-ctl-lg: 40px;
  --dp5-h-field: 44px;
  --dp5-h-row: 44px;
}
@media (max-width: 768px), (pointer: coarse) {
  :root.dpt-v5.dpt-app, :root.dpt-v5.dpt-app :is(.dpt-dark, .dpt-light) {
    --dp5-h-ctl-lg: 44px;
  }
}
/* The primary is the one filled action. Ghost is plain text: no fill, no outline. */
.dpt-v5.dpt-app .dp4-btn { border-radius: 12px; background: var(--dp5-action); color: var(--dp5-action-ink); }
.dpt-v5.dpt-app .dp4-btn:hover { background: var(--dp5-action-hover); color: var(--dp5-action-ink); }
.dpt-v5.dpt-app .dp4-btn:active { background: var(--dp5-action-press); color: var(--dp5-action-ink); }
.dpt-v5.dpt-app .dp4-btn--ghost,
.dpt-v5.dpt-app .dp4-btn--ghost:active {
  background: transparent;
  color: var(--dp5-secondary-ink);
  border: 0;
  box-shadow: none;
}
.dpt-v5.dpt-app .dp4-btn--ghost:hover { background: transparent; color: var(--dp5-secondary-ink-hover); }
.dpt-v5.dpt-v5.dpt-v5.dpt-app .dp4-btn--ghost:focus-visible { box-shadow: var(--dp5-focus); }
.dpt-v5.dpt-app .dp4-btn:disabled { background: var(--dp5-raised-hover); color: var(--dp5-text-off); opacity: 1; }
.dpt-v5.dpt-app .dp4-btn--ghost:disabled { background: transparent; }

/* The track draws its edge inside; the picked segment is the white slab, so it has no edge. */
.dpt-v5.dpt-app .dp4-seg { box-shadow: inset 0 0 0 1px var(--dp5-line-card); }
.dpt-v5.dpt-app .dp4-seg button.is-on { box-shadow: none; }
.dpt-v5.dpt-app .dp4-seg button:not(.is-on):hover { color: var(--dp5-text); }

/* Screen-reader-only submit buttons are 1px and clipped, but Chrome still paints its dark-scheme default
   button face (a charcoal grey) under them. No fill. */
button.dp-sr { background: none; color: inherit; }

/* Visible keyboard focus for the shared tabs; the active green underline remains a location marker. */
.dp2-nav a:focus-visible, .dp2-nav button:focus-visible { box-shadow: var(--dp5-focus); }

/* Every bottom sheet fits on the screen and scrolls inside itself when it is taller. It is one step lighter than the page tiles, its rows one step lighter again, and the page behind dims to the kit scrim, so it reads as on top. */
.dp2-sheet { max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px); overflow-y: auto; overscroll-behavior: contain; }
.dp2-sheet.is-scroll { touch-action: pan-y pinch-zoom; }
/* A scrolled sheet keeps its X on screen (the more-sheet recipe in styles.css). */
.dp2-sheet.is-scroll .dp2-sheetx { position: sticky; top: 0; float: right; margin: -44px -20px 0 0; background: var(--dp5-raised-hover); border-top-right-radius: var(--dp3-r-xl); z-index: 1; }
:root.dpt-v5.dpt-app .dp2-sheet { background: var(--dp5-raised-hover); border-color: var(--dp5-line-strong); --dp5-raised: var(--dp5-raised-press); --dp4-card-2: var(--dp5-raised-press); --dp4-field: var(--dp5-raised-press); --dp4-field-line: var(--dp5-raised-press); --well: var(--dp5-raised-press); --dp2-well: var(--dp5-raised-press); }
:root.dpt-v5.dpt-app .dp2-sheetgrip { background: var(--dp5-line-strong); }
:root.dpt-v5.dpt-app .dp2-sheetback { background: var(--dp5-scrim); }

/* viewport-fit=cover (header.ejs) makes the safe-area insets real on iPhones. A phone turned sideways keeps the
   content clear of the notch. */
@media (max-width: 768px) { main { padding-left: max(16px, env(safe-area-inset-left, 0px)); padding-right: max(16px, env(safe-area-inset-right, 0px)); } }
