/* Blackgrove search chrome.
 *
 * Self-contained: this file owns every value it uses -- no import, no CDN, no
 * framework. The palette is pure-neutral grays at chroma 0 with a single black
 * accent, one link blue, and two chip families (peach for a filter, blue for
 * its value) generated at matched OKLCH weight so neither outshouts the other.
 *
 * Prior art for the token structure is credited in README.md, not here: a
 * stylesheet is a product surface and carries no one else's name. */

/* ── tokens ─────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light;
  --ox-bg-base:#ffffff; --ox-bg-subtle:#fafafa; --ox-bg-muted:#f5f5f5; --ox-bg-emphasis:#ebebeb;
  --ox-text-primary:#171717; --ox-text-secondary:#3f3f3f; --ox-text-tertiary:#5c5c5c;
  --ox-text-muted:#8a8a8a; --ox-text-disabled:#bcbcbc; --ox-text-inverse:#ffffff;
  --ox-border-subtle:#f0f0f0; --ox-border-default:#e2e2e2; --ox-border-strong:#d4d4d4;
  --ox-accent:#000000; --ox-accent-hover:#1a1a1a;
  --ox-info-fg:#1f6feb; --ox-link:#1f6feb;
  --ox-success-fg:#1a7f37; --ox-success-bg:#e6f7ec; --ox-success-border:#b9e3c6;
  --ox-danger-fg:#cf222e; --ox-danger-bg:#feeceb; --ox-danger-border:#fbc6c2;
  --ox-font-sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",sans-serif;
  --ox-font-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --ox-radius-xs:4px; --ox-radius-sm:6px; --ox-radius-md:8px; --ox-radius-lg:12px; --ox-radius-pill:9999px;
  --ox-elev-1:0 3px 6px -2px rgba(0,0,0,.02), 0 1px 1px 0 rgba(0,0,0,.04);
  --ox-elev-2:0 0 0 1px var(--ox-border-default), 0 3px 6px -2px rgba(0,0,0,.02), 0 1px 1px 0 rgba(0,0,0,.04);
  --ox-elev-overlay:0 12px 32px -8px rgba(0,0,0,.18), 0 4px 12px -4px rgba(0,0,0,.08);
  --ox-duration-base:150ms; --ox-ease:cubic-bezier(.25,.46,.45,.94);
  --ox-topbar-height:56px; --ox-rail-width:300px;
  /* builder chip families: peach = a filter, blue = its value */
  --kw-fg:#4e5662; --kw-bg:#e7ecf1;
  --conn-fg:#b25d06; --conn-bg:#fdf6f0;
  --prop-fg:#b25d06; --prop-bg:#fae1d1; --prop-bg-hov:#f3d0b7;
  --val-fg:#1f6feb; --val-bg:#dbe7ff; --val-bg-hov:#c7d8fb;
  --vconn-fg:#1f6feb; --vconn-bg:#f2f6fd;
  --w-author:#047857; --w-source:#b45309;
  --ink:#0a0a0a; --muted:#52525b; --faint:#a1a1aa; --hair:#f0f0f2;
}
*,*::before,*::after { box-sizing:border-box; }
body {
  margin:0; background:var(--ox-bg-base); color:var(--ox-text-primary);
  font-family:var(--ox-font-sans); font-size:14px; line-height:24px;
  -webkit-font-smoothing:antialiased;
}
button,input,select,textarea { font:inherit; color:inherit; }
a { color:var(--ox-link); text-decoration:none; }
a:hover { text-decoration:underline; }
:focus-visible { outline:2px solid var(--ox-accent); outline-offset:2px; }
svg { display:block; }
.num { font-variant-numeric:tabular-nums slashed-zero; }
/* The UA rule for [hidden] is display:none at the lowest specificity, so any
   author rule that sets display -- .btn does, inline-flex -- beats it and the
   element stays on screen with its hidden attribute set. Everything that hides
   itself in this application does it with that attribute. */
[hidden] { display:none !important; }

/* ── top bar ───────────────────────────────────────────────────────────────── */
.topbar {
  position:sticky; top:0; z-index:100; height:var(--ox-topbar-height);
  display:flex; align-items:center; gap:28px; padding:0 20px;
  background:var(--ox-bg-base); border-bottom:1px solid transparent;
}
.topbar.on-serp { border-bottom-color:var(--ox-border-subtle); }
.brand { display:flex; align-items:center; cursor:pointer; background:none; border:0; padding:0; }
/* The lockup is 6.4:1 and sized by HEIGHT only -- a width would distort it. */
.brand .wordmark { height:22px; width:auto; color:var(--ink); display:block; }
.nav { display:flex; align-items:center; gap:4px; }
.nav button, .nav a {
  display:inline-flex; align-items:center; gap:3px; padding:6px 10px; border:0; background:none;
  border-radius:var(--ox-radius-sm); font-size:14px; font-weight:400; color:var(--ox-text-primary);
  cursor:pointer; text-decoration:none;
}
.nav button:hover, .nav a:hover { background:var(--ox-bg-muted); text-decoration:none; }
.topbar-right { margin-left:auto; display:flex; align-items:center; gap:8px; }
.btn {
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  height:34px; padding:0 16px; border-radius:var(--ox-radius-md);
  border:1px solid var(--ox-border-default); background:var(--ox-bg-base);
  font-size:14px; font-weight:500; cursor:pointer; transition:background var(--ox-duration-base) var(--ox-ease);
}
.btn:hover { background:var(--ox-bg-muted); }
.btn-dark { background:var(--ox-accent); border-color:var(--ox-accent); color:var(--ox-text-inverse); }
.btn-dark:hover { background:var(--ox-accent-hover); }
.btn-ghost { border-color:transparent; background:none; }
.btn-ghost:hover { background:var(--ox-bg-muted); }
.iconbtn {
  display:inline-flex; align-items:center; justify-content:center; width:28px; height:28px;
  border:0; background:none; border-radius:var(--ox-radius-sm); color:var(--ox-text-tertiary); cursor:pointer;
}
.iconbtn:hover { background:var(--ox-bg-muted); color:var(--ox-text-primary); }
.iconbtn.on { background:var(--ox-bg-emphasis); color:var(--ox-text-primary); }

/* ── landing ───────────────────────────────────────────────────────────────── */
.hero {
  display:grid; grid-template-columns:1fr 1fr; gap:88px; align-items:center;
  max-width:1280px; margin:0 auto; padding:56px 40px 72px;
  min-height:calc(100vh - var(--ox-topbar-height));
}
.hero > * { min-width:0; }
/* Two lines, and the <br> decides where. At 60px "Unlock precision data" is
   ~655px against a ~556px column, so it wrapped itself into three. Sized to
   fit the narrower line with headroom, and clamped so it holds as the column
   moves. No text-wrap:balance -- the break is explicit, and balance re-wraps
   around it. */
.hero-headline {
  font-size:clamp(30px, 3.6vw, 46px); font-weight:700; line-height:1.08;
  letter-spacing:-.03em; color:var(--ink); margin:0 0 20px; text-wrap:nowrap;
}
.hero-subhead { font-size:18px; line-height:1.65; color:var(--muted); max-width:520px; margin:0 0 40px; }
.hero-search { width:100%; max-width:500px; }

/* two-deck search box */
.searchbox {
  position:relative; border:1px solid var(--ox-border-default);
  border-radius:var(--ox-radius-md); background:var(--ox-bg-base);
}
.hero-search .searchbox { border-color:#333; }
.searchbox-q { display:flex; align-items:center; padding:12px 14px 4px; }
.searchbox-q input {
  flex:1; min-width:0; border:0; background:none; outline:none;
  font-size:19px; line-height:28px; letter-spacing:-.01em;
}
.searchbox-q input::placeholder { color:var(--ox-text-muted); }
.searchbox-foot { display:flex; align-items:center; gap:8px; padding:4px 10px 10px 14px; }
.entity-select {
  display:inline-flex; align-items:center; gap:4px; border:0; background:none; cursor:pointer;
  font-size:17px; padding:4px 6px; border-radius:var(--ox-radius-sm); color:var(--ox-text-primary);
}
.entity-select:hover { background:var(--ox-bg-muted); }
.searchbox-foot .spacer { flex:1; }
.searchbox-foot .btn-dark { height:38px; padding:0 22px; font-size:16px; font-weight:600; border-radius:var(--ox-radius-md); }

/* typeahead */
.typeahead {
  position:absolute; left:0; right:0; top:calc(100% + 8px); z-index:200;
  background:var(--ox-bg-base); border:1px solid var(--ox-border-default);
  border-radius:var(--ox-radius-md); box-shadow:var(--ox-elev-overlay); overflow:hidden;
}
.ta-row {
  display:flex; align-items:center; gap:14px; width:100%; padding:10px 18px;
  border:0; background:none; text-align:left; cursor:pointer; font-size:17px; color:var(--ox-text-primary);
}
.ta-row:hover, .ta-row.active { background:var(--ox-bg-muted); }
.ta-row svg { flex:none; color:var(--ox-text-muted); }
.ta-row .ta-label { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ta-enter { border-top:1px solid var(--ox-border-subtle); }
.ta-enter em { font-style:italic; }
.keycap {
  border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-xs);
  padding:1px 8px; font-size:12px; color:var(--ox-text-tertiary); background:var(--ox-bg-base);
}

/* live feed */
.hero-viz { display:flex; flex-direction:column; align-self:stretch; padding:6vh 0; min-height:520px; }
.added {
  display:grid; grid-template-columns:18px minmax(0,1fr); column-gap:8px; align-items:center;
  font-size:13px; font-weight:500; letter-spacing:.08em; text-transform:uppercase; color:var(--faint);
  padding:0 2px 12px; border-bottom:1px solid #d4d4d8; background:var(--ox-bg-base);
  position:relative; z-index:2; box-shadow:0 5px 6px -5px rgba(0,0,0,.10);
}
.added b { color:var(--muted); font-weight:500; font-variant-numeric:tabular-nums; }
.live-dot { width:7px; height:7px; border-radius:50%; background:#43a047; justify-self:center; animation:pulse 2s ease-out infinite; }
@keyframes pulse {
  0% { box-shadow:0 0 0 0 rgba(67,160,71,.5); }
  70% { box-shadow:0 0 0 8px rgba(67,160,71,0); }
  100% { box-shadow:none; }
}
.feedport { flex:1; min-height:0; overflow:hidden; position:relative; }
.feedport::before, .feedport::after { content:''; position:absolute; left:0; right:0; height:15%; z-index:1; pointer-events:none; }
.feedport::before { top:0; background:linear-gradient(180deg,#fff,rgba(255,255,255,0)); }
.feedport::after { bottom:0; background:linear-gradient(0deg,#fff,rgba(255,255,255,0)); }
.belt { position:absolute; top:0; left:0; width:100%; will-change:transform; animation:belt 150s linear infinite; }
.feedport:hover .belt { animation-play-state:paused; }
@keyframes belt { from { transform:translateY(0); } to { transform:translateY(-50%); } }
.item {
  display:grid; grid-template-columns:22px minmax(0,1fr) 62px; gap:3px 10px;
  padding:15px 2px; border-top:1px solid var(--hair); align-items:start;
}
.item .eyebrow {
  grid-column:2; grid-row:1; justify-self:start; font-size:10px; letter-spacing:.07em;
  text-transform:uppercase; color:var(--ink);
}
.item .lead { grid-column:1; grid-row:2; padding-top:4px; color:var(--ink); }
.item .t {
  grid-column:2; grid-row:2; font-size:16px; line-height:1.4; color:#2563eb; text-align:left;
  border:0; background:none; padding:0; cursor:pointer;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden;
}
.item .t:hover { text-decoration:underline; }
/* The belt's third column carries the score that put the row on it -- a
   military-relevance total, a CARVER out of 30, an award in CNY -- so the
   number rides in the badge the column already draws. 12px because ¥29.3M
   is six characters and the track is 62px. */
.item .pdf {
  grid-column:3; grid-row:2; justify-self:end; font-size:12px; font-weight:600; color:var(--ink);
  border:1px solid var(--ink); border-radius:var(--ox-radius-sm); padding:3px 7px; white-space:nowrap;
}
.item .pdf:hover { background:var(--ink); color:#fff; text-decoration:none; }
.item .by { grid-column:2; grid-row:3; font-size:14px; line-height:1.55; color:var(--ink); }
.item .by .w { font-weight:600; }
.w-author { color:var(--w-author); }
.w-source { color:var(--w-source); }
.hero { position:relative; }
.hero-learnmore {
  position:absolute; bottom:20px; left:50%; transform:translateX(-50%);
  display:inline-flex; align-items:center; gap:2px; color:var(--muted); font-size:15px;
}

/* ── SERP ──────────────────────────────────────────────────────────────────── */
.serp { display:grid; grid-template-columns:var(--ox-rail-width) minmax(0,1fr); align-items:start; }
.rail {
  position:sticky; top:var(--ox-topbar-height); height:calc(100vh - var(--ox-topbar-height));
  overflow-y:auto; padding:10px 14px 60px; background:var(--ox-bg-base);
}
.rail-tools { display:flex; align-items:center; justify-content:center; gap:12px; padding:2px 0 10px; }
.facet {
  border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-md);
  margin-bottom:12px; background:var(--ox-bg-base); box-shadow:var(--ox-elev-1);
}
.facet-head { display:flex; align-items:center; gap:8px; padding:8px 8px 8px 6px; }
.facet-head .grip { color:var(--ox-text-disabled); cursor:grab; }
.facet-head h3 { flex:1; margin:0; font-size:15px; font-weight:500; letter-spacing:-.005em; }
.facet-body { padding:0 14px 14px; }
.facet-row {
  display:grid; grid-template-columns:20px minmax(0,1fr) auto; gap:10px; align-items:start;
  width:100%; border:0; background:none; text-align:left; padding:5px 4px; margin:0 -4px;
  border-radius:var(--ox-radius-xs); cursor:pointer; font-size:14px; line-height:20px;
}
.facet-row:hover { background:var(--ox-bg-muted); }
.facet-row.selected { background:var(--ox-bg-emphasis); }
.facet-row .cnt { color:var(--ox-text-secondary); font-variant-numeric:tabular-nums; }
.facet-row .box {
  width:17px; height:17px; margin-top:2px; border:1.6px solid var(--ox-text-tertiary);
  border-radius:3px; display:flex; align-items:center; justify-content:center; color:#fff;
}
.facet-row.on .box { background:var(--ox-accent); border-color:var(--ox-accent); }
.facet-row .radio {
  width:26px; height:26px; border-radius:50%; border:2px solid var(--ox-accent);
  display:flex; align-items:center; justify-content:center; margin-top:-2px;
}
.facet-row .radio::after { content:''; width:13px; height:13px; border-radius:50%; background:var(--ox-accent); }
.facet-more {
  border:0; background:none; color:var(--ox-text-tertiary); font-size:14px;
  cursor:pointer; padding:4px 0 0; margin-left:auto; display:block;
}
.facet-more:hover { color:var(--ox-text-primary); text-decoration:underline; }
.facet-empty { color:var(--ox-text-muted); font-size:13px; padding:4px 0; }

/* year histogram + range */
.hist { display:flex; align-items:flex-end; gap:2px; height:74px; padding:0 2px; }
.hist span { flex:1; background:#bdbdbd; border-radius:1px 1px 0 0; min-height:1px; }
.hist span.dim { background:#ededed; }
.range { position:relative; height:26px; margin:10px 2px 0; }
.range-track { position:absolute; left:0; right:0; top:11px; height:2px; background:var(--ox-border-strong); border-radius:2px; }
.range-fill { position:absolute; top:9px; height:6px; background:var(--ox-accent); border-radius:3px; }
.range-knob {
  position:absolute; top:5px; width:15px; height:15px; margin-left:-7.5px; border-radius:50%;
  background:var(--ox-accent); border:0; padding:0; cursor:grab; touch-action:none;
}
.range-knob:active { cursor:grabbing; }
.range-labels {
  display:flex; justify-content:space-between; font-size:13px; color:var(--ox-text-secondary);
  font-variant-numeric:tabular-nums; padding:0 2px;
}

/* main column */
.main { padding:12px 22px 80px; max-width:1320px; }
.modebar { display:flex; align-items:center; gap:2px; padding:0 4px 8px; }
.modetab {
  border:0; background:none; padding:5px 14px; border-radius:var(--ox-radius-sm);
  font-size:14px; cursor:pointer; color:var(--ox-text-secondary);
}
.modetab:hover { background:var(--ox-bg-muted); }
.modetab.on { background:var(--ox-bg-emphasis); color:var(--ox-text-primary); }
.modebar .spacer { flex:1; }

.serp-input { border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-md); background:var(--ox-bg-base); box-shadow:var(--ox-elev-1); }
.serp-input-top { position:relative; display:flex; align-items:center; gap:10px; padding:9px 12px 9px 14px; }
.serp-input-top input { flex:1; min-width:0; border:0; background:none; outline:none; font-size:16px; }
.chiprow { display:flex; flex-wrap:wrap; align-items:center; gap:8px; padding:0 12px 12px 14px; }
.fchip {
  display:inline-flex; align-items:center; gap:7px; height:34px; padding:0 13px;
  border-radius:var(--ox-radius-md); border:1px solid var(--ox-border-default);
  background:var(--ox-bg-base); font-size:14px; cursor:pointer; white-space:nowrap;
}
.fchip:hover { background:var(--ox-bg-muted); }
.fchip.on { background:var(--ox-accent); border-color:var(--ox-accent); color:var(--ox-text-inverse); }
.fchip.on:hover { background:var(--ox-accent-hover); }
.fchip .x { display:inline-flex; opacity:.8; }
.fchip .x:hover { opacity:1; }
.chiprow .more { border:0; background:none; color:var(--ox-text-secondary); cursor:pointer; padding:0 6px; font-size:14px; }
.chiprow .more:hover { color:var(--ox-text-primary); }

/* advanced builder */
.builder { border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-md); box-shadow:var(--ox-elev-1); overflow:hidden; }
.builder-head { display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--ox-border-subtle); }
.builder-head .ent {
  display:inline-flex; align-items:center; gap:5px; border:0; background:none; cursor:pointer;
  font-size:15px; padding:3px 8px; border-radius:var(--ox-radius-sm);
}
.builder-head .ent:hover { background:var(--ox-bg-muted); }
.builder-head .where { color:var(--ox-text-muted); font-size:15px; }
.blines { padding:12px 14px 14px; display:flex; flex-direction:column; gap:7px; }
.bline { display:flex; align-items:center; gap:6px; font-size:13px; }
.bline .ln { width:16px; text-align:right; color:#c98a3c; font-variant-numeric:tabular-nums; flex:none; }
.brick {
  display:inline-flex; align-items:center; gap:6px; height:26px; padding:0 10px; border-radius:var(--ox-radius-xs);
  border:0; font-size:13px; font-family:var(--ox-font-mono); cursor:pointer; white-space:nowrap;
}
.brick.prop { background:var(--prop-bg); color:var(--prop-fg); border-top-right-radius:0; border-bottom-right-radius:0; }
.brick.prop.solo { border-radius:var(--ox-radius-xs); }
.brick.op { background:var(--prop-bg); color:var(--prop-fg); margin-left:-4px; }
.brick.val { background:var(--val-bg); color:var(--val-fg); border-radius:13px; padding:0 12px; }
.brick.val:hover { background:var(--val-bg-hov); }
.brick.prop:hover, .brick.op:hover { background:var(--prop-bg-hov); }
.brick.conn { background:none; color:var(--prop-fg); padding:0 2px; cursor:default; font-weight:500; }
.brick.vconn { background:var(--vconn-bg); color:var(--vconn-fg); padding:0 8px; cursor:default; }
.brick.placeholder { background:var(--prop-bg); color:#c98a3c; min-width:150px; font-style:italic; }
.brick input {
  border:0; outline:none; background:transparent; font:inherit; color:inherit;
  min-width:80px; max-width:340px; field-sizing:content;
}
.brick .del { opacity:.55; margin-left:2px; }
.brick .del:hover { opacity:1; }

/* BQL editor */
.bqlbox { border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-md); box-shadow:var(--ox-elev-1); overflow:hidden; }
.bql-tools { display:flex; justify-content:flex-end; gap:2px; padding:6px 8px 0; }
.bql-edit { display:grid; grid-template-columns:44px minmax(0,1fr); background:var(--ox-bg-base); }
.bql-gutter {
  padding:10px 10px 16px 0; text-align:right; color:var(--ox-text-disabled);
  font-family:var(--ox-font-mono); font-size:13px; line-height:24px; user-select:none;
  background:var(--ox-bg-subtle); border-right:1px solid var(--ox-border-subtle);
}
.bql-edit textarea {
  border:0; outline:none; resize:none; padding:10px 14px 16px; min-height:240px;
  font-family:var(--ox-font-mono); font-size:13px; line-height:24px; background:none;
  white-space:pre; overflow-x:auto;
}
.bql-foot { display:flex; align-items:center; padding:10px 14px 14px; }
.validity {
  display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 12px;
  border-radius:var(--ox-radius-pill); font-family:var(--ox-font-mono); font-size:12px;
  background:var(--ox-success-bg); color:var(--ox-success-fg); border:1px solid var(--ox-success-border);
}
.validity.bad { background:var(--ox-danger-bg); color:var(--ox-danger-fg); border-color:var(--ox-danger-border); }
.bql-foot .spacer { flex:1; }

/* results */
.results { margin-top:18px; border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-md); box-shadow:var(--ox-elev-1); }
.results-head { display:flex; align-items:center; gap:10px; padding:11px 14px; border-bottom:1px solid var(--ox-border-subtle); }
.results-head .count { font-size:15px; font-weight:500; }
.results-head .spacer { flex:1; }
.res {
  display:grid; grid-template-columns:minmax(0,1fr) auto; gap:4px 14px; align-items:start;
  padding:14px 16px; border-bottom:1px solid var(--ox-border-subtle);
}
.res:last-child { border-bottom:0; }
.res:hover { background:var(--ox-bg-subtle); }
.res .rt {
  grid-column:1; border:0; background:none; padding:0; text-align:left; cursor:pointer;
  font-size:16px; line-height:1.4; color:var(--ox-link);
}
.res .rt:hover { text-decoration:underline; }
.res .pdf {
  grid-column:2; grid-row:1; align-self:start; font-size:12px; font-weight:600; letter-spacing:.02em;
  border:1px solid var(--ox-border-strong); border-radius:var(--ox-radius-sm); padding:3px 9px; color:var(--ox-text-primary);
}
.res .pdf:hover { background:var(--ox-accent); border-color:var(--ox-accent); color:#fff; text-decoration:none; }
.res .meta { grid-column:1; font-size:14px; color:var(--ox-text-secondary); }
.res .meta em { font-style:italic; }
.res .meta .dot { color:var(--ox-text-disabled); padding:0 2px; }
.res .meta .cites { display:inline-flex; align-items:center; gap:4px; color:var(--ox-text-tertiary); }

.rtable { width:100%; border-collapse:collapse; font-size:14px; }
.rtable th {
  text-align:left; font-weight:400; color:var(--ox-text-tertiary); font-size:13px;
  padding:9px 12px; border-bottom:1px solid var(--ox-border-subtle); white-space:nowrap;
}
.rtable td { padding:9px 12px; border-bottom:1px solid var(--ox-border-subtle); vertical-align:top; }
.rtable tr:last-child td { border-bottom:0; }
.rtable tbody tr:hover { background:var(--ox-bg-muted); }
.rtable .c-title button { border:0; background:none; padding:0; text-align:left; color:var(--ox-link); cursor:pointer; font-size:14px; line-height:1.4; }
.rtable .c-title button:hover { text-decoration:underline; }
.rtable .c-num { text-align:right; font-variant-numeric:tabular-nums; }
.rtable .c-bool { text-align:center; }
.rtable .c-check { width:34px; }
.tablewrap { overflow-x:auto; }
.cbox {
  width:17px; height:17px; border:1.6px solid var(--ox-text-tertiary); border-radius:3px;
  display:inline-flex; align-items:center; justify-content:center; background:none;
  padding:0; cursor:pointer; color:#fff; vertical-align:-3px;
}
.cbox.on { background:var(--ox-accent); border-color:var(--ox-accent); }

.pager { display:flex; align-items:center; justify-content:center; gap:4px; padding:14px; }
.pager button {
  min-width:32px; height:32px; border:0; background:none; border-radius:var(--ox-radius-sm);
  cursor:pointer; font-size:14px; font-variant-numeric:tabular-nums;
}
.pager button:hover:not(:disabled) { background:var(--ox-bg-muted); }
.pager button.on { background:var(--ox-accent); color:var(--ox-text-inverse); }
.pager button:disabled { color:var(--ox-text-disabled); cursor:default; }
.noresults { padding:40px 16px; text-align:center; color:var(--ox-text-tertiary); }

/* ── menus ─────────────────────────────────────────────────────────────────── */
.menu {
  position:fixed; z-index:500; min-width:210px; max-height:340px; overflow-y:auto;
  background:var(--ox-bg-base); border:1px solid var(--ox-border-default);
  border-radius:var(--ox-radius-lg); box-shadow:var(--ox-elev-overlay); padding:6px;
}
.menu button {
  display:flex; align-items:center; gap:10px; width:100%; padding:7px 10px; border:0; background:none;
  border-radius:var(--ox-radius-md); text-align:left; cursor:pointer; font-size:14px; white-space:nowrap;
}
.menu button:hover { background:var(--ox-bg-muted); }
.menu button svg { flex:none; color:var(--ox-text-tertiary); }
.menu .sep { height:1px; background:var(--ox-border-subtle); margin:5px 2px; }
.menu .mcheck { margin-left:auto; color:var(--ox-text-primary); opacity:0; }
.menu button.sel .mcheck { opacity:1; }
.menu input.mfilter {
  width:100%; border:1px solid var(--ox-border-default); border-radius:var(--ox-radius-sm);
  padding:6px 9px; margin-bottom:5px; outline:none; font-size:14px;
}
.menu input.mfilter:focus { border-color:var(--ox-border-strong); }

/* ── drawer ────────────────────────────────────────────────────────────────── */
.scrim { position:fixed; inset:0; background:rgba(0,0,0,.32); z-index:300; }
.drawer {
  position:fixed; top:0; right:0; bottom:0; width:50vw; z-index:400;
  background:var(--ox-bg-base); box-shadow:var(--ox-elev-overlay); overflow-y:auto;
  animation:slidein 200ms var(--ox-ease);
}
@keyframes slidein { from { transform:translateX(30px); opacity:.4; } to { transform:none; opacity:1; } }
.drawer-inner { padding:22px 34px 80px; }
.drawer-eyebrow { display:flex; align-items:center; gap:7px; color:var(--ox-text-tertiary); font-size:14px; }
.drawer h1 { font-size:36px; font-weight:700; line-height:1.18; letter-spacing:-.02em; margin:14px 0 20px; text-wrap:balance; }
.drawer-actions { display:flex; gap:10px; margin-bottom:22px; }
.drawer hr { border:0; border-top:1px solid var(--ox-border-subtle); margin:20px 0; }
.drow { font-size:15px; line-height:1.6; margin-bottom:5px; }
.drow b { font-weight:600; }
.drow .more { border:0; background:none; color:var(--ox-link); font-weight:600; cursor:pointer; padding:0 0 0 4px; }
.drawer-close { position:sticky; top:0; float:right; }
@media (max-width:900px) {
  /* minmax(0, 1fr), not bare 1fr: a plain 1fr track still floors at its
     content's min-content width, so one long facet row or result line would
     force this whole column -- and the page -- wider than the viewport. */
  .serp { grid-template-columns:minmax(0,1fr); }
  .rail { position:static; height:auto; }
  .hero { grid-template-columns:1fr; gap:40px; padding:32px 20px 48px; min-height:0; }
  .hero-headline { font-size:clamp(28px, 7vw, 40px); }
  .drawer { width:90vw; }
  .nav { display:none; }
  .topbar-email { display:none; }
}
@media (prefers-reduced-motion:reduce) {
  .belt { animation:none; }
  .live-dot { animation:none; }
  .drawer { animation:none; }
}

/* ── server-rendered chrome ───────────────────────────────────────────────────
 * Every control on the SERP is a link or a form field, not a scripted button:
 * a filter IS a URL here, so the browser's own history, back button and
 * open-in-new-tab work on facets for free. These rules stop the global link
 * color from painting that chrome blue, and restore the metrics the
 * button-based originals carried.
 * ------------------------------------------------------------------------- */
.facet-row, .fchip, .modetab, .brick, .iconbtn, .pager a, .sortmenu a, .ta-row {
  text-decoration: none;
  color: inherit;
}
.facet-row:hover, .fchip:hover, .modetab:hover, .brick:hover,
.iconbtn:hover, .pager a:hover, .ta-row:hover { text-decoration: none; }
.brick.val { color: var(--val-fg); }
.brick.prop, .brick.op, .brick.conn, .brick.placeholder { color: var(--prop-fg); }
.fchip.on { color: var(--ox-text-inverse); }
.res .rt, .rtable .c-title a, .item .t { color: var(--ox-link); }

/* The entity picker, on the same panel as the typeahead it sits above. It was
   a native <select>, whose list is drawn by the operating system -- dark, in
   its own type, at its own corner radius, three pixels under a white overlay
   that matched none of it. */
.typemenu { position:relative; }
.typemenu > summary { list-style:none; }
.typemenu > summary::-webkit-details-marker { display:none; }
.typemenu > summary svg { color:var(--ox-text-tertiary); }
.typemenu[open] > summary svg { transform:rotate(180deg); }
/* .menu-inline anchors right; this one hangs off the left edge of its own
   summary, which is where the control is. */
.typemenu .menu { top:calc(100% + 6px); left:0; right:auto; min-width:190px; }
.tmrow {
  display:flex; align-items:center; gap:10px; padding:7px 10px;
  border-radius:var(--ox-radius-md); cursor:pointer; font-size:15px; white-space:nowrap;
}
.tmrow:hover { background:var(--ox-bg-muted); }
/* The check follows the radio itself, so it cannot drift out of step with
   what will actually be submitted. */
.tmrow input { position:absolute; opacity:0; pointer-events:none; }
.tmrow .mcheck { margin-left:auto; color:var(--ox-text-primary); opacity:0; }
.tmrow:has(input:checked) .mcheck { opacity:1; }
.tmrow:has(input:focus-visible) { outline:2px solid var(--ox-accent); outline-offset:-2px; }
.searchbox-foot input[type="submit"] { height: 38px; padding: 0 22px; font-size: 16px; font-weight: 600; }
.searchbox-q input[type="search"] { appearance: none; }
.searchbox-q input::-webkit-search-cancel-button { display: none; }

/* pager, as links */
.pager a, .pager .gap {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; height: 32px; border-radius: var(--ox-radius-sm);
  font-size: 14px; font-variant-numeric: tabular-nums;
}
.pager a:hover { background: var(--ox-bg-muted); }
.pager a.on, .pager a.on:hover { background: var(--ox-accent); color: var(--ox-text-inverse); }
.pager a.disabled, .pager .gap { color: var(--ox-text-disabled); pointer-events: none; }

/* sort menu — a <details> popover, no script */
.sortmenu { position: relative; }
.sortmenu > summary { list-style: none; cursor: pointer; }
.sortmenu > summary::-webkit-details-marker { display: none; }
.menu-inline {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 500; min-width: 230px;
  background: var(--ox-bg-base); border: 1px solid var(--ox-border-default);
  border-radius: var(--ox-radius-lg); box-shadow: var(--ox-elev-overlay); padding: 6px;
}
.menu-inline a {
  display: flex; align-items: center; gap: 10px; padding: 7px 10px;
  border-radius: var(--ox-radius-md); font-size: 14px; white-space: nowrap;
}
.menu-inline a:hover { background: var(--ox-bg-muted); }
.menu-inline .mcheck { margin-left: auto; opacity: 0; }
.menu-inline a.sel .mcheck { opacity: 1; }

/* the drawer's scrim is a link, so it needs a box to cover the page with */
a.scrim { display: block; }

/* the landing feed's controlled badge sits where the mock put its PDF pill */
.item .pdf, .res .pdf { font-variant-numeric: tabular-nums; }

/* a turbo-frame is inline by default; the drawer must not add a layout box */
turbo-frame#drawer { display: contents; }

/* ── the door ────────────────────────────────────────────────────────────────
 * Sign-in and password reset. Same tokens as the search, one narrow column.
 * ------------------------------------------------------------------------- */
.auth { max-width: 380px; margin: 0 auto; padding: 72px 24px 120px; }
.auth .wordmark { height: 26px; width: auto; color: var(--ink); display: block; }
.auth h1 { font-size: 26px; font-weight: 600; letter-spacing: -.02em; margin: 28px 0 24px; }
.auth form { display: flex; flex-direction: column; gap: 6px; }
.auth label {
  font-size: 12px; font-weight: 500; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ox-text-tertiary); margin-top: 14px;
}
.auth input[type="email"], .auth input[type="password"] {
  width: 100%; padding: 10px 13px; border: 1px solid var(--ox-border-default);
  border-radius: var(--ox-radius-md); background: var(--ox-bg-base); font-size: 15px; outline: none;
}
.auth input:focus { border-color: var(--ox-border-strong); box-shadow: var(--ox-focus-ring); }
.auth input[type="submit"] { margin-top: 26px; width: 100%; height: 40px; cursor: pointer; }
.auth-aside { margin-top: 20px; font-size: 14px; color: var(--ox-text-tertiary); }

/* how many records carry a suggested name -- the pair a search will show */
.ta-count {
  flex: none; font-size: 12px; color: var(--ox-text-muted);
  font-variant-numeric: tabular-nums;
}

/* ── canvas ───────────────────────────────────────────────────────────────────
 * One node's neighborhood, drawn. Every position in the markup was computed
 * on the server, so this file only sizes and colors what is already placed.
 * The tokens are the SERP's own: the accent ring is where you are, the danger
 * red is a controlled node, and the grey ramp between them is the year.
 * ------------------------------------------------------------------------- */
.canvas-grid {
  display:grid; grid-template-columns:var(--ox-rail-width) minmax(0,1fr) 380px;
  height:calc(100vh - var(--ox-topbar-height));
}
.canvas-list { overflow-y:auto; border-right:1px solid var(--ox-border-default); }
/* The rows ARE result rows -- same markup, same class -- so a reader moving
   from the search to the canvas is reading the same list. These add only the
   state the SERP has no use for: which row the cursor is on. */
.cres { border-left:3px solid transparent; }
.cres.origin { background:var(--ox-bg-subtle); border-left-color:var(--ox-accent); }
.cres.on { background:var(--ox-bg-muted); border-left-color:var(--ox-text-tertiary); }

.canvas-stage { position:relative; overflow:hidden; background:var(--ox-bg-base); }
/* user-select, because a drag across a labelled drawing otherwise selects the
   labels instead of moving the view. */
.canvas-svg { width:100%; height:100%; cursor:grab; touch-action:none; user-select:none; }
.canvas-grid.panning .canvas-svg { cursor:grabbing; }
/* Lines are drawn at 1px and scale with the view, so the stroke thins as the
   reader zooms in. The wide companion is what the pointer actually hits: a
   1px target is not one a cursor can find. */
.cedge-line { stroke:var(--ox-border-default); stroke-width:calc(1px / var(--k, 1)); pointer-events:none; }
.cedge-hit { stroke:transparent; stroke-width:calc(11px / var(--k, 1)); }
.cedge.hot .cedge-line { stroke:var(--ox-text-tertiary); stroke-width:calc(1.8px / var(--k, 1)); }
.cedge.lit .cedge-line { stroke:var(--ox-accent); stroke-width:calc(2.4px / var(--k, 1)); }
.cedge { cursor:pointer; }
.cnode { cursor:pointer; }
/* Truncated on the server; the tip and the panel carry the whole name. The
   halo is what keeps two overlapping labels readable, and the label holds its
   size as the drawing grows so zooming in reads as moving closer. */
.clabel {
  font-size:calc(14px / var(--k, 1)); fill:var(--ox-text-tertiary); text-anchor:middle;
  pointer-events:none; paint-order:stroke; stroke:var(--ox-bg-base);
  stroke-width:calc(4px / var(--k, 1)); stroke-linejoin:round;
}
.cnode.origin .clabel { fill:var(--ox-text-primary); font-weight:600; }
.cnode.on .clabel { fill:var(--ox-text-primary); font-weight:600; }
/* Every stroke on a circle is divided by the zoom for the same reason the
   lines are: a 2px ring drawn inside a group scaled to 3x is a 6px ring, and
   the rings swallowed their own circles as soon as a reader zoomed in. */
.cnode .dot { stroke:var(--ox-border-strong); stroke-width:calc(.8px / var(--k, 1)); }
.cnode .dot.ctrl { stroke:var(--ox-danger-fg); stroke-width:calc(2px / var(--k, 1)); }
.cnode .ring { fill:none; stroke:var(--ox-accent); stroke-width:calc(2px / var(--k, 1)); opacity:0; }
.cnode.origin .ring, .cnode.on .ring { opacity:1; }
.cnode.dim { opacity:.28; }
.cnode:focus-visible { outline:none; }
.cnode:focus-visible .ring { opacity:1; stroke-dasharray:calc(3px / var(--k, 1)) calc(3px / var(--k, 1)); }

.canvas-tip {
  position:absolute; z-index:2; transform:translateX(-50%); pointer-events:none;
  max-width:260px; padding:6px 10px; border-radius:var(--ox-radius-sm);
  background:var(--ink); color:var(--ox-text-inverse); font-size:13px; line-height:1.35;
  box-shadow:var(--ox-elev-overlay);
}
/* The cap and the counts ride here, in the line the canvas already carries.
   There is no box on the drawing explaining itself. */
.canvas-status { position:absolute; left:20px; bottom:16px; margin:0; font-size:13px; color:var(--ox-text-muted); }
.canvas-back { position:absolute; left:14px; top:12px; z-index:2; }
.canvas-reset { position:absolute; right:14px; top:12px; z-index:2; }
.canvas-legend { position:absolute; right:20px; bottom:16px; width:190px; }
.canvas-legend .ramp { height:8px; border-radius:2px; background:linear-gradient(90deg,#e8e8e8,#4a4a4a); }
.canvas-legend .ends {
  display:flex; justify-content:space-between; align-items:center; gap:8px;
  font-size:12px; color:var(--ox-text-muted); padding-top:3px;
}
.canvas-legend .ends svg { display:inline-block; vertical-align:-2px; }

.canvas-detail { overflow-y:auto; border-left:1px solid var(--ox-border-default); padding:22px 24px 60px; }
.cpanel h2 { font-size:26px; font-weight:700; line-height:1.2; letter-spacing:-.02em; margin:12px 0 18px; text-wrap:balance; }
.cpanel .here { color:var(--ox-text-muted); }
.cpanel .mono { font-family:var(--ox-font-mono); font-size:13px; }

@media (max-width:1100px) { .canvas-grid { grid-template-columns:250px minmax(0,1fr) 310px; } }
/* Narrow: the same three parts, stacked, with the drawing between the names
   and the panel so a tap on a row still has somewhere to land. */
@media (max-width:900px) {
  .canvas-grid { grid-template-columns:1fr; height:auto; }
  .canvas-list { max-height:40vh; border-right:0; border-bottom:1px solid var(--ox-border-default); }
  .canvas-stage { height:70vh; }
  .canvas-detail { border-left:0; border-top:1px solid var(--ox-border-default); }
  /* Status and legend anchor to opposite bottom corners of the same row; at
     900px the legend's fixed 190px plus the status line's text run into each
     other regardless of wrap width, since the status text length varies with
     the query. Give the legend its own row above instead of sharing one. */
  .canvas-status { max-width:calc(100% - 40px); }
  .canvas-legend { bottom:60px; }
}
/* ── the address/footprint map ─────────────────────────────────────────────
 * Two panes of the canvas grid reused as-is (the list, the stage); the third
 * (detail) isn't needed here because there's nothing per-point to page
 * between -- the list row already carries every fact, and the map only adds
 * where it sits. */
.geo-grid { grid-template-columns:var(--ox-rail-width) minmax(0,1fr); }
.geo-stage { background:var(--ox-bg-muted); }
.geo-map { position:absolute; inset:0; }
.georow { cursor:pointer; }
.geo-source { font-family:var(--ox-font-mono); font-size:12px; color:var(--ox-text-muted); }
.geo-flag { font-weight:500; }
.geo-flag.geo-ok { color:var(--ox-success-fg); }
.geo-flag.geo-no_footprint { color:var(--ox-danger-fg); }
.geo-flag.geo-no_match { color:var(--ox-text-muted); }
@media (max-width:900px) { .geo-grid { grid-template-columns:1fr; } }

/* ── the document reader ────────────────────────────────────────────────── */
/* A mention edge cites a passage, and a citation a reader cannot open is one
 * they have to take on trust. Only the public-domain tier reaches this page:
 * `document_chunks` holds no other, so there is nothing here to gate. */
.document { max-width: 46rem; margin: 0 auto; padding: 32px 24px 96px; }
.document-head { border-bottom: 1px solid var(--ox-border-default); padding-bottom: 20px; margin-bottom: 8px; }
.document-head h1 { font-size: 26px; line-height: 1.25; margin: 16px 0 8px; }
.document-meta { color: var(--ox-text-muted); font-size: 13px; margin: 0; }

.document-file { width: 100%; height: 82vh; border: 1px solid var(--ox-border-default);
                 border-radius: var(--ox-radius-md); background: var(--ox-bg-subtle);
                 display: block; margin: 16px 0 8px; }
.document-file p { padding: 24px; }

.passage { display: grid; grid-template-columns: 64px 1fr; gap: 16px;
           padding: 14px 12px; border-radius: var(--ox-radius-md);
           scroll-margin-top: calc(var(--ox-topbar-height) + 24px); }
.passage p { margin: 0; line-height: 1.7; color: var(--ox-text-secondary); white-space: pre-wrap; }
.passage-page { font-family: var(--ox-font-mono); font-size: 12px;
                color: var(--ox-text-muted); padding-top: 4px; text-align: right; }

/* The passage the edge was built from. Marked by weight and a rule, not by a
 * colour wash: the reader arrived here to read it, not to be told where it is. */
.passage.cited { background: var(--ox-bg-subtle); box-shadow: inset 3px 0 0 var(--ox-accent); }
.passage.cited p { color: var(--ox-text-primary); }
.passage.cited .passage-page { color: var(--ox-text-primary); font-weight: 600; }

/* ── CARVER, and the pictures ───────────────────────────────────────────── */
/* Six components on one line. The letters spell the method, so the row needs
 * no label of its own -- the score above it already said what this is. */
.carver { display: flex; gap: 6px; margin: 6px 0 10px; }
.carver-part { flex: 1; text-align: center; padding: 6px 0;
               border: 1px solid var(--ox-border-default);
               border-radius: var(--ox-radius-sm); background: var(--ox-bg-subtle); }
.carver-part span { display: block; font-family: var(--ox-font-mono);
                    font-size: 10px; color: var(--ox-text-muted); letter-spacing: .04em; }
.carver-part b { font-size: 15px; }

.listing-shots { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin: 8px 0 4px; }
.listing-shots figure { margin: 0; }
.listing-shots img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
                     border-radius: var(--ox-radius-sm);
                     border: 1px solid var(--ox-border-default); display: block; }
.listing-shots figcaption { font-size: 11px; line-height: 1.4; margin-top: 4px;
                            color: var(--ox-text-muted); }


/* ── the dual-use grade ─────────────────────────────────────────────────── */
/* How hard the join is, beside the claim it supports. `exact` means an
 * identifier -- a CAGE code, a NIIN -- and `probable` means a name, which is
 * not an identifier. The badge carries the limit so no box has to. */
.grade { font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
         padding: 2px 7px; border-radius: var(--ox-radius-pill);
         border: 1px solid var(--ox-border-default); color: var(--ox-text-tertiary); }
.grade.exact { border-color: var(--ox-success-border); background: var(--ox-success-bg);
               color: var(--ox-success-fg); }


/* ── identifiers ────────────────────────────────────────────────────────── */
/* The number a reader arrived holding. Monospace, because a digit that
 * changes width between rows cannot be compared down a column. */
.ident { display: flex; align-items: baseline; gap: 7px; margin: 2px 0 1px; }
.ident-kind { font-size: 10px; letter-spacing: .06em; text-transform: uppercase;
              color: var(--ox-text-muted); }
.ident-value { font-family: var(--ox-font-mono); font-size: 13px;
               color: var(--ox-text-secondary); }
.ident-value:hover { color: var(--ox-link); }

.idents { display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px;
          margin: 10px 0 14px; padding: 12px 14px; border-radius: var(--ox-radius-md);
          background: var(--ox-bg-subtle); }
.idents dt { font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
             color: var(--ox-text-muted); align-self: center; }
.idents dd { margin: 0; font-family: var(--ox-font-mono); font-size: 13px; }
