:root{
  --paper:#F7F5F0; --paper2:#FDFCFA; --card:#FFFFFF;
  --ink:#1A1E1C; --ink-soft:#565C57; --ink-faint:#8A9089;
  --accent:#1F4D3F; --accent-soft:#E7EDE9; --accent-line:#C7D6CE;
  --copper:#A9662E; --copper-soft:#F3ECE3; --copper-line:#E7D6C4;
  --line:#E3DED3; --line-strong:#D3CCBD;
  --good:#1F6E4F; --warn:#B0743C; --bad:#9C4A38;
  --serif:"Iowan Old Style","Palatino Linotype",Palatino,"Book Antiqua",Georgia,serif;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,Helvetica,Arial,sans-serif;
  --mono:"SF Mono",ui-monospace,"JetBrains Mono",Menlo,Consolas,monospace;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;letter-spacing:-0.003em}
svg{display:block}
img{display:block}
a{color:inherit;text-decoration:none}
button{font-family:inherit}
.wrap{max-width:1240px;margin:0 auto;padding:0 32px}
.eyebrow{text-transform:uppercase;letter-spacing:.16em;font-size:.72rem;font-weight:600;color:var(--accent)}
h1,h2,h3{font-family:var(--serif);font-weight:600;letter-spacing:-0.01em;text-wrap:balance;margin:0}
.mono{font-family:var(--mono)}
.hidden{display:none!important}

/* ---------------- nav ---------------- */
.nav{position:sticky;top:0;z-index:60;background:rgba(247,245,240,.85);
  backdrop-filter:saturate(140%) blur(10px);border-bottom:1px solid var(--line)}
.nav .wrap{display:flex;align-items:center;gap:26px;height:64px}
.brand{font-family:var(--serif);font-size:1.32rem;font-weight:600;display:flex;align-items:center;gap:9px;cursor:pointer}
/* Brand mark: the upright route tree, in the map's own ramp shades (favicon.svg, same asset as
   the tab icon). Replaces the former rotated square — the header now carries the shape of a
   synthesis route instead of a generic dot. */
.brand .dot{width:18px;height:18px;background:url(favicon.svg?v=2) center/contain no-repeat}
.chip{font-family:var(--mono);font-size:.6rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--accent);border:1px solid var(--accent-line);border-radius:999px;padding:2px 8px}
.nav .links{display:flex;gap:6px;margin-left:auto}
.nav .links a{padding:7px 13px;border-radius:8px;font-size:.92rem;color:var(--ink-soft);transition:.14s}
.nav .links a:hover{color:var(--ink);background:#fff}
.nav .links a.active{color:var(--accent);background:var(--accent-soft);font-weight:600}
/* Mobile menu button — hidden at desktop widths, where the links sit inline. */
.nav-toggle{display:none;margin-left:auto;width:44px;height:44px;align-items:center;justify-content:center;
  background:transparent;border:1px solid var(--line-strong);border-radius:9px;color:var(--ink);cursor:pointer}
.nav-toggle:hover{border-color:var(--ink);background:#fff}
.nav-toggle .i-close{display:none}
.nav.open .nav-toggle .i-menu{display:none}
.nav.open .nav-toggle .i-close{display:block}
/* Keyboard users must be able to see where they are — the button is the only way into the menu. */
.nav-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.nav .links a:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
.btn{font-size:.9rem;font-weight:600;border-radius:8px;padding:9px 15px;cursor:pointer;
  display:inline-flex;align-items:center;gap:7px;transition:.16s;border:1px solid transparent}
.btn-primary{background:var(--accent);color:#fff}
.btn-primary:hover{background:#173a30}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line-strong)}
.btn-ghost:hover{border-color:var(--ink);background:#fff}
/* The third rank, between primary and ghost: tinted in the accent so it reads as an invitation
   rather than another way to browse. Used only for "Suggest a target" — the one action on the
   site that asks the reader for something. Arrow slides on hover, the usual "this goes somewhere"
   cue; suppressed under prefers-reduced-motion along with the rest of .btn's transition. */
.btn-suggest{color:var(--accent);background:var(--accent-soft);border-color:var(--accent-line)}
.btn-suggest:hover{background:#fff;border-color:var(--accent)}
.btn-suggest svg{transition:transform .16s}
.btn-suggest:hover svg{transform:translateX(2px)}
.btn-sm{padding:6px 11px;font-size:.82rem}

/* ---------------- landing ---------------- */
.hero{background:var(--paper2);border-bottom:1px solid var(--line)}
.hero .wrap{display:grid;grid-template-columns:1.2fr .8fr;gap:56px;
  align-items:start;padding-top:56px;padding-bottom:56px}
/* max-width is gone: the spans below decide where the lines break, so a character cap would only
   fight them. Each .hl is one intended line of the headline (see the markup in viewHome). */
.hero h1{font-size:clamp(1.6rem,2.7vw,2.2rem);line-height:1.2;margin:14px 0 0}
.hero h1 .hl{display:block}
/* The longest line ("AI-planned total synthesis routes") needs ~407px at the clamped-minimum
   25.6px, and a phone column gives ~311px — it fits again around a 471px viewport. Below 520px,
   where it cannot fit, it breaks at its own seam instead of wrapping late and leaving "routes"
   alone on the next line. Above that the parts are inline and the line reads as one. */
.hero h1 .hl-part{display:inline}
@media (max-width:520px){ .hero h1 .hl-part{display:block} }
.hero .lede{font-size:1.04rem;color:var(--ink-soft);max-width:60ch;margin:18px 0 0;line-height:1.6}
.hero .features{margin:12px 0 0;padding-left:20px;color:var(--ink-soft);max-width:60ch;
  font-size:1.02rem;line-height:1.6}
.hero .features li{margin:6px 0}
.hero .features li::marker{color:var(--accent)}
.hero .cta{display:flex;gap:13px;flex-wrap:wrap}
/* Sits under the CTA row, quieter than the buttons and than the lede — it is a reference, not an
   invitation. No 60ch limit as on the prose above: that is for reading comfort over several lines,
   and here it would wrap the id onto a line of its own while the column still has room. The id
   trails the title inline and stays unbroken when the title does wrap, as it does on a phone. */
.hero-paper{margin:18px 0 0;font-size:.92rem;line-height:1.55;color:var(--ink-soft)}
.hero-paper .paper-id{font-size:.8rem;color:var(--ink-faint);white-space:nowrap}
.ext{text-decoration:underline;text-underline-offset:2px;text-decoration-color:var(--accent-line)}
.ext:hover{text-decoration-color:var(--accent)}
.notice{margin:20px 0 26px;max-width:60ch;padding:13px 16px;background:var(--copper-soft);
  border:1px solid var(--copper-line);border-left:3px solid var(--warn);border-radius:6px;
  font-size:.94rem;line-height:1.55;color:var(--ink-soft)}
.notice strong{color:var(--ink)}
.route-card-hero{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px 20px 16px;
  box-shadow:0 1px 2px rgba(26,30,28,.04),0 22px 46px -26px rgba(26,30,28,.28);cursor:pointer}
.route-card-hero .rc-head{display:flex;justify-content:space-between;font-family:var(--mono);
  font-size:.66rem;letter-spacing:.04em;color:var(--ink-faint);text-transform:uppercase}
.route-card-hero .ok{color:var(--accent);font-weight:600}
.route-card-hero .struct{background:linear-gradient(180deg,#fff,#fbfaf7);border:1px solid var(--line);
  border-radius:9px;margin:12px 0;padding:10px}
.route-card-hero .struct img{width:100%;max-height:230px;object-fit:contain}
.home-section{padding:48px 0;border-bottom:1px solid var(--line)}
.sec-h{font-size:1.4rem;margin:0 0 8px}
.sec-sub{color:var(--ink-soft);max-width:72ch;margin:0 0 26px;font-size:.98rem}
.summary-table{border-collapse:collapse;width:100%;max-width:780px;font-size:.95rem;margin-top:14px}
.summary-table th{font-weight:600;text-align:left;color:var(--ink);padding:10px 32px 10px 0;
  white-space:nowrap;vertical-align:top;width:1%}
.summary-table th .dim{font-weight:400;color:var(--ink-faint)}
.summary-table td{color:var(--ink-soft);padding:10px 0;font-variant-numeric:tabular-nums}
.summary-table tr+tr th,.summary-table tr+tr td{border-top:1px solid var(--line)}
.explore-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
.explore-card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:22px;cursor:pointer;transition:.16s}
.explore-card:hover{border-color:var(--accent-line);transform:translateY(-2px);box-shadow:0 16px 36px -28px rgba(26,30,28,.4)}
.explore-card .ec-n{font-family:var(--serif);font-size:1.9rem;color:var(--accent);font-variant-numeric:tabular-nums}
.explore-card h3{font-size:1.1rem;margin:8px 0 6px}
.explore-card p{color:var(--ink-soft);font-size:.9rem;margin:0}

/* ---------------- page header + toolbar ---------------- */
.page{padding:40px 0 90px;min-height:70vh}
.page-head{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;margin-bottom:24px;flex-wrap:wrap}
.page-head h1{font-size:2rem}
.page-head .count{color:var(--ink-faint);font-family:var(--mono);font-size:.82rem;margin-top:4px}
.toolbar{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin-bottom:26px;
  padding:14px 16px;background:var(--paper2);border:1px solid var(--line);border-radius:12px}
.toolbar input[type=search],.toolbar select{font-family:inherit;font-size:.88rem;color:var(--ink);
  background:#fff;border:1px solid var(--line-strong);border-radius:8px;padding:8px 11px}
.toolbar input[type=search]{min-width:230px;flex:1}
.toolbar label{font-size:.78rem;color:var(--ink-soft);display:inline-flex;align-items:center;gap:6px}
.toolbar .seg{display:flex;border:1px solid var(--line-strong);border-radius:8px;overflow:hidden}
.toolbar .seg button{background:#fff;border:none;padding:7px 12px;font-size:.82rem;color:var(--ink-soft);cursor:pointer}
.toolbar .seg button.on{background:var(--accent);color:#fff}
.tags{display:flex;gap:6px;flex-wrap:wrap}
.tag{font-size:.76rem;padding:5px 11px;border-radius:999px;border:1px solid var(--line-strong);
  background:#fff;color:var(--ink-soft);cursor:pointer;transition:.14s}
.tag.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.reliable-toggle{font-weight:600;color:var(--accent);background:var(--accent-soft);
  border:1px solid var(--accent-line);border-radius:8px;padding:8px 12px;display:inline-flex;align-items:center;gap:7px}
.reliable-toggle .hint2{font-weight:400;color:var(--ink-faint);font-size:.74rem}
.count a{color:var(--accent);text-decoration:none;border-bottom:1px solid var(--accent-line)}
.count a:hover{border-color:var(--accent)}

/* ---------------- badges ---------------- */
.badge{font-size:.72rem;font-weight:600;padding:3px 9px;border-radius:999px;
  background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-line);white-space:nowrap}
.badge.alt{background:var(--copper-soft);color:var(--copper);border-color:var(--copper-line)}
.badge.gray{background:#EFEDE6;color:var(--ink-soft);border-color:var(--line-strong)}
.badge.key{background:#F6EEDD;color:#8A6320;border-color:#E7D6A8}
.feas{font-weight:700;text-transform:capitalize}
.feas-excellent{color:var(--good)} .feas-good{color:var(--good)}
.feas-moderate{color:var(--warn)} .feas-fair{color:var(--warn)}
.feas-acceptable{color:var(--warn)} .feas-fair2{color:var(--warn)}
.feas-poor{color:var(--bad)} .feas-challenging{color:var(--bad)} .feas-infeasible{color:var(--bad)}

/* ---------------- gallery cards ---------------- */
.grid{display:grid;gap:18px}
/* min(Npx, 100%) rather than a bare Npx: a plain minmax() floor cannot shrink below its minimum,
   so on a narrow screen the column stays wider than the container and the whole page scrolls
   sideways. The reaction grid's 360px floor did exactly that at 390px viewport width (360 + the
   wrap's 64px padding = 424 > 390), pushing every card 2px past the edge. The min() lets the
   column collapse to the available width instead. */
.grid.routes{grid-template-columns:repeat(auto-fill,minmax(min(270px,100%),1fr))}
.grid.mols{grid-template-columns:repeat(auto-fill,minmax(min(190px,100%),1fr))}
.grid.rxns{grid-template-columns:repeat(auto-fill,minmax(min(360px,100%),1fr))}
.card{background:var(--card);border:1px solid var(--line);border-radius:13px;overflow:hidden;
  cursor:pointer;transition:.16s;display:flex;flex-direction:column;position:relative}
.fav-star{position:absolute;top:8px;right:8px;z-index:1;width:26px;height:26px;border-radius:50%;
  background:#fff;border:1px solid var(--line);display:flex;align-items:center;justify-content:center;
  color:#d9a514;font-size:.95rem;box-shadow:0 2px 6px rgba(26,30,28,.12)}
.card:hover{border-color:var(--accent-line);transform:translateY(-2px);box-shadow:0 18px 40px -30px rgba(26,30,28,.45)}
.card .thumb{background:linear-gradient(180deg,#fff,#fbfaf7);border-bottom:1px solid var(--line);
  padding:12px;display:flex;align-items:center;justify-content:center;height:190px}
.card .thumb img{max-width:100%;max-height:166px;object-fit:contain}
.card .body{padding:14px 15px 15px}
.card .cid{font-family:var(--mono);font-size:.74rem;color:var(--ink-faint)}
.card .ctitle{font-family:var(--serif);font-size:1.02rem;margin:3px 0 4px;line-height:1.25}
.card .rxn-prose{font-size:.85rem;line-height:1.45;margin:3px 0 6px}
.card .org{font-style:italic;font-size:.78rem;color:var(--ink-faint);margin:0 0 10px}
.org-inline{font-style:italic}
.card .meta-badges{display:flex;flex-wrap:wrap;gap:6px}
.scorebar{display:flex;gap:6px;margin:2px 0 10px}
.sc{flex:1;text-align:center;border-radius:7px;padding:4px 2px;font-family:var(--serif);font-weight:600;
  font-size:1rem;font-variant-numeric:tabular-nums;line-height:1.05}
.sc i{display:block;font-family:var(--sans);font-style:normal;font-weight:600;font-size:.55rem;
  text-transform:uppercase;letter-spacing:.06em;opacity:.72;margin-top:1px}
.sc-o{background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-line)}
.sc-g{background:#E7F0E4;color:#2E6B33;border:1px solid #CADEC4}
.sc-f{background:var(--copper-soft);color:var(--copper);border:1px solid var(--copper-line)}
.sc-c{background:#E8EEF2;color:#33586B;border:1px solid #C9D8E0}
.scorebar.big .sc{padding:10px 4px;font-size:1.7rem}
.scorebar.big .sc i{font-size:.62rem;margin-top:3px}
.mol-card .thumb{height:150px}.mol-card .thumb img{max-height:128px}
.mol-card .formula{font-family:var(--mono);font-size:.8rem;color:var(--ink)}
.mol-card .sub{font-size:.72rem;color:var(--ink-faint);margin-top:3px}
.target-dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--accent);margin-right:5px;vertical-align:middle}

/* ---------------- reaction scheme ---------------- */
/* Every structure image comes off render_svg's fixed bond-length scale (see
   mol_rendering/BRIEF.md), so its own <img> width/height IS the true relative size --
   reactant and product, and one reaction next to another, are only comparable if we let
   that intrinsic size through instead of stretching each into its own fixed box. max-width/
   max-height below are a safety net for rare oversized structures, not a display size. */
.scheme{display:flex;align-items:center;gap:12px;flex-wrap:wrap;justify-content:center}
.scheme .mol{display:flex;align-items:center;justify-content:center}
.scheme .mol img{display:block;width:auto;height:auto;max-width:675px;max-height:415px} /* ~p99.5 ×1.3 */
.scheme .plus{font-family:var(--serif);font-size:1.3rem;color:var(--ink-faint)}
/* compact scheme used in reaction cards */
/* wide schemes wrap to a second line instead of clipping or shrinking, so the one
   shared MINI_SCALE holds across every card */
.scheme.mini{gap:6px;flex-wrap:wrap;align-items:center;justify-content:center}
.scheme.mini .mol{flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.scheme.mini .mol img{max-width:235px;max-height:145px} /* ≥ MINI_SCALE × p99.5 — max-* also overrides the inline JS sizes, so it must not bind */
.scheme.mini .plus{font-size:1rem}
.scheme.mini .arrow-wrap{min-width:54px;flex:0 1 64px}
.scheme.mini .arrow-wrap .arrow{min-width:44px}
.rxn-card{cursor:default}
.rxn-card .rxn-top{display:flex;align-items:center;justify-content:center;padding:16px;min-height:158px;
  border-bottom:1px solid var(--line);background:linear-gradient(180deg,#fff,#fbfaf7);cursor:pointer;overflow:hidden}
.rxn-card .rxn-cond{font-family:var(--mono);font-size:.72rem;color:var(--ink-soft);
  padding:11px 15px 0;line-height:1.35}
.arrow-wrap{display:flex;flex-direction:column;align-items:center;min-width:150px;flex:1}
.arrow-wrap .cond{font-family:var(--mono);font-size:.66rem;color:var(--ink-soft);text-align:center;
  margin-bottom:5px;max-width:230px;line-height:1.3}
.arrow-wrap .arrow{height:2px;width:100%;min-width:110px;background:var(--copper);position:relative}
.arrow-wrap .arrow:after{content:"";position:absolute;right:-1px;top:-4px;border-left:9px solid var(--copper);
  border-top:5px solid transparent;border-bottom:5px solid transparent}
.arrow-wrap .rxn-class{font-size:.68rem;color:var(--copper);font-weight:600;margin-top:6px;text-align:center}

/* ---------------- route detail ---------------- */
.detail{display:grid;grid-template-columns:1fr 340px;gap:44px;align-items:start}
.back{font-size:.85rem;color:var(--ink-soft);margin-bottom:18px;display:inline-block}
.back:hover{color:var(--accent)}
.route-switch{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:4px 0 26px;
  padding:13px 15px;background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:12px}
.route-switch .rs-label{font-size:.82rem;color:var(--accent);font-weight:600;margin-right:2px}
.rs-chip{font-size:.8rem;padding:6px 12px;border-radius:999px;background:#fff;
  border:1px solid var(--accent-line);color:var(--ink-soft);transition:.14s;white-space:nowrap}
.rs-chip:hover{border-color:var(--accent);color:var(--ink)}
.rs-chip.on{background:var(--accent);color:#fff;border-color:var(--accent)}
.rs-chip.on .feas,.rs-chip.on b{color:#fff}
.rs-more{display:inline-flex;gap:8px;align-items:center}
.rs-more-btn{font-family:var(--sans);font-size:.8rem;padding:6px 12px;border-radius:999px;cursor:pointer;
  background:transparent;border:1px dashed var(--line-strong);color:var(--ink-soft);white-space:nowrap}
.rs-more-btn:hover{border-color:var(--accent);color:var(--ink)}
.rs-more-list{display:none;gap:8px}
.rs-more.open .rs-more-list{display:inline-flex;flex-wrap:wrap}
.rs-more.open .rs-more-btn{display:none}
.route-summary{font-family:var(--serif);font-size:1.18rem;line-height:1.5;
  border-left:3px solid var(--accent);padding-left:20px;margin:20px 0 34px}
.step-note.route-critic{margin:-14px 0 22px;font-size:.98rem}
.steer-note{background:var(--copper-soft);border:1px solid var(--copper-line);border-radius:10px;
  padding:12px 16px;margin:0 0 22px;font-size:.88rem;color:var(--ink)}
.steer-note .lbl{display:block;font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;
  color:var(--copper);font-weight:700;margin-bottom:4px}
/* full-route overview (JACS-style strip) */
.overview{position:relative;background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px 22px;margin:24px 0 28px}
.fig-expand{position:absolute;bottom:14px;right:14px;z-index:4;background:#fff;
  border:1px solid var(--line-strong);border-radius:8px;width:28px;height:28px;
  font-size:.9rem;line-height:1;cursor:pointer;color:var(--ink-soft)}
/* on a reaction step scheme the product sits center-right, so a floating button would overlap
   it (see issue). Instead the scheme reserves a strip below the molecules (padding-bottom on
   .step-scheme) and the button sits inside that strip — never over a structure. */
.step-scheme .fig-expand{bottom:8px;right:8px;width:26px;height:26px;font-size:.82rem}
.fig-expand:hover{color:var(--ink);border-color:var(--ink)}
.fig-modal{position:fixed;inset:0;z-index:100;background:rgba(20,24,22,.72);
  display:flex;align-items:center;justify-content:center;padding:28px}
.fig-modal-body{background:#fff;border-radius:14px;padding:26px;max-width:96vw;max-height:92vh;overflow:auto}
.fig-modal .fig-expand{display:none}
.fig-modal .scheme .mol img{max-width:845px;max-height:520px}
.fig-modal .scheme{gap:22px}
.fig-modal .step-scheme{border:none;padding:0;margin:0}
.fig-close{position:fixed;top:22px;right:26px;z-index:101;background:#fff;border:1px solid var(--line-strong);
  border-radius:50%;width:36px;height:36px;cursor:pointer;font-size:1rem}
.ov-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:14px;gap:12px;flex-wrap:wrap}
.ov-hint{font-size:.78rem;color:var(--ink-faint)}
/* overflow-x is what keeps a wide structure from breaking the page. The old `max-width` on
   .ov-node img did that job as a side effect of clamping every image to the cell — which is what
   broke the shared scale — so it has to be paid for here instead. The widest published molecule is
   720px, giving a ~324px cell: too wide for a 320px phone on 6 of 724 real linear routes. Those
   scroll inside this card rather than pushing the whole page sideways.
   Chosen over shrinking the figure to fit the viewport, which would mean duplicating the padding
   values below in JS and keeping them in sync by hand. */
.overview-inner{display:flex;flex-wrap:wrap;align-items:center;gap:4px;overflow-x:auto}
.ov-unit{display:flex;align-items:center;flex:0 0 auto}
/* Cells size to their content so the strip's wrap is content-driven: rows hold as many
   structures as actually fit, instead of a fixed count set by a uniform cell width. */
.ov-node{min-width:72px;flex:0 0 auto;cursor:pointer;border:1px solid transparent;border-radius:9px;
  padding:6px 6px 4px;transition:.14s;background:#fff}
/* NO max-width here. app.js sizes each <img> from its true render size (molecules.json w/h)
   times ONE per-route scale, so every structure shares the same bond length. A max-width would
   still clamp that inline width — max-width beats width regardless of specificity — giving each
   molecule its own scale again. That was the bug. Scale, don't clamp. */
.ov-node img{height:auto;display:block;margin:0 auto}
.ov-node:hover{border-color:var(--accent);background:var(--accent-soft);transform:translateY(-2px)}
.ov-node.key{background:linear-gradient(180deg,#fff,var(--copper-soft))}
.ov-node.target{background:linear-gradient(180deg,#fff,var(--accent-soft))}
.ov-tag{display:block;text-align:center;font-family:var(--mono);font-size:.6rem;color:var(--ink-faint);
  margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ov-node.key .ov-tag{color:var(--copper)}
.ov-node.target .ov-tag{color:var(--accent);font-weight:600}
.ov-tag.start{color:var(--ink-soft)}
.ov-tag.keyint{color:var(--copper);font-weight:700;white-space:normal;overflow:visible;line-height:1.2}
.ov-arrow{flex:0 0 auto;min-width:66px;display:flex;flex-direction:column;justify-content:center;align-items:center;cursor:pointer}
.ov-arrow .line{width:40px;height:2px;background:var(--copper);position:relative}
.ov-arrow .line:after{content:"";position:absolute;right:-1px;top:-3px;
  border-left:7px solid var(--copper);border-top:4px solid transparent;border-bottom:4px solid transparent}
.ov-arrow .ov-step{font-family:var(--mono);font-size:.6rem;color:var(--ink-faint);margin-top:5px;white-space:nowrap}
.ov-arrow:hover .ov-step{color:var(--ink)}
.ov-arrow.key .line{background:var(--copper);height:2.5px}
.ov-arrow.key .line:after{border-left-color:var(--copper)}
.ov-arrow.key .ov-step{color:var(--copper);font-weight:700}
.ov-node.rx-key{background:linear-gradient(180deg,#fff,var(--copper-soft));
  border-color:var(--copper-line);box-shadow:0 10px 22px -12px rgba(169,102,46,.4)}
/* convergent/mixed tree — Cytoscape + dagre graph, real per-molecule node sizes */
.cy-tree{width:100%;height:320px;border:1px solid var(--line);border-radius:10px;background:#fff;cursor:default}
.tree-detailed-wrap{padding:4px 2px 2px}
.cy-tree.detailed{width:min(94vw,1700px);height:min(86vh,1000px);border:none;cursor:grab}
.cy-tree.detailed:active{cursor:grabbing}

.step{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:22px;margin-bottom:18px;scroll-margin-top:80px}
.step.key{border-color:var(--copper-line);box-shadow:0 0 0 3px var(--copper-soft)}
.step.flash{box-shadow:0 0 0 3px var(--accent);transition:box-shadow .2s}
.step-head{display:flex;align-items:center;gap:10px;margin-bottom:14px}
.step-class{font-weight:600;font-size:.98rem}
/* extra bottom padding reserves a strip for the expand button below the molecules,
   so the button never overlaps a structure (see gabriel/issues expand-button issue) */
.step-scheme{position:relative;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:18px 0 42px;margin:14px 0}
.step-note{font-size:.92rem;color:var(--ink-soft);margin:10px 0 0}
.page>.wrap>.step-note{margin:18px 0}
.step-note .lbl{font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;color:var(--ink-faint);font-weight:600;margin-bottom:3px}
.step-note .mono{font-family:var(--mono);font-size:.86rem}
.risk-note{color:var(--copper)}
.verdict{display:inline-flex;align-items:center;gap:8px;font-weight:600;font-size:.84rem;color:var(--accent);
  background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:8px;padding:7px 12px;margin-top:12px}
.verdict .tick{width:16px;height:16px;border-radius:50%;background:var(--accent);color:#fff;
  display:inline-flex;align-items:center;justify-content:center;font-size:.66rem}
.verdict.bad{color:var(--bad);background:#F6E9E5;border-color:#E4C6BD}
.verdict.bad .tick{background:var(--bad)}
.cond-chip{font-family:var(--mono);font-size:.82rem;background:var(--paper);border:1px solid var(--line);
  border-radius:7px;padding:8px 11px;color:var(--ink);display:inline-block}
/* Reaxys literature-precedent chip. Used both on the Reactions browser cards and
   in the route step note (Literature precedent). The count is a trust signal for
   everyone; the link itself only resolves for Reaxys subscribers. */
.reaxys-chip{display:inline-block;margin:6px 0 2px;font-size:.74rem;font-weight:600;
  color:var(--accent);background:var(--accent-soft);border:1px solid var(--accent-line);
  border-radius:999px;padding:2px 9px;text-decoration:none;transition:.14s}
.reaxys-chip:hover{border-color:var(--accent)}
/* "related" band: softer than a close precedent */
.reaxys-chip.related{color:var(--ink-soft);background:transparent;border-color:var(--line)}
.reaxys-chip.related:hover{border-color:var(--ink-soft)}
.step-details{margin-top:12px;border-top:1px dashed var(--line);padding-top:10px}
.step-details summary{cursor:pointer;font-size:.68rem;text-transform:uppercase;letter-spacing:.1em;color:var(--ink-faint);font-weight:600}
.step-details p{margin:9px 0 0;color:var(--ink-soft);font-size:.92rem}
/* SMILES copy: chip buttons (data-smiles) + click-to-copy structures on route steps */
.smiles-chip{font:inherit;font-size:.8rem;font-weight:600;color:var(--accent);background:none;border:0;padding:0;cursor:pointer;white-space:nowrap}
.smiles-chip:hover{text-decoration:underline}
.smiles-p code{font-family:var(--mono);font-size:.8rem;word-break:break-all;margin-right:10px}
.step-scheme .mol img{cursor:copy}
.reason-details summary{cursor:pointer;color:var(--ink-soft);font-size:.92rem;list-style:none}
.reason-details summary::-webkit-details-marker{display:none}
.reason-details summary::after{content:" ▸ read more";color:var(--accent);font-weight:600;font-size:.8rem;white-space:nowrap}
.reason-details[open] summary{display:none}
.reason-details p{margin:0;color:var(--ink-soft);font-size:.92rem}
.rd-less{background:none;border:0;padding:0;cursor:pointer;color:var(--accent);font-weight:600;font-size:.8rem;font-family:inherit;white-space:nowrap;vertical-align:baseline}
.rd-less:hover{text-decoration:underline}
.aside-p{font-size:.86rem;color:var(--ink-soft);margin:0;line-height:1.5}
.risk-list em{color:var(--accent);font-style:normal;display:block;margin-top:3px}
.step-jump{color:var(--accent);cursor:pointer;font-weight:600;white-space:nowrap}
.step-jump:hover{text-decoration:underline}
.aside-card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px;margin-bottom:16px}
.aside-card h3{font-size:.78rem;text-transform:uppercase;letter-spacing:.11em;color:var(--ink-faint);font-weight:600;margin-bottom:14px}
.spec-row{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--line);font-size:.9rem}
.spec-row:last-child{border-bottom:none}
.spec-row .v{font-weight:600;font-variant-numeric:tabular-nums}
.risk-list{list-style:none;padding:0;margin:0}
.risk-list li{font-size:.85rem;color:var(--ink-soft);padding:8px 0;border-bottom:1px solid var(--line)}
.risk-list li:last-child{border-bottom:none}
.risk-list b{color:var(--ink);display:block;margin-bottom:2px}
/* molecule-index key */
.molkey{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.mk{border:1px solid var(--line);border-radius:9px;padding:6px 6px 4px;cursor:pointer;
  background:linear-gradient(180deg,#fff,#fbfaf7);transition:.14s;text-align:center}
.mk:hover{border-color:var(--accent-line);transform:translateY(-1px)}
.mk-img img{width:100%;height:auto;max-height:66px;object-fit:contain}
.mk-lbl{font-family:var(--serif);font-weight:600;font-size:.9rem;color:var(--accent)}
.mk-hint{font-size:.72rem;color:var(--ink-faint);margin-top:9px;line-height:1.35}
/* building blocks: a left→right row of clickable structure thumbnails, no letter labels */
.bb-row{display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.bb-item{position:relative;flex:0 0 auto;width:64px;height:56px;display:flex;align-items:center;justify-content:center;
  border:1px solid var(--line);border-radius:8px;padding:4px;cursor:pointer;background:#fff;transition:.14s}
.bb-item:hover{border-color:var(--accent);background:var(--accent-soft)}
.bb-item img{max-width:100%;max-height:100%;width:auto;height:auto}
/* ⚗ badge: this building block has an AiZynthFinder synthesis on its molecule page */
.bb-route{position:absolute;top:-6px;right:-6px;width:18px;height:18px;border-radius:50%;
  background:var(--copper);color:#fff;font-size:.7rem;line-height:18px;text-align:center}
/* sourcing category — colour the chip's left edge; matched dots/legend below */
.bb-buyable{border-left:3px solid var(--good)}
.bb-obtainable{border-left:3px solid var(--copper)}
.bb-small{border-left:3px solid var(--ink-faint)}
.bb-unavailable{border-left:3px solid var(--bad)}
.bb-legend{display:flex;flex-wrap:wrap;gap:10px 14px;margin-top:12px}
.bb-leg{font-size:.72rem;color:var(--ink-soft);display:flex;align-items:center;gap:5px}
.bb-leg::before{content:"";width:9px;height:9px;border-radius:2px;background:var(--line-strong)}
.bb-leg.bb-buyable{border:0}.bb-leg.bb-buyable::before{background:var(--good)}
.bb-leg.bb-obtainable{border:0}.bb-leg.bb-obtainable::before{background:var(--copper)}
.bb-leg.bb-small{border:0}.bb-leg.bb-small::before{background:var(--ink-faint)}
.bb-leg.bb-unavailable{border:0}.bb-leg.bb-unavailable::before{background:var(--bad)}
/* category dot in the "How to obtain it" card heading/text */
.cat-dot{display:inline-block;width:9px;height:9px;border-radius:2px;margin-right:7px;vertical-align:baseline}
.cat-buyable{background:var(--good)}
.cat-obtainable{background:var(--copper)}

/* ---------------- leaf sourcing ("how to obtain it") ---------------- */
.leaf-route{margin-top:20px}
.leaf-steps{display:flex;flex-direction:column;gap:14px;margin:4px 0 12px}
.leaf-step{display:flex;align-items:center;gap:10px}
.leaf-step-n{flex:0 0 auto;width:22px;height:22px;border-radius:50%;background:var(--paper);
  border:1px solid var(--line);font-size:.72rem;font-weight:600;color:var(--ink-soft);
  display:flex;align-items:center;justify-content:center}
.leaf-step .scheme{margin:0}
.leaf-steps img[data-hash]{cursor:copy}

/* ---------------- molecule detail page ---------------- */
.mol-view-card{padding:20px}
.mol-view{background:linear-gradient(180deg,#fff,#fbfaf7);border:1px solid var(--line);border-radius:10px;
  padding:24px;display:flex;align-items:center;justify-content:center;min-height:520px}
.mol-view-img{width:100%;height:100%;max-height:640px;object-fit:contain}
@media (max-width:960px){.mol-view{min-height:320px}}

/* ---------------- ratings + comments ---------------- */
.engage{background:var(--paper2);border:1px solid var(--line);border-radius:14px;padding:22px;margin:26px 0 32px}
.engage .note{font-size:.76rem;color:var(--ink-faint);background:#fff;border:1px dashed var(--line-strong);
  border-radius:8px;padding:8px 11px;margin-bottom:16px}
.stars{display:inline-flex;gap:3px;font-size:1.5rem;cursor:pointer}
.stars .star{color:var(--line-strong);transition:.1s;line-height:1}
.stars .star.on{color:var(--copper)}
.stars .star:hover{transform:scale(1.15)}
.rate-summary{font-size:.85rem;color:var(--ink-soft);margin-left:10px}
.cmt-form{display:flex;flex-direction:column;gap:9px;margin-top:16px}
.cmt-form textarea{font-family:inherit;font-size:.92rem;border:1px solid var(--line-strong);border-radius:9px;
  padding:11px;min-height:70px;resize:vertical}
.cmt-list{margin-top:18px;display:flex;flex-direction:column;gap:12px}
.cmt{background:#fff;border:1px solid var(--line);border-radius:10px;padding:12px 14px}
.cmt .who{font-size:.78rem;font-weight:600;color:var(--accent)}
.cmt .when{font-size:.72rem;color:var(--ink-faint)}
.cmt .txt{font-size:.92rem;margin-top:5px}

/* ---------------- chemical space (round TMAP, landing page) ----------------
   Replaces the old full-width dark map panel. The OGDF FM^3 layout is radially symmetric, so a
   square/disc frame fits it without the dead corners a 16:9 panel left, and a paper background
   keeps it part of the page instead of a black slab dropped into it. */
/* No scroll-margin-top here as on the other anchor targets: where #/map lands depends on whether
   the disc fits under the sticky nav, which a fixed offset cannot express — scrollToChemicalSpace()
   in app.js measures it. */
.tmap-section{padding-bottom:16px}
.tmap-wrap{display:flex;flex-direction:column;align-items:center;gap:14px}
.tmap-round{position:relative;width:100%;max-width:660px;aspect-ratio:1/1;margin:0 auto;
  background:var(--paper2);border:1px solid var(--line);border-radius:50%;
  box-shadow:inset 0 0 60px -30px rgba(31,77,63,.18)}
#tmap{width:100%;height:100%;display:block;border-radius:50%}
/* Controls sit ABOVE the disc rather than floating on it: on a light background an overlay chip
   either fights the points or needs a scrim, and a circle has no quiet corner to put one in. */
.tmap-controls{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:0 auto 4px}
.tmap-controls .tmc{background:#fff;color:var(--ink-soft);border:1px solid var(--line-strong);
  border-radius:8px;padding:6px 12px;font-family:inherit;font-size:.8rem;cursor:pointer;transition:.14s}
.tmap-controls .tmc:hover{color:var(--ink);border-color:var(--accent-line)}
.tmap-controls .tmc.on{background:var(--accent-soft);border-color:var(--accent-line);
  color:var(--accent);font-weight:600}
.tmap-legend{font-family:var(--mono);font-size:.72rem;color:var(--ink-faint);width:230px;margin:0 auto}
.tmap-legend .grad{height:8px;border-radius:3px;margin:0 0 3px;
  background:linear-gradient(90deg,#E7EDE9,#A8C0B4,#5E8877,#1F4D3F)}   /* must match SA_RAMP in app.js */
.tmap-legend .ends{display:flex;justify-content:space-between}
.tmap-hint{font-size:.8rem;color:var(--ink-faint);text-align:center}
.map-tip{position:absolute;pointer-events:none;z-index:8;background:#fff;border:1px solid var(--line);
  border-radius:10px;padding:8px;box-shadow:0 12px 30px -12px rgba(26,30,28,.35);width:170px;display:none}
.map-tip img{width:100%;max-height:130px;object-fit:contain}
.map-tip .cap{font-family:var(--mono);font-size:.7rem;color:var(--ink-soft);text-align:center;margin-top:4px}

/* ---------------- footer ---------------- */
.foot{background:var(--paper2);padding:40px 0;border-top:1px solid var(--line)}
.foot .wrap{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:18px}
.foot .attr{font-size:.84rem;color:var(--ink-soft);margin-top:6px}
/* The credit line is the second .attr — tighter to the tagline above it than the tagline is to the
   brand, so the two read as one block rather than three loose lines. */
.foot .attr.credit{margin-top:3px}
/* Underlined rather than merely tinted: it sits mid-sentence, where a colour change alone does not
   read as a link. */
.foot .attr a{color:var(--ink-soft);text-decoration:underline;text-underline-offset:2px;
  text-decoration-color:var(--line-strong);transition:.14s}
.foot .attr a:hover{color:var(--accent);text-decoration-color:var(--accent)}
.foot-right{display:flex;align-items:center;gap:22px}
.foot-link{font-size:.86rem;color:var(--ink-soft);transition:.14s}
.foot-link:hover{color:var(--accent)}
.epfl-logo{display:inline-flex;align-items:center}
.epfl-logo img{display:block;height:26px;width:auto}

/* nav account box (Supabase mode) */
.authbox{display:inline-flex;align-items:center;gap:8px}
.authbox:empty{display:none}
.who-nav{font-family:inherit;font-size:.86rem;color:var(--ink-soft);max-width:16ch;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  background:none;border:none;padding:0;cursor:pointer;border-bottom:1px dashed var(--line-strong)}
.who-nav:hover{color:var(--accent);border-bottom-color:var(--accent-line)}

/* sign-in dialog */
.auth-modal{position:fixed;inset:0;z-index:220;background:rgba(26,30,28,.42);
  backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;padding:20px}
.auth-card{position:relative;background:var(--paper);border:1px solid var(--line);border-radius:16px;
  width:100%;max-width:400px;padding:30px 28px 26px;box-shadow:0 30px 80px -30px rgba(26,30,28,.5)}
.auth-card h2{font-family:var(--serif);font-size:1.35rem;margin:0 0 4px}
.auth-close{position:absolute;top:14px;right:14px;background:none;border:none;font-size:1.05rem;
  color:var(--ink-faint);cursor:pointer;line-height:1;padding:4px}
.auth-close:hover{color:var(--ink)}
.auth-sub{color:var(--ink-soft);font-size:.92rem;margin:6px 0 16px}
/* Two fields now (name + email), so each needs a label — placeholders alone stop telling you which
   is which once they are filled in. */
.auth-label{display:block;font-size:.78rem;font-weight:600;color:var(--ink-soft);margin:0 0 5px}
.auth-label + .auth-input{margin-bottom:2px}
.auth-hint{font-size:.76rem;color:var(--ink-faint);margin:5px 0 14px;line-height:1.4}
.auth-input{width:100%;box-sizing:border-box;font-family:inherit;font-size:1rem;color:var(--ink);
  background:#fff;border:1px solid var(--line-strong);border-radius:9px;padding:11px 13px}
.auth-input:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-soft)}
.auth-btn{width:100%;justify-content:center;margin-top:12px;padding:11px}
.auth-alt{display:block;margin:12px auto 0;background:none;border:none;font-family:inherit;
  font-size:.82rem;color:var(--ink-soft);text-decoration:underline;cursor:pointer}
.auth-alt:hover{color:var(--accent)}
.auth-msg{min-height:1.1em;margin-top:12px;font-size:.84rem;text-align:center}
.auth-msg.ok{color:var(--accent)}
.auth-msg.err{color:#b0402f}
.auth-step[hidden]{display:none}
/* Turnstile widget. Usually renders nothing (the check is invisible), so the container must not
   reserve space or leave a gap above the button — it only takes up room if a challenge appears.
   :empty covers "Turnstile not configured" and "invisible mode" alike. */
.auth-captcha{margin-top:14px;display:flex;justify-content:center}
.auth-captcha:empty{display:none;margin:0}

/* ---------------- Suggest a target (#/suggest) ----------------
   Deliberately a single conservative column: no fixed pixel widths, every control
   box-sizing:border-box and max-width:100%, and the one horizontal row (type dropdown + target
   input) wraps to two lines rather than overflowing. That way narrow screens are safe by
   construction rather than by testing. Text inputs reuse .auth-input; strategy blocks reuse the
   --paper2 card treatment of .engage. */
.sug{max-width:760px}
.sug-who{background:var(--paper2);border:1px solid var(--line);border-radius:11px;
  padding:13px 16px;margin:20px 0 6px;font-size:.9rem;color:var(--ink-soft);
  display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.sug-who b{color:var(--ink)}
.sug-restored{font-size:.82rem;color:var(--ink-faint);margin:10px 0 0}
.sug-restored[hidden]{display:none}
.sug-link{background:none;border:none;padding:0;font-family:inherit;font-size:inherit;
  color:var(--accent);text-decoration:underline;cursor:pointer}
.sug-form{margin-top:26px}
.sug-field{margin:0 0 30px}
.sug-label{display:block;font-weight:600;font-size:.98rem;color:var(--ink);line-height:1.45}
.sug-req,.sug-opt{font-weight:400;font-size:.72rem;text-transform:uppercase;letter-spacing:.05em;
  margin-left:6px;white-space:nowrap}
.sug-req{color:#b0402f}
.sug-opt{color:var(--ink-faint)}
.sug-hint{font-size:.85rem;color:var(--ink-soft);margin:6px 0 12px;line-height:1.55}
/* wrap, don't overflow: below ~420px the dropdown sits on its own line above the input */
.sug-row{display:flex;flex-wrap:wrap;gap:10px}
.sug-type{flex:0 0 auto;width:auto;min-width:140px;font-size:.92rem}
.sug-target{flex:1 1 260px;min-width:0;font-family:var(--mono);font-size:.92rem}
.sug-ta{width:100%;box-sizing:border-box;font-family:inherit;font-size:.92rem;color:var(--ink);
  background:#fff;border:1px solid var(--line-strong);border-radius:9px;padding:11px 13px;
  line-height:1.55;resize:vertical}
.sug-ta:focus{outline:none;border-color:var(--accent-line);box-shadow:0 0 0 3px var(--accent-soft)}
.sug-status{margin-top:9px;font-size:.83rem;line-height:1.5}
.sug-status[hidden]{display:none}
.sug-status.ok{color:var(--accent)}
.sug-status.ok::before{content:"✓ ";font-weight:700}
.sug-status.err{color:#b0402f}
.sug-status.err::before{content:"✕ ";font-weight:700}
.sug-status.busy,.sug-status.hint{color:var(--ink-faint)}
/* "we already have routes to this" — informational, never a warning: the person may still be
   suggesting a strategy those routes don't take, so this reads as a helpful aside, not a rejection */
.sug-known{margin-top:10px;padding:10px 13px;border:1px solid var(--line);border-left:3px solid var(--accent);
  border-radius:9px;background:var(--paper2);font-size:.85rem;line-height:1.55}
.sug-known[hidden]{display:none}
.sug-known a{color:var(--accent);font-weight:600;white-space:nowrap}
.sug-known-note{display:block;margin-top:3px;color:var(--ink-faint);font-size:.8rem}
.sug-preview{margin-top:12px;background:#fff;border:1px solid var(--line);border-radius:11px;
  padding:10px;display:inline-block;max-width:100%;overflow:hidden}
.sug-preview[hidden]{display:none}
.sug-preview svg{display:block;max-width:100%;height:auto}
.sug-strategy{background:var(--paper2);border:1px solid var(--line);border-radius:12px;
  padding:16px;margin:0 0 12px}
.sug-strategy-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:9px}
.sug-strategy-n{font-size:.74rem;text-transform:uppercase;letter-spacing:.06em;color:var(--ink-faint)}
.sug-remove{background:none;border:none;padding:0;font-family:inherit;font-size:.78rem;
  color:var(--ink-faint);text-decoration:underline;cursor:pointer}
.sug-remove:hover{color:#b0402f}
.sug-strategy .sug-ta{margin-bottom:9px}
.sug-add{margin-top:2px}
.sug-radios{display:flex;flex-wrap:wrap;gap:20px;margin-top:10px;font-size:.92rem}
.sug-radios label{display:flex;align-items:center;gap:7px;cursor:pointer}
.sug-actions{display:flex;flex-wrap:wrap;align-items:center;gap:14px;margin-top:34px;
  padding-top:22px;border-top:1px solid var(--line)}
.sug-actions .btn[disabled]{opacity:.45;cursor:not-allowed}
.sug-gate{font-size:.83rem;color:var(--ink-faint)}
.sug-thanks{margin-top:26px;background:var(--paper2);border:1px solid var(--line);
  border-radius:14px;padding:24px}
.sug-thanks h2{font-family:var(--serif);font-size:1.3rem;margin:0 0 10px}
.sug-thanks p{font-size:.92rem;color:var(--ink-soft);margin:0 0 12px}
.sug-mine{margin-top:34px;font-size:.88rem}
.sug-mine summary{cursor:pointer;color:var(--ink-soft)}
.sug-mine-list{margin:12px 0 0;padding-left:20px}
.sug-mine-list li{margin-bottom:7px;line-height:1.55}

/* comment form controls + collapsible list */
.cmt-actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:8px}
.cmt-private{font-size:.8rem;color:var(--ink-soft);display:inline-flex;align-items:center;gap:6px;cursor:pointer}
.cmt-collapse{margin-top:14px}
.cmt-collapse>summary{cursor:pointer;font-size:.82rem;font-weight:600;color:var(--ink-soft);
  list-style:none;display:inline-flex;align-items:center;gap:6px;user-select:none}
.cmt-collapse>summary::-webkit-details-marker{display:none}
.cmt-collapse>summary::before{content:"▸";color:var(--ink-faint);transition:transform .15s}
.cmt-collapse[open]>summary::before{transform:rotate(90deg)}
.cmt-collapse>summary:hover{color:var(--accent)}
.cmt.private{background:var(--paper2);border-left:2px solid var(--accent-line);padding-left:10px}
.cmt-badge{font-family:var(--mono);font-size:.6rem;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-faint);border:1px solid var(--line-strong);border-radius:999px;padding:1px 7px}
.cmt-edited{font-size:.7rem;color:var(--ink-faint);font-style:italic}
.cmt-edit{font-family:inherit;font-size:.74rem;color:var(--ink-faint);background:none;border:none;
  padding:0;margin-left:6px;cursor:pointer;text-decoration:underline}
.cmt-edit:hover{color:var(--accent)}
.cmt-editor{margin-top:8px}
.cmt-edit-text{width:100%;min-height:70px;font-family:inherit;font-size:.92rem;color:var(--ink);
  background:#fff;border:1px solid var(--line-strong);border-radius:8px;padding:9px 11px;resize:vertical}
.cmt-edit-actions{display:flex;align-items:center;gap:12px;margin-top:8px;flex-wrap:wrap}

/* legal / privacy page */
.legal{max-width:760px}
.legal h1{margin-bottom:4px}
.legal-meta{font-family:var(--mono);font-size:.78rem;color:var(--ink-faint);margin:0 0 22px}
.legal h2{font-size:1.06rem;margin:26px 0 8px}
.legal p,.legal li{color:var(--ink-soft);line-height:1.6;font-size:.95rem}
.legal ul{padding-left:1.2em;margin:8px 0}
.legal li{margin:6px 0}
.legal a{color:var(--accent);text-decoration:underline}

/* ---------------- about ---------------- */
.about-lede{font-size:1.02rem;color:var(--ink-soft)}
.about h2{margin-top:30px}
/* One card per lab. auto-fit with min(...,100%) so cards sit side by side on a wide screen and
   stack cleanly on a phone with no media query — and, critically, so the column can shrink below
   its preferred width instead of pushing the page into horizontal scroll. */
.about-groups{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));
  gap:18px;margin-top:14px}
.about-group{background:var(--paper2);border:1px solid var(--line);border-radius:12px;padding:18px 20px}
.about-group h3{font-size:1.02rem;margin:0}
.about-group-meta{font-family:var(--mono);font-size:.74rem;color:var(--ink-faint);margin:5px 0 2px}
.about-team{list-style:none;padding:0;margin:10px 0 0}
.about-team li{padding:6px 0;border-bottom:1px solid var(--line);font-size:.95rem}
.about-team li:last-child{border-bottom:none}
/* Deep-link target for #/about/team. The nav is sticky, so without this the heading scrolls to
   y=0 and sits underneath it. Matches the offsets used by .step and .glossary .gl-entry. */
.about h2[id]{scroll-margin-top:80px}
.about-list{margin:12px 0 0;padding-left:20px}
.about-list li{margin-bottom:10px}
.about-desc{color:var(--ink-soft);font-size:.92rem;margin-top:2px}
/* Funder wording that has to appear verbatim — set apart so it is not casually reworded. */
.about-fundnote{margin-top:14px;padding:12px 14px;background:var(--accent-soft);
  border:1px solid var(--accent-line);border-radius:10px;font-size:.93rem;color:var(--ink)}

/* Ready-to-paste BibTeX. A BibTeX entry has meaningful line breaks and alignment, so it must not
   reflow: the block scrolls horizontally inside itself rather than wrapping or widening the page. */
.bib{margin-top:16px;border:1px solid var(--line);border-radius:10px;background:var(--paper2);
  overflow:hidden}
.bib-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:8px 10px 8px 14px;border-bottom:1px solid var(--line)}
.bib-head .mono{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-faint)}
.bib-copy{font-family:inherit;font-size:.8rem;font-weight:600;color:var(--accent);
  background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:7px;
  padding:4px 10px;cursor:pointer;transition:.16s}
.bib-copy:hover{background:#fff;border-color:var(--accent)}
.bib-copy:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.bib-body{margin:0;padding:13px 14px;overflow-x:auto;font-family:var(--mono);font-size:.78rem;
  line-height:1.65;color:var(--ink);tab-size:2}

/* ---------------- glossary ---------------- */
/* plain entries (no boxes — they made the page hard to scan): heading + prose,
   separated by a hairline */
.glossary .gl-entry{margin:0;padding:16px 0;border-bottom:1px solid var(--line);scroll-margin-top:65px}
.glossary .gl-entry:last-child{border-bottom:none}
.glossary .gl-entry.gl-hit{animation:gl-flash 2s ease-out}
@keyframes gl-flash{0%,40%{background:color-mix(in srgb,var(--accent) 12%,transparent)}100%{background:transparent}}
.glossary .gl-entry h3{font-size:1rem;margin:0 0 6px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.glossary .gl-body{color:var(--ink-soft);line-height:1.6;font-size:.93rem}
.glossary h2{margin-top:36px}
.gl-chip{display:inline-block;font-family:var(--mono);font-size:.62rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;padding:2px 8px;border-radius:999px;vertical-align:middle}
.gl-chip.computed{background:var(--accent-soft);color:var(--accent);border:1px solid var(--accent-line)}
.gl-chip.ai{background:var(--copper-soft);color:var(--copper);border:1px solid var(--copper-line)}

/* small ⓘ linking to the glossary from score bars */
.info-i{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  width:16px;height:16px;border-radius:50%;border:1px solid var(--line-strong);
  font-family:var(--serif);font-style:italic;font-size:.68rem;font-weight:700;
  color:var(--ink-faint);background:#fff;align-self:center;transition:.14s}
.info-i:hover{color:var(--accent);border-color:var(--accent)}

.empty{text-align:center;color:var(--ink-faint);padding:60px 20px;font-size:.95rem}
/* Inside a .grid it is a grid item, so without this it lands in the first column and centres
   itself in one narrow track rather than across the row it is standing in for. */
.grid>.empty{grid-column:1/-1}

/* Sits between the toolbar and the routes grid, so it is deliberately thin — one line of copy and
   a small button, tinted like .btn-suggest so the two read as one thread. Anything taller would
   push the first row of results below the fold, which is not a trade worth making for a prompt
   most visitors do not need. The button never shrinks below its label, so the copy is what wraps. */
.suggest-strip{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:12px;margin:0 0 20px;padding:11px 16px;font-size:.9rem;color:var(--ink-soft);
  background:var(--accent-soft);border:1px solid var(--accent-line);border-radius:11px}
.suggest-strip>div{max-width:70ch}
.suggest-strip b{color:var(--ink)}
.suggest-strip .btn-suggest{flex:0 0 auto;background:#fff}
.suggest-strip .btn-suggest:hover{border-color:var(--accent)}

@media (max-width:960px){
  .hero .wrap{grid-template-columns:1fr;gap:34px}
  .summary-table th{white-space:normal}
  .explore-grid{grid-template-columns:repeat(2,1fr)}
  .detail{grid-template-columns:1fr}
  .aside-card{position:static}
  /* The links collapse into a panel under the bar instead of vanishing. `.nav` is sticky, hence
     already a positioned ancestor, so the panel resolves against it and spans the full width
     rather than being trapped inside .wrap's padding. */
  .nav .wrap{gap:12px}
  .nav-toggle{display:inline-flex}
  .nav .links{display:none;position:absolute;left:0;right:0;top:64px;flex-direction:column;
    gap:2px;margin:0;padding:10px 20px 16px;background:var(--paper2);
    border-bottom:1px solid var(--line);box-shadow:0 18px 40px -24px rgba(26,30,28,.35)}
  .nav.open .links{display:flex}
  /* Roomier rows: these are touch targets now, not pointer targets. */
  .nav .links a{padding:12px 12px;font-size:1rem;border-radius:10px}
}
/* Below ~420px the brand + beta chip + Sign in + toggle stop fitting on one 64px row. */
@media (max-width:420px){
  .brand{font-size:1.12rem}
  .brand .dot{width:16px;height:16px}
  .brand .chip{display:none}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ---------------- back-to-top ---------------- */
#to-top{position:fixed;right:22px;bottom:22px;z-index:150;width:44px;height:44px;border-radius:50%;
  background:var(--accent);color:#fff;border:none;cursor:pointer;display:flex;align-items:center;justify-content:center;
  box-shadow:0 8px 22px -8px rgba(26,30,28,.5);opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity .2s,transform .2s,background .15s}
#to-top.show{opacity:1;transform:translateY(0);pointer-events:auto}
#to-top:hover{background:#173a30}

/* ---------------- print / PDF export (route detail) ---------------- */
.print-only{display:none}
.cy-print{display:none}
@media print{
  @page{margin:14mm}
  /* reaction arrows are drawn with background/border colors, which browsers strip when printing —
     force exact color rendering so shafts + arrowheads survive in the PDF */
  *{-webkit-print-color-adjust:exact!important;print-color-adjust:exact!important}
  body{background:#fff;color:#000}
  .nav,.foot,.route-switch,.engage,.back,.no-print,.stars,.rate-summary{display:none!important}
  /* convergent/mixed figure: canvas prints blank, so show the rasterized PNG instead */
  .overview:has(.cy-print) .cy-tree{display:none!important}
  .cy-print{display:block!important;width:100%;height:auto;break-inside:avoid}
  .print-only{display:block}
  .print-head{font-family:var(--mono);font-size:.7rem;letter-spacing:.04em;color:var(--ink-soft);
    border-bottom:1px solid var(--line);padding-bottom:8px;margin-bottom:14px}
  .page{padding:0!important;min-height:0}
  .wrap{max-width:none;padding:0}
  .detail{display:block}
  .detail>div:last-child{margin-top:20px}
  .aside-card{position:static;margin:0 0 12px;break-inside:avoid}
  .overview,.step,.aside-card,.route-summary,.route-critic,.steer-note{box-shadow:none!important;break-inside:avoid}
  .disclosure{display:block!important}          /* expand Reasoning + Mechanistic analysis in the PDF */
  .disclosure summary{display:none}
  .fig-modal{display:none!important}
  .cy-tree{border:none}
  .overview{border-color:var(--line)}
  a[href]{color:inherit;text-decoration:none}
  .aside-card,.step{page-break-inside:avoid}
}
