/* ===========================================================================
   Saba design system
   ---------------------------------------------------------------------------
   One stylesheet, no build step. Token names and component anatomy follow the
   shadcn/ui convention deliberately, so that reference markup from the shadcn
   registry maps onto these classes without translation. shadcn itself ships
   React; this application is server-rendered Django templates, so the tokens
   and anatomy are adopted and the runtime is not. See docs/DESIGN_SYSTEM.md.

   Structure
     1  Tokens (light, dark)
     2  Reset and base elements
     3  Typography
     4  Layout primitives
     5  Application shell (sidebar, topbar, page header)
     6  Components
     7  Marketing surfaces
     8  Charts
     9  Responsive
    10  Print
   ======================================================================== */

/* -- 1  Tokens ----------------------------------------------------------- */

:root {
  color-scheme: light;

  /* Surfaces. Warm neutral paper, not cold slate: it sits better under the
     photography and under a green brand, and it is the fastest way to tell
     this apart from every blue-grey admin tool. */
  --bg: #f4f7fc;
  --surface: #ffffff;
  --surface-2: #edf2f9;
  --surface-3: #dfe7f3;
  --overlay: rgba(20, 22, 16, .55);

  /* Ink. Every value below is measured against --surface, --bg or --surface-2;
     see tests/test_design_tokens.py, which fails the build if a pair used for
     text drops under WCAG AA. */
  --fg: #0f1a2e;
  --fg-muted: #46536b;
  --fg-subtle: #4f5d77;
  --fg-inverse: #ffffff;

  /* Lines */
  --border: #dde5f0;
  --border-strong: #a3b1c7;

  /* Brand. Taken from the Saba Center mark: three figures in green, blue and
     red. Green is the largest and the central one, so it leads. The mark's own
     green (#6da343) is 3.01:1 on white, which is fine for a large shape and
     not enough for text, so --primary is the text-safe step of the same hue
     and --brand-green is the mark's value for fills.
     The previous palette was navy and rust -- neither appears in the logo. */
  --brand-green: #2fae5f;
  --brand-blue: #1d63d6;
  --brand-red: #e8453c;

  --primary: #0a7a45;
  --primary-hover: #07623a;
  --primary-fg: #ffffff;
  --primary-soft: #dcf5e8;
  --primary-soft-fg: #064d2c;
  --navy: #0b1f3a;
  --warm: #c23b22;
  --warm-hover: #a32f19;
  --gold: #ffc53d;

  /* Status. Foreground values are for text on the matching -soft fill. */
  --success: #0a7a45;
  --success-soft: #dcf5e8;
  --warning: #9a4a00;
  --warning-soft: #fff1dc;
  --danger: #c0271c;
  --danger-hover: #9f1f16;
  --danger-soft: #fde8e6;
  --info: #1759c4;
  --info-soft: #e2edfe;

  /* Chart series. Green and violet, not green and orange: the intuitive
     brand pairing (green + warm) separates by only dE 2.4 for a deuteranope,
     which is to say not at all. Measured with the palette validator --
     deutan dE 22.4, tritan 12.0, normal 29.6, both >= 3:1 on the surface. */
  --chart-1: #4f8a33;
  --chart-2: #7c4bb0;
  /* Third and fourth series are separated by lightness rather than hue, which
     survives every colour-vision deficiency: deep navy and mid grey against
     the green/violet pair. Worst adjacent CVD dE 23.1, all >= 3.2:1 on white. */
  --chart-3: #1d3557;
  --chart-4: #8f8f8f;
  /* Fifth: unclassified money in the long view (D-35). Amber, always stacked
     on the grey \"other\" and never beside the green, which is the pairing a
     deuteranope cannot separate. */
  --chart-5: #a86008;


  /* Vivid layer (2026-09 redesign). The logo's three figures -- green, blue,
     red -- used at full strength for fills, gradients and the navigation,
     with text-safe steps above for anything that carries words. */
  --accent: #1d63d6;
  --accent-soft: #e2edfe;
  --coral: #e8553d;
  --grad-hero: linear-gradient(135deg, #053d2a 0%, #0a7a45 42%, #1d63d6 100%);
  --grad-brand: linear-gradient(90deg, #2fae5f, #1d63d6 55%, #e8453c);
  --sidebar-bg: #0b1f3a;
  --sidebar-fg: #e6eefb;
  --sidebar-muted: #a9bbd8;
  --sidebar-hover: #13305a;
  --sidebar-active: #3ddc97;
  --sidebar-active-fg: #04231a;

  /* Focus */
  --ring: #1d63d6;

  /* Radius */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;

  /* Elevation. Deliberately shallow: depth marks what floats above the page
     (menus, sheets), not every card. */
  --shadow-sm: 0 1px 2px rgba(24, 26, 18, .06);
  --shadow: 0 1px 3px rgba(24, 26, 18, .08), 0 1px 2px rgba(24, 26, 18, .04);
  --shadow-lg: 0 12px 32px rgba(24, 26, 18, .16), 0 2px 8px rgba(24, 26, 18, .08);

  /* Shell metrics */
  --sidebar-w: 256px;
  --topbar-h: 60px;
  --page-max: 1320px;

  --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-serif: Georgia, 'Times New Roman', serif;
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

/* Dark theme. Selected, not an inversion: the ramps are re-stepped against a
   dark ground so brand green stays legible and status colours keep their
   meaning.

   The two rules below are byte-for-byte identical on purpose -- one applies the
   viewer's system setting, the other an explicit choice, and CSS cannot share a
   body across a media query boundary. tests/test_design_tokens.py asserts they
   stay identical, because a token edited in one and not the other is exactly
   how a page ends up with light ink on a dark card. Edit both, or edit
   neither. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0a1122;
    --surface: #101a30;
    --surface-2: #16233e;
    --surface-3: #203052;
    --overlay: rgba(6, 8, 4, .7);

    --fg: #eaf0fa;
    --fg-muted: #aab6cc;
    --fg-subtle: #9aa8c1;
    --fg-inverse: #0a1122;

    --border: #22314f;
    --border-strong: #3d5078;

    --brand-green: #3ddc97;
    --brand-blue: #5b9bff;
    --brand-red: #ff6b5e;

    --primary: #3ddc97;
    --primary-hover: #6ae8b0;
    --primary-fg: #032416;
    --primary-soft: #0c3a2a;
    --primary-soft-fg: #a6f1cf;
    --navy: #0b1f3a;
    --warm: #ff8a6b;
    --warm-hover: #ffa68d;
    --gold: #ffc53d;

    --success: #3ddc97;
    --success-soft: #0c3a2a;
    --warning: #ffb35c;
    --warning-soft: #3a2610;
    --danger: #ff8a80;
    --danger-hover: #ffaaa2;
    --danger-soft: #3d1a1a;
    --info: #8ab8ff;
    --info-soft: #14284b;

    --chart-1: #6da343;
    --chart-2: #9a72cc;
    --chart-3: #a9c9ec;
    --chart-4: #a3a79b;
    --chart-5: #e0a23a;

    --accent: #8ab8ff;
    --accent-soft: #14284b;
    --coral: #ff8a6b;
    --grad-hero: linear-gradient(135deg, #053d2a 0%, #0a7a45 42%, #1d63d6 100%);
    --grad-brand: linear-gradient(90deg, #3ddc97, #5b9bff 55%, #ff6b5e);
    --sidebar-bg: #070d1b;
    --sidebar-fg: #e6eefb;
    --sidebar-muted: #a9bbd8;
    --sidebar-hover: #13244a;
    --sidebar-active: #3ddc97;
    --sidebar-active-fg: #04231a;

    --ring: #8ab8ff;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow: 0 1px 3px rgba(0, 0, 0, .45), 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-lg: 0 14px 38px rgba(0, 0, 0, .6), 0 2px 8px rgba(0, 0, 0, .4);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0a1122;
  --surface: #101a30;
  --surface-2: #16233e;
  --surface-3: #203052;
  --overlay: rgba(6, 8, 4, .7);

  --fg: #eaf0fa;
  --fg-muted: #aab6cc;
  --fg-subtle: #9aa8c1;
  --fg-inverse: #0a1122;

  --border: #22314f;
  --border-strong: #3d5078;

  --brand-green: #3ddc97;
  --brand-blue: #5b9bff;
  --brand-red: #ff6b5e;

  --primary: #3ddc97;
  --primary-hover: #6ae8b0;
  --primary-fg: #032416;
  --primary-soft: #0c3a2a;
  --primary-soft-fg: #a6f1cf;
  --navy: #0b1f3a;
  --warm: #ff8a6b;
  --warm-hover: #ffa68d;
  --gold: #ffc53d;

  --success: #3ddc97;
  --success-soft: #0c3a2a;
  --warning: #ffb35c;
  --warning-soft: #3a2610;
  --danger: #ff8a80;
  --danger-hover: #ffaaa2;
  --danger-soft: #3d1a1a;
  --info: #8ab8ff;
  --info-soft: #14284b;

  --chart-1: #6da343;
  --chart-2: #9a72cc;
  --chart-3: #a9c9ec;
  --chart-4: #a3a79b;
  --chart-5: #e0a23a;

  --accent: #8ab8ff;
  --accent-soft: #14284b;
  --coral: #ff8a6b;
  --grad-hero: linear-gradient(135deg, #053d2a 0%, #0a7a45 42%, #1d63d6 100%);
  --grad-brand: linear-gradient(90deg, #3ddc97, #5b9bff 55%, #ff6b5e);
  --sidebar-bg: #070d1b;
  --sidebar-fg: #e6eefb;
  --sidebar-muted: #a9bbd8;
  --sidebar-hover: #13244a;
  --sidebar-active: #3ddc97;
  --sidebar-active-fg: #04231a;

  --ring: #8ab8ff;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow: 0 1px 3px rgba(0, 0, 0, .45), 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-lg: 0 14px 38px rgba(0, 0, 0, .6), 0 2px 8px rgba(0, 0, 0, .4);
}

/* -- 2  Reset and base --------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 16px/1.6 var(--font);
  -webkit-font-smoothing: antialiased;
}

img, svg, video { max-width: 100%; }

a { color: inherit; text-underline-offset: 4px; }

button, input, textarea, select { font: inherit; color: inherit; }
button { border: 0; background: none; cursor: pointer; }

/* One focus treatment everywhere. Two rings so it stays visible on both a
   light card and a dark band. */
:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

::selection { background: var(--primary-soft); color: var(--primary-soft-fg); }

hr { border: 0; border-top: 1px solid var(--border); margin: 24px 0; }

code, kbd, pre, samp { font-family: var(--font-mono); }

pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 16px;
  border-radius: var(--radius);
  font-size: 13px;
}

code {
  font-size: .9em;
  background: var(--surface-2);
  border-radius: 4px;
  padding: 2px 5px;
}

details { margin: 16px 0; }
summary { cursor: pointer; font-weight: 600; }

/* Visually hidden but announced. */
.sr-only {
  position: absolute; inset-inline-start: 0; top: 0; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* Hidden until focused. Positioned with a logical offset, not left: -10000px:
   under right-to-left that physical offset is off the *far* edge and extends
   the scrollable width of the document -- the Farsi page rendered 11,440px
   wide because of this one declaration. */
.skip {
  position: absolute; inset-inline-start: -10000px; top: 10px; z-index: 200;
  background: var(--surface); color: var(--fg);
  padding: 12px 16px; border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.skip:focus { inset-inline-start: 12px; }

/* -- 3  Typography ------------------------------------------------------- */

h1, h2, h3, h4, h5, p { margin-top: 0; }
h1, h2, h3, h4, h5 { line-height: 1.2; letter-spacing: -.02em; font-weight: 600; margin-bottom: .5em; }
p { margin-bottom: 1em; }
p:last-child { margin-bottom: 0; }

.muted { color: var(--fg-muted); }
.subtle { color: var(--fg-subtle); }
small { font-size: 13px; color: var(--fg-muted); }

/* Eyebrow: a small uppercase label above a heading. */
.eyebrow {
  font-size: 11.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--fg-muted);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--primary); flex: none; }

.text-link {
  font-weight: 600;
  color: var(--primary);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}
.text-link:hover { color: var(--primary-hover); }

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

/* -- 4  Layout primitives ------------------------------------------------ */

.container { max-width: var(--page-max); margin: 0 auto; padding: 32px 24px 72px; }
.stack > * + * { margin-top: 16px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; }
.two-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.three-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.cluster { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; }
.spaced { margin-top: 24px; }

/* -- 5  Application shell ------------------------------------------------ */

/* The administration and member portals do not wear the marketing chrome.
   They get a sidebar, a working top bar, and no Donate button. */

.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}

.sidebar {
  background: var(--surface);
  border-inline-end: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.sidebar-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  min-height: var(--topbar-h);
  border-bottom: 1px solid var(--border);
  font-weight: 650;
  letter-spacing: -.02em;
  text-decoration: none;
  flex: none;
}
.sidebar-head img { height: 24px; width: auto; display: block; }
.sidebar-head .portal {
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-muted); font-weight: 700; display: block; line-height: 1.3;
}
.sidebar-head .name { font-size: 14.5px; line-height: 1.2; display: block; }

.sidebar-nav { padding: 12px 10px 24px; flex: 1; }
.sidebar-group + .sidebar-group { margin-top: 18px; }
.sidebar-group > h2 {
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-subtle); font-weight: 700; margin: 0 0 6px; padding: 0 10px;
}
.sidebar-nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  text-decoration: none; font-size: 14px; font-weight: 500;
  color: var(--fg-muted); line-height: 1.3;
}
.sidebar-nav a:hover { background: var(--surface-2); color: var(--fg); }
.sidebar-nav a[aria-current="page"] {
  background: var(--primary-soft); color: var(--primary-soft-fg); font-weight: 600;
}
.sidebar-nav a svg { width: 16px; height: 16px; flex: none; opacity: .85; }
.sidebar-nav .count {
  margin-inline-start: auto; font-size: 11.5px; font-variant-numeric: tabular-nums;
  color: var(--fg-subtle); background: var(--surface-2);
  border-radius: 20px; padding: 1px 7px;
}

.sidebar-foot { padding: 12px; border-top: 1px solid var(--border); flex: none; }

.app-main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  min-height: var(--topbar-h);
  display: flex; align-items: center; gap: 14px;
  padding: 10px 24px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
@supports not (backdrop-filter: blur(1px)) { .topbar { background: var(--bg); } }

/* The title shrinks and truncates; the controls never do. Without this a
   long page name ("Recommendations") pushed the search box and the account
   menu past the right edge of a phone, taking the whole document with it. */
.topbar-title {
  font-size: 14px; font-weight: 600; margin: 0;
  flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.topbar-actions { margin-inline-start: auto; display: flex; align-items: center; gap: 10px; flex: none; }

.app-body { padding: 24px; max-width: var(--page-max); width: 100%; }

/* Page header: what this page is, and what you can do on it. */
.page-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 20px; flex-wrap: wrap; margin-bottom: 22px;
}
.page-head h1 { font-size: 26px; margin: 0 0 4px; letter-spacing: -.025em; }
.page-head p { margin: 0; color: var(--fg-muted); font-size: 14px; max-width: 70ch; }
.page-head-actions { display: flex; gap: 10px; flex-wrap: wrap; }



/* Theme toggle: shows the theme you would switch to, so the control describes
   its result rather than the current state. Hidden until app.js enables it --
   a control that cannot work without JavaScript should not be offered. */
.theme-toggle .sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: none; }
}
:root[data-theme="dark"] .theme-toggle .sun { display: block; }
:root[data-theme="dark"] .theme-toggle .moon { display: none; }

.topbar-search { width: 240px; }
.topbar-search input { min-height: 34px; font-size: 13.5px; background: var(--surface); }
.app-messages { padding: 14px 24px 0; max-width: var(--page-max); }
.app-messages .message { margin: 0 0 10px; }
.menu-identity { padding: 2px 10px 6px; margin: 0; font-size: 13.5px; font-weight: 600; }
.account-menu > summary { border-radius: 50%; }
.sidebar-nav [role="list"] { display: flex; flex-direction: column; gap: 1px; }

@media (max-width: 760px) {
  .topbar-search { width: 150px; }
  .app-messages { padding: 12px 16px 0; }
}

/* -- 6  Components ------------------------------------------------------- */

/* Button ---------------------------------------------------------------- */
.button, button[type=submit], .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 0 16px; min-height: 40px;
  background: var(--primary); color: var(--primary-fg);
  border: 1px solid transparent; border-radius: var(--radius-sm);
  font-size: 14px; font-weight: 600; line-height: 1;
  text-decoration: none; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease;
}
.button:hover, button[type=submit]:hover, .btn:hover { background: var(--primary-hover); }

.button.secondary, .btn.secondary {
  background: var(--surface); color: var(--fg); border-color: var(--border-strong);
}
.button.secondary:hover, .btn.secondary:hover { background: var(--surface-2); }

.button.outline, .btn.outline {
  background: transparent; color: var(--fg); border-color: var(--border-strong);
}
.button.outline:hover, .btn.outline:hover { background: var(--surface-2); }

.button.ghost, .btn.ghost { background: transparent; color: var(--fg-muted); }
.button.ghost:hover, .btn.ghost:hover { background: var(--surface-2); color: var(--fg); }

/* `button.danger` as well as `.button.danger`: a bare <button> is already
   styled as the primary action, so a submit button carrying only `danger`
   matched nothing and rendered green. On the confirmation page that put a
   calm brand-green button under the words "this cannot be recalled" -- the
   colour disagreeing with the sentence. Caught by looking at a screenshot,
   not by a test. */
.button.danger, .btn.danger, button.danger { background: var(--danger); color: #fff; border-color: transparent; }
.button.danger:hover, .btn.danger:hover, button.danger:hover { background: var(--danger-hover); }

/* Giving. Gold with dark ink (8.76:1), deliberately neither the brand green
   nor the destructive red -- a donate button must not read as "primary action"
   or as "danger". */
.button.warm { background: var(--gold); color: #2a1e05; border-color: transparent; }
.button.warm:hover { background: #e0a51e; }

.button.navy { background: var(--navy); color: #fff; }
.button.navy:hover { filter: brightness(1.2); }

.button.light { background: var(--surface); color: var(--fg); border-color: transparent; }
.button.light:hover { background: var(--surface-2); }

.button.small, .btn.small { min-height: 34px; padding: 0 12px; font-size: 13px; }
.button.large { min-height: 46px; padding: 0 22px; font-size: 15px; }
.button.block { width: 100%; }
.button[disabled], button[disabled] { opacity: .5; cursor: not-allowed; }
button[data-busy] { opacity: .7; cursor: progress; }

/* Icon-only control. */
.icon-button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--radius-sm);
  color: var(--fg-muted); background: transparent; border: 1px solid transparent;
}
.icon-button:hover { background: var(--surface-2); color: var(--fg); }
.icon-button svg { width: 17px; height: 17px; }

/* The sidebar is permanent at desktop width, so the control that opens it does
   not exist there. Declared after .icon-button, which also sets display. */
.sidebar-toggle { display: none; }

/* Card ------------------------------------------------------------------ */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.card > h3, .card > .card-head h3 { font-size: 16px; margin: 0 0 4px; }
.card > h2 { font-size: 18px; margin: 0 0 4px; }
.card .eyebrow { margin-bottom: 10px; }
.card-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 14px; flex-wrap: wrap; margin-bottom: 16px;
}
.card-head p { font-size: 13.5px; color: var(--fg-muted); margin: 0; }
.card-foot {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border);
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  font-size: 13.5px; flex-wrap: wrap;
}
a.card, .card-link { text-decoration: none; display: block; }
a.card:hover, .card-link:hover { border-color: var(--border-strong); }

/* Metric: one number, labelled, with optional context underneath. */
.metric-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.metric {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 16px 18px;
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.metric .label {
  font-size: 12.5px; color: var(--fg-muted); font-weight: 500;
  display: flex; align-items: center; gap: 6px;
}
.metric .value {
  font-size: 28px; font-weight: 600; letter-spacing: -.03em; line-height: 1.25;
  font-variant-numeric: tabular-nums;
}
.metric .value.small { font-size: 22px; }
.metric .foot { font-size: 12.5px; color: var(--fg-subtle); }
.metric.attention { border-color: var(--warning); background: var(--warning-soft); }
.metric.attention .label, .metric.attention .foot { color: var(--warning); }

/* Badge ----------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  border-radius: 20px; padding: 2px 9px;
  font-size: 12px; font-weight: 600; line-height: 1.5; white-space: nowrap;
  background: var(--surface-2); color: var(--fg-muted);
  border: 1px solid var(--border);
}
.badge.success { background: var(--success-soft); color: var(--success); border-color: transparent; }
.badge.warning { background: var(--warning-soft); color: var(--warning); border-color: transparent; }
.badge.danger  { background: var(--danger-soft);  color: var(--danger);  border-color: transparent; }
.badge.info    { background: var(--info-soft);    color: var(--info);    border-color: transparent; }
.badge.solid   { background: var(--primary); color: var(--primary-fg); border-color: transparent; }
/* Status is never colour alone: a dot shape plus the written word. */
.badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.badge.plain::before { display: none; }

/* Alert / messages ------------------------------------------------------ */
.messages { max-width: var(--page-max); margin: 16px auto 0; padding: 0 24px; }
.message, .notice, .alert {
  border: 1px solid var(--border); border-inline-start: 3px solid var(--primary);
  background: var(--surface); border-radius: var(--radius);
  padding: 13px 16px; margin: 12px 0; font-size: 14px;
}
.message.success, .notice { border-inline-start-color: var(--success); }
.message.error, .alert.error { border-inline-start-color: var(--danger); background: var(--danger-soft); }
.message.warning { border-inline-start-color: var(--warning); background: var(--warning-soft); }

.form-alert {
  border: 1px solid var(--danger); border-inline-start-width: 3px;
  background: var(--danger-soft); border-radius: var(--radius);
  padding: 14px 18px; margin-bottom: 22px;
}
.form-alert strong { display: block; color: var(--danger); font-size: 14.5px; }
.form-alert p { margin: 6px 0 0; font-size: 13.5px; }

/* Forms ----------------------------------------------------------------- */
label { display: block; font-size: 13.5px; font-weight: 600; margin-bottom: 6px; }

input:not([type=checkbox]):not([type=radio]), textarea, select {
  display: block; width: 100%;
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  padding: 9px 11px; min-height: 40px;
}
input::placeholder, textarea::placeholder { color: var(--fg-subtle); }
input:hover:not([disabled]), textarea:hover, select:hover { border-color: var(--fg-subtle); }
textarea { resize: vertical; min-height: 96px; }
select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) 17px, calc(100% - 12px) 17px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-inline-end: 34px;
}
input[type=checkbox], input[type=radio] {
  width: 17px; height: 17px; accent-color: var(--primary);
  vertical-align: middle; margin: 0;
}

.field { margin-bottom: 20px; }
.field > label { display: block; }
.field input:not([type=checkbox]):not([type=radio]), .field textarea, .field select { margin: 0; }
.helptext, .field .helptext { font-size: 12.5px; color: var(--fg-muted); display: block; margin: 6px 0 0; }
.helptext ul { padding-inline-start: 18px; margin: 4px 0 0; }
.field-message { margin: 6px 0 0; font-size: 13px; color: var(--danger); font-weight: 500; }
.has-error > label { color: var(--danger); }
.has-error input:not([type=checkbox]), .has-error textarea, .has-error select { border-color: var(--danger); }
.errorlist { color: var(--danger); background: var(--danger-soft); border-radius: var(--radius-sm); padding: 10px 24px; font-size: 13.5px; }
abbr.req { color: var(--danger); text-decoration: none; font-weight: 700; border: 0; }
.required-note { font-size: 12.5px; color: var(--fg-muted); margin: 0 0 12px; }
.is-required::after { content: " *"; color: var(--danger); font-weight: 700; }

.check-row { display: flex; gap: 10px; align-items: flex-start; }
.check-row input { margin-top: 3px; flex: 0 0 auto; }
.check-row label { font-weight: 400; font-size: 14px; margin: 0; line-height: 1.45; }

.choice-set {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px 16px 14px; margin: 0; min-width: 0;
}
.choice-set legend { font-size: 13.5px; font-weight: 600; padding: 0 6px; }
.choice-set > div > div, .choice-set li { margin-top: 8px; list-style: none; }
.choice-set ul { padding: 0; margin: 0; }
.choice-set label { font-weight: 400; font-size: 14px; margin: 0; display: flex; gap: 10px; align-items: center; }

.form-shell, .account-shell {
  max-width: 640px; margin: 40px auto 72px; padding: 28px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.form-shell h1, .account-shell h1 { font-size: 24px; }
.form-shell > p, .account-shell > p { color: var(--fg-muted); font-size: 14.5px; }
.account-shell nav { display: none; }
form p { margin-bottom: 20px; }

/* Toolbar: filters and search above a table. */
.toolbar {
  display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 14px 16px; margin-bottom: 16px;
}
.toolbar > div { flex: 1 1 150px; min-width: 130px; }
.toolbar label { font-size: 12px; color: var(--fg-muted); }
.toolbar .actions, .toolbar button { flex: 0 0 auto; }
.filters { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin: 20px 0; }
.filters > div { flex: 1; min-width: 130px; }
.filters label { font-size: 12px; color: var(--fg-muted); }

/* Search box with a leading icon. */
.search { position: relative; }
.search svg { position: absolute; inset-inline-start: 11px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; color: var(--fg-subtle); pointer-events: none; }
.search input:not([type=checkbox]) { padding-inline-start: 33px; }

/* Table ----------------------------------------------------------------- */
/* position:relative matters: a visually hidden <caption> is position:absolute,
   and without a positioned ancestor its containing block is the page, so it
   escapes this scroll container and widens the document. */
.table-wrap {
  position: relative; overflow: auto;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface);
}
.table-wrap:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }

table { width: 100%; border-collapse: collapse; font-size: 13.5px; text-align: start; }
/* Column headers only. A row header (<th scope="row">) is a person's name or a
   plan, not a label -- an earlier version styled both alike and rendered every
   member's name in small uppercase. */
thead th {
  background: var(--surface-2); color: var(--fg-muted);
  font-weight: 600; font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase;
  padding: 10px 16px; white-space: nowrap;
  position: sticky; top: 0; z-index: 1;
  border-bottom: 1px solid var(--border);
}
td, tbody th { padding: 11px 16px; border-top: 1px solid var(--border); vertical-align: middle; }
tbody th { font-weight: 600; text-align: start; }
tbody tr:first-child td, tbody tr:first-child th { border-top: 0; }
tbody tr:hover { background: var(--surface-2); }
td a { font-weight: 500; color: var(--primary); text-decoration: none; }
td a:hover { text-decoration: underline; }
/* A row header holds the link and a sub-line of plain text, so the link sits
   inside a text block: axe's link-in-text-block rule, and it is right --
   colour alone would not distinguish it. Underlined, not restyled away. */
tbody th a { font-weight: 600; color: var(--primary); text-underline-offset: 3px; }
td.right, th.right { text-align: end; }
td.num, th.num { text-align: end; font-variant-numeric: tabular-nums; }
/* A timestamp is one thing; wrapping it into three lines triples every row. */
td.when, th.when { white-space: nowrap; font-variant-numeric: tabular-nums; }
.table-wrap + .table-foot, .table-foot {
  display: flex; justify-content: space-between; align-items: center;
  gap: 12px; flex-wrap: wrap; padding: 12px 2px; font-size: 13px; color: var(--fg-muted);
}
.cell-strong { font-weight: 600; color: var(--fg); }
.cell-sub { display: block; font-size: 12px; color: var(--fg-subtle); }
td code, th code { font-size: 12px; }

/* A column marked optional is dropped at phone width. Tables still scroll,
   but the first thing on screen should be the column someone came for. */
@media (max-width: 760px) { .col-optional { display: none; } }

/* Row actions live at the end of a row and stay quiet until hover/focus. */
.row-actions { display: flex; gap: 6px; justify-content: flex-end; }

/* Tabs ------------------------------------------------------------------ */
.tabs {
  display: flex; gap: 2px; margin-bottom: 20px;
  border-bottom: 1px solid var(--border); overflow-x: auto;
}
.tabs a {
  padding: 9px 14px; text-decoration: none; font-size: 14px; font-weight: 500;
  color: var(--fg-muted); border-bottom: 2px solid transparent; white-space: nowrap;
}
.tabs a:hover { color: var(--fg); }
.tabs a[aria-current="page"] { color: var(--primary); border-bottom-color: var(--primary); font-weight: 600; }

/* Empty state ----------------------------------------------------------- */
.empty {
  padding: 40px 28px; text-align: center; color: var(--fg-muted);
  border: 1px dashed var(--border-strong); border-radius: var(--radius-lg);
  background: var(--surface);
}
.empty h3 { font-size: 15px; color: var(--fg); margin-bottom: 6px; }
.empty p { font-size: 13.5px; margin: 0 auto 14px; max-width: 46ch; }
td .empty, td.empty { border: 0; background: none; padding: 28px; }

/* List row -------------------------------------------------------------- */
.list-row {
  padding: 12px 0; border-bottom: 1px solid var(--border);
  display: flex; justify-content: space-between; gap: 16px; align-items: center;
  font-size: 14px;
}
.list-row:last-child { border-bottom: 0; }
.list-row p { margin: 2px 0; font-size: 13.5px; }

/* Pagination ------------------------------------------------------------ */
.pagination {
  display: flex; gap: 8px; align-items: center; justify-content: center;
  padding: 18px; font-size: 13.5px;
}
.pagination a { text-decoration: none; padding: 6px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.pagination a:hover { background: var(--surface-2); }

/* Progress -------------------------------------------------------------- */
progress {
  width: 100%; height: 8px; display: block; margin: 18px 0 8px;
  border: 0; border-radius: 4px; accent-color: var(--primary); background: var(--surface-3);
}
progress::-webkit-progress-bar { background: var(--surface-3); border-radius: 4px; }
progress::-webkit-progress-value { background: var(--primary); border-radius: 4px; }
.progress-info { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; flex-wrap: wrap; }

/* Dropdown menu. Native <details>, so it works without JavaScript. */
.menu { position: relative; }
.menu > summary { list-style: none; display: inline-flex; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-panel {
  position: absolute; inset-inline-end: 0; top: calc(100% + 6px); z-index: 50;
  min-width: 200px; padding: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.menu-panel a, .menu-panel button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 10px; border-radius: var(--radius-sm);
  font-size: 13.5px; text-decoration: none; color: var(--fg); text-align: start;
}
.menu-panel a:hover, .menu-panel button:hover { background: var(--surface-2); }
.menu-panel hr { margin: 6px 0; }
.menu-panel .label { padding: 6px 10px 4px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--fg-subtle); font-weight: 700; }

/* Avatar ---------------------------------------------------------------- */
.avatar {
  display: inline-grid; place-items: center; flex: none;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-soft-fg);
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
}

/* Environment ribbon ---------------------------------------------------- */
.environment {
  padding: 6px 16px; text-align: center; font-size: 11.5px; letter-spacing: .04em;
  background: var(--warning-soft); color: var(--warning); font-weight: 600;
}
.environment span { padding: 0 8px; }

/* Definition list used on detail pages. */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px 24px; margin: 0; }
.facts > div { min-width: 0; }
.facts dt { font-size: 12px; color: var(--fg-muted); font-weight: 500; margin-bottom: 2px; }
.facts dd { margin: 0; font-size: 14.5px; font-weight: 500; }

.status-list { display: grid; gap: 8px; padding: 0; margin: 0; }
.status-list li { padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); list-style: none; font-size: 13.5px; }

.inline-form { display: inline; }
.inline-form button { padding: 0 10px; min-height: 30px; font-size: 12.5px; }

/* Catalogue tables. A cell here often holds several facts about one row --
   an amount, what it is called, and where the money is taken from -- so it
   needs to stack rather than run on in a line. */
.stack-line { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.stack-line + .stack-line { margin-block-start: 8px; }

/* A form of a few fields inside a card or a table cell. */
.stacked-form { display: flex; flex-direction: column; gap: 6px; align-items: stretch; margin-block-start: 10px; }
.stacked-form label { font-size: 12.5px; font-weight: 600; color: var(--fg-muted); }
/* Only the text-ish controls stretch. A radio or a checkbox that grew to the
   width of its container is how a choice group ends up with its inputs on one
   side of the card and its labels on the other. */
.stacked-form input:not([type=radio]):not([type=checkbox]), .stacked-form select { width: 100%; }
.stacked-form button { align-self: flex-start; margin-block-start: 4px; }

/* An action that is a verb, not a destination: styled as a link because it
   sits among links, but it is a real button inside a real form, so it is
   keyboard reachable and announced as a button. */
/* The selector carries `button[type=submit]` deliberately: the base button
   rule matches on that, so a bare class would lose to it and a quiet action
   would render as a loud green primary button. */
.link-button, button[type=submit].link-button, .inline-form button.link-button {
  display: inline; background: none; border: 0; padding: 0; min-height: 0;
  color: var(--primary); font: inherit; font-size: 13px; font-weight: 600;
  text-decoration: underline; text-underline-offset: 3px; cursor: pointer;
  white-space: normal;
}
.link-button:hover, button[type=submit].link-button:hover { background: none; color: var(--primary-hover); }
.link-button.danger, button[type=submit].link-button.danger { color: var(--danger); }

/* A row that is still true but is not work: a retired price, a membership
   that renews itself. De-emphasised by its surface, never by dimming the
   text.
   `opacity` was the first attempt and it is wrong: it multiplies every
   foreground against the background, so a 4.6:1 label lands at about 3:1 and
   the whole row fails WCAG AA. axe caught it on the renewals screen. The row
   now reads at full contrast and is set back by a tint instead. */
.row-muted th, .row-muted td { background: var(--surface-2); }
.row-muted .cell-sub, .row-muted .muted { color: var(--fg-muted); }

/* A checkbox and its label on one line, for a single yes/no beside a form
   rendered by the field partial. */
.checkbox-line { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; font-weight: 500; }
.checkbox-line input { margin-block-start: 2px; flex: 0 0 auto; }

/* One participant: a name and an age on a line, stacking on a phone. */
/* A filter that sits in a page header rather than above a table. */
.inline-filters { display: flex; gap: 8px; align-items: center; margin: 0; }
.inline-filters label { font-size: 12.5px; font-weight: 600; color: var(--fg-muted); white-space: nowrap; }

.participant-row { display: flex; gap: 10px; margin-block-end: 8px; }
.participant-row input:first-of-type { flex: 1 1 auto; min-width: 0; }
.participant-row input:last-of-type { flex: 0 0 90px; }
@media (max-width: 560px) { .participant-row { flex-wrap: wrap; } .participant-row input:last-of-type { flex: 1 1 100%; } }

.receipt { max-width: 820px; }
.content-text { white-space: pre-line; font-size: 17px; line-height: 1.8; max-width: 72ch; }

/* -- 7  Marketing surfaces ----------------------------------------------- */

.site-header { border-bottom: 1px solid var(--border); background: var(--surface); }
.nav-wrap {
  max-width: var(--page-max); margin: auto; min-height: 72px;
  padding: 14px 24px; display: flex; align-items: center; gap: 28px;
}
.brand {
  display: flex; gap: 10px; align-items: center; font-weight: 650; font-size: 17px;
  text-decoration: none; letter-spacing: -.025em; white-space: nowrap;
}
.brand-logo { height: 26px; width: auto; display: block; }
.site-nav { display: flex; gap: 24px; margin: auto; }
.site-nav a, .nav-actions > a:not(.button) { text-decoration: none; font-size: 14px; font-weight: 500; color: var(--fg-muted); }
.site-nav a:hover, .nav-actions > a:not(.button):hover { color: var(--fg); }
.nav-actions { display: flex; gap: 16px; align-items: center; }

.hero {
  max-width: var(--page-max); margin: auto;
  padding: 64px 24px 56px;
  display: grid; grid-template-columns: 1.1fr 1fr; gap: 56px; align-items: center;
}
.hero h1 { font-size: clamp(2.6rem, 5.2vw, 4.4rem); font-weight: 600; letter-spacing: -.035em; margin-bottom: 20px; }
.hero em { font-family: var(--font-serif); font-style: italic; font-weight: 400; }
.lead { font-size: 17px; line-height: 1.65; max-width: 48ch; color: var(--fg-muted); }
.actions { display: flex; gap: 20px; align-items: center; flex-wrap: wrap; margin-top: 24px; }
.hero-note { display: flex; gap: 12px; align-items: center; margin-top: 36px; font-size: 13px; }
.hero-note p { margin: 0; }
.note-mark { font-size: 30px; color: var(--warm); line-height: 1; }

.hero-figure {
  position: relative; border-radius: var(--radius-xl); overflow: hidden;
  min-height: 460px; background: var(--navy); display: flex; flex-direction: column;
}
.hero-figure img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-figure figcaption {
  position: relative; z-index: 1; margin-top: auto; padding: 26px; color: #fff;
  background: linear-gradient(to top, rgba(8, 18, 36, .94), rgba(8, 18, 36, .5) 60%, rgba(8, 18, 36, 0));
  display: flex; flex-direction: column; gap: 5px;
}
.hero-figure figcaption strong { font-size: 18px; letter-spacing: -.02em; }
.hero-figure figcaption span { font-size: 13px; color: #d7e3f2; }

.photo { display: block; width: 100%; height: 100%; object-fit: cover; }

.section { max-width: var(--page-max); margin: auto; padding: 56px 24px; }
.section-heading, .page-heading {
  display: flex; justify-content: space-between; align-items: flex-end;
  gap: 28px; margin-bottom: 28px; flex-wrap: wrap;
}
.section-heading h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); margin: 0; letter-spacing: -.03em; }
.section-heading > p { font-size: 15px; color: var(--fg-muted); max-width: 42ch; margin: 0; }
.page-heading h1 { font-size: 30px; margin: 0; }

.impact-band {
  background: var(--primary-soft); border-radius: var(--radius-xl); padding: 32px;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 24px;
}
.impact-band div { display: flex; flex-direction: column; gap: 3px; }
.impact-band .figure { font-size: 36px; line-height: 1.1; letter-spacing: -.04em; font-weight: 600; color: var(--primary-soft-fg); }
.impact-band .caption { font-size: 13px; color: var(--fg-muted); }

.program-card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden;
  display: flex; flex-direction: column; text-decoration: none;
}
.program-card .shot { aspect-ratio: 16 / 10; overflow: hidden; background: var(--surface-3); }
.program-card .body { padding: 20px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.program-card h3 { font-size: 18px; margin: 0; }
.program-card p { font-size: 14px; color: var(--fg-muted); margin: 0; }
.program-card .meta { margin-top: auto; padding-top: 12px; font-size: 13px; font-weight: 600; color: var(--primary); }
a.program-card:hover { border-color: var(--primary); }
a.program-card:hover .meta { text-decoration: underline; }

.split { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 44px; align-items: center; }
/* Not .hero-figure's image: that one is absolutely positioned to fill its
   frame, and a max-height left a strip of the frame's background showing
   below it. */
.split > img { border-radius: var(--radius-xl); width: 100%; height: 100%; max-height: 420px; object-fit: cover; }

.benefits { padding: 0; list-style: none; margin: 20px 0; }
.benefits li { padding: 9px 0; border-bottom: 1px solid var(--border); font-size: 14.5px; display: flex; gap: 10px; }
.benefits li::before { content: '✓'; color: var(--success); font-weight: 700; flex: 0 0 auto; }
/* The tick is the only thing that gets its own column; everything after it
   is one flow, so a bold lead-in does not split the sentence in two on a
   phone. */
.benefits li > span { min-width: 0; }

.feature-card { padding: 32px; text-decoration: none; position: relative; border-radius: var(--radius-xl); min-height: 300px; }
.feature-card h3 { font-size: 30px; font-weight: 500; margin-bottom: 14px; }
.feature-card p { font-size: 14.5px; }
.mint { background: var(--primary-soft); }
.yellow { background: var(--gold); color: #2a1e05; }
.circle-arrow { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; border: 1px solid currentColor; position: absolute; inset-inline-end: 26px; bottom: 26px; }

.join-band {
  background: var(--navy); color: #fff;
  padding: 52px max(24px, calc((100vw - var(--page-max)) / 2 + 24px));
  display: flex; justify-content: space-between; align-items: center; gap: 28px; flex-wrap: wrap;
}
.join-band h2 { margin: 0; font-size: clamp(1.7rem, 3vw, 2.4rem); }
.join-band .eyebrow { color: #a9c4e2; }

.plan-card { display: flex; flex-direction: column; }
.plan-card.featured { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.plan-card .plan-prices { margin-top: auto; }
.plan-prices form { padding: 14px 0 0; border-top: 1px solid var(--border); }
.plan-badge {
  display: inline-flex; align-self: flex-start; background: var(--gold); color: #2a1e05;
  border-radius: 20px; padding: 3px 11px; font-size: 11.5px; font-weight: 700;
  letter-spacing: .03em; margin-bottom: 10px;
}
.price { font-size: 32px; letter-spacing: -.035em; margin: 8px 0; font-weight: 600; font-variant-numeric: tabular-nums; }
.price span { font-size: 13px; color: var(--fg-muted); letter-spacing: 0; font-weight: 400; }

.campaign-art { height: 150px; border-radius: var(--radius); overflow: hidden; background: var(--surface-3); margin-bottom: 18px; }
.campaign-art img { width: 100%; height: 100%; object-fit: cover; display: block; }
.campaign-card { display: flex; flex-direction: column; }
.campaign-card .progress-info { margin-top: auto; }

/* Membership highlight card in the member portal. */
.membership-card { background: var(--navy); color: #fff; border: 0; padding: 26px; }
.membership-card p { color: #cfdcec; }
.membership-card h2 { font-size: 26px; margin: 14px 0 10px; color: #fff; }
.membership-card .badge { background: var(--gold); color: #2a1e05; border: 0; }
.membership-card .button.light { color: var(--navy); }
/* The card is navy in both themes, so its buttons carry their own fill rather
   than --surface. With --surface they rendered dark-on-dark in the dark theme
   -- 1.13:1, an invisible button -- and nothing caught it because the browser
   scan only ran in light. Ink on white is 13.9:1 (light) and 15.0:1 (dark). */
.membership-card .button.light { background: #ffffff; }
.membership-card .button.light:hover { background: #e9ede4; }

.dashboard-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 20px; }

/* Programme enrolment --------------------------------------------------- */
.rate-compare { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin: 22px 0; }
.rate {
  border: 1px solid var(--border); border-radius: var(--radius); padding: 16px;
  background: var(--surface); display: flex; flex-direction: column; gap: 3px;
}
.rate.chosen { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); background: var(--primary-soft); }
.rate .label { font-size: 11.5px; letter-spacing: .06em; font-weight: 700; text-transform: uppercase; color: var(--fg-muted); }
.rate.chosen .label { color: var(--primary-soft-fg); }
.rate .figure { font-size: 30px; letter-spacing: -.035em; line-height: 1.15; font-weight: 600; font-variant-numeric: tabular-nums; }
.rate .unit { font-size: 12.5px; color: var(--fg-muted); }
.child-row { display: grid; grid-template-columns: 2fr 1fr; gap: 10px; margin-top: 10px; }
.child-row input { margin: 0; }
.consent { border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; background: var(--primary-soft); margin: 22px 0; }
.consent h3 { margin-bottom: 6px; font-size: 16px; }
.enrollment-card { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; background: var(--surface); margin-top: 12px; }
.enrollment-card .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 14px; flex-wrap: wrap; }

/* Roles ----------------------------------------------------------------- */
.role-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 16px; margin-top: 20px; }
.role-grid .card p { font-size: 13.5px; }
.grant { text-align: center; }
.grant .yes { color: var(--success); font-weight: 700; }
.grant .no { color: var(--fg-subtle); }

/* Footer ---------------------------------------------------------------- */
.site-footer {
  padding: 44px max(24px, calc((100vw - var(--page-max)) / 2 + 24px));
  display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 36px;
  border-top: 1px solid var(--border); font-size: 13px; background: var(--surface);
}
.site-footer > div { display: flex; flex-direction: column; gap: 8px; }
.site-footer strong { font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--fg); }
.site-footer p { margin: 8px 0; color: var(--fg-muted); }
.site-footer a:not(.brand) { color: var(--fg-muted); text-decoration: none; }
.site-footer a:not(.brand):hover { color: var(--fg); text-decoration: underline; }
.site-footer .brand-logo { height: 24px; }


/* Public navigation drawer. A native <details>, open in the markup so the
   links render inline at desktop width (a closed <details> renders nothing,
   whatever CSS says). app.js closes it on a phone; without JavaScript a phone
   simply shows the links as a list, which is the right fallback. */
.nav-drawer { display: contents; }
.nav-drawer > summary { display: none; list-style: none; }
.nav-drawer > summary::-webkit-details-marker { display: none; }
.nav-drawer-actions { display: none; }
.site-nav a[aria-current="page"] { color: var(--fg); font-weight: 600; }
.site-header { position: sticky; top: 0; z-index: 40; background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: blur(8px); }
@supports not (backdrop-filter: blur(1px)) { .site-header { background: var(--surface); } }
.public main { min-height: 50vh; }

.button.large { min-height: 46px; padding: 0 22px; font-size: 15px; }
.hero-copy h1 { max-width: 12ch; }
.impact-band.compact { padding: 22px; margin-bottom: 28px; }
.plan-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.plan-mini { display: flex; flex-direction: column; gap: 6px; text-decoration: none; }
.plan-mini h3 { font-size: 20px; margin: 0; }
.plan-mini .price { margin: 4px 0; }
.plan-mini .meta { margin-top: auto; padding-top: 12px; font-size: 13px; font-weight: 600; color: var(--primary); }
.plan-mini.featured { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.plan-mini.soft { background: var(--primary-soft); border-color: transparent; }
.plan-mini.soft .benefits { margin: 8px 0 0; }
.plan-mini.soft .benefits li { border-bottom-color: color-mix(in srgb, var(--primary) 20%, transparent); }
a.plan-mini:hover { border-color: var(--primary); }
.program-card .body .eyebrow { margin-bottom: 2px; }

.volunteer-band {
  display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: 40px; align-items: center;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-xl); padding: 40px;
}
.volunteer-band img { width: 100%; height: 100%; max-height: 380px; object-fit: cover; border-radius: var(--radius-lg); }
.volunteer-band h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); }

.testimonial {
  margin: 0; padding: 44px 48px; text-align: center;
  background: var(--navy); color: #fff; border-radius: var(--radius-xl);
}
.testimonial p { font-family: var(--font-serif); font-size: clamp(1.3rem, 2.4vw, 1.9rem); line-height: 1.45; max-width: 30ch; margin: 0 auto 14px; }
.testimonial footer { color: #cfe0cc; font-size: 14px; }

.join-band p { color: #cfe0cc; margin: 10px 0 0; max-width: 60ch; }
.join-band .actions { margin: 0; }
.footer-brand .social { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 6px; }
.footer-brand .social a { font-weight: 600; color: var(--fg); }
.footer-language { margin-top: 10px; }
.site-footer { grid-template-columns: 1.4fr 1fr 1fr 1fr; }

/* Article pages: terms, privacy, about, contact. Measure for reading. */
.article-page { padding-top: 40px; }
.article-head { max-width: 72ch; margin-bottom: 28px; }
.article-head h1 { font-size: clamp(1.9rem, 3.4vw, 2.8rem); letter-spacing: -.03em; }
.article-meta { font-size: 13px; }
.article-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 40px; align-items: start; }
.article-body { max-width: 72ch; font-size: 16.5px; line-height: 1.75; }
.article-body h2 { font-size: 22px; margin: 32px 0 10px; }
.article-body h2:first-child { margin-top: 0; }
.article-body h3 { font-size: 17px; margin: 22px 0 8px; }
.article-body ul { padding-inline-start: 22px; }
.article-body li { margin-bottom: 6px; }
.article-aside { position: sticky; top: 90px; }
.article-aside .card h3 { font-size: 15px; margin-bottom: 8px; }
.facts.stacked { grid-template-columns: 1fr; gap: 10px; }
.social.spaced { display: flex; gap: 8px; flex-wrap: wrap; }
.form-shell.wide { max-width: 760px; margin-inline: 0; }

/* Provider chips on the integrations page and the dashboard. */
.provider-strip { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
.provider-strip.compact { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.provider-chip {
  display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; text-decoration: none;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); font-size: 14px; font-weight: 600; min-width: 0;
}
.provider-chip:hover { border-color: var(--border-strong); }
.provider-chip.current { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary); }
.provider-chip .cell-sub { font-weight: 500; }
.status-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; margin-bottom: 4px; background: var(--border-strong); }
.status-dot.ok { background: var(--success); }
.status-dot.bad { background: var(--danger); }
.status-dot.untested { background: var(--warning); }
.integration-layout { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
a.badge { text-decoration: none; }

/* Cohort table: lightness carries the level, the number carries the value. */
.cohort th, .cohort td { padding: 7px 10px; font-size: 13px; }
.cohort-cell[data-level="5"] { background: color-mix(in srgb, var(--chart-1) 60%, var(--surface)); }
.cohort-cell[data-level="4"] { background: color-mix(in srgb, var(--chart-1) 45%, var(--surface)); }
.cohort-cell[data-level="3"] { background: color-mix(in srgb, var(--chart-1) 30%, var(--surface)); }
.cohort-cell[data-level="2"] { background: color-mix(in srgb, var(--chart-1) 18%, var(--surface)); }
.cohort-cell[data-level="1"] { background: color-mix(in srgb, var(--chart-1) 8%, var(--surface)); }
.metric .value small { font-size: 14px; font-weight: 500; color: var(--fg-muted); letter-spacing: 0; }


/* -- 7b  Membership: applying, leaving, belonging ------------------------ */

/* Facts inside the dark membership panel. */
.card-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px 20px; margin: 16px 0; }
/* Colours, not opacity. These three all live inside the dark membership panel
   and were faded with `opacity`, which multiplies the foreground against
   whatever is behind it and takes a compliant colour below AA. They read at
   full strength now and are set back by their own token, which is measured.
   See tests/test_design_tokens.py. */
.card-facts dt { font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--fg-muted); margin-bottom: 2px; }
.card-facts dd { margin: 0; font-size: 15px; font-weight: 600; }
.member-number { font-size: 12px; letter-spacing: .08em; font-variant-numeric: tabular-nums; color: var(--fg-muted); }
.fine { font-size: 12.5px; color: var(--fg-muted); }
/* On the navy panel the muted token would be dark on dark, so the panel
   states its own. #cfdcec measures 9.97:1 against --navy. */
.membership-card .card-facts dt,
.membership-card .member-number,
.membership-card .fine { color: #cfdcec; }

/* What is left to set up. A list that disappears when it is done. */
.checklist { list-style: none; counter-reset: step; margin: 0; padding: 0; }
.checklist li { counter-increment: step; border-bottom: 1px solid var(--border); }
.checklist li:last-child { border-bottom: 0; }
.checklist a {
  display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 12px; align-items: baseline;
  padding: 11px 0; text-decoration: none; color: var(--fg);
}
.checklist a::before {
  content: counter(step); grid-row: span 2; align-self: center;
  display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-soft-fg); font-size: 12px; font-weight: 700;
}
.checklist a:hover strong { color: var(--primary); text-decoration: underline; }
.checklist .cell-sub { grid-column: 2; }

.list-row.unread { border-inline-start: 3px solid var(--primary); padding-inline-start: 12px; }
.recommend-card { background: var(--primary-soft); border-color: transparent; }
.recommend-card h3, .recommend-card p { color: var(--primary-soft-fg); }

/* Application progress. Four states, in order, no cleverness. */
.progress-steps { list-style: none; margin: 18px 0; padding: 0; display: grid; gap: 2px; }
.progress-steps li {
  display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 12px; align-items: center;
  padding: 11px 0; border-bottom: 1px solid var(--border); font-size: 14px;
}
.progress-steps li:last-child { border-bottom: 0; }
.progress-steps li::before {
  content: ''; width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--border-strong); justify-self: center;
}
.progress-steps li.done::before { background: var(--success); border-color: var(--success); }
.progress-steps li.failed::before { background: var(--danger); border-color: var(--danger); }
.progress-steps li span { color: var(--fg-muted); font-size: 13px; }
.notice.success { border-inline-start-color: var(--success); background: var(--success-soft); }

blockquote.sample { margin: 0; padding: 16px 18px; background: var(--surface-2); border-radius: var(--radius); font-size: 13.5px; }
blockquote.sample p { margin: 0 0 8px; }
blockquote.sample p:last-child { margin-bottom: 0; }
code.copyable { user-select: all; word-break: break-all; font-size: 11.5px; }

/* Member directory */
.directory-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; }
.person-card { display: flex; gap: 14px; align-items: flex-start; }
.person-card p { margin: 6px 0 0; font-size: 13.5px; }
.avatar.large { width: 44px; height: 44px; font-size: 15px; }
.contact-lines { display: flex; flex-direction: column; gap: 2px; font-size: 13px; }

/* The membership card itself. Printable, and readable at arm's length. */
.member-card-wrap { display: grid; grid-template-columns: minmax(0, 420px) minmax(0, 1fr); gap: 20px; align-items: start; }
.member-card {
  background: linear-gradient(145deg, var(--navy), color-mix(in srgb, var(--navy) 70%, var(--primary)));
  color: #fff; border-radius: var(--radius-xl); padding: 24px; box-shadow: var(--shadow-lg);
  aspect-ratio: 1.586; display: flex; flex-direction: column;
}
.member-card-top { display: flex; justify-content: space-between; align-items: flex-start; }
.member-card-top .badge { background: var(--gold); color: #2a1e05; border: 0; }
.member-card-name { font-size: 24px; font-weight: 650; letter-spacing: -.02em; margin: 18px 0 2px; }
.member-card-plan { margin: 0; color: #cfe0cc; font-size: 14px; }
.member-card-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: auto 0 0; }
.member-card-facts dt { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: #a9c4a5; margin-bottom: 2px; }
.member-card-facts dd { margin: 0; font-size: 13.5px; font-weight: 600; }
.member-card-foot { margin: 14px 0 0; font-size: 11.5px; color: #a9c4a5; }

/* A recommended visitor's landing page */
.referral-hero { padding-top: 40px; }
.referral-note {
  margin: 0 0 20px; padding: 14px 18px; border-inline-start: 3px solid var(--primary);
  background: var(--primary-soft); border-radius: var(--radius); font-family: var(--font-serif);
}
.referral-note p { margin: 0 0 6px; font-size: 17px; font-style: italic; color: var(--primary-soft-fg); }
.referral-note footer { font-size: 13px; font-style: normal; color: var(--fg-muted); }

/* Approvals queue */
.approval-row + .approval-row { margin-top: 14px; }
.approval-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; flex-wrap: wrap; margin-bottom: 14px; }
.approval-head h3 { margin: 6px 0 2px; font-size: 18px; }
.approval-head h3 a { text-decoration: none; color: var(--fg); }
.approval-head h3 a:hover { color: var(--primary); text-decoration: underline; }
.approval-head p { margin: 0; font-size: 13.5px; }
.approval-meta { text-align: end; display: flex; flex-direction: column; gap: 4px; align-items: flex-end; }
.quote-block { margin: 14px 0; padding: 12px 16px; background: var(--surface-2); border-radius: var(--radius); }
.quote-block .label { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--fg-subtle); font-weight: 700; margin: 0 0 4px; }
.quote-block p:last-child { margin: 0; font-size: 14px; }
.decision { margin: 16px 0 0; }
.decision > summary { display: inline-flex; list-style: none; }
.decision > summary::-webkit-details-marker { display: none; }
.decision-form { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border); }
.card.quiet { background: var(--surface-2); }

/* Door check */
.verify-result { display: flex; gap: 20px; align-items: flex-start; margin-top: 18px; border-width: 2px; }
.verify-result.good { border-color: var(--success); }
.verify-result.bad { border-color: var(--danger); }
.verify-mark { font-size: 40px; line-height: 1; width: 64px; height: 64px; display: grid; place-items: center; border-radius: 50%; flex: none; }
.verify-result.good .verify-mark { background: var(--success-soft); color: var(--success); }
.verify-result.bad .verify-mark { background: var(--danger-soft); color: var(--danger); }
.verify-result h2 { margin: 0 0 4px; font-size: 22px; }
.verify-state { font-weight: 600; margin: 0 0 14px; }


/* -- 7c  Editable prose, and the editor that produces it ----------------- */

/* Rendered markup. Everything here is produced by core/richtext.py, so the
   selectors are element-level on purpose: the writer picks the words, the
   stylesheet picks how they look, and neither can reach into the other. */
.rich-body > :first-child { margin-top: 0; }
.rich-body > :last-child { margin-bottom: 0; }
.rich-body p { font-size: 14.5px; line-height: 1.65; }
.rich-body h2 { font-size: 20px; margin: 26px 0 10px; }
.rich-body h3 { font-size: 16px; margin: 20px 0 8px; }
.rich-body ul, .rich-body ol { padding-inline-start: 0; margin: 0 0 14px; list-style: none; }
.rich-body li { padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 14.5px; display: flex; gap: 10px; }
.rich-body li:last-child { border-bottom: 0; }
.rich-body ul > li::before { content: '✓'; color: var(--success); font-weight: 700; flex: none; }
.rich-body ol { counter-reset: rich; }
.rich-body ol > li { counter-increment: rich; }
.rich-body ol > li::before { content: counter(rich) '.'; color: var(--fg-muted); font-weight: 700; flex: none; }
.rich-body blockquote { margin: 0 0 16px; padding-inline-start: 14px; border-inline-start: 3px solid var(--primary); color: var(--fg-muted); }
.rich-body .notice { margin: 0 0 16px; }
.rich-image { display: block; width: 100%; height: auto; border-radius: var(--radius); margin: 0 0 16px; }
.rich-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; margin: 0 0 16px; }
.article-body.rich-body p { font-size: 16.5px; line-height: 1.75; }
.article-body.rich-body li { font-size: 16px; }
blockquote.sample .rich-body, blockquote.sample p { font-size: 13.5px; }
blockquote.sample h2, blockquote.sample h3 { font-size: 15px; margin: 12px 0 6px; }
blockquote.sample .button { pointer-events: none; }

/* The editing screen: an index of what can be changed, and one editor. */
.content-layout { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 24px; align-items: start; }
.content-index { position: sticky; top: 88px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 12px 10px; max-height: calc(100vh - 120px); overflow-y: auto; }
.content-index .sidebar-group + .sidebar-group { margin-top: 14px; }
.content-index a {
  display: flex; align-items: center; gap: 8px; justify-content: space-between;
  padding: 7px 10px; border-radius: var(--radius-sm); text-decoration: none;
  font-size: 13.5px; color: var(--fg-muted); line-height: 1.35;
}
.content-index a:hover { background: var(--surface-2); color: var(--fg); }
.content-index a[aria-current="page"] { background: var(--primary-soft); color: var(--primary-soft-fg); font-weight: 600; }
.content-index .badge { font-size: 10px; padding: 1px 6px; }

.editor-toolbar { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; padding: 8px; background: var(--surface-2); border: 1px solid var(--border); border-bottom: 0; border-radius: var(--radius) var(--radius) 0 0; }
.editor-toolbar button {
  min-height: 30px; padding: 0 10px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border); color: var(--fg);
  font-size: 12.5px; font-weight: 600;
}
.editor-toolbar button:hover { background: var(--primary-soft); color: var(--primary-soft-fg); border-color: var(--primary); }
.editor-sep { width: 1px; height: 20px; background: var(--border-strong); margin: 0 4px; }
.editor-area {
  font-family: var(--font-mono); font-size: 13.5px; line-height: 1.7;
  border-radius: 0 0 var(--radius) var(--radius); min-height: 280px;
}
.editor-card .field { margin-bottom: 14px; }
.rich-preview { border: 1px dashed var(--border-strong); border-radius: var(--radius); padding: 20px; background: var(--bg); }

/* What happened to one invitation. */
.journey { list-style: none; margin: 14px 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.journey li {
  display: flex; flex-direction: column; gap: 1px; padding: 7px 12px;
  background: var(--surface-2); border-radius: var(--radius-sm); font-size: 12.5px;
}
.journey li strong { font-size: 12.5px; }
.journey li span { color: var(--fg-subtle); font-size: 11.5px; }
.journey li.joined { background: var(--success-soft); color: var(--success); }
.journey li.declined { background: var(--surface-3); color: var(--fg-muted); }
.journey li.failed, .journey li.unconfigured { background: var(--warning-soft); color: var(--warning); }
.referral-row + .referral-row { margin-top: 12px; }
.referral-row h3 { font-size: 16px; margin: 0 0 2px; }
.referral-row code.copyable { display: inline-block; margin-top: 4px; }

/* -- 8  Charts ----------------------------------------------------------- */
/* Server-rendered inline SVG. Colour is never the only carrier of meaning:
   every chart ships a legend, direct labels and a table view. */
.chart { margin: 0; }
.chart figcaption h3 { margin: 0 0 4px; font-size: 15px; }
.chart figcaption p { font-size: 13px; margin: 0 0 14px; max-width: 62ch; color: var(--fg-muted); }
.chart-svg { width: 100%; height: auto; display: block; overflow: visible; }
.gridline { stroke: var(--border); stroke-width: 1; }
.axisline { stroke: var(--border-strong); stroke-width: 1; }
.axis-label { font-size: 11px; fill: var(--fg-muted); }
.bar-value { font-size: 11px; fill: var(--fg); font-weight: 600; }
.legend { display: flex; gap: 18px; flex-wrap: wrap; margin: 0 0 12px; font-size: 13px; color: var(--fg-muted); }
.legend .key { display: inline-flex; align-items: center; gap: 7px; }
.legend .swatch { width: 11px; height: 11px; border-radius: 3px; display: inline-block; flex: none; }
.chart-data { margin-top: 14px; }
.chart-data summary { font-size: 13.5px; font-weight: 600; color: var(--fg-muted); }
.chart-data .table-wrap { margin-top: 10px; }
.bar-table { width: 100%; font-size: 13.5px; min-width: 0; }
.bar-table td, .bar-table th { padding: 9px 14px; }
.bar-cell { display: flex; align-items: center; gap: 12px; min-width: 160px; }
.bar-cell .bar { height: 10px; border-radius: 3px; background: var(--primary); min-width: 4px; max-width: 100%; flex: 0 1 auto; }
.chart-bar { height: 12px; border-radius: 3px; background: var(--primary); max-width: 100%; min-width: 4px; }

/* -- 9  Responsive ------------------------------------------------------- */

@media (max-width: 1100px) {
  .content-layout { grid-template-columns: minmax(0, 1fr); }
  .content-index { position: static; max-height: none; }
  .member-card-wrap { grid-template-columns: minmax(0, 1fr); }
  .provider-strip, .provider-strip.compact { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .plan-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .article-layout { grid-template-columns: minmax(0, 1fr); }
  .article-aside { position: static; }
  .volunteer-band { grid-template-columns: minmax(0, 1fr); padding: 28px; }
  .integration-layout { grid-template-columns: minmax(0, 1fr); }
  .site-footer { grid-template-columns: 1fr 1fr; }
  .metric-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dashboard-grid { grid-template-columns: minmax(0, 1fr); }
  .impact-band { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 24px; }
  .split { grid-template-columns: minmax(0, 1fr); gap: 24px; }
  .three-grid, .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  /* Shell collapses: the sidebar becomes a panel the top bar opens. */
  .app { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 60; width: 280px;
    transform: translateX(-100%); transition: transform .18s ease;
    box-shadow: var(--shadow-lg);
  }
  .app[data-nav="open"] .sidebar { transform: none; }
  .app[data-nav="open"]::after {
    content: ''; position: fixed; inset: 0; z-index: 55; background: var(--overlay);
  }
  .sidebar-toggle { display: inline-flex; }
  .app-body { padding: 18px 16px 56px; }
  .topbar { padding: 8px 16px; }
}

@media (max-width: 760px) {
  .nav-wrap { gap: 10px; padding: 10px 16px; min-height: 0; }
  .nav-drawer { display: block; order: 3; margin-inline-start: auto; position: static; }
  .nav-drawer > summary {
    display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
    border-radius: var(--radius-sm); border: 1px solid var(--border-strong); cursor: pointer;
  }
  .nav-drawer > summary svg { width: 20px; height: 20px; }
  .nav-drawer > summary .close { display: none; }
  .nav-drawer[open] > summary .close { display: block; }
  .nav-drawer[open] > summary svg:not(.close) { display: none; }
  .nav-drawer .site-nav {
    position: absolute; inset-inline: 0; top: 100%; display: flex; flex-direction: column; gap: 0;
    background: var(--surface); border-bottom: 1px solid var(--border); box-shadow: var(--shadow-lg);
    padding: 8px 16px 16px; margin: 0;
  }
  .nav-drawer .site-nav a { padding: 12px 4px; border-bottom: 1px solid var(--border); font-size: 16px; color: var(--fg); }
  .nav-drawer-actions { display: flex; flex-direction: column; margin-top: 6px; }
  .nav-actions { gap: 10px; }
  .nav-actions > a:not(.button) { display: none; }
  .site-header { position: relative; }
  .plan-strip, .provider-strip, .provider-strip.compact { grid-template-columns: minmax(0, 1fr); }
  .provider-strip.compact { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .testimonial { padding: 28px 20px; }
  .article-page { padding-top: 24px; }
  .form-shell.wide { margin-inline: 0; }
  .site-footer { grid-template-columns: 1fr; }
  .hero { grid-template-columns: 1fr; padding: 32px 16px; gap: 28px; }
  .hero-figure { min-height: 300px; }
  .section { padding: 36px 16px; }
  .container { padding: 24px 16px 56px; }
  .section-heading, .page-heading { flex-direction: column; align-items: flex-start; gap: 14px; }
  .two-grid, .three-grid, .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); }
  .metric-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .metric { padding: 13px 14px; }
  .metric .value { font-size: 23px; }
  .impact-band { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; padding: 20px; }
  .impact-band .figure { font-size: 28px; }
  .join-band { padding: 36px 16px; align-items: flex-start; }
  .site-footer { grid-template-columns: 1fr; padding: 32px 16px; gap: 24px; }
  .form-shell, .account-shell { margin: 24px 16px 48px; padding: 20px; }
  .messages { padding: 0 16px; }
  .rate-compare { grid-template-columns: minmax(0, 1fr); }
  .child-row { grid-template-columns: 1fr; }
  .feature-card { padding: 24px; min-height: 260px; }
  .feature-card h3 { font-size: 26px; }
  .page-head h1 { font-size: 22px; }
  .list-row { flex-wrap: wrap; }
  .member-card { aspect-ratio: auto; padding: 20px; }
  .rich-columns { grid-template-columns: minmax(0, 1fr); }
  .editor-toolbar { gap: 3px; padding: 6px; }
  .editor-toolbar button { padding: 0 8px; font-size: 12px; }
  .member-card-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .approval-meta { text-align: start; align-items: flex-start; }
  .verify-result { flex-direction: column; gap: 14px; }
  .directory-grid { grid-template-columns: minmax(0, 1fr); }
  .progress-steps li { grid-template-columns: 22px minmax(0, 1fr); }
  .progress-steps li span { grid-column: 2; }
  .bar-cell { min-width: 90px; }
  .bar-table td, .bar-table th { padding: 8px 10px; }
  th, td { padding-inline-start: 12px; padding-inline-end: 12px; }
}

/* -- 10  Print ----------------------------------------------------------- */

@media print {
  .member-card { box-shadow: none; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .environment, .site-header, .sidebar, .topbar, .site-footer,
  .actions, .filters, .toolbar, .page-head-actions, .row-actions { display: none !important; }
  body { background: #fff; }
  .app { display: block; }
  .app-body, .container { padding: 0; max-width: none; }
  .card, .metric { break-inside: avoid; border-color: #ccc; }
  .chart-data[open] summary { display: none; }
  .chart-data { display: block; }
}

/* Development-phase version banner. Public, deliberately: during development
   the owner needs to confirm at a glance which build is live without signing
   in. Removed before launch by one setting -- see SHOW_VERSION_BANNER. */
.version-banner {
  background: var(--navy);
  color: #fff;
  font-size: 12.5px;
  padding: 8px max(16px, calc((100vw - var(--page-max)) / 2 + 24px));
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.version-banner strong { font-weight: 650; }
.version-banner span { color: #cfe0cc; }
.version-banner code {
  background: rgba(255, 255, 255, .14);
  color: #fff;
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 11.5px;
}
.version-banner details { margin: 0; margin-inline-start: auto; }
.version-banner summary { font-size: 12.5px; font-weight: 600; color: #fff; }
.version-banner details[open] { flex: 1 1 100%; margin-inline-start: 0; }
.version-banner ul { margin: 10px 0 0; padding-inline-start: 20px; color: #dbe8d8; }
.version-banner li { margin-bottom: 5px; }
.version-banner details p { margin: 10px 0 0; color: #a9c4a5; font-size: 12px; }

/* Schedule: a month-grouped agenda rather than a calendar grid.
   A grid is what people picture and an agenda is what they can actually read
   on a phone -- a seven-column month view either overflows or shrinks each day
   to a dot. Logical properties throughout so it mirrors under right-to-left. */
.schedule-month {
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 28px 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.schedule { list-style: none; margin: 0; padding: 0; }
.schedule-row {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  padding: 16px 0;
  border-bottom: 1px solid var(--border);
}
.schedule-row:last-child { border-bottom: 0; }
.schedule-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: var(--primary-soft);
  color: var(--primary-soft-fg);
  border-radius: var(--radius);
  padding: 8px 4px;
  min-height: 58px;
}
.schedule-date .day { font-size: 22px; font-weight: 650; line-height: 1.1; font-variant-numeric: tabular-nums; }
.schedule-date .weekday { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; }
.schedule-body h4 { font-size: 16px; margin: 0 0 4px; }
.schedule-body h4 a { text-decoration: none; color: var(--fg); }
.schedule-body h4 a:hover { color: var(--primary); text-decoration: underline; }
.schedule-body p { font-size: 13.5px; margin: 0; }
.schedule-body p + p { margin-top: 4px; }
.schedule-status { justify-self: end; }

@media (max-width: 760px) {
  .schedule-row { grid-template-columns: 52px minmax(0, 1fr); gap: 14px; }
  .schedule-status { grid-column: 2; justify-self: start; margin-top: 6px; }
}

/* -- 11  Right to left ---------------------------------------------------- */
/*
   Almost nothing is needed here, and that is the point. The layout above uses
   logical properties (margin-inline-start rather than margin-left, inset-inline
   -end rather than right, text-align: start rather than left), so setting
   dir="rtl" on <html> mirrors the whole interface without a parallel
   stylesheet. This section covers only the things logical properties cannot:

     1. Type. Persian needs a font stack that actually has the glyphs, and a
        little more line height -- Arabic-script letterforms have taller
        ascenders and deeper descenders than Latin ones, so the default leading
        reads cramped.
     2. Characters whose meaning is directional. An arrow pointing "forward"
        points left in a right-to-left interface.
     3. Anything positioned with a transform, which is geometry, not layout, and
        does not mirror.
*/

:root[dir="rtl"] {
  /* Vazirmatn and IRANSans are the common Persian web faces; Tahoma is the one
     almost every machine already has and renders Persian acceptably. No web
     font is fetched: the Content-Security-Policy permits no external origins,
     and a family on a slow connection should not wait for a typeface. */
  --font: 'Vazirmatn', 'IRANSans', 'Segoe UI', Tahoma, 'Noto Naskh Arabic', 'Geeza Pro', Arial, sans-serif;
}

:root[dir="rtl"] body { line-height: 1.85; }
:root[dir="rtl"] h1,
:root[dir="rtl"] h2,
:root[dir="rtl"] h3,
:root[dir="rtl"] h4 { line-height: 1.5; letter-spacing: 0; }

/* Latin letter-spacing on Persian text separates letters that must join. */
:root[dir="rtl"] .eyebrow,
:root[dir="rtl"] thead th,
:root[dir="rtl"] .sidebar-group > h2,
:root[dir="rtl"] .schedule-month,
:root[dir="rtl"] .rate .label,
:root[dir="rtl"] .site-footer strong { letter-spacing: 0; }

/* A decorative arrow points the way the reader is going. */
:root[dir="rtl"] .arrow { display: inline-block; transform: scaleX(-1); }

/* Transforms are geometry and do not mirror on their own. */
:root[dir="rtl"] .search svg { transform: translateY(-50%) scaleX(-1); }
/* Only where the sidebar is a drawer (900px and below). Unscoped, it pushed
   the permanent desktop sidebar off the screen in Farsi. */
@media (max-width: 900px) {
  :root[dir="rtl"] .sidebar { transform: translateX(100%); }
  :root[dir="rtl"] .app[data-nav="open"] .sidebar { transform: none; }
}

/* Numbers, money, dates and identifiers stay left-to-right inside Persian text.
   Without this a price renders as 00.25 and a commit hash reverses. */
:root[dir="rtl"] .num,
:root[dir="rtl"] .price,
:root[dir="rtl"] .metric .value,
:root[dir="rtl"] .schedule-date .day,
:root[dir="rtl"] .rate .figure,
:root[dir="rtl"] code,
:root[dir="rtl"] time { direction: ltr; unicode-bidi: isolate; }

/* A table of numbers reads right-aligned in both directions; `end` would flip
   it to the wrong side of the column under RTL. */
:root[dir="rtl"] td.num,
:root[dir="rtl"] th.num { text-align: left; }

.language-switch { display: flex; gap: 4px; align-items: center; }
.language-switch button {
  /* Explicitly not a submit button's fill. These are submit buttons -- the
     switcher posts -- so without this they inherit the primary background and
     the muted label becomes dark green on dark green. */
  background: transparent;
  border: 1px solid transparent;
  min-height: 0;
  font-size: 13px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: var(--radius-sm);
  color: var(--fg-muted);
}
.language-switch button:hover { background: var(--surface-2); color: var(--fg); }
.language-switch button[aria-current="true"] { background: var(--primary-soft); color: var(--primary-soft-fg); }

/* -- Timeline -------------------------------------------------------------
   Everything that happened with one person, assembled from the records that
   already describe it. The rail is drawn with a border on the list rather
   than a pseudo-element per row, so it cannot drift out of step with the
   markers on a long list. */
.timeline { list-style: none; margin: 16px 0 0; padding: 0 0 0 4px; border-inline-start: 2px solid var(--border); }
.timeline-entry { position: relative; display: flex; gap: 16px; padding: 10px 0 10px 22px; }
.timeline-entry::before {
  content: ''; position: absolute; inset-inline-start: -7px; top: 17px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--fg-subtle);
}
.timeline-entry.kind-money::before { border-color: var(--success); }
.timeline-entry.kind-membership::before { border-color: var(--primary); }
.timeline-entry.kind-decision::before { border-color: var(--warning); }
.timeline-entry.kind-staff::before { border-color: var(--fg-muted); }
.timeline-when { flex: 0 0 96px; display: flex; flex-direction: column; font-size: 12.5px; color: var(--fg-muted); }
.timeline-when span { font-size: 11.5px; }
.timeline-what { display: flex; flex-direction: column; gap: 2px; min-width: 0; font-size: 14px; }
.timeline-what .muted { font-size: 13px; overflow-wrap: anywhere; }
@media (max-width: 560px) {
  .timeline-entry { flex-direction: column; gap: 2px; }
  .timeline-when { flex-direction: row; gap: 6px; }
}

/* -- Ticketing ------------------------------------------------------------
   Buying, holding and scanning a ticket. Three surfaces, one of which is
   used standing up at a door with a queue in front of you. */

.ticket-types { display: flex; flex-direction: column; gap: 10px; margin: 16px 0; }
.ticket-type {
  display: flex; gap: 16px; align-items: center; justify-content: space-between;
  padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface);
}
.ticket-type.unavailable { background: var(--surface-2); }
.ticket-type-what { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ticket-type-qty input { width: 84px; text-align: center; }
@media (max-width: 560px) { .ticket-type { flex-wrap: wrap; } }

/* The order total. A table, because it is one. */
.totals { width: 100%; border-collapse: collapse; margin-block-start: 8px; }
.totals th, .totals td { padding: 8px 0; text-align: start; font-weight: 500; border-bottom: 1px solid var(--border); }
.totals .num { text-align: end; font-variant-numeric: tabular-nums; }
.totals .discount-row th, .totals .discount-row td { color: var(--success); }
.totals .total-row th, .totals .total-row td { border-bottom: 0; font-weight: 700; font-size: 16px; }

/* The wallet: one card per admission, each with its own code. */
.ticket-wallet { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 16px; margin: 16px 0; }
.eticket {
  display: flex; gap: 14px; align-items: center; padding: 14px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
}
.eticket.used { background: var(--surface-2); }
.eticket-qr { flex: 0 0 96px; }
.eticket-qr svg { width: 96px; height: 96px; display: block; }
.eticket-what { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ticket-code { font-size: 11px; overflow-wrap: anywhere; color: var(--fg-muted); }

/* The door. Large targets, one field, one verdict you can read at arm's length. */
.door-form { display: flex; flex-direction: column; gap: 8px; max-width: 560px; margin-block-end: 20px; }
.door-form input { font-size: 18px; min-height: 52px; }
.door-form button { min-height: 52px; font-size: 16px; }
.door-result { padding: 18px; border-radius: var(--radius); border: 2px solid var(--border); margin-block-end: 20px; }
.door-result.ok { border-color: var(--success); background: var(--success-soft); }
.door-result.no, .door-result.wrong { border-color: var(--danger); background: var(--danger-soft); }
.door-result.order, .door-result.undone { border-color: var(--warning); background: var(--warning-soft); }
.door-verdict { font-size: 22px; font-weight: 700; margin: 0; }
.door-detail { margin: 6px 0 0; font-size: 14px; }
.door-tickets { margin: 10px 0 0; padding-inline-start: 18px; font-size: 14px; }
.door-tickets li { padding: 3px 0; }

/* The confirmation page (core/confirm.html). One job: make the consequence
   impossible to miss before the button is reachable. The verb sits last, after
   the facts, because that is the order somebody reads in -- and the primary
   action is `danger`, so the colour agrees with the words. */
.confirm-shell { max-width: 640px; }
.confirm-lede { font-size: 16px; color: var(--fg); margin-block: 0 16px; }
.confirm-subhead { font-size: 15px; text-transform: uppercase; letter-spacing: .04em; color: var(--fg-muted); margin-block: 22px 8px; }
.confirm-facts { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; margin: 0; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.confirm-facts dt { padding: 10px 14px 2px; font-size: 13px; color: var(--fg-muted); background: var(--surface-2); }
.confirm-facts dd { margin: 0; padding: 2px 14px 10px; font-size: 15px; font-weight: 600; background: var(--surface-2); }
@media (min-width: 560px) {
  .confirm-facts { grid-template-columns: minmax(0, 40%) minmax(0, 1fr); }
  .confirm-facts dt { padding: 10px 14px; }
  .confirm-facts dd { padding: 10px 14px; }
}
.confirm-extra { margin: 14px 0 0; padding-inline-start: 18px; font-size: 14px; }
.confirm-extra li { padding: 3px 0; }
.confirm-form { margin-block-start: 22px; }
.confirm-phrase code { font-size: 14px; padding: 1px 5px; border-radius: var(--radius-sm); background: var(--surface-2); }
.confirm-actions { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-block-start: 18px; }

/* Stripe reference health, on Staff → Synchronisation. The summary line carries
   the verdict; the tables carry the objects. "warn" and "bad" are separate
   because a stale reference and a blocked checkout are different jobs. */
.health-head { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-start; justify-content: space-between; margin-block-end: 8px; }
.health-head > div { flex: 1 1 320px; min-width: 0; }
.health-summary { margin: 0; font-size: 15px; font-weight: 600; }
.health-summary.good { color: var(--success); }
.health-summary.warn { color: var(--warning); }
.health-summary.bad { color: var(--danger); }
.health-meta { margin: 4px 0 0; font-size: 13px; color: var(--fg-muted); }
.health-group { font-size: 14px; margin-block: 16px 6px; }
.health-group.bad { color: var(--danger); }

/* -- 8  Wayfinding and dashboards ---------------------------------------- */

/* Every colour pair below is one tests/test_design_tokens.py already
   measures in both themes; no new pairing was introduced here. */

.h3 { font-size: 16px; margin: 0 0 4px; }

/* Jump-to filter at the top of the staff sidebar. Shown by app.js. */
.sidebar-jump {
  position: relative; margin: 12px 10px 0; flex: none;
}
.sidebar-jump svg {
  position: absolute; inset-inline-start: 10px; top: 50%; width: 15px; height: 15px;
  transform: translateY(-50%); color: var(--fg-muted); pointer-events: none;
}
.sidebar-jump input[type=search] {
  min-height: 34px; font-size: 13.5px; padding-inline: 32px 34px; background: var(--bg);
}
.sidebar-jump kbd {
  position: absolute; inset-inline-end: 8px; top: 50%; transform: translateY(-50%);
  font: 600 11px/1 var(--font-mono, ui-monospace, monospace); color: var(--fg-muted);
  border: 1px solid var(--border-strong); border-radius: 4px; padding: 3px 6px; background: var(--surface);
}
.sidebar-nav a[hidden], .sidebar-group[hidden], .sidebar-empty[hidden] { display: none; }
.sidebar-empty { font-size: 13px; color: var(--fg-muted); padding: 4px 10px; margin: 0; }

/* Foldable groups: the heading is the control. */
details.sidebar-group > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between;
  border-radius: var(--radius-sm); padding-inline-end: 8px;
}
details.sidebar-group > summary::-webkit-details-marker { display: none; }
details.sidebar-group > summary h2 {
  font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--fg-subtle); font-weight: 700; margin: 0; padding: 6px 10px;
}
details.sidebar-group > summary:hover { background: var(--surface-2); }
details.sidebar-group > summary:hover h2 { color: var(--fg-muted); }
details.sidebar-group > summary .chevron { width: 14px; height: 14px; color: var(--fg-muted); transition: transform .15s ease; }
details.sidebar-group[open] > summary .chevron { transform: rotate(180deg); }
details.sidebar-group[open] > summary { margin-bottom: 4px; }
.sidebar-nav .nav-label { min-width: 0; }
.sidebar-nav .count.attention { background: var(--primary); color: var(--primary-fg); font-weight: 700; }

/* Breadcrumb in the top bar. */
.crumbs { display: flex; align-items: center; gap: 8px; font-weight: 500; }
.crumbs > * { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crumbs > * + *::before { content: '/'; margin-inline-end: 8px; color: var(--fg-subtle); font-weight: 400; }
.crumbs .crumb-group { color: var(--fg-muted); flex: none; }
.crumbs a { color: var(--fg-muted); text-decoration: none; }
.crumbs a:hover { color: var(--fg); text-decoration: underline; }
.crumbs [aria-current] { color: var(--fg); font-weight: 600; }

.sidebar-foot { display: flex; flex-direction: column; gap: 6px; }

/* Dashboards. Cards size to their content; the member card no longer
   stretches to match a taller neighbour and become an empty dark slab. */
.dashboard-grid { align-items: start; }

/* Quick actions: one tap to the jobs people come for. */
.section-title { font-size: 18px; margin: 0 0 12px; letter-spacing: -.01em; }
.section-title.spaced { margin-top: 32px; }
.quick-actions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.quick-actions.compact { grid-template-columns: minmax(0, 1fr); gap: 6px; }
.quick-action {
  display: flex; align-items: center; gap: 12px; padding: 12px;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface);
  color: var(--fg); text-decoration: none; min-height: 56px;
  transition: border-color .12s ease, background .12s ease;
}
.quick-actions.compact .quick-action { padding: 9px 12px; min-height: 44px; }
.quick-action:hover { border-color: var(--border-strong); background: var(--surface-2); }
.quick-action > svg {
  width: 36px; height: 36px; padding: 8px; flex: none; border-radius: var(--radius-sm);
  background: var(--primary-soft); color: var(--primary-soft-fg);
}
.quick-actions.compact .quick-action > svg { width: 30px; height: 30px; padding: 7px; }
.quick-action strong { display: block; font-size: 14px; line-height: 1.3; }
.quick-action .cell-sub { display: block; margin-top: 1px; }

/* Setup progress. */
.progress-count { font-size: 13px; font-weight: 600; color: var(--primary); white-space: nowrap; }
.setup-card progress { margin: 4px 0 6px; }
.checklist.columns { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); column-gap: 24px; }
.checklist.columns li:last-child { border-bottom: 1px solid var(--border); }

/* A date chip beside an event. */
.date-row { display: flex; align-items: center; gap: 12px; min-width: 0; }
.date-row > div { min-width: 0; }
.date-row .cell-sub { display: block; }
.date-chip {
  display: grid; place-items: center; width: 44px; flex: none; padding: 5px 0; line-height: 1.1;
  border-radius: var(--radius-sm); background: var(--primary-soft); color: var(--primary-soft-fg);
}
.date-chip span { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.date-chip strong { font-size: 17px; }

.inline-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 6px 0 2px; }
.inline-empty p { margin: 0; color: var(--fg-muted); font-size: 14px; }

/* Staff dashboard: what needs someone, and what to start. */
.dashboard-top { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr); gap: 20px; align-items: start; margin-bottom: 20px; }
.inbox-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: 12px; margin: 0 -12px; border-radius: var(--radius-sm);
  color: var(--fg); text-decoration: none; border-top: 1px solid var(--border);
}
.inbox-row:first-of-type { border-top: 0; }
.inbox-row:hover { background: var(--surface-2); }
.inbox-row strong { display: block; font-size: 14.5px; }
.inbox-count {
  min-width: 40px; height: 40px; padding: 0 8px; display: grid; place-items: center;
  border-radius: var(--radius-sm); font-size: 17px; font-weight: 700;
}
.inbox-row.danger .inbox-count { background: var(--danger-soft); color: var(--danger); }
.inbox-row.warning .inbox-count { background: var(--warning-soft); color: var(--warning); }
.inbox-row.info .inbox-count { background: var(--info-soft); color: var(--info); }
.inbox-go { width: 18px; height: 18px; color: var(--fg-muted); }
.inbox-row:hover .inbox-go { color: var(--fg); }
.all-clear { display: flex; gap: 12px; align-items: center; padding: 6px 0; }
.all-clear > svg {
  width: 40px; height: 40px; padding: 9px; flex: none; border-radius: 50%;
  background: var(--success-soft); color: var(--success);
}
.all-clear strong { display: block; }

a.metric { color: inherit; text-decoration: none; }
a.metric[href] { transition: border-color .12s ease, background .12s ease; }
a.metric[href]:hover { border-color: var(--border-strong); background: var(--surface-2); }
a.metric[href] .label::after { content: ' →'; }
.small-note { font-size: 13px; margin: 10px 0 0; }

/* Member bottom navigation on a phone. The sidebar stays the full map. */
.tabbar { display: none; }

@media (max-width: 1100px) {
  .dashboard-top { grid-template-columns: minmax(0, 1fr); }
  .quick-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 760px) {
  .quick-actions { grid-template-columns: minmax(0, 1fr); }
  .crumbs .crumb-group, .crumbs > a { display: none; }
  .crumbs > * + *::before { content: none; }
  .tabbar {
    position: fixed; inset-inline: 0; bottom: 0; z-index: 50;
    display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
    background: var(--surface); border-top: 1px solid var(--border);
    padding: 6px 6px calc(6px + env(safe-area-inset-bottom));
  }
  .tabbar a {
    display: flex; flex-direction: column; align-items: center; gap: 3px;
    padding: 6px 2px; border-radius: var(--radius-sm); min-height: 48px;
    font-size: 11.5px; font-weight: 600; color: var(--fg-muted); text-decoration: none;
  }
  .tabbar a svg { width: 22px; height: 22px; }
  .tabbar a[aria-current="page"] { background: var(--primary-soft); color: var(--primary-soft-fg); }
  .app.has-tabbar .app-body { padding-bottom: 96px; }
}

@media print { .tabbar, .sidebar-jump { display: none; } }

/* -- 9  Front door (member.sabacenter.org without the public site) ------- */

/* The landing page, sign in, sign up, policies and checkout returns. Nothing
   here to browse: the public website lives on sabacenter.org. */
body.door { background: var(--bg); min-height: 100vh; display: flex; flex-direction: column; }
.door-header {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 16px clamp(16px, 4vw, 48px); max-width: 1240px; width: 100%; margin: 0 auto;
}
.door-header .brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 700; text-decoration: none; color: var(--fg); letter-spacing: -.02em; }
.door-header .brand-logo { height: 26px; width: auto; }
.door-product {
  font-weight: 600; font-size: 12px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--fg-muted); margin-inline-start: 6px; padding-inline-start: 10px; border-inline-start: 1px solid var(--border-strong);
}
.door-actions { display: flex; gap: 8px; }
.door-main { flex: 1; width: 100%; max-width: 1240px; margin: 0 auto; padding: 8px clamp(16px, 4vw, 48px) 56px; }
body.door .messages { max-width: 1240px; margin: 0 auto; padding: 0 clamp(16px, 4vw, 48px); width: 100%; }

.door-hero {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); gap: clamp(24px, 5vw, 72px);
  align-items: center; padding: clamp(16px, 4vw, 48px) 0;
}
.door-hero h1 { font-size: clamp(34px, 5vw, 54px); line-height: 1.04; letter-spacing: -.035em; margin: 6px 0 16px; }
.door-hero .lede { font-size: 17px; line-height: 1.6; color: var(--fg-muted); max-width: 52ch; margin: 0 0 28px; }
.door-benefits { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 24px; }
.door-benefits li { display: flex; gap: 12px; align-items: flex-start; }
.door-benefits svg {
  width: 38px; height: 38px; padding: 9px; flex: none; border-radius: var(--radius-sm);
  background: var(--primary-soft); color: var(--primary-soft-fg);
}
.door-benefits strong { display: block; font-size: 14.5px; margin-bottom: 2px; }
.door-benefits span { font-size: 13.5px; color: var(--fg-muted); line-height: 1.45; }
.door-benefits span strong { color: var(--fg); }

/* The sign-in card sits over the photograph, which is decoration only. */
.door-panel { position: relative; padding: 40px 0 40px 56px; }
.door-photo {
  position: absolute; inset: 0 auto 0 0; width: 62%; margin: 0;
  border-radius: var(--radius-lg); overflow: hidden; background: var(--surface-3);
}
.door-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.door-card { position: relative; margin-inline-start: auto; max-width: 400px; padding: 28px; box-shadow: var(--shadow-lg); }
.door-card h2 { font-size: 22px; margin: 0 0 2px; letter-spacing: -.02em; }
.door-card > .muted { margin: 0 0 18px; }
.door-card .field { margin-bottom: 14px; }
.door-divider { display: flex; align-items: center; gap: 12px; margin: 20px 0 14px; color: var(--fg-muted); font-size: 13px; }
.door-divider::before, .door-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

.door-section { padding: 40px 0 8px; border-top: 1px solid var(--border); margin-top: 24px; }
.door-section h2 { font-size: 24px; letter-spacing: -.02em; margin: 0 0 18px; }
.door-section-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.door-section-head h2 { margin-bottom: 18px; }
.door-steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.door-steps li { display: flex; flex-direction: column; gap: 6px; padding: 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.door-steps li > span:last-child { color: var(--fg-muted); font-size: 14px; line-height: 1.5; }
.door-step-num {
  display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; margin-bottom: 6px;
  background: var(--primary); color: var(--primary-fg); font-weight: 700; font-size: 14px;
}
.door-plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 16px; }
.door-plan h3 { font-size: 18px; margin: 0 0 6px; }
.door-plan-prices { list-style: none; padding: 0; margin: 14px 0; }
.door-plan-prices .price { font-size: 26px; font-weight: 700; letter-spacing: -.02em; }

.door-footer {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px;
  padding: 20px clamp(16px, 4vw, 48px); border-top: 1px solid var(--border);
  font-size: 13.5px; color: var(--fg-muted);
}
.door-footer p { margin: 0; }
.door-footer nav { display: flex; flex-wrap: wrap; gap: 16px; }
.door-footer a { color: var(--fg-muted); }
.door-footer a:hover { color: var(--fg); }

/* Sign in, sign up, reset, policies: one calm column. */
body.door .form-shell, body.door .account-shell {
  max-width: 480px; margin: 24px auto; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg); padding: clamp(20px, 4vw, 36px);
}

@media (max-width: 900px) {
  .door-hero { grid-template-columns: minmax(0, 1fr); }
  /* On a phone the form comes first: most people here are signing in. */
  .door-panel { order: -1; padding: 0; }
  .door-photo { display: none; }
  .door-card { max-width: none; box-shadow: none; }
  .door-steps { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .door-benefits { grid-template-columns: minmax(0, 1fr); }
  .door-product { display: none; }
}

/* -- 10  Dashboard figures ------------------------------------------------ */
.section-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-top: 8px; }
.kpi-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.kpi {
  position: relative; display: flex; flex-direction: column; gap: 4px; overflow: hidden;
  padding: 16px 18px 42px; border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); color: var(--fg); text-decoration: none; min-height: 150px;
}
a.kpi[href]:hover { border-color: var(--border-strong); background: var(--surface-2); }
.kpi-label { font-size: 13px; font-weight: 600; color: var(--fg-muted); }
.kpi-value { font-size: 30px; font-weight: 700; letter-spacing: -.03em; line-height: 1.15; }
.kpi-value small { font-size: 13px; font-weight: 600; color: var(--fg-muted); letter-spacing: 0; }
.kpi-foot { display: flex; flex-wrap: wrap; gap: 4px 8px; font-size: 12.5px; color: var(--fg-muted); line-height: 1.4; }
.spark { position: absolute; inset-inline: 0; bottom: 0; width: 100%; height: 36px; }
.spark polyline { fill: none; stroke: var(--chart-1); stroke-width: 2; vector-effect: non-scaling-stroke; stroke-linejoin: round; stroke-linecap: round; }
.delta { font-weight: 700; white-space: nowrap; }
.delta.up { color: var(--success); }
.delta.down { color: var(--danger); }
.delta.flat { color: var(--fg-muted); font-weight: 600; }

.activity-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; align-items: center;
  padding: 10px 12px; margin: 0 -12px; border-radius: var(--radius-sm); color: var(--fg); text-decoration: none;
}
.activity-row + .activity-row { border-top: 1px solid var(--border); }
a.activity-row:hover { background: var(--surface-2); }
.activity-text { min-width: 0; }
.activity-text strong, .activity-text .cell-sub { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity-amount { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.activity-icon {
  width: 34px; height: 34px; display: grid; place-items: center; border-radius: 50%;
  background: var(--primary-soft); color: var(--primary-soft-fg);
}
.activity-icon svg { width: 16px; height: 16px; }

/* The long view on the dashboard (D-35): headline figures since the first
   payment beside one small bar per year. The current year is lighter, and
   says "to date" in its title, because it is not a whole year. */
.long-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 16px; }
.long-head p { margin: 4px 0 0; color: var(--fg-muted); font-size: 13.5px; }
.long-body { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: 20px 28px; align-items: end; margin-top: 16px; }
.long-figures { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px 24px; margin: 0; }
.long-figures dt { font-size: 12.5px; font-weight: 600; color: var(--fg-muted); }
.long-figures dd { margin: 2px 0 0; font-size: 24px; font-weight: 700; letter-spacing: -.02em; line-height: 1.2; }
.long-figures dd.sub { font-size: 12.5px; font-weight: 500; letter-spacing: 0; color: var(--fg-muted); }
.year-bars { display: flex; align-items: flex-end; gap: 6px; height: 132px; padding-bottom: 2px; border-bottom: 1px solid var(--border); }
.yb { flex: 1 1 0; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 4px; }
.yb-bar { width: 100%; max-width: 34px; min-height: 2px; border-radius: 4px 4px 0 0; background: var(--chart-1); }
.yb.partial .yb-bar { background: color-mix(in srgb, var(--chart-1) 50%, var(--surface)); }
.yb-label { font-size: 11px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
@media (max-width: 760px) { .long-body { grid-template-columns: minmax(0, 1fr); } .long-figures dd { font-size: 20px; } }

@media (max-width: 1100px) { .kpi-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .kpi-row { grid-template-columns: minmax(0, 1fr); } .kpi { min-height: 0; } }

/* Pages that were the public website -- What's on, Give, Programmes, Join --
   now open inside the portal. Their marketing scale (section padding, display
   headings) is brought down to the portal's, so they read as one product. */
.app-body .section, .app-body .container { padding: 0 0 32px; max-width: none; }
.app-body .section + .section { padding-top: 8px; border-top: 1px solid var(--border); margin-top: 8px; }
.app-body .section-heading { margin-bottom: 18px; gap: 16px; }
.app-body .section-heading h2, .app-body .container h1 { font-size: 26px; letter-spacing: -.025em; margin: 2px 0 0; }
.app-body .section-heading p { font-size: 14px; }
.app-body .form-shell { margin: 0; max-width: 680px; }
.plan-name { font-size: 26px; margin-bottom: 10px; }
body.public .plan-name { font-size: 32px; }
body.public .container > .section-heading h1 { font-size: 52px; }


/* ===========================================================================
   11  Vivid redesign (2026-09)
   ---------------------------------------------------------------------------
   Layered on top of everything above rather than rewriting it: the component
   anatomy stays, the look changes. A navy navigation rail with a bright
   active pill, a brand gradient hairline, rounder cards with a soft lift, and
   a front door and joining flow built around the logo's green, blue and red.
   Every text colour still comes from a token measured in
   tests/test_design_tokens.py.
   ======================================================================== */

body { letter-spacing: -.005em; }
h1, h2, h3 { letter-spacing: -.025em; }

/* -- Brand hairline: one gradient line that says "Saba" everywhere -------- */
.topbar, .door-header { position: relative; }
.topbar::after, .door-header::after {
  content: ''; position: absolute; inset-inline: 0; bottom: -1px; height: 3px;
  background: var(--grad-brand); opacity: .9; pointer-events: none;
}

/* -- Buttons -------------------------------------------------------------- */
.button, button[type=submit], .btn { border-radius: 10px; transition: background .15s ease, box-shadow .15s ease, transform .15s ease; }
.button:hover, button[type=submit]:hover, .btn:hover { box-shadow: 0 6px 18px -8px color-mix(in srgb, var(--primary) 70%, transparent); }
.button:active, button[type=submit]:active { transform: translateY(1px); }
.button.warm { background: var(--gold); color: #2a1e05; }
.button.warm:hover { background: #ffb61a; box-shadow: 0 6px 18px -8px rgba(255, 180, 20, .8); }
.button.accent { background: var(--brand-blue); color: #fff; }
.button.accent:hover { background: #164fb0; }
.button.on-dark { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.45); }
.button.on-dark:hover { background: rgba(255,255,255,.18); box-shadow: none; }
.button.xl { min-height: 54px; padding: 0 26px; font-size: 16px; border-radius: 12px; }

/* -- Cards ---------------------------------------------------------------- */
.card { border-radius: 16px; box-shadow: 0 1px 2px rgba(15, 26, 46, .04), 0 8px 24px -18px rgba(15, 26, 46, .25); }
a.card:hover, .card.lift:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--border)); box-shadow: 0 14px 36px -20px rgba(15, 26, 46, .4); }

/* -- Navigation rail ------------------------------------------------------ */
.sidebar { background: var(--sidebar-bg); color: var(--sidebar-fg); border-inline-end: 0; }
.sidebar-head { color: var(--sidebar-fg); border-bottom-color: rgba(255,255,255,.08); }
.sidebar-head img { background: #fff; border-radius: 8px; padding: 3px 5px; height: 30px; }
.sidebar-head .portal { color: var(--sidebar-active); }
.sidebar-head .name { color: #fff; }
.sidebar .sidebar-group > h2, .sidebar details.sidebar-group > summary h2 { color: var(--sidebar-muted); }
details.sidebar-group > summary:hover { background: var(--sidebar-hover); }
details.sidebar-group > summary:hover h2 { color: #fff; }
details.sidebar-group > summary .chevron { color: var(--sidebar-muted); }
.sidebar-nav a { color: var(--sidebar-fg); border-radius: 10px; padding: 9px 12px; }
.sidebar-nav a svg { opacity: .8; }
.sidebar-nav a:hover { background: var(--sidebar-hover); color: #fff; }
.sidebar-nav a[aria-current="page"] {
  background: var(--sidebar-active); color: var(--sidebar-active-fg); font-weight: 700;
  box-shadow: 0 8px 20px -10px rgba(61, 220, 151, .7);
}
.sidebar-nav a[aria-current="page"] svg { opacity: 1; }
.sidebar-nav .count { background: rgba(255,255,255,.12); color: var(--sidebar-fg); }
.sidebar-nav .count.attention { background: #c23b22; color: #fff; }
.sidebar-nav a[aria-current="page"] .count { background: rgba(4, 35, 26, .15); color: var(--sidebar-active-fg); }
.sidebar-empty { color: var(--sidebar-muted); }
.sidebar-jump svg { color: var(--sidebar-muted); }
.sidebar-jump input[type=search] { background: rgba(255,255,255,.07); color: var(--sidebar-fg); border-color: rgba(255,255,255,.16); }
.sidebar-jump input[type=search]::placeholder { color: var(--sidebar-muted); }
.sidebar-jump kbd { background: transparent; color: var(--sidebar-muted); border-color: rgba(255,255,255,.25); }
.sidebar-foot { border-top-color: rgba(255,255,255,.08); }
.sidebar-foot .button.secondary, .sidebar-foot .button.ghost { background: transparent; color: var(--sidebar-fg); border-color: rgba(255,255,255,.22); }
.sidebar-foot .button.secondary:hover, .sidebar-foot .button.ghost:hover { background: var(--sidebar-hover); color: #fff; box-shadow: none; }
.sidebar :focus-visible { outline-color: var(--sidebar-active); }

/* -- Top bar and page header ---------------------------------------------- */
.topbar { background: color-mix(in srgb, var(--surface) 90%, transparent); border-bottom-color: transparent; }
.avatar { background: var(--grad-hero); color: #fff; }
.page-head h1 { font-size: clamp(24px, 2.4vw, 30px); letter-spacing: -.03em; }

/* -- Member bottom bar ---------------------------------------------------- */
@media (max-width: 1100px) {
  .tabbar a[aria-current="page"] { background: var(--primary); color: var(--primary-fg); }
}

/* ===========================================================================
   Front door: member.sabacenter.org
   ======================================================================== */
body.door { background:
  radial-gradient(1200px 500px at 90% -10%, color-mix(in srgb, var(--brand-blue) 14%, transparent), transparent 60%),
  radial-gradient(900px 420px at -10% 10%, color-mix(in srgb, var(--brand-green) 14%, transparent), transparent 60%),
  var(--bg); }
.door-header { background: color-mix(in srgb, var(--surface) 85%, transparent); backdrop-filter: blur(10px); position: sticky; top: 0; z-index: 20;
  max-width: none; padding-inline: max(clamp(16px, 4vw, 48px), calc((100% - 1144px) / 2)); }
.door-block-head .eyebrow, .join-top .eyebrow { justify-content: center; }
.door-actions .text-link { border-bottom: 0; }
.door-header .brand-logo { height: 32px; }
.door-actions { align-items: center; }
.door-actions .text-link { font-size: 14px; font-weight: 600; color: var(--fg-muted); text-decoration: none; padding: 0 8px; }
.door-actions .text-link:hover { color: var(--fg); }

.welcome { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 32px; align-items: stretch;
  background: var(--grad-hero); color: #fff; border-radius: 28px; padding: clamp(28px, 5vw, 56px);
  margin-top: 24px; position: relative; overflow: hidden; box-shadow: 0 30px 60px -30px rgba(5, 61, 42, .55); }
.welcome::before { content: ''; position: absolute; width: 520px; height: 520px; border-radius: 50%;
  right: -160px; bottom: -260px; background: radial-gradient(circle, rgba(255,197,61,.35), transparent 65%); pointer-events: none; }
.welcome::after { content: ''; position: absolute; width: 380px; height: 380px; border-radius: 50%;
  left: 35%; top: -220px; background: radial-gradient(circle, rgba(232,69,60,.28), transparent 65%); pointer-events: none; }
.welcome > * { position: relative; z-index: 1; }
.welcome .eyebrow { color: #c9f5de; display: inline-flex; gap: 8px; align-items: center; background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.2); padding: 6px 12px; border-radius: 999px; letter-spacing: .08em; }
.welcome h1 { font-size: clamp(36px, 5.4vw, 62px); line-height: 1.02; letter-spacing: -.04em; margin: 18px 0 16px; color: #fff; }
.welcome h1 .hl { background: linear-gradient(90deg, #ffe08a, #ffc53d); -webkit-background-clip: text; background-clip: text; color: transparent; }
.welcome .lede { font-size: 18px; line-height: 1.6; color: #e3f1ff; max-width: 50ch; margin: 0 0 28px; }
.welcome-ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 28px; }
.welcome-trust { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 10px 22px; font-size: 14px; color: #e3f1ff; }
.welcome-trust li { display: inline-flex; gap: 8px; align-items: center; }
.welcome-trust svg { width: 16px; height: 16px; color: #7ff0bd; }
.welcome .door-card { margin: 0; max-width: none; color: var(--fg); align-self: center; border: 0; }
.welcome .door-card h2 { font-size: 24px; }

.door-block { padding: 56px 0 8px; }
.door-block-head { text-align: center; max-width: 680px; margin: 0 auto 30px; }
.door-block-head .eyebrow { color: var(--primary); }
.door-block-head h2 { font-size: clamp(26px, 3vw, 36px); margin: 8px 0 10px; letter-spacing: -.03em; }
.door-block-head p { color: var(--fg-muted); font-size: 16px; margin: 0; }

.tier-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); gap: 22px; max-width: 900px; margin: 0 auto; }
.tier-card { position: relative; display: flex; flex-direction: column; gap: 14px; padding: 30px; border-radius: 22px;
  background: var(--surface); border: 2px solid var(--border); box-shadow: 0 20px 40px -32px rgba(15,26,46,.5); }
.tier-card.featured { border-color: var(--brand-blue); box-shadow: 0 30px 60px -34px rgba(29, 99, 214, .6); }
.tier-ribbon { position: absolute; top: -13px; inset-inline-start: 26px; background: var(--brand-blue); color: #fff;
  font-size: 12px; font-weight: 700; letter-spacing: .04em; padding: 5px 12px; border-radius: 999px; }
.tier-card .plan-icon { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; background: var(--primary-soft); color: var(--primary); }
.tier-card.featured .plan-icon { background: var(--accent-soft); color: var(--info); }
.tier-card .plan-icon svg { width: 24px; height: 24px; }
.tier-card h3 { font-size: 22px; margin: 0; }
.tier-card .plan-desc { color: var(--fg-muted); margin: 0; font-size: 15px; }
.plan-amount { display: flex; align-items: baseline; gap: 6px; margin: 4px 0; }
.plan-amount strong { font-size: 48px; letter-spacing: -.04em; line-height: 1; }
.plan-amount span { color: var(--fg-muted); font-size: 15px; }
.check-list { list-style: none; padding: 0; margin: 0 0 6px; display: grid; gap: 10px; }
.check-list li { display: flex; gap: 10px; align-items: flex-start; font-size: 15px; line-height: 1.45; }
.check-list li::before { content: ''; flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 50%;
  background: var(--primary-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230a7a45' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12l5 5L20 7'/%3E%3C/svg%3E") center / 12px no-repeat; }
.tier-card .button { margin-top: auto; }

.steps-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; list-style: none; padding: 0; margin: 0; counter-reset: s; }
.steps-grid li { background: var(--surface); border: 1px solid var(--border); border-radius: 18px; padding: 22px; display: flex; flex-direction: column; gap: 8px; }
.steps-grid .num { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; font-weight: 800; color: #fff; font-size: 17px; }
.steps-grid li:nth-child(1) .num { background: #0a7a45; }
.steps-grid li:nth-child(2) .num { background: #1d63d6; }
.steps-grid li:nth-child(3) .num { background: #c23b22; }
.steps-grid li:nth-child(4) .num { background: #7a4bd0; }
.steps-grid strong { font-size: 16px; }
.steps-grid span { color: var(--fg-muted); font-size: 14px; line-height: 1.5; }

.perk-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px; }
.perk { display: flex; gap: 14px; align-items: flex-start; padding: 20px; border-radius: 18px; background: var(--surface); border: 1px solid var(--border); }
.perk .tile { flex: none; width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; color: #fff; }
.perk .tile svg { width: 22px; height: 22px; }
.perk strong { display: block; font-size: 15.5px; margin-bottom: 3px; }
.perk span { color: var(--fg-muted); font-size: 14px; line-height: 1.5; }
.tile.green { background: linear-gradient(135deg, #0a7a45, #2fae5f); }
.tile.blue { background: linear-gradient(135deg, #1759c4, #4c8dff); }
.tile.coral { background: linear-gradient(135deg, #c23b22, #f07a4a); }
.tile.gold { background: linear-gradient(135deg, #b77900, #ffc53d); }
.tile.violet { background: linear-gradient(135deg, #5b35b0, #9a72ff); }
.tile.teal { background: linear-gradient(135deg, #0b6e7a, #2bb7c4); }

.cta-band { margin: 56px 0 8px; border-radius: 24px; padding: 34px clamp(22px, 4vw, 44px); background: var(--navy); color: #fff;
  display: flex; gap: 20px; justify-content: space-between; align-items: center; flex-wrap: wrap; position: relative; overflow: hidden; }
.cta-band::before { content: ''; position: absolute; inset: 0 0 auto 0; height: 4px; background: var(--grad-brand); }
.cta-band h2 { color: #fff; margin: 0 0 4px; font-size: 24px; }
.cta-band p { margin: 0; color: #c7d5ec; }

.door-footer { border-top: 0; position: relative; }
.door-footer::before { content: ''; position: absolute; inset-inline: 0; top: 0; height: 3px; background: var(--grad-brand); }

/* ===========================================================================
   Joining steps: /become-a-member/
   ======================================================================== */
.join { max-width: 1080px; margin: 18px auto 0; }
.join-top { text-align: center; margin: 10px 0 22px; }
.join-top h1 { font-size: clamp(28px, 3.4vw, 40px); margin: 6px 0 6px; letter-spacing: -.035em; }
.join-top p { color: var(--fg-muted); margin: 0; }
.stepper { list-style: none; padding: 0; margin: 0 auto 26px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; max-width: 820px; }
.stepper li { display: flex; flex-direction: column; gap: 8px; font-size: 13px; font-weight: 600; color: var(--fg-muted); }
.stepper li::before { content: ''; height: 6px; border-radius: 99px; background: var(--surface-3); }
.stepper li.done::before { background: var(--primary); }
.stepper li.current::before { background: var(--grad-brand); }
.stepper li.current { color: var(--fg); }
.stepper .n { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; margin-inline-end: 6px;
  font-size: 12px; background: var(--surface-3); color: var(--fg); }
.stepper li.done .n { background: var(--primary); color: var(--primary-fg); }
.stepper li.current .n { background: var(--brand-blue); color: #fff; }
.stepper a { color: inherit; text-decoration: none; }
.stepper a:hover { text-decoration: underline; }

.join-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 24px; align-items: start; }
.join-main { padding: clamp(20px, 3vw, 34px); }
.join-main > h2 { font-size: 22px; margin: 0 0 6px; }
.join-main > .muted { margin: 0 0 20px; }
.join-aside { position: sticky; top: 90px; display: grid; gap: 14px; }
.join-summary { padding: 22px; background: var(--grad-hero); color: #fff; border: 0; }
.join-summary .eyebrow { color: #c9f5de; }
.join-summary h3 { color: #fff; font-size: 20px; margin: 4px 0 6px; }
.join-summary .amount { font-size: 34px; font-weight: 800; letter-spacing: -.03em; }
.join-summary .amount span { font-size: 14px; font-weight: 500; color: #e3f1ff; }
.join-summary p { color: #e3f1ff; font-size: 14px; margin: 8px 0 0; }
.join-summary a { color: #fff; }
.join-secure { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; color: var(--fg-muted); padding: 16px; }
.join-secure svg { flex: none; width: 20px; height: 20px; color: var(--primary); }
.join-actions { display: flex; gap: 12px; justify-content: space-between; align-items: center; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border); flex-wrap: wrap; }

.plan-choice { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); gap: 16px; border: 0; padding: 0; margin: 0; }
.plan-choice legend { font-weight: 700; margin-bottom: 12px; }
.plan-option { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 22px; border: 2px solid var(--border); border-radius: 18px; cursor: pointer; background: var(--surface); transition: border-color .15s, box-shadow .15s; }
.plan-option:hover { border-color: var(--border-strong); }
.plan-option input { position: absolute; top: 20px; inset-inline-end: 20px; width: 22px; height: 22px; accent-color: var(--primary); }
.plan-option:has(input:checked) { border-color: var(--primary); box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 18%, transparent); }
.plan-option:has(input:focus-visible) { outline: 2px solid var(--ring); outline-offset: 3px; }
.plan-option h3 { margin: 0; font-size: 19px; padding-inline-end: 34px; }
.plan-option .plan-amount strong { font-size: 36px; }
.plan-option .check-list li { font-size: 14px; }

.doc-scroll { max-height: 360px; overflow: auto; border: 1px solid var(--border); border-radius: 14px; padding: 18px 20px; background: var(--surface-2); font-size: 14.5px; }
.doc-scroll h2 { font-size: 18px; margin: 18px 0 8px; }
.doc-scroll h2:first-child, .doc-scroll h3:first-child { margin-top: 0; }
.doc-scroll h3 { font-size: 16px; margin: 16px 0 6px; }
.doc-section + .doc-section { margin-top: 22px; }
.doc-section > h3 { display: flex; align-items: center; gap: 10px; font-size: 17px; margin: 0 0 10px; }
.doc-section > h3 .tile { width: 32px; height: 32px; border-radius: 10px; }
.doc-section > h3 .tile svg { width: 17px; height: 17px; }
.read-hint { font-size: 13px; color: var(--fg-muted); margin: 8px 0 0; }

.consent-box { margin-top: 24px; padding: 20px; border-radius: 16px; border: 2px solid var(--primary-soft); background: color-mix(in srgb, var(--primary-soft) 45%, var(--surface)); display: grid; gap: 12px; }
.consent-box .field { margin: 0; }
.signature-pad { display: grid; gap: 8px; margin-top: 8px; }
.signature-pad canvas { width: 100%; height: 170px; border-radius: 14px; border: 2px dashed var(--border-strong); background: #fff; touch-action: none; cursor: crosshair; }
.signature-pad.signed canvas { border-style: solid; border-color: var(--primary); }
.signature-pad .sig-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; font-size: 13px; color: var(--fg-muted); }
.signature-preview { max-width: 320px; background: #fff; border-radius: 10px; border: 1px solid var(--border); padding: 6px; }

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 18px; }
.form-grid .span-2 { grid-column: 1 / -1; }
.form-section { border: 0; padding: 0; margin: 0 0 22px; }
.form-section > legend, .form-section > h3 { display: flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 700; margin: 0 0 14px; padding: 0; }
.form-section > legend .tile, .form-section > h3 .tile { width: 32px; height: 32px; border-radius: 10px; }
.form-section > legend .tile svg, .form-section > h3 .tile svg { width: 17px; height: 17px; }
.inline-choices .choice-set > div, .inline-choices .choice-set ul { display: flex; gap: 10px 22px; flex-wrap: wrap; }

.review-list { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 10px 18px; margin: 0; }
.review-list dt { color: var(--fg-muted); font-size: 14px; }
.review-list dd { margin: 0; font-weight: 600; white-space: pre-line; overflow-wrap: anywhere; }
.review-block + .review-block { margin-top: 22px; padding-top: 22px; border-top: 1px solid var(--border); }
.review-block h3 { display: flex; justify-content: space-between; align-items: center; font-size: 16px; margin: 0 0 12px; }
.review-block h3 a { font-size: 13px; font-weight: 600; }

@media (max-width: 1100px) {
  .steps-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .perk-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .welcome { grid-template-columns: minmax(0, 1fr); }
  .join-layout { grid-template-columns: minmax(0, 1fr); }
  .join-aside { position: static; }
}
/* Long calls to action wrap rather than push the page sideways. */
.join-actions .button, .welcome-ctas .button, .cta-band .button { white-space: normal; text-align: center; line-height: 1.25; }
@media (max-width: 640px) {
  .join-actions { flex-direction: column-reverse; align-items: stretch; }
  .welcome-ctas .button { flex: 1 1 100%; }
  .steps-grid, .perk-grid, .form-grid { grid-template-columns: minmax(0, 1fr); }
  .review-list { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .review-list dd { margin-bottom: 10px; }
  .stepper li { font-size: 0; }
  .stepper li .n { font-size: 12px; }
  .stepper li.current { font-size: 12px; }
  .welcome { border-radius: 20px; }
  .door-actions .text-link { display: none; }
}
@media print { .stepper, .join-aside, .door-header::after { display: none; } }

/* Membership status card on the member overview: the brand gradient, so the
   one thing a member comes to check is the brightest thing on the page. */
.membership-card { background: var(--grad-hero); border: 0; box-shadow: 0 24px 48px -30px rgba(5, 61, 42, .7); }
/* The gradient's blue end is lighter than navy: muted ink drops under AA
   there, so everything on the card is near-white (>= 5:1 on #1d63d6). */
.membership-card p, .membership-card dt, .membership-card dd, .membership-card small, .membership-card .member-number, .membership-card .cell-sub { color: #f4f8ff; }
/* Phones: the logo stands for the name so the two buttons fit. */
@media (max-width: 480px) {
  .door-header .brand > span { display: none; }
  .door-actions { gap: 6px; }
}

/* Language switch in the top bar, beside the theme toggle (owner request):
   visible on every page before anybody signs in. */
.language-switch.compact { gap: 2px; padding: 2px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); }
.language-switch.compact .lang-globe { color: var(--fg-muted); margin-inline: 6px 2px; flex: none; }
.language-switch.compact button { padding: 4px 10px; border-radius: 999px; font-size: 12.5px; line-height: 1.2; }
.language-switch.compact button[aria-current="true"] { background: var(--primary); color: var(--primary-fg); }
.home-link { flex: none; }
@media (max-width: 480px) {
  .language-switch.compact .lang-globe { display: none; }
  .language-switch.compact button { padding: 4px 7px; }
}

.door-footer .door-tax { flex-basis: 100%; color: var(--fg-muted); font-size: 13px; margin: 0; }

/* Staff messaging (views.staff_message) */
.message-layout { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 20px; align-items: start; }
.message-layout textarea { font-family: var(--font-mono); font-size: 13.5px; line-height: 1.55; }
.email-preview { width: 100%; height: 760px; border: 1px solid var(--border); border-radius: 12px; background: #eef2f9; }
.inbox-item { display: flex; align-items: center; gap: 6px; }
.inbox-item .inbox-row { flex: 1 1 auto; min-width: 0; }
.inbox-message { flex: none; }
@media (max-width: 1100px) { .message-layout { grid-template-columns: minmax(0, 1fr); } .email-preview { height: 600px; } }
@media (max-width: 640px) { .inbox-item { flex-wrap: wrap; } .inbox-message { margin-inline-start: 52px; } }

/* A field the member may not change (their legal name) looks it. */
input:disabled, select:disabled, textarea:disabled {
  background: var(--surface-2); color: var(--fg-muted); border-style: dashed; cursor: not-allowed;
}
@media (max-width: 480px) {
  .door-actions .button.warm { display: none; }
}

/* Persian: Vazirmatn (SIL OFL, static/fonts/VAZIRMATN-OFL.txt), self-hosted
   because the Content-Security-Policy allows fonts only from this site. The
   unicode-range limits it to Arabic-script characters; Latin keeps the
   system font. */
@font-face {
  font-family: 'Vazirmatn'; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/vazirmatn-arabic-400.49c0cc018008.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EFD-10EFF, U+1EE00-1EEFF;
}
@font-face {
  font-family: 'Vazirmatn'; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/vazirmatn-arabic-600.6da23f69b4f7.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EFD-10EFF, U+1EE00-1EEFF;
}
@font-face {
  font-family: 'Vazirmatn'; font-style: normal; font-weight: 700; font-display: swap;
  src: url("fonts/vazirmatn-arabic-700.51265c214faf.woff2") format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EFD-10EFF, U+1EE00-1EEFF;
}
:root[lang="fa"] { --font: 'Vazirmatn', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif; }

/* Narrow screens: the top bar keeps every control without pushing the page
   sideways. The language switch shows only the language you can switch TO,
   the dashboard link lives in the menu, and the staff search moves out of the
   bar on a phone (Members has its own search). */
@media (max-width: 760px) {
  .topbar .home-link { display: none; }
  .language-switch.compact button[aria-current="true"] { display: none; }
  .language-switch.compact .lang-globe { display: inline; }
  .topbar-actions { gap: 6px; }
}
@media (max-width: 480px) {
  .topbar .topbar-search { display: none; }
}

/* Public website header on a phone: the logo stands for the name. */
@media (max-width: 480px) {
  .site-header .brand > span { display: none; }
  .site-header .nav-actions { gap: 6px; }
}

/* Review: community photography and a reachable, keyboard-safe phone drawer. */
.welcome-signin { display: none; }
#sign-in, #plans { scroll-margin-top: 100px; }
.community-mosaic { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; margin-top: 56px; }
.community-mosaic img { width: 100%; height: 220px; object-fit: cover; border-radius: 20px; }
.community-mosaic img:nth-child(2) { object-position: center 35%; }
.sidebar-close { display: none; }
@media (max-width: 900px) {
  .sidebar-close { display: inline-flex; position: absolute; inset-inline-end: 12px; top: 12px; color: var(--sidebar-fg); background: var(--sidebar-bg); }
  .sidebar-head { padding-inline-end: 52px; }
  .app[data-nav="closed"] .sidebar { visibility: hidden; }
  body:has(.app[data-nav="open"]) { overflow: hidden; }
}
@media (max-width: 760px) {
  .welcome-signin { display: inline-flex; }
  .welcome { padding: 24px; }
  .welcome .lede { font-size: 16px; line-height: 1.55; }
  .welcome-ctas { gap: 8px; margin-bottom: 20px; }
  .welcome-ctas .button { min-height: 44px; }
  .welcome-trust { font-size: 12px; }
  .community-mosaic { gap: 8px; margin-top: 32px; }
  .community-mosaic img { height: 130px; border-radius: 12px; }
}

/* Stripe subscriptions (D-31): a failing payment that was paying until
   recently. A solid edge, not a tint or opacity -- opacity composites and
   drops text below AA. */
tr.row-alert td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
pre.notes { white-space: pre-wrap; }

/* -- 12 Coach: the register, the children, the photos (D-33) ------------- */

/* Written for a phone held in one hand at the side of a pitch: every target
   is at least 44px, one row per child, and the state of a row is carried by
   colour AND text, never colour alone. */
.coach-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.coach-head h1 { margin: 0; }
.day-nav { display: grid; grid-template-columns: 48px minmax(0, 1fr) 48px; align-items: center; gap: 8px; padding: 10px 12px; }
.day-nav .day-step { width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.day-nav svg.flip, [dir="rtl"] .day-nav svg:not(.flip) { transform: scaleX(-1); }
[dir="rtl"] .day-nav svg.flip { transform: none; }
.day-pick { display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center; }
.day-label { font-weight: 700; font-size: 16px; }
.day-pick input[type=date] { max-width: 190px; min-height: 40px; }
.tally { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 10px; }
.tally-item { display: inline-flex; align-items: baseline; gap: 6px; padding: 8px 14px; border-radius: 999px; background: var(--surface); border: 1px solid var(--border); font-size: 14px; color: var(--fg); text-decoration: none; }
.tally-item strong { font-size: 18px; }
.tally-item.here { background: var(--success-soft); color: var(--success); border-color: transparent; }
.tally-item.away { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.tally-item.alert { background: var(--warning-soft); color: var(--warning); border-color: transparent; }
.chips { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 4px; margin-bottom: 12px; }
.chips a { flex: none; display: inline-flex; align-items: center; gap: 6px; min-height: 40px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--surface); color: var(--fg); font-size: 14px; font-weight: 600; text-decoration: none; }
.chips a span { color: var(--fg-muted); font-weight: 500; }
.chips a[aria-current="page"] { background: var(--primary); border-color: var(--primary); color: var(--primary-fg); }
.chips a[aria-current="page"] span { color: inherit; }

.register { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.kid-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); border-inline-start: 5px solid var(--border-strong); }
.kid-row.is-present, .kid-row.is-late { border-inline-start-color: var(--success); }
.kid-row.is-absent { border-inline-start-color: var(--danger); }
.kid-row.is-excused { border-inline-start-color: var(--info); }
.kid-id { display: flex; align-items: center; gap: 12px; min-width: 0; color: inherit; text-decoration: none; }
.kid-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.kid-text strong { font-size: 16px; overflow-wrap: anywhere; }
.kid-sub { font-size: 13px; color: var(--fg-muted); overflow-wrap: anywhere; }
.kid-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 3px; }
.kid-photo { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; flex: none; background: var(--primary-soft); }
.kid-photo.large { width: 180px; height: 180px; border-radius: var(--radius-xl); }
.kid-initials { display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 18px; color: var(--primary-soft-fg); }
.kid-initials.large { font-size: 56px; }
.mark-buttons { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.mark-buttons .mark { min-height: 44px; min-width: 64px; padding: 0 10px; border-radius: var(--radius); border: 1.5px solid var(--border-strong); background: var(--surface); color: var(--fg); font: inherit; font-size: 14px; font-weight: 700; cursor: pointer; }
.mark-buttons .mark:focus-visible { outline: 3px solid var(--ring); outline-offset: 2px; }
/* Decoration only: the alternative text after the slash keeps the tick out of
   the button's accessible name, which aria-pressed already carries. */
.mark-buttons .mark:hover { background: var(--primary-soft); color: var(--primary-soft-fg); }
.mark-buttons .mark[aria-pressed="true"]::before { content: '✓ '; content: '✓ ' / ''; }
/* The soft-and-ink pairs the badges use, which clear AA in both themes. */
.mark-buttons .mark.present[aria-pressed="true"], .mark-buttons .mark.late[aria-pressed="true"] { background: var(--success-soft); border: 2px solid var(--success); color: var(--success); }
.mark-buttons .mark.absent[aria-pressed="true"] { background: var(--danger-soft); border: 2px solid var(--danger); color: var(--danger); }
.mark-buttons .mark.excused[aria-pressed="true"] { background: var(--info-soft); border: 2px solid var(--info); color: var(--info); }
.mark-form.is-busy .mark { cursor: progress; }
.session-options summary { cursor: pointer; min-height: 32px; }

.kid-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 170px), 1fr)); gap: 12px; }
.kid-card { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 16px 12px; color: inherit; text-decoration: none; height: 100%; }
.kid-card .kid-photo { width: 88px; height: 88px; }
.kid-card .kid-badges { justify-content: center; }
.program-pick { display: flex; flex-direction: column; gap: 8px; color: inherit; text-decoration: none; }

.profile-hero { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 20px; align-items: start; }
.profile-text h1 { margin: 0 0 4px; overflow-wrap: anywhere; }
.photo-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-top: 12px; }
.photo-form .small, .muted.small, .small { font-size: 13px; }
.photo-form p { flex: 1 1 100%; margin: 0; }
.camera-button { position: relative; cursor: pointer; }
.file-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.camera-button:focus-within { outline: 3px solid var(--ring); outline-offset: 2px; }
.lead-line { font-size: 17px; font-weight: 700; margin: 0 0 10px; }
.attendance-list { list-style: none; margin: 0; padding: 0; }
.attendance-list li { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.mark-pill { font-weight: 700; font-size: 13px; padding: 2px 10px; border-radius: 999px; background: var(--surface-2, var(--bg)); }
.mark-pill.present, .mark-pill.late { background: var(--success-soft); color: var(--success); }
.mark-pill.absent { background: var(--danger-soft); color: var(--danger); }
.mark-pill.excused { background: var(--info-soft); color: var(--info); }
.history-grid th.cancelled { color: var(--fg-subtle); text-decoration: line-through; }
.mark-dot { display: inline-flex; width: 26px; height: 26px; align-items: center; justify-content: center; border-radius: 50%; font-weight: 700; font-size: 13px; }
.mark-dot.present, .mark-dot.late { background: var(--success-soft); color: var(--success); }
.mark-dot.absent { background: var(--danger-soft); color: var(--danger); }
.mark-dot.excused { background: var(--info-soft); color: var(--info); }
.mark-dot.none { color: var(--fg-subtle); }
.kid-cell { display: flex; align-items: center; gap: 10px; }
.kid-cell .kid-photo { width: 40px; height: 40px; font-size: 14px; }
.inline-resolve { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.inline-resolve input { flex: 1 1 180px; min-width: 0; }
.setup-link input { flex: 1 1 260px; min-width: 0; font-family: var(--font-mono); font-size: 13px; }
.followup { margin-bottom: 10px; }
.coach-row { padding: 12px 0; border-bottom: 1px solid var(--border); }
.coach-row:last-child { border-bottom: 0; }
.coach-row p { margin: 2px 0; }
.coach-row .cluster { margin-top: 8px; gap: 8px; }
.tabbar.coach { grid-template-columns: repeat(4, minmax(0, 1fr)); }

@media (max-width: 760px) {
  .kid-row { grid-template-columns: minmax(0, 1fr); }
  .mark-buttons .mark { min-width: 0; padding: 0 4px; }
  .profile-hero { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; }
  .profile-hero .photo-form, .profile-hero .cluster { justify-content: center; }
  .kid-photo.large { width: 160px; height: 160px; }
  .coach-head .button { min-height: 44px; }
}
@media print { .mark-form, .chips, .day-nav, .session-options { display: none; } }

/* -- 13 Messages and parents (D-34) ------------------------------------- */
.icon-button.bell { position: relative; }
.bell-count { position: absolute; top: 2px; inset-inline-end: 0; min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px; background: var(--danger); color: #fff; font-size: 11px; font-weight: 700;
  line-height: 18px; text-align: center; }
.message-list { display: grid; gap: 12px; }
.message-item { border-inline-start: 4px solid var(--border-strong); }
.message-item.level-warning { border-inline-start-color: var(--warning); }
.message-item.level-urgent { border-inline-start-color: var(--danger); }
.message-item.is-new { box-shadow: var(--shadow); }
.message-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 8px; align-items: baseline; }
.message-head h2 { margin: 0; overflow-wrap: anywhere; }
.pinned-message { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; }
.pinned-message p { margin: 4px 0 0; }
.child-strip { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr)); gap: 12px; }
.child-strip a { display: flex; gap: 12px; align-items: center; color: inherit; text-decoration: none; }
.child-card h2 { margin: 0 0 4px; }


/* -- 15  Roster email schedule (D-36) -- */
.schedule-layout { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); gap: 20px; align-items: start; }
.schedule-layout .card-head h2 { margin: 0 0 4px; font-size: 18px; }
.schedule-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 16px;
  padding: 14px 0; border-bottom: 1px solid var(--border); }
.schedule-row:last-of-type { border-bottom: 0; }
.schedule-row p { margin: 2px 0; }
.schedule-row.is-paused .schedule-who strong, .schedule-row.is-paused .schedule-when { color: var(--fg-muted); }
.schedule-main { flex: 1 1 260px; min-width: 0; overflow-wrap: anywhere; }
.schedule-who { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; font-size: 15px; }
.schedule-when { font-size: 14px; font-weight: 500; }
.schedule-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
.schedule-form .field { margin-bottom: 16px; }
.day-toggles .choice-set > div { display: flex; flex-wrap: wrap; gap: 8px; padding-top: 8px; }
.day-toggles .choice-set > div > div { margin-top: 0; }
.day-toggles .choice-set label { gap: 8px; min-height: 40px; padding: 0 12px 0 10px; border: 1px solid var(--border-strong);
  border-radius: 999px; background: var(--surface); cursor: pointer; font-weight: 500; }
.day-toggles .choice-set label:has(input:checked) { background: var(--primary-soft); color: var(--primary-soft-fg);
  border-color: var(--primary); }
.preset-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: -4px 0 18px; }
.preset-row > span { flex-basis: 100%; }
@media (max-width: 900px) {
  .schedule-layout { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .schedule-actions { width: 100%; }
  .schedule-actions .button { min-height: 40px; }
}

/* -- 14  Roster print and share (D-36) -- */
/* The staff roster on a phone at the pitch, the print view, click-to-copy,
   and the coach's sheet at 390px. Every target a thumb uses is 44px. */

/* Click to copy: a small button beside an email address. */
.copy-button { display: inline-flex; align-items: center; gap: 5px; min-height: 32px; padding: 0 10px; flex: none;
  border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--fg);
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1; cursor: pointer; vertical-align: middle; }
.copy-button:hover { background: var(--surface-2); }
.copy-button[data-state="copied"] { background: var(--success-soft); color: var(--success); border-color: var(--success); }
.copy-button svg { flex: none; }
td .copy-button, .cell-sub .copy-button { margin-inline-start: 6px; }

/* Toolbar: filter chips and the sort. */
.ro-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; }
.ro-chips { flex-wrap: wrap; overflow: visible; margin-bottom: 0; }
.ro-sort { display: flex; align-items: center; gap: 8px; }
.ro-sort label { font-size: 13px; font-weight: 600; color: var(--fg-muted); }
.ro-sort select { min-height: 44px; width: auto; }
.ro-intro { margin: 12px 0 0; font-size: 14px; max-width: 70ch; }
.ro-select { margin: 14px 0 10px; gap: 8px; }
.ro-select .button { min-height: 40px; }

/* One card per child. Phone first: tick, photo and name, Open on one line;
   status, then the parent's contact, full width underneath. */
.ro-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.ro-item { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  grid-template-areas: "check child open" "status status status" "contact contact contact" "end end end";
  gap: 8px 10px; align-items: center; padding: 10px 14px 14px 8px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg);
  border-inline-start: 5px solid var(--border-strong); }
.ro-item[data-tone="danger"] { border-inline-start-color: var(--danger); }
.ro-item[data-tone="warning"] { border-inline-start-color: var(--warning); }
.ro-item[data-tone="success"] { border-inline-start-color: var(--success); }
.ro-item:has(.ro-check input:checked) { background: var(--surface-2); box-shadow: 0 0 0 2px var(--primary); }
.ro-check { grid-area: check; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--radius); cursor: pointer; }
.ro-check:hover { background: var(--surface-2); }
.ro-check input { width: 22px; height: 22px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.ro-child { grid-area: child; display: flex; align-items: center; gap: 10px; min-width: 0; }
.ro-child .kid-photo { width: 44px; height: 44px; font-size: 15px; }
.ro-name { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ro-name strong { font-size: 16.5px; line-height: 1.25; overflow-wrap: anywhere; }
.ro-sub { font-size: 13px; color: var(--fg-muted); }
.ro-open { grid-area: open; display: inline-flex; align-items: center; min-height: 44px; padding: 0 8px; font-weight: 600;
  color: var(--primary); text-decoration: underline; text-underline-offset: 3px; border-radius: var(--radius); }
.ro-open:hover { background: var(--primary-soft); color: var(--primary-soft-fg); }
.ro-status { grid-area: status; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; padding-inline-start: 8px; }
.ro-status .badge { font-size: 13px; padding: 3px 10px; }
.ro-detail { flex: 1 1 100%; font-size: 14px; color: var(--fg-muted); line-height: 1.4; }
.ro-flags { display: flex; flex-wrap: wrap; gap: 6px; }
.ro-contact { grid-area: contact; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  margin-inline-start: 8px; padding-top: 10px; border-top: 1px solid var(--border); }
.ro-parent { flex: 1 1 100%; font-weight: 700; font-size: 15px; overflow-wrap: anywhere; }
.ro-phone { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 14px; border-radius: 999px;
  background: var(--primary-soft); color: var(--primary-soft-fg); font-weight: 700; font-size: 15px;
  font-variant-numeric: tabular-nums; text-decoration: none; white-space: nowrap; }
.ro-phone:hover { background: var(--primary); color: var(--primary-fg); }
.ro-none { font-size: 14px; color: var(--fg-muted); }
.ro-email { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; }
.ro-email-text { font-size: 13.5px; color: var(--fg-muted); overflow-wrap: anywhere; min-width: 0; }
.ro-end { grid-area: end; gap: 8px; margin-inline-start: 8px; }
.ro-end .button { min-height: 44px; }

/* The action bar: always in reach at the bottom of the screen. */
.ro-actions { position: sticky; bottom: max(10px, env(safe-area-inset-bottom)); z-index: 6; margin-top: 14px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px;
  padding: 10px 12px; background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.ro-form:has(input[name="ids"]:checked) .ro-actions { border-color: var(--primary); }
.ro-count { margin: 0; font-size: 14px; font-weight: 600; color: var(--fg-muted); }
.ro-form:has(input[name="ids"]:checked) .ro-count { color: var(--fg); }
.ro-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
.ro-buttons .button { min-height: 44px; }
.ro-buttons [data-share][aria-busy="true"] { cursor: progress; }

@media (min-width: 1000px) {
  .ro-item { grid-template-columns: 44px minmax(0, 1.2fr) minmax(0, 1.3fr) minmax(0, 1.3fr) auto;
    grid-template-areas: "check child status contact open" ". end end end end"; row-gap: 0; padding: 10px 14px 10px 8px; }
  .ro-status { padding-inline-start: 0; }
  .ro-contact { margin-inline-start: 0; padding-top: 0; border-top: 0; gap: 4px 10px; }
  .ro-phone { min-height: 36px; font-size: 14px; }
  .ro-end { margin: 10px 0 2px; }
}
@media (max-width: 760px) {
  .ro-toolbar { align-items: stretch; }
  .ro-sort { width: 100%; }
  .ro-sort select { flex: 1; min-width: 0; }
  .ro-actions { padding: 8px; gap: 6px; }
  .ro-count { font-size: 13px; padding-inline: 4px; }
  .ro-buttons { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 1fr); gap: 6px; width: 100%; }
  .ro-buttons .button { padding: 0 8px; gap: 6px; font-size: 13.5px; white-space: normal; text-align: center; line-height: 1.15; }
  .ro-buttons .button svg { flex: none; }
  .ro-select .button { min-height: 44px; }
  .copy-button { min-height: 44px; min-width: 44px; justify-content: center; }
}
@media print { .ro-actions, .ro-select, .ro-sort, .ro-check, .copy-button { display: none !important; } }

/* The print view (coach/roster_print.html): a phone-width column of cards
   on screen, two columns on paper. Light theme always: it is a printout. */
.rp-body { margin: 0; background: var(--bg); color: var(--fg); }
.rp-sheet { max-width: 480px; margin: 0 auto; padding: 14px 14px 40px; }
.rp-head { position: relative; overflow: hidden; background: var(--primary); color: var(--primary-fg);
  border-radius: var(--radius-xl); padding: 18px 18px 20px; }
.rp-head::after { content: ''; position: absolute; inset: auto 0 0 0; height: 4px; background: var(--grad-brand); }
.rp-org { margin: 0 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--primary-soft); }
.rp-head h1 { margin: 0 0 4px; font-size: 26px; line-height: 1.15; color: var(--primary-fg); overflow-wrap: anywhere; }
.rp-scope { margin: 0; font-size: 15px; font-weight: 600; }
.rp-when { margin: 8px 0 0; font-size: 13px; color: var(--primary-soft); }
.rp-counts { list-style: none; margin: 12px 0; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.rp-counts li { display: flex; flex-direction: column; padding: 10px 12px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg); }
.rp-counts strong { font-size: 24px; line-height: 1.15; font-variant-numeric: tabular-nums; }
.rp-counts span { font-size: 13px; color: var(--fg-muted); }
.rp-counts .is-warning { background: var(--warning-soft); border-color: transparent; }
.rp-counts .is-warning strong, .rp-counts .is-warning span { color: var(--warning); }
.rp-counts .is-success { background: var(--success-soft); border-color: transparent; }
.rp-counts .is-success strong, .rp-counts .is-success span { color: var(--success); }
.rp-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 6px; }
.rp-actions .button { flex: 1 1 auto; min-height: 44px; }
.rp-section { margin-top: 14px; }
.rp-section h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 13px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--fg-muted); }
.rp-section h2 span { padding: 1px 8px; border-radius: 999px; background: var(--surface); color: var(--fg); font-size: 12px; letter-spacing: 0; }
.rp-attention { padding: 12px 10px 10px; background: var(--warning-soft); border-radius: var(--radius-xl); }
.rp-attention h2 { color: var(--warning); }
.rp-hint { margin: -4px 0 10px; font-size: 13.5px; color: var(--warning); }
.rp-list { display: grid; gap: 10px; }
.rp-group { margin: 8px 0 0; font-size: 15px; }
.rp-card { background: var(--surface); border: 1px solid var(--border); border-inline-start: 5px solid var(--border-strong);
  border-radius: var(--radius-lg); padding: 14px 14px 12px; break-inside: avoid; }
.rp-card[data-tone="danger"] { border-inline-start-color: var(--danger); }
.rp-card[data-tone="warning"] { border-inline-start-color: var(--warning); }
.rp-card[data-tone="success"] { border-inline-start-color: var(--success); }
.rp-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.rp-card h3 { margin: 0; font-size: 19px; line-height: 1.2; overflow-wrap: anywhere; }
.rp-card .badge { flex: none; margin-top: 1px; font-size: 13px; padding: 3px 10px; }
.rp-sub { margin: 3px 0 0; font-size: 14px; color: var(--fg-muted); }
.rp-detail { margin: 8px 0 0; font-size: 15px; line-height: 1.4; }
.rp-parent { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--border-strong); }
.rp-parent-name { margin: 0 0 6px; font-size: 16px; font-weight: 700; overflow-wrap: anywhere; }
.rp-phone { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; border-radius: 999px;
  background: var(--primary-soft); color: var(--primary-soft-fg); font-size: 17px; font-weight: 700;
  font-variant-numeric: tabular-nums; text-decoration: none; }
.rp-none { margin: 0; font-size: 14px; color: var(--fg-muted); }
.rp-email { margin: 6px 0 0; font-size: 13.5px; color: var(--fg-muted); overflow-wrap: anywhere; }
.rp-flags { display: flex; align-items: center; gap: 6px; margin: 10px 0 0; padding: 8px 10px; border-radius: var(--radius);
  background: var(--warning-soft); color: var(--warning); font-size: 14px; font-weight: 700; }
.rp-foot { margin-top: 24px; padding-top: 12px; border-top: 1px solid var(--border); font-size: 13px; color: var(--fg-muted); }
@media (min-width: 400px) { .rp-counts { grid-template-columns: repeat(4, minmax(0, 1fr)); } .rp-counts span { font-size: 12px; } }
@media print {
  @page { margin: 12mm; }
  .rp-body { background: #fff; }
  .rp-sheet { max-width: none; padding: 0; }
  .rp-actions { display: none !important; }
  .rp-head { background: none; color: var(--fg); border-radius: 0; padding: 0 0 8px; border-bottom: 3px solid var(--primary); }
  .rp-head::after { display: none; }
  .rp-head h1 { color: var(--fg); }
  .rp-org, .rp-when { color: var(--fg-muted); }
  .rp-counts { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .rp-counts li { border-color: #bbb; }
  .rp-attention { padding: 0; background: none; }
  .rp-list { display: block; columns: 2; column-gap: 8mm; }
  .rp-card { display: block; margin: 0 0 4mm; border-color: #bbb; print-color-adjust: exact; -webkit-print-color-adjust: exact; }
  .rp-group { break-after: avoid; column-span: none; }
  .rp-phone { min-height: 0; padding: 0; background: none; color: var(--fg); font-size: 15px; }
}

/* The coach's pages at 390px: every tap target 44px, nothing wider than the screen. */
@media (max-width: 760px) {
  .chips a, .tally-item.alert { min-height: 44px; }
  .tally-item.alert { align-items: center; }
  .day-pick input[type=date] { min-height: 44px; }
  .session-options summary { display: flex; align-items: center; min-height: 44px; }
  .coach-head { align-items: center; }
  .kid-card { min-height: 44px; }
  .profile-hero .cluster .button, .photo-form .button { min-height: 44px; }
  .stacked-form .button, .stacked-form button[type=submit], .session-options .button { min-height: 44px; }
  .back-link { display: inline-flex; align-items: center; min-height: 44px; }
}
.flag-list { padding-inline-start: 0; }
/* The coaches' follow-ups on a phone: one block per child, not a table to scroll sideways. */
@media (max-width: 760px) {
  .ro-followups { padding: 4px 16px; }
  .ro-followups table, .ro-followups tbody, .ro-followups tr, .ro-followups th, .ro-followups td { display: block; width: 100%; min-width: 0; }
  .ro-followups thead { display: none; }
  .ro-followups tr { padding: 12px 0; border-bottom: 1px solid var(--border); }
  .ro-followups tr:last-child { border-bottom: 0; }
  .ro-followups th, .ro-followups td { padding: 3px 0; border: 0; white-space: normal; }
  .ro-followups th a { font-size: 16px; }
  .ro-followups .inline-resolve button { min-height: 44px; }
  .ro-followups td .text-link { display: inline-flex; align-items: center; min-height: 44px; }
}

/* -- 16  Version pill (D-37) -- */
/* The deployed version in the administration header: a small pill that opens
   into the release notes. Native <details>, like the account menu. On a phone
   the panel becomes a full-width sheet under the top bar. */
.version-pill > summary::-webkit-details-marker { display: none; }
.version-pill-button {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 32px; padding: 0 12px; border-radius: 999px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border-strong);
  color: var(--fg); font-size: 12.5px; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: .01em; white-space: nowrap;
}
.version-pill-button:hover { background: var(--surface-2); }
.version-pill[open] > .version-pill-button { background: var(--surface-2); border-color: var(--primary); }
.version-pill-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--primary); flex: none; }
.version-pill-dot.dev { background: var(--warning); }
/* A small chevron says "this opens"; it turns when it has. */
.version-pill-button::after, .version-earlier > summary::after {
  content: ''; flex: none; width: 6px; height: 6px; margin-inline-start: 1px;
  border-inline-end: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform .15s ease;
}
.version-pill[open] > .version-pill-button::after,
.version-earlier[open] > summary::after { transform: translateY(1px) rotate(-135deg); }
.version-panel {
  position: absolute; inset-inline-end: 0; top: calc(100% + 8px); z-index: 50;
  width: 380px; max-height: min(72vh, 560px); overflow-y: auto; overscroll-behavior: contain;
  padding: 16px; text-align: start;
  background: var(--surface); color: var(--fg);
  border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
}
.version-panel-head { padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--border); }
.version-panel-version { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.version-panel-meta { margin: 0; font-size: 12.5px; color: var(--fg-muted); }
.version-panel-meta code { font-size: 12px; padding: 1px 5px; }
.version-panel-title { margin: 0 0 6px; font-size: 14px; font-weight: 650; line-height: 1.35; }
.version-panel-notes { margin: 0; padding-inline-start: 18px; font-size: 13px; line-height: 1.5; color: var(--fg-muted); }
.version-panel-notes li + li { margin-top: 5px; }
.version-panel-label {
  margin: 16px 0 6px; font-size: 11.5px; font-weight: 700; letter-spacing: .07em;
  text-transform: uppercase; color: var(--fg-subtle);
}
.version-earlier { border-top: 1px solid var(--border); }
.version-earlier:last-of-type { border-bottom: 1px solid var(--border); }
.version-earlier > summary {
  display: flex; align-items: center; gap: 8px; padding: 9px 6px; cursor: pointer; list-style: none;
  font-size: 13px; color: var(--fg); border-radius: var(--radius-sm);
}
.version-earlier > summary::-webkit-details-marker { display: none; }
.version-earlier > summary::after { margin-inline-start: auto; color: var(--fg-muted); }
.version-earlier > summary:hover { background: var(--surface-2); }
.version-earlier[open] > summary { font-weight: 600; }
.version-earlier > .version-panel-meta { margin: 2px 6px 6px; }
.version-earlier > .version-panel-notes { margin: 0 6px 10px; }
.version-earlier-number { flex: none; font-weight: 700; font-variant-numeric: tabular-nums; }
.version-earlier-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.version-earlier[open] .version-earlier-title { white-space: normal; }
.version-panel-link {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 14px; min-height: 32px;
  font-size: 13.5px; font-weight: 600; color: var(--primary); text-decoration: none;
}
.version-panel-link:hover { color: var(--primary-hover); text-decoration: underline; }

@media (max-width: 760px) {
  /* The panel anchors to the top bar, not the pill, and spans the screen. */
  .version-pill.menu { position: static; }
  .version-pill-button { min-height: 36px; padding: 0 10px; gap: 6px; }
  .version-panel {
    top: 100%; inset-inline: 8px; width: auto; max-height: min(calc(100dvh - 150px), 640px);
    border-radius: var(--radius); margin-top: 4px;
  }
  .version-earlier > summary, .version-panel-link { min-height: 44px; }
}
@media (max-width: 480px) {
  /* Room for the page title: the pill drops its dot and tightens. */
  .version-pill-dot { display: none; }
  .version-pill-button { padding: 0 9px; font-size: 12px; }
}

/* The release history on /staff/version/: one card per release, newest first. */
.release-commit { margin: 10px 0 0; font-size: 13px; color: var(--fg-muted); }
.release-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.release-card {
  padding: 16px 18px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
}
.release-card.current { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary), var(--shadow); }
.release-head { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-bottom: 4px; }
.release-version { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
.release-date { font-size: 13px; color: var(--fg-muted); font-variant-numeric: tabular-nums; }
.release-title { margin: 0 0 8px; font-size: 16px; line-height: 1.35; }
.release-notes { margin: 0; padding-inline-start: 20px; font-size: 14px; line-height: 1.55; color: var(--fg-muted); }
.release-notes li + li { margin-top: 6px; }

/* -- 17  Parent reminders (D-37) -- */
/* The roster's "Email parents" button, and the review page before a payment
   reminder goes (templates/coach/remind.html). The button needs no script:
   it appears once a ticked child is one that needs attention. */
.ro-buttons .ro-remind { display: none; }
.ro-form:has(.ro-item[data-attention] input[name="ids"]:checked) .ro-buttons .ro-remind { display: inline-flex; }
@media (max-width: 760px) { .ro-buttons .ro-remind { grid-column: 1 / -1; } }

.rm-heading { margin: 0 0 10px; }
.rm-lock strong { color: var(--fg); }
.rm-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.rm-parent { padding: 14px 16px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); border-inline-start: 5px solid var(--warning); min-width: 0; }
.rm-recent { border-inline-start-color: var(--info); }
.rm-who { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.rm-who strong { font-size: 15.5px; }
.rm-email { font-size: 13.5px; color: var(--fg-muted); overflow-wrap: anywhere; }
.rm-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-inline-start: auto; }
.rm-kids { list-style: none; margin: 10px 0 0; padding: 10px 0 0; border-top: 1px solid var(--border); display: grid; gap: 8px; }
.rm-kids li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.rm-kid { font-weight: 600; }
.rm-owed { flex-basis: 100%; font-size: 14px; color: var(--fg); }
.rm-source { color: var(--fg-muted); font-size: 13px; }
.rm-again { display: flex; gap: 10px; align-items: flex-start; margin: 12px 0 0; padding: 10px 12px; min-height: 44px;
  border-radius: 10px; background: var(--info-soft); color: var(--fg); font-size: 14px; font-weight: 400; cursor: pointer; }
.rm-again input { width: 20px; height: 20px; margin: 1px 0 0; flex: none; }
.rm-skipped h2 { margin: 0 0 8px; }
.rm-skip-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.rm-skip-list li { display: grid; gap: 2px; padding: 8px 0; border-top: 1px solid var(--border); }
.rm-skip-list li:first-child { border-top: 0; padding-top: 0; }
.rm-skip-list span { font-size: 14px; color: var(--fg-muted); }
.rm-placeholders { margin-top: 10px; }
.rm-cannot { margin: 0; max-width: 40ch; }
@media (min-width: 1000px) {
  .rm-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 760px) {
  .rm-badges { margin-inline-start: 0; flex-basis: 100%; }
  .rm-parent { padding: 12px; }
}

/* -- 18  Roster gaps (D-38) -- */
/* Paid places with no child named, on top of the staff roster: one compact
   row per parent with a call button (or "No phone: email instead"), the
   email with its copy button, and a link to the member. */
.gap-card { padding: 14px 16px; border-inline-start: 5px solid var(--warning); }
.gap-title { margin: 0 0 4px; font-size: 17px; line-height: 1.3; }
.gap-intro { margin: 0 0 10px; font-size: 14px; color: var(--fg-muted); line-height: 1.45; max-width: 70ch; }
.gap-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.gap-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 14px;
  padding: 10px 0; border-top: 1px solid var(--border); min-width: 0; }
.gap-who { display: grid; gap: 2px; min-width: 0; }
.gap-name { font-weight: 600; font-size: 15.5px; }
.gap-places { font-size: 13.5px; color: var(--fg-muted); }
.gap-contact { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-width: 0; }
.gap-nophone { display: inline-flex; align-items: center; min-height: 32px; padding: 0 10px; border-radius: 999px;
  background: var(--warning-soft); color: var(--warning); font-size: 13.5px; font-weight: 600; }
/* On every child card it repeats, so it is quieter there: an outline, not a fill. */
.ro-contact .gap-nophone { background: transparent; color: var(--fg-muted); border: 1px dashed var(--border); font-weight: 500; }
/* "Missed 3 sessions in a row": informative on the staff roster, quieter on the coach's sheet. */
.streak-chip { font-size: 12.5px; }
.streak-chip.subtle { background: transparent; color: var(--fg-muted); border: 1px solid var(--border); font-weight: 500; }
/* Contributions: how many draft or open invoices are hidden, and the switch. */
.pay-pending { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 12px 0; font-size: 14px; color: var(--fg-muted); }
.pay-pending-text { max-width: 60ch; }
@media (max-width: 760px) {
  .gap-card { padding: 12px; }
  .gap-row { align-items: flex-start; }
  .gap-contact { flex-basis: 100%; }
}

/* -- 19  Member experience (D-40) -- */
/* "What needs your attention" on the member overview, the billing page's one
   list of what a family pays for, and the payments list a parent reads on a
   phone. Owed things carry a warning edge; the all-paid-up line is calm. */
.attention-panel { margin: 0 0 20px; padding: 18px 20px; border-inline-start: 5px solid var(--border-strong); }
.attention-panel.is-owed { border-inline-start-color: var(--warning); }
.attention-panel.is-note { border-inline-start-color: var(--warning); }
.attention-panel.is-calm { border-inline-start-color: var(--success); padding: 12px 16px; }
.attention-panel h2 { margin: 0 0 8px; }
.attention-panel .attention-sub { margin: 16px 0 0; padding-top: 14px; border-top: 1px solid var(--border); font-size: 15px; }
.attention-list, .attention-notes { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.attention-list > li, .attention-notes > li { padding: 12px 0; border-top: 1px solid var(--border); min-width: 0; }
.attention-list > li:first-child { border-top: 0; padding-top: 4px; }
.attention-what { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 12px; }
.attention-what strong { font-size: 16.5px; line-height: 1.35; }
.attention-amount { font-weight: 600; white-space: nowrap; }
.attention-when { margin: 4px 0 0; color: var(--fg-muted); font-size: 14.5px; line-height: 1.5; }
.attention-do { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); display: grid; gap: 8px; }
.attention-do p { margin: 0; }
.attention-do .cluster { display: flex; flex-wrap: wrap; gap: 8px; }
.attention-calm { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.attention-calm svg { color: var(--success); }
.attention-notes > li { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.attention-notes > li p { margin: 2px 0 0; font-size: 14px; }
.attention-notes > li:first-child { border-top: 0; }

.bill-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.bill-row { padding: 16px 18px; border-inline-start: 5px solid var(--success); }
.bill-row.bill-owed { border-inline-start-color: var(--danger); }
.bill-row.bill-ending { border-inline-start-color: var(--warning); }
.bill-row.bill-ended { border-inline-start-color: var(--border-strong); }
.bill-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: flex-start; gap: 6px 12px; }
.bill-head h3 { margin: 0; font-size: 17px; line-height: 1.35; }
.bill-head .cell-sub { display: block; }
.bill-state { margin: 8px 0 0; font-size: 14.5px; line-height: 1.5; }
.bill-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px 16px; margin: 12px 0 0; }
.bill-facts dt { font-size: 12.5px; color: var(--fg-muted); }
.bill-facts dd { margin: 2px 0 0; font-weight: 600; }
.bill-foot { display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; margin-top: 12px; }

.pay-list { list-style: none; margin: 0; padding: 0; }
.pay-item { display: grid; grid-template-columns: 1fr auto; gap: 2px 12px; padding: 12px 0; border-top: 1px solid var(--border); }
.pay-item:first-child { border-top: 0; }
.pay-what { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.pay-amount { font-weight: 600; text-align: end; white-space: nowrap; }
.pay-meta { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; font-size: 13.5px; color: var(--fg-muted); }
.child-owed { margin: 6px 0; font-weight: 600; }
/* The inbox is a list of cards, not a bulleted list. */
ul.message-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.pay-totals { display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: baseline; }
@media (max-width: 760px) {
  .attention-panel { padding: 14px; }
  .bill-row { padding: 14px; }
  .attention-notes > li { flex-direction: column; }
}

/* -- 20  Staff control (D-40) -- */
/* T-409: the member list's quick filters and selection, the compose screen's
   delivery summary, "Add a person", the contact card and the plain-words
   history on the member page. Tokens only; phone first. */
.quick-filters { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 100%; border: 0; margin: 0; padding: 0; }
.filter-chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border: 1px solid var(--border-strong); border-radius: 999px; font-size: 13.5px; background: var(--surface); cursor: pointer; }
.filter-chip:has(input:checked) { background: var(--primary-soft); color: var(--primary-soft-fg); border-color: var(--primary); }
.filter-chip input { margin: 0; }
.bulk-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 12px 0; }
.col-pick { width: 36px; text-align: center; }
.col-pick input { width: 18px; height: 18px; margin: 0; }

.msg-who { margin-bottom: 16px; }
.msg-audience, .msg-template { align-items: flex-end; }
.msg-audience .field, .msg-template .field { margin: 0; flex: 1 1 220px; }
.msg-count { margin: 10px 0 0; font-size: 14.5px; }
.msg-plan { padding: 14px 16px; border: 1px solid var(--border); border-radius: var(--radius, 10px); background: var(--bg); }
.msg-plan h3 { margin: 0 0 6px; font-size: 15px; }
.msg-lock { margin: 0 0 8px; padding: 8px 12px; border-inline-start: 4px solid var(--warning); background: var(--warning-soft); font-size: 14px; }
.msg-plan-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.msg-plan-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.msg-recipients th { font-weight: 600; }
.msg-list > summary { cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.msg-list > summary h2 { margin: 0; display: inline; }
.msg-list[open] > summary { margin-bottom: 10px; }

.person-form { display: grid; gap: 16px; max-width: 880px; }
.person-step h2 { display: flex; align-items: center; gap: 10px; margin: 0 0 12px; }
.person-step h2 .muted { font-size: 13px; font-weight: 400; }
.step-no { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--primary); color: var(--primary-fg); font-size: 14px; }
.person-child-row { display: grid; grid-template-columns: 2fr 1fr; gap: 0 12px; }

.contact-card { margin: 0 0 18px; display: grid; gap: 10px; }
.contact-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; }
.contact-action { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; min-height: 48px; border: 1px solid var(--border); border-radius: var(--radius, 10px); color: var(--fg); text-decoration: none; min-width: 0; }
a.contact-action:hover { border-color: var(--primary); background: var(--primary-soft); color: var(--primary-soft-fg); }
.contact-action.is-missing { border-style: dashed; color: var(--fg-muted); }
.contact-label { font-size: 12px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: .04em; }
.contact-email { overflow-wrap: anywhere; font-weight: 600; }
.contact-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin: 0; font-size: 14px; color: var(--fg-muted); }
.contact-family p { margin: 0 0 6px; }
.chip-list { list-style: none; margin: 0 0 6px; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.chip { padding: 4px 10px; border-radius: 999px; background: var(--info-soft); color: var(--fg); font-size: 13.5px; }

.member-history h2 { margin-bottom: 4px; }
.history-since { margin: 0 0 4px; font-size: 16px; }
.origin-tag { display: inline-block; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--border-strong); color: var(--fg-muted); font-size: 11.5px; font-weight: 600; vertical-align: middle; }
.sub-list { list-style: none; margin: 8px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.sub-item { padding: 12px 14px; border: 1px solid var(--border); border-inline-start: 4px solid var(--success); border-radius: var(--radius, 10px); background: var(--surface); display: grid; gap: 4px; }
.sub-item.is-failing { border-inline-start-color: var(--danger); }
.sub-item.is-ended { border-inline-start-color: var(--border-strong); }
.sub-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sub-name { overflow-wrap: anywhere; }
.year-group { border: 1px solid var(--border); border-radius: var(--radius, 10px); background: var(--surface); margin-top: 8px; }
.year-group > summary { padding: 10px 14px; cursor: pointer; }
.hist-pays { list-style: none; margin: 0; padding: 0 14px 8px; }
.hist-pays li { display: grid; grid-template-columns: 56px 1fr auto; gap: 2px 12px; align-items: baseline; padding: 8px 0; border-top: 1px solid var(--border); }
.hist-pays li .origin-tag { grid-column: 2 / -1; justify-self: start; }
.hist-pay-when { color: var(--fg-muted); font-size: 13px; }
.hist-pay-what { min-width: 0; overflow-wrap: anywhere; }
.hist-pay-amount { text-align: end; font-weight: 600; white-space: nowrap; }
.timeline-entry.kind-message::before { border-color: var(--info); }
.timeline-entry.kind-subscription::before { border-color: var(--primary); }
.timeline-entry.kind-flag::before { border-color: var(--danger); }
.contact-action .copy-button { align-self: flex-start; margin-top: 4px; }
/* Only the household field that applies to the choice made is shown. */
.person-form:not(:has(input[name="household_mode"][value="existing"]:checked)) .field:has(#id_household) { display: none; }
.person-form:not(:has(input[name="household_mode"][value="new"]:checked)) .field:has(#id_household_name) { display: none; }
@media (max-width: 760px) {
  .person-child-row { grid-template-columns: 1fr 110px; }
  .contact-actions { grid-template-columns: 1fr 1fr; }
  .contact-action:has(.contact-email), .contact-action.is-missing { grid-column: 1 / -1; }
  .msg-plan { padding: 12px; }
}

/* -- 21  Staff fixes: programme enrolments at phone width -- */
/* /staff/programs/<slug>/: six columns do not fit 390px, and scrolling
   sideways hid Status and Rate, the two a coordinator came for. Below 560px
   each enrolment becomes a card: the household on top, then one labelled
   line per column (labels from data-label, so nothing is duplicated). */
@media (max-width: 560px) {
  .enrol-table { overflow: visible; border: 0; background: transparent; }
  .enrol-table table, .enrol-table tbody, .enrol-table tr,
  .enrol-table tbody th, .enrol-table td { display: block; width: 100%; }
  .enrol-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .enrol-table tr {
    border: 1px solid var(--border); border-radius: var(--radius-lg);
    background: var(--surface); padding: 12px 14px; margin-bottom: 10px;
  }
  .enrol-table tbody tr:hover { background: var(--surface); }
  .enrol-table tbody th, .enrol-table td { padding: 4px 0; border-top: 0; }
  .enrol-table tbody th { padding-bottom: 8px; }
  .enrol-table td {
    display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 10px;
    align-items: baseline; text-align: start;
  }
  .enrol-table td::before {
    content: attr(data-label); color: var(--fg-muted);
    font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  }
  .enrol-table td.num { text-align: start; }
  .enrol-table td .cell-sub { grid-column: 2; }
}

/* -- 23  Member exports (agent X) -- */
/* /staff/members/: "Export these N: CSV · PDF", one group that wraps as a
   unit on a phone rather than splitting its label from its buttons. */
.export-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.export-label { font-size: 13px; font-weight: 600; color: var(--fg-muted); }
@media (max-width: 480px) { .export-group { width: 100%; } }

/* -- 24  Gap fixes (agent G) -- */
/* Contributions: one action per line in the Details cell (classify or mark
   as a loan repayment, refund), each a comfortable tap target on a phone. */
.pay-links { display: inline-flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.pay-links a { min-height: 24px; display: inline-flex; align-items: center; }
/* Member page payment history: the "Mark as loan repayment" link. */
.hist-pay-what .hist-pay-fix { display: inline-block; margin-top: 2px; color: var(--primary, inherit); text-decoration: underline; }
/* Stripe follow-up list: the no-phone marker sits on its own line. */
.cell-sub .gap-nophone { margin: 4px 6px 2px 0; min-height: 26px; }

/* -- 22  Roster layouts: phone or full page (agent P) -- */
/* The same roster in two shapes: "Phone" (the card list, § 14) and "Full
   page", a landscape table with more columns for a computer and a printer
   (coach/roster_print_compact.html). First the choice in the roster's action
   bar: a label and two joined buttons, Print and PDF. */
.rl-choice { display: inline-flex; align-items: stretch; overflow: hidden; background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.rl-choice-label { display: inline-flex; align-items: center; gap: 6px; padding: 0 10px; background: var(--surface-2);
  color: var(--fg-muted); font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  border-inline-end: 1px solid var(--border); white-space: nowrap; }
.ro-buttons .rl-choice .button, .rl-choice .button { min-height: 44px; padding: 0 14px; border: 0; border-radius: 0;
  background: var(--surface); color: var(--fg); }
.rl-choice .button + .button { border-inline-start: 1px solid var(--border); }
.rl-choice .button:hover { background: var(--primary-soft); color: var(--primary-soft-fg); }
.rl-choice .button:focus-visible { position: relative; z-index: 1; }
.rl-choice:first-child { border-color: var(--primary); }
.rl-choice:first-child .rl-choice-label { background: var(--primary); color: var(--primary-fg); border-color: var(--primary); }
@media (max-width: 760px) {
  .ro-buttons { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .ro-buttons .rl-choice { min-width: 0; }
  .ro-buttons .rl-choice-label { padding: 0 7px; font-size: 10.5px; letter-spacing: .04em; }
  .ro-buttons .rl-choice-label svg { display: none; }
  .ro-buttons .rl-choice .button { flex: 1 1 0; min-width: 0; padding: 0 5px; }
  .ro-buttons [data-share] { grid-column: 1 / -1; }
}

/* A layout switch on the print pages: two links as one segmented control. */
.rl-seg { display: inline-flex; overflow: hidden; background: var(--surface);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); }
.rl-seg a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 14px;
  color: var(--fg); font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.rl-seg a + a { border-inline-start: 1px solid var(--border); }
.rl-seg a:hover { background: var(--surface-2); }
.rl-seg a[aria-current="page"] { background: var(--primary-soft); color: var(--primary-soft-fg); box-shadow: inset 0 -3px 0 var(--primary); }
.rp-actions .rl-seg { flex: 1 1 100%; }
.rp-actions .rl-seg a { flex: 1; }

/* The full-page table. On screen: a wide sheet that scrolls sideways on a
   phone. On paper: landscape (the page size is set in the template), about
   7.6 pt, one line per child, the headings repeated on every page. */
.rl-body { margin: 0; background: var(--bg); color: var(--fg); }
.rl-sheet { max-width: 1320px; margin: 0 auto; padding: 18px 20px 40px; }
.rl-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 24px;
  padding-bottom: 12px; border-bottom: 3px solid transparent; border-image: var(--grad-brand) 1; }
.rl-title { min-width: 0; }
.rl-org { margin: 0 0 2px; color: var(--primary); font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.rl-head h1 { margin: 0; font-size: 24px; line-height: 1.15; overflow-wrap: anywhere; }
.rl-meta { margin: 4px 0 0; color: var(--fg-muted); font-size: 13px; }
.rl-counts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.rl-counts li { display: flex; flex-direction: column; min-width: 92px; padding: 6px 10px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius); }
.rl-counts strong { font-size: 20px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.rl-counts span { color: var(--fg-muted); font-size: 11.5px; }
.rl-counts .is-warning { background: var(--warning-soft); border-color: transparent; }
.rl-counts .is-warning strong, .rl-counts .is-warning span { color: var(--warning); }
.rl-counts .is-success { background: var(--success-soft); border-color: transparent; }
.rl-counts .is-success strong, .rl-counts .is-success span { color: var(--success); }
.rl-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 12px 0; }
.rl-actions .button { min-height: 44px; }
.rl-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.rl-table { width: 100%; border-collapse: collapse; font-size: 12.5px; line-height: 1.3; font-variant-numeric: tabular-nums; }
.rl-table th, .rl-table td { padding: 5px 7px; text-align: start; vertical-align: middle; border-bottom: 1px solid var(--border); }
/* One line per child: only Notes wraps (the sheet scrolls sideways on a narrow screen). */
.rl-table tbody td, .rl-table tbody th { white-space: nowrap; }
.rl-table tbody .rl-notes, .rl-section th { white-space: normal; }
.rl-table thead th { position: sticky; top: 0; z-index: 1; background: var(--surface-2); color: var(--fg-muted);
  font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap;
  border-bottom: 2px solid var(--primary); }
.rl-table a { color: inherit; text-decoration: none; }
.rl-row.is-zebra { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
.rl-row > :first-child { box-shadow: inset 3px 0 0 var(--border-strong); }
.rl-row[data-tone="success"] > :first-child { box-shadow: inset 3px 0 0 var(--brand-green); }
.rl-row[data-tone="warning"] > :first-child { box-shadow: inset 3px 0 0 #e08a1e; }
.rl-row[data-tone="danger"] > :first-child { box-shadow: inset 3px 0 0 var(--brand-red); }
.rl-row[data-tone="success"][data-flagged] > :first-child { box-shadow: inset 3px 0 0 #e08a1e; }
.rl-table .rl-n { width: 2.6em; color: var(--fg-muted); text-align: end; }
.rl-table .rl-c { text-align: center; }
.rl-table .rl-tick { width: 26px; text-align: center; }
.rl-box { display: inline-block; width: 12px; height: 12px; vertical-align: middle; background: var(--surface);
  border: 1.5px solid var(--fg-muted); border-radius: 3px; }
.rl-table .rl-name { font-weight: 700; white-space: nowrap; }
.rl-pill { display: inline-block; padding: 1px 8px; border-radius: 999px; background: var(--surface-2); color: var(--fg-muted);
  font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.rl-row[data-tone="success"] .rl-pill { background: var(--success-soft); color: var(--success); }
.rl-row[data-tone="warning"] .rl-pill { background: var(--warning-soft); color: var(--warning); }
.rl-row[data-tone="danger"] .rl-pill { background: var(--danger-soft); color: var(--danger); }
.rl-nowrap { white-space: nowrap; }
.rl-table .rl-email { color: var(--fg-muted); font-size: 12px; overflow-wrap: anywhere; }
.rl-table .rl-notes { min-width: 12em; color: var(--fg-muted); font-size: 11.5px; }
.rl-flag { color: var(--warning); font-weight: 700; }
.rl-section th { padding: 6px 8px; background: var(--surface-2); color: var(--fg); font-size: 11px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; }
.rl-section[data-tone="warning"] th { background: var(--warning-soft); color: var(--warning); }
.rl-section-count { display: inline-block; margin-inline-start: 6px; padding: 0 7px; border-radius: 999px;
  background: var(--surface); color: var(--fg); letter-spacing: 0; }
.rl-section-hint { margin-inline-start: 8px; color: var(--fg-muted); font-weight: 500; letter-spacing: 0; text-transform: none; }
.rl-unnamed { margin-top: 14px; padding: 10px 14px; background: var(--warning-soft); border-radius: var(--radius-lg); }
.rl-unnamed h2 { margin: 0; color: var(--warning); font-size: 12px; letter-spacing: .06em; text-transform: uppercase; }
.rl-unnamed p { margin: 2px 0 6px; color: var(--fg-muted); font-size: 13px; }
.rl-unnamed ul { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; font-size: 13px; }
.rl-unnamed a { color: inherit; text-decoration: none; }
.rl-foot { margin-top: 16px; color: var(--fg-muted); font-size: 12px; }
.rl-foot p { margin: 0 0 4px; }
@media print {
  .rl-body { background: #fff; }
  .rl-sheet { max-width: none; padding: 0; }
  .rl-actions { display: none !important; }
  .rl-head { gap: 6px 16px; padding-bottom: 5pt; border-bottom-width: 2px; }
  .rl-org { font-size: 7pt; }
  .rl-head h1 { font-size: 15pt; }
  .rl-meta { margin-top: 1pt; font-size: 8pt; }
  .rl-counts { gap: 5pt; }
  .rl-counts li { min-width: 0; padding: 2pt 7pt; }
  .rl-counts strong { font-size: 12pt; }
  .rl-counts span { font-size: 6.5pt; }
  .rl-wrap { overflow: visible; margin-top: 5pt; background: none; border: 0; border-radius: 0; }
  .rl-table { font-size: 7.6pt; line-height: 1.15; }
  .rl-table th, .rl-table td { padding: 1.2pt 2.6pt; border-bottom-width: .5pt; }
  .rl-table thead { display: table-header-group; }
  .rl-table thead th { position: static; padding: 3pt 2.6pt; font-size: 6.2pt; letter-spacing: .02em; white-space: normal;
    border-bottom-width: 1pt; }
  .rl-table .rl-email { font-size: 6.6pt; }
  .rl-table .rl-notes { min-width: 0; font-size: 6.8pt; }
  .rl-row { break-inside: avoid; }
  .rl-pill { padding: 0 4pt; font-size: 7pt; line-height: 1.25; }
  .rl-box { width: 8pt; height: 8pt; border-width: .8pt; border-radius: 1.5pt; }
  .rl-section th { padding: 2.5pt 3pt; font-size: 7pt; }
  .rl-unnamed { margin-top: 6pt; padding: 4pt 6pt; break-inside: avoid; }
  .rl-unnamed h2 { font-size: 7pt; }
  .rl-unnamed p, .rl-unnamed ul { font-size: 7.5pt; }
  .rl-foot { margin-top: 6pt; font-size: 6.5pt; }
  .rl-foot p:first-child { display: none; }   /* the page footer says it on every page */
  .rl-head, .rl-counts li, .rl-table, .rl-unnamed { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* -- 26  Members: email and print by category (agent M2) -- */
/* /staff/members/: category chips (counts, the dashboard's definitions), the
   Email and Print-or-export action groups, an Email button per row; the
   compose screen's template picker; the print page (members_print.html). */
.category-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 4px 0 12px; }
.category-chip { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 14px;
  border: 1px solid var(--border-strong); border-radius: 999px; background: var(--surface); color: var(--fg);
  font-size: 14px; font-weight: 600; text-decoration: none; white-space: nowrap; }
.category-chip:hover { background: var(--surface-2); }
.category-chip.is-on { background: var(--primary); border-color: var(--primary); color: var(--primary-fg); }
.category-count { min-width: 1.6em; padding: 1px 7px; border-radius: 999px; background: var(--surface-2); color: var(--fg-muted);
  font-size: 12.5px; font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; }
.category-chip.is-on .category-count { background: color-mix(in srgb, var(--primary-fg) 22%, transparent); color: var(--primary-fg); }
.category-clear { font-size: 13.5px; }
.category-hint { margin: -4px 0 12px; color: var(--fg-muted); font-size: 13.5px; }
.members-actions { display: flex; flex-wrap: wrap; align-items: stretch; gap: 10px 14px; margin: 12px 0; }
.members-actions .action-group { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 8px 10px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.members-actions .action-group:first-of-type { border-color: var(--primary); }
.members-actions .action-label { display: inline-flex; align-items: center; gap: 6px; color: var(--fg-muted);
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.members-actions .action-sub { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding-inline-start: 8px; border-inline-start: 1px solid var(--border); color: var(--fg-muted); font-size: 13px; }
/* Nothing ticked (agent Z): a dashed rule and the muted token, never opacity,
   which would drop the label below AA (test_design_tokens.OpacityTests). The
   buttons inside are [disabled] and fade by themselves. */
.members-actions .action-sub.is-idle { border-inline-start-style: dashed; color: var(--fg-muted); }
.members-actions button[disabled] { cursor: not-allowed; opacity: .55; }
.col-email { width: 1%; white-space: nowrap; }
.col-email .button { min-height: 34px; }
@media (max-width: 560px) {
  .category-chips { flex-wrap: nowrap; overflow-x: auto; margin-inline: -16px; padding: 2px 16px 6px; scrollbar-width: none; }
  .category-chips::-webkit-scrollbar { display: none; }
  .members-actions .action-group { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); width: 100%; }
  .members-actions .action-label, .members-actions .action-group > .cell-sub { grid-column: 1 / -1; }
  .members-actions .action-group:first-of-type > .button { grid-column: 1 / -1; }
  .members-actions .action-sub { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    padding: 8px 0 0; border-inline-start: 0; border-top: 1px solid var(--border); }
  .members-actions .action-sub-label { grid-column: 1 / -1; }
  .members-actions .button { justify-content: center; min-height: 42px; }
}

/* The compose screen: the template picker comes first and large. */
.msg-picker { border-color: var(--primary); }
.msg-picker .card-head h2 { margin: 0; }
.msg-picker-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 12px; }
.msg-picker-form .field { margin: 0; flex: 0 1 150px; }
.msg-picker-form .msg-picker-main { flex: 1 1 280px; }
.msg-picker-form select { min-height: 46px; font-size: 15.5px; }
.msg-picker-form .button { min-height: 46px; }

/* The print page: a clean landscape table; the head repeats on every sheet. */
.mp-body { margin: 0; background: var(--bg); color: var(--fg); }
.mp-sheet { max-width: 1320px; margin: 0 auto; padding: 18px 20px 40px; }
.mp-head { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px 20px; padding-bottom: 12px;
  border-bottom: 3px solid transparent; border-image: var(--grad-brand) 1; }
.mp-logo { align-self: center; width: 48px; height: 48px; object-fit: contain; }
.mp-title { flex: 1 1 320px; min-width: 0; }
.mp-org { margin: 0 0 2px; color: var(--primary); font-size: 11.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.mp-head h1 { margin: 0; font-size: 24px; line-height: 1.15; }
.mp-meta { margin: 4px 0 0; color: var(--fg-muted); font-size: 13px; }
.mp-filters { margin: 2px 0 0; color: var(--fg); font-size: 13px; }
.mp-counts { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.mp-counts li { display: flex; flex-direction: column; min-width: 88px; padding: 6px 10px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius); }
.mp-counts strong { font-size: 20px; line-height: 1.1; font-variant-numeric: tabular-nums; }
.mp-counts span { color: var(--fg-muted); font-size: 11.5px; }
.mp-counts .is-success { background: var(--success-soft); border-color: transparent; }
.mp-counts .is-success strong, .mp-counts .is-success span { color: var(--success); }
.mp-counts .is-danger { background: var(--danger-soft); border-color: transparent; }
.mp-counts .is-danger strong, .mp-counts .is-danger span { color: var(--danger); }
.mp-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 12px 0; }
.mp-actions .button { min-height: 44px; }
.mp-wrap { overflow-x: auto; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); }
.mp-table { width: 100%; border-collapse: collapse; font-size: 12.5px; line-height: 1.3; font-variant-numeric: tabular-nums; }
.mp-table th, .mp-table td { padding: 5px 7px; text-align: start; vertical-align: top; border-bottom: 1px solid var(--border); }
.mp-table thead th { background: var(--surface-2); color: var(--fg-muted); font-size: 10.5px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; border-bottom: 2px solid var(--primary); }
.mp-table thead .mp-running th { display: none; }
.mp-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--surface-2) 55%, var(--surface)); }
.mp-table tbody th { font-weight: 400; }
.mp-name { display: block; font-weight: 700; }
.mp-sub { display: block; color: var(--fg-muted); font-size: 11px; }
.mp-n { width: 2.6em; color: var(--fg-muted); text-align: end; }
.mp-tick { width: 22px; text-align: center; }
.mp-box { display: inline-block; width: 12px; height: 12px; vertical-align: middle; border: 1.5px solid var(--fg-muted); border-radius: 3px; }
.mp-email { overflow-wrap: anywhere; }
.mp-phone { white-space: nowrap; }
.mp-state { display: inline-block; padding: 1px 8px; border-radius: 999px; background: var(--surface-2); color: var(--fg-muted);
  font-size: 11.5px; font-weight: 700; white-space: nowrap; }
.mp-state.is-success { background: var(--success-soft); color: var(--success); }
.mp-state.is-warning { background: var(--warning-soft); color: var(--warning); }
.mp-state.is-danger { background: var(--danger-soft); color: var(--danger); }
.mp-foot { margin-top: 14px; color: var(--fg-muted); font-size: 12px; }
@media print {
  .mp-body { background: #fff; }
  .mp-sheet { max-width: none; padding: 0; }
  .mp-actions, .mp-foot { display: none !important; }
  .mp-head { gap: 6px 14px; padding-bottom: 5pt; border-bottom-width: 2px; }
  .mp-logo { width: 30pt; height: 30pt; }
  .mp-org { font-size: 7pt; }
  .mp-head h1 { font-size: 15pt; }
  .mp-meta, .mp-filters { margin-top: 1pt; font-size: 8pt; }
  .mp-counts { gap: 5pt; }
  .mp-counts li { min-width: 0; padding: 2pt 7pt; }
  .mp-counts strong { font-size: 12pt; }
  .mp-counts span { font-size: 6.5pt; }
  .mp-wrap { overflow: visible; margin-top: 5pt; background: none; border: 0; border-radius: 0; }
  .mp-table { font-size: 7.8pt; line-height: 1.2; }
  .mp-table th, .mp-table td { padding: 1.6pt 2.8pt; border-bottom-width: .5pt; }
  .mp-table thead { display: table-header-group; }
  .mp-table thead .mp-running th { display: table-cell; padding: 0 0 3pt; background: none; color: #46536b; border: 0;
    font-size: 6.8pt; letter-spacing: .03em; text-align: end; }
  .mp-table thead tr:not(.mp-running) th { padding: 3pt 2.8pt; font-size: 6.4pt; white-space: normal; border-bottom-width: 1pt; }
  .mp-table tbody tr { break-inside: avoid; page-break-inside: avoid; }
  .mp-sub { font-size: 6.6pt; }
  .mp-state { padding: 0 4pt; font-size: 7pt; line-height: 1.25; }
  .mp-box { width: 8pt; height: 8pt; border-width: .8pt; border-radius: 1.5pt; }
  .mp-head, .mp-counts li, .mp-table, .mp-state { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
}

/* -- 25  Roster: email parents, columns, child notes and contact (agent R2) -- */
/* Owner's notes, Oct 3. The roster's action bar gains "Email parents:
   Message | Payment reminder" for any selection (or the whole view), and a
   "Columns" chooser for Print, PDF and Share; the print pages carry the same
   chooser; the child page gains "Contact the parent" and staff notes. */
.ro-buttons .pm-choice .button { background: var(--surface); }
.pm-choice .pm-message, .pm-choice .pm-remind { font-weight: 600; }
@media (max-width: 760px) { .ro-buttons .pm-choice { grid-column: 1 / -1; } }

/* Columns: a quiet disclosure; open, a grid of checkboxes. */
.rc-cols { margin-top: 12px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); }
.rc-cols > summary { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 44px; padding: 0 12px;
  cursor: pointer; font-size: 14px; font-weight: 600; color: var(--fg); }
.rc-cols > summary svg { flex: none; color: var(--fg-muted); }
.rc-cols-state { font-weight: 500; color: var(--fg-muted); font-size: 13px; }
.rc-cols[data-changed] { border-color: var(--warning); }
.rc-cols[data-changed] .rc-cols-state { color: var(--fg); }
.rc-cols-form { margin: 0; }
.rc-cols-body { display: grid; gap: 10px; padding: 4px 12px 12px; border-top: 1px solid var(--border); }
.rc-cols-set { margin: 0; padding: 0; border: 0; min-width: 0; }
.rc-cols-legend { padding: 8px 0 6px; font-size: 13px; color: var(--fg-muted); }
.rc-cols-boxes { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px; }
.rc-cols-box { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 10px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm); font-size: 14px; cursor: pointer; }
.rc-cols-box input { width: 18px; height: 18px; margin: 0; flex: none; }
.rc-cols-box:has(input:checked) { background: var(--primary-soft); border-color: var(--primary); color: var(--primary-soft-fg); }
.rc-cols-hint { margin: 0; font-size: 12.5px; color: var(--fg-muted); }
.rc-cols-body > .button { justify-self: start; }
.rc-cols-note { font-weight: 600; }
.rp-actions .rc-cols, .rl-actions .rc-cols { flex: 1 1 100%; margin-top: 0; }
.rc-schedule-cols #id_columns { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px 12px; }
@media (max-width: 480px) { .rc-cols-boxes { grid-template-columns: 1fr 1fr; } }
@media print { .rc-cols { display: none !important; } }

/* The child page: "Contact the parent". Email works; text and WhatsApp are
   shown, switched off, and say so in words (no SMS/WhatsApp is sent, D-31). */
.pc-card { display: grid; gap: 10px; }
.pc-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; }
.pc-head h2 { margin: 0; font-size: 18px; }
.pc-who { display: flex; flex-wrap: wrap; gap: 2px 12px; margin: 0; overflow-wrap: anywhere; }
.pc-detail { color: var(--fg-muted); font-size: 14px; }
.pc-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; }
.pc-action { min-height: 48px; justify-content: center; flex-wrap: wrap; gap: 2px 6px; text-align: center; }
.pc-action.is-off { cursor: not-allowed; background: var(--surface-2); color: var(--fg-muted); border-style: dashed; }
.pc-soon { flex-basis: 100%; font-size: 11.5px; font-weight: 600; color: var(--fg-muted); }
.pc-note { margin: 0; font-size: 13.5px; color: var(--fg-muted); }

/* Staff notes on a child, in the Follow-ups and Attendance column. */
.cn-intro { margin: 2px 0 8px; font-size: 13px; color: var(--fg-muted); }
.cn-form { display: grid; gap: 8px; margin-bottom: 10px; }
.cn-form textarea { width: 100%; min-height: 64px; resize: vertical; }
.cn-form .button { justify-self: start; }
.cn-list { list-style: none; margin: 0 0 18px; padding: 0; display: grid; gap: 8px; }
.cn-item { padding: 10px 12px; background: var(--surface-2); border: 1px solid var(--border); border-inline-start: 3px solid var(--info);
  border-radius: var(--radius-sm); }
.cn-body { margin: 0; overflow-wrap: anywhere; }
.cn-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin: 4px 0 0; font-size: 12.5px; color: var(--fg-muted); }
.cn-delete { display: inline; margin: 0 0 0 auto; }
.cn-delete .button { min-height: 32px; }

/* A coach's open flag on a roster card reads as a flag from the coach, not
   as a second status beside "Paid" (agent Q2's finding 8). */
.ro-coach-flag { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600;
  color: var(--warning); }
.ro-coach-flag svg { flex: none; }

/* -- 27  Round-2 fixes: member chips that add up, settled coach flags (agent Z) -- */
/* /staff/members/: the first chip row adds up to "Everyone" (an "=" before
   it); the second row ("Within these:") looks across the first. */
.category-sum { color: var(--fg-muted); font-size: 18px; font-weight: 700; padding: 0 2px; }
.category-chips.category-within { margin-top: -4px; gap: 6px; }
.category-within .category-chip { min-height: 34px; padding: 0 11px; font-size: 13px; font-weight: 600;
  border-style: dashed; }
.category-within .category-chip.is-on { border-style: solid; }
.category-within-label { color: var(--fg-muted); font-size: 12.5px; font-weight: 700; white-space: nowrap; }
/* A coach asked about payment, but the records show the child paid up: a
   note for the office, in the muted ink, not the warning colour of a flag. */
.ro-coach-note { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--fg-muted); }
.ro-coach-note svg { flex: none; }
.rp-flag-note { margin: 4px 0 0; color: var(--fg-muted); font-size: 13px; }

/* -- 28  Roster schedule: people outside the portal (agent SC) -- */
/* The "People outside the portal" rows on /staff/roster/<slug>/schedule/.
   The form sits in a narrow column, so each person takes two lines at every
   width: the name, then the email with Remove beside it. Tokens only. */
.sc-external .helptext { max-width: 72ch; }
.sc-external .sc-external-rows { list-style: none; margin: 8px 0 12px; padding: 0; display: grid; gap: 14px; }
.sc-external-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 8px; align-items: center; }
.sc-external-row label { display: block; min-width: 0; }
.sc-external-row .sc-external-name { grid-column: 1 / -1; }
.sc-external-row .sc-external-email input { letter-spacing: 0; }
.sc-external-row input { width: 100%; min-width: 0; }
.sc-outside ul { list-style: none; margin: 6px 0 4px; padding: 0; display: grid; gap: 6px; }
.sc-outside li { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 14px; }
.sc-outside li > span { min-width: 0; overflow-wrap: anywhere; }
.sc-outside summary { cursor: pointer; }

/* -- 29  Roster columns: "Summarized_details" (agent PN) -- */
/* The owner's one-tick choice under the column boxes (roster page, print
   pages, schedule form): set apart by a hairline, its helper text beneath. */
.rc-cols-preset { display: grid; gap: 4px; padding-top: 10px; border-top: 1px dashed var(--border); }
.rc-cols-preset .rc-cols-box { justify-self: start; min-width: 150px; font-weight: 600; }
.rc-cols-preset .rc-cols-hint { padding-left: 2px; }
.rc-schedule-cols .rc-cols-preset { margin-top: 10px; }
.rc-schedule-cols .rc-cols-preset .field { margin: 0; }
.rc-schedule-cols .rc-cols-preset label { font-weight: 600; }
