/* Complementary styles for the dashboard. Tailwind Play CDN handles the rest. */

/* Phase 3 (spec §3.9) — mobile admin reflow at <640px.
   * Traffic light detail line stacks below the label.
   * Sticky first column on the scraper / job_runs tables so scraper
     and job names don't scroll out of view inside `overflow-x-auto`.
   * Touch targets ≥ 44px on action buttons. */
@media (max-width: 640px) {
  .admin-traffic-light p.detail {
    display: block;
    margin-top: 0.25rem;
  }
  .admin-table th:first-child,
  .admin-table td:first-child {
    position: sticky;
    left: 0;
    background: rgb(15 23 42);  /* slate-900 */
    z-index: 10;
  }
  .admin-action-btn {
    min-height: 44px;
    padding-block: 0.5rem;
  }
}


/* Phase 1 a11y — focus indicator token. Declared here so the admin
   layout (which does NOT include `_layout.html`'s inline <style>
   block) resolves var(--color-focus). Public layout duplicates the
   declaration in `:root` inline at _layout.html (intentional — spec
   §3.9). Keep in sync. */
:root { --color-focus: oklch(0.85 0.16 215); }

/* Phase 2 (spec §3.7) — skip-link smooth-scroll polish. Gated by
   `(prefers-reduced-motion: no-preference)` so RM users get the
   instant jump — WCAG 2.3.3 invariant. The Phase 1 `archive.html:14`
   `scrollIntoView({behavior: 'smooth'})` is unaffected: explicit
   behavior arguments override `scroll-behavior`. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

html { color-scheme: dark; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: #0f172a; }
::-webkit-scrollbar-thumb { background: #1e293b; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #334155; }

/* Chart.js canvas wrapper: keep aspect ratio sane on small viewports. */
.chart-wrap { position: relative; width: 100%; height: 220px; }

/* Smooth pill transitions when status flips on auto-refresh. */
.pill { transition: background-color 120ms, color 120ms, border-color 120ms; }

/* Hide Alpine cloak (avoids flash-of-uncloaked-content). */
[x-cloak] { display: none !important; }

/* HTMX in-flight state (auto-applied via the .htmx-request class).
   v2.0 microinteraction #3: 120ms request, 200ms settling. */
.htmx-request { opacity: 0.7; transition: opacity 120ms; }
.htmx-settling { opacity: 1; transition: opacity 200ms; }

/* v2.0 Step 12 — microinteractions catalog (spec §3.9).
   Items 1, 7, 9 are already wired earlier in this file (trending pill
   hover/polyline draw-in; details[open] svg.chevron rotation;
   *:focus-visible ring). Items 4 + 8 have no CSS in v2.0 (browser-
   default cross-fade for view-transition; Chart.js handles sparkline
   draw-in via animation.duration). The blocks below cover items 2, 5,
   6, 10. The universal prefers-reduced-motion opt-out at the end of
   this file zeroes everything; per-rule RM degradation hits the
   static end states. */

/* #2 — filter chip count badge pop */
.filter-chip[data-active="true"] .filter-chip-badge {
  animation: chip-badge-pop 360ms var(--ease-spring);
}
@keyframes chip-badge-pop {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}

/* #5 — theme toggle: sun/moon icon rotation + body fade */
.theme-toggle svg {
  transition: transform 240ms var(--ease-spring);
}
.theme-toggle[data-active="true"] svg {
  transform: rotate(180deg);
}
body {
  transition: background-color 360ms ease-out, color 360ms ease-out;
}

/* #6 — hamburger sheet: backdrop & slide. Alpine x-transition handles
   slide on open; this CSS pins the resting backdrop attributes. */
.mobile-nav-backdrop { transition: opacity 200ms; }
.mobile-nav-sheet { transition: transform 240ms var(--ease-spring); }

/* #10 — visit-link card press */
.visit-link-card {
  transition:
    transform 200ms,
    border-color 200ms;
}
.visit-link-card:active {
  transform: scale(0.98);
  border-color: var(--color-accent-cyan-dim);
  transition-duration: 80ms;
}

/* v2.0 Step 10 — drop-cap on first paragraph of prose (spec §3.7
   + Blocker B12 fragile-selector fix). Uses .prose-dropcap > p:first-
   of-type::first-letter so the rule survives Jinja inserting a future
   <div>/<aside> as the prose container's first child. */
.prose-dropcap > p:first-of-type::first-letter {
  float: left;
  font-size: 3em;
  font-family: var(--font-body);
  font-weight: 600;
  padding-right: 8px;
  line-height: 1;
}

/* v2.0 Step 9 — sticky filter chip row on /archive (spec §3.6).
   Backdrop-blurred translucent base behind the chip strip so content
   below remains legible while pinned. Cyan-glow on the active chip
   pairs the color signal with a border-weight signal (a11y rule:
   color is never the sole signal). */
.filter-chip {
  transition:
    border-color 200ms,
    color 200ms,
    background-color 200ms;
}
.filter-chip[data-active="true"] {
  box-shadow: 0 0 0 4px var(--color-accent-cyan-glow);
  border-color: var(--color-accent-cyan);
}
.scroll-snap-type-x-mandatory {
  scroll-snap-type: x mandatory;
}

/* v2.0 Step 8 — per-source 90-day Chart.js sparkline (spec §3.10 / §4.1).
   Fixed-height placeholder until Chart.js fires (CLS protection). */
.source-spark-wrap {
  position: relative;
  width: 100%;
  height: 60px;
  margin-top: 4px;
}
.source-spark-wrap canvas {
  width: 100% !important;
  height: 60px !important;
  display: block;
}

/* v2.0 Step 7 — trending ribbon polyline draw-in (spec §3.4).
   Default state: line invisible (stroke-dashoffset: 100), opacity 0.3.
   Active state (hover/focus on .ribbon-pill via Alpine data-active):
   stroke-dashoffset: 0 over 600ms ease-out; opacity 1 over 240ms
   var(--ease-spring). pathLength="100" pinned in markup so CSS
   interpolates without JS. */
.ribbon-spark {
  display: inline-block;
  width: 60px;
  height: 16px;
  vertical-align: middle;
}
.ribbon-spark polyline {
  fill: none;
  stroke: var(--color-accent-cyan);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  opacity: 0.3;
  transition:
    stroke-dashoffset 600ms ease-out,
    opacity 240ms var(--ease-spring);
}
.ribbon-pill[data-active="true"] .ribbon-spark polyline {
  stroke-dashoffset: 0;
  opacity: 1;
}
.ribbon-pill {
  transition:
    transform 240ms var(--ease-spring),
    box-shadow 240ms var(--ease-spring),
    background-color 240ms var(--ease-spring);
}
.ribbon-pill[data-active="true"] {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px var(--color-accent-cyan-glow);
}

/* v2.0 Step 6 — two-column desktop home (spec §3.5).
   <1024px: single column (mobile + tablet share the stacked shape).
   ≥1024px: 2fr 1fr grid; right rail sticky-pins below header. */
.home-grid { display: grid; grid-template-columns: 1fr; gap: 32px; }
.home-grid-right { width: 100%; }
@media (min-width: 1024px) {
  .home-grid { grid-template-columns: 2fr 1fr; gap: 32px; }
  .home-grid-right {
    position: sticky;
    top: 16px;
    align-self: start;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    width: min(280px, 25vw);
    justify-self: end;
  }
}
/* "This week" rows align via shared track widths (subgrid where supported). */
@supports (grid-template-rows: subgrid) {
  .this-week-list { grid-template-rows: subgrid; }
}

/* v1.5 Step 5 — chevron rotates on details[open] (spec §3.7 lazy-related). */
details[open] svg.chevron {
  transform: rotate(90deg);
  transition: transform 200ms var(--ease-spring);
}
svg.chevron { transition: transform 200ms var(--ease-spring); }

/* v1.5 Step 4 — keyboard a11y focus-visible ring (spec §3.9 item 9).
   Outline is instant for a11y; only the cyan box-shadow eases. */
*:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--color-accent-cyan-glow);
  transition: box-shadow 120ms;
}

/* Phase 1 a11y — skip-to-content link (spec §3.1). Resting state is
   the standard sr-only pattern; on focus it pins to the top-left at
   ≥ 44×44 px (WCAG 2.5.5). Inherits the focus-visible outline via
   `*:focus-visible` above; no per-element override. */
.skip-link {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
}
.skip-link:focus,
.skip-link:focus-visible {
  position: fixed;
  top: 8px;
  left: 8px;
  width: auto;
  height: auto;
  clip: auto;
  padding: 12px 16px;
  min-height: 44px;
  min-width: 44px;
  background: var(--color-bg-raised);
  color: var(--color-fg-primary);
  border: 2px solid var(--color-focus);
  border-radius: 6px;
  z-index: 100;
  font-family: var(--font-ui);
  font-weight: 600;
}

/* v1.5 Step 4 — universal prefers-reduced-motion opt-out (spec §3.9 RM
   block). Mesh hides; transitions/animations zeroed. Per-rule RM
   degradation hits via static end states on hover/active. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0ms !important;
    animation-duration: 0ms !important;
  }
  .atmospheric-mesh { display: none; }
  /* Phase 1 a11y (spec §3.5) — `*` selector does NOT match
     ::view-transition pseudo-elements; UA fires `animation`-driven
     keyframes on these even when transitions are zeroed. RM-only
     override (Decision G's "no API styling" exception). */
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none; }
  /* Phase 1 a11y (spec §3.5) — under RM the universal `*` rule zeroes
     the polyline draw-in transition, but the default state
     (stroke-dashoffset: 100; opacity: 0.3) leaves the line invisible.
     Force-visible static end state under RM. */
  .ribbon-spark polyline {
    stroke-dashoffset: 0;
    opacity: 1;
  }
}

/* Phase 1 a11y — prefers-reduced-data (spec §3.7). Save-Data users
   skip the atmospheric mesh; everything else stays. Single rule —
   the mesh is the only opt-in atmospheric cost on the public site. */
@media (prefers-reduced-data: reduce) {
  .atmospheric-mesh { display: none; }
}

/* Phase 2 (spec §3.9) — Continue reading rail on home. Inherits the
   home-grid-left card shape; only spacing differs. */
.continue-reading-rail { margin-top: 0; }

/* Phase 4 (spec §3.4) — loading radar glyph. The SVG always sits in
   the markup; CSS controls visibility. By default visible (covers
   the lazy-related panel where the glyph IS the affordance). Hosts
   that opt-in via `data-loading-glyph="true"` only show the glyph
   while .htmx-request is active — the empty state stays clean. */
.loading-radar {
  display: inline-block;
  animation: radar-loading-spin 1200ms linear infinite;
  transform-origin: 50% 50%;
}
[data-loading-glyph="true"] .loading-radar { display: none; }
[data-loading-glyph="true"].htmx-request .loading-radar {
  display: inline-block;
}
@keyframes radar-loading-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Phase 4 (spec §3.6) — reading-end pulse on the first related-rail
   card. data-reached-end is written by readingEndPulse() in
   _layout.html when the prose-end sentinel intersects the viewport;
   self-clears after 1800ms. */
.related-rail-first-card[data-reached-end="true"] {
  animation: pulse-cyan 1800ms var(--ease-spring) 1;
}
@keyframes pulse-cyan {
  0%   { box-shadow: 0 0 0 0 var(--color-accent-cyan-glow); }
  50%  { box-shadow: 0 0 0 8px var(--color-accent-cyan-glow); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Phase 4 (spec §3.7) — admin traffic-light pulse on green only.
   Scoped via attribute selector so amber/red stay solid (alarm
   semantics must not feel playful). */
.admin-traffic-light[data-traffic-light-state="ok"] .traffic-light-dot {
  animation: pulse-on-green 2000ms ease-in-out infinite;
}
@keyframes pulse-on-green {
  0%, 100% { box-shadow: 0 0 0 0 oklch(0.78 0.16 140 / 0.6); }
  50%      { box-shadow: 0 0 0 6px oklch(0.78 0.16 140 / 0); }
}

/* Phase 5 — desktop power layer. ⌘K command palette, j/k card nav,
   ? help overlay, mouse-tracking radar, live header chip, wider
   desktop layouts. All additive; mobile reflows back to existing
   shape via media queries. */

/* Phase 5 — platform-conditional kbd glyph. The data-platform
   attribute is set once at load via navigator.platform (see <head>).
   .kbd-mac shows on Mac; .kbd-other shows everywhere else. */
.kbd-mac, .kbd-other { display: none; }
:root[data-platform="mac"] .kbd-mac { display: inline; }
:root[data-platform="mac"] .kbd-other { display: none; }
:root[data-platform="other"] .kbd-other { display: inline; }
:root[data-platform="other"] .kbd-mac { display: none; }
/* Pre-platform-detection flash (script in <head> sets this before
   first paint, but defensive default = both hidden, fallback shows
   the cross-platform glyph). */
:root:not([data-platform]) .kbd-other { display: inline; }

/* Phase 5 — kbd glyph for help overlay + quick actions. Uses the
   existing JetBrains Mono token. */
.kbd-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-fg-muted);
  background: var(--color-bg-base);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  line-height: 1;
}

/* Phase 5 — live "scanning" header chip. Pulsing cyan dot uses the
   pulse-on-green keyframe pattern from Phase 4 (admin traffic light)
   but tinted cyan. RM users get the static dot — the universal
   `*` rule zeroes the animation-duration. */
.live-chip-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--color-accent-cyan);
  box-shadow: 0 0 0 0 var(--color-accent-cyan-glow);
  animation: live-chip-pulse 2400ms ease-in-out infinite;
  flex-shrink: 0;
}
@keyframes live-chip-pulse {
  0%, 100% { box-shadow: 0 0 0 0 var(--color-accent-cyan-glow); }
  50%      { box-shadow: 0 0 0 6px transparent; }
}
.live-chip {
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: oklch(0.22 0.025 240 / 0.4);
}

/* Phase 5 — search-pill (header search button widens on lg+). */
.search-pill {
  transition:
    background-color 200ms,
    border-color 200ms,
    width 200ms;
}
.search-pill:hover { border-color: var(--color-accent-cyan-dim); }

/* Phase 5 — j/k card-active highlight. Uses the existing focus
   ring tokens so the highlight visually rhymes with keyboard focus.
   `data-pick-active="true"` is set by cardMove() in _layout.html. */
[data-pick-card] {
  scroll-margin-block: 80px;
  transition:
    box-shadow 200ms var(--ease-spring),
    border-color 200ms var(--ease-spring);
}
[data-pick-card][data-pick-active="true"] {
  border-color: var(--color-accent-cyan);
  box-shadow: 0 0 0 4px var(--color-accent-cyan-glow);
}

/* Phase 5 — help overlay. Backdrop blur + centered card. Mobile
   keeps the same shape since the panel maxes at max-w-md. */
.help-overlay { backdrop-filter: blur(2px); }

/* Phase 5 — quick-action rows in the search overlay. Hidden when the
   user has typed something. The input is nested in a flex header row,
   so a simple sibling combinator can't reach .search-quick-actions —
   the :has() form on the overlay container is the working selector
   in 2026 browsers (Chrome/Edge 105+, Safari 15.4+, Firefox 121+). */
.search-quick-actions {
  background: oklch(0.22 0.025 240 / 0.35);
}
.search-overlay:has(#search-overlay-input:not(:placeholder-shown)) .search-quick-actions {
  display: none;
}
.quick-action-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 6px;
  color: var(--color-fg-secondary);
  border: 1px solid transparent;
  background: transparent;
  cursor: pointer;
  text-align: left;
}
.quick-action-link:hover,
.quick-action-link:focus-visible {
  background: oklch(0.22 0.025 240 / 0.6);
  border-color: var(--color-border-soft, oklch(0.28 0.02 240));
  color: var(--color-fg-primary);
}
.palette-cycle-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 999px;
}

/* Phase 5 — mouse-tracking hero radar. heroRadar() Alpine factory:
   - On mousemove: pauseAnimations() on the SVG to freeze the SMIL
     children, then writes an inline `transform: rotate(deg)` onto
     <g class="hero-radar-arm">.
   - On mouseleave: clears the inline transform and unpauseAnimations().

   The CSS rule below pins transform-box + transform-origin so the
   inline rotate() spins around the radar's user-coordinate (0,0)
   — which is the visual centre of the viewBox `-100 -100 200 200`
   — instead of the bbox centre of the wedge path. transform-box:
   view-box is supported by Chrome 64+, Safari 11+, Firefox 55+. */
.hero-radar { cursor: crosshair; }
.hero-radar-arm {
  transform-box: view-box;
  transform-origin: center;
}
.hero-radar.is-tracking .hero-radar-arm {
  filter: drop-shadow(0 0 8px var(--color-accent-cyan-glow));
}

@media (prefers-reduced-motion: reduce) {
  .hero-radar { cursor: default; }
  .live-chip-dot { animation: none; }
}

/* Phase 5 — wider desktop breakpoints. The header / footer keep
   max-w-6xl; the home + archive main columns expand to 1024–1280px
   so the trending rail breathes. */
@media (min-width: 1280px) {
  .home-grid { grid-template-columns: 3fr 1fr; gap: 40px; }
  .home-grid-right {
    width: min(320px, 28vw);
  }
}

/* Phase 4 (spec §3.1) — palette swatch row. 24×24 swatch wrapped in
   a 44×44 button so the visible dot stays small without breaking the
   Phase 1 minimum-touch-target rule. aria-checked="true" gets a
   ring; default (cyan) is pre-checked at first paint via x-init. */
.theme-toggle-palette { border: 0; padding: 0; margin: 0; }
.palette-swatch {
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: transparent;
  position: relative;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.palette-swatch::after {
  content: "";
  display: block;
  width: 18px;
  height: 18px;
  border-radius: 999px;
  border: 1px solid oklch(1 0 0 / 0.15);
}
.palette-cyan::after   { background: oklch(0.83 0.13 215); }
.palette-violet::after { background: oklch(0.70 0.18 290); }
.palette-orange::after { background: oklch(0.78 0.16 60); }
.palette-mint::after   { background: oklch(0.85 0.16 165); }
.palette-swatch[aria-checked="true"] { border-color: var(--color-accent-cyan); }
.palette-swatch[aria-checked="true"]::after {
  box-shadow: 0 0 0 2px var(--color-bg-base), 0 0 0 4px var(--color-accent-cyan);
}

/* Phase 2 (spec §3.5) — trending-ribbon inline help. Native <details>
   handles Enter/Space toggle + UA aria-expanded. Anchored at the right
   end of the ribbon section; the [open] paragraph absolutely positions
   below the summary. z-index: 5 clears the polyline sparkline.

   The popover sets an explicit width (not max-width) because its
   offset parent is the 24×24 .ribbon-help <details>; with only
   right:0 set it would otherwise shrink-to-fit inside that 24px box
   and wrap one word per line. */
.trending-ribbon { position: relative; }
.ribbon-help {
  position: absolute;
  top: 0;
  right: 0;
}
.ribbon-help summary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  cursor: pointer;
  list-style: none;
  color: var(--color-fg-muted);
  transition: color 160ms, background-color 160ms;
}
.ribbon-help summary:hover,
.ribbon-help[open] summary {
  color: var(--color-accent-cyan);
  background: var(--color-bg-raised);
}
.ribbon-help summary::-webkit-details-marker { display: none; }
.ribbon-help summary::marker { display: none; }
.ribbon-help[open] p {
  position: absolute;
  top: 36px;
  right: 0;
  width: min(260px, calc(100vw - 32px));
  padding: 10px 12px;
  margin: 0;
  background: var(--color-bg-raised);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  box-shadow: 0 8px 24px oklch(0 0 0 / 0.35);
  z-index: 5;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--color-fg-secondary);
}

/* About page — hand-numbered step list. CSS grid puts a fixed-width
   mono numeral column to the left of the body text so the digits hang
   instead of sitting inline (default ::marker would apply). Used by
   the "How it works" section in public/about.html. */
.about-steps { list-style: none; padding: 0; }
.about-steps > li {
  display: grid;
  grid-template-columns: 2.25rem 1fr;
  gap: 0.75rem;
  align-items: baseline;
}
.about-step-num {
  font-size: 0.875rem;
  letter-spacing: 0.04em;
}

/* About page — primary CTA card. Subtle inner glow on hover to signal
   "this is the call to action" without a hard button-shaped affordance
   that fights the editorial typography. */
.about-cta { transition: background-color 200ms, box-shadow 200ms; }
.about-cta:hover {
  box-shadow: 0 0 0 1px var(--color-accent-cyan), 0 8px 24px var(--color-accent-cyan-glow);
}

/* Phase 2 (spec §3.3) — share row. Three buttons inline on desktop,
   stacked full-width on mobile. Min-touch 44 px enforced via min-h-11
   on the buttons themselves; this rule sets layout only. */
.share-row { margin-top: 8px; }

/* Phase 2 (spec §3.2) — saved-pick star button. Min 44×44 px touch
   target (Phase 1). aria-pressed="true" pairs with cyan fill — the
   accessible name stays static ("Save pick") and aria-pressed is the
   sole state carrier (rec #4). */
button[aria-label="Save pick"] {
  min-width: 44px;
  min-height: 44px;
  transition: color 200ms, border-color 200ms, background-color 200ms;
}
button[aria-label="Save pick"][aria-pressed="false"] svg use {
  fill: none;
  stroke: currentColor;
}
button[aria-label="Save pick"][aria-pressed="true"] {
  color: var(--color-accent-cyan);
  border-color: var(--color-accent-cyan);
}
button[aria-label="Save pick"][aria-pressed="true"] svg use {
  fill: currentColor;
}

/* Phase 2 (spec §3.1) — search overlay. Mobile = full-screen sheet
   (inset: 0). Desktop ≥sm: centered card 720px wide, 80vh max-height. */
.search-overlay {
  inset: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
}
@media (min-width: 640px) {
  .search-overlay {
    inset: 10vh auto auto 50%;
    transform: translateX(-50%);
    width: min(720px, 92vw);
    max-height: 80vh;
    border-radius: 12px;
  }
}

/* Phase 2 (spec §3.6 + Blocker 9) — print stylesheet. Hide every
   interactive / atmospheric surface; keep the editorial drop-cap so
   Cmd-P preserves the publication identity. URL-annotated anchors
   make the printed artifact self-contained. Class names match the
   selectors in Steps 5 / 6 / 7 / 8 / 12 — copy verbatim if those
   change. */
@media print {
  body { background: white; color: black; }
  header, footer, nav, #mobile-nav, .mobile-nav-backdrop,
  .atmospheric-mesh, .trending-ribbon, .ribbon-help,
  .search-overlay, .search-overlay-backdrop,
  .skip-link,
  .share-row,
  button[aria-label="Save pick"],
  .continue-reading-rail,
  button[hx-swap="beforeend"],
  details {
    display: none !important;
  }
  article, main { display: block; }
  .prose, .prose-invert {
    font-size: 11pt;
    line-height: 1.5;
    color: black;
  }
  a { color: black; text-decoration: underline; }
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
  }
  /* Editorial drop-cap survives Cmd-P (spec §3.6). */
  .prose-dropcap > p:first-of-type::first-letter {
    float: left;
    font-size: 3em;
    font-family: var(--font-body);
    font-weight: 600;
    padding-right: 8px;
    line-height: 1;
  }
}

/* ============================================================
   v2.1 — "step into the future" home page (design handoff).
   Adds: ingestion-pulse strip, bolder hero, signal-card grid,
   topic-ribbon as full-width grid, coverage bars, footer CTA.
   ============================================================ */

/* Ingestion pulse strip — 28 abstract cells, source-agnostic. */
.ingestion {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid oklch(0.28 0.02 240);
  background: oklch(0.18 0.022 240 / 0.5);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-fg-muted);
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
}
.ingestion__label { color: oklch(0.42 0.02 240); white-space: nowrap; }
.ingestion__cells {
  display: flex;
  gap: 4px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  align-items: center;
}
.ingestion__cell {
  flex: 1 1 0;
  height: 10px;
  min-width: 4px;
  max-width: 24px;
  border-radius: 1px;
  background: oklch(0.30 0.025 240);
  opacity: 0.35;
}
.ingestion__cell[data-active="true"] {
  background: var(--color-accent-cyan);
  opacity: 0.55;
  box-shadow: 0 0 6px var(--color-accent-cyan-glow);
  animation: ingestion-blink 4.8s ease-in-out infinite;
}
.ingestion__cell[data-active="true"][data-intense="true"] {
  opacity: 0.95;
  box-shadow: 0 0 10px var(--color-accent-cyan-glow);
}
@keyframes ingestion-blink {
  0%, 100% { opacity: 0.35; }
  20%, 60% { opacity: 0.85; }
}
.ingestion__count {
  margin-left: auto;
  color: var(--color-fg-primary);
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.ingestion__count strong { color: var(--color-accent-cyan); font-weight: 500; }

/* Hero v2 — big radar + eyebrow + gradient title + lead + CTAs. */
.hero-v2 {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.2fr);
  gap: 48px;
  align-items: center;
  padding: 56px 0 32px;
}
@media (max-width: 900px) {
  .hero-v2 {
    grid-template-columns: 1fr;
    gap: 24px;
    padding: 24px 0 16px;
  }
}
.hero-v2__stage {
  position: relative;
  aspect-ratio: 1;
  max-width: 460px;
  width: 100%;
  margin: 0 auto;
}
.hero-v2__stage::before {
  content: "";
  position: absolute;
  inset: -8%;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--color-accent-cyan-glow), transparent 70%);
  filter: blur(40px);
  pointer-events: none;
  z-index: -1;
}
.hero-v2__stage .hero-radar,
.hero-v2__stage .hero-radar svg {
  width: 100%;
  height: 100%;
  display: block;
}
.hero-v2__badges {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.hero-v2__badge {
  position: absolute;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-fg-secondary);
  padding: 3px 8px;
  background: oklch(0.18 0.022 240 / 0.85);
  border: 1px solid oklch(0.83 0.13 215 / 0.4);
  border-radius: 999px;
  letter-spacing: 0.05em;
  white-space: nowrap;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: hero-badge-blip 6s linear infinite;
}
.hero-v2__badge::before {
  content: "";
  width: 4px;
  height: 4px;
  background: var(--color-accent-cyan);
  border-radius: 50%;
  display: inline-block;
  vertical-align: middle;
  margin-right: 6px;
  box-shadow: 0 0 6px var(--color-accent-cyan);
}
@keyframes hero-badge-blip {
  0%, 6% { opacity: 0; transform: translateY(2px); }
  10%, 90% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; }
}
.hero-v2__copy {
  display: flex;
  flex-direction: column;
  gap: 20px;
}
.hero-v2__eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-cyan);
  display: inline-flex;
  align-items: center;
  gap: 12px;
}
.hero-v2__eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: linear-gradient(to right, transparent, var(--color-accent-cyan));
}
.hero-v2__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(34px, 4.2vw, 60px);
  line-height: 1.04;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--color-fg-primary);
  text-wrap: balance;
}
.hero-v2__title em {
  font-style: normal;
  background: linear-gradient(120deg, var(--color-accent-cyan), oklch(0.82 0.16 290));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero-v2__lead {
  font-family: var(--font-body);
  font-size: 18px;
  line-height: 1.55;
  color: var(--color-fg-secondary);
  max-width: 56ch;
  margin: 0;
  text-wrap: pretty;
}
.hero-v2__stats {
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
  padding-top: 8px;
}
.hero-v2__stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.hero-v2__stat strong {
  font-family: var(--font-mono);
  font-size: 28px;
  font-weight: 500;
  color: var(--color-fg-primary);
  letter-spacing: -0.02em;
}
.hero-v2__stat strong small {
  font-size: 14px;
  color: var(--color-fg-muted);
  margin-left: 2px;
}
.hero-v2__stat span {
  font-family: var(--font-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--color-fg-muted);
}
.hero-v2__cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-top: 4px;
}

/* Generic primary / ghost button for the new home surfaces. */
.btn-radar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 500;
  padding: 11px 18px;
  border-radius: 8px;
  background: var(--color-accent-cyan);
  color: var(--color-bg-base);
  letter-spacing: 0.02em;
  transition: 200ms var(--ease-spring);
  box-shadow: 0 8px 28px -10px var(--color-accent-cyan-glow);
  border: 0;
  cursor: pointer;
}
.btn-radar:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 32px -8px var(--color-accent-cyan-glow);
}
.btn-radar--ghost {
  background: transparent;
  color: var(--color-fg-primary);
  border: 1px solid var(--color-border);
  box-shadow: none;
}
.btn-radar--ghost:hover {
  border-color: var(--color-accent-cyan);
  color: var(--color-accent-cyan);
}

/* Section scaffolding — eyebrow + heading + sub, separators. */
.tr-section { padding: 40px 0; position: relative; }
.tr-section + .tr-section { border-top: 1px solid oklch(0.28 0.02 240); }
.tr-section__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.tr-section__title {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.tr-section__eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-cyan);
}
.tr-section__heading {
  font-family: var(--font-ui);
  font-size: 22px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--color-fg-primary);
  margin: 0;
}
.tr-section__heading em {
  font-style: normal;
  color: var(--color-fg-muted);
  font-weight: 400;
}
.tr-section__sub {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-fg-muted);
  letter-spacing: 0.04em;
}

/* Latest signals — grid of pick cards with hover lift + cyan rail. */
.signals-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 16px;
}
.signal-card {
  position: relative;
  padding: 20px;
  border: 1px solid oklch(0.28 0.02 240);
  border-radius: 10px;
  background: oklch(0.20 0.02 240 / 0.6);
  display: flex;
  flex-direction: column;
  gap: 12px;
  cursor: pointer;
  transition: 220ms var(--ease-spring);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}
.signal-card::before {
  content: "";
  position: absolute;
  left: 0; top: 0;
  height: 100%; width: 2px;
  background: var(--color-accent-cyan);
  transform: scaleY(0.2);
  transform-origin: top;
  opacity: 0;
  transition: 280ms var(--ease-spring);
}
.signal-card:hover {
  border-color: oklch(0.83 0.13 215 / 0.4);
  background: oklch(0.22 0.02 240 / 0.85);
  transform: translateY(-2px);
}
.signal-card:hover::before { transform: scaleY(1); opacity: 1; }
.signal-card__row {
  display: flex;
  gap: 12px;
  align-items: center;
}
.signal-card__index {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-fg-muted);
  padding: 3px 0;
}
.signal-card__date {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-fg-muted);
  letter-spacing: 0.06em;
  margin-left: auto;
}
.signal-card__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 21px;
  line-height: 1.2;
  color: var(--color-fg-primary);
  letter-spacing: -0.01em;
  margin: 0;
  text-wrap: balance;
}
.signal-card:hover .signal-card__title { color: var(--color-accent-cyan); }
.signal-card__brief {
  font-family: var(--font-body);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--color-fg-secondary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.signal-card__foot {
  display: flex;
  gap: 12px;
  align-items: center;
  padding-top: 4px;
  margin-top: auto;
}
.signal-card__tag {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--color-fg-muted);
  letter-spacing: 0.04em;
}
.signal-card__tag + .signal-card__tag::before {
  content: "·";
  margin-right: 8px;
  color: oklch(0.42 0.02 240);
}
.signal-card__arrow {
  margin-left: auto;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  color: var(--color-fg-muted);
  transition: 220ms var(--ease-spring);
}
.signal-card:hover .signal-card__arrow {
  border-color: var(--color-accent-cyan);
  color: var(--color-accent-cyan);
  transform: rotate(-45deg);
}

/* Trending ribbon as full-width grid of topic cells with sparklines. */
.topic-ribbon {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1px;
  background: oklch(0.28 0.02 240);
  border: 1px solid oklch(0.28 0.02 240);
  border-radius: 14px;
  overflow: hidden;
}
.topic-cell {
  background: var(--color-bg-raised);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  position: relative;
  cursor: pointer;
  transition: 200ms var(--ease-spring);
  min-height: 132px;
  text-decoration: none;
  color: inherit;
}
.topic-cell:hover {
  background: var(--color-bg-muted);
  z-index: 1;
}
.topic-cell__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 8px;
}
.topic-cell__label {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--color-fg-primary);
  text-transform: lowercase;
}
.topic-cell__kind {
  font-family: var(--font-mono);
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: oklch(0.42 0.02 240);
  padding: 2px 6px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
}
.topic-cell__count {
  font-family: var(--font-mono);
  font-size: 30px;
  color: var(--color-fg-primary);
  letter-spacing: -0.02em;
  font-weight: 500;
  line-height: 1;
}
.topic-cell__count small {
  font-size: 11px;
  color: var(--color-fg-muted);
  margin-left: 4px;
  letter-spacing: 0.08em;
}
.topic-cell__spark {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 56px;
  pointer-events: none;
  overflow: hidden;
}
.topic-cell__spark svg {
  width: 100%;
  height: 100%;
  display: block;
}
.topic-cell__spark polygon { fill: var(--color-accent-cyan); opacity: 0.06; }
.topic-cell__spark polyline {
  fill: none;
  stroke: var(--color-accent-cyan);
  stroke-width: 1.4;
  opacity: 0.4;
  stroke-dasharray: 100;
  stroke-dashoffset: 0;
  transition: opacity 240ms var(--ease-spring);
}
.topic-cell:hover .topic-cell__spark polyline { opacity: 1; }
.topic-cell:hover .topic-cell__spark polygon { opacity: 0.18; }
.topic-cell::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 2px; width: 0;
  background: var(--color-accent-cyan);
  transition: width 280ms var(--ease-spring);
  box-shadow: 0 0 8px var(--color-accent-cyan-glow);
}
.topic-cell:hover::after { width: 100%; }

/* Coverage ledger — topic count bars. */
.coverage-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.coverage-cell {
  position: relative;
  padding: 16px 20px;
  border: 1px solid oklch(0.28 0.02 240);
  border-radius: 10px;
  background: oklch(0.20 0.02 240 / 0.5);
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  transition: 200ms var(--ease-spring);
}
.coverage-cell:hover {
  border-color: oklch(0.83 0.13 215 / 0.4);
}
.coverage-cell__name {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-fg-primary);
  letter-spacing: 0.04em;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.coverage-cell__name code {
  font-family: var(--font-mono);
  font-size: 9px;
  color: var(--color-fg-muted);
  letter-spacing: 0.06em;
  padding: 2px 6px;
  background: var(--color-bg-raised);
  border-radius: 4px;
}
.coverage-cell__num {
  font-family: var(--font-mono);
  font-size: 24px;
  font-weight: 500;
  color: var(--color-fg-primary);
  letter-spacing: -0.02em;
}
.coverage-cell__meta {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--color-fg-muted);
  text-transform: uppercase;
}
.coverage-cell__bar {
  position: absolute;
  left: 0; bottom: 0;
  height: 3px;
  background: linear-gradient(to right, var(--color-accent-cyan), transparent);
  box-shadow: 0 0 6px var(--color-accent-cyan-glow);
  transition: width 600ms var(--ease-spring);
}

/* Footer CTA card — bordered subscribe card before the regular footer. */
.foot-cta {
  position: relative;
  padding: 32px;
  border: 1px dashed oklch(0.83 0.13 215 / 0.4);
  border-radius: 14px;
  background:
    radial-gradient(180% 60% at 0% 0%, oklch(0.83 0.13 215 / 0.18), transparent 60%),
    oklch(0.20 0.02 240 / 0.7);
  overflow: hidden;
  margin-top: 32px;
}
.foot-cta::after {
  content: "";
  position: absolute;
  right: -40px; top: -40px;
  width: 220px; height: 220px;
  border-radius: 50%;
  background: radial-gradient(closest-side, var(--color-accent-cyan-glow), transparent);
  pointer-events: none;
}
.foot-cta__eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-cyan);
  position: relative;
  z-index: 1;
}
.foot-cta__heading {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 28px;
  line-height: 1.15;
  margin: 8px 0 8px;
  letter-spacing: -0.01em;
  position: relative;
  z-index: 1;
}
.foot-cta__lead {
  font-family: var(--font-body);
  font-size: 15px;
  color: var(--color-fg-secondary);
  line-height: 1.55;
  margin: 0 0 20px;
  max-width: 44ch;
  position: relative;
  z-index: 1;
}
.foot-cta__row {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  position: relative;
  z-index: 1;
}

/* Hero-v2 radar enlarges the existing inline-block .hero-radar to fit
   the stage. The cursor + filter rules from Phase 5 still apply. */
.hero-v2 .hero-radar { display: block; }
.hero-v2 .hero-radar svg { width: 100%; height: 100%; }

/* RM degradation for the new home surfaces. The universal RM rule
   zeroes transitions/animations; below pins static end-states so the
   visual signal survives. */
@media (prefers-reduced-motion: reduce) {
  .ingestion__cell[data-active="true"] { opacity: 0.85; }
  .hero-v2__badge { opacity: 1; }
  .topic-cell__spark polyline { stroke-dashoffset: 0; opacity: 1; }
}

/* Print parity for the new home surfaces. */
@media print {
  .ingestion,
  .hero-v2__badges,
  .foot-cta,
  .topic-ribbon,
  .coverage-grid {
    display: none !important;
  }
}

/* ============================================================
   v2.1 — Tweaks panel (design handoff).
   Floating trigger (bottom-right) + slide-in card with palette,
   mesh, motion, density, scanlines, sound, theme controls.
   ============================================================ */
.tweaks-trigger {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: 80;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  background: oklch(0.22 0.025 240 / 0.85);
  color: var(--color-fg-secondary);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 18px oklch(0 0 0 / 0.35);
  transition:
    transform 200ms var(--ease-spring),
    border-color 200ms,
    color 200ms;
  cursor: pointer;
}
.tweaks-trigger:hover {
  border-color: var(--color-accent-cyan);
  color: var(--color-accent-cyan);
  transform: translateY(-1px);
}
.tweaks-trigger[aria-expanded="true"] {
  border-color: var(--color-accent-cyan);
  color: var(--color-accent-cyan);
  box-shadow: 0 6px 18px var(--color-accent-cyan-glow);
}

.tweaks-panel {
  position: fixed;
  right: 16px;
  bottom: 72px;
  z-index: 79;
  width: min(320px, calc(100vw - 32px));
  padding: 16px;
  border-radius: 14px;
  border: 1px solid var(--color-accent-cyan);
  background:
    radial-gradient(140% 60% at 100% 0%, var(--color-accent-cyan-glow), transparent 60%),
    oklch(0.20 0.022 240 / 0.95);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 24px 60px -16px oklch(0 0 0 / 0.6);
  display: flex;
  flex-direction: column;
  gap: 14px;
  font-family: var(--font-ui);
}
@media (max-width: 480px) {
  .tweaks-panel {
    right: 8px;
    left: 8px;
    width: auto;
    bottom: 64px;
  }
}
.tweaks-panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.tweaks-panel__eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-cyan);
}
.tweaks-panel__close {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  border: 1px solid var(--color-border);
  color: var(--color-fg-muted);
  transition: 160ms;
  cursor: pointer;
}
.tweaks-panel__close:hover {
  color: var(--color-accent-cyan);
  border-color: var(--color-accent-cyan);
}
.tweaks-group {
  border: 0;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tweaks-group__label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-fg-muted);
}
.tweaks-group__row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.tweaks-panel .palette-swatch {
  width: 32px;
  height: 32px;
}
.tweaks-panel .palette-swatch::after {
  width: 14px;
  height: 14px;
}
.tweaks-pill {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--color-fg-secondary);
  padding: 6px 10px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: oklch(0.20 0.02 240 / 0.6);
  text-transform: lowercase;
  cursor: pointer;
  transition: 160ms var(--ease-spring);
}
.tweaks-pill:hover {
  color: var(--color-fg-primary);
  border-color: var(--color-accent-cyan-dim);
}
.tweaks-pill[data-active="true"] {
  color: var(--color-accent-cyan);
  border-color: var(--color-accent-cyan);
  background: oklch(0.83 0.13 215 / 0.12);
  box-shadow: 0 0 16px -4px var(--color-accent-cyan-glow);
}
.tweaks-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  color: var(--color-fg-secondary);
  text-transform: none;
  letter-spacing: 0.04em;
  font-size: 12px;
  font-family: var(--font-ui);
}
.tweaks-switch {
  position: relative;
  width: 40px;
  height: 22px;
  border-radius: 999px;
  background: oklch(0.30 0.025 240);
  border: 1px solid var(--color-border);
  transition: 200ms var(--ease-spring);
  cursor: pointer;
  flex-shrink: 0;
}
.tweaks-switch::before {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-fg-secondary);
  transition: 200ms var(--ease-spring);
}
.tweaks-switch[data-on="true"] {
  background: var(--color-accent-cyan);
  border-color: var(--color-accent-cyan);
  box-shadow: 0 0 12px -2px var(--color-accent-cyan-glow);
}
.tweaks-switch[data-on="true"]::before {
  left: 20px;
  background: var(--color-bg-base);
}

/* ============================================================
   v2.1 — Command-palette skin on the search overlay.
   Restyles .search-overlay so the empty/cmdk state matches the
   design's centered "cmdk" panel. The existing HTMX behaviour
   (#search-overlay-input + #search-results-overlay) is preserved.
   ============================================================ */
@media (min-width: 640px) {
  .search-overlay {
    inset: 12vh auto auto 50%;
    width: min(560px, 92vw);
    border-radius: 14px;
    border: 1px solid var(--color-accent-cyan);
    background:
      radial-gradient(140% 60% at 0% 0%, var(--color-accent-cyan-glow), transparent 60%),
      oklch(0.21 0.022 240 / 0.96);
    box-shadow:
      0 40px 80px -20px oklch(0 0 0 / 0.6),
      0 0 80px var(--color-accent-cyan-glow);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
  }
}
.search-overlay-backdrop {
  background: oklch(0.10 0.015 240 / 0.7);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.search-overlay > div:first-child {
  /* Input row — pill it with subtle border-bottom only. */
  border-bottom: 1px solid oklch(0.28 0.02 240);
}
#search-overlay-input {
  font-family: var(--font-ui);
  font-size: 16px;
}
.search-quick-actions {
  border-top: 1px solid oklch(0.28 0.02 240);
  background: transparent;
}
.search-quick-actions p {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-fg-muted);
}
.quick-action-link {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--color-fg-primary);
  border-radius: 8px;
  padding: 8px 12px;
  transition: 120ms var(--ease-spring);
}
.quick-action-link:hover,
.quick-action-link:focus-visible {
  background: oklch(0.83 0.13 215 / 0.12);
  border-color: oklch(0.83 0.13 215 / 0.4);
  color: var(--color-accent-cyan);
}
.quick-action-link .kbd-key,
.quick-action-link kbd {
  background: oklch(0.18 0.02 240);
  border: 1px solid var(--color-border);
  color: var(--color-fg-muted);
}

@media (prefers-reduced-motion: reduce) {
  .tweaks-trigger,
  .tweaks-pill,
  .tweaks-switch,
  .tweaks-switch::before { transition: none !important; }
}
