/* ═══════════════════════════════════════════════════════════════════
   The Link Desk — "the card catalog"
   House palette: pitch black #060606 · zinc borders biased slightly
   violet · the library's bookmarks accent #9d7cf5 (--color-cat-bookmarks,
   oklch(68% .17 280)). Dark-committed, like the rest of /tools.
   Type: Inter (UI) · JetBrains Mono (URLs, dates, counts).

   Three surfaces, one filter state:
     the frame    sidebar facets + card grid          (Direction A)
     the console  ⌘K / "/" palette over the frame     (Direction B)
     the rail     collapsed run strip above the grid  (Direction C)
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --bg: #060606;
  --panel: #0d0d10;
  --panel-2: #131318;
  --panel-3: #1a1a20;
  --border: #27272e;
  --border-soft: #1b1b21;
  --text: #f4f4f5;
  --dim: #a1a1aa;
  --faint: #6b6b76;
  --accent: #9d7cf5;
  --accent-soft: rgba(157, 124, 245, .14);
  --ok: #34d399;
  --warn: #fbbf24;
  --bad: #fb7185;

  --font-body: "Inter", system-ui, -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

  --sidebar-w: 244px;
  --panel-w: 460px;
  --radius: 12px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
[hidden] { display: none !important; }

html { scrollbar-color: #2e2e36 var(--bg); scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}
body.is-locked { overflow: hidden; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font-family: inherit; color: inherit; background: none; border: none; cursor: pointer; }
select, input { font-family: inherit; font-size: inherit; color: inherit; }
h1, h2, h3 { line-height: 1.2; font-weight: 700; letter-spacing: -.02em; }

.mono { font-family: var(--font-mono); font-size: .92em; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

kbd {
  font-family: var(--font-mono); font-size: 10.5px; line-height: 1;
  padding: 3px 5px; border: 1px solid var(--border); border-radius: 5px;
  background: var(--panel-2); color: var(--dim);
}

.grain {
  position: fixed; inset: -50%; pointer-events: none; z-index: 60; opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ─────────────────────────────── top bar ─────────────────────────────── */

.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 16px;
  min-height: 61px; padding: 10px 22px;
  border-bottom: 1px solid var(--border-soft);
  background: rgba(6, 6, 6, .86);
  backdrop-filter: blur(14px);
}
.brand { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto; color: inherit; }
.brand:hover { text-decoration: none; }
.brand svg { width: 34px; height: 34px; border-radius: 9px; }
.brand span { display: grid; line-height: 1.2; }
.brand strong { font-size: 14px; font-weight: 700; }
.brand small { font-size: 11px; color: var(--faint); font-family: var(--font-mono); }

.omni-open {
  flex: 1 1 auto; max-width: 520px;
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px 8px 12px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel); color: var(--faint);
  font-size: 13.5px; text-align: left;
  transition: border-color .15s, color .15s;
}
.omni-open:hover { border-color: #39394a; color: var(--dim); }
.omni-open svg { width: 15px; height: 15px; flex: 0 0 auto; }
.omni-open-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.omni-open-hint { color: #4d4d58; }
.omni-open kbd { flex: 0 0 auto; }

.topbar .tool-share { flex: 0 0 auto; margin-left: auto; }

/* ─────────────────────────────── shell ──────────────────────────────── */

.shell { max-width: 1560px; margin: 0 auto; padding: 30px 22px 60px; }

.hero {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 30px; align-items: end;
  padding-bottom: 26px; margin-bottom: 22px;
  border-bottom: 1px solid var(--border-soft);
}
.eyebrow {
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 10px;
}
.hero h1 { font-size: clamp(34px, 5.2vw, 56px); font-weight: 800; letter-spacing: -.035em; }
.lede { margin-top: 12px; max-width: 68ch; color: var(--dim); font-size: 15.5px; }
.hero .tool-share { margin-top: 16px; }

.stats { display: flex; flex-wrap: wrap; gap: 10px; }
.stats div {
  min-width: 96px; padding: 10px 14px;
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel) 0%, #08080a 100%);
}
.stats dt { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--faint); }
.stats dd { font-family: var(--font-mono); font-size: 21px; font-weight: 600; margin-top: 3px; }
.stats dd small { font-size: 11px; color: var(--faint); font-weight: 400; }

.layout { display: grid; grid-template-columns: var(--sidebar-w) minmax(0, 1fr); gap: 26px; align-items: start; }
/* Grid items default to min-width:auto, so the rail's horizontally-scrolling
   track would size the whole column to its content and put the PAGE into a
   7,000px horizontal scroll instead of scrolling inside its own strip. */
.layout > *, .results > * { min-width: 0; }

/* ────────────────────────────── sidebar ─────────────────────────────── */

.sidebar { position: sticky; top: 78px; max-height: calc(100vh - 96px); overflow-y: auto; padding-right: 4px; }
.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-thumb { background: #24242c; border-radius: 3px; }

.facet { border-bottom: 1px solid var(--border-soft); padding: 4px 0 10px; }
.facet > summary {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 2px; cursor: pointer; list-style: none;
  font-size: 11px; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
}
.facet > summary::-webkit-details-marker { display: none; }
.facet > summary::before {
  content: ""; width: 6px; height: 6px; flex: 0 0 auto;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(-45deg); transition: transform .18s;
}
.facet[open] > summary::before { transform: rotate(45deg); }
.facet > summary:hover { color: var(--dim); }
.facet-n { margin-left: auto; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0; }

.facet-list { list-style: none; display: grid; gap: 1px; }
.facet-scroll { max-height: 260px; overflow-y: auto; }
.facet-list button {
  width: 100%; display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border-radius: 7px;
  font-size: 13px; color: var(--dim); text-align: left;
  transition: background .12s, color .12s;
}
.facet-list button:hover { background: var(--panel-2); color: var(--text); }
.facet-list button[aria-pressed="true"] { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.facet-list .fl-label { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.facet-list .fl-n { font-family: var(--font-mono); font-size: 11px; color: var(--faint); }
.facet-list button[aria-pressed="true"] .fl-n { color: var(--dim); }

.dot { width: 8px; height: 8px; flex: 0 0 auto; border-radius: 50%; background: currentColor; display: inline-block; }
.dot.ok { color: var(--ok); }
.dot.empty { color: var(--warn); }
.dot.broken { color: var(--bad); }

.facet-note { padding: 8px 8px 2px; font-size: 11.5px; line-height: 1.5; color: var(--faint); }

.side-exports { margin-top: 18px; padding: 14px; border: 1px solid var(--border-soft); border-radius: var(--radius); background: var(--panel); }
.side-exports h2 { font-size: 11px; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); }
.side-exports p { margin: 8px 0 10px; font-size: 11.5px; line-height: 1.5; color: var(--faint); }
.side-exports ul { list-style: none; display: grid; gap: 6px; }
.side-exports a { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--dim); }
.side-exports a:hover { color: var(--text); text-decoration: none; }
.side-exports .fl-n { margin-left: auto; font-family: var(--font-mono); font-size: 10.5px; color: var(--faint); }

/* ───────────────────────── the drop rail (C) ─────────────────────────── */

.rail { border: 1px solid var(--border-soft); border-radius: var(--radius); background: var(--panel); margin-bottom: 14px; }
.rail-toggle { display: flex; align-items: center; gap: 10px; width: 100%; padding: 11px 14px; font-size: 13px; }
.rail-caret { width: 15px; height: 15px; color: var(--faint); transition: transform .18s; }
.rail-toggle[aria-expanded="true"] .rail-caret { transform: rotate(90deg); }
.rail-toggle strong { font-weight: 600; }
.rail-sub { color: var(--faint); font-size: 12px; font-family: var(--font-mono); }
.rail-body { border-top: 1px solid var(--border-soft); padding: 12px 14px 10px; }

.rail-track {
  display: flex; gap: 9px; overflow-x: auto; padding-bottom: 10px;
  scroll-snap-type: x proximity;
}
.rail-track::-webkit-scrollbar { height: 7px; }
.rail-track::-webkit-scrollbar-thumb { background: #24242c; border-radius: 4px; }

.tile {
  position: relative; flex: 0 0 auto; width: 132px; scroll-snap-align: start;
  display: grid; gap: 6px; padding: 9px;
  border: 1px solid var(--border-soft); border-radius: 10px;
  background: var(--panel-2); text-align: left;
  transition: border-color .14s, transform .14s;
}
.tile:hover { border-color: var(--tile, var(--accent)); transform: translateY(-2px); }
.tile[aria-pressed="true"] { border-color: var(--tile, var(--accent)); background: var(--panel-3); }
.tile.is-gap { border-style: dashed; }
.tile-art {
  height: 52px; border-radius: 7px; overflow: hidden; position: relative;
  background:
    radial-gradient(120% 120% at 20% 0%, color-mix(in srgb, var(--tile) 42%, transparent) 0%, transparent 70%),
    linear-gradient(140deg, #101016 0%, #08080b 100%);
}
.tile-art img { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: cover; display: block; }
.tile-art .tile-mark {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 17px; font-weight: 600; color: var(--tile);
  opacity: .85;
}
.tile-date { font-family: var(--font-mono); font-size: 11.5px; font-weight: 600; }
.tile-stream { font-size: 10.5px; color: var(--faint); display: flex; align-items: center; gap: 5px; line-height: 1.3; }
.tile-stream i { color: var(--tile); }
.tile-n { font-family: var(--font-mono); font-size: 10.5px; color: var(--dim); }
.tile-badge {
  position: absolute; top: 7px; right: 7px;
  padding: 2px 6px; border-radius: 999px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
}
.tile-badge.new { background: var(--accent); color: #0b0b0f; }
.tile-badge.empty { background: rgba(251, 191, 36, .16); color: var(--warn); border: 1px solid rgba(251, 191, 36, .34); }
.tile-badge.broken { background: rgba(251, 113, 133, .14); color: var(--bad); border: 1px solid rgba(251, 113, 133, .32); }

.rail-legend { display: flex; flex-wrap: wrap; gap: 14px; font-size: 11px; color: var(--faint); padding-top: 4px; }
.rail-legend span { display: inline-flex; align-items: center; gap: 6px; }

/* the gap explainer, shown in the results column when a gap tile is picked.
   It lives inside the grid, so it has to span every column of it. */
.gapnote {
  grid-column: 1 / -1;
  display: grid; gap: 8px; padding: 16px 18px; margin-bottom: 14px;
  border: 1px dashed var(--gapc, var(--warn)); border-radius: var(--radius);
  background: color-mix(in srgb, var(--gapc, var(--warn)) 6%, var(--panel));
}
.gapnote h3 { font-size: 14.5px; }
.gapnote p { font-size: 13.5px; color: var(--dim); max-width: 78ch; }
.gapnote .gap-cands { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.gapnote .gap-cands a {
  padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
  font-size: 12px; color: var(--dim); background: var(--panel-2);
}
.gapnote .gap-cands a:hover { color: var(--text); border-color: var(--gapc); text-decoration: none; }

/* ────────────────────────────── toolbar ─────────────────────────────── */

.toolbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 2px 0 12px; }
.sortbox { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--faint); }
.sortbox select {
  padding: 6px 10px; border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); font-size: 13px;
}
.viewtoggle { display: inline-flex; border: 1px solid var(--border); border-radius: 999px; overflow: hidden; }
.vt { padding: 6px 14px; font-size: 12.5px; color: var(--faint); }
.vt.is-active { background: var(--panel-3); color: var(--text); font-weight: 600; }
.count { margin-left: auto; font-family: var(--font-mono); font-size: 12.5px; color: var(--dim); }
.count b { color: var(--text); font-weight: 600; }

.btn-ghost {
  padding: 6px 12px; border: 1px solid var(--border); border-radius: 999px;
  font-size: 12.5px; color: var(--dim);
}
.btn-ghost:hover { border-color: var(--accent); color: var(--text); }

/* ─── export menu ───
   Anchored to the toolbar button rather than centred like the console: it acts
   on the view behind it, so it should not cover it. */
.exportbox { position: relative; }
.exportbox .btn-ghost { display: inline-flex; align-items: center; gap: 7px; }
.export-menu {
  position: absolute; z-index: 40; top: calc(100% + 7px); left: 0; width: 268px;
  padding: 6px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel-2); box-shadow: 0 18px 44px rgba(0, 0, 0, .55);
}
.export-head {
  padding: 7px 9px 9px; margin-bottom: 4px; border-bottom: 1px solid var(--border-soft);
  font-size: 11.5px; line-height: 1.45; color: var(--faint);
}
.export-head b { color: var(--text); font-family: var(--font-mono); font-weight: 600; }
.export-menu [data-fmt] {
  display: block; width: 100%; padding: 7px 9px; border-radius: 7px;
  text-align: left; font-size: 13px; color: var(--text);
}
.export-menu [data-fmt] small {
  display: block; font-size: 11px; color: var(--faint); font-family: var(--font-mono);
}
.export-menu [data-fmt]:hover:not(:disabled) { background: var(--accent-soft); }
.export-menu [data-fmt]:disabled { opacity: .38; cursor: not-allowed; }

/* Which set the four formats act on. A segmented pair rather than two menus:
   the formats do not change between scopes, only their input does. */
.export-scope {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  padding: 4px; margin-bottom: 4px; border-radius: 8px; background: var(--panel);
}
.export-scope button {
  padding: 6px 8px; border-radius: 6px; font-size: 12px; color: var(--dim);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.export-scope button b { font-family: var(--font-mono); font-size: 11px; color: var(--faint); font-weight: 600; }
.export-scope button:hover:not(:disabled) { color: var(--text); }
.export-scope button.is-active { background: var(--accent-soft); color: var(--text); font-weight: 600; }
.export-scope button.is-active b { color: var(--accent); }
.export-scope button:disabled { opacity: .35; cursor: not-allowed; }

/* The whole archive cut by stream or topic — collapsed, because it is 18 rows
   under a menu whose first four items are the common case. */
.export-packs { margin-top: 4px; border-top: 1px solid var(--border-soft); padding-top: 4px; }
.packs-toggle {
  display: flex; align-items: center; gap: 7px; width: 100%;
  padding: 7px 9px; border-radius: 7px; font-size: 12.5px; color: var(--dim);
}
.packs-toggle:hover { background: var(--panel-3); color: var(--text); }
.packs-toggle::after {
  content: ""; width: 6px; height: 6px; margin-left: auto; margin-right: 3px;
  border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
}
.packs-toggle[aria-expanded="true"]::after { transform: rotate(-135deg) translate(-1px, -1px); }
.packs-body { max-height: 244px; overflow-y: auto; padding: 2px 0 4px; }
.packs-note { padding: 2px 9px 7px; font-size: 11px; line-height: 1.45; color: var(--faint); }
.packs-note code { font-family: var(--font-mono); font-size: 10.5px; color: var(--dim); }
.packs-group {
  padding: 7px 9px 3px; font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint);
}
.packs-body [data-pack] {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 6px 9px; border-radius: 7px; text-align: left; font-size: 12.5px; color: var(--dim);
}
.packs-body [data-pack]:hover { background: var(--accent-soft); color: var(--text); }
.packs-body [data-pack] .fl-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.packs-body [data-pack] .fl-n { font-family: var(--font-mono); font-size: 11px; color: var(--faint); }

.sig-n { font-family: var(--font-mono); color: var(--accent); font-weight: 600; }

/* ─── the selection tray ───
   Between the chips and the grid, so it reads as another thing narrowing what
   is below it — which is exactly what it is, for the export button. Accent
   border because unlike a chip it survives a filter change, and that has to
   be visible or a stale pick looks like a bug. */
.tray {
  margin-bottom: 14px; padding: 11px 13px 12px;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border));
  border-radius: var(--radius); background: color-mix(in srgb, var(--accent) 5%, var(--panel));
}
.tray-head { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.tray-head b { font-size: 13px; color: var(--text); font-weight: 650; }
.tray-note { flex: 1 1 auto; font-size: 11.5px; color: var(--faint); font-family: var(--font-mono); }
.tray-note b { color: var(--dim); font-weight: 600; }
.tray-head .btn-ghost { border-color: var(--accent); color: var(--text); }
.tray-head .btn-ghost:hover { background: var(--accent-soft); }
.tray-head .linklike { font-size: 12px; }
.tray-list { display: flex; flex-wrap: wrap; gap: 6px; list-style: none; margin-top: 10px; }
.tray-list button {
  display: inline-flex; align-items: center; gap: 6px; max-width: 260px;
  padding: 3px 9px 3px 7px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-2); font-size: 12px; color: var(--dim);
}
.tray-list button span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tray-list button svg { flex: 0 0 auto; color: var(--faint); }
.tray-list button:hover { border-color: var(--bad); color: var(--text); }
.tray-list button:hover svg { color: var(--bad); }
.tray-list .fav { margin-right: 0; }

/* ─── the per-card toggle ───
   Inside .card-title, not a child of .card: the row view switches columns off
   that grid and a new direct child there wraps every row. Same reason the
   favicon lives in the heading. */
.pick {
  --pick-px: 17px;
  flex: 0 0 auto; width: var(--pick-px); height: var(--pick-px); margin-top: 1px;
  border: 1.5px solid var(--border); border-radius: 5px; background: var(--panel-2);
  position: relative;
}
.pick:hover { border-color: var(--accent); }
.pick::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 32%; height: 60%; border-right: 2px solid #0b0b0f; border-bottom: 2px solid #0b0b0f;
  transform: rotate(42deg) translate(-6%, -14%); opacity: 0;
}
.pick[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); }
.pick[aria-pressed="true"]::after { opacity: 1; }
.grid.is-rows .pick { --pick-px: 15px; margin-top: 0; }

.pick-btn.is-on { border-color: var(--accent); color: var(--text); background: var(--accent-soft); }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chips:not(:empty) { padding-bottom: 14px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-2); font-size: 12px; color: var(--dim);
  max-width: 320px;
}
.chip .x { color: var(--faint); font-size: 14px; line-height: 1; }
.chip:hover .x { color: var(--bad); }
button.chip:hover { border-color: #3a3a46; color: var(--text); }
.chip .chip-k { color: var(--faint); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; }

/* ──────────────────────────── the card grid ─────────────────────────── */

.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(288px, 1fr)); gap: 12px; }

.card {
  position: relative; display: grid; gap: 9px; align-content: start;
  padding: 15px 16px 14px;
  border: 1px solid var(--border-soft); border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel) 0%, #08080b 100%);
  text-align: left;
  transition: border-color .14s, transform .14s;
}
.card::before {
  content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 2px; border-radius: 2px;
  background: var(--card, var(--accent)); opacity: .55;
}
.card:hover { border-color: #33333e; transform: translateY(-2px); }
.card:hover::before { opacity: 1; }

/* Laid out like a browser tab — favicon hard left, label beside it. flex
   rather than an inline icon so a title that wraps to two lines hangs off the
   icon instead of flowing back underneath it. */
.card-title { display: flex; align-items: flex-start; gap: 10px; font-size: 15.5px; font-weight: 650; letter-spacing: -.01em; }
/* The line box is 15.5 x 1.2 = 18.6px against a 20px icon, so flex-start
   leaves it hanging ~1px low. This centres it on the FIRST line, which is
   where the eye expects it. */
.card-title .fav { margin-top: -1px; }
.card-title a { color: var(--text); min-width: 0; }
.card-title a:hover { color: var(--accent); text-decoration: none; }

.card-meta { display: flex; align-items: center; gap: 8px; overflow: hidden; font-family: var(--font-mono); font-size: 11px; color: var(--faint); white-space: nowrap; }
/* Only the domain may shrink; everything else keeps its width, or a flex item
   squeezed below its content wraps the date onto a second line. */
.card-meta > * { flex: 0 0 auto; }
.card-meta .dom { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-meta .sep { opacity: .4; }

/* ──────────────────────────── favicons ────────────────────────────
   One sprite, one request, no third-party calls — see tools-src/link-desk/
   icons.mjs. --fav-sheet and --fav-sheet-size are set on <html> by script.js,
   because only the build knows the sheet's hash and dimensions.

   The chip is not decoration. This page is committed dark (#060606) and a
   large share of real favicons are dark marks on transparency: without
   something light behind them they vanish outright. The inverse case — a
   white wordmark, invisible ON the light chip — is measured from the pixels
   at build time and marked .on-dark. */
.fav {
  --fav-px: 20px;
  display: inline-block; flex: 0 0 auto;
  width: var(--fav-px); height: var(--fav-px);
  border-radius: calc(var(--fav-px) * .26);
  background-color: #f1f1f4;
  background-image: var(--fav-sheet);
  /* --fx/--fy are the tile's column and row, set inline by script.js; every
     pixel here comes off --fav-px, so one override resizes an icon correctly
     in all three places at once. */
  background-size: calc(var(--fav-cols) * var(--fav-px)) calc(var(--fav-rows) * var(--fav-px));
  background-position: calc(var(--fx) * var(--fav-px) * -1) calc(var(--fy) * var(--fav-px) * -1);
  background-repeat: no-repeat;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07);
}
.fav.on-dark { background-color: #1d1d24; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12); }
.fav.sm { --fav-px: 16px; }
/* Inside a text cell. inline-block (not a flex parent) is what keeps the
   sibling text's text-overflow: ellipsis working. */
.fav.in-row { vertical-align: -3.5px; margin-right: 7px; }

.card-desc {
  font-size: 13.5px; color: var(--dim); line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.card-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 999px;
  font-size: 11px; line-height: 1.5;
  border: 1px solid color-mix(in srgb, var(--pc, var(--accent)) 34%, transparent);
  background: color-mix(in srgb, var(--pc, var(--accent)) 11%, transparent);
  color: color-mix(in srgb, var(--pc, var(--accent)) 72%, #ffffff);
}
.pill.topic { --pc: var(--tc, var(--accent)); }
.pill.slot { border-style: dashed; }
.pill.repeat { --pc: #ffffff; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .02em; }
.pill.multi { --pc: var(--accent); font-weight: 600; }
.pill.flag { --pc: #52525b; }

/* rows view — the dense read of the same result set. The card keeps its DOM;
   the parts that belong to one view or the other are switched here, and the
   column count must match exactly what stays visible or rows wrap. */
.grid.is-rows { display: block; border: 1px solid var(--border-soft); border-radius: var(--radius); overflow: hidden; }
.grid.is-rows .card {
  display: grid; grid-template-columns: minmax(0, 1fr) 210px 150px 54px 78px;
  align-items: center; gap: 14px;
  border: 0; border-bottom: 1px solid var(--border-soft); border-radius: 0;
  padding: 9px 16px 9px 18px; background: none; transform: none;
}
.grid.is-rows .card:hover { background: var(--panel); }
.grid.is-rows .card::before { top: 6px; bottom: 6px; }
.grid.is-rows .card-desc,
.grid.is-rows .card-foot,
.grid.is-rows .card-meta { display: none; }
/* text-overflow does nothing on a flex container, so the clamp moves to the
   label itself — and the icon shrinks a little to keep the row height. */
.grid.is-rows .card-title { font-size: 14px; align-items: center; gap: 9px; }
.grid.is-rows .card-title .fav { --fav-px: 17px; margin-top: 0; }
.grid.is-rows .card-title a { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grid.is-rows .row-dom { font-family: var(--font-mono); font-size: 11.5px; color: var(--dim); }
.grid.is-rows .row-topic { font-size: 12px; color: var(--dim); }
.grid.is-rows .row-dom, .grid.is-rows .row-topic { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grid.is-rows .row-n, .grid.is-rows .row-date { font-family: var(--font-mono); font-size: 11.5px; color: var(--faint); text-align: right; }
.grid:not(.is-rows) .row-dom,
.grid:not(.is-rows) .row-topic,
.grid:not(.is-rows) .row-n,
.grid:not(.is-rows) .row-date { display: none; }

/* Scoped to the paragraph on purpose: `.empty` is also a legend/badge modifier
   in the rail, and an unscoped rule here stretched those 8px dots to 88px. */
p.empty { padding: 44px 0; text-align: center; color: var(--dim); }
.linklike { color: var(--accent); text-decoration: underline; }

.more-wrap { display: grid; place-items: center; padding: 22px 0 4px; }
.btn-more {
  padding: 9px 22px; border: 1px solid var(--border); border-radius: 999px;
  font-size: 13px; color: var(--dim); background: var(--panel);
}
.btn-more:hover { border-color: var(--accent); color: var(--text); }

.foot { padding-top: 26px; margin-top: 22px; border-top: 1px solid var(--border-soft); font-size: 12px; color: var(--faint); }

/* ─────────────────────────── the entry panel ────────────────────────── */

.scrim { position: fixed; inset: 0; z-index: 40; background: rgba(3, 3, 5, .66); backdrop-filter: blur(2px); }

.panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 41;
  width: min(var(--panel-w), 100%);
  display: flex; flex-direction: column;
  border-left: 1px solid var(--border);
  background: var(--panel);
  animation: slideIn .18s ease-out;
}
@keyframes slideIn { from { transform: translateX(18px); opacity: .4; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .panel { animation: none; } }

.panel-close {
  position: absolute; top: 12px; right: 14px; z-index: 2;
  display: grid; place-items: center; width: 30px; height: 30px;
  border: 1px solid var(--border); border-radius: 8px; color: var(--dim); background: var(--panel-2);
}
.panel-close:hover { color: var(--text); border-color: var(--accent); }

.panel-scroll { flex: 1 1 auto; overflow-y: auto; padding: 22px 22px 26px; }
.panel-head { padding-right: 38px; }
.panel-kicker { font-family: var(--font-mono); font-size: 11px; color: var(--faint); letter-spacing: .06em; }
.panel-head h2 { font-size: 22px; margin: 6px 0 8px; }
.panel-url { display: block; font-size: 12px; color: var(--accent); word-break: break-all; }
.panel-head .chips { padding-top: 12px; }

.panel-desc { margin-top: 14px; font-size: 14px; color: var(--dim); line-height: 1.62; }

.panel-clauses { margin-top: 18px; display: grid; gap: 1px; border: 1px solid var(--border-soft); border-radius: 10px; overflow: hidden; }
.panel-clauses div { display: grid; grid-template-columns: 108px minmax(0, 1fr); gap: 10px; padding: 9px 12px; background: var(--panel-2); }
.panel-clauses dt { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--faint); padding-top: 2px; }
.panel-clauses dd { font-size: 13px; color: var(--text); word-break: break-word; }

.panel-appear { margin-top: 24px; }
.panel-appear h3 { font-size: 12px; letter-spacing: .13em; text-transform: uppercase; color: var(--faint); display: flex; gap: 8px; }
.panel-appear h3 span { font-family: var(--font-mono); color: var(--dim); letter-spacing: 0; }
.panel-appear-note { margin: 8px 0 12px; font-size: 12.5px; color: var(--dim); }

.timeline { list-style: none; display: grid; gap: 0; padding-left: 6px; }
.timeline li { position: relative; display: flex; align-items: center; gap: 10px; padding: 7px 0 7px 20px; font-size: 13px; }
.timeline li::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 9px; height: 9px; margin-top: -4.5px;
  border-radius: 50%; background: var(--tl, var(--accent));
}
.timeline li::after { content: ""; position: absolute; left: 4px; top: 50%; bottom: -7px; width: 1px; background: var(--border); }
.timeline li:last-child::after { display: none; }
.timeline .tl-date { font-family: var(--font-mono); font-size: 12px; color: var(--faint); margin-left: auto; }
.timeline .tl-stream { color: var(--dim); }

.panel-foot {
  flex: 0 0 auto; display: flex; align-items: center; gap: 12px;
  padding: 13px 18px; border-top: 1px solid var(--border-soft); background: var(--panel-2);
}
/* The share bar shrinks; the button never wraps its label. */
.panel-foot .tool-share { flex: 1 1 auto; min-width: 0; }
.btn-primary {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 16px; border-radius: 999px; white-space: nowrap;
  background: var(--accent); color: #0b0b0f; font-size: 13px; font-weight: 650;
}
.btn-primary:hover { text-decoration: none; filter: brightness(1.08); }

/* ──────────────────────── the console (Direction B) ─────────────────── */

.omni { position: fixed; inset: 0; z-index: 50; display: grid; place-items: start center; padding: 9vh 18px 18px; }
.omni-scrim { position: fixed; inset: 0; background: rgba(3, 3, 5, .72); backdrop-filter: blur(3px); }

.omni-box {
  position: relative; width: min(940px, 100%); max-height: 78vh;
  display: flex; flex-direction: column;
  border: 1px solid var(--border); border-radius: 14px; overflow: hidden;
  background: var(--panel);
  box-shadow: 0 26px 70px rgba(0, 0, 0, .6);
}
.omni-field { display: flex; align-items: center; gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border-soft); }
.omni-field svg { width: 17px; height: 17px; color: var(--faint); flex: 0 0 auto; }
.omni-field input { flex: 1 1 auto; border: 0; background: none; font-size: 16px; outline: none; }
.omni-field input::placeholder { color: #46464f; }
.omni-clear { color: var(--faint); font-size: 20px; line-height: 1; padding: 0 4px; }

.omni-tokens { display: flex; flex-wrap: wrap; gap: 6px; padding: 10px 16px; border-bottom: 1px solid var(--border-soft); }
.omni-tokens button {
  padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--dim); background: var(--panel-2);
}
.omni-tokens button:hover { border-color: var(--accent); color: var(--text); }
.omni-tokens .tk-note { padding: 3px 2px; font-family: var(--font-body); font-size: 11.5px; color: var(--faint); border: 0; background: none; cursor: default; }

.omni-results { flex: 1 1 auto; overflow-y: auto; }
.omni-results table { width: 100%; border-collapse: collapse; }
.omni-results th {
  position: sticky; top: 0; z-index: 1;
  padding: 7px 12px; text-align: left; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--faint); background: var(--panel-2); border-bottom: 1px solid var(--border-soft); cursor: pointer;
  white-space: nowrap; font-weight: 600;
}
.omni-results th:hover { color: var(--dim); }
.omni-results th .arrow { color: var(--accent); }
.omni-results td { padding: 7px 12px; border-bottom: 1px solid var(--border-soft); font-size: 13px; vertical-align: middle; }
.omni-results tr { cursor: pointer; }
.omni-results tr.is-cursor td { background: var(--accent-soft); }
.omni-results tr:hover td { background: var(--panel-2); }
.omni-results .c-name { max-width: 340px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.omni-results .c-dom, .omni-results .c-topic { color: var(--dim); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.omni-results .c-dom { font-family: var(--font-mono); font-size: 11.5px; }
.omni-results .c-n, .omni-results .c-date { font-family: var(--font-mono); font-size: 11.5px; color: var(--faint); text-align: right; white-space: nowrap; }
.omni-results .c-dot { width: 22px; }
.omni-empty { padding: 40px 16px; text-align: center; color: var(--faint); font-size: 13.5px; }

.omni-foot {
  flex: 0 0 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
  padding: 9px 16px; border-top: 1px solid var(--border-soft); background: var(--panel-2);
  font-size: 11.5px; color: var(--faint);
}
.omni-foot span { display: inline-flex; align-items: center; gap: 4px; }
.omni-count { margin-left: auto; font-family: var(--font-mono); }

/* ─────────────────────────────── toast ──────────────────────────────── */

.toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 70; transform: translateX(-50%);
  padding: 9px 18px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--panel-3); font-size: 13px; color: var(--text);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .5);
}

/* ───────────────────────────── responsive ───────────────────────────── */

@media (max-width: 1080px) {
  .hero { grid-template-columns: 1fr; align-items: start; }
  .layout { grid-template-columns: 1fr; }
  /* The sidebar is the first thing that breaks on a narrow screen, so it stops
     being a sidebar: the facets become a scrollable row of collapsed groups
     above the results instead of a column beside them. */
  .sidebar {
    position: static; max-height: none; overflow: visible;
    display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 20px;
    padding: 0 0 8px; border-bottom: 1px solid var(--border-soft); margin-bottom: 16px;
  }
  .side-exports { grid-column: 1 / -1; }
  .grid.is-rows .card { grid-template-columns: minmax(0, 1fr) 54px 78px; }
  .grid.is-rows .row-dom, .grid.is-rows .row-topic { display: none; }
}

@media (max-width: 720px) {
  .shell { padding: 22px 14px 48px; }
  .topbar { padding: 9px 12px; gap: 10px; }
  .omni-open-hint { display: none; }
  .brand small { display: none; }
  /* The share bar does not wrap, so at phone widths it pushed the page into a
     horizontal scroll. The hero carries the same bar — one is enough. */
  .topbar .tool-share { display: none; }
  .stats div { min-width: 82px; padding: 8px 11px; }
  .stats dd { font-size: 18px; }
  .grid { grid-template-columns: 1fr; }
  .omni { padding: 4vh 8px 8px; }
  .omni-results .c-topic, .omni-results .c-date { display: none; }
  .panel { --panel-w: 100%; }

  /* On a phone the grid is one column and the tray scrolls away after two
     cards, which is the moment you stop trusting that anything was staged.
     Pinned to the bottom, chips dropped: the count and the export button are
     the only two things worth the height. */
  .tray {
    position: fixed; z-index: 45; left: 8px; right: 8px; bottom: 8px; margin: 0;
    padding: 9px 11px; box-shadow: 0 12px 34px rgba(0, 0, 0, .6);
    background: color-mix(in srgb, var(--accent) 7%, var(--panel-2));
  }
  .tray-list, .tray-note { display: none; }
  .tray-head { gap: 8px; }
  .tray-head b { flex: 1 1 auto; }
  /* Clear of the pinned bar, so the last card is never trapped under it. */
  body:has(.tray:not([hidden])) .more-wrap { padding-bottom: 62px; }
}
