/* Aluma for families: the adult app at /family (parents.html + parents.js).

   A standalone sheet on purpose: the student app's bundles are huge and
   dark-first, and a parent on a phone should get one small light sheet.
   The look follows aluma.fun (Geist, deep teal, white cards with a soft drop,
   pill buttons with a pressed lip), set on a creamier ground. Every token is
   namespaced --f-* so nothing here collides with the app-wide ladder or the
   ink/material checks in the regression gate.

   Contrast, measured (WCAG 4.5:1 for text):
     --f-text-2 #536159 is 5.5:1 or better on every surface here.
     --f-text-3 #626e67 is 4.78:1 on --f-surface-3 and better elsewhere; it
     is never set on --f-accent-soft (4.49:1), where --f-text-2 is used.
     --f-accent #1c6a5b is 5.7:1 or better as text; white on it is 6.4:1.
     Status inks on their softened fills: danger 5.7, streak 5.2, soon 5.1,
     night 7.0, sky 5.3. The bright streak orange is only the flame.
     Controls (WCAG 3:1): the off switch track and the checkbox border are
     --f-icon #74807a, 4.11:1 on the card. */

:root {
  --f-bg: #f6f8f2;
  --f-surface: #fff;
  --f-surface-2: #fbfcf7;
  --f-surface-3: #eff4ee;
  --f-text: #13201b;
  --f-text-2: #536159;
  --f-text-3: #626e67;
  --f-icon: #74807a;
  --f-border: rgba(19, 32, 27, 0.09);
  --f-border-strong: rgba(19, 32, 27, 0.14);
  --f-hair: rgba(19, 32, 27, 0.07);
  --f-accent: #1c6a5b;
  --f-accent-hover: #175a4d;
  --f-accent-lip: #0e4238;
  --f-accent-soft: #e5eee7;
  --f-accent-soft-ink: #1a5f52;
  --f-danger: #a43243;
  --f-danger-hover: #8e2837;
  --f-danger-lip: #74202d;
  --f-danger-soft: #f8e8e6;
  --f-streak: #d9730d;
  --f-streak-ink: #9a4d07;
  --f-streak-soft: #f8ecd9;
  --f-soon-ink: #8a5a00;
  --f-soon-soft: #f7eed6;
  --f-night-ink: #0d5963;
  --f-night-soft: #def4f3;
  --f-sky-ink: #477016;
  --f-sky-soft: #eef7dd;
  --f-ring: 0 0 0 4px rgba(28, 106, 91, 0.16);
  --f-shadow: 0 0 0 1px rgba(19, 32, 27, 0.04), 0 22px 44px -22px rgba(19, 32, 27, 0.24);
  --f-shadow-sm: 0 0 0 1px rgba(19, 32, 27, 0.04), 0 10px 24px -16px rgba(19, 32, 27, 0.22);
  --f-shadow-hover: 0 0 0 1px rgba(19, 32, 27, 0.05), 0 30px 54px -24px rgba(19, 32, 27, 0.30);
  --f-shadow-pop: 0 0 0 1px rgba(19, 32, 27, 0.05), 0 32px 72px -24px rgba(19, 32, 27, 0.36);
  --f-radius-card: 28px;
  --f-radius-hero: 36px;
  --f-radius-input: 18px;
  --f-radius-pill: 999px;
  --f-font: 'Geist', Inter, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --f-mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  --f-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --f-max: 1080px;
  --f-gutter: 16px;
}

@media (min-width: 640px) {
  :root { --f-gutter: 24px; }
}

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

[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: 84px;
}

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: var(--f-bg);
  background-image:
    radial-gradient(1100px 520px at 50% -260px, rgba(186, 228, 204, 0.55), rgba(186, 228, 204, 0) 72%),
    linear-gradient(180deg, #eef3ea 0, rgba(246, 248, 242, 0) 440px);
  background-repeat: no-repeat;
  color: var(--f-text);
  font-family: var(--f-font);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

html.modal-open { overflow: hidden; }

h1, h2, h3, h4, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img, svg { display: block; }
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
a { color: var(--f-accent); }

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--f-accent);
  outline-offset: 3px;
}

[tabindex="-1"]:focus { outline: none; }

.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px;
  top: -80px;
  z-index: 200;
  padding: 10px 16px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface);
  color: var(--f-text);
  font-weight: 650;
  text-decoration: none;
  box-shadow: var(--f-shadow);
}
.skip-link:focus { top: 12px; }

.ico {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
}
.ico svg { width: 100%; height: 100%; }
.ico-sm { width: 16px; height: 16px; }

.num { font-variant-numeric: tabular-nums; }
.unit { font-size: 0.55em; font-weight: 620; color: var(--f-text-2); margin-left: 1px; letter-spacing: 0; }

/* ── top bar ──────────────────────────────────────────────────────────── */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color 0.2s var(--f-ease), border-color 0.2s var(--f-ease);
}
.topbar.is-scrolled {
  background: rgba(246, 248, 242, 0.86);
  -webkit-backdrop-filter: saturate(1.4) blur(16px);
  backdrop-filter: saturate(1.4) blur(16px);
  border-bottom-color: var(--f-hair);
}

.topbar-inner {
  max-width: var(--f-max);
  height: 66px;
  margin: 0 auto;
  padding: 0 var(--f-gutter);
  display: flex;
  align-items: center;
  gap: 12px;
}

.brand {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 10px;
  color: var(--f-text);
  text-decoration: none;
  border-radius: 12px;
}
/* The student app's sidebar lockup, as it renders there: the mark in a 42px
   slot (its artwork is half the PNG) beside "Aluma" at 15px. */
.brand-logo { width: 42px; height: 42px; object-fit: contain; }
.brand-word { font-size: 15px; font-weight: 700; letter-spacing: -0.02em; }

.topbar-family {
  min-width: 0;
  padding-left: 12px;
  border-left: 1px solid var(--f-border-strong);
  color: var(--f-text-2);
  font-size: 14px;
  font-weight: 560;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 459px) {
  .topbar-family { display: none; }
}

.topbar-end {
  position: relative;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
}

.acct-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 4px 12px 4px 4px;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface);
  box-shadow: var(--f-shadow-sm);
  cursor: pointer;
  transition: box-shadow 0.18s var(--f-ease);
}
.acct-btn:hover { box-shadow: var(--f-shadow); }
.acct-btn .avatar { width: 34px; height: 34px; font-size: 14px; }
.acct-name {
  max-width: 140px;
  font-size: 14px;
  font-weight: 640;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.acct-btn .ico { width: 16px; height: 16px; color: var(--f-icon); transition: transform 0.18s var(--f-ease); }
.acct-btn[aria-expanded="true"] .ico { transform: rotate(180deg); }

.acct-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  z-index: 60;
  width: min(290px, calc(100vw - 32px));
  padding: 8px;
  border-radius: 24px;
  background: var(--f-surface);
  box-shadow: var(--f-shadow-pop);
  animation: f-pop 0.18s var(--f-ease);
}
.acct-menu-head { padding: 10px 14px 12px; border-bottom: 1px solid var(--f-hair); margin-bottom: 6px; }
.acct-menu-name { font-weight: 700; font-size: 15px; overflow-wrap: anywhere; }
.acct-menu-email { color: var(--f-text-2); font-size: 13px; overflow-wrap: anywhere; }
.acct-menu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: 16px;
  background: none;
  color: var(--f-text);
  font-size: 15px;
  font-weight: 580;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.acct-menu-item:hover { background: var(--f-surface-3); }
.acct-menu-item .ico { color: var(--f-icon); }
.acct-menu-item.is-danger,
.acct-menu-item.is-danger .ico { color: var(--f-danger); }
.acct-menu-item.is-danger:hover { background: var(--f-danger-soft); }

/* ── page shell ───────────────────────────────────────────────────────── */
.page {
  flex: 1 0 auto;
  width: 100%;
  max-width: var(--f-max);
  margin: 0 auto;
  padding: 20px var(--f-gutter) 64px;
}
@media (min-width: 900px) {
  .page { padding-top: 36px; }
}

.footer-inner {
  max-width: var(--f-max);
  margin: 0 auto;
  padding: 18px var(--f-gutter) calc(28px + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 24px;
}
.footer-promise { color: var(--f-text-2); font-size: 13px; }
.footer-links { display: flex; flex-wrap: wrap; gap: 4px 18px; }
@media (min-width: 700px) {
  .footer-links { margin-left: auto; }
}
.footer-links a {
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 580;
  text-decoration: none;
  border-radius: 6px;
}
.footer-links a:hover { color: var(--f-text); text-decoration: underline; }

.noscript {
  max-width: 520px;
  margin: 24px auto;
  padding: 18px 22px;
  border-radius: var(--f-radius-card);
  background: var(--f-surface);
  box-shadow: var(--f-shadow);
  text-align: center;
}

/* ── loading skeleton ─────────────────────────────────────────────────── */
.boot { display: flex; flex-direction: column; gap: 14px; }
.boot-grid {
  display: grid;
  gap: 20px;
  margin-top: 16px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}
.sk {
  display: block;
  border-radius: 14px;
  background: linear-gradient(90deg, #e5eee7 0%, #eff4ee 45%, #e5eee7 90%);
  background-size: 220% 100%;
  animation: f-shimmer 1.4s linear infinite;
}
.sk-line { height: 14px; }
.sk-title { height: 36px; width: min(420px, 80%); border-radius: 16px; }
.sk-card { height: 480px; border-radius: var(--f-radius-card); }
/* stands in for the "Your kids" heading */
.sk-h2 { height: 26px; width: 130px; margin-top: 26px; border-radius: 13px; }
.sk-row { height: 56px; border-radius: 18px; }
.sk-w30 { width: 30%; max-width: 180px; }
.sk-w60 { width: 60%; max-width: 360px; }
.sk-code { display: inline-block; width: 120px; height: 24px; vertical-align: middle; border-radius: var(--f-radius-pill); }

/* ── type ─────────────────────────────────────────────────────────────── */
.display {
  font-size: clamp(38px, 8.4vw, 58px);
  line-height: 1.02;
  font-weight: 800;
  letter-spacing: -0.05em;
}
.h1 {
  font-size: clamp(28px, 5.6vw, 38px);
  line-height: 1.1;
  font-weight: 780;
  letter-spacing: -0.04em;
}
.h2 {
  font-size: 21px;
  line-height: 1.25;
  font-weight: 750;
  letter-spacing: -0.025em;
}
.lede { color: var(--f-text-2); font-size: 17px; line-height: 1.5; overflow-wrap: anywhere; }
.muted { color: var(--f-text-2); }
.tiny { font-size: 13px; }

.section-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 16px;
}

.mini-label {
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 650;
  letter-spacing: 0;
}

/* ── cards ────────────────────────────────────────────────────────────── */
.card {
  background: var(--f-surface);
  border-radius: var(--f-radius-card);
  box-shadow: var(--f-shadow);
}
.card-pad { padding: 22px; }
@media (min-width: 640px) {
  .card-pad { padding: 26px; }
}

.icon-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 20px;
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.icon-badge .ico { width: 26px; height: 26px; }
.icon-badge.is-danger { background: var(--f-danger-soft); color: var(--f-danger); }
.icon-badge.is-warm { background: var(--f-streak-soft); color: var(--f-streak-ink); }
.icon-badge.is-night { background: var(--f-night-soft); color: var(--f-night-ink); }

/* ── buttons: pills with a pressed lip, as on aluma.fun ───────────────── */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 0 22px;
  border: 1px solid transparent;
  border-radius: var(--f-radius-pill);
  background: transparent;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s var(--f-ease), box-shadow 0.12s var(--f-ease),
    color 0.18s var(--f-ease), transform 0.12s var(--f-ease);
}
.btn[disabled] { cursor: not-allowed; opacity: 0.6; }
.btn .ico { width: 18px; height: 18px; }

.btn-primary {
  background: var(--f-accent);
  color: #fff;
  box-shadow: 0 3px 0 var(--f-accent-lip);
}
.btn-primary:hover:not([disabled]) { background: var(--f-accent-hover); }
.btn-primary:active:not([disabled]) { transform: translateY(2px); box-shadow: 0 1px 0 var(--f-accent-lip); }

.btn-secondary {
  background: #fff;
  border-color: var(--f-border);
  color: var(--f-text);
  box-shadow: 0 3px 0 rgba(19, 32, 27, 0.10);
}
.btn-secondary:hover:not([disabled]) { background: var(--f-surface-2); }
.btn-secondary:active:not([disabled]) { transform: translateY(2px); box-shadow: 0 1px 0 rgba(19, 32, 27, 0.10); }

.btn-soft {
  background: var(--f-accent-soft);
  color: var(--f-accent-soft-ink);
  box-shadow: 0 3px 0 rgba(26, 95, 82, 0.16);
}
.btn-soft:hover:not([disabled]) { background: #dae8de; }
.btn-soft:active:not([disabled]) { transform: translateY(2px); box-shadow: 0 1px 0 rgba(26, 95, 82, 0.16); }

.btn-quiet { min-height: 40px; padding: 0 14px; color: var(--f-accent); }
.btn-quiet:hover:not([disabled]) { background: var(--f-accent-soft); }
.btn-quiet.is-danger { color: var(--f-danger); }
.btn-quiet.is-danger:hover:not([disabled]) { background: var(--f-danger-soft); }
.btn-secondary.is-danger { color: var(--f-danger); }
.btn-secondary.is-danger:hover:not([disabled]) { background: var(--f-danger-soft); }

.btn-danger { background: var(--f-danger); color: #fff; box-shadow: 0 3px 0 var(--f-danger-lip); }
.btn-danger:hover:not([disabled]) { background: var(--f-danger-hover); }
.btn-danger:active:not([disabled]) { transform: translateY(2px); box-shadow: 0 1px 0 var(--f-danger-lip); }

.btn-sm { min-height: 38px; padding: 0 16px; font-size: 14px; }
.btn-lg { min-height: 54px; padding: 0 26px; font-size: 16px; }
.btn-block { width: 100%; }

.btn.is-busy { color: transparent !important; }
.btn.is-busy .ico { visibility: hidden; }
.btn.is-busy::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 18px;
  height: 18px;
  margin: -9px 0 0 -9px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.95);
  border-right-color: transparent;
  animation: f-spin 0.7s linear infinite;
}
.btn-secondary.is-busy::after,
.btn-quiet.is-busy::after,
.btn-soft.is-busy::after {
  border-color: var(--f-text-2);
  border-right-color: transparent;
}

.link-btn {
  display: inline;
  padding: 2px 0;
  border: 0;
  border-radius: 4px;
  background: none;
  color: var(--f-accent);
  font-size: inherit;
  font-weight: 640;
  text-decoration: underline;
  text-decoration-color: rgba(28, 106, 91, 0.3);
  text-underline-offset: 3px;
  cursor: pointer;
}
.link-btn:hover { text-decoration-color: currentColor; }
.link-btn.is-quiet { color: var(--f-text-2); text-decoration-color: rgba(83, 97, 89, 0.4); font-weight: 580; }

.actions { display: flex; flex-wrap: wrap; gap: 12px; }

/* ── forms ────────────────────────────────────────────────────────────── */
.form { display: flex; flex-direction: column; gap: 16px; }
.field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.label, .field > label, .label-row > label { font-size: 14px; font-weight: 640; color: var(--f-text); }
.label-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.label-row .link-btn { font-size: 13px; }

.input {
  width: 100%;
  min-height: 52px;
  padding: 13px 16px;
  border: 1px solid var(--f-border-strong);
  border-radius: var(--f-radius-input);
  background: var(--f-surface-2);
  color: var(--f-text);
  font-size: 16px;
  line-height: 1.3;
  transition: border-color 0.15s var(--f-ease), box-shadow 0.15s var(--f-ease), background-color 0.15s var(--f-ease);
}
.input::placeholder { color: var(--f-text-3); opacity: 1; }
.input:hover { border-color: rgba(19, 32, 27, 0.24); }
.input:focus { outline: none; border-color: var(--f-accent); box-shadow: var(--f-ring); background-color: #fff; }
.input[readonly] { background-color: var(--f-surface-3); color: var(--f-text-2); border-color: transparent; }
/* Fill only (background-color) in the two rules above: a `background:`
   shorthand on focus also wiped any icon a field paints as an image, so a
   dropdown's chevron vanished the moment it was opened. */
.input:disabled { opacity: 0.6; cursor: not-allowed; }

/* A dropdown, should a page grow one: the 12px stroked chevron the student
   and educator apps draw, in --f-text-3, its ink 16px inside the border with
   38px of room so no option runs under it. A list box ([multiple], or a
   [size] over 1) opens nothing and keeps no arrow; :where() holds this at
   select.input's own (0,1,1). */
select.input:where(:not([multiple]):is(:not([size]), [size="0"], [size="1"])) {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none' stroke='%23626e67' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2 4l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: 12px 12px;
  background-position: right 14px center;
  text-overflow: ellipsis;
  cursor: pointer;
}
select.input:disabled { cursor: not-allowed; }

/* The calendar and clock glyphs: on the same 16px line as the chevron (the
   date field's sat 20.5px in, past its own padding), and in the muted ink
   instead of full black. The date field keeps 14px on that side for it; the
   time fields already pad 12px. */
input.input[type="date"] { padding-right: 14px; }
.input::-webkit-calendar-picker-indicator { margin-inline-end: -2px; opacity: 0.62; cursor: pointer; }
.input::-webkit-calendar-picker-indicator:hover { opacity: 1; }
.input[aria-invalid="true"] { border-color: var(--f-danger); }
.input[aria-invalid="true"]:focus { box-shadow: 0 0 0 4px rgba(164, 50, 67, 0.14); }

.input-lock { position: relative; }
.input-lock .input { padding-right: 46px; }
.input-lock .ico {
  position: absolute;
  right: 16px;
  top: 50%;
  width: 18px;
  height: 18px;
  margin-top: -9px;
  color: var(--f-icon);
  pointer-events: none;
}

.pw-wrap { position: relative; }
.pw-wrap .input { padding-right: 54px; }
.pw-toggle {
  position: absolute;
  right: 6px;
  top: 50%;
  width: 40px;
  height: 40px;
  margin-top: -20px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: none;
  color: var(--f-icon);
  cursor: pointer;
}
.pw-toggle:hover { color: var(--f-text); background: var(--f-surface-3); }
.pw-toggle[aria-pressed="true"] { color: var(--f-accent); }

.field-hint { color: var(--f-text-2); font-size: 13px; }
/* An error says what the hint said ("Use at least 8 characters"): one of them. */
.field:has(> .field-error:not([hidden])) > .field-hint { display: none; }
.field-error { color: var(--f-danger); font-size: 13px; font-weight: 600; }

.form-error {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 18px;
  background: var(--f-danger-soft);
  color: var(--f-danger);
  font-size: 14px;
  font-weight: 580;
  line-height: 1.45;
}
.form-error .ico { width: 18px; height: 18px; margin-top: 1px; }
.form-error .link-btn { color: var(--f-danger); }
/* An invite for the other adult account waits at the address (adultSteer):
   a question with two ways on, not an error. */
.form-error.is-steer { background: var(--f-accent-soft); color: var(--f-text); }
.form-error.is-steer .ico { color: var(--f-accent); }
.form-error.is-steer .link-btn { color: var(--f-accent); }
.steer-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 18px; margin-top: 8px; }
.steer-go { display: inline-flex; align-items: center; min-height: 32px; color: var(--f-accent); font-weight: 680; }

.checks { display: flex; flex-direction: column; gap: 12px; }
.check {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: 11px;
  align-items: start;
  align-content: center;
  font-size: 14px;
  line-height: 1.45;
  cursor: pointer;
}
.check input {
  appearance: none;
  -webkit-appearance: none;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin: 0;
  border: 1.5px solid var(--f-icon);
  border-radius: 7px;
  background: #fff;
  cursor: pointer;
  transition: background-color 0.15s var(--f-ease), border-color 0.15s var(--f-ease);
}
.check input:checked { background: var(--f-accent); border-color: var(--f-accent); }
.check input:checked::after {
  content: "";
  width: 6px;
  height: 11px;
  border: solid #fff;
  border-width: 0 2.4px 2.4px 0;
  transform: translateY(-1px) rotate(45deg);
}
.check input[aria-invalid="true"] { border-color: var(--f-danger); }
.check-sub { display: block; color: var(--f-text-2); font-size: 13px; }
.check-tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 12px;
  font-weight: 640;
  vertical-align: 1px;
}

.divider-or {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--f-text-3);
  font-size: 13px;
  font-weight: 600;
}
.divider-or::before,
.divider-or::after { content: ""; flex: 1; height: 1px; background: var(--f-hair); }

/* ── tabs (a pill segmented control) ──────────────────────────────────── */
.tabs {
  display: flex;
  gap: 4px;
  padding: 5px;
  margin-bottom: 26px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
}
.tab {
  flex: 1 1 auto;
  min-height: 42px;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: none;
  color: var(--f-text-2);
  font-size: 14px;
  font-weight: 650;
  line-height: 1.2;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s var(--f-ease), color 0.18s var(--f-ease), box-shadow 0.18s var(--f-ease);
}
.tab:hover { color: var(--f-text); }
.tab[aria-selected="true"] {
  background: #fff;
  color: var(--f-text);
  box-shadow: 0 0 0 1px rgba(19, 32, 27, 0.04), 0 2px 6px rgba(19, 32, 27, 0.10);
}

/* ── signed-out landing ───────────────────────────────────────────────── */
.auth {
  display: grid;
  gap: 24px;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "hero" "card" "more";
}
.auth-hero { grid-area: hero; display: flex; flex-direction: column; gap: 12px; }
.auth-hero .lede { font-size: 18px; max-width: 32ch; text-wrap: pretty; }
/* The landing's headline runs a little looser than .display once there is
   room: at 800 weight -0.05em ran its letters together. */
@media (min-width: 640px) {
  .auth-hero .display { letter-spacing: -0.035em; }
}
.auth-card { grid-area: card; padding: 22px; border-radius: var(--f-radius-hero); }
.auth-more { grid-area: more; display: flex; flex-direction: column; gap: 16px; }
.auth-student { margin-top: 18px; text-align: center; font-size: 14px; }
.auth-student a { font-weight: 640; }
/* Educators have their own app: one quiet door to it, worded for the tab.
   The question sits over its link, so a phone never breaks the link. */
.auth-helper { display: flex; flex-direction: column; align-items: center; gap: 2px; margin-top: 18px; text-align: center; }
.auth-q { color: var(--f-text-2); font-size: 13px; }
.auth-helper a { display: block; font-size: 14px; font-weight: 640; }
.auth-helper + .auth-student { margin-top: 10px; }
/* Each door is a target of its own, never a 20px line of text. */
.auth-helper a,
.auth-student a { display: inline-flex; align-items: center; justify-content: center; min-height: 28px; }
/* Two tabs in a 320px card: each takes half and may wrap, never poking out. */
@media (max-width: 359px) {
  .auth-card .tabs .tab { flex: 1 1 0; min-width: 0; padding-inline: 8px; white-space: normal; text-align: center; }
}
@media (min-width: 640px) {
  .auth-card { padding: 32px; }
}
/* Two columns: the headline's top lines up with the card's, and the sample
   fills the column under it, so the two sides end near the same line. */
@media (min-width: 920px) {
  .auth {
    grid-template-columns: minmax(0, 1fr) minmax(380px, 440px);
    grid-template-areas: "hero card" "more card";
    grid-template-rows: auto 1fr;
    column-gap: 64px;
    row-gap: 28px;
    align-items: start;
  }
  .auth-card { position: sticky; top: 96px; }
}
/* One column: the sign-in card is as wide as every other signed-out card. */
@media (max-width: 919px) {
  .auth { max-width: 480px; margin: 0 auto; }
}

/* The sample card fills its column. From 500px wide it splits in two (the
   week on the left, what's next on the right), so it reads as a card rather
   than a tall strip. */
.preview { width: 100%; margin: 0; container: preview / inline-size; }
.preview-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 24px;
  border-radius: var(--f-radius-card);
  background: var(--f-surface);
  box-shadow: var(--f-shadow);
}
@container preview (min-width: 500px) {
  .preview-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas:
      "head head"
      "counts counts"
      "study next"
      "chips next";
    grid-template-rows: auto auto auto 1fr;
    column-gap: 28px;
    row-gap: 16px;
    align-items: start;
  }
  .preview-card > .kid-head { grid-area: head; }
  .preview-card > .counts { grid-area: counts; }
  .preview-card > .study-row { grid-area: study; }
  .preview-card > .next { grid-area: next; align-self: stretch; padding-left: 24px; border-left: 1px solid var(--f-hair); }
  .preview-card > .chips { grid-area: chips; }
  .preview-card .next-title { white-space: normal; overflow-wrap: anywhere; }
}

.privacy-line {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--f-text-2);
  font-size: 14px;
  font-weight: 580;
}
.privacy-line .ico { width: 18px; height: 18px; color: var(--f-accent); }

/* ── narrow centered cards (invites, the code step, results) ──────────── */
.narrow { max-width: 480px; margin: 0 auto; }
.narrow.is-wide { max-width: 540px; }
.center-card {
  padding: 32px 22px;
  border-radius: var(--f-radius-hero);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
@media (min-width: 640px) {
  .center-card { padding: 40px 40px 36px; }
}
.center-card .h1 { font-size: 28px; line-height: 1.15; }
.center-card .lede { font-size: 16px; line-height: 1.5; }
.center-card .actions { justify-content: center; margin-top: 6px; }
@media (max-width: 559px) {
  .center-card .actions { align-self: stretch; }
  .center-card .actions .btn { flex: 1 1 100%; }
}
.center-card .form { width: 100%; text-align: left; }
.center-foot { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; font-size: 14px; color: var(--f-text-2); }

.code-input {
  text-align: center;
  font-family: var(--f-mono);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: 0.22em;
  min-height: 64px;
}
.code-input::placeholder { letter-spacing: 0.22em; }

.note {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 13px 15px;
  border-radius: 18px;
  background: var(--f-surface-2);
  color: var(--f-text-2);
  font-size: 14px;
  text-align: left;
}
.note .ico { width: 18px; height: 18px; margin-top: 2px; color: var(--f-icon); }
.note > span { min-width: 0; overflow-wrap: anywhere; }
.note strong { color: var(--f-text); }
.note.is-warm { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.note.is-warm .ico { color: var(--f-soon-ink); }
.note.is-ok { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }
.note.is-ok .ico { color: var(--f-accent); }

.invite-card { padding: 30px 22px 24px; border-radius: var(--f-radius-hero); }
@media (min-width: 640px) {
  .invite-card { padding: 40px 40px 30px; }
}
.invite-head { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; margin-bottom: 26px; }
.invite-head .lede { font-size: 16px; }
.invite-decline { margin-top: 22px; text-align: center; font-size: 14px; color: var(--f-text-2); }
/* A student account at an adult invite's address: the ways out. */
.invite-mistake { margin: -10px 0 18px; font-size: 15px; color: var(--f-text-2); }
.invite-other { margin-top: 16px; text-align: center; font-size: 14px; }
/* What an educator would see, said in Add an educator before the Send:
   three short lines, each led by its word. */
.scope-note .ico { color: var(--f-accent); }
.scope-lines { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.scope-line { display: grid; grid-template-columns: 50px minmax(0, 1fr); gap: 8px; line-height: 1.45; }
.scope-line strong { font-weight: 720; }
.scope-line span { min-width: 0; overflow-wrap: anywhere; }
.action-stack { display: flex; flex-direction: column; gap: 12px; }

/* ── avatars ──────────────────────────────────────────────────────────── */
.avatar {
  --av-bg: #dcf1e4;
  --av-ink: #1d6641;
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--av-bg);
  color: var(--av-ink);
  font-size: 16px;
  font-weight: 740;
  letter-spacing: -0.02em;
  line-height: 1;
  user-select: none;
}
.avatar-lg { width: 52px; height: 52px; font-size: 20px; }
.avatar-xl { width: 68px; height: 68px; font-size: 27px; }
.avatar-sm { width: 32px; height: 32px; font-size: 13px; }

/* ── dashboard ────────────────────────────────────────────────────────── */
.dash { display: flex; flex-direction: column; gap: 40px; }
.dash.is-empty { max-width: 640px; margin: 0 auto; gap: 32px; }
.greet { display: flex; flex-direction: column; gap: 6px; }
.greet-date { color: var(--f-text-2); font-size: 14px; font-weight: 600; }
.greet-sub { color: var(--f-text-2); font-size: 17px; max-width: 60ch; }

.kids-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.kid-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px;
  transition: transform 0.2s var(--f-ease), box-shadow 0.2s var(--f-ease);
}
.kid-card:hover { transform: translateY(-2px); box-shadow: var(--f-shadow-hover); }
.kid-card:active { transform: translateY(0); }
.kid-head { display: flex; align-items: center; gap: 14px; min-width: 0; }
.kid-id { min-width: 0; flex: 1; }
.kid-name { font-size: 20px; font-weight: 760; letter-spacing: -0.025em; line-height: 1.2; }
.kid-open {
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.kid-open::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: var(--f-radius-card);
}
.kid-open:focus-visible { outline: 2px solid var(--f-accent); outline-offset: 2px; }
@supports selector(:has(*)) {
  .kid-open:focus-visible { outline: none; }
  .kid-card:has(.kid-open:focus-visible) { outline: 2px solid var(--f-accent); outline-offset: 3px; }
}
.kid-meta { color: var(--f-text-2); font-size: 14px; margin-top: 2px; }

.streak {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 5px;
  padding: 6px 12px 6px 9px;
  border-radius: var(--f-radius-pill);
  background: var(--f-streak-soft);
  color: var(--f-streak-ink);
  font-size: 15px;
  font-weight: 740;
}
.streak .ico { width: 18px; height: 18px; color: var(--f-streak); }
.streak.is-zero { background: var(--f-surface-3); color: var(--f-text-2); }
.streak.is-zero .ico { color: var(--f-icon); }

.badges { display: flex; flex-wrap: wrap; gap: 8px; }
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 650;
}
.badge .ico { width: 15px; height: 15px; }
.badge.is-night { background: var(--f-night-soft); color: var(--f-night-ink); }

.counts {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px;
  padding: 14px 4px;
  border-radius: 22px;
  background: var(--f-surface-2);
}
.count { display: flex; flex-direction: column; align-items: center; gap: 3px; text-align: center; min-width: 0; }
.count-num { font-size: 25px; font-weight: 760; letter-spacing: -0.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.count-label { color: var(--f-text-2); font-size: 12px; font-weight: 600; line-height: 1.25; }
.count.is-alert .count-num,
.count.is-alert .count-label { color: var(--f-danger); }
.count.is-zero .count-num { color: var(--f-text-3); }

.study-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.study-label { color: var(--f-text-2); font-size: 14px; font-weight: 600; }
.study-value { font-size: 24px; font-weight: 760; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.study-today { color: var(--f-text-3); font-size: 13px; font-weight: 560; }

.next { display: flex; flex-direction: column; gap: 6px; }
.next-list { display: flex; flex-direction: column; }
.next-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 12px;
  padding: 10px 0;
}
.next-row + .next-row { border-top: 1px solid var(--f-hair); }
.next-title { font-size: 15px; font-weight: 640; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.next-class { color: var(--f-text-2); font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.next-empty { color: var(--f-text-2); font-size: 14px; padding: 4px 0; }

.due {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 11px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 650;
  white-space: nowrap;
}
.due.is-today { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.due.is-done,
.due.is-soon { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }
.due.is-late { background: var(--f-danger-soft); color: var(--f-danger); }

/* the kinds of work worth planning around: a test, a quiz, an essay */
.kind-badge {
  display: inline-flex;
  flex: none;
  align-items: center;
  padding: 1px 7px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 11px;
  font-weight: 720;
  line-height: 1.5;
  white-space: nowrap;
}
.kind-badge.is-test { background: var(--f-streak-soft); color: var(--f-streak-ink); }
.kind-badge.is-quiz { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.kind-badge.is-project { background: var(--f-night-soft); color: var(--f-night-ink); }
.kind-badge.is-essay { background: var(--f-sky-soft); color: var(--f-sky-ink); }
.kind-badge.is-lab { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px 6px 10px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 620;
  white-space: nowrap;
}
.chip .ico { width: 14px; height: 14px; color: var(--f-icon); }
.chip.is-off { background: var(--f-night-soft); color: var(--f-night-ink); }
.chip.is-off .ico { color: var(--f-night-ink); }

.kid-foot {
  margin-top: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding-top: 2px;
}
.kid-more { display: inline-flex; align-items: center; gap: 2px; margin-left: auto; color: var(--f-accent); font-size: 14px; font-weight: 680; }
.kid-more .ico { width: 16px; height: 16px; transition: transform 0.2s var(--f-ease); }
.kid-card:hover .kid-more .ico { transform: translateX(3px); }

.adult-note {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border-radius: 18px;
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 14px;
}
.adult-note .ico { width: 18px; height: 18px; margin-top: 1px; }

.add-kid-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 200px;
  padding: 24px 20px;
  border: 1.5px dashed rgba(19, 32, 27, 0.16);
  border-radius: var(--f-radius-card);
  background: rgba(255, 255, 255, 0.5);
  color: var(--f-text);
  font: inherit;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.2s var(--f-ease), background-color 0.2s var(--f-ease);
}
.add-kid-tile:hover { border-color: var(--f-accent); background: rgba(229, 238, 231, 0.6); }
.add-kid-ico {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.add-kid-title { font-size: 18px; font-weight: 740; letter-spacing: -0.015em; }
.add-kid-sub { color: var(--f-text-2); font-size: 14px; }
@media (max-width: 699px) {
  .add-kid-tile {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 14px;
    row-gap: 2px;
    justify-items: start;
    min-height: 0;
    padding: 18px 20px;
    text-align: left;
  }
  .add-kid-ico { grid-row: 1 / span 2; align-self: center; width: 44px; height: 44px; }
  .add-kid-title { align-self: end; font-size: 16px; }
  .add-kid-sub { align-self: start; }
}

.dash-cols { display: grid; gap: 20px; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 960px) {
  .dash-cols { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
  .dash-cols.is-single { grid-template-columns: minmax(0, 1fr); }
}

/* invites waiting on this parent; an approval is the loudest thing here */
.incoming { display: flex; flex-direction: column; gap: 16px; }
.approve-card {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 28px 22px;
  border-radius: var(--f-radius-hero);
  background:
    radial-gradient(90% 120% at 100% 0%, rgba(206, 234, 214, 0.6), rgba(206, 234, 214, 0) 60%),
    var(--f-surface);
  box-shadow: 0 0 0 1px rgba(28, 106, 91, 0.12), 0 28px 56px -24px rgba(19, 32, 27, 0.32);
}
@media (min-width: 640px) {
  .approve-card { padding: 36px 40px; }
}
.approve-head { display: flex; align-items: center; gap: 18px; }
.approve-title { font-size: clamp(24px, 4.8vw, 32px); line-height: 1.12; font-weight: 780; letter-spacing: -0.035em; }
.approve-head .lede { margin-top: 6px; font-size: 16px; }
.approve-card .consent-note { background: rgba(251, 252, 247, 0.9); }
@media (max-width: 559px) {
  .approve-head { flex-direction: column; align-items: flex-start; gap: 14px; }
  .approve-card .actions .btn { flex: 1 1 100%; }
}

.incoming-card { display: flex; flex-direction: column; gap: 16px; padding: 22px 24px; }
.incoming-top { display: flex; gap: 14px; align-items: center; }
.incoming-title { font-size: 18px; font-weight: 740; letter-spacing: -0.02em; }
.incoming-text { color: var(--f-text-2); font-size: 15px; margin-top: 2px; }
.from-email { margin-top: 2px; color: var(--f-text-2); font-size: 14px; font-weight: 600; overflow-wrap: break-word; }

/* the race */
.race { padding: 24px; }
/* 16px to the first row, the gap every toolbar in the app leaves. */
.race-head { display: flex; flex-direction: column; gap: 16px; margin-bottom: 16px; }
.race-title-row { display: flex; align-items: center; gap: 12px; }
.race-trophy {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 14px;
  background: var(--f-soon-soft);
  color: var(--f-soon-ink);
}
.race-list { display: flex; flex-direction: column; }
.race-row { display: grid; grid-template-columns: 30px 38px minmax(0, 1fr) 80px; align-items: center; gap: 12px; padding: 12px 0; }
.race-row + .race-row { border-top: 1px solid var(--f-hair); }
.race-row .avatar { width: 38px; height: 38px; font-size: 15px; }
.rank {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 760;
  font-variant-numeric: tabular-nums;
}
.rank.is-gold { background: linear-gradient(160deg, #fbe7a6, #f0cd5f); color: #5c4300; }
.rank.is-silver { background: linear-gradient(160deg, #f1f3f4, #d8dde1); color: #3b4650; }
.rank.is-bronze { background: linear-gradient(160deg, #f7dcc5, #e9bd97); color: #6b3a12; }
.race-name { font-weight: 680; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.race-bar { height: 6px; margin-top: 7px; border-radius: var(--f-radius-pill); background: var(--f-surface-3); overflow: hidden; }
.race-bar span {
  display: block;
  height: 100%;
  min-width: 6px;
  border-radius: inherit;
  background: linear-gradient(90deg, #8fd0ad, var(--f-accent));
  transition: width 0.35s var(--f-ease);
}
.race-value { text-align: right; font-size: 21px; font-weight: 760; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
/* Out of the race: the name at full contrast in the muted ink, only the
   avatar faded (opacity put the name at 4.44:1). */
.race-row.is-hidden .race-name { color: var(--f-text-2); }
.race-row.is-hidden .avatar { opacity: 0.6; }
.race-off { color: var(--f-text-3); font-size: 13px; font-weight: 560; }

/* a segmented control built from radio inputs */
.seg { display: flex; gap: 2px; padding: 4px; border-radius: var(--f-radius-pill); background: var(--f-surface-3); }
.seg-opt { position: relative; flex: 1 1 0; min-width: 0; display: flex; }
.seg-opt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.seg-opt label {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  padding: 6px 8px;
  border-radius: var(--f-radius-pill);
  color: var(--f-text-2);
  font-size: 14px;
  font-weight: 650;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s var(--f-ease), color 0.18s var(--f-ease), box-shadow 0.18s var(--f-ease);
}
.seg-opt input:checked + label {
  background: #fff;
  color: var(--f-text);
  box-shadow: 0 0 0 1px rgba(19, 32, 27, 0.04), 0 2px 6px rgba(19, 32, 27, 0.10);
}
.seg-opt input:hover:not(:checked) + label { color: var(--f-text); }
.seg-opt input:focus-visible + label { outline: 2px solid var(--f-accent); outline-offset: 1px; }
.seg-opt input:disabled + label { cursor: not-allowed; opacity: 0.6; }

/* activity */
.activity { padding: 24px; }
@media (min-width: 960px) {
  /* level with the race's title beside it */
  .activity .section-head { min-height: 40px; }
}
.activity-list { display: flex; flex-direction: column; }
.activity-row { display: grid; grid-template-columns: 34px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 10px 0; }
.activity-row + .activity-row { border-top: 1px solid var(--f-hair); }
.activity-ico {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 12px;
  background: var(--f-surface-3);
  color: var(--f-text-2);
}
.activity-ico .ico { width: 17px; height: 17px; }
.activity-ico.is-green { background: var(--f-accent-soft); color: var(--f-accent); }
.activity-ico.is-night { background: var(--f-night-soft); color: var(--f-night-ink); }
.activity-ico.is-warm { background: var(--f-streak-soft); color: var(--f-streak-ink); }
.activity-ico.is-danger { background: var(--f-danger-soft); color: var(--f-danger); }
.activity-text { font-size: 14px; line-height: 1.4; overflow-wrap: anywhere; }
.activity-time { color: var(--f-text-3); font-size: 13px; white-space: nowrap; }
.activity-empty { color: var(--f-text-2); font-size: 14px; padding: 6px 0; }
.activity-more { margin-top: 6px; }
@media (max-width: 559px) {
  .activity-row { grid-template-columns: 34px minmax(0, 1fr); row-gap: 0; }
  .activity-time { grid-column: 2; font-size: 12px; }
}

/* ── add your child ───────────────────────────────────────────────────── */
.onboard { overflow: hidden; border-radius: var(--f-radius-hero); }
.onboard-main { display: flex; flex-direction: column; gap: 22px; padding: 28px 22px 24px; }
@media (min-width: 640px) {
  .onboard-main { padding: 38px 40px 30px; }
}
.onboard-head { display: flex; flex-direction: column; gap: 8px; }
.onboard-title { font-size: clamp(26px, 5vw, 32px); line-height: 1.12; font-weight: 780; letter-spacing: -0.035em; overflow-wrap: break-word; }
.onboard-head .lede,
.sent .lede { font-size: 16px; }
.support-line { color: var(--f-text-2); font-size: 14px; }
.support-line a,
.consent-note a { font-weight: 640; }
.consent-note a { white-space: nowrap; }
.consent-note {
  padding: 12px 14px;
  border-radius: 18px;
  background: var(--f-surface-2);
  color: var(--f-text-2);
  font-size: 13px;
  line-height: 1.5;
}
@media (max-width: 559px) {
  .onboard .actions .btn-primary,
  .modal .form .actions .btn-primary { flex: 1 1 auto; }
  .sent .actions { align-self: stretch; }
  .sent .actions .btn { flex: 1 1 100%; }
}

.onboard-code { padding: 16px 22px 20px; border-top: 1px solid var(--f-hair); background: var(--f-surface-2); }
@media (min-width: 640px) {
  .onboard-code { padding: 18px 40px 22px; }
}
.code-line { color: var(--f-text-2); font-size: 14px; line-height: 1.9; }
.code-line strong { color: var(--f-text); font-weight: 640; white-space: nowrap; }
.code-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 4px 1px 11px;
  border-radius: var(--f-radius-pill);
  background: #fff;
  box-shadow: 0 0 0 1px var(--f-border);
  color: var(--f-text);
  font-family: var(--f-mono);
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0.06em;
  white-space: nowrap;
  vertical-align: 1px;
}
.code-copy {
  display: inline-grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: none;
  color: var(--f-accent);
  cursor: pointer;
}
.code-copy:hover { background: var(--f-accent-soft); }
.code-copy .ico { width: 16px; height: 16px; }

.sent { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.sent-badge {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border-radius: 20px;
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.sent-badge .ico { width: 27px; height: 27px; }
.sent-badge.is-warm { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.sent-check {
  position: absolute;
  right: -5px;
  bottom: -5px;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--f-accent);
  color: #fff;
  box-shadow: 0 0 0 3px var(--f-surface);
}
.sent-check .ico { width: 14px; height: 14px; }
.sent-check.is-waiting { background: var(--f-surface); color: var(--f-accent); box-shadow: 0 0 0 3px var(--f-surface), inset 0 0 0 1.5px rgba(28, 106, 91, 0.35); }
.sent-meta { color: var(--f-text-3); font-size: 13px; font-weight: 580; }
.sent .actions { margin-top: 4px; }
.sent .btn-quiet { margin-left: -14px; }
.sent-others { width: 100%; display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.sent-others .row { padding-left: 0; padding-right: 0; }

.waiting .row:first-child { border-top: 0; }
.list-card { padding: 4px 0; }
.row.is-closed .row-title { color: var(--f-text-2); }

/* ── family settings: one card, two columns on wide screens ───────────── */
.settings-card { display: grid; grid-template-columns: minmax(0, 1fr); padding: 6px 0; }
.settings-col { display: flex; flex-direction: column; min-width: 0; }
.settings-col + .settings-col { border-top: 1px solid var(--f-hair); }
@media (min-width: 900px) {
  .settings-card { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .settings-col + .settings-col { border-top: 0; border-left: 1px solid var(--f-hair); }
}
.group-body { display: flex; flex-direction: column; }
.group-sub { padding: 18px 24px 4px; }
.row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  min-height: 60px;
  padding: 12px 24px;
  border-top: 1px solid var(--f-hair);
}
.group-sub + .row,
.settings-col > .row:first-child,
.row-form:first-child { border-top: 0; }
.row > .avatar,
.row > .activity-ico { flex: none; }
.row-main { min-width: 0; flex: 1 1 110px; }
.row-title { font-size: 15px; font-weight: 640; overflow-wrap: break-word; word-break: break-word; }
.row-sub { color: var(--f-text-2); font-size: 13px; overflow-wrap: break-word; }
.row-actions { display: flex; flex: none; gap: 6px; margin-left: auto; }
.row-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 12px 24px 16px; }
.row-form .input { flex: 1 1 200px; min-height: 46px; }
.row-buttons { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 24px 16px; }
.row-buttons.is-end { margin-top: auto; padding-top: 16px; }
.row-buttons.is-end > .btn-quiet:first-child { margin-left: -14px; }
.code-row { padding: 6px 24px 14px; }
.tag {
  display: inline-block;
  padding: 1px 9px;
  margin-left: 6px;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent-soft);
  color: var(--f-accent-soft-ink);
  font-size: 12px;
  font-weight: 680;
  vertical-align: 1px;
}
.tag.is-muted { background: var(--f-surface-3); color: var(--f-text-2); }

.code-small { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.code-value { font-family: var(--f-mono); font-size: 26px; font-weight: 650; letter-spacing: 0.06em; line-height: 1.1; font-variant-numeric: tabular-nums; user-select: all; }
.code-value.is-sm { font-size: 22px; }
.code-meta { color: var(--f-text-2); font-size: 13px; font-weight: 580; }
.code-actions { display: flex; flex-wrap: wrap; gap: 8px; flex-basis: 100%; }

/* ── the kid view ─────────────────────────────────────────────────────── */
.kid-view { display: flex; flex-direction: column; gap: 28px; }
.back-btn { align-self: flex-start; min-height: 44px; margin-left: -12px; }
.kid-hero { display: flex; align-items: center; gap: 18px; }
.kid-hero-text { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.kid-hero .h1 { overflow-wrap: anywhere; }
.kid-hero-meta { color: var(--f-text-2); font-size: 15px; }
/* The age and last active, then (13 and up) the status word beside them. */
.kid-hero-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.kid-hero-status { display: inline-flex; }
.kid-hero-status .status-pill { padding: 3px 10px; font-size: 12.5px; }
.kid-hero .badges { margin-top: 4px; }
/* A jump to what sits far down at every width: the rules from 13 (below the
   calendar and the educators), the schoolwork under 13 (below the rules). */
.jump-rules { align-self: flex-start; margin-top: 6px; }

.banner {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 16px 20px;
  border-radius: 22px;
  background: var(--f-surface);
  box-shadow: var(--f-shadow-sm);
  font-size: 15px;
}
.banner .ico { color: var(--f-accent); }
.banner strong { font-weight: 700; }

.stats-card { padding: 22px 24px; }
.stats { display: grid; gap: 20px 12px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 720px) {
  .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stats.is-three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.stat { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.stat-label { display: flex; align-items: center; gap: 7px; color: var(--f-text-2); font-size: 13px; font-weight: 640; }
.stat-label .ico { width: 16px; height: 16px; color: var(--f-icon); }
.stat-label .ico.is-warm { color: var(--f-streak); }
.stat-value { font-size: 30px; font-weight: 780; letter-spacing: -0.035em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.stat-sub { color: var(--f-text-3); font-size: 13px; font-weight: 560; }
.goal-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--f-hair);
}
@media (min-width: 720px) {
  .goal-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr); gap: 28px; }
}
.goal-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.goal-title { font-size: 17px; font-weight: 720; letter-spacing: -0.015em; }
.goal-bar { display: flex; align-items: center; gap: 12px; }
.progress { flex: 1; height: 8px; border-radius: var(--f-radius-pill); background: var(--f-surface-3); overflow: hidden; }
.progress span { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #8fd0ad, var(--f-accent)); }
.goal-pct { flex: none; min-width: 44px; text-align: right; font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; }

.kid-layout { display: grid; gap: 24px; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 980px) {
  .kid-layout { grid-template-columns: minmax(0, 1.2fr) minmax(360px, 1fr); gap: 28px; }
}
.kid-main,
.kid-side { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
/* The detail didn't come: say so plainly, with the way to ask again. */
.detail-error { display: flex; align-items: flex-start; gap: 16px; }
.detail-error-text { min-width: 0; }
.detail-error-title { font-size: 16px; font-weight: 720; letter-spacing: -0.01em; overflow-wrap: anywhere; }
.detail-error .muted { margin-top: 2px; font-size: 14px; }
.icon-badge.is-sm { flex: none; width: 44px; height: 44px; border-radius: 16px; }
.icon-badge.is-sm .ico { width: 21px; height: 21px; }

.work-card { padding: 4px 24px 10px; }
.work-group + .work-group { border-top: 1px solid var(--f-hair); }
.work-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 0 4px; }
.work-title { font-size: 16px; font-weight: 740; letter-spacing: -0.015em; }
.work-count {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 8px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 720;
  font-variant-numeric: tabular-nums;
}
.work-group.is-alert .work-title { color: var(--f-danger); }
.work-group.is-alert .work-count { background: var(--f-danger-soft); color: var(--f-danger); }
.work-head-end { display: inline-flex; flex: none; align-items: center; gap: 8px; }
/* "2 missing" beside the Overdue count */
.work-note { color: var(--f-danger); font-size: 13px; font-weight: 680; }
.work-list { display: flex; flex-direction: column; }
.work-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 11px 0; }
.work-row + .work-row { border-top: 1px solid var(--f-hair); }
.work-name { font-size: 15px; font-weight: 640; overflow-wrap: anywhere; }
.work-class { color: var(--f-text-2); font-size: 13px; }
.work-row.is-done .work-name { color: var(--f-text-2); }
.work-empty { color: var(--f-text-2); font-size: 14px; padding: 4px 0 14px; }
.work-more { padding: 4px 0 12px; }
.grade { font-size: 15px; font-weight: 720; font-variant-numeric: tabular-nums; }

/* ── the calendar card: due work and planned study, a week at a time ──── */
.cal-card { display: flex; flex-direction: column; gap: 16px; padding: 20px 16px 18px; }
@media (min-width: 640px) {
  .cal-card { padding: 24px 24px 20px; }
}
.cal-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; }
.cal-title-wrap { display: flex; align-items: center; gap: 12px; min-width: 0; }
.cal-ico {
  display: grid;
  flex: none;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 14px;
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.cal-range { min-height: 21px; color: var(--f-text-2); font-size: 14px; font-weight: 600; }
.cal-nav { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.cal-step {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--f-border);
  border-radius: 50%;
  background: #fff;
  color: var(--f-text);
  cursor: pointer;
  box-shadow: 0 2px 0 rgba(19, 32, 27, 0.08);
  transition: background-color 0.18s var(--f-ease), transform 0.12s var(--f-ease);
}
.cal-step:hover:not([disabled]) { background: var(--f-surface-2); }
.cal-step:active:not([disabled]) { transform: translateY(1px); }
.cal-step[disabled] { cursor: not-allowed; opacity: 0.5; }
.cal-home { min-height: 44px; }
/* On this week already: it stays focusable (focus doesn't jump), just quiet. */
.cal-home[aria-disabled="true"] { background: var(--f-surface-3); border-color: transparent; color: var(--f-text-2); box-shadow: none; cursor: default; }
.cal-home[aria-disabled="true"]:active { transform: none; }

.cal-body { min-width: 0; }
/* Phones and tablets: one day under the next, the date at the side. */
.cal-days { display: flex; flex-direction: column; gap: 8px; }
.cal-day {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  min-width: 0;
  padding: 12px;
  border-radius: 20px;
  background: var(--f-surface-2);
  box-shadow: inset 0 0 0 1px var(--f-hair);
}
.cal-day.is-today { background: var(--f-accent-soft); box-shadow: inset 0 0 0 1.5px rgba(28, 106, 91, 0.32); }
.cal-days.is-loading .cal-day { min-height: 64px; box-shadow: none; }
.cal-date { display: flex; flex-direction: column; align-items: center; gap: 1px; font-size: inherit; text-align: center; }
.cal-wd { color: var(--f-text-2); font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; }
.cal-dn { font-size: 22px; font-weight: 760; letter-spacing: -0.03em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.cal-day.is-past .cal-dn { color: var(--f-text-2); }
.cal-today {
  margin-top: 3px;
  padding: 1px 8px;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent);
  color: #fff;
  font-size: 11px;
  font-weight: 720;
}
/* A free day is one quiet line. */
.cal-day.is-empty { align-items: center; padding-top: 7px; padding-bottom: 7px; background: transparent; }
.cal-day.is-empty.is-today { background: var(--f-accent-soft); }
.cal-day.is-empty .cal-date { flex-direction: row; justify-content: center; align-items: baseline; gap: 5px; }
.cal-day.is-empty .cal-dn { font-size: 16px; }
.cal-day.is-empty .cal-today { margin: 0; }
/* A free today carries its Today pill on the same line: the date column
   grows to hold it instead of running over "Free". */
.cal-day.is-empty.is-today { grid-template-columns: auto minmax(0, 1fr); }
.cal-day-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.cal-free { color: var(--f-text-2); font-size: 14px; }
.cal-list { display: flex; flex-direction: column; gap: 6px; }
.cal-item {
  min-width: 0;
  padding: 8px 10px 8px 12px;
  border-radius: 14px;
  background: #fff;
  box-shadow: inset 3px 0 0 var(--f-accent), 0 0 0 1px var(--f-hair);
}
.cal-item.is-late { background: var(--f-danger-soft); box-shadow: inset 3px 0 0 var(--f-danger); }
.cal-item.is-late .cal-title { color: var(--f-danger); }
.cal-item.is-done { background: transparent; box-shadow: 0 0 0 1px var(--f-hair); }
.cal-item.is-done .cal-title { color: var(--f-text-2); text-decoration: line-through; text-decoration-color: rgba(83, 97, 89, 0.5); }
/* A planned sitting is the student's own plan: outlined, not a deadline. */
.cal-item.is-plan { padding-left: 10px; background: rgba(255, 255, 255, 0.6); box-shadow: inset 0 0 0 1.5px rgba(28, 106, 91, 0.26); }
.cal-item.is-plan.is-done { box-shadow: inset 0 0 0 1px var(--f-hair); }
.cal-item.is-plan.is-done .cal-title { color: var(--f-text-2); }
.cal-plan-line { color: var(--f-accent-soft-ink); font-size: 12px; font-weight: 720; line-height: 1.4; }
.cal-plan-line .ico { margin-right: 4px; vertical-align: -3px; color: var(--f-accent); }
.cal-session {
  display: inline-block;
  padding: 0 6px;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent-soft);
  color: var(--f-accent-soft-ink);
  font-size: 11px;
  font-weight: 720;
  white-space: nowrap;
}
.cal-title { font-size: 14px; font-weight: 650; line-height: 1.3; overflow-wrap: anywhere; }
.cal-tick { display: inline-flex; margin-right: 4px; vertical-align: -3px; color: var(--f-accent); }
.cal-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 6px; margin-top: 3px; color: var(--f-text-2); font-size: 12px; font-weight: 560; }
.cal-class { min-width: 0; overflow-wrap: anywhere; }
.cal-flag { color: var(--f-danger); font-weight: 720; }
/* "Moved by Ms Ortiz": the educator's hand in the accent, as on the kid's own calendar. */
.cal-meta.cal-by { flex-wrap: nowrap; align-items: flex-start; gap: 4px; color: var(--f-accent-soft-ink); font-weight: 680; }
.cal-by .ico { flex: none; margin-top: 1px; color: var(--f-accent); }
.cal-by span { min-width: 0; overflow-wrap: anywhere; }
.cal-mins { color: var(--f-text-2); font-size: 12px; font-weight: 680; }
.cal-foot { color: var(--f-text-2); font-size: 14px; font-weight: 600; }
/* A week on its way: the last one stays, dimmed, instead of a skeleton. */
.cal-body,
.cal-foot { transition: opacity 0.18s var(--f-ease); }
.cal-body.is-stale,
.cal-foot.is-stale { opacity: 0.45; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  .cal-body,
  .cal-foot { transition: none; }
}
.cal-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 16px;
  border-radius: 22px;
  background: var(--f-surface-2);
  color: var(--f-text-2);
  font-size: 15px;
  font-weight: 580;
  text-align: center;
}
.cal-empty-ico {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 16px;
  background: var(--f-surface-3);
  color: var(--f-icon);
}
.cal-error {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 12px;
  padding: 14px 16px;
  border-radius: 18px;
  background: var(--f-danger-soft);
  color: var(--f-danger);
  font-size: 14px;
  font-weight: 580;
}
.cal-error p { flex: 1 1 160px; min-width: 0; }
.cal-error .ico { width: 18px; height: 18px; }

/* Wide: the week as seven columns, Monday first. */
@media (min-width: 900px) {
  .cal-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px; }
  .cal-day,
  .cal-day.is-empty {
    display: flex;
    flex-direction: column;
    gap: 10px;
    align-items: stretch;
    min-height: 168px;
    padding: 10px 8px 12px;
    background: var(--f-surface-2);
  }
  .cal-days.is-loading .cal-day { min-height: 168px; }
  .cal-date,
  .cal-day.is-empty .cal-date {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: baseline;
    gap: 2px 6px;
    padding: 0 4px 8px;
    border-bottom: 1px solid var(--f-hair);
  }
  .cal-dn,
  .cal-day.is-empty .cal-dn { font-size: 20px; }
  .cal-today,
  .cal-day.is-empty .cal-today { margin: 0 0 0 auto; }
  .cal-day.is-today .cal-date { border-bottom-color: rgba(28, 106, 91, 0.22); }
  .cal-free { padding: 0 4px; color: var(--f-text-2); font-size: 13px; }
  .cal-item { padding: 7px 8px 7px 10px; }
  .cal-item.is-plan { padding-left: 8px; }
  .cal-title { font-size: 13px; }
  .cal-mins { padding: 0 4px; }
}

/* ── educators: who helps a kid, what they may do, what they did ────────
   The parent's side (parents.js paintEducators). Each educator row carries
   its three permission switches, or a read-only line when someone else
   sets them, and its own activity under a toggle. */
.edu-card,
.approvals-card { padding: 4px 0; }
.edu-head,
.approvals-head { display: flex; flex-direction: column; gap: 4px; padding: 18px 22px 10px; }
.edu-title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; }
.edu-head .h2,
.approvals-head .h2 { font-size: 18px; overflow-wrap: anywhere; }
.edu-sub { color: var(--f-text-2); font-size: 13px; line-height: 1.45; }
.approvals-head .lede { font-size: 15px; }
.approvals-scope summary { width: fit-content; cursor: pointer; color: var(--f-accent); font-size: 14px; font-weight: 650; }
.approvals-scope .scope-note { margin-top: 8px; }
.edu-card .row,
.approvals-card .row { padding-left: 22px; padding-right: 22px; }
.edu-card .row-title .tag { margin-left: 8px; }
.people-email { margin-top: 1px; color: var(--f-text-3); }
/* Nobody helps this kid yet: a soft box that says who could, and what. */
.people-empty {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 4px 22px 4px;
  padding: 14px 16px;
  border-radius: 20px;
  background: var(--f-surface-2);
  box-shadow: inset 0 0 0 1px var(--f-hair);
  color: var(--f-text-2);
  font-size: 14px;
  line-height: 1.45;
}
.people-empty strong { color: var(--f-text); font-weight: 680; }
.people-empty-ico {
  display: grid;
  flex: none;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 12px;
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.people-empty-ico .ico { width: 18px; height: 18px; }
.edu-loading { padding: 4px 22px 14px; }
.people-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: 6px;
  padding: 10px 12px;
  border-radius: 14px;
  background: var(--f-surface-2);
  color: var(--f-text-2);
  font-size: 13px;
  line-height: 1.45;
}
.people-note .ico { width: 16px; height: 16px; margin-top: 1px; color: var(--f-accent); }
.edu-card .row-buttons { padding: 12px 22px 16px; }

/* An educator who asked and waits on a parent: a thin accent edge. */
.people-row.is-waiting { box-shadow: inset 3px 0 0 var(--f-accent); }
.people-row.is-waiting .row-actions { flex-wrap: wrap; }
.people-row.is-waiting .row-sub + .row-sub { margin-top: 2px; }
/* An invite this page sent: the address gets the row's width, and Resend
   and Cancel sit under it at the row's end, as an educator's buttons do. */
.edu-card .people-row.is-invite { align-items: flex-start; }
.edu-card .people-row.is-invite > .activity-ico { margin-top: 2px; }
.edu-card .people-row.is-invite .row-actions { flex: 1 1 100%; justify-content: flex-end; gap: 4px; margin-top: -6px; }
@media (max-width: 559px) {
  .edu-card .people-row.is-invite .row-actions { gap: 8px; margin-top: 0; }
  .edu-card .people-row.is-invite .row-actions .btn { flex: 1 1 0; min-height: 44px; background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair); }
}
.wait-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.chip.is-quiet { padding: 2px 10px; background: var(--f-surface-3); color: var(--f-text-2); font-size: 12px; font-weight: 650; }
@media (max-width: 559px) {
  /* Add and Not now share the row under the words, each a full target. */
  .people-row.is-waiting .row-actions { flex: 1 1 100%; margin-left: 52px; }
  .people-row.is-waiting .row-actions .btn { flex: 1 1 0; min-height: 44px; }
}
.approvals-card { box-shadow: 0 0 0 1px rgba(28, 106, 91, 0.12), 0 22px 44px -22px rgba(19, 32, 27, 0.28); }

/* One educator: the name as the kid sees it, then two short lines (what
   they do and where; who added them and when), then the address. The
   switches, the buttons and the activity go full width under the name. */
.edu-row { align-items: flex-start; row-gap: 12px; padding-top: 16px; padding-bottom: 14px; }
.edu-row > .avatar { margin-top: 2px; }
.edu-row .row-title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.edu-row .row-sub { line-height: 1.45; }
.edu-role { margin-top: 1px; font-weight: 600; }
.edu-perms,
.edu-row-activity { flex: 1 1 100%; min-width: 0; }
@media (min-width: 560px) {
  .edu-perms,
  .edu-row-activity { flex-basis: calc(100% - 52px); margin-left: 52px; }
}
.edu-perms { display: flex; flex-direction: column; padding: 2px 14px; border-radius: 18px; background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair); }
.perm-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 44px; padding: 10px 0; }
.perm-row + .perm-row { border-top: 1px solid var(--f-hair); }
.perm-name { display: block; font-size: 14px; font-weight: 660; cursor: pointer; }
.perm-desc { display: block; margin-top: 1px; color: var(--f-text-2); font-size: 13px; line-height: 1.4; }
/* Someone else sets them: three on/off chips, and who decides beneath. */
.edu-perms.is-ro { gap: 8px; padding: 0; border-radius: 0; background: none; box-shadow: none; }
.perm-ro { display: flex; flex-wrap: wrap; gap: 6px; }
.perm-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 3px 11px 3px 9px;
  border-radius: var(--f-radius-pill);
  font-size: 12.5px;
  font-weight: 650;
  white-space: nowrap;
}
.perm-chip::before { content: ""; flex: none; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.perm-chip.is-on { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }
.perm-chip.is-off { background: var(--f-surface-3); color: var(--f-text-2); }
.perm-chip.is-off::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.perm-note { display: flex; align-items: flex-start; gap: 6px; color: var(--f-text-2); font-size: 13px; line-height: 1.45; }
.perm-note .ico { flex: none; margin-top: 1px; color: var(--f-icon); }
.edu-row[aria-busy="true"] .edu-perms { opacity: 0.75; }
/* Activity and Remove: quiet, at the row's end; a full-width pair on a phone. */
.edu-row .edu-actions { flex: 1 1 100%; justify-content: flex-end; gap: 4px; margin: -4px 0 0; }
.edu-actions .btn .ico { order: 2; width: 16px; height: 16px; transition: transform 0.2s var(--f-ease); }
.edu-actions .btn[aria-expanded="true"] .ico { transform: rotate(180deg); }
@media (max-width: 559px) {
  .edu-row .edu-actions { gap: 8px; margin-top: 0; }
  .edu-row .edu-actions .btn { flex: 1 1 0; min-height: 44px; background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair); }
}
/* One educator's own lines: under the name, on an accent rail. */
.edu-row-activity { padding: 2px 0 2px 14px; border-left: 2px solid rgba(28, 106, 91, 0.45); }
.edu-row-acts { display: flex; flex-direction: column; }
.edu-row-act { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; padding: 7px 0; }
.edu-row-act + .edu-row-act { border-top: 1px solid var(--f-hair); }
.edu-row-activity .activity-empty { padding: 4px 0; }

/* What educators did: its own card, under the work (13 and up) or beside it. */
.edu-did-card { padding: 4px 0 8px; }
.edu-did-head { display: flex; flex-direction: column; gap: 4px; padding: 18px 22px 6px; }
.edu-did-head .h2 { font-size: 18px; }
.edu-activity { padding: 0 22px 8px; }
.edu-did-empty { padding: 6px 22px 14px; }
.edu-more { padding: 2px 0 8px; }

/* ── how they're doing (13 and up) ────────────────────────────────────── */
.insight-card { display: flex; flex-direction: column; gap: 6px; padding: 22px 20px; }
@media (min-width: 640px) {
  .insight-card { padding: 24px; }
}
.insight-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; }
.insight-head .h2 { overflow-wrap: anywhere; }
/* Why, in the status's own ink (the pill says the word; this says the reason). */
.insight-reasons { color: var(--f-text-2); font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.insight-reasons.is-warn { color: var(--f-soon-ink); }
.insight-reasons.is-danger { color: var(--f-danger); }
.insight-loading { display: flex; flex-direction: column; gap: 10px; padding-top: 6px; }
.insight-loading .insight-grid { margin-top: 6px; }
.sk-block { height: 132px; border-radius: 22px; }
/* The one thing worth a word with them (parents.js nextStep). */
.insight-next {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-top: 10px;
  padding: 12px 16px 12px 12px;
  border-radius: 20px;
  background: var(--f-accent-soft);
}
.insight-next-ico {
  display: grid;
  flex: none;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 12px;
  background: var(--f-surface);
  color: var(--f-accent);
}
.insight-next-ico .ico { width: 18px; height: 18px; }
.insight-next-label { color: var(--f-accent-soft-ink); font-size: 12px; font-weight: 720; letter-spacing: 0.04em; text-transform: uppercase; }
.insight-next-text { margin-top: 1px; color: var(--f-text); font-size: 15px; line-height: 1.45; overflow-wrap: anywhere; }
.insight-next-text strong { font-weight: 720; }
.insight-grid { display: grid; gap: 12px; grid-template-columns: minmax(0, 1fr); margin-top: 12px; }
/* Two up on a tablet (the third block takes the row under them), three up
   from 1024px: at 768 a third of the card left a weak topic 60px. */
@media (min-width: 760px) {
  .insight-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .insight-grid > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 1024px) {
  .insight-grid { grid-template-columns: repeat(3, minmax(200px, 1fr)); }
  .insight-grid > :last-child:nth-child(odd) { grid-column: auto; }
}
.insight-block { display: flex; flex-direction: column; gap: 3px; min-width: 0; padding: 16px 18px; border-radius: 22px; background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair); }
.insight-value { font-size: 26px; font-weight: 780; letter-spacing: -0.03em; line-height: 1.15; font-variant-numeric: tabular-nums; }
.insight-sub { color: var(--f-text-2); font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
.insight-clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.insight-time { color: var(--f-text-3); font-size: 12px; font-weight: 560; }
/* Seven days of study, today last: small bars, never a chart to read. */
.spark { display: flex; align-items: flex-end; gap: 2px; height: 28px; margin: 6px 0 4px; }
.spark-bar { flex: none; width: 4px; min-height: 3px; border-radius: 2px; background: rgba(28, 106, 91, 0.55); }
.spark-bar.is-today { background: var(--f-accent); }
.spark-bar.is-zero { height: 3px; background: var(--f-border-strong); }
.weak-list { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.weak-row { display: grid; grid-template-columns: minmax(0, 1fr) 56px 44px; gap: 10px; align-items: center; }
/* A long topic ("Stoichiometry and limiting reagents") gets two lines. */
.weak-topic { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: 14px; font-weight: 640; line-height: 1.3; overflow-wrap: break-word; }
.weak-subject { color: var(--f-text-2); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.weak-bar { height: 6px; border-radius: var(--f-radius-pill); background: var(--f-surface-3); overflow: hidden; }
.weak-bar span { display: block; height: 100%; min-width: 4px; border-radius: inherit; background: var(--f-soon-ink); }
.weak-pct { min-width: 44px; color: var(--f-text-2); font-size: 13px; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
/* A phone: the bar goes under the topic, so the topic has the row's width. */
@media (max-width: 419px) {
  .weak-row { grid-template-columns: minmax(0, 1fr) 44px; row-gap: 6px; }
  .weak-row > .minw0 { grid-column: 1; grid-row: 1; }
  .weak-row .weak-pct { grid-column: 2; grid-row: 1; }
  .weak-row .weak-bar { grid-column: 1 / -1; grid-row: 2; }
}

/* The status word is text first; the colour only repeats it. The pairs are
   the measured ones above: accent, soon and danger inks on their fills. */
.status-pill {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--f-radius-pill);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
}
.status-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status-pill.is-good { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }
.status-pill.is-warn { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.status-pill.is-danger { background: var(--f-danger-soft); color: var(--f-danger); }

/* ── under 13: the rules first, the activity under them ───────────────── */
.kid-activity { display: flex; flex-direction: column; gap: 20px; }
.kid-activity-title { margin: 8px 0 -4px; }
.kid-work { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
/* The work beside what educators did, as the two columns above. */
.kid-activity-cols { display: grid; gap: 20px; grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 980px) {
  .kid-activity-cols { grid-template-columns: minmax(0, 1.2fr) minmax(360px, 1fr); gap: 28px; }
  .kid-activity-cols:has(> .edu-did-card[hidden]) { grid-template-columns: minmax(0, 1fr); }
  /* Wide: the rules on the left with About under them; the numbers, then
     the educators and their switches, on the right. The two columns'
     cards are placed on one grid so neither column runs on alone. On a
     phone they stack in the page's order: rules, educators, numbers. */
  .kid-layout.is-control { grid-template-rows: auto auto auto 1fr; }
  .kid-layout.is-control > .kid-main,
  .kid-layout.is-control > .kid-side { display: contents; }
  .kid-layout.is-control > .kid-main > * { grid-column: 1; grid-row: 1 / span 2; }
  .kid-layout.is-control .stats-card { grid-column: 2; grid-row: 1; }
  .kid-layout.is-control .edu-card { grid-column: 2; grid-row: 2 / span 3; }
  .kid-layout.is-control .about-card { grid-column: 1; grid-row: 3; }
  .kid-layout.is-control > .kid-side > .privacy-line { grid-column: 1; grid-row: 4; align-self: start; }
}
/* The numbers sit in the narrow column here: two across. */
.kid-layout.is-control .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kid-layout.is-control .goal-row { grid-template-columns: minmax(0, 1fr); gap: 12px; }

/* rules: grouped rows in the manner of Screen Time settings */
.rules { display: flex; flex-direction: column; gap: 14px; }
.rules-head { display: flex; flex-direction: column; gap: 4px; }
.rules-title-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 30px; }
/* Under 13: one card, the way Educators is beside it. The groups inside
   are soft boxes, as an educator's switches are. */
.rules.is-card { gap: 0; padding: 4px 0 18px; }
.rules.is-card .rules-head { padding: 18px 22px 14px; }
.rules.is-card .h2 { font-size: 18px; }
.rules.is-card .rules-body { gap: 12px; padding: 0 16px; }
.rules.is-card .fieldset-reset { gap: 12px; }
.rules.is-card .set-card { border-radius: 22px; background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair); }
.rules.is-card .set-row { padding: 14px 16px; }
.rules.is-card .set-block { padding: 12px 16px 16px; }
.rules.is-card .set-block.is-inset { padding-left: 68px; }
.rules.is-card .always { padding: 4px 6px 0; }
@media (max-width: 420px) {
  .rules.is-card .rules-body { padding: 0 12px; }
  .rules.is-card .set-block.is-inset { padding-left: 16px; }
}
.rules-body { display: flex; flex-direction: column; gap: 14px; }
/* 13 and up: a quieter panel, the rules as chips until Change rules. */
.rules.is-quiet { padding: 18px 18px 20px; border-radius: var(--f-radius-card); background: var(--f-surface-2); box-shadow: 0 0 0 1px var(--f-border); }
.rules.is-quiet .h2 { font-size: 18px; }
.rules-summary { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; }
.rules-summary .chips { flex: 1 1 180px; }
.rules-summary .chip { background: var(--f-surface); box-shadow: 0 0 0 1px var(--f-border); }
.rules-summary .chip.is-off { background: var(--f-night-soft); box-shadow: none; }
/* The limit and downtime rest while the tutor is paused. Their controls
   still work (a parent can set them ahead), so their words keep full
   contrast: the icon goes grey and the name drops to the second ink, and
   "Off while the tutor is paused." says the rest. */
.rules .is-waiting .set-ico { filter: grayscale(1); opacity: 0.5; }
.rules .is-waiting .set-name { color: var(--f-text-2); }
.save-state {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 28px;
  padding: 3px 12px;
  border-radius: var(--f-radius-pill);
  color: var(--f-text-2);
  font-size: 13px;
  font-weight: 680;
  transition: opacity 0.3s var(--f-ease);
}
.save-state .ico { width: 15px; height: 15px; }
.save-state.is-saved { background: var(--f-accent-soft); color: var(--f-accent-soft-ink); }
.save-state.is-error { background: var(--f-danger-soft); color: var(--f-danger); }
.save-state.is-fading { opacity: 0; }

.set-card { overflow: hidden; }
.set-row { display: grid; grid-template-columns: 38px minmax(0, 1fr) auto; gap: 14px; align-items: center; padding: 16px 20px; }
.set-row + .set-row,
.set-block + .set-row,
.set-row + .set-block,
.set-block + .set-block { border-top: 1px solid var(--f-hair); }
.set-ico {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 13px;
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.set-ico .ico { width: 19px; height: 19px; }
.set-ico.is-green { background: var(--f-accent-soft); color: var(--f-accent); }
.set-ico.is-orange { background: var(--f-streak-soft); color: var(--f-streak-ink); }
.set-ico.is-indigo { background: var(--f-night-soft); color: var(--f-night-ink); }
.set-ico.is-blue { background: var(--f-sky-soft); color: var(--f-sky-ink); }
.set-ico.is-gold { background: var(--f-soon-soft); color: var(--f-soon-ink); }
.set-text { min-width: 0; }
.set-name { display: block; font-size: 15px; font-weight: 680; cursor: pointer; }
.set-desc { display: block; color: var(--f-text-2); font-size: 13px; line-height: 1.4; margin-top: 1px; }
.set-block { padding: 14px 20px 18px; display: flex; flex-direction: column; gap: 12px; }
.set-block.is-inset { padding-left: 72px; }
.set-block > * { max-width: 360px; }
@media (max-width: 420px) {
  .set-block.is-inset { padding-left: 20px; }
}
.set-meta { color: var(--f-text-2); font-size: 13px; font-weight: 580; }
.set-meta strong { color: var(--f-text); font-weight: 720; font-variant-numeric: tabular-nums; }
.set-help { color: var(--f-text-2); font-size: 13px; line-height: 1.45; }
.set-error { color: var(--f-danger); font-size: 13px; font-weight: 620; }

.switch {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  flex: none;
  width: 51px;
  height: 31px;
  margin: 0;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: var(--f-icon);
  cursor: pointer;
  transition: background-color 0.22s var(--f-ease);
}
.switch::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2), 0 0 0 0.5px rgba(0, 0, 0, 0.05);
  transition: transform 0.22s var(--f-ease);
}
.switch:checked { background: var(--f-accent); }
.switch:checked::before { transform: translateX(20px); }
.switch:disabled { cursor: not-allowed; opacity: 0.5; }

.times { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.time-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.time-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 22px; }
.time-field label { font-size: 13px; font-weight: 660; color: var(--f-text-2); }
.time-field .input { min-height: 48px; padding: 10px 12px; font-variant-numeric: tabular-nums; }
.time-next { padding: 1px 9px; border-radius: var(--f-radius-pill); background: var(--f-night-soft); color: var(--f-night-ink); font-size: 12px; font-weight: 680; }

.days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; max-width: 360px; }
.day { position: relative; display: flex; }
.day input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.day label {
  flex: 1;
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  min-height: 36px;
  border-radius: 50%;
  background: var(--f-surface-3);
  color: var(--f-text-2);
  font-size: 14px;
  font-weight: 720;
  cursor: pointer;
  transition: background-color 0.18s var(--f-ease), color 0.18s var(--f-ease);
}
.day input:checked + label { background: var(--f-night-soft); color: var(--f-night-ink); box-shadow: inset 0 0 0 2px var(--f-night-ink); }
.day input:focus-visible + label { outline: 2px solid var(--f-accent); outline-offset: 2px; }
.day input:disabled + label { cursor: not-allowed; opacity: 0.6; }

.presets { display: flex; flex-wrap: wrap; gap: 8px; }
.preset {
  min-height: 36px;
  padding: 0 16px;
  border: 1px solid var(--f-border);
  border-radius: var(--f-radius-pill);
  background: #fff;
  color: var(--f-text);
  font-size: 14px;
  font-weight: 640;
  cursor: pointer;
  box-shadow: 0 2px 0 rgba(19, 32, 27, 0.08);
  transition: background-color 0.18s var(--f-ease), color 0.18s var(--f-ease);
}
.preset:hover:not([disabled]) { background: var(--f-surface-2); }
.preset[aria-pressed="true"] { background: var(--f-night-soft); border-color: transparent; color: var(--f-night-ink); box-shadow: none; }
.preset[disabled] { cursor: not-allowed; opacity: 0.6; }

.always { display: flex; gap: 10px; align-items: flex-start; padding: 0 8px; color: var(--f-text-2); font-size: 14px; }
.always .ico { color: var(--f-accent); margin-top: 1px; }
.always strong { color: var(--f-text); font-weight: 700; }

.fieldset-reset { border: 0; margin: 0; padding: 0; min-width: 0; display: flex; flex-direction: column; gap: 16px; }

.about-card { padding: 4px 0; }
.bday { padding: 16px 22px; display: flex; flex-direction: column; gap: 12px; }
.bday-row { display: flex; align-items: center; gap: 12px; }
.bday-ico { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 14px; background: var(--f-streak-soft); color: var(--f-streak-ink); }
.bday-form { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; }
.bday-form .field { flex: 1 1 180px; }
/* Save and Cancel stand as tall as the date field beside them (38px next to
   52). On a phone they wrap under it, where .kid-view .btn-sm sets 44. */
.bday-actions { display: flex; gap: 10px; }
.bday-actions .btn { min-height: 52px; }
.about-card .row-buttons { border-top: 1px solid var(--f-hair); padding: 10px 14px 12px; }
/* "Remove Christopher-Michael from family" wraps instead of widening a phone. */
.about-card .row-buttons .btn { max-width: 100%; white-space: normal; overflow-wrap: anywhere; text-align: left; padding-top: 6px; padding-bottom: 6px; }
.kid-side .privacy-line { padding: 0 8px; }

/* ── modal ────────────────────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  /* 16px: the phone gutter every page in the three apps keeps. */
  padding: 16px;
  background: rgba(19, 32, 27, 0.36);
  animation: f-fade 0.18s var(--f-ease);
}
@media (min-width: 640px) {
  .modal-backdrop { align-items: center; padding: 24px; }
}
.modal {
  width: 100%;
  max-width: 480px;
  max-height: calc(100vh - 24px);
  overflow: auto;
  overscroll-behavior: contain;
  padding: 24px 22px 22px;
  border-radius: 32px;
  background: var(--f-surface);
  box-shadow: var(--f-shadow-pop);
  animation: f-rise 0.24s var(--f-ease);
}
@supports (max-height: 100dvh) {
  .modal { max-height: calc(100dvh - 24px); }
}
@media (min-width: 640px) {
  .modal { padding: 30px 30px 26px; }
}
.modal-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
.modal-title { font-size: 21px; font-weight: 760; letter-spacing: -0.025em; line-height: 1.25; }
.modal-close {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin: -6px -8px 0 0;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: none;
  color: var(--f-icon);
  cursor: pointer;
}
.modal-close:hover { background: var(--f-surface-3); color: var(--f-text); }
.modal-body { display: flex; flex-direction: column; gap: 16px; color: var(--f-text-2); font-size: 15px; }
.modal-body .form { color: var(--f-text); }
/* Your account: who you are, then the password and the email choice. */
.acct-who { display: flex; align-items: center; gap: 12px; color: var(--f-text); }
/* Each part is a soft grouped well rather than a run of hairlines, and its
   title is a calm section label - quieter than the field labels under it,
   the way the student app's Settings headings sit above their rows. */
.acct-part {
  display: flex; flex-direction: column; gap: 12px;
  padding: 16px; border: 0; border-radius: 22px;
  background: var(--f-surface-2); box-shadow: inset 0 0 0 1px var(--f-hair);
  color: var(--f-text);
}
.acct-part-title { font-size: 13px; font-weight: 650; color: var(--f-text-3); letter-spacing: 0; }
.modal .acct-actions .btn-sm { min-height: 44px; }
.acct-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.modal-actions { display: flex; flex-wrap: wrap-reverse; justify-content: flex-end; gap: 10px; margin-top: 24px; }
@media (max-width: 479px) {
  .modal-actions .btn { flex: 1 1 140px; }
}

.chip-radios { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-radio { position: relative; display: flex; }
.chip-radio input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.chip-radio label {
  display: inline-flex;
  align-items: center;
  min-height: 38px;
  padding: 0 16px;
  border-radius: var(--f-radius-pill);
  background: var(--f-surface-3);
  color: var(--f-text);
  font-size: 14px;
  font-weight: 640;
  cursor: pointer;
  transition: background-color 0.18s var(--f-ease), color 0.18s var(--f-ease);
}
.chip-radio input:checked + label { background: var(--f-accent); color: #fff; }
.chip-radio input:focus-visible + label { outline: 2px solid var(--f-accent); outline-offset: 2px; }

/* ── toasts ───────────────────────────────────────────────────────────── */
.toasts {
  position: fixed;
  left: 50%;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 150;
  width: min(440px, calc(100vw - 32px));
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
}
/* While a modal or phone sheet is open, toasts move up out of its way. */
html.modal-open .toasts { top: calc(12px + env(safe-area-inset-top, 0px)); bottom: auto; }
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-radius: 22px;
  background: var(--f-surface);
  color: var(--f-text);
  font-size: 14px;
  font-weight: 560;
  line-height: 1.4;
  box-shadow: var(--f-shadow-pop);
  pointer-events: auto;
  animation: f-toast 0.24s var(--f-ease);
}
.toast .ico { width: 18px; height: 18px; color: var(--f-accent); }
.toast.is-error .ico { color: var(--f-danger); }
.toast-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.toast-action {
  flex: none;
  padding: 6px 12px;
  border: 0;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent-soft);
  color: var(--f-accent-soft-ink);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.toast-action:hover { background: #dae8de; }
.toast.is-leaving { opacity: 0; transform: translateY(6px); transition: opacity 0.2s var(--f-ease), transform 0.2s var(--f-ease); }

/* ── small utilities ──────────────────────────────────────────────────── */
.minw0 { min-width: 0; }
.nowrap { white-space: nowrap; }
.mt-10 { margin-top: 10px; }
.mt-12 { margin-top: 12px; }
.mt-16 { margin-top: 16px; }
.basis-full { flex-basis: 100%; }

/* ── motion ───────────────────────────────────────────────────────────── */
.view-in { animation: f-view 0.22s var(--f-ease); }

@keyframes f-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
@keyframes f-spin { to { transform: rotate(360deg); } }
@keyframes f-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes f-rise { from { opacity: 0; transform: translateY(16px) scale(0.99); } to { opacity: 1; transform: none; } }
@keyframes f-pop { from { opacity: 0; transform: translateY(-4px) scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes f-toast { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes f-view { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

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

/* ── touch: 44px targets ──────────────────────────────────────────────── */
/* A phone-wide kid page gets them whatever the pointer says. */
@media (max-width: 559px) {
  .kid-view .btn-sm,
  .kid-view .preset { min-height: 44px; }
  /* An educator's switch: its whole 44px row flips it, as a rule's does on touch. */
  .perm-row { position: relative; }
  .perm-row label.perm-name::after { content: ""; position: absolute; inset: 0; }
}
@media (pointer: coarse) {
  .btn-sm, .btn-quiet, .seg-opt label, .preset, .chip-radio label, .day { min-height: 44px; }
  /* A link-shaped button, the newsletter boxes, the landing's doors and the
     sign-in tabs: a thumb's 44px too. */
  .link-btn { display: inline-flex; align-items: center; min-height: 44px; }
  .check { min-height: 44px; }
  .auth-helper a,
  .auth-student a,
  .tab { min-height: 44px; }
  .modal-close { width: 44px; height: 44px; }
  .days { gap: 2px; }
  .day label { min-height: 0; }
  .code-copy { width: 44px; height: 44px; margin: -7px -2px; }
  .footer-links a { display: inline-flex; align-items: center; min-height: 44px; }
  /* A tap anywhere on a rule's row flips its switch (the label covers it). */
  .set-row,
  .perm-row { position: relative; }
  .set-row label.set-name::after,
  .perm-row label.perm-name::after { content: ""; position: absolute; inset: 0; }
}

/* ── Announcements (core/announcements.py) ────────────────────────────────
   The one popup an admin queued for this parent (parents.js
   maybeAnnouncement). Centred at every width, unlike the other dialogs,
   which sit at the bottom of a phone; its tile carries the category's glyph,
   the student app's drawing. */
.modal-backdrop.is-announce { align-items: center; }
.modal.announce-modal { position: relative; max-width: 520px; text-align: center; }
.announce-modal .announce-art {
  width: 72px;
  height: 72px;
  margin: 2px auto 14px;
  display: grid;
  place-items: center;
  border-radius: var(--f-radius-card);
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.announce-kicker {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 720;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--f-accent-soft-ink);
}
.announce-modal .modal-head { justify-content: center; }
.announce-modal .modal-title { font-size: 30px; letter-spacing: -0.03em; line-height: 1.15; }
.announce-modal .modal-close { position: absolute; top: 14px; right: 14px; width: 44px; height: 44px; margin: 0; }
.announce-modal .announce-art svg { width: 30px; height: 30px; display: block; }
/* pre-line: a custom announcement's blank line is a paragraph break, and
   its text is never markup, so a newline is the only way to make one. */
.announce-lede { max-width: 40ch; margin: 0 auto; font-size: 16px; line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }
.announce-modal .modal-title { overflow-wrap: anywhere; }
.announce-points {
  margin: 0;
  padding: 16px 18px;
  list-style: none;
  display: grid;
  gap: 10px;
  text-align: left;
  border-radius: var(--f-radius-input);
  background: var(--f-surface-2);
  box-shadow: inset 0 0 0 1px var(--f-hair);
  color: var(--f-text);
}
.announce-points li { display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 10px; align-items: start; font-size: 15px; line-height: 1.45; }
.announce-points .ico {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  padding: 4px;
  border-radius: var(--f-radius-pill);
  background: var(--f-accent-soft);
  color: var(--f-accent);
}
.announce-modal .modal-actions { justify-content: center; }
@media (max-width: 479px) {
  .modal.announce-modal { padding-left: 20px; padding-right: 20px; }
  .announce-modal .modal-title { font-size: 26px; }
  .announce-modal .modal-actions { flex-direction: column-reverse; }
  .announce-modal .modal-actions .btn { flex: none; width: 100%; }
  .announce-modal .modal-close { top: 8px; right: 8px; }
}
@media (prefers-reduced-motion: reduce) {
  .modal.announce-modal { animation: none !important; }
}
