/* ============================================================
   rxdx study site — site.css
   Shared component + layout rules. Lifts from rxdx-ds/components
   and past/s537 layout. tokens.css supplies all color/type/space.
   ============================================================ */

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}  /* iOS: don't inflate text on rotate */
html,body{margin:0;padding:0}
body{
  background:var(--bg);color:var(--ink);
  font-family:var(--body);font-size:var(--t-body);
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:rgba(194,65,12,.10); /* subtle branded tap flash, not the default gray */
  accent-color:var(--accent);                      /* native checkbox/radio/search controls in brand rust */
  color-scheme:light;                              /* keep native controls/scrollbars light on a dark-OS device */
  min-height:100vh;
}
button{font-family:inherit;font-size:inherit;cursor:pointer;border:none;background:none;color:inherit}
input{font-family:inherit;font-size:inherit}
a{color:var(--accent);text-decoration:none}
svg{display:block}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-1)}

/* ============================================================
   APP SHELL — sticky top, push sidebar, sticky bottom
   ============================================================ */
/* content sits to the RIGHT of a persistent var(--rail) icon rail; the rail is fixed and, when
   expanded, floats OVER the content and both sticky bars (never pushes). */
.app{display:flex;flex-direction:column;min-height:100vh;padding-left:var(--rail)}

/* ---- sticky TOP bar = wayfinding: [ham][back?] · context title · [actions] ---- */
.topbar{
  position:sticky;top:0;z-index:50;flex:none;
  /* the bar's surface extends UP into the notch (safe-area) and its content is padded below it, so
     on a notched iPhone the status bar sits on the bar's own background, not on top of the burger/
     title. env=0 with no notch → identical to before on desktop/iPad. (This is the "top-top".) */
  height:calc(var(--topbar-h) + var(--sa-top));
  padding-top:var(--sa-top);padding-left:var(--sa-left);padding-right:var(--sa-right);
  background:var(--surface);border-bottom:1px solid var(--line);
  box-shadow:var(--shadow-1);
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;
}
/* Home is a single search field — it holds no wayfinding title and no actions, so the top bar renders
   as an empty band. Sticky bars appear only when needed: hide the top bar on home (the bottom bar is
   already hidden there via setBottomBar(null)). The left rail + its home mark stay. */
body[data-page="home"] .topbar{display:none}
/* Home = Google layout. The SEARCH BAR is the centered anchor: dead-center of the CONTENT AREA (the space
   RIGHT of the 60px menu rail — .content already sits there, so centering here accounts for the rail and
   is NOT skewed under it). The rxdx wordmark floats directly ABOVE the bar (it does not shift the bar off
   center). No top/bottom sticky bars on home. */
body[data-page="home"] .main{display:flex;flex-direction:column;padding:0}
body[data-page="home"] .hero{position:relative;display:block;flex:1;min-height:0;padding:0;gap:0}
body[data-page="home"] .searchfield{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(560px, calc(100% - 2 * var(--s-4)));max-width:none;margin:0;
}
/* wordmark sits above the bar: its bottom edge = bar top (bar half-height 26px) minus a gap */
body[data-page="home"] .hero-logo{
  position:absolute;left:50%;bottom:calc(50% + 26px + var(--s-5));transform:translateX(-50%);margin:0;
}
.topleft{display:flex;align-items:center;min-width:var(--s-2);padding-left:var(--s-4)}
/* back = LEFT. A plain TEXT pill ("Home" / "Drugs"), no leading arrow — same bordered-surface
   treatment as the right-cluster controls (densebtn/glossbtn family) so the whole top menu reads
   as one set of pills. */
/* Back pill (drug CARD → drug list). Styled like the neutral top-bar controls (glossbtn/densebtn
   family): bordered surface + INK text, NOT accent/orange — so the whole top menu reads as one set
   of calm pills and the accent stays reserved for primary actions. */
.topback{
  height:var(--ctl-sm);min-height:var(--ctl-sm);cursor:pointer;
  display:inline-flex;align-items:center;gap:var(--s-1);padding:0 var(--s-3);
  border:1px solid var(--line-2);border-radius:var(--r-1);
  background:var(--surface);color:var(--ink-2);white-space:nowrap;
}
.topback::before{content:"←";font-size:var(--t-h3);line-height:1;color:var(--ink-3)}
.topback:hover{color:var(--ink);border-color:var(--line-2)}
.topback:active{background:var(--surface-2)}
.topback-lb{font-family:var(--body);font-size:var(--t-meta);font-weight:600;line-height:1}
/* context title is ABSOLUTELY centered across the whole top bar. Because .app has a var(--rail)
   left pad the top bar spans the content region exactly, so left:0/right:0 centers the title
   on the SAME axis as the centered content column (not the shrunken 1fr grid cell). The generous
   line-height + vertical padding keep the display serif's descenders (g / y) from being clipped;
   the side padding reserves room for the left back pill and the right action cluster. */
.topctx{
  /* anchored to the topbar-h region BELOW the safe-area (top:--sa-top, height:--topbar-h) and
     vertically centered by line-height — so the title clears the notch exactly like the grid-placed
     burger/actions do, and stays a single ellipsizing line. env=0 off-notch → visually unchanged. */
  position:absolute;left:0;right:0;top:var(--sa-top);height:var(--topbar-h);margin:0 auto;
  text-align:center;pointer-events:none;padding:0 120px;
  font-family:var(--display);font-weight:700;font-size:var(--t-h2);letter-spacing:-.01em;
  color:var(--accent);line-height:var(--topbar-h);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* RIGHT cluster — flush to the right edge with an even gap between every control (Back + tools). */
.topact{display:flex;align-items:center;gap:var(--s-2);justify-self:end;padding-right:var(--s-4);min-width:var(--tap)}
.topactions{display:flex;align-items:center;gap:var(--s-2)}
/* ECG Lab's flat view row — Drug · Target · Manual · Learn — lifted into the top bar (app.js initEcgLab
   moves the tool's .topnav here). One row instead of a Simulate/Learn tier over a Drug/Target/Manual tier.
   Styled in the site's top-bar control family (.densebtn/.backbtn): bordered surface + BODY font, the
   active view taking the accent treatment. The tool toggles .on on the buttons (setNavActive). */
.topact .ecg-viewtabs{display:inline-flex;align-items:center;gap:var(--s-2);margin:0;padding:0;border:none;background:none}
.topact .ecg-viewtabs button{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  height:var(--ctl-sm);min-width:4rem;padding:0 var(--s-3);border:1px solid var(--line-2);border-radius:var(--r-1);
  background:var(--surface);color:var(--ink-2);font-family:var(--body);font-size:var(--t-meta);
  font-weight:600;white-space:nowrap;cursor:pointer}
.topact .ecg-viewtabs button:hover{color:var(--ink);border-color:var(--line-2)}
.topact .ecg-viewtabs button.on{background:var(--accent-bg);border-color:var(--accent);color:var(--accent-press)}
@media(max-width:600px){.topact .ecg-viewtabs{gap:4px}.topact .ecg-viewtabs button{min-width:0;padding:0 var(--s-2);font-size:var(--t-tag)}}

/* the middle band just holds the page content; the sidebar is a FIXED overlay, not in flow */
.band{flex:1;display:flex;align-items:stretch;min-height:0}

/* loading state — a spinner shown while a page's data loads (e.g. the course setup
   waiting on the question feed), so the screen is never a blank freeze. */
.loading{display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:var(--s-4);text-align:center;
  /* fill the real content area (viewport − top bar − main's own padding) so the spinner sits at the
     TRUE vertical center, not the upper third. */
  min-height:calc(100vh - var(--topbar-h) - var(--sa-top) - 2 * var(--s-5))}
.spinner{width:48px;height:48px;border-radius:50%;
  border:4px solid var(--line);border-top-color:var(--accent);
  animation:spin .8s linear infinite}
.loading-msg{font-family:var(--body);font-size:var(--t-body);color:var(--ink-2);max-width:34ch;line-height:1.4}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spinner{animation:none;opacity:.5}}

/* SIDEBAR = fixed left drawer. Collapsed = var(--rail) icon rail (RX/537/535/300), always visible,
   sitting over the far-left gutter. Open = var(--drawer) drawer that slides OVER the content and both
   sticky bars (top:0 → bottom:0, z above them). Never pushes — content stays put behind a scrim. */
.sidebar{
  position:fixed;top:0;left:0;bottom:0;width:var(--rail);overflow:hidden;
  /* pad the drawer clear of the notch (top) + home-indicator (bottom); the rail-bg still fills those
     areas since it's on the fixed full-height element. env=0 off-notch → no change on desktop/iPad. */
  padding-top:var(--sa-top);padding-bottom:var(--sa-bottom);padding-left:var(--sa-left);
  background:var(--rail-bg);border-right:1px solid var(--line);
  transition:width .2s ease;z-index:100;
}
.app.nav-open .sidebar{width:var(--drawer);box-shadow:2px 0 20px rgba(60,46,24,.20)}
/* full-height flex column: brand (flush top) · nav (scrolls) · toggle (pinned bottom) */
.sidebar-inner{width:var(--drawer);height:100%;display:flex;flex-direction:column}

/* RAIL TOP — a topbar-height cell (matching bottom border → one clean seam with the top bar) that
   now holds a small thin HOME icon. The icon sits in the same var(--rail) column the course marks occupy,
   so Home reads as the FIRST mark in the rail's icon stack, on the same vertical pitch. */
.side-top{
  flex:none;width:var(--rail);height:var(--topbar-h);border-bottom:1px solid var(--line);
  display:flex;align-items:center;
}
.app.nav-open .side-top{width:var(--drawer)}
/* the rail BRAND = home. Collapsed rail = a compact accent logo icon (triangle placeholder), centered
   in the 60px column like the course marks below it. Open drawer = the full "rxdx" + pulse wordmark,
   left-aligned. Click → home. */
.side-brand{
  flex:none;width:100%;height:100%;
  display:flex;align-items:center;justify-content:center;
  color:var(--accent);text-decoration:none;overflow:hidden;white-space:nowrap;
}
.app.nav-open .side-brand{justify-content:flex-start;padding-left:var(--s-4)}
.side-brand-icon{font-size:var(--t-h2);line-height:1;color:var(--accent);flex:none}
.side-brand:hover .side-brand-icon{opacity:.7}
.side-brand-full{display:none;align-items:center;gap:var(--s-2)}
.side-brand-full .brand-mark{color:var(--accent)}
.app.nav-open .side-brand-icon{display:none}
.app.nav-open .side-brand-full{display:inline-flex}

/* nav groups live in a scrollable middle region */
.sidebar-nav{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:var(--s-3) var(--s-2);display:flex;flex-direction:column;gap:var(--s-3)}

/* bottom collapse toggle (Cloudflare-style) — pinned to the rail floor, above a divider */
.rail-toggle{
  flex:none;display:flex;align-items:center;gap:var(--s-3);
  height:var(--tap);padding:0;border-top:1px solid var(--line);
  color:var(--ink-3);font-family:var(--body);font-size:var(--t-meta);font-weight:500;
  cursor:pointer;background:none;
}
.rail-toggle:hover{color:var(--ink-2)}
.rail-toggle .rt-ic{width:var(--rail);text-align:center;flex:none;font-size:var(--t-h3);line-height:1;transition:transform .2s ease}
.rail-toggle .rt-lbl{display:none}
.app.nav-open .rail-toggle{padding-right:var(--s-4)}
.app.nav-open .rail-toggle .rt-ic{transform:scaleX(-1)}
.app.nav-open .rail-toggle .rt-lbl{display:inline}

/* footer links moved OFF the pages into the rail floor (above the collapse toggle). Small muted
   links; only shown when the drawer is open (the var(--rail) rail is too narrow for them). */
.side-foot{flex:none;display:flex;flex-direction:column;gap:2px;padding:var(--s-3) var(--s-3) var(--s-2)}
.app:not(.nav-open) .side-foot{display:none}
.side-foot a,.side-foot span{font-family:var(--body);font-size:var(--t-eye);color:var(--ink-3);line-height:1.5;text-decoration:none;white-space:nowrap}
.side-foot a{cursor:pointer}
.side-foot a:hover{color:var(--ink-2)}

/* scrim — covers everything (content + both bars) when the drawer is open; tap to close */
.scrim{display:none}
.app.nav-open .scrim{display:block;position:fixed;inset:0;z-index:99;background:var(--scrim)}

/* mobile menu button — the drawer opener on phones. Hidden on desktop (the rail is always visible
   there); the mobile @media below reveals it. See the @media(max-width:720px) block for its layout. */
.navburger{display:none}
.drawer-close{display:none}
.navgroup > .glabel{
  font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 var(--s-1);padding:0 var(--s-2);
}
/* nav labels use a cleaner, SMALLER face than body text (13px vs 15px) and even 36px rows */
.navlink{
  display:flex;align-items:center;gap:var(--s-3);
  height:var(--ctl);padding:0 var(--s-2);border-radius:var(--r-1);
  color:var(--ink-2);font-family:var(--body);font-size:var(--t-meta);font-weight:500;white-space:nowrap;
  transition:color .12s;
}
/* course marks (Rx / 537 / 535 / 300) are treated as ICONS, not text: one uniform mono glyph — same
   size, weight, tabular width and centred alignment — so they read as an even column like the Home
   mark above them. Tabular numerals keep 2- and 3-char marks optically identical in the icon cell. */
.navlink .nl-ic{font-family:var(--mono);font-size:var(--t-tag);font-weight:600;letter-spacing:-.01em;
  font-variant-numeric:tabular-nums;line-height:1;color:var(--ink-2);width:24px;text-align:center;flex:none}
/* subtle hover — a faint text-colour shift, no filled block */
.navlink:hover{color:var(--ink)}
/* instant press feedback: the tint flashes on tap so a rail click feels responsive during the page load */
.navlink:active{background:var(--accent-bg);color:var(--accent)}
.navlink:active .nl-ic{color:var(--accent)}
/* selected row reads ORANGE — the vivid accent (not the pressed/burnt tone) on both label and mark. */
.navlink.active{background:var(--accent-bg);color:var(--accent);font-weight:600}
.navlink.active .nl-ic{color:var(--accent)}
/* ECG Lab rail mark — an ECG pulse (one beat). It inherits the row's tint via currentColor exactly
   like the text marks: muted at rest, accent only when the row is selected. Sized to match the mono
   marks' optical height so every mark in the column reads the same size. */
.navlink .nl-ic svg{width:16px;height:16px;display:block;margin:0 auto}
.navlink[href="/ecg-lab.html"] .nl-ic svg{width:15px;height:15px}

/* ---- collapsed RAIL: only the icons (RX/537/535/300) show, centred in the var(--rail) rail and
   EVENLY spaced. Group headers collapse to zero height so every icon sits on one uniform pitch. ---- */
.app:not(.nav-open) .navgroup > .glabel{height:0;margin:0;overflow:hidden;opacity:0;pointer-events:none}
.app:not(.nav-open) .sidebar-nav{gap:0;padding:var(--s-2) 0}
.app:not(.nav-open) .navlink > span:last-child{display:none}
.app:not(.nav-open) .navlink{gap:0;padding:0}
.app:not(.nav-open) .navlink .nl-ic{width:var(--rail)}

/* ============================================================
   MOBILE (<=720px) — the left rail is NOT a persistent gutter here.
   The desktop keeps the Cloudflare-style always-on 60px rail; on
   phones that rail steals horizontal space and squishes the page, so
   it becomes an off-canvas drawer opened by the .navburger button and
   the content spans the full width.
   ============================================================ */
@media(max-width:720px){
  /* content reclaims the rail's 60px gutter */
  .app{padding-left:0}
  /* rail → off-canvas drawer: always full drawer width, slid out of view until opened */
  .sidebar{width:var(--drawer);transform:translateX(-100%);transition:transform .22s ease}
  .app.nav-open .sidebar{transform:translateX(0)}
  /* reduced-motion: the drawer snaps open/closed instead of sliding */
  @media (prefers-reduced-motion:reduce){.sidebar{transition:none}}
  /* fixed top-left menu button — above the top bar (z-50), below the scrim (z-99) and drawer (z-100) */
  .navburger{
    display:flex;flex-direction:column;justify-content:center;gap:5px;
    position:fixed;top:calc(var(--sa-top) + 8px);left:calc(var(--sa-left) + var(--s-3));z-index:60;
    width:40px;height:40px;padding:0 9px;cursor:pointer;
    background:var(--rail-bg);border:1px solid var(--line);border-radius:var(--r-1);box-shadow:var(--shadow-1);
  }
  .navburger span{display:block;height:2px;width:100%;background:var(--accent);border-radius:2px}
  /* On pages with a real top bar (everything but home) the burger is the SAME icon-button
     component as the bar's tools (.searchbtn/.sortbtn-m/.collapsebtn — STYLE_GUIDE §3): a --ctl
     square, --line-2 border, --r-1 radius, muted icon, vertically centered in the bar. It must
     match its siblings — not a bespoke shape. Home has no bar, so it keeps the floating button. */
  body:not([data-page="home"]) .navburger{
    top:calc(var(--sa-top) + (var(--topbar-h) - var(--ctl)) / 2);left:calc(var(--sa-left) + var(--s-4));
    width:var(--ctl);height:var(--ctl);padding:0;gap:4px;align-items:center;justify-content:center;
    background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-1);box-shadow:none;
  }
  body:not([data-page="home"]) .navburger span{width:18px;background:var(--ink-2)}
  /* while the drawer is open the scrim + its own controls close it — hide the button so it doesn't
     ghost through the scrim */
  .app.nav-open .navburger{opacity:0;pointer-events:none}
  /* "Collapse" is a desktop concept (shrink the drawer back to the 60px icon rail). On mobile there
     is no icon rail — the drawer is just open/closed — so it's redundant with the × below. Hide it. */
  .rail-toggle{display:none}
  /* explicit × close, pinned to the right of the drawer header */
  .side-top{position:relative}
  .drawer-close{
    display:flex;align-items:center;justify-content:center;
    position:absolute;top:50%;right:var(--s-3);transform:translateY(-50%);
    width:var(--ctl);height:var(--ctl);padding:0;cursor:pointer;
    background:none;border:none;color:var(--ink-2);font-size:var(--t-h1);line-height:1;
  }
  .drawer-close:hover{color:var(--ink)}
  /* Mobile drawer breathes: the desktop rail's 36px rows / 12px gaps read tiny on a full-width phone
     drawer, so give the rows tap height, more air between them, and a body-sized label + icon. */
  .sidebar-nav{gap:var(--s-2);padding:var(--s-3)}
  .navlink{height:var(--tap);gap:var(--s-4);padding:0 var(--s-3);font-size:var(--t-body)}
  .navlink .nl-ic{width:28px;font-size:var(--t-h3)}
  .navlink .nl-ic svg{width:20px;height:20px}
  .navlink[href="/ecg-lab.html"] .nl-ic svg{width:19px;height:19px}
  /* keep the centered page title clear of the fixed button and the right action cluster */
  /* mobile: title sits LEFT, right next to the burger (burger ends at --s-4+--ctl = 52px, + --s-3 gap),
     left-aligned; right edge clears the action cluster so a long title ellipsizes instead of colliding. */
  .topctx{
    text-align:left;margin:0;padding:0;   /* vertical centering inherits base top/height/line-height */
    left:calc(var(--s-4) + var(--ctl) + var(--s-3));
    right:calc(var(--ctl) * 3 + var(--s-6));
  }
}

/* content column: holds the page main + a per-page sticky bottom bar */
.content{flex:1;min-width:0;display:flex;flex-direction:column}
.main{flex:1;width:100%;max-width:1040px;margin:0 auto;
  /* base horizontal pad + the landscape safe-area (a notch on the left/right in landscape) so body
     copy never hides behind the notch; env=0 in portrait/off-notch → unchanged. */
  padding:var(--s-5) calc(var(--s-4) + var(--sa-right)) var(--s-5) calc(var(--s-4) + var(--sa-left))}
.main.narrow{max-width:640px}

/* ---- sticky BOTTOM bar (per page) ---- */
.bottombar{
  position:sticky;bottom:0;z-index:40;flex:none;
  background:var(--surface);border-top:1px solid var(--line);
  box-shadow:0 -1px 3px rgba(60,46,24,.08);
}
.bottombar-inner{
  max-width:1040px;margin:0 auto;
  padding:var(--s-3) var(--s-4);
  padding-bottom:calc(var(--s-3) + env(safe-area-inset-bottom,0px));
  display:flex;align-items:center;gap:var(--s-3);
}
.bottombar-inner.narrow{max-width:640px}
.bb-count{font-size:var(--t-meta);color:var(--ink-2)}
.bb-count b{color:var(--ink);font-weight:600}
.bb-spacer{flex:1}

/* ============================================================
   BUTTONS  (from components/button.html)
   ============================================================ */
.btn{
  font-family:var(--body);font-weight:600;font-size:var(--t-body);
  height:var(--ctl);min-height:var(--tap);padding:0 var(--s-5);
  border-radius:var(--r-1);border:1px solid transparent;
  display:inline-flex;align-items:center;justify-content:center;line-height:1;gap:var(--s-2);
}
.btn--primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.btn--primary:active{background:var(--accent-press);border-color:var(--accent-press)}
.btn--ghost{background:transparent;color:var(--accent);border-color:var(--line-2)}
.btn--ghost:active{background:var(--accent-bg)}
.btn--disabled,.btn:disabled{background:var(--surface-2);color:var(--ink-3);border-color:var(--line);cursor:not-allowed}
.btn--full{width:100%}

/* ============================================================
   CHIPS  (from components/chip.html)
   ============================================================ */
.chiprow{display:flex;gap:var(--s-2);flex-wrap:wrap;align-items:center}
.chip{
  font-family:var(--body);font-weight:500;font-size:var(--t-meta);
  height:var(--ctl);padding:0 var(--s-4);border-radius:var(--r-3);
  display:inline-flex;align-items:center;gap:var(--s-2);line-height:1;
  background:var(--surface);color:var(--ink-2);border:1px solid var(--line-2);
}
.chip .n{font-size:var(--t-eye);color:var(--ink-2)}  /* solid --ink-2, not opacity-dimmed: AA-legible count (2026-07-25) */
/* small superscript status badge on a chip label (e.g. Recall "Beta", Cases "New") */
.chip-badge{font-family:var(--sans);font-size:var(--t-micro);font-weight:700;letter-spacing:.03em;text-transform:uppercase;vertical-align:super;margin-left:4px;line-height:0}
.chip-badge-beta{color:var(--ink-3)}
.chip-badge-new{color:var(--accent)}
.chip.on .chip-badge-beta{color:var(--accent-press)}
.chip.on{background:var(--accent-bg);color:var(--accent-press);border-color:var(--accent);font-weight:600}
.chip.on .n{color:var(--accent-press)}
.chip:disabled,.chip.chip-empty{opacity:.4;border-style:dashed;cursor:default;color:var(--ink-3)}

/* ============================================================
   eyebrow / section headings
   ============================================================ */
.eyebrow{font-family:var(--sans);font-weight:600;font-size:var(--t-eye);letter-spacing:.14em;text-transform:uppercase;color:var(--ink-2);margin:0 0 var(--s-3)}
.h-title{font-family:var(--display);font-weight:600;font-size:var(--t-h1);margin:0 0 var(--s-2);line-height:1.12}
.h-sub{font-family:var(--body);font-size:var(--t-body);color:var(--ink-2);margin:0 0 var(--s-5);line-height:1.5}

/* ============================================================
   HOME — Google-style centered search hero
   ============================================================ */
.hero{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;padding:var(--s-6) var(--s-4);gap:var(--s-5);min-height:60vh;
}
.hero-logo{font-family:var(--display);font-weight:700;font-size:var(--t-hero);line-height:1;color:var(--accent);letter-spacing:-.02em;display:inline-flex;align-items:center;gap:var(--s-3)}
.hero-logo b{color:var(--accent)}
.hero-tag{font-family:var(--sans);font-size:var(--t-meta);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3);margin-top:calc(-1 * var(--s-3))}
.searchbox{
  display:flex;align-items:center;gap:var(--s-3);width:100%;max-width:560px;
  height:52px;padding:0 var(--s-5);
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-2);
  box-shadow:var(--shadow-1);
}
.searchbox:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-bg)}
.searchbox .si-ic{color:var(--ink-3);font-size:var(--t-h3)}
.searchbox input{flex:1;border:none;background:none;outline:none;color:var(--ink);font-size:var(--t-h3)}
.searchbox input::placeholder{color:var(--ink-3)}
.hero-hint{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.06em;color:var(--ink-3)}

/* search results list (home + drug bank) */
.results{width:100%;max-width:560px;margin:0 auto;display:flex;flex-direction:column;gap:var(--s-2);text-align:left}
.result{
  display:flex;align-items:center;gap:var(--s-3);
  padding:var(--s-3) var(--s-4);border-radius:var(--r-1);
  background:var(--surface);border:1px solid var(--line);
}
.result:hover{border-color:var(--line-2)}
.result .r-generic{font-family:var(--display);font-weight:600;font-size:var(--t-h3);color:var(--ink)}
.result .r-brand{font-size:var(--t-meta);color:var(--ink-2)}
.result .r-class{font-family:var(--sans);font-size:var(--t-eye);text-transform:uppercase;letter-spacing:.06em;color:var(--accent);margin-left:auto;text-align:right}
.result-empty{color:var(--ink-3);font-size:var(--t-meta);text-align:center;padding:var(--s-5)}

/* ============================================================
   SHARED SEARCH COMBOBOX  (home hero + drug-bank field)
   .searchfield / .searchwrap are the position:relative hosts;
   .sugg is the floating ranked dropdown built by attachDrugSearch.
   ============================================================ */
.searchfield{position:relative;width:100%;max-width:560px;margin:0 auto}
.sugg{
  position:absolute;left:0;right:0;top:calc(100% + var(--s-2));z-index:40;
  background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-2);
  box-shadow:var(--shadow-2);
  padding:var(--s-1);max-height:min(60vh,420px);overflow-y:auto;overscroll-behavior:contain;
  animation:suggIn .12s ease-out;
}
@keyframes suggIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.sugg{animation:none}}
.sugg[hidden]{display:none}
.sugg-row{
  display:flex;align-items:center;gap:var(--s-3);cursor:pointer;
  padding:var(--s-3) var(--s-4);border-radius:var(--r-1);
}
.sugg-row.on{background:var(--accent-bg)}
/* Rx/Dx type badge on the unified home search (drug vs disease) */
.sugg-kind{flex:0 0 auto;font-family:var(--sans);font-size:var(--t-micro);font-weight:600;letter-spacing:.06em;text-transform:uppercase;padding:2px var(--s-2);border-radius:var(--r-3);line-height:1.5}
.sugg-kind--rx{color:var(--accent-press);background:var(--accent-bg)}
.sugg-kind--dx{color:var(--ink-2);background:var(--surface-2)}
.sugg-main{display:flex;align-items:baseline;gap:var(--s-3);min-width:0;flex:1}
.sugg-generic{font-family:var(--display);font-weight:600;font-size:var(--t-h3);color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sugg-brand{font-size:var(--t-meta);color:var(--ink-2);white-space:nowrap}
.sugg-class{font-family:var(--sans);font-size:var(--t-eye);text-transform:uppercase;letter-spacing:.06em;color:var(--accent);margin-left:auto;text-align:right;white-space:nowrap}
.sugg-hl{background:transparent;color:var(--accent-press);font-weight:700;padding:0}
.sugg-row.on .sugg-hl{color:var(--accent-press)}
.sugg-empty{color:var(--ink-3);font-size:var(--t-meta);text-align:center;padding:var(--s-5) var(--s-4)}

/* ============================================================
   DRUG BANK — LIST  (verbatim port of 537's drugsView / renderDrugList
   CSS: .dview column, search field, Organize strip, "Drugs N" title,
   grouped list with letter headers + counts + "›" chevron rows.
   Colors re-pointed to rxdx rust/cream tokens; heights 38→34 to sit
   inside rxdx's 44px top bar.)
   ============================================================ */
.dview{display:flex;flex-direction:column}
/* search field — opens BELOW the bar when the magnifier is toggled (537 .searchwrap/.search) */
.search{width:100%;height:var(--ctl);background:var(--surface);border:1px solid var(--line-2);
  border-radius:var(--r-1);padding:0 var(--s-4);font-size:var(--t-body);color:var(--ink);margin-bottom:var(--s-3)}
.search:focus{outline:none;border-color:var(--accent)}
.search:focus-visible{box-shadow:0 0 0 3px var(--accent-bg)}  /* keyboard focus ring (border tint alone isn't enough) */
.searchwrap{margin:0 0 var(--s-3);position:relative}
.searchwrap .search{margin-bottom:0}
.search::placeholder{color:var(--ink-3)}

/* top-bar list tools (icon-only): collapse-all / Organize / Search (537 .dtools) */
.dtools{display:inline-flex;gap:var(--s-2);align-items:center;flex-wrap:nowrap}
.searchbtn,.sortbtn-m,.collapsebtn{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  width:var(--ctl);height:var(--ctl);border:1px solid var(--line-2);border-radius:var(--r-1);
  background:var(--surface);color:var(--ink-2);cursor:pointer}
.searchbtn:active,.sortbtn-m:active,.collapsebtn:active{background:var(--surface-2)}
/* all three toggles share ONE "on" look — accent border + icon + tint (matches 537) */
.collapsebtn.open,.sortbtn-m.open,.searchbtn.open{border-color:var(--accent);color:var(--accent);background:var(--accent-bg)}
.searchbtn-ic,.collapsebtn-ic,.sortbtn-ic{display:inline-flex;align-items:center;justify-content:center}
.ic{width:20px;height:20px;display:block}
.searchbtn .ic,.sortbtn-m .ic,.collapsebtn .ic{width:18px;height:18px}
.collapsebtn-ic.right{transform:rotate(-90deg)}  /* caret points down when expanded, right when all-collapsed */

/* Organize strip — the four sort options, 2×2 on narrow, one row of 4 ≥560px (537 .sortpanel) */
.sortpanel{display:block;background:transparent;border:none;padding:var(--s-2) 0 var(--s-3);margin-bottom:0}
.sortpanel.closed{display:none}
.sortpanel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--s-2)}
/* Course FILTER row — same option-button look as the sort tabs, its own labelled grid of 4. */
.coursepanel-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--s-2)}
/* small muted caption separating Sort from Course within the Organize panel */
.sortpanel-cap{font-family:var(--sans);font-size:var(--t-eye);text-transform:uppercase;
  letter-spacing:.12em;color:var(--ink-2);margin:var(--s-2) 0 var(--s-1)}
.sortpanel-cap:first-child{margin-top:0}
.sortopt{height:var(--ctl);padding:0 var(--s-2);background:var(--bg);border:1px solid var(--line-2);
  border-radius:var(--r-1);font-size:var(--t-meta);color:var(--ink-2);text-align:center;
  display:flex;align-items:center;justify-content:center;line-height:1.2;cursor:pointer}
.sortopt.on{background:var(--accent-bg);border-color:var(--accent);color:var(--accent-press);font-weight:600}
.sortopt:active{opacity:.7}

/* "Drugs N · by class" title row (537 .dtitle) */
.dtitle{display:flex;align-items:baseline;gap:var(--s-3);padding:var(--s-2) 0 var(--s-3);margin-bottom:var(--s-2)}
.dtitle-h{font-family:var(--display);font-weight:600;font-size:var(--t-h1);line-height:1;color:var(--ink)}
.dtitle-meta{font-size:var(--t-meta);color:var(--ink-2);font-variant-numeric:tabular-nums}

/* grouped list — section header (letter/class/topic/exam) + count, foldable (537 .dgroup) */
.dgroup{display:flex;align-items:baseline;gap:var(--s-2);font-family:var(--sans);font-size:var(--t-meta);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);padding:var(--s-4) 0 var(--s-2);
  margin-top:var(--s-2);border-bottom:1px solid var(--line-2);
  cursor:pointer;-webkit-user-select:none;user-select:none;transition:color .12s}
.dgroup:first-child{margin-top:0;padding-top:0}
.dgroup:active{opacity:.6}
.dgroup-caret{font-size:var(--t-meta);color:var(--ink-3);opacity:.7;width:1em;display:inline-block}
.dgroup.collapsed{color:var(--ink-2)}
.dgroup-n{margin-left:auto;font-size:var(--t-eye);color:var(--ink-2);font-variant-numeric:tabular-nums}
/* rows: generic (bold) + class subtitle stacked, "›" chevron right (537 .drow) */
.dlist{display:flex;flex-direction:column}
.drow{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-2) 0;
  border-bottom:1px solid var(--line);text-align:left;width:100%;background:none;cursor:pointer;transition:color .12s}
.drow:active{background:var(--surface-2)}
.drow:hover .nm{color:var(--accent)}
/* NOTE: this inner column is `.drow-main`, NOT `.main` — the layout `.main` (the centred content
   column) carries 24px vertical padding, and the old class collision inflated every row ~48px. */
.drow .drow-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--s-1)}
.drow .nm{font-weight:600;font-size:var(--t-body);line-height:1.2;color:var(--ink)}
.drow .cl{font-size:var(--t-meta);color:var(--ink-2);line-height:1.2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.drow .chev{color:var(--ink-3);font-size:var(--t-h2);flex:0 0 auto}
/* Rx/Dx type tag — shown on rows only in the mixed "All" view of the unified bank, so a drug and a
   disease are told apart at a glance. Rx = accent tint (the drug side), Dx = neutral surface. */
.drow .drow-tag{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  min-width:2rem;height:1.25rem;padding:0 var(--s-1);border-radius:var(--r-3);
  font-family:var(--mono);font-size:var(--t-micro);font-weight:700;letter-spacing:.02em}
.drow .drow-tag-rx{background:var(--accent-bg);color:var(--accent)}
.drow .drow-tag-dx{background:var(--surface-2);color:var(--ink-2)}
/* TYPE FILTER — [All · Drugs · Diseases]. Reuses the .sortopt button look so it matches the Sort row; it
   is its OWN .sortpanel so it collapses TOGETHER with the Sort row under the one Organize toggle. Just a
   small gap to the Sort row below — no divider line. */
.sortpanel.banktype{padding-bottom:0;margin-bottom:0}
/* (it carries .sortpanel, so the existing .sortpanel.closed rule hides it with the Sort row) */
.empty{text-align:center;color:var(--ink-3);padding:var(--s-6) 0;font-size:var(--t-body)}

/* ---- amber "!" call-out note (537 clarnote) — drug card + explanation ---- */
.clarnote{
  display:flex;gap:var(--s-3);align-items:flex-start;
  margin-top:var(--s-3);padding:var(--s-3) var(--s-4);
  background:var(--warn-bg);border:1px solid var(--warn-border);border-radius:var(--r-1);
}
.card .clarnote{margin-top:var(--s-4)}
.explain .clarnote,.exp-why .clarnote,.ebody .clarnote{margin:var(--s-3) 0 0}
.clarnote-ic{
  flex:none;width:20px;height:20px;border-radius:50%;
  background:var(--warn);color:var(--on-accent);font-weight:700;font-size:var(--t-tag);
  display:flex;align-items:center;justify-content:center;line-height:1;margin-top:1px;
}
.clarnote-tx{font-size:var(--t-meta);line-height:1.55;color:var(--ink)}
.clarnote-tx b{color:var(--warn-ink)}

/* ============================================================
   DRUG BANK — CARD  (verbatim port of 537's drugDetailView: .card
   identity table + .subtab strip + bordered .subpanel per tab.)
   ============================================================ */
.dcard{width:100%}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--s-5)}
.dd-name{font-family:var(--display);font-weight:600;font-size:var(--t-h1);line-height:1.05;margin-bottom:var(--s-2)}
/* identity + field tables are real <table>s (537 .dd-tbl) */
.dd-tbl{width:100%;border-collapse:collapse}
.dd-tbl td{padding:var(--s-3) 0;border-bottom:1px solid var(--line);vertical-align:middle;font-size:var(--t-body);color:var(--ink)}
.dd-tbl td:first-child{color:var(--ink-2);width:34%;font-family:var(--sans);font-size:var(--t-eye);  /* --ink-2 for AA contrast (Governance A, 2026-07-25) */
  text-transform:uppercase;letter-spacing:.12em;padding-right:var(--s-3);vertical-align:middle}
.dd-tbl tr:last-child td{border-bottom:none}
.dd-dash{color:var(--ink-3)}
/* DB-tag pills: each governed value renders as a .tag (537 .tag/.tagrow) */
.tagrow{display:flex;flex-wrap:wrap;gap:var(--s-1)}
.tag{display:inline-block;padding:2px var(--s-2);background:var(--surface-2);border:1px solid var(--line-2);
  border-radius:var(--r-1);font-size:var(--t-meta);line-height:1.5;color:var(--ink-2)}
.tag-merged{border-width:2px;border-color:var(--ink-3);padding:1px calc(var(--s-2) - 1px)}
.dd-section{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);margin-bottom:var(--s-3)}
.dd-subsec{margin-bottom:var(--s-3)}
.dd-bullets{margin:0 0 var(--s-4);padding-left:1.1em;list-style:disc}
.dd-bullets li{font-size:var(--t-body);color:var(--ink);line-height:1.5;margin-bottom:var(--s-2)}
.dd-bullets li:last-child{margin-bottom:0}
.dd-empty{color:var(--ink-3);font-size:var(--t-meta);padding:var(--s-1) 0}
/* Contraindication pills (Clinical): condition term + an ABSOLUTE/relative badge. Absolute carries a
   red border + red badge; the split is governed (FDA) and itself testable, so it's shown, not hidden. */
.tag.contra-absolute{border-color:var(--danger)}
.tag.contra-relative{border-color:var(--line-2)}
.contra-lvl{margin-left:var(--s-1);font-family:var(--sans);font-size:var(--t-eye);
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)}
.tag.contra-absolute .contra-lvl{color:var(--danger)}
/* Lipid / ECG panels (Pharma): a compact key→direction mini-grid (LDL/HDL/TG/VLDL, PR/QRS/QT). */
.lipidgrid{display:grid;grid-template-columns:auto 1fr;gap:var(--s-1) var(--s-3);align-items:baseline}
.lipidgrid .lp-k{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.12em;color:var(--ink-3);text-transform:uppercase}
.lipidgrid .lp-v{font-size:var(--t-meta);color:var(--ink);font-variant-numeric:tabular-nums}
.lipidgrid .lp-none{font-size:var(--t-meta);color:var(--ink-3);font-style:italic}
/* Dose "By scenario" matrix (Dosing): scenario groups, each a scenario pill + per-slot dose lines. */
.dose-matrix-h{margin-top:var(--s-3)}
.dose-scenarios{display:flex;flex-direction:column;gap:var(--s-3)}
.dose-scenario{display:flex;flex-direction:column;gap:var(--s-2)}
.dose-scenario-key{display:flex}
.dose-scenario-body{display:flex;flex-direction:column;gap:var(--s-2);padding-left:var(--s-3)}
.dose-line{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap}
.dose-pills{display:flex;gap:var(--s-1);flex-wrap:wrap;align-items:center}
.dose-slot-pill{min-width:78px;text-align:center}
/* composite dose bubble = amount + unit + frequency fused into one fact; heavier border flags the fusion */
.tag-composite{border-width:2px;border-color:var(--ink-3);color:var(--ink);font-variant-numeric:tabular-nums}
.gap{height:var(--s-3)}
/* TEMP: hide the Overview→Decisions tab section on DISEASE cards only (drug cards keep theirs). Scoped by
   page so it's one line to remove when we rework the disease card. (owner: hide for now, revisit later.) */
.dcard-dz .subtabs{display:none}   /* disease cards: hide the Overview→Decisions tab section for now (any host page) */
/* subcards: segmented tab strip (mobile) → each panel its own bordered card (537 .subtab/.subpanel) */
.subtab-strip{display:flex;flex-wrap:wrap;background:var(--surface-2);border-radius:var(--r-1);padding:var(--s-1);
  gap:var(--s-1);margin-bottom:var(--s-3)}
/* flex:1 1 auto + wrap: each tab is at least as wide as its own label and grows to fill the row; when the
   full set won't fit (6 disease tabs on a phone) they wrap onto a second row instead of truncating. */
.subtab{flex:1 1 auto;min-width:4.5rem;height:var(--ctl-sm);border:none;background:transparent;border-radius:var(--r-3);
  padding:0 var(--s-2);color:var(--ink-2);font-family:var(--body);font-size:var(--t-body);font-weight:500;cursor:pointer;
  white-space:nowrap;transition:background .12s,color .12s,box-shadow .12s}
.subtab.on{background:var(--surface);color:var(--accent);font-weight:600;box-shadow:0 1px 2px rgba(42,32,24,.10)}
.subtab-dim{opacity:.4;cursor:default;font-style:italic;box-shadow:none}
.subtab-dim:active{background:transparent}
.subpanel{display:none;background:var(--surface);border:1px solid var(--line-2);border-radius:var(--r-1);padding:var(--s-4)}
.subpanel.on{display:block}
.subpanel-h{display:none}   /* the tab strip already labels it */
/* disease card: labeled atomic sections inside each subpanel (twin of the drug card's dd-tbl rows) */
.dz-field{padding:var(--s-3) 0;border-bottom:1px solid var(--line)}
.dz-field:last-child{border-bottom:none}
.dz-lbl{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);margin-bottom:var(--s-2)}
.dz-val{font-size:var(--t-body);color:var(--ink);line-height:1.5}
.dz-val p{margin:0}
.dz-list{margin:0;padding-left:1.1em}
.dz-list li{margin:.2em 0}
/* grouped disease atoms: values grouped under their element (element = a --meta caption, values joined) */
.grp{margin:0 0 var(--s-3)}
.grp:last-child{margin-bottom:0}
.grp-k{font-size:var(--t-meta);color:var(--ink-2);font-weight:600;margin-bottom:2px}
/* keyed-atom bullets (classification / criteria / therapies / targets / tools): bold lead reads as one phrase */
.dz-key{font-weight:600;color:var(--ink)}
.grp-v{font-size:var(--t-body);color:var(--ink);line-height:1.45}
/* Connections: causal edges (concept-map propositions). Each edge = a target + its plain why/how
   (self-explanation). Target is the proposition; why/how are muted, constrained elaborations. */
.dz-edges{list-style:none;margin:0;padding:0}
.dz-edge{padding:var(--s-2) 0;border-bottom:1px dashed var(--line)}
.dz-edge:last-child{border-bottom:none}
.dz-edge-to{display:block;font-weight:600;color:var(--ink)}
.dz-edge-q{display:block;font-size:var(--t-meta);color:var(--ink-2);line-height:1.45;margin-top:2px}
.dz-edge-q em{font-style:normal;text-transform:uppercase;letter-spacing:.08em;font-size:.85em;color:var(--ink-3,var(--ink-2));margin-right:.35em}
/* Decision forks — one question + its when→then branches (the lecture's "pure fork" trees) */
.dz-fork{padding:var(--s-2) 0;border-bottom:1px dashed var(--line)}
.dz-fork:last-child{border-bottom:none}
.dz-fork-q{font-weight:600;color:var(--ink);margin-bottom:var(--s-2)}
.dz-fork-ax{font-weight:400;font-size:var(--t-meta);color:var(--ink-3,var(--ink-2));text-transform:uppercase;letter-spacing:.06em;margin-left:.5em}
.dz-branches{list-style:none;margin:0;padding:0}
.dz-branch{display:grid;grid-template-columns:1fr auto auto;align-items:baseline;gap:.5em;padding:3px 0;line-height:1.45}
.dz-when{color:var(--ink-2)}
.dz-arrow{color:var(--accent);font-weight:600}
.dz-then{font-weight:600;color:var(--ink);text-align:right}
@media (max-width:560px){.dz-branch{grid-template-columns:1fr;gap:0}.dz-then{text-align:left}.dz-arrow{display:none}}
.dz-guide{color:var(--accent)}
.dz-druglink{color:var(--accent);text-decoration:none;border-bottom:1px solid transparent}
.dz-druglink:hover{border-bottom-color:currentColor}
.dz-empty{color:var(--ink-3)}
/* ============================================================
   537-PORTED TOP/BOTTOM BAR CHROME  (markup + CSS lifted from
   past/s537 bar()/navArrows()/quizExitBtn()/glossaryBtn() and its
   .barlogo/.brand-mark/.pulse-mark/.densebtn/.glossbtn/.backbtn/
   .navarrows/.contactfoot rules; colors re-pointed to rust tokens,
   heights nudged 38→34 to sit inside rxdx's 44px top bar.)
   ============================================================ */
/* LEFT section mark — 537 .barlogo + .brand-mark + .pulse-mark */
.barmark{display:inline-flex;align-items:center;gap:var(--s-2);height:var(--tap);padding:0 var(--s-4);
  background:none;border:none;line-height:1;white-space:nowrap;text-decoration:none}
.barmark:active{opacity:.55}
.brand-mark{font-family:var(--display);font-weight:600;font-size:var(--t-brand);line-height:1;color:var(--accent);letter-spacing:-.02em}
.brand-mark b{color:var(--accent);font-weight:700}

/* RIGHT cluster — bordered pill controls (537 .backbtn/.densebtn/.glossbtn family, shared surface+border) */
.densebtn,.glossbtn,.backbtn,.clearbtn{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;gap:var(--s-1);
  height:var(--ctl-sm);border:1px solid var(--line-2);border-radius:var(--r-1);
  background:var(--surface);color:var(--ink-2);white-space:nowrap;
  font-family:var(--body);font-size:var(--t-meta);font-weight:600;cursor:pointer;
}
.densebtn:active,.glossbtn:active,.backbtn:active,.clearbtn:active{opacity:.65}
/* Clear-all-selections — course setup sticky menu (restored from the old 537 "× Clear"). Muted text
   pill; shows only once a filter is engaged. The "×" glyph precedes the label. */
.clearbtn{padding:0 var(--s-3);color:var(--ink-3)}
.clearbtn::before{content:"\00d7";font-size:var(--t-h3);line-height:1;margin-right:var(--s-1)}
.clearbtn:hover{color:var(--ink);border-color:var(--line-2)}
/* Hide-empty toggle — 537 .densebtn (eye icon + label; accent when on) */
.densebtn{padding:0 var(--s-3)}
.densebtn.on{background:var(--accent-bg);border-color:var(--accent);color:var(--accent-press)}
.densebtn-ic{display:inline-flex;align-items:center}
.densebtn-ic .ic{width:15px;height:15px}
.densebtn.on .ic{stroke:var(--accent-press)}
/* glossary/book button — 537 .glossbtn (square icon) */
.glossbtn{width:var(--ctl-sm);padding:0}
.glossbtn .ic{width:17px;height:17px}
/* ← Drugs back button — 537 .backbtn (bordered, accent text) */
.backbtn{padding:0 var(--s-3);color:var(--accent)}
.backbtn-ic{font-size:var(--t-h3);line-height:1}
.backbtn-lb{font-size:var(--t-meta);font-weight:600;line-height:1}
/* quiz Exit — 537 .quizexit arm-to-confirm: the armed ("Confirm (n)") state fills accent-tint */
.quizexit.arm{background:var(--accent-bg);border-color:var(--accent);color:var(--accent-press)}

/* joined [← | Drugs →] nav pill — 537 .navarrows/.navarrow */
.navarrows{display:inline-flex;align-items:center;gap:0;flex:0 0 auto;height:var(--ctl-sm);
  border:1px solid var(--line-2);border-radius:var(--r-1);background:var(--surface);overflow:hidden}
.navarrow{display:inline-flex;align-items:center;justify-content:center;gap:var(--s-1);
  height:100%;min-width:var(--ctl-sm);padding:0 var(--s-3);background:none;border:none;color:var(--accent);
  font-family:var(--body);font-weight:600;text-decoration:none;cursor:pointer}
.navarrow:active{background:var(--accent-bg)}
.navarrow-ic{font-size:var(--t-h2);line-height:1}
.navarrow-lb{font-size:var(--t-meta);font-weight:600;line-height:1}
.navarrow.disabled,.navarrow:disabled{color:var(--line-2);cursor:default;pointer-events:none}
.navarrow-div{width:1px;align-self:stretch;background:var(--line-2)}

/* (contact footer .contactfoot/.footlink/.footsig removed — those links now live in .side-foot.) */

/* ============================================================
   REFERENCE SHEET — swipe-up bottom sheet (ported from 537's
   glossary sheet: scrim + slide-up panel + grip + sticky A–Z jump).
   Single "Abbreviations" page for now; see _notes/REFERENCE_SHEET_TODO.md.
   ============================================================ */
body.sheet-open{overflow:hidden}
#glossary-host{position:relative;z-index:200}
.sheet-scrim{position:fixed;inset:0;z-index:200;background:var(--scrim);animation:scrimIn .18s ease}
@keyframes scrimIn{from{opacity:0}to{opacity:1}}
.sheet{position:fixed;left:0;right:0;bottom:0;z-index:201;max-height:82vh;display:flex;flex-direction:column;
  background:var(--bg);border-top-left-radius:var(--r-2);border-top-right-radius:var(--r-2);
  box-shadow:0 -8px 30px rgba(42,32,24,.22);animation:sheetUp .24s cubic-bezier(.22,1,.36,1);
  transition:transform .18s ease;touch-action:none}
@keyframes sheetUp{from{transform:translateY(100%)}to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){.sheet{animation:none}.sheet-scrim{animation:none}}
.sheet-grip{flex:0 0 auto;width:38px;height:4px;border-radius:var(--r-pill);background:var(--line-2);margin:var(--s-2) auto var(--s-1);cursor:grab}
/* constrain the inner column to the page width (640px) so rows don't run edge-to-edge on desktop */
.sheet-inner{flex:1 1 auto;min-height:0;width:100%;max-width:640px;margin:0 auto;display:flex;flex-direction:column}
.sheet-head{flex:0 0 auto;display:flex;align-items:baseline;gap:var(--s-3);padding:0 var(--s-5) var(--s-3)}
.sheet-title{font-family:var(--display);font-weight:600;font-size:var(--t-h2);color:var(--ink)}
.sheet-sub{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2)}
.sheet-body{flex:1 1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:0 var(--s-5) var(--s-5)}
/* sticky A–Z jump bar over the abbreviation list */
.gl-az{position:sticky;top:0;z-index:3;display:flex;gap:1px;background:var(--bg);
  padding:var(--s-2) 0;margin-bottom:var(--s-3);border-bottom:1px solid var(--line)}
.gl-azk{flex:1 1 0;min-width:0;text-align:center;font-family:var(--mono);font-size:var(--t-eye);
  font-weight:600;color:var(--accent);padding:4px 0;line-height:1;background:none;border:0;border-radius:var(--r-3);cursor:pointer}
.gl-azk:hover{background:var(--accent-bg)}
.gl-group{margin-bottom:var(--s-5)}
.gl-group:last-child{margin-bottom:var(--s-2)}
.gl-letter{scroll-margin-top:var(--s-2)}
.gl-gtitle{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:1px;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 var(--s-2)}
/* row = one entry: a bold lead term, an abbreviation chip on the right, a plain meaning below */
.gl-arow{padding:var(--s-2) 0}
.gl-arow + .gl-arow{border-top:1px solid var(--line)}
.gl-atop{display:flex;gap:var(--s-3);align-items:baseline}
/* the ABBREVIATION is the lead — it's what people look up — with the full term as its expansion beside it */
.gl-aabbr{flex:0 0 auto;font-family:var(--mono);font-size:var(--t-body);font-weight:600;color:var(--accent-press);letter-spacing:.3px}
.gl-aword{flex:1 1 auto;min-width:0;font-family:var(--body);font-weight:500;color:var(--ink);font-size:var(--t-meta);line-height:1.3}
.gl-ameaning{color:var(--ink-2);font-size:var(--t-meta);line-height:1.4;margin-top:3px}

/* ---- UPDATE NOTICE: a low-key dark, slightly-transparent bar that slides up when a new deploy is
   detected, offering a reload. Sits above everything (incl. the quiz sticky bar); content page-width. ---- */
/* starts at the RAIL edge (not the viewport edge) so its box matches the .app content column exactly —
   the rail stays visible, and the inner lines up with the page's cards instead of floating off-centre. */
/* A skinny notice that slides DOWN from the top, sized exactly like the top bar (--topbar-h + the notch
   strip) so it reads as chrome, not a floating card. SOLID near-black (fully opaque — a translucent bar
   let the top-bar title bleed through as a smudge). Overlays the sticky top bar (z above its 50). */
.update-toast{position:fixed;left:0;right:0;top:0;z-index:300;transform:translateY(-110%);   /* FULL width — spans the whole top, over the rail too */
  display:flex;align-items:center;                     /* vertically centre the inner in the top-bar-h region */
  min-height:calc(var(--topbar-h) + var(--sa-top));padding-top:var(--sa-top);   /* content sits below the notch, like the top bar */
  transition:transform .3s cubic-bezier(.22,1,.36,1);
  background:color-mix(in srgb, black 92%, var(--ink));   /* solid near-black, a hair of warmth to match the palette */
  border-bottom:1px solid color-mix(in srgb, var(--on-accent) 14%, transparent)}
.update-toast.in{transform:translateY(0)}
/* Span the bar EDGE-TO-EDGE like the top bar's own row — message hard-left (--s-5 indent), Reload+× hard-
   right in the corner (--s-4 gutter, matching the top-bar tools). ut-msg flex:1 pushes the controls right. */
.update-toast .ut-inner{flex:1 1 auto;width:100%;display:flex;align-items:center;gap:var(--s-2);
  padding:0 calc(var(--s-4) + var(--sa-right)) 0 calc(var(--s-5) + var(--sa-left))}   /* no vertical pad — the bar height is the top-bar's */
.update-toast .ut-msg{flex:1;min-width:0;font-family:var(--body);font-size:var(--t-meta);color:var(--bg)}
.update-toast .ut-reload{flex:none;font-family:var(--body);font-size:var(--t-meta);font-weight:600;color:var(--bg);
  background:transparent;border:1px solid color-mix(in srgb, var(--bg) 34%, transparent);border-radius:var(--r-1);
  height:var(--ctl-sm);padding:0 var(--s-4);cursor:pointer;transition:background .14s}
.update-toast .ut-reload:hover{background:color-mix(in srgb, var(--bg) 14%, transparent)}
.update-toast .ut-x{flex:none;width:var(--ctl-sm);height:var(--ctl-sm);border:0;background:transparent;
  color:color-mix(in srgb, var(--bg) 55%, transparent);font-size:var(--t-h3);line-height:1;cursor:pointer;border-radius:var(--r-3)}
.update-toast .ut-x:hover{color:var(--bg)}
/* Mobile: tighter side gutters (the bar is already full-width). Reload/× stay --ctl-sm to fit the 56px bar. */
@media (max-width:720px){
  .update-toast .ut-inner{padding:0 var(--s-3)}
}
@media (prefers-reduced-motion:reduce){.update-toast{transition:none}}

/* ============================================================
   QUIZ RUNNER — question card (from components/question-card.html)
   ============================================================ */
.qwrap{max-width:640px;margin:0 auto}
.qmeta{display:flex;align-items:center;gap:var(--s-2);flex-wrap:wrap;margin-bottom:var(--s-4)}
.qmeta .qtag{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2);background:var(--surface-2);border:1px solid var(--line-2);border-radius:var(--r-3);padding:2px var(--s-2)}
/* qid + progress use --ink-2 (not --ink-3): muted metadata that still meets WCAG AA contrast at
   --t-eye/--t-meta on the bar surfaces. --ink-3 was ~2.5:1 (fails 4.5:1). Governance ADR-0009 ruling
   2026-07-25 (option A) — token-usage change, palette values stay locked. */
.qmeta .qtag.qid{font-family:var(--mono);letter-spacing:.02em;text-transform:none;color:var(--ink-2)}
/* recall vs case type badge (ADR-0012) — token-tinted so the two read apart at a glance */
.qmeta .qtag.qkind-recall{color:var(--accent);background:var(--accent-bg);border-color:var(--accent-bg)}
.qmeta .qtag.qkind-case{color:var(--warn-ink);background:var(--warn-bg);border-color:var(--warn-border)}
.qprog{font-size:var(--t-meta);color:var(--ink-2);margin-left:auto}

.qcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--s-5)}
.qcard .qtype{font-family:var(--sans);font-weight:500;font-size:var(--t-eye);letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin:0 0 var(--s-3)}
.qcard .stem{font-family:var(--body);font-weight:500;font-size:var(--t-h3);line-height:1.45;margin:0 0 var(--s-4)}
/* med-chem STRUCTURE renderer (ported from 535). A single molecule caps at 300px; a row of analogs
   spreads full width. Cream inset frames the diagram; serif A/B/C labels match the source. */
.medstruct{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-1);padding:var(--s-3);margin:0 0 var(--s-4);text-align:center}
.medstruct>svg{display:block;margin:0 auto;width:100%;height:auto;max-width:min(100%,28rem)}
.molrow{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin:0}
.molcell{flex:1 1 160px;min-width:140px;max-width:210px;text-align:center}
.mollab{font-family:var(--display);font-weight:600;color:var(--ink-2);font-size:var(--t-h3);margin-bottom:var(--s-1)}
.molcell svg{max-width:100%;height:auto}
.exp-concept .medstruct,.exp-why .medstruct{margin-top:var(--s-4)}
/* zoomable stem figure — a button reset back to the framed .medstruct look, plus a "tap to zoom" hint */
.medstruct--zoom{display:block;width:100%;font:inherit;color:inherit;cursor:zoom-in;position:relative;-webkit-tap-highlight-color:transparent;transition:border-color .12s ease,box-shadow .12s ease}
.medstruct--zoom:hover,.medstruct--zoom:focus-visible{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-bg);outline:none}
.medstruct--zoom .medstruct-fig{display:block}
.medstruct--zoom .medstruct-fig{display:block}
.medstruct--zoom .medstruct-fig>svg{display:block;margin:0 auto;width:100%;height:auto;max-width:min(100%,28rem)}
.medstruct-zoomhint{display:inline-flex;align-items:center;gap:4px;margin-top:var(--s-2);font-family:var(--sans);font-size:var(--t-meta);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-3)}
.medstruct-zoomhint .ic{width:14px;height:14px}
/* structure lightbox */
.zoomov{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--s-4);opacity:0;transition:opacity .18s ease}
.zoomov.open{opacity:1}
.zoomov-scrim{position:absolute;inset:0;background:var(--scrim-strong);cursor:zoom-out}
.zoomov-box{position:relative;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--s-5);width:min(96vw,1100px);max-width:96vw;max-height:92vh;overflow:hidden;box-shadow:var(--shadow-3);transform:scale(.96);transition:transform .18s ease;display:flex;align-items:center;justify-content:center}
.zoomov.open .zoomov-box{transform:scale(1)}
.zoomov-close{position:absolute;top:var(--s-2);right:var(--s-2);width:var(--ctl-sm);height:var(--ctl-sm);border:1px solid var(--line);border-radius:50%;background:var(--surface);color:var(--ink-2);font-size:var(--t-body);line-height:1;cursor:pointer;display:flex;align-items:center;justify-content:center}
.zoomov-close:hover{border-color:var(--accent);color:var(--accent)}
/* the figure fills the enlarged box and is the pan/zoom target (JS drives transform); centred both ways */
.zoomov-fig{text-align:center;touch-action:none;transform-origin:center center;will-change:transform;max-width:100%;max-height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;cursor:zoom-in}
.zoomov-fig svg{width:100%;height:auto;display:block;margin:0 auto}
.zoomov-fig>svg{max-width:min(90vw,1000px);max-height:84vh}
.zoomov-fig .molrow{gap:24px;justify-content:center;flex-wrap:wrap}
.zoomov-fig .molcell{flex:1 1 40%;min-width:280px;max-width:none}
.zoomov-fig .mollab{font-size:var(--t-h2)}
.zoomov-hint{position:absolute;left:50%;bottom:var(--s-3);transform:translateX(-50%);font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.06em;text-transform:uppercase;color:var(--ink-3);pointer-events:none;white-space:nowrap}
.opts{display:flex;flex-direction:column;gap:var(--s-2);margin:0 0 var(--s-4)}
.opt{
  display:flex;align-items:center;gap:var(--s-3);min-height:var(--tap);
  padding:var(--s-2) var(--s-4);border-radius:var(--r-1);
  border:1px solid var(--line-2);background:var(--surface);
  /* option text reads as PROSE — body reading font, comfortable size + line-height. */
  font-family:var(--body);font-size:var(--t-body);line-height:1.45;color:var(--ink);text-align:left;width:100%;
  transition:border-color .12s ease, background-color .12s ease;
}
/* the option KEY (A/B/C/D or rank) stays mono — it's a label, not prose. */
.opt .key{font-family:var(--mono);font-size:var(--t-meta);color:var(--ink-3);flex:none}
.opt .lbl{flex:1;min-width:0;overflow-wrap:anywhere;font-family:var(--body);line-height:1.45}
.opt:not(:disabled):hover{border-color:var(--accent)}
.opt:not(:disabled):active{border-color:var(--accent);background:var(--accent-bg)}  /* immediate tap feedback on phones */
.opt.picked{border-color:var(--accent);background:var(--accent-bg)}
.opt.correct{background:var(--good-bg);border-color:var(--good);color:var(--good)}
.opt.correct .key{color:var(--good)}
.opt.wrong{background:var(--bad-bg);border-color:var(--bad);color:var(--bad)}
.opt.wrong .key{color:var(--bad)}
.opt:disabled{cursor:default}
.opt .mk{margin-left:auto;font-family:var(--mono);font-size:var(--t-meta);font-weight:600}

/* concept "why" card (from components/explanation-concept.html) */
.exp-concept{margin-top:var(--s-4);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2);overflow:hidden}
.exp-concept .status{display:flex;align-items:center;gap:var(--s-3);padding:var(--s-4) var(--s-5);border-bottom:1px solid var(--line)}
.exp-concept .dot{width:10px;height:10px;border-radius:var(--r-3);flex:none}
.exp-concept .verdict{font-family:var(--display);font-weight:600;font-size:var(--t-h2);margin:0}
.exp-concept .status--good{background:var(--good-bg)}
.exp-concept .status--good .dot{background:var(--good)}
.exp-concept .status--good .verdict{color:var(--good)}
.exp-concept .status--bad{background:var(--bad-bg)}
.exp-concept .status--bad .dot{background:var(--bad)}
.exp-concept .status--bad .verdict{color:var(--bad)}
/* the echoed "your answer: …" reads as PROSE (body font, sentence case) — it repeats a full option,
   so mono-uppercase made it hard to read. Drops to its own line under the verdict on narrow widths. */
.exp-concept .status{flex-wrap:wrap}
.exp-concept .picked{flex:1 1 100%;font-family:var(--body);font-size:var(--t-meta);letter-spacing:0;text-transform:none;color:var(--ink-2);margin-top:var(--s-1)}
.exp-concept .ebody{padding:var(--s-5)}
/* the "WHY" eyebrow is a LABEL → stays mono (537 keeps its section labels mono). */
.exp-concept .ee{font-family:var(--sans);font-weight:600;font-size:var(--t-eye);letter-spacing:.14em;text-transform:uppercase;color:var(--accent);margin:0 0 var(--s-2)}
.exp-concept .rationale{font-family:var(--body);font-size:var(--t-body);line-height:1.6;color:var(--ink);margin:0}
.exp-concept .rationale b{color:var(--accent);font-weight:600}

/* recall COMPACT fact-card (from components/explanation-recall.html) */
.explain{margin-top:var(--s-4);padding:var(--s-4);border-radius:var(--r-2);font-size:var(--t-body);line-height:1.55;
  background:var(--surface-2);border:1px solid var(--line);border-left:2px solid var(--ink-3)}
.explain.ok{background:var(--good-bg);border-color:var(--line);border-left-color:var(--good)}
.explain.no{background:var(--bad-bg);border-color:var(--line);border-left-color:var(--bad)}
.explain .h{display:flex;align-items:baseline;gap:var(--s-2);font-family:var(--sans);font-size:var(--t-eye);
  letter-spacing:.5px;text-transform:uppercase;margin-bottom:var(--s-3)}
.explain.ok .h{color:var(--good)} .explain.no .h{color:var(--bad)}
.explain .h .ans{font-family:var(--body);text-transform:none;letter-spacing:0;font-size:var(--t-body);font-weight:600;color:var(--ink)}
.explain .fc{margin-top:var(--s-1)}
.explain .fc-name{font-family:var(--display);font-size:var(--t-h3);font-weight:600;color:var(--ink);margin-bottom:var(--s-2)}
.explain .fc-rows{display:grid;grid-template-columns:max-content minmax(0,1fr);column-gap:var(--s-3);row-gap:4px;font-size:var(--t-body);align-items:baseline}
.explain .fc-row{display:contents}
.explain .fc-k{font-family:var(--sans);font-size:var(--t-meta);text-transform:uppercase;letter-spacing:.5px;color:var(--ink-3)}
.explain .fc-v{color:var(--ink-2);min-width:0;overflow-wrap:anywhere}
.explain .fc-v b{color:var(--ink);font-weight:600}
.explain .fc-link{display:inline-block;margin-top:var(--s-3);font-size:var(--t-body);color:var(--accent);text-decoration:none;border-bottom:1px solid currentColor;padding-bottom:1px}
.explain .fc-link:hover{color:var(--accent-press)}
/* bare recall = verdict only (no fact-card body): compact, evenly-padded box, header hugs its single line */
.explain--bare{padding:var(--s-3) var(--s-4)}
.explain--bare .h{margin-bottom:0}

/* NOTE: the old '.exp-why' cases box (accent-tinted, no correctness state) was RETIRED 2026-07-13 — cases now
   use '.exp-concept' good/bad like concepts. Do not reintroduce an accent-colored feedback box: --accent (rust)
   reads as the error red. See STYLE_GUIDE §1 (accent≈bad guard) + tools/render_lint.py FEEDBACK_ACCENT. */
/* ---- MULTI-PART CASE vignette banner (ported from 537, rust/cream tokens) ----
   Header (Case X of N + point value), part-track bar, shared vignette body, labs table. Shown once
   above each part; the "Part X of N" line + the part lead-in follow below it in the question card. */
.case-vignette{background:var(--surface-2);border:1px solid var(--line);border-left:2px solid var(--accent);border-radius:var(--r-1);overflow:hidden;margin-bottom:var(--s-4)}
.case-vhead{display:flex;align-items:center;justify-content:space-between;gap:var(--s-2);padding:var(--s-3) var(--s-4) 0}
.case-tag{font-family:var(--sans);font-weight:600;font-size:var(--t-eye);letter-spacing:.08em;text-transform:uppercase;color:var(--accent)}
.case-pts{font-size:var(--t-eye);color:var(--accent);background:var(--surface);border:1px solid var(--accent-bg);border-radius:var(--r-pill);padding:3px 12px;white-space:nowrap}
.case-track{display:flex;gap:4px;padding:var(--s-3) var(--s-4) 0}
.ctrk{flex:1 1 0;height:6px;border-radius:var(--r-pill);background:var(--line);cursor:pointer;transition:background .15s ease}
.ctrk.now{background:var(--accent)}
.ctrk.ok{background:var(--good)}
.ctrk.miss{background:var(--bad)}
.case-body{padding:var(--s-3) var(--s-4) var(--s-4);font-size:var(--t-body);line-height:1.6;color:var(--ink-2)}
.case-body .case-narr{margin:0 0 var(--s-3)}
.case-body .case-dl{margin:0 0 var(--s-1);line-height:1.5}
.case-body .case-dl:last-child{margin-bottom:0}
.case-body .case-dt{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.3px;text-transform:uppercase;color:var(--ink-3)}
/* the labs read as a plain table INSIDE the vignette, not a bordered box-in-a-box: a top rule separates
   them from the narrative, header + row hairlines give structure, no outer border/fill. */
.case-labs{margin:0 var(--s-4) var(--s-4);padding-top:var(--s-2);border-top:1px solid var(--line);font-size:var(--t-meta)}
.case-labs .lab-head,.case-labs .lab-row{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);column-gap:var(--s-4);align-items:center;padding:var(--s-2) var(--s-4)}
.case-labs .lab-head{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.4px;text-transform:uppercase;color:var(--ink-3);border-bottom:1px solid var(--line)}
/* header labels sit directly over their column's data: Lab left, Value centred, Reference right-aligned */
.case-labs .lab-head span:nth-child(2){text-align:center}
.case-labs .lab-head span:nth-child(3){text-align:right}
.case-labs .lab-row+.lab-row,.case-labs .lab-head+.lab-row{border-top:1px solid var(--line)}
.case-labs .lab-name{color:var(--ink-2)}
.case-labs .lab-val{text-align:center;color:var(--ink)}
.case-labs .lab-ref{text-align:right;color:var(--ink-3)}
/* Reveal-only abnormal flag (dataRole cases): shown once the case is answered — H/L/crit badge next to the
   value. Uses the governed correctness/warn tokens; neutral 'inert' never carries one. */
.case-labs .lab-flag{font-family:var(--sans);font-size:var(--t-eye);font-weight:600;letter-spacing:.3px;
  padding:0 5px;border-radius:var(--r-pill);background:var(--warn-bg,color-mix(in srgb,var(--bad) 12%,var(--surface)));color:var(--bad);vertical-align:middle}
.case-partline{display:flex;align-items:center;margin:0 0 var(--s-3)}
.case-part{font-family:var(--sans);font-weight:600;font-size:var(--t-meta);letter-spacing:.02em;color:var(--ink-2)}
/* per-case results breakdown (each case's parts-correct as a labeled bar) */
.breakdown{margin-top:var(--s-5);display:flex;flex-direction:column;gap:var(--s-3)}
.brow{display:grid;grid-template-columns:minmax(72px,auto) 1fr auto;gap:var(--s-3);align-items:center}
.brow .name{font-family:var(--sans);font-size:var(--t-meta);letter-spacing:.02em;color:var(--ink-2)}
.brow .bar{height:8px;border-radius:var(--r-pill);background:var(--surface-2);overflow:hidden}
.brow .bar i{display:block;height:100%;background:var(--accent);border-radius:var(--r-pill)}
.brow .v{font-size:var(--t-meta);color:var(--ink-3);white-space:nowrap}

/* ---- quiz sticky-bar controls: Back (left) · Skip + Submit/Next (right) ----
   The "Q n / N" progress counter lives ONLY on the question card (.qprog); the
   bottom bar deliberately omits it to avoid a duplicate indicator. */
.qb-back{flex:0 0 auto;min-width:92px;padding:0 var(--s-4)}
.qb-skip{flex:0 0 auto;min-width:64px}
.qb-go{flex:0 0 auto;min-width:110px}
@media(max-width:560px){
  .qb-back{min-width:0;padding:0 var(--s-3)}
  .qb-go{flex:1 1 auto;min-width:0}
}

/* ============================================================
   RESULTS SCREEN — 537 result card: eyebrow · big % + phrase ·
   the ECG "rhythm strip" completion effect · actions · review list.
   ============================================================ */
/* results container — its OWN class (not `.card .result`, which collides with the search-result row). */
.results-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--s-5)}
.res-eyebrow{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:1px;text-transform:uppercase;color:var(--ink-2);margin-bottom:var(--s-4)}
.res-score{display:flex;align-items:flex-end;gap:var(--s-4)}
.res-score .pct{font-family:var(--display);font-weight:700;font-size:var(--t-hero);line-height:.85;color:var(--ink);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.res-score .pct small{font-size:var(--t-h2);color:var(--ink-2)}
.res-phrase{margin-bottom:var(--s-2);display:flex;flex-direction:column}
.res-phrase b{font-family:var(--display);font-weight:600;font-size:var(--t-h2);color:var(--accent);line-height:1.1}
.res-phrase i{font-style:normal;font-size:var(--t-body);color:var(--ink-2);font-variant-numeric:tabular-nums}

/* the rhythm strip (completion effect) — draws left→right with a glowing sweep line */
.strip{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-2);padding:var(--s-4) var(--s-3) var(--s-3);margin-top:var(--s-5);box-shadow:var(--shadow-1)}
.strip-head{display:flex;align-items:baseline;justify-content:space-between;margin-bottom:var(--s-3);
  font-family:var(--sans);font-size:var(--t-eye);letter-spacing:1px;text-transform:uppercase;color:var(--ink-3)}
.strip-lead{font-variant-numeric:tabular-nums;text-transform:none;letter-spacing:.5px}
.strip-trace{position:relative;background:var(--bg);border-radius:var(--r-1);padding:8px 6px;overflow:hidden}
.strip-grid{width:100%;height:auto;display:block;position:relative;z-index:1}
.strip-grid line{stroke:var(--line);stroke-width:1}
.strip-svg{width:calc(100% - 12px);height:auto;display:block;position:absolute;top:8px;left:6px;z-index:2;
  animation:drawStrip 1.5s cubic-bezier(.4,0,.2,1) .2s backwards}
.strip-sweep{position:absolute;top:6px;bottom:6px;width:2px;z-index:3;
  background:linear-gradient(var(--accent),transparent);box-shadow:0 0 8px 1px rgba(194,65,12,.45);
  animation:sweep 1.5s cubic-bezier(.4,0,.2,1) .2s backwards}
@keyframes drawStrip{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes sweep{0%{left:0;opacity:0}8%{opacity:1}92%{opacity:1}100%{left:100%;opacity:0}}
@media (prefers-reduced-motion:reduce){.strip-svg,.strip-sweep{animation:none}.strip-sweep{display:none}}
.strip-legend{display:flex;align-items:center;gap:var(--s-5);margin-top:var(--s-3);padding-top:11px;border-top:1px solid var(--line)}
.strip-legend .lg{display:flex;align-items:center;gap:7px;font-size:var(--t-meta);color:var(--ink-2)}
.strip-legend .lg svg{display:inline-block}
.strip-legend .lg b{color:var(--ink);font-variant-numeric:tabular-nums}
.strip-legend .lg b.miss{color:var(--bad)}

.results-actions{display:flex;gap:var(--s-3);margin-top:var(--s-5);flex-wrap:wrap}
.results-actions .btn{flex:1 1 auto}
.res-review{margin-top:var(--s-5);max-width:100%}

/* small helpers */
.hide{display:none!important}
.muted{color:var(--ink-3)}

/* ============================================================
   QUIZ SETUP  (faithful port of the 537 build screen)
   Labeled chip GROUPS in a vertical stack; crisp rounded-rect
   chips laid out in equal columns; per-chip live counts; empty
   chips greyed/dashed; whole rows greyed when "not applicable".
   ============================================================ */
.sview{display:flex;flex-direction:column}
.group{margin-bottom:var(--s-5)}
/* Two compact binary toggles (Feedback + Expand abbreviations) sharing one line. */
.group-pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--s-4);margin-bottom:var(--s-5)}
.group-pair > .group{margin-bottom:0}
.group > .label{font-family:var(--sans);font-size:var(--t-eye);letter-spacing:.12em;text-transform:uppercase;color:var(--ink-2);margin:0 0 var(--s-3)}
.chips{display:grid;gap:var(--s-2)}
.chips + .chips{margin-top:var(--s-2)}
.chips.col1{grid-template-columns:1fr}
.chips.col2{grid-template-columns:repeat(2,1fr)}
.chips.col3{grid-template-columns:repeat(3,1fr)}
.chips.col4{grid-template-columns:repeat(4,1fr)}
.chips.col5{grid-template-columns:repeat(5,1fr)}
.chips.col6{grid-template-columns:repeat(6,1fr)}
/* grid chips fill their cell (full-width, balanced grid) and WRAP long labels to a 2nd line
   instead of clipping — so "Harirforoosh" fits without breaking the full-width layout, same on
   mobile and desktop, both courses. */
.chips .chip{width:100%;justify-content:center;text-align:center;cursor:pointer;
  height:auto;min-height:var(--ctl);padding:var(--s-2) var(--s-3);line-height:1.2}
.chips .chip span.lbl{white-space:normal;overflow-wrap:break-word}
.chips.col5 .chip,.chips.col6 .chip{padding:var(--s-2);font-size:var(--t-eye)}
/* chips-wrap — used for the Teacher row: chips SIZE TO CONTENT and wrap onto new lines instead of
   being forced into rigid equal columns. This stops long names (e.g. "Harirforoosh", especially once
   selected + counted) from being clipped by the fixed grid cell. */
.chips.chips-wrap{display:flex;flex-wrap:wrap}
.chips.chips-wrap .chip{width:auto;flex:0 1 auto;min-width:88px;padding:0 var(--s-4)}
.chips.chips-wrap .chip span.lbl{overflow:visible;text-overflow:clip;white-space:normal}
.chip.chip-empty .n{display:none}
.group-disabled{opacity:.5}
.group-disabled .chip{background:var(--bg);border-style:dashed;cursor:default;color:var(--ink-3)}
.cat-grid .chip{font-size:var(--t-meta)}

/* SUB-TOPIC accordion — subcard-family rows (Identity/Med-chem/…) that expand to facet pills.
   Full-width rows mirror the drug card's subcards; the pills are their sub-subtopic children. */
/* SUB-TOPIC accordion — SEPARATE stacked cards (537 parity), each = wide row + separate chevron box. */
/* Sub-topic rows share the setup's box system: same between-box gap (--s-2), same box height (--ctl) and
   horizontal padding (--s-3) and radius (--r-3) as every .chip — so the section reads as one family. */
.subtopic-acc{display:flex;flex-direction:column;gap:var(--s-2);background:transparent}
.famrow{display:flex;gap:var(--s-2);align-items:stretch}
.subcard-row{flex:1 1 auto;display:flex;align-items:center;gap:var(--s-3);
  height:var(--ctl);padding:0 var(--s-3);border:1px solid var(--line-2);border-radius:var(--r-3);
  background:var(--surface);font-family:var(--body);font-size:var(--t-meta);color:var(--ink-2);cursor:pointer;text-align:left}
.subcard-row:hover{background:var(--bg)}
.subcard-row .dir{flex:0 0 auto;width:18px;font-size:var(--t-meta);color:var(--ink-3);line-height:1;text-align:center}
.subcard-row .scname{flex:1 1 auto;font-weight:500;font-size:var(--t-meta);color:var(--ink-2)}
.subcard-row.open .scname,.subcard-row.has-sel .scname{font-weight:600}
.subcard-row .scn{flex:0 0 auto;font-size:var(--t-eye);color:var(--ink-2);min-width:24px;text-align:right}
.subcard-row.open,.subcard-row.has-sel{border-color:var(--accent)}
.subcard-row.has-sel .scname,.subcard-row.has-sel .dir{color:var(--accent)}
/* separate square chevron box on the right (537 .fam-car). Height is NOT hard-coded: the .famrow is
   align-items:stretch, so the chevron STRETCHES to whatever height .subcard-row is — the row is the single
   source of truth for the pair's height. This makes the two boxes structurally impossible to mismatch
   (the old bug: both hard-coded 44px independently and drifted when one changed). Width stays 44 = square. */
.fam-car{flex:0 0 auto;align-self:stretch;display:inline-flex;align-items:center;justify-content:center;
  width:var(--ctl);min-height:var(--ctl);border:1px solid var(--line-2);border-radius:var(--r-3);
  background:var(--surface);color:var(--ink-3);font-size:var(--t-h3);line-height:1;cursor:pointer}
.fam-car:hover{background:var(--bg)}
.fam-car.open{border-color:var(--accent);color:var(--accent)}
.fam-car-dis{opacity:.35;cursor:default}
/* facet chips (sub-sub-topics) under a left accent bar — same box DNA as every .chip: --ctl tall, crisp
   --r-3 radius, --t-meta body text. NOT rounded pills (that broke the site's boxes-and-sizes protocol). */
.facet-pills{display:flex;flex-wrap:wrap;gap:var(--s-2);
  margin:calc(-1 * var(--s-1)) var(--s-3) 0 var(--s-3);padding:var(--s-2) 0 var(--s-2) var(--s-4);
  border-left:2px solid var(--line-2);background:transparent}
.facet-pill{display:inline-flex;align-items:center;gap:var(--s-2);
  font-family:var(--body);font-weight:500;font-size:var(--t-meta);line-height:1;
  height:var(--ctl);padding:0 var(--s-4);border-radius:var(--r-3);cursor:pointer;
  background:var(--surface);color:var(--ink-2);border:1px solid var(--line-2)}
.facet-pill .n{font-size:var(--t-eye);color:var(--ink-2)}  /* solid --ink-2, AA-legible count (2026-07-25) */
.facet-pill.on{background:var(--accent-bg);color:var(--accent-press);border-color:var(--accent);font-weight:600}
.facet-pill.on .n{color:var(--accent-press)}

.rule{border:none;border-top:1px solid var(--line);margin:var(--s-2) 0 var(--s-4)}

/* status line + Start, inside the sticky bottom bar */
.bb-startwrap{display:flex;flex-direction:column;gap:var(--s-2);width:100%}
.startrow{display:flex;align-items:baseline;gap:var(--s-2);width:100%}
.startrow .count{flex:0 0 auto;font-size:var(--t-meta);color:var(--ink-2);white-space:nowrap}
.startrow .count b{color:var(--ink);font-weight:600}
.startrow .count .muted{color:var(--ink-3)}
.startrow .hint{flex:1 1 auto;margin-left:auto;min-width:0;font-size:var(--t-meta);color:var(--ink-2);text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.startrow .hint b{color:var(--ink-2);font-weight:600}
.startrow .count .ready,.startrow .hint .ready{color:var(--good);font-weight:600}

@media(max-width:520px){
  .hero-logo{font-size:var(--t-hero-sm)}
}

/* ===== TOP 300 · quiz.  Setup uses the SHARED .group/.chips/.chip setup components (identical to
   537/535 — PAGE_FORMAT_STANDARD), so nothing bespoke is needed here. Only the two quiz-specific
   bits below: the hint highlight on the stem, and the At-end review detail. ===== */
/* Hint suffix-stem highlight on the question subject (DRUGBANK_HINT_RULES §1). A YELLOW HIGHLIGHTER over
   the stem — NOT a padded pill. Horizontal padding is 0 so the highlight sits flush against the rest of the
   word (e.g. "Labetalol" stays ONE word, not "Labet alol"); text colour/weight inherit so the marked
   letters read as continuous text with a marker over them. box-decoration-break keeps it clean across wraps. */
mark.hl{background:var(--hl);color:inherit;font-weight:inherit;border-radius:2px;padding:0;
  -webkit-box-decoration-break:clone;box-decoration-break:clone}
.fc-row.fc-hint .fc-v{color:var(--ink-2)}
/* At-end results review — per-question your-answer / correct-answer / hint lines. */
.rev-detail{margin-top:var(--s-2)}
.rev-ans{display:flex;gap:var(--s-2);font-size:var(--t-meta);line-height:1.5}
.rev-ans .fc-k{font-family:var(--sans);font-weight:400;font-size:var(--t-eye);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink-3);min-width:56px;flex:0 0 auto}
.rev-ans .fc-v{color:var(--ink-2);min-width:0;overflow-wrap:anywhere}

/* ============================================================
   CANONICAL TYPE ROLES — enforced. Placed LAST so it wins by source
   order. ONE definition per role; components must not fork these.
   A genuinely new role is raised before it's added. See
   docs/TEXT_STYLE_MAP.md for the full role table + location map.
   ============================================================ */
/* SECTION LABEL ("eyebrow") — the single small uppercase label style.
   Regular weight (NOT bold), 11px, .12em tracking, uppercase. Each element
   keeps its own color (ink-3 default, accent where it's an emphasis label)
   and its own margins — only the type shape is normalized here. */
.eyebrow,.navgroup>.glabel,.group>.label,.dd-section,.dd-tbl td:first-child,
.sortpanel-cap,.dgroup,.contra-lvl,.lipidgrid .lp-k,.sheet-sub,.gl-gtitle,.res-eyebrow,
.strip-head,.qmeta .qtag,.qcard .qtype,.medstruct-zoomhint,.hero-tag,.result .r-class,
.sugg-class,.explain .h,.explain .fc-k,.case-tag,.case-body .case-dt,.case-labs .lab-head,
.exp-concept .ee,.exp-why h4{
  font-family:var(--sans);font-weight:400;font-size:var(--t-eye);
  letter-spacing:.12em;text-transform:uppercase;
}

/* SELECTION STATE — the ONE "selected/active" treatment (accent tint + accent
   border + accent text + 600). Grouped so there is a single source of truth;
   .navlink.active and .densebtn.on are intentional near-variants (nav = tint only;
   dense = accent-press) and keep their own rules. */
.chip.on,.sortopt.on,.facet-pill.on{
  /* selected-state text = --accent-press (the "active" accent, #9a330a ~6.1:1 on --accent-bg) not
     --accent (~4.3:1, fails WCAG AA on the tint). Fill + border stay --accent, so the treatment is
     unchanged; only the text darkens a hair. 2026-07-25. */
  background:var(--accent-bg);border-color:var(--accent);color:var(--accent-press);font-weight:600;
}

/* NUMBERS (counts · scores · progress · lab/dose values) = BODY font with tabular alignment.
   MONO is reserved for coded IDs & code-keys ONLY (question IDs, rail course tags Rx/537/535/300,
   option keys A/B/C/D, the A–Z glossary index, abbreviation chips). Enforced here, source-order-last. */
.bb-count,.bb-count b,.chip .n,.facet-pill .n,.subcard-row .scn,.dgroup-n,
.dtitle-meta,.qprog,.case-pts,.case-labs .lab-val,.case-labs .lab-ref,.brow .v,
.startrow .count,.startrow .count b,.strip-legend .lg b{
  font-family:var(--body);font-variant-numeric:tabular-nums;
}
