/* ---------------------------------------------------------------- tokens --
   Ambient dark shell over a full-bleed backdrop, with glass panels above it.
   The backdrop is a gradient standing in for a photograph — swap --bg-image for
   a url() and the rest still works, which is why the glass reads from a
   translucent white rather than from a fixed surface colour. */
:root{
  /* The member app is the roomier of the two: the same .btn from ui.css, bigger. */
  --control-pad-y:var(--space-3); --control-pad-x:var(--space-4); --control-text:var(--text-sm);
  /* The palette is ui.css's default palette (the FORx Dark preset), overridden by
     /theme.css. Only what is the member app's own is here. */

  /* White at the top warming to Azalea and Supernova low down — the guide's own
     light-and-warm feel. Swap --bg-image for a url() and the surfaces still work. */
  --bg-image:
    radial-gradient(80% 50% at 82% 92%, rgba(246,191,178,.34) 0%, transparent 64%),
    radial-gradient(70% 45% at 18% 96%, rgba(255,97,91,.20) 0%, transparent 62%),
    radial-gradient(115% 70% at 24% 2%, #062044 0%, transparent 58%),
    linear-gradient(174deg, #000E29 0%, #04193a 20%, #0b2a52 40%, #40355a 60%, #8a5560 76%, #c2836c 90%, #f6bfb2 100%);

  --alert-fill:color-mix(in srgb,var(--alert) 18%,transparent);
  --warn-fill:rgba(255,97,91,.13);
  --warn-edge:rgba(246,191,178,.30);

  /* Typography default. Overridden by /theme.css when the operator has set it in
     Branding; declared here so the page renders correctly with no database, and so the
     stack always ends in a generic family — a webfont that fails to load must fall back
     to the system sans, not to Times. */
  --font-body:Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --rail:284px;
  /* A card's inset: sources, courses, the account and team cards, SOPs, quizzes. */
  --pad-card:var(--pad-container) var(--space-5);
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;color:var(--ink);background:var(--bg);overflow-x:hidden;
  font:calc(var(--text-md) * var(--font-scale))/1.55 var(--font-body);
  -webkit-font-smoothing:antialiased;
}
/* Keeps text legible whatever photograph lands here later. */
/* Just enough to hold text contrast at the top; the lower stop stays light so the
   warm horizon survives rather than being flattened to navy. */
#veil{position:fixed;inset:0;z-index:var(--z-veil);pointer-events:none;
  background:linear-gradient(180deg,color-mix(in srgb,var(--surface-solid) 46%,transparent) 0%,color-mix(in srgb,var(--surface-solid) 10%,transparent) 34%,color-mix(in srgb,var(--surface-solid) 16%,transparent) 100%)}
button,input,select,textarea{font:inherit;color:inherit}
a{color:inherit;text-decoration:none}
::selection{background:rgba(255,180,56,.45)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-xs)}

/* ---------------------------------------------------------------- topbar -- */
.topbar{position:sticky;top:0;z-index:var(--z-topbar);display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);
  transition:background .2s}
/* Once the page scrolls, the header gets a ground of its own: a long chat ran its text
   straight under the logo and the plan picker. */
.topbar.scrolled{background:color-mix(in srgb,var(--surface-solid) 80%,transparent);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.iconbtn{display:grid;place-items:center;width:38px;height:38px;border:0;border-radius:11px;
  background:transparent;cursor:pointer;color:var(--ink);transition:background .15s}
.iconbtn:hover{background:var(--glass-2)}
.brand{display:flex;align-items:center;gap:var(--space-2);font-weight:650;letter-spacing:-.01em}
/* A logo replaces the generated initials block. Both limits are max-*, with width and
   height auto, so the browser scales to whichever binds first and keeps proportions; a
   fixed height plus max-width stretched a wordmark wider than the limit. */
.brand img.logo{max-width:300px}
/* Hidden until /api/theme has answered, so the header never flashes generated initials
   and then swaps them for the logo. applyBranding() reveals it — and boot() does too, so
   a failed fetch still ends with a visible header. */
.brand:not(.ready){visibility:hidden}
.drawerfoot{margin-top:var(--space-4);padding:var(--space-3) var(--space-3) var(--space-1);border-top:var(--hairline);
  font-size:var(--text-xs);line-height:1.5;color:var(--ink-3);white-space:pre-wrap;word-break:break-word}
.plan{display:flex;align-items:center;gap:var(--space-2);background:var(--glass-2);border:var(--hairline);
  border-radius:var(--radius-pill);padding:var(--space-1) var(--space-2) var(--space-1) var(--space-3);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.plan span{font-size:var(--text-xs);color:var(--ink-3)}
.plan select{background:transparent;border:0;outline:0;font-weight:640;font-size:var(--text-sm);cursor:pointer}
.plan select option{background:#12222f;color:var(--ink)}

/* ---------------------------------------------------------------- drawer -- */
.scrim{position:fixed;inset:0;z-index:var(--z-scrim);background:color-mix(in srgb,var(--surface-solid) 28%,transparent);opacity:0;pointer-events:none;
  transition:opacity .22s;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}
.scrim.on{opacity:1;pointer-events:auto}
.drawer{position:fixed;left:0;top:0;bottom:0;width:var(--rail);z-index:var(--z-drawer);
  transform:translateX(-102%);transition:transform .26s var(--ease-sheet);
  /* --nav-* come from Branding and are BLANK by default, so the second value in each
     var() is what has always rendered here. An install that never opens the editor is
     byte-identical to before. */
  background:var(--nav-bg,rgba(10,20,30,.86));border-right:1px solid var(--nav-edge,var(--edge));
  backdrop-filter:var(--blur-sheet);-webkit-backdrop-filter:var(--blur-sheet);
  padding:var(--space-3) var(--space-3);overflow-y:auto;box-shadow:var(--shadow);color:var(--nav-ink,inherit)}
.drawer.on{transform:none}
.drawer h4{margin:var(--space-4) var(--space-3) var(--space-2);font-size:var(--text-xs);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--ink-3)}
.navitem{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-3);border:0;
  border-radius:var(--r-2,10px);
  background:transparent;cursor:pointer;text-align:left;font-size:var(--text-md);
  color:var(--nav-ink,var(--ink-2))}
.navitem:hover{background:var(--glass-2);color:var(--nav-ink,var(--ink))}
.navitem.on{background:var(--nav-active-bg,var(--glass-hi));
  color:var(--nav-active-ink,var(--ink));font-weight:620}
.navitem .dot{width:8px;height:8px;border-radius:3px;flex:none}
.navitem .cnt{margin-left:auto;font:var(--text-xs)/1 var(--font-mono);color:var(--ink-3)}
.drawer .tags{display:flex;flex-wrap:wrap;gap:var(--space-1);padding:var(--space-0) var(--space-3) var(--space-3)}
.tagmini{font-size:var(--text-xs);padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);background:var(--glass-2);
  border:var(--hairline);color:var(--ink-2);cursor:pointer}
.tagmini:hover{border-color:var(--edge-2)}
.tagmini.on{background:var(--accent);border-color:transparent;color:var(--accent-ink);font-weight:620}

/* ------------------------------------------------------------------ hero -- */
/* clip, not hidden: it trims the composer's full-width wash at the window's edge without
   making main a scroll container, which would stop the composer from sticking. */
main{padding:0 var(--space-5) var(--space-9);min-width:0;overflow-x:clip}
.hero{max-width:860px;margin:0 auto;padding:clamp(var(--space-5),8vh,var(--space-9)) 0 0;text-align:center}
.greet{font-size:var(--text-display);font-weight:600;letter-spacing:-.02em;line-height:1.22;
  margin:0 0 var(--space-5)}
.greet .second{display:block;font-weight:450;color:var(--ink-2)}
.askbox{background:var(--glass);border:var(--hairline);border-radius:26px;
  backdrop-filter:blur(26px) saturate(150%);-webkit-backdrop-filter:blur(26px) saturate(150%);
  box-shadow:var(--shadow);padding:var(--space-2) var(--space-2) var(--space-2) 0;text-align:left;
  transition:border-color .16s, box-shadow .16s}
.askbox:focus-within{border-color:var(--edge-2);box-shadow:var(--shadow),var(--ring)}
.askbox textarea{width:100%;background:transparent;border:0;outline:0;resize:none;
  padding:var(--space-4) var(--space-4) var(--space-2);font-size:var(--text-md);line-height:1.5;max-height:180px}
.askbox textarea::placeholder{color:var(--ink-3)}
.askrow{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-0) var(--space-2) var(--space-1) var(--space-4)}
.send{margin-left:auto;display:grid;place-items:center;width:38px;height:38px;border:0;border-radius:50%;
  background:var(--btn-bg);color:var(--btn-ink);cursor:pointer;transition:transform .14s,opacity .14s}
.send:hover{transform:scale(1.06)}
.send:disabled{opacity:.4;cursor:default;transform:none}
.suggest{display:flex;flex-wrap:wrap;gap:var(--space-2);justify-content:center;margin-top:var(--space-5)}
.sug{padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);background:var(--glass-2);border:var(--hairline);
  color:var(--ink-2);font-size:var(--text-sm);cursor:pointer;transition:all .15s;
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.sug:hover{background:var(--glass-hi);color:var(--ink);border-color:var(--edge-2);transform:translateY(-1px)}

/* ----------------------------------------------------------------- decks -- */
.decks{display:grid;grid-template-columns:repeat(auto-fit,minmax(288px,1fr));gap:var(--space-4);
  max-width:1220px;margin:clamp(var(--space-6),7vh,var(--space-8)) auto 0}
.deck{background:var(--panel-bg);border:var(--panel-border);border-radius:var(--panel-radius);padding:var(--space-4) var(--space-4) var(--space-3);
  backdrop-filter:var(--panel-blur);-webkit-backdrop-filter:var(--panel-blur);
  box-shadow:var(--panel-shadow);min-height:196px;display:flex;flex-direction:column}
.deck.fit{min-height:auto}
.deckhead{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-3);color:var(--ink-2)}
.deckhead h3{margin:0;font-size:var(--text-sm);font-weight:620}
.deckhead .n{margin-left:auto;font:var(--text-xs)/1 var(--font-mono);color:var(--ink-3)}
.deckrow{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2);border-radius:11px;cursor:pointer;
  transition:background .14s}
.deckrow:hover{background:var(--glass-2)}
.deckrow .ico{width:34px;height:34px;border-radius:9px;flex:none;display:grid;place-items:center;
  font:700 var(--text-xs)/1 var(--font-mono);color:#fff;text-shadow:0 1px 4px rgba(0,0,0,.5)}
.deckrow .ico.plain{background:rgba(255,255,255,.09)}
.deckrow .txt{min-width:0;flex:1}
.deckrow .t1{font-size:var(--text-sm);font-weight:560;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.deckrow .t2{font-size:var(--text-xs);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.deck .none{flex:1;display:grid;place-items:center;text-align:center;color:var(--ink-3);
  font-size:var(--text-sm);padding:var(--space-4) var(--space-2);line-height:1.5}
.bar{height:4px;border-radius:var(--radius-bar);background:var(--glass-2);overflow:hidden;margin-top:var(--space-1)}
.bar i{display:block;height:100%;background:var(--accent);border-radius:var(--radius-bar)}
.cert{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-2);border-radius:11px}
.cert .seal{width:34px;height:34px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:linear-gradient(135deg,var(--brand-amber),var(--brand-coral));color:var(--brand-dark)}

/* ---------------------------------------------------------------- shared -- */
.wrap{max-width:1220px;margin:0 auto}
.crumb{display:flex;align-items:center;gap:var(--space-3);margin:var(--space-2) 0 var(--space-4);font-size:var(--text-sm);color:var(--ink-3)}
.crumb button{background:none;border:0;color:var(--accent-text);cursor:pointer;padding:0;font-weight:620;white-space:nowrap}
.sectitle{font-size:var(--text-md);font-weight:620;margin:0 0 var(--space-4);display:flex;align-items:center;gap:var(--space-2)}
.sectitle small{font-weight:450;color:var(--ink-3);font-size:var(--text-sm)}
/* A second heading on a page, after the cards of the first. */
.sectitle.next{margin-top:var(--space-6)}
.chipwrap{position:relative}
/* Arrows for the course and topic banner. It scrolls sideways, and with a mouse there is
   otherwise no visible way to reach the chips past the right edge. */
.chipnav{position:absolute;top:2px;z-index:2;width:34px;height:34px;border-radius:50%;
  border:var(--hairline);background:var(--surface-solid);color:var(--ink);
  display:none;place-items:center;cursor:pointer;box-shadow:0 4px 14px rgba(0,0,0,.25)}
.chipnav:hover{background:var(--glass-hi)}
.chipnav.prev{left:-6px}
.chipnav.next{right:-6px}
.chipwrap.more .chipnav.next,.chipwrap.less .chipnav.prev{display:grid}
.chipwrap.less::before{content:"";position:absolute;left:0;top:0;bottom:14px;width:52px;pointer-events:none;z-index:1;
  background:linear-gradient(to left,transparent,color-mix(in srgb,var(--surface-solid) 72%,transparent))}
/* The Library's search bar: a course picker and free text, side by side. */
.libbar{display:flex;gap:var(--gap-inline);flex-wrap:wrap;align-items:center}
/* Every page says where you are: a title and one line about what is on it. */
.pagehead h1{margin:0;font-size:var(--text-xl);font-weight:700;letter-spacing:-.02em;line-height:1.15}
.pagehead p{margin:var(--space-1) 0 0;color:var(--ink-3);font-size:var(--text-md)}
/* Lessons | Courses on the Library page. */
.tabs{display:inline-flex;gap:var(--space-1);padding:var(--space-1);border-radius:var(--radius-pill);background:var(--glass-2);
  border:var(--hairline)}
.tabs button{border:0;background:none;color:var(--ink-2);padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);
  font-size:var(--text-md);font-weight:600;cursor:pointer;display:inline-flex;gap:var(--space-2);align-items:center}
.tabs button .n{font-size:var(--text-sm);color:var(--ink-3);font-weight:500}
.tabs button.on{background:var(--accent);color:var(--accent-ink)}
.tabs button.on .n{color:var(--accent-ink);opacity:.75}
.poplabel{font-size:var(--text-xs);font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);margin-bottom:var(--space-2)}
.suggest .poplabel{flex-basis:100%;text-align:center;margin:0}
.filterchip{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-2) var(--space-2) var(--space-4);border-radius:var(--radius-pill);
  background:var(--accent-soft);border:var(--hairline);font-size:var(--text-sm)}
.filterchip button{border:0;background:var(--glass-2);color:var(--ink);width:22px;height:22px;
  border-radius:50%;cursor:pointer;font-size:var(--text-sm);line-height:1}
.libbar .lsearch{flex:1 1 280px;position:relative;min-width:0}
.libbar .lsearch svg{position:absolute;left:14px;top:50%;transform:translateY(-50%);color:var(--ink-3);pointer-events:none}
.libbar input,.libbar select{background:var(--field-bg);border:var(--field-border);border-radius:var(--radius-pill);
  padding:var(--space-3) var(--space-4);outline:0;font-size:var(--text-md);color:var(--field-ink)}
.libbar input{width:100%;padding-left:var(--space-7)}
.libbar select{flex:0 1 300px;min-width:180px;cursor:pointer}
.libbar input:focus,.libbar select:focus{border-color:var(--field-focus)}
/* The Courses page: one card per course, with progress. */
.sources{padding:var(--pad-card);display:flex;flex-direction:column;gap:var(--space-3)}
.sources .srchead{font-size:var(--text-xs);font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
.src{display:flex;flex-direction:column;gap:var(--space-1);padding-left:var(--space-3);border-left:2px solid var(--accent)}
.src.stale{border-left-color:var(--warn-text)}
.src .st{font-weight:640;font-size:var(--text-md)}
.src .sm{font-size:var(--text-sm);color:var(--ink-3)}
.src .sw{font-size:var(--text-sm);color:var(--warn-text)}
.src a{font-size:var(--text-sm);color:var(--accent-text);text-underline-offset:2px}
.src .btn.link{align-self:flex-start;font-size:var(--text-sm)}
.coursegrid{display:grid;gap:var(--space-4);grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.coursecard{background:var(--glass);border:var(--hairline);border-radius:var(--radius-xl);overflow:hidden;cursor:pointer;
  display:flex;flex-direction:column;text-align:left;padding:var(--pad-card);color:inherit;font:inherit}
.coursecard:hover{border-color:var(--accent)}
.coursecard .cthumb{height:92px;display:flex;align-items:flex-end;padding:var(--space-3) var(--space-4);
  font-size:var(--text-sm);font-weight:700;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.4)}
.coursecard .cbody{padding:var(--space-3) var(--space-4) var(--space-4);display:flex;flex-direction:column;gap:var(--space-2)}
.coursecard .ct{font-size:var(--text-md);font-weight:640;line-height:1.3}
.coursecard .cs{font-size:var(--text-sm);color:var(--ink-3)}
.chipwrap::after{content:"";position:absolute;right:0;top:0;bottom:14px;width:52px;pointer-events:none;
  background:linear-gradient(to right,transparent,color-mix(in srgb,var(--surface-solid) 72%,transparent));opacity:0;transition:opacity .18s}
.chipwrap.more::after{opacity:1}
.chiprow{display:flex;gap:var(--space-2);overflow-x:auto;padding-bottom:var(--space-4);scrollbar-width:none;scroll-behavior:smooth}
.chiprow::-webkit-scrollbar{display:none}
.chip{flex:none;padding:var(--space-2) var(--space-4);border-radius:var(--radius-pill);background:var(--glass-2);border:var(--hairline);
  font-size:var(--text-sm);cursor:pointer;white-space:nowrap;color:var(--ink-2)}
.chip:hover{background:var(--glass-hi);color:var(--ink)}
.chip.on{background:var(--accent);color:var(--accent-ink);font-weight:640;border-color:transparent}
.grid{display:grid;gap:var(--space-5) var(--space-4);grid-template-columns:repeat(auto-fill,minmax(258px,1fr))}
.card{cursor:pointer;display:flex;flex-direction:column;gap:var(--space-3)}
.thumb{position:relative;aspect-ratio:16/9;border-radius:13px;overflow:hidden;display:grid;place-items:center;
  transition:transform .18s ease,box-shadow .18s ease;border:var(--hairline)}
.card:hover .thumb{transform:translateY(-3px);box-shadow:var(--shadow)}
.thumb .glyph{font:var(--heading-weight) var(--text-md)/1.3 var(--font-heading);color:#fff;opacity:.97;padding:var(--space-4);
  text-align:center;text-shadow:0 1px 12px rgba(0,0,0,.5);max-width:92%}
.thumb .play{position:absolute;inset:0;display:grid;place-items:center;opacity:0;
  background:color-mix(in srgb,var(--surface-solid) 32%,transparent);transition:opacity .16s}
.card:hover .play{opacity:1}
.badge{position:absolute;right:7px;bottom:7px;background:color-mix(in srgb,var(--surface-solid) 82%,transparent);color:#fff;
  font:600 var(--text-xs)/1 var(--font-mono);padding:var(--space-1) var(--space-2);border-radius:5px}
.badge.range{left:7px;right:auto;background:var(--accent);color:var(--accent-ink)}
.tick-done{position:absolute;left:7px;top:7px;width:22px;height:22px;border-radius:50%;
  background:var(--accent);color:var(--brand-dark);display:grid;place-items:center}
.ctitle{font-weight:600;font-size:var(--text-md);line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;
  -webkit-box-orient:vertical;overflow:hidden}
.csub{font-size:var(--text-sm);color:var(--ink-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ctags{display:flex;gap:var(--space-1);flex-wrap:wrap;margin-top:var(--space-1)}
.ctag{font-size:var(--text-xs);padding:var(--space-0) var(--space-2);border-radius:var(--radius-pill);background:var(--glass-2);color:var(--ink-3)}
/* Lesson stills (D-53). Served by this server from /api/thumb, behind the lesson's own
   entitlement; the browser never asks Vimeo. The generated gradient stays underneath as
   the fallback, so a lesson with no still, or one that fails, looks as it always did.
   The still is the first child, so the play overlay, badges and tick paint over it. */
.still{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .28s ease}
.still.in{opacity:1}
.thumb.has-still .glyph{visibility:hidden}
.cthumb{position:relative;overflow:hidden}
.cthumb .clabel{position:relative;z-index:2}
.cthumb.has-still::after,.player.has-still::after{content:"";position:absolute;inset:0;z-index:1;
  pointer-events:none;background:linear-gradient(to top,rgba(0,0,0,.6),rgba(0,0,0,0) 65%)}
.player.has-still::after{background:rgba(0,0,0,.45)}

/* ---------------------------------------------------------------- answer -- */
.answer{padding:var(--space-5);margin-bottom:var(--space-5)}
.ahead{display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-3)}
.avatar{width:30px;height:30px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:linear-gradient(135deg,var(--brand-coral),var(--brand-amber));color:var(--brand-dark);font-weight:800;font-size:var(--text-xs)}
/* The initials on a sign-in screen with no logo. */
.avatar.lockmark{margin:0 auto;width:38px;height:38px;font-size:var(--text-sm)}
.ahead b{font-size:var(--text-sm);font-weight:640}
.ahead .q{color:var(--ink-3);font-size:var(--text-sm);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.atext{font-size:var(--text-md);line-height:1.65;white-space:pre-wrap}
.atext.none{color:var(--ink-2)}
.ameta{display:flex;gap:var(--space-2);flex-wrap:wrap;align-items:center;margin-top:var(--space-4);padding-top:var(--space-3);
  border-top:var(--hairline);font:var(--text-xs)/1 var(--font-mono);color:var(--ink-3)}
.tick{padding:var(--space-1) var(--space-2);border-radius:var(--radius-pill);background:var(--glass-2)}
.tick.route{background:var(--accent-soft);color:var(--warn-text);font-weight:700}

/* ------------------------------------------------------------------ chat --
   Home becomes a conversation once a question is asked (D-55): each turn is the
   member's question as a bubble, then Vera's answer and the helpful videos side by side
   on a desktop, stacked on anything narrower. The composer is pinned to the bottom of
   the viewport so a follow-up is always one keystroke away. */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}
/* At least a screen tall, so the composer sits at the bottom even under one short turn. */
.chat{max-width:1220px;margin:0 auto;padding-top:var(--space-2);display:flex;flex-direction:column;
  min-height:calc(100vh - 140px)}
.chathead{display:flex;align-items:center;gap:var(--gap-inline);flex-wrap:wrap}
.chathead h1{margin:0;flex:1 1 220px;min-width:0;font-size:var(--text-md);font-weight:640;color:var(--ink-2);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.thread{display:flex;flex-direction:column;gap:var(--space-7);margin-top:var(--space-5);margin-bottom:var(--space-6)}
/* Below the sticky header when scrolled to, not under it. */
.turn{display:flex;flex-direction:column;gap:var(--space-4);scroll-margin-top:76px}
.ubub{align-self:flex-end;max-width:min(680px,88%);padding:var(--space-3) var(--space-4);border-radius:18px 18px 6px 18px;
  background:var(--accent-soft);border:var(--hairline);font-size:var(--text-md);line-height:1.5;
  white-space:pre-wrap;overflow-wrap:anywhere}
.tbody{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--gap-container);align-items:start}
@media (min-width:1024px){
  .tbody{grid-template-columns:minmax(0,3fr) minmax(0,2fr)}
  /* A plan without lesson videos (D-59): one answer column, no Helpful videos beside it. */
  .tbody.solo{grid-template-columns:minmax(0,1fr)}
}
.tbody .answer{margin:0}
.tbody .sources{margin-top:var(--space-4);padding:var(--space-4) 0 0;border-top:var(--hairline);gap:var(--space-2)}
.tbody .src .st{font-size:var(--text-sm)}
.vids .sectitle{margin-bottom:var(--gap-content)}
.vlist{display:flex;flex-direction:column;gap:var(--gap-content)}
.vids .none{color:var(--ink-3);font-size:var(--text-sm);padding:var(--space-3) 0}
.vids .none .btn.link{margin-top:var(--space-2);font-size:var(--text-sm)}
.tbody.solo .answer{max-width:820px}
/* The one honest upgrade line under such an answer. Small, and never in the answer text. */
.upline{margin-top:var(--space-4);padding-top:var(--space-3);border-top:1px dashed var(--edge);
  font-size:var(--text-sm);line-height:1.5;color:var(--ink-3)}
.upline a{color:inherit;text-decoration:underline;text-underline-offset:2px;white-space:nowrap}
/* "Vera · Powered by Front Office Rocks": the chat header, the hero and the sign-in box. */
.poweredby{font-size:var(--text-sm);line-height:1.4;color:var(--ink-3);letter-spacing:.01em}
.chathead .poweredby{flex:1 0 100%;order:3;margin-top:calc(var(--space-0) * -1)}
.hero .poweredby{text-align:center;margin:var(--space-2) auto var(--space-4)}
.lock .poweredby{margin:calc(var(--space-3) * -1) 0 var(--space-4)}
.upsell .actions{display:flex;flex-wrap:wrap;gap:var(--gap-inline);align-items:center;margin-top:var(--space-3)}
/* A clip card laid out as a row: the thumbnail on the left, its title beside it. Five
   full-width 16:9 cards stacked in a 40% column ran to well over a screen. */
.card.compact{flex-direction:row;align-items:flex-start;gap:var(--gap-content)}
.card.compact .thumb{flex:0 0 44%;max-width:188px}
/* The title is right beside it; in a small thumbnail it only collided with the badges. */
.card.compact .thumb .glyph{display:none}
.card.compact .badge{font-size:var(--text-xs);padding:var(--space-1) var(--space-1)}
.card.compact>div:last-child{flex:1;min-width:0}
.card.compact .ctitle{font-size:var(--text-md)}
.lcard{cursor:default}
.lcard .thumb{cursor:pointer}
.lcard:hover .thumb{transform:none;box-shadow:none}
.lcard .thumb:hover,.lcard .thumb:focus-visible{transform:translateY(-3px);box-shadow:var(--shadow)}
.lcard:hover .play{opacity:0}
.lcard .thumb:hover .play,.lcard .thumb:focus-visible .play{opacity:1}
.moments{margin-top:var(--space-2)}
.moments .tagmini{font-variant-numeric:tabular-nums;cursor:pointer}
.skelrow{display:flex;gap:var(--gap-content)}
.skelrow .skel.t{flex:0 0 44%;max-width:188px}
.skelrow>div{flex:1}
/* Thinking. A pulsing ring on Vera's avatar, three typing dots and a status line that
   names the real stage as it starts, with friendly lines in between. */
.avatar.think{position:relative}
.avatar.think::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:2px solid var(--accent);
  opacity:0;animation:vring 1.6s ease-out infinite}
@keyframes vring{0%{transform:scale(.85);opacity:.75}100%{transform:scale(1.35);opacity:0}}
.dots{display:inline-flex;gap:var(--space-1);align-items:center;flex:none}
.dots i{width:6px;height:6px;border-radius:50%;background:var(--ink-2);animation:vdot 1.2s infinite ease-in-out}
.dots i:nth-child(2){animation-delay:.15s}
.dots i:nth-child(3){animation-delay:.3s}
@keyframes vdot{0%,80%,100%{opacity:.25;transform:translateY(0)}40%{opacity:1;transform:translateY(-3px)}}
.thinking{display:flex;align-items:center;gap:var(--space-3);color:var(--ink-2);font-size:var(--text-md);min-height:24px}
.thinking .lbl{min-width:0;animation:vfade .35s ease}
.thinking .el{margin-left:auto;flex:none;font:var(--text-sm)/1 var(--font-mono);color:var(--ink-3)}
/* Never from fully transparent: a tab that is not painting holds an animation on its
   first frame, and the status line must still be readable there. */
@keyframes vfade{from{opacity:.45;transform:translateY(2px)}to{opacity:1;transform:none}}
.atext.arrive{animation:vfade .35s ease}
/* Both arrival fades are declared HERE, above the reduced-motion block, because a media
   query adds no specificity: the same selector written after it would win the cascade
   and animate for a viewer who asked for no motion. */
.expbody.arrive{animation:vfade .35s ease}
@media (prefers-reduced-motion:reduce){
  .avatar.think::after,.dots i,.thinking .lbl,.atext.arrive,.expbody.arrive{animation:none}
  .dots i{opacity:.6}
  .skel{animation:none}
  .still{transition:none}
}
.err.turnerr{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;margin:0}
.turnerr span{flex:1 1 220px}

/* --------------------------------------------------------------- expand --
   The step-by-step version of an answer (D-77): under the short answer, with its own toggle. */
.expand{margin-top:var(--space-4);padding-top:var(--space-3);border-top:var(--hairline);scroll-margin-top:var(--space-9)}
.expgo{display:flex;flex-wrap:wrap;align-items:center;gap:var(--gap-inline)}
.expnote{margin:0;font-size:var(--text-xs);color:var(--ink-3)}
.expnote.fallback{font-size:var(--text-md);color:var(--ink-2);line-height:1.65}
.expand .expnote+.expgo,.expand .turnerr+.expgo{margin-top:var(--space-2)}
.expand .thinking+.btn{margin-top:var(--space-2)}
.exphead{display:flex;align-items:center;justify-content:space-between;gap:var(--gap-inline);margin-bottom:var(--space-2)}
.exptitle{margin:0;font-size:var(--text-xs);font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}
/* "This one keeps it general — …": under the heading of a general version, above its
   body, so it is read before the content it qualifies. Quieter than the body and with no
   upgrade control of its own; the answer's own .upline below is the single one. */
.exproute{margin:0 0 var(--space-3);font-size:var(--text-sm);line-height:1.5;color:var(--ink-3)}
.expbody{font-size:var(--text-md);line-height:1.65}
.expbody .explead{margin:0 0 var(--space-3)}
.expbody p{margin:0 0 var(--space-2);white-space:pre-wrap}
.expbody h3{margin:var(--space-4) 0 var(--space-2);font-size:var(--text-md);font-weight:640}
/* Spaced the way every other list in the product is — margins, not a flex box. A
   display:flex list is dropped from the accessibility tree by some screen readers, and
   "list, 6 items" is most of what the Steps section is for. */
.expbody ol,.expbody ul{margin:0;padding-left:var(--space-5)}
.expbody li+li{margin-top:var(--space-2)}
.expfoot{display:flex;flex-wrap:wrap;gap:var(--gap-inline);margin-top:var(--space-3)}
@media (min-width:1024px){.expfoot .expvids{display:none}}
@media (max-width:720px){.expgo .expbtn{width:100%;justify-content:center}}
@media print{.expand [hidden]{display:none}}
/* The composer: the ask box, pinned to the bottom of the screen while chatting. The
   wash behind it keeps the thread from showing through the text. */
.composer{position:sticky;bottom:0;z-index:var(--z-sticky);margin-top:auto;padding:var(--space-5) 0 var(--space-3)}
/* The wash runs the full width of the window: drawn to the column's width it showed as a
   dark box with hard edges. */
.composer::before{content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;transform:translateX(-50%);
  z-index:-1;pointer-events:none;
  background:linear-gradient(to top,color-mix(in srgb,var(--surface-solid) 88%,transparent) 55%,transparent)}
.composer .askbox{max-width:860px;margin:0 auto}
.phinote{max-width:860px;margin:var(--space-2) auto 0;text-align:center;font-size:var(--text-sm);color:var(--ink-3)}
.hero .phinote{margin-top:var(--space-3)}
/* The drawer's Recent list: one line each, cut with an ellipsis, the full question in
   the tooltip. */
.navitem.recent{font-size:var(--text-sm);padding:var(--space-2) var(--space-3)}
.navitem .rt{min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.drawer .none{padding:var(--space-0) var(--space-3) var(--space-2);font-size:var(--text-sm);color:var(--ink-3)}
.recentmore{padding:var(--space-1) var(--space-3) var(--space-0)}
/* History page. */
.histlist{padding:var(--space-2) var(--pad-container)}
.hrow{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) 0;border-top:var(--hairline)}
.hrow:first-child{border-top:0}
.hrow .hopen{flex:1 1 180px;min-width:0;display:flex;flex-direction:column;gap:var(--space-0);text-align:left;
  background:none;border:0;padding:0;color:inherit;cursor:pointer}
.hrow .hopen b{display:block;font-weight:620;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hrow .hopen span{font-size:var(--text-sm);color:var(--ink-3)}
.hrow .hopen:hover b{color:var(--accent-text)}
.hrow.on .hopen b{color:var(--accent-text)}
.histnote{font-size:var(--text-sm);color:var(--ink-3)}

/* ----------------------------------------------------------------- watch -- */
.watch{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:var(--space-5);align-items:start}
@media (max-width:1100px){.watch{grid-template-columns:minmax(0,1fr)}}
.player{aspect-ratio:16/9;border-radius:var(--radius-xl);overflow:hidden;position:relative;display:grid;
  place-items:center;text-align:center;border:var(--hairline)}
.player .pmsg{position:relative;z-index:2;color:#fff;font-size:var(--text-sm);padding:var(--space-4);max-width:460px;
  text-shadow:0 1px 14px rgba(0,0,0,.6)}
.player .pmsg code{font:var(--text-sm)/1 var(--font-mono);background:rgba(0,0,0,.45);padding:var(--space-1) var(--space-2);border-radius:5px}
.pmsg .startnote{margin-top:var(--space-2);opacity:.85;font-size:var(--text-sm)}
/* Vimeo's player (D-55), over the generated gradient so a slow load still looks like
   the lesson rather than a black box. */
.player iframe{position:absolute;inset:0;width:100%;height:100%;border:0;z-index:3;background:#000}
.clipbar{display:flex;align-items:center;gap:var(--gap-inline);flex-wrap:wrap;margin-top:var(--space-3);
  font-size:var(--text-sm);color:var(--ink-2)}
.clipbar .mk{font:600 var(--text-sm)/1 var(--font-mono);color:var(--accent-text);padding:var(--space-1) var(--space-2);border-radius:var(--radius-pill);
  background:var(--accent-soft)}
.clipend{margin-top:var(--space-3);padding:var(--space-3) var(--space-4);display:flex;gap:var(--space-3);
  align-items:center;flex-wrap:wrap;font-size:var(--text-sm)}
.clipend span{flex:1 1 220px}
.pnote{margin-top:var(--space-3);font-size:var(--text-sm);color:var(--warn-text)}
.wtitle{font-size:var(--text-xl);font-weight:660;letter-spacing:-.015em;margin:var(--space-4) 0 var(--space-2);line-height:1.28}
.wsub{color:var(--ink-3);font-size:var(--text-sm)}
.wbox{padding:var(--space-4);margin-top:var(--space-4)}
.wbox h3{margin:0 0 var(--space-3);font-size:var(--text-xs);font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-3)}
.seg{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);cursor:pointer}
.seg:hover{background:var(--glass-2)}
button.seg{width:100%;border:0;background:none;color:inherit;font:inherit;text-align:left}
.seg .num{width:22px;height:22px;border-radius:7px;background:var(--glass-2);display:grid;place-items:center;
  font:600 var(--text-xs)/1 var(--font-mono);color:var(--ink-3);flex:none}
.seg .t{font:var(--text-sm)/1 var(--font-mono);color:var(--accent-text)}
.seg .d{font-size:var(--text-sm);color:var(--ink-3);margin-left:auto}

/* ------------------------------------------------------------------ lock -- */
.lockwrap{min-height:72vh;display:grid;place-items:center;padding:var(--space-5)}
.lock{width:min(400px,100%);padding:var(--space-5);text-align:center}
.lock h2{margin:var(--space-4) 0 var(--space-2);font-size:var(--text-lg);font-weight:640}
.lock p{margin:0 0 var(--space-4);color:var(--ink-3);font-size:var(--text-sm);line-height:1.5}
.lock .or{margin:var(--space-4) 0 var(--space-3);font-size:var(--text-xs);letter-spacing:.1em;text-transform:uppercase;color:var(--ink-3)}

/* --------------------------------------------------------------- account --
   Sign-in and the practice-location card. Inputs share the lock screen's look, so the
   two forms a member meets first read as one product. */
.signin{display:flex;flex-direction:column;gap:var(--space-2);text-align:left}
.signin input,.loccard input:not([type=checkbox]),.loccard select{width:100%;background:var(--field-bg);
  border:var(--field-border);border-radius:var(--radius-md);padding:var(--space-3) var(--space-4);outline:0;font-size:var(--text-md)}
.signin input:focus,.loccard input:focus,.loccard select:focus{border-color:var(--field-focus)}
/* An error line with nothing to say takes no room. */
.loccard .bad:empty,.signin .bad:empty{display:none}
.facform .bad{grid-column:1/-1;margin-top:0}
.signin .btn{justify-content:center}
.legal-note,.drawer-legal{font-size:var(--text-sm);color:var(--ink-3);margin:0;line-height:1.5}
.legal-note a,.drawer-legal a{color:inherit;text-decoration:underline}
.drawer-legal{padding:var(--space-3) var(--space-2) 0}
.loccard{max-width:680px;margin-left:auto;margin-right:auto;padding:var(--pad-card)}
.loccard h3{margin:0 0 var(--space-1);font-size:var(--text-md);font-weight:640}
.loccard>p{margin:0 0 var(--space-4);color:var(--ink-3);font-size:var(--text-sm);line-height:1.5}
.loccard .bad{color:var(--alert);font-size:var(--text-sm);margin-top:var(--space-2);min-height:16px}
/* The facility address form: name and street full width, then city / state / ZIP. */
.facform{display:grid;grid-template-columns:2fr 1.3fr 1fr;gap:var(--space-3) var(--gap-content)}
.facform .full,.facform .zipnote,.facform .actions{grid-column:1/-1}
.ff{display:flex;flex-direction:column;gap:var(--space-1);text-align:left;min-width:0}
.ff>span{font-size:var(--text-xs);font-weight:660;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3)}
.ff>span em{font-style:normal;text-transform:none;letter-spacing:0;font-weight:450}
.ff .fe{color:var(--alert);font-size:var(--text-sm)}
.ff.has-err input,.ff.has-err select{border-color:var(--alert-edge)}
.facform .zipnote{font-size:var(--text-sm);color:var(--ink-3);min-height:17px;margin-top:calc(var(--space-1) * -1)}
.facform .zipnote.warn{color:var(--warn-text)}
.addr{padding:var(--space-3) var(--space-4);border:var(--hairline);border-radius:var(--radius-md);
  background:var(--glass-2);line-height:1.6;font-size:var(--text-md)}
.addr b{font-weight:640}
.applies{margin:var(--space-3) 0;font-size:var(--text-sm);color:var(--ink-3);display:flex;gap:var(--space-2);
  align-items:center;flex-wrap:wrap}
/* A small badge: the jurisdictions a rule applies to, a team member's role. */
.jchip,.rolechip{display:inline-flex;padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);border:var(--hairline);
  background:var(--glass-2);font-size:var(--text-sm);font-weight:600}
.jchip{color:var(--ink)}
.facwarn{margin:var(--space-3) 0;padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);
  background:var(--warn-fill);border:1px solid var(--warn-edge);color:var(--warn-text);font-size:var(--text-sm);line-height:1.5}
.confirmline{display:flex;gap:var(--space-2);align-items:flex-start;font-size:var(--text-sm);
  margin-bottom:var(--space-3);cursor:pointer}
.confirmline input{margin-top:var(--space-1);width:16px;height:16px;flex:none;accent-color:var(--accent)}
.flash{max-width:680px;margin-left:auto;margin-right:auto;padding:var(--space-3) var(--space-4);
  font-size:var(--text-sm);display:flex;gap:var(--space-3);align-items:center}
.account{margin:var(--space-3) 0 var(--space-1);padding:var(--space-3) var(--space-3);border-top:var(--hairline);border-bottom:var(--hairline);font-size:var(--text-sm);
  color:var(--ink-3);display:flex;flex-direction:column;gap:var(--space-2)}
.account b{color:var(--ink);font-weight:620}
.account .lnk,.deck .lnk,.recentmore .lnk,.coursecard .lnk,.teamnote .lnk{background:none;border:0;padding:0;color:var(--accent-text);
  font:inherit;font-size:var(--text-sm);cursor:pointer;text-align:left;text-decoration:underline;
  text-underline-offset:2px}

/* ------------------------------------------------------------------ team --
   The Team page (owners and managers): seats, the shared facility, people, invites. Each
   block is a ui.css .panel; rows wrap at phone width so nothing scrolls sideways. */
.teamcard{padding:var(--pad-card)}
.teamcard h3{margin:0 0 var(--space-2);font-size:var(--text-md);font-weight:640}
.teamnote{margin:var(--space-2) 0 0;color:var(--ink-3);font-size:var(--text-sm);line-height:1.5}
.seathead{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap}
.seathead h3{margin:0}
.seatnum{font-size:var(--text-md);font-weight:620;font-variant-numeric:tabular-nums}
.bar.seatbar{height:8px;margin-top:var(--space-3)}
.person{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) 0;
  border-top:var(--hairline)}
.person:first-child{border-top:0;padding-top:var(--space-1)}
.person .who{flex:1 1 220px;min-width:0;display:flex;flex-direction:column;gap:var(--space-0)}
.person .who b{font-weight:620;overflow-wrap:anywhere}
.person .who span{font-size:var(--text-sm);color:var(--ink-3);overflow-wrap:anywhere}
.person .acts{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.person select,.inviteform input,.inviteform select,.linkrow input{background:var(--field-bg);
  border:var(--field-border);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);outline:0;font-size:var(--text-md);color:var(--field-ink)}
.person select:focus,.inviteform input:focus,.inviteform select:focus{border-color:var(--field-focus)}
.person select option,.inviteform select option{background:var(--surface-solid);color:var(--ink)}
.rolechip{color:var(--ink-2)}
.confirmq{font-size:var(--text-sm);color:var(--warn-text)}
.inviteform{display:flex;gap:var(--space-2);flex-wrap:wrap;margin-top:var(--space-3)}
.inviteform input{flex:1 1 220px;min-width:0}
.inviteform .bad{flex-basis:100%;color:var(--alert);font-size:var(--text-sm)}
.inviteform .bad:empty{display:none}
.linkbox{margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);
  border:1px solid var(--accent);background:var(--accent-soft)}
.linklabel{font-size:var(--text-sm);font-weight:620;color:var(--ink);overflow-wrap:anywhere}
.linkbox>.btn{margin-top:var(--space-3)}
.linkrow{display:flex;gap:var(--space-2);margin-top:var(--space-2)}
.linkrow input{flex:1;min-width:0;font:var(--text-sm)/1.4 var(--font-mono)}
.signin input[readonly]{opacity:.72;cursor:default}
/* "Forgot password?" and the reset request it opens (D-65). */
.signin .forgotlink{align-self:flex-start;font-size:var(--text-sm)}
.signin .forgotlead,.lock .signin .forgotlead{margin:0;text-align:left}
.forgotsent:empty{display:none}
.forgotsent{padding:var(--space-3) var(--space-4);border:var(--hairline);border-radius:var(--radius-md);
  background:var(--glass-2);font-size:var(--text-sm);line-height:1.5;text-align:left}
.forgotsent p,.lock .forgotsent p{margin:0 0 var(--space-2);color:var(--ink)}
.forgotsent p:last-child,.lock .forgotsent p:last-child{margin:0;color:var(--ink-3)}
/* Joining with a sign-in someone already has (D-63): what moving changes, in a box they
   read before the sign-in moves. */
.joinconfirm{text-align:left;margin-top:var(--space-2);padding:var(--space-3) var(--space-4);
  border:var(--hairline);border-radius:var(--radius-md);background:var(--glass-2);font-size:var(--text-sm);line-height:1.5}
.joinconfirm p{margin:0 0 var(--space-2);color:var(--ink);font-weight:600}
.joinconfirm ul{margin:0 0 var(--space-3);padding-left:var(--space-4);color:var(--ink-2)}
.joinconfirm .actions{display:flex;flex-wrap:wrap;gap:var(--gap-inline)}

/* ------------------------------------------------------------------ sops --
   The practice's own SOPs and checklists (premium). The list reuses the Library's
   .coursegrid / .coursecard so the two pages read as one product; the viewer and the
   editor are ui.css .panel blocks. Everything wraps at phone width. */
.sopbar{display:flex;gap:var(--gap-inline);flex-wrap:wrap;align-items:center}
.coursecard.archived{opacity:.62}
/* .sectitle's own margin outranks the flow gap, so a second heading sat on the cards. */
.sopres>.coursegrid+.sectitle{margin-top:var(--space-6)}
.coursecard .cthumb.kind{height:64px}
.sopdoc{padding:var(--pad-card);max-width:880px}
.sopdoc .pagehead{margin-bottom:var(--space-4)}
.sopsum{margin:0 0 var(--space-4);color:var(--ink-2);font-size:var(--text-md);line-height:1.6;white-space:pre-wrap}
.sopsec+.sopsec{margin-top:var(--space-5)}
.sopsec h2{margin:0 0 var(--space-2);font-size:var(--text-md);font-weight:640}
.sopsteps{margin:0;padding-left:var(--space-5);display:flex;flex-direction:column;gap:var(--space-2);
  font-size:var(--text-md);line-height:1.55;overflow-wrap:anywhere}
.sopsteps.checks{list-style:none;padding-left:0}
.checkstep{display:flex;gap:var(--space-3);align-items:flex-start;cursor:pointer}
.checkstep input{margin-top:var(--space-1);width:18px;height:18px;flex:none;accent-color:var(--accent)}
.checkstep .sn{flex:none;min-width:1.4em;color:var(--ink-3);font-variant-numeric:tabular-nums}
.checkstep.done .st{text-decoration:line-through;color:var(--ink-3)}
.sophint{font-size:var(--text-sm);color:var(--ink-3)}
.sopform{padding:var(--pad-card);display:flex;flex-direction:column;gap:var(--gap-content);max-width:880px}
.sopform input[type=text],.sopform textarea,.sopform select{width:100%;background:var(--field-bg);
  border:var(--field-border);border-radius:var(--radius-md);padding:var(--space-3) var(--space-3);outline:0;font-size:var(--text-md);color:var(--field-ink)}
.sopform textarea{resize:vertical;min-height:44px;line-height:1.45}
.sopform input:focus,.sopform textarea:focus,.sopform select:focus{border-color:var(--field-focus)}
.sopform select option{background:var(--surface-solid);color:var(--ink)}
.sopform .bad{color:var(--alert);font-size:var(--text-sm)}
.sopform .bad:empty{display:none}
.sopsecedit{border:var(--hairline);border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);
  display:flex;flex-direction:column;gap:var(--space-2)}
.sophead{display:flex;gap:var(--gap-inline);align-items:center}
.sophead input{flex:1;min-width:0}
.steprow{display:flex;gap:var(--gap-inline);align-items:flex-start}
.steprow .sn{flex:none;width:24px;padding-top:var(--space-3);text-align:right;font:600 var(--text-sm)/1 var(--font-mono);color:var(--ink-3)}
.steprow textarea{flex:1;min-width:0}
.mini{display:inline-flex;gap:var(--space-1);flex:none}
.mini button{display:grid;place-items:center;width:34px;height:34px;border-radius:var(--radius-sm);
  border:var(--hairline);background:var(--glass-2);color:var(--ink);cursor:pointer}
.mini button:hover:not(:disabled){border-color:var(--edge-2)}
.mini button:disabled{opacity:.35;cursor:default}
.upsell ul{margin:var(--space-2) 0 var(--space-4);padding-left:var(--space-4);color:var(--ink-2);font-size:var(--text-md);line-height:1.6}
@media (max-width:600px){
  .facform{grid-template-columns:1fr 1fr}
  .facform .ff.city{grid-column:1/-1}
  .sopdoc,.sopform{padding:var(--space-4)}
  /* The step takes the full line and its move/remove buttons drop beneath it; side by
     side they left a step about twelve characters wide on a phone. */
  .steprow{flex-wrap:wrap}
  .steprow textarea{flex:1 1 calc(100% - 32px)}
  .steprow .mini{margin-left:var(--space-6)}
  .sophead{flex-wrap:wrap}
  .sophead input{flex:1 1 100%}
}
/* ---------------------------------------------------------- certificates -- (D-70) */
.wprog{margin-top:var(--space-2);font-size:var(--text-sm);color:var(--ink-3)}
.wprog b{color:var(--ink);font-weight:620}
.certlist{display:grid;gap:var(--space-3)}
.coursecard h3{margin:0;font-size:var(--text-md);font-weight:640}
.coursecard .meta{font-size:var(--text-sm);color:var(--ink-3);margin-top:var(--space-1)}
.coursecard .bar{height:6px;margin-top:var(--space-3)}
.coursecard .state{display:flex;flex-wrap:wrap;gap:var(--gap-inline);align-items:center;
  margin-top:var(--space-3);font-size:var(--text-sm)}
.coursecard .lessons{list-style:none;margin:var(--space-3) 0 0;padding:0;display:grid;gap:var(--space-0)}
.coursecard .lessons button{display:flex;gap:var(--space-3);align-items:center;width:100%;text-align:left;
  background:none;border:0;border-radius:9px;padding:var(--space-2) var(--space-2);color:var(--ink);cursor:pointer;font:inherit;font-size:var(--text-sm)}
.coursecard .lessons button:hover{background:var(--glass-2)}
.coursecard .lessons .lcheck{width:20px;height:20px;flex:none;display:grid;place-items:center;
  border-radius:50%;border:var(--hairline);color:var(--accent-text);font-size:var(--text-xs)}
.coursecard .lessons .lcheck.on{background:var(--accent);color:var(--accent-ink);border-color:transparent}
.coursecard .lessons .lt{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.coursecard .lessons .lp{font-size:var(--text-sm);color:var(--ink-3);flex:none}
.pill{display:inline-block;font-size:var(--text-sm);font-weight:620;padding:var(--space-1) var(--space-3);border-radius:var(--radius-pill);
  border:var(--hairline);background:var(--glass-2);color:var(--ink-2)}
.pill.ok{color:var(--accent-text)}
.pill.bad{color:var(--alert)}
.quizq{padding:var(--pad-card);border:0;margin:0}
/* Floated so the question sits inside the panel, not on its top border. */
.quizq legend{float:left;width:100%;font-weight:620;font-size:var(--text-md);padding:0;margin-bottom:var(--space-2)}
.quizq legend+*{clear:both}
.quizq label{display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);
  border:var(--hairline);margin-top:var(--space-2);cursor:pointer;font-size:var(--text-md);line-height:1.45}
.quizq label:hover{background:var(--glass-2)}
.quizq input{margin-top:var(--space-1);flex:none}
.quizq .right{border-color:var(--accent);}
.quizq .wrong{border-color:var(--alert-edge)}
.quizq .why{margin-top:var(--space-3);font-size:var(--text-sm);color:var(--ink-2)}
.namebox{display:flex;gap:var(--gap-inline);flex-wrap:wrap;margin-top:var(--space-3)}
.namebox input{flex:1;min-width:220px;font:inherit;padding:var(--space-3) var(--space-3);border-radius:var(--radius-sm);
  border:var(--field-border);background:var(--field-bg);color:var(--field-ink)}
/* The certificate itself: drawn on paper colors whatever the theme, so the screen shows
   what the PDF will be. */
.certsheet{position:relative;background:#fffdf8;color:#14213d;border-radius:6px;
  padding:var(--space-8) var(--space-8);text-align:center;box-shadow:0 18px 50px rgba(0,0,0,.25);
  font-family:var(--font-body);aspect-ratio:1.414/1;display:flex;flex-direction:column;
  justify-content:center;gap:var(--space-3);max-width:980px;margin:0 auto}
.certsheet::before{content:"";position:absolute;inset:14px;border:2px solid #c9a646;border-radius:3px;pointer-events:none}
.certsheet::after{content:"";position:absolute;inset:20px;border:1px solid #c9a646;border-radius:2px;pointer-events:none}
.certsheet .cbrand{display:flex;justify-content:center;align-items:center;gap:var(--space-3);
  font-family:var(--font-heading);font-size:var(--text-lg);font-weight:700;letter-spacing:.02em}
.certsheet .cbrand img{height:34px;width:auto}
.certsheet .ckicker{font-size:var(--text-sm);letter-spacing:.32em;text-transform:uppercase;color:#7a6320;margin-top:var(--space-2)}
.certsheet .clead{font-size:var(--text-md);color:#3d4a66}
.certsheet .cname{font-family:var(--font-heading);font-size:var(--text-display);font-weight:700;line-height:1.15;
  border-bottom:1px solid #c9a646;padding:0 var(--space-5) var(--space-2);margin:0 auto;max-width:90%}
.certsheet .ccourse{font-family:var(--font-heading);font-size:var(--text-xl);font-weight:650;line-height:1.25}
.certsheet .cmeta{font-size:var(--text-md);color:#3d4a66}
.certsheet .cfoot{margin-top:var(--space-4);font-size:var(--text-sm);color:#3d4a66;line-height:1.6}
.certsheet .cfoot b{color:#14213d;letter-spacing:.06em}
.certsheet .crevoked{position:absolute;top:44px;right:44px;transform:rotate(8deg);border:2px solid #b3261e;
  color:#b3261e;font-weight:700;letter-spacing:.2em;padding:var(--space-1) var(--space-3);border-radius:6px}
.certactions{display:flex;flex-wrap:wrap;gap:var(--gap-inline);align-items:center;margin:var(--space-4) 0}

/* Print the document and nothing else: no header, drawer, backdrop or buttons, and dark
   type on white paper whatever the theme. A checklist prints its tick boxes. */
@media print{
  /* A certificate prints as one landscape page (D-70): "Save as PDF" in the print dialog
     is the PDF. Only while one is open (render() sets the class). */
  body.printing-cert main .wrap>:not(.certprint){display:none!important}
  body.printing-cert .certprint>:not(.certsheet){display:none!important}
  body.printing-cert .certprint{page:cert}
  body.printing-cert .certsheet{box-shadow:none!important;border-radius:0;max-width:none;
    width:100%;height:100vh;aspect-ratio:auto;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  /* Native tick boxes follow the color scheme; dark ones print as black squares. */
  :root{color-scheme:light}
  body{background:#fff;color:#000}
  #backdrop,#veil,.topbar,.drawer,.scrim{display:none!important}
  main{padding:0}
  /* Only while an SOP is open (render() sets the class): on any other page this rule
     printed a blank sheet. */
  body.printing-sop main .wrap>:not(.sopprint){display:none!important}
  .sopprint,.sopprint *:not(input){color:#000!important;background:none!important;box-shadow:none!important;
    backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
  .sopprint{border:0!important;padding:0!important}
  .sopsec{break-inside:avoid-page}
  /* Drawn, not native: a native box takes its look from the screen theme. */
  .checkstep input{appearance:none;-webkit-appearance:none;border:1.5px solid #000;border-radius:3px;
    background:#fff;box-shadow:none}
  .checkstep input:checked{background:#000;box-shadow:inset 0 0 0 3px #fff}
}
/* A named page, so only the certificate turns the sheet sideways; an SOP keeps the
   browser's defaults. */
@page cert{size:landscape;margin:10mm}

/* ------------------------------------------------------------------ misc -- */
.notice{display:flex;gap:var(--space-3);align-items:flex-start;border-radius:var(--radius-lg);padding:var(--space-3) var(--space-4);margin-bottom:var(--space-5);
  font-size:var(--text-sm);color:var(--warn-text);background:var(--warn-fill);border:1px solid var(--warn-edge);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
.notice>div:first-child{flex:1 1 auto;min-width:0}
.notice ul{margin:var(--space-1) 0 0;padding-left:var(--space-4)}
.notice button{background:none;border:0;color:inherit;cursor:pointer;font-size:var(--text-sm);
  text-decoration:underline;padding:0;margin-left:auto;white-space:nowrap}
.err{background:var(--alert-fill);border:1px solid var(--alert-edge);color:var(--alert);border-radius:var(--radius-lg);
  padding:var(--space-3) var(--space-4);font-size:var(--text-sm);margin-bottom:var(--space-5)}
.skel.t{aspect-ratio:16/9}
.skel.l{height:12px;margin-top:var(--space-2)}
.skel.l.s{width:60%}
details.trace{margin-top:var(--space-5);border-radius:var(--radius-lg);overflow:hidden}
details.trace>summary{cursor:pointer;padding:var(--space-3) var(--space-4);font-size:var(--text-sm);font-weight:620;color:var(--ink-3);
  list-style:none;display:flex;align-items:center;gap:var(--space-2)}
details.trace>summary::-webkit-details-marker{display:none}
details.trace>summary::before{content:"\25B8";transition:transform .15s}
details[open].trace>summary::before{transform:rotate(90deg)}
.tracebody{padding:0 var(--space-4) var(--space-4);font:var(--text-sm)/1.6 var(--font-mono)}
.trow{display:flex;justify-content:space-between;gap:var(--space-3);padding:var(--space-1) 0;border-bottom:1px dashed var(--edge)}
.trow:last-of-type{border-bottom:0}
.trow .k{color:var(--ink-3)}
.note{margin-top:var(--space-2);padding:var(--space-2) var(--space-3);background:var(--glass-2);border-radius:var(--radius-xs);color:var(--ink-3);
  font-size:var(--text-xs);word-break:break-word}
.withheld{margin-top:var(--space-5);padding:var(--space-4) var(--space-4);border:1px dashed var(--edge);border-radius:var(--radius-lg);
  color:var(--ink-3);font-size:var(--text-sm);text-align:center}

@media (max-width:720px){
  main{padding:0 var(--space-4) var(--space-8)}
  /* The badge crowded the wordmark into two lines at phone width. */
  .brand{white-space:nowrap;font-size:var(--text-md);min-width:0}
  .brand em{display:none}
  /* 22px tall is ~200px of wordmark, which leaves the plan picker room on a 375px phone. */
  .brand img.logo{max-height:min(var(--logo-h),22px);max-width:52vw}
  .topbar{padding:var(--space-3) var(--space-3)}
  .decks{gap:var(--space-4)}
  .grid{grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:var(--space-4) var(--space-3)}
  .plan span{display:none}
  /* The pinned composer leaves the thread more of a phone's height. */
  .composer{padding-top:var(--space-4)}
  .composer .askbox textarea{padding:var(--space-3) var(--space-4) var(--space-0)}
  .thread{gap:var(--space-6)}
  .certsheet{padding:var(--space-6) var(--space-5);aspect-ratio:auto}
  .certsheet .cbrand img{max-width:100%;height:auto;max-height:30px}
  .certsheet .crevoked{top:26px;right:26px;font-size:var(--text-xs);padding:var(--space-0) var(--space-2)}
  .certsheet .cname{font-size:var(--text-xl)}
  .certsheet .ccourse{font-size:var(--text-lg)}
}
