/* dreamy blurry gradient base */
:root {
  --fg: #f5f0ff;
  --fg-dim: #b0a4d8;
  --shell: rgba(8, 6, 22, 0.45);
  --card: rgba(18, 14, 38, 0.55);
  --card-edge: rgba(255, 255, 255, 0.10);
  --good: #6ee7b7;
  --bad: #f87171;
  --unknown: #888;
}

/* ---------- passcode gate ---------- */
.gate {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  background: rgba(10, 4, 24, 0.35);
  backdrop-filter: blur(24px) saturate(1.2);
  -webkit-backdrop-filter: blur(24px) saturate(1.2);
  transition: opacity 1.2s ease, transform 1.2s ease;
}
.gate.dismissed {
  opacity: 0;
  transform: scale(1.08);
  pointer-events: none;
}
.gate-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 28px;
  padding: 48px 56px;
}
.gate-brand {
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  opacity: 0.55;
}
.gate-title {
  font-size: clamp(28px, 4vw, 44px);
  font-weight: 200;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 30px rgba(255,255,255,0.2);
}
.gate-digits {
  display: flex;
  gap: 10px;
}
.gate-digit {
  width: 86px;
  height: 124px;
  padding: 0;
  border-radius: 18px;
  background: rgba(20, 14, 44, 0.6);
  border: 1px solid var(--card-edge);
  color: var(--fg);
  text-align: center;
  font-size: 46px;
  font-weight: 300;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-feature-settings: "tnum" 1;
  letter-spacing: -0.01em;
  outline: none;
  caret-color: transparent;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, background 0.3s ease;
  text-shadow: 0 2px 24px rgba(255,255,255,0.32);
  backdrop-filter: blur(6px);
}
.gate-digit::placeholder { color: rgba(255,255,255,0.16); }
.gate-digit:focus {
  border-color: rgba(255,255,255,0.45);
  box-shadow: 0 0 0 4px rgba(255,255,255,0.06), 0 0 28px 4px rgba(245,158,11,0.18) inset;
  transform: translateY(-2px);
}
.gate-digit.filled {
  background: rgba(20, 14, 44, 0.85);
  border-color: rgba(255,255,255,0.25);
}
.gate-digit.wrong {
  animation: shake 0.45s cubic-bezier(.36,.07,.19,.97) both;
  border-color: rgba(248, 113, 113, 0.55);
  color: var(--bad);
}
@keyframes shake {
  10%, 90% { transform: translate3d(-1px, 0, 0); }
  20%, 80% { transform: translate3d(2px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-4px, 0, 0); }
  40%, 60% { transform: translate3d(4px, 0, 0); }
}
.gate-digit.correct {
  animation: glow-pulse 1s ease-out both;
  border-color: rgba(110, 231, 183, 0.55);
}
@keyframes glow-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(110,231,183, 0.6); }
  60%  { box-shadow: 0 0 0 24px rgba(110,231,183, 0); }
  100% { box-shadow: 0 0 0 0 rgba(110,231,183, 0); }
}
.gate-hint {
  font-size: 12px;
  opacity: 0.5;
  letter-spacing: 0.06em;
  text-align: center;
  min-height: 16px;
}
.gate-hint.error { color: var(--bad); opacity: 0.85; }


* { box-sizing: border-box; }
/* Disable double-tap-to-zoom across the app — preserves single-tap latency
   and prevents the scene canvas from getting stuck at a small render size
   after a pinch/double-tap zoom on mobile. */
html { touch-action: manipulation; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
button, .tag-chip, .icon-btn, .nav-tab, .vis-toggle, .auto-drift-toggle, .filter-panel-apply { touch-action: manipulation; }
html, body { margin: 0; padding: 0; overflow-x: hidden; background: #0a0418; color: var(--fg); font-family: 'Inter', system-ui, -apple-system, sans-serif; }
html { height: 100%; }
body { min-height: 100vh; }

#scene {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  /* heavier blur — larger orbs already overlap, so the field reads as soft fog */
  filter: blur(12px) saturate(1.18);
}
/* Multi-layer background blend stack (Slice 27). Bottom → top:
     z:0  #scene             — Three.js canvas (orbs + particles + bg shader)
     z:1  body::before       — low-freq luminosity mottling (soft-light)
     z:2  html::before       — color-wash with slow hue-rotate (color-dodge)
     z:3  body::after        — analog film grain (overlay)
     z:4  html::after        — vignette darkening at edges (multiply)
     z:10 .ui                — content
   pointer-events:none everywhere so layers never intercept input. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'%3E%3Cfilter id='lum'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012' numOctaves='2' stitchTiles='stitch' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23lum)'/%3E%3C/svg%3E");
  opacity: .04;
  mix-blend-mode: hard-light;
  animation: bg-mottle 18s ease-in-out infinite alternate;
}
html::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(135deg,
    rgba(94, 234, 212, 0.08) 0%,
    rgba(99, 102, 241, 0.05) 50%,
    rgba(168, 85, 247, 0.08) 100%);
  mix-blend-mode: color-dodge;
  opacity: 0.2;
  animation: bg-hue-shift 60s linear infinite;
}
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='8' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.75 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 1;
  mix-blend-mode: overlay;
}
html::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  background: radial-gradient(ellipse at center,
    transparent 32%,
    rgba(0,0,0,0.32) 78%,
    rgba(0,0,0,0.55) 100%);
  mix-blend-mode: multiply;
}
@keyframes bg-mottle {
  0%   { transform: translate3d(0,    0,    0) scale(1.0);  }
  100% { transform: translate3d(-3%, -2%, 0)  scale(1.08); }
}
@keyframes bg-hue-shift {
  0%   { filter: hue-rotate(0deg); }
  100% { filter: hue-rotate(360deg); }
}

.ui {
  position: relative;
  z-index: 10;
  padding: 28px 32px 80px;   /* room for the pinned bottom bar */
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

.hud {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px;
  letter-spacing: 0.04em;
  flex-wrap: wrap;
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 700;
  font-size: 13px;
  opacity: 0.85;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
  transition: opacity 0.18s;
}
.brand:hover { opacity: 1; }
.brand-logo { color: var(--fg); opacity: 0.85; }
.brand-logo line { transform-origin: 16px 16px; animation: brand-spin 8s linear infinite; }
@keyframes brand-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
.hint { font-size: 12px; opacity: 0.55; }
.provider {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  opacity: 0.6;
  padding: 3px 9px;
  border: 1px solid var(--card-edge);
  border-radius: 999px;
}

.nav { display: flex; gap: 4px; }
.nav-tab {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  padding: 5px 14px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.2s ease, background 0.2s ease, border-color 0.2s ease;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.nav-tab.help-tab {
  padding: 5px 11px;
  font-weight: 600;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
/* Icon-only nav tabs (saved, history) — square-ish chip with no label text. */
.nav-tab.nav-icon-tab {
  padding: 5px 9px;
  gap: 5px;
}
.nav-tab.nav-icon-tab svg { display: block; }
.nav-tab:hover { opacity: 0.85; }
.nav-tab.active {
  opacity: 1;
  background: rgba(255,255,255,0.08);
  border-color: rgba(255,255,255,0.2);
}
.nav-tab .badge {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,0.08);
  opacity: 0.85;
}

.author-wrap { display: none; }
.author-input.legacy-author { display: none; }   /* hidden — see HTML comment */
.author-input {
  background: transparent;
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  color: var(--fg);
  padding: 4px 10px;
  font-size: 12px;
  width: 120px;
  outline: none;
}
.author-input::placeholder { color: rgba(255,255,255,0.3); }
.author-input:focus { border-color: rgba(255,255,255,0.4); }

/* ---------- login pill (head icon + name; opens rename modal) ---------- */
.login-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 10px;
}
.login-pill .login-icon {
  opacity: 0.85;
  flex-shrink: 0;
}
.login-pill .login-name {
  font-size: 11px;
  letter-spacing: 0.04em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.login-pill.signed-in .login-name {
  color: var(--good);
  opacity: 0.9;
}
.login-pill.signed-in .login-icon {
  color: var(--good);
  opacity: 0.85;
}

/* ---------- login modal ---------- */
.login-modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-modal[hidden] { display: none; }
.login-modal-scrim {
  position: absolute;
  inset: 0;
  background: rgba(8, 4, 22, 0.55);
  backdrop-filter: blur(8px);
}
.login-modal-card {
  position: relative;
  z-index: 1;
  width: min(420px, 92vw);
  padding: 26px 28px 22px;
  background: rgba(12, 8, 30, 0.95);
  border: 1px solid var(--card-edge);
  border-radius: 16px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.55);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.login-modal-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.85;
}
.login-modal-body {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  opacity: 0.65;
}
#login-name-input,
#add-name-input,
#add-name-notes {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  border-radius: 8px;
  color: var(--fg);
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.2;
  font-family: inherit;
  outline: none;
  transition: border-color 0.18s;
}
/* Single-line inputs need a tighter line-height + explicit height so the
   caret + text sit centered in the box (default 1.5 line-height made the
   prefilled name visually float above center). */
#login-name-input,
#add-name-input {
  height: 40px;
}
#login-name-input:focus,
#add-name-input:focus,
#add-name-notes:focus { border-color: rgba(255,255,255,0.4); }
#add-name-notes { resize: vertical; min-height: 64px; font-family: inherit; }
.login-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
}
.login-modal-cancel,
.login-modal-save {
  background: transparent;
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  color: var(--fg);
  padding: 6px 16px;
  font-size: 12px;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-family: inherit;
  transition: border-color 0.18s, background 0.18s;
}
.login-modal-cancel:hover { border-color: rgba(255,255,255,0.4); }
.login-modal-save {
  background: var(--fg);
  color: #0a0418;
  border-color: var(--fg);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.login-modal-save:hover { transform: translateY(-1px); }

/* ---------- session cost pill (replaces the old model picker) ---------- */
.cost-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: rgba(8, 6, 22, 0.6);
  color: var(--fg);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  padding: 4px 12px 4px 10px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: default;
  user-select: none;
  transition: border-color 0.18s, opacity 0.18s;
}
.cost-pill:hover { border-color: rgba(255,255,255,0.25); }
.cost-pill.warm   { border-color: rgba(245,158,11,0.45); }
.cost-pill.hot    { border-color: rgba(248,113,113,0.55); color: var(--bad); }
.cost-pill.error  { opacity: 0.55; }
.cost-pill-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--good);
  box-shadow: 0 0 6px var(--good);
}
.cost-pill.warm .cost-pill-dot { background: #f59e0b; box-shadow: 0 0 6px #f59e0b; }
.cost-pill.hot  .cost-pill-dot { background: var(--bad);  box-shadow: 0 0 6px var(--bad); }
.cost-pill.error .cost-pill-dot { background: var(--unknown); box-shadow: none; }

.model-wrap { display: none; }    /* legacy hidden — kept so older builds don't 404 */
.model-picker {
  background: rgba(8, 6, 22, 0.6);
  color: var(--fg);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  padding: 4px 24px 4px 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.02em;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  outline: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 16 16' fill='%23b0a4d8'><path d='M8 11 2 5h12z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 8px center;
  opacity: 0.8;
  transition: opacity 0.2s, border-color 0.2s;
}
.model-picker:hover, .model-picker:focus { opacity: 1; border-color: rgba(255,255,255,0.25); }
.model-picker option { background: #0a0418; color: var(--fg); }

.view { display: flex; flex-direction: column; gap: 26px; }
.view[hidden] { display: none; }

/* ---------- saved page ---------- */
.saved-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding-top: 12px;
  flex-wrap: wrap;
}
.saved-search {
  flex: 0 1 240px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  color: var(--fg);
  padding: 6px 14px;
  font-size: 12px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  outline: none;
  transition: border-color 0.18s, background 0.18s;
}
.saved-search:focus {
  border-color: rgba(255,255,255,0.4);
  background: rgba(255,255,255,0.07);
}
.saved-search::placeholder { color: rgba(255,255,255,0.35); }
/* Hide the native browser "clear" icon in WebKit search inputs since we
   don't style for it. */
.saved-search::-webkit-search-cancel-button { -webkit-appearance: none; }

.export-btn {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 12px;
  letter-spacing: 0.04em;
  cursor: pointer;
  opacity: 0.75;
  transition: opacity 0.18s, border-color 0.18s, background 0.18s;
  font-family: inherit;
}
.export-btn:hover { opacity: 1; border-color: rgba(255,255,255,0.35); background: rgba(255,255,255,0.04); }
.export-btn.busy { opacity: 0.5; cursor: default; }
.saved-title {
  font-size: 32px;
  font-weight: 200;
  letter-spacing: -0.01em;
  margin: 0;
}
.saved-meta { font-size: 12px; opacity: 0.55; }
/* Slice 45: saved list reuses the .feed grid + .feed-card chassis so the
   saved tab looks identical to the drift tab. The only saved-specific
   bits are the per-card stars wrapper and the rating meta/breakdown
   that get appended after the action row. */
.saved-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 4px;
}
@media (max-width: 720px) {
  .saved-list { grid-template-columns: 1fr; }
}
.saved-empty {
  text-align: center;
  padding: 60px 20px;
  opacity: 0.5;
  font-size: 13px;
  grid-column: 1 / -1;     /* span both feed columns */
}
.saved-stars { display: inline-flex; align-items: center; gap: 6px; }
.saved-avg   { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px; opacity: 0.8; }
.saved-count { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 10.5px; opacity: 0.5; margin-left: -2px; }
.feed-card .breakdown { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; font-size: 10.5px; }
.feed-card .author-tag {
  padding: 1px 6px;
  border-radius: 4px;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--card-edge);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  opacity: 0.75;
}

/* ---------- history tab (Slice 37) ---------- */
.history-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  padding-top: 12px;
  flex-wrap: wrap;
}
.history-title {
  font-size: 32px;
  font-weight: 200;
  letter-spacing: -0.01em;
  margin: 0;
}
.history-meta {
  flex: 1 1 0;
  font-size: 12px;
  opacity: 0.55;
}
.history-clear {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 12px;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-family: inherit;
  opacity: 0.65;
  transition: opacity 0.18s, border-color 0.18s, color 0.18s;
}
.history-clear:hover { opacity: 1; border-color: rgba(248,113,113,0.45); color: var(--bad); }
.history-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.history-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  text-align: center;
  padding: 56px 20px;
  color: var(--fg-dim);
}
.history-empty-icon {
  opacity: 0.45;
  display: flex;
  align-items: center;
  justify-content: center;
}
.history-empty-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  opacity: 0.85;
}
.history-empty-sub {
  font-size: 12px;
  opacity: 0.6;
  letter-spacing: 0.02em;
}
.history-card {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 12px;
  padding: 12px 16px;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "head replay" "filter replay";
  gap: 4px 14px;
  align-items: center;
  backdrop-filter: blur(20px);
  transition: border-color 0.18s, transform 0.15s;
}
.history-card:hover { border-color: rgba(255,255,255,0.22); transform: translateY(-1px); }
.history-head {
  grid-area: head;
  display: flex;
  align-items: baseline;
  gap: 12px;
  min-width: 0;
}
.history-ts {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  opacity: 0.55;
  flex-shrink: 0;
}
.history-seed {
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.history-filter {
  grid-area: filter;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
  opacity: 0.7;
  letter-spacing: 0.02em;
}
.history-zone {
  padding: 1px 8px;
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  background: rgba(255,255,255,0.03);
}
.history-zone.history-and  { color: #fbbf24; border-color: rgba(251,191,36,0.35); }
.history-zone.history-or   { color: #93c5fd; border-color: rgba(147,197,253,0.35); }
.history-zone.history-perm { color: #fca5a5; border-color: rgba(252,165,165,0.35); }
.history-zone.history-models { color: var(--fg-dim); }
.history-count { opacity: 0.5; }
.history-replay {
  grid-area: replay;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 12px;
  letter-spacing: 0.06em;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.18s, border-color 0.18s, transform 0.15s;
}
.history-replay:hover {
  background: rgba(255,255,255,0.12);
  border-color: rgba(255,255,255,0.4);
  transform: translateY(-1px);
}

/* ---------- help page ---------- */
.help {
  max-width: 720px;
  margin: 12px auto 60px;
  padding: 28px 32px;
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  backdrop-filter: blur(20px);
  line-height: 1.6;
  font-size: 14px;
}
.help-title {
  font-size: 28px;
  font-weight: 200;
  margin: 0 0 8px;
}
.help-lede {
  opacity: 0.85;
  margin: 0 0 22px;
}
.help h3 {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.65;
  margin: 22px 0 10px;
}
.help ul, .help ol {
  padding-left: 22px;
  margin: 0 0 14px;
}
.help li { margin: 6px 0; opacity: 0.85; }
.help li b { color: var(--fg); }
.help code {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  padding: 1px 6px;
  background: rgba(255,255,255,0.07);
  border-radius: 4px;
}
.help a { color: var(--good); text-decoration: none; border-bottom: 1px solid rgba(110,231,183,0.4); }
.help a:hover { color: #fff; border-bottom-color: rgba(255,255,255,0.8); }
.help-footer { opacity: 0.55; font-size: 12px; margin-top: 26px; }

.save-this {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  opacity: 0.7;
  /* Stable width regardless of state ("save" / "saved" / "busy") so the
     button doesn't reflow when a save lands. */
  min-width: 70px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.save-this:hover { opacity: 1; border-color: rgba(110, 231, 183, 0.5); color: var(--good); }
.save-this.saved { color: var(--good); border-color: rgba(110, 231, 183, 0.5); cursor: default; pointer-events: none; }
.save-this.busy  { opacity: 0.5; pointer-events: none; }

.copy-this {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  opacity: 0.7;
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 11px;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-weight: 500;
  min-width: 64px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  transition: background 0.2s, border-color 0.2s, color 0.2s, opacity 0.18s;
  font-family: inherit;
}
.copy-this:hover  { opacity: 1; border-color: rgba(94,234,212,0.5); color: #5eead4; }
.copy-this.copied { color: #5eead4; border-color: rgba(94,234,212,0.6); }

/* Slice 42 — variations button. Shares the copy-this chassis but tints to
   amber (matches the language tag color) so it reads as a "branch into a
   related word" affordance rather than a clipboard action. */
.variations-this {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  opacity: 0.7;
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 11px;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-weight: 500;
  min-width: 84px;
  text-align: center;
  transition: background 0.2s, border-color 0.2s, color 0.2s, opacity 0.18s;
  font-family: inherit;
}
.variations-this:hover { opacity: 1; border-color: rgba(245,158,11,0.55); color: #fbbf24; }

/* Slice 43 — unified icon buttons. Used identically on drift cards and
   saved cards via buildCandidateActions in util.js. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  background: transparent;
  border: 1px solid var(--card-edge);
  border-radius: 8px;
  color: var(--fg);
  opacity: 0.7;
  cursor: pointer;
  transition: background 0.18s, border-color 0.18s, color 0.18s, opacity 0.18s, transform 0.12s;
  padding: 0;
}
.icon-btn:hover { opacity: 1; transform: translateY(-1px); }
.icon-btn:active { transform: translateY(0); }
.icon-btn svg { display: block; }
.icon-btn:disabled { cursor: default; pointer-events: none; }
.icon-btn.busy { opacity: 0.5; pointer-events: none; }

/* Per-action tint on hover. */
.icon-btn.center-btn:hover     { border-color: rgba(167,139,250,0.55); color: #c4b5fd; }
.icon-btn.save-btn:hover       { border-color: rgba(110,231,183,0.55); color: var(--good); }
.icon-btn.copy-btn:hover       { border-color: rgba(94,234,212,0.55);  color: #5eead4; }
.icon-btn.variations-btn:hover { border-color: rgba(245,158,11,0.55);  color: #fbbf24; }
.icon-btn.save-btn.saved {
  border-color: rgba(110,231,183,0.55);
  color: var(--good);
  opacity: 1;
}
.icon-btn.flash-ok { border-color: rgba(94,234,212,0.6); color: #5eead4; opacity: 1; }

/* Smaller refresh button inside the domain row. */
.icon-refresh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-left: 2px;
  background: transparent;
  border: 1px solid var(--card-edge);
  border-radius: 6px;
  color: var(--fg);
  opacity: 0.55;
  cursor: pointer;
  padding: 0;
  transition: opacity 0.18s, border-color 0.18s, color 0.18s, transform 0.4s;
}
.icon-refresh-btn:hover { opacity: 1; border-color: rgba(255,255,255,0.35); }
.icon-refresh-btn.spinning svg { animation: refresh-spin 0.8s linear infinite; }
@keyframes refresh-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ---------- star rating widget ---------- */
.stars {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  letter-spacing: 1px;
  user-select: none;
}
.stars.editable .star { cursor: pointer; transition: transform 0.1s ease; }
.stars.editable .star:hover { transform: scale(1.18); }
.star {
  font-size: 14px;
  line-height: 1;
  color: rgba(255,255,255,0.18);
  background: none;
  border: none;
  padding: 0 1px;
  font-family: inherit;
}
.star.filled { color: #c8a96a; }   /* muted, low-saturation gold */
.star.half {
  position: relative;
  color: rgba(255,255,255,0.18);
}
.star.half::before {
  content: "★";
  position: absolute;
  left: 1px;
  top: 0;
  color: #c8a96a;
  width: 50%;
  overflow: hidden;
}
.rating-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  opacity: 0.85;
  margin-top: 2px;
  flex-wrap: wrap;
}
.rating-row .avg-label {
  opacity: 0.55;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10px;
}
.rating-row .your-label {
  opacity: 0.5;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.rating-row .breakdown {
  width: 100%;
  font-size: 10px;
  opacity: 0.55;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.rating-row .breakdown .author-tag { white-space: nowrap; margin-right: 8px; }

.trail {
  font-size: 12px;
  opacity: 0.5;
  min-height: 16px;
  letter-spacing: 0.05em;
}
.trail .arrow { opacity: 0.4; margin: 0 6px; }

/* ---------- "current center" display (Slice 6c: glass card, lighter) ---------- */
.selected {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  scroll-margin-top: 96px;
}
.selected-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.5;
}
/* Lighter card, smaller max-width. No split-flap dark gradient anymore. */
.selected-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 6px 20px;
  width: min(500px, 95vw);
  border-radius: 14px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--card-edge);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.05),
    0 8px 30px rgba(0,0,0,0.35);
  backdrop-filter: blur(20px) saturate(1.1);
}
/* Seed input: thinner weight, monospace feel, 0.8 opacity, more letter
   spacing. Read-only by default — pointer-events:none, caret hidden, no tab
   focus. The pencil button toggles `.editing` to unlock everything. */
.seed-input {
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  border: none;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: clamp(20px, 3.6vw, 34px);
  font-weight: 200;
  letter-spacing: 0.06em;
  color: var(--fg);
  text-align: left;
  outline: none;
  padding: 10px 10px;
  opacity: 0.8;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  caret-color: transparent;
  cursor: default;
  text-shadow: 0 0 18px rgba(255,255,255,0.12);
}
.seed-input::placeholder { color: rgba(255,255,255,0.2); }
.seed-input.editing {
  pointer-events: auto;
  user-select: text;
  -webkit-user-select: text;
  cursor: text;
  background: rgba(255,255,255,0.05);
  border-radius: 8px;
  opacity: 1;
  caret-color: rgba(255,255,255,0.85);
}
.seed-input.editing:focus { color: #fff; }

.edit-seed, #reset {
  position: relative;
  background: transparent;
  border: 1px solid var(--card-edge);
  color: #fff;                     /* was --fg-dim — now pure white */
  width: 36px;
  height: 36px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 15px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.2s, border-color 0.2s, background 0.2s, transform 0.15s;
  -webkit-tap-highlight-color: rgba(255,255,255,0.1);
  touch-action: manipulation;
}
/* Reset button: a bit larger and lighter-weight than the pencil so the
   ↺ glyph reads as decisive without crowding the seed. */
#reset {
  width: 42px;
  height: 42px;
  font-size: 22px;
  font-weight: 200;
  line-height: 1;
}
/* Invisible square hit-target that extends beyond the visible disc. */
.edit-seed::after, #reset::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 12px;
}
@media (max-width: 640px) {
  .edit-seed { width: 44px; height: 44px; }
  #reset     { width: 48px; height: 48px; font-size: 24px; }
  .edit-seed::after, #reset::after { inset: -8px; }
}
.edit-seed:hover, #reset:hover { border-color: rgba(255,255,255,0.55); background: rgba(255,255,255,0.05); }
#reset:hover { transform: rotate(-90deg); }
.edit-seed.confirming {
  color: var(--good);
  border-color: rgba(110,231,183,0.5);
  background: rgba(110,231,183,0.06);
}
/* Make the inner SVGs ignore pointer events. Otherwise hit-testing only
 * registers clicks that land on the path stroke (i.e. the diagonal of the
 * pencil glyph), leaving dead corners around it. */
.edit-seed svg, .center-this svg, .center-this *, .save-this *, .refresh-btn * {
  pointer-events: none;
}
.edit-seed.confirming:hover { color: #fff; background: rgba(110,231,183,0.15); }
.edit-seed .icon-check { display: none; }
.edit-seed.confirming .icon-pencil { display: none; }
.edit-seed.confirming .icon-check { display: inline-block; }
#reset { margin-right: 6px; }
.selected-desc {
  font-size: 13px;
  line-height: 1.5;
  opacity: 0.72;
  text-align: center;
  max-width: 720px;
  min-height: 20px;
  letter-spacing: 0.01em;
}

.status-line {
  text-align: center;
  opacity: 0.55;
  font-size: 12px;
  min-height: 16px;
  letter-spacing: 0.02em;
  white-space: pre-line;
}
.status-line.error { color: var(--bad); opacity: 0.9; }

/* ---------- tag picker (multi-select buckets) ---------- */
.tag-picker {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.tag-category {
  background: var(--shell);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  padding: 10px 14px;
  backdrop-filter: blur(14px);
}
.tag-category-header {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 8px;
}
.tag-category-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0.7;
}
.tag-category-hint {
  font-size: 11px;
  opacity: 0.45;
}
.tag-category-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
}
.tag-chip {
  background: rgba(255, 255, 255, 0.03);
  color: var(--fg);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  padding: 5px 11px;
  font-size: 12px;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: background 0.18s, border-color 0.18s, color 0.18s, transform 0.12s;
}
.tag-chip:hover { background: rgba(255, 255, 255, 0.07); transform: translateY(-1px); }
.tag-chip.selected {
  background: var(--cat-color, var(--fg));
  color: #0a0418;
  border-color: var(--cat-color, var(--fg));
  font-weight: 600;
}
.tag-chip.custom-chip {
  border-style: dashed;
  opacity: 0.85;
  background: transparent;
}
.tag-chip.custom-chip:hover { opacity: 1; }
.tag-custom-input {
  flex: 1 1 160px;
  min-width: 140px;
  background: transparent;
  border: 1px dashed var(--card-edge);
  border-radius: 999px;
  padding: 5px 11px;
  color: var(--fg);
  font-size: 12px;
  outline: none;
  letter-spacing: 0.01em;
}
.tag-custom-input::placeholder { color: rgba(255,255,255,0.32); font-style: italic; }
.tag-custom-input:focus { border-color: rgba(255,255,255,0.35); background: rgba(255,255,255,0.03); }

/* ---------- drift bar ---------- */
.drift-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-top: 4px;
}
.drift-btn {
  background: var(--fg);
  color: #0a0418;
  border: 1px solid var(--fg);
  border-radius: 999px;
  padding: 10px 28px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.2s ease;
  box-shadow: 0 8px 30px rgba(255,255,255,0.12);
}
.drift-btn:hover { transform: translateY(-2px); box-shadow: 0 12px 38px rgba(255,255,255,0.18); }
.drift-btn:disabled, .drift-btn.busy { opacity: 0.5; cursor: default; transform: none; }
.drift-hint { font-size: 11px; opacity: 0.5; }

.candidates {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 4px;
}

.candidate {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  padding: 14px 16px;
  transition: transform 0.15s ease, border-color 0.2s ease, background 0.2s ease;
  display: flex;
  flex-direction: column;
  gap: 6px;
  backdrop-filter: blur(20px);
  position: relative;
}
.candidate.current {
  border-color: rgba(255,255,255,0.28);
  background: linear-gradient(180deg, rgba(255,255,255,0.06), rgba(255,255,255,0.02));
}
.candidate.current::before {
  content: "current";
  position: absolute;
  top: 8px;
  right: 12px;
  font-size: 9px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.55;
}
/* Unavailable-domain candidates used to fade. The user preferred uniform
 * opacity; the domain badges already communicate availability. */
.candidate.dim { opacity: 1; }
.candidate-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.center-this, .save-this {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  font-size: 11px;
  letter-spacing: 0.04em;
  border-radius: 999px;
  cursor: pointer;
  font-weight: 500;
  transition: background 0.2s, border-color 0.2s, color 0.2s;
}
.center-this {
  background: var(--fg);
  color: #0a0418;
  border: 1px solid var(--fg);
}
.center-this:hover {
  background: #fff;
  border-color: #fff;
}
.center-this.is-current,
.center-this[disabled] {
  background: rgba(255,255,255,0.12);
  color: var(--fg);
  border-color: rgba(255,255,255,0.2);
  cursor: default;
  pointer-events: none;
}
.center-icon { display: inline-block; }
.candidate .name {
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
}
.candidate .why {
  font-size: 12px;
  opacity: 0.6;
  line-height: 1.4;
}
.candidate .domains {
  display: flex;
  gap: 8px;
  margin-top: 4px;
  font-size: 11px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.02em;
  align-items: center;
}
.refresh-btn {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg-dim);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  font-size: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.18s, border-color 0.18s, transform 0.4s;
}
.refresh-btn:hover { color: var(--fg); border-color: rgba(255,255,255,0.4); }
.refresh-btn.spinning { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.candidate .tld {
  padding: 2px 8px;
  border-radius: 5px;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--card-edge);
}
.candidate .tld.available { color: var(--good); border-color: rgba(110,231,183,0.4); }
.candidate .tld.registered { color: var(--bad); opacity: 0.55; }
.candidate .tld.error, .candidate .tld.unknown { color: var(--unknown); }

.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 36px 16px 28px;
  opacity: 0.92;
}
.loading-words-scramble {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.14em;
  color: var(--fg-dim);
  text-align: center;
  width: 100%;
  max-width: 520px;
  min-height: 18px;
  /* Monospace + tabular-nums keeps the text width stable as letters lock
     in, so the surrounding layout doesn't jitter on each tick. */
  font-feature-settings: "tnum" 1;
  text-shadow: 0 0 6px currentColor;
  opacity: 0.82;
  white-space: pre;          /* preserve spaces that the scrambler skips */
}

.loading-label {
  font-size: 14px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg);
  display: flex;
  align-items: center;
  gap: 12px;
}
.loading-label .pulse-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: currentColor;
  animation: pulse 1.2s ease-in-out infinite;
  box-shadow: 0 0 12px 2px currentColor;
}
@keyframes pulse {
  0%, 100% { transform: scale(0.6); opacity: 0.4; }
  50% { transform: scale(1.2); opacity: 1; }
}

.loading-arc {
  width: 56px;
  height: 56px;
  position: relative;
}
.loading-arc::before, .loading-arc::after {
  content: '';
  position: absolute;
  inset: 0;
  border: 2px solid transparent;
  border-radius: 50%;
}
.loading-arc::before {
  border-top-color: currentColor;
  border-right-color: currentColor;
  animation: arc-spin 1.6s linear infinite;
  opacity: 0.85;
}
.loading-arc::after {
  border-bottom-color: currentColor;
  animation: arc-spin 2.4s linear infinite reverse;
  opacity: 0.45;
  inset: 6px;
}
@keyframes arc-spin {
  to { transform: rotate(360deg); }
}

/* ---------- infinite-scroll feed (v2) ---------- */
/* Max 2 columns on desktop, 1 on mobile. Cards are wide-format with a
   left "name column" and a right "body column". */
.feed {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  margin-top: 4px;
  position: relative;
}
@media (max-width: 720px) {
  .feed { grid-template-columns: 1fr; }
}
.feed-card {
  background: var(--card);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  padding: 22px 18px 14px;     /* extra top so the corner badge has breathing room */
  display: grid;
  grid-template-columns: minmax(120px, 32%) 1fr;
  gap: 6px 18px;
  align-items: center;
  backdrop-filter: blur(50px);
  -webkit-backdrop-filter: blur(50px);
  position: relative;
  animation: card-enter 320ms cubic-bezier(.2,.7,.2,1) both;
  animation-delay: calc(min(var(--idx, 0), 8) * 40ms);
  will-change: transform, opacity;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}
.feed-card-name-col {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  align-self: center;
}
.feed-card-body-col {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
@media (max-width: 600px) {
  .feed-card {
    grid-template-columns: 1fr;
    gap: 6px;
  }
}
@keyframes card-enter {
  from { transform: translateY(24px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.feed-card.dim { opacity: 0.85; }
.feed-card .name-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.feed-card .name {
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
  flex: 1 1 auto;
  min-width: 0;
}
.feed-card .why {
  font-size: 12px;
  opacity: 0.7;
  line-height: 1.4;
}
.feed-card .why-expand {
  display: inline;
  background: none;
  border: none;
  padding: 0 0 0 2px;
  margin: 0;
  color: var(--fg);
  opacity: 0.55;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  transition: opacity 0.15s, color 0.15s;
}
.feed-card .why-expand:hover {
  opacity: 1;
  color: var(--good);
}
.feed-card .domains {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  font-size: 10.5px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.02em;
  align-items: center;
  flex-wrap: nowrap;
}
.feed-card .domains .slug-hint {
  opacity: 0.32;
  font-size: 10px;
  margin-left: 2px;
}
.feed-card .tld {
  padding: 2px 5px;
  border-radius: 5px;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--card-edge);
  white-space: nowrap;
}
.feed-card .tld.available { color: var(--good); border-color: rgba(110,231,183,0.4); }
.feed-card .tld.registered { color: var(--bad); opacity: 0.55; }
.feed-card .tld.error, .feed-card .tld.unknown { color: var(--unknown); }
.feed-card-actions {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  align-items: center;
  flex-wrap: wrap;
}
.feed-card .seen-chip {
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--card-edge);
  color: var(--fg-dim);
  opacity: 0.7;
}

/* "N hidden — already seen" inline pill (Slice 16).
   ALWAYS rendered alongside the seen cards it covers. CSS, driven by
   body[data-hide-dupes], decides whether to show the pill or the cards.
   Click 'show' on the pill reveals just that group, regardless of toggle. */
.hidden-batch {
  grid-column: 1 / -1;
  display: none;     /* default: hide-dupes OFF → show cards inline, pill hidden */
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 18px;
  background: rgba(255,255,255,0.025);
  border: 1px dashed var(--card-edge);
  border-radius: 12px;
  font-size: 12px;
  opacity: 0.75;
}
/* hide-dupes ON: show unexpanded pills, hide seen cards that haven't been
   individually revealed. */
body[data-hide-dupes="1"] .hidden-batch:not(.expanded) { display: flex; }
body[data-hide-dupes="1"] .feed-card-seen[data-seen-group]:not([data-revealed="1"]) {
  display: none;
}
.hidden-batch-headline { letter-spacing: 0.02em; }
.hidden-batch-show {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.18s, border-color 0.18s;
}
.hidden-batch-show:hover { opacity: 1; border-color: rgba(255,255,255,0.4); }

/* Silent-step divider — appears between batches when the seed auto-promotes */
.silent-step-divider {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 4px 8px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.6;
}
.silent-step-divider .divider-rule {
  flex: 1 1 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
}
.silent-step-divider .divider-label {
  flex: 0 0 auto;
  color: var(--fg-dim);
  text-shadow: 0 0 12px rgba(255,255,255,0.18);
}
.silent-step-divider.spinning .divider-label::after {
  content: " …";
  animation: dot-cycle 1.4s steps(4) infinite;
}
@keyframes dot-cycle {
  0%   { content: " ."; }
  25%  { content: " .."; }
  50%  { content: " ..."; }
  75%  { content: " ...."; }
}

/* End-of-cap "Keep going?" prompt */
.cap-prompt {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  padding: 28px 20px;
  background: rgba(255,255,255,0.03);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  margin-top: 8px;
  animation: cap-glow 2.6s ease-in-out infinite;
}
.cap-prompt-title { font-size: 14px; opacity: 0.8; letter-spacing: 0.02em; }
.cap-prompt-sub { font-size: 12px; opacity: 0.55; text-align: center; }
.cap-prompt-btn {
  background: var(--fg);
  color: #0a0418;
  border: 1px solid var(--fg);
  border-radius: 999px;
  padding: 8px 22px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: transform 0.15s ease;
}
.cap-prompt-btn:hover { transform: translateY(-2px); }
@keyframes cap-glow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0.06); }
  50%      { box-shadow: 0 0 32px 6px rgba(255,255,255,0.08); }
}

/* Feed loading placeholder (replaces a card during fetch) */
.feed-loading-wrap {
  grid-column: 1 / -1;
  display: flex;
  justify-content: center;
}

/* Skeleton cards (Slice 17) — shown between primer and tail landings. */
.feed-card-skeleton {
  pointer-events: none;
  user-select: none;
  cursor: default;
  background: rgba(255,255,255,0.04);
  border-color: rgba(255,255,255,0.12);
  /* Pronounced breathing: wide opacity range + slight scale + per-card
     stagger reads as a clear "loading" wave instead of a static row. */
  animation: skeleton-breathe 1.8s ease-in-out infinite;
  animation-delay: calc(min(var(--idx, 0), 8) * 110ms);
  transform-origin: center;
}
.feed-card-skeleton .skeleton-line {
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0.05) 0%,
    rgba(255,255,255,0.22) 50%,
    rgba(255,255,255,0.05) 100%
  );
  background-size: 220% 100%;
  border-radius: 6px;
  height: 14px;
  animation: skeleton-shimmer 1.9s linear infinite;
}
.feed-card-skeleton .skeleton-name {
  height: 26px;
  width: 70%;
}
.feed-card-skeleton .skeleton-why { width: 100%; margin-bottom: 4px; }
.feed-card-skeleton .skeleton-why-short { width: 78%; }
.feed-card-skeleton .skeleton-domains {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}
.feed-card-skeleton .skeleton-tld {
  width: 54px;
  height: 18px;
  background: rgba(255,255,255,0.08);
  border-radius: 6px;
}
@keyframes skeleton-breathe {
  0%, 100% { opacity: 0.35; transform: scale(0.985); }
  50%      { opacity: 0.95; transform: scale(1.005); }
}
@keyframes skeleton-shimmer {
  0%   { background-position: 220% 0; }
  100% { background-position: -120% 0; }
}

/* Failure placeholder */
.feed-failure {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  background: rgba(248,113,113,0.06);
  border: 1px solid rgba(248,113,113,0.25);
  border-radius: 12px;
  font-size: 12px;
  color: rgba(248,113,113,0.95);
}
.feed-retry {
  background: transparent;
  border: 1px solid rgba(248,113,113,0.4);
  color: var(--fg);
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.feed-retry:hover { background: rgba(248,113,113,0.08); }

/* Prefetch sentinel — invisible, only there for IntersectionObserver */
.prefetch-sentinel {
  grid-column: 1 / -1;
  height: 1px;
  pointer-events: none;
}

/* Bottom-bar "hide unavailable" toggle drives this. When ON, cards where
   BOTH .com and .ai are registered get hidden. Unknown/error/? statuses
   stay visible by design. */
body[data-hide-unavailable="1"] .feed-card[data-both-unavailable="1"] {
  display: none;
}

/* Double-tap heart pop — full-screen overlay element */
.heart-pop {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  transform: translate(-50%, -50%);
  font-size: 64px;
  color: #ff6b81;
  text-shadow: 0 0 24px rgba(255,107,129,0.6);
  animation: heart-pop 700ms ease-out forwards;
  user-select: none;
}
@keyframes heart-pop {
  0%   { transform: translate(-50%, -50%) scale(0);   opacity: 0; }
  30%  { transform: translate(-50%, -50%) scale(1.4); opacity: 1; }
  60%  { transform: translate(-50%, -50%) scale(1);   opacity: 1; }
  100% { transform: translate(-50%, -65%) scale(0.95); opacity: 0; }
}

/* Card bounce when a user double-taps to like — subtle pop-and-settle
   that reinforces the gesture landed. perspective gives the impression
   of motion toward the viewer rather than a flat scale-up. */
.feed-card.liked-bounce {
  animation: liked-bounce 480ms cubic-bezier(.34, 1.56, .64, 1);
  transform-origin: center;
}
@keyframes liked-bounce {
  0%   { transform: scale(1)    translateZ(0); }
  40%  { transform: scale(1.04) translateZ(20px); }
  70%  { transform: scale(0.99) translateZ(-4px); }
  100% { transform: scale(1)    translateZ(0); }
}

/* Trail enhancements — last 5 + ellipsis */
.trail .trail-ellipsis {
  cursor: pointer;
  opacity: 0.6;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.trail .trail-current {
  font-weight: 700;
  text-shadow: 0 0 12px currentColor;
}
.trail-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(10, 4, 24, 0.6);
  backdrop-filter: blur(12px);
  display: flex;
  align-items: center;
  justify-content: center;
}
.trail-overlay-card {
  background: rgba(18, 14, 38, 0.95);
  border: 1px solid var(--card-edge);
  border-radius: 16px;
  padding: 24px 28px;
  min-width: 320px;
  max-width: 480px;
  max-height: 70vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.trail-overlay-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0.55;
  margin-bottom: 6px;
}
.trail-overlay-entry {
  display: flex;
  gap: 10px;
  font-size: 14px;
  padding: 6px 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
.trail-overlay-entry.trail-current { font-weight: 600; }
.trail-overlay-idx {
  opacity: 0.45;
  width: 26px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  flex-shrink: 0;
}
.trail-overlay-close {
  margin-top: 14px;
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 11px;
  cursor: pointer;
  letter-spacing: 0.08em;
  align-self: flex-end;
}
.trail-overlay-close:hover { border-color: rgba(255,255,255,0.4); }

/* Scene blur stays constant — the prior "halve blur during scroll for perf"
   hedge read as a visual glitch (Alex noticed the background changing on
   scroll). Three.js + the modern Cloudflare-served devices handle the
   12px blur without dropping frames in practice. */

/* Drift-page navigation states (Slice 22). Brand logo → home. Drift tab
   or hitting the drift button → active. Feed (and its skeletons, dividers,
   trail entries, etc.) preserved in DOM; only display flips. */
body[data-drift-page="home"] #feed,
body[data-drift-page="home"] #trail {
  display: none;
}
/* Also halve during active drag, so the ghost feels snappy */
body[data-dnd-active] #scene {
  filter: blur(4px) saturate(1.1);
}
body[data-dnd-active] {
  /* prevent overscroll while dragging — hit-test stays clean */
  overscroll-behavior: contain;
}

/* ---------- drift bar (centered button below the compose components) ---------- */
.drift-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 6px 0 4px;
}
.drift-now-btn {
  background: var(--fg);
  color: #0a0418;
  border: 1px solid var(--fg);
  border-radius: 999px;
  padding: 11px 36px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  box-shadow: 0 8px 28px rgba(255,255,255,0.12);
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.drift-now-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 14px 36px rgba(255,255,255,0.2);
}
.drift-now-btn:active { transform: translateY(0); }

/* Reset-all: transparent blurred pill, sits next to the drift button. */
.reset-all-btn {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 9px 22px;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  opacity: 0.6;
  transition: opacity 0.18s, border-color 0.18s, background 0.18s, color 0.18s;
}
.reset-all-btn:hover {
  opacity: 1;
  border-color: rgba(248,113,113,0.45);
  color: var(--bad);
  background: rgba(248,113,113,0.06);
}

/* ---------- tag summary pill (v2 entry point to filter panel) ---------- */
.tag-summary-pill, .tag-summary-pill * {
  user-select: none;
  -webkit-user-select: none;
  caret-color: transparent;
}
.tag-summary-pill {
  display: inline-flex;
  align-self: center;
  align-items: center;
  gap: 10px;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  color: var(--fg);
  padding: 9px 18px;
  font-size: 12px;
  letter-spacing: 0.02em;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.18s, border-color 0.18s, transform 0.15s;
  max-width: 100%;
  text-align: left;
  backdrop-filter: blur(14px);
}
.tag-summary-pill:hover {
  background: rgba(255,255,255,0.1);
  border-color: rgba(255,255,255,0.3);
  transform: translateY(-1px);
}
/* Sliders icon — clean white, with a faint glow on hover. */
.tag-summary-pill-icon {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: #fff;
  filter: drop-shadow(0 0 6px rgba(255,255,255,0.25));
  transition: transform 0.25s ease, filter 0.2s ease;
}
.tag-summary-pill:hover .tag-summary-pill-icon {
  transform: scale(1.08);
  filter: drop-shadow(0 0 10px rgba(255,255,255,0.45));
}
.tag-summary-pill-text {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---------- filter panel (full-screen overlay) ---------- */
.filter-panel-scrim {
  position: fixed;
  inset: 0;
  z-index: 54;        /* one less than the panel so it dims without covering */
  background: rgba(8, 4, 22, 0.55);
  backdrop-filter: blur(12px);
  transition: opacity 0.28s ease;
}
.filter-panel {
  position: fixed;
  z-index: 55;          /* above scrim (40) AND above gate (50) so a stale */
                        /* opacity:0 gate can't block the panel content */
  top: 50%;
  left: 50%;
  display: flex;
  flex-direction: column;
  gap: 18px;
  width: min(960px, 92vw);
  height: min(680px, 92vh);
  padding: 22px 26px;
  /* Opaque-ish base so the heavily-blurred scene behind never reads through
     the chip text. Used to be 0.85 + backdrop-filter, which on some GPUs
     compositied the scene blur ON TOP of the panel content. */
  background: rgba(12, 8, 30, 0.95);
  border: 1px solid var(--card-edge);
  border-radius: 18px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.65);
  transform: translate(-50%, calc(-50% + 28px)) scale(0.98);
  opacity: 0;
  transition: transform 0.28s cubic-bezier(.2,.7,.2,1), opacity 0.28s ease;
  overflow: hidden;
}
.filter-panel.open {
  transform: translate(-50%, -50%);
  opacity: 1;
}
.filter-panel[hidden] { display: none; }
.filter-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.filter-panel-title {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
}
.filter-panel-close {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  width: 32px;
  height: 32px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 14px;
  font-family: inherit;
  transition: border-color 0.18s, background 0.18s;
}
.filter-panel-close:hover { border-color: rgba(255,255,255,0.4); background: rgba(255,255,255,0.05); }

.filter-panel-grid {
  flex: 1 1 0;
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  grid-template-areas:
    "pool and"
    "pool or"
    "pool perm";
  gap: 12px;
  min-height: 0;
}
.drop-zone-pool { grid-area: pool; position: relative; }
.drop-zone-and  { grid-area: and; }
.drop-zone-or   { grid-area: or; }
.drop-zone-perm { grid-area: perm; }

/* Pool list scrolls within the full-height column. Dark thin scrollbar. */
.drop-zone-pool .drop-zone-list {
  overflow-y: auto;
  scrollbar-color: rgba(255,255,255,0.22) rgba(0,0,0,0.35);
  scrollbar-width: thin;
}
.drop-zone-pool .drop-zone-list::-webkit-scrollbar { width: 8px; }
.drop-zone-pool .drop-zone-list::-webkit-scrollbar-track { background: rgba(0,0,0,0.35); border-radius: 4px; }
.drop-zone-pool .drop-zone-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.18); border-radius: 4px; }
.drop-zone-pool .drop-zone-list::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.32); }

/* Subtle drag-hint arrow in the pool's top-right corner. */
.drop-zone-pool-arrow {
  position: absolute;
  top: 10px;
  right: 14px;
  font-size: 16px;
  color: var(--fg-dim);
  opacity: 0.55;
  pointer-events: none;
  animation: pool-arrow-bob 2.6s ease-in-out infinite;
  z-index: 1;
}
@keyframes pool-arrow-bob {
  0%, 100% { transform: translate(0, 0);    opacity: 0.45; }
  50%      { transform: translate(5px, 0);  opacity: 0.95; }
}

@media (max-width: 720px) {
  .filter-panel-grid {
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto auto;
    grid-template-areas: "pool" "and" "or" "perm";
    /* Single-column grids stack their natural height; remove flex:1 so
       rows don't fight for a shared 236px and squeeze the pool's chip
       list to 0. Outer panel scrolls instead. */
    flex: 0 0 auto;
    min-height: 0;
  }
  .filter-panel {
    /* Truly full-screen on phones: edge-to-edge, square corners, hefty
       bottom scroll padding so the last fields aren't shoved into the
       keyboard. */
    top: 0;
    left: 0;
    width: 100vw;
    height: 100dvh;
    max-width: 100vw;
    max-height: 100dvh;
    padding: 14px 14px 200px;
    border-radius: 0;
    transform: none;
    border: none;
    overflow-y: auto;
    overflow-x: hidden;
  }
  .filter-panel.open {
    transform: none;
  }
  /* Lists are flex:1 1 0 by default for desktop's fixed-height grid; on
     mobile the parent has natural height, so we need to size to content
     or chips render but the container collapses to 0. */
  .drop-zone-list { flex: 0 0 auto; overflow-y: visible; }
  /* Pool list keeps a max-height + internal scrollbar so it doesn't
     dominate the panel; everyone else sizes to their chips. */
  .drop-zone-pool .drop-zone-list {
    max-height: 220px;
    min-height: 160px;
    overflow-y: auto;
  }
  /* Empty AND/OR/PERM zones still need vertical presence so the hint
     copy reads and the drop target is tappable. */
  .drop-zone-and .drop-zone-list,
  .drop-zone-or .drop-zone-list,
  .drop-zone-perm .drop-zone-list {
    min-height: 36px;
  }
}

.drop-zone {
  background: rgba(8, 6, 22, 0.5);
  border: 1px dashed rgba(255,255,255,0.14);
  border-radius: 14px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  transition: border-color 0.15s, background 0.15s;
}
.drop-zone.drop-target {
  border-color: rgba(255,255,255,0.6);
  background: rgba(255,255,255,0.08);
}
.drop-zone-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.drop-zone-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.85;
}
.drop-zone-pool .drop-zone-label { color: #c0b8e0; }
.drop-zone-and  .drop-zone-label { color: #fbbf24; }
.drop-zone-or   .drop-zone-label { color: #93c5fd; }
.drop-zone-perm .drop-zone-label { color: #fca5a5; }
.drop-zone-hint {
  font-size: 10px;
  opacity: 0.5;
  letter-spacing: 0.04em;
}
.drop-zone-list {
  flex: 1 1 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-content: flex-start;
  overflow-y: auto;
  padding-right: 4px;
}
.drop-zone-add {
  display: flex;
  gap: 6px;
  align-items: center;
}
.tag-add-input {
  flex: 1 1 0;
  min-width: 80px;
  background: transparent;
  border: 1px dashed var(--card-edge);
  border-radius: 999px;
  padding: 5px 11px;
  color: var(--fg);
  font-size: 12px;
  outline: none;
}
.tag-add-input:focus { border-color: rgba(255,255,255,0.35); background: rgba(255,255,255,0.03); }
.tag-add-category {
  background: rgba(8, 6, 22, 0.65);
  color: var(--fg);
  border: 1px solid var(--card-edge);
  border-radius: 6px;
  padding: 4px 8px;
  font-size: 11px;
  font-family: inherit;
  cursor: pointer;
  outline: none;
  flex-shrink: 0;
}
.tag-add-category:hover { border-color: rgba(255,255,255,0.3); }
.tag-add-category option { background: #0a0418; color: var(--fg); }
.tag-add-button {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  width: 26px;
  height: 26px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  font-family: inherit;
  flex-shrink: 0;
  transition: border-color 0.15s, background 0.15s;
}
.tag-add-button:hover { border-color: rgba(255,255,255,0.4); background: rgba(255,255,255,0.05); }

/* Rounded-rect chip with a category-colored drag handle (grid of 6 dots).
   Replaces the earlier solid-color or stripe-only treatment so each chip
   reads at a glance as draggable AND shows its category at a glance.
   Touch-action: none so vertical pan doesn't hijack the drag. */
.tag-chip.in-zone {
  display: inline-grid;
  grid-template-columns: auto 1fr;
  align-items: stretch;
  padding: 0;
  border: 1px solid var(--card-edge);
  border-radius: 8px;
  background: rgba(255,255,255,0.05);
  color: var(--fg);
  font-size: 12px;
  font-weight: 500;
  cursor: grab;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  overflow: hidden;
  transition: background 0.15s, border-color 0.15s;
  font-family: inherit;
}
.tag-chip.in-zone:hover {
  background: rgba(255,255,255,0.1);
  border-color: rgba(255,255,255,0.28);
}
.tag-chip.in-zone .tag-chip-handle {
  display: grid;
  grid-template-columns: repeat(2, 1px);
  grid-template-rows: repeat(3, 1px);
  gap: 3px;
  padding: 6px 6px;
  /* consistent neutral background across categories — category comes
     through in the dot color instead */
  background: rgb(50 50 50 / 45%);
  align-content: center;
  justify-content: center;
  flex-shrink: 0;
}
.tag-chip.in-zone .tag-chip-dot {
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: rgba(255,255,255,0.5);  /* fallback for chips without a category */
}
/* Dot color carries the category (was previously the handle background). */
.tag-chip.in-zone[data-category="theme"]    .tag-chip-dot { background: #14b8a6; }
.tag-chip.in-zone[data-category="language"] .tag-chip-dot { background: #f59e0b; }
.tag-chip.in-zone[data-category="vibe"]     .tag-chip-dot { background: #a855f7; }
.tag-chip.in-zone .tag-chip-label {
  padding: 6px 12px 6px 10px;
  white-space: nowrap;
  letter-spacing: 0.01em;
}
/* Custom chips already read as different via the italic label + fallback
   dot color; no need to differentiate the handle background or outline. */
.tag-chip.in-zone.custom-chip .tag-chip-label {
  font-style: italic;
}
.tag-chip.in-zone:active { cursor: grabbing; }
.tag-chip.in-zone.dragging { opacity: 0.3; }
.tag-chip-ghost {
  cursor: grabbing;
  opacity: 0.95;
  box-shadow: 0 12px 30px rgba(0,0,0,0.5);
}

/* Slice 38: FORM CONSTRAINTS row — sits between the grid and the
   models row. starts-with / ends-with text inputs + POS chip group. */
.filter-panel-form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 4px 0;
}
.filter-panel-form-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
}
.form-input {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  color: var(--fg);
  padding: 4px 11px;
  font-size: 11px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  width: 130px;
  outline: none;
  transition: border-color 0.18s, background 0.18s;
}
.form-input:focus { border-color: rgba(255,255,255,0.4); background: rgba(255,255,255,0.07); }
.form-input::placeholder { color: rgba(255,255,255,0.35); font-style: italic; }
.form-pos {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.form-pos-chip {
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  color: var(--fg-dim);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 10px;
  letter-spacing: 0.04em;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.form-pos-chip:hover { border-color: rgba(255,255,255,0.3); color: var(--fg); }
.form-pos-chip.active {
  background: rgba(94,234,212,0.14);
  border-color: rgba(94,234,212,0.55);
  color: #5eead4;
}

.filter-panel-models {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.85;
  flex-wrap: wrap;
}
.filter-panel-models-label {
  font-weight: 700;
  opacity: 0.7;
}
/* Slice 6b: model selector becomes a checkbox row with a literal × glyph
   inside the box when checked. Replaces the older fill-the-pill style. */
.model-check {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  font-size: 11px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.04em;
  user-select: none;
  color: var(--fg-dim);
  transition: color 0.18s;
}
.model-check input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  margin: 0;
}
.model-check-box {
  width: 16px;
  height: 16px;
  border: 1px solid var(--card-edge);
  border-radius: 3px;
  display: inline-grid;
  place-items: center;
  font-size: 13px;
  line-height: 1;
  color: transparent;
  transition: border-color 0.18s, color 0.18s;
  flex-shrink: 0;
}
.model-check input:checked + .model-check-box {
  color: var(--good);
  border-color: var(--good);
}
.model-check input:checked ~ .model-check-text {
  color: var(--fg);
}
.model-check:hover .model-check-box { border-color: rgba(255,255,255,0.35); }
/* legacy class kept so any cached HTML doesn't 404 — visually hidden */
.model-pill { display: none; }

.filter-panel-footer {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-top: 4px;
  border-top: 1px solid var(--card-edge);
  padding: 12px 0 0;
}
.filter-panel-counter {
  flex: 1 1 0;
  font-size: 11px;
  opacity: 0.65;
  letter-spacing: 0.02em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
}
.filter-panel-counter.over-cap {
  color: var(--bad);
  opacity: 0.95;
}
.filter-panel-cancel,
.filter-panel-save {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 6px 16px;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  opacity: 0.7;
  transition: opacity 0.18s, border-color 0.18s, background 0.18s;
}
.filter-panel-cancel:hover { opacity: 1; border-color: rgba(255,255,255,0.4); }
.filter-panel-save:hover { opacity: 1; border-color: rgba(110,231,183,0.5); color: var(--good); }

/* In-panel reset — discrete link-style so it doesn't compete with the
   pill buttons. Hover tints red to telegraph destructive intent. */
.filter-panel-reset {
  background: transparent;
  border: none;
  color: var(--fg-dim);
  padding: 6px 8px;
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  font-family: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  opacity: 0.7;
  transition: opacity 0.18s, color 0.18s;
}
.filter-panel-reset:hover { opacity: 1; color: var(--bad); }
.filter-panel-apply {
  background: var(--fg);
  color: #0a0418;
  border: 1px solid var(--fg);
  border-radius: 999px;
  padding: 9px 28px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  transition: transform 0.15s ease, box-shadow 0.2s ease;
}
.filter-panel-apply:hover { transform: translateY(-2px); box-shadow: 0 12px 38px rgba(255,255,255,0.18); }
.filter-panel-apply:disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ---------- origin badge on feed cards (Slice 14) ---------- */
/* Floats to a corner of the card so it doesn't compete with the name. No
   left-pipe — the text color (fork color) is enough of a visual link. */
.feed-card .origin-badge {
  position: absolute;
  top: 10px;
  left: 16px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.08em;
  opacity: 0.45;
  color: var(--fork-color, var(--fg-dim));
  white-space: nowrap;
  pointer-events: none;
  z-index: 1;
}
/* Mobile (single-column cards): badge to top-right so it doesn't overlap
   the leading name. */
@media (max-width: 600px) {
  .feed-card .origin-badge {
    left: auto;
    right: 16px;
  }
}

/* Saved-card "by ${author}" badge — reuses the origin-badge slot, but
   the text needs more presence than the per-fork drift-card badge.
   Bump font + opacity so it clears WCAG AA against the translucent glass. */
.feed-card[data-kind="saved"] .origin-badge {
  font-size: 10.5px;
  opacity: 0.75;
  letter-spacing: 0.06em;
}

/* Seed card — the current center rendered inline so users see its own
   TLD availability + can save/copy it. Visually distinct (thicker glow,
   "this is your seed" tag) without competing with the candidates. */
.feed-card.is-seed {
  border-color: rgba(167,139,250,0.55);
  background: linear-gradient(180deg, rgba(167,139,250,0.08), rgba(255,255,255,0.02));
  box-shadow: 0 0 0 1px rgba(167,139,250,0.18), 0 12px 30px rgba(167,139,250,0.12);
}
.feed-card.is-seed::before {
  content: "seed";
  position: absolute;
  top: 10px;
  right: 16px;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #c4b5fd;
  opacity: 0.8;
  pointer-events: none;
}

/* Help-page TLD list — keep ".com · .ai · .org · .md" together as one
   chunk so it doesn't start a line orphaned. */
.tld-list { white-space: nowrap; }

/* ---------- clearable text inputs (× button) ----------
   attachClearButton(input) wraps an input in .clearable-wrap with a
   tiny × button that appears only when the value is non-empty. */
.clearable-wrap {
  position: relative;
  display: inline-flex;
  align-items: stretch;
  flex: 1 1 auto;
}
.clearable-wrap > input,
.clearable-wrap > textarea {
  width: 100%;
  flex: 1 1 auto;
  padding-right: 32px;
}
.clearable-x {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(255,255,255,0.08);
  border: 1px solid var(--card-edge);
  border-radius: 50%;
  color: var(--fg);
  font-size: 14px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  opacity: 0.6;
  transition: opacity 0.15s, background 0.15s;
  font-family: inherit;
}
.clearable-wrap.has-value .clearable-x { display: inline-flex; }
.clearable-x:hover { opacity: 1; background: rgba(255,255,255,0.14); }

/* ---------- compose-fold sections (tags / form / models) ----------
   Native <details>/<summary> so the browser handles toggle state; we
   just style the chrome. Form + models start closed (no open attr);
   tags starts open via the inline open="" set in JS. */
.compose-fold { margin: 8px 0; }
.compose-fold > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  background: rgba(255,255,255,0.025);
  border: 1px solid var(--card-edge);
  border-radius: 10px;
  transition: background 0.15s, border-color 0.15s;
}
.compose-fold > summary::-webkit-details-marker { display: none; }
.compose-fold > summary:hover {
  background: rgba(255,255,255,0.05);
  border-color: rgba(255,255,255,0.22);
}
.compose-fold-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.85;
}
.compose-fold-chevron {
  font-size: 12px;
  opacity: 0.65;
  transition: transform 0.18s;
}
.compose-fold[open] > summary .compose-fold-chevron { transform: rotate(90deg); }
.compose-fold > .filter-panel-grid,
.compose-fold > .filter-panel-form,
.compose-fold > .filter-panel-models {
  margin-top: 10px;
}

/* ---------- zone popover (tap-to-bucket fallback) ----------
   Drag-and-drop is fiddly on touch — tap a pool chip and a small
   popover floats below it with AND/OR/PERM buttons. Desktop users
   can keep dragging; this just adds an alternative path. */
.zone-popover {
  position: fixed;
  z-index: 70;
  padding: 8px 10px;
  background: rgba(16, 10, 36, 0.97);
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 12px;
  box-shadow: 0 16px 40px rgba(0,0,0,0.65);
  display: flex;
  flex-direction: column;
  gap: 8px;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.14s, transform 0.14s;
  pointer-events: none;
}
.zone-popover.open {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.zone-popover-label {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  color: var(--cat-color, var(--fg-dim));
  opacity: 0.85;
  text-align: center;
  text-transform: uppercase;
  font-weight: 600;
}
.zone-popover-row {
  display: flex;
  gap: 6px;
}
.zone-popover-btn {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  font-family: inherit;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s, transform 0.1s;
}
.zone-popover-btn:hover { background: rgba(255,255,255,0.06); }
.zone-popover-btn:active { transform: translateY(1px); }
.zone-popover-btn-and:hover  { border-color: rgba(245,158,11,0.55); color: #fbbf24; }
.zone-popover-btn-or:hover   { border-color: rgba(167,139,250,0.55); color: #c4b5fd; }
.zone-popover-btn-perm:hover { border-color: rgba(251,146,60,0.55); color: #fb923c; }

/* Per-fork left edge stripe on cards in multi-fork mode */
.feed-card { border-left: 3px solid transparent; }
.feed-card[data-fork-id] { border-left-color: var(--fork-color, transparent); }

/* Fork banner — shown above first batch in multi-fork mode */
.fork-banner {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 14px;
  margin-top: 8px;
  font-size: 11px;
  letter-spacing: 0.04em;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: var(--fork-color, var(--fg-dim));
  border-left: 3px solid var(--fork-color, var(--fg));
  background: linear-gradient(90deg, rgba(255,255,255,0.04), transparent);
  border-radius: 0 999px 999px 0;
}
.fork-banner-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--fork-color, var(--fg));
  box-shadow: 0 0 10px var(--fork-color, var(--fg));
}

/* Request history row (Slice 31) — one per active fork. Mono, white-ish,
   HH:MM prefix, "see prompt" link at the end. */
.trail .trail-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 2px 0;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: #fff;
  letter-spacing: 0.02em;
  line-height: 1.4;
  flex-wrap: wrap;
}
.trail .trail-ts {
  opacity: 0.55;
  flex-shrink: 0;
}
.trail .trail-model {
  opacity: 0.55;
  flex-shrink: 0;
}
.trail .trail-sep {
  opacity: 0.4;
  flex-shrink: 0;
}
.trail .trail-see-prompt {
  flex-shrink: 0;
  color: #fff;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  opacity: 0.6;
  cursor: pointer;
  font-size: 11px;
  letter-spacing: 0.04em;
}
.trail .trail-see-prompt:hover { opacity: 1; }
.trail .trail-fork-badge {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-right: 4px;
  padding: 1px 6px;
  border: 1px solid currentColor;
  border-radius: 999px;
}

/* "See prompt" modal */
.prompt-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(8, 4, 22, 0.6);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.prompt-modal-card {
  background: rgba(12, 8, 30, 0.97);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  max-width: 760px;
  /* explicit height so the inner <pre>'s flex:1 has room to grow.
     Without this the card sized to header-content (~50px). */
  height: min(700px, 82vh);
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-shadow: 0 30px 80px rgba(0,0,0,0.55);
}
.prompt-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--card-edge);
}
.prompt-modal-title {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  opacity: 0.85;
}
.prompt-modal-close {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  cursor: pointer;
  font-size: 13px;
  font-family: inherit;
}
.prompt-modal-close:hover { border-color: rgba(255,255,255,0.4); }
.prompt-modal-pre {
  flex: 1 1 0;
  min-height: 0;        /* lets the flex child actually shrink + scroll */
  margin: 0;
  padding: 18px 22px;
  overflow: auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  line-height: 1.55;
  color: #cbd5e1;
  white-space: pre-wrap;
  word-break: break-word;
}

/* ---------- bottom bar (log + auto-drift toggle) ---------- */
.bottom-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 35;
  height: 36px;
  display: flex;
  align-items: center;
  gap: 24px;     /* breathing room between log / vis-toggles / auto-drift */
  padding: 0 18px;
  background: rgba(8, 4, 22, 0.78);
  border-top: 1px solid var(--card-edge);
  backdrop-filter: blur(20px) saturate(1.15);
  -webkit-backdrop-filter: blur(20px) saturate(1.15);
  font-size: 11px;
  letter-spacing: 0.02em;
  transition: border-color 0.2s ease, box-shadow 0.4s ease;
}
.bottom-bar[hidden] { display: none; }
.bb-compose {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  background: rgba(255,255,255,0.06);
  border: 1px solid var(--card-edge);
  color: var(--fg);
  padding: 5px 12px 5px 10px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  font-family: inherit;
  opacity: 0.85;
  transition: background 0.15s, border-color 0.15s, opacity 0.15s;
}
.bb-compose:hover {
  opacity: 1;
  background: rgba(255,255,255,0.1);
  border-color: rgba(255,255,255,0.28);
}
.bb-compose svg { display: block; }
.bottom-bar-log {
  flex: 1 1 0;
  min-width: 0;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11px;
  color: var(--fg-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0.92;
}
.bottom-bar-log.error { color: var(--bad); opacity: 1; }
.bottom-bar-log.fade-in { animation: log-fade-in 0.25s ease; }
@keyframes log-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 0.92; transform: none; }
}

/* Eye-style visibility toggles (Slice 32) — replaces the previous
   iOS-switch chassis for hide-duplicates + hide-unavailable. Open eye =
   items visible (checkbox unchecked); closed eye with diagonal slash =
   items hidden (checked). Underlying <input type="checkbox"> still
   carries state so bindBBToggle keeps working. */
.vis-toggles {
  display: inline-flex;
  align-items: center;
  gap: 22px;     /* clearer separation between the two eye+label pairs */
  flex-shrink: 0;
  margin-right: 4px;
}
.vis-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-dim);
  user-select: none;
  transition: color 0.18s;
}
.vis-toggle:hover { color: var(--fg); }
.vis-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  margin: 0;
}
.vis-toggle-eye {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}
.vis-toggle-eye svg {
  width: 18px;
  height: 18px;
  color: #fff;
  transition: color 0.18s, opacity 0.18s;
}
/* Unchecked = visible = open eye, no slash. */
.vis-toggle input:not(:checked) ~ .vis-toggle-eye .vis-slash { opacity: 0; }
.vis-toggle input:not(:checked) ~ .vis-toggle-eye .vis-eye-shape,
.vis-toggle input:not(:checked) ~ .vis-toggle-eye .vis-pupil  { opacity: 0.95; }
/* Checked = hidden = closed eye with slash; eye + pupil dim. */
.vis-toggle input:checked ~ .vis-toggle-eye .vis-slash      { opacity: 1; }
.vis-toggle input:checked ~ .vis-toggle-eye .vis-eye-shape,
.vis-toggle input:checked ~ .vis-toggle-eye .vis-pupil      { opacity: 0.4; }
.vis-toggle input:checked ~ .vis-toggle-label { opacity: 0.6; }
.vis-toggle-label {
  transition: opacity 0.18s;
}

/* iOS-style toggles — only auto-drift uses this chassis now. */
.bb-toggle, .auto-drift-toggle {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  cursor: pointer;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--fg-dim);
  user-select: none;
  flex-shrink: 0;
}
.bb-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  margin: 0;
}
.bb-toggle-track {
  position: relative;
  display: inline-block;
  width: 32px;
  height: 18px;
  background: rgba(255,255,255,0.08);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  transition: background 0.18s, border-color 0.18s;
}
.bb-toggle-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  background: var(--fg-dim);
  border-radius: 50%;
  transition: transform 0.2s cubic-bezier(.3,1.5,.5,1), background 0.18s;
}
.bb-toggle:hover .bb-toggle-track { border-color: rgba(255,255,255,0.3); }
.bb-toggle input:checked + .bb-toggle-track {
  background: rgba(255,255,255,0.18);
  border-color: rgba(255,255,255,0.38);
}
.bb-toggle input:checked + .bb-toggle-track .bb-toggle-knob {
  transform: translateX(14px);
  background: var(--fg);
}
.bb-toggle input:checked ~ .bb-toggle-label { color: var(--fg); }
/* visually-hidden but in layout so label clicks reliably fire change */
.auto-drift-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  margin: 0;
}
.auto-drift-track {
  position: relative;
  display: inline-block;
  width: 32px;
  height: 18px;
  background: rgba(255,255,255,0.08);
  border: 1px solid var(--card-edge);
  border-radius: 999px;
  transition: background 0.18s, border-color 0.18s;
}
.auto-drift-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  background: var(--fg-dim);
  border-radius: 50%;
  transition: transform 0.2s cubic-bezier(.3,1.5,.5,1), background 0.18s;
}
.auto-drift-toggle:hover .auto-drift-track {
  border-color: rgba(255,255,255,0.3);
}
.auto-drift-toggle input:checked + .auto-drift-track {
  background: rgba(110,231,183,0.32);
  border-color: rgba(110,231,183,0.55);
}
.auto-drift-toggle input:checked + .auto-drift-track .auto-drift-knob {
  transform: translateX(14px);
  background: var(--good);
}
.auto-drift-toggle input:checked ~ .auto-drift-label {
  color: var(--good);
}

/* When auto-drift is on, give the bar a soft glow so it's clearly engaged. */
.bottom-bar.auto-on {
  border-top-color: rgba(110,231,183,0.45);
  animation: bottom-bar-pulse 2.6s ease-in-out infinite;
}
@keyframes bottom-bar-pulse {
  0%, 100% { box-shadow: 0 -2px 24px 0 rgba(110,231,183,0); }
  50%      { box-shadow: 0 -2px 24px 0 rgba(110,231,183,0.18); }
}

/* ---------- intro section (front-page, below the compose pill) ---------- */
.intro {
  display: grid;
  grid-template-columns: 320px 1fr;
  gap: 22px;
  align-items: start;
  padding: 22px 24px 26px;
  /* darker radial gradient so the intro reads as a distinct "explainer"
     plate against the dreamy background, without losing the orbs underneath */
  background: radial-gradient(ellipse at center, #000000b5 0%, #00000026 100%);
  border: 1px solid var(--card-edge);
  border-radius: 14px;
  backdrop-filter: blur(18px);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.55;
  color: var(--fg);
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.intro.dismissed {
  display: none;
}
.intro-diagram {
  width: 100%;
  max-width: 320px;
  height: auto;
  filter: drop-shadow(0 6px 18px rgba(0,0,0,0.55));
}
.intro-copy p {
  margin: 0 0 10px;
  opacity: 0.92;
}
.intro-copy p:last-of-type {
  margin-bottom: 14px;
}
.intro-copy b {
  color: #fff;
  letter-spacing: 0.01em;
  font-weight: 700;
}
.intro-dismiss {
  background: transparent;
  border: 1px solid var(--card-edge);
  color: var(--fg);
  border-radius: 999px;
  padding: 5px 14px;
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.18s, border-color 0.18s;
}
.intro-dismiss:hover { opacity: 1; border-color: rgba(255,255,255,0.4); }
@media (max-width: 720px) {
  .intro { grid-template-columns: 1fr; gap: 14px; }
  .intro-diagram { margin: 0 auto; }
}

/* Help view variant of the intro card — kept fullwidth, includes the
   symbol legend + gestures section below the diagram + copy. */
.intro.intro-help {
  grid-template-columns: 1fr;
  gap: 18px;
  padding: 22px 24px 26px;
}
.intro-help .intro-diagram { max-width: 360px; margin: 0 auto; }
.help-legend-title {
  margin: 14px 0 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.7;
  border-top: 1px solid var(--card-edge);
  padding-top: 14px;
}
.help-legend {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
}
.help-legend li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--fg);
}
.help-legend-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--card-edge);
  color: var(--fg);
  flex-shrink: 0;
  margin-top: 1px;
}
.help-legend b { font-weight: 700; }
.help-tips {
  margin: 6px 0 0;
  padding-left: 1.2em;
  font-size: 13px;
  line-height: 1.5;
  color: var(--fg);
}
.help-tips li { margin: 4px 0; opacity: 0.92; }

/* ============================================================
   Mobile polish (≤480px) — slice 44
   Addresses: bottom-bar AUTO-DRIFT truncation, filter-panel DRIFT
   button clip, top-nav crowding + identity shift, and card icon
   row crowded against stars. CSS-only.
   ============================================================ */
@media (max-width: 480px) {
  /* Hide the mini per-fork request log on mobile — saves vertical space
     and the same info is in the history tab. */
  .trail .trail-row { display: none; }

  /* The compose footer's "will send N query (1 gpt)" preview takes prime
     real estate on a phone but the same info is implicit from the chips
     visible above. Hide on mobile. */
  .filter-panel-counter { display: none !important; }

  /* Bottom-toolbar compose button: icon-only on mobile to keep the bar
     one line with the visibility toggles + auto-drift. */
  .bb-compose-label { display: none; }
  .bb-compose { padding: 5px 9px; gap: 0; }

  /* iOS auto-zooms any input whose font-size is < 16px on focus. Force
     every text/search/textarea to 16px on mobile so the viewport stays
     stable when the keyboard opens. */
  input[type="text"],
  input[type="search"],
  input[type="email"],
  input[type="number"],
  input[type="tel"],
  input[type="url"],
  input[type="password"],
  input:not([type]),
  textarea,
  select {
    font-size: 16px !important;
  }

  /* --- top nav (HUD) --- */
  /* Tighter spacing, allow flex-wrap to a second row if absolutely
     needed. Hide the "Not signed in" placeholder text — the head
     icon already communicates the slot. Cap signed-in name. */
  .hud { gap: 10px; }
  .nav { gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
  .nav-tab { padding: 5px 10px; font-size: 11px; }
  .nav-tab.nav-icon-tab { padding: 5px 8px; }
  .login-pill { padding: 5px 9px; gap: 0; }
  .login-pill .login-name { display: none; }   /* icon-only on mobile */
  .cost-pill { padding: 4px 10px 4px 9px; font-size: 10.5px; }
  .brand { font-size: 12px; }

  /* --- filter panel footer --- */
  /* Allow wrap; counter takes its own row so the DRIFT pill never
     gets pushed off the right edge. Tighter padding inside DRIFT. */
  .filter-panel-footer { flex-wrap: wrap; gap: 8px; }
  .filter-panel-counter { flex: 1 1 100%; order: -1; font-size: 10.5px; }
  .filter-panel-reset,
  .filter-panel-cancel,
  .filter-panel-save { padding: 6px 12px; flex-shrink: 0; }
  .filter-panel-apply {
    padding: 9px 18px;
    flex-shrink: 0;
    margin-left: auto;     /* pin DRIFT to the right edge */
  }

  /* --- bottom bar --- */
  /* Hide the vis-toggle text labels — the eye icon (with optional
     slash) already conveys state. Tighten gaps. Shorten the
     auto-drift label to "AUTO" via content swap. */
  .bottom-bar { gap: 12px; padding: 0 12px; }
  .vis-toggles { gap: 14px; margin-right: 0; }
  .vis-toggle-label { display: none; }
  .auto-drift-toggle { gap: 6px; }
  .auto-drift-label { font-size: 9.5px; letter-spacing: 0.1em; }

  /* --- card actions row: pull stars onto its own line --- */
  /* Adds visual separation between the action icons and the rating
     stars, and gives the icons more horizontal room. */
  .feed-card-actions {
    margin-top: 10px;
    row-gap: 10px;
    column-gap: 8px;
  }
  .feed-card-actions .stars {
    flex-basis: 100%;
    justify-content: flex-end;
    margin-top: 2px;
  }
  /* Slightly larger tap targets on mobile (still under 44 HIG, but
     more comfortable). Stays in step with the existing icon row
     widths so nothing else needs to change. */
  .icon-btn { width: 32px; height: 32px; border-radius: 9px; }
  .icon-btn svg { width: 16px; height: 16px; }
}
