/* ZoeziZone web theme — light and dark.
 *
 * Palette: Radix Colors (MIT), vendored in tokens.css, which must load first.
 * This file turns those 12-step scales into ROLES, then styles components in
 * terms of the roles only. No component rule may name a scale step directly
 * and no rule may hardcode a hex — either would stop following the theme.
 *
 * WHY RADIX. It is the only openly-licensed system that ships a designed
 * 12-step scale with matching light and dark values under identical variable
 * names, as plain CSS with no build step. But its contrast guarantee is APCA,
 * not WCAG, so four corrections are applied below and each is marked. These
 * pages take M-Pesa payments and are read outdoors on cheap screens; the AA
 * floor is not negotiable, and it must hold in BOTH modes.
 *
 * WHY THESE PATTERNS. From published practice rather than taste:
 *  - Khan Academy (same hardware profile, MIT design system) treats
 *    "not started" as a first-class NEUTRAL state in a three-state progress
 *    scale. This product's honesty bar says the same thing — "not started",
 *    never "weak" — so .state.new is grey, never red, never zero.
 *  - Nielsen Norman's lower-literacy research: these users do not scan, they
 *    read word by word and lose their place when they scroll. Hence single
 *    column, linear nav, the point at the top.
 *  - GOV.UK: one thing per page, and the focus state below.
 *
 * COLOUR SEMANTICS, and they do not overlap:
 *    green  — the brand, and "yes": paid, active, mastered, published.
 *    amber  — attention and "in progress".
 *    red    — danger and refusal only. Never decoration.
 *    blue   — links and neutral information.
 *    sand   — everything else. A warm neutral, because the app it belongs to
 *             is warm; a grey page would disown the product.
 */

/* ---------------------------------------------------------------------------
   Type. Gabarito carries the headings — geometric, warm, a little quirky in
   the g and a — and Public Sans does the reading, because it was drawn for
   government text at small sizes and this site is mostly forms and tables.
   Both variable, latin only, self-hosted: 61KB for the pair.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: Gabarito;
  src: url('/static/fonts/gabarito-var.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Public Sans";
  src: url('/static/fonts/public-sans-var.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
}

/* ===========================================================================
   ROLES
   Bare :root defines every role, so nothing is ever undefined. The media
   query and the attribute only ever REDEFINE. The :not() guard breaks the
   0-1-0 specificity tie so an explicit Light choice beats a dark OS.
   This and tokens.css are the ONLY two places prefers-color-scheme appears.

   THE DIRECTION, taken from the school-admin dashboard the client chose as
   the reference:
     * white ground -- not grey, not cream, not a dark chrome bar;
     * ONE accent, green, doing every job that needs emphasis: the active nav
       item, the selected row, the primary button, a link;
     * no borders. Separation is whitespace, a pale green tint, and a soft
       wide shadow. Gridlines in particular are gone;
     * generous row heights and padding. The reference breathes, and that is
       most of why it reads as considered;
     * large radius on cards, full pill on buttons and badges.

   The green was already this product's brand, so the reference does not
   impose a palette -- it tells us to stop hedging it with a second accent.

   ONE PLACE THE REFERENCE IS NOT COPIED. Its selected row is a bright
   saturated green carrying white text, which lands near 3:1. These pages
   take M-Pesa payments and are read outdoors on cheap screens, so filled
   green is a deeper green here: white on it measures 5.38:1. The freshness
   comes from the pale tints instead, which cost nothing in contrast.

   WHY LITERAL HEX. These roles no longer map onto a vendored Radix scale.
   The rule that COMPONENT rules may never name a hex still stands -- that is
   what keeps the theme switchable. This is the role layer, where values
   belong, and every role is defined in all three blocks so none can go
   undefined in one mode.

   EVERY PAIR IS MEASURED: test_theme_modes.py resolves this file against
   tokens.css and fails under 4.5:1 for text, 3.0:1 for state-bearing
   borders, in BOTH modes.
   =========================================================================== */

:root {
  color-scheme: light;

  --surface:        #ffffff;   /* the ground is white, like the reference */
  --surface-raised: #ffffff;
  --surface-sunk:   #f2f7f4;
  --surface-zebra:  #f5faf7;   /* the pale green table stripe */

  --border:         #edf1ef;   /* almost never drawn; a fallback, not a device */
  --border-strong:  #78877f;   /* state-bearing, >=3:1 */

  --text:           #17211d;
  --text-2:         #5c6b63;

  --link:           #0e6f4a;
  --brand:          #0e6f4a;

  --brand-bg:       #0e7a4b;   /* filled green: white on it is 5.38:1 */
  --brand-fg:       #ffffff;
  --danger-bg:      #b42318;
  --danger-fg:      #ffffff;

  --ok-bg:          #e8f7ef;
  --ok-text:        #0b4a2f;
  --ok-line:        #34c77b;
  --notice-bg:      #fff6e5;
  --notice-text:    #4a3208;
  --notice-line:    #d69e2e;
  --danger-tint:    #feeceb;
  --danger-text:    #7a1610;
  --danger-line:    #d9534f;
  --info-bg:        #eaf0fb;
  --info-text:      #1b3a73;

  --on-amber:       var(--amber-12);

  /* The accent at low opacity: nav hover, row hover, the active pill. */
  --accent-wash:    #eaf6f0;
  --accent-wash-2:  #dff0e7;

  --overlay-hover:  rgb(14 122 75 / 0.06);
  --overlay-press:  rgb(14 122 75 / 0.11);

  /* Soft and wide. Elevation is a suggestion, never an outline. */
  --shadow-card:  0 1px 2px rgb(16 40 28 / 0.03), 0 10px 30px rgb(16 40 28 / 0.06);
  --shadow-lift:  0 2px 6px rgb(16 40 28 / 0.05), 0 20px 48px rgb(16 40 28 / 0.10);

  --font-display: Gabarito, "Segoe UI", system-ui, sans-serif;
  --font-body: "Public Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, monospace;

  --climb: linear-gradient(100deg, #0e7a4b 0%, #34c77b 100%);
  --accent: #0e7a4b;
  --glow: color-mix(in srgb, #34c77b 18%, transparent);

  --dot: rgb(14 122 75 / 0.05);

  --arr-bg:      #ffffff;
  --arr-glow-a:  color-mix(in srgb, #34c77b 12%, transparent);
  --arr-glow-b:  color-mix(in srgb, #0e7a4b 7%, transparent);
  --float-bg:    #ffffff;
  --float-line:  #edf1ef;
  --float-shadow: 0 2px 6px rgb(16 40 28 / .05), 0 28px 60px rgb(16 40 28 / .10);
  --pill-bg:     #eaf6f0;
  --pill-line:   transparent;
  --pill-fg:     #0e6f4a;
  --field-bg:    #ffffff;
  --field-line:  #e2e8e5;
  --on-climb:    #ffffff;

  --panel-bg:     #0b1a12;
  --panel-fg:     #ffffff;
  --panel-dim:    #9fb5a9;
  --panel-kicker: #4ade9b;
  --panel-accent: #4ade9b;
  --panel-glow:   color-mix(in srgb, #34c77b 18%, transparent);

  --pad: clamp(1rem, 4vw, 1.75rem);
  --radius: 16px;
  --radius-sm: 10px;
  --radius-pill: 999px;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --surface:        #0f1512;
    --surface-raised: #151d19;
    --surface-sunk:   #0a0f0d;
    --surface-zebra:  #131b17;

    --border:         #223029;
    --border-strong:  #6d7d74;

    --text:           #eef3f0;
    --text-2:         #98a89f;

    --link:           #4ade9b;
    --brand:          #4ade9b;

    --brand-bg:       #22c07a;
    --brand-fg:       #06120c;
    --danger-bg:      #c4443a;
    --danger-fg:      #ffffff;

    --ok-bg:          #0d2a1c;
    --ok-text:        #6ee7b7;
    --ok-line:        #2f9e68;
    --notice-bg:      #2a2008;
    --notice-text:    #f4ce85;
    --notice-line:    #b8871c;
    --danger-tint:    #2a1210;
    --danger-text:    #f6aba5;
    --danger-line:    #c4443a;
    --info-bg:        #10192b;
    --info-text:      #a6c4f5;

    --accent-wash:    #13251c;
    --accent-wash-2:  #17301f;

    --overlay-hover:  rgb(74 222 155 / 0.10);
    --overlay-press:  rgb(74 222 155 / 0.16);

    --shadow-card: none;
    --shadow-lift: 0 24px 56px rgb(0 0 0 / 0.5);
    --dot: rgb(74 222 155 / 0.05);

    --climb: linear-gradient(100deg, #4ade9b 0%, #a7f3d0 100%);
    --accent: #4ade9b;
    --glow: color-mix(in srgb, #4ade9b 16%, transparent);

    --arr-bg:      #0f1512;
    --arr-glow-a:  color-mix(in srgb, #4ade9b 12%, transparent);
    --arr-glow-b:  color-mix(in srgb, #22c07a 8%, transparent);
    --float-bg:    #151d19;
    --float-line:  #223029;
    --float-shadow: 0 28px 60px rgb(0 0 0 / 0.5);
    --pill-bg:     #13251c;
    --pill-line:   transparent;
    --pill-fg:     #4ade9b;
    --field-bg:    #151d19;
    --field-line:  #2a3a32;
    --on-climb:    #06120c;

    --panel-bg:    #0a0f0d;
    --panel-dim:   #98a89f;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --surface:        #0f1512;
  --surface-raised: #151d19;
  --surface-sunk:   #0a0f0d;
  --surface-zebra:  #131b17;

  --border:         #223029;
  --border-strong:  #6d7d74;

  --text:           #eef3f0;
  --text-2:         #98a89f;

  --link:           #4ade9b;
  --brand:          #4ade9b;

  --brand-bg:       #22c07a;
  --brand-fg:       #06120c;
  --danger-bg:      #c4443a;
  --danger-fg:      #ffffff;

  --ok-bg:          #0d2a1c;
  --ok-text:        #6ee7b7;
  --ok-line:        #2f9e68;
  --notice-bg:      #2a2008;
  --notice-text:    #f4ce85;
  --notice-line:    #b8871c;
  --danger-tint:    #2a1210;
  --danger-text:    #f6aba5;
  --danger-line:    #c4443a;
  --info-bg:        #10192b;
  --info-text:      #a6c4f5;

  --accent-wash:    #13251c;
  --accent-wash-2:  #17301f;

  --overlay-hover:  rgb(74 222 155 / 0.10);
  --overlay-press:  rgb(74 222 155 / 0.16);

  --shadow-card: none;
  --shadow-lift: 0 24px 56px rgb(0 0 0 / 0.5);
  --dot: rgb(74 222 155 / 0.05);

  --climb: linear-gradient(100deg, #4ade9b 0%, #a7f3d0 100%);
  --accent: #4ade9b;
  --glow: color-mix(in srgb, #4ade9b 16%, transparent);

  --arr-bg:      #0f1512;
  --arr-glow-a:  color-mix(in srgb, #4ade9b 12%, transparent);
  --arr-glow-b:  color-mix(in srgb, #22c07a 8%, transparent);
  --float-bg:    #151d19;
  --float-line:  #223029;
  --float-shadow: 0 28px 60px rgb(0 0 0 / 0.5);
  --pill-bg:     #13251c;
  --pill-line:   transparent;
  --pill-fg:     #4ade9b;
  --field-bg:    #151d19;
  --field-line:  #2a3a32;
  --on-climb:    #06120c;

  --panel-bg:    #0a0f0d;
  --panel-dim:   #98a89f;
}

/* ===========================================================================
   BASE
   =========================================================================== */

* { box-sizing: border-box; }

html {
  /* Explicit, so the UA canvas never shows through in the wrong colour. */
  background: var(--surface);
}

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.55;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3 {
  font-family: var(--font-display);
  margin: 0 0 0.6rem; line-height: 1.15; text-wrap: balance; font-weight: 700;
}
h1 { font-size: clamp(1.75rem, 1.3rem + 2vw, 2.6rem); letter-spacing: -0.025em; }
h2 { font-size: clamp(1.2rem, 1.1rem + 0.4vw, 1.35rem); margin-top: 1.8rem; }
h3 { font-size: 1.05rem; margin-top: 1.3rem; }
.card > h1:first-child, .card > h2:first-child, .card > h3:first-child { margin-top: 0; }

/* Line length capped for readability; lower-literacy readers lose their place
   on long measures. */
p, li { margin: 0 0 0.8rem; max-width: 68ch; }
ul, ol { padding-left: 1.3rem; }
a { color: var(--link); text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }
strong { font-weight: 700; }
hr { border: 0; height: 1px; background: var(--border); margin: 1.6rem 0; }
.note, .muted, .meta { color: var(--text-2); font-size: 0.9375rem; }

::selection { background: var(--brand-bg); color: var(--brand-fg); }

/* Correction 4: GOV.UK's focus state. Radix's own focus step measures
   1.86-2.34 against a light ground — a WCAG 1.4.11 failure. Neither half of
   this works alone (yellow on light is 1.31:1); the black bar is what makes
   it carry on any background, in either mode. */
/* GOV.UK's focus states, and the distinction I first missed: the yellow
   FILL is their treatment for links and buttons. Applied to a text field it
   turns the field itself yellow and buries what the user is typing. Fields
   get the yellow RING with a dark inner border instead. */
a:focus-visible, button:focus-visible, .button:focus-visible,
summary:focus-visible, [role="button"]:focus-visible {
  outline: 3px solid transparent;
  background-color: #ffdd00;
  box-shadow: 0 -2px #ffdd00, 0 4px #0b0c0c;
  color: #0b0c0c;
  text-decoration: none;
}
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: 3px solid #ffdd00; outline-offset: 0;
  border-color: var(--text);
  box-shadow: inset 0 0 0 1px var(--text);
  background: var(--surface-raised);
}

.skip-link {
  position: absolute; left: -9999px;
  padding: 0.6rem 1rem; background: #ffdd00; color: #0b0c0c; font-weight: 700;
}
.skip-link:focus { left: 0; top: 0; z-index: 10; }

/* ===========================================================================
   SHELL — single column, linear nav
   =========================================================================== */

header.site {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: 0.7rem var(--pad);
  /* The cover. Ink in both modes, so the masthead is the one thing that does
     NOT flip with the theme -- a bound book keeps its cover either way, and
     it gives the page a constant edge to start from. */
  background: var(--cover);
  color: var(--cover-fg);
  border-bottom: 3px solid var(--rule);
}
header.site a.wordmark {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-size: 1.15rem; font-weight: 700; letter-spacing: -0.015em;
  color: var(--cover-fg); text-decoration: none;
}
/* THE SIGNATURE.
   One Z read as a path: three legs, start, climb, arrive — the Journey map
   the child already uses, not a letter. Ruled in the brand doc (one Z, never
   ZZ: Zzz means sleep, and Kenya says "zed"). It is the only place this
   design raises its voice; everything around it stays quiet. */
.zmark { width: 1.75rem; height: 1.75rem; flex: none; display: block; }
.zmark .leg  { stroke: currentColor; stroke-width: 2.6; stroke-linecap: round;
               stroke-linejoin: round; fill: none; }
.zmark .stop { fill: currentColor; }
.zmark .arrive { fill: var(--accent); }

header.site a.wordmark .zmark {
  color: var(--brand-fg);
  padding: 0.28rem; box-sizing: content-box;
  width: 1.2rem; height: 1.2rem;
  border-radius: var(--radius-sm);
  background-image: var(--climb);
  box-shadow: 0 2px 10px var(--glow);
}
header.site .who { color: var(--cover-dim); font-size: 0.875rem; }
/* Site-wide top navigation, on the cover with the wordmark. */
header.site .topnav { display: flex; align-items: center; gap: 0.2rem 1rem; flex-wrap: wrap; font-size: 0.875rem; margin-left: auto; }
header.site .topnav a, header.site .topnav button {
  color: var(--cover-dim); text-decoration: none; background: none; border: 0; padding: 0.15rem 0;
  font: inherit; font-size: 0.875rem; cursor: pointer; border-bottom: 2px solid transparent; border-radius: 0;
}
header.site .topnav a:hover, header.site .topnav button:hover, header.site .topnav a.active { color: #fff; border-bottom-color: var(--accent); background: none; box-shadow: none; transform: none; }
header.site .topnav-form { display: inline; margin: 0; }
footer.site .footlinks { margin-top: 0.6rem; }
/* A pressed submit button while the request is in flight. */
button.is-loading, .button.is-loading { position: relative; color: transparent !important; pointer-events: none; }
button.is-loading::after, .button.is-loading::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 1.1em; height: 1.1em; margin: -0.55em 0 0 -0.55em;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%;
  color: var(--text); animation: zz-spin 0.7s linear infinite;
}
button.pay.is-loading::after, button.primary.is-loading::after { color: #fff; }
@keyframes zz-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { button.is-loading::after, .button.is-loading::after { animation: none; border-right-color: currentColor; opacity: 0.5; } }
/* Roles at sign-in: every role the account holds, the active one marked. */
.roles-strip { list-style: none; display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0; margin: 0.75rem 0 0.25rem; }
.roles-strip .badge { font-size: 0.8125rem; padding: 0.35rem 0.7rem; }
.roles-strip .role-active { background: var(--accent); color: #fff; border-color: var(--accent); }
.roles-strip .role-switch { display: inline; margin: 0; }
.roles-strip .role-other { cursor: pointer; }
header.site .who-more { opacity: 0.75; font-size: 0.8125rem; }

aside { background: var(--surface-raised); border-bottom: 1px solid var(--border); }
nav { display: flex; overflow-x: auto; scrollbar-width: none; padding: 0 max(0px, calc(var(--pad) - 0.75rem)); }
nav::-webkit-scrollbar { display: none; }
nav a {
  flex: 0 0 auto; padding: 0.7rem 0.75rem;
  color: var(--text-2); text-decoration: none;
  font-weight: 600; font-size: 0.9375rem; white-space: nowrap;
  border-bottom: 3px solid transparent;
}
nav a:hover { color: var(--text); background: var(--overlay-hover); }
nav a.active { color: var(--brand); border-bottom-color: transparent; position: relative; }
nav a.active::after {
  content: ""; position: absolute; inset: auto 0.75rem 0 0.75rem; height: 3px;
  background-image: var(--climb); border-radius: 3px 3px 0 0;
}

main { width: min(46rem, 100%); margin: 0 auto; padding: clamp(1.25rem, 4vw, 2rem) var(--pad) 2.5rem; }
main.wide { width: min(72rem, 100%); }


/* Appearance: three joined segments in the masthead. A plain form, so it
   still works with JavaScript disabled — the whole reason the theme is
   applied server-side in the first place. */
.appearance {
  display: inline-flex; margin: 0; padding: 2px; gap: 2px;
  background: var(--surface-sunk);
  border: 1px solid var(--border); border-radius: 999px;
}
.appearance button {
  display: grid; place-items: center;
  margin: 0; padding: 0; min-height: 0;
  width: 1.95rem; height: 1.95rem; border-radius: 999px;
  background: transparent; color: var(--text-3);
  border: 0; box-shadow: none;
}
.appearance button svg { width: 1rem; height: 1rem; }
.appearance button:hover { background: var(--overlay-hover); color: var(--text); transform: none; box-shadow: none; }
.appearance button[aria-pressed="true"] {
  background: var(--surface-raised); color: var(--brand);
  box-shadow: 0 1px 2px rgb(0 0 0 / .08);
}

/* The footer is now one quiet line of links, centred under the page. */
footer.site {
  width: min(46rem, 100%); margin: 0 auto;
  padding: 1.5rem var(--pad) 2.5rem; text-align: center;
  color: var(--text-3); font-size: 0.875rem;
}
footer.site p { margin: 0 auto; max-width: none; }
footer.site a { color: var(--text-2); text-decoration: none; }
footer.site a:hover { color: var(--text); text-decoration: underline; }

/* ===========================================================================
   CARDS, TILES
   =========================================================================== */

.card {
  position: relative;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1.2rem 1.3rem;
  margin: 0 0 1rem;
  box-shadow: var(--shadow-card);
}
/* A hairline of the climb along the top edge — visible, not shouted. */
.card.featured::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 3px;
  border-radius: var(--radius) var(--radius) 0 0;
  background-image: var(--climb);
}
.card.featured { border-color: var(--brand-bg); overflow: hidden; }

.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr)); gap: 0.75rem; }
.tile {
  background: var(--surface-raised); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 0.8rem 0.9rem;
}
.tile .big, .tile .value {
  display: block; font-size: 1.6rem; font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.tile .label { display: block; color: var(--text-2); font-size: 0.8125rem; }
/* Role chooser on the sign-in page: tiles that are links, one per role. */
.role-group { font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-2); margin: 1.1rem 0 0.4rem; }
.tiles.roles { margin-bottom: 0.25rem; }
a.tile.role { display: block; text-decoration: none; color: inherit; }
a.tile.role .big { font-size: 1.1rem; }
a.tile.role:hover, a.tile.role:focus-visible { border-color: var(--accent); background: var(--surface-hover, var(--surface-raised)); }

.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1rem; }
.stack { display: grid; gap: 1rem; }

/* ===========================================================================
   FORMS — one thing per page, generous targets
   =========================================================================== */

label { display: block; margin: 1.25rem 0 0.4rem; font-weight: 600;
        font-size: 0.875rem; color: var(--text); }
/* A hint belongs with its field, not adrift after it. */
label + input + .muted, label + select + .muted, label + textarea + .muted,
.password-field + .muted { margin: 0.4rem 0 0; font-size: 0.8125rem; }
label.check {
  display: flex; align-items: flex-start; gap: 0.55rem;
  font-weight: 400; font-size: 1rem;
}

input, select, textarea {
  /* `font: inherit` covers neither of these, and both inherit — a control
     inside a styled label would otherwise render the user's typed text in
     the label's casing and tracking. */
  text-transform: none; letter-spacing: normal;
  width: 100%; max-width: 100%; font: inherit; font-size: 1.0625rem;
  min-height: 2.9rem;                        /* comfortably over the 44px bar */
  padding: 0.7rem 0.85rem; margin: 0;
  color: var(--text);
  /* Recessed against the card it sits in, so a field reads as somewhere to
     put something rather than as another panel. */
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  border-radius: 10px;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
/* The native select arrow was the last thing here that looked like somebody
   else's design. */
select {
  appearance: none; padding-right: 2.6rem;
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 55%, calc(100% - 0.8rem) 55%;
  background-size: 0.36rem 0.36rem, 0.36rem 0.36rem;
  background-repeat: no-repeat;
}
input::placeholder, textarea::placeholder { color: var(--text-3); opacity: 1; }
input:hover, select:hover, textarea:hover { border-color: var(--border-strong); }
input:disabled, select:disabled, textarea:disabled { opacity: 0.55; cursor: not-allowed; }
textarea { min-height: 8rem; resize: vertical; }
input[type="checkbox"], input[type="radio"] {
  width: 1.15rem; height: 1.15rem; min-height: 0; flex: none;
  margin: 0.2rem 0 0; padding: 0; accent-color: var(--brand-bg);
}

.password-field { position: relative; display: block; }
.password-field input { padding-right: 3rem; }
.password-field .reveal {
  position: absolute; right: 0.45rem; top: 50%; transform: translateY(-50%);
  display: grid; place-items: center;
  margin: 0; min-height: 0; width: 2.1rem; height: 2.1rem; padding: 0;
  background: transparent; color: var(--text-2);
  border: 0; border-radius: 8px;
}
.password-field .reveal svg { width: 1.15rem; height: 1.15rem; }
/* One attribute drives the swap, so the script stays a one-liner. */
.password-field .reveal .i-eye-off { display: none; }
.password-field .reveal[aria-pressed="true"] .i-eye { display: none; }
.password-field .reveal[aria-pressed="true"] .i-eye-off { display: block; }
.password-field .reveal[aria-pressed="true"] { color: var(--brand); }
.password-field .reveal:hover { background: var(--overlay-hover); color: var(--text); }

/* ===========================================================================
   BUTTONS
   =========================================================================== */

button, .button {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem;
  margin-top: 1rem; min-height: 2.75rem; padding: 0.65rem 1.15rem;
  font: inherit; font-size: 1rem; font-weight: 600;
  color: var(--brand-fg); background: var(--brand-bg);
  border: 1px solid transparent; border-radius: var(--radius-sm);
  text-decoration: none; cursor: pointer;
}
button, .button { transition: transform .12s ease, box-shadow .18s ease, background .18s ease; }
button:hover, .button:hover {
  background: color-mix(in srgb, var(--brand-bg) 88%, #000);
  box-shadow: 0 3px 14px var(--glow); transform: translateY(-1px);
}
button:active, .button:active { transform: none; box-shadow: none; }
button:disabled, .button.disabled { opacity: 0.5; cursor: not-allowed; }

button.pay, .button.pay { background: var(--brand-bg); color: var(--brand-fg); }

button.ghost, .button.ghost {
  background: transparent; color: var(--text);
  border-color: var(--border-strong);
}
button.ghost:hover, .button.ghost:hover { background: var(--overlay-hover); }

button.danger, .button.danger { background: var(--danger-bg); color: var(--danger-fg); }
button.danger:hover, .button.danger:hover { background: color-mix(in srgb, var(--danger-bg) 88%, #000); }

form.inline { display: inline; margin: 0; }
form.inline button { margin-top: 0; }

.links { display: flex; flex-wrap: wrap; gap: 0.75rem 1.25rem; margin-top: 1.1rem; font-size: 0.9375rem; }

/* ===========================================================================
   MESSAGES
   =========================================================================== */

.error, .success, .flash, .callout, .warn-money {
  padding: 0.8rem 0.95rem; margin: 0 0 1rem;
  border: 1px solid; border-left-width: 4px; border-radius: var(--radius-sm);
  font-size: 1rem;
}
.error, .success, .flash, .callout, .warn-money { }
.error   { background: var(--danger-tint); border-color: var(--danger-line); color: var(--danger-text); }
.success,
.flash   { background: var(--ok-bg);      border-color: var(--ok-line);     color: var(--ok-text); }
.callout { background: var(--notice-bg);  border-color: var(--notice-line); color: var(--notice-text); }

/* The M-Pesa PIN warning. It sits beside the button that triggers the
   prompt, never below the fold — a parent who has tapped Buy has stopped
   reading. */
.warn-money { background: var(--notice-bg); border-color: var(--notice-line); color: var(--notice-text); }
.error > :last-child, .success > :last-child, .flash > :last-child,
.callout > :last-child, .warn-money > :last-child { margin-bottom: 0; }
.error a, .success a, .flash a, .callout a, .warn-money a { color: inherit; }

/* ===========================================================================
   STATES — three of them, because "not started" is not "weak"
   =========================================================================== */

.badge, .state {
  display: inline-block; padding: 0.15rem 0.5rem;
  font-family: var(--font-body);   /* never inherit a display face into these */
  font-size: 0.8125rem; font-weight: 600; white-space: nowrap;
  border-radius: 999px; border: 1px solid;
  background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-text);
}
.badge.ok,   .state.ok   { background: var(--ok-bg);     border-color: var(--ok-line);     color: var(--ok-text); }
.badge.warn, .state.warn { background: var(--notice-bg); border-color: var(--notice-line); color: var(--notice-text); }
.badge.bad,  .state.bad  { background: var(--danger-tint); border-color: var(--danger-line); color: var(--danger-text); }
/* Khan's third state, and this product's honesty bar: not started is
   neutral. Never red, never a zero. */
.badge.dim,  .state.dim,
.badge.new,  .state.new  { background: var(--surface-sunk); border-color: var(--border); color: var(--text-2); }

.dot {
  display: inline-block; width: 0.7rem; height: 0.7rem; border-radius: 999px;
  margin-right: 0.35rem; vertical-align: baseline;
  border: 1px solid var(--text);   /* the swatch alone rarely clears 3:1 */
}

code, .code, .hash {
  font-family: var(--font-mono); font-size: 0.9em;
  background: var(--surface-sunk); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.05rem 0.35rem;
  overflow-wrap: anywhere;
}
.hash { display: block; padding: 0.5rem 0.6rem; font-size: 0.8125rem; color: var(--text-2); }
td.hash { display: table-cell; border: 0; border-bottom: 1px solid var(--border); background: transparent; }

/* ===========================================================================
   TABLES
   =========================================================================== */

.table-wrap, .scroll { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; background: var(--surface-raised); }
.table-wrap table, .scroll table, .card table {
  border: 1px solid var(--border); border-radius: var(--radius);
}
th, td { text-align: left; padding: 0.6rem 0.7rem; vertical-align: top; border-bottom: 1px solid var(--border); font-size: 0.9375rem; }
th {
  background: var(--surface-sunk); color: var(--text-2);
  font-size: 0.8125rem; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:nth-child(even) td { background: var(--surface-zebra); }
td.wrap, th.wrap { white-space: normal; }
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

dl { display: grid; grid-template-columns: max-content 1fr; gap: 0.4rem 1rem; margin: 0.8rem 0 1.2rem; }
dt { font-weight: 600; color: var(--text-2); }
dd { margin: 0; }

fieldset {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 0.9rem 1rem; margin: 1rem 0;
}
legend { padding: 0 0.4rem; font-weight: 700; font-size: 0.9375rem; }

.preview {
  background: var(--surface); border: 1px solid var(--border-strong);
  border-left: 4px solid var(--brand-bg);
  border-radius: var(--radius); padding: 1rem; margin: 1rem 0;
}

/* ===========================================================================
   RESPONSIVE, MOTION, PRINT, FORCED COLOURS
   =========================================================================== */

@media (max-width: 700px) {
  body { font-size: 1rem; }
  .card { padding: 0.95rem 1rem; }
  button, .button { width: 100%; }
  form.inline, form.inline button, .theme-switch button, .password-field .reveal { width: auto; }
  dl { grid-template-columns: 1fr; }
  dt { margin-top: 0.5rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

@media (forced-colors: active) {
  .card, .tile, table, fieldset, input, select, textarea { border: 1px solid CanvasText; }
  .badge, .state { border: 1px solid CanvasText; }
  button, .button { border: 1px solid ButtonText; }
}

@media print {
  header.site, aside, footer.site, button, .button, .theme-switch { display: none !important; }
  body, html { background: #fff; color: #000; }
  .card { border: 1px solid #999; box-shadow: none; break-inside: avoid; }
  a { color: #000; }
  main { width: auto; max-width: none; }
}

/* ===========================================================================
   THE ARRIVAL COMPOSITION

   Matched to the sister site at cybervant.co.ke, which is the house style:
   a near-black ground, display type at a size that actually commands the
   page, two or three words of the headline clipped to a gradient, pill
   badges with a live dot, and content sitting in floating cards rather than
   naked on the ground.

   The old version of this failed on all four counts — 40px type on a flat
   green block with the form floating in an empty white field.
   =========================================================================== */

@media (min-width: 62rem) {
  .shell.split {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: center;
    gap: clamp(2rem, 5vw, 5rem);
    padding: clamp(2rem, 6vh, 5rem) clamp(1.5rem, 5vw, 5rem);
    min-height: calc(100vh - 3.6rem);
  }
  .shell.split main { width: 100%; max-width: 30rem; margin: 0; padding: 0; }
}

body.arrival { background: var(--arr-bg); }
body.arrival::before {          /* the ambient wash, well behind everything */
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(48rem 34rem at 12% -6%,  var(--arr-glow-a), transparent 65%),
    radial-gradient(40rem 30rem at 88% 108%, var(--arr-glow-b), transparent 65%);
}
body.arrival header.site { background: transparent; border-bottom: 0; }

.brandpanel { display: flex; flex-direction: column; gap: 1.5rem; padding: 0; }

/* The pill. A live dot, a hairline ring, a tinted ground. */
.pill {
  display: inline-flex; align-items: center; gap: 0.5rem; align-self: flex-start;
  padding: 0.4rem 0.9rem; border-radius: 999px;
  background: var(--pill-bg); border: 1px solid var(--pill-line);
  color: var(--pill-fg);
  font-size: 0.78rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
}
.pill::before {
  content: ""; width: 0.45rem; height: 0.45rem; border-radius: 999px;
  background: currentColor;
}

/* Display type at a size that carries the page. */
.brandpanel h2 {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(2.6rem, 1.2rem + 5.2vw, 5rem);
  line-height: 0.98; letter-spacing: -0.035em;
  margin: 0; max-width: 12ch; color: var(--text);
}
.brandpanel .lede { font-size: clamp(1rem, 0.95rem + 0.3vw, 1.15rem); color: var(--text-2); max-width: 44ch; margin: 0; }

/* The one signature move, borrowed from the sister site: a couple of words
   clipped to the gradient, the rest plain. */
.grad {
  background-image: var(--climb);
  -webkit-background-clip: text; background-clip: text;
  color: transparent; -webkit-text-fill-color: transparent;
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .grad { color: var(--brand); -webkit-text-fill-color: currentColor; }
}

/* Floating fact cards, the shape the sister site uses for its products. */
.factcards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.7rem; margin: 0; padding: 0; list-style: none; max-width: 30rem; }
.factcards li {
  display: flex; align-items: center; gap: 0.7rem; margin: 0; max-width: none;
  padding: 0.7rem 0.85rem; border-radius: 12px;
  background: var(--float-bg); border: 1px solid var(--float-line);
}
.factcards .n {
  flex: none; display: grid; place-items: center;
  width: 2.3rem; height: 2.3rem; border-radius: 9px;
  background-image: var(--climb); color: var(--on-climb);
  font-family: var(--font-display); font-weight: 700; font-size: 0.92rem;
}
.factcards .t { font-size: 0.85rem; color: var(--text-2); line-height: 1.3; }

/* THE FORM SITS IN A CARD. Naked on the ground was the single worst thing
   about the previous attempt. */
.shell.split main > .card,
.shell.split main > section.card {
  background: var(--float-bg);
  border: 1px solid var(--float-line);
  border-radius: 16px;
  padding: clamp(1.4rem, 3vw, 2rem);
  box-shadow: var(--float-shadow);
}
.shell.split main h1 {
  font-family: var(--font-display); font-size: clamp(1.6rem, 1.3rem + 1vw, 2.1rem);
  letter-spacing: -0.025em; margin-bottom: 0.35rem;
}

@media (max-width: 61.99rem) {
  .shell.split { padding: 0; }
  .brandpanel { padding: 1.75rem var(--pad) 0.5rem; gap: 1rem; }
  .brandpanel h2 { font-size: clamp(2rem, 7vw, 2.8rem); max-width: none; }
  .brandpanel .lede { display: none; }
  .factcards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem; }
  .factcards li { padding: 0.55rem 0.6rem; }
  .factcards .n { width: 2rem; height: 2rem; font-size: 0.82rem; }
  .shell.split main { padding: 1rem var(--pad) 2rem; }
}

/* ===========================================================================
   PAGE HEADS — interior pages get a proper opening, not a bare <h1>
   =========================================================================== */

.page-head { margin: 0 0 1.4rem; }
.page-head .eyebrow { color: var(--brand); }
.page-head h1 { margin: 0 0 0.3rem; }
.page-head p { color: var(--text-2); margin: 0; font-size: 1.05rem; }

/* ===========================================================================
   DESTINATION CARDS
   The signed-in home was a greeting, a dropdown and one button. These are
   the places an account can actually go, one card each, shown only when the
   role can open them.
   =========================================================================== */

.destinations { display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr)); gap: 0.85rem; margin: 0 0 1.5rem; }

.dest {
  display: flex; align-items: flex-start; gap: 0.9rem;
  padding: 1.05rem 1.1rem;
  background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 14px;
  color: inherit; text-decoration: none;
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.dest:hover {
  border-color: var(--brand-bg); transform: translateY(-2px);
  box-shadow: var(--float-shadow); color: inherit;
}
.dest .ic {
  flex: none; display: grid; place-items: center;
  width: 2.5rem; height: 2.5rem; border-radius: 10px;
  background: var(--pill-bg); color: var(--brand);
  border: 1px solid var(--pill-line);
}
.dest .ic svg { width: 1.25rem; height: 1.25rem; }
/* Money keeps its own colour here as everywhere else. */
.dest .ic-money { background: var(--ok-bg); border-color: var(--ok-line); color: var(--ok-text); }
.dest .body { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.dest .t { font-weight: 700; font-size: 1.02rem; }
.dest .d { color: var(--text-2); font-size: 0.9rem; line-height: 1.45; }
.dest .chev { flex: none; width: 1.1rem; height: 1.1rem; margin-top: 0.65rem; color: var(--text-3); }
.dest:hover .chev { color: var(--brand); }



/* ===========================================================================
   BILLING
   =========================================================================== */

/* What this account already owns, before what it could buy. */
.owned { display: grid; gap: 0.6rem; margin: 0 0 1.4rem; padding: 0; list-style: none; }
.owned li {
  display: flex; align-items: center; gap: 0.8rem; margin: 0; max-width: none;
  padding: 0.8rem 0.95rem;
  background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: 12px;
}
.owned .ic {
  flex: none; display: grid; place-items: center;
  width: 2.2rem; height: 2.2rem; border-radius: 9px;
  background: var(--ok-bg); border: 1px solid var(--ok-line); color: var(--ok-text);
}
.owned .ic svg { width: 1.1rem; height: 1.1rem; }
.owned .body { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1; }
.owned .t { font-weight: 700; }
.owned .d { color: var(--text-2); font-size: 0.875rem; }

.plans { display: grid; gap: 1rem; }
.plan-head { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; margin-bottom: 0.2rem; }
.plan-head h2 { margin: 0; font-size: 1.2rem; }

/* The number a parent is deciding on, at the size of a decision. */
.price { display: flex; align-items: baseline; gap: 0.6rem; flex-wrap: wrap; margin: 0.6rem 0 0.2rem; }
.price .amount {
  font-family: var(--font-display); font-weight: 700; font-size: 1.9rem;
  line-height: 1; color: var(--ok-text); font-variant-numeric: tabular-nums;
}
.price .terms { color: var(--text-2); font-size: 0.9rem; }

/* A real sequence, so it is numbered. The M-Pesa steps are the one place on
   the site where the reader is partway through the list while reading it. */
.steps { margin: 1rem 0; padding-left: 1.4rem; }
.steps li { margin-bottom: 0.5rem; }
.steps li::marker { color: var(--brand); font-weight: 700; }

/* ===========================================================================
   THE SCHOOL-DASHBOARD LAYER
   Everything the reference does that the base rules do not. Appended last on
   purpose: these are overrides of same-specificity rules above, so cascade
   order decides, which is predictable and easy to read.
   =========================================================================== */

/* No cover bar. The masthead is the page: white, quiet, and the only thing
   that separates it is air and a hairline that is barely there. */
header.site {
  background: var(--surface);
  color: var(--text);
  border-bottom: 1px solid var(--border);
  padding: 0.9rem var(--pad);
}
header.site a.wordmark { color: var(--text); }
header.site .who { color: var(--text-2); }
header.site .appearance { border-color: var(--border); }
header.site .appearance button { color: var(--text-2); }
header.site .appearance button:hover,
header.site .appearance button[aria-pressed="true"] {
  background: var(--accent-wash); color: var(--brand);
}

/* Nav: the active item is green, on a soft green pill. The gold underline is
   gone -- one accent, doing one job. */
aside { background: var(--surface); border-bottom: 1px solid var(--border); }
nav a {
  border-bottom: 0;
  border-radius: var(--radius-pill);
  padding: 0.55rem 0.95rem;
  margin: 0.35rem 0.1rem;
  font-weight: 500;
}
nav a:hover { background: var(--accent-wash); color: var(--brand); }
nav a.active { color: var(--brand); background: var(--accent-wash); font-weight: 600; }
nav a.active::after { content: none; }

/* Cards: no outline. A card is a fill and a soft shadow, and on a white
   ground that is enough. */
.card {
  border: 0;
  border-radius: var(--radius);
  padding: 1.4rem 1.5rem;
  margin: 0 0 1.1rem;
  box-shadow: var(--shadow-card);
}
.card.featured { border: 0; box-shadow: var(--shadow-lift); }
.card.featured::before { content: none; }

/* Buttons are pills, and the primary one is the single green thing on the
   screen. `.pay` keeps its own rule above; this is the shape. */
button, .button {
  border-radius: var(--radius-pill);
  padding: 0.7rem 1.35rem;
  font-weight: 600;
  border: 0;
}
button.ghost, .button.ghost {
  background: var(--surface-sunk); color: var(--text); border: 0;
}
button.ghost:hover, .button.ghost:hover { background: var(--accent-wash); color: var(--brand); }

/* Badges are pills too, and lose their outline. */
.badge, .state { border-radius: var(--radius-pill); border: 0; padding: 0.28rem 0.7rem; }

/* TABLES ARE THE POINT. The reference has no gridlines at all: a header row
   in quiet grey, a pale green stripe, generous height, and a filled row for
   the one that matters. This site is mostly tables, so this is where the
   direction earns its keep. */
table { border-collapse: separate; border-spacing: 0; width: 100%; }
th {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--border);
  color: var(--text-2);
  font-weight: 500;
  font-size: 0.875rem;
  text-align: left;
  padding: 0.85rem 1rem;
  white-space: nowrap;
}
td {
  border: 0;
  padding: 0.95rem 1rem;
  vertical-align: middle;
}
tbody tr { background: var(--surface); }
tbody tr:nth-child(even) { background: var(--surface-zebra); }
tbody tr:hover { background: var(--accent-wash); }
/* The selected row: filled green, white text, rounded at both ends -- the
   reference's clearest single move. Deeper than its green so white on it
   measures 5.38:1 rather than the reference's ~3. */
tbody tr.selected, tbody tr[aria-selected="true"] {
  background: var(--brand-bg); color: var(--brand-fg);
}
tbody tr.selected a, tbody tr[aria-selected="true"] a { color: var(--brand-fg); }
tbody tr.selected td:first-child,
tbody tr[aria-selected="true"] td:first-child {
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}
tbody tr.selected td:last-child,
tbody tr[aria-selected="true"] td:last-child {
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

/* Fields: no heavy outline, a soft fill, and the green only on focus. */
input[type="text"], input[type="email"], input[type="password"], input[type="tel"],
input[type="number"], input[type="search"], input[type="date"], select, textarea {
  border-radius: var(--radius-sm);
  border: 1px solid var(--field-line);
  background: var(--field-bg);
  padding: 0.75rem 0.9rem;
}

/* Air. The reference reads as considered mostly because it breathes; this is
   the cheapest and largest part of the whole direction. */
main { padding-top: clamp(1.5rem, 4vw, 2.5rem); padding-bottom: 3.5rem; }
h2 { margin-top: 2.2rem; }
.page-head { margin-bottom: 1.8rem; }

/* Eyebrow: quiet grey, letterspaced. The green is spent on the action, not
   on a label. */
.eyebrow {
  display: block;
  font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: 0.4rem;
}
.page-head .eyebrow { color: var(--text-2); }

/* Figures line up: this site is money, counts and dates. */
.amount, .tile .big, .tile .value, time, .code, td.num, th.num {
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ===========================================================================
   ONE MEASURE, AND EVERYTHING ALIGNED TO IT

   The bug this fixes: the masthead, the nav and the footer ran edge to edge
   while `main` was a 46rem column centred in the viewport. So the wordmark
   sat ~28px from the left and the content it belonged to started ~430px in,
   with dead space either side. Nothing lined up, and on a wide screen the
   page read as a narrow strip under a full-width bar.

   The fix is not to centre the header -- a masthead SHOULD be full bleed, it
   is what binds the page. It is to pad the full-bleed elements by however
   much is needed to bring their CONTENT onto the same left and right edges
   as the column. One variable does it, and the arithmetic is the same one
   the column uses, so they cannot drift apart.

   The measure is also wider than it was. 46rem is a prose measure -- right
   for the legal pages, far too narrow for a dashboard, which is what most of
   this site is. Long-form text keeps the narrow measure inside the wider
   column, where it belongs.
   =========================================================================== */

:root {
  /* The column every surface shares. */
  --measure: 64rem;
  /* Ideal line length for continuous reading, applied to prose only. */
  --measure-prose: 46rem;
}

/* The gutter that pulls a full-bleed element's content onto the column's
   edge. Never smaller than the page padding, so it still works on a phone. */
header.site,
aside nav,
footer.site {
  /* + var(--pad) because `main` centres its 64rem box and THEN pads inside
     it, so the text edge is half the leftover plus the padding. Leaving the
     padding off put the masthead 15px to the left of everything it labels,
     which is exactly the kind of near-miss that reads as sloppy. */
  padding-inline: max(var(--pad), calc((100% - var(--measure)) / 2 + var(--pad)));
}

main {
  width: min(var(--measure), 100%);
  margin-inline: auto;
  padding-inline: var(--pad);
}
/* `wide` was a second measure for table-heavy pages. With the column at
   64rem there is no longer a reason for a page to disagree with the rest of
   the site about where its edges are. */
main.wide { width: min(var(--measure), 100%); }

footer.site { width: 100%; max-width: none; margin-inline: 0; }
footer.site > * { width: 100%; max-width: none; margin-inline: 0; }

/* Prose keeps the short line. A privacy policy read at 64rem is a wall. */
.legal main > *,
main > article,
main > .prose > * {
  max-width: var(--measure-prose);
}

@media (max-width: 40rem) {
  :root { --measure: 100%; }
}

/* ===========================================================================
   SIGNED-IN WORKSPACE

   Arrival pages deliberately keep the composition above. Once someone has
   signed in, the product changes mode: a stable navigation rail, a calm work
   canvas, and stronger page/section hierarchy. Every selector is scoped away
   from `.arrival`, so the approved sign-in experience cannot drift as the
   workspace evolves.
   =========================================================================== */

body:not(.arrival) {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 17.5rem minmax(0, 1fr);
  grid-template-rows: 4.75rem minmax(0, 1fr) auto;
  background: var(--surface-sunk);
}

body:not(.arrival) > header.site {
  grid-column: 1 / -1;
  grid-row: 1;
  position: sticky;
  top: 0;
  z-index: 20;
  min-width: 0;
  padding: 0 1.5rem;
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 var(--border), 0 8px 30px color-mix(in srgb, var(--panel-bg) 5%, transparent);
  backdrop-filter: blur(14px);
}

body:not(.arrival) header.site a.wordmark {
  font-family: var(--font-display);
  font-size: 1.25rem;
  letter-spacing: -0.025em;
}

body:not(.arrival) header.site a.wordmark .zmark {
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 11px;
  box-shadow: 0 5px 18px var(--glow);
}

.product-context {
  margin-right: auto;
  padding-left: 1rem;
  border-left: 1px solid var(--border);
  color: var(--text-2);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

body:not(.arrival) > aside {
  grid-column: 1;
  grid-row: 2 / 4;
  min-width: 0;
  padding: 1.75rem 1rem;
  background:
    radial-gradient(circle at 20% 4%, var(--panel-glow), transparent 13rem),
    var(--panel-bg);
  color: var(--panel-fg);
  border: 0;
}

.nav-kicker {
  display: block;
  padding: 0 0.9rem 0.75rem;
  color: var(--panel-dim);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

body:not(.arrival) > aside nav {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  overflow: visible;
  padding: 0;
}

body:not(.arrival) > aside nav a {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0;
  padding: 0.78rem 0.9rem;
  border: 0;
  border-radius: 12px;
  color: var(--panel-dim);
  font-size: 0.92rem;
  font-weight: 600;
  line-height: 1.25;
  white-space: normal;
}

body:not(.arrival) > aside nav a::before {
  content: "";
  flex: none;
  width: 0.55rem;
  height: 0.55rem;
  border: 2px solid currentColor;
  border-radius: 4px;
  opacity: 0.72;
  transform: rotate(45deg);
}

body:not(.arrival) > aside nav a:hover {
  color: var(--panel-fg);
  background: color-mix(in srgb, var(--panel-fg) 8%, transparent);
}

body:not(.arrival) > aside nav a.active {
  color: var(--panel-fg);
  background: color-mix(in srgb, var(--panel-accent) 18%, transparent);
  box-shadow: inset 3px 0 0 var(--panel-accent);
}

body:not(.arrival) > aside nav a.active::before {
  color: var(--panel-accent);
  background: currentColor;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--panel-accent) 12%, transparent);
}

body:not(.arrival) > .shell {
  grid-column: 1 / -1;
  grid-row: 2;
  min-width: 0;
  background:
    radial-gradient(circle at 100% 0, var(--accent-wash), transparent 28rem),
    var(--surface-sunk);
}

body:not(.arrival) > aside + .shell { grid-column: 2; }

body:not(.arrival) main,
body:not(.arrival) main.wide {
  width: min(78rem, 100%);
  min-width: 0;
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 3.5rem);
}

body:not(.arrival) > footer.site {
  grid-column: 1 / -1;
  grid-row: 3;
  width: auto;
  padding: 1.25rem clamp(1.5rem, 4vw, 3.5rem) 2rem;
  background: var(--surface-sunk);
  color: var(--text-2);
  text-align: left;
  border: 0;
}

body:not(.arrival) > aside + .shell + footer.site { grid-column: 2; }
body:not(.arrival) > footer.site p { width: min(78rem, 100%); margin: 0 auto; }

body:not(.arrival) .page-head {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin: 0 0 1.5rem;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border-radius: 22px;
  background:
    linear-gradient(125deg, var(--panel-bg), color-mix(in srgb, var(--panel-bg) 74%, var(--brand-bg)));
  color: var(--panel-fg);
  box-shadow: 0 18px 45px color-mix(in srgb, var(--panel-bg) 16%, transparent);
}

body:not(.arrival) .page-head::after {
  content: "";
  position: absolute;
  z-index: -1;
  width: 18rem;
  height: 18rem;
  right: -6rem;
  top: -9rem;
  border: 3rem solid color-mix(in srgb, var(--panel-accent) 10%, transparent);
  border-radius: 50%;
}

body:not(.arrival) .page-head .eyebrow {
  color: var(--panel-kicker);
  margin-bottom: 0.65rem;
}

body:not(.arrival) .page-head h1 {
  max-width: 18ch;
  margin-bottom: 0.55rem;
  color: var(--panel-fg);
  font-size: clamp(2rem, 1.5rem + 2.1vw, 3.2rem);
  line-height: 1.02;
}

body:not(.arrival) .page-head p {
  max-width: 62ch;
  margin: 0;
  color: var(--panel-dim);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.08rem);
}

body:not(.arrival) .page-head strong { color: var(--panel-fg); }

body:not(.arrival) .card {
  padding: clamp(1.25rem, 2.5vw, 1.8rem);
  margin-bottom: 1.25rem;
  border: 1px solid color-mix(in srgb, var(--border) 82%, transparent);
  border-radius: 20px;
  background: var(--surface-raised);
  box-shadow: 0 10px 32px color-mix(in srgb, var(--panel-bg) 7%, transparent);
}

body:not(.arrival) .card h2,
body:not(.arrival) .card h3 { letter-spacing: -0.015em; }

body:not(.arrival) .card > h2:first-child,
body:not(.arrival) .card > h3:first-child { margin-bottom: 0.9rem; }

body:not(.arrival) main > h1:first-child {
  margin-bottom: 0.5rem;
  font-size: clamp(2rem, 1.55rem + 1.8vw, 3rem);
}

body:not(.arrival) main > h1:first-child + .note,
body:not(.arrival) main > h1:first-child + .muted {
  margin-bottom: 1.75rem;
  font-size: 1rem;
}

.section-kicker {
  display: block;
  margin-bottom: 0.45rem;
  color: var(--brand);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
}

body:not(.arrival) .section-kicker + h2 { margin: 0 0 0.45rem; }

.content-grid {
  display: grid;
  grid-template-columns: minmax(17rem, 0.9fr) minmax(20rem, 1.1fr);
  gap: 1.25rem;
  align-items: start;
}

.content-grid > .card { margin: 0; }

.account-controls {
  display: grid;
  grid-template-columns: minmax(18rem, 1fr) auto;
  gap: 0.75rem 1.25rem;
  align-items: end;
}

.account-controls > h2,
.account-controls > .muted { grid-column: 1 / -1; }
.account-controls > h2 { margin: 0; }
.account-controls > form { margin: 0; }
.account-controls > form:last-child { justify-self: end; }
.account-controls > form:last-child button { margin-bottom: 0; }

.mode-switcher {
  display: grid;
  grid-template-columns: minmax(14rem, 1fr) auto;
  gap: 0.75rem;
  align-items: end;
}

.mode-switcher label { grid-column: 1 / -1; margin-top: 0; }
.mode-switcher button { margin-top: 0; }

body:not(.arrival) .destinations {
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

body:not(.arrival) .dest {
  min-height: 9rem;
  padding: 1.35rem;
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: 0 8px 26px color-mix(in srgb, var(--panel-bg) 6%, transparent);
}

body:not(.arrival) .dest:hover {
  border-color: color-mix(in srgb, var(--brand-bg) 55%, var(--border));
  box-shadow: 0 16px 36px color-mix(in srgb, var(--panel-bg) 11%, transparent);
  transform: translateY(-3px);
}

body:not(.arrival) .dest .ic {
  width: 2.8rem;
  height: 2.8rem;
  border: 0;
  border-radius: 13px;
}

body:not(.arrival) .dest .t { font-family: var(--font-display); font-size: 1.08rem; }
body:not(.arrival) .dest .d { margin-top: 0.15rem; }

.demo-group {
  margin: 0 0 1.75rem;
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
  border: 1px solid var(--border);
  border-radius: 20px;
  background: color-mix(in srgb, var(--surface-raised) 88%, transparent);
}

.demo-group > h2 { margin: 0 0 0.4rem; }
.demo-group > .muted { margin-bottom: 1rem; }
.demo-links { margin: 0; }
body:not(.arrival) .demo-links .dest { min-height: 7.2rem; box-shadow: none; }

body:not(.arrival) .owned {
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 0.8rem;
}

body:not(.arrival) .owned li {
  min-height: 5rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface-raised);
  box-shadow: 0 6px 22px color-mix(in srgb, var(--panel-bg) 5%, transparent);
}

body:not(.arrival) .plans {
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  align-items: stretch;
}

body:not(.arrival) .plans > .card { display: flex; flex-direction: column; }
body:not(.arrival) .plans > .card form { margin-top: auto; }

body:not(.arrival) .stack article {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--border);
}

body:not(.arrival) .stack article:first-child { padding-top: 0.35rem; }
body:not(.arrival) .stack article:last-child { padding-bottom: 0.35rem; border-bottom: 0; }

.profile-list article > span { display: grid; gap: 0.2rem; }
.profile-list small { color: var(--text-2); font-size: 0.85rem; }
.text-action { font-size: 0.9rem; font-weight: 700; text-decoration: none; white-space: nowrap; }
.text-action:hover { text-decoration: underline; }

.empty-state {
  padding: 2rem 1rem;
  border: 1px dashed var(--border-strong);
  border-radius: 16px;
  background: var(--surface-sunk);
  text-align: center;
}

.empty-state p { margin: 0.25rem auto 0; }

body:not(.arrival) label {
  margin-top: 1.1rem;
  color: var(--text);
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.015em;
}

body:not(.arrival) input,
body:not(.arrival) select,
body:not(.arrival) textarea {
  min-height: 3.15rem;
  border: 1px solid var(--field-line);
  border-radius: 12px;
  background: var(--surface-sunk);
  box-shadow: inset 0 1px 0 color-mix(in srgb, var(--surface) 70%, transparent);
}

body:not(.arrival) input:hover,
body:not(.arrival) select:hover,
body:not(.arrival) textarea:hover { background: var(--surface); }

body:not(.arrival) button,
body:not(.arrival) .button {
  min-height: 2.9rem;
  padding: 0.72rem 1.25rem;
  border: 0;
  border-radius: 11px;
  box-shadow: 0 6px 16px color-mix(in srgb, var(--brand-bg) 18%, transparent);
}

body:not(.arrival) button:hover,
body:not(.arrival) .button:hover {
  box-shadow: 0 9px 22px color-mix(in srgb, var(--brand-bg) 24%, transparent);
}

body:not(.arrival) button.ghost,
body:not(.arrival) .button.ghost { box-shadow: none; }

body:not(.arrival) .table-wrap,
body:not(.arrival) main > table {
  border: 1px solid var(--border);
  border-radius: 18px;
  background: var(--surface-raised);
  box-shadow: 0 8px 28px color-mix(in srgb, var(--panel-bg) 6%, transparent);
}

body:not(.arrival) .card .table-wrap {
  border-radius: 14px;
  box-shadow: none;
}

body:not(.arrival) th {
  padding: 0.9rem 1rem;
  background: var(--surface-sunk);
  color: var(--text-2);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

body:not(.arrival) td { padding: 1rem; }
body:not(.arrival) tbody tr:nth-child(even) { background: var(--surface-zebra); }

body:not(.arrival) .error,
body:not(.arrival) .success,
body:not(.arrival) .flash,
body:not(.arrival) .callout,
body:not(.arrival) .warn-money {
  padding: 1rem 1.15rem;
  border-width: 0 0 0 4px;
  border-radius: 12px;
  box-shadow: 0 6px 20px color-mix(in srgb, var(--panel-bg) 5%, transparent);
}

@media (max-width: 56rem) {
  body:not(.arrival) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 4.25rem auto minmax(0, 1fr) auto;
  }

  body:not(.arrival) > header.site {
    grid-column: 1;
    min-height: 4.25rem;
    padding: 0 1rem;
  }

  .product-context { display: none; }

  body:not(.arrival) > aside {
    grid-column: 1;
    grid-row: 2;
    padding: 0.55rem 0.75rem;
    overflow: hidden;
  }

  .nav-kicker { display: none; }

  body:not(.arrival) > aside nav {
    flex-direction: row;
    gap: 0.25rem;
    overflow-x: auto;
    scrollbar-width: none;
  }

  body:not(.arrival) > aside nav a {
    flex: 0 0 auto;
    padding: 0.65rem 0.8rem;
    white-space: nowrap;
  }

  body:not(.arrival) > aside nav a::before { display: none; }
  body:not(.arrival) > aside nav a.active { box-shadow: inset 0 -2px 0 var(--panel-accent); }

  body:not(.arrival) > .shell,
  body:not(.arrival) > aside + .shell {
    grid-column: 1;
    grid-row: 3;
  }

  body:not(.arrival) > footer.site,
  body:not(.arrival) > aside + .shell + footer.site {
    grid-column: 1;
    grid-row: 4;
  }

  body:not(.arrival) main,
  body:not(.arrival) main.wide { padding: 1.25rem; }

  .content-grid { grid-template-columns: 1fr; }

  .account-controls { grid-template-columns: 1fr; }
  .account-controls > form:last-child { justify-self: stretch; }
}

@media (max-width: 40rem) {
  body:not(.arrival) header.site .appearance { margin-left: auto; }
  body:not(.arrival) .page-head { padding: 1.4rem; border-radius: 18px; }
  body:not(.arrival) .page-head h1 { font-size: 2rem; }
  body:not(.arrival) .card { padding: 1.15rem; border-radius: 17px; }
  body:not(.arrival) .destinations,
  body:not(.arrival) .plans { grid-template-columns: 1fr; }
  body:not(.arrival) .dest { min-height: 0; }
  .mode-switcher { grid-template-columns: 1fr; }
  body:not(.arrival) .stack article { align-items: flex-start; flex-direction: column; }
  body:not(.arrival) button,
  body:not(.arrival) .button { width: 100%; }
  body:not(.arrival) form.inline,
  body:not(.arrival) form.inline button,
  body:not(.arrival) .appearance button,
  body:not(.arrival) .password-field .reveal { width: auto; }
}

/* ===========================================================================
   SCHOOL WORKSPACE — add teachers
   =========================================================================== */
.school-stats { margin: 0 0 1.25rem; }
.school-stats a.tile { text-decoration: none; color: inherit; }
.school-stats a.tile:hover, .school-stats a.tile:focus-visible { border-color: var(--accent); }

.segmented { display: inline-flex; gap: 0.25rem; padding: 0.25rem; margin: 0.4rem 0 0.2rem;
  background: var(--surface-sunk); border: 1px solid var(--border); border-radius: var(--radius-pill); flex-wrap: wrap; }
.segmented button { margin: 0; min-height: 2.4rem; padding: 0.45rem 1rem; border-radius: var(--radius-pill);
  background: transparent; color: var(--text-2); font-size: 0.9375rem; }
.segmented button:hover { background: var(--overlay-hover); box-shadow: none; transform: none; color: var(--text); }
.segmented button[aria-selected="true"] { background: var(--brand-bg); color: var(--brand-fg); }
.panel { padding-top: 0.4rem; }

.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: 0 1rem; }
input[aria-invalid="true"] { border-color: var(--danger-line); box-shadow: 0 0 0 3px var(--danger-tint); }
.field-error { color: var(--danger-text); font-size: 0.875rem; font-weight: 600; margin: 0.6rem 0 0; }

.subject-picks { margin: 1.25rem 0 0; }
.picks-tools { display: flex; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin: 0.2rem 0 0.6rem; }
.picks-tools input[type="search"] { flex: 1 1 14rem; min-height: 2.5rem; padding: 0.5rem 0.8rem; font-size: 0.9375rem; }
.picks-count { font-size: 0.875rem; color: var(--text-2); white-space: nowrap; }
.picks-count span { font-weight: 700; color: var(--text); }
.picks-note { font-size: 0.875rem; margin: 0 0 0.6rem; }
button.linklike { display: inline; margin: 0; min-height: 0; padding: 0; background: none; border: 0;
  color: var(--link); font-weight: 600; font-size: inherit; text-decoration: underline; }
button.linklike:hover { background: none; box-shadow: none; transform: none; }
.chips { display: grid; grid-template-columns: repeat(auto-fill, minmax(13.5rem, 1fr)); gap: 0.45rem; }
label.chip { display: flex; align-items: center; gap: 0.55rem; margin: 0; padding: 0.5rem 0.7rem;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-sunk);
  font-weight: 500; font-size: 0.9375rem; line-height: 1.25; cursor: pointer; }
label.chip[hidden] { display: none; }
label.chip input { width: 1.1rem; min-height: 0; height: 1.1rem; padding: 0; margin: 0; flex: none; accent-color: var(--brand-bg); }
label.chip small { display: block; color: var(--text-2); font-size: 0.75rem; font-weight: 400; margin-top: 0.1rem; }
label.chip:hover { border-color: var(--border-strong); }
label.chip:has(input:checked) { border-color: var(--brand-bg); background: var(--accent-wash); }
label.chip:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }

ol.steps { margin: 0.6rem 0 0; padding-left: 1.3rem; display: grid; gap: 0.6rem; }
ol.steps li { padding-left: 0.2rem; }
.step-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; }
.step-actions .button { margin-top: 0.5rem; min-height: 2.4rem; padding: 0.45rem 0.9rem; font-size: 0.9375rem; }
label.dropzone { position: relative; display: grid; place-items: center; gap: 0.2rem; text-align: center;
  margin: 1.2rem 0 0; padding: 1.6rem 1rem; border: 2px dashed var(--border-strong); border-radius: var(--radius);
  background: var(--surface-sunk); cursor: pointer; font-weight: 400; }
label.dropzone input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; min-height: 0; }
label.dropzone .dz-title { font-weight: 700; font-size: 1rem; }
label.dropzone .dz-sub { font-size: 0.875rem; }
label.dropzone.over, label.dropzone:hover, label.dropzone:focus-within { border-color: var(--accent); background: var(--accent-wash); }
label.dropzone.has-file { border-style: solid; border-color: var(--brand-bg); }
label.dropzone.has-file .dz-sub { color: var(--text); font-weight: 600; }
#many-panel details { margin-top: 1.2rem; }
#many-panel summary { cursor: pointer; color: var(--link); font-weight: 600; font-size: 0.9375rem; }

#teachers h3 { display: flex; align-items: center; gap: 0.5rem; }
.inline-form { display: flex; align-items: flex-end; gap: 0.75rem; flex-wrap: wrap; }
.inline-form > div { flex: 1 1 16rem; }
.inline-form button { flex: none; }

/* The Sign out button sat a hair above the links beside it. */
header.site .topnav a, header.site .topnav button { line-height: 1.5; min-height: 0; margin: 0; display: inline-block; }
header.site .topnav-form { display: inline-flex; }

/* ===========================================================================
   ACCOUNT MENU — who you are, switch role, sign out
   =========================================================================== */
header.site .account-menu { position: relative; }
header.site .account-menu summary { list-style: none; display: flex; align-items: center; gap: 0.55rem;
  cursor: pointer; padding: 0.3rem 0.6rem 0.3rem 0.3rem; border-radius: var(--radius-pill);
  border: 1px solid var(--border); color: var(--text); }
header.site .account-menu summary::-webkit-details-marker { display: none; }
header.site .account-menu summary:hover, header.site .account-menu[open] summary { background: var(--overlay-hover); border-color: var(--border-strong); }
.am-avatar { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%;
  background: var(--brand-bg); color: var(--brand-fg); font-weight: 700; font-size: 0.9375rem; flex: none; }
.am-text { display: grid; line-height: 1.15; text-align: left; }
.am-name { font-size: 0.875rem; font-weight: 600; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.am-role { font-size: 0.75rem; color: var(--text-2); }
.am-caret { width: 0.45rem; height: 0.45rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translateY(-2px); margin: 0 0.2rem; opacity: 0.7; transition: transform .15s ease; }
.account-menu[open] .am-caret { transform: rotate(-135deg) translateY(-1px); }
.am-panel { position: absolute; right: 0; top: calc(100% + 0.5rem); z-index: 50; width: min(18rem, calc(100vw - 2rem));
  padding: 0.6rem; background: var(--float-bg); border: 1px solid var(--float-line); border-radius: var(--radius);
  box-shadow: var(--float-shadow); }
.am-email { margin: 0.2rem 0.5rem 0.5rem; font-size: 0.8125rem; color: var(--text-2); overflow-wrap: anywhere; }
.am-heading { margin: 0.5rem 0.5rem 0.3rem; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-2); }
.am-roles { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.1rem; }
.am-roles form { margin: 0; }
.account-menu .am-role-item, .account-menu .am-links a, .account-menu .am-signout button {
  display: flex; align-items: center; justify-content: space-between; width: 100%; margin: 0; min-height: 2.4rem;
  padding: 0.45rem 0.6rem; border: 0; border-radius: var(--radius-sm); background: none; box-shadow: none;
  color: var(--text); font: inherit; font-size: 0.9375rem; font-weight: 500; text-align: left; text-decoration: none; cursor: pointer; }
.account-menu .am-role-item:hover, .account-menu .am-links a:hover, .account-menu .am-signout button:hover {
  background: var(--overlay-hover); transform: none; box-shadow: none; }
.account-menu .am-role-item.current { background: var(--accent-wash); font-weight: 700; cursor: default; }
.am-check { color: var(--brand); font-weight: 700; }
.am-links { border-top: 1px solid var(--border); margin-top: 0.5rem; padding-top: 0.4rem; display: grid; }
.am-signout { border-top: 1px solid var(--border); margin: 0.4rem 0 0; padding-top: 0.4rem; }
.account-menu .am-signout button { color: var(--danger-text); }

/* Role chips on the account home: one shape for the current role and the
   others (the active one was a span, the rest buttons with the global button
   margin and height, so it floated above the row). */
.roles-strip li { display: flex; }
.roles-strip .badge, .roles-strip button.badge { display: inline-flex; align-items: center; margin: 0; min-height: 2.25rem;
  padding: 0.35rem 0.85rem; font-size: 0.875rem; font-weight: 600; line-height: 1.2; box-shadow: none; border-radius: var(--radius-pill); }
.roles-strip button.badge { background: var(--surface-sunk); color: var(--text); border: 1px solid var(--border); }
.roles-strip button.badge:hover { border-color: var(--accent); background: var(--accent-wash); transform: none; box-shadow: none; }
.roles-strip .role-active { border: 1px solid transparent; }
header.site .topnav button { box-shadow: none; }

/* Buttons that sit inside a table cell or an inline form are small and flush:
   the page-level button's 1rem top margin, 46px height and drop shadow made
   them float above their row. */
td form { margin: 0; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.4rem; }
td form label { margin: 0; }
td button, td .button, form.inline button, .inline-form button {
  margin-top: 0; box-shadow: none; }
td button, td .button { min-height: 2.25rem; padding: 0.4rem 0.8rem; font-size: 0.875rem; }
td select, td input:not([type=checkbox]):not([type=radio]) { min-height: 2.25rem; padding: 0.35rem 0.6rem; font-size: 0.875rem; width: auto; }

/* ===========================================================================
   TEACHING RECORDS, CALENDAR, DIRECTORIES
   =========================================================================== */
.name-row { grid-template-columns: minmax(6.5rem, 0.6fr) 1fr 1fr; }
@media (max-width: 640px) { .name-row { grid-template-columns: 1fr; } }
.field-hint { display: block; font-size: 0.8125rem; margin-top: 0.3rem; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
ul.teach-list { list-style: none; margin: 0.2rem 0 0; padding: 0; display: grid; gap: 0.25rem; }
ul.teach-list .muted { font-size: 0.8125rem; }
.status-withdrawn, li.status-withdrawn { opacity: 0.6; }
tr.status-withdrawn td:nth-child(-n+3) { text-decoration: line-through; }
nav.year-picker { display: inline-flex; margin: 0.6rem 0 1rem; }
nav.year-picker a { display: inline-flex; align-items: center; min-height: 2.4rem; padding: 0.45rem 1rem;
  border-radius: var(--radius-pill); color: var(--text-2); text-decoration: none; font-weight: 600; font-size: 0.9375rem; }
nav.year-picker a:hover { background: var(--overlay-hover); color: var(--text); }
nav.year-picker a[aria-current="page"] { background: var(--brand-bg); color: var(--brand-fg); }
table.teach-table td form { margin-right: 0.3rem; }
table.teach-table td input[type="date"] { width: 9.5rem; }
.calendar-form details, #calendar details { margin-top: 1rem; }
#calendar summary, .directory summary { cursor: pointer; color: var(--link); font-weight: 600; }
.term-row label { font-weight: 500; }
.terms-note { margin: 1rem 0 0; font-size: 0.875rem; }
.directory-tools { display: flex; gap: 0.6rem; align-items: flex-end; flex-wrap: wrap; margin: 0.4rem 0 1rem; }
.directory-tools > div { flex: 1 1 16rem; }
.directory-tools label { margin-top: 0; }
.directory-tools button, .directory-tools .button { margin-top: 0; }
.pager { display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; margin-top: 1rem; font-size: 0.9375rem; }
.pager .button { margin-top: 0; min-height: 2.4rem; padding: 0.45rem 0.9rem; }
.pager .button.disabled { pointer-events: none; }

/* ===========================================================================
   CONTENT MAP (System admin)
   =========================================================================== */
.cmap-tiles{margin:0 0 .6rem}
.cmap-stat{cursor:pointer;text-align:left;font:inherit;color:inherit;margin:0;box-shadow:none;display:block;min-height:0}
.cmap-stat:hover{transform:none;box-shadow:none;background:var(--surface-raised);border-color:var(--border-strong)}
.cmap-stat[aria-pressed="true"]{border-color:var(--text)}
.cmap-stat .label{display:flex;align-items:center;gap:.4rem}
.cmap-dot{width:.7rem;height:.7rem;border-radius:3px;flex:none;display:inline-block}
.cmap-note{font-size:.875rem;margin:.4rem 0 1rem}
table.cmap{border-collapse:separate;border-spacing:0;min-width:760px;width:100%}
table.cmap th,table.cmap td{padding:3px 2px;border-bottom:1px solid var(--border)}
table.cmap thead th{font-size:.75rem;text-align:center;color:var(--text-2);font-family:var(--font-mono)}
table.cmap thead th:first-child,table.cmap tbody th{text-align:left;padding-left:.6rem}
table.cmap tbody th{font-size:.875rem;font-weight:500;white-space:nowrap}
.cmap-cell{display:grid;place-items:center;width:100%;height:2.5rem;min-height:0;margin:0;padding:0;border:0;border-radius:5px;box-shadow:none;cursor:pointer;
  font-family:var(--font-mono);font-size:.75rem;font-weight:500;font-variant-numeric:tabular-nums;color:var(--text)}
.cmap-cell:hover{transform:none;box-shadow:none;filter:brightness(.97)}
.cmap-cell small{display:block;font-size:.625rem;font-weight:400;opacity:.85;line-height:1.1}
.s-live{background:var(--brand-bg);color:var(--brand-fg)}
.s-both{background:var(--accent-wash);box-shadow:inset 0 0 0 1.5px var(--accent)}
.s-book{background:var(--notice-bg);box-shadow:inset 0 0 0 1.5px var(--notice-line)}
.s-past{background:var(--info-bg);box-shadow:inset 0 0 0 1.5px var(--info-text)}
.s-none{background:var(--surface-sunk);color:var(--text-2)}
.s-empty{background:transparent;cursor:default;color:var(--text-2)}
span.cmap-dot.s-none{box-shadow:inset 0 0 0 1px var(--border-strong)}
table.cmap.dim .cmap-cell[data-state]:not(.match){opacity:.18}
.cmap-detail h2{font-size:1rem;margin:0 0 .3rem}
.cmap-detail p{margin:.2rem 0}
