/* 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('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);
  /* 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 asking Jon; #00A651 is the edge if he asks for one 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;
  /* 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 1px 2px rgba(13, 17, 23, .06);
  --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 {
  border-color: var(--dp3-focus);
  box-shadow: inset 0 0 0 1px 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);
}
.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 to Jon. */
.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-line);
  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-line);
  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);
    color: var(--dp3-text);
    border: 1.5px solid var(--dp3-line-strong);
    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;
  }
}

