/* ===================== OpLog — design system ===================== */
:root {
  --bg: #f4f6f9;
  --surface: #ffffff;
  --surface-2: #fbfcfe;
  --ink: #0f1722;
  --ink-2: #5a6675;
  --ink-3: #8a94a3;
  --line: #e8ebf0;
  --line-2: #f0f2f5;
  --accent: #3667f0;
  --accent-ink: #ffffff;
  --accent-soft: #eef3ff;
  --ok: #12a67c; --ok-soft: #e7f7f1;
  --warn: #c77a17; --warn-soft: #fdf3e3;
  --info: #2f6bff; --info-soft: #e9f0ff;
  --danger: #e0484d;
  --r: 18px; --r-md: 13px; --r-sm: 10px; --pill: 999px;
  --sh-sm: 0 1px 2px rgba(15,23,34,.05);
  --sh: 0 1px 2px rgba(15,23,34,.04), 0 6px 16px rgba(15,23,34,.05);
  --sh-lg: 0 10px 40px rgba(15,23,34,.16);
  --nav-h: 62px;
  font-synthesis: none;
}
* { box-sizing: border-box; }
/* Rotating an iPhone makes Safari re-run its text autosizer and inflate every font in a
   block it decides got wider — the page never zooms, the type just grows and stays grown.
   Pinning the adjustment is the only fix; the viewport meta has no say in it. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--ink);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 8px);
}
/* The two FABs are fixed above the nav bar and occupy ~142px of the bottom-right. Page padding only
   cleared the nav, so whatever sat at the end of a scrolled list ended up underneath them — on
   Techniques that was the "Import from Evernote…" button, half-covered by the mic. Reserve the
   space, but only on the views that actually show the FABs, so Attendings and Progress don't carry
   a strip of empty page for no reason. */
body.has-fabs { padding-bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 150px); }
.muted { color: var(--ink-2); }
.small { font-size: 12.5px; }
b { font-weight: 650; }

/* ===================== app bar ===================== */
.appbar {
  position: sticky; top: 0; z-index: 30;
  background: rgba(244,246,249,.82); backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
  padding: max(14px, env(safe-area-inset-top)) 16px 12px;
}
.appbar h1 { margin: 0; font-size: 21px; font-weight: 750; letter-spacing: -.02em; }
.appbar h1 span { color: var(--accent); }
#stats { color: var(--ink-2); font-size: 12.5px; margin-top: 3px; }
#stats b { color: var(--ink); }
.appbar { --gear-right: 12px; }
.gear { position: absolute; top: max(14px, calc(env(safe-area-inset-top) + 0px)); right: var(--gear-right);
  background: none; border: none; color: var(--ink-3); cursor: pointer; line-height: 0;
  display: inline-flex; align-items: center; justify-content: center; padding: 5px; border-radius: 10px; }
.gear svg { width: 21px; height: 21px; }
.gear:hover { color: var(--ink); background: var(--line-2); }
#helpBtn { right: calc(var(--gear-right) + 37px); }  /* tracks the gear at every breakpoint */
#bugBtn  { right: calc(var(--gear-right) + 74px); }  /* pilot only — remove with FEATURE_BUGBTN */
#adminBtn { right: calc(var(--gear-right) + 111px); }  /* admins only; hidden otherwise */

/* Password show/hide toggle (injected by addPasswordToggles) */
.pw-wrap { position: relative; display: block; width: 100%; }
/* The input was a grid/flex child before it got wrapped, so it no longer stretches on its own. */
.pw-wrap > input { width: 100%; padding-right: 46px !important; }
.pw-eye { position: absolute; right: 5px; top: 50%; transform: translateY(-50%); line-height: 0;
  background: none; border: none; padding: 8px; border-radius: 9px; cursor: pointer; color: var(--ink-3);
  display: inline-flex; align-items: center; justify-content: center; }
.pw-eye:hover { color: var(--ink); background: var(--line-2); }
.pw-eye:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.pw-eye svg { width: 19px; height: 19px; }

.searchwrap { margin-top: 12px; }
#search {
  width: 100%; padding: 11px 14px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); font-size: 15px; color: var(--ink);
}
#search::placeholder { color: var(--ink-3); }
#search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* filters */
/* One row of chrome at every width:  [Filters ▾] ................ [Import ▾] [ACGME]
   Five always-visible dropdowns ate a whole row and were mostly unused, and any wrapping layout
   eventually strands the action buttons on a line of their own beside a band of dead space.
   Collapsing the filters behind a single button with an active-count badge avoids both. */
.filterbar { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 9px; align-items: center; }
.fgroup { display: none; flex-wrap: wrap; gap: 7px; align-items: center; order: 3; flex: 1 0 100%; margin-top: 3px; }
.filterbar.f-open .fgroup { display: flex; }
.filterbar .fbar-actions { margin-left: auto; flex: 0 0 auto; }
.ftoggle {
  flex: 0 0 auto; font-weight: 600;
  border: 1px solid var(--line);
  background: var(--surface); color: var(--ink); cursor: pointer;
}
.ftoggle:hover { border-color: var(--accent); color: var(--accent); }
.ftoggle[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.ftoggle .fcount {
  background: var(--accent); color: #fff; border-radius: var(--pill);
  padding: 0 6px; font-size: 11px; font-weight: 700; line-height: 17px; min-width: 17px; text-align: center;
}
.fsel { padding: 7px 8px; border: 1px solid var(--line); border-radius: var(--pill); background: var(--surface);
  font-size: 12.5px; color: var(--ink); appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-3) 50%), linear-gradient(135deg, var(--ink-3) 50%, transparent 50%);
  background-position: right 10px top 14px, right 6px top 14px; background-size: 4px 4px, 4px 4px; background-repeat: no-repeat; padding-right: 22px; }
.fsel:focus { outline: none; border-color: var(--accent); }
/* Every control in this bar shares one vertical metric — same padding-block, font-size and
   line-height — so their boxes line up. The primary action earns prominence from colour and
   weight plus wider horizontal padding, never from being a different height. */
.fclear, .fexport, .btn.fimport, .ftoggle {
  padding: 7px 14px; font-size: 12.5px; line-height: 18px; border-radius: var(--pill);
  height: 34px; display: inline-flex; align-items: center; gap: 6px;
}
.btn.fexport { background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 640; padding: 7px 18px; }
.btn.fexport:hover { background: #2a55d4; border-color: #2a55d4; }

/* ===================== nav: top tabs (desktop) + bottom bar (mobile) ===================== */
/* Segmented control — light track, white active pill (iOS-style). */
.topnav { display: none; gap: 2px; margin-top: 14px; padding: 3px;
  background: #eaedf2; border-radius: 11px; }
.ttab { flex: 1; padding: 8px 12px; border: none; background: transparent;
  border-radius: 8px; font-size: 13.5px; font-weight: 640; color: var(--ink-2); cursor: pointer;
  transition: background .14s, color .14s, box-shadow .14s; }
.ttab:hover { color: var(--ink); }
.ttab.active { background: var(--surface); color: var(--ink); box-shadow: var(--sh-sm); }

.bottomnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: flex; justify-content: center; gap: 2px;
  background: rgba(255,255,255,.92); backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-top: 1px solid var(--line);
  padding: 7px 8px calc(7px + env(safe-area-inset-bottom));
}
.navbtn {
  flex: 1; max-width: 130px; background: none; border: none; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 3px 2px; color: var(--ink-3); font-size: 11px; font-weight: 620; border-radius: 12px;
}
.navbtn svg { width: 23px; height: 23px; }
.navbtn.active { color: var(--accent); }
.navbtn:active { background: var(--line-2); }

/* desktop: top tabs, no bottom bar, everything aligned to the 720px content column */
@media (min-width: 720px) {
  .topnav { display: flex; }
  .bottomnav { display: none; }
  body { padding-bottom: 28px; }
  .fab { bottom: 24px; }
  .fab-mic { bottom: 92px; }
  .appbar { padding-left: 24px; padding-right: 24px; }
  .appbar > h1, .appbar > #stats, .appbar > .topnav, .appbar > .searchwrap, .appbar > .filterbar {
    max-width: 692px; margin-left: auto; margin-right: auto; width: 100%; }
  .appbar { --gear-right: max(24px, calc(50% - 346px)); }  /* both header buttons follow this */
  /* Import + ACGME travel as ONE unit, so a narrow row can never strand one of them. */
  .filterbar .fbar-actions { margin-left: auto; flex: 0 0 auto; }
}

/* ===================== lists / cards ===================== */
main { max-width: 720px; margin: 0 auto; padding: 14px 14px 0; }
.group { margin-bottom: 6px; }
.group-title { font-size: 12px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3);
  margin: 18px 6px 10px; font-weight: 650; }
.group-title span { background: var(--line); color: var(--ink-2); border-radius: var(--pill); padding: 1px 8px; font-size: 11px; margin-left: 5px; }

.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--sh-sm); padding: 14px 16px; margin-bottom: 11px; cursor: pointer;
  transition: transform .08s ease, box-shadow .18s ease, border-color .18s ease;
}
.card:hover { box-shadow: var(--sh); }
/* Confirmed but not yet in ACGME — a subtle blue tint + accent edge marks what's queued to sync. */
.card-queued { background: #f3f7ff; border-color: #d3e1ff; box-shadow: inset 3px 0 0 var(--accent), var(--sh-sm); }
@media (prefers-color-scheme: dark) { .card-queued { background: rgba(54,103,240,.10); border-color: rgba(54,103,240,.35); } }
.card:active { transform: scale(.992); }
.card-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.proc { font-weight: 680; font-size: 16.5px; letter-spacing: -.01em; }
.date { color: var(--ink-3); font-size: 13px; white-space: nowrap; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.meta { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 9px; color: var(--ink-2); font-size: 12.5px; }
.pearls { margin-top: 10px; font-size: 13.5px; color: #43506a; background: var(--surface-2);
  border: 1px solid var(--line-2); padding: 8px 11px; border-radius: var(--r-md); }
.tview-cases { display: flex; align-items: baseline; gap: 7px; width: 100%; margin-bottom: 14px;
  padding: 9px 12px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2);
  font: inherit; font-size: 13px; color: var(--ink-2); cursor: pointer; text-align: left;
  transition: border-color .12s, background .12s; }
.tview-cases:hover { border-color: var(--accent); background: var(--accent-soft); }
.tview-cases b { color: var(--ink); font-weight: 650; }
.tview-cases-go { margin-left: auto; color: var(--accent); font-weight: 600; flex: none; }
/* An inline icon inside a button label — sized to the text, not to a FAB. */
.btn-ico { width: 1.05em; height: 1.05em; vertical-align: -0.16em; margin-right: 2px; }

/* ---- CSV import: busy state and the "what now" panel ---- */
.imp-busy { display: flex; gap: 13px; align-items: center; padding: 8px 0 4px; }
.spinner { width: 22px; height: 22px; flex: none; border-radius: 50%;
  border: 2.5px solid var(--line); border-top-color: var(--accent); animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.impdone-hero { text-align: center; padding: 10px 0 4px; }
.impdone-n { font-size: 40px; font-weight: 700; line-height: 1.1; color: var(--accent);
  font-variant-numeric: tabular-nums; }
.impdone-grid { display: flex; gap: 8px; flex-wrap: wrap; }
.impdone-row { flex: 1 1 96px; display: flex; flex-direction: column; gap: 1px; align-items: center;
  padding: 10px 8px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2); }
.impdone-row span { font-size: 12px; color: var(--ink-2); }
.impdone-row b { font-size: 19px; font-variant-numeric: tabular-nums; }
/* Attendings: program-roster state + inline add */
/* Informational, not a warning — importing the roster is worth doing, not a problem to fix. Amber
   here read as something being broken. */
.att-roster { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  margin: 0 0 12px; padding: 9px 12px; border-radius: var(--r-md);
  border: 1px solid var(--line); background: var(--surface-2); color: var(--ink-2);
  font-size: 12.5px; line-height: 1.5; }
.att-roster span { flex: 1; min-width: 0; }
.linkbtn { background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  font-weight: 600; color: var(--accent); flex: none; }
.linkbtn:hover { text-decoration: underline; }
.att-addrow { display: flex; gap: 8px; margin-bottom: 12px; }
.att-addrow input { flex: 1; min-width: 0; padding: 9px 11px; border: 1px solid var(--accent);
  border-radius: var(--r-sm); font: inherit; }
.att-addrow input:focus { outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

.bl-paste { border: 1px solid var(--accent-soft); background: var(--accent-soft);
  border-radius: var(--r-md); padding: 12px; margin-bottom: 14px; }
.bl-paste textarea { width: 100%; margin-top: 8px; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: var(--r-sm); font: inherit; font-size: 13px; resize: vertical; background: var(--surface); }
.bl-paste textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(54,103,240,.14); }
.bl-paste .muted { margin-top: 6px; }

.rec-actions { display: flex; gap: 8px; margin-bottom: 4px; }
.rec-actions .btn { flex: 1; }

/* First-visit tab intro — inline and dismissible, never a modal. */
.tabintro { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px;
  padding: 13px 14px; border: 1px solid var(--accent-soft); border-radius: var(--r-md);
  background: var(--accent-soft); }
.tabintro-body { flex: 1; min-width: 0; font-size: 13px; line-height: 1.55; color: #33405c; }
/* Only the TITLE is a block. Scoping this to `b` alone made every inline <b> in the body break onto
   its own line — the same defect as .cleanrow-t b, where "other" rendered as its own paragraph. */
.tabintro-body > b:first-child { display: block; margin-bottom: 3px; color: var(--ink); font-size: 14px; }
.tabintro-x { flex: none; background: none; border: none; cursor: pointer; color: var(--ink-3);
  font-size: 14px; line-height: 1; padding: 3px 5px; border-radius: 7px; }
.tabintro-x:hover { background: rgba(15,23,34,.07); color: var(--ink); }
.impdone-defs { display: flex; gap: 8px; flex-wrap: wrap; }
.impdone-def { flex: 1 1 140px; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.impdone-def span { font-size: 12px; color: var(--ink-2); }
.impdone-def select { padding: 9px 10px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); font: inherit; min-width: 0; }
.impdone-saved { font-weight: 600; color: var(--ok); font-size: 12px; margin-left: 6px; }
.impdone-next { display: flex; gap: 8px; flex-wrap: wrap; }
.impdone-next .btn { flex: 1 1 auto; }
.match-why { margin-top: 9px; font-size: 12.5px; color: var(--ink-2); }
.match-why span { color: var(--ink); }
.badges { margin-top: 11px; display: flex; gap: 6px; align-items: center; }
.card-del { margin-left: auto; background: none; border: none; cursor: pointer; color: var(--ink-3);
  padding: 5px 6px; border-radius: 8px; line-height: 0; display: inline-flex; transition: color .12s, background .12s; }
.card-del svg { width: 17px; height: 17px; }
.card-del:hover { color: var(--danger); background: #fdf0f0; }

/* undo snackbar */
.snackbar { position: fixed; left: 50%; transform: translateX(-50%) translateY(16px);
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 16px); z-index: 70;
  background: #1c2735; color: #fff; border-radius: 12px; padding: 12px 16px;
  display: none; align-items: center; gap: 16px; box-shadow: var(--sh-lg); font-size: 14px;
  max-width: 90vw; opacity: 0; transition: opacity .2s, transform .2s; }
.snackbar.show { display: flex; opacity: 1; transform: translateX(-50%) translateY(0); }
.snackbar button { background: none; border: none; color: #86abff; font-weight: 750; font-size: 14px; cursor: pointer; padding: 2px 4px; }

/* chips + badges */
.chip { font-size: 12px; padding: 3px 10px; border-radius: var(--pill); font-weight: 600; white-space: nowrap; }
.chip.approach.a-robotic { background: #f3ecff; color: #7c4dd1; }
.chip.approach.a-lap { background: #e6f2fe; color: #1f74c4; }
.chip.approach.a-open { background: #e7f7ee; color: #1a9460; }
.chip.approach.a-endoscopic { background: #e2f6f3; color: #12897c; }
.chip.role { background: #eef7f2; color: #16875f; }
.chip.person { background: #eef1f6; color: #3d4a5c; }
.chip.rot { background: #fbf1e0; color: #a06a1a; }
.chip.cpt { background: #eef1ff; color: #3d55c9; font-variant-numeric: tabular-nums; }
.chip.att { background: var(--ok-soft); color: var(--ok); font-variant-numeric: tabular-nums; }
.chip.cat { background: #eef1ff; color: #3d55c9; cursor: pointer; }
.badge { font-size: 11.5px; padding: 3px 10px; border-radius: var(--pill); font-weight: 650;
  display: inline-flex; align-items: center; gap: 4px; }
.badge svg { width: 13px; height: 13px; }
.badge.ok { background: var(--ok-soft); color: var(--ok); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.info { background: var(--info-soft); color: var(--info); }
.badge.muted { background: var(--line-2); color: var(--ink-2); }
.badge.acg-in { background: var(--ok-soft); color: var(--ok); }
.badge.acg-out { background: var(--warn-soft); color: var(--warn); }
.acg-toggle { cursor: pointer; }
.acg-toggle:hover { filter: brightness(.97); text-decoration: underline; text-underline-offset: 2px; }

/* list "show more" footer */
.list-more { text-align: center; padding: 8px 0 20px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.list-more .btn { min-width: 160px; }

/* empty state */
.empty { text-align: center; color: var(--ink-2); padding: 56px 18px; }
.empty p { font-size: 16px; margin-bottom: 18px; line-height: 1.5; }
.empty .btn { margin: 5px; }

/* ===================== buttons ===================== */
.btn { border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  padding: 10px 15px; border-radius: var(--r-sm); font-size: 14px; font-weight: 620; cursor: pointer;
  transition: background .12s, border-color .12s, filter .12s; -webkit-appearance: none; }
.btn:hover { background: var(--surface-2); }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
.btn.primary:hover { filter: brightness(1.06); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--accent); padding-left: 6px; padding-right: 6px; }
.btn.ghost:hover { background: var(--accent-soft); }
.btn.danger { color: var(--danger); border-color: #f6d3d4; background: #fdf3f3; }

/* FABs */
.fab { position: fixed; right: 18px; z-index: 35; width: 58px; height: 58px; border-radius: 50%;
  border: none; cursor: pointer; color: #fff; font-size: 27px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 16px);
  background: var(--accent); box-shadow: 0 8px 22px rgba(54,103,240,.42);
  transition: transform .08s; }
.fab:active { transform: scale(.94); }
.fab svg { width: 25px; height: 25px; }
.fab-mic svg { width: 23px; height: 23px; }
.fab-mic { bottom: calc(var(--nav-h) + env(safe-area-inset-bottom) + 84px); background: #0ea371;
  box-shadow: 0 8px 22px rgba(14,163,113,.42); font-size: 23px; }
.fab-mic.rec { animation: pulse 1.1s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .55; } }

/* ===================== sheets / overlays ===================== */
.overlay { position: fixed; inset: 0; z-index: 60; background: rgba(15,23,34,.42);
  display: none; align-items: flex-end; justify-content: center; }
.overlay.open { display: flex; }
.sheet { background: var(--surface); width: 100%; max-width: 640px; max-height: 92vh; overflow-y: auto;
  overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  border-radius: 22px 22px 0 0; box-shadow: var(--sh-lg); }
@media (min-width: 640px) { .overlay { align-items: center; } .sheet { border-radius: 22px; } }
/* Lock background scroll while any sheet/gate is open, so the page behind doesn't move under it. */
body:has(.overlay.open), body:has(.authgate.open) { overflow: hidden; }
.sheet-head { position: sticky; top: 0; background: var(--surface); border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; padding: 16px; z-index: 2; }
.sheet-head h2 { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.01em; }
.icon-btn { background: none; border: none; font-size: 19px; color: var(--ink-3); cursor: pointer; padding: 2px 6px; }
.icon-btn:hover { color: var(--ink); }
.sheet-actions { position: sticky; bottom: 0; background: var(--surface); border-top: 1px solid var(--line);
  display: flex; gap: 8px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom)); justify-content: flex-end; align-items: center; }
.sheet-actions .spacer { flex: 1; }

/* forms */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 16px; }
.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field.span2 { grid-column: 1 / -1; }
.field > span { font-size: 12.5px; font-weight: 640; color: #3b4557; }
.field > span em { color: var(--ink-3); font-weight: 400; font-style: normal; }
.field input, .field select, .field textarea { max-width: 100%; padding: 11px 12px; border: 1px solid var(--line);
  border-radius: var(--r-sm); font-size: 15px; background: var(--surface); color: var(--ink); font-family: inherit; -webkit-appearance: none; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.field.checkbox { flex-direction: row; align-items: center; gap: 9px; font-size: 14.5px; cursor: pointer; }
/* Restore the NATIVE checkbox — the .field input reset (appearance:none, padding, border) breaks it otherwise. */
.field.checkbox input[type="checkbox"] {
  -webkit-appearance: auto; appearance: auto;
  width: 18px; height: 18px; min-height: 0; flex: none;
  padding: 0; margin: 0; border: none; border-radius: 0; box-shadow: none;
  accent-color: var(--accent); cursor: pointer;
}
.hint { font-size: 12px; color: var(--ink-2); min-height: 16px; }
.hint a { color: var(--accent); font-weight: 600; text-decoration: none; }
@media (max-width: 560px) { .form-grid { grid-template-columns: 1fr; } }

/* cpt + category editors */
.cpt-add { display: flex; gap: 8px; }
.cpt-add input, .cpt-add select { flex: 1; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 15px; min-width: 0; }
.cpt-results { display: none; flex-direction: column; gap: 1px; margin-top: 6px; max-height: 260px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); box-shadow: 0 8px 24px rgba(15,23,34,.10); }
.cpt-results.open { display: flex; }
.cpt-opt { display: flex; gap: 8px; align-items: baseline; text-align: left; width: 100%; padding: 9px 11px;
  background: none; border: none; border-radius: 7px; cursor: pointer; font: inherit; color: var(--ink); }
.cpt-opt:hover, .cpt-opt:focus { background: var(--accent-soft); outline: none; }
.cpt-opt b { color: #3d55c9; font-variant-numeric: tabular-nums; flex: none; }
.cpt-opt span { color: var(--ink-2); font-size: 13px; }
.cat-suggest { display: none; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 8px; }
.cat-suggest-label { font-size: 12px; color: var(--ink-3); margin-right: 2px; }
.chip.cat-add { cursor: pointer; border: 1px dashed var(--accent); background: var(--accent-soft); color: #3d55c9;
  padding: 4px 10px; border-radius: 999px; font-size: 12.5px; font: inherit; line-height: 1.4; }
.chip.cat-add:hover, .chip.cat-add:focus { background: #e2ebff; outline: none; }
.chip.sample { background: #fff4dc; color: #8a5a00; border: 1px solid #f0d089; font-weight: 600; }
.cpt-list { margin-top: 9px; display: flex; flex-direction: column; gap: 7px; }
.cpt-row { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: var(--r-sm); background: var(--surface-2); flex-wrap: wrap; }
.cpt-row.is-primary { border-color: #e2c98a; background: #fffdf5; }
.cpt-row .cpt-info { flex: 1; font-size: 13px; min-width: 120px; }
.cpt-row .cpt-info b { font-variant-numeric: tabular-nums; color: #3d55c9; }
.cpt-row .cpt-info span { color: var(--ink-2); }
.cpt-row .cpt-nocode { color: var(--ink-3); font-style: italic; }
.cpt-toggles { display: flex; align-items: center; gap: 6px; }
.cpt-tog { border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); cursor: pointer;
  font-size: 11.5px; font-weight: 640; padding: 5px 9px; border-radius: var(--pill); white-space: nowrap; transition: all .12s; }
.cpt-tog.prim.on { background: #fbf1d9; border-color: #eccf85; color: #9a6a12; }
.cpt-tog.robo.on { background: #f3ecff; border-color: #d9c6f5; color: #7c4dd1; }
.cpt-row .x { background: none; border: none; color: var(--danger); cursor: pointer; font-size: 14px; padding: 2px 4px; }
.cat-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }

#opNoteOverlay textarea { width: 100%; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 14px; line-height: 1.5; background: var(--surface); color: var(--ink); resize: vertical; font-family: inherit; }
#opNoteOverlay textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
#opNoteOverlay .opnote-text { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
#opNoteCase b { color: var(--ink); }

.transcript-box { padding: 10px 12px; border: 1px dashed var(--line); border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--ink-2); font-size: 13px; line-height: 1.5; white-space: pre-wrap; }

.low-banner { margin: 12px 16px 0; padding: 9px 13px; border-radius: var(--r-sm); background: var(--warn-soft); color: var(--warn); font-size: 12.5px; }
input.low, select.low, .cpt-list.low { border-color: #eaa23b !important; background: #fffdf7; box-shadow: 0 0 0 3px rgba(234,162,59,.16); }

/* settings */
.setgroup { font-size: 12px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3); font-weight: 700; margin-bottom: 9px; }

/* Settings sheet — clean, clearly-sectioned layout (replaces the flat, cramped look). */
.settings-body { padding: 6px 20px 12px; }
.settings-body .setgroup {
  margin: 22px -20px 12px; padding: 18px 20px 0;
  border-top: 1px solid var(--line);
  font-size: 13px; letter-spacing: 0; text-transform: none;
  color: var(--accent); font-weight: 700;
}
.settings-body .setgroup:first-child { margin-top: 4px; padding-top: 0; border-top: none; }
.settings-body .field { margin-top: 12px !important; }
.settings-body .setgroup + .field,
.settings-body .setgroup + .muted + .field,
.settings-body .setgroup + p + .field { margin-top: 2px !important; }
.settings-body .field input, .settings-body .field select, .settings-body .field textarea { padding: 12px 13px; border-radius: 12px; }
.settings-body .btn { border-radius: 12px; }

/* --- Settings: sectioned panes, one at a time on every screen. Desktop gets a left rail,
   mobile a scrollable chip row. (Stacking all panes on mobile killed the section dividers,
   because the base rule drops the top border on any .setgroup that is a first child.) --- */
.setpane { display: none; }
.setpane.active { display: block; }
.setpane .setgroup:first-child { margin-top: 0; padding-top: 0; border-top: none; }

@media (max-width: 759px) {
  .set-nav { display: flex; gap: 6px; overflow-x: auto; margin: 0 -20px 6px; padding: 2px 20px 12px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .set-nav::-webkit-scrollbar { display: none; }
  .set-navbtn { flex: 0 0 auto; font: inherit; font-size: 13px; font-weight: 600; white-space: nowrap;
    padding: 8px 14px; border-radius: var(--pill); cursor: pointer;
    border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); }
  .set-navbtn.active { background: var(--accent-soft); color: #3d55c9; border-color: transparent; }
}
.acct-id { display: flex; align-items: center; gap: 12px; padding: 13px 15px; border-radius: 14px;
  background: var(--accent-soft); border: 1px solid #dfe6fb; }
.acct-id-name { font-size: 15px; font-weight: 700; color: var(--ink); }
.acct-id-sub { font-size: 12px; color: var(--ink-2); margin-top: 2px; }

@media (min-width: 760px) {
  #settingsOverlay .sheet { max-width: 800px; }
  .settings-body { display: grid; grid-template-columns: 186px minmax(0, 1fr); gap: 26px;
    align-items: start; padding: 10px 22px 14px; }
  .set-nav { display: flex; flex-direction: column; gap: 2px; position: sticky; top: 6px; }
  .set-navbtn { text-align: left; border: none; background: none; cursor: pointer; font: inherit;
    padding: 9px 12px; border-radius: 9px; font-size: 13.5px; font-weight: 600; color: var(--ink-2); }
  .set-navbtn:hover { background: var(--line-2); color: var(--ink); }
  .set-navbtn.active { background: var(--accent-soft); color: #3d55c9; }
  .set-panes { min-width: 0; }
  /* Section dividers full-bleed via negative side margins, which was right for the old
     single-column sheet but bleeds into the nav gutter in the two-column grid. Align them
     to the content column instead. */
  .settings-body .setgroup { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
}
.settings-body #acct_out, .settings-body #acct_in { margin-top: 4px; }
.statlink { color: var(--accent); text-decoration: none; }
.statlink:hover { text-decoration: underline; }
.queue-banner { background: var(--accent-soft); color: #2748b8; border: 1px solid #d6e0ff; border-radius: var(--r-md);
  padding: 11px 13px; margin-bottom: 12px; font-size: 13px; display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.queue-banner a { color: var(--accent); }
.qexport { padding: 5px 11px; font-size: 12px; }

/* ===================== progress ===================== */
.progress { padding-bottom: 24px; }
.prog-head h2 { margin: 8px 4px 3px; font-size: 19px; font-weight: 720; letter-spacing: -.01em; }
.prog-head .muted { margin: 0 4px 14px; }
.prog-sec { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--sh-sm); padding: 6px 16px 14px; margin-bottom: 12px; }
.prog-sec-title { font-size: 12px; text-transform: uppercase; letter-spacing: .07em; color: var(--ink-3); margin: 13px 0 6px; font-weight: 700; }
.pgrow { padding: 9px 0; border-bottom: 1px solid var(--line-2); }
.pgrow:last-child { border-bottom: none; }
.pgrow.sub { padding-left: 16px; }
.pgrow.sub .pglabel { color: var(--ink-2); font-size: 13px; font-weight: 600; }
.pglabel { font-weight: 640; font-size: 14.5px; margin-bottom: 6px; }
.pgbar { height: 8px; background: #edeff3; border-radius: var(--pill); overflow: hidden; }
.pgbar > span { display: block; height: 100%; background: var(--accent); border-radius: var(--pill); transition: width .35s ease; }
.pgbar > span.done { background: var(--ok); }
.pgnum { font-size: 12px; color: var(--ink-2); margin-top: 5px; font-variant-numeric: tabular-nums; }
.pgnum b { color: var(--ink); }

/* ===================== technique folders / view / editor ===================== */
.folder-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 11px; padding-top: 4px; }
.folder { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--sh-sm);
  padding: 20px 14px; cursor: pointer; text-align: center; transition: transform .08s, box-shadow .18s; }
.folder:hover { box-shadow: var(--sh); }
.folder:active { transform: scale(.98); }
.folder-ico { font-size: 30px; line-height: 1; }
.folder-name { font-weight: 680; margin-top: 9px; font-size: 15px; }
.folder-count { color: var(--ink-3); font-size: 12.5px; margin-top: 2px; }

.tech-link { width: 100%; text-align: left; }
.tech-snippet { margin-top: 6px; font-size: 13px; color: var(--ink-2); }
/* In normal flow at the end of the card, right-aligned. Absolute positioning put it under the
   excerpt's last line on a narrow screen, and reserving enough padding to clear that cost more
   height than simply letting it take a row. The card's own job is still to open the technique, so
   this must never read as the primary action. */
.tech-share { display: block; margin: 8px 0 -4px auto; background: none; border: 1px solid transparent;
  color: var(--ink-3); font: inherit; font-size: 12.5px; font-weight: 600; padding: 4px 10px;
  border-radius: var(--pill); cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.tech-share:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-soft); }
.tech-share:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tech-sec { display: grid; grid-template-columns: 1fr auto; gap: 8px; margin-bottom: 14px; padding-bottom: 14px; border-bottom: 1px dashed var(--line); align-items: start; }
.tsec-title { grid-column: 1; font-weight: 650; padding: 10px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 15px; min-width: 0; }
.tsec-tools { grid-column: 2; grid-row: 1 / span 2; align-self: center; display: flex; flex-direction: column; gap: 2px; align-items: center; }
.tsec-move { background: none; border: none; color: var(--ink-3); cursor: pointer; font-size: 15px; line-height: 1;
  padding: 4px 6px; border-radius: 6px; transition: background .12s, color .12s; }
.tsec-move:hover:not(:disabled) { background: var(--accent-soft); color: var(--accent); }
.tsec-move:disabled { opacity: .28; cursor: default; }
.tech-sec .x { background: none; border: none; color: var(--danger); cursor: pointer; padding: 4px 6px; }
.tsec-moved { animation: tsecFlash .5s ease; }
@keyframes tsecFlash { from { background: var(--accent-soft); } to { background: transparent; } }
.tsec-body { grid-column: 1; min-height: 64px; padding: 10px 11px; border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 14.5px; line-height: 1.5; resize: none; overflow: hidden; font-family: inherit; min-width: 0; }
.tsec-title:focus, .tsec-body:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.tview-sec { margin-bottom: 18px; }
.tview-sec h3 { margin: 0 0 5px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--accent); font-weight: 720; }
.tview-body { font-size: 14.5px; color: #1c2432; line-height: 1.55; }
.tview-body p { margin: 3px 0; }
.tview-body ol, .tview-body ul { margin: 5px 0; padding-left: 22px; }
.tview-body li { margin: 4px 0; }

/* attending prefs */
.apref-row { display: grid; grid-template-columns: 1fr auto; gap: 7px 8px; margin-bottom: 11px; padding-bottom: 11px; border-bottom: 1px dashed var(--line); align-items: start; }
.apref-row input.apref-name { grid-column: 1; font-weight: 640; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 14px; min-width: 0; }
.apref-row textarea.apref-note { grid-column: 1; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 14px; min-height: 54px; resize: vertical; font-family: inherit; min-width: 0; }
.apref-row .x { grid-column: 2; grid-row: 1 / span 2; background: none; border: none; color: var(--danger); cursor: pointer; align-self: center; }
.apref-view { padding: 7px 0; border-bottom: 1px solid var(--line-2); }
.apref-view:last-child { border-bottom: none; }
.apref-view b { color: #3b4557; }

/* attending detail */
.att-item { padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: 14px; }
.att-item:last-child { border-bottom: none; }
.att-item > div { color: #3b4557; margin-top: 3px; white-space: pre-wrap; }
.att-item .chip { margin-left: 6px; }
#attBody textarea { width: 100%; padding: 11px; border: 1px solid var(--line); border-radius: var(--r-sm); font: inherit; font-size: 15px; resize: vertical; }
#attBody textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.att-caserow { padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: 14px; font-weight: 640; cursor: pointer; }
.att-caserow:last-child { border-bottom: none; }
.att-caserow:hover { color: var(--accent); }
.att-caserow .muted { font-weight: 400; }

/* capture sheet */
.sheet.capture #capText { width: 100%; padding: 13px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 15.5px; line-height: 1.45; resize: vertical; }
.sheet.capture #capText:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.cap-controls { display: flex; align-items: center; gap: 10px; margin-top: 11px; }
#micBtn.rec { background: #fbe9e9; border-color: #f2b8b8; color: var(--danger); }

/* small button variant */
.btn.small { padding: 6px 11px; font-size: 12.5px; border-radius: var(--pill); }

/* merge / rename attending picker */
.merge-search { width: 100%; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 15px; -webkit-appearance: none; }
.merge-search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.merge-sec { font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); font-weight: 700; margin: 4px 2px 8px; }
.merge-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 13px;
  border: 1px solid var(--line); border-radius: var(--r-sm); margin-bottom: 8px; cursor: pointer; transition: background .12s, border-color .12s; }
.merge-row:hover { background: var(--accent-soft); border-color: #cdd9ff; }
.merge-name { font-weight: 650; }
.merge-count { color: var(--ink-3); font-size: 12.5px; white-space: nowrap; }
.merge-row.rename { color: var(--accent); font-weight: 600; }
.merge-row.rename b { font-weight: 750; }

/* list toolbar (sort / show-hidden) */
.listbar { display: flex; align-items: center; gap: 10px; margin: 2px 2px 4px; flex-wrap: wrap; }
.seg { display: inline-flex; background: #eaedf2; border-radius: 10px; padding: 3px; gap: 2px; }
.segbtn { border: none; background: transparent; padding: 6px 13px; border-radius: 7px; font-size: 12.5px;
  font-weight: 640; color: var(--ink-2); cursor: pointer; transition: background .14s, color .14s, box-shadow .14s; }
.segbtn.active { background: var(--surface); color: var(--ink); box-shadow: var(--sh-sm); }
.listbar .btn.small { margin-left: auto; }
/* Techniques: approach filter chips (colors mirror the approach chips on cards) */
.techfilters { display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.fchip { border: 1px solid var(--line); background: var(--surface); color: var(--ink-2); cursor: pointer;
  font-size: 12px; font-weight: 600; padding: 5px 11px; border-radius: var(--pill); }
.fchip:hover { border-color: var(--accent); }
.fchip .fchip-n { opacity: .5; margin-left: 3px; font-variant-numeric: tabular-nums; }
.fchip.active { border-color: transparent; }
.fchip.active.a-all { background: var(--accent-soft); color: #3d55c9; }
.fchip.active.a-lap { background: #e6f2fe; color: #1f74c4; }
.fchip.active.a-robotic { background: #f3ecff; color: #7c4dd1; }
.fchip.active.a-open { background: #e7f7ee; color: #1a9460; }
.fchip.active.a-endoscopic { background: #e2f6f3; color: #12897c; }
@media (max-width: 560px) { .techfilters { margin-left: 0; width: 100%; } }

/* attending cards + detail */
.muted-chip { background: var(--line-2); color: var(--ink-3); }
.att-card.is-hidden { opacity: .62; }
.att-hero { display: flex; gap: 10px; margin-bottom: 6px; align-items: stretch; }
.att-stat { flex: 1; background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--r-md);
  padding: 12px 10px; text-align: center; min-width: 0; }
.att-stat b { display: block; font-size: 22px; font-weight: 740; letter-spacing: -.02em; }
.att-stat span { font-size: 11.5px; color: var(--ink-2); }
.att-stat { display: flex; flex-direction: column; justify-content: center; min-height: 74px; text-align: center; }

/* folder icon (svg) */
.folder-ico svg { width: 30px; height: 30px; color: var(--accent); }
.tech-hint { text-align: center; margin: 22px auto 0; max-width: 420px; }

/* progress baseline bar + editor */
.baseline-bar { display: flex; align-items: center; gap: 12px; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--sh-sm); padding: 11px 14px; margin: 4px 0 14px; font-size: 13px; color: var(--ink-2); }
.baseline-bar > div { flex: 1; min-width: 0; }
.baseline-bar b { color: var(--ink); }
.baseline-bar .btn { white-space: nowrap; }
.baseline-bar.stale { border-color: #f0d9a8; background: #fdf8ee; }
.baseline-stale { color: #9a6b12; font-weight: 600; }
.ti-drop { border: 2px dashed var(--line); border-radius: 12px; padding: 22px 18px; text-align: center; background: var(--surface-2); transition: border-color .15s, background .15s; }
.ti-drop.over { border-color: var(--accent); background: var(--accent-soft); }
.ti-drop .link { color: var(--accent); font-weight: 600; cursor: pointer; }
.ti-drop-main { font-size: 14px; color: var(--ink); }
.ti-drop-sub { font-size: 12px; color: var(--ink-3); margin-top: 7px; }
.ti-or { display: flex; align-items: center; gap: 12px; color: var(--ink-3); font-size: 12px; margin: 16px 0 10px; }
.ti-or::before, .ti-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.ti-skip { opacity: .5; }
.apref-att { color: var(--accent); font-weight: 700; text-decoration: none; cursor: pointer; }
.apref-att:hover { text-decoration: underline; }
.fbar-actions { display: inline-flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.fimport-wrap { position: relative; display: inline-flex; }
.btn.fimport { background: var(--surface); border: 1px solid var(--line); color: var(--ink); font-weight: 650; }
.btn.fimport:hover { border-color: var(--accent); color: var(--accent); }
.fmenu { position: absolute; top: calc(100% + 6px); left: 0; z-index: 40; min-width: 236px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 13px;
  box-shadow: 0 14px 36px rgba(15, 23, 34, .16); padding: 5px; }
.fmenu[hidden] { display: none; }
.fmenu-item { display: block; width: 100%; text-align: left; border: none; background: none; cursor: pointer;
  padding: 9px 11px; border-radius: 9px; font: inherit; color: var(--ink); }
.fmenu-item:hover { background: var(--accent-soft); }
.fmenu-item b { display: block; font-size: 13.5px; font-weight: 650; }
.fmenu-item span { display: block; font-size: 12px; color: var(--ink-2); margin-top: 1px; }
.tech-foot { display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; padding: 20px 12px 8px; }
.tech-foot p { margin: 0; max-width: 470px; }
.bl-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 7px 0; border-bottom: 1px solid var(--line-2); }
.bl-row.sub { padding-left: 16px; }
.bl-row.sub span { color: var(--ink-2); font-size: 13.5px; }
.bl-row span { font-size: 14.5px; font-weight: 600; }
.bl-row input { width: 88px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 15px; text-align: right; font-variant-numeric: tabular-nums; -webkit-appearance: none; }
.bl-row input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* PIN lock */
.lockscreen { position: fixed; inset: 0; z-index: 2147483000; background: var(--bg); display: none; align-items: center; justify-content: center; }
.lockscreen.open { display: flex; }
.lockbox { text-align: center; width: 260px; }
.lock-logo { font-size: 32px; font-weight: 800; letter-spacing: -.02em; margin-bottom: 6px; }
.lock-logo span { color: var(--accent); }
.lockbox input { width: 100%; padding: 13px; border: 1px solid var(--line); border-radius: var(--r-sm); font-size: 22px; text-align: center; letter-spacing: 6px; }
.lockbox input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.lock-err { color: var(--danger); font-size: 13px; margin-top: 8px; min-height: 16px; }

/* Account gate (front door) */
.authgate { position: fixed; inset: 0; z-index: 2147483000; background: var(--bg); display: none; align-items: center; justify-content: center; padding: 24px; overflow-y: auto; }
.authgate.open { display: flex; }
.authbox { width: 100%; max-width: 340px; text-align: center; }
.auth-logo { font-size: 34px; font-weight: 800; letter-spacing: -.02em; }
.auth-logo span { color: var(--accent); }
.auth-tag { color: var(--ink-3); font-size: 13.5px; margin: 2px 0 22px; }
.gate-view { text-align: left; }
.gstep { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--accent); margin-bottom: 14px; text-align: center; }
.auth-note { font-size: 12.5px; color: var(--ink-2, #5a6678); line-height: 1.5; margin: 0 0 14px; }
.gfield { display: block; margin-bottom: 12px; }
.gfield > span { display: block; font-size: 12.5px; font-weight: 640; color: #3b4557; margin-bottom: 6px; }
.gfield > span em { color: var(--ink-3); font-weight: 400; font-style: normal; }
.gfield input, .gfield select { width: 100%; padding: 12px 13px; border: 1px solid var(--line); border-radius: 12px; font-size: 15px; background: var(--surface); color: var(--ink); }
.gfield input:focus, .gfield select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.gbtn { width: 100%; justify-content: center; margin-top: 4px; padding: 13px; font-size: 15px; }
.gbtn + .gbtn { margin-top: 10px; }
.gmsg { font-size: 13px; margin-top: 10px; min-height: 18px; text-align: center; }
.gate-alt { text-align: center; font-size: 13.5px; color: var(--ink-3); margin-top: 14px; }
.gate-alt a { color: var(--accent); cursor: pointer; text-decoration: none; font-weight: 600; }
.gate-alt a.muted { color: var(--ink-3); font-weight: 400; }
.gate-alt a:hover { text-decoration: underline; }
.rec-box { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 21px; letter-spacing: 2px; text-align: center; padding: 16px; border: 1px dashed var(--line); border-radius: 12px; margin: 4px 0 12px; color: var(--ink); }

/* --- Sign-in: single centered form on phones; brand/value panel + form on desktop.
   The split maps to a native onboarding screen later (hero art left, form right). --- */
.authwrap { width: 100%; display: flex; justify-content: center; }
.auth-hero { display: none; }
/* App mark. On the blue hero it needs separation from the gradient, hence the ring + shadow. */
.auth-mark { display: block; margin: 0 auto 14px; border-radius: 15px;
  box-shadow: 0 8px 22px rgba(10, 20, 50, .26), 0 0 0 1px rgba(255, 255, 255, .3); }
@media (min-width: 900px) {
  .authgate { padding: 32px; }
  .authwrap { display: grid; grid-template-columns: 1.05fr .95fr; max-width: 880px;
    background: var(--surface); border: 1px solid var(--line); border-radius: 22px;
    overflow: hidden; box-shadow: 0 18px 50px rgba(20, 28, 48, .13); }
  .auth-hero { display: flex; flex-direction: column; gap: 16px; padding: 46px 42px;
    background: linear-gradient(158deg, #4170f1, #2b4bc7); color: #fff; text-align: left; }
  .auth-hero .auth-mark { margin: 0 0 16px; }        /* left-aligned with the hero copy */
  .auth-hero .auth-logo { font-size: 30px; color: #fff; }
  .auth-hero .auth-logo span { color: #c9dbff; }
  .auth-hero .auth-tag { color: rgba(255, 255, 255, .82); margin: 0 0 4px; font-size: 14px; }
  .auth-points { list-style: none; margin: 4px 0 0; padding: 0; display: grid; gap: 13px; }
  .auth-points li { position: relative; padding-left: 26px; font-size: 13.6px; line-height: 1.5;
    color: rgba(255, 255, 255, .95); }
  .auth-points li::before { content: "✓"; position: absolute; left: 0; font-weight: 800; color: #b9d1ff; }
  .auth-hero-foot { margin-top: auto; padding-top: 26px; font-size: 12.5px; line-height: 1.55;
    color: rgba(255, 255, 255, .72); }
  .auth-hero-foot a { color: #fff; font-weight: 600; text-decoration: underline; white-space: nowrap; }
  .authgate .authbox { max-width: none; padding: 46px 42px; display: flex;
    flex-direction: column; justify-content: center; }
  .authbox .auth-mark, .authbox .auth-logo, .authbox .auth-tag, .gate-privacy { display: none; } /* hero covers these */
}

/* Recently deleted (trash) rows */
.trash-row { display: flex; align-items: center; gap: 12px; padding: 11px 2px; border-bottom: 1px solid var(--line); }
.trash-row:last-child { border-bottom: none; }
.trash-info { flex: 1; min-width: 0; }
.trash-title { font-weight: 640; font-size: 14px; }

/* Pull-to-refresh indicator */
html, body { overscroll-behavior-y: contain; }
#ptr { position: fixed; top: -46px; left: 50%; transform: translateX(-50%); z-index: 40; background: var(--surface); border: 1px solid var(--line); border-radius: 20px; padding: 7px 14px; font-size: 13px; font-weight: 600; color: var(--ink-3); box-shadow: 0 6px 18px rgba(20,30,50,.12); opacity: 0; transition: top .18s, opacity .18s; display: flex; align-items: center; gap: 5px; pointer-events: none; }
#ptr.spin span { display: inline-block; animation: ptrspin .8s linear infinite; }
@keyframes ptrspin { to { transform: rotate(360deg); } }

/* Onboarding / how it works */
.ob-body { padding: 20px 24px 6px; }
/* Fixed height, not min-height. The dialog used to grow and shrink with each slide's text, which
   moved Next out from under the cursor between steps — you could not just click through. Short
   slides now centre in the same box; the one long slide scrolls inside it. */
/* Fixed height so the dialog does not resize between slides and move Next out from under the
   cursor. `safe center` matters: plain centring clips overflow at BOTH ends, so on the longest
   slide the icon was cut off and unreachable by scrolling. */
.ob-step { height: 320px; display: flex; flex-direction: column; align-items: center; text-align: center;
  justify-content: safe center; overflow-y: auto; overscroll-behavior: contain; }
@media (max-height: 760px) { .ob-step { height: 250px; } }
.ob-icon { width: 62px; height: 62px; border-radius: 18px; background: var(--accent-soft); display: flex; align-items: center; justify-content: center; font-size: 31px; line-height: 1; margin: 2px 0 18px; }
.ob-step h3 { margin: 0 0 10px; font-size: 20px; font-weight: 780; letter-spacing: -.015em; color: var(--ink); }
.ob-step p { margin: 0; color: var(--ink-2); font-size: 14.5px; line-height: 1.6; max-width: 340px; }
.ob-step em { color: var(--ink); font-style: normal; font-weight: 640; }
.ob-count { font-size: 12px; font-weight: 640; color: var(--ink-3); font-variant-numeric: tabular-nums; letter-spacing: .02em; }
.ob-dots { display: flex; gap: 7px; justify-content: center; padding: 22px 0 4px; }
/* import guide */
.ig-lbl { font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); margin: 0 0 9px; }
.ig-steps { margin: 0; padding-left: 22px; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.ig-steps li { margin: 8px 0; padding-left: 3px; }
.ig-steps li::marker { color: var(--accent); font-weight: 700; }
.ig-steps b { color: var(--ink); font-weight: 640; }
.ig-help { display: inline-block; margin-top: 14px; font-size: 13.5px; font-weight: 640; color: var(--accent); text-decoration: none; }
.ig-help:hover { text-decoration: underline; }
.ob-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line); transition: background .18s, width .18s; }
.ob-dot.on { background: var(--accent); width: 20px; border-radius: 4px; }

/* Pilot survey */
.survey-body { padding: 10px 20px 12px; max-height: 66vh; overflow: auto; }
.sv-q { margin: 0 0 18px; }
.sv-qt { font-weight: 640; font-size: 14px; margin-bottom: 9px; line-height: 1.4; }
.sv-likert { display: flex; gap: 6px; }
.sv-choices { display: flex; flex-direction: column; gap: 7px; }
.sv-opt { display: flex; align-items: center; gap: 8px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; font-size: 13px; background: var(--surface); transition: border-color .12s, background .12s; }
.sv-likert .sv-opt { flex: 1; flex-direction: column; text-align: center; gap: 7px; font-size: 11px; padding: 10px 4px; }
.sv-opt:hover { border-color: var(--accent); }
.sv-opt input { accent-color: var(--accent); margin: 0; }
.sv-opt:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.sv-num, .sv-text { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; font-size: 14px; font-family: inherit; background: var(--surface); color: var(--ink); box-sizing: border-box; }
.sv-num:focus, .sv-text:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

/* Clearer busy/disabled feedback — the Parse button shows a spinner while Claude works. */
.btn:disabled { opacity: .55; cursor: default; }
#parseBtn { position: relative; }
#parseBtn:disabled { opacity: 1; color: transparent; }
#parseBtn:disabled::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px;
  border: 2.5px solid rgba(255,255,255,.4); border-top-color: #fff; border-radius: 50%; animation: parsespin .7s linear infinite;
}
@keyframes parsespin { to { transform: rotate(360deg); } }
#capStatus { color: var(--accent); font-weight: 600; }

/* Signup acknowledgement — deliberately readable rather than fine print. */
.gack { display: flex; gap: 10px; align-items: flex-start; margin: 4px 0 12px;
  padding: 11px 12px; background: var(--surface); border: 1px solid var(--line);
  border-radius: 11px; font-size: 12.5px; line-height: 1.5; color: var(--ink-2); cursor: pointer; }
.gack input { margin: 2px 0 0; flex: 0 0 auto; width: 16px; height: 16px; accent-color: var(--accent); }
.gack b { color: var(--ink); font-weight: 650; }
.gack a { color: var(--accent); }

/* Mic pulses with your voice while recording — the only feedback between speaking and the first
   phrase appearing. --lvl is set per-frame from the audio peak. */
/* Ring capped at 8px and damped in JS: at 14px of raw per-frame peak it jittered hard and spilled
   past the edge of the sheet on a phone. */
#micBtn.rec { box-shadow: 0 0 0 calc(var(--lvl, .3) * 8px) rgba(65, 112, 241, .16); transition: box-shadow .1s ease-out; }

/* On a phone, let the revealed filters sit two per row rather than ragged. */
@media (max-width: 700px) {
  .fsel { flex: 1 1 calc(50% - 4px); min-width: 0; }
}

/* Data-flow figure on the privacy page. The SVG carries its own white plate so it reads the same
   in the browser and in the counsel PDF; on a phone it scrolls sideways inside its own box rather
   than shrinking the type past legibility. */
.dataflow { margin: 18px 0 22px; padding: 0; }
.dataflow figcaption { font-size: 12.5px; color: var(--ink-2); margin-bottom: 8px; font-weight: 600; }
.dataflow > svg { width: 100%; height: auto; min-width: 620px; border: 1px solid var(--line); border-radius: 12px; display: block; }
.dataflow { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Share affordance on each attending-preference row. Quiet until hovered — the note is the content,
   the button is a tool. */
/* Quiet until you want it. Previously a bordered pill that read as a dated form control whether
   idle or hovered; now it sits back as a subtle action and only gains a surface on hover. */
.apref-share {
  appearance: none; border: 1px solid transparent; background: transparent; color: var(--ink-3);
  font: inherit; font-size: 12px; font-weight: 640; padding: 4px 9px; border-radius: 8px;
  cursor: pointer; white-space: nowrap; display: inline-flex; align-items: center; gap: 5px;
  transition: background .12s, color .12s, border-color .12s;
}
.apref-share::before {
  content: ""; width: 13px; height: 13px; flex: 0 0 auto; background: currentColor;
  -webkit-mask: var(--share-ico) center/contain no-repeat; mask: var(--share-ico) center/contain no-repeat;
}
.apref-share:hover { background: var(--accent-soft); border-color: var(--accent-soft); color: var(--accent); }
.apref-share:active { transform: translateY(.5px); }

/* Share preview — deliberately looks like the card the recipient gets, because this IS the safety
   control: it is the moment someone spots a patient name they typed into a technique note. */
.share-preview {
  border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; background: var(--surface);
  max-height: 340px; overflow-y: auto;
}
.share-preview h4 { margin: 0 0 2px; font-size: 16px; }
.share-preview .sp-who { color: var(--ink-2); font-size: 13px; margin: 0 0 10px; }
.share-preview .sp-sec { margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--line); }
.share-preview .sp-sec:first-of-type { border-top: none; padding-top: 0; }
.share-preview h5 { margin: 0 0 3px; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-3); font-weight: 750; }
.share-preview .sp-body { font-size: 13.5px; line-height: 1.45; color: var(--ink); }

/* ---- share: picking what goes on the card ------------------------------------------------ */
/* The picker is the safety control as much as the interface, so each row shows enough of the
   body to recognise it without having to remember what a section title contains. */
.share-picks { border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.pick-group + .pick-group { border-top: 1px solid var(--line); }
.pick-head { font-size: 11px; font-weight: 750; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted); background: var(--bg-2, #f4f6fb); padding: 7px 12px; }
.pick { display: grid; grid-template-columns: auto 1fr; gap: 2px 10px; align-items: baseline;
  padding: 9px 12px; cursor: pointer; }
.pick + .pick { border-top: 1px solid var(--line-2); }
.pick:hover { background: var(--bg-2, #f4f6fb); }
.pick input { grid-row: 1 / span 2; align-self: center; width: 17px; height: 17px; margin: 0; cursor: pointer; }
.pick-t { font-weight: 640; font-size: 14px; }
.pick-p { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Keep the preview from pushing the footer off-screen on a laptop. */
.share-preview { max-height: 260px; overflow-y: auto; }

/* Attending row: name and Share on one line, the note underneath — the button was previously
   inline inside the sentence and read as part of the text. */
.apref-line { display: flex; align-items: center; gap: 10px; }
.apref-line .apref-att { flex: 0 0 auto; }
.apref-share { margin-left: auto; flex: 0 0 auto; }
.apref-note-view { margin-top: 3px; }

/* .sheet-body / .sheet-foot were used in markup but never defined, so the share and import sheets
   rendered with no padding and a footer that scrolled away with the content — the primary action
   ended up below the fold. These mirror the .sheet-actions convention used by the other sheets. */
.sheet-body { padding: 16px; }
.sheet-foot { position: sticky; bottom: 0; background: var(--surface); border-top: 1px solid var(--line);
  display: flex; gap: 8px; padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  justify-content: flex-end; align-items: center; z-index: 2; }

/* Preview bodies are formatted HTML now (same as the public card), not pre-wrap text. */
.sp-body p { margin: 0 0 6px; }
.sp-body p:last-child { margin-bottom: 0; }
.sp-body ol, .sp-body ul { margin: 0 0 6px; padding-left: 20px; }
.sp-body ol:last-child, .sp-body ul:last-child { margin-bottom: 0; }
.sp-body li { margin: 0 0 3px; }

/* ---- multi-select for a technique's services ---------------------------------------------- */
/* A technique belongs to several services at once, so this is a set of toggles rather than a
   dropdown — the whole point is that more than one can be true. */
.sys-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.sys-chip {
  appearance: none; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  font: inherit; font-size: 12.5px; font-weight: 640; padding: 5px 11px; border-radius: var(--pill);
  cursor: pointer; transition: background .12s, border-color .12s, color .12s;
}
.sys-chip:hover { border-color: var(--accent); color: var(--accent); }
.sys-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.sys-chip.on:hover { background: var(--accent); color: #fff; }


/* Share glyph, inlined so the button needs no network and no icon font. */
:root { --share-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 16V3'/%3E%3Cpath d='M8 7l4-4 4 4'/%3E%3Cpath d='M4 13v6a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-6'/%3E%3C/svg%3E"); }

/* Chips on the share preview, mirroring the public card. */
.sp-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 6px 0 2px; }
.sp-chip { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: var(--pill);
  background: var(--accent-soft); color: var(--accent); letter-spacing: .01em; }
.sp-chip:not(:first-child) { background: transparent; color: var(--ink-3); border: 1px solid var(--line); }

/* ---- storage readout -------------------------------------------------------------------- */
.stbar { height: 8px; border-radius: 5px; background: var(--line); overflow: hidden; margin: 8px 0 10px; }
.stbar i { display: block; height: 100%; background: var(--accent); border-radius: 5px; transition: width .3s; }
.stbar.warn i { background: var(--warn, #a8500a); }
.stbar.bad i { background: var(--danger, #b4231a); }
.strow { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 5px 0;
  border-bottom: 1px solid var(--line-2); }
.strow:last-child { border-bottom: none; }
.strow b { font-weight: 640; }
.strow span { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- techniques: list view -----------------------------------------------------------------
   The same folders as the grid, at higher density — Finder's list view is still a hierarchy, not
   a flat dump of every file. Rows expand in place rather than navigating away. */
.sys-list { border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--surface); }
.sys-row { display: flex; align-items: center; gap: 9px; padding: 11px 13px; cursor: pointer;
  border-top: 1px solid var(--line-2); transition: background .12s; }
.sys-row:first-child { border-top: none; }
.sys-row:hover { background: var(--accent-soft); }
.sys-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sys-chev { color: var(--muted); font-size: 17px; line-height: 1; width: 12px; text-align: center;
  transition: transform .16s ease; }
.sys-row.open .sys-chev { transform: rotate(90deg); }
.sys-folder { color: var(--accent); display: flex; width: 19px; height: 19px; flex: 0 0 auto; }
.sys-folder svg { width: 100%; height: 100%; }
.sys-name { font-weight: 650; font-size: 14.5px; }
.sys-count { margin-left: auto; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

.sys-kids { display: none; background: var(--bg-2, #f7f9fd); }
.sys-kids.open { display: block; }
.sys-kid { display: flex; align-items: center; gap: 9px; padding: 9px 13px 9px 42px; cursor: pointer;
  border-top: 1px solid var(--line-2); font-size: 14px; }
.sys-kid:hover { background: var(--accent-soft); }
.sys-kid-name { flex: 1; min-width: 0; }

/* ---- technique tidy-up preview -------------------------------------------------------------
   One bordered list rather than a card per technique: most techniques have a single change, and a
   card each turned a short list into a long scroll. Columns are aligned so the eye can run down
   the field names instead of re-parsing every row. */
.tidy-list { border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; }
.tidy-item + .tidy-item { border-top: 1px solid var(--line); }

/* Three columns — tick, field, change — with the technique name on its own line above when it is
   shown. Spreading name/field/change across one wide row left big gaps and wrapped the arrow onto
   a second line anyway; stacking reads as one thought. */
.tidy-row { display: grid; grid-template-columns: auto max-content minmax(0, 1fr);
  gap: 3px 10px; align-items: baseline; padding: 8px 12px; cursor: pointer; }
.tidy-row:hover { background: var(--accent-soft); }
.tidy-row input { grid-row: 1 / span 2; align-self: center; width: 16px; height: 16px; margin: 0; cursor: pointer; }
.tidy-row.nested { padding-left: 34px; }
.tidy-proc { grid-column: 2 / -1; }
.tidy-proc:empty { display: none; }
.tidy-row .tidy-proc:empty ~ input { grid-row: 1; }
.tidy-proc { font-weight: 650; font-size: 14px; }
.tidy-field { font-size: 10px; font-weight: 750; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.tidy-delta { font-size: 13px; line-height: 1.45; }
.tidy-delta s { color: var(--muted); }
.tidy-delta b { color: var(--ok, #15704b); font-weight: 640; }
.tidy-arrow { color: var(--muted); }
.tidy-row input:not(:checked) ~ * { opacity: .4; }

.tidy-group-head { display: flex; align-items: center; gap: 10px; padding: 9px 12px 3px; cursor: pointer; }
.tidy-group-head input { width: 16px; height: 16px; margin: 0; cursor: pointer; flex: 0 0 auto; }
.tidy-group-head b { font-size: 14px; }
.tidy-n { margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---- multi-select for a technique's services ---------------------------------------------- */
/* A technique belongs to several services at once, so this is a set of toggles rather than a
   dropdown — the whole point is that more than one can be true. */
.sys-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.sys-chip {
  appearance: none; border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  font: inherit; font-size: 12.5px; font-weight: 640; padding: 5px 11px; border-radius: var(--pill);
  cursor: pointer; transition: background .12s, border-color .12s, color .12s;
}
.sys-chip:hover { border-color: var(--accent); color: var(--accent); }
.sys-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.sys-chip.on:hover { background: var(--accent); color: #fff; }


/* Share glyph, inlined so the button needs no network and no icon font. */
:root { --share-ico: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 16V3'/%3E%3Cpath d='M8 7l4-4 4 4'/%3E%3Cpath d='M4 13v6a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-6'/%3E%3C/svg%3E"); }

/* Chips on the share preview, mirroring the public card. */
.sp-chips { display: flex; flex-wrap: wrap; gap: 5px; margin: 6px 0 2px; }
.sp-chip { font-size: 11px; font-weight: 700; padding: 2px 9px; border-radius: var(--pill);
  background: var(--accent-soft); color: var(--accent); letter-spacing: .01em; }
.sp-chip:not(:first-child) { background: transparent; color: var(--ink-3); border: 1px solid var(--line); }

/* ---- storage readout -------------------------------------------------------------------- */
.stbar { height: 8px; border-radius: 5px; background: var(--line); overflow: hidden; margin: 8px 0 10px; }
.stbar i { display: block; height: 100%; background: var(--accent); border-radius: 5px; transition: width .3s; }
.stbar.warn i { background: var(--warn, #a8500a); }
.stbar.bad i { background: var(--danger, #b4231a); }
.strow { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 5px 0;
  border-bottom: 1px solid var(--line-2); }
.strow:last-child { border-bottom: none; }
.strow b { font-weight: 640; }
.strow span { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- techniques: list view -----------------------------------------------------------------
   The same folders as the grid, at higher density — Finder's list view is still a hierarchy, not
   a flat dump of every file. Rows expand in place rather than navigating away. */
.sys-list { border: 1px solid var(--line); border-radius: var(--r-sm); overflow: hidden; background: var(--surface); }
.sys-row { display: flex; align-items: center; gap: 9px; padding: 11px 13px; cursor: pointer;
  border-top: 1px solid var(--line-2); transition: background .12s; }
.sys-row:first-child { border-top: none; }
.sys-row:hover { background: var(--accent-soft); }
.sys-row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.sys-chev { color: var(--muted); font-size: 17px; line-height: 1; width: 12px; text-align: center;
  transition: transform .16s ease; }
.sys-row.open .sys-chev { transform: rotate(90deg); }
.sys-folder { color: var(--accent); display: flex; width: 19px; height: 19px; flex: 0 0 auto; }
.sys-folder svg { width: 100%; height: 100%; }
.sys-name { font-weight: 650; font-size: 14.5px; }
.sys-count { margin-left: auto; font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

.sys-kids { display: none; background: var(--bg-2, #f7f9fd); }
.sys-kids.open { display: block; }
.sys-kid { display: flex; align-items: center; gap: 9px; padding: 9px 13px 9px 42px; cursor: pointer;
  border-top: 1px solid var(--line-2); font-size: 14px; }
.sys-kid:hover { background: var(--accent-soft); }
.sys-kid-name { flex: 1; min-width: 0; }

/* ---- technique tidy-up preview -------------------------------------------------------------- */
.tidy-item { border: 1px solid var(--line); border-radius: var(--r-sm); padding: 11px 13px; margin-bottom: 9px; }
.tidy-item > b { font-size: 14.5px; }
.tidy-chg { display: flex; gap: 8px; align-items: baseline; font-size: 13px; margin-top: 6px; flex-wrap: wrap; }
.tidy-field { font-size: 10.5px; font-weight: 750; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); flex: 0 0 auto; min-width: 62px; }
.tidy-from { color: var(--muted); text-decoration: line-through; }
.tidy-to { color: var(--ok, #15704b); font-weight: 640; }

/* "+ Add" reads as an action rather than another service you could pick. */
.sys-chip.add { border-style: dashed; color: var(--muted); font-weight: 600; }
.sys-chip.add:hover { border-style: solid; border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

/* Two cleanup passes, one section. The row keeps each button beside the thing it acts on, so the
   difference between them (free/rule-based vs AI/costs money) is readable at a glance. */
.cleanrow { display: flex; gap: 14px; align-items: flex-start; padding: 12px 0;
  border-top: 1px solid var(--line-2); }
.cleanrow:first-of-type { border-top: none; padding-top: 4px; }
.cleanrow-t { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.cleanrow-t > b { font-size: 14.5px; }
.cleanrow > .btn { flex: 0 0 auto; margin-top: 2px; min-width: 116px; justify-content: center; }
@media (max-width: 560px) {
  .cleanrow { flex-direction: column; gap: 8px; }
  .cleanrow > .btn { align-self: flex-start; }
}

/* Per-change selection. Rejecting one rename should not force you to reject the section headings
   alongside it, so every row is independently selectable and the technique header is a tri-state. */
.tidy-head { display: flex; align-items: center; gap: 9px; cursor: pointer; }
.tidy-head input { width: 16px; height: 16px; margin: 0; cursor: pointer; flex: 0 0 auto; }
.tidy-chg { cursor: pointer; }
.tidy-chg input { width: 15px; height: 15px; margin: 0; cursor: pointer; flex: 0 0 auto; }
.tidy-chg:hover { background: var(--accent-soft); border-radius: 6px; }
.tidy-chg input:not(:checked) ~ span { opacity: .42; }

/* A procedure name is longer than "cases" — let the tile label wrap to two lines and clamp there,
   rather than forcing the row out of alignment. */
.att-stat span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; line-height: 1.25; }

/* ---- progress: lead with the gap ------------------------------------------------------------ */
.prog-met { margin-top: 10px; border-top: 1px solid var(--line); padding-top: 4px; }
.prog-met > summary { cursor: pointer; padding: 8px 2px; font-size: 13.5px; color: var(--muted);
  font-weight: 640; list-style: none; display: flex; align-items: center; gap: 7px; }
.prog-met > summary::-webkit-details-marker { display: none; }
.prog-met > summary::before { content: "›"; font-size: 16px; transition: transform .16s; }
.prog-met[open] > summary::before { transform: rotate(90deg); }
.prog-met > summary:hover { color: var(--accent); }
.prog-allmet { padding: 10px 2px; color: var(--ok, #15704b); font-weight: 640; font-size: 14px; }
.prog-foot { margin: 16px 2px 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* A prompt that waits for the right moment. Dismissible, and never shown again once answered —
   a nudge you have to decline twice is an advert. */
.nudge { border: 1px solid var(--accent); background: var(--accent-soft); border-radius: var(--r-sm);
  padding: 13px 15px; margin-bottom: 12px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  font-size: 14px; line-height: 1.5; }
.nudge > div:first-child { flex: 1; min-width: 220px; }
.nudge-act { display: flex; gap: 8px; flex: 0 0 auto; }

/* Features that are shipped but still being proven. Honest labelling costs nothing and buys the
   right to iterate in front of real users. */
.tag-preview { font-size: 10.5px; font-weight: 750; letter-spacing: .06em; text-transform: uppercase;
  color: var(--warn, #a8500a); background: var(--warn-soft, #fdf1e2); border-radius: 20px;
  padding: 2px 8px; vertical-align: 3px; margin-left: 6px; }

/* Suggested add — offered, never pre-ticked. Something that can leave the case and end up on a
   shareable card has to be a deliberate act, the same rule the share picker follows. */
.pref-offer { display: flex; gap: 10px; align-items: flex-start; padding: 11px 13px;
  border: 1px dashed var(--accent); background: var(--accent-soft); border-radius: var(--r-sm); cursor: pointer; }
.pref-offer input[type="checkbox"] {
  -webkit-appearance: auto; appearance: auto;
  width: 18px; height: 18px; min-height: 0; flex: none;
  padding: 0; margin: 1px 0 0; border: none; border-radius: 0; box-shadow: none;
  accent-color: var(--accent); cursor: pointer;
}
.pref-offer > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.pref-offer b { font-size: 14px; }
.pref-quote { font-size: 13.5px; color: var(--ink); font-style: italic; }

/* The attending chip on a case card opens that attending. Made visibly interactive so it reads as
   a target rather than being a hidden trapdoor inside the card's own click area. */
.chip.att-jump { cursor: pointer; transition: background .12s, color .12s; }
.chip.att-jump:hover { background: var(--accent); color: #fff; }
.chip.att-jump:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* A row can carry more than one action — keep them together on the right rather than letting the
   flex row break them onto separate lines. */
.cleanrow-btns { display: flex; gap: 6px; flex: 0 0 auto; margin-top: 2px; }
/* An <a> styled as a button still inherits link underlines from the surrounding prose. */
a.btn { text-decoration: none; }

/* ---- lock & security spacing ---------------------------------------------------------------
   Save sat directly beneath the PIN box on a negative margin, so the whole block read as one
   smudge. Put Save on the same line as the field it saves, and give the lock buttons their own
   breathing room below. */
.pinrow { display: flex; gap: 8px; align-items: stretch; }
.pinrow .pw-wrap, .pinrow > input { flex: 1; min-width: 0; }
.pinrow > .btn { flex: 0 0 auto; }
.field > label > span { font-size: 12.5px; font-weight: 640; color: #3b4557; }
.lockrow { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; align-items: center; }

/* ---- iOS focus zoom ---------------------------------------------------------------------------
   iOS Safari zooms the page whenever a focused field is under 16px, and ignores maximum-scale.
   The previous attempt at this used bare element selectors (`input, textarea { … }`), which lose
   to every class-scoped rule in this file — so it changed nothing and the zoom persisted.
   These mirror the exact selectors that set a smaller size, at equal specificity but later in the
   cascade, so they win. Desktop sizing is untouched, and the lock screen's deliberately large PIN
   field is left alone rather than being shrunk to 16px. */
@media (pointer: coarse) {
  /* EVERY text-entry field, not a hand-maintained list of them. The list approach was wrong three
     separate times — the search box, the technique section editor, both import paste boxes — because
     a field added later has no reason to know the list exists, and a class-scoped rule quietly
     outranks a bare element selector. !important is the point: losing the specificity race IS the
     bug. Audit with: every input/textarea/select computed font-size must be >= 16 at coarse pointer. */
  /* :where() so the exclusions cost no specificity — with :not() this rule outranked .lockbox input
     below and shrank the PIN field to 16px. */
  input:where(:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file])),
  textarea, select { font-size: 16px !important; }
  /* The one field deliberately larger than that: PIN / unlock entry. */
  .lockbox input { font-size: 22px !important; }
}

/* An identifier that was deliberately dropped, not one that is missing. Reads as a state,
   not as an empty field the user forgot to fill. */
.mrn-gone { opacity: .55; font-style: italic; }

/* The shared key is typed by hand into a phone, so it is set wide and grouped — a dense
   32-character string in body type is genuinely hard to transcribe without losing your place. */
.mfa-key {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px; letter-spacing: .12em; word-spacing: .3em; word-break: break-all;
  background: var(--sunk, rgba(127,127,127,.09)); border-radius: 8px;
  padding: 10px 12px; margin-top: 8px; user-select: all;
}
.mfa-code { width: 8em; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 16px; letter-spacing: .18em; text-align: center; }

/* Sign-in history. Scrolls rather than growing without bound — 200 entries in a settings
   sheet would bury everything below it. */
.activity-list { margin-top: 10px; max-height: 300px; overflow-y: auto;
  border: 1px solid var(--rule, rgba(127,127,127,.22)); border-radius: 8px; }
.activity-row { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 8px 11px; border-bottom: 1px solid var(--rule-soft, rgba(127,127,127,.12)); font-size: 13px; }
.activity-row:last-child { border-bottom: none; }
.activity-row .a-when { font-variant-numeric: tabular-nums; min-width: 12em; }
.activity-row .a-where { opacity: .6; font-size: 12px; margin-left: auto; }
.activity-row.bad .a-what { color: var(--bad, #b3402f); }

/* The QR keeps a white ground of its own regardless of theme — a scanner needs the contrast the
   code was generated with, not the page's. */
.mfa-qr { margin-top: 10px; display: inline-block; line-height: 0;
  background: #fff; padding: 8px; border-radius: 10px;
  border: 1px solid var(--rule, rgba(127,127,127,.22)); }
.mfa-qr svg { display: block; }

/* ---- combobox (see js/combo.js) --------------------------------------------------------- */
/* Fixed and body-mounted, so it escapes the .sheet's overflow-y:auto rather than being
   clipped or shoved to the viewport edge the way the native datalist popup was.
   z-index sits above the settings overlay (60), below the lockscreen. */
.combo-pop { position: fixed; z-index: 70; overflow-y: auto; -webkit-overflow-scrolling: touch;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  box-shadow: var(--sh-lg); padding: 5px; }
.combo-opt { padding: 10px 11px; border-radius: 7px; font-size: 15px; color: var(--ink);
  cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.combo-opt:hover, .combo-opt.on { background: var(--accent-soft); color: var(--accent); }
