/* Calm UI tokens. Dark first; light follows the system. Chrome is monochrome; colour comes from content. */
:root {
  --canvas: #1A1A1A; --canvas-deep: #171717; --surface: #262626; --surface-raised: #333333; --surface-muted: #404040;
  --hairline: rgba(255,255,255,0.12); --fg: #FFFFFF; --fg-muted: #A1A1A1; --fg-faint: #525252;
  --accent: #E5E5E5; --on-accent: #171717; --error: #FF6568;
  /* content colours: one per sound, used on its leaves, dot, chips and chart line, never on chrome.
     Soft and distinct from each other, and from the three outcome colours (sage = fine, honey = borderline,
     coral = off), so no sound can be mistaken for a verdict. The same in both modes. Defined once here and read everywhere via tintFor(). */
  --tint-r: #5DADE2;         /* sky */
  --tint-s: #B59AE6;         /* violet */
  --tint-th: #D195C9;        /* orchid */
  --tint-l: #9FB4EC;         /* periwinkle */
  --tint-sh: #7EC8D4;        /* teal */
  --tint-ch: #EFA6C3;        /* pink */
  --tint-j: #C9DB86;         /* lime */
  --tint-k: #8FA3D9;         /* steel */
  --tint-g: #86D1C0;         /* aqua */
  --tint-f: #D4C4A8;         /* sand */
  --tint-v: #E39BDA;         /* mauve */
  --tint-z: #A9BF78;         /* olive */
  /* outcome colours are content (what the check found). Soft, never on controls. */
  --ok: #9FD1B8; --warn: #F0C987; --bad: #FF6568; --neutral: #A1A1A1;
  --r-xs: 4px; --r-sm: 8px; --r-md: 12px; --r-lg: 14px; --r-xl: 16px; --r-2xl: 20px; --r-3xl: 24px; --r-pill: 999px;
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 28px; --s8: 32px; --s16: 64px;
  --t-instant: 100ms; --t-quick: 180ms; --t-base: 200ms; --t-content: 300ms; --t-reveal: 500ms;
  --ease-out: cubic-bezier(0, 0, 0.58, 1); --ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1); --ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1); --ease-out-back: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  .hero::before { opacity: 0.6; }
  .water-stage::before { opacity: 0.6; }
  :root {
    --canvas: #FFFFFF; --canvas-deep: #FAFAFA; --surface: #F5F5F5; --surface-raised: #E5E5E5; --surface-muted: #D4D4D4;
    --hairline: rgba(0,0,0,0.10); --fg: #0A0A0A; --fg-muted: #737373; --fg-faint: #A3A3A3;
    --accent: #171717; --on-accent: #FAFAFA; --error: #E40014;
    --ok: #2F8F5B; --warn: #B07A1C; --bad: #E40014; --neutral: #737373;
    color-scheme: light;
  }
}

* { box-sizing: border-box; }
/* type scales with the person's text size: every size is in rem; on iOS the root follows Dynamic Type */
html { font-size: 100%; -webkit-text-size-adjust: 100%; }
@supports (font: -apple-system-body) { html { font: -apple-system-body; font-family: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } }
html, body { margin: 0; padding: 0; background: var(--canvas); color: var(--fg); overflow-x: hidden; }
main, .view { max-width: 100%; }
body { font-family: "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; font-size: 1rem; line-height: 1.3; letter-spacing: 0.01em; -webkit-font-smoothing: antialiased; }
main { max-width: 680px; margin: 0 auto; padding: var(--s4) calc(var(--s4) + env(safe-area-inset-right, 0px)) calc(var(--s16) + env(safe-area-inset-bottom, 0px)) calc(var(--s4) + env(safe-area-inset-left, 0px)); }
body.in-session main { padding-top: calc(var(--s3) + env(safe-area-inset-top, 0px)); }
@media (min-width: 600px) { main { padding-left: var(--s8); padding-right: var(--s8); } }

h1 { font-size: 1.25rem; font-weight: 600; letter-spacing: 0.03em; margin: var(--s2) 0 var(--s4); }
h2 { font-size: 1rem; font-weight: 600; letter-spacing: 0.02em; margin: var(--s7) 0 var(--s3); }
p { margin: 0 0 var(--s3); line-height: 1.5; }
.muted { color: var(--fg-muted); }
.small { font-size: 0.875rem; font-weight: 500; line-height: 1.5; }
.caption { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-muted); }
.hidden { display: none !important; }
a { color: inherit; }

/* top bar */
.topbar { display: flex; flex-wrap: nowrap; gap: 2px; align-items: center; padding: calc(var(--s2) + env(safe-area-inset-top, 0px)) calc(var(--s3) + env(safe-area-inset-right, 0px)) var(--s2) calc(var(--s3) + env(safe-area-inset-left, 0px)); background: var(--canvas); border-bottom: 0.5px solid var(--hairline); position: sticky; top: 0; z-index: 2; min-height: 60px; }
.topbar .nav { background: none; border: none; color: var(--fg-muted); font: inherit; font-size: 0.875rem; font-weight: 500; padding: var(--s2) 8px; border-radius: var(--r-sm); min-height: 44px; cursor: pointer; transition: color var(--t-quick) var(--ease-out), background var(--t-quick) var(--ease-out); }
/* hover only where there is a pointer: on a phone a tapped button would otherwise stay lit */
@media (hover: hover) { .topbar .nav:hover { color: var(--fg); } }
.topbar .nav.active { color: var(--fg); font-weight: 600; }
.badge { margin-left: auto; font-size: 0.6875rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; padding: 3px 8px; border-radius: var(--r-pill); color: var(--fg-muted); border: 0.5px solid var(--hairline); white-space: nowrap; }
.badge-warn { color: var(--error); border-color: var(--error); }

/* icons: one outlined set, currentColor */
.icon { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex: none; vertical-align: -5px; }
.btn .icon, .text-btn .icon { margin-right: 8px; }
.text-btn.stack { display: inline-flex; flex-direction: column; align-items: center; gap: 4px; min-width: 72px; font-size: 0.75rem; font-weight: 500; padding: 8px 6px; }
.text-btn.stack .icon { width: 22px; height: 22px; margin: 0; }
.topbar .icon-btn { margin-left: auto; padding: 10px; min-width: 44px; display: inline-flex; align-items: center; justify-content: center; }
.topbar .icon-btn .icon { width: 22px; height: 22px; }
/* the cog turns a third of a revolution, always the same way, each time it is tapped */
.topbar .icon-btn .icon { transform: rotate(var(--turn, 0deg)); transition: transform 600ms var(--ease-out-cubic); }
.topbar .badge { margin-left: auto; }
.topbar .badge:not(.hidden) + .icon-btn { margin-left: var(--s1); }

/* cards and lists */
.list { display: flex; flex-direction: column; gap: var(--s3); }
.card { background: var(--surface); border: 0.5px solid var(--hairline); border-radius: var(--r-2xl); padding: var(--s5); transition: background var(--t-quick) var(--ease-out), transform var(--t-instant) var(--ease-out); }
.card.clickable { cursor: pointer; }
.card.clickable:hover { background: color-mix(in srgb, var(--surface) 96%, var(--fg)); }
.card.clickable:active { transform: scale(0.97); transition-duration: 80ms; }
.card h3 { margin: 0; font-size: 1rem; font-weight: 600; letter-spacing: 0.02em; }
.card .sub { color: var(--fg-muted); font-size: 0.875rem; font-weight: 500; margin-top: var(--s1); }

/* home: one tile per sound, the only colour on the page */
.course { border-radius: var(--r-3xl); overflow: hidden; background: var(--surface); border: 0.5px solid var(--hairline); }
.course .tile { padding: var(--s6) var(--s5) var(--s16); position: relative; color: #0A0A0A; }
.course .tile h2 { margin: 0; font-size: 1.75rem; font-weight: 700; letter-spacing: 0.02em; }
.course .tile .caption { color: rgba(10,10,10,0.7); margin-top: var(--s1); }
.course .tile::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 56px; background: linear-gradient(to bottom, transparent, var(--surface)); }
.course .tile { padding: var(--s6) var(--s5) var(--s8); }
.course .tile::after { height: 40px; }
.course .sets { padding: 0 var(--s2) var(--s2); display: flex; flex-direction: column; position: relative; }
.course .set { display: flex; align-items: center; gap: var(--s3); padding: var(--s4) var(--s3); border-bottom: 0.5px solid var(--hairline); min-height: 56px; cursor: pointer; transition: background var(--t-quick) var(--ease-out); border-radius: var(--r-sm); }
.course .set:last-child { border-bottom: none; }
.course .set:hover { background: color-mix(in srgb, var(--surface) 94%, var(--fg)); }
.course .set:active { opacity: 0.7; }
.course .set b { font-weight: 500; }
.course .set .sub { margin-left: auto; color: var(--fg-muted); font-size: 0.875rem; font-weight: 500; white-space: nowrap; }
.course .set { flex-direction: column; align-items: stretch; gap: var(--s2); }
.course .set .set-main { display: flex; align-items: center; gap: var(--s2); min-height: 28px; }
.course .set .set-main b { font-size: 1.0625rem; }
.course .set .set-main .sub { margin-left: auto; }
.course .set .today-tick { margin-left: auto; color: var(--ok); display: inline-flex; }
.course .set .today-tick .icon { width: 22px; height: 22px; stroke-width: 2.25; }
.course .set.is-done .set-main b { color: var(--fg-muted); }
.upnext { padding: var(--s5) var(--s5) var(--s4); }
.upnext-title { font-size: 1.5rem; font-weight: 700; letter-spacing: 0.01em; margin-top: 2px; }
/* level control: a stepped slider. The track fills in the sound's tint up to the chosen stage, deeper the further
   along; a dot per stage, a tick on done ones, a ring on the goal; the chosen stage's name beside it. */
.level { display: flex; align-items: center; gap: var(--s3); width: 100%; min-height: 36px; --tint: var(--fg-muted); }
.level-track { position: relative; flex: 1; height: 36px; border-radius: var(--r-pill); cursor: pointer; touch-action: pan-y; }
.level-track::before { content: ""; position: absolute; left: 5px; right: 5px; top: 50%; height: 4px; margin-top: -2px; border-radius: var(--r-xs); background: var(--surface-muted); }
.level-fill { position: absolute; left: 5px; top: 50%; height: 4px; margin-top: -2px; border-radius: var(--r-xs); max-width: calc(100% - 10px); background: var(--tint); opacity: calc(0.45 + 0.55 * var(--frac, 0)); transition: width var(--t-content) var(--ease-out-cubic), opacity var(--t-content) var(--ease-out); }
.level.dragging .level-fill { transition: none; }   /* the fill follows the finger exactly while dragging */
.level-stop { position: absolute; top: 50%; width: 20px; height: 20px; margin: -10px 0 0 -10px; padding: 0; border-radius: 50%; border: none; background: var(--surface-muted); color: var(--on-accent); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: transform var(--t-quick) var(--ease-out-cubic), background var(--t-quick) var(--ease-out), box-shadow var(--t-quick) var(--ease-out); }
.level-stop::before { content: ""; position: absolute; inset: -12px; }                 /* 44px touch target */
.level-stop.passed { background: color-mix(in srgb, var(--tint) 55%, var(--surface-muted)); }
.level-stop.done-stage { background: var(--ok); }
.level-stop .mini-tick { width: 12px; height: 12px; margin: 0; stroke-width: 3; color: #0A0A0A; }
.level-stop.goal { box-shadow: 0 0 0 2px var(--canvas), 0 0 0 3.5px var(--tint); }
.level-stop.sel, .level-stop.on { background: var(--tint); transform: scale(1.25); z-index: 1; }
.level-stop.sel .mini-tick, .level-stop.on .mini-tick { color: #0A0A0A; }
.level-stop:active { transform: scale(1.1); }
/* a position with a single stage shows the stage as a label, not a slider */
.level.single { min-height: 36px; }
.level.single .level-only { display: inline-flex; align-items: center; gap: 4px; padding: 5px 10px; border-radius: var(--r-pill); font-size: 0.8125rem; font-weight: 600; color: var(--fg); background: color-mix(in srgb, var(--tint) 22%, transparent); }
.level.single .level-only .mini-tick { width: 12px; height: 12px; margin: 0; stroke-width: 3; color: var(--ok); }
.level.single .level-stop.done { margin-left: auto; }
.level.is-done .level-only { opacity: 0.4; }
/* the label sits left of the track, so a thumb on the slider never covers it; it lines up with the one-stage label */
.level-name { flex: none; width: 88px; text-align: left; font-size: 0.875rem; font-weight: 600; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 360px) { .level-name { width: 76px; font-size: 0.8125rem; } }
.level.is-done .level-name, .level.is-done .level-fill { opacity: 0.4; }
/* the finished tick at the end of a goal slider */
.level-stop.done { position: relative; top: auto; margin: 0; width: 32px; height: 32px; border-radius: 50%; background: none; border: 0.5px solid var(--hairline); color: var(--fg-muted); flex: none; transform: none; }
.level-stop.done::before { inset: -6px; }
.level-stop.done .icon { width: 16px; height: 16px; margin: 0; }
.level-stop.done.on { background: var(--ok); border-color: transparent; color: #0A0A0A; }
.goals-note { color: var(--fg-muted); font-size: 0.875rem; margin: 0 0 var(--s2); }
#goals-root .set { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s3) 0; border-bottom: 0.5px solid var(--hairline); }
#goals-root .set:last-child { border-bottom: none; }
#goals-root .set .set-main { display: flex; align-items: center; gap: var(--s2); }
.day-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; background: var(--surface-muted); margin-right: 6px; vertical-align: 1px; }
.day-dot.partial { background: var(--warn); }
.day-dot.full { background: var(--ok); }
.week { padding: var(--s4) var(--s3) var(--s2); margin-top: var(--s4); }
.week .week-row { padding: var(--s3) var(--s2); border-bottom: 0.5px solid var(--hairline); border-radius: var(--r-sm); }
.week .week-row:last-child { border-bottom: none; }
.week .week-row.met .set-main b { color: var(--fg-muted); }
.week .set { display: flex; flex-direction: column; align-items: stretch; gap: 4px; cursor: pointer; }
.week .set .set-main { display: flex; align-items: center; gap: var(--s2); min-height: 28px; }
.week .set .set-main .sub { margin-left: auto; color: var(--fg-muted); font-size: 0.875rem; }
.week .set .today-tick { margin-left: auto; color: var(--ok); display: inline-flex; }
/* the row itself starts a session: a quiet play glyph at the end of the name line, brighter on press */
.week .set .set-main .go { margin-left: auto; display: inline-flex; width: 32px; height: 32px; border-radius: 50%; align-items: center; justify-content: center; color: var(--fg-muted); border: 0.5px solid var(--hairline); flex: none; transition: color var(--t-quick) var(--ease-out), background var(--t-quick) var(--ease-out); }
.week .set .set-main .go .icon { width: 16px; height: 16px; margin: 0 0 0 2px; }
.week .set .set-main .today-tick + .go, .week .set .set-main .sub + .go { margin-left: var(--s2); }
.week .set:active .set-main .go { color: var(--fg); background: var(--surface-raised); }
.week .set:active { opacity: 0.85; }
.week .set .today-tick .icon { width: 22px; height: 22px; stroke-width: 2.25; }
fieldset { min-width: 0; }
body.in-session .topbar { display: none; }

/* buttons: monochrome. Primary is the inverse of the surface. */
.btn { font: inherit; font-size: 1rem; font-weight: 600; letter-spacing: 0.01em; padding: 12px 18px; border-radius: var(--r-sm); border: 0.5px solid var(--hairline); background: var(--surface); color: var(--fg); cursor: pointer; min-height: 48px; transition: background var(--t-quick) var(--ease-out), transform var(--t-instant) var(--ease-out), opacity var(--t-quick) var(--ease-out); }
.btn:hover { background: color-mix(in srgb, var(--surface) 96%, var(--fg)); }
.btn:active { transform: scale(0.97); transition-duration: 80ms; }
.btn:disabled { opacity: 0.4; cursor: default; transform: none; }
.btn-big { min-width: 200px; padding: 14px 24px; background: var(--accent); color: var(--on-accent); border-color: transparent; }
.controls:has(#btn-stoprec:not(.hidden)) #btn-pause { background: var(--surface); color: var(--fg); border-color: var(--hairline); }
.btn-danger { background: transparent; color: var(--fg-muted); }
.btn-danger:hover { color: var(--error); background: transparent; }
.text-btn { font: inherit; font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; color: var(--fg-muted); background: none; border: none; padding: 10px 12px; min-height: 44px; border-radius: var(--r-sm); cursor: pointer; transition: color var(--t-quick) var(--ease-out), background var(--t-quick) var(--ease-out), opacity var(--t-quick) var(--ease-out); }
.text-btn:hover { color: var(--fg); background: var(--surface); }
.text-btn:disabled { opacity: 0.35; cursor: default; }
.text-btn:active:not(:disabled), .level-stop:active, .all-sets > summary:active, details.more > summary:active { transform: scale(0.97); transition-duration: 80ms; }
.text-btn, .level-stop { transition-property: color, background, opacity, transform; transition-duration: var(--t-quick); }
.text-btn.on { color: var(--fg); }
#btn-readaloud { margin-left: auto; }
/* switch: track in surface-raised, knob in fg; on = accent track with on-accent knob */
.switch { display: inline-flex; align-items: center; gap: 10px; background: none; border: none; padding: 6px 8px; min-height: 44px; cursor: pointer; font: inherit; font-size: 0.875rem; font-weight: 500; color: var(--fg-muted); border-radius: var(--r-sm); }
.switch .switch-track { position: relative; width: 44px; height: 26px; border-radius: var(--r-pill); background: var(--surface-muted); transition: background var(--t-quick) var(--ease-out); flex: none; }
.switch .switch-knob { position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: var(--fg); transition: transform var(--t-quick) var(--ease-out-cubic), background var(--t-quick) var(--ease-out); }
.switch[aria-checked="true"] { color: var(--fg); }
.switch[aria-checked="true"] .switch-track { background: var(--accent); }
.switch[aria-checked="true"] .switch-knob { transform: translateX(18px); background: var(--on-accent); }
.switch:active .switch-knob { transform: scale(0.95) translateX(0); }
.switch[aria-checked="true"]:active .switch-knob { transform: scale(0.95) translateX(18px); }

/* session */
.session-head { display: flex; align-items: center; gap: var(--s1); min-height: 44px; }
.cue-text { min-height: 0; color: var(--fg-muted); font-size: 0.875rem; text-align: center; }
.cue-text:empty { display: none; }
.stage { min-height: 46vh; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: var(--s6) 0; position: relative; border-radius: var(--r-3xl); }
.stage::before { content: ""; position: absolute; inset: -8px 0; border-radius: inherit; background: radial-gradient(ellipse at 50% 45%, var(--wash, transparent) 0%, transparent 70%); opacity: 0; transition: opacity 500ms var(--ease-out); pointer-events: none; }
.stage[data-state] { --wash: transparent; }
.stage { --sound: var(--tint-r); }
.stage[data-state="listening"] { --wash: color-mix(in srgb, var(--sound) 18%, transparent); }
.stage[data-state="heard"] { --wash: color-mix(in srgb, var(--sound) 30%, transparent); }
.stage[data-state="listening"]::before { animation: breathe 2.6s var(--ease-in-out-cubic) infinite; }
.stage[data-state="heard"]::before { animation: breathe 1.3s var(--ease-in-out-cubic) infinite; }
@keyframes breathe { 0%, 100% { opacity: 0.55; transform: scale(0.96); } 50% { opacity: 1; transform: scale(1.04); } }
.stage[data-state="checking"] { --wash: color-mix(in srgb, var(--fg) 6%, transparent); }
.stage[data-state="accepted"] { --wash: color-mix(in srgb, var(--ok) 22%, transparent); }
.stage[data-state="try_again"] { --wash: color-mix(in srgb, var(--warn) 20%, transparent); }
.stage[data-state="uncertain"] { --wash: color-mix(in srgb, var(--fg) 6%, transparent); }
.stage[data-state="unable_to_assess"] { --wash: color-mix(in srgb, var(--error) 14%, transparent); }
.stage[data-state]:not([data-state="idle"])::before { opacity: 1; }
.stage > * { position: relative; }
.status.listening, .status.heard { color: var(--sound); }
.status.listening::before, .status.heard::before { content: ""; display: inline-block; width: 10px; height: 10px; border-radius: 50%; background: currentColor; margin-right: 10px; vertical-align: 1px; animation: pulse 1.2s var(--ease-in-out-cubic) infinite; }
.status.heard::before { animation-duration: 0.6s; }
@keyframes pulse { 0%, 100% { transform: scale(0.7); opacity: 0.5; } 50% { transform: scale(1.15); opacity: 1; } }
.item-text { font-size: 4rem; font-weight: 700; letter-spacing: 0; text-align: center; margin: 0 0 var(--s2); line-height: 1.08; word-break: break-word; }
@media (max-width: 400px) { .item-text { font-size: 3.5rem; } }
.item-text.long { font-size: 2.125rem; line-height: 1.2; }
#item-target { text-align: center; }
.status { text-align: center; font-size: 1.125rem; font-weight: 500; color: var(--fg-muted); margin: var(--s5) 0 0; min-height: 1.5em; transition: color var(--t-base) var(--ease-out); }
.status.speak { color: var(--fg); font-weight: 600; font-size: 1.25rem; }
.status:empty { display: none; }
.result { text-align: center; margin: var(--s4) 0 0; animation: fade-in var(--t-content) var(--ease-out) both; }
.outcome { font-size: 1.5rem; font-weight: 700; letter-spacing: 0.01em; }
.outcome.accepted { color: var(--ok); }
.outcome.try_again { color: var(--warn); }
.outcome.uncertain { color: var(--fg-muted); }
.outcome.unable_to_assess { color: var(--error); }
.heard { margin-top: var(--s2); font-size: 0.875rem; color: var(--fg-muted); }
.heard .ipa { font-family: "Charis SIL", "Doulos SIL", "Gentium Plus", "Figtree", serif; font-size: 1rem; color: var(--fg); }
.heard .label { display: block; font-size: 0.75rem; font-weight: 500; color: var(--fg-muted); margin-top: var(--s1); }
.heard .details { display: none; }
.heard.open .details { display: block; animation: fade-in var(--t-base) var(--ease-out) both; }
.flags { font-size: 0.875rem; color: var(--fg-muted); margin-top: var(--s1); }
.controls { display: flex; justify-content: center; gap: var(--s1); margin: var(--s3) 0; flex-wrap: wrap; }
.controls.secondary { margin-top: 0; }
.note { margin-top: var(--s4); padding: var(--s4); border-radius: var(--r-lg); background: var(--surface); border: 0.5px solid var(--hairline); color: var(--fg); line-height: 1.5; }
.note.error { color: var(--error); }

/* review and progress */
.summary { margin: 0 0 var(--s5); color: var(--fg-muted); font-size: 1rem; line-height: 1.5; }
.summary b { color: var(--fg); font-weight: 600; }
.rows { display: flex; flex-direction: column; }
.rows > .card { background: none; border: none; border-bottom: 0.5px solid var(--hairline); border-radius: 0; padding: var(--s4) 0; animation: rise 500ms var(--ease-out-cubic) both; }
.rows > .card:last-child { border-bottom: none; }
.rows .word { font-size: 1.125rem; font-weight: 600; }
.rows .reason { color: var(--fg-muted); font-size: 0.875rem; margin-top: 2px; }
.rows .actions { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s2); }
/* my rating: a labelled segmented control. The chosen segment takes the outcome colour it stands for,
   which is the one place colour appears on a control, because the choice is content: your own verdict. */
.rows .actions { flex-wrap: wrap; row-gap: var(--s2); }
.rate-wrap { display: flex; align-items: center; gap: var(--s2); margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
.rate-label { color: var(--fg-muted); font-size: 0.75rem; font-weight: 500; }
.rate { display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--r-pill); background: var(--surface-raised); border: 0.5px solid var(--hairline); }
.rate-opt { font: inherit; font-size: 0.8125rem; font-weight: 600; color: var(--fg-muted); background: none; border: none; border-radius: var(--r-pill); padding: 6px 10px; min-height: 32px; cursor: pointer; transition: background var(--t-quick) var(--ease-out), color var(--t-quick) var(--ease-out), transform var(--t-quick) var(--ease-out); }
.rate-opt:hover { color: var(--fg); }
.rate-opt:active { transform: scale(0.97); transition-duration: 80ms; }
.rate-opt.on { color: var(--fg); background: var(--surface-muted); }
.rate-opt.on.acceptable { color: var(--ok); background: color-mix(in srgb, var(--ok) 20%, transparent); }
.rate-opt.on.borderline { color: var(--warn); background: color-mix(in srgb, var(--warn) 20%, transparent); }
.rate-opt.on.incorrect { color: var(--error); background: color-mix(in srgb, var(--error) 18%, transparent); }
.rate-opt.unable_to_rate { margin-left: 4px; }
@media (max-width: 400px) { .rate-wrap { width: 100%; justify-content: space-between; } .rate-opt { padding: 6px 8px; font-size: 0.75rem; } }
/* history: a card per session that opens to its words */
details.hist > summary { list-style: none; cursor: pointer; }
details.hist > summary::-webkit-details-marker { display: none; }
details.hist > summary .row .word { font-size: 1rem; }
.day-head { margin: var(--s4) var(--s1) 0; }
.day-head:first-child { margin-top: 0; }
#history-list.list { gap: var(--s2); }
/* a small chevron says the card opens; it turns down when it has */
details.hist .chev { display: inline-flex; color: var(--fg-faint); transition: transform var(--t-content) var(--ease-out-cubic); }
details.hist .chev .icon { width: 18px; height: 18px; margin: 0; }
details.hist[open] .chev { transform: rotate(90deg); color: var(--fg-muted); }
details.hist .hist-body { margin-top: var(--s3); animation: fade-in var(--t-base) var(--ease-out) both; }
.hist-row { display: flex; align-items: center; gap: var(--s2); min-height: 44px; padding: 4px 0; border-top: 0.5px solid var(--hairline); }
.hist-row .pill { font-size: 0.75rem; }
.hist-row .play { min-height: 36px; padding: 6px 8px; }
.hist-row .play .icon { margin: 0; width: 18px; height: 18px; }
.play.playing { color: var(--fg); }
.row { display: flex; gap: var(--s2) var(--s3); align-items: center; flex-wrap: wrap; }
.row .grow { flex: 1; min-width: 0; }
.pill { font-size: 0.8125rem; font-weight: 600; white-space: nowrap; }
.pill.accepted { color: var(--ok); } .pill.try_again { color: var(--warn); } .pill.uncertain { color: var(--fg-muted); } .pill.unable_to_assess { color: var(--error); }
.chips { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); margin: var(--s2) 0; }
.review-list .chips, .card .chips { justify-content: flex-start; }
.chip { padding: 4px 10px; border-radius: var(--r-pill); font-size: 0.875rem; font-weight: 600; background: var(--surface-raised); color: var(--fg); cursor: help; }
.chip.green { color: var(--ok); } .chip.yellow { color: var(--warn); } .chip.red { color: var(--error); } .chip.grey { color: var(--fg-muted); }
.bar { height: 6px; background: var(--surface-raised); border-radius: var(--r-xs); overflow: hidden; margin-top: var(--s2); }
.unit-row { display: grid; grid-template-columns: 1fr auto; gap: var(--s1) var(--s3); align-items: center; padding: var(--s3) 0; border-bottom: 0.5px solid var(--hairline); }
.unit-row:last-child { border-bottom: none; }
.unit-row .name { font-weight: 500; }
.unit-row .meta { color: var(--fg-muted); font-size: 0.875rem; white-space: nowrap; }
.unit-row .bar { grid-column: 1 / -1; margin-top: 0; }
.unit-row .done-btn { font: inherit; font-size: 0.875rem; color: var(--fg-muted); background: none; border: 0.5px solid var(--hairline); border-radius: var(--r-pill); padding: 4px 10px; min-height: 32px; cursor: pointer; transition: all var(--t-quick) var(--ease-out); }
.unit-row .done-btn.on { color: var(--on-accent); background: var(--accent); border-color: transparent; }
.sound-head { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s1); font-weight: 600; }
details.more > summary { cursor: pointer; list-style: none; color: var(--fg-muted); font-size: 0.875rem; font-weight: 600; padding: var(--s3) var(--s1); min-height: 44px; display: flex; align-items: center; }
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::after { content: "\203A"; margin-left: auto; font-size: 1.25rem; color: var(--fg-faint); transition: transform var(--t-quick) var(--ease-out); }
details.more[open] > summary::after { transform: rotate(90deg); }
details.more .list { margin-top: var(--s2); }
.bar .fill { height: 100%; background: var(--accent); border-radius: var(--r-xs); transition: width var(--t-content) var(--ease-out-cubic); }
.bar.segmented { display: flex; gap: 3px; background: transparent; }
.bar.segmented .seg { background: var(--surface-raised); border-radius: var(--r-xs); overflow: hidden; height: 100%; }
.dots i { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 3px; }
.tile-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: var(--s2); vertical-align: middle; }
svg text { font-family: inherit; }
.streak { font-size: 1.375rem; font-weight: 700; color: var(--fg); animation: pop 500ms var(--ease-out-back) both; }

/* settings */
select, input[type=number] { font: inherit; font-size: 1rem; padding: 10px 12px; border-radius: var(--r-md); border: 0.5px solid var(--hairline); background: var(--surface-raised); color: var(--fg); max-width: 190px; min-height: 44px; }
input[type=number] { max-width: 110px; }
.settings label.sub-row { min-height: 40px; padding-left: var(--s4); color: var(--fg-muted); font-size: 0.875rem; }
input[type=range] { -webkit-appearance: none; appearance: none; width: 160px; height: 28px; background: transparent; margin: 0; }
input[type=range]::-webkit-slider-runnable-track { height: 4px; border-radius: var(--r-xs); background: var(--surface-muted); }
input[type=range]::-moz-range-track { height: 4px; border-radius: var(--r-xs); background: var(--surface-muted); }
input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 20px; height: 20px; margin-top: -8px; border-radius: 50%; background: var(--fg); border: none; transition: transform var(--t-quick) var(--ease-out); }
input[type=range]::-moz-range-thumb { width: 20px; height: 20px; border-radius: 50%; background: var(--fg); border: none; }
input[type=range]:active::-webkit-slider-thumb { transform: scale(1.12); }
input[type=checkbox] { width: 20px; height: 20px; accent-color: var(--accent); }
.settings fieldset { border: 0.5px solid var(--hairline); border-radius: var(--r-2xl); background: var(--surface); margin: 0 0 var(--s3); padding: var(--s3) var(--s5) var(--s4); display: flex; flex-direction: column; gap: var(--s3); }
.settings legend { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-muted); padding: 0 var(--s2); }
.settings label { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); min-height: 44px; font-size: 1rem; }
.settings .actions { display: flex; gap: var(--s2); margin-top: var(--s2); }
.settings details.advanced { margin: 0 0 var(--s3); }
.settings details.advanced > summary { cursor: pointer; list-style: none; color: var(--fg-muted); font-size: 0.875rem; font-weight: 600; letter-spacing: 0.02em; padding: var(--s3) 0; min-height: 44px; display: flex; align-items: center; }
.settings details.advanced > summary::-webkit-details-marker { display: none; }
.settings details.advanced > summary::after { content: "\203A"; margin-left: auto; font-size: 1.25rem; color: var(--fg-faint); transition: transform var(--t-quick) var(--ease-out); }
.settings details.advanced[open] > summary::after { transform: rotate(90deg); }

/* toast */
.toast { position: fixed; left: 50%; bottom: var(--s6); transform: translateX(-50%); background: var(--accent); color: var(--on-accent); padding: 10px 16px; border-radius: var(--r-md); max-width: 90vw; z-index: 5; font-weight: 500; animation: fade-in var(--t-base) var(--ease-out) both; }

/* skeletons */
.skeleton { background: var(--surface-raised); border-radius: var(--r-lg); position: relative; overflow: hidden; }
.skeleton::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--fg) 6%, transparent), transparent); transform: translateX(-100%); animation: shimmer 1.5s linear infinite; }

/* motion */
.view { animation: enter var(--t-reveal) var(--ease-out-cubic) both; }
.view.leaving { animation: leave 160ms var(--ease-out) both; pointer-events: none; }
@keyframes leave { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-6px) scale(0.99); } }
.topbar { position: sticky; }
.topbar .nav { position: relative; }
.topbar .nav::after { content: ""; position: absolute; left: 10px; right: 10px; bottom: 4px; height: 2px; border-radius: 2px; background: var(--fg); transform: scaleX(0); transform-origin: center; transition: transform var(--t-content) var(--ease-out-cubic); }
.topbar .nav.active:not(.brand):not(.icon-btn)::after { transform: scaleX(1); }
.list > .card, .list > .course, #progress-root > .card, #review-list > .card { animation: rise 600ms var(--ease-out-cubic) both; }
.list > :nth-child(2), #progress-root > :nth-child(2), #review-list > :nth-child(2) { animation-delay: 120ms; }
.list > :nth-child(3), #progress-root > :nth-child(3), #review-list > :nth-child(3) { animation-delay: 240ms; }
.list > :nth-child(n+4), #progress-root > :nth-child(n+4), #review-list > :nth-child(n+4) { animation-delay: 320ms; }
@keyframes enter { from { opacity: 0; transform: scale(0.98); } to { opacity: 1; transform: none; } }
@keyframes rise { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop { from { opacity: 0; transform: scale(0.8); } to { opacity: 1; transform: none; } }
@keyframes shimmer { to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) {
  .status.listening::before, .status.heard::before { animation: none; }
  *, *::before, *::after { animation-duration: 150ms !important; transition-duration: 150ms !important; }
  .view, .list > *, #progress-root > *, #review-list > *, .streak { animation-name: fade-in !important; animation-delay: 0ms !important; }
  .view.leaving { animation: none; opacity: 0; }
  .topbar .nav::after { transition: none; }
  .topbar .icon-btn .icon { transition: none; }
  .skeleton::after { animation: none; }
  .btn:active, .card.clickable:active, .course .set:active { transform: none; }
}


/* header wordmark */
.brand { display: inline-flex; align-items: center; gap: 6px; color: var(--fg); font-weight: 700; font-size: 1.0625rem; letter-spacing: 0.01em; padding: var(--s2) var(--s1); margin-right: var(--s2); text-decoration: none; background: none; border: none; cursor: pointer; font-family: inherit; }
.brand .icon { width: 24px; height: 24px; fill: currentColor; stroke: none; }
.topbar:has(.badge:not(.hidden)) .brand span { display: none; }
.badge { font-size: 0.625rem; padding: 3px 7px; letter-spacing: 0.04em; }

/* home hero: the plant */
.hero { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--s6) 0 var(--s4); }
.hero::before { content: ""; position: absolute; inset: -20px 0; background: radial-gradient(ellipse at 50% 40%, color-mix(in srgb, var(--tint-s) 22%, transparent), color-mix(in srgb, var(--tint-r) 12%, transparent) 45%, transparent 72%); pointer-events: none; }
.hero::before, .water-stage::before { transform-origin: 50% 42%; animation: glow-breathe 9s var(--ease-in-out-cubic) infinite; }
/* the glow breathes very slightly at rest; tapping the plant gives it one soft pulse */
@keyframes glow-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.03); } }
.hero.pulse::before, .water-stage.pulse::before { animation: glow-pulse 900ms var(--ease-out-cubic) both; }
@keyframes glow-pulse { 0% { transform: scale(1); } 30% { transform: scale(1.08); } 100% { transform: scale(1); } }
.hero > * { position: relative; }
.hero .plant-wrap { display: inline-block; }
.hero .next-line { margin-top: var(--s3); font-size: 1.125rem; font-weight: 600; }
.hero .next-line .muted { font-weight: 500; font-size: 0.875rem; display: block; margin-bottom: 2px; }
.hero .quiet { margin-top: var(--s3); color: var(--fg-muted); font-size: 0.875rem; }
.hero .btn-big { margin-top: var(--s4); }
.all-sets { margin-top: var(--s4); }
.all-sets > summary { list-style: none; cursor: pointer; color: var(--fg-muted); font-size: 0.875rem; font-weight: 600; min-height: 44px; display: flex; align-items: center; justify-content: center; gap: 6px; }
.all-sets > summary::-webkit-details-marker { display: none; }
.all-sets > summary::after { content: "\203A"; transform: rotate(90deg); display: inline-block; font-size: 1.125rem; color: var(--fg-faint); transition: transform var(--t-quick) var(--ease-out); }
.all-sets[open] > summary::after { transform: rotate(-90deg); }
.all-sets .list { margin-top: var(--s3); }
.plant-wrap.breathe .plant { animation: plant-breathe 900ms var(--ease-in-out-cubic) both; transform-origin: 50% 90%; }
@keyframes plant-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.03); } }
.leaf-new { animation: unfurl 500ms var(--ease-out-back) both; transform-box: fill-box; transform-origin: 0% 50%; }
/* growing (the summary, after the shower): from the plant as it was, the view eases back if the tree outgrew its
   space, the trunk lengthens and the mark at its top rises with it, the new leaf's shoot draws out, then the leaf
   unfurls. Each element carries where it starts as a custom property; with none set it simply holds still. */
.plant .plant-cam { transform-box: view-box; transform-origin: 120px 266px; }
.plant.growing .plant-cam { animation: cam-ease 1000ms var(--ease-in-out-cubic) both; }
@keyframes cam-ease { from { transform: scale(var(--c, 1)); } to { transform: none; } }
.plant.growing .trunk { stroke-dasharray: 1 2; animation: draw-on 1000ms var(--ease-out-cubic) both; }
.plant.growing .shoot-grow { stroke-dasharray: 1 2; animation: draw-on 480ms var(--ease-out-cubic) 480ms both; }
@keyframes draw-on { from { stroke-dashoffset: var(--off, 0); } to { stroke-dashoffset: 0; } }
.plant.growing .seed-rise { animation: rise 1000ms var(--ease-out-cubic) both; }
@keyframes rise { from { transform: translateY(var(--dy, 0px)); } to { transform: none; } }
.plant.growing .leaf-new { animation-delay: 900ms; }
/* tap to sway: the stem tilts away from the finger and settles; branches and the seed follow with a small lag */
.plant .plant-body, .plant .branch, .plant .seed { transform-box: view-box; }
.plant-wrap { position: relative; cursor: pointer; -webkit-tap-highlight-color: transparent; user-select: none; }
.speck { position: absolute; width: 3px; height: 3px; border-radius: 50%; opacity: 0; pointer-events: none; transition: opacity 300ms var(--ease-out); }
.speck.fade { opacity: 0 !important; }
@keyframes speck-fall { 0% { opacity: 0; transform: translate(0, 0); } 12% { opacity: 0.75; } 100% { opacity: 0.75; transform: translate(var(--drift, 0px), var(--fall, 32px)); } }
.plant.sway .plant-body { animation: sway 900ms var(--ease-out-cubic) both; }
.plant.sway .branch { animation: sway-follow 900ms var(--ease-out-cubic) both; }
.plant.sway .seed { animation: sway-follow 900ms var(--ease-out-cubic) both; }
@keyframes sway { 0% { transform: rotate(0); } 28% { transform: rotate(calc(var(--dir, 1) * 4deg)); } 62% { transform: rotate(calc(var(--dir, 1) * -2deg)); } 84% { transform: rotate(calc(var(--dir, 1) * 0.6deg)); } 100% { transform: rotate(0); } }
@keyframes sway-follow { 0% { transform: rotate(0); } 34% { transform: rotate(calc(var(--dir, 1) * 3deg)); } 68% { transform: rotate(calc(var(--dir, 1) * -1.6deg)); } 88% { transform: rotate(calc(var(--dir, 1) * 0.4deg)); } 100% { transform: rotate(0); } }
@keyframes unfurl { from { opacity: 0; transform: scale(0.2); } to { opacity: 1; transform: scale(1); } }

/* summary screen: watering */
.review-head { display: flex; align-items: center; gap: var(--s2); min-height: 48px; margin-bottom: var(--s2); }
/* text actions that start a line sit on the gutter with the text above them. No box on hover or press, so nothing
   can be out of line; the response is colour and a small scale. */
.review-head .text-btn:first-child, .rows .actions .text-btn:first-child { padding-left: 0; padding-right: 12px; }
.review-head .text-btn:first-child:hover, .rows .actions .text-btn:first-child:hover, .rows .actions .text-btn:first-child:active { background: none; color: var(--fg); }
.review-head .btn-big { margin-left: auto; min-width: 0; padding: 10px 18px; min-height: 44px; }
.water-stage { position: relative; display: flex; flex-direction: column; align-items: center; padding: var(--s4) 0 var(--s2); }
.water-stage::before { content: ""; position: absolute; inset: -10px 0; background: radial-gradient(ellipse at 50% 55%, var(--wash, transparent), transparent 70%); pointer-events: none; }
.water-stage > * { position: relative; }
.drops { position: absolute; left: 0; right: 0; top: 0; height: 100%; pointer-events: none; }
.drop { position: absolute; top: 6px; width: 10px; height: 14px; border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%; opacity: 0.7; animation: fall 420ms cubic-bezier(0.55, 0, 1, 0.45) forwards; }
.drop.landed { animation: ring 300ms var(--ease-out) forwards; }
@keyframes fall { from { transform: translateY(0); } to { transform: translateY(var(--fall, 200px)); } }
@keyframes ring { from { transform: translateY(var(--fall, 200px)) scale(1); opacity: 0.7; border-radius: 50%; } to { transform: translateY(var(--fall, 200px)) scale(3.2, 1.2); opacity: 0; border-radius: 50%; } }
.splash { position: absolute; top: calc(6px + var(--fall, 200px)); width: 5px; height: 5px; border-radius: 50%; opacity: 0.8; animation: splash 380ms var(--ease-out-cubic) forwards; }
@keyframes splash { from { transform: translate(0, 0) scale(1); opacity: 0.8; } to { transform: translate(var(--dx), var(--dy)) scale(0.3); opacity: 0; } }
.drops-line { margin-top: var(--s2); }
.summary-body { opacity: 0; transition: opacity var(--t-reveal) var(--ease-out); }
.summary-body.in { opacity: 1; }
.kind-line { text-align: center; color: var(--fg-muted); margin: var(--s2) 0 var(--s4); }
@media (prefers-reduced-motion: reduce) {
  .stage[data-state]::before { animation: none !important; }
  .drop, .splash { animation: none; display: none; }
  .plant-wrap.breathe .plant, .leaf-new, .plant.sway .plant-body, .plant.sway .branch, .plant.sway .seed { animation: none !important; }
  .plant.growing .plant-cam, .plant.growing .trunk, .plant.growing .shoot-grow, .plant.growing .seed-rise { animation: none !important; }
  .hero::before, .water-stage::before, .hero.pulse::before, .water-stage.pulse::before { animation: none !important; }
  .speck { display: none; }
  .summary-body { transition-duration: 150ms; }
}

/* small phones */
@media (max-width: 360px) {
  .topbar { padding: var(--s2) var(--s2); }
  .topbar .nav { padding: var(--s2) 6px; font-size: 0.8125rem; }
  .brand { margin-right: 0; padding: var(--s2) 2px; }
  .badge { padding: 3px 6px; font-size: 0.5625rem; }
  .item-text { font-size: 3rem; }
  .text-btn.stack { min-width: 64px; }
  .btn-big { min-width: 0; width: 100%; }
}
/* tablets and desktop: a little more room, nothing stretches past 680 */
@media (min-width: 900px) {
  .item-text { font-size: 4.5rem; }
  .stage { min-height: 52vh; }
}

/* phones: a double tap is a tap, never a zoom (pinch still zooms) */
html { touch-action: manipulation; }

/* progress: each sound is one tappable card; the chevron sits on the name row, the bar under it */
.sound details.more > summary { flex-wrap: wrap; padding: 0; min-height: 0; color: inherit; font-size: inherit; font-weight: inherit; }
.sound details.more > summary .sbar, .sound .row > .sbar { flex: 1 1 100%; margin-top: 8px; order: 2; }
.sound details.more > summary::after { order: 1; margin-left: 8px; }

/* settings: sound chips; off is quiet, not gone */
/* settings: one card per sound, its switch in the header, its positions and levels inside */
.sound-card { border-top: 0.5px solid var(--hairline); }
.sound-card:first-child { border-top: none; }
.sound-card > summary { list-style: none; cursor: pointer; display: flex; align-items: center; gap: var(--s3); min-height: 56px; padding: var(--s2) 0; }
.sound-card > summary::-webkit-details-marker { display: none; }
.sound-card .sound-name { display: block; font-weight: 600; }
.sound-card .sound-line { display: block; margin-top: 1px; }
.sound-card.off .sound-name { color: var(--fg-muted); }
.sound-card.off .tile-dot { opacity: 0.35; }
/* the name and status take the width, so every switch lines up at the right whatever the text */
.sound-card > summary .grow { flex: 1 1 auto; min-width: 0; }
.sound-card .sound-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sound-card .sound-switch { padding: 6px 0; min-height: 36px; flex: none; }
.sound-card .chev { flex: none; }
.sound-card .chev { display: inline-flex; color: var(--fg-faint); transition: transform var(--t-content) var(--ease-out-cubic); }
.sound-card .chev .icon { width: 18px; height: 18px; margin: 0; }
.sound-card[open] .chev { transform: rotate(90deg); }
.sound-card .sound-body { padding: 0 0 var(--s3) calc(10px + var(--s3)); animation: fade-in var(--t-base) var(--ease-out) both; }
.sound-card .sound-body .set { display: flex; flex-direction: column; gap: 2px; padding: var(--s2) 0; }
.sound-card .sound-body .set .set-main b { font-weight: 500; font-size: 0.9375rem; }
.sound-card .sound-body .set.is-done .set-main b { color: var(--fg-muted); }
.settings fieldset.sounds { gap: 0; padding-top: var(--s2); }
.settings fieldset.sounds .goals-note { margin-bottom: var(--s2); }

/* deferred feedback: a quiet line for the last check that caught up */
.last-result { margin-left: 8px; white-space: nowrap; max-width: 40%; overflow: hidden; text-overflow: ellipsis; }
.last-result.accepted { color: var(--ok); } .last-result.try_again { color: var(--warn); }
.outcome.saved { color: var(--fg-muted); }

/* offline: how much is waiting to upload, quietly */
.pending-count { margin-left: 8px; white-space: nowrap; }
#home-pending:empty { display: none; }


/* the first open: one plant that grows as you swipe, three lines of copy, a question, one button. Nothing else on the
   screen moves at rest except the glow's breath. See docs/BRAND.md "The first open". */
/* registered, so the glow's colour eases from one blend of picks to the next instead of snapping */
@property --tint-intro { syntax: '<color>'; inherits: true; initial-value: #8AA3E4; }
.intro { --glow: 0.10; max-width: 22rem; margin: 0 auto; display: flex; flex-direction: column; align-items: center; min-height: calc(100dvh - var(--s16) - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px)); touch-action: pan-y; user-select: none; -webkit-user-select: none; outline: none; transition: opacity 220ms var(--ease-out), transform 220ms var(--ease-out-cubic), --tint-intro 900ms var(--ease-out); }
.intro.out { opacity: 0; transform: scale(0.98); }
.intro-stage { position: relative; display: flex; align-items: flex-end; justify-content: center; width: 100%; height: 264px; margin-top: var(--s4); }
.intro-glow { position: absolute; left: 50%; top: 50%; width: 300px; height: 300px; margin: -150px 0 0 -150px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--tint-intro) calc(var(--glow) * 100%), transparent), color-mix(in srgb, var(--tint-intro) calc(var(--glow) * 45%), transparent) 45%, transparent 70%);
  animation: glow-breathe 7s var(--ease-in-out-cubic) infinite; transition: background 900ms var(--ease-out); }
.intro-stage.pulse .intro-glow { animation: glow-pulse 900ms var(--ease-out-cubic) both; }
.intro .plant-wrap { position: relative; }
.intro .plant .leaf { transition: fill 700ms var(--ease-out); }
/* growth between slides, quicker than the ceremony on the summary: the trunk draws on, each new leaf unfurls in turn */
.intro .plant.growing .trunk { animation-duration: 600ms; }
.intro .plant.growing .shoot-grow { animation-duration: 360ms; animation-delay: 240ms; }
.intro .plant.growing .seed-rise, .intro .plant.growing .plant-cam { animation-duration: 600ms; }
.intro .plant.growing .leaf-new { animation-delay: calc(360ms + var(--i, 0) * 90ms); }
/* the word card on slide two: floats up beside the plant, then "Clear" and its tick arrive */
.intro-card { position: absolute; right: 2%; top: 26%; display: flex; flex-direction: column; gap: 2px; padding: var(--s3) var(--s4); border-radius: var(--r-xl); background: var(--surface); border: 0.5px solid var(--hairline); opacity: 0; transform: translateY(10px); pointer-events: none; transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out-cubic); }
.intro-card .intro-card-word { font-size: 1.125rem; font-weight: 700; }
.intro-card .intro-card-verdict { display: inline-flex; align-items: center; gap: 4px; font-size: 0.875rem; font-weight: 600; color: var(--ok); opacity: 0; transition: opacity 300ms var(--ease-out) 700ms; }
.intro-card .icon { width: 16px; height: 16px; margin: 0; stroke-width: 2.5; stroke-dasharray: 24; stroke-dashoffset: 24; }
.intro[data-step="1"] .intro-card { opacity: 1; transform: none; transition-delay: 500ms; }
.intro[data-step="1"] .intro-card .intro-card-verdict { opacity: 1; transition-delay: 1100ms; }
.intro[data-step="1"] .intro-card .icon { animation: tick-draw 320ms var(--ease-out-cubic) 1200ms forwards; }
.intro-copy { position: relative; text-align: center; margin-top: var(--s4); min-height: 9.5rem; width: 100%; transition: transform 200ms var(--ease-out-cubic); }
.intro-copy.swap-next { animation: intro-swap-next 320ms var(--ease-out-cubic) both; }
.intro-copy.swap-back { animation: intro-swap-back 320ms var(--ease-out-cubic) both; }
@keyframes intro-swap-next { from { opacity: 0; transform: translateX(14px); } to { opacity: 1; transform: none; } }
@keyframes intro-swap-back { from { opacity: 0; transform: translateX(-14px); } to { opacity: 1; transform: none; } }
.intro-copy h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: 0.01em; line-height: 1.2; margin: 0 0 var(--s3); text-wrap: balance; }
.intro-copy p { color: var(--fg-muted); line-height: 1.5; margin: 0 auto; max-width: 20rem; text-wrap: pretty; }
.intro-sounds { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); margin-top: var(--s2); }
.intro-sound { min-width: 52px; min-height: 44px; padding: 0 var(--s4); border-radius: var(--r-pill); border: 0.5px solid var(--hairline); background: var(--surface); color: var(--fg); font: inherit; font-weight: 600; cursor: pointer;
  transition: border-color var(--t-quick) var(--ease-out), color var(--t-quick) var(--ease-out), transform var(--t-instant) var(--ease-out), background var(--t-quick) var(--ease-out); }
.intro-sound:active { transform: scale(0.95); }
/* the text leans toward the foreground so a pale tint stays readable on its own wash, in light and in dark */
.intro-sound.on { border-color: var(--tint); color: color-mix(in srgb, var(--tint) 62%, var(--fg)); background: color-mix(in srgb, var(--tint) 14%, var(--surface)); }
.intro-note { min-height: 1.5em; margin-top: var(--s3); font-size: 0.875rem; color: var(--fg-muted); transition: opacity var(--t-content) var(--ease-out); }
.intro-dots { display: flex; gap: 8px; margin: auto 0 var(--s4); padding-top: var(--s4); cursor: pointer; }
.intro-dots i { display: block; width: 6px; height: 6px; border-radius: var(--r-pill); background: var(--fg-faint); transition: width 300ms var(--ease-out-cubic), background 300ms var(--ease-out); }
.intro-dots i.on { width: 20px; background: var(--fg); }
.intro-next { width: 100%; min-width: 0; min-height: 52px; }
.intro-switch { margin: var(--s2) 0 0; color: var(--fg-muted); font-size: 0.9375rem; text-align: center; }
@media (prefers-reduced-motion: reduce) {
  .intro-glow, .intro-copy.swap-next, .intro-copy.swap-back, .intro-stage.pulse .intro-glow { animation: none !important; }
  .intro-card, .intro-card .intro-card-verdict { transition-delay: 0ms; transform: none; }
  .intro[data-step="1"] .intro-card .icon { animation: none; stroke-dashoffset: 0; }
  .intro.out { transform: none; }
}

/* sign in: a quiet front door. While signed out there is no top bar and no status, only the mark over its glow,
   a greeting, and the fields the step needs. See docs/BRAND.md "Signing in". */
body.signed-out .topbar, body.signed-out #scorer-warning, body.signed-out #home-pending { display: none !important; }
body.signed-out main { padding-top: calc(var(--s6) + env(safe-area-inset-top, 0px)); }
[hidden] { display: none !important; }
.login-card { position: relative; max-width: 22rem; margin: 0 auto; transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out-cubic); }
.login-card.out-back { opacity: 0; transform: translateX(16px); }
/* back: a bare chevron on the gutter, above the mark; no box, no label */
.login-back { position: absolute; top: 0; left: -10px; z-index: 1; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; border-radius: var(--r-pill); background: none; color: var(--fg-muted); cursor: pointer;
  transition: color var(--t-quick) var(--ease-out), transform var(--t-instant) var(--ease-out); }
.login-back .icon { width: 24px; height: 24px; margin: 0; }
.login-back:active { transform: scale(0.9); }
@media (hover: hover) { .login-back:hover { color: var(--fg); } }
.login-body.swap-back { animation: login-swap-back 260ms var(--ease-out-cubic) both; }
@keyframes login-swap-back { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }
.login-hero { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; padding: var(--s8) 0 var(--s6); }
.login-glow { position: absolute; top: 0; left: 50%; width: 240px; height: 240px; margin-left: -120px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--tint-r) 22%, transparent), color-mix(in srgb, var(--tint-s) 11%, transparent) 45%, transparent 70%);
  animation: glow-breathe 9s var(--ease-in-out-cubic) infinite; }
.login-mark { position: relative; transform-origin: 50% 90%; animation: mark-sprout 700ms var(--ease-out-back) both; }
@keyframes mark-sprout { from { transform: scale(0.82); opacity: 0; } to { transform: none; opacity: 1; } }
.login-hero h1 { position: relative; font-size: 1.75rem; font-weight: 700; letter-spacing: 0.01em; margin: var(--s5) 0 var(--s2); }
.login-sub { position: relative; color: var(--fg-muted); margin: 0; max-width: 19rem; line-height: 1.5; }
.login-sub b { display: inline-block; max-width: 100%; color: var(--fg); font-weight: 600; overflow-wrap: anywhere; }   /* a whole email moves to its own line before it breaks */
.login-form { display: flex; flex-direction: column; gap: var(--s3); }
.login-body { display: flex; flex-direction: column; gap: var(--s5); }
.login-body.swap { animation: login-swap 260ms var(--ease-out-cubic) both; }
@keyframes login-swap { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.login-card.nudge .login-form { animation: login-nudge 320ms var(--ease-out-cubic); }
@keyframes login-nudge { 0%, 100% { transform: none; } 20% { transform: translateX(-6px); } 45% { transform: translateX(5px); } 70% { transform: translateX(-2px); } }

/* fields: label above, a full-width input, a hint beneath when the step has a rule */
.field { display: flex; flex-direction: column; gap: 8px; }
.field-label { font-size: 0.875rem; font-weight: 600; color: var(--fg-muted); }
.field-label-row { display: flex; align-items: center; justify-content: space-between; min-height: 24px; }
.field-input { position: relative; }
.login-form input[type=email], .login-form input[type=password], .login-form input[type=text]:not(.code-input) {
  width: 100%; font: inherit; font-size: 1rem; min-height: 52px; padding: 0 var(--s4); border-radius: var(--r-md);
  border: 1px solid var(--hairline); background: var(--surface); color: var(--fg); -webkit-appearance: none; appearance: none;
  transition: border-color var(--t-quick) var(--ease-out), box-shadow var(--t-quick) var(--ease-out); }
.login-form .field-input input { padding-right: 52px; }
.login-form input::placeholder { color: var(--fg-faint); }
.login-form input:focus { outline: none; border-color: color-mix(in srgb, var(--fg) 45%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 10%, transparent); }
.field.invalid input:not(.code-input), .field.invalid .code-cell { border-color: var(--error); }
.reveal { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; border-radius: var(--r-sm); color: var(--fg-muted); cursor: pointer; transition: color var(--t-quick) var(--ease-out); }
.reveal:active { transform: translateY(-50%) scale(0.92); }
.reveal .icon { margin: 0; width: 20px; height: 20px; }
.field-hint { display: flex; align-items: center; gap: 6px; font-size: 0.8125rem; color: var(--fg-muted); transition: color var(--t-quick) var(--ease-out); }
.field-hint .mini-tick { width: 14px; height: 14px; margin: 0; stroke-width: 2.5; opacity: 0.35; transition: opacity var(--t-quick) var(--ease-out), transform var(--t-quick) var(--ease-out-back); }
.field-hint.met { color: var(--ok); }
.field-hint.met .mini-tick { opacity: 1; transform: scale(1.1); }
.text-btn.small { font-size: 0.875rem; padding: 4px 0 4px 12px; min-height: 32px; }

/* the code: six boxes over one real input */
.code-boxes { position: relative; display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
.login-form .code-input { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; border: 0; padding: 0; margin: 0; font-size: 16px; color: transparent; background: transparent; caret-color: transparent; z-index: 1; }
.code-cell { height: 56px; border-radius: var(--r-md); border: 1px solid var(--hairline); background: var(--surface); display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; font-weight: 600; font-variant-numeric: tabular-nums; transition: border-color var(--t-quick) var(--ease-out), box-shadow var(--t-quick) var(--ease-out); }
.code-cell.at { border-color: color-mix(in srgb, var(--fg) 45%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 10%, transparent); }
.code-cell.at:empty::after { content: ""; width: 2px; height: 24px; border-radius: 1px; background: var(--fg); animation: code-caret 1s steps(1) infinite; }
@keyframes code-caret { 50% { opacity: 0; } }
.code-cell.pop { animation: code-pop 200ms var(--ease-out-back) both; }
@keyframes code-pop { from { transform: scale(0.85); } to { transform: none; } }

/* the button answers: working (three dots), then done (a tick drawn in), then home */
.login-submit { width: 100%; min-width: 0; min-height: 52px; position: relative; margin-top: var(--s2); }
.login-submit .label { transition: opacity var(--t-quick) var(--ease-out); }
.login-submit .busy, .login-submit .done { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 6px; opacity: 0; pointer-events: none; transition: opacity var(--t-quick) var(--ease-out); }
.login-form.busy .login-submit .label, .login-form.done .login-submit .label { opacity: 0; }
.login-form.busy .login-submit .busy, .login-form.done .login-submit .done { opacity: 1; }
.login-submit .busy i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: busy-dot 900ms var(--ease-in-out-cubic) infinite; }
.login-submit .busy i:nth-child(2) { animation-delay: 150ms; }
.login-submit .busy i:nth-child(3) { animation-delay: 300ms; }
@keyframes busy-dot { 0%, 100% { opacity: 0.3; transform: scale(0.8); } 50% { opacity: 1; transform: none; } }
.login-submit .done .icon { width: 24px; height: 24px; margin: 0; stroke-width: 2.5; stroke-dasharray: 24; stroke-dashoffset: 24; }
.login-form.done .login-submit .done .icon { animation: tick-draw 320ms var(--ease-out-cubic) 60ms forwards; }
@keyframes tick-draw { to { stroke-dashoffset: 0; } }
.login-note { min-height: 1.5em; margin: 0; text-align: center; font-size: 0.875rem; color: var(--error); }
.login-note.info { color: var(--fg-muted); }
.login-switch { display: flex; flex-direction: column; align-items: center; gap: 0; margin-top: var(--s2); color: var(--fg-muted); font-size: 0.9375rem; text-align: center; }
.login-switch p { margin: 0; }
.login-switch .login-fine { margin-top: var(--s4); font-size: 0.8125rem; color: var(--fg-faint); max-width: 18rem; line-height: 1.45; }
.text-btn.inline { padding: 8px 4px; min-height: 44px; color: var(--fg); font-weight: 600; }
.text-btn.inline.quiet { color: var(--fg-muted); font-weight: 500; }
.text-btn.inline:hover, .text-btn.small:hover, .text-btn.inline:active, .text-btn.small:active { background: none; }
@media (hover: hover) { .text-btn.inline:hover, .text-btn.small:hover { text-decoration: underline; text-underline-offset: 3px; } }
.text-btn.inline:disabled { opacity: 0.55; }
@media (prefers-reduced-motion: reduce) {
  .login-glow, .login-mark, .login-body.swap, .login-body.swap-back, .login-card.nudge .login-form, .code-cell.pop, .code-cell.at:empty::after, .login-submit .busy i { animation: none !important; }
  .login-form.done .login-submit .done .icon { animation: none; stroke-dashoffset: 0; }
}

.text-btn.danger { color: var(--error); }

/* settings: the account group (same look as the other groups), with deletion behind a sheet */
fieldset.account { border: 0.5px solid var(--hairline); border-radius: var(--r-2xl); background: var(--surface); margin: 0 0 var(--s3); padding: var(--s3) var(--s5) var(--s3); display: flex; flex-direction: column; gap: var(--s3); min-width: 0; }
fieldset.account legend { font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--fg-muted); padding: 0 var(--s2); }
.account-who { display: flex; align-items: center; gap: var(--s3); min-height: 48px; min-width: 0; }
.account-who .grow { flex: 1 1 auto; min-width: 0; }
.account-avatar { width: 40px; height: 40px; flex: none; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-raised); color: var(--fg); font-weight: 700; font-size: 1.0625rem; }
.account-label { display: block; font-size: 0.8125rem; color: var(--fg-muted); }
.account-email { display: block; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.account-signout { position: relative; width: 100%; min-height: 48px; }
.account-delete { align-self: center; font-weight: 500; }
.account-delete:hover { background: none; }
/* busy dots inside any button that is working (sign out, hold to delete) */
.btn .busy { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 6px; opacity: 0; pointer-events: none; transition: opacity var(--t-quick) var(--ease-out); }
.btn .busy i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: busy-dot 900ms var(--ease-in-out-cubic) infinite; }
.btn .busy i:nth-child(2) { animation-delay: 150ms; }
.btn .busy i:nth-child(3) { animation-delay: 300ms; }
.btn.working .label { opacity: 0; }
.btn.working .busy { opacity: 1; }
.btn .label { position: relative; transition: opacity var(--t-quick) var(--ease-out); }

/* a sheet from the bottom: the scrim fades in, the panel slides up; it is the one floating thing, so it may cast a shadow */
.sheet { position: fixed; inset: 0; z-index: 40; display: flex; align-items: flex-end; justify-content: center; }
.sheet-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.5); opacity: 0; transition: opacity 300ms var(--ease-out); }
.sheet-panel { position: relative; width: 100%; max-width: 30rem; display: flex; flex-direction: column; gap: var(--s3); background: var(--surface); border: 0.5px solid var(--hairline); border-bottom: none;
  border-radius: var(--r-3xl) var(--r-3xl) 0 0; padding: var(--s3) var(--s5) calc(var(--s6) + env(safe-area-inset-bottom, 0px)); box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.45);
  transform: translateY(100%); transition: transform 300ms var(--ease-out-cubic); }
.sheet.in .sheet-scrim { opacity: 1; }
.sheet.in .sheet-panel { transform: none; }
.sheet-grab { width: 36px; height: 4px; border-radius: 2px; background: var(--surface-muted); align-self: center; margin-bottom: var(--s2); }
.sheet-panel h2 { margin: 0; font-size: 1.25rem; font-weight: 700; }
.sheet-panel p { margin: 0 0 var(--s2); color: var(--fg-muted); line-height: 1.5; }
.sheet-panel .btn { width: 100%; min-width: 0; min-height: 52px; }
/* hold to delete: the button fills while held, and only a full fill deletes */
.btn.hold { position: relative; overflow: hidden; color: var(--error); background: color-mix(in srgb, var(--error) 8%, var(--surface)); border-color: color-mix(in srgb, var(--error) 35%, transparent);
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: none; }
.btn.hold:hover { background: color-mix(in srgb, var(--error) 8%, var(--surface)); }
.hold-fill { position: absolute; inset: 0; transform-origin: left center; transform: scaleX(0); background: color-mix(in srgb, var(--error) 30%, transparent); transition: transform 220ms var(--ease-out); }
.btn.hold.holding .hold-fill, .btn.hold.working .hold-fill { transform: scaleX(1); transition: transform 1600ms cubic-bezier(0.4, 0, 0.2, 1); }
@media (prefers-color-scheme: light) { .sheet-panel { box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.16); } }
@media (prefers-reduced-motion: reduce) {
  .sheet-panel { transition: opacity 150ms var(--ease-out); transform: none; opacity: 0; }
  .sheet.in .sheet-panel { opacity: 1; }
  .btn .busy i { animation: none; }
}

.account-password { margin: .25rem 0 .5rem; }
.account-password summary { cursor: pointer; list-style: none; }
.account-password summary::-webkit-details-marker { display: none; }
.account-password form { margin-top: .5rem; }

/* ---- hover and keyboard focus ------------------------------------------------------------------------------------
   Hover: a faint glow eases in around anything pressable, in the control's own colour (the accent for the primary
   button, a sound's tint for its chip or level dot, the foreground for grey controls); boxless controls (text buttons,
   tabs, icons) glow through their glyphs. Only with a real pointer, so a touch never leaves a glow behind.
   Keyboard: whatever has focus carries a clear ring in the foreground colour, set off from the control by a gap of
   canvas, plus the same glow; a mouse click never shows the ring (:focus-visible). See docs/BRAND.md "Hover and focus". */
/* a glow on a dark canvas is light; on a light canvas a dark glow reads as a drop shadow, so it is fainter there */
:root { --halo: color-mix(in srgb, var(--fg) 18%, transparent); --glow-accent: color-mix(in srgb, var(--accent) 34%, transparent); }
@media (prefers-color-scheme: light) { :root { --halo: color-mix(in srgb, var(--fg) 9%, transparent); --glow-accent: color-mix(in srgb, var(--accent) 14%, transparent); } }
.btn, .intro-sound, .level-stop, .switch .switch-track, .rate { transition-property: background, color, border-color, opacity, transform, box-shadow; transition-duration: var(--t-quick), var(--t-quick), var(--t-quick), var(--t-quick), var(--t-instant), 260ms; transition-timing-function: var(--ease-out); }
.text-btn, .topbar .nav, .login-back, .reveal, .rate-opt, .all-sets > summary, details.more > summary { transition-property: color, background, opacity, transform, filter; transition-duration: var(--t-quick), var(--t-quick), var(--t-quick), var(--t-instant), 260ms; transition-timing-function: var(--ease-out); }
@media (hover: hover) {
  .btn:hover:not(:disabled) { border-color: color-mix(in srgb, var(--fg) 22%, transparent); box-shadow: 0 0 22px 0 var(--halo); }
  .btn-big:hover:not(:disabled) { opacity: 1; background: var(--accent); box-shadow: 0 0 28px 2px var(--glow-accent); }
  .btn-danger:hover:not(:disabled) { box-shadow: 0 0 22px 0 color-mix(in srgb, var(--error) 28%, transparent); }
  .text-btn:hover:not(:disabled), .topbar .nav:hover, .login-back:hover, .reveal:hover, .rate-opt:hover, .all-sets > summary:hover, details.more > summary:hover { color: var(--fg); filter: drop-shadow(0 0 6px var(--halo)); }
  .text-btn:hover:not(:disabled) { background: none; }
  .intro-sound:hover { border-color: var(--tint); box-shadow: 0 0 20px 0 color-mix(in srgb, var(--tint) 40%, transparent); }
  .level-stop:not(.done):hover { box-shadow: 0 0 0 5px color-mix(in srgb, var(--tint) 20%, transparent); }
  .level-stop.goal:not(.done):hover { box-shadow: 0 0 0 2px var(--canvas), 0 0 0 3.5px var(--tint), 0 0 0 8px color-mix(in srgb, var(--tint) 18%, transparent); }
  .level-stop.done:hover { box-shadow: 0 0 16px 0 var(--halo); }
  .switch:hover .switch-track { box-shadow: 0 0 16px 0 var(--halo); }
}
:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }
.btn:focus-visible { box-shadow: 0 0 22px 0 var(--halo); }
.btn-big:focus-visible { box-shadow: 0 0 28px 2px var(--glow-accent); }
.intro-sound:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; box-shadow: 0 0 20px 0 color-mix(in srgb, var(--tint) 40%, transparent); }
.text-btn:focus-visible, .topbar .nav:focus-visible, .login-back:focus-visible, .reveal:focus-visible, .rate-opt:focus-visible { color: var(--fg); filter: drop-shadow(0 0 6px var(--halo)); }
/* a switch's ring goes round its track, where the eye already is */
.switch:focus-visible { outline: none; }
.switch:focus-visible .switch-track { outline: 2px solid var(--fg); outline-offset: 3px; }
/* the six code boxes stand in for their hidden input, and the login fields keep their own soft ring */
.login-form .code-input:focus-visible, .intro:focus-visible { outline: none; }
@media (forced-colors: active) { :focus-visible { outline-color: Highlight; } }
