/* Our Care. Tokens and rules: DESIGN.md. No inline styles anywhere (strict CSP). */
:root {
  color-scheme: light;
  --fs: 1rem;
  --font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", system-ui, sans-serif;
  --shell: #12324a; --shell-ink: #f2f7f8; --shell-ink-2: #b5c9d2; --shell-rule: rgba(242, 247, 248, .16);
  --ground: #eef4f5; --surface: #ffffff; --rule: #cfdde2; --ink: #10202b; --ink-2: #4a5f6b; --placeholder: #6f8893;
  --band: rgba(127, 183, 196, .30);
  --now: #c2187a; --now-on-shell: #ff74b8;
  --taken: #1f7a5a; --taken-on-shell: #8fd3b4; --taken-soft: #e3f1ea;
  --late: #8a5a00; --late-mark: #c98a1a; --late-on-shell: #f0b54a; --late-bg: #f6ead1;
  --missed: #b8322a; --missed-on-shell: #ff9283; --missed-bg: #f8e3e0;
  --upcoming: #4a5f6b; --upcoming-on-shell: #b5c9d2;
  --primary: #12324a; --on-primary: #ffffff;
  --bar: #f7fafb; --tab-on: #12324a; --seg: #e1eaed; --av: #d3e6eb; --av-ink: #12324a;
  --tick-ring: #6f8893; --toast: #10202b; --toast-ink: #f2f7f8; --toast-act: #9fd3df; --focus: #2b7f96;
  /* The AI sheen (Plan 4a, an AI-only exception: DESIGN.md): teal, harbour blue and lilac over a pearl fill. */
  --ai-1: #2b7f96; --ai-2: #3d6db3; --ai-3: #6a58b5; --ai-fill-1: #e3f0f4; --ai-fill-2: #ebe7f8; --ai-fill-3: #e1f0ee;
  --ai-glint: rgba(255, 255, 255, .92); --ai-on: #ffffff;
  --how-bezel: #24333d; --how-screen: #f7fafb; --how-ui: #e3eaed; --how-line: #4a5f6b; --how-page: #dbe5e9;
  --how-pop: #ffffff; --how-wall: #cfe2e7; --how-app: #b9ccd3; --how-scrim: rgba(4, 16, 24, .32); --how-finger: rgba(16, 32, 43, .26);
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --shell: #0c2131; --shell-ink: #efe6d6; --shell-ink-2: #a8a08f; --shell-rule: rgba(239, 230, 214, .14);
    --ground: #07141d; --surface: #0e2030; --rule: #1d3344; --ink: #efe6d6; --ink-2: #aaa190; --placeholder: #7d776b;
    --band: rgba(80, 150, 170, .26);
    --now: #ec6aaa; --now-on-shell: #ec6aaa;
    --taken: #6cc39c; --taken-on-shell: #6cc39c; --taken-soft: rgba(108, 195, 156, .12);
    --late: #e6ad50; --late-mark: #e6ad50; --late-on-shell: #e6ad50; --late-bg: rgba(230, 173, 80, .13);
    --missed: #ef7d70; --missed-on-shell: #ef7d70; --missed-bg: rgba(239, 125, 112, .13);
    --upcoming: #aaa190; --upcoming-on-shell: #a8a08f;
    --primary: #8cc6d3; --on-primary: #07141d;
    --bar: #0a1923; --tab-on: #8cc6d3; --seg: #152a3a; --av: #17324a; --av-ink: #cfe6ec;
    --tick-ring: #66808b; --toast: #e9e1d2; --toast-ink: #10202b; --toast-act: #12324a; --focus: #8cc6d3;
    --ai-1: #7cc0cf; --ai-2: #8fa6e6; --ai-3: #b29fea; --ai-fill-1: #10293a; --ai-fill-2: #1a2243; --ai-fill-3: #0f2a33;
    --ai-glint: rgba(239, 230, 214, .2); --ai-on: #07141d;
    --how-bezel: #31495a; --how-screen: #0b1b26; --how-ui: #18303f; --how-line: #aaa190; --how-page: #15293a;
    --how-pop: #142838; --how-wall: #12303f; --how-app: #24404f; --how-scrim: rgba(0, 0, 0, .45); --how-finger: rgba(239, 230, 214, .3);
  }
}

html { font-size: 17px; -webkit-text-size-adjust: 100%; }
@supports (font: -apple-system-body) { html { font: -apple-system-body; } }
* { box-sizing: border-box; margin: 0; padding: 0; }
button, input, select { font: inherit; color: inherit; background: none; border: 0; }
button, select, a { cursor: pointer; -webkit-tap-highlight-color: transparent; }
a { color: inherit; text-decoration: none; }
fieldset { border: 0; min-width: 0; }
body { background: var(--ground); color: var(--ink); font-family: var(--font); font-size: var(--fs); line-height: 1.3; -webkit-font-smoothing: antialiased; }
::selection { background: var(--band); }
input, select { caret-color: var(--primary); }
:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 2px; border-radius: 6px; }
.shell :focus-visible { outline-color: var(--shell-ink); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.tnum { font-variant-numeric: tabular-nums; }
[hidden] { display: none !important; }

.app { min-height: 100dvh; padding-bottom: calc(83px + env(safe-area-inset-bottom)); }
.page { padding-bottom: 28px; }
.page.surface { background: var(--surface); min-height: calc(100dvh - 120px); }

/* shell */
.shell { position: sticky; top: 0; z-index: 3; background: var(--shell); color: var(--shell-ink); padding-top: env(safe-area-inset-top); }
.shell-body { padding: 10px 20px 16px; }
.status-line { font-variant-numeric: tabular-nums; font-size: min(calc(32 / 17 * var(--fs)), 36px); font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; }
.status-sub { margin-top: 4px; font-size: min(calc(15 / 17 * var(--fs)), 17px); color: var(--shell-ink-2); font-variant-numeric: tabular-nums; }
.shell-title { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; padding: 10px 20px 14px; }
.shell-title h1 { font-size: calc(32 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.025em; }
.shell-btn { min-height: 44px; padding: 0 16px; border-radius: 999px; border: 1.5px solid var(--shell-rule); color: var(--shell-ink); font-size: calc(15 / 17 * var(--fs)); font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.shell-btn svg { width: 16px; height: 16px; }
.navbar { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; padding: 6px 12px 12px; }
.navbar strong { font-weight: 600; text-align: center; overflow-wrap: anywhere; }
.navbar .l, .navbar .r { min-height: 44px; display: inline-flex; align-items: center; padding: 0 8px; }
.navbar .l { justify-self: start; color: var(--shell-ink-2); }
.navbar .r { justify-self: end; font-weight: 700; }

/* day line (signature) */
.dayline { display: block; margin-top: 10px; overflow: visible; }
.dl-name { margin-top: 12px; font-size: calc(13 / 17 * var(--fs)); font-weight: 600; color: var(--shell-ink-2); }
.dl-band { fill: var(--band); }
.dl-track { fill: var(--shell-rule); }
.dl-tick { stroke: var(--shell-ink-2); stroke-opacity: .7; stroke-width: 1; }
.dl-tick.minor { stroke-opacity: .4; }
.dl-label { fill: var(--shell-ink-2); font-size: min(calc(11 / 17 * var(--fs)), 15px); font-weight: 500; font-variant-numeric: tabular-nums; }
.dl-now { stroke: var(--now-on-shell); stroke-width: 2; stroke-linecap: round; }
.dl-now-label { fill: var(--now-on-shell); font-size: min(calc(12 / 17 * var(--fs)), 16px); font-weight: 700; font-variant-numeric: tabular-nums; }

/* marks: shape and colour both carry state */
.on-shell { --hole: var(--shell); }
.on-ground { --hole: var(--ground); }
.on-surface { --hole: var(--surface); }
.mk-taken { --c: var(--taken); }
.mk-takenLate, .mk-late { --c: var(--late-mark); }
.mk-due { --c: var(--ink); }
.mk-upcoming, .mk-skipped { --c: var(--upcoming); }
.mk-missed { --c: var(--missed); }
.on-shell .mk-taken { --c: var(--taken-on-shell); }
.on-shell .mk-takenLate, .on-shell .mk-late { --c: var(--late-on-shell); }
.on-shell .mk-due { --c: var(--shell-ink); }
.on-shell .mk-upcoming, .on-shell .mk-skipped { --c: var(--upcoming-on-shell); }
.on-shell .mk-missed { --c: var(--missed-on-shell); }
.mk .mk-fill { fill: var(--c); }
.mk .mk-ring { fill: var(--hole); stroke: var(--c); }
.mk .mk-check { fill: none; stroke: var(--hole); }
.mk .mk-line { fill: none; stroke: var(--c); }
.mk-ico { flex: none; }

/* banners */
.banner { padding: 12px 20px; font-size: calc(15 / 17 * var(--fs)); font-weight: 600; display: flex; align-items: center; justify-content: space-between; gap: 12px; border-bottom: 1px solid var(--rule); }
.banner-delayed, .banner-nobody, .banner-push { background: var(--late-bg); color: var(--ink); }
.banner-failing { background: var(--missed-bg); color: var(--ink); }

/* groups and rows */
.band-surface { background: var(--surface); }
.group { padding: 0 20px; }
.group-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 24px 0 10px; }
.group-head h2 { font-size: calc(20 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.015em; }
.group-head .count { font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.subhead { font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); padding: 12px 0 6px; }
.group-end { height: 8px; }
.row { display: grid; grid-template-columns: 1fr 48px; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--rule); }
.row-main { display: grid; grid-template-columns: minmax(0, 1fr); text-align: left; align-items: start; min-height: 48px; padding: 2px 0; border-radius: 10px; }
/* doses due at the same time share one time on the left */
.slot { display: grid; grid-template-columns: calc(70 / 17 * var(--fs)) minmax(0, 1fr); gap: 12px; align-items: start; padding: 12px 0; border-top: 1px solid var(--rule); }
.slot .t { padding-top: 3px; }
.slot-doses .row { border-top: 0; padding: 0; }
.slot-doses .row + .row { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--rule); }
/* collapsible section headings (Recently completed, Earlier today) */
.fold-h { padding: 14px 0 0; }
.fold { width: 100%; min-height: 44px; display: flex; justify-content: space-between; align-items: center; gap: 12px; text-align: left; font-size: calc(20 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.015em; margin-bottom: 6px; }
.fold-meta { display: flex; align-items: center; gap: 6px; }
.fold .count { font-size: calc(15 / 17 * var(--fs)); font-weight: 400; letter-spacing: 0; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.fold .chev { transition: transform .2s cubic-bezier(.16, 1, .3, 1); }
.fold[aria-expanded="true"] .chev { transform: rotate(90deg); }
.t { font-size: calc(20 / 17 * var(--fs)); font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; white-space: nowrap; padding-top: 1px; }
.t small { font-size: calc(13 / 17 * var(--fs)); font-weight: 500; color: var(--ink-2); margin-left: 2px; letter-spacing: 0; }
.name { display: block; font-size: var(--fs); font-weight: 600; }
.detail { display: block; font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; }
.state { display: flex; gap: 6px; align-items: center; margin-top: 6px; font-size: calc(14 / 17 * var(--fs)); font-weight: 600; font-variant-numeric: tabular-nums; }
.c-due { color: var(--ink); font-weight: 700; }
.c-late { color: var(--late); }
.c-missed { color: var(--missed); }
.c-taken { color: var(--taken); }
.c-muted { color: var(--ink-2); font-weight: 500; }
.tick { width: 48px; height: 48px; border-radius: 50%; border: 2px solid var(--tick-ring); display: grid; place-items: center; transition: background-color .25s cubic-bezier(.16, 1, .3, 1), border-color .25s cubic-bezier(.16, 1, .3, 1), transform .2s cubic-bezier(.16, 1, .3, 1); }
.tick.need { border-color: var(--primary); border-width: 2.5px; }
.tick:active { transform: scale(.92); }
.tick svg { width: 24px; height: 24px; }
.tick svg path { stroke: var(--taken); stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset .4s cubic-bezier(.16, 1, .3, 1) .05s; }
.tick.on { background: var(--taken-soft); border-color: var(--taken); border-width: 1.5px; }
.tick.on svg path { stroke-dashoffset: 0; }
.empty { padding: 48px 28px; text-align: center; color: var(--ink-2); font-size: var(--fs); line-height: 1.5; }
.empty a { color: var(--primary); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.note { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.45; padding: 10px 0 0; }

/* buttons */
.btn-sm { min-height: 44px; padding: 0 18px; border-radius: 999px; font-size: calc(15 / 17 * var(--fs)); font-weight: 600; display: inline-flex; align-items: center; gap: 7px; }
.btn-sm svg { width: 16px; height: 16px; }
.btn-fill { background: var(--primary); color: var(--on-primary); }
.btn-line { border: 1.5px solid var(--tick-ring); color: var(--ink); }
.btn-primary { width: 100%; min-height: 54px; border-radius: 15px; background: var(--primary); color: var(--on-primary); font-size: var(--fs); font-weight: 650; margin-top: 16px; font-variant-numeric: tabular-nums; }
.btn-quiet { width: 100%; min-height: 50px; border-radius: 15px; border: 1.5px solid var(--rule); font-size: var(--fs); font-weight: 600; margin-top: 10px; }
.textbtn { font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--missed); min-height: 44px; padding: 0 8px; display: inline-flex; align-items: center; }
.textbtn.ink { color: var(--primary); }

/* tab bar */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 4; background: var(--bar); border-top: 1px solid var(--rule); display: grid; grid-template-columns: repeat(3, 1fr); padding: 7px 0 calc(8px + env(safe-area-inset-bottom)); }
.tab { display: flex; flex-direction: column; align-items: center; gap: 3px; min-height: 48px; font-size: calc(10.5 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); }
.tab svg { width: 26px; height: 26px; }
.tab[aria-current="page"] { color: var(--tab-on); }
/* The dock: the timer bar and the tab bar, fixed together at the bottom (spec 2, 14.3). */
.dock { position: fixed; left: 0; right: 0; bottom: 0; z-index: 4; }
.dock .tabbar { position: static; }
.tbar { display: flex; align-items: center; gap: 4px; padding: 2px 4px 2px 16px; background: var(--shell); color: var(--shell-ink); border-top: 1px solid var(--shell-rule); }
.tbar-lines { flex: 1 1 auto; min-width: 0; }
.tbar-line { display: flex; align-items: center; gap: 8px; min-height: max(48px, calc(30 / 17 * var(--fs) + 14px)); }
.tbar-what span:last-child { flex: 1 1 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.tbar-line + .tbar-line { border-top: 1px solid var(--shell-rule); }
.tbar-what { flex: 1 1 auto; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; color: inherit; text-decoration: none; font-size: calc(15 / 17 * var(--fs)); font-weight: 600; font-variant-numeric: tabular-nums; padding: 8px 0; min-height: 44px; }
.tbar-what .run-ico, .tpill .run-ico { color: var(--taken-on-shell); }
.tbar-act { position: relative; flex: none; min-height: 36px; padding: 0 14px; border-radius: 999px; background: var(--shell-ink); color: var(--shell); font-weight: 700; font-size: calc(15 / 17 * var(--fs)); }
.tbar-act::before { content: ""; position: absolute; inset: -4px 0; }
.tbar-fold { flex: none; width: 44px; height: 44px; display: grid; place-items: center; color: var(--shell-ink-2); }
.tbar-fold svg { width: 20px; height: 20px; }
.tpill { position: absolute; right: 12px; bottom: calc(100% + 8px); display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 16px; border-radius: 999px; background: var(--shell); color: var(--shell-ink); font-weight: 700; font-size: calc(15 / 17 * var(--fs)); font-variant-numeric: tabular-nums; box-shadow: 0 8px 20px -10px rgba(0, 0, 0, .45); }
/* Room for it: the page scrolls clear of the strip, and toasts float above the strip or the pill. */
.has-timerbar .app:has(.dock) { padding-bottom: calc(83px + 56px + env(safe-area-inset-bottom)); }
.big.has-timerbar .app:has(.dock) { padding-bottom: calc(83px + 112px + env(safe-area-inset-bottom)); }
/* The toast clears the dock (tab bar and timer strip, whatever height the text makes them). Browsers with anchor
   positioning put it just above the dock itself (spec 20.2, H1). The rules before it are the fallback, an estimate that
   grows with the text: the tab bar's labels wrap at the largest sizes, and a strip line takes up to three rows. */
:root:has(.dock) .toast { bottom: calc(max(96px, 3.4 * var(--fs) + 12px) + env(safe-area-inset-bottom)); }
.has-timerbar:has(.dock) .toast, .has-timerpill:has(.dock) .toast { bottom: calc(max(96px, 3.4 * var(--fs) + 12px) + max(56px, 1.8 * var(--fs) + 22px) + env(safe-area-inset-bottom)); }
/* Two or more lines (twins, has-timerbar-2): each line leads with a badge and name, so a feed line wraps on a phone;
   two lines take about 116px, twice that at the accessibility text sizes. */
.has-timerbar-2 .app:has(.dock) { padding-bottom: calc(83px + 116px + env(safe-area-inset-bottom)); }
.big.has-timerbar-2 .app:has(.dock) { padding-bottom: calc(83px + 232px + env(safe-area-inset-bottom)); }
.has-timerbar-2:has(.dock) .toast { bottom: calc(max(96px, 3.4 * var(--fs) + 12px) + 2 * (3.6 * var(--fs) + 22px) + env(safe-area-inset-bottom)); }
@supports (anchor-name: --dock) {
  .dock { anchor-name: --dock; }
  .has-timerbar:has(.dock) .toast, .has-timerbar-2:has(.dock) .toast, :root:has(.dock) .toast { position-anchor: --dock; bottom: calc(anchor(top) + 12px); }
  /* The folded pill floats 8px above the dock's top edge, 44px tall. */
  .has-timerpill:has(.dock) .toast { position-anchor: --dock; bottom: calc(anchor(top) + 8px + 44px + 12px); }
}

/* toast */
.toast { position: fixed; left: 14px; right: 14px; bottom: calc(96px + env(safe-area-inset-bottom)); z-index: 8; background: var(--toast); color: var(--toast-ink); border-radius: 16px; padding: 10px 8px 10px 16px; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 2px 10px; font-size: calc(15 / 17 * var(--fs)); font-weight: 500; box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .45); opacity: 0; transform: translateY(14px); pointer-events: none; transition: opacity .3s cubic-bezier(.16, 1, .3, 1), transform .3s cubic-bezier(.16, 1, .3, 1); }
.toast.show { opacity: 1; transform: none; pointer-events: auto; }
/* When the actions don't fit beside the message (large text, narrow screens) they drop to their own line, on the right. */
.toast .msg { flex: 1 1 8em; }
/* The toast itself stays a live region when hidden; its buttons go once it has faded (ui.js then empties it). */
.toast .tacts { display: flex; flex: 0 1 auto; flex-wrap: wrap; justify-content: flex-end; margin-left: auto; visibility: hidden; transition: visibility 0s linear .3s; }
.toast.show .tacts { visibility: visible; transition-delay: 0s; }
.toast button { min-height: 44px; font-weight: 700; color: var(--toast-act); padding: 6px 10px; border-radius: 8px; }

/* sheet */
.sheet-back { position: fixed; inset: 0; z-index: 6; background: rgba(4, 16, 24, .45); }
.sheet { position: fixed; left: 0; right: 0; bottom: 0; z-index: 7; max-height: 92dvh; overflow-y: auto; background: var(--surface); border-radius: 28px 28px 0 0; padding: 8px 20px calc(28px + env(safe-area-inset-bottom)); box-shadow: 0 -12px 40px -16px rgba(0, 0, 0, .35); }
.grab { width: 36px; height: 5px; border-radius: 3px; background: var(--rule); margin: 0 auto 16px; }
.sheet-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }
.sheet .timer-head h3 { font-variant-numeric: tabular-nums; }
.sheet h3 { font-size: calc(24 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.02em; }
.sheet .state { font-size: calc(15 / 17 * var(--fs)); margin-top: 12px; }
.icon-btn { width: 44px; height: 44px; margin: -5px -5px 0 0; display: grid; place-items: center; color: var(--ink-2); flex: none; }
.icon-btn span { width: 34px; height: 34px; border-radius: 50%; background: var(--seg); display: grid; place-items: center; }
.icon-btn svg { width: 18px; height: 18px; }
.field-label { font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); margin: 22px 0 8px; }
.seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; background: var(--seg); border-radius: 11px; padding: 3px; gap: 2px; }
.seg button, .seg label span { min-height: 44px; border-radius: 8px; font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; display: grid; place-items: center; }
.seg button[aria-pressed="true"], .seg input:checked + span { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 2px 6px -2px rgba(0, 0, 0, .12); }
.seg label { position: relative; }
.seg input { position: absolute; opacity: 0; inset: 0; }
/* The Other… choice in a dose sheet's Taken at: a label with the native time list over it, chosen once a time is picked. */
.seg label.on span { background: var(--surface); color: var(--ink); box-shadow: 0 1px 2px rgba(0, 0, 0, .12), 0 2px 6px -2px rgba(0, 0, 0, .12); }
.seg label select { position: absolute; inset: 0; opacity: 0; width: 100%; }
.seg.filter { margin: 16px 20px 0; grid-auto-columns: minmax(0, 1fr); }
.seg.filter button { overflow-wrap: anywhere; padding: 4px 6px; }
.list { margin-top: 18px; }
.list-row { width: 100%; min-height: 52px; display: flex; align-items: center; justify-content: space-between; gap: 10px; border-top: 1px solid var(--rule); font-size: var(--fs); text-align: left; position: relative; }
.list-row:last-child { border-bottom: 1px solid var(--rule); }
.list-row select { position: absolute; inset: 0; opacity: 0; width: 100%; }
/* With a mouse or trackpad the browser opens its list as wide as the picker, so the picker covers only the value on
   the right and its list opens there, compact (Slade, 13 Oct). A touch still opens the phone's own picker from
   anywhere on the row. */
@media (pointer: fine) {
  .list-row select { left: auto; width: auto; }
}
.chev { width: 18px; height: 18px; color: var(--ink-2); flex: none; }
.skip-form { display: flex; gap: 10px; padding: 10px 0; }
/* min-width 0: a text field won't otherwise shrink below about 20 characters, which at the largest text sizes on a
   narrow phone pushed its button, and the whole sheet, off the side of the screen. */
.skip-form input { flex: 1; min-width: 0; min-height: 44px; border-bottom: 1px solid var(--rule); }
/* A care task's note. Pending: "Add a note" sits between the time and Mark as done, and opens a one-line field
   there. Done: the note and "Edit note" hang under the state words, past the 16px mark and its 6px gap; "Add a
   note" puts its plus in the mark's column, so its words line up with the state words too. */
.add-note, .note-act { display: flex; width: fit-content; }
.add-note { gap: 6px; margin: 0 0 -10px -8px; }
.add-note svg { width: 16px; height: 16px; flex: none; }
.seg + .add-note { margin: 6px 0 -6px -8px; }
.take-note { padding: 6px 0 0; }
.dose-note { margin: 6px 0 0 22px; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; overflow-wrap: anywhere; }
/* Edit note's 44pt tap area starts below the note rather than over its last line, and "Add a note" under the state
   line starts 6px down so its focus ring clears the state words. Each keeps its words, and what follows, where they
   were (padding below the words lifts them inside the tap area); only at the largest sizes do they sit a little
   lower, as the words outgrow the space above the padding. */
.note-act { margin: 0 0 -14px 14px; padding-bottom: 8px; }
.note-view > .add-note { margin-top: 6px; margin-bottom: -16px; padding-bottom: 12px; }
/* On the baby sheets the note's button sits in the sheet's own flow, with no negative pull on what follows. */
.baby-note { margin-top: 6px; }
.baby-note .add-note, .baby-note .note-act { margin: 0 0 0 -8px; padding-bottom: 0; }
.baby-note .dose-note { margin-left: 0; }
.note-form { margin-left: 22px; padding: 6px 0 0; }
.sheet h4 { font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); margin: 20px 0 6px; }
.activity li { list-style: none; display: grid; grid-template-columns: calc(70 / 17 * var(--fs)) 1fr; gap: 12px; font-size: calc(15 / 17 * var(--fs)); padding: 5px 0; }
.activity .tnum { color: var(--ink-2); }

/* lists, forms, people */
.field { display: flex; justify-content: space-between; align-items: center; gap: 16px; min-height: 52px; border-top: 1px solid var(--rule); }
.field.rule-end, .rule-end { border-bottom: 1px solid var(--rule); }
.field label, .field > span:first-child { flex: none; }
.field input, .field select { text-align: right; color: var(--ink-2); width: 100%; min-width: 0; padding: 14px 0; outline: none; }
.field input:focus, .field select:focus { color: var(--ink); }
.field .val { color: var(--ink-2); }
.field .pair { display: flex; gap: 8px; align-items: center; }
.field .pair input { width: 5em; }
.field .pair select { width: auto; }
.note-inline { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; padding: 4px 0; }
.chip { min-height: 44px; padding: 0 6px 0 14px; border-radius: 999px; background: var(--surface); border: 1px solid var(--rule); display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-variant-numeric: tabular-nums; position: relative; }
.chip .x { width: 44px; height: 44px; margin-right: -6px; border-radius: 50%; display: grid; place-items: center; color: var(--ink-2); }
.chip .x svg { width: 14px; height: 14px; }
.chip.add { border-style: dashed; border-color: var(--tick-ring); padding: 0 16px 0 12px; background: none; }
.chip.add svg { width: 16px; height: 16px; }
.chip.add select { position: absolute; inset: 0; opacity: 0; width: 100%; }
.switch { width: 51px; height: 31px; border-radius: 16px; background: var(--tick-ring); position: relative; flex: none; }
.switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 27px; height: 27px; border-radius: 50%; background: #fff; box-shadow: 0 2px 4px rgba(0, 0, 0, .2); transition: left .25s cubic-bezier(.16, 1, .3, 1); }
.switch[aria-checked="true"] { background: var(--taken); }
.switch[aria-checked="true"]::after { left: 22px; }
.danger-row { display: flex; gap: 10px; padding: 26px 0 30px; }
.danger-row button { flex: 1; min-height: 48px; border-radius: 15px; border: 1.5px solid var(--rule); font-weight: 600; }
.danger-row .stop { color: var(--missed); }
.av { width: 40px; height: 40px; border-radius: 50%; background: var(--av); color: var(--av-ink); font-weight: 700; display: grid; place-items: center; font-size: calc(16 / 17 * var(--fs)); }
.av.pending { background: none; border: 1.5px dashed var(--tick-ring); color: var(--ink-2); }
.who { display: block; font-size: var(--fs); font-weight: 600; overflow-wrap: anywhere; }
.sub { display: block; font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; }
.inline-form { display: grid; gap: 10px; padding: 12px 0; border-top: 1px solid var(--rule); }
.inline-form label { font-size: calc(15 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); }
.inline-form input, .inline-form select { min-height: 44px; border-bottom: 1px solid var(--rule); }

/* Settings' sign-out card: the one card left (the rest is a grouped list, below) */
.card { margin: 16px 16px 0; padding: 0 16px 16px; background: var(--surface); border: 1px solid var(--rule); border-radius: 16px; scroll-margin-top: calc(84px + env(safe-area-inset-top)); }
.card .group-head { padding: 16px 0 4px; }
.card-note { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; padding-bottom: 10px; }
.card .field { flex-wrap: wrap; column-gap: 12px; }
.card .field > span:first-child { flex: 1 1 10em; min-width: 0; padding: 12px 0; }
.card .field > button { margin-left: auto; }

/* form error line (dose details) */
.form-error { color: var(--missed); font-weight: 600; font-size: calc(15 / 17 * var(--fs)); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; }
}

/* Proposed additions to public/app.css for Plans 2 and 3. Same tokens, same rules (DESIGN.md):
   every size a ratio of --fs, tabular figures for times, hairlines not cards, magenta only for now.
   The build moves these into app.css unchanged once the mockups are approved. */

/* ---------- shared ---------- */
.ico { width: 22px; height: 22px; flex: none; }
.page-pad { padding: 0 20px; }
.lede { font-size: var(--fs); line-height: 1.45; color: var(--ink-2); margin-top: 8px; max-width: 34ch; }
.h-screen { font-size: calc(28 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.022em; line-height: 1.15; text-wrap: balance; }
.btn-primary:disabled { opacity: .38; }
.mt { margin-top: 24px; }
.tabbar.tabs-4 { grid-template-columns: repeat(4, 1fr); }
.navbar .l svg { width: 20px; height: 20px; margin-left: -6px; }
.list-row .val { display: inline-flex; align-items: center; gap: 4px; color: var(--ink-2); }

/* ---------- welcome, invite code, first-time setup ---------- */
.welcome-shell { padding: 26px 20px 30px; }
.app-mark { width: 60px; height: 60px; border-radius: 14px; display: block; box-shadow: 0 0 0 1px var(--shell-rule); }
.welcome-shell h1 { margin-top: 18px; font-size: calc(34 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.026em; line-height: 1.05; }
.welcome-shell p { margin-top: 10px; font-size: var(--fs); line-height: 1.4; color: var(--shell-ink-2); max-width: 28ch; }
.welcome-shell .tide { display: block; margin-top: 22px; }
.tide-track { fill: var(--shell-rule); }
.tide-band { fill: var(--band); }
.tide-now { stroke: var(--now-on-shell); stroke-width: 2; stroke-linecap: round; }
.paths { display: grid; gap: 12px; padding: 24px 20px 0; }
.path { width: 100%; min-height: 76px; display: grid; grid-template-columns: 40px minmax(0, 1fr) 18px; gap: 14px; align-items: center; padding: 14px 16px; border-radius: 16px; background: var(--surface); border: 1px solid var(--rule); text-align: left; }
.path.main { border: 2px solid var(--primary); }
.path .disc { width: 40px; height: 40px; border-radius: 50%; background: var(--seg); color: var(--primary); display: grid; place-items: center; }
.path.main .disc { background: var(--primary); color: var(--on-primary); }
.path .disc svg { width: 22px; height: 22px; }
.path strong { display: block; font-weight: 650; }
.path em { display: block; font-style: normal; font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; line-height: 1.35; }
.foot-note { padding: 18px 20px 0; font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.45; }

.code-screen { padding: 22px 20px 0; }
.code-wrap { position: relative; margin: 26px auto 0; max-width: 340px; }
.code-boxes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)) calc(6 / 17 * var(--fs)) repeat(3, minmax(0, 1fr)); gap: 8px; }
/* The boxes are the code field's only visible outline, so even an empty one has a --tick-ring edge (3.4:1 on the
   page, 3.7:1 on its own fill; 4.5 and 4.0 at night: WCAG 1.4.11), the same edge a filled one has. Digits stop
   growing at a tenth of the screen's width, so at the largest text sizes they still fit their boxes. */
.code-box { aspect-ratio: 46 / 60; border-radius: 12px; background: var(--surface); border: 1.5px solid var(--tick-ring); display: grid; place-items: center; position: relative;
  font-size: min(calc(30 / 17 * var(--fs)), 10vw); font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
.code-box.next { border: 2.5px solid var(--primary); }
.code-box.next::after { content: ""; width: 2px; height: 46%; border-radius: 1px; background: var(--primary); animation: caret 1.05s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }
.code-input { position: absolute; inset: 0; width: 100%; opacity: 0; font-size: 16px; color: transparent; caret-color: transparent; }
.code-help { margin-top: 16px; text-align: center; font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.45; }
.code-error .code-box { border-color: var(--missed); }
.code-error .code-boxes { animation: shake .42s cubic-bezier(.36, .07, .19, .97); }
@keyframes shake { 20%, 60% { transform: translateX(-7px); } 40%, 80% { transform: translateX(7px); } }
.err { display: flex; gap: 8px; align-items: flex-start; justify-content: center; margin-top: 14px; color: var(--missed); font-weight: 600; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; text-align: left; }
.err svg { width: 18px; height: 18px; flex: none; margin-top: 1px; }

.setup-form { display: grid; gap: 4px; padding: 6px 0 0; }
.setup-form label { font-weight: 650; margin-top: 18px; }
.setup-form .hint { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; margin-bottom: 6px; }
.setup-form input { min-height: 52px; padding: 0 14px; border-radius: 12px; background: var(--surface); border: 1px solid var(--rule); }

.steps { list-style: none; counter-reset: step; margin-top: 20px; }
.steps li { counter-increment: step; display: grid; grid-template-columns: 34px minmax(0, 1fr); gap: 12px; padding: 14px 0; border-top: 1px solid var(--rule); line-height: 1.45; }
.steps li:last-child { border-bottom: 1px solid var(--rule); }
.steps li::before { content: counter(step); width: 34px; height: 34px; border-radius: 50%; background: var(--primary); color: var(--on-primary); display: grid; place-items: center; font-weight: 700; font-variant-numeric: tabular-nums; }
.steps .inl { display: inline-grid; place-items: center; width: 1.45em; height: 1.45em; border-radius: 6px; background: var(--seg); color: var(--primary); vertical-align: -0.38em; margin: 0 2px; }
.steps .inl svg { width: 1em; height: 1em; }
.steps strong { font-weight: 650; }
/* A text button inside a note keeps its 44pt tap height without opening up the note's line spacing. */
.note .textbtn { margin-block: -12px; }

/* ---------- Today: household names, moving, care tasks, when needed ---------- */
.slot .t .hh { display: block; margin-top: 3px; font-size: calc(13 / 17 * var(--fs)); font-weight: 600; letter-spacing: 0; color: var(--ink-2); }
.row-extra { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 8px; }
.btn-move { min-height: 44px; padding: 0 16px 0 12px; border-radius: 999px; border: 1.5px solid var(--primary); color: var(--primary); font-size: calc(15 / 17 * var(--fs)); font-weight: 650; display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.btn-move svg { width: 18px; height: 18px; }
.mk-todo { --c: var(--ink); }
.mk-notdone { --c: var(--upcoming); }
.on-shell .mk-todo { --c: var(--shell-ink); }
.on-shell .mk-notdone { --c: var(--upcoming-on-shell); }
.c-todo { color: var(--ink); font-weight: 600; }
.prn-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 12px 0; border-top: 1px solid var(--rule); }
.prn-row .btn-sm { flex: none; }
.prn-row .when { display: block; margin-top: 6px; font-size: calc(14 / 17 * var(--fs)); font-weight: 600; font-variant-numeric: tabular-nums; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 10px; font-size: min(calc(13 / 17 * var(--fs)), 15px); color: var(--shell-ink-2); }
.legend span { display: inline-flex; gap: 6px; align-items: center; }

/* dose details: move to later today */
/* minmax(0, 1fr): the two columns never push the sheet sideways (at large text they stack, below). */
.move-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.move-grid button { min-height: 58px; padding: 8px 12px; border-radius: 12px; border: 1px solid var(--rule); background: var(--surface); text-align: left; display: grid; align-content: center; gap: 1px; }
.move-grid strong { font-weight: 650; }
.move-grid span { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.move-grid .other { border-style: dashed; border-color: var(--tick-ring); }
.cycle { display: flex; gap: 8px; align-items: flex-start; margin-top: 10px; padding: 10px 12px; border-radius: 12px; background: var(--ground); font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; }
.cycle svg { width: 18px; height: 18px; flex: none; color: var(--primary); margin-top: 1px; }

/* ---------- add chooser, medication and care task form ---------- */
.choice { width: 100%; min-height: 72px; display: grid; grid-template-columns: 44px minmax(0, 1fr) 18px; gap: 14px; align-items: center; padding: 12px 0; border-top: 1px solid var(--rule); text-align: left; }
.choice:last-of-type { border-bottom: 1px solid var(--rule); }
.choice .disc { width: 44px; height: 44px; border-radius: 12px; background: var(--seg); color: var(--primary); display: grid; place-items: center; }
.choice .disc svg { width: 24px; height: 24px; }
.choice strong { display: block; font-weight: 650; }
.choice em { display: block; font-style: normal; font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; }

/* Care task kind (Care plan redesign): four choices with their icons, one or none chosen. */
.kind-pick { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; flex-basis: 100%; }
.kind-pick button { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 12px; border: 1px solid var(--rule); border-radius: 12px; background: var(--surface); color: var(--ink); font-weight: 600; font-size: calc(15 / 17 * var(--fs)); text-align: left; }
.kind-pick button[aria-pressed="true"] { border: 2px solid var(--primary); background: var(--seg); }
.kind-ico { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; background: var(--taken-soft); color: var(--taken); flex: none; }
.kind-ico svg { width: 20px; height: 20px; }
.big .kind-pick { grid-template-columns: 1fr; }
.reading { padding: 16px 0 14px; border-bottom: 1px solid var(--rule); }
.reading p { display: flex; justify-content: space-between; gap: 12px; font-weight: 650; }
.reading p span { font-weight: 400; color: var(--ink-2); font-size: calc(14 / 17 * var(--fs)); }
.reading .bar { margin-top: 10px; height: 4px; border-radius: 2px; background: var(--seg); overflow: hidden; }
.reading .bar::after { content: ""; display: block; width: 38%; height: 100%; border-radius: 2px; background: var(--primary); animation: sweep 1.4s cubic-bezier(.16, 1, .3, 1) infinite; }
@keyframes sweep { from { transform: translateX(-100%); } to { transform: translateX(270%); } }
.check-band { margin: 0 -20px; padding: 14px 20px; background: var(--band); }
.check-band strong { display: block; font-weight: 650; }
.check-band q { display: block; margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--rule); font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; quotes: none; }
.check-band q b { font-weight: 650; }
.field.from :is(input, textarea), .field.from .val { color: var(--ink); }
/* Plan 4a: the label screen (Take a photo of the label, or speak the words instead) and the AI sheen, as approved in
   the Plan 4a mockups (mockups/plan-4a, L1, L1b, L2 and L3, round 5).
   The AI sheen ("pāua") is one look for everything the label reader does: the photo button, the listening panel and
   every "From label" pill. It's the app's one gradient and its one glint, for AI only (DESIGN.md, Plan 4a additions).
   - An iridescent edge (teal, harbour blue, lilac), the colours of a pāua shell, over a pale pearl fill (night: a deep
     one). No magenta: that stays "now" only.
   - A soft glint crosses it three times, 7 seconds apart, while the edge's colours drift; then it rests.
   - Words on it are plain ink (night: cream): 13.7:1 or more by day; 12:1 at night, 6.9:1 where the glint peaks. The
     pill keeps its words, so it's never told by colour alone. */
:is(.ai, .from-label) {
  border: 1.5px solid transparent; color: var(--ink);
  background:
    linear-gradient(100deg, transparent 38%, var(--ai-glint) 50%, transparent 62%) padding-box,
    linear-gradient(115deg, var(--ai-fill-1), var(--ai-fill-2) 55%, var(--ai-fill-3)) padding-box,
    linear-gradient(100deg, var(--ai-1), var(--ai-2) 16.67%, var(--ai-3) 33.33%, var(--ai-1) 50%, var(--ai-2) 66.67%, var(--ai-3) 83.33%, var(--ai-1)) border-box;
  background-size: 300% 100%, 100% 100%, 200% 100%;
  background-position: 100% 0, 0 0, 0 0;
}
/* The glint crosses three times, 7 seconds apart, then rests (Slade, 13 October). Never infinite. */
:is(.ai, .from-label) { animation: ai-sheen 7s linear 3; }
/* The glint crosses in the first 2.8 s, then rests; the edge drifts the whole time (its colours repeat, so the loop
   doesn't jump). */
@keyframes ai-sheen {
  0% { background-position: 100% 0, 0 0, 0 0; }
  40% { background-position: 0% 0, 0 0, 40% 0; }
  100% { background-position: 0% 0, 0 0, 100% 0; }
}
/* The AI mark: a four-point spark, on the photo button and in every pill. */
svg.spark { fill: currentColor; stroke: none; color: var(--ai-3); flex: none; }
/* The label's start: the photo leads, full width. No heading and no tips until a photo reads nothing (.label-help).
   Speaking is a small link under it (.speak-link). */
.label-ai { padding: 16px 0; border-bottom: 1px solid var(--rule); display: grid; grid-template-columns: minmax(0, 1fr); justify-items: start; row-gap: 10px; }
.ai-photo {
  position: relative; justify-self: stretch; min-height: calc(3 * 1.4 * 15 / 17 * var(--fs) + 28px); padding: 12px 40px 12px 14px;
  border-width: 2px; border-radius: 16px; display: grid; grid-template-columns: 44px minmax(0, 1fr); align-items: center; column-gap: 14px;
  text-align: left; font-weight: 650; line-height: 1.3; text-wrap: balance;
}
.ai-photo > .spark { position: absolute; top: 12px; right: 12px; width: 14px; height: 14px; }
.ai-disc { width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center; color: var(--ai-on);
  background: linear-gradient(135deg, var(--ai-1), var(--ai-2) 55%, var(--ai-3)); }
.ai-disc svg { width: 22px; height: 22px; }
/* "+ or speak the words instead", in Slade's words: the app's navy text button (night: teal) with a small plus before
   it; no fill, no edge, no sheen. Tap to start, Done to finish. Its tap area is 44 pt by padding at every text size,
   not a bigger look. */
.speak-link { min-height: 44px; margin: -6px 0 -6px -8px; gap: 6px; text-align: left; }
.speak-link > svg { width: 1em; height: 1em; flex: none; }
/* Listening: the photo's place becomes the live panel, with Cancel and Done. */
.ai-live { display: block; padding: 12px 14px 8px; }
.listen-acts { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 4px 12px; margin-top: 6px; }
/* Cancel in ink, not navy (night: teal), which falls to the 4.5:1 line at night where the glint passes. */
.listen-acts .textbtn { margin-left: -8px; color: var(--ink); }
.listening { display: grid; grid-template-columns: minmax(0, 1fr); align-content: start; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; }
.listen-head { display: flex; align-items: center; gap: 8px; font-weight: 650; color: var(--ink); }
.listen-head > span:nth-child(2) { flex: 1; min-width: 0; }
.listen-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--ai-2); animation: run-pulse 1.4s ease-in-out infinite; }
.listen-time { font-weight: 650; font-variant-numeric: tabular-nums; }
/* The level: the minute as a line, with what it's heard drawn up to now, half a second a bar. */
.listen-line { display: flex; align-items: center; gap: 8px; height: calc(1.4 * 15 / 17 * var(--fs)); }
/* The listening line: 120 bars, one per half second, in a row of their own so a whole minute fits the line's width.
   The minute is a solid 1.5 px track (mockup L2); unheard bars are clear over it, and each heard one is sized by how
   loud it was (data-l; no styles from JS). */
.listen-bars { flex: 1 1 auto; min-width: 0; height: 20px; display: flex; align-items: center; gap: 1px;
  background: linear-gradient(var(--rule), var(--rule)) center / 100% 1.5px no-repeat; }
.listen-bars i { flex: 1 1 0; min-width: 0; height: 2px; border-radius: 1px; background: transparent; }
.listen-bars i[data-l] { background: var(--ai-2); }
/* Heard bars take the sheen's colours, oldest to newest: teal, blue, lilac (data-c, the third of what's heard so far
   that each bar is in). Each keeps 3:1 or more against the panel in both themes, where the glint passes too. */
.listen-bars i[data-c="1"] { background: var(--ai-1); }
.listen-bars i[data-c="3"] { background: var(--ai-3); }
.listen-bars i[data-l="1"] { height: 6px; }
.listen-bars i[data-l="2"] { height: 10px; }
.listen-bars i[data-l="3"] { height: 14px; }
.listen-bars i[data-l="4"] { height: 18px; }
.listen-end { font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.listen-tip { color: var(--ink-2); }
/* On the sheen, muted ink would fall under 4.5:1 at night where the glint passes; plain ink keeps 6.9:1 or more. */
.ai-live :is(.listen-tip, .listen-end) { color: var(--ink); }
.ai-live .listen-tip { font-weight: 400; }
/* After a photo reads nothing, the help shows above the photo button and the link (it replaces the toast): the label
   reader's own pale-water band, as for "Check each detail", so it reads calm, not as an error. */
.label-help { justify-self: stretch; margin: -16px -20px 4px; padding: 14px 20px 16px; background: var(--band); }
.label-help strong { display: block; font-weight: 650; }
/* At most three lines at standard text: each sentence its own line. */
.label-how { margin-top: 4px; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; }
.label-how > span { display: block; }
/* The "From label" pill, in the sheen, with its spark and its words. */
.from-label { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; padding: 1px 7px 1px 5px; border-width: 1px; border-radius: 999px;
  font-size: calc(12 / 17 * var(--fs)); font-weight: 650; line-height: 1.35; vertical-align: 1px; white-space: nowrap; }
.from-label svg.spark { width: .85em; height: .85em; }
/* The heard name's safeguard (spec 20.6), under the Name row. */
.field.heard { flex-wrap: wrap; row-gap: 0; }
.field.heard > input { flex: 1 1 6em; width: 0; }
/* At the largest sizes a filled row's label and pill can take the width; then its value drops under them, on the right,
   instead of running off the screen. */
.big .field.from { flex-wrap: wrap; column-gap: 12px; }
.big .field.from > input { flex: 1 1 6em; width: 0; }
.big .field.from > .val { margin-left: auto; }
.big .field.from > :first-child { flex: 0 1 auto; min-width: 0; white-space: normal; }
.heard-note { flex-basis: 100%; margin: -8px 0 12px; font-size: calc(14 / 17 * var(--fs)); font-weight: 600; line-height: 1.35; color: var(--ink); }
/* Reduce Motion: nothing moves. The glint rests a little left of centre, the edge holds still, and so does the dot.
   The line still follows the voice, since that's how she knows it's hearing (mockup L2). */
@media (prefers-reduced-motion: reduce) {
  :is(.ai, .from-label) { animation: none; background-position: 60% 0, 0 0, 0 0; }
  .ai-photo, .ai-live, .listen-dot { animation: none; transition: none; }
}

.type-opts { margin-top: 2px; }
.type-opt { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 12px; align-items: start; padding: 12px 0; border-top: 1px solid var(--rule); position: relative; }
.type-opt input { position: absolute; opacity: 0; inset: 0; }
.type-opt .radio { width: 22px; height: 22px; margin-top: 1px; border-radius: 50%; border: 2px solid var(--tick-ring); display: grid; place-items: center; }
.type-opt input:checked ~ .radio { border-color: var(--primary); }
.type-opt input:checked ~ .radio::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--primary); }
.type-opt strong { display: block; font-weight: 600; }
.type-opt em { display: block; font-style: normal; font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; line-height: 1.35; }
.type-opt.rule-end { border-bottom: 1px solid var(--rule); }
.quick { margin: 4px 0 10px; }
.chip .hh { color: var(--ink-2); font-weight: 500; }
.stepper { display: inline-flex; align-items: center; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); flex: none; }
.stepper button { width: 44px; height: 40px; display: grid; place-items: center; color: var(--primary); }
.stepper button svg { width: 18px; height: 18px; }
.stepper button[aria-disabled="true"] { opacity: .38; }
.step-val { position: relative; display: flex; }
.step-val select { position: absolute; inset: -2px 0; width: 100%; height: calc(100% + 4px); opacity: 0; }
.stepper output { min-width: 4.6em; padding-inline: 11px; box-sizing: content-box; text-align: center; white-space: nowrap; font-weight: 600; font-variant-numeric: tabular-nums; border-inline: 1px solid var(--rule); line-height: 40px; }
.field.stack { flex-wrap: wrap; padding: 12px 0; }
.field.stack .note { flex-basis: 100%; padding-top: 0; }
/* A multi-line note (Instructions): the label above, a full-width boxed field below, like the label-words box. 16pt or more so iOS doesn't zoom. */
.field.stack textarea { flex: 1 0 100%; box-sizing: border-box; width: 100%; font: inherit; font-size: var(--fs); line-height: 1.4; padding: 10px 12px; border: 1px solid var(--rule); border-radius: 10px; background: var(--surface); color: var(--ink); resize: vertical; caret-color: var(--primary); }
.field.stack textarea:focus { border-color: var(--primary); }
/* The read-only Instructions: a long, multi-line note reads under its label, not squeezed into the right-hand column. */
.field.stack > .val { flex: 1 0 100%; white-space: pre-line; overflow-wrap: anywhere; }
.ro-type { display: flex; justify-content: space-between; gap: 12px; padding: 14px 0; border-top: 1px solid var(--rule); color: var(--ink-2); }

/* care plan list */

/* settings: household times, phones */
button.hh-row { width: 100%; text-align: left; }
.hh-row .val { display: inline-flex; align-items: center; gap: 2px; font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 600; }
.hh-row .val small { font-weight: 500; color: var(--ink-2); }
.moves { list-style: none; margin-top: 14px; }
.moves li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; padding: 12px 0; border-top: 1px solid var(--rule); }
.moves li:last-child { border-bottom: 1px solid var(--rule); }
.moves .tnum { font-weight: 600; }
.moves .tnum s { color: var(--ink-2); font-weight: 500; margin-right: 6px; }

/* ---------- baby log ---------- */
.day-nav { display: inline-flex; align-items: center; gap: 2px; }
.day-nav button { width: 44px; height: 44px; display: grid; place-items: center; color: var(--shell-ink); border-radius: 50%; }
.day-nav button[disabled] { color: var(--shell-rule); }
.day-nav svg { width: 20px; height: 20px; }
.babyline { display: block; margin-top: 12px; overflow: visible; }
.bl-sleep { fill: var(--band); }
.bl-mark { fill: var(--shell-ink); }
.bl-ring { fill: var(--shell); stroke: var(--shell-ink); }
.bl-label { fill: var(--shell-ink-2); font-size: min(calc(11 / 17 * var(--fs)), 15px); font-weight: 500; font-variant-numeric: tabular-nums; }
.bl-tick { stroke: var(--shell-ink-2); stroke-opacity: .55; }
.totals { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--shell-rule); font-size: calc(15 / 17 * var(--fs)); color: var(--shell-ink); font-variant-numeric: tabular-nums; }
.totals b { font-weight: 700; }
.baby-acts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; padding: 16px 20px 0; }
.baby-act { min-height: 88px; border-radius: 16px; background: var(--surface); border: 1px solid var(--rule); display: grid; place-items: center; align-content: center; gap: 6px; font-weight: 650; color: var(--ink); }
.baby-act svg { width: 30px; height: 30px; color: var(--primary); }
.baby-act[aria-expanded="true"] { border: 2px solid var(--primary); }
/* Timers on the Baby tab (spec 2, section 14). */
.run-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--taken); flex: none; animation: run-pulse 2s ease-in-out infinite; }
@keyframes run-pulse { 50% { opacity: .35; } }
/* A running timer's icon in the strip and the pill: 16pt, pulsing like the dot. It keeps pulsing with Reduce Motion (Slade, 11 October). */
.run-ico { display: inline-flex; flex: none; width: 16px; height: 16px; animation: run-pulse 2s ease-in-out infinite; }
.run-ico svg { width: 16px; height: 16px; }
.tpill-t { display: inline-flex; align-items: center; gap: 4px; }
.baby-act.running { border: 2px solid var(--primary); }
.ba-run { display: inline-flex; align-items: center; gap: 6px; font-size: calc(14 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.ba-run .run-dot { color: var(--taken); }
.timer-cleared { margin: 12px 20px 0; }
.check-len { margin-top: 10px; padding: 10px 12px; border-radius: 10px; background: var(--late-bg); color: var(--late); font-weight: 600; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; }
.sheet .or-log { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--rule); }
.nappy-pick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; padding: 10px 20px 0; }
.nappy-pick button { min-height: 54px; border-radius: 14px; background: var(--primary); color: var(--on-primary); font-weight: 650; }
.blog .row { grid-template-columns: minmax(0, 1fr) 18px; cursor: pointer; }
.blog .name { display: flex; gap: 8px; align-items: center; }
.blog .name svg { width: 18px; height: 18px; color: var(--ink-2); flex: none; }
.blog .detail { padding-left: 26px; }
.picks { display: flex; flex-wrap: wrap; gap: 8px; }
.pick { min-height: 44px; padding: 0 12px; border-radius: 999px; border: 1px solid var(--rule); background: var(--surface); font-weight: 600; font-variant-numeric: tabular-nums; }
.pick[aria-pressed="true"] { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); background: var(--band); }
.pick.other { border-style: dashed; border-color: var(--tick-ring); }
.slept { margin-top: 14px; font-weight: 600; font-variant-numeric: tabular-nums; }
.baby-band { background: var(--surface); border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); padding: 14px 20px; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
/* Two babies' cards in a row share one hairline between them. */
.baby-band + .baby-band { border-top: 0; }
.baby-band .who { display: flex; gap: 8px; align-items: center; }
.baby-band .who > svg { width: 18px; height: 18px; color: var(--primary); }
.baby-band p { font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); margin-top: 3px; font-variant-numeric: tabular-nums; line-height: 1.35; }

/* ---------- people: a badge per cared-for person ---------- */
:root { --pb1-bg: #d3e6eb; --pb1-ink: #12324a; --pb2-bg: #e5def4; --pb2-ink: #3b2d66; --pb3-bg: #f2e1d6; --pb3-ink: #5c3624; --pb4-bg: #dde3e8; --pb4-ink: #26343f; --pb5-bg: #fdd3d3; --pb5-ink: #6b2a3c; --pb6-bg: #cae3f9; --pb6-ink: #23396b; --pb7-bg: #e7e6dc; --pb7-ink: #3d3429; --pb8-bg: #f6dbeb; --pb8-ink: #542a51; }
@media (prefers-color-scheme: dark) {
  :root { --pb1-bg: #1d3a52; --pb1-ink: #cfe6ec; --pb2-bg: #2d2650; --pb2-ink: #ddd3f5; --pb3-bg: #3d2a20; --pb3-ink: #f0d6c6; --pb4-bg: #263540; --pb4-ink: #d5dee5; --pb5-bg: #4a2530; --pb5-ink: #f3d3dc; --pb6-bg: #22304f; --pb6-ink: #d4def4; --pb7-bg: #3a332a; --pb7-ink: #e6ddd1; --pb8-bg: #3f2440; --pb8-ink: #ecd4ea; }
}
.pb-1 { --pb-bg: var(--pb1-bg); --pb-ink: var(--pb1-ink); }
.pb-2 { --pb-bg: var(--pb2-bg); --pb-ink: var(--pb2-ink); }
.pb-3 { --pb-bg: var(--pb3-bg); --pb-ink: var(--pb3-ink); }
.pb-4 { --pb-bg: var(--pb4-bg); --pb-ink: var(--pb4-ink); }
.pb-5 { --pb-bg: var(--pb5-bg); --pb-ink: var(--pb5-ink); }
.pb-6 { --pb-bg: var(--pb6-bg); --pb-ink: var(--pb6-ink); }
.pb-7 { --pb-bg: var(--pb7-bg); --pb-ink: var(--pb7-ink); }
.pb-8 { --pb-bg: var(--pb8-bg); --pb-ink: var(--pb8-ink); }
.pb { width: calc(22 / 17 * var(--fs)); height: calc(22 / 17 * var(--fs)); border-radius: 50%; display: inline-grid; place-items: center; flex: none; background: var(--pb-bg); color: var(--pb-ink); font-size: calc(12 / 17 * var(--fs)); font-weight: 700; line-height: 1; letter-spacing: 0; }
.pb svg { width: 68%; height: 68%; }
.pb.pb-lg { width: 40px; height: 40px; font-size: calc(16 / 17 * var(--fs)); }
.row-main.with-pb { grid-template-columns: calc(22 / 17 * var(--fs)) minmax(0, 1fr); column-gap: 10px; }
.row-main.with-pb .pb { margin-top: 1px; }
.pbc { fill: var(--pb-bg); }
.pbt { fill: var(--pb-ink); }
.pbl { font-size: 11px; font-weight: 700; }
.st-name { fill: var(--shell-ink-2); font-size: min(calc(13 / 17 * var(--fs)), 16px); font-weight: 600; }

/* care tasks: rounded-square ticks to match their marks; medications stay round */
.tick.sq { border-radius: 14px; }

/* Skipped (Slade, 12 Oct): the tick button takes the skipped mark's dashed outline in muted ink, so a skip reads at a glance. */
.tick.skip { border-style: dashed; border-color: var(--upcoming); border-width: 2px; }
.tick.skip svg { display: none; }

/* nappy marks on the baby line */
.bl-hole { fill: var(--shell); }
.bl-line { fill: none; stroke: var(--shell-ink); }
.nappy-pick button { display: flex; align-items: center; justify-content: center; gap: 8px; }
.nappy-pick svg { width: 22px; height: 22px; }

/* wheel picker: two columns (Each dose) or three (a household time) */
.pick-row { width: 100%; text-align: left; }
.pick-row .val { display: inline-flex; align-items: center; gap: 4px; }
.wheel { --wh: calc(44 / 17 * var(--fs)); position: relative; display: grid; grid-template-columns: 1fr 1.4fr; gap: 8px; height: calc(var(--wh) * 5); margin-top: 18px; }
.wheel:has(> .wheel-col:nth-child(4)) { grid-template-columns: repeat(3, 1fr); }
.wheel-band { position: absolute; left: 0; right: 0; top: calc(var(--wh) * 2); height: var(--wh); border-radius: 10px; background: var(--seg); pointer-events: none; }
.wheel-col { position: relative; overflow-y: auto; scroll-snap-type: y mandatory; padding: calc(var(--wh) * 2) 0; scrollbar-width: none; border-radius: 10px;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 34%, #000 66%, transparent); mask-image: linear-gradient(to bottom, transparent, #000 34%, #000 66%, transparent); }
.wheel-col::-webkit-scrollbar { display: none; }
.wheel-col [role="option"] { height: var(--wh); display: grid; place-items: center; scroll-snap-align: center; font-size: calc(20 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.wheel-col [aria-selected="true"] { color: var(--ink); font-weight: 650; }
.wheel-other { text-align: center; margin-top: 6px; }

@media (prefers-reduced-motion: reduce) {
  .code-box.next::after, .code-error .code-boxes, .reading .bar::after { animation: none !important; }
}

/* Today: Another time… in the move grid, and When needed rows with a person badge */
.move-grid label { min-height: 58px; padding: 8px 12px; border-radius: 12px; border: 1px dashed var(--tick-ring); display: grid; align-content: center; gap: 1px; position: relative; }
.move-grid label strong { font-weight: 650; }
.move-grid label span { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); }
.move-grid select { position: absolute; inset: 0; opacity: 0; width: 100%; }
.prn-row.with-pb { grid-template-columns: calc(22 / 17 * var(--fs)) minmax(0, 1fr) auto; }
.prn-row.with-pb .pb { margin-top: 1px; align-self: start; }
.sheet .form-error { margin-top: 12px; }
/* The Feed sheet's typed number: its error sits straight under its field (the form's own 10px below the field is the
   gap), and the field's rule turns brick with it. Scoped to that field, so Today's dose-sheet error (after its hidden
   Skip form) keeps its 12px. */
.sheet [data-form="other"] + .form-error { margin-top: 0; }
.skip-form input[aria-invalid="true"] { border-bottom-color: var(--missed); }

/* Care plan form: Course rows read "Today" or "No end date"; the native date picker sits over the row */
.date-row { position: relative; }
.date-row input { position: absolute; inset: 0; opacity: 0; width: 100%; }

/* ---------- design audit fixes (keyboard, large text) ---------- */
/* Placeholders are hints, so they sit clearly lighter than a typed value (--ink-2, 6.7:1), yet stay readable:
   --placeholder is 3.7:1 on surfaces and 3.4:1 on the ground in light, 3.7:1 and 4.2:1 at night. */
::placeholder { color: var(--placeholder); opacity: 1; }
/* Rows with an invisible native control over them (pickers, radios, dates) and label-left text fields show
   keyboard focus on the row. Not after a tap: the iPhone's own picker or caret shows it then.
   (A date field's focus sits in its inner parts, which WebKit doesn't count as :focus-visible.) */
html:not(.pointer) :is(.type-opt, .list-row, .chip.add, .move-grid label, .seg label):has(> :is(input, select):focus-visible),
html:not(.pointer) .field:has(> input:focus-visible),
html:not(.pointer) .step-val:has(> select:focus-visible),
html:not(.pointer) .date-row:has(> input:focus) { outline: 2.5px solid var(--focus); outline-offset: 2px; }
/* A sheet's heading takes focus when it opens, and a Join screen's when it shows, so each is read first; a heading
   isn't a control, so it shows no ring. */
#sheet-title:focus, h1[tabindex="-1"]:focus { outline: none; }
/* Tap areas of at least 44pt without redrawing anything: a stepper's buttons are 40 tall inside its 1px frame and
   a switch is 31 tall, so each reaches 44 with a transparent layer above and below it (within its 52pt row). */
.stepper button { position: relative; }
.stepper button::before { content: ""; position: absolute; inset: -2px 0; }
.switch::before { content: ""; position: absolute; inset: -6.5px 0; }
/* A stepper drops below its label when they don't fit side by side (narrow screens, large text). */
.field:has(> .stepper) { flex-wrap: wrap; row-gap: 8px; padding-block: 4.5px; }
.field > .stepper { margin-left: auto; }
/* Accessibility text sizes (.big, set by ui.js watchScreen): Today's list leads, and the header keeps to about a
   quarter of the screen. Its text stops at its XL size (the caps on .status-line, .status-sub and .legend, which
   only bite above XL), the day line draws compact (ui.js), the spacing tightens, the key is left out (each row
   in the list shows the same round or square mark, with its words), and the header scrolls away with the page.
   Each time sits above its names (DESIGN.md, One Dial Rule). */
.big .shell:has(> .shell-body) { position: relative; }
.big .shell-body { padding: 8px 20px 12px; }
.big .shell-body .dayline { margin-top: 6px; }
.big .shell-body .dayline + .legend { display: none; }
.big .shell-body .babyline + .legend { display: none; }
.big .slot { grid-template-columns: minmax(0, 1fr); row-gap: 8px; }
.big .slot .t .hh { display: inline; margin: 0 0 0 8px; }
/* The move-to tiles stack, so a time's name ("Bedtime", "Another time…") keeps clear of its tile's edges. */
.big .move-grid { grid-template-columns: minmax(0, 1fr); }
/* The edit screens' title wraps between Cancel and Save rather than pushing Save off the screen. */
.big .navbar { grid-template-columns: auto minmax(0, 1fr) auto; }

/* Today's now line: the day line's magenta now, echoed in the list above what's still to come (today.js nowLine).
   A 2px rule from the "Now 10:20am" label, which starts on the time column's edge, in the now label's type. */
.now-line { display: flex; align-items: center; gap: 8px; padding: 18px 20px 0; color: var(--now); font-size: calc(13 / 17 * var(--fs)); font-weight: 700; font-variant-numeric: tabular-nums; }
.now-line::after { content: ""; flex: 1; height: 2px; border-radius: 1px; background: var(--now); }
.now-line + .group > .group-head { padding-top: 14px; }

/* The Baby tab (baby.js): day arrows as links, the log buttons inside Today's Log sheet, a note field in a sheet */
.day-nav a { width: 44px; height: 44px; display: grid; place-items: center; color: var(--shell-ink); border-radius: 50%; }
.sheet .baby-acts, .sheet .nappy-pick { padding: 12px 0 0; }
.sheet-input { width: 100%; min-height: 44px; border-bottom: 1px solid var(--rule); margin-top: 4px; }
.blog .row-main.static { cursor: default; }
/* A typed amount sits on the Other pick once chosen: it then reads as a chosen pick, not a dashed "add". */
.pick.other[aria-pressed="true"] { border-style: solid; border-color: var(--primary); }
/* Long instructions: the Care plan list cuts its detail line at one line; Today's rows give the instructions a small line
   of their own, cut at one line at every text size; the dose sheet shows them in full. */
.instr-line { display: block; font-size: calc(14 / 17 * var(--fs)); line-height: 1.35; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.instr { font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); margin-top: 2px; overflow-wrap: anywhere; white-space: pre-line; }

/* Care plan (redesign, spec 3): day tiles in the shell, By kind | By time, rows with a mark and time pills. */
:root { --med-tint: #e3edf2; }
@media (prefers-color-scheme: dark) { :root { --med-tint: #17324a; } }
.cp-day { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 14px 20px 0; }
.cp-tile { min-height: 44px; border: 1px solid var(--shell-rule); border-radius: 12px; padding: 9px 6px 8px; color: var(--shell-ink); text-align: center; display: flex; flex-direction: column; align-items: center; gap: 1px; }
.cp-tile b { font-size: calc(13 / 17 * var(--fs)); font-weight: 700; }
.cp-tile i { font-style: normal; font-size: calc(12 / 17 * var(--fs)); color: var(--shell-ink-2); font-variant-numeric: tabular-nums; }
.cp-ic { display: flex; flex-wrap: wrap; justify-content: center; gap: 2px 8px; margin-top: 6px; font-size: calc(12 / 17 * var(--fs)); font-weight: 700; font-variant-numeric: tabular-nums; }
.cp-ic span { display: inline-flex; align-items: center; gap: 2px; }
.cp-ic svg { width: 16px; height: 16px; }
.cp-ic .ic-task { color: var(--taken-on-shell); }
.cp-none { margin-top: 6px; font-size: calc(12 / 17 * var(--fs)); color: var(--shell-ink-2); }
/* The view switch is a quiet control beside its short labels: drawn about 32pt tall (28pt buttons in 2pt padding), with an
   invisible 8pt above and below each button so it is still 44pt to tap (the way the stepper is). It grows with large text. */
.shell:has(> .seg.on-shell) { padding-bottom: 14px; } /* the switch's own bottom margin would collapse out of the shell, leaving it flush with the edge */
.seg.on-shell { margin: 14px 20px 0; background: var(--shell-rule); padding: 2px; border-radius: 9px; }
.seg.on-shell button { position: relative; min-height: 28px; border-radius: 7px; font-size: calc(13 / 17 * var(--fs)); color: var(--shell-ink-2); }
.seg.on-shell button::before { content: ""; position: absolute; inset: -8px 0; }
.seg.on-shell button[aria-pressed="true"] { background: var(--shell-ink); color: var(--shell); box-shadow: none; }
.cp-row { display: grid; grid-template-columns: 30px 1fr auto; gap: 12px; align-items: start; padding: 12px 0; border-top: 1px solid var(--rule); color: inherit; text-decoration: none; min-height: 52px; }
.cp-row > svg { align-self: center; }
.cp-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cp-mark { width: 30px; height: 30px; display: grid; place-items: center; }
.cp-mark svg { width: 20px; height: 20px; }
.cp-mark.med { border-radius: 50%; background: var(--med-tint); color: var(--primary); }
.cp-mark.task { border-radius: 8px; background: var(--taken-soft); color: var(--taken); }
.cp-row.faded { opacity: .55; }
.cp-row.faded .cp-mark { background: transparent; border: 1.5px dashed var(--tick-ring); }
.detail.one-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cp-pills { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.cp-pill { border: 1px solid var(--rule); background: var(--surface); border-radius: 999px; padding: 3px 10px; font-size: calc(12 / 17 * var(--fs)); font-weight: 600; font-variant-numeric: tabular-nums; }
.is-task .cp-pill { border-color: var(--taken-soft); }
.cp-pill.lim { background: var(--seg); font-weight: 500; }
.cp-pill.end { color: var(--ink-2); font-weight: 500; }
.big .cp-day { grid-template-columns: 1fr 1fr; }
/* Large text: the tiles are too tall to pin, so this header scrolls away with the page. */
.big .shell:has(.cp-day) { position: relative; }

/* Settings (redesign, spec 5): a grouped list that opens into pages. */
:root { --tile-navy: #12324a; --tile-teal: #2b7f96; --tile-slate: #4a5f6b; --tile-ink: #ffffff; }
@media (prefers-color-scheme: dark) { :root { --tile-navy: #8cc6d3; --tile-teal: #5aa9bb; --tile-slate: #3a5466; --tile-ink: #07141d; } }
.me-row { display: flex; gap: 12px; align-items: center; margin-top: 14px; padding: 0 20px 16px; }
.me-row .av { width: 44px; height: 44px; flex: none; }
.me-row b { display: block; font-size: var(--fs); color: var(--shell-ink); }
.me-row span span { font-size: calc(13 / 17 * var(--fs)); color: var(--shell-ink-2); }
.set-gl { display: flex; justify-content: space-between; gap: 8px; margin: 22px 20px 6px; font-size: calc(13 / 17 * var(--fs)); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-2); }
.set-gl span { min-width: 0; overflow-wrap: anywhere; }
.set-gl em { font-style: normal; text-transform: none; letter-spacing: 0; font-weight: 600; }
.set-grp { background: var(--surface); border-block: 1px solid var(--rule); }
.set-grp.set-gap { margin-top: 12px; }
.set-row { --inset: 64px; display: grid; grid-template-columns: 32px minmax(0, 1fr) fit-content(50%) auto; gap: 12px; align-items: center; min-height: 52px; padding: 9px 16px 9px 20px; color: inherit; text-decoration: none; }
.set-row + .set-row { box-shadow: inset var(--inset) 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); }
.set-row.plain, .set-row.sw { --inset: 20px; }
.set-row.plain { display: flex; flex-wrap: wrap; justify-content: space-between; column-gap: 12px; }
.set-row.sw { grid-template-columns: minmax(0, 1fr) auto; }
.set-tile { width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; color: var(--tile-ink); }
.set-tile svg { width: 20px; height: 20px; }
.set-tile.navy { background: var(--tile-navy); }
.set-tile.teal { background: var(--tile-teal); }
.set-tile.slate { background: var(--tile-slate); color: #ffffff; }
.set-label, .set-val, .set-lead, .set-foot, .set-act .set-lbl, .me-row b, .card .field > span { overflow-wrap: anywhere; }
.set-label { font-size: var(--fs); min-width: 0; }
.set-sub { display: block; margin-top: 2px; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.set-val { font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); text-align: right; font-variant-numeric: tabular-nums; }
.set-val.c-taken { color: var(--taken); font-weight: 600; }
.set-row > svg { width: 10px; height: 16px; color: var(--placeholder); }
.set-lead { padding: 14px 20px 2px; font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; }
.set-foot { padding: 8px 20px 0; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; }
.set-pad { padding: 0 20px; }
.set-person { --inset: 72px; display: grid; grid-template-columns: 40px minmax(0, 1fr) auto auto; gap: 12px; align-items: center; min-height: 60px; padding: 10px 16px 10px 20px; color: inherit; text-decoration: none; }
.set-person + .set-person { box-shadow: inset var(--inset) 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); }
.set-person .sub { display: block; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); margin-top: 1px; font-variant-numeric: tabular-nums; }
.set-person > svg { width: 10px; height: 16px; color: var(--placeholder); }
.set-person .textbtn { grid-column: 3; margin-right: -8px; }
.big .set-person { grid-template-columns: 40px minmax(0, 1fr) auto; }
.big .set-person .set-val { grid-column: 2; text-align: left; }
.big .set-person > svg { grid-column: 3; grid-row: 1 / span 2; }
.person-hero { text-align: center; padding: 22px 20px 4px; }
.person-hero .av { width: 64px; height: 64px; font-size: calc(26 / 17 * var(--fs)); margin: 0 auto; color: var(--av-ink); }
.person-hero b { display: block; font-size: calc(20 / 17 * var(--fs)); margin-top: 8px; overflow-wrap: anywhere; }
.person-hero span { font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); }
.set-act { display: flex; align-items: center; gap: 12px; min-height: 50px; padding: 0 16px 0 20px; width: 100%; text-align: left; font-size: var(--fs); color: var(--primary); font-weight: 600; }
.set-act.danger { color: var(--missed); }
.set-act svg { width: 22px; height: 22px; flex: none; }
.set-act + .set-act { box-shadow: inset 54px 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); }
.set-act .set-lbl { flex: 1; min-width: 0; white-space: normal; }
.set-act .set-val { font-weight: 400; }
.set-act > svg:last-child:not(:first-child) { width: 10px; height: 16px; color: var(--placeholder); }
.set-phone { display: flex; align-items: center; gap: 12px; min-height: 52px; padding: 6px 16px 6px 20px; }
.set-phone + .set-phone { box-shadow: inset 54px 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); }
.set-phone > svg { width: 22px; height: 22px; flex: none; color: var(--ink-2); }
.set-phone .set-label { flex: 1; }
.set-phone .textbtn { margin-right: -8px; }
.role-opts { margin-top: 14px; border-block: 1px solid var(--rule); }
.role-opt { display: flex; justify-content: space-between; align-items: center; width: 100%; min-height: 52px; font-size: var(--fs); font-weight: 600; text-align: left; }
.role-opt + .role-opt { border-top: 1px solid var(--rule); }
.role-opt svg { width: 22px; height: 22px; color: var(--primary); }
.set-pick { flex: 1; min-width: 6em; min-height: 44px; text-align: right; text-align-last: right; color: var(--ink-2); -webkit-appearance: none; appearance: none; }
.set-row.plain > svg { flex: none; width: 10px; height: 16px; }
.big .set-row { grid-template-columns: 32px minmax(0, 1fr) auto; }
.big .set-val { grid-column: 2; text-align: left; }
.big .set-row.sw { grid-template-columns: minmax(0, 1fr) auto; }
.navbar strong:focus-visible { outline: none; }
.set-row.plain .set-label { flex: 1 1 10em; }
.set-row.plain > .textbtn { margin-left: auto; }
/* Settings pages: People cared for, Household times, Feed reminders */
.set-in { flex: 1; min-width: 6em; min-height: 44px; text-align: right; color: var(--ink-2); outline: none; }
.set-in:focus { color: var(--ink); }
html:not(.pointer) .set-row.plain:has(> .set-in:focus-visible) { outline: 2.5px solid var(--focus); outline-offset: -2px; }
.set-row.plain > .stepper { margin-left: auto; }
.set-row.plain:is(.hh-row, .has-step) > .set-label { flex: 1 1 5em; }
.cared-hero { text-align: center; padding: 22px 20px 4px; }
.cared-hero .pb { width: 64px; height: 64px; font-size: calc(26 / 17 * var(--fs)); margin: 0 auto; display: grid; }
.cared-hero b { display: block; font-size: calc(20 / 17 * var(--fs)); margin-top: 8px; overflow-wrap: anywhere; }
/* Plan 4a: the terms step and setup's terms, the caring line, the zone note and setup's zone line, the pilot line on
   Welcome, three tabs. As approved in the Plan 4a mockups (mockups/plan-4a, screens A, B and K). */
.terms-box { margin-top: 18px; padding: 14px 16px 4px; border-radius: 15px; background: var(--surface); border: 1px solid var(--rule); }
.terms-box .subhead { padding-top: 0; }
.terms-points { margin: 10px 0 0; padding-left: 20px; display: grid; gap: 8px; font-size: calc(15 / 17 * var(--fs)); line-height: 1.45; font-variant-numeric: tabular-nums; }
.terms-points li::marker { color: var(--ink-2); }
/* Each link is its own 44 pt tap, side by side, wrapping when they don't fit. */
.terms-links { display: flex; flex-wrap: wrap; column-gap: 20px; margin-top: 4px; font-size: calc(15 / 17 * var(--fs)); }
.terms-links a { min-height: 44px; display: inline-flex; align-items: center; color: var(--primary); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* A tick line: the box drawn in the app's look in both themes, not the browser's own. The [type] keeps .setup-form
   input (52 pt tall, padded, rounded) off it. */
.ack { display: flex; gap: 12px; align-items: flex-start; min-height: 44px; padding: 10px 0; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; cursor: pointer; }
.ack input[type="checkbox"] {
  -webkit-appearance: none; appearance: none; flex: none; width: 24px; height: 24px; min-height: 0; margin: -1px 0 0; padding: 0;
  border: 2px solid var(--tick-ring); border-radius: 6px; background: var(--surface); display: grid; place-items: center; cursor: pointer;
}
.ack input[type="checkbox"]:checked { background: var(--primary); border-color: var(--primary); }
.ack input[type="checkbox"]:checked::after { content: ""; width: 11px; height: 6px; margin-top: -3px; border: solid var(--on-primary); border-width: 0 0 2.5px 2.5px; transform: rotate(-45deg); }
.ack + .ack { border-top: 1px solid var(--rule); }
/* Setup's form styles every label in it; the caring and agree lines read as plain text. */
.setup-form .ack { margin-top: 10px; font-weight: 400; }
.setup-form .ack + .ack { margin-top: 0; }
.setup-form .subhead { margin-top: 14px; padding-bottom: 0; }
/* At the accessibility text sizes a text field's default width (about 20 characters) pushed setup's form, and the
   sheets' forms, off the side of the screen; the column and the fields may shrink. */
.setup-form, .inline-form { grid-template-columns: minmax(0, 1fr); }
.setup-form input, .inline-form input { min-width: 0; }
/* Setup says which time zone the family's copy is in (R9), only before setup. */
.zone-line { display: flex; gap: 8px; align-items: center; margin-top: 12px; font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; }
.zone-line svg { width: 18px; height: 18px; flex: none; color: var(--primary); }
/* The pilot line for family members sits on Welcome, with its link as a 44 pt text button. */
.pilot-line .textbtn { display: flex; width: fit-content; margin: -4px 0 0 -8px; }
/* Today's zone note stops at its XL size, like the rest of Today's header (the cap .legend has). */
.zone-note { font-size: min(calc(13 / 17 * var(--fs)), 15px); opacity: .85; margin-top: 4px; }
.tabbar.tabs-3 { grid-template-columns: repeat(3, 1fr); }
/* Times in sentences are tabular too (sheet ledes, rows, the person's line). */
.lede, .set-label, .set-lbl, .person-hero span, .set-lead, .set-foot { font-variant-numeric: tabular-nums; }
/* Plan 4a: banners, roles, sign-in codes, Household's time zone and areas (mockups C to G). */
.banner-owners, .banner-support { background: var(--late-bg); color: var(--ink); }
/* The words sit in a span, so the buttons drop under them when they'd be squeezed (large text); times are tabular. */
.banner { flex-wrap: wrap; font-variant-numeric: tabular-nums; }
.banner > span { flex: 1 1 12em; }
.banner > .btn-sm { flex: none; margin-left: auto; }
/* An owner hides the second-owner banner with the sheet's own close button (44 pt, a 34 pt disc), its disc tinted from
   the ink so it sits on the sand in both themes. It keeps beside People, and drops under the words with it. */
.banner > .icon-btn { margin: -6px -5px -6px -6px; color: var(--ink); }
.banner > .icon-btn span { background: color-mix(in srgb, var(--ink) 9%, transparent); }
.role-opt { gap: 12px; }
.role-opt > span { text-align: left; padding: 8px 0; }
/* The tick keeps its size beside a note that wraps (at the accessibility sizes it was squeezed to a speck). */
.role-opt > svg { flex: none; }
.role-opt .role-note { display: block; font-weight: 400; font-size: calc(13 / 17 * var(--fs)); line-height: 1.35; color: var(--ink-2); margin-top: 2px; }
/* An open sign-in code sits under Get a sign-in code, lined up with its words, with a hairline above. */
.set-code { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; column-gap: 12px; min-height: 44px; padding: 4px 16px 4px 54px;
  box-shadow: inset 54px 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.set-code > span { flex: 1 1 9em; padding: 6px 0; }
.set-code .textbtn { margin-right: -8px; }
/* A role you can't change reads in words, in the same column as the rows around it. */
.set-act.ro { color: var(--ink); font-weight: 400; cursor: default; padding-block: 10px; }
.set-act.ro > svg:first-child { color: var(--ink-2); }
.big .set-act.ro, .big .set-act:has(.set-val) { flex-wrap: wrap; padding-block: 8px; }
/* Household's Time zone is a setting with a value, drawn like the times above it, not a navy action row. */
button.set-row { width: 100%; text-align: left; }
/* Our Care support has its own badge in People, the Settings tile's lifebuoy. */
.av.av-support { background: var(--tile-slate); color: #ffffff; }
.av.av-support svg { width: 60%; height: 60%; }
.person-hero .av.av-support { color: #ffffff; }
.set-row.plain .set-label { text-wrap: pretty; }
/* At large text a row with no value kept an empty line under its label with the chevron alone on it. */
.big .set-val:empty { display: none; }
/* Plan 4a: the Owners group, Notices, Records and Our Care support (mockups F, H, I and J). */
/* Notices' "3 new" reads in ink, so it's seen. */
.set-val.new { color: var(--ink); font-weight: 650; }
.notice { position: relative; }
.notice.unread .set-label { font-weight: 650; }
.notice.unread .set-sub { font-weight: 400; }
/* An unread notice also has a dot in the margin, so it isn't told by weight alone. */
.notice.unread::before { content: ""; position: absolute; left: 7px; top: calc(5px + .65em); width: 8px; height: 8px; border-radius: 50%; background: var(--primary); }
.set-act .set-sub { display: block; font-weight: 400; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); margin-top: 1px; }
a.set-act { text-decoration: none; }
.set-act:has(.set-sub) { padding-block: 8px; }
.btn-danger { color: var(--missed); border-color: var(--missed); }
/* Download everything first is a text button (44 pt), not a bare link that reads like the note around it. */
.dl-first { gap: 6px; margin: 6px 0 2px -8px; }
.dl-first svg { width: 18px; height: 18px; }
/* The label to type stands out from the words around it. */
.inline-form label strong { color: var(--ink); }
/* Support's reason is the thing being decided, so it reads at body size, in its own words. */
.ask-head { display: block; font-weight: 650; }
.ask-reason { display: block; margin-top: 4px; font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; }
/* J3: End now sits 16 px below the support band. Only there: other pads' first buttons keep their own spacing. */
.set-pad.end-now > .btn-quiet { margin-top: 16px; }
/* What it's for and Looks like (Task 26; mockups L3, W1 to W3). Two optional one-line rows after Strength, each with
   a hint. Under a medicine's name, "For pain" is a quiet line in ink at the detail size, so it reads before the muted
   detail, and what it looks like is a second, quieter line (14 pt, muted): on the Care plan row and in a dose's
   details. Today's When needed rows carry "For pain" only; Today's scheduled rows carry neither. */
.field.has-hint { flex-wrap: wrap; row-gap: 0; }
.field.has-hint > input { flex: 1 1 6em; width: 0; }
.field-hint { flex-basis: 100%; margin: -8px 0 12px; font-size: calc(14 / 17 * var(--fs)); line-height: 1.35; color: var(--ink-2); }
.for-line { display: block; font-size: calc(15 / 17 * var(--fs)); line-height: 1.3; color: var(--ink); }
.sheet .for-line { margin-top: 4px; }
.looks-line { display: block; font-size: calc(14 / 17 * var(--fs)); line-height: 1.35; color: var(--ink-2); }
.sheet .looks-line { margin-top: 2px; }
/* A When needed row's limits ("At least 4 hours between doses · no more than 4 a day") in tabular figures, as DESIGN.md
   asks for every count. */
.prn-row .limits { font-variant-numeric: tabular-nums; }

/* ---------- Install help (spec 10): drawn steps that play in a loop ----------
   One stage per platform: the drawing (4 scenes, 3.5 s each, 14 s a loop) with a finger dot that taps the button each
   step names, and the numbered steps underneath, whose number fills while its scene plays. The drawings are SVG
   symbols (public/js/install-art.js); the scenes stay still and only the dot, the scene swap and the step numbers move.
   Reduce Motion: no stage; each step shows its own still frame, with the dot resting on the button. */
.how-switch { margin-top: 18px; }
.how { margin-top: 14px; }
.how-stage { position: relative; border-radius: 16px; background: var(--surface); border: 1px solid var(--rule); overflow: hidden; }
.how-art { display: block; width: 100%; height: auto; aspect-ratio: 300 / 210; }
.how-art text { font-family: var(--font); }
.how-scene, .how-pop { animation: how-scene 14s linear infinite; }
/* scene k shows from (k-1) x 3.5 s: its delay is minus (14 - (k-1) x 3.5) s, so at 0 s scene 1 starts its window */
.how-scene:nth-of-type(1) { animation-delay: -14s; }
.how-scene:nth-of-type(2) { animation-delay: -10.5s; }
.how-scene:nth-of-type(3) { animation-delay: -7s; }
.how-scene:nth-of-type(4) { animation-delay: -3.5s; }
@keyframes how-scene { 0% { opacity: 0; } 1.2%, 24% { opacity: 1; } 25.2%, 100% { opacity: 0; } }
/* A menu that opens inside scene 1 (iPhone 26's ··· menu): from the first tap to the end of the scene. */
.how-pop { animation-name: how-pop; animation-delay: 0s; }
@keyframes how-pop { 0%, 10.5% { opacity: 0; } 11.5%, 24% { opacity: 1; } 25.2%, 100% { opacity: 0; } }
.how-dot .fd { fill: var(--how-finger); }
.how-dot .fr { fill: none; stroke: var(--surface); stroke-width: 2; }
.how-dot.still .fd { fill: none; }
.how-dot.still .fr { stroke: var(--primary); stroke-width: 2.4; }
.h-bz { fill: var(--how-bezel); }
.h-sc { fill: var(--how-screen); }
.h-ui { fill: var(--how-ui); }
.h-pg { fill: var(--how-page); }
.h-pgs { fill: var(--shell); }
.h-pop { fill: var(--how-pop); stroke: var(--rule); stroke-width: 1; }
.h-wall { fill: var(--how-wall); }
.h-app { fill: var(--how-app); }
.h-scrim { fill: var(--how-scrim); }
.h-tgt { fill: var(--band); }
.h-hi { fill: var(--primary); }
.h-on { fill: var(--taken); }
.h-knob { fill: #fff; }
.h-sep { fill: none; stroke: var(--rule); stroke-width: 1; }
.h-ln { fill: none; stroke: var(--how-line); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.h-lnh { fill: none; stroke: var(--primary); stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.h-dot { fill: var(--ink); }
.h-hm { fill: var(--ink); opacity: .55; }
.h-tx { fill: var(--ink); font-size: 10px; font-weight: 600; }
.h-tb { fill: var(--ink); font-size: 9.5px; font-weight: 700; }
.h-tbs { fill: var(--ink); font-size: 8.5px; font-weight: 700; }
.h-tl { fill: var(--ink); font-size: 15px; font-weight: 700; letter-spacing: -0.02em; }
.h-t2 { fill: var(--ink-2); font-size: 8.5px; font-weight: 500; }
.h-t3 { fill: var(--ink-2); font-size: 7px; font-weight: 500; }
.h-th { fill: var(--primary); font-size: 10px; font-weight: 700; }
.h-ton { fill: var(--on-primary); font-size: 9.5px; font-weight: 700; }
.h-tsh { fill: var(--shell-ink); font-size: 9px; font-weight: 700; }
/* the app's own icon, as on the Home Screen (its colours are the icon's, in both themes) */
.oc-bg { fill: #12324a; }
.oc-l { fill: #7fb7c4; }
.oc-r { fill: #3f6378; }
.oc-dot { fill: #ff74b8; }
/* iOS Settings' own coloured squares, drawn as the phone shows them */
.h-ios-red { fill: #ff3b30; } .h-ios-pink { fill: #ff2d55; } .h-ios-ind { fill: #5856d6; }
.h-ios-pur { fill: #af52de; } .h-ios-grn { fill: #34c759; } .h-ios-gry { fill: #8e8e93; } .h-ios-yel { fill: #ffcc00; }
.h-gl { fill: none; stroke: #fff; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }

/* the steps under the stage: the number fills while its scene plays */
.how-steps { margin-top: 6px; }
.how-steps li::before { background: transparent; color: var(--ink-2); border: 1.5px solid var(--tick-ring); animation: how-step 14s linear infinite; }
.how-steps li:nth-child(1)::before { animation-delay: -14s; }
.how-steps li:nth-child(2)::before { animation-delay: -10.5s; }
.how-steps li:nth-child(3)::before { animation-delay: -7s; }
.how-steps li:nth-child(4)::before { animation-delay: -3.5s; }
@keyframes how-step {
  0% { background: transparent; color: var(--ink-2); border-color: var(--tick-ring); }
  1.2%, 24% { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
  25.2%, 100% { background: transparent; color: var(--ink-2); border-color: var(--tick-ring); }
}
.how-steps .how-still { display: none; grid-column: 2; width: 100%; max-width: 260px; height: auto; margin-top: 10px; border-radius: 12px; border: 1px solid var(--rule); background: var(--surface); }
.how-steps li { align-items: start; }
.how-steps li > span { grid-column: 2; }
.how-other { margin-top: 2px; }
@media (prefers-reduced-motion: reduce) {
  .how-stage { display: none; }
  .how-steps .how-still { display: block; }
  .how-steps li::before { animation: none; background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
}
/* Android: Chrome offers its own install (spec 9). One tap, then the menu steps only as a fallback. */
.install-btn { margin-top: 20px; display: flex; align-items: center; justify-content: center; gap: 10px; }
.install-btn svg { width: 22px; height: 22px; }
.or-menu { margin-top: 22px; }
/* Settings, This phone, in the browser: the same steps under the Reminders row, behind a fold (not saved). */
.how-help { padding: 0 20px 14px; box-shadow: inset 20px 0 0 0 var(--surface), inset 0 1px 0 0 var(--rule); }
.how-help .fold-plain { border-block: 0; min-height: 48px; padding: 0; }
.how-help .how-switch { margin-top: 4px; }
.how-help .install-btn { margin-top: 16px; }
.fold-plain { width: 100%; min-height: 48px; display: flex; align-items: center; justify-content: space-between; gap: 10px; border-block: 1px solid var(--rule);
  font-size: var(--fs); font-weight: 600; color: var(--ink); text-align: left; }
.fold-plain svg { width: 12px; height: 18px; color: var(--placeholder); transform: rotate(90deg); }
/* another browser (spec 9): the address to copy, and the one button */
.copy-link { margin-top: 18px; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 8px 12px 16px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--rule); font-variant-numeric: tabular-nums; }
.copy-link span { font-weight: 600; overflow-wrap: anywhere; }

/* ---------- Install help: the finger dot ---------- */
/* The finger dot, per drawing: it comes in from below right, taps the button its step names, and fades before the scene changes. Generated from each scene's tap points (x, y in the drawing's 300 by 210 units). */
.how-dot.d-ios26 { animation: dot-ios26 14s linear infinite; }
@keyframes dot-ios26 {
  0% { transform: translate(256px, 212px) scale(1); opacity: 0; }
  4% { transform: translate(256px, 212px) scale(1); opacity: 1; }
  8.5% { transform: translate(222px, 166px) scale(1); }
  9.7% { transform: translate(222px, 166px) scale(0.76); }
  10.8% { transform: translate(222px, 166px) scale(1); }
  16% { transform: translate(178px, 68px) scale(1); }
  17.5% { transform: translate(178px, 68px) scale(0.76); }
  18.8% { transform: translate(178px, 68px) scale(1); }
  21% { transform: translate(178px, 68px) scale(1); opacity: 1; }
  23.5% { transform: translate(178px, 68px) scale(1); opacity: 0; }
  25% { transform: translate(184px, 173px) scale(1); opacity: 0; }
  29% { transform: translate(184px, 173px) scale(1); opacity: 1; }
  36% { transform: translate(150px, 127px) scale(1); }
  38% { transform: translate(150px, 127px) scale(0.76); }
  40% { transform: translate(150px, 127px) scale(1); }
  46% { transform: translate(150px, 127px) scale(1); opacity: 1; }
  48.5% { transform: translate(150px, 127px) scale(1); opacity: 0; }
  50% { transform: translate(253px, 83px) scale(1); opacity: 0; }
  54% { transform: translate(253px, 83px) scale(1); opacity: 1; }
  61% { transform: translate(219px, 37px) scale(1); }
  63% { transform: translate(219px, 37px) scale(0.76); }
  65% { transform: translate(219px, 37px) scale(1); }
  71% { transform: translate(219px, 37px) scale(1); opacity: 1; }
  73.5% { transform: translate(219px, 37px) scale(1); opacity: 0; }
  75% { transform: translate(206px, 122px) scale(1); opacity: 0; }
  79% { transform: translate(206px, 122px) scale(1); opacity: 1; }
  86% { transform: translate(172px, 76px) scale(1); }
  88% { transform: translate(172px, 76px) scale(0.76); }
  90% { transform: translate(172px, 76px) scale(1); }
  96% { transform: translate(172px, 76px) scale(1); opacity: 1; }
  98.5% { transform: translate(172px, 76px) scale(1); opacity: 0; }
  100% { transform: translate(256px, 212px) scale(1); opacity: 0; }
}
.how-dot.d-ios18 { animation: dot-ios18 14s linear infinite; }
@keyframes dot-ios18 {
  0% { transform: translate(184px, 220px) scale(1); opacity: 0; }
  4% { transform: translate(184px, 220px) scale(1); opacity: 1; }
  11% { transform: translate(150px, 174px) scale(1); }
  13% { transform: translate(150px, 174px) scale(0.76); }
  15% { transform: translate(150px, 174px) scale(1); }
  21% { transform: translate(150px, 174px) scale(1); opacity: 1; }
  23.5% { transform: translate(150px, 174px) scale(1); opacity: 0; }
  25% { transform: translate(184px, 173px) scale(1); opacity: 0; }
  29% { transform: translate(184px, 173px) scale(1); opacity: 1; }
  36% { transform: translate(150px, 127px) scale(1); }
  38% { transform: translate(150px, 127px) scale(0.76); }
  40% { transform: translate(150px, 127px) scale(1); }
  46% { transform: translate(150px, 127px) scale(1); opacity: 1; }
  48.5% { transform: translate(150px, 127px) scale(1); opacity: 0; }
  50% { transform: translate(253px, 83px) scale(1); opacity: 0; }
  54% { transform: translate(253px, 83px) scale(1); opacity: 1; }
  61% { transform: translate(219px, 37px) scale(1); }
  63% { transform: translate(219px, 37px) scale(0.76); }
  65% { transform: translate(219px, 37px) scale(1); }
  71% { transform: translate(219px, 37px) scale(1); opacity: 1; }
  73.5% { transform: translate(219px, 37px) scale(1); opacity: 0; }
  75% { transform: translate(206px, 122px) scale(1); opacity: 0; }
  79% { transform: translate(206px, 122px) scale(1); opacity: 1; }
  86% { transform: translate(172px, 76px) scale(1); }
  88% { transform: translate(172px, 76px) scale(0.76); }
  90% { transform: translate(172px, 76px) scale(1); }
  96% { transform: translate(172px, 76px) scale(1); opacity: 1; }
  98.5% { transform: translate(172px, 76px) scale(1); opacity: 0; }
  100% { transform: translate(184px, 220px) scale(1); opacity: 0; }
}
.how-dot.d-android { animation: dot-android 14s linear infinite; }
@keyframes dot-android {
  0% { transform: translate(260px, 94px) scale(1); opacity: 0; }
  4% { transform: translate(260px, 94px) scale(1); opacity: 1; }
  11% { transform: translate(226px, 48px) scale(1); }
  13% { transform: translate(226px, 48px) scale(0.76); }
  15% { transform: translate(226px, 48px) scale(1); }
  21% { transform: translate(226px, 48px) scale(1); opacity: 1; }
  23.5% { transform: translate(226px, 48px) scale(1); opacity: 0; }
  25% { transform: translate(206px, 201px) scale(1); opacity: 0; }
  29% { transform: translate(206px, 201px) scale(1); opacity: 1; }
  36% { transform: translate(172px, 155px) scale(1); }
  38% { transform: translate(172px, 155px) scale(0.76); }
  40% { transform: translate(172px, 155px) scale(1); }
  46% { transform: translate(172px, 155px) scale(1); opacity: 1; }
  48.5% { transform: translate(172px, 155px) scale(1); opacity: 0; }
  50% { transform: translate(230px, 209px) scale(1); opacity: 0; }
  54% { transform: translate(230px, 209px) scale(1); opacity: 1; }
  61% { transform: translate(196px, 163px) scale(1); }
  63% { transform: translate(196px, 163px) scale(0.76); }
  65% { transform: translate(196px, 163px) scale(1); }
  71% { transform: translate(196px, 163px) scale(1); opacity: 1; }
  73.5% { transform: translate(196px, 163px) scale(1); opacity: 0; }
  75% { transform: translate(204px, 168px) scale(1); opacity: 0; }
  79% { transform: translate(204px, 168px) scale(1); opacity: 1; }
  86% { transform: translate(170px, 122px) scale(1); }
  88% { transform: translate(170px, 122px) scale(0.76); }
  90% { transform: translate(170px, 122px) scale(1); }
  96% { transform: translate(170px, 122px) scale(1); opacity: 1; }
  98.5% { transform: translate(170px, 122px) scale(1); opacity: 0; }
  100% { transform: translate(260px, 94px) scale(1); opacity: 0; }
}
.how-dot.d-ionote { animation: dot-ionote 14s linear infinite; }
@keyframes dot-ionote {
  0% { transform: translate(250px, 74px) scale(1); opacity: 0; }
  4% { transform: translate(250px, 74px) scale(1); opacity: 1; }
  11% { transform: translate(216px, 28px) scale(1); }
  13% { transform: translate(216px, 28px) scale(0.76); }
  15% { transform: translate(216px, 28px) scale(1); }
  21% { transform: translate(216px, 28px) scale(1); opacity: 1; }
  23.5% { transform: translate(216px, 28px) scale(1); opacity: 0; }
  25% { transform: translate(174px, 103px) scale(1); opacity: 0; }
  29% { transform: translate(174px, 103px) scale(1); opacity: 1; }
  36% { transform: translate(140px, 57px) scale(1); }
  38% { transform: translate(140px, 57px) scale(0.76); }
  40% { transform: translate(140px, 57px) scale(1); }
  46% { transform: translate(140px, 57px) scale(1); opacity: 1; }
  48.5% { transform: translate(140px, 57px) scale(1); opacity: 0; }
  50% { transform: translate(174px, 155px) scale(1); opacity: 0; }
  54% { transform: translate(174px, 155px) scale(1); opacity: 1; }
  61% { transform: translate(140px, 109px) scale(1); }
  63% { transform: translate(140px, 109px) scale(0.76); }
  65% { transform: translate(140px, 109px) scale(1); }
  71% { transform: translate(140px, 109px) scale(1); opacity: 1; }
  73.5% { transform: translate(140px, 109px) scale(1); opacity: 0; }
  75% { transform: translate(244px, 120px) scale(1); opacity: 0; }
  79% { transform: translate(244px, 120px) scale(1); opacity: 1; }
  86% { transform: translate(210px, 74px) scale(1); }
  88% { transform: translate(210px, 74px) scale(0.76); }
  90% { transform: translate(210px, 74px) scale(1); }
  96% { transform: translate(210px, 74px) scale(1); opacity: 1; }
  98.5% { transform: translate(210px, 74px) scale(1); opacity: 0; }
  100% { transform: translate(250px, 74px) scale(1); opacity: 0; }
}
.how-dot.d-anote { animation: dot-anote 14s linear infinite; }
@keyframes dot-anote {
  0% { transform: translate(174px, 194px) scale(1); opacity: 0; }
  4% { transform: translate(174px, 194px) scale(1); opacity: 1; }
  11% { transform: translate(140px, 148px) scale(1); }
  13% { transform: translate(140px, 148px) scale(0.76); }
  15% { transform: translate(140px, 148px) scale(1); }
  21% { transform: translate(140px, 148px) scale(1); opacity: 1; }
  23.5% { transform: translate(140px, 148px) scale(1); opacity: 0; }
  25% { transform: translate(174px, 158px) scale(1); opacity: 0; }
  29% { transform: translate(174px, 158px) scale(1); opacity: 1; }
  36% { transform: translate(140px, 112px) scale(1); }
  38% { transform: translate(140px, 112px) scale(0.76); }
  40% { transform: translate(140px, 112px) scale(1); }
  46% { transform: translate(140px, 112px) scale(1); opacity: 1; }
  48.5% { transform: translate(140px, 112px) scale(1); opacity: 0; }
  50% { transform: translate(174px, 220px) scale(1); opacity: 0; }
  54% { transform: translate(174px, 220px) scale(1); opacity: 1; }
  61% { transform: translate(140px, 174px) scale(1); }
  63% { transform: translate(140px, 174px) scale(0.76); }
  65% { transform: translate(140px, 174px) scale(1); }
  71% { transform: translate(140px, 174px) scale(1); opacity: 1; }
  73.5% { transform: translate(140px, 174px) scale(1); opacity: 0; }
  75% { transform: translate(244px, 148px) scale(1); opacity: 0; }
  79% { transform: translate(244px, 148px) scale(1); opacity: 1; }
  86% { transform: translate(210px, 102px) scale(1); }
  88% { transform: translate(210px, 102px) scale(0.76); }
  90% { transform: translate(210px, 102px) scale(1); }
  96% { transform: translate(210px, 102px) scale(1); opacity: 1; }
  98.5% { transform: translate(210px, 102px) scale(1); opacity: 0; }
  100% { transform: translate(174px, 194px) scale(1); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .how-dot { animation: none; } }

/* The install drawings' sprite: out of sight, but not display: none (its clip paths must still work). */
.how-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.fold-plain[aria-expanded="true"] svg { transform: rotate(-90deg); }

/* ---------- Joining, by who's joining (Plan 4b, mockups B3 to B8) ---------- */
.hello { padding: 18px 20px 22px; }
/* the badge grows with text size up to the header's XL cap, as Today's header does */
.hello .pb.pb-xl, .hello .av { width: min(calc(56 / 17 * var(--fs)), 72px); height: min(calc(56 / 17 * var(--fs)), 72px); font-size: min(calc(24 / 17 * var(--fs)), 31px); }
.hello .pb.pb-xl.emoji { font-size: min(calc(30 / 17 * var(--fs)), 38px); }
.hello h1 { margin-top: 14px; font-size: calc(32 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.025em; line-height: 1.1; text-wrap: balance; }
.hello p { margin-top: 6px; color: var(--shell-ink-2); font-size: calc(15 / 17 * var(--fs)); line-height: 1.4; max-width: 34ch; }
.hello .av { background: var(--shell-rule); color: var(--shell-ink); }
.ob-step { font-size: calc(13 / 17 * var(--fs)); font-weight: 600; color: var(--shell-ink-2); font-variant-numeric: tabular-nums; }
.ob-h { margin: 22px 20px 0; font-size: calc(20 / 17 * var(--fs)); font-weight: 700; letter-spacing: -0.015em; }
.ob-points { list-style: none; margin: 10px 20px 0; border-top: 1px solid var(--rule); }
.ob-points li { display: grid; grid-template-columns: 26px minmax(0, 1fr); gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--rule); line-height: 1.45; }
.ob-points svg { width: 22px; height: 22px; color: var(--primary); margin-top: 1px; }
.ob-points b { font-weight: 650; }
.ob-privacy { margin: 14px 20px 0; padding: 12px 14px; border-radius: 12px; background: var(--band); font-size: calc(15 / 17 * var(--fs)); line-height: 1.45; }
.ob-privacy b { font-weight: 650; }
.ob-acts { padding: 22px 20px 0; }
.ob-acts .textbtn { display: flex; margin: 6px auto 0; }
/* their reminders today, as the times they'll come */
.ob-times { margin: 10px 20px 0; border-block: 1px solid var(--rule); }
.ob-times div { display: grid; grid-template-columns: calc(70 / 17 * var(--fs)) minmax(0, 1fr); gap: 12px; padding: 11px 0; font-variant-numeric: tabular-nums; }
.ob-times div + div { border-top: 1px solid var(--rule); }
.ob-times .t { font-weight: 600; font-size: calc(17 / 17 * var(--fs)); }
.ob-times .t small { font-size: calc(13 / 17 * var(--fs)); font-weight: 500; color: var(--ink-2); margin-left: 1px; }
.ob-times .t span { display: block; font-size: calc(13 / 17 * var(--fs)); font-weight: 600; color: var(--ink-2); }
.ob-times .w { line-height: 1.4; }
.ob-times .w small { display: block; color: var(--ink-2); font-size: calc(14 / 17 * var(--fs)); }
/* the admin's checklist: ordinary Settings rows, with a done mark or the next step */
.ob-check .set-val.c-taken { font-weight: 600; }
/* How ticking works: one real row that ticks itself every 5 s, then the toast it raises. Reduce Motion: drawn ticked. */
.ob-demo { position: relative; margin: 12px 20px 0; padding: 0 0 66px; }
.ob-demo .row { background: var(--surface); border-block: 1px solid var(--rule); padding-inline: 14px; margin-inline: -20px; padding-left: 20px; padding-right: 20px; }
.ob-demo .tick { animation: ob-tick 5s cubic-bezier(.16, 1, .3, 1) infinite; }
.ob-demo .tick path { stroke-dasharray: 22; stroke-dashoffset: 22; animation: ob-check 5s cubic-bezier(.16, 1, .3, 1) infinite; }
.ob-demo .toast { position: absolute; left: 0; right: 0; bottom: 0; animation: ob-toast 5s cubic-bezier(.16, 1, .3, 1) infinite; }
@keyframes ob-tick { 0%, 22% { transform: none; background: transparent; border-color: var(--primary); } 26% { transform: scale(.92); } 30%, 88% { transform: none; background: var(--taken-soft); border-color: var(--taken); } 94%, 100% { background: transparent; border-color: var(--primary); } }
@keyframes ob-check { 0%, 26% { stroke-dashoffset: 22; stroke: var(--taken); } 36%, 88% { stroke-dashoffset: 0; stroke: var(--taken); } 94%, 100% { stroke-dashoffset: 22; } }
@keyframes ob-toast { 0%, 30% { opacity: 0; transform: translateY(14px); } 36%, 86% { opacity: 1; transform: none; } 92%, 100% { opacity: 0; transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) {
  .ob-demo * { animation: none !important; }
  .ob-demo .tick { background: var(--taken-soft); border-color: var(--taken); }
  .ob-demo .tick path { stroke-dashoffset: 0; stroke: var(--taken); }
  .ob-demo .toast { opacity: 1; transform: none; }
}
/* The reminders step: a live preview of how a reminder reads, following the switch (spec 11.3) */
.preview { margin: 14px 20px 0; padding: 14px 14px 16px; border-radius: 22px; background: linear-gradient(170deg, #6f9fb1, #2f5d75 70%); }
.preview .ln { display: grid; grid-template-columns: 38px minmax(0, 1fr); gap: 10px; align-items: start; padding: 12px 14px 13px 12px; border-radius: 22px; font: 400 15px/1.3 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; }
.preview .ln .appicon { width: 38px; height: 38px; border-radius: 9px; display: block; }
.preview .ln .top { display: flex; justify-content: space-between; gap: 8px; }
.preview .ln .top b { font-weight: 600; min-width: 0; }
.preview .ln .top time { flex: none; font-size: 13px; opacity: .55; }
.preview .an { padding: 14px 16px 15px; border-radius: 24px; font: 400 14px/1.35 system-ui, sans-serif; }
.preview .an .hdr { display: flex; align-items: center; gap: 7px; font-size: 12px; opacity: .7; }
.preview .an .hdr .appicon { width: 18px; height: 18px; border-radius: 50%; }
.preview .an b { display: block; margin-top: 6px; font-weight: 500; font-size: 15px; }
.preview .ln, .preview .an { box-shadow: 0 8px 18px -12px rgba(0, 0, 0, .45); }
.preview .ln { background: rgba(246, 247, 248, .9); color: #111; }
.preview .an { background: rgba(244, 245, 248, .95); color: #1b1c1f; }
.preview-cap { margin: 8px 20px 0; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; }
@media (prefers-color-scheme: dark) {
  .preview { background: linear-gradient(170deg, #1d3a4c, #0f2433 70%); }
  .preview .ln { background: rgba(40, 42, 46, .86); color: #f2f2f2; }
  .preview .an { background: rgba(30, 32, 37, .95); color: #e6e7ea; }
}

/* ---------- The Carer role: the invite sheet's people and choices (mockup B2) ---------- */
.scope { margin-top: 6px; border-top: 1px solid var(--rule); }
.scope .ack { align-items: center; padding: 8px 0; border-bottom: 1px solid var(--rule); }
.scope .ack + .ack { border-top: 0; }
.scope .ack .pb { width: calc(30 / 17 * var(--fs)); height: calc(30 / 17 * var(--fs)); }
.scope .ack .pb.emoji, .set-row .pb.emoji, .helps .pb.emoji { font-size: calc(17 / 17 * var(--fs)); }
.scope .ack b { font-weight: 600; font-size: var(--fs); }
.scope .ack small { display: block; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); }
.sw-list { margin-top: 6px; border-block: 1px solid var(--rule); }
.sw-list .sw-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 52px; padding: 8px 0; }
.sw-list .sw-row + .sw-row { border-top: 1px solid var(--rule); }
.sw-list small { display: block; font-size: calc(13 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.35; }
.helps { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 8px; }
.helps .pb { width: 26px; height: 26px; }

/* ---------- Badges (spec 13) ---------- */
/* An emoji sits in the same tinted circle as the initial; the phone draws it from its own emoji font. */
.pb.emoji { font-size: calc(13 / 17 * var(--fs)); font-weight: 400; }
.pb.pb-lg.emoji { font-size: calc(22 / 17 * var(--fs)); }
.pb.pb-xl { width: min(calc(64 / 17 * var(--fs)), 84px); height: min(calc(64 / 17 * var(--fs)), 84px); font-size: min(calc(26 / 17 * var(--fs)), 34px); }
.pb.pb-xl.emoji { font-size: min(calc(34 / 17 * var(--fs)), 44px); }
.pbe { font-size: 12px; font-weight: 400; } /* in the station rows' SVG badge, like .pbl's 11px initials */
.cared-hero .pb.pb-xl { margin: 0 auto; }
.badge-prev { display: flex; align-items: center; gap: 14px; margin-top: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--rule); }
.badge-prev b { font-size: calc(20 / 17 * var(--fs)); }
.badge-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(44px, 1fr)); gap: 6px 4px; margin-top: 4px; }
.badge-grid button { position: relative; height: 48px; border-radius: 50%; display: grid; place-items: center; }
.badge-grid .pb { width: 40px; height: 40px; font-size: calc(21 / 17 * var(--fs)); }
.badge-grid .pb:not(.emoji) { font-size: calc(16 / 17 * var(--fs)); font-weight: 700; }
.badge-grid [aria-checked="true"]::after, .tint-pick [aria-checked="true"]::after { content: ""; position: absolute; inset: 0; margin: auto; width: 48px; height: 48px; border-radius: 50%; box-shadow: inset 0 0 0 2.5px var(--primary); }
.tint-pick { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; max-width: 228px; }
.tint-pick button { position: relative; width: 48px; height: 48px; display: grid; place-items: center; }
.tint-pick .sw { width: 38px; height: 38px; border-radius: 50%; background: var(--pb-bg); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06); }
.sheet .field-label + .badge-grid { margin-top: 2px; }
.set-row .pb { width: 30px; height: 30px; }

.cared-hero .pb.emoji { font-size: calc(34 / 17 * var(--fs)); font-weight: 400; }
.set-person .pb.pb-lg.emoji { font-size: calc(22 / 17 * var(--fs)); }

/* ---------- The missed-dose alert (spec 12) ---------- */
/* Under a late group on Today: who was told, and I'm checking. Once someone is checking, their name and time. */
.check-strip { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; margin-top: 2px;
  padding: 10px 0 2px; border-top: 1px dashed var(--rule); font-size: calc(14 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; font-variant-numeric: tabular-nums; }
.check-strip > span { flex: 1 1 12em; display: flex; gap: 8px; align-items: flex-start; }
.check-strip > span svg { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--late); }
.check-strip b { color: var(--ink); font-weight: 650; }
.check-strip.checking > span svg { color: var(--primary); }
.btn-check { min-height: 44px; padding: 0 16px 0 12px; border-radius: 999px; border: 1.5px solid var(--primary); color: var(--primary); font-size: calc(15 / 17 * var(--fs)); font-weight: 650;
  display: inline-flex; align-items: center; gap: 7px; margin-left: auto; }
.btn-check svg { width: 18px; height: 18px; }
/* the dose sheet: the same line under the state words, and I'm checking as a quiet button */
.sheet .check-line { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; font-size: calc(15 / 17 * var(--fs)); color: var(--ink-2); line-height: 1.4; font-variant-numeric: tabular-nums; }
.sheet .check-line svg { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--late); }
.sheet .check-line.checking svg { color: var(--primary); }
.sheet .check-line b { color: var(--ink); font-weight: 650; }
.btn-quiet.with-ico { display: flex; align-items: center; justify-content: center; gap: 8px; }
.btn-quiet.with-ico svg { width: 20px; height: 20px; color: var(--primary); }

/* ---------- My reminders (spec 11.3, 12.1, 20.4) ---------- */
.set-row.seg-row { display: block; padding: 12px 16px 14px 20px; }
.set-row.seg-row .set-label { display: block; margin-bottom: 10px; }
.set-row.seg-row .seg { width: 100%; }

/* Must be on time: the dose sheet's line (I3) */
.sheet .check-line.ontime svg { color: var(--primary); }
