/* ─────────────────────────────────────────────────────────────────────────
   Account redesign — Home crawl cards + Crawl hub.
   Component styles for the new /account/ home and /account/crawl/ pages.
   Scoped with an `rl-` prefix so nothing here collides with account.css; all
   tokens use var(--x, #fallback) so it renders even where a token is unset.
   Reuses .badge / .btn / .brand-avatar from account.css.
   ───────────────────────────────────────────────────────────────────────── */

:root { --rl-accent:#c8ff00; --rl-amber:#facc15; --rl-blue:#38bdf8; --rl-red:#f87171; }

/* ── Crawls page (/account/audits/) — signal cards over the existing data ── */
.dash--audits .series-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
.dash--audits .account-subtabs { top: 64px; }
.rl-signal__idwrap { flex: 1; min-width: 0; }
.rl-signal__head .brand-avatar { width: 54px; height: 54px; border-radius: 14px; flex: none; }
.rl-signal__head .brand-avatar__mono { font-size: 1.4rem; }
.rl-signal__head .brand-avatar__img { border-radius: 14px; }
.rl-signal__head .row-menu { margin-left: 4px; }
.rl-signal .attn-vis { justify-content: flex-end; }
.rl-signal .series__nextrun { margin-top: 14px; }
.rl-signal .series-card__cycles, .rl-signal .audit-rows.cyc-timeline { margin-top: 14px; }
.rl-signal .series-team { margin-top: 14px; }
.rl-signal__nowrow { margin-top: 14px; }
.rl-signal__nowrow .rl-now { color: var(--text-secondary, #e4e4e7); font-size: .9rem; }
.rl-signal__foot .series-access { flex: 1; margin: 0; min-width: 0; }
.rl-signal__foot .series-access--empty { flex: 0 0 auto; }
/* A shared card's footer carries the CTA alone — there is no access manager on a
   crawl you don't own — so it sits at the end rather than floating mid-row where
   space-between would leave it. */
.rl-signal__foot--shared { justify-content: flex-end; }
/* clickable status line (single-cycle) */
.rl-nowrow { display: flex; align-items: center; gap: 10px; text-decoration: none; margin-top: 14px;
  padding: 12px 14px; border: 1px solid var(--border, #27272a); border-radius: 11px; background: var(--bg-card, #141416); transition: .15s; }
.rl-nowrow:hover { border-color: var(--accent, #c8ff00); }
.rl-nowrow .rl-now { flex: 1; color: var(--text-secondary, #e4e4e7); font-size: .9rem; }
.rl-nowrow__go { color: var(--text-muted, #a1a1aa); transition: .15s; }
.rl-nowrow:hover .rl-nowrow__go { color: var(--accent, #c8ff00); transform: translateX(2px); }
/* collapsed "Shared with" (avatars + Manage) */
.series-access--collapsed { margin: 0; }
.series-access__summary { display: inline-flex; align-items: center; gap: 10px; background: none; border: none; cursor: pointer; padding: 4px 0; color: var(--text-muted, #a1a1aa); font: inherit; }
.series-access__summary:hover .series-access__chev { color: var(--accent, #c8ff00); }
.series-access__summary .rl-avstack .rl-av { width: 26px; height: 26px; font-size: .6rem; border-color: var(--bg-card, #141416); }
.series-access__chev { font-family: var(--mono, monospace); font-size: .64rem; text-transform: uppercase; letter-spacing: .06em; color: var(--text-faint, #71717a); }
.series-access__panel { margin-top: 12px; }


/* ── Single-bar account nav (artifact style) ──────────────────────────────
   The account links live INSIDE the top logo bar instead of a separate row
   below it, reclaiming ~48px of vertical space. .site-nav__inner is already a
   flex row with space-between (main.css), so the subnav simply lands on the
   right. Desktop only — on ≤640px account.css hides .account-subnav and
   account-nav.js takes over with the hamburger + bottom tab bar. */
@media (min-width: 641px) {
  .rl-topbar .account-subnav {
    position: static; top: auto; z-index: auto;
    border: none; background: none; margin: 0; padding: 0; flex: 0 0 auto;
    display: flex; align-items: center; gap: 10px;
  }
  .rl-topbar .account-subnav__links { gap: 0.05rem; }
  .rl-topbar .account-subnav__link { font-size: 0.84rem; padding: 0.5rem 0.66rem; }
  /* Sign out moved into the profile dropdown; the inline button stays in the DOM
     (each page wires #signout) but is hidden here. */
  .rl-topbar .account-subnav__signout { display: none; }
}
/* Hidden until auth resolves (the nav lives outside #dash now). */
.rl-topbar .account-subnav[hidden] { display: none; }

/* ── Profile dropdown (desktop) ────────────────────────────────────────────
   Avatar button pinned to the right of the top bar; opens a small menu of the
   secondary destinations + Sign out. Hidden on mobile with the rest of
   .account-subnav (the hamburger covers those links there). */
.rl-profile { position: relative; flex: 0 0 auto; }
.rl-profile__btn {
  display: grid; place-items: center; padding: 0; border: none; background: none; cursor: pointer;
  border-radius: 999px; line-height: 0;
}
.rl-profile__avatar {
  position: relative; width: 34px; height: 34px; border-radius: 999px; display: grid; place-items: center;
  color: var(--text-muted, #a1a1aa); background: var(--bg-card, #141416);
  border: 1px solid var(--border-light, #3f3f46); transition: .15s;
}
.rl-profile__avatar svg { width: 19px; height: 19px; }
.rl-profile__avatar--mono {
  color: #0a0a0a; font-weight: 700; font-size: .95rem; border-color: transparent;
  background: linear-gradient(135deg, #eaffa0, var(--accent, #c8ff00));
}
.rl-profile__btn:hover .rl-profile__avatar { border-color: var(--accent, #c8ff00); }
.rl-profile__btn.is-active .rl-profile__avatar,
.rl-profile__btn[aria-expanded="true"] .rl-profile__avatar {
  box-shadow: 0 0 0 2px var(--bg, #09090b), 0 0 0 4px rgba(200, 255, 0, .55);
}
.rl-profile__menu {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 62; min-width: 210px;
  background: var(--bg-secondary, #0f0f11); border: 1px solid var(--border-light, #3f3f46);
  border-radius: 14px; box-shadow: 0 24px 60px -20px rgba(0,0,0,.9); padding: 7px; display: flex; flex-direction: column;
}
.rl-profile__menu[hidden] { display: none; }
.rl-profile__link, .rl-profile__signout {
  display: block; width: 100%; text-align: left; font: inherit; font-size: .88rem; color: var(--text, #fafafa);
  background: none; border: none; padding: 9px 12px; border-radius: 9px; cursor: pointer; text-decoration: none;
}
.rl-profile__link:hover, .rl-profile__signout:hover { background: var(--bg-card, #141416); }
.rl-profile__link[aria-current="page"] { color: var(--accent, #c8ff00); }
.rl-profile__signout { color: var(--text-muted, #a1a1aa); }
.rl-profile__sep { height: 1px; background: var(--border, #27272a); margin: 6px 4px; }

/* Activity unread badge — reuses .acct-badge (account.css). On desktop it rides
   the avatar (corner dot) and the Activity row inside the dropdown; on mobile it
   rides the hamburger button (the "more" surface Activity now lives behind). */
.rl-profile__btn { position: relative; }
.rl-profile__btn .acct-badge { position: absolute; top: -3px; right: -3px; }
.rl-profile__link.has-badge { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.acct-burger { position: relative; }
.acct-burger .acct-badge { position: absolute; top: 3px; right: 1px; }

.rl-mono { font-family: var(--mono, 'JetBrains Mono', ui-monospace, monospace); }
.rl-tnum { font-variant-numeric: tabular-nums; }
.rl-eyebrow { font-family: var(--mono, 'JetBrains Mono', monospace); text-transform:uppercase;
  letter-spacing:.14em; font-size:.66rem; color:var(--text-muted,#a1a1aa); font-weight:500; }
.rl-idcode { font-family: var(--mono, 'JetBrains Mono', monospace); font-size:.64rem; color:var(--text-muted,#a1a1aa);
  background:var(--bg-card,#141416); border:1px solid var(--border,#27272a); padding:2px 7px; border-radius:6px; letter-spacing:.02em; }
.rl-delta { font-family: var(--mono, 'JetBrains Mono', monospace); font-size:.78rem; font-weight:600; }
.rl-delta.up { color:var(--accent,#c8ff00); } .rl-delta.down { color:var(--rl-red); } .rl-delta.flat { color:var(--text-muted,#a1a1aa); }

/* ── home header + toolbar ─────────────────────────────────────────────── */
.rl-homehead { display:flex; align-items:flex-end; justify-content:space-between; gap:20px; flex-wrap:wrap; margin:6px 0 24px; }
.rl-homehead h1 { font-size:1.9rem; margin:9px 0 0; letter-spacing:-.02em; }
.rl-homehead p { color:var(--text-muted,#a1a1aa); margin:8px 0 0; max-width:48ch; font-size:.97rem; }
.rl-homehead__r { display:flex; flex-direction:column; align-items:flex-end; gap:12px; }
/* The crawl count, sitting with the view toggle it describes. /account/audits/
   used to carry this in its own .view-bar strip below a second page header;
   folding it into the shared head is what let that whole strip go. */
.rl-headcount { font-family:var(--mono,monospace); font-size:.68rem; letter-spacing:.08em;
  text-transform:uppercase; color:var(--text-muted,#a1a1aa); }
.rl-seg { display:inline-flex; background:var(--bg-card,#141416); border:1px solid var(--border,#27272a); border-radius:10px; padding:3px; }
.rl-seg button { font-family:var(--mono,monospace); font-size:.68rem; text-transform:uppercase; letter-spacing:.08em;
  color:var(--text-muted,#a1a1aa); border:none; background:none; padding:7px 13px; border-radius:7px; transition:.15s; display:flex; align-items:center; gap:6px; cursor:pointer; }
.rl-seg button.on { background:var(--bg-card-hover,#1b1b1f); color:var(--text,#fafafa); }
.rl-seg svg { width:13px; height:13px; }

.rl-cards { display:grid; gap:18px; }
.rl-list { display:grid; gap:10px; }
.rl-home[data-view="list"] .rl-cards { display:none; }
.rl-home:not([data-view="list"]) .rl-list { display:none; }

/* ── monogram tile (falls back to brand-avatar from account.css when used) ─ */
.rl-mono-tile { width:46px; height:46px; border-radius:12px; flex:none; display:grid; place-items:center;
  font-weight:700; font-size:1.15rem; color:#0a0a0a; background:linear-gradient(135deg,#eaffa0,var(--accent,#c8ff00)); }
.rl-mono-tile--alt { background:linear-gradient(135deg,#3f3f46,#27272a); color:#e4e4e7; }
.rl-mono-tile--lg { width:58px; height:58px; border-radius:15px; font-size:1.5rem; }
.rl-url { font-family:var(--mono,monospace); font-size:.74rem; color:var(--text-faint,#71717a); }
.rl-chip-mini { display:inline-flex; align-items:center; gap:6px; font-family:var(--mono,monospace); font-size:.62rem;
  color:var(--text-muted,#a1a1aa); border:1px solid var(--border,#27272a); border-radius:999px; padding:3px 10px; }

/* ── signal card ───────────────────────────────────────────────────────── */
.rl-signal { position:relative; overflow:hidden; text-align:left; width:100%; display:block; cursor:pointer;
  background:linear-gradient(158deg,#191a1d 0%,var(--bg-card,#141416) 46%,#101012 100%);
  border:1px solid var(--border-light,#3f3f46); border-radius:22px; padding:24px 26px 20px; transition:.2s; color:inherit; }
.rl-signal::after { content:""; position:absolute; left:0; right:0; top:0; height:1px;
  background:linear-gradient(90deg,transparent,rgba(200,255,0,.5),transparent); }
.rl-signal:hover { transform:translateY(-3px); box-shadow:0 26px 60px -30px rgba(0,0,0,.95), 0 0 0 1px rgba(200,255,0,.14); }
.rl-signal__rings { position:absolute; top:-90px; right:-70px; width:340px; height:340px; pointer-events:none; opacity:.5; }
.rl-signal__head { display:flex; align-items:flex-start; gap:14px; position:relative; }
.rl-signal__idname { display:flex; align-items:center; gap:9px; font-size:1.22rem; font-weight:600; }
.rl-signal__meta { margin-left:auto; text-align:right; display:flex; flex-direction:column; gap:6px; align-items:flex-end; }
.rl-signal--sec { background:linear-gradient(158deg,#151517,var(--bg-card,#141416)); border-color:var(--border,#27272a); }
.rl-signal--sec .rl-readout__val { font-size:2.5rem; }
.rl-signal--sec .rl-signal__rings { display:none; }

.rl-readout { display:flex; align-items:center; gap:22px; margin:20px 0 6px; position:relative; }
.rl-readout__num { flex:none; }
.rl-readout__val { font-size:3.3rem; font-weight:700; letter-spacing:-.04em; line-height:.92; margin-top:6px;
  display:flex; align-items:baseline; gap:10px; text-shadow:0 0 44px rgba(200,255,0,.10); }
.rl-readout__val .pct { font-size:1.3rem; color:var(--text-muted,#a1a1aa); font-weight:600; }
.rl-readout__val.muted { color:var(--text-faint,#71717a); text-shadow:none; }
.rl-readout__pending { font-size:.8rem; font-family:var(--mono,monospace); color:var(--rl-blue); align-self:center; }
.rl-readout__cap { font-size:.86rem; color:var(--text-muted,#a1a1aa); margin-top:10px; max-width:34ch; }
.rl-readout__wave { flex:1; min-width:0; }
.rl-readout__wave svg { width:100%; height:auto; display:block; }

/* ── journey track + pin ───────────────────────────────────────────────── */
.rl-track { position:relative; margin:20px 0 4px; }
/* Five stages: Foundations · Questions · Crawl · Visibility · Actions. Node
   centers land at (i+0.5)/5 → 10%…90%, so the rail runs 10% in from each edge
   (trackHTML computes the fill's left/width to match). */
.rl-track__nodes { position:relative; display:grid; grid-template-columns:repeat(5,1fr); padding-top:26px; }
.rl-track__nodes::before { content:""; position:absolute; top:calc(26px + 13px); left:10%; right:10%; height:2px;
  background:var(--border,#27272a); border-radius:2px; }
.rl-track__fill { position:absolute; top:calc(26px + 13px); height:2px; background:var(--accent,#c8ff00); border-radius:2px;
  box-shadow:0 0 8px rgba(200,255,0,.5); z-index:1; }
.rl-stop { position:relative; display:flex; flex-direction:column; align-items:center; gap:9px; }
.rl-node { width:26px; height:26px; border-radius:50%; display:grid; place-items:center; position:relative; z-index:2;
  font-family:var(--mono,monospace); font-size:.72rem; font-weight:600; background:var(--bg-card-hover,#1b1b1f);
  border:2px solid var(--border-light,#3f3f46); color:var(--text-faint,#71717a); }
.rl-stop.done .rl-node { background:var(--accent,#c8ff00); border-color:var(--accent,#c8ff00); color:#0a0a0a; }
.rl-stop.is-active.you .rl-node { border-color:var(--rl-amber); color:var(--rl-amber); background:rgba(250,204,21,.08); }
.rl-stop.is-active.working .rl-node { border-color:var(--rl-blue); color:var(--rl-blue); background:rgba(56,189,248,.08); }
.rl-stop.is-active .rl-node { box-shadow:0 0 0 4px rgba(200,255,0,.10); }
a.rl-stop { text-decoration:none; color:inherit; }
.rl-stop.is-link { cursor:pointer; }
.rl-stop.is-link:hover .rl-node { border-color:var(--accent,#c8ff00); color:var(--accent,#c8ff00); box-shadow:0 0 0 4px rgba(200,255,0,.12); }
.rl-stop.done.is-link:hover .rl-node { filter:brightness(1.12); box-shadow:0 0 0 4px rgba(200,255,0,.18); }
.rl-stop.is-link:hover .rl-stop__lbl { color:var(--text,#fafafa); }
.rl-stop__lbl { font-family:var(--mono,monospace); font-size:.62rem; text-transform:uppercase; letter-spacing:.07em; color:var(--text-faint,#71717a); }
.rl-stop.done .rl-stop__lbl, .rl-stop.is-active .rl-stop__lbl { color:var(--text-secondary,#e4e4e7); }
.rl-pin { position:absolute; top:-2px; left:50%; transform:translateX(-50%); z-index:4; line-height:0; filter:drop-shadow(0 3px 6px rgba(0,0,0,.6)); }
.rl-pin svg { display:block; }
@keyframes rl-pinbob { 0%,100%{transform:translateX(-50%) translateY(0)} 50%{transform:translateX(-50%) translateY(-3px)} }
.rl-pin { animation:rl-pinbob 2.4s ease-in-out infinite; }
@keyframes rl-ringpulse { 0%{box-shadow:0 0 0 0 rgba(200,255,0,.22)} 70%{box-shadow:0 0 0 9px rgba(200,255,0,0)} 100%{box-shadow:0 0 0 0 rgba(200,255,0,0)} }
.rl-stop.is-active .rl-node { animation:rl-ringpulse 2.4s ease-out infinite; }
@media (prefers-reduced-motion: reduce) { .rl-pin, .rl-stop.is-active .rl-node { animation:none; } }

/* Peek-ahead: a greyed stage on a card is tappable to reveal what it will hold.
   A dotted underline on the label hints there's more without a hover (works on
   touch too); the node lights lime while its panel is open. */
.rl-signal .rl-stop.locked { cursor:pointer; }
.rl-signal .rl-stop.locked .rl-stop__lbl { text-decoration:underline dotted; text-underline-offset:3px; text-decoration-color:rgba(255,255,255,.2); }
.rl-signal .rl-stop.locked:hover .rl-node { border-color:var(--text-muted,#a1a1aa); color:var(--text-secondary,#e4e4e7); }
.rl-signal .rl-stop.locked:hover .rl-stop__lbl { color:var(--text-secondary,#e4e4e7); }
.rl-stop.is-peek .rl-node { border-color:var(--accent,#c8ff00); color:var(--accent,#c8ff00); box-shadow:0 0 0 4px rgba(200,255,0,.10); }
.rl-stop.is-peek .rl-stop__lbl { color:var(--text,#fafafa); }

/* The "what's coming" panel — a dashed, softly-lit placeholder (the universal
   "nothing here yet") that says what the stage will fill with. */
.rl-stagedesc {
  margin:14px 0 2px; padding:16px 18px; border-radius:14px;
  border:1px dashed var(--border-light,#3f3f46); background:rgba(200,255,0,.03);
  animation:rl-stagedesc-in .18s ease;
}
.rl-stagedesc__hd { display:flex; align-items:center; gap:8px; font-size:1rem; color:var(--text,#fafafa); }
.rl-stagedesc__hd svg { width:16px; height:16px; flex:none; color:var(--text-muted,#a1a1aa); }
.rl-stagedesc__tag {
  margin-left:6px; font-family:var(--mono,monospace); font-size:.6rem; text-transform:uppercase; letter-spacing:.1em;
  color:var(--text-faint,#71717a); border:1px solid var(--border,#27272a); border-radius:999px; padding:2px 8px;
}
.rl-stagedesc__msg { margin:9px 0 0; font-size:.9rem; line-height:1.55; color:var(--text-secondary,#e4e4e7); max-width:70ch; }
.rl-stagedesc__x { margin-top:12px; font:inherit; font-size:.8rem; font-weight:600; color:var(--accent,#c8ff00); background:none; border:0; padding:0; cursor:pointer; }
.rl-stagedesc__x:hover { text-decoration:underline; }
@keyframes rl-stagedesc-in { from{opacity:0; transform:translateY(-4px)} to{opacity:1; transform:none} }

/* ── card footer: collaborators + cta ──────────────────────────────────── */
.rl-signal__foot { display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap;
  margin-top:18px; padding-top:16px; border-top:1px solid var(--border,#27272a); }
.rl-collab { display:flex; align-items:center; gap:11px; }
/* Same cluster, now the way into the share sheet. Styled to stay a label, not
   become a second button competing with the CTA beside it. */
.rl-collab--btn { background:none; border:0; padding:0; font:inherit; cursor:pointer; text-align:left; }
.rl-collab--btn:hover .rl-collab__lbl { color:var(--text,#fafafa); }
.rl-collab--btn:focus-visible { outline:2px solid var(--accent,#c8ff00); outline-offset:3px; border-radius:6px; }
.rl-collab__lbl { font-family:var(--mono,monospace); font-size:.6rem; text-transform:uppercase; letter-spacing:.1em; color:var(--text-muted,#a1a1aa); }
/* Shared-with-you variant: avatar first, then who shared it. Lowercase and
   allowed to wrap, because an owner's email is far longer than the "Shared with"
   label this replaces and must not push the card sideways on a phone. */
.rl-collab--shared { min-width:0; }
.rl-collab--shared .rl-collab__lbl { text-transform:none; letter-spacing:.02em; font-size:.68rem;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.rl-avstack { display:flex; }
.rl-av { width:29px; height:29px; border-radius:50%; display:grid; place-items:center; font-size:.64rem; font-weight:700;
  color:#0a0a0a; border:2px solid var(--bg-card,#141416); margin-left:-8px; font-family:var(--mono,monospace); }
.rl-av:first-child { margin-left:0; }
.rl-av--more { background:var(--bg-card-hover,#1b1b1f); color:var(--text-muted,#a1a1aa); }
.rl-av--you { box-shadow:0 0 0 2px var(--accent,#c8ff00); }
/* A real <a> to the hub's share panel. min-height keeps it a 44px touch target —
   at the old 6px/.78rem padding it measured 34px, under the thumb-size floor. */
.rl-sharebtn { display:inline-flex; align-items:center; gap:6px; font-size:.78rem; font-weight:500; color:var(--text-secondary,#e4e4e7);
  background:none; border:1px dashed var(--border-light,#3f3f46); border-radius:999px; padding:6px 12px; transition:.15s; cursor:pointer;
  min-height:44px; box-sizing:border-box; text-decoration:none; }
.rl-sharebtn:hover { border-color:var(--accent,#c8ff00); color:var(--accent,#c8ff00); border-style:solid; }
.rl-sharebtn svg { width:13px; height:13px; }
.rl-ctaline { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.rl-now { font-size:.9rem; color:var(--text-secondary,#e4e4e7); } .rl-now b { color:var(--text,#fafafa); font-weight:600; }
.rl-cta { display:inline-flex; align-items:center; gap:7px; background:var(--accent,#c8ff00); color:#0a0a0a; font-weight:600;
  font-size:.9rem; padding:10px 17px; border-radius:11px; border:none; transition:.15s; }
.rl-cta--ghost { background:var(--bg-card,#141416); color:var(--text,#fafafa); border:1px solid var(--border-light,#3f3f46); }
.rl-signal:hover .rl-cta { gap:10px; }

/* ── start-new tile ────────────────────────────────────────────────────── */
.rl-newtile { display:flex; align-items:center; gap:14px; width:100%; text-align:left; cursor:pointer;
  border:1px dashed var(--border-light,#3f3f46); border-radius:18px; padding:18px 22px; background:none; color:inherit; transition:.15s; }
.rl-newtile:hover { border-color:var(--accent,#c8ff00); background:rgba(200,255,0,.03); }
.rl-newtile .rl-mono-tile { background:var(--bg-card-hover,#1b1b1f); color:var(--accent,#c8ff00); border:1px dashed var(--border-light,#3f3f46); }
.rl-newtile__t { font-size:1.02rem; font-weight:600; }

/* ── list rows ─────────────────────────────────────────────────────────── */
.rl-row { display:grid; grid-template-columns:auto 1.5fr 1.6fr auto auto; align-items:center; gap:16px; width:100%; text-align:left;
  background:var(--bg-card,#141416); border:1px solid var(--border,#27272a); border-radius:14px; padding:15px 18px; transition:.15s; cursor:pointer; color:inherit; }
.rl-row:hover { border-color:var(--border-light,#3f3f46); background:var(--bg-card-hover,#1b1b1f); }
.rl-row__id { display:flex; align-items:center; gap:12px; min-width:0; }
.rl-row__name { font-weight:600; font-size:.98rem; display:flex; align-items:center; gap:8px; }
.rl-row .rl-track { margin:0; }
.rl-track--sm .rl-track__nodes { padding-top:20px; }
.rl-track--sm .rl-node { width:20px; height:20px; font-size:.6rem; border-width:2px; }
.rl-track--sm .rl-track__nodes::before, .rl-track--sm .rl-track__fill { top:calc(20px + 10px); }
.rl-track--sm .rl-stop__lbl { display:none; }
.rl-track--sm .rl-pin svg { width:15px; height:15px; }
.rl-row__vis { text-align:right; }
.rl-row__vis .n { font-size:1.4rem; font-weight:700; letter-spacing:-.03em; }
.rl-row__vis .l { font-family:var(--mono,monospace); font-size:.55rem; text-transform:uppercase; letter-spacing:.1em; color:var(--text-muted,#a1a1aa); }
.rl-row__go { width:34px; height:34px; border-radius:9px; border:1px solid var(--border-light,#3f3f46); background:var(--bg-card,#141416);
  display:grid; place-items:center; color:var(--text-secondary,#e4e4e7); transition:.15s; }
.rl-row:hover .rl-row__go { border-color:var(--accent,#c8ff00); color:var(--accent,#c8ff00); }

/* ── empty state ───────────────────────────────────────────────────────── */
.rl-empty { position:relative; border:1px solid var(--border-light,#3f3f46); border-radius:24px; overflow:hidden;
  background:linear-gradient(180deg,#17181a,var(--bg-secondary,#0f0f11)); padding:56px 40px; }
.rl-empty__rings { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); width:640px; height:640px; opacity:.4; pointer-events:none; }
.rl-empty__in { position:relative; max-width:54ch; margin:0 auto; text-align:center; }
.rl-empty h1 { font-size:2.9rem; margin:16px 0 0; letter-spacing:-.04em; }
.rl-empty h1 em { font-style:normal; color:var(--accent,#c8ff00); text-shadow:0 0 34px rgba(200,255,0,.10); }
.rl-empty p { color:var(--text-muted,#a1a1aa); margin:16px auto 0; font-size:1.02rem; }
.rl-empty__engines { display:flex; gap:10px; justify-content:center; flex-wrap:wrap; margin-top:22px; }
.rl-chip { font-family:var(--mono,monospace); font-size:.72rem; color:var(--text-secondary,#e4e4e7); border:1px solid var(--border-light,#3f3f46);
  border-radius:999px; padding:6px 13px; background:rgba(255,255,255,.02); }
.rl-empty__cta { display:inline-flex; align-items:center; gap:9px; margin-top:30px; background:var(--accent,#c8ff00); color:#0a0a0a;
  font-weight:600; font-size:1rem; padding:13px 24px; border-radius:12px; border:none; transition:.15s; }
.rl-empty__cta:hover { transform:translateY(-2px); box-shadow:0 16px 34px -16px var(--accent,#c8ff00); }
.rl-empty__sub { margin-top:16px; font-size:.82rem; color:var(--text-faint,#71717a); }
.rl-empty__sub a { color:var(--text-muted,#a1a1aa); text-decoration:underline; text-underline-offset:3px; }

/* ── CRAWL HUB ─────────────────────────────────────────────────────────── */
.rl-back { display:inline-flex; align-items:center; gap:7px; font-family:var(--mono,monospace); font-size:.72rem; text-transform:uppercase;
  letter-spacing:.1em; color:var(--text-muted,#a1a1aa); margin-bottom:18px; background:none; border:none; cursor:pointer; }
.rl-back:hover { color:var(--text,#fafafa); }
/* ── F1 · the crawl hub has NO operator chrome ─────────────────────────────
   There was an `.rl-opbar` here, and four `.hub-op` controls inlined into the
   hub's own sections. Both are gone: the hub renders identically for an
   operator and for the customer. Operator work lives on the ops board, and
   acting as the customer goes through "View as client" on the global operator
   bar (`.rl-opbar-g`, in account.css) — which is injected above every account
   page, so operator context is solved once instead of per page.
   Adding an operator-only rule scoped to this page is the regression. */
/* The hub's own layout lives in the `hub-*` block at the foot of this file —
   see "CRAWL HUB — ported design". What stays here is what the hub shares with
   the rest of the account: the back link, the operator bar, the series strip,
   the embedded viewers, the share-of-voice bars and the actions reader. */

/* Inline-embedded viewer (iframe + its ?embed=1 chrome-hiding). Currently
   unused: the ported hub summarises each deliverable natively and links out to
   its viewer, as the approved design does. Kept because restoring the embed is
   a markup change, not a restyle. */
.rl-embed-wrap { margin-top:16px; border:1px solid var(--border,#27272a); border-radius:12px; overflow:hidden; background:var(--bg,#09090b); }
.rl-embed-frame { width:100%; height:72vh; border:none; display:block; background:var(--bg,#09090b); }
.rl-embed-loading { padding:44px; text-align:center; color:var(--text-muted,#a1a1aa); font-family:var(--mono,monospace); font-size:.78rem; letter-spacing:.04em; }
/* earlier cycles directory (series) */
.rl-earlier { margin-top:24px; }
.rl-cyrows { display:grid; gap:8px; }
.rl-cyrow { display:flex; align-items:center; gap:12px; text-decoration:none; color:inherit; background:var(--bg-card,#141416);
  border:1px solid var(--border,#27272a); border-radius:11px; padding:12px 15px; transition:.15s; }
.rl-cyrow:hover { border-color:var(--border-light,#3f3f46); transform:translateY(-1px); }
.rl-cyrow__dot { width:7px; height:7px; border-radius:50%; background:var(--accent,#c8ff00); flex:none; }
.rl-cyrow__main { flex:1; font-size:.9rem; color:var(--text-muted,#a1a1aa); } .rl-cyrow__main b { color:var(--text,#fafafa); font-weight:600; }
.rl-cyrow__vis { font-family:var(--mono,monospace); color:var(--accent,#c8ff00); font-size:.82rem; }
.rl-cyrow__go { color:var(--text-muted,#a1a1aa); } .rl-cyrow:hover .rl-cyrow__go { color:var(--accent,#c8ff00); }
.rl-serieswrap { display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin:16px 0 0; padding:14px 0 0; border-top:1px dashed var(--border,#27272a); }
.rl-series { display:flex; align-items:center; flex-wrap:wrap; }
.rl-series__lbl { font-family:var(--mono,monospace); font-size:.6rem; text-transform:uppercase; letter-spacing:.1em; color:var(--text-muted,#a1a1aa); margin-right:12px; }
.rl-scy { display:flex; flex-direction:column; align-items:center; gap:6px; padding:0; background:none; border:none; text-decoration:none; cursor:pointer; }
.rl-scy__node { padding:7px 13px; border-radius:10px; border:1px solid var(--border-light,#3f3f46); background:var(--bg-card,#141416);
  font-family:var(--mono,monospace); font-size:.72rem; color:var(--text-secondary,#e4e4e7); display:flex; align-items:center; gap:8px; transition:.15s; white-space:nowrap; }
.rl-scy:hover .rl-scy__node { border-color:var(--accent,#c8ff00); color:var(--text,#fafafa); transform:translateY(-1px); }
.rl-scy.is-current .rl-scy__node { border-color:var(--accent,#c8ff00); background:rgba(200,255,0,.12); color:var(--accent,#c8ff00); }
.rl-scy__vis { font-weight:700; }
.rl-scy__lbl { font-family:var(--mono,monospace); font-size:.54rem; text-transform:uppercase; letter-spacing:.08em; color:var(--text-faint,#71717a); }
.rl-scy.is-current .rl-scy__lbl { color:var(--accent,#c8ff00); }
.rl-sconn { width:24px; height:2px; background:var(--border-light,#3f3f46); flex:none; margin-top:-15px; }
.rl-scy--new .rl-scy__node { border-style:dashed; color:var(--accent,#c8ff00); }
/* `.rl-opnote` is gone with the rest of the operator chrome (F1) — it was two
   amber "◂ operator: …" hints shipped inside the customer's series strip and
   hidden by CSS, which is still operator copy sitting in her page. */
.rl-plabel { font-family:var(--mono,monospace); font-size:.62rem; text-transform:uppercase; letter-spacing:.1em; color:var(--text-muted,#a1a1aa); margin-bottom:13px; }
.rl-hbars { display:grid; gap:9px; }
.rl-hbar { display:grid; grid-template-columns:118px 1fr 40px; align-items:center; gap:10px; font-size:.82rem; }
.rl-hbar__name { color:var(--text-secondary,#e4e4e7); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rl-hbar__name.focal { color:var(--accent,#c8ff00); font-weight:600; }
.rl-hbar__track { height:10px; background:var(--border,#27272a); border-radius:5px; overflow:hidden; }
/* display:block is load-bearing — these are <span>s, and an inline box ignores
   width/height, so every share-of-voice bar rendered as an empty track. */
.rl-hbar__fill { display:block; height:100%; border-radius:5px; background:var(--border-light,#3f3f46); }
.rl-hbar__fill.focal { background:var(--accent,#c8ff00); }
.rl-hbar__val { font-family:var(--mono,monospace); text-align:right; color:var(--text-muted,#a1a1aa); font-size:.78rem; }
.rl-hbar__val.focal { color:var(--accent,#c8ff00); }
.rl-trend svg { width:100%; height:auto; display:block; }
.rl-progline { display:flex; align-items:center; gap:12px; margin-bottom:14px; }
.rl-progline__bar { flex:1; height:8px; background:var(--border,#27272a); border-radius:4px; overflow:hidden; }
.rl-progline__fill { display:block; height:100%; background:var(--accent,#c8ff00); border-radius:4px; }
.rl-progline__lbl { font-family:var(--mono,monospace); font-size:.76rem; color:var(--text-secondary,#e4e4e7); white-space:nowrap; }
@media (max-width:720px) {
  .rl-readout { flex-wrap:wrap; gap:12px; } .rl-readout__wave { width:100%; flex:1 0 100%; } .rl-readout__val { font-size:2.7rem; }
  .rl-signal__foot { flex-direction:column; align-items:stretch; }
  .rl-empty h1 { font-size:2.1rem; }
  .rl-row { grid-template-columns:auto 1fr auto; gap:12px; } .rl-row .rl-track, .rl-row .rl-avstack { display:none; }
  .rl-hbar { grid-template-columns:90px 1fr 36px; }
}

/* ── Native Actions reader (crawl hub) ───────────────────────────────────────
   The action plan renders inline from action_items — a working to-do list the
   customer checks off (DB-backed), filters by layer, and copies out. */
.rl-actwrap { display:grid; gap:14px; }
.rl-acthd { display:flex; flex-direction:column; gap:12px; }
.rl-actbar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.rl-actfilters { display:flex; gap:6px; flex-wrap:wrap; }
.rl-actf { font-family:var(--mono,monospace); font-size:.68rem; letter-spacing:.04em; padding:6px 11px; border-radius:8px; cursor:pointer; border:1px solid var(--border-light,#3f3f46); background:transparent; color:var(--text-muted,#a1a1aa); }
.rl-actf.on { background:var(--bg-card-hover,#1b1b1f); color:var(--text,#fafafa); border-color:var(--text-muted,#a1a1aa); }
.rl-actf:hover { color:var(--text,#fafafa); }
.rl-actcopy { margin-left:auto; display:inline-flex; align-items:center; gap:7px; font-size:.8rem; font-weight:600; padding:8px 14px; border-radius:9px; cursor:pointer; border:1px solid var(--accent,#c8ff00); background:var(--accent,#c8ff00); color:#0a0a0a; }
.rl-actcopy svg { width:14px; height:14px; }
.rl-actlist { display:flex; flex-direction:column; gap:9px; }
.rl-act { display:grid; grid-template-columns:auto 24px 1fr auto; gap:13px; align-items:start; background:var(--bg-card,#141416); border:1px solid var(--border,#27272a); border-radius:12px; padding:14px 16px; }
.rl-act:hover { border-color:var(--border-light,#3f3f46); }
.rl-act.is-done { opacity:.55; }
.rl-act.is-done .rl-act__title { text-decoration:line-through; }
.rl-act__chk { width:20px; height:20px; border-radius:6px; border:1.5px solid var(--border-light,#3f3f46); background:transparent; cursor:pointer; margin-top:1px; display:grid; place-items:center; flex:none; padding:0; }
.rl-act__chk.on { background:var(--accent,#c8ff00); border-color:var(--accent,#c8ff00); }
.rl-act__chk svg { width:12px; height:12px; opacity:0; }
.rl-act__chk.on svg { opacity:1; }
.rl-act__rank { font-family:var(--mono,monospace); font-size:.95rem; color:var(--text-faint,#71717a); text-align:center; margin-top:1px; }
.rl-act__title { font-weight:600; font-size:.93rem; letter-spacing:-.01em; }
.rl-act__why { font-size:.82rem; color:var(--text-muted,#a1a1aa); margin-top:4px; line-height:1.5; }
.rl-act__tags { display:flex; gap:7px; margin-top:9px; flex-wrap:wrap; }
.rl-act__tag { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.04em; padding:3px 8px; border-radius:6px; border:1px solid var(--border-light,#3f3f46); color:var(--text-muted,#a1a1aa); text-transform:uppercase; }
.rl-act__tag--l { color:var(--accent,#c8ff00); border-color:rgba(200,255,0,.3); background:rgba(200,255,0,.1); }
.rl-act__open { color:var(--text-muted,#a1a1aa); text-decoration:none; font-size:1.15rem; padding:2px 6px; align-self:center; }
.rl-act__open:hover { color:var(--accent,#c8ff00); }
.rl-toast { position:fixed; bottom:24px; left:50%; transform:translateX(-50%) translateY(16px); background:var(--accent,#c8ff00); color:#0a0a0a; font-weight:600; font-size:.85rem; padding:11px 20px; border-radius:11px; opacity:0; transition:.22s; pointer-events:none; z-index:120; box-shadow:0 10px 40px -10px rgba(200,255,0,.55); }
.rl-toast.show { opacity:1; transform:translateX(-50%) translateY(0); }

/* ═══════════════════════════════════════════════════════════════════════════
   CRAWL HUB — ported design
   ──────────────────────────────────────────────────────────────────────────
   The approved crawl-hub mockup, ported verbatim. Everything here is prefixed
   `hub-` and scoped under `.rl-hub`: the mockup's own class names (.hero,
   .panel, .stat, .badge, .chip, .track, .find, .open, .btn, .team …) collide
   head-on with main.css and account.css, and a bare `.stat` rule would repaint
   half the account. The prefix is the only change made to the design.

   Design tokens map onto the live system's variables, with the mockup's
   literals as fallbacks, so the hub inherits any future palette move.
   ══════════════════════════════════════════════════════════════════════════ */
.rl-hub {
  --hub-card:   var(--bg-card, #141416);
  --hub-card-2: var(--bg-card-hover, #1b1b1f);
  --hub-card-3: #212127;
  --hub-bd:     var(--border, #27272a);
  --hub-bd-lt:  var(--border-light, #3f3f46);
  --hub-text:   var(--text, #fafafa);
  --hub-text-2: var(--text-secondary, #e4e4e7);
  --hub-muted:  var(--text-muted, #a1a1aa);
  --hub-faint:  var(--text-faint, #71717a);
  --hub-accent: var(--accent, #c8ff00);
  --hub-accent-dim: rgba(200,255,0,.14);

  /* Severity ramp — deliberately not the accent, so "needs attention" never
     renders in the same colour as "done". */
  --hub-sev-high:#fb923c; --hub-sev-med:#fbbf24; --hub-sev-low:#71717a;
  --hub-info:#7dd3fc; --hub-info-dim:rgba(125,211,252,.12);

  /* Track geometry as tokens so the rail's vertical position always follows
     the dot size — changing one on mobile can't desync the other. */
  --hub-dot:28px; --hub-track-pt:1.85rem;

  --hub-r:14px; --hub-r-sm:9px;
}
.rl-hub .hub-num { font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .rl-hub *, .rl-hub *::before, .rl-hub *::after { animation:none !important; transition:none !important; }
}

/* ── needs-you banner ────────────────────────────────────────────────────
   One place that answers "is anything waiting on me?" — the question a
   returning customer actually arrives with. A single row, not a card: this is
   a signpost, and the explaining is already done by the stage explainer and
   the section itself. Two states, and the quiet one still earns its space by
   naming what's next. */
.hub-needs { display:flex; align-items:center; gap:.7rem; flex-wrap:wrap; border-radius:10px; padding:.5rem .75rem; margin-top:1.15rem; }
.hub-needs--act { background:linear-gradient(100deg, rgba(200,255,0,.13), rgba(200,255,0,.045)); border:1px solid rgba(200,255,0,.4); }
.hub-needs--idle { background:var(--hub-card); border:1px solid var(--hub-bd); }
.hub-needs__i { width:22px; height:22px; border-radius:6px; display:grid; place-items:center; font-size:.72rem; flex:none; }
.hub-needs--act .hub-needs__i { background:var(--hub-accent); color:#0a0a0a; }
.hub-needs--idle .hub-needs__i { background:var(--hub-card-2); border:1px solid var(--hub-bd-lt); color:var(--hub-faint); }
.hub-needs__k { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.12em; text-transform:uppercase;
  padding:.16rem .42rem; border-radius:4px; white-space:nowrap; flex:none; }
.hub-needs--act .hub-needs__k { color:var(--hub-accent); background:var(--hub-accent-dim); }
.hub-needs--idle .hub-needs__k { color:var(--hub-faint); background:var(--hub-card-2); }
.hub-needs__t { font-size:.86rem; color:var(--hub-text); font-weight:600; letter-spacing:-.01em; }
.hub-needs--idle .hub-needs__t { font-weight:500; color:var(--hub-text-2); }
.hub-needs__s { font-size:.82rem; color:var(--hub-muted); }
.hub-needs__cta { margin-left:auto; display:flex; align-items:center; gap:.4rem; text-decoration:none; white-space:nowrap;
  background:var(--hub-accent); color:#0a0a0a; font-weight:600; font-size:.8rem; border-radius:7px; padding:.36rem .8rem; }
.hub-needs__cta:hover { background:#d9ff3d; }
.hub-needs__eta { margin-left:auto; font-family:var(--mono,monospace); font-size:.68rem; color:var(--hub-faint); white-space:nowrap; }
@media (max-width:700px) {
  .hub-needs__s { flex-basis:100%; font-size:.78rem; }
  .hub-needs__cta, .hub-needs__eta { margin-left:0; }
}

/* ── dateline ──────────────────────────────────────────────────────────── */
.hub-dates { display:flex; flex-wrap:wrap; gap:.35rem .5rem; align-items:center;
  font-family:var(--mono,monospace); font-size:.68rem; color:var(--hub-faint); padding:.85rem .2rem 0; }
.hub-dates__i { display:flex; align-items:center; gap:.35rem; white-space:nowrap; }
.hub-dates__d { width:5px; height:5px; border-radius:50%; background:var(--hub-accent); flex:none; }
.hub-dates__i--now .hub-dates__d { background:var(--hub-info); }
.hub-dates__i--wait .hub-dates__d { background:var(--hub-bd-lt); }
.hub-dates__i b { color:var(--hub-text-2); font-weight:500; }
.hub-dates__i--wait b { color:var(--hub-faint); }
.hub-dates__arw { color:var(--hub-bd-lt); }

/* ── sticky mini-bar ─────────────────────────────────────────────────────
   Appears once the hero scrolls away. The page is long, so the track — already
   the page's navigation metaphor — comes with you. Its dots reflect the
   section you're scrolled into (scroll-spy), a different job from the hero
   explainer: that one shows what you deliberately picked. */
/* Parks directly under whatever chrome is pinned above it. That is NOT a
   constant: .site-nav is 64px and sticky at z-index 100, but for an operator
   the .rl-opbar-g strip sits above it and initOperatorBar() pushes the nav
   down by its height. Hardcoding 64px put the mini-bar *behind* the nav for
   every operator — present in the DOM, invisible on screen. The hub measures
   the nav's bottom edge into --hub-sticky-top instead. */
/* FIXED, not sticky. As a sticky element it stayed in flow and reserved its own
   39px at the top of the page even while translated out of sight — so an
   invisible bar was pushing the crawl itself down on every load. It only ever
   appears over the content on scroll, which is what fixed is for. left/right
   pin it across the viewport, so the inner row re-centres to the hub's width. */
.hub-mini { position:fixed; top:var(--hub-sticky-top, 64px); left:0; right:0; z-index:39;
  background:rgba(9,9,11,.92); backdrop-filter:blur(10px);
  border-bottom:1px solid var(--hub-bd); transform:translateY(-100%); opacity:0; pointer-events:none;
  transition:transform .22s ease, opacity .22s ease; }
/* Reading progress along the bar's foot — how far through the deliverables you
   are, on a page whose length depends on how much has been delivered. */
.hub-mini__prog { position:absolute; left:0; bottom:-1px; height:2px; width:0;
  background:var(--hub-accent); transition:width .1s linear; }
.hub-mini.is-on { transform:none; opacity:1; pointer-events:auto; }
/* Re-centres to the hub's column now that .hub-mini spans the viewport (fixed).
   The horizontal padding lives here, not on an earlier rule — this one is later
   in the file and its `padding` shorthand would reset it. */
.hub-mini__in { display:flex; align-items:center; gap:1rem;
  max-width:920px; margin:0 auto; padding:.6rem 1.5rem; }
@media (max-width:640px) { .hub-mini__in { padding:.6rem 1.1rem; } }
.hub-mini__id { display:flex; align-items:center; gap:.5rem; font-size:.85rem; font-weight:600; white-space:nowrap; }
.hub-mini__tile { width:22px; height:22px; border-radius:5px; background:var(--hub-accent); color:#0a0a0a;
  display:grid; place-items:center; font-size:.7rem; font-weight:700; }
.hub-mini__cyc { font-family:var(--mono,monospace); font-size:.62rem; color:var(--hub-faint); font-weight:400; }
.hub-mini__nav { display:flex; align-items:center; gap:.15rem; margin:0 auto; }
.hub-mdot { background:none; border:0; cursor:pointer; font:inherit; color:var(--hub-faint); font-size:.76rem;
  padding:.28rem .6rem; border-radius:6px; white-space:nowrap; display:flex; align-items:center; gap:.4rem; }
.hub-mdot:hover { color:var(--hub-text); background:var(--hub-card-2); }
.hub-mdot__d { width:7px; height:7px; border-radius:50%; background:var(--hub-bd-lt); flex:none; }
.hub-mdot.done .hub-mdot__d { background:var(--hub-accent); }
.hub-mdot.now .hub-mdot__d { background:var(--hub-info); }
.hub-mdot.is-view { color:var(--hub-text); background:var(--hub-card-2); }
.hub-mdot.is-view .hub-mdot__d { box-shadow:0 0 0 3px rgba(255,255,255,.09); }
/* Each stop carries its own headline figure, so the bar is a summary of the
   page and not just a set of labels. */
.hub-mdot__n { font-family:var(--mono,monospace); font-size:.66rem; color:var(--hub-faint); }
.hub-mdot.is-view .hub-mdot__n, .hub-mdot:hover .hub-mdot__n { color:var(--hub-accent); }
.hub-mini__r { display:flex; align-items:center; gap:.7rem; white-space:nowrap; }
.hub-mini__stat { font-family:var(--mono,monospace); font-size:.7rem; color:var(--hub-muted); }
@media (max-width:820px) {
  .rl-hub .hub-mini__nav .hub-mdot span:not(.hub-mdot__d) { display:none; }
  .hub-mdot { padding:.3rem .4rem; }
  /* …except the one you're looking at. Five anonymous dots tell you there are
     five places to go and nothing else; keeping the active label turns the row
     into a "you are here" as well as a jump list, for the width of one word.
     The figure (.hub-mdot__n) stays hidden — it's the label that navigates. */
  .rl-hub .hub-mini__nav .hub-mdot.is-view span:not(.hub-mdot__d):not(.hub-mdot__n) { display:inline; }
  .hub-mdot.is-view { padding:.3rem .55rem; }
}
@media (max-width:640px) { .hub-mini__stat, .hub-mini__cyc { display:none; } }

/* ── section deep-link + bulk expand ───────────────────────────────────── */
.hub-lnk { background:none; border:1px solid transparent; color:var(--hub-faint); width:24px; height:24px;
  border-radius:6px; cursor:pointer; display:grid; place-items:center; opacity:0; transition:opacity .15s ease; padding:0; }
.hub-sec__head:hover .hub-lnk, .hub-lnk:focus-visible { opacity:1; }
.hub-lnk:hover { color:var(--hub-accent); border-color:var(--hub-bd-lt); }
.hub-lnk.copied { opacity:1; color:var(--hub-accent); border-color:var(--hub-accent); }

.hub-dirbar { display:flex; align-items:center; gap:.6rem; justify-content:flex-end; margin:1.4rem .2rem -.35rem; }
.hub-dirbar__b { background:none; border:1px solid var(--hub-bd-lt); color:var(--hub-muted); font:inherit;
  font-size:.75rem; border-radius:7px; padding:.28rem .65rem; cursor:pointer; }
.hub-dirbar__b:hover { color:var(--hub-accent); border-color:var(--hub-accent); }

/* ── hero ──────────────────────────────────────────────────────────────── */
.hub-hero { background:var(--hub-card); border:1px solid var(--hub-bd); border-radius:var(--hub-r); margin-top:.9rem; overflow:hidden; }
.hub-hero__top { display:grid; grid-template-columns:1fr auto; gap:1.5rem 2rem; align-items:center; padding:1.5rem 1.5rem 1.3rem; }
@media (max-width:760px) { .hub-hero__top { grid-template-columns:1fr; } }

/* min-width:0 on BOTH: a grid/flex item defaults to min-width:auto and refuses
   to shrink below its content, so a long crawl name (or the shared-with-you
   chip's owner email) pushed .hub-ident past its grid track and .hub-hero's
   overflow:hidden silently clipped it on a phone. */
.hub-ident { display:flex; gap:1rem; align-items:center; min-width:0; }
.hub-ident > div { min-width:0; }
.hub-tile { width:56px; height:56px; flex:none; border-radius:var(--hub-r-sm);
  background:linear-gradient(145deg,var(--hub-accent),#a3d100); color:#0a0a0a; display:grid; place-items:center;
  font-weight:700; font-size:1.45rem; letter-spacing:-.03em; }
.rl-hub .hub-ident h1 { margin:0; font-size:clamp(1.45rem,3.2vw,1.95rem); letter-spacing:-.025em; line-height:1.1; }
.hub-ident__row { display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; margin-top:.35rem; }
.hub-host { color:var(--hub-muted); font-size:.85rem; }
.hub-idcode { font-family:var(--mono,monospace); font-size:.67rem; color:var(--hub-faint); background:var(--hub-card-2);
  border:1px solid var(--hub-bd); padding:.16rem .45rem; border-radius:5px; }
.hub-cycle { font-family:var(--mono,monospace); font-size:.62rem; letter-spacing:.09em; text-transform:uppercase;
  color:var(--hub-accent); background:var(--hub-accent-dim); border:1px solid rgba(200,255,0,.3); padding:.2rem .5rem; border-radius:5px; }

/* "Shared with you by <owner> · read-only". A viewer whose only crawl is a
   shared one is redirected here from Home, so this page has to answer "whose
   crawl am I looking at?" without a hover. Cool blue, deliberately NOT the lime
   accent — accent means "yours" everywhere else in the account. min-width:0 lets
   a long owner email ellipsize instead of widening the header on mobile. */
.hub-shared { display:flex; align-items:center; gap:.4rem; margin-top:.5rem; max-width:100%; min-width:0; width:fit-content;
  font-size:.75rem; color:#bae6fd; background:rgba(125,211,252,.1); border:1px solid rgba(125,211,252,.28);
  padding:.24rem .55rem; border-radius:6px; }
/* The owner's email is the only unbounded part, so it's the only part allowed to
   ellipsize — "Shared with you by" and "· read-only" always stay legible. */
.hub-shared b { font-weight:600; color:#e0f2fe; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; flex:0 1 auto; }
.hub-shared__k, .hub-shared__ro { white-space:nowrap; flex:none; }
/* A tag, not a trailing "· read-only" clause: when the chip wraps on a phone
   this lands on its own line, and a lone leading "·" reads like a typo where a
   small caps tag reads like a label. */
.hub-shared__ro { font-family:var(--mono,monospace); font-size:.58rem; letter-spacing:.09em; text-transform:uppercase;
  color:#7dd3fc; border:1px solid rgba(125,211,252,.35); border-radius:4px; padding:.1rem .3rem; }
/* On a phone all four parts on one line squeezed the email down to "koli…" —
   the one part a reader actually needs. Wrapping gives it a full line. */
@media (max-width:760px) { .hub-shared { flex-wrap:wrap; row-gap:.22rem; } }
.hub-shared svg { flex:none; opacity:.85; }
@media print { .hub-shared { display:none; } }

/* live readout — carries crawl state now, the % once it exists */
.hub-live { min-width:250px; }
@media (max-width:760px) { .hub-live { min-width:0; } }
.hub-live__k { font-family:var(--mono,monospace); font-size:.62rem; letter-spacing:.13em; text-transform:uppercase; color:var(--hub-faint); }
.hub-live__v { font-size:1.55rem; font-weight:600; letter-spacing:-.02em; line-height:1.2; margin-top:.25rem;
  display:flex; align-items:baseline; gap:.45rem; }
.hub-live__v .big { font-size:2.4rem; letter-spacing:-.045em; }
.hub-live__v .pct { font-size:1.3rem; color:var(--hub-muted); font-weight:500; }
.hub-live__of { color:var(--hub-faint); font-size:.95rem; font-weight:400; }
.hub-live__bar { height:5px; border-radius:3px; background:var(--hub-card-3); margin-top:.6rem; overflow:hidden; }
.hub-live__fill { height:100%; border-radius:3px; background:linear-gradient(90deg,var(--hub-info),#38bdf8); animation:hub-pulse 2.4s ease-in-out infinite; }
.hub-live__fill--done { background:var(--hub-accent); animation:none; }
@keyframes hub-pulse { 0%,100% { opacity:1 } 50% { opacity:.55 } }
.hub-live__sub { color:var(--hub-muted); font-size:.79rem; margin-top:.45rem; }

/* ── stage track ─────────────────────────────────────────────────────────
   One continuous rail with the dots sitting on it. The rail is a single
   element spanning first-dot-centre to last-dot-centre, NOT a pseudo-element
   per stop — per-item segments get clipped by anything painted over a stop.
   Nothing draws a background across the rail: the hover/active affordance
   lives on the label, below it. */
.hub-track { position:relative; display:grid; grid-template-columns:repeat(5,1fr);
  padding:var(--hub-track-pt) 1.5rem 1.5rem; }   /* top pad reserves the pin row */
.hub-rail, .hub-rail__fill, .hub-rail__now {
  position:absolute; top:calc(var(--hub-track-pt) + (var(--hub-dot) / 2));   /* dot centre */
  height:2px; border-radius:2px; }
.hub-rail { left:10%; right:10%; background:var(--hub-bd-lt); }
.hub-rail__fill { left:10%; background:var(--hub-accent); }
.hub-rail__now { background:linear-gradient(90deg,var(--hub-accent),var(--hub-info)); animation:hub-flow 2.4s ease-in-out infinite; }
@keyframes hub-flow { 0%,100% { opacity:.45 } 50% { opacity:1 } }

.hub-stop { position:relative; z-index:1; display:grid; grid-template-rows:var(--hub-dot) auto; justify-items:center;
  gap:.55rem; background:none; border:0; padding:0; cursor:pointer; font:inherit; color:inherit; }
.hub-dot { width:var(--hub-dot); height:var(--hub-dot); border-radius:50%; display:grid; place-items:center;
  font-family:var(--mono,monospace); font-size:.7rem; font-weight:500; border:1.5px solid var(--hub-bd-lt);
  background:var(--hub-card); color:var(--hub-faint); box-shadow:0 0 0 4px var(--hub-card);  /* mask the rail behind the dot */
  transition:transform .18s ease, border-color .18s ease; }
.hub-stop:hover .hub-dot { transform:translateY(-2px); border-color:var(--hub-muted); }
.hub-stop.done .hub-dot { background:var(--hub-accent); border-color:var(--hub-accent); color:#0a0a0a; }
.hub-stop.now .hub-dot { border-color:var(--hub-info); color:var(--hub-info); background:var(--hub-card);
  box-shadow:0 0 0 4px var(--hub-card), 0 0 0 7px var(--hub-info-dim); }
.hub-stop.you .hub-dot { border-color:var(--hub-accent); color:var(--hub-accent);
  box-shadow:0 0 0 4px var(--hub-card), 0 0 0 7px var(--hub-accent-dim); }
.hub-stop__l { font-size:.76rem; color:var(--hub-faint); text-align:center; line-height:1.25; padding:.22rem .6rem;
  border-radius:6px; border:1px solid transparent; transition:color .15s ease, background .15s ease, border-color .15s ease; }
.hub-stop.done .hub-stop__l { color:var(--hub-text-2); }
.hub-stop.now .hub-stop__l, .hub-stop.you .hub-stop__l { color:var(--hub-text); font-weight:600; }
.hub-stop:hover .hub-stop__l { background:var(--hub-card-2); color:var(--hub-text); }
.hub-stop[aria-expanded="true"] .hub-stop__l { background:var(--hub-card-2); border-color:var(--hub-bd-lt); color:var(--hub-text); }
.hub-stop:focus-visible { outline:none; }
.hub-stop:focus-visible .hub-stop__l { outline:2px solid var(--hub-accent); outline-offset:2px; }

/* Pin sits in the track's reserved top padding, above the dot row, so it can
   never touch the dot, the rail, or the label. */
.hub-pin { position:absolute; top:-22px; left:50%; transform:translateX(-50%); display:flex; flex-direction:column;
  align-items:center; gap:2px; font-size:.54rem; letter-spacing:.1em; font-family:var(--mono,monospace);
  color:var(--hub-info); text-transform:uppercase; white-space:nowrap; }
.hub-pin::after { content:""; width:0; height:0; border-left:4px solid transparent; border-right:4px solid transparent;
  border-top:5px solid var(--hub-info); }
.hub-stop.you .hub-pin { color:var(--hub-accent); }
.hub-stop.you .hub-pin::after { border-top-color:var(--hub-accent); }

/* ── the explainer panel — the point of the hero ───────────────────────── */
.hub-peek { border-top:1px solid var(--hub-bd); background:var(--hub-card-2); padding:1.25rem 1.5rem 1.35rem;
  display:grid; grid-template-columns:1fr auto; gap:1.25rem 2rem; align-items:center; }
@media (max-width:760px) { .hub-peek { grid-template-columns:1fr; } }
.hub-peek__k { font-family:var(--mono,monospace); font-size:.61rem; letter-spacing:.12em; text-transform:uppercase;
  display:flex; align-items:center; gap:.45rem; }
.hub-peek__k.is-done { color:var(--hub-accent); }
.hub-peek__k.is-now { color:var(--hub-info); }
.hub-peek__k.is-next { color:var(--hub-faint); }
.rl-hub .hub-peek h2 { margin:.4rem 0 .35rem; font-size:1.12rem; letter-spacing:-.015em; font-weight:600; }
.rl-hub .hub-peek p { margin:0; color:var(--hub-muted); font-size:.88rem; max-width:64ch; }
.hub-peek__got { margin-top:.7rem; display:flex; flex-wrap:wrap; gap:.4rem; }
.hub-peek__cta { display:flex; flex-direction:column; gap:.5rem; align-items:flex-start; }

.hub-kv { font-family:var(--mono,monospace); font-size:.7rem; color:var(--hub-text-2); background:var(--hub-card-3);
  border:1px solid var(--hub-bd-lt); padding:.25rem .55rem; border-radius:5px; }
.hub-kv b { color:var(--hub-accent); font-weight:600; }
.hub-kv.dim b { color:var(--hub-faint); }

.hub-btn { font-size:.84rem; text-decoration:none; white-space:nowrap; border-radius:8px; padding:.5rem .9rem;
  border:1px solid var(--hub-bd-lt); background:var(--hub-card-3); color:var(--hub-text-2); }
.hub-btn:hover { border-color:var(--hub-accent); color:var(--hub-accent); }
.hub-btn--go { background:var(--hub-accent); color:#0a0a0a; border-color:var(--hub-accent); font-weight:600; }
.hub-btn--go:hover { background:#d9ff3d; color:#0a0a0a; }
.hub-eta { font-family:var(--mono,monospace); font-size:.7rem; color:var(--hub-faint); }

.hub-meta { display:flex; gap:1.1rem; flex-wrap:wrap; align-items:center; color:var(--hub-faint); font-size:.78rem; padding:1rem .2rem 0; }
.hub-meta .sep { width:3px; height:3px; border-radius:50%; background:var(--hub-bd-lt); }
.hub-meta__r { margin-left:auto; display:flex; align-items:center; gap:.7rem; }

/* ── team ──────────────────────────────────────────────────────────────── */
.hub-team { display:flex; align-items:center; gap:.5rem; }
/* The whole cluster is the target now — avatars included. Button reset, so it
   still reads as the meta row it lives in. */
.hub-team--btn { background:none; border:0; padding:0; font:inherit; cursor:pointer; }
.hub-team--btn:hover .hub-share--ro { border-color:rgba(125,211,252,.5); color:#bae6fd; }
.hub-team--btn:focus-visible { outline:2px solid var(--hub-accent); outline-offset:3px; border-radius:8px; }
.hub-avs { display:flex; }
.hub-av { width:25px; height:25px; border-radius:50%; display:grid; place-items:center; font-size:.66rem; font-weight:600;
  color:#0a0a0a; border:2px solid var(--bg,#09090b); margin-left:-7px; }
.hub-av:first-child { margin-left:0; }
.hub-av--wait { background:var(--hub-card-3); color:var(--hub-muted); border-color:var(--bg,#09090b); font-weight:500; }
.hub-share { display:inline-flex; align-items:center; gap:.35rem; font-size:.78rem; color:var(--hub-text-2);
  background:var(--hub-card-2); border:1px solid var(--hub-bd-lt); border-radius:7px; padding:.3rem .65rem;
  cursor:pointer; font-family:inherit; }
.hub-share:hover { border-color:var(--hub-accent); color:var(--hub-accent); }
/* A viewer's version reveals the roster instead of an invite form, so it hovers
   blue (informational) rather than lime (an action that changes something). */
.hub-share--ro:hover { border-color:rgba(125,211,252,.5); color:#bae6fd; }
/* The hero's copy — the primary Share affordance, sitting beside the crawl's
   name where the decision to share is actually made. Sized as a real touch
   target; the meta-row twin below it stays a small secondary link. */
.hub-share--top { font-size:.85rem; font-weight:500; padding:.55rem .9rem; border-radius:9px;
  min-height:44px; color:var(--hub-text); border-color:var(--hub-bd-lt); }
.hub-share--top svg { width:14px; height:14px; }
.hub-hero__acts { display:flex; align-items:center; gap:.7rem; flex-wrap:wrap; justify-content:flex-end; }
@media (max-width:760px) {
  /* The hero stacks here, so without an explicit order Share fell BELOW the
     whole live-status block — title, stage, progress bar, caption — which is
     most of a phone screen and the opposite of "toward the top". */
  .hub-hero__acts { justify-content:flex-start; flex-direction:column; align-items:stretch; gap:.85rem; }
  .hub-share--top { order:-1; width:100%; justify-content:center; }
}

/* Share panel — /api/shares is complete (list / create / revoke); this is its UI. */
.hub-sharebox { margin:.8rem 0 0; background:var(--hub-card); border:1px solid var(--hub-bd-lt); border-radius:var(--hub-r-sm); padding:1rem; }
.hub-sharebox[hidden] { display:none; }
.hub-sharebox__k { font-family:var(--mono,monospace); font-size:.62rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--hub-faint); margin-bottom:.7rem; }
.hub-sharerow { display:flex; align-items:center; gap:.6rem; padding:.4rem 0; font-size:.84rem; color:var(--hub-text-2);
  border-top:1px solid var(--hub-bd); }
.hub-sharerow:first-of-type { border-top:none; }
.hub-sharerow__tag { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--hub-faint); background:var(--hub-card-2); border-radius:4px; padding:.14rem .4rem; }
.hub-sharerow__x { margin-left:auto; background:none; border:1px solid var(--hub-bd-lt); color:var(--hub-muted);
  font:inherit; font-size:.72rem; border-radius:6px; padding:.2rem .55rem; cursor:pointer; }
.hub-sharerow__x:hover { color:#f87171; border-color:#f87171; }
.hub-shareform { display:flex; gap:.5rem; margin-top:.8rem; flex-wrap:wrap; }
.hub-shareform input { flex:1; min-width:200px; background:var(--hub-card-2); border:1px solid var(--hub-bd-lt);
  color:var(--hub-text); border-radius:7px; padding:.45rem .7rem; font:inherit; font-size:.84rem; }
.hub-shareform button { background:var(--hub-accent); color:#0a0a0a; border:none; border-radius:7px; padding:.45rem .9rem;
  font:inherit; font-size:.82rem; font-weight:600; cursor:pointer; }
.hub-sharemsg { font-size:.78rem; margin-top:.6rem; color:var(--hub-muted); }
.hub-sharemsg.err { color:#f87171; }

/* ── feedback guidance ─────────────────────────────────────────────────── */
.hub-fb { display:grid; grid-template-columns:auto 1fr auto; gap:.8rem; align-items:center;
  background:rgba(200,255,0,.05); border:1px solid rgba(200,255,0,.22); border-radius:var(--hub-r-sm); padding:.7rem .9rem; }
.hub-fb__i { width:26px; height:26px; border-radius:6px; display:grid; place-items:center;
  background:var(--hub-accent-dim); color:var(--hub-accent); font-size:.85rem; }
.hub-fb__t { font-size:.83rem; color:var(--hub-text-2); }
.hub-fb__t b { color:var(--hub-text); font-weight:600; }
.hub-fb__go { font-size:.78rem; text-decoration:none; white-space:nowrap; color:#0a0a0a; background:var(--hub-accent);
  border-radius:7px; padding:.34rem .7rem; font-weight:600; }
.hub-fb__go:hover { background:#d9ff3d; }
@media (max-width:620px) { .hub-fb { grid-template-columns:auto 1fr; } .hub-fb__go { grid-column:2; justify-self:start; } }

/* in-viewer coach mark */
.hub-coach { background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm);
  padding:.9rem 1rem; display:flex; flex-direction:column; gap:.6rem; }
.hub-coach__q { display:flex; align-items:flex-start; gap:.6rem; font-size:.85rem; color:var(--hub-text-2);
  background:var(--hub-card); border:1px solid var(--hub-bd-lt); border-radius:7px; padding:.6rem .7rem; position:relative; }
.hub-coach__pen { width:21px; height:21px; flex:none; border-radius:5px; display:grid; place-items:center;
  background:var(--hub-accent); color:#0a0a0a; font-size:.72rem; }
.hub-coach__bub { align-self:flex-start; margin-left:2.2rem; position:relative; background:var(--hub-card-3);
  border:1px solid var(--hub-accent); border-radius:8px; padding:.55rem .75rem; font-size:.79rem; color:var(--hub-text-2); max-width:44ch; }
.hub-coach__bub::before { content:""; position:absolute; top:-6px; left:16px; width:9px; height:9px;
  background:var(--hub-card-3); border-left:1px solid var(--hub-accent); border-top:1px solid var(--hub-accent); transform:rotate(45deg); }

/* ── export ────────────────────────────────────────────────────────────── */
.hub-exp { display:grid; grid-template-columns:auto 1fr auto; gap:1.2rem 1.6rem; align-items:center; }
@media (max-width:900px) { .hub-exp { grid-template-columns:1fr; justify-items:start; } }
.hub-exp__list { display:flex; flex-direction:column; gap:.35rem; margin-top:.75rem; }
.hub-exp__row { display:grid; grid-template-columns:auto 1fr auto; gap:.7rem; align-items:center; font-size:.83rem; color:var(--hub-text-2); }
.hub-tick { width:16px; height:16px; border-radius:4px; display:grid; place-items:center; font-size:.65rem;
  background:var(--hub-accent-dim); color:var(--hub-accent); border:1px solid rgba(200,255,0,.3); }
.hub-tick--wait { background:var(--hub-card-3); color:var(--hub-faint); border-color:var(--hub-bd-lt); }
.hub-exp__note { font-family:var(--mono,monospace); font-size:.66rem; color:var(--hub-faint); }
.hub-exp__cta { display:flex; flex-direction:column; gap:.5rem; align-items:stretch; min-width:210px; }
@media (max-width:720px) { .hub-exp__cta { min-width:0; } }
.hub-dl { display:flex; align-items:center; justify-content:center; gap:.45rem; font-size:.86rem; font-weight:600;
  text-decoration:none; background:var(--hub-accent); color:#0a0a0a; border-radius:8px; padding:.6rem 1rem; }
.hub-dl:hover { background:#d9ff3d; }
.hub-dl--ghost { background:var(--hub-card-2); color:var(--hub-text-2); border:1px solid var(--hub-bd-lt); font-weight:500; }
.hub-dl--ghost:hover { border-color:var(--hub-accent); color:var(--hub-accent); background:var(--hub-card-2); }

/* ── report cover ────────────────────────────────────────────────────────
   The PDF is light while the account is dark: it's printed, forwarded and read
   outside the product. Shown here at ~40% of a US Letter page. */
.hub-cover { width:250px; aspect-ratio:8.5 / 11; flex:none; background:#faf9f6; color:#18181b; border-radius:4px;
  border:1px solid var(--hub-bd-lt); box-shadow:0 10px 34px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.4);
  padding:20px 19px 17px; display:flex; flex-direction:column; font-size:7px; line-height:1.5; }
.hub-cover__brand { display:flex; align-items:center; gap:4px; font-size:7.5px; font-weight:700; letter-spacing:-.01em; color:#18181b; }
.hub-cover__rule { height:2px; background:#c8ff00; margin:11px 0 0; border-radius:2px; }
.hub-cover__eyebrow { font-family:var(--mono,monospace); font-size:5.6px; letter-spacing:.16em; text-transform:uppercase; color:#7a7a85; margin-top:13px; }
.hub-cover__client { font-size:25px; font-weight:700; letter-spacing:-.035em; line-height:1.02; margin-top:5px; color:#0d0d0f; }
.hub-cover__sub { font-size:8px; color:#52525b; margin-top:4px; letter-spacing:-.01em; }
.hub-cover__mid { margin-top:auto; }
.hub-cover__num { display:flex; align-items:baseline; gap:4px; }
.hub-cover__num b { font-size:31px; font-weight:700; letter-spacing:-.045em; color:#0d0d0f; font-variant-numeric:tabular-nums; }
.hub-cover__num span { font-size:6.5px; color:#7a7a85; font-family:var(--mono,monospace); letter-spacing:.1em; text-transform:uppercase; }
/* The foundation edition's cover carries a claim where the report carries the
   visibility figure. At facsimile scale it is unreadable as prose either way,
   so it is set to occupy the numeral's optical weight — the card is a picture of
   the document, and the picture has to have the right shape. */
.hub-cover__claim { font-size:9px; line-height:1.3; font-weight:600; color:#0d0d0f;
  letter-spacing:-.01em; border-left:1.5px solid #c8ff00; padding-left:5px; max-width:105px; }
.hub-cover__toc { margin-top:12px; padding-top:9px; border-top:1px solid #e2e1dc; display:flex; flex-direction:column; gap:3.5px; }
.hub-cover__toc div { display:flex; justify-content:space-between; color:#3f3f46; font-size:6.4px; }
.hub-cover__toc .p { color:#a1a1aa; font-family:var(--mono,monospace); }
.hub-cover__foot { margin-top:11px; padding-top:8px; border-top:1px solid #e2e1dc; display:flex; justify-content:space-between;
  color:#8a8a93; font-size:5.8px; font-family:var(--mono,monospace); letter-spacing:.05em; }
.hub-cover__wrap { display:flex; flex-direction:column; align-items:center; gap:.55rem; }
.hub-cover__cap { font-family:var(--mono,monospace); font-size:.63rem; color:var(--hub-faint); letter-spacing:.06em; }

/* The shared readers (deliverable.css) take their palette from the host page.
   Mapping the hub's tokens here is the ONLY styling the hub does to them — the
   components themselves are identical to the ones the report mounts. */
.rl-hub .dv {
  --dvx-panel:var(--hub-card); --dvx-panel-2:var(--hub-card-2); --dvx-rule:var(--hub-bd);
  --dvx-rule-2:var(--hub-bd-lt); --dvx-text:var(--hub-text); --dvx-text-2:var(--hub-text-2);
  --dvx-muted:var(--hub-muted); --dvx-faint:var(--hub-faint); --dvx-accent:var(--hub-accent);
  --dvx-accent-dim:var(--hub-accent-dim); --dvx-high:var(--hub-sev-high);
  --dvx-med:var(--hub-sev-med); --dvx-low:var(--hub-sev-low);
}

/* ── deliverable sections ──────────────────────────────────────────────── */
.hub-dir { display:flex; flex-direction:column; gap:1rem; margin-top:1.5rem; }
/* Sections are jumped to (mini-bar dots, #sec- links, a hash on load) and every
   one of those lands via scrollIntoView({block:"start"}) — which parks the head
   underneath the fixed top nav plus the sticky mini-bar, so you arrive mid-card
   with no sign you moved. --hub-sticky-top is the nav's measured bottom edge
   (set in crawl/index.html); +52px clears the mini-bar. Same formula the
   booklet and deliverable readers use. */
.hub-sec { background:var(--hub-card); border:1px solid var(--hub-bd); border-radius:var(--hub-r); overflow:hidden;
  scroll-margin-top:calc(var(--hub-sticky-top, 64px) + 52px); }
.hub-sec.is-now { border-color:rgba(125,211,252,.4); box-shadow:0 0 0 1px rgba(125,211,252,.12); }
.hub-sec__head { display:grid; grid-template-columns:auto 1fr auto; gap:1rem; align-items:center; padding:1.15rem 1.3rem; cursor:pointer; }
.hub-sec__n { font-family:var(--mono,monospace); font-size:.72rem; color:var(--hub-faint); border:1px solid var(--hub-bd);
  border-radius:5px; padding:.22rem .45rem; }
.hub-sec__t { display:flex; flex-direction:column; gap:.15rem; min-width:0; }
.hub-sec__eyebrow { font-family:var(--mono,monospace); font-size:.61rem; letter-spacing:.11em; text-transform:uppercase; color:var(--hub-faint); }
.rl-hub .hub-sec__t h2 { margin:0; font-size:1.05rem; letter-spacing:-.015em; font-weight:600; }
.hub-sec__r { display:flex; align-items:center; gap:.7rem; flex-wrap:wrap; justify-content:flex-end; }

/* ── collapse ────────────────────────────────────────────────────────────
   Only the current stage is open on a first visit; the rest collapse to a
   header that still carries its badge and a one-line summary, so collapsing
   hides bulk without hiding value. Open state persists per crawl. */
.hub-sec__toggle { background:var(--hub-card-2); border:1px solid var(--hub-bd-lt); color:var(--hub-muted);
  width:26px; height:26px; border-radius:6px; cursor:pointer; flex:none; display:grid; place-items:center;
  font-size:.7rem; line-height:1; padding:0; transition:transform .2s ease, color .15s ease, border-color .15s ease; }
.hub-sec__toggle:hover { color:var(--hub-accent); border-color:var(--hub-accent); }
.hub-sec.is-open .hub-sec__toggle { transform:rotate(180deg); }
.hub-sec__head:hover .hub-sec__toggle { color:var(--hub-accent); }

/* summary line, shown only while collapsed. Pinned to row 2 / col 2 explicitly:
   auto-placement alone would push the badge+toggle group down a row, because
   the summary precedes it in the DOM. */
.hub-sec__sum { grid-column:2 / 3; grid-row:2; font-size:.79rem; color:var(--hub-faint);
  display:flex; flex-wrap:wrap; gap:.5rem; align-items:center; margin-top:.15rem; }
.hub-sec.is-open .hub-sec__sum { display:none !important; }
.hub-sec__sum .sep { width:3px; height:3px; border-radius:50%; background:var(--hub-bd-lt); }
.hub-sec__sum .hot { color:var(--hub-sev-high); }

/* Collapse is expressed as :not(.is-open) — specificity (0,2,0) beats the bare
   `.hub-sec__body { display:flex }` rule below (0,1,0), so this can't be
   silently undone by source order. Writing it as `.hub-sec__body{display:none}`
   here did exactly that: the later rule won and nothing ever collapsed. */
.hub-sec:not(.is-open) .hub-sec__body { display:none; }
.hub-sec__body { padding:0 1.3rem 1.3rem; display:flex; flex-direction:column; gap:1rem; }

.hub-badge { font-family:var(--mono,monospace); font-size:.65rem; letter-spacing:.05em; padding:.24rem .55rem;
  border-radius:5px; white-space:nowrap; }
.hub-badge--done { background:var(--hub-accent-dim); color:var(--hub-accent); border:1px solid rgba(200,255,0,.3); }
.hub-badge--run { background:var(--hub-info-dim); color:var(--hub-info); border:1px solid rgba(125,211,252,.28); }
.hub-badge--wait { background:var(--hub-card-2); color:var(--hub-faint); border:1px solid var(--hub-bd-lt); }
.hub-badge--you { background:rgba(251,191,36,.12); color:var(--hub-sev-med); border:1px solid rgba(251,191,36,.32); }

.hub-open { font-size:.82rem; color:var(--hub-text-2); text-decoration:none; border:1px solid var(--hub-bd-lt);
  border-radius:7px; padding:.36rem .75rem; white-space:nowrap; background:var(--hub-card-2); }
.hub-open:hover { border-color:var(--hub-accent); color:var(--hub-accent); }
.hub-open[aria-disabled="true"] { opacity:.4; pointer-events:none; }
/* `.hub-op` is gone: operator controls no longer live in the customer's
   sections at all. See the operator rail (.rl-oprail) near the top of this
   file — putting one back here is the regression that comment describes. */

.rl-hub .hub-lede { font-size:.9rem; color:var(--hub-text-2); margin:0 0 .1rem; border-left:2px solid var(--hub-bd-lt);
  padding-left:.85rem; max-width:70ch; }
.rl-hub .hub-lede b { color:var(--hub-text); font-weight:600; }

/* The Voice-of-Customer line is a link, not a paragraph. It reads as body text on
   purpose — it belongs to the Foundations card rather than competing with the card's
   own CTA — so the accent border and the trailing "Read what buyers said →" are what
   say it is clickable. Both strengthen on hover; neither shouts when idle. */
.rl-hub a.hub-lede--link { display:block; text-decoration:none; transition:border-color .15s, background .15s; }
.rl-hub a.hub-lede--link:hover, .rl-hub a.hub-lede--link:focus-visible {
  border-left-color:var(--rl-accent,#c8ff00); background:rgba(200,255,0,.045); }
.rl-hub a.hub-lede--link:focus-visible { outline:2px solid var(--rl-accent,#c8ff00); outline-offset:3px; }
.hub-lede__go { display:inline-block; margin-left:.4rem; white-space:nowrap;
  color:var(--rl-accent,#c8ff00); font-weight:600; }
.rl-hub a.hub-lede--link:hover .hub-lede__go { text-decoration:underline; }

/* ── Section 01's doors (F3) ────────────────────────────────────────────────
   A count that opens. These replaced `.hub-stat` tiles, which were <div>s that
   looked exactly like this and did nothing — so the whole job of this block is
   to make "looks like a control" and "is a control" the same set. Hence a real
   <button>, a hover state, a caret that turns, and an open state that reads as
   connected to the panel it opened. */
.hub-doors { display:flex; flex-direction:column; gap:.6rem; }
.hub-doors__tiles { display:grid; grid-template-columns:repeat(auto-fit,minmax(118px,1fr)); gap:.6rem; }
.hub-door { display:flex; flex-direction:column; gap:.1rem; text-align:left; width:100%; cursor:pointer;
  background:var(--hub-card-2); border:1px solid var(--hub-bd-lt); border-radius:var(--hub-r-sm);
  padding:.7rem .8rem; color:inherit; font:inherit; transition:background .13s ease, border-color .13s ease; }
.hub-door:hover { background:var(--hub-card-3,var(--hub-card-2)); border-color:var(--hub-bd); }
.hub-door__k { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.1em; text-transform:uppercase; color:var(--hub-faint); }
.hub-door__k::after { content:" ▾"; color:var(--hub-faint); }
.hub-door[aria-expanded="true"] { background:var(--hub-accent-dim); border-color:var(--hub-accent); }
.hub-door[aria-expanded="true"] .hub-door__k::after { content:" ▴"; color:var(--hub-accent); }
.hub-door[aria-expanded="true"] .hub-door__v { color:var(--hub-accent); }
.hub-door__v { font-size:1.5rem; font-weight:600; letter-spacing:-.03em; margin-top:.15rem; color:var(--hub-text); }
.hub-door__s { font-size:.72rem; color:var(--hub-faint); }

.hub-dpanel { border:1px solid var(--hub-accent); border-radius:var(--hub-r-sm);
  background:var(--hub-card-2); overflow:hidden; }
.hub-dpanel[hidden] { display:none; }
.hub-dpanel:focus-visible { outline:2px solid var(--hub-accent); outline-offset:2px; }
.hub-dpanel__h { display:flex; flex-wrap:wrap; gap:.5rem 1rem; align-items:baseline; justify-content:space-between;
  padding:.7rem .95rem; border-bottom:1px solid var(--hub-bd-lt); background:var(--hub-card); }
.hub-dpanel__all { font-size:.8rem; font-weight:600; color:var(--hub-accent); text-decoration:none; white-space:nowrap; }
.hub-dpanel__all:hover { text-decoration:underline; }
.hub-prows { display:flex; flex-direction:column; }
.hub-prow { display:grid; grid-template-columns:1fr auto; gap:.2rem .7rem; align-items:baseline;
  padding:.65rem .95rem; border-bottom:1px solid var(--hub-bd-lt); }
.hub-prow:last-child { border-bottom:none; }
.hub-prow__t { font-size:.9rem; color:var(--hub-text); font-weight:550; }
.hub-prow__s { grid-column:1/-1; font-size:.78rem; color:var(--hub-faint); line-height:1.45; }
.hub-pill { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.09em; text-transform:uppercase;
  padding:.12rem .42rem; border-radius:4px; white-space:nowrap; border:1px solid var(--hub-bd-lt); color:var(--hub-text-2); }
.hub-pill--flag { color:var(--hub-sev-high); border-color:rgba(248,113,113,.4); }
.hub-pill--mid { color:var(--hub-sev-med); border-color:rgba(251,191,36,.36); }
.hub-pill--ok { color:var(--hub-accent); border-color:rgba(200,255,0,.32); }
@media (max-width:620px) { .hub-doors__tiles { grid-template-columns:repeat(2,1fr); } }

.hub-stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(118px,1fr)); gap:.6rem; }
.hub-stat { background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.7rem .8rem; }
.hub-stat__k { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.1em; text-transform:uppercase; color:var(--hub-faint); }
.hub-stat__v { font-size:1.5rem; font-weight:600; letter-spacing:-.03em; margin-top:.15rem; }
.hub-stat--hero .hub-stat__v { color:var(--hub-accent); }
.hub-stat__s { font-size:.72rem; color:var(--hub-faint); }

.hub-panel { background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.95rem 1rem; }
.hub-panel__k { font-family:var(--mono,monospace); font-size:.62rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--hub-faint); margin-bottom:.75rem; }
.hub-grid2 { display:grid; grid-template-columns:1fr 1fr; gap:.6rem; }
@media (max-width:760px) { .hub-grid2 { grid-template-columns:1fr; } }

/* gauges carry a plain-language read */
.hub-gauges { display:grid; grid-template-columns:repeat(auto-fit,minmax(238px,1fr)); gap:1rem 1.6rem; }
.hub-g__top { display:flex; justify-content:space-between; align-items:baseline; gap:.5rem; font-size:.82rem; }
.hub-g__v { font-family:var(--mono,monospace); font-size:.76rem; color:var(--hub-text-2); }
.hub-g__track { height:5px; border-radius:3px; background:var(--hub-card-3); margin-top:.4rem; overflow:hidden; }
.hub-g__fill { height:100%; border-radius:3px; }
.hub-g__read { font-size:.77rem; color:var(--hub-faint); margin-top:.35rem; line-height:1.4; }

.hub-finds { display:flex; flex-direction:column; gap:.4rem; }
.hub-find { display:grid; grid-template-columns:3px auto 1fr auto; gap:.8rem; align-items:center;
  background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.6rem .8rem .6rem 0; overflow:hidden; }
.hub-find__stripe { align-self:stretch; border-radius:3px 0 0 3px; }
.hub-find__sev { font-family:var(--mono,monospace); font-size:.57rem; letter-spacing:.1em; text-transform:uppercase;
  padding:.16rem .4rem; border-radius:4px; white-space:nowrap; }
.hub-find__t { font-size:.85rem; color:var(--hub-text-2); min-width:0; }
.hub-find__m { font-family:var(--mono,monospace); font-size:.66rem; color:var(--hub-faint); display:flex; gap:.55rem; white-space:nowrap; }
@media (max-width:640px) { .hub-find { grid-template-columns:3px auto 1fr; } .hub-find__m { display:none; } }
.hub-sev-critical, .hub-sev-high { color:var(--hub-sev-high); background:rgba(251,146,60,.13); }
.hub-sev-medium { color:var(--hub-sev-med); background:rgba(251,191,36,.12); }
.hub-sev-low { color:var(--hub-sev-low); background:rgba(113,113,122,.16); }
.hub-bg-critical, .hub-bg-high { background:var(--hub-sev-high); }
.hub-bg-medium { background:var(--hub-sev-med); }
.hub-bg-low { background:var(--hub-sev-low); }

.hub-chips { display:flex; flex-wrap:wrap; gap:.4rem; }
.hub-chip { font-size:.75rem; color:var(--hub-text-2); background:var(--hub-card-3); border:1px solid var(--hub-bd-lt);
  border-radius:20px; padding:.24rem .65rem; }
.hub-chip .n { font-family:var(--mono,monospace); font-size:.68rem; color:var(--hub-faint); margin-left:.3rem; }
/* A chip that is a link INTO the report — the cross-links (a feature an action
   moves, the action that answers a question) read as destinations, not labels. */
.hub-chip--go { text-decoration:none; white-space:nowrap; }
.hub-chip--go:hover { border-color:var(--hub-accent); color:var(--hub-accent); }
.hub-q__a { font-size:.68rem; padding:.14rem .5rem; }
.hub-chip--warn { border-color:rgba(251,146,60,.5); }

.hub-crawlers { display:flex; flex-wrap:wrap; gap:.35rem; }
.hub-cr { font-family:var(--mono,monospace); font-size:.68rem; padding:.2rem .5rem; border-radius:5px;
  background:var(--hub-accent-dim); color:var(--hub-accent); border:1px solid rgba(200,255,0,.25); }
.hub-cr--no { background:rgba(248,113,113,.12); color:#f87171; border-color:rgba(248,113,113,.3); }

.hub-empty { display:flex; align-items:center; gap:.7rem; color:var(--hub-muted); font-size:.86rem;
  background:var(--hub-card-2); border:1px dashed var(--hub-bd-lt); border-radius:var(--hub-r-sm); padding:.9rem 1rem; }
.hub-empty b { color:var(--hub-text); font-weight:600; }
/* A gate that names her move carries the way to make it (see gateHTML). It
   wraps under the sentence on a phone rather than squeezing it to nothing. */
.hub-empty .hub-open { margin-left:auto; flex:none; }
@media (max-width:620px) { .hub-empty { flex-wrap:wrap; } .hub-empty .hub-open { margin-left:0; } }
.hub-spin { width:13px; height:13px; flex:none; border-radius:50%; border:1.5px solid var(--hub-bd-lt);
  border-top-color:var(--hub-info); animation:hub-sp 1s linear infinite; }
@keyframes hub-sp { to { transform:rotate(360deg); } }

/* Actions "shape" preview — what the row will hold once the plan lands. */
.hub-acts { display:flex; flex-direction:column; gap:.4rem; }
.hub-act { display:grid; grid-template-columns:auto auto 1fr auto; gap:.8rem; align-items:center;
  background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.65rem .85rem; }
.hub-box { width:17px; height:17px; border-radius:5px; border:1.5px solid var(--hub-bd-lt); }
.hub-rank { font-family:var(--mono,monospace); font-size:.72rem; color:var(--hub-faint); }
.hub-act__t { font-size:.85rem; color:var(--hub-text-2); }
.hub-lyr { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.07em; padding:.16rem .42rem; border-radius:4px;
  background:var(--hub-card-3); color:var(--hub-muted); border:1px solid var(--hub-bd-lt); }

/* ─────────────────────────────────────────────────────────────────────────
   MOBILE
   The track is the piece that genuinely breaks: five columns of labels at
   375px leaves ~66px each. Rather than hide the labels (which would make the
   dots unidentifiable) the whole track scales down via the --hub-dot /
   --hub-track-pt tokens, so the rail follows automatically.
   ───────────────────────────────────────────────────────────────────────── */
@media (max-width:680px) {
  .rl-hub { --hub-dot:24px; --hub-track-pt:1.6rem; }
  .hub-track { padding-left:.35rem; padding-right:.35rem; }
  .hub-stop__l { font-size:.66rem; padding:.2rem .3rem; line-height:1.2; hyphens:auto; }
  .hub-stop { gap:.4rem; }
  .hub-pin { font-size:.5rem; top:-19px; }
  .hub-dot { font-size:.64rem; }

  .hub-hero__top { padding:1.15rem 1.1rem 1rem; gap:1.15rem; }
  .hub-peek { padding:1.05rem 1.1rem 1.15rem; }
  .hub-tile { width:46px; height:46px; font-size:1.2rem; }
  .hub-live__v .big { font-size:2rem; }

  .hub-sec__head { padding:.95rem 1rem; gap:.7rem; column-gap:.7rem; }
  .hub-sec__body { padding:0 1rem 1.1rem; }
  .hub-sec__n { display:none; }                 /* the title already says which */
  .hub-sec__sum { grid-column:1 / -1; grid-row:2; }
  .rl-hub .hub-sec__t h2 { font-size:1rem; }

  /* The header's right-hand group wraps under the title instead of squeezing
     the title to nothing. */
  .hub-sec__r { grid-column:1 / -1; grid-row:3; justify-content:flex-start; gap:.5rem; }
  .hub-sec.is-open .hub-sec__r { grid-row:2; }
  .hub-lnk { opacity:1; }                       /* no hover on touch */

  .hub-stats { grid-template-columns:repeat(2,1fr); }
  .hub-gauges { grid-template-columns:1fr; }
  .hub-meta { gap:.55rem .9rem; }
  .hub-meta__r { margin-left:0; width:100%; padding-top:.5rem; }
  .hub-dates { font-size:.64rem; }
  .hub-dates__arw { display:none; }

  .hub-exp { gap:1.1rem; }
  .hub-cover { width:min(230px, 72vw); }
  .hub-exp__cta { width:100%; }

  .hub-dirbar { justify-content:flex-start; }
}

/* Mini-bar: let the section jumper scroll rather than overflow the page. */
@media (max-width:820px) {
  /* Keeps the horizontal padding: .hub-mini is fixed and full-bleed now, so a
     0 here put the bar's contents hard against the screen edge. */
  .hub-mini__in { gap:.6rem; padding:.5rem 1.1rem; }
  .hub-mini__nav { margin:0 0 0 auto; overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
  .hub-mini__nav::-webkit-scrollbar { display:none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   VIEWER OVERLAY  (viewer-overlay.js)
   Deliverables open ON TOP of the crawl hub instead of navigating away, so
   closing one puts the reader back exactly where they were — same scroll,
   same expanded sections. Lives on <body>, outside .rl-hub, so it styles off
   the account-wide tokens rather than the hub's.
   ───────────────────────────────────────────────────────────────────────── */
.rlv { position:fixed; inset:0; z-index:150;   /* above .site-nav (100) and the account modals */ display:flex; align-items:center; justify-content:center;
  padding:clamp(0px, 3vh, 34px) clamp(0px, 3vw, 34px); }
.rlv[hidden] { display:none; }
.rlv__scrim { position:absolute; inset:0; background:rgba(4,4,6,.72); backdrop-filter:blur(3px);
  opacity:0; transition:opacity .18s ease; border:0; padding:0; cursor:pointer; }
.rlv.is-on .rlv__scrim { opacity:1; }
.rlv__panel { position:relative; display:flex; flex-direction:column; width:min(1180px, 100%); height:100%;
  background:var(--bg,#09090b); border:1px solid var(--border-light,#3f3f46); border-radius:16px; overflow:hidden;
  box-shadow:0 24px 70px rgba(0,0,0,.6); opacity:0; transform:translateY(10px) scale(.995);
  transition:opacity .18s ease, transform .18s ease; }
.rlv.is-on .rlv__panel { opacity:1; transform:none; }

.rlv__bar { display:flex; align-items:center; gap:.9rem; padding:.7rem .95rem; flex:none;
  background:var(--bg-card,#141416); border-bottom:1px solid var(--border,#27272a); }
.rlv__grip { display:none; }
.rlv__id { display:flex; flex-direction:column; min-width:0; }
.rlv__eyebrow { font-family:var(--mono,monospace); font-size:.58rem; letter-spacing:.11em; text-transform:uppercase;
  color:var(--text-faint,#71717a); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rlv__title { font-size:.95rem; font-weight:600; color:var(--text,#fafafa); letter-spacing:-.015em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.rlv__acts { margin-left:auto; display:flex; align-items:center; gap:.5rem; flex:none; }
.rlv__act { display:inline-flex; align-items:center; justify-content:center; gap:.45rem; height:36px; padding:0 .8rem;
  border-radius:9px; border:1px solid var(--border-light,#3f3f46); background:var(--bg,#09090b);
  color:var(--text-secondary,#e4e4e7); font-size:.82rem; font-weight:600; text-decoration:none; cursor:pointer; }
.rlv__act:hover { border-color:var(--accent,#c8ff00); color:var(--accent,#c8ff00); }
.rlv__act svg { width:15px; height:15px; flex:none; }
.rlv__act--x { width:36px; padding:0; }

.rlv__stage { position:relative; flex:1; min-height:0; background:var(--bg,#09090b); }
.rlv__frame { width:100%; height:100%; border:0; display:block; background:var(--bg,#09090b); opacity:0;
  transition:opacity .2s ease; }
.rlv.is-loaded .rlv__frame { opacity:1; }
.rlv__load { position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:.6rem;
  color:var(--text-muted,#a1a1aa); font-family:var(--mono,monospace); font-size:.76rem; letter-spacing:.06em; }
.rlv.is-loaded .rlv__load { display:none; }
.rlv__spin { width:14px; height:14px; border-radius:50%; border:1.6px solid var(--border-light,#3f3f46);
  border-top-color:var(--accent,#c8ff00); animation:hub-sp .9s linear infinite; }

/* Phone: a full-bleed sheet. There is no room for a 34px gutter, and a
   part-height modal on a 375px screen wastes the only asset it has. dvh (not
   vh) so the browser chrome collapsing doesn't crop the viewer's own footer. */
@media (max-width:760px) {
  .rlv { padding:0; align-items:flex-end; }
  .rlv__panel { width:100%; height:100dvh; max-height:100dvh; border-radius:0; border:0; transform:translateY(2%); }
  .rlv__bar { padding:.55rem .7rem; padding-top:max(.55rem, env(safe-area-inset-top)); gap:.6rem; }
  .rlv__title { font-size:.88rem; }
  .rlv__act { height:40px; }                 /* thumb-sized, not pointer-sized */
  .rlv__act__l { display:none; }
  .rlv__act:not(.rlv__act--x) { width:40px; padding:0; }
}
@media (prefers-reduced-motion: reduce) {
  .rlv__scrim, .rlv__panel, .rlv__frame { transition:none; }
}

/* ─────────────────────────────────────────────────────────────────────────
   INLINE READERS  (findings · questions · actions)
   The hub used to summarise each deliverable and send you elsewhere for the
   detail. These are the detail, on the page: expandable rows, a filter, a
   search, and a link INTO the viewer for anyone who wants the whole document.
   ───────────────────────────────────────────────────────────────────────── */
.hub-panel--reader { padding-bottom:.7rem; }
.hub-panel__hd { display:flex; align-items:center; gap:.7rem; margin-bottom:.7rem; }
.hub-panel__hd .hub-panel__k { margin:0; flex:1; min-width:0; }
.hub-panel__note { font-size:.76rem; color:var(--hub-faint); margin:.6rem 0 0; }
.hub-mini-b { font-family:var(--mono,monospace); font-size:.63rem; letter-spacing:.05em; text-transform:uppercase;
  padding:.34rem .6rem; border-radius:7px; cursor:pointer; flex:none;
  border:1px solid var(--hub-bd-lt); background:transparent; color:var(--hub-muted); }
.hub-mini-b:hover { color:var(--hub-accent); border-color:var(--hub-accent); }

.hub-filters { display:flex; flex-wrap:wrap; gap:.35rem; margin-bottom:.7rem; }
.hub-fchip { display:inline-flex; align-items:center; gap:.4rem; font-family:var(--mono,monospace); font-size:.64rem;
  letter-spacing:.04em; text-transform:uppercase; padding:.32rem .6rem; border-radius:7px; cursor:pointer;
  border:1px solid var(--hub-bd-lt); background:transparent; color:var(--hub-muted); }
.hub-fchip:hover { color:var(--hub-text); }
.hub-fchip.on { background:var(--hub-card-3); color:var(--hub-text); border-color:var(--hub-muted); }
.hub-fdot { width:6px; height:6px; border-radius:50%; flex:none; }

/* A finding: severity row you already knew, with the write-up under it. */
.hub-find2 { background:var(--hub-card-2); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm);
  overflow:hidden; transition:border-color .15s ease; }
.hub-find2:hover { border-color:var(--hub-bd-lt); }
.hub-find2.is-open { border-color:var(--hub-bd-lt); background:var(--hub-card-3); }
.hub-find2__hd { display:grid; grid-template-columns:3px auto 1fr auto auto; gap:.8rem; align-items:center; width:100%;
  padding:.6rem .8rem .6rem 0; background:none; border:0; cursor:pointer; text-align:left; font:inherit; color:inherit; }
.hub-find2__hd .hub-find__stripe { align-self:stretch; border-radius:3px 0 0 3px; }
.hub-find2__body { display:none; padding:0 .9rem 1rem 1.1rem; }
.hub-find2.is-open .hub-find2__body { display:block; }
.hub-chev { color:var(--hub-faint); font-size:.7rem; transition:transform .18s ease; flex:none; }
.hub-find2.is-open .hub-chev, .rl-act.is-open .hub-chev { transform:rotate(180deg); color:var(--hub-accent); }

.hub-block { margin-top:.75rem; }
.hub-block:first-child { margin-top:.2rem; }
.hub-block__k { font-family:var(--mono,monospace); font-size:.58rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--hub-faint); margin-bottom:.25rem; }
.rl-hub .hub-block p { margin:0; font-size:.85rem; line-height:1.55; color:var(--hub-text-2); max-width:72ch; }
.rl-hub .hub-block__none { margin:.4rem 0 0; font-size:.82rem; color:var(--hub-faint); }
.hub-bullets { margin:.2rem 0 0; padding-left:1.05rem; display:flex; flex-direction:column; gap:.3rem; }
.rl-hub .hub-bullets li { font-size:.85rem; line-height:1.5; color:var(--hub-text-2); }
.hub-urls { display:flex; flex-wrap:wrap; gap:.35rem; }
.hub-url { font-family:var(--mono,monospace); font-size:.68rem; color:var(--hub-muted); background:var(--hub-card);
  border:1px solid var(--hub-bd); border-radius:6px; padding:.2rem .45rem; word-break:break-all; }
.rl-hub .hub-scope { margin:.7rem 0 0; font-size:.76rem; color:var(--hub-faint); }
.hub-rowacts { margin-top:.9rem; display:flex; gap:.5rem; flex-wrap:wrap; }
.hub-open--sm { font-size:.74rem; padding:.3rem .6rem; }

.hub-readfoot { display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; margin-top:.75rem; }
.hub-readfoot__c { font-family:var(--mono,monospace); font-size:.66rem; color:var(--hub-faint); margin-right:auto; }
.hub-more { font-size:.78rem; font-weight:600; padding:.4rem .8rem; border-radius:8px; cursor:pointer;
  border:1px dashed var(--hub-bd-lt); background:transparent; color:var(--hub-text-2); }
.hub-more:hover { border-style:solid; border-color:var(--hub-accent); color:var(--hub-accent); }

/* Questions: the persona chips are the filter, the list is the answer. */
.hub-chip--b { cursor:pointer; font:inherit; font-size:.75rem; }
.hub-chip--b:hover { border-color:var(--hub-muted); color:var(--hub-text); }
.hub-chip--b.on { background:var(--hub-accent-dim); border-color:rgba(200,255,0,.45); color:var(--hub-accent); }
.hub-chip--b.on .n { color:var(--hub-accent); }
.hub-search { display:flex; align-items:center; gap:.5rem; margin:.7rem 0 .6rem; padding:0 .7rem;
  background:var(--hub-card); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); }
.hub-search__i { color:var(--hub-faint); font-size:.95rem; }
.hub-search input { flex:1; min-width:0; background:none; border:0; outline:none; color:var(--hub-text);
  font:inherit; font-size:.85rem; padding:.55rem 0; }
.hub-search input::placeholder { color:var(--hub-faint); }
.hub-qlist { display:flex; flex-direction:column; gap:.3rem; }
.hub-q { display:grid; grid-template-columns:1.6rem 1fr auto auto; gap:.7rem; align-items:baseline;
  background:var(--hub-card); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.5rem .7rem; }
.hub-q__n { font-family:var(--mono,monospace); font-size:.66rem; color:var(--hub-faint); }
.hub-q__t { font-size:.85rem; color:var(--hub-text-2); line-height:1.45; }
.hub-q__p { font-family:var(--mono,monospace); font-size:.6rem; letter-spacing:.04em; text-transform:uppercase;
  color:var(--hub-faint); white-space:nowrap; }

/* Report section jumper — each opens the report overlay already scrolled. */
.hub-jumps { display:grid; grid-template-columns:repeat(auto-fit,minmax(196px,1fr)); gap:.5rem; }
.hub-jump { display:grid; grid-template-columns:1fr auto; align-items:center; gap:.3rem .6rem; text-decoration:none;
  background:var(--hub-card); border:1px solid var(--hub-bd); border-radius:var(--hub-r-sm); padding:.6rem .75rem; }
.hub-jump:hover { border-color:var(--hub-accent); }
.hub-jump__l { font-size:.85rem; font-weight:600; color:var(--hub-text); }
.hub-jump__s { grid-column:1; font-size:.72rem; color:var(--hub-faint); }
.hub-jump__go { grid-column:2; grid-row:1 / span 2; color:var(--hub-faint); }
.hub-jump:hover .hub-jump__go { color:var(--hub-accent); }

/* Actions: the row body opens in place rather than only in the plan. */
.rl-act__main { text-align:left; background:none; border:0; padding:0; font:inherit; color:inherit; cursor:pointer;
  min-width:0; }
.rl-act__main:focus-visible { outline:2px solid var(--accent,#c8ff00); outline-offset:3px; border-radius:6px; }
.rl-act__more { display:none; margin-top:.85rem; }
.rl-act.is-open { border-color:var(--border-light,#3f3f46); }
.rl-act.is-open .rl-act__more { display:block; }
.rl-act__side { display:flex; align-items:center; gap:.5rem; }
.rl-act__side .hub-chev { display:grid; place-items:center; width:26px; height:26px; border-radius:7px;
  border:1px solid var(--border,#27272a); background:var(--bg-card-hover,#1b1b1f); color:var(--text-muted,#a1a1aa);
  font-size:.68rem; }
.rl-act:hover .rl-act__side .hub-chev { border-color:var(--border-light,#3f3f46); color:var(--text,#fafafa); }
.rl-act .hub-open--sm { white-space:nowrap; }

@media (max-width:680px) {
  .hub-find2__hd { grid-template-columns:3px auto 1fr auto; gap:.6rem; padding-right:.6rem; }
  .hub-find2__hd .hub-find__m { display:none; }
  .hub-find2__body { padding:0 .8rem .9rem .8rem; }
  .hub-panel--reader { padding-left:.8rem; padding-right:.8rem; }
  .hub-jumps { grid-template-columns:1fr; }
  .hub-q { grid-template-columns:1.4rem 1fr; }
  .hub-q__p, .hub-q__a { grid-column:2; justify-self:start; }
  /* Footer controls stack: side-by-side, "Show 3 more findings" wraps to three
     lines inside a 150px box and stops reading as a button. */
  .hub-readfoot { flex-direction:column; align-items:stretch; gap:.45rem; }
  .hub-readfoot__c { order:3; margin-right:0; text-align:center; }
  .hub-more, .hub-readfoot .hub-open { text-align:center; justify-content:center; }
  /* Filters scroll sideways rather than stacking four rows deep. */
  .hub-filters, .hub-chips { flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; padding-bottom:.2rem; }
  .hub-filters::-webkit-scrollbar, .hub-chips::-webkit-scrollbar { display:none; }
  .hub-fchip, .hub-chip { flex:none; }
  /* Tap targets: 38px minimum on anything you're expected to hit with a thumb. */
  .hub-mini-b, .hub-more, .hub-open, .rl-actf { min-height:38px; display:inline-flex; align-items:center; }
  .rl-act { grid-template-columns:auto 1fr auto; gap:.7rem .8rem; padding:12px 13px; }
  .rl-act__rank { display:none; }
  /* The row is ~300px wide on a phone — every pixel the side column takes is a
     pixel of action title. Label off, arrow only. */
  .hub-lbl-sm { display:none; }
  .rl-act__side { flex-direction:column; align-items:flex-end; gap:.4rem; }
  .rl-act .hub-open--sm { padding:.3rem .45rem; }
  .rl-actcopy__l { display:none; }
  .rl-actcopy { margin-left:0; }
  .rl-actbar { gap:.5rem; }
  .rl-actfilters { flex:1; overflow-x:auto; scrollbar-width:none; flex-wrap:nowrap; }
  .rl-actfilters::-webkit-scrollbar { display:none; }
  .rl-actf { flex:none; }
}

/* ── Boot guard ─────────────────────────────────────────────────────────────
   The "we're loading / we couldn't load" panel that boot-guard.js paints. It has
   to be styled here rather than inline because the guard runs before any module
   does, and its whole job is to be legible when the app is not working. */
.bootg { max-width: 30rem; margin: 4rem auto; padding: 2rem 1.75rem; text-align: center;
  background: var(--bg-card, #141416); border: 1px solid var(--border, #27272a); border-radius: 16px; }
.bootg[hidden] { display: none; }   /* author display would defeat the attribute */
.bootg__spin { width: 26px; height: 26px; margin: 0 auto 1rem; border-radius: 50%;
  border: 2px solid var(--border-light, #3f3f46); border-top-color: var(--accent, #c8ff00);
  animation: bootg-spin 0.7s linear infinite; }
@keyframes bootg-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .bootg__spin { animation-duration: 2.4s; } }
.bootg__msg { margin: 0; color: var(--text-secondary, #e4e4e7); font-size: 0.95rem; line-height: 1.5; }
.bootg__msg strong { color: var(--text, #fafafa); }
.bootg__sub { margin: 0.5rem 0 0; color: var(--text-muted, #a1a1aa); font-size: 0.85rem; line-height: 1.5; }
.bootg__acts { display: flex; gap: 0.75rem; justify-content: center; align-items: center;
  flex-wrap: wrap; margin: 1.25rem 0 0; }
.bootg__btn { font: inherit; font-size: 0.88rem; font-weight: 600; cursor: pointer;
  padding: 0.6rem 1.1rem; border-radius: 10px; border: 0;
  background: var(--accent, #c8ff00); color: #09090b; }
.bootg__link { font-size: 0.88rem; color: var(--text-muted, #a1a1aa); }
.bootg.is-stuck { border-color: rgba(250, 204, 21, 0.4); }
