/* ═══════════════════════════════════════════════════════════════════════
   ADMIN PANEL — a clean, light, efficient back-office. Deliberately NOT the
   CRT visitor theme: this is a tool. Everything is scoped under .admin-shell
   so it never leaks into the storefront, and it overrides the shared admin-*
   classes the pages already use so the whole panel restyles at once.
   ═══════════════════════════════════════════════════════════════════════ */
.admin-shell {
  --a-bg:        #f4f5f7;   /* app background */
  --a-surface:   #ffffff;   /* cards / panels */
  --a-surface-2: #f7f8fa;   /* subtle fills, table headers */
  --a-border:    #e3e6ea;   /* hairlines */
  --a-border-2:  #d3d8de;   /* stronger borders */
  --a-ink:       #1f2328;   /* primary text */
  --a-ink-2:     #57606a;   /* secondary text */
  --a-ink-3:     #8b949e;   /* muted / meta */
  --a-accent:    #7c3aed;   /* brand violet, calmed for UI */
  --a-accent-ink:#ffffff;
  --a-accent-soft:#f3ecfe;  /* active nav / selected tint */
  --a-ok:        #1a7f37;   --a-ok-soft:#e6f4ea;
  --a-warn:      #9a6700;   --a-warn-soft:#fdf3d7;
  --a-bad:       #cf222e;   --a-bad-soft:#fdecee;
  --a-radius:    10px;
  --a-radius-sm: 7px;
  --a-shadow:    0 1px 2px rgba(27,31,36,0.06), 0 1px 3px rgba(27,31,36,0.05);
  --a-shadow-lg: 0 4px 16px rgba(27,31,36,0.10);
  --a-sidebar-w: 208px;

  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--a-ink);
  background: var(--a-bg);
  /* The storefront sets body{overflow:hidden} (it scrolls an inner container),
     so the admin app must own a full-viewport box and scroll the MAIN column
     itself — otherwise the page can't scroll at all. */
  height: 100dvh;
  overflow: hidden;
  text-align: left;   /* the storefront centres text; admin is left-aligned */
  -webkit-font-smoothing: antialiased;
  text-transform: none;
  letter-spacing: normal;
}
.admin-shell *, .admin-shell *::before, .admin-shell *::after { box-sizing: border-box; }

/* ── Layout: sidebar + main ─────────────────────────────────────────── */
.admin-layout { display: flex; height: 100%; }

.admin-sidebar {
  width: var(--a-sidebar-w);
  flex-shrink: 0;
  background: var(--a-surface);
  border-right: 1px solid var(--a-border);
  display: flex;
  flex-direction: column;
  height: 100%;
}
.admin-sidebar-brand {
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--a-border);
}
.admin-sidebar-brand-mark {
  width: 26px; height: 26px; border-radius: 6px; flex-shrink: 0;
  background: linear-gradient(135deg, #7c3aed, #4b2488);
  color: #fff; font-weight: 700; font-size: 0.78rem;
  display: flex; align-items: center; justify-content: center;
}
.admin-sidebar-brand-text { display: flex; flex-direction: column; line-height: 1.15; }
.admin-sidebar-brand-title { font-size: 0.8rem; font-weight: 650; color: var(--a-ink); }
.admin-sidebar-brand-sub { font-size: 0.64rem; color: var(--a-ink-3); }

.admin-nav { padding: 0.5rem 0.5rem; display: flex; flex-direction: column; gap: 0.06rem; flex: 1; overflow-y: auto; }
.admin-nav-item {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.4rem 0.6rem;
  border-radius: var(--a-radius-sm);
  color: var(--a-ink-2);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 500;
  transition: background 0.12s, color 0.12s;
}
.admin-nav-item:hover { background: var(--a-surface-2); color: var(--a-ink); }
.admin-nav-item.is-active { background: var(--a-accent-soft); color: var(--a-accent); font-weight: 600; }
.admin-nav-icon { width: 18px; height: 18px; flex-shrink: 0; stroke-width: 1.9; }
.admin-nav-badge {
  margin-left: auto; min-width: 20px; height: 18px; padding: 0 5px;
  border-radius: 9px; background: var(--a-accent); color: #fff;
  font-size: 0.66rem; font-weight: 700; display: flex; align-items: center; justify-content: center;
}
.admin-nav-sep { height: 1px; background: var(--a-border); margin: 0.5rem 0.4rem; }

.admin-sidebar-foot { padding: 0.6rem 0.55rem; border-top: 1px solid var(--a-border); display: flex; flex-direction: column; gap: 0.15rem; }

/* overflow-y:auto makes the browser compute overflow-x to `auto` too, which lets
   you drag the page sideways. Pin overflow-x:hidden so it only ever scrolls up/down. */
.admin-main { flex: 1; min-width: 0; height: 100%; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; }

/* ── Topbar ─────────────────────────────────────────────────────────── */
.admin-topbar {
  height: 46px; flex-shrink: 0;
  background: var(--a-surface);
  border-bottom: 1px solid var(--a-border);
  display: flex; align-items: center; gap: 0.8rem;
  padding: 0 1.1rem;
  position: sticky; top: 0; z-index: 20;
}
.admin-topbar-title { font-size: 0.95rem; font-weight: 650; color: var(--a-ink); }
.admin-topbar-spacer { flex: 1; }
.admin-burger { display: none; background: none; border: none; cursor: pointer; padding: 0.3rem; color: var(--a-ink-2); }

.admin-content { padding: 1.1rem; max-width: 1180px; width: 100%; margin: 0 auto; }

/* ── Page header (inside content) ───────────────────────────────────── */
.admin-shell .admin-header {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin: 0 0 0.9rem; flex-wrap: wrap;
}
.admin-shell .admin-header-actions { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; }
.admin-shell .panel-title,
.admin-shell .admin-title {
  font-size: 1.2rem; font-weight: 680; color: var(--a-ink);
  letter-spacing: -0.01em; text-transform: none; margin: 0; text-shadow: none;
}
.admin-shell .admin-hint { font-size: 0.82rem; color: var(--a-ink-2); letter-spacing: normal; text-transform: none; }
.admin-shell .admin-label {
  font-size: 0.78rem; font-weight: 600; color: var(--a-ink-2);
  letter-spacing: normal; text-transform: none; margin-bottom: 0.35rem;
}

/* The page container: neutralise the CRT panel and make a plain surface. */
.admin-shell .page-panel,
.admin-shell .admin-panel {
  background: transparent; border: none; box-shadow: none;
  padding: 0; margin: 0; max-width: none; width: 100%; display: block;
  color: var(--a-ink); font-family: inherit; animation: none;
  text-align: left;      /* the CRT .page-panel centres text — force left for lists */
  text-transform: none;  /* …and UPPERCASES everything — reset so data shows as typed */
}
.admin-shell .page-panel::before,
.admin-shell .page-panel::after { display: none; }

/* Card wrapper for grouping */
.admin-card {
  background: var(--a-surface); border: 1px solid var(--a-border);
  border-radius: var(--a-radius); box-shadow: var(--a-shadow);
  padding: 1.1rem 1.2rem; margin-bottom: 1.1rem;
}
.admin-card-title { font-size: 0.95rem; font-weight: 650; margin: 0 0 0.9rem; color: var(--a-ink); display: flex; align-items: center; gap: 0.5rem; }

/* ── Buttons ────────────────────────────────────────────────────────── */
.admin-shell .admin-btn,
.admin-shell .admin-card-btn,
.admin-shell .admin-action-btn {
  font-family: inherit; font-size: 0.82rem; font-weight: 550;
  letter-spacing: normal; text-transform: none;
  padding: 0.44rem 0.8rem; border-radius: var(--a-radius-sm);
  border: 1px solid var(--a-border-2); background: var(--a-surface); color: var(--a-ink);
  cursor: pointer; transition: background 0.12s, border-color 0.12s, box-shadow 0.12s;
  display: inline-flex; align-items: center; gap: 0.35rem; line-height: 1.2; white-space: nowrap;
  /* .admin-card-btn is also used unscoped by the shop card's admin overlay
     (07-admin-auth.css), which sets flex:1 to split two buttons evenly
     across the overlay strip. That declaration otherwise leaks through
     here since this rule never set flex at all — found live stretching
     AdminGhost.jsx's transport/reboot buttons to equal-width boxes
     regardless of their text length. */
  flex: none;
}
.admin-shell .admin-btn:hover:not(:disabled),
.admin-shell .admin-card-btn:hover:not(:disabled),
.admin-shell .admin-action-btn:hover:not(:disabled) { background: var(--a-surface-2); border-color: var(--a-ink-3); }
.admin-shell .admin-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.admin-shell .admin-btn--add,
.admin-shell .admin-btn--save {
  background: var(--a-accent); border-color: var(--a-accent); color: var(--a-accent-ink); font-weight: 600;
}
.admin-shell .admin-btn--add:hover:not(:disabled),
.admin-shell .admin-btn--save:hover:not(:disabled) { background: #6d28d9; border-color: #6d28d9; }

.admin-shell .admin-btn--logout,
.admin-shell .admin-card-btn--delete,
.admin-shell .admin-action-btn--delete { color: var(--a-bad); border-color: var(--a-border-2); background: var(--a-surface); }
.admin-shell .admin-btn--logout:hover:not(:disabled),
.admin-shell .admin-card-btn--delete:hover:not(:disabled),
.admin-shell .admin-action-btn--delete:hover:not(:disabled) { background: var(--a-bad-soft); border-color: var(--a-bad); }

/* ── Inputs / forms ─────────────────────────────────────────────────── */
.admin-shell .admin-input,
.admin-shell .admin-textarea,
.admin-shell select.admin-input {
  font-family: inherit; font-size: 0.9rem; color: var(--a-ink);
  background: var(--a-surface); border: 1px solid var(--a-border-2);
  border-radius: var(--a-radius-sm); padding: 0.55rem 0.7rem;
  width: 100%; letter-spacing: normal; transition: border-color 0.12s, box-shadow 0.12s;
}
.admin-shell .admin-input:focus,
.admin-shell .admin-textarea:focus,
.admin-shell select.admin-input:focus {
  outline: none; border-color: var(--a-accent);
  box-shadow: 0 0 0 3px var(--a-accent-soft); background: var(--a-surface);
}
.admin-shell .admin-input::placeholder,
.admin-shell .admin-textarea::placeholder { color: var(--a-ink-3); }
.admin-shell .admin-field { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.9rem; }
.admin-shell .admin-form { text-align: left; }
.admin-shell .admin-error { color: var(--a-bad); font-size: 0.82rem; letter-spacing: normal; text-transform: none; }

/* ── Dashboard: stat tiles + quick nav ──────────────────────────────── */
.admin-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 0.9rem; margin-bottom: 1.3rem; }
.admin-stat {
  background: var(--a-surface); border: 1px solid var(--a-border);
  border-radius: var(--a-radius); box-shadow: var(--a-shadow); padding: 0.95rem 1.05rem;
  display: flex; flex-direction: column; gap: 0.2rem;
}
.admin-stat-value { font-size: 1.55rem; font-weight: 700; color: var(--a-ink); letter-spacing: -0.02em; line-height: 1; }
.admin-stat-label { font-size: 0.78rem; color: var(--a-ink-2); }
.admin-stat-sub { font-size: 0.72rem; color: var(--a-ink-3); margin-top: 0.15rem; }

/* Old .admin-hub grid (dashboard quick links) → clean cards */
.admin-shell .admin-hub { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.8rem; margin: 0 0 1.3rem; }
.admin-shell .admin-hub-card {
  background: var(--a-surface); border: 1px solid var(--a-border); border-radius: var(--a-radius);
  box-shadow: var(--a-shadow); padding: 0.9rem 1rem; text-decoration: none;
  display: flex; flex-direction: column; gap: 0.2rem; transition: border-color 0.12s, box-shadow 0.12s, transform 0.12s;
}
.admin-shell .admin-hub-card:hover { border-color: var(--a-accent); box-shadow: var(--a-shadow-lg); transform: translateY(-1px); }
.admin-shell .admin-hub-card-title { font-size: 0.9rem; font-weight: 650; color: var(--a-ink); letter-spacing: normal; text-transform: none; }
.admin-shell .admin-hub-card-meta { font-size: 0.76rem; color: var(--a-ink-3); letter-spacing: normal; text-transform: none; }

/* ── Product list rows ──────────────────────────────────────────────── */
.admin-shell .adm-prod-list { display: flex; flex-direction: column; gap: 0; border: 1px solid var(--a-border); border-radius: var(--a-radius); overflow: hidden; background: var(--a-surface); box-shadow: var(--a-shadow); }
.admin-shell .adm-prod-row {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.55rem 0.8rem; border-bottom: 1px solid var(--a-border); background: var(--a-surface);
}
.admin-shell .adm-prod-row:last-child { border-bottom: none; }
.admin-shell .adm-prod-row:hover { background: var(--a-surface-2); }
.admin-shell .adm-prod-row--busy { opacity: 0.55; }
.admin-shell .adm-prod-thumb { width: 38px; height: 38px; border-radius: var(--a-radius-sm); overflow: hidden; background: var(--a-surface-2); border: 1px solid var(--a-border); flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.admin-shell .adm-prod-thumb img { width: 100%; height: 100%; object-fit: cover; }
.admin-shell .adm-prod-thumb-empty { color: var(--a-ink-3); }
/* Video-clip thumbnails default to a landscape box (see AdminVideoLibrary.jsx/
   AdminGhost.jsx, which override the base square size above) — a square
   (Pepper's Ghost / HyperPixel) clip needs its own box shape or a 1:1 clip
   letterboxes oddly inside a 16:9-shaped frame. */
.admin-shell .adm-prod-thumb--video { width: 80px; height: 46px; }
.admin-shell .adm-prod-thumb--video.adm-prod-thumb--square { width: 46px; height: 46px; }
.admin-shell .adm-prod-thumb--video video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Smaller inline thumbnail used inside the playlist-picker chips on
   Displays (AdminGhost.jsx) — same landscape-vs-square shape concern as
   .adm-prod-thumb--video above, just at chip scale. */
.admin-shell .adm-clip-chip-thumb { width: 44px; height: 26px; object-fit: cover; border-radius: 3px; background: #000; flex-shrink: 0; display: block; }
.admin-shell .adm-clip-chip-thumb--square { width: 26px; height: 26px; }
.admin-shell .adm-prod-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.admin-shell .adm-prod-name { font-size: 0.9rem; font-weight: 600; color: var(--a-ink); letter-spacing: normal; text-transform: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.admin-shell .adm-prod-meta { font-size: 0.76rem; color: var(--a-ink-3); letter-spacing: normal; text-transform: none; }
.admin-shell .adm-prod-stock { display: flex; align-items: center; gap: 0.6rem; flex-shrink: 0; }
.admin-shell .adm-prod-stepper { display: inline-flex; align-items: center; border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm); overflow: hidden; }
.admin-shell .adm-prod-stepper button { border: none; background: var(--a-surface); color: var(--a-ink); width: 26px; height: 26px; cursor: pointer; font-size: 1rem; }
.admin-shell .adm-prod-stepper button:hover:not(:disabled) { background: var(--a-surface-2); }
.admin-shell .adm-prod-stock-num { min-width: 26px; text-align: center; font-size: 0.85rem; font-weight: 600; }
.admin-shell .adm-prod-toggle { font-family: inherit; font-size: 0.76rem; padding: 0.35rem 0.6rem; border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm); background: var(--a-surface); color: var(--a-ink-2); cursor: pointer; letter-spacing: normal; text-transform: none; }
.admin-shell .adm-prod-toggle:hover:not(:disabled) { background: var(--a-surface-2); }
.admin-shell .adm-prod-actions { display: flex; gap: 0.35rem; flex-shrink: 0; }

/* ── Status badges (shared) ─────────────────────────────────────────── */
.admin-shell .adm-prod-badge,
.admin-shell .admin-product-status,
.admin-shell .order-status {
  font-size: 0.7rem; font-weight: 600; letter-spacing: normal; text-transform: none;
  padding: 0.16rem 0.5rem; border-radius: 20px; display: inline-flex; align-items: center; gap: 0.3rem; white-space: nowrap;
}
/* Green = good/available/in-stock/published; amber = low; red = out/sold;
   grey = muted/draft/awaiting. Aliased so every page's tone vocabulary lands
   on a colour (stockStatus → available|low|out|sold; lore → published|draft). */
.admin-shell .adm-prod-badge--ok,
.admin-shell .adm-prod-badge--available,
.admin-shell .adm-prod-badge--published,
.admin-shell .admin-product-status.available { background: var(--a-ok-soft); color: var(--a-ok); }
.admin-shell .adm-prod-badge--warn,
.admin-shell .adm-prod-badge--low { background: var(--a-warn-soft); color: var(--a-warn); }
.admin-shell .adm-prod-badge--bad,
.admin-shell .adm-prod-badge--out,
.admin-shell .adm-prod-badge--sold,
.admin-shell .admin-product-status.sold { background: var(--a-bad-soft); color: var(--a-bad); }
.admin-shell .adm-prod-badge--muted,
.admin-shell .adm-prod-badge--draft { background: var(--a-surface-2); color: var(--a-ink-3); border: 1px solid var(--a-border); }

/* ── Generic list rows (subscribers, enquiries, comments) ───────────── */
.admin-shell .admin-product-row,
.admin-shell .admin-subscriber-row,
.admin-shell .admin-comment-row {
  display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap;
  padding: 0.65rem 0.9rem; border: 1px solid var(--a-border); border-radius: var(--a-radius-sm);
  background: var(--a-surface); margin-bottom: 0.5rem;
}
.admin-shell .admin-comment-row { flex-direction: column; align-items: stretch; }
.admin-shell .admin-product-info { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; flex: 1; min-width: 0; }
.admin-shell .admin-product-sku,
.admin-shell .admin-subscriber-date,
.admin-shell .admin-comment-post { font-size: 0.76rem; color: var(--a-ink-3); letter-spacing: normal; text-transform: none; }
.admin-shell .admin-product-name,
.admin-shell .admin-subscriber-email,
.admin-shell .admin-comment-author { font-size: 0.85rem; color: var(--a-ink); font-weight: 550; letter-spacing: normal; text-transform: none; }
.admin-shell .admin-product-price { font-size: 0.82rem; color: var(--a-ink); font-weight: 600; }
.admin-shell .admin-comment-body { font-size: 0.85rem; color: var(--a-ink-2); line-height: 1.5; letter-spacing: normal; text-transform: none; }
.admin-shell .admin-comment-actions,
.admin-shell .admin-subscriber-actions { display: flex; gap: 0.4rem; }
.admin-shell .admin-subscribers,
.admin-shell .admin-pending-comments { margin-top: 0; }
.admin-shell .admin-copy-btn { margin-bottom: 0.8rem; }

/* ── FilterChips in admin ───────────────────────────────────────────── */
.admin-shell .filter-chips { gap: 0.4rem; margin: 0 0 1rem; flex-wrap: wrap; }
.admin-shell .filter-chip {
  font-family: inherit; font-size: 0.8rem; letter-spacing: normal; text-transform: none;
  padding: 0.35rem 0.75rem; border-radius: 20px; border: 1px solid var(--a-border-2);
  background: var(--a-surface); color: var(--a-ink-2); cursor: pointer;
}
.admin-shell .filter-chip.is-active { background: var(--a-accent); border-color: var(--a-accent); color: #fff; }

/* ── Rich-text editor (lighten from its dark CRT theme) ─────────────── */
.admin-shell .rte-wrap { border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm); background: var(--a-surface); overflow: hidden; }
.admin-shell .rte-toolbar { background: var(--a-surface-2); border-bottom: 1px solid var(--a-border); padding: 0.3rem 0.4rem; display: flex; flex-wrap: wrap; gap: 0.15rem; align-items: center; }
.admin-shell .rte-btn { font-family: inherit; font-size: 0.78rem; color: var(--a-ink-2); background: none; border: 1px solid transparent; border-radius: 5px; padding: 0.25rem 0.45rem; cursor: pointer; letter-spacing: normal; text-transform: none; }
.admin-shell .rte-btn:hover { background: var(--a-surface); border-color: var(--a-border); color: var(--a-ink); }
.admin-shell .rte-btn--active { background: var(--a-accent-soft); color: var(--a-accent); border-color: transparent; }
.admin-shell .rte-sep { width: 1px; height: 18px; background: var(--a-border); margin: 0 0.2rem; }
.admin-shell .rte-content { background: var(--a-surface); color: var(--a-ink); min-height: 160px; padding: 0.7rem 0.85rem; font-family: inherit; font-size: 0.9rem; line-height: 1.6; }
.admin-shell .rte-content:focus { outline: none; }

/* ── ImageUpload (lore/blog forms) — lighten from the dark CRT default ── */
.admin-shell .admin-form-image-col { display: flex; flex-direction: column; gap: 0.6rem; }
.admin-shell .admin-image-preview {
  position: relative;
  aspect-ratio: 1 / 1; width: 100%; border-radius: var(--a-radius-sm);
  background: var(--a-surface-2); border: 1px solid var(--a-border);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.admin-shell .admin-image-preview--wide { aspect-ratio: 16 / 9; }
.admin-shell .admin-image-preview img { width: 100%; height: 100%; object-fit: cover; }
.admin-shell .admin-image-placeholder { color: var(--a-ink-3); font-size: 0.8rem; letter-spacing: normal; text-transform: none; }
.admin-shell .admin-image-preview .pim-working {
  background: rgba(20, 16, 32, 0.82); color: #f4f1ea;
  font-size: 0.72rem; letter-spacing: 0.08em; text-transform: none;
}

/* ── SingleImageUpload (category/blog forms) — crop + BG action row ── */
.admin-shell .siu-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.admin-shell .siu-actions .admin-upload-btn { flex: 1; min-width: 8rem; }
.admin-shell .admin-upload-btn {
  display: inline-flex; align-items: center; justify-content: center; text-align: center;
  font-family: inherit; font-size: 0.82rem; letter-spacing: normal; text-transform: none;
  padding: 0.5rem 0.8rem; border-radius: var(--a-radius-sm);
  border: 1px dashed var(--a-border-2); background: var(--a-surface-2); color: var(--a-ink-2); cursor: pointer;
}
.admin-shell .admin-upload-btn:hover { border-color: var(--a-accent); color: var(--a-accent); background: var(--a-accent-soft); }
.admin-shell .admin-progress { display: flex; align-items: center; gap: 0.5rem; font-size: 0.76rem; color: var(--a-ink-3); }
.admin-shell .admin-progress-bar-track { flex: 1; height: 6px; border-radius: 999px; background: var(--a-border); overflow: hidden; }
.admin-shell .admin-progress-bar { height: 100%; background: var(--a-accent); }

/* ── Product image manager (lighten) ────────────────────────────────── */
.admin-shell .pim-head { display: flex; align-items: baseline; gap: 0.6rem; margin-bottom: 0.5rem; }
.admin-shell .pim-hint { font-size: 0.76rem; color: var(--a-ink-3); letter-spacing: normal; text-transform: none; }
.admin-shell .pim-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 0.6rem; background: transparent; border: none; padding: 0; }
.admin-shell .pim-card { border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm); overflow: hidden; background: var(--a-surface); }
.admin-shell .pim-add { border: 1px dashed var(--a-border-2); border-radius: var(--a-radius-sm); background: var(--a-surface-2); color: var(--a-ink-3); }
.admin-shell .pim-add:hover { border-color: var(--a-accent); color: var(--a-accent); background: var(--a-accent-soft); }
.admin-shell .pim-add-label { letter-spacing: normal; text-transform: none; font-size: 0.72rem; }
.admin-shell .pim-add-sub { letter-spacing: normal; text-transform: none; font-size: 0.66rem; }
.admin-shell .pim-actions button { background: var(--a-surface); color: var(--a-ink-2); letter-spacing: normal; text-transform: none; }
.admin-shell .pim-note { font-size: 0.74rem; color: var(--a-ink-3); letter-spacing: normal; text-transform: none; margin-top: 0.5rem; }

/* ── Switch (on/off) ────────────────────────────────────────────────── */
.admin-shell .admin-switch {
  display: inline-flex; align-items: center; gap: 0.6rem;
  background: none; border: none; padding: 0; margin: 0; cursor: pointer; font: inherit;
}
.admin-shell .admin-switch:disabled { opacity: 0.5; cursor: not-allowed; }
.admin-shell .admin-switch-track {
  width: 42px; height: 24px; border-radius: 999px; background: var(--a-border-2);
  position: relative; flex-shrink: 0; transition: background 0.16s ease;
}
.admin-shell .admin-switch.is-on .admin-switch-track { background: var(--a-accent); }
.admin-shell .admin-switch-thumb {
  position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 2px rgba(27,31,36,0.35); transition: transform 0.16s ease;
}
.admin-shell .admin-switch.is-on .admin-switch-thumb { transform: translateX(18px); }
.admin-shell .admin-switch-label { font-size: 0.85rem; font-weight: 550; color: var(--a-ink-2); min-width: 5.5rem; text-align: left; }
.admin-shell .admin-switch:focus-visible .admin-switch-track { outline: none; box-shadow: 0 0 0 3px var(--a-accent-soft); }

/* ── Segmented control (2+ mutually-exclusive options, e.g. product type) ── */
.admin-shell .admin-seg {
  display: inline-flex; flex-wrap: wrap; width: 100%; max-width: 320px; padding: 3px; gap: 3px;
  background: var(--a-surface-2); border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm);
}
.admin-shell .admin-seg-btn {
  /* flex-basis:auto (not 0) + min-width:min-content — a button never
     shrinks below what its own label needs to render on one line. With a
     fixed-width container (max-width:320px above) and 4+ uneven-length
     labels (e.g. "Specimen"/"System boot"), flex:1 1 0 with min-width:0
     let buttons shrink past their text's natural width, which doesn't
     truncate the label — it WRAPS it, and with no defined per-row height
     the wrapped second line overlapped the next button. flex-wrap on the
     container (above) is the other half of the fix: once buttons can't
     all fit on one row at their natural size, the control grows to a
     second row instead of squeezing labels into overlapping text. */
  flex: 1 1 auto; min-width: min-content;
  font-family: inherit; font-size: 0.82rem; letter-spacing: normal; text-transform: none;
  padding: 0.42rem 0.6rem; border: none; background: none; color: var(--a-ink-2);
  border-radius: calc(var(--a-radius-sm) - 2px); cursor: pointer; transition: background 0.12s, color 0.12s;
  white-space: nowrap;
}
.admin-shell .admin-seg-btn:hover:not(.is-active) { color: var(--a-ink); }
.admin-shell .admin-seg-btn.is-active {
  background: var(--a-surface); color: var(--a-accent); font-weight: 650; box-shadow: var(--a-shadow);
}

/* Wider variant — the 320px cap above suits 2–3 short labels, but the parcel
   picker has five options each carrying two price lines, which at 320px wraps
   to three cramped rows. */
.admin-shell .admin-seg--wrap { max-width: 620px; }
/* Stacked: size name over its UK and international price. Overrides the base
   white-space:nowrap, which would otherwise keep the sublabel inline. */
.admin-shell .admin-seg--wrap .admin-seg-btn {
  display: flex; flex-direction: column; align-items: center; gap: 0.12rem;
  white-space: normal; line-height: 1.2; padding: 0.5rem 0.7rem;
}

/* What each size charges. Tabular figures so the prices form a column across
   the five buttons rather than jittering — the whole point is comparing them
   at a glance. */
.admin-shell .adm-parcel-cost {
  display: flex; flex-direction: column; gap: 0.02rem;
  font-size: 0.68rem; font-weight: 500; color: var(--a-ink-3);
  font-variant-numeric: tabular-nums;
}
.admin-shell .admin-seg-btn.is-active .adm-parcel-cost { color: var(--a-accent); opacity: 0.8; }

/* Multi-select chip — e.g. the playlist picker on Displays (AdminGhost.jsx),
   where any number of clips can be "on" at once. Deliberately NOT nested
   inside an .admin-seg container: that background+border reads as "pick
   one of this joined set" everywhere else in the admin panel, which is the
   wrong signal for a checklist. A free-standing pill with its own border
   keeps the same is-active/accent-color language without implying
   single-select. */
.admin-shell .admin-seg-btn--chip {
  flex: 0 1 auto;
  border: 1px solid var(--a-border-2);
  border-radius: 999px;
  background: var(--a-surface);
}
.admin-shell .admin-seg-btn--chip:hover:not(.is-active) { border-color: var(--a-ink-3); }
.admin-shell .admin-seg-btn--chip.is-active {
  border-color: var(--a-accent); background: var(--a-accent-soft); box-shadow: none;
}

/* Legacy text-toggle (kept minimal for any stragglers) */
.admin-shell .admin-toggle {
  font-family: inherit; letter-spacing: normal; text-transform: none; font-size: 0.82rem;
  padding: 0.5rem 0.8rem; border-radius: var(--a-radius-sm);
  border: 1px solid var(--a-border-2); background: var(--a-surface); color: var(--a-ink-2); cursor: pointer;
}
.admin-shell .admin-toggle--on { background: var(--a-accent-soft); border-color: var(--a-accent); color: var(--a-accent); font-weight: 600; }

/* ── Section labels (grouping headers inside forms) ─────────────────── */
.admin-shell .admin-section-label,
.admin-shell .checkout-section-label {
  font-size: 0.95rem; font-weight: 680; letter-spacing: normal; text-transform: none;
  color: var(--a-ink); margin: 0 0 0.8rem; padding-bottom: 0.45rem;
  border-bottom: 1px solid var(--a-border); text-shadow: none;
}
.admin-shell .admin-section-label { margin-top: 0.4rem; }

/* ── Layout helpers used across forms ───────────────────────────────── */
.admin-shell .admin-input-row { display: flex; gap: 0.5rem; align-items: center; }
.admin-shell .admin-field--inline { flex-direction: row; align-items: center; justify-content: space-between; gap: 0.8rem; }
.admin-shell .admin-field--inline .admin-label { margin-bottom: 0; }
.admin-shell .admin-form-cols { display: grid; grid-template-columns: minmax(240px, 320px) 1fr; gap: 1.4rem; align-items: start; }
.admin-shell .admin-form-fields-col { min-width: 0; }
.admin-shell .admin-specs-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.4rem; }

/* ── Payment / connection status lines ──────────────────────────────── */
.admin-shell .admin-pay-status {
  font-size: 0.85rem; letter-spacing: normal; text-transform: none; margin: 0.1rem 0 0;
  padding: 0.5rem 0.7rem; border-radius: var(--a-radius-sm);
  border: 1px solid var(--a-border); background: var(--a-surface-2); color: var(--a-ink-2);
}
.admin-shell .admin-pay-status--on  { color: var(--a-ok);   background: var(--a-ok-soft);   border-color: #bfe3c8; }
.admin-shell .admin-pay-status--off { color: var(--a-warn); background: var(--a-warn-soft); border-color: #ecdca2; }

/* ── QR sections (product form) ─────────────────────────────────────── */
.admin-shell .admin-qr-section {
  background: var(--a-surface); border: 1px solid var(--a-border); border-radius: var(--a-radius);
  box-shadow: var(--a-shadow); padding: 1.1rem 1.2rem; margin-top: 1.1rem;
}
.admin-shell .admin-qr-result { margin-top: 0.8rem; display: flex; flex-direction: column; gap: 0.5rem; align-items: flex-start; }
.admin-shell .admin-qr-img { width: 200px; height: 200px; border: 1px solid var(--a-border); border-radius: var(--a-radius-sm); background: #fff; }
.admin-shell .admin-qr-url { font-size: 0.74rem; color: var(--a-ink-3); word-break: break-all; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

/* ── Orders ─────────────────────────────────────────────────────────── */
.admin-shell .adm-order-filters { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1.1rem; }
.admin-shell .adm-order-filter {
  font-family: inherit; font-size: 0.78rem; letter-spacing: normal; text-transform: none;
  padding: 0.35rem 0.75rem; border-radius: 20px; border: 1px solid var(--a-border-2);
  background: var(--a-surface); color: var(--a-ink-2); cursor: pointer;
}
.admin-shell .adm-order-filter:hover { background: var(--a-surface-2); }
.admin-shell .adm-order-filter--active { background: var(--a-accent); border-color: var(--a-accent); color: var(--a-accent-ink); font-weight: 600; }
.admin-shell .adm-order-list { display: flex; flex-direction: column; gap: 0.9rem; }
.admin-shell .adm-order-card { background: var(--a-surface); border: 1px solid var(--a-border); border-radius: var(--a-radius); box-shadow: var(--a-shadow); padding: 1rem 1.1rem; }
.admin-shell .adm-order-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.8rem; padding-bottom: 0.7rem; border-bottom: 1px solid var(--a-border); margin-bottom: 0.7rem; }
.admin-shell .adm-order-ref { font-weight: 650; font-size: 0.9rem; color: var(--a-ink); }
.admin-shell .adm-order-date { display: block; font-size: 0.74rem; color: var(--a-ink-3); margin-top: 0.15rem; }
.admin-shell .adm-order-body { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.admin-shell .adm-order-col { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.admin-shell .adm-order-label { font-size: 0.7rem; font-weight: 700; letter-spacing: normal; text-transform: none; color: var(--a-ink-3); margin-bottom: 0.25rem; }
.admin-shell .adm-order-item { font-size: 0.82rem; color: var(--a-ink); }
.admin-shell .adm-order-totals { font-size: 0.82rem; color: var(--a-ink-2); margin-top: 0.35rem; }
.admin-shell .adm-order-actions { display: flex; align-items: center; gap: 0.6rem; margin-top: 0.9rem; padding-top: 0.7rem; border-top: 1px solid var(--a-border); }
.admin-shell .adm-order-select { max-width: 220px; }

/* ── Dashboard: comments + subscribers ──────────────────────────────── */
.admin-shell .admin-comment-author { font-weight: 650; color: var(--a-ink); }
.admin-shell .admin-comment-post { font-size: 0.78rem; color: var(--a-ink-3); }
.admin-shell .admin-comment-body { font-size: 0.86rem; color: var(--a-ink); margin: 0.45rem 0 0.6rem; }
.admin-shell .admin-comment-actions { display: flex; gap: 0.5rem; }
.admin-shell .admin-subscriber-email { font-size: 0.85rem; color: var(--a-ink); }
.admin-shell .admin-subscriber-date { font-size: 0.76rem; color: var(--a-ink-3); }

/* ── Loading ────────────────────────────────────────────────────────── */
.admin-loading { padding: 3rem; text-align: center; color: var(--a-ink-3); font-size: 0.9rem; }

/* ── Responsive: sidebar collapses to an off-canvas drawer ──────────── */
@media (max-width: 860px) {
  .admin-sidebar {
    position: fixed; left: 0; top: 0; z-index: 60;
    transform: translateX(-100%); transition: transform 0.22s ease; box-shadow: var(--a-shadow-lg);
  }
  .admin-shell.admin-nav-open .admin-sidebar { transform: translateX(0); }
  .admin-burger { display: inline-flex; }
  .admin-scrim { position: fixed; inset: 0; background: rgba(15,20,25,0.4); z-index: 55; }
  .admin-content { padding: 1rem; }
}

@media (max-width: 760px) {
  .admin-shell .admin-form-cols { grid-template-columns: 1fr; }
  .admin-shell .admin-specs-grid { grid-template-columns: 1fr; }
  .admin-shell .adm-order-body { grid-template-columns: 1fr; gap: 0.7rem; }
}

/* Narrow screens: list rows reflow to two lines so nothing is cut off —
   thumb + name on line 1, status + actions on line 2. */
@media (max-width: 560px) {
  .admin-shell .adm-prod-row { flex-wrap: wrap; row-gap: 0.55rem; padding: 0.75rem 0.8rem; }
  .admin-shell .adm-prod-main { flex: 1 1 auto; }
  .admin-shell .adm-prod-stock { order: 3; flex: 0 0 auto; }
  .admin-shell .adm-prod-actions { order: 4; margin-left: auto; flex: 0 0 auto; }
  .admin-shell .adm-order-actions { flex-wrap: wrap; }
  .admin-shell .adm-order-select { max-width: none; flex: 1 1 auto; }
}

/* ── Toasts ─────────────────────────────────────────────────────────── */
.admin-toasts {
  position: fixed; z-index: 200; right: 1rem; bottom: 1rem;
  display: flex; flex-direction: column; gap: 0.5rem; max-width: min(360px, calc(100vw - 2rem));
}
.admin-toast {
  display: flex; align-items: flex-start; gap: 0.55rem; cursor: pointer;
  background: var(--a-surface); color: var(--a-ink); border: 1px solid var(--a-border);
  border-left: 3px solid var(--a-ink-3); border-radius: var(--a-radius-sm);
  box-shadow: var(--a-shadow-lg); padding: 0.6rem 0.8rem; font-size: 0.85rem;
  animation: admin-toast-in 0.18s ease;
}
@keyframes admin-toast-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.admin-toast--success { border-left-color: var(--a-ok); }
.admin-toast--error   { border-left-color: var(--a-bad); }
.admin-toast--info    { border-left-color: var(--a-accent); }
.admin-toast-icon {
  flex-shrink: 0; width: 18px; height: 18px; border-radius: 50%; margin-top: 1px;
  display: flex; align-items: center; justify-content: center; font-size: 0.72rem; font-weight: 700; color: #fff;
}
.admin-toast--success .admin-toast-icon { background: var(--a-ok); }
.admin-toast--error   .admin-toast-icon { background: var(--a-bad); }
.admin-toast--info    .admin-toast-icon { background: var(--a-accent); }
.admin-toast-msg { line-height: 1.35; }

/* ── Confirm modal ──────────────────────────────────────────────────── */
.admin-modal-scrim {
  position: fixed; inset: 0; z-index: 210; background: rgba(15,20,25,0.45);
  display: flex; align-items: center; justify-content: center; padding: 1rem;
  animation: admin-toast-in 0.12s ease;
}
.admin-modal {
  background: var(--a-surface); border: 1px solid var(--a-border); border-radius: var(--a-radius);
  box-shadow: var(--a-shadow-lg); padding: 1.3rem 1.4rem; width: 100%; max-width: 420px;
}
.admin-modal-title { font-size: 1.05rem; font-weight: 680; color: var(--a-ink); margin: 0 0 0.5rem; }
.admin-modal-body { font-size: 0.88rem; color: var(--a-ink-2); line-height: 1.5; margin: 0 0 1.2rem; }
.admin-modal-actions { display: flex; justify-content: flex-end; gap: 0.6rem; }

/* ── Orders: toolbar + clickable rows ───────────────────────────────── */
.admin-shell .adm-order-toolbar { display: flex; gap: 0.6rem; margin-bottom: 0.9rem; flex-wrap: wrap; }
.admin-shell .adm-order-toolbar .admin-input:first-child { flex: 1 1 240px; }
.admin-shell .adm-order-toolbar select.admin-input { flex: 0 0 auto; width: auto; max-width: 220px; }

.admin-shell .adm-order-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem; width: 100%;
  text-align: left; font: inherit; cursor: pointer;
  padding: 0.8rem 0.9rem; border: none; border-bottom: 1px solid var(--a-border); background: var(--a-surface);
}
.admin-shell .adm-order-row:last-child { border-bottom: none; }
.admin-shell .adm-order-row:hover { background: var(--a-surface-2); }
.admin-shell .adm-order-row-main { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
.admin-shell .adm-order-row-ref { font-size: 0.86rem; font-weight: 650; color: var(--a-ink); }
.admin-shell .adm-order-row-sub { font-size: 0.76rem; color: var(--a-ink-3); }
.admin-shell .adm-order-row-items { font-size: 0.78rem; color: var(--a-ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 46ch; }
.admin-shell .adm-order-row-right { display: flex; align-items: center; gap: 0.9rem; flex-shrink: 0; }
.admin-shell .adm-order-row-total { font-size: 0.9rem; font-weight: 650; color: var(--a-ink); }

/* Selectable order line: checkbox + the existing row button as siblings.
   The border-bottom moves up here, because the row is no longer the direct
   child of the list — leaving it on .adm-order-row would draw the rule under
   the button only, stopping short of the checkbox. */
.admin-shell .adm-order-line {
  display: flex; align-items: stretch;
  border-bottom: 1px solid var(--a-border); background: var(--a-surface);
}
.admin-shell .adm-order-line:last-child { border-bottom: none; }
.admin-shell .adm-order-line .adm-order-row { border-bottom: none; }
.admin-shell .adm-order-line:hover { background: var(--a-surface-2); }
.admin-shell .adm-order-line:hover .adm-order-row { background: transparent; }

.admin-shell .adm-order-pick {
  display: flex; align-items: center; padding: 0 0.2rem 0 0.9rem; cursor: pointer;
}
.admin-shell .adm-order-pick input { width: 1rem; height: 1rem; cursor: pointer; accent-color: var(--a-accent); }

/* Bulk action bar — only rendered when something is selected. */
.admin-shell .adm-order-bulk {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  margin-top: 0.7rem; padding: 0.55rem 0.8rem;
  border: 1px solid var(--a-accent); border-radius: var(--a-radius-sm);
  background: var(--a-accent-soft);
}
.admin-shell .adm-order-bulk-count {
  font-size: 0.82rem; font-weight: 650; color: var(--a-accent); margin-right: auto;
}

/* The archive toggle is a view switch, not a status — set apart from the pills. */
.admin-shell .adm-order-filter--archive { margin-left: auto; }

/* ── Order detail ───────────────────────────────────────────────────── */
/* min-width:0 on the grid items — without it, a 1fr track won't shrink
   below its content's intrinsic min-width (grid items default to
   min-width:auto), so a long line (order ref, "£32.00" total row) forces
   the whole track wider than the grid container and the card overflows
   the viewport instead of wrapping. Found live: order totals clipped off
   the right edge of the screen on a real phone-width order detail page. */
.admin-shell .adm-od-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.admin-shell .adm-od-grid > .admin-card { min-width: 0; }
.admin-shell .adm-od-items { display: flex; flex-direction: column; gap: 0.4rem; }
.admin-shell .adm-od-item { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.85rem; color: var(--a-ink); }
.admin-shell .adm-od-totals { margin-top: 0.8rem; padding-top: 0.7rem; border-top: 1px solid var(--a-border); display: flex; flex-direction: column; gap: 0.3rem; }
.admin-shell .adm-od-totals > div { display: flex; justify-content: space-between; font-size: 0.85rem; color: var(--a-ink-2); }
.admin-shell .adm-od-grand { font-weight: 700; color: var(--a-ink) !important; font-size: 0.95rem !important; }
.admin-shell .adm-od-row { display: flex; gap: 0.8rem; padding: 0.3rem 0; font-size: 0.85rem; }
.admin-shell .adm-od-key { flex: 0 0 5.5rem; color: var(--a-ink-3); }
.admin-shell .adm-od-val { color: var(--a-ink); min-width: 0; }
.admin-shell .adm-od-fulfil { display: grid; grid-template-columns: 1fr 1fr 1.4fr; gap: 0.8rem; }
.admin-shell .adm-od-fulfil > .admin-field { min-width: 0; }

@media (max-width: 760px) {
  .admin-shell .adm-od-grid { grid-template-columns: 1fr; }
  .admin-shell .adm-od-fulfil { grid-template-columns: 1fr; }
  .admin-shell .adm-order-row-items { max-width: 30ch; }
}

/* PageSectionsEditor — shared add/remove/reorder list editor (About/Shipping
   sections, FAQ items). */
.admin-shell .pse { display: flex; flex-direction: column; gap: 0.9rem; }
.admin-shell .pse-card { border: 1px solid var(--a-border); border-radius: var(--a-radius); background: var(--a-surface); padding: 0.9rem; box-shadow: var(--a-shadow); }
.admin-shell .pse-card--over { outline: 2px dashed var(--a-accent); outline-offset: -2px; }
.admin-shell .pse-card-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.6rem; }
.admin-shell .pse-drag-handle { cursor: grab; color: var(--a-ink-3); letter-spacing: -0.2em; user-select: none; }
.admin-shell .pse-card-head .admin-hint { flex: 1; margin: 0; font-weight: 600; }

  /* ── Shipping admin (AdminShipping.jsx) ─────────────────────────────────
     Eight price fields, four sizes × UK/international. This replaced ~200
     lines of styles for weight bands, zone tables and courier toggles — see
     the header of AdminShipping.jsx. */
  .admin-shell .adm-ship-card { margin-bottom: 1.1rem; }
  .admin-shell .adm-ship-card:last-child { margin-bottom: 0; }
  .admin-shell .adm-ship-dest { margin-top: 1.2rem; }
  .admin-shell .adm-ship-dest:first-of-type { margin-top: 0.6rem; }

  .admin-shell .adm-ship-prices {
    display: grid; gap: 0.55rem; margin-top: 0.6rem;
  }

  /* Label left, price right, on one row. Grid rather than flex so every input
     starts at the same x regardless of how long the size note is — ragged
     inputs read as a rendering bug. */
  .admin-shell .adm-ship-price {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 8.5rem;
    align-items: center;
    gap: 0.8rem;
  }
  .admin-shell .adm-ship-price-name {
    display: flex; flex-direction: column; gap: 0.1rem;
    font-size: 0.86rem; font-weight: 600; color: var(--a-ink);
  }
  .admin-shell .adm-ship-price-name .admin-hint { margin: 0; font-weight: 400; }

  /* The £ sits INSIDE the field. Absolute rather than a flex sibling so it
     can't be pushed out of the box by a long value, and the input carries
     matching left padding so typed text never slides under it. */
  .admin-shell .adm-ship-price-input { position: relative; display: block; }
  .admin-shell .adm-ship-price-sym {
    position: absolute; left: 0.6rem; top: 50%; transform: translateY(-50%);
    color: var(--a-ink-3); pointer-events: none; font-size: 0.9rem;
  }
  .admin-shell .adm-ship-price-input .admin-input {
    width: 100%; padding-left: 1.5rem; text-align: right;
    font-variant-numeric: tabular-nums;
  }

  /* Stack on narrow screens — 8.5rem of input plus a two-line label doesn't
     fit a phone, and squeezing it makes the price unreadable. */
  @media (max-width: 640px) {
    .admin-shell .adm-ship-price { grid-template-columns: 1fr; gap: 0.3rem; }
    .admin-shell .adm-ship-price-input .admin-input { text-align: left; }
  }


/* Drop-off label booking on the order detail page. Set apart from the
   fulfilment controls above it because it creates a real courier order. */
.admin-shell .adm-od-label {
  margin-top: 0.9rem; padding-top: 0.9rem;
  border-top: 1px solid var(--a-border);
}
.admin-shell .adm-od-label-head { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin: 0 0 0.3rem; }
.admin-shell .adm-od-label-tag {
  font-size: 0.68rem; font-weight: 650; letter-spacing: 0.04em;
  color: var(--a-ok); background: var(--a-ok-soft);
  border-radius: 999px; padding: 0.1rem 0.5rem;
}
.admin-shell .adm-od-label-meta { font-size: 0.8rem; color: var(--a-ink-2); }

/* Courier-reported movement. Distinct from the label tag above: that says a
   label exists, this says the parcel has actually been scanned. */
.admin-shell .adm-od-track {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0.4rem 0.6rem; margin: 0.6rem 0 0;
}
.admin-shell .adm-od-track-tag {
  font-size: 0.68rem; font-weight: 650; letter-spacing: 0.04em;
  color: var(--a-accent); background: var(--a-accent-soft);
  border-radius: 999px; padding: 0.1rem 0.5rem;
}
.admin-shell .adm-od-track-tag.is-delivered { color: var(--a-ok); background: var(--a-ok-soft); }
.admin-shell .adm-od-track-meta { font-size: 0.8rem; color: var(--a-ink-2); }

.admin-shell .adm-od-track-log { margin-top: 0.5rem; font-size: 0.82rem; }
.admin-shell .adm-od-track-log summary {
  cursor: pointer; color: var(--a-ink-2); padding: 0.2rem 0;
}
.admin-shell .adm-od-track-log summary:hover { color: var(--a-accent); }
.admin-shell .adm-od-track-log ul {
  list-style: none; margin: 0.3rem 0 0; padding: 0;
  border-left: 2px solid var(--a-border-2); padding-left: 0.7rem;
}
.admin-shell .adm-od-track-log li {
  display: flex; flex-wrap: wrap; gap: 0.2rem 0.6rem; padding: 0.22rem 0;
  color: var(--a-ink);
}
.admin-shell .adm-od-track-when {
  color: var(--a-ink-2); font-variant-numeric: tabular-nums; min-width: 8.5rem;
}

/* Booked-label thumbnail + the full-screen scan view. */
.admin-shell .adm-od-label-tag.is-unpaid { color: var(--a-warn); background: var(--a-warn-soft); }
.admin-shell .adm-od-label-thumb {
  display: block; margin-top: 0.5rem; padding: 0; cursor: zoom-in;
  border: 1px solid var(--a-border-2); border-radius: var(--a-radius-sm);
  background: #fff; max-width: 260px; overflow: hidden;
}
.admin-shell .adm-od-label-thumb img { display: block; width: 100%; height: auto; }
.admin-shell .adm-od-label-thumb:hover { border-color: var(--a-accent); }

/* Portalled to <body>, so it is NOT under .admin-shell — these rules are
   deliberately unscoped. White ground and maximum size: a handheld scanner
   needs contrast and a big barcode, and the phone's own brightness does the
   rest. */
.adm-scan {
  position: fixed; inset: 0; z-index: 1000;
  background: #fff;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem; cursor: zoom-out;
}
.adm-scan-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.adm-scan-close {
  position: fixed; top: 1rem; right: 1rem;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 0.9rem; padding: 0.6rem 1rem; min-height: 44px;
  border: 1px solid #d3d8de; border-radius: 8px; background: #fff; color: #1f2328;
  cursor: pointer;
}
/* Generated: ordered @imports — DO NOT reorder (cascade depends on it). */
/* ═══════════════════════════════════════════════════════════════════════
   DESIGN TOKENS — single source of truth for colour, type, space, motion.
   Use rgba(var(--violet-3), .x) for tints; --ink-* for readable text levels.
   ═══════════════════════════════════════════════════════════════════════ */
/* The CRT terminal font, self-hosted (13.5KB). Every font-family in the app
   names "Share Tech Mono" first — without this face it silently fell back to
   Courier New. swap = text renders immediately in the fallback, then upgrades. */
@font-face {
  font-family: "Share Tech Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/share-tech-mono.woff2") format("woff2");
}
:root {
  /* Palette (raw RGB triplets for rgba(var(--x), a)) */
  --violet-1: 232, 218, 252;   /* brightest ink / headings */
  --violet-2: 196, 158, 232;   /* secondary */
  --violet-3: 155, 95, 255;    /* core accent */
  --violet-4: 120, 60, 200;    /* deep accent / glow */
  --amber:    255, 140, 55;    /* G.L.O.O.M. / observation */
  --toxic:    120, 255, 172;   /* available / success */
  --warn:     255, 200, 80;    /* low stock / caution */
  --blood:    255, 74, 74;     /* sold / claimed / danger */

  --surface-0: 6, 3, 14;       /* deepest background */
  --surface-1: 12, 6, 24;      /* panel */
  --surface-2: 20, 11, 36;     /* raised */

  /* Ink (text) — readable floors; never go below --ink-faint for real copy */
  --ink-strong: rgba(232, 218, 252, 0.98);
  --ink:        rgba(216, 198, 242, 0.92);
  --ink-dim:    rgba(198, 172, 240, 0.84);
  --ink-faint:  rgba(180, 154, 222, 0.74);

  /* Spacing scale */
  --space-1: 0.25rem; --space-2: 0.5rem;  --space-3: 0.75rem; --space-4: 1rem;
  --space-5: 1.5rem;  --space-6: 2rem;    --space-8: 3rem;

  /* Type scale (rem — scales with the CRT base font-size) */
  --fs-caption: 0.6rem;
  --fs-small:   0.72rem;
  --fs-body:    0.82rem;
  --fs-h3:      0.95rem;
  --fs-h2:      1.2rem;
  --fs-h1:      clamp(1.4rem, 4.5vw, 2.1rem);

  /* Motion */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur-fast: 140ms;
  --dur-med:  220ms;

  /* Effects */
  --glow-violet: 0 0 14px rgba(155, 95, 255, 0.38);
  --line-soft:   1px solid rgba(155, 95, 255, 0.18);
  --line-mid:    1px solid rgba(155, 95, 255, 0.3);

  /* Container widths — tablet/laptop layer (see 17-responsive.css).
     min() only ever narrows, so these resolve to 100%-equivalent widths on
     mobile by construction and never force width on a narrow screen. */
  --w-prose:  min(70ch,   calc(100vw - 4rem));  /* blog body, entries */
  --w-narrow: min(760px,  calc(100vw - 3rem));  /* forms, single col  */
  --w-mid:    min(1080px, calc(100vw - 4rem));  /* featured, dossier  */
  --w-grid:   min(1180px, calc(100vw - 4rem));  /* card grids         */
  --w-wide:   min(1360px, calc(100vw - 5rem));  /* ≥1600 grids        */
}
/* Single themed focus ring everywhere (accessibility + consistency).
   Uses outline so it never disturbs existing layout/box-shadows. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid rgba(var(--violet-3), 0.75);
  outline-offset: 2px;
}
/* Themed text selection */
::selection { background: rgba(var(--violet-3), 0.35); color: #fff; }
/* ── Public product page ────────────────────────────── */
.pub-page {
  width: 100%;
  min-height: 100dvh;
  background: #06040e;
  /* Use plain px so text is readable regardless of the CRT rem scale */
  font-size: 14px;
  color: #e2d5ff;
  font-family: inherit;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}
/* Scanline texture removed site-wide so images never sit under it. */
.pub-scanlines {
  display: none;
}
.pub-page--loading,
.pub-page--404 {
  justify-content: center;
  align-items: center;
}
/* Loading state */
.pub-loading-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
}
.pub-loading-brand {
  font-size: 13px;
  letter-spacing: 0.24em;
  color: rgba(155, 95, 255, 0.6);
}
.pub-loading-dots {
  font-size: 18px;
  letter-spacing: 0.3em;
  color: rgba(155, 95, 255, 0.85);
  animation: text-flicker 1.4s ease-in-out infinite;
}
/* 404 state */
.pub-404-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  padding: 2rem;
  text-align: center;
}
.pub-404 {
  font-size: 16px;
  letter-spacing: 0.2em;
  color: rgba(155, 95, 255, 0.85);
  margin: 0;
}
.pub-404-sub {
  font-size: 13px;
  color: rgba(196, 160, 255, 0.7);
  margin: 0;
}
.pub-404-link {
  margin-top: 0.5rem;
  font-size: 12px;
  letter-spacing: 0.16em;
  color: rgba(155, 95, 255, 0.8);
  text-decoration: none;
  border: 1px solid rgba(155, 95, 255, 0.3);
  padding: 0.4rem 0.9rem;
  transition: color 160ms, border-color 160ms, background 160ms;
}
.pub-404-link:hover {
  color: #b97fff;
  border-color: rgba(155, 95, 255, 0.6);
  background: rgba(155, 95, 255, 0.08);
}
/* Channel limit notice */
.pub-channel-limit-notice {
  font-size: 11px;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.5);
  text-align: center;
  padding: 0.7rem 1rem;
  border-top: 1px solid rgba(155, 95, 255, 0.1);
  margin: 0;
}
.pub-inner {
  width: 100%;
  max-width: 860px;
  padding: 2rem 1.5rem 3rem;
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  position: relative;
  z-index: 11; /* sit above scanlines so text is crisp */
}
/* Branding header */
.pub-brand {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding-bottom: 0.8rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.25);
}
.pub-brand-name {
  font-size: 13px;
  letter-spacing: 0.22em;
  color: #b97fff;
  text-shadow: 0 0 14px rgba(155, 95, 255, 0.6);
}
.pub-brand-sep {
  color: rgba(155, 95, 255, 0.5);
}
.pub-brand-sub {
  font-size: 11px;
  letter-spacing: 0.16em;
  color: rgba(180, 140, 255, 0.8);
}
/* Two-column layout */
.pub-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2.4rem;
  align-items: start;
}
/* Image column */
.pub-img-col {}
.pub-img-wrap {
  position: relative;
  aspect-ratio: 3 / 4;
  background: rgba(155, 95, 255, 0.04);
  border: 1px solid rgba(155, 95, 255, 0.2);
  /* z-index: 11 not needed — pub-inner already sits above scanlines */
}
.pub-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.pub-img-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: rgba(155, 95, 255, 0.4);
  min-height: 280px;
}
.pub-sold-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  letter-spacing: 0.2em;
  color: rgba(255, 80, 80, 0.95);
  background: rgba(6, 4, 14, 0.6);
  text-shadow: 0 0 20px rgba(255, 80, 80, 0.7);
}
/* Info column */
.pub-info-col {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding-top: 0.4rem;
}
.pub-sku {
  font-size: 11px;
  letter-spacing: 0.2em;
  color: rgba(180, 140, 255, 0.75);
  margin: 0;
}
.pub-title {
  font-size: clamp(22px, 4vw, 36px);
  letter-spacing: 0.06em;
  color: #ffffff;
  margin: 0;
  text-shadow: 0 0 24px rgba(155, 95, 255, 0.5);
  line-height: 1.15;
}
.pub-divider {
  height: 1px;
  background: linear-gradient(to right, rgba(155, 95, 255, 0.35), transparent);
}
.pub-desc {
  font-size: 15px;
  line-height: 1.75;
  letter-spacing: 0.02em;
  color: #c8b4e8;
  margin: 0;
  text-transform: none;
}
.pub-meta-row {
  display: flex;
  align-items: center;
  gap: 1.4rem;
}
.pub-price {
  font-size: 22px;
  letter-spacing: 0.08em;
  color: #ffffff;
}
.pub-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 12px;
  letter-spacing: 0.14em;
}
.pub-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  flex-shrink: 0;
}
.pub-status--available .pub-status-dot { background: #78ffb0; box-shadow: 0 0 8px rgba(120, 255, 172, 0.6); }
.pub-status--available { color: #78ffb0; }
.pub-status--sold .pub-status-dot { background: rgba(255, 80, 80, 0.85); }
.pub-status--sold { color: rgba(255, 100, 100, 0.9); }
.pub-cta {
  font-size: 12px;
  letter-spacing: 0.06em;
  color: rgba(180, 140, 255, 0.85);
  margin: 0;
}
.pub-cta-link {
  color: #b97fff;
  text-decoration: none;
  border-bottom: 1px solid rgba(155, 95, 255, 0.5);
  transition: color 150ms, border-color 150ms;
}
.pub-cta-link:hover {
  color: #e2d5ff;
  border-color: #e2d5ff;
}
/* Channel trigger button */
.pub-channel-btn {
  margin-top: 0.4rem;
  padding: 10px 18px;
  font-size: 12px;
  letter-spacing: 0.16em;
  color: #b97fff;
  background: transparent;
  border: 1px solid rgba(155, 95, 255, 0.4);
  cursor: pointer;
  transition: background 180ms, border-color 180ms, color 180ms;
  align-self: flex-start;
}
.pub-channel-btn:hover {
  background: rgba(155, 95, 255, 0.12);
  border-color: #b97fff;
  color: #e2d5ff;
}
/* Channel section */
.pub-channel {
  border: 1px solid rgba(155, 95, 255, 0.2);
  display: flex;
  flex-direction: column;
}
.pub-channel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  border-bottom: 1px solid rgba(155, 95, 255, 0.15);
  gap: 0.6rem;
  flex-wrap: wrap;
}
.pub-channel-title {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(180, 140, 255, 0.9);
}
.pub-channel-meta {
  display: flex;
  gap: 0.8rem;
  align-items: center;
}
.pub-channel-gate {
  padding: 2rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  text-align: center;
}
.pub-channel-gate-text {
  font-size: 13px;
  letter-spacing: 0.14em;
  color: #b97fff;
  margin: 0;
}
.pub-channel-gate-sub {
  font-size: 14px;
  letter-spacing: 0.02em;
  color: #c8b4e8;
  text-transform: none;
  max-width: 380px;
  line-height: 1.7;
  margin: 0;
}
.pub-channel-messages {
  min-height: 200px;
  height: 44vh;
  max-height: 520px;
}
/* Footer */
.pub-footer {
  padding-top: 1rem;
  border-top: 1px solid rgba(155, 95, 255, 0.12);
  text-align: center;
}
.pub-footer-text {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.55);
}
/* Mobile */
@media (max-width: 600px) {
  .pub-page {
    font-size: 15px;
  }

  .pub-inner {
    padding: 1.2rem 1rem 2rem;
    gap: 1.4rem;
  }

  .pub-layout {
    grid-template-columns: 1fr;
    gap: 1.4rem;
  }

  .pub-img-wrap {
    /* On phones, don't let the image take more than half the screen height */
    max-height: 55vw;
    aspect-ratio: auto;
  }

  .pub-title {
    font-size: clamp(20px, 7vw, 28px);
  }

  .pub-desc {
    font-size: 15px;
  }

  .pub-channel-messages {
    min-height: 160px;
    height: 38vh;
  }

  .channel-input-row {
    gap: 0.4rem;
    padding: 0.5rem 0.6rem;
  }

  .channel-input {
    font-size: 14px;
  }
}
/* ── Launch gate ─────────────────────────────────────────────────────────── */
/* The pre-launch SiteGate (a hardcoded shared password) and its styles were
   removed when the site went live. The comment below refers to it because
   .launch-gate deliberately duplicated its shell mechanics rather than sharing
   them. */
/* Full-screen overlay: fixed/inset/z-index/font, self-contained so it doesn't
   depend on the shell's layout being mounted behind it. */
.launch-gate {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: #05020e;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Share Tech Mono", "Courier New", monospace;
  overflow: hidden;
  animation: screen-on 420ms ease both;
}
/* Ambient phosphor bloom behind the box — the tube's own emission, not a
   page background. Static (no drift) so it reads as glow, not decoration. */
.launch-gate-glow {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 60% 50% at 50% 42%,
    rgba(155, 95, 255, 0.16),
    rgba(155, 95, 255, 0.05) 45%,
    transparent 72%
  );
}
/* Gloomeria's system — orrery diagram behind the readout: star, tilted
   orbits, markers, and cycling detail callouts. Full-bleed so the canvas's
   own pixel coordinates match the container the callout boxes are
   positioned in (--lx/--ly below are canvas-local px). */
.launch-gate-orrery {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.68;
}
.launch-gate-planet {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.launch-gate-callout {
  position: absolute;
  left: var(--lx);
  top: var(--ly);
  animation: callout-in 320ms ease both;
}
.launch-gate-callout-leader {
  position: absolute;
  top: 0;
  height: 1px;
  width: 46px;
  background: rgba(155, 95, 255, 0.5);
}
.launch-gate-callout-box {
  position: absolute;
  top: -1px;
  width: max-content;
  /* Hard viewport-relative cap as a last-resort safety net. The JS side
     only guarantees ONE side has cw/2 clear (roomLeft + roomRight always
     equals cw, so the larger of the two is always >= cw/2) — not both, and
     not the full desktop footprint — so the cap has to match that same
     cw/2 guarantee (minus the leader) rather than the full viewport width,
     or a panel could still claim more room than the JS side actually
     reserved for it. */
  max-width: min(210px, calc(50vw - 46px));
  border: 1px solid rgba(155, 95, 255, 0.35);
  background: rgba(10, 5, 20, 0.55);
  padding: 0.45rem 0.6rem;
  backdrop-filter: blur(1px);
}
.launch-gate-callout-title {
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  color: rgba(232, 218, 252, 0.85);
  margin: 0 0 0.3rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.25);
  padding-bottom: 0.25rem;
}
.launch-gate-callout-line {
  display: flex;
  justify-content: space-between;
  gap: 0.6rem;
  font-size: 0.44rem;
  letter-spacing: 0.06em;
  margin: 0.16rem 0;
  white-space: nowrap;
}
.launch-gate-callout-label {
  color: rgba(196, 158, 232, 0.55);
}
.launch-gate-callout-value {
  color: rgba(210, 178, 255, 0.85);
}
/* Leader runs right from the marker by default; mirrored when the marker
   sits in the right half of the screen so the box never runs off-canvas. */
.launch-gate-callout--right .launch-gate-callout-leader { left: 0; }
.launch-gate-callout--right .launch-gate-callout-box { left: 46px; }
.launch-gate-callout--left .launch-gate-callout-leader { right: 0; }
.launch-gate-callout--left .launch-gate-callout-box { right: 46px; text-align: right; }
.launch-gate-callout--left .launch-gate-callout-line { flex-direction: row-reverse; }
@keyframes callout-in {
  from { opacity: 0; transform: translateY(-3px); }
  to { opacity: 1; transform: translateY(0); }
}
.launch-gate-box {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  width: min(560px, 92vw);
  text-align: center;
}
.launch-gate-system {
  font-size: 0.56rem;
  letter-spacing: 0.28em;
  color: rgba(255, 150, 60, 0.75);
  margin: 0;
}
.launch-gate-header {
  font-size: clamp(0.78rem, 2.2vw, 1rem);
  letter-spacing: 0.14em;
  color: rgba(232, 218, 252, 0.95);
  margin: 0;
  text-shadow: 0 0 18px rgba(155, 95, 255, 0.45);
}
.launch-gate-sub {
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  color: rgba(210, 178, 255, 0.75);
  margin: 0 0 0.4rem;
}
.launch-gate-digits {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.4rem 0;
}
.launch-gate-digit-group {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
}
.launch-gate-digit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  min-width: 3.2rem;
  padding: 0.5rem 0.3rem 0.6rem;
  border: 1px solid rgba(155, 95, 255, 0.22);
  background: rgba(20, 11, 36, 0.5);
  border-radius: 2px;
}
.launch-gate-digit--tick {
  animation: digit-pulse 1s ease;
}
.launch-gate-digit-value {
  font-size: clamp(1.7rem, 5.5vw, 2.7rem);
  font-variant-numeric: tabular-nums;
  color: rgba(232, 218, 252, 0.98);
  text-shadow: 0 0 22px rgba(155, 95, 255, 0.6), 0 0 4px rgba(232, 218, 252, 0.5);
  line-height: 1;
}
.launch-gate-digit-label {
  font-size: 0.48rem;
  letter-spacing: 0.18em;
  color: rgba(196, 158, 232, 0.6);
}
.launch-gate-digit-sep {
  font-size: clamp(1.7rem, 5.5vw, 2.7rem);
  line-height: 1;
  color: rgba(155, 95, 255, 0.35);
  align-self: flex-start;
  margin-top: 0.5rem;
}
.launch-gate-status {
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  color: rgba(155, 95, 255, 0.65);
  margin: 0.6rem 0 0;
  animation: boot-line-in 320ms ease both;
}
.launch-gate-status-prompt {
  color: rgba(155, 95, 255, 0.85);
}
.launch-gate-live {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
}
@keyframes digit-pulse {
  0% { text-shadow: 0 0 22px rgba(155, 95, 255, 0.6), 0 0 4px rgba(232, 218, 252, 0.5); }
  30% { text-shadow: 0 0 32px rgba(155, 95, 255, 0.9), 0 0 8px rgba(232, 218, 252, 0.8); border-color: rgba(155, 95, 255, 0.4); }
  100% { text-shadow: 0 0 22px rgba(155, 95, 255, 0.6), 0 0 4px rgba(232, 218, 252, 0.5); }
}
/* /login rendered bare (no CRT shell) while the launch gate is up — .page-panel
   normally relies on a flex parent (.crt-page's <main>) to fill the viewport;
   this wrapper stands in for that so the login box still centers cleanly. */
.launch-gate-bare {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: #05020e;
}
/* ── */
.app-logo.large {
  width: 320px;
  max-width: 80vw;
  height: auto;
}
/* Centered logo styling */
.logo-container {
  position: relative;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.app-logo {
  width: 120px;
  height: auto;
  display: block;
  filter: drop-shadow(0 0 16px #9b5fff88);
}
.nav-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 30;
  height: 2.2rem;
  display: flex;
  align-items: stretch;
  padding: 4px 4px 0;
  background: linear-gradient(180deg, rgba(6, 4, 14, 0.98) 0%, rgba(8, 5, 18, 0.94) 100%);
  border-bottom: 1px solid rgba(155, 95, 255, 0.12);
  overflow: visible;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.nav-bar::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background: repeating-linear-gradient(
    to bottom,
    rgba(180, 130, 255, 0.22) 0 1px,
    rgba(0, 0, 0, 0.32) 1px 3px
  );
  opacity: 0.55;
  animation: scanline-drift 12s linear infinite;
}
.cabinet-menu {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: stretch;
  flex-wrap: nowrap;
  gap: 0.25rem;
  overflow-x: auto;
  overflow-y: visible;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-x;
  position: relative;
  z-index: 1;
}
.cabinet-menu::-webkit-scrollbar {
  display: none;
}
/* ── Cart icon (nav bar, top right) ───────────────────── */
.nav-cart {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 0 0.55rem;
  margin-left: 0.4rem;
  color: rgba(200, 170, 255, 0.85);
  text-decoration: none;
  transition: color 160ms ease, transform 160ms ease;
}
.nav-cart:hover { color: rgba(226, 207, 255, 1); }
.nav-cart:active { transform: scale(0.92); }
.nav-cart.is-active { color: rgba(150, 235, 120, 0.95); }
.nav-cart.has-items { color: rgba(150, 235, 120, 0.95); }
.nav-cart-icon {
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.nav-cart-badge {
  position: absolute;
  top: -1px;
  right: -3px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  box-sizing: border-box;
  border-radius: 8px;
  background: rgba(110, 220, 80, 0.95);
  color: #06140a;
  font-size: 9px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
  box-shadow: 0 0 6px rgba(110, 220, 80, 0.6);
}
/* ── Per-tab colour identity ──────────────────────────── */
/* --tc: R, G, B  used via rgba(var(--tc), opacity)       */
.tag-amber   { --tc: 155,  95, 255; }
.tag-olive   { --tc: 110, 220,  80; }
.tag-red     { --tc: 220,  55,  65; }
.tag-blue    { --tc:  60, 200, 220; }
.tag-purple  { --tc: 190,  90, 255; }
.tag-admin   { --tc: 255, 140,  50; }
.tag-account { --tc: 180, 130, 255; }
.tag-login   { --tc: 180, 130, 255; }
.cabinet-tag {
  position: relative;
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  /* Thin coloured top edge = a subtle hint of the section's channel colour;
     the full colour only blooms on hover/active so the resting nav stays calm. */
  border-top: 2px solid rgba(var(--tc), 0.5);
  border-left: 1px solid rgba(var(--tc), 0.14);
  border-right: none;
  border-bottom: none;
  border-radius: 3px 3px 0 0;
  padding: 0 0.85rem;
  text-decoration: none;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-size: 0.64rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  flex: 0 0 auto;
  color: var(--ink-dim);
  /* Tab body is slightly lighter than the nav — a separate physical card sitting in the drawer */
  background: #181228;
  cursor: pointer;
  /* Hard right shadow = the card's physical thickness (2px of visible "edge") */
  box-shadow:
    2px 0 0 #000,
    inset 0 -1px 0 rgba(0, 0, 0, 0.5);
  transition: color 140ms ease, text-shadow 140ms ease, background 140ms ease,
              border-color 140ms ease, box-shadow 140ms ease, transform 120ms ease;
  z-index: 1;
}
/* Phosphor glow strip under the top colour bar — CRT bleed */
.cabinet-tag::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0.25rem;
  background: rgba(var(--tc), 0.08);
  pointer-events: none;
}
/* Hover scan sweep — CRT phosphor charge across the card face */
.cabinet-tag::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    108deg,
    transparent            0%,
    rgba(var(--tc), 0.05) 40%,
    rgba(var(--tc), 0.18) 50%,
    rgba(var(--tc), 0.05) 60%,
    transparent           100%
  );
  transform: translateX(-140%);
  z-index: 1;
}
.cabinet-tag:hover::after {
  animation: tab-scan 380ms ease-out forwards;
}
@keyframes tab-scan {
  from { transform: translateX(-140%); }
  to   { transform: translateX(140%); }
}
.cabinet-tag:hover {
  color: rgba(var(--tc), 0.95);
  text-shadow: 0 0 8px rgba(var(--tc), 0.45);
  border-top-color: rgba(var(--tc), 1);
  background: #1e1535;
  box-shadow:
    2px 0 0 #000,
    inset 0 -1px 0 rgba(0, 0, 0, 0.4);
}
.cabinet-tag:focus-visible {
  outline: 2px solid rgba(248, 244, 215, 0.95);
  outline-offset: 2px;
}
/* Active = this drawer is open: card rises, coloured light floods down into the page */
.cabinet-tag.is-active {
  color: rgba(var(--tc), 1);
  text-shadow:
    0 0  6px rgba(var(--tc), 1),
    0 0 16px rgba(var(--tc), 0.5);
  border-top: 4px solid rgba(var(--tc), 1);
  border-left-color: rgba(var(--tc), 0.40);
  background: #221840;
  /* Card physically rises out of the drawer slot */
  transform: translateY(-3px);
  z-index: 3;
  box-shadow:
    /* Physical thickness — right edge stays dark */
    2px 0 0 #000,
    /* Open-drawer light: coloured glow floods DOWN into the content area */
    0  6px 20px -1px rgba(var(--tc), 0.7),
    0 12px 40px -4px rgba(var(--tc), 0.4),
    0  2px  6px  0px rgba(var(--tc), 0.5);
}
/* Brighter glow strip under top bar when active */
.cabinet-tag.is-active::before {
  background: rgba(var(--tc), 0.40);
  box-shadow: 0 2px 8px rgba(var(--tc), 0.3);
}
html {
  /* Scale the rem base fluidly: stays 16px on mobile, reaches 22px on wide laptops.
     All rem values in this file scale with it — no per-element overrides needed.
     Admin is a separate back-office tool (.admin-shell, see admin.css) that
     was never meant to inherit this — it got pulled up to the same 22px
     ceiling as the flashy public site, making every rem-sized admin element
     ~40% larger than its own CSS intended. Reset to a normal 16px base
     whenever the admin shell is what's actually on screen. */
  font-size: clamp(16px, 1.65vw, 22px);
}
html:has(body > #root .admin-shell) {
  font-size: 16px;
}
:root {
  font-family: "Share Tech Mono", "Courier New", Consolas, monospace;
  line-height: 1.4;
  font-weight: 400;
  color-scheme: dark;
  color: #dbbeff;
  background: #070510;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  width: 100dvw;
  min-height: 100dvh;
  background: #0b0912;
  overflow: hidden;
  overscroll-behavior: none;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22'%3E%3Cline x1='11' y1='1' x2='11' y2='9' stroke='%239b5fff' stroke-width='1.5' opacity='0.85'/%3E%3Cline x1='11' y1='13' x2='11' y2='21' stroke='%239b5fff' stroke-width='1.5' opacity='0.85'/%3E%3Cline x1='1' y1='11' x2='9' y2='11' stroke='%239b5fff' stroke-width='1.5' opacity='0.85'/%3E%3Cline x1='13' y1='11' x2='21' y2='11' stroke='%239b5fff' stroke-width='1.5' opacity='0.85'/%3E%3Crect x='10' y='10' width='2' height='2' fill='%239b5fff' opacity='0.85'/%3E%3C/svg%3E") 11 11, crosshair;
}
a, button {
  cursor: pointer;
}
#root {
  width: 100dvw;
  height: 100dvh;
  max-width: none;
}
.crt-page {
  position: fixed;
  left: 0;
  top: 0;
  width: 100dvw;
  height: 100dvh;
  overflow: hidden;
}
/* Full-viewport CRT glass effects — corner vignette over all UI chrome */
/* Scanline line texture removed site-wide so images never sit under it. */
/* Vignette suppressed on dossier/item pages so specimen photographs render clean. */
.crt-page:has(.dossier-page)::after {
  display: none;
}
.crt-page::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 401;
  background: radial-gradient(
    ellipse at center,
    transparent 38%,
    rgba(0, 0, 0, 0.58) 100%
  );
}
.crt-content {
  position: fixed;
  inset: 0;
  z-index: 10;
}
.crt-screen {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 50% 18%, rgba(180, 110, 255, 0.11), rgba(5, 3, 12, 0.94) 62%),
    #070510;
  box-shadow:
    inset 0 0 48px rgba(160, 80, 255, 0.07);
  overflow: hidden;
  isolation: isolate;
}
/* ── Ambient section colour leak — tints the screen corners ─ */
.page-viewport:has(.home-panel)        { --leak: 155,  95, 255; }
.page-viewport:has(.shop-panel)        { --leak: 110, 220,  80; }
.page-viewport:has(.lore-panel)        { --leak: 220,  55,  65; }
.page-viewport:has(.blog-panel)        { --leak: 190,  90, 255; }
.page-viewport:has(.contact-panel)     { --leak:  60, 200, 220; }
.page-viewport:has(.cart-page)         { --leak: 245, 200,  50; }
.page-viewport:has(.admin-panel)       { --leak: 255, 140,  50; }
.page-viewport:has(.admin-login-panel) { --leak: 180, 130, 255; }
.page-viewport::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(ellipse 55% 35% at 0% 0%,
      rgba(var(--leak, 155, 95, 255), 0.055) 0%, transparent 100%),
    radial-gradient(ellipse 55% 35% at 100% 100%,
      rgba(var(--leak, 155, 95, 255), 0.055) 0%, transparent 100%);
}
.page-viewport {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 2.4rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.65) transparent;
}
.page-viewport::-webkit-scrollbar {
  width: 4px;
}
.page-viewport::-webkit-scrollbar-thumb {
  background: rgba(155, 95, 255, 0.35);
  border-radius: 2px;
}
.crt-screen.is-flickering {
  animation: random-flicker 180ms linear;
}
.crt-screen.is-switching {
  animation: channel-jump 300ms linear;
}
.crt-screen::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(180, 130, 255, 0.09) 0 1px,
    rgba(0, 0, 0, 0.22) 1px 3px
  );
  opacity: 0.4;
  animation: scanline-drift 12s linear infinite;
}
.crt-screen::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(circle at 50% 50%, transparent 54%, rgba(0, 0, 0, 0.42) 100%),
    linear-gradient(120deg, rgba(255, 0, 80, 0.03), rgba(120, 0, 255, 0.025), rgba(0, 60, 255, 0.02));
  animation: crt-flicker 140ms infinite;
  opacity: 0.55;
}
.app {
  position: relative;
  z-index: 2;
  display: grid;
  gap: 1rem;
  justify-items: center;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-shadow: 0 0 12px rgba(155, 95, 255, 0.42);
}
.app button {
  border-radius: 4px;
  border: 1px solid rgba(155, 95, 255, 0.4);
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  color: #dbbeff;
  background: linear-gradient(180deg, rgba(155, 95, 255, 0.12), rgba(155, 95, 255, 0.03));
  cursor: pointer;
  transition: transform 120ms ease, box-shadow 120ms ease;
}
.app button:hover {
  transform: translateY(-1px);
  box-shadow: 0 0 14px rgba(155, 95, 255, 0.28);
}
.app button:focus,
.app button:focus-visible {
  outline: 2px solid rgba(186, 255, 215, 0.9);
  outline-offset: 2px;
}
.page-panel {
  position: relative;
  z-index: 2;
  width: 100%;
  /* Grow to fill the viewport minus the footer (sticky-footer), instead of
     forcing a full 100% which pushed the footer entirely below the fold. */
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  align-items: center;
  justify-content: center;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  text-shadow: 0 0 12px rgba(180, 110, 255, 0.38);
  padding: 2rem 1.5rem;
}
.home-panel {
  gap: 1.2rem;
}
.home-sticker-link {
  position: absolute;
  top: 1.2rem;
  right: 1.4rem;
  z-index: 3;
  display: block;
  transform: rotate(6deg);
  transition: transform 160ms ease, filter 160ms ease;
}
.home-sticker-link:hover {
  transform: rotate(4deg) scale(1.06);
}
.home-sticker {
  width: clamp(100px, 14vw, 170px);
  display: block;
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.6));
}
/* ── Shop ────────────────────────────────────── */
.shop-panel {
  justify-content: flex-start;
  align-items: center;
  gap: 1.4rem;
  padding-top: 2.5rem;
}
.shop-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}
.shop-meta {
  margin: 0;
  font-size: 0.6rem;
  letter-spacing: 0.12em;
  color: rgba(214, 186, 255, 0.9);
}
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-auto-rows: 1fr; /* every card the same height across all rows */
  gap: 1.2rem;
  width: 100%;
  max-width: 820px;
  padding-bottom: 2rem;
}
/* Sealed-records toggle in the header count line. */
.shop-sealed-toggle {
  font: inherit;
  color: rgba(255, 122, 122, 0.85);
  background: none;
  border: none;
  padding: 0;
  letter-spacing: inherit;
  cursor: pointer;
  transition: color 140ms;
}
.shop-sealed-toggle:hover { color: rgba(255, 150, 150, 1); }
/* Divider announcing the sealed section — reads as an archive marker, not a
   gap. The rule fades out from a centred label. */
.shop-sealed-divider {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  width: 100%;
  max-width: 820px;
  margin: 0.4rem 0 1.4rem;
  color: rgba(255, 122, 122, 0.6);
  font-size: 0.56rem;
  letter-spacing: 0.24em;
}
.shop-sealed-divider::before,
.shop-sealed-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 122, 122, 0.28), transparent);
}
/* The sealed grid sits quieter than the live one — these are records, not
   offers. Cards keep their own sold treatment; this just lowers the whole
   pool a touch, lifting on hover so they're still explorable. */
.shop-grid--sealed { opacity: 0.72; transition: opacity 200ms; }
.shop-grid--sealed:hover { opacity: 0.9; }
@media (prefers-reduced-motion: reduce) {
  .shop-grid--sealed, .shop-sealed-toggle { transition: none; }
}
.product-card {
  display: flex;
  flex-direction: column;
  background: rgba(4, 2, 12, 0.92);
  border: 1px solid rgba(155, 95, 255, 0.14);
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.product-card:hover {
  border-color: rgba(176, 120, 255, 0.8);
  box-shadow: 0 0 22px rgba(140, 60, 255, 0.13);
}
.product-img-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  /* Subtle pulse while lazy image loads — prevents jarring pop-in */
  background: linear-gradient(135deg, #0d0a14 0%, #1a0f28 50%, #0d0a14 100%);
  background-size: 200% 200%;
  animation: img-shimmer 2s ease-in-out infinite;
}
@keyframes img-shimmer {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
.product-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  transition: transform 200ms ease;
  /* Stop shimmer once loaded */
  animation: none;
}
.product-card:hover .product-img-wrap img {
  transform: scale(1.03);
}
.product-sold-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.62);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: rgba(255, 80, 80, 0.9);
  text-shadow: 0 0 12px rgba(255, 60, 60, 0.6);
}
.product-info {
  padding: 0.75rem 0.8rem 0.8rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1;
}
.product-id {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.75);
}
.product-name {
  margin: 0;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #dbbeff;
  text-shadow: 0 0 8px rgba(180, 110, 255, 0.45);
  text-transform: uppercase;
}
.product-sub {
  margin: 0;
  font-size: 0.54rem;
  letter-spacing: 0.06em;
  color: rgba(202, 170, 255, 0.88);
  text-transform: uppercase;
  /* Clamp to 2 lines so descriptions don't make cards uneven */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.product-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Push price/status + button to the bottom so they line up across cards */
  margin-top: auto;
  padding-top: 0.5rem;
}
.product-price {
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: #dbbeff;
  text-shadow: 0 0 6px rgba(155, 95, 255, 0.45);
}
.product-status {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.46rem;
  letter-spacing: 0.1em;
  color: rgba(210, 178, 255, 0.85);
}
.status-dot {
  width: 0.32rem;
  height: 0.32rem;
  border-radius: 50%;
  background: rgba(155, 95, 255, 0.9);
  box-shadow: 0 0 4px rgba(155, 95, 255, 0.8);
}
.status-dot.sold {
  background: rgba(255, 80, 80, 0.9);
  box-shadow: 0 0 4px rgba(255, 80, 80, 0.7);
}
/* Stock-status tones for storefront */
.status-dot--available { background: rgba(120, 255, 172, 0.9); box-shadow: 0 0 4px rgba(120, 255, 172, 0.7); }
.status-dot--low       { background: rgba(255, 200, 80, 0.9);  box-shadow: 0 0 4px rgba(255, 200, 80, 0.7); }
.status-dot--out,
.status-dot--sold      { background: rgba(255, 80, 80, 0.9);   box-shadow: 0 0 4px rgba(255, 80, 80, 0.7); }
.product-btn {
  width: 100%;
  margin-top: 0.65rem;
  padding: 0.42rem 0.5rem;
  background: transparent;
  border: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(210, 178, 255, 0.85);
  font-family: inherit;
  font-size: 0.54rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}
.product-btn:hover:not(:disabled) {
  background: rgba(155, 95, 255, 0.07);
  border-color: rgba(155, 95, 255, 0.7);
  color: #dbbeff;
}
.product-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.panel-title {
  margin: 0;
  font-size: clamp(1.9rem, 5vw, 3rem);
  line-height: 1;
  color: #e2cfff;
  animation: text-flicker 6s ease-in-out infinite;
  text-shadow:
    -1.5px 0 rgba(255, 30, 100, 0.5),
    1.5px 0 rgba(80, 0, 255, 0.5),
    0 0 14px rgba(180, 110, 255, 0.6);
}
.panel-copy {
  margin: 0;
  max-width: 46ch;
  font-size: clamp(0.75rem, 1.6vw, 0.96rem);
  color: rgba(225, 200, 255, 0.92);
}
/* ── Boot sequence ─────────────────────────────── */
.boot-panel {
  align-items: flex-start;
  justify-content: flex-start;
  padding: 2.4rem 2rem;
}
.boot-log {
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
  text-align: left;
  font-size: clamp(0.62rem, 1.4vw, 0.82rem);
  letter-spacing: 0.06em;
  color: rgba(210, 178, 255, 0.82);
}
.boot-line {
  animation: boot-line-in 60ms ease both;
  white-space: pre;
}
.boot-line--blank {
  height: 0.9em;
}
.boot-line--cmd {
  color: #dbbeff;
  text-shadow: 0 0 10px rgba(155, 95, 255, 0.7);
}
.boot-line--warn {
  color: rgba(255, 160, 60, 0.9);
  text-shadow: 0 0 8px rgba(255, 130, 30, 0.5);
}
/* ── Blinking cursor ────────────────────────────── */
.crt-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  background: rgba(210, 178, 255, 0.85);
  vertical-align: text-bottom;
  margin-left: 0.1em;
  animation: cursor-blink 900ms step-end infinite;
}
/* ── Home panel live (post-boot) ────────────────── */
.home-panel--live {
  animation: screen-on 320ms ease both;
}
.panel-tagline {
  display: flex;
  align-items: center;
  gap: 0;
}
.home-desc {
  font-size: clamp(0.62rem, 1.3vw, 0.78rem);
  color: rgba(216, 190, 255, 0.9);
  max-width: 38ch;
  line-height: 1.8;
  letter-spacing: 0.04em;
}
/* The one un-themed sentence on the site. Slightly larger and brighter than
   .home-desc because it does the plain-English job the archival voice can't:
   telling a first-time visitor what's actually for sale. */
.home-plain {
  font-size: clamp(0.72rem, 1.5vw, 0.92rem);
  color: rgba(232, 214, 255, 0.95);
  max-width: 46ch;
  line-height: 1.7;
  letter-spacing: 0.03em;
  text-transform: none;
}
.channel-static {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  z-index: 9;
  background:
    repeating-radial-gradient(circle at 50% 50%, rgba(220, 255, 236, 0.08) 0 1px, transparent 1px 4px),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, 0.08) 0 1px, rgba(0, 0, 0, 0.12) 1px 2px);
}
.channel-static.is-switching {
  animation: static-pop 300ms linear;
}
@keyframes scanline-drift {
  from { background-position-y: 0; }
  to   { background-position-y: 3px; }
}
@keyframes random-flicker {
  0%   { filter: brightness(1);    }
  15%  { filter: brightness(0.45); }
  30%  { filter: brightness(0.92); }
  50%  { filter: brightness(0.2);  }
  65%  { filter: brightness(0.88); }
  80%  { filter: brightness(0.55); }
  100% { filter: brightness(1);    }
}
@keyframes channel-jump {
  /* Quick CRT channel-change: brief flash, short dip (hides the content swap),
     re-lock flash, normalise. Faster + gentler than a full black-out. */
  0%   { filter: brightness(1)    saturate(1);   }
  16%  { filter: brightness(2.2)  saturate(0.3); }
  /* Dim — the route content swaps behind this dip (~36% ≈ 108ms) */
  36%  { filter: brightness(0.08) saturate(0);   }
  48%  { filter: brightness(0.08) saturate(0);   }
  /* New channel locks in */
  60%  { filter: brightness(1.9)  saturate(0.5); }
  100% { filter: brightness(1)    saturate(1);   }
}
@keyframes static-pop {
  0%   { opacity: 0; }
  18%  { opacity: 0.55; }
  40%  { opacity: 0.5; }
  100% { opacity: 0; }
}
@keyframes crt-flicker {
  0% {
    opacity: 0.24;
  }

  50% {
    opacity: 0.32;
  }

  100% {
    opacity: 0.26;
  }
}
@keyframes boot-line-in {
  from {
    opacity: 0;
    transform: translateX(-4px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}
@keyframes cursor-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes screen-on {
  0% {
    opacity: 0;
    filter: brightness(2.4) blur(2px);
  }
  40% {
    opacity: 1;
    filter: brightness(1.3) blur(0px);
  }
  100% {
    opacity: 1;
    filter: brightness(1) blur(0px);
  }
}
@keyframes text-flicker {
  0%, 93%, 96%, 100% { opacity: 1; }
  94% { opacity: 0.82; }
  95% { opacity: 0.94; }
}
/* ── No Signal / 404 ─────────────────────────────── */
.no-signal-panel {
  position: relative;
  overflow: hidden;
  justify-content: center;
}
.no-signal-noise {
  position: absolute;
  inset: 0;
  background:
    repeating-linear-gradient(
      0deg,
      rgba(210, 178, 255, 0.06) 0 1px,
      transparent 1px 3px
    ),
    repeating-linear-gradient(
      90deg,
      rgba(210, 178, 255, 0.03) 0 1px,
      transparent 1px 3px
    );
  animation: noise-shift 0.1s steps(3) infinite;
  opacity: 0.9;
}
.no-signal-content {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}
.no-signal-heading {
  margin: 0;
  font-size: clamp(2.4rem, 7vw, 4rem);
  font-weight: 700;
  letter-spacing: 0.18em;
  color: rgba(226, 207, 255, 0.92);
  text-shadow:
    -1.5px 0 rgba(255, 30, 100, 0.5),
    1.5px 0 rgba(80, 0, 255, 0.5),
    0 0 20px rgba(180, 110, 255, 0.65);
  animation: text-flicker 3s ease-in-out infinite;
}
.no-signal-code {
  margin: 0;
  font-size: 0.65rem;
  letter-spacing: 0.12em;
  color: rgba(210, 178, 255, 0.87);
}
.no-signal-return {
  margin-top: 1.2rem;
  padding: 0.42rem 1rem;
  border: 1px solid rgba(155, 95, 255, 0.3);
  color: rgba(210, 178, 255, 0.85);
  text-decoration: none;
  font-size: 0.58rem;
  letter-spacing: 0.12em;
  font-family: inherit;
  text-transform: uppercase;
  transition: border-color 160ms ease, color 160ms ease;
}
.no-signal-return:hover {
  border-color: rgba(155, 95, 255, 0.85);
  color: #dbbeff;
}
@keyframes noise-shift {
  0%  { background-position: 0 0,      0 0;     }
  33% { background-position: 3px -2px, -2px 4px; }
  66% { background-position: -4px 3px, 5px -1px; }
}
/* ── Blog ───────────────────────────────────────────── */
.blog-panel {
  justify-content: flex-start;
  align-items: center;
  gap: 1.4rem;
  padding-top: 2.5rem;
}
.blog-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
  max-width: 700px;
  padding-bottom: 2rem;
}
.blog-card {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  border: 1px solid rgba(155, 95, 255, 0.12);
  background: rgba(4, 2, 12, 0.85);
  text-decoration: none;
  color: inherit;
  transition: border-color 180ms ease, box-shadow 180ms ease;
  overflow: hidden;
}
.blog-card-img-wrap {
  width: 100%;
  aspect-ratio: 2 / 1;
  overflow: hidden;
  flex-shrink: 0;
}
.blog-card-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: saturate(0.6) brightness(0.85);
  transition: filter 180ms ease, transform 300ms ease;
}
.blog-card:hover .blog-card-img {
  filter: saturate(0.85) brightness(1);
  transform: scale(1.03);
}
.blog-card-content {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1rem 1.1rem;
  flex: 1;
  min-width: 0;
}
.blog-card:hover {
  border-color: rgba(176, 120, 255, 0.74);
  box-shadow: 0 0 18px rgba(140, 60, 255, 0.10);
}
.blog-card-meta {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.blog-card-date {
  font-size: 0.5rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.75);
}
.blog-card-title {
  margin: 0;
  font-size: clamp(0.78rem, 2vw, 1rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #dbbeff;
  text-shadow: 0 0 8px rgba(180, 110, 255, 0.38);
  text-transform: uppercase;
}
.blog-card-excerpt {
  margin: 0;
  font-size: 0.58rem;
  letter-spacing: 0.05em;
  color: rgba(210, 178, 255, 0.7);
  line-height: 1.6;
}
.blog-card-read {
  margin-top: 0.3rem;
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  color: rgba(196, 160, 255, 0.83);
  transition: color 160ms ease;
}
.blog-card:hover .blog-card-read {
  color: rgba(225, 200, 255, 0.92);
}
/* Blog post page */
.blog-post-panel {
  justify-content: flex-start;
  align-items: center;
  padding-top: 2rem;
  gap: 1.2rem;
}
.blog-post-date {
  font-size: 0.5rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.75);
}
.blog-post {
  width: 100%;
  max-width: 680px;
  display: flex;
  flex-direction: column;
  gap: 1.2rem;
  text-align: left;
}
.blog-post-title {
  font-size: clamp(1.2rem, 3.5vw, 2rem);
  text-align: left;
  color: #e2cfff;
  text-shadow: 0 0 12px rgba(180, 110, 255, 0.45);
}
.blog-post-body {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}
.blog-post-body p {
  margin: 0;
  font-size: clamp(0.62rem, 1.5vw, 0.8rem);
  letter-spacing: 0.05em;
  color: rgba(218, 192, 255, 0.85);
  line-height: 1.75;
}
/* Blog post full image */
.blog-post-img-wrap {
  width: 100%;
  border: 1px solid rgba(155, 95, 255, 0.12);
}
.blog-post-img {
  width: 100%;
  height: auto;
  display: block;
  filter: saturate(0.65) brightness(0.9);
}
/* Taller textarea for blog body */
.admin-textarea--tall {
  min-height: 16rem;
}
/* ── Gloomopedia — specimen field guide ──────────────── */
.gpedia-panel {
  justify-content: flex-start;
  align-items: stretch;
  min-height: unset;
  padding: 1.2rem clamp(1rem, 4vw, 2.4rem) 3rem;
  gap: 0;
}
/* Masthead */
.gpedia-masthead {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding-bottom: 0.9rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.22);
}
.gpedia-title {
  margin: 0;
  font-size: clamp(1.3rem, 4vw, 2rem);
  letter-spacing: 0.16em;
  color: rgba(226, 207, 255, 0.98);
  text-shadow: 0 0 18px rgba(155, 95, 255, 0.4);
}
.gpedia-sub {
  margin: 0.25rem 0 0;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.6);
}
/* ── Gloomeria briefing — landing-page orientation only ── */
.gpedia-intro {
  margin: 1.2rem 0 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid rgba(155, 95, 255, 0.16);
  background: rgba(20, 11, 36, 0.4);
}
.gpedia-intro-text {
  margin: 0 0 0.8rem;
  font-size: 0.72rem;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: rgba(216, 198, 242, 0.85);
  max-width: 62ch;
}
.gpedia-intro-link {
  display: inline-block;
  margin-top: 0.7rem;
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.8);
  text-decoration: none;
}
.gpedia-intro-link:hover { color: rgba(196, 158, 232, 0.98); }
/* ── Loading skeleton cards — matches .shop-skel technique ── */
.gpedia-skel {
  border: 1px solid rgba(155, 95, 255, 0.12);
  background: rgba(6, 3, 14, 0.7);
}
.gpedia-skel-img {
  aspect-ratio: 3 / 4;
  background: linear-gradient(100deg, rgba(155, 95, 255, 0.05) 40%, rgba(155, 95, 255, 0.12) 50%, rgba(155, 95, 255, 0.05) 60%);
  background-size: 200% 100%;
  animation: skel-sweep 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .gpedia-skel-img { animation: none; }
}
.gpedia-meta {
  padding: 2rem 0;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  color: rgba(155, 95, 255, 0.6);
  text-align: center;
}
.gpedia-count {
  margin: 0.9rem 0 1.1rem;
  font-size: 0.58rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.5);
}
/* Grid */
.gpedia-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: clamp(0.8rem, 2vw, 1.4rem);
}
/* Card */
.gpedia-card {
  display: flex;
  flex-direction: column;
  background: rgba(12, 6, 24, 0.72);
  border: 1px solid rgba(155, 95, 255, 0.18);
  padding: 0;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
}
.gpedia-card-plate {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  /* Subtle pulse while the lazy image loads — matches .product-img-wrap */
  background: linear-gradient(135deg, #0d0a14 0%, #1a0f28 50%, #0d0a14 100%);
  background-size: 200% 200%;
  animation: img-shimmer 2s ease-in-out infinite;
}
.gpedia-card-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.78) contrast(1.05);
  transition: filter 220ms ease, transform 600ms ease;
}
.gpedia-card:hover .gpedia-card-img {
  filter: saturate(1) contrast(1.08);
  transform: scale(1.04);
}
.gpedia-card-noimg,
.gpedia-entry-noimg {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.55rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.4);
  text-transform: uppercase;
}
/* Violet duotone wash over the plate for cohesion */
.gpedia-card-plate-wash {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(180deg, rgba(10, 5, 24, 0) 55%, rgba(10, 5, 24, 0.6) 100%),
    radial-gradient(circle at 50% 40%, rgba(120, 70, 220, 0.08), transparent 70%);
}
.gpedia-card-threat {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
  padding: 0.16rem 0.42rem;
  font-size: 0.5rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--tc);
  border: 1px solid var(--tc);
  background: rgba(8, 4, 18, 0.78);
  backdrop-filter: blur(2px);
}
.gpedia-card-draft {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.16rem 0.42rem;
  font-size: 0.5rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 200, 80, 0.95);
  border: 1px solid rgba(255, 200, 80, 0.5);
  background: rgba(8, 4, 18, 0.78);
}
.gpedia-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.6rem 0.7rem 0.7rem;
}
.gpedia-card-name {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: rgba(232, 218, 252, 0.96);
  line-height: 1.25;
}
.gpedia-card-cat {
  font-size: 0.5rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.55);
}
/* ── Entry detail ── */
.gpedia-back {
  align-self: flex-start;
  margin-bottom: 1rem;
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.3);
  color: rgba(196, 158, 232, 0.85);
  font-family: inherit;
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.32rem 0.7rem;
  cursor: pointer;
  transition: border-color 160ms, color 160ms;
}
.gpedia-back:hover {
  border-color: rgba(155, 95, 255, 0.8);
  color: rgba(226, 207, 255, 1);
}
.gpedia-entry-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: saturate(0.85) contrast(1.04);
}
.gpedia-entry-head {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-top: 1.1rem;
}
.gpedia-entry-cat {
  font-size: 0.56rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.65);
}
.gpedia-entry-title {
  margin: 0;
  font-size: clamp(1.4rem, 5vw, 2.2rem);
  letter-spacing: 0.04em;
  color: rgba(232, 218, 252, 0.98);
  text-shadow: 0 0 16px rgba(155, 95, 255, 0.32);
}
.gpedia-entry-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.9rem;
}
.gpedia-chip {
  padding: 0.26rem 0.6rem;
  font-size: 0.54rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c);
  border: 1px solid var(--c);
  background: rgba(10, 5, 22, 0.5);
}
.gpedia-entry-rule {
  height: 1px;
  background: rgba(155, 95, 255, 0.2);
  margin: 1.3rem 0;
}
.gpedia-entry-body {
  font-size: 0.82rem;
  line-height: 1.75;
  color: rgba(214, 198, 240, 0.9);
  letter-spacing: 0.01em;
}
.gpedia-entry-body p { margin: 0 0 1rem; }
@media (max-width: 600px) {
  .gpedia-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}
/* ── Comments ───────────────────────────────────────── */
.comments-section {
  width: 100%;
  max-width: 700px;
  margin-top: 2.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(155, 95, 255, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.comments-heading {
  font-size: 0.48rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.62);
  margin: 0 0 0.2rem;
}
.comments-count {
  color: rgba(210, 178, 255, 0.7);
}
.comment-card {
  background: rgba(4, 10, 6, 0.55);
  border: 1px solid rgba(155, 95, 255, 0.1);
  padding: 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.comment-card--pending {
  border-color: rgba(255, 180, 50, 0.48);
  opacity: 0.8;
}
.comment-meta {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  flex-wrap: wrap;
}
.comment-author {
  font-size: 0.52rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: rgba(210, 178, 255, 0.87);
}
.comment-date {
  font-size: 0.44rem;
  letter-spacing: 0.07em;
  color: rgba(196, 160, 255, 0.75);
}
.comment-pending-badge {
  font-size: 0.42rem;
  letter-spacing: 0.12em;
  color: rgba(255, 180, 50, 0.8);
  border: 1px solid rgba(255, 180, 50, 0.22);
  padding: 0.1rem 0.35rem;
}
.comment-body {
  font-size: 0.6rem;
  line-height: 1.7;
  color: rgba(210, 178, 255, 0.82);
  letter-spacing: 0.03em;
  margin: 0;
}
.comment-mod-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.15rem;
}
.comment-empty {
  font-size: 0.48rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.73);
  margin: 0;
}
.comment-form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.4rem;
}
.comment-form-textarea {
  min-height: 5.5rem;
  resize: vertical;
}
.comment-pending-notice {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(255, 180, 50, 0.8);
  border: 1px solid rgba(255, 180, 50, 0.18);
  padding: 0.55rem 0.8rem;
  margin: 0;
}
.comment-login-prompt {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(210, 178, 255, 0.83);
  margin: 0;
}
.comment-login-link {
  color: rgba(210, 178, 255, 0.88);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.comment-login-link:hover {
  color: rgba(210, 178, 255, 0.9);
}
/* ── Admin pending comments ─────────────────────────── */
.admin-pending-comments {
  width: 100%;
  max-width: 900px;
  margin-bottom: 1rem;
}
.admin-comment-row {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.65rem 0.8rem;
  border: 1px solid rgba(255, 180, 50, 0.15);
  background: rgba(6, 3, 14, 0.55);
  margin-bottom: 0.4rem;
}
.admin-comment-meta {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.admin-comment-author {
  font-size: 0.5rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: rgba(210, 178, 255, 0.8);
}
.admin-comment-post {
  font-size: 0.44rem;
  letter-spacing: 0.08em;
  color: rgba(196, 160, 255, 0.77);
}
.admin-comment-body {
  font-size: 0.54rem;
  line-height: 1.55;
  color: rgba(210, 178, 255, 0.9);
  margin: 0;
}
.admin-comment-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.15rem;
}
/* ── Product card link ──────────────────────────────── */
.product-card--link {
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
}
/* ── Product detail page ─────────────────────────────── */
/* ── Product page — mobile-first layout ──────────────── */
.product-page {
  padding: 0;
  justify-content: flex-start;
  align-items: stretch;
  gap: 0;
  text-align: left;
}
.product-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.1);
  flex-shrink: 0;
  gap: 0.6rem;
}
/* Mobile: image on top, content below */
.product-layout {
  display: flex;
  flex-direction: column;
  flex: 1;
  width: 100%;
}
.product-img-area {
  width: 100%;
  flex-shrink: 0;
}
.product-img-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #000;
}
.product-img-wrap img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  filter: saturate(0.7) brightness(0.9);
}
/* Tabs */
.product-content-area {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  border-top: 1px solid rgba(155, 95, 255, 0.1);
}
.product-tab-strip {
  display: flex;
  flex-shrink: 0;
  border-bottom: 1px solid rgba(155, 95, 255, 0.1);
}
.product-tab {
  flex: 1;
  padding: 0.6rem 0.5rem;
  background: transparent;
  border: none;
  border-right: 1px solid rgba(155, 95, 255, 0.08);
  color: rgba(196, 160, 255, 0.87);
  font-family: inherit;
  font-size: 0.46rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 140ms ease, background 140ms ease;
}
.product-tab:last-child {
  border-right: none;
}
.product-tab--active {
  color: rgba(210, 178, 255, 0.9);
  background: rgba(155, 95, 255, 0.04);
  box-shadow: inset 0 -2px 0 rgba(155, 95, 255, 0.5);
}
.product-tab:hover:not(.product-tab--active) {
  color: rgba(210, 178, 255, 0.88);
  background: rgba(155, 95, 255, 0.04);
}
.product-tab--closed {
  color: rgba(255, 80, 80, 0.9);
}
.product-tab--owner {
  color: rgba(255, 200, 80, 0.85);
}
.product-tab--owner.product-tab--active {
  color: rgba(255, 220, 120, 0.95);
  box-shadow: inset 0 -2px 0 rgba(255, 200, 80, 0.6);
}
/* Shared tab body — flex column so each tab handles its own scroll */
.product-tab-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.45) transparent;
  /* No overflow-y here — each tab body scrolls itself */
}
/* Catalog tab scrolls itself */
.product-catalog-body {
  overflow-y: auto;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.2rem 1rem;
}
.product-page-title {
  margin: 0;
  font-size: clamp(1.1rem, 5vw, 1.8rem);
  line-height: 1.1;
  color: #e2cfff;
  animation: text-flicker 6s ease-in-out infinite;
  text-shadow:
    0 0 8px rgba(180, 110, 255, 0.65),
    0 0 22px rgba(150, 70, 255, 0.28);
}
.product-page-desc {
  margin: 0;
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  color: rgba(218, 190, 255, 0.82);
  line-height: 1.75;
}
.product-page-meta {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.product-page-acquire {
  width: 100%;
  padding: 0.6rem 0.5rem;
  font-size: 0.56rem;
}
.product-page-note {
  margin: 0;
  font-size: 0.46rem;
  letter-spacing: 0.07em;
  color: rgba(210, 178, 255, 0.75);
  line-height: 1.75;
}
.product-channel-hint {
  background: transparent;
  border: none;
  color: rgba(196, 160, 255, 0.87);
  font-family: inherit;
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  cursor: pointer;
  padding: 0;
  text-align: left;
  transition: color 140ms ease;
}
.product-channel-hint:hover {
  color: rgba(225, 200, 255, 0.95);
}
/* Channel tab */
.product-channel-body {
  display: flex;
  flex-direction: column;
  padding: 0;
}
.channel-auth-gate {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.4rem 1rem;
}
.channel-auth-label {
  font-size: 0.46rem;
  letter-spacing: 0.16em;
  color: rgba(196, 160, 255, 0.87);
  margin: 0;
}
.channel-auth-sub {
  font-size: 0.52rem;
  letter-spacing: 0.06em;
  color: rgba(210, 178, 255, 0.87);
  line-height: 1.75;
  margin: 0;
}
.channel-status-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.5rem 0.9rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.08);
  flex-shrink: 0;
  gap: 0.8rem;
}
.channel-status-label {
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  color: rgba(196, 160, 255, 0.77);
}
.channel-status-right {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-shrink: 0;
}
.channel-resumed {
  font-size: 0.38rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.73);
  white-space: nowrap;
}
.channel-observers {
  font-size: 0.38rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.7);
  white-space: nowrap;
}
.channel-counter {
  font-size: 0.4rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.7);
  white-space: nowrap;
}
.channel-messages {
  /* Concrete height — always creates a real scroll container */
  height: 44vh;
  min-height: 150px;
  overflow-y: scroll;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 1rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.45) transparent;
}
.channel-connecting {
  font-size: 0.48rem;
  letter-spacing: 0.14em;
  color: rgba(196, 160, 255, 0.85);
  margin: 0;
  animation: channel-blink 1s ease infinite;
}
@keyframes channel-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.25; }
}
.channel-message {
  font-size: 0.54rem;
  letter-spacing: 0.05em;
  line-height: 1.8;
}
.channel-message--creature {
  color: rgba(218, 190, 255, 0.88);
  text-shadow: 0 0 10px rgba(180, 110, 255, 0.18);
}
/* Streaming cursor on the last creature message while text is arriving */
.channel-message--streaming::after {
  content: "▋";
  display: inline;
  color: rgba(196, 148, 255, 0.85);
  animation: channel-blink 0.7s ease infinite;
  margin-left: 1px;
}
.channel-message--user {
  color: rgba(196, 160, 255, 0.8);
  display: flex;
  gap: 0.45rem;
  align-items: baseline;
}
/* (glooom interjections now route to the bottom surveillance panel, not the specimen channel) */
.channel-thinking {
  opacity: 0.4;
  animation: channel-blink 0.9s ease infinite;
}
.channel-prompt {
  color: rgba(196, 160, 255, 0.8);
  flex-shrink: 0;
  font-size: 0.5rem;
}
.channel-input-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.9rem;
  border-top: 1px solid rgba(155, 95, 255, 0.08);
  flex-shrink: 0;
}
.channel-input {
  flex: 1;
  background: transparent;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 0.54rem;
  letter-spacing: 0.07em;
  color: rgba(210, 178, 255, 0.85);
  caret-color: #9b5fff;
}
.channel-input::placeholder {
  color: rgba(196, 160, 255, 0.72);
}
.channel-send-btn {
  background: transparent;
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(196, 160, 255, 0.87);
  font-family: inherit;
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  padding: 0.3rem 0.75rem;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
  flex-shrink: 0;
  white-space: nowrap;
}
.channel-send-btn:hover:not(:disabled) {
  background: rgba(155, 95, 255, 0.06);
  color: rgba(210, 178, 255, 0.85);
}
.channel-send-btn:disabled {
  opacity: 0.25;
  cursor: default;
}
/* Desktop: side-by-side */
@media (min-width: 780px) {
  .product-page {
    height: 100%;
  }

  .product-layout {
    flex-direction: row;
    flex: 1;
    overflow: hidden;
    min-height: 0;
  }

  .product-img-area {
    width: 42%;
    flex-shrink: 0;
    position: relative;
  }

  /* Scoped to .product-img-area (product detail page only) — .product-img-wrap
     is also used unscoped by the shop grid's cards (04-shop-home.css), which
     have no positioned .product-img-area ancestor. An unscoped rule here was
     absolutely-positioning the shop card's image over its own product-info,
     hiding every card's name/price/status behind the image at this width. */
  .product-img-area .product-img-wrap {
    position: absolute;
    inset: 0;
    aspect-ratio: unset;
    height: 100%;
    border-right: 1px solid rgba(155, 95, 255, 0.1);
  }

  .product-content-area {
    border-top: none;
    border-left: none;
    flex: 1;
    min-width: 0;
  }

  /* Desktop: channel body fills the flex tab-body; messages flex-fill inside it */
  .product-channel-body {
    flex: 1;
    min-height: 0;
  }

  .product-channel-body .channel-messages {
    height: auto;
    min-height: 0;
    flex: 1;
  }
}
/* ── Mobile channel scroll fix ───────────────────────── */
@media (max-width: 779px) {
  /* Product page: give the whole channel body a fixed height so
     flex:1 on messages has a bounded parent to fill */
  .product-channel-body {
    height: 56vh;
    flex-shrink: 0;
    overflow: hidden;
  }

  .product-channel-body .channel-messages {
    height: auto;
    min-height: 0;
    flex: 1;
  }

  /* Public page messages use the base 44vh — no extra override needed */
}
/* ── Mobile admin section ────────────────────────────── */
.mobile-menu-section-label {
  padding: 0.7rem 1.2rem 0.3rem;
  font-size: 0.4rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.5);
}
/* ── Right-side auth tab ──────────────────────────────── */
.cabinet-menu-right {
  flex-shrink: 0;
  display: flex;
  align-items: stretch;
  padding-left: 4px;
  border-left: 1px solid rgba(155, 95, 255, 0.14);
  position: relative;
  z-index: 1;
}
/* ── Admin / Auth shared ─────────────────────────────── */
.admin-panel {
  justify-content: flex-start;
  align-items: center;
  gap: 0;
  padding-top: 2rem;
}
.admin-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  max-width: 900px;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.12);
  margin-bottom: 0.6rem;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.admin-header-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.admin-title {
  font-size: clamp(1rem, 2.5vw, 1.6rem);
}
.admin-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.32rem 0.72rem;
  border: 1px solid rgba(155, 95, 255, 0.3);
  background: transparent;
  color: rgba(210, 178, 255, 0.85);
  font-family: inherit;
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
  white-space: nowrap;
}
.admin-btn:hover {
  background: rgba(155, 95, 255, 0.07);
  border-color: rgba(155, 95, 255, 0.7);
  color: #dbbeff;
}
.admin-btn--add {
  border-color: rgba(155, 95, 255, 0.75);
  color: rgba(210, 178, 255, 0.85);
}
.admin-btn--logout {
  border-color: rgba(255, 80, 80, 0.6);
  color: rgba(255, 150, 150, 0.75);
}
.admin-btn--logout:hover {
  background: rgba(255, 80, 80, 0.06);
  border-color: rgba(255, 80, 80, 0.7);
  color: rgba(255, 140, 140, 0.9);
}
.admin-btn--save {
  width: 100%;
  max-width: 360px;
  padding: 0.5rem 1rem;
  font-size: 0.58rem;
  align-self: center;
  margin-top: 0.4rem;
}
/* Product list */
.admin-product-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
  max-width: 900px;
}
.admin-product-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid rgba(155, 95, 255, 0.1);
  background: rgba(4, 2, 12, 0.8);
}
.admin-product-row--sold {
  opacity: 0.55;
}
.admin-product-row--unread {
  border-color: rgba(var(--toxic), 0.4);
  box-shadow: 0 0 14px rgba(var(--toxic), 0.12);
}
.admin-product-thumb-wrap {
  flex-shrink: 0;
  width: 3rem;
  height: 3rem;
}
.admin-product-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.admin-thumb-empty {
  background: rgba(155, 95, 255, 0.04);
  border: 1px solid rgba(155, 95, 255, 0.08);
}
.admin-product-info {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.7rem;
  flex: 1;
  align-items: center;
  min-width: 0;
}
.admin-product-sku {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.77);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.containment-unread-pill {
  display: inline-flex;
  align-items: center;
  font-size: 0.42rem;
  letter-spacing: 0.12em;
  padding: 0.14rem 0.4rem;
  border-radius: 999px;
  background: rgba(var(--toxic), 0.12);
  border: 1px solid rgba(var(--toxic), 0.5);
  color: rgba(var(--toxic), 0.95);
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
}
.admin-product-name {
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #dbbeff;
  text-shadow: 0 0 8px rgba(155, 95, 255, 0.28);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-product-price {
  font-size: 0.56rem;
  color: rgba(210, 178, 255, 0.9);
}
.admin-product-status {
  font-size: 0.48rem;
  letter-spacing: 0.1em;
  padding: 0.1rem 0.38rem;
  border: 1px solid;
}
.admin-product-status.available {
  border-color: rgba(155, 95, 255, 0.6);
  color: rgba(155, 95, 255, 0.85);
}
.admin-product-status.sold {
  border-color: rgba(255, 80, 80, 0.6);
  color: rgba(255, 100, 100, 0.8);
}
.admin-enquiry-badge {
  font-size: 0.46rem;
  letter-spacing: 0.08em;
  padding: 0.1rem 0.38rem;
  background: rgba(255, 200, 80, 0.06);
  border: 1px solid rgba(255, 200, 80, 0.28);
  color: rgba(255, 220, 120, 0.9);
  white-space: nowrap;
}
.admin-product-actions {
  display: flex;
  gap: 0.4rem;
  flex-shrink: 0;
  align-items: center;
}
.admin-action-btn {
  padding: 0.22rem 0.54rem;
  border: 1px solid rgba(155, 95, 255, 0.22);
  background: transparent;
  color: rgba(210, 178, 255, 0.7);
  font-family: inherit;
  font-size: 0.46rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.admin-action-btn:hover {
  background: rgba(155, 95, 255, 0.07);
  border-color: rgba(155, 95, 255, 0.8);
  color: #dbbeff;
}
.admin-action-btn--delete {
  border-color: rgba(255, 80, 80, 0.5);
  color: rgba(255, 100, 100, 0.8);
}
.admin-action-btn--delete:hover {
  background: rgba(255, 80, 80, 0.06);
  border-color: rgba(255, 80, 80, 0.78);
  color: rgba(255, 120, 120, 0.85);
}
.admin-action-btn--unread {
  border-color: rgba(var(--toxic), 0.6);
  color: rgba(var(--toxic), 0.95);
}
.admin-action-btn--unread:hover {
  background: rgba(var(--toxic), 0.08);
  border-color: rgba(var(--toxic), 0.85);
  color: rgba(var(--toxic), 1);
}
/* Login */
.admin-login-panel {
  justify-content: center;
}
.login-box {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  width: 100%;
  max-width: 320px;
  align-items: center;
}
.login-title {
  font-size: clamp(1.1rem, 3vw, 1.8rem);
  text-align: center;
}
.login-mode-toggle {
  display: flex;
  width: 100%;
  border: 1px solid rgba(155, 95, 255, 0.18);
}
.login-mode-btn {
  flex: 1;
  padding: 0.36rem 0.5rem;
  background: transparent;
  border: none;
  color: rgba(210, 178, 255, 0.7);
  font-family: inherit;
  font-size: 0.52rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.login-mode-btn.active {
  background: rgba(155, 95, 255, 0.1);
  color: rgba(210, 178, 255, 0.85);
}
.login-mode-btn:hover:not(.active) {
  background: rgba(155, 95, 255, 0.04);
  color: rgba(210, 178, 255, 0.7);
}
/* Admin form */
.admin-login-form,
.admin-form {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
  width: 100%;
}
.admin-form {
  gap: 1rem;
  max-width: 700px;
}
.admin-form-cols {
  display: flex;
  gap: 1.4rem;
  align-items: flex-start;
  flex-wrap: wrap;
}
.admin-form-image-col {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  align-items: center;
  flex: 0 0 auto;
}
.admin-image-preview {
  width: 160px;
  height: 160px;
  border: 1px solid rgba(155, 95, 255, 0.16);
  background: rgba(4, 2, 12, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.admin-image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.admin-image-placeholder {
  font-size: 0.48rem;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.52);
}
.admin-upload-btn {
  display: block;
  width: 160px;
  padding: 0.28rem 0.6rem;
  border: 1px dashed rgba(155, 95, 255, 0.22);
  color: rgba(210, 178, 255, 0.75);
  font-family: inherit;
  font-size: 0.48rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: border-color 140ms ease, color 140ms ease;
}
.admin-upload-btn:hover {
  border-color: rgba(155, 95, 255, 0.78);
  color: rgba(210, 178, 255, 0.9);
}
.admin-image-preview--wide {
  width: 220px;
  height: 160px;
}
.admin-upload-btn--wide {
  width: 220px;
}
.admin-form-fields-col {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  flex: 1;
  min-width: 220px;
}
.admin-field {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.admin-field--inline {
  flex-direction: row;
  align-items: center;
  gap: 0.7rem;
}
.admin-label {
  font-size: 0.48rem;
  letter-spacing: 0.14em;
  color: rgba(196, 160, 255, 0.83);
}
.admin-input {
  background: rgba(4, 2, 12, 0.9);
  border: 1px solid rgba(155, 95, 255, 0.18);
  color: rgba(210, 178, 255, 0.82);
  font-family: inherit;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  padding: 0.38rem 0.55rem;
  outline: none;
  transition: border-color 140ms ease;
  width: 100%;
}
.admin-input:focus {
  border-color: rgba(155, 95, 255, 0.78);
}
.admin-input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.admin-textarea {
  resize: vertical;
  min-height: 4.5rem;
}
.admin-toggle {
  padding: 0.28rem 0.64rem;
  border: 1px solid;
  background: transparent;
  font-family: inherit;
  font-size: 0.54rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: background 140ms ease;
}
.admin-toggle--on {
  border-color: rgba(155, 95, 255, 0.68);
  color: rgba(155, 95, 255, 0.9);
}
.admin-toggle--on:hover {
  background: rgba(155, 95, 255, 0.06);
}
.admin-toggle--off {
  border-color: rgba(255, 80, 80, 0.62);
  color: rgba(255, 100, 100, 0.8);
}
.admin-toggle--off:hover {
  background: rgba(255, 80, 80, 0.05);
}
.admin-error {
  margin: 0;
  font-size: 0.52rem;
  letter-spacing: 0.08em;
  color: rgba(255, 100, 100, 0.82);
  text-shadow: 0 0 8px rgba(255, 60, 60, 0.35);
}
.admin-progress {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.48rem;
  color: rgba(210, 178, 255, 0.75);
  width: 160px;
}
.admin-progress-bar-track {
  flex: 1;
  height: 3px;
  background: rgba(155, 95, 255, 0.08);
  border: 1px solid rgba(155, 95, 255, 0.18);
}
.admin-progress-bar {
  height: 100%;
  background: rgba(155, 95, 255, 0.65);
  transition: width 200ms ease;
}
/* ── Wishlist button ─────────────────────────────────── */
.wishlist-btn {
  position: absolute;
  top: 0.4rem;
  right: 0.4rem;
  z-index: 5;
  background: rgba(6, 3, 14, 0.82);
  border: 1px solid rgba(155, 95, 255, 0.15);
  color: rgba(155, 95, 255, 0.62);
  font-size: 0.85rem;
  width: 1.8rem;
  height: 1.8rem;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  transition: color 140ms ease, border-color 140ms ease, background 140ms ease;
}
.wishlist-btn:hover {
  color: rgba(255, 90, 90, 0.93);
  border-color: rgba(255, 90, 90, 0.62);
  background: rgba(6, 3, 14, 0.92);
}
.wishlist-btn--active {
  color: rgba(255, 70, 70, 0.9);
  border-color: rgba(255, 70, 70, 0.68);
}
.wishlist-btn--active:hover {
  color: rgba(155, 95, 255, 0.75);
  border-color: rgba(155, 95, 255, 0.5);
}
/* Inline variant on product detail page */
.wishlist-btn--inline {
  position: static;
  width: auto;
  height: auto;
  padding: 0.32rem 0.9rem;
  font-size: 0.52rem;
  font-family: inherit;
  font-weight: 700;
  letter-spacing: 0.1em;
}
/* ── Account page ─────────────────────────────────────── */
.account-section {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  max-width: 700px;
  padding: 1rem 0;
  border-top: 1px solid rgba(155, 95, 255, 0.08);
}
.account-section-label {
  font-size: 0.44rem;
  letter-spacing: 0.18em;
  color: rgba(196, 160, 255, 0.9);
  text-shadow: 0 0 8px rgba(180, 110, 255, 0.25);
  margin-bottom: 0.25rem;
}
/* ── Filter chips ─────────────────────────────────────── */
.filter-chips {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.4rem;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  padding-bottom: 0.2rem;
  max-width: 820px;
  width: 100%;
}
.filter-chips::-webkit-scrollbar {
  display: none;
}
.filter-chip {
  flex-shrink: 0;
  padding: 0.22rem 0.65rem;
  border: 1px solid rgba(155, 95, 255, 0.2);
  background: transparent;
  color: rgba(210, 178, 255, 0.75);
  font-family: inherit;
  font-size: 0.48rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
  white-space: nowrap;
}
.filter-chip:hover {
  background: rgba(155, 95, 255, 0.06);
  border-color: rgba(155, 95, 255, 0.75);
  color: rgba(210, 178, 255, 0.9);
}
.filter-chip--active {
  border-color: rgba(155, 95, 255, 0.7);
  background: rgba(155, 95, 255, 0.08);
  color: #dbbeff;
  text-shadow: 0 0 8px rgba(155, 95, 255, 0.4);
}
/* ── Product card admin overlay ───────────────────────── */
.product-card-wrap {
  position: relative;
  height: 100%;
}
.product-card {
  height: 100%;
}
.admin-card-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  gap: 0;
  z-index: 4;
  pointer-events: auto;
}
.admin-card-btn {
  flex: 1;
  padding: 0.28rem 0.4rem;
  border: none;
  border-bottom: 1px solid rgba(155, 95, 255, 0.18);
  background: rgba(4, 2, 12, 0.88);
  color: rgba(210, 178, 255, 0.75);
  font-family: inherit;
  font-size: 0.44rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.admin-card-btn:hover {
  background: rgba(155, 95, 255, 0.1);
  color: #dbbeff;
}
.admin-card-btn--delete {
  border-left: 1px solid rgba(155, 95, 255, 0.1);
  color: rgba(255, 100, 100, 0.8);
}
.admin-card-btn--delete:hover {
  background: rgba(255, 60, 60, 0.08);
  color: rgba(255, 130, 130, 0.9);
}
/* ── Blog card admin overlay ──────────────────────────── */
.blog-card-wrap {
  position: relative;
  width: 100%;
}
.blog-card-wrap .blog-card {
  width: 100%;
}
/* ── Draft badge ──────────────────────────────────────── */
.draft-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.08rem 0.38rem;
  background: rgba(255, 200, 60, 0.08);
  border: 1px solid rgba(255, 200, 60, 0.35);
  color: rgba(255, 220, 100, 0.93);
  font-size: 0.42rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}
/* ── Blog card tags ───────────────────────────────────── */
.blog-card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.28rem;
  margin-top: 0.2rem;
}
.blog-tag {
  padding: 0.1rem 0.38rem;
  border: 1px solid rgba(155, 95, 255, 0.18);
  color: rgba(155, 95, 255, 0.75);
  font-size: 0.42rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}
/* ── Admin form helpers ───────────────────────────────── */
.admin-input-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
}
.admin-section-label {
  font-size: 0.44rem;
  letter-spacing: 0.16em;
  color: rgba(155, 95, 255, 0.9);
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  padding-bottom: 0.35rem;
  margin-bottom: 0.5rem;
}
.admin-hint {
  margin-left: 0.5rem;
  font-size: 0.42rem;
  letter-spacing: 0.08em;
  color: rgba(155, 95, 255, 0.55);
  text-transform: none;
  font-weight: 400;
}
/* ── Contact page ─────────────────────────────────────── */
.contact-panel {
  display: flex;
  flex-direction: column;
  gap: 2.4rem;
  padding: 1.6rem 1.2rem;
  max-width: 640px;
  margin: 0 auto;
  width: 100%;
}
.contact-section {
  display: flex;
  flex-direction: column;
  gap: 0.8rem;
}
.contact-section-label {
  font-size: 0.48rem;
  letter-spacing: 0.2em;
  color: rgba(196, 160, 255, 0.93);
  text-shadow: 0 0 8px rgba(180, 110, 255, 0.28);
  margin: 0;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.28);
}
.contact-fields {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.contact-field-row {
  display: flex;
  gap: 1rem;
  align-items: baseline;
}
.contact-field-label {
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  color: rgba(196, 160, 255, 0.77);
  min-width: 6rem;
  flex-shrink: 0;
}
.contact-field-value {
  font-size: 0.52rem;
  letter-spacing: 0.06em;
  color: rgba(210, 178, 255, 0.9);
}
.contact-link {
  text-decoration: none;
  transition: color 0.15s;
}
.contact-link:hover {
  color: #9b5fff;
}
.contact-note {
  font-size: 0.46rem;
  letter-spacing: 0.08em;
  color: rgba(155, 95, 255, 0.58);
  line-height: 1.7;
  margin: 0;
}
/* ── Newsletter ───────────────────────────────────────── */
.newsletter-desc {
  font-size: 0.5rem;
  letter-spacing: 0.08em;
  color: rgba(210, 178, 255, 0.75);
  line-height: 1.8;
  margin: 0;
}
.newsletter-form {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.newsletter-input-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  padding-bottom: 0.3rem;
}
.newsletter-prompt {
  font-size: 0.6rem;
  color: rgba(155, 95, 255, 0.7);
  flex-shrink: 0;
}
.newsletter-input {
  background: transparent;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 0.54rem;
  letter-spacing: 0.1em;
  color: #dbbeff;
  caret-color: #9b5fff;
  width: 100%;
}
.newsletter-input::placeholder {
  color: rgba(155, 95, 255, 0.5);
}
.newsletter-btn {
  align-self: flex-start;
}
.newsletter-success {
  font-size: 0.5rem;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.7);
  margin: 0;
  line-height: 1.8;
}
.newsletter-email {
  color: #9b5fff;
  font-size: 0.52rem;
}
/* ── Admin subscribers panel ──────────────────────────── */
.admin-subscribers {
  width: 100%;
  max-width: 900px;
  margin-top: 1.4rem;
}
.admin-subscriber-row {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid rgba(155, 95, 255, 0.06);
}
.admin-subscriber-email {
  font-size: 0.52rem;
  letter-spacing: 0.06em;
  color: rgba(210, 178, 255, 0.85);
  flex: 1;
}
.admin-subscriber-date {
  font-size: 0.44rem;
  letter-spacing: 0.08em;
  color: rgba(155, 95, 255, 0.6);
  white-space: nowrap;
}
.admin-subscriber-actions {
  display: flex;
  gap: 0.4rem;
}
.admin-copy-btn {
  align-self: flex-start;
  margin-bottom: 0.6rem;
}
/* ── Cart nav indicator ───────────────────────────────── */
.cabinet-tag.has-items {
  --tc: 245, 200, 50;
}
.cabinet-tag.has-items.is-active {
  background: linear-gradient(180deg, #1e1a0a, #15120a);
}
/* ── Cart page ────────────────────────────────────────── */
.cart-page {
  /* .page-panel is a centring flex column, so its children shrink to their own
     content width — the item rows rendered 273px wide inside a 412px phone
     with 70px dead either side, while the header and totals (which carry their
     own width rules) spanned properly. `align-items: stretch` pins every child
     to the panel's measure instead.
     The panel itself keeps the 680px cap and stays centred: `align-self` here
     would stretch the panel across the full 1366px desktop viewport and pin the
     content hard left. */
  max-width: 680px;
  margin-inline: auto;
  align-items: stretch;
  /* The rows are label/value pairs; the inherited centre alignment left names
     and SKUs floating mid-row with ragged gaps. */
  text-align: left;
}
.cart-empty {
  padding: 2rem 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
}
.cart-items {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 1rem 0;
  border-top: 1px solid rgba(155, 95, 255, 0.1);
}
.cart-item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: 0.8rem;
  align-items: center;
  padding: 0.8rem 0;
  border-bottom: 1px solid rgba(155, 95, 255, 0.1);
}
.cart-item--sold {
  opacity: 0.5;
}
.cart-item-img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  display: block;
}
.cart-item-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.cart-item-sku {
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.7);
  margin: 0;
}
.cart-item-name {
  font-size: 0.54rem;
  letter-spacing: 0.1em;
  color: #dbbeff;
  margin: 0;
}
.cart-item-unavailable {
  font-size: 0.42rem;
  letter-spacing: 0.12em;
  color: #f5c842;
  margin: 0;
}
.cart-item-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
}
.cart-item-price {
  font-size: 0.58rem;
  letter-spacing: 0.1em;
  color: #9b5fff;
  margin: 0;
}
.cart-remove-btn {
  background: none;
  border: none;
  font-family: inherit;
  font-size: 0.4rem;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.6);
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
}
.cart-remove-btn:hover {
  color: #f5c842;
}
.cart-footer {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-top: 0.8rem;
}
.cart-total-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 0.6rem 0;
  border-top: 1px solid rgba(155, 95, 255, 0.15);
  border-bottom: 1px solid rgba(155, 95, 255, 0.15);
  margin-bottom: 0.4rem;
}
.cart-total-label {
  font-size: 0.5rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.8);
}
.cart-total-amount {
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  color: #9b5fff;
}
.cart-checkout-btn {
  max-width: 300px;
}
.cart-note {
  font-size: 0.42rem;
  letter-spacing: 0.08em;
  color: rgba(155, 95, 255, 0.55);
  margin: 0.2rem 0 0;
}
/* The product name links back to its specimen page. Underline only on hover so
   a list of links doesn't read as busier than the plain text it replaces. */
.cart-item-link {
  color: inherit;
  text-decoration: none;
  transition: color 0.15s;
}
.cart-item-link:hover .cart-item-name,
.cart-item-link:focus-visible .cart-item-name {
  color: #f0e0ff;
  text-decoration: underline;
  text-underline-offset: 0.22em;
}
.cart-item-link:focus-visible {
  outline: 1px solid rgba(155, 95, 255, 0.7);
  outline-offset: 3px;
}
/* The thumbnail is the same link — keep the two in step on hover. */
.cart-item-thumb { display: block; }
.cart-item-thumb:hover .cart-item-img { opacity: 0.82; }
.cart-item-thumb:focus-visible { outline: 1px solid rgba(155, 95, 255, 0.7); outline-offset: 3px; }
.cart-item-img { transition: opacity 0.15s; }
/* A line whose product no longer exists in Firestore. It can't link anywhere
   and has no price, so it only offers removal. */
.cart-item--missing .cart-item-name { color: rgba(219, 190, 255, 0.55); }
/* Stands in for the absent thumbnail so the row keeps its three-column rhythm
   instead of leaving a blank square where a photo should be. */
.cart-item-ghost {
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(155, 95, 255, 0.28);
  color: rgba(155, 95, 255, 0.45);
  font-size: 0.7rem;
}
/* ── Cart on phones ──────────────────────────────────────
   Use the width. The panel's own 1rem gutter is plenty on a 390px screen, so
   the row spans it edge to edge and the thumbnail grows — the old 56px square
   in a 273px column made the whole page read as a narrow strip. */
@media (max-width: 600px) {
  .cart-page {
    padding-inline: 0.85rem;
    max-width: none;
  }
  .cart-item {
    grid-template-columns: 72px 1fr auto;
    gap: 0.7rem;
    padding: 0.75rem 0;
    /* Top-align: the info column is 3 short lines against a 72px thumbnail, and
       centring left it floating in the middle of a tall row. */
    align-items: start;
  }
  .cart-item-img,
  .cart-item-thumb .cart-item-img,
  .cart-item-ghost {
    width: 72px;
    height: 72px;
  }
  /* The thumbnail is the tallest thing in the row, so cap it rather than let a
     portrait image stretch the row — object-fit already crops to the square. */
  .cart-item-thumb { line-height: 0; }
  /* Bigger tap targets than the 0.4rem desktop type — REMOVE was a ~10px
     target, well under the 24px minimum. */
  .cart-remove-btn {
    font-size: 0.46rem;
    padding: 0.35rem 0;
  }
  .cart-qty-btn {
    min-width: 30px;
    min-height: 30px;
  }
  .cart-checkout-btn {
    max-width: none;
  }
}
/* ── Orders / acquired specimens ──────────────────────── */
.order-pending-banner {
  border: 1px solid rgba(245, 200, 66, 0.3);
  background: rgba(245, 200, 66, 0.04);
  padding: 0.8rem 1rem;
  margin-bottom: 1rem;
}
.order-pending-label {
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  color: #f5c842;
  margin: 0 0 0.25rem;
}
.order-pending-sub {
  font-size: 0.44rem;
  letter-spacing: 0.08em;
  color: rgba(245, 200, 66, 0.7);
  margin: 0;
  line-height: 1.6;
}
.order-row {
  padding: 0.8rem 0;
  border-bottom: 1px solid rgba(155, 95, 255, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.order-row-meta {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.order-status {
  font-size: 0.44rem;
  letter-spacing: 0.14em;
  padding: 0.15rem 0.4rem;
  border: 1px solid currentColor;
}
.order-status--paid {
  color: #9b5fff;
  border-color: rgba(155, 95, 255, 0.7);
}
.order-status--pending {
  color: #f5c842;
  border-color: rgba(245, 200, 66, 0.7);
}
/* Dispatched. Toxic green rather than the violet of "acquired": it reads as a
   later, active state, and matches the dispatch email's accent. */
.order-status--fulfilled {
  color: #78ffac;
  border-color: rgba(120, 255, 172, 0.7);
}
/* The courier's tracking code, shown as soon as the parcel is scanned. Wraps
   and breaks anywhere — some international codes are long enough to push the
   row into horizontal scroll on a phone otherwise. */
.order-tracking {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.4rem 0.6rem;
  margin: 0.1rem 0 0;
}
.order-tracking-label {
  font-size: 0.4rem;
  letter-spacing: 0.14em;
  color: rgba(120, 255, 172, 0.75);
}
.order-tracking-code {
  font-size: 0.46rem;
  letter-spacing: 0.08em;
  color: #cbb4ff;
  overflow-wrap: anywhere;
}
.order-tracking-carrier {
  font-size: 0.4rem;
  letter-spacing: 0.1em;
  color: rgba(155, 95, 255, 0.6);
}
.order-date {
  font-size: 0.44rem;
  letter-spacing: 0.1em;
  color: rgba(155, 95, 255, 0.6);
}
.order-total {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(155, 95, 255, 0.75);
  margin-left: auto;
}
.order-items {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.order-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.order-item-sku {
  font-size: 0.42rem;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.65);
  flex-shrink: 0;
}
.order-item-name {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: #dbbeff;
  flex: 1;
}
/* ── Admin QR section ─────────────────────────────────── */
.admin-qr-section {
  margin-top: 1.6rem;
  padding-top: 1.2rem;
  border-top: 1px solid rgba(155, 95, 255, 0.12);
}
.admin-qr-result {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.7rem;
  margin-top: 1rem;
}
.admin-qr-img {
  width: 160px;
  height: 160px;
  image-rendering: pixelated;
  border: 2px solid rgba(155, 95, 255, 0.25);
}
.admin-qr-url {
  font-size: 0.42rem;
  letter-spacing: 0.06em;
  color: rgba(155, 95, 255, 0.75);
  word-break: break-all;
  max-width: 380px;
  margin: 0;
}
/* ── Claim page ───────────────────────────────────────── */
.claim-page {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 2rem 1rem;
  min-height: 60vh;
}
.claim-terminal {
  width: min(520px, 100%);
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 1.4rem 1.6rem 1.6rem;
  background: rgba(2, 0, 14, 0.5);
}
.claim-header {
  font-size: 0.48rem;
  letter-spacing: 0.2em;
  color: rgba(155, 95, 255, 0.65);
  margin: 0 0 1.4rem;
}
.claim-block {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.claim-line {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  color: #c9a6ff;
  margin: 0;
}
.claim-sub {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(210, 178, 255, 0.8);
  margin: 0;
  line-height: 1.7;
}
.claim-token {
  color: #f5c842;
  letter-spacing: 0.12em;
}
.claim-step {
  font-size: 0.52rem;
  letter-spacing: 0.12em;
  margin: 0;
  line-height: 1.8;
}
.claim-step--done {
  color: rgba(155, 95, 255, 0.7);
}
.claim-step--active {
  color: #c9a6ff;
}
.claim-step--active::after {
  content: "▋";
  animation: cursor-blink 0.9s step-end infinite;
  margin-left: 0.2em;
}
.claim-success {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: #c9a6ff;
  margin: 0.4rem 0 0;
}
.claim-error {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  color: #f5c842;
  margin: 0;
}
.claim-action-btn {
  margin-top: 0.6rem;
  align-self: flex-start;
}
/* ── Confirm dialog (ConfirmDialog.jsx) ───────────────────
   Visitor-facing destructive-action confirm. The admin panel has its own
   (AdminUI's useConfirm), but that's light-themed and lives inside
   AdminUIProvider, which the storefront never mounts.
   z-index sits above the lightbox (600) — a dialog must never open behind
   something else. */
.cd-backdrop {
  position: fixed;
  inset: 0;
  z-index: 700;
  background: rgba(3, 1, 8, 0.86);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  animation: cd-fade 140ms ease both;
}
.cd-panel {
  width: 100%;
  max-width: 380px;
  background: #0b0518;
  border: 1px solid rgba(155, 95, 255, 0.45);
  box-shadow: 0 0 40px rgba(120, 60, 220, 0.28), inset 0 0 30px rgba(80, 30, 160, 0.12);
  padding: 1.3rem 1.2rem 1.1rem;
  text-align: left;
  animation: cd-rise 160ms ease both;
}
.cd-title {
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  color: #f5c842;
  margin: 0 0 0.6rem;
  text-transform: uppercase;
}
.cd-body {
  font-size: 0.5rem;
  letter-spacing: 0.09em;
  line-height: 1.7;
  color: rgba(219, 190, 255, 0.85);
  margin: 0 0 1.1rem;
  text-transform: uppercase;
}
.cd-actions {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.cd-btn {
  font-family: inherit;
  font-size: 0.48rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.6rem 0.9rem;
  /* 40px min — these are the two most consequential taps on the page and the
     REMOVE link that opens the dialog is itself tiny. */
  min-height: 40px;
  cursor: pointer;
  background: none;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.cd-btn--cancel {
  border: 1px solid rgba(155, 95, 255, 0.3);
  color: rgba(219, 190, 255, 0.75);
}
.cd-btn--cancel:hover { border-color: rgba(155, 95, 255, 0.6); color: #dbbeff; }
.cd-btn--confirm {
  border: 1px solid rgba(245, 200, 66, 0.55);
  color: #f5c842;
}
.cd-btn--confirm:hover { background: rgba(245, 200, 66, 0.12); border-color: #f5c842; }
.cd-btn:focus-visible {
  outline: 1px solid rgba(155, 95, 255, 0.9);
  outline-offset: 2px;
}
@keyframes cd-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cd-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
/* The dialog is a decision point — don't animate it in for readers who've
   asked for stillness. */
@media (prefers-reduced-motion: reduce) {
  .cd-backdrop, .cd-panel { animation: none; }
}
@media (max-width: 600px) {
  .cd-actions { gap: 0.5rem; }
  .cd-btn { flex: 1 1 auto; text-align: center; }
}
/* ── Mobile hamburger & fullscreen nav ────────────────── */
.nav-hamburger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0 0.55rem;
  flex-shrink: 0;
  height: 100%;
}
.nav-hamburger span {
  display: block;
  width: 20px;
  height: 2px;
  background: rgba(var(--mb, 155, 95, 255), 0.70);
  transition: background 200ms ease;
}
.nav-hamburger:hover span {
  background: rgba(var(--mb, 155, 95, 255), 1);
}
.nav-mobile-brand {
  display: none;
  flex: 1;
  align-items: center;
  gap: 0.45rem;
  min-width: 0;
  cursor: pointer;
}
.nav-mobile-cursor {
  display: inline-block;
  flex-shrink: 0;
  width: 0.48rem;
  height: 0.9em;
  background: #9b5fff;
  box-shadow: 0 0 6px rgba(155, 95, 255, 0.95), 0 0 16px rgba(155, 95, 255, 0.45);
  animation: nav-cursor-blink 0.72s step-end infinite;
  vertical-align: text-bottom;
}
@keyframes nav-cursor-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0; }
}
/* Nav brand label colour — matches the menu item for the current page */
.brand--home    { --mb: 155,  95, 255; }
.brand--shop    { --mb: 110, 220,  80; }
.brand--gloom   { --mb: 220,  55,  65; }
.brand--blog    { --mb: 190,  90, 255; }
.brand--contact { --mb:  60, 200, 220; }
.brand--cart    { --mb: 245, 200,  50; }
.brand--account { --mb: 180, 130, 255; }
.brand--login   { --mb: 180, 130, 255; }
.brand--admin   { --mb: 255, 140,  50; }
.nav-mobile-page {
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  font-weight: 700;
  color: rgba(var(--mb, 210, 178, 255), 0.88);
  text-shadow: 0 0 10px rgba(var(--mb, 155, 95, 255), 0.50);
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 200ms ease, text-shadow 200ms ease;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ── Filing cabinet drawer — mobile menu ───────────────── */
.mobile-menu {
  position: fixed;
  /* Starts just below the nav bar — the drawer opens beneath the cabinet top */
  top: 2.6rem;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  /* Drawer interior: dark metal floor with faint horizontal ridges */
  background:
    repeating-linear-gradient(
      180deg,
      transparent                      0px,
      transparent                      3px,
      rgba(155, 95, 255, 0.016)        3px,
      rgba(155, 95, 255, 0.016)        4px
    ),
    linear-gradient(180deg, #0f0b1e 0%, #090714 100%);
  /* Drawer slides in from the left — mechanical spring with hard stop */
  animation: drawer-open 380ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes drawer-open {
  from { opacity: 0.5; transform: translateX(-100%); }
  82%  {               transform: translateX(6px);   }  /* overshoot — hits the stop */
  100% { opacity: 1;   transform: translateX(0); }
}
@keyframes drawer-close {
  from { opacity: 1;   transform: translateX(0); }
  to   { opacity: 0.6; transform: translateX(-100%); }
}
.mobile-menu--closing {
  animation: drawer-close 280ms cubic-bezier(0.55, 0, 0.78, 0) both;
}
/* Drawer label holder — the inset label panel on the front of the drawer */
.mobile-menu-header {
  display: flex;
  align-items: center;
  padding: 0.75rem 1rem;
  flex-shrink: 0;
  background: linear-gradient(180deg, #1a1230 0%, #120e26 100%);
  border-bottom: 2px solid rgba(155, 95, 255, 0.22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 3px 10px rgba(0, 0, 0, 0.5);
}
.mobile-menu-title {
  font-size: 0.46rem;
  letter-spacing: 0.28em;
  color: rgba(155, 95, 255, 0.55);
  margin: 0;
  text-transform: uppercase;
  cursor: pointer;
  flex: 1;
  transition: color 140ms ease;
}
.mobile-menu-title:hover {
  color: rgba(155, 95, 255, 0.85);
}
/* Tap-to-close hint on the right */
.mobile-menu-header::after {
  content: "TAP TO CLOSE";
  font-size: 0.38rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.28);
  text-transform: uppercase;
  pointer-events: none;
}
.mobile-menu-nav {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 0.4rem 0 1rem;
}
/* ── Per-folder colour identity ── */
.mobile-menu-link {
  --mc: 155, 95, 255; /* default: purple */
}
.mobile-menu-link--home    { --mc: 155,  95, 255; }
.mobile-menu-link--shop    { --mc: 110, 220,  80; }
.mobile-menu-link--gloom   { --mc: 220,  55,  65; }
.mobile-menu-link--blog    { --mc: 190,  90, 255; }
.mobile-menu-link--contact { --mc:  60, 200, 220; }
.mobile-menu-link--cart    { --mc: 245, 200,  50; }
.mobile-menu-link--admin   { --mc: 255, 140,  50; }
.mobile-menu-link--account { --mc: 180, 130, 255; }
.mobile-menu-link--login   { --mc: 180, 130, 255; }
/* ── Staggered folder entrance ─────────────────────────── */
@keyframes folder-in {
  from { opacity: 0; transform: translateX(-22px); }
  to   { opacity: 1; transform: translateX(0); }
}
.mobile-menu-link,
.mobile-menu-divider {
  animation: folder-in 200ms ease-out both;
}
/* Each folder slides in 45ms after the previous one */
.mobile-menu-nav > :nth-child(1) { animation-delay:  60ms; }
.mobile-menu-nav > :nth-child(2) { animation-delay: 105ms; }
.mobile-menu-nav > :nth-child(3) { animation-delay: 150ms; }
.mobile-menu-nav > :nth-child(4) { animation-delay: 195ms; }
.mobile-menu-nav > :nth-child(5) { animation-delay: 240ms; }
.mobile-menu-nav > :nth-child(6) { animation-delay: 275ms; }
.mobile-menu-nav > :nth-child(7) { animation-delay: 310ms; }
.mobile-menu-nav > :nth-child(8) { animation-delay: 345ms; }
.mobile-menu-nav > :nth-child(9) { animation-delay: 380ms; }
/* Don't re-animate individual folders on close — the drawer slides as a unit */
.mobile-menu--closing .mobile-menu-link,
.mobile-menu--closing .mobile-menu-divider {
  animation: none;
}
/* Each link = a coloured folder standing in the drawer */
.mobile-menu-link {
  display: flex;
  align-items: center;
  /* Extra left padding for the colour stripe */
  padding: 0 1.2rem 0 1.6rem;
  height: 3.5rem;
  font-size: 0.82rem;
  letter-spacing: 0.16em;
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: none;
  color: rgba(var(--mc), 0.70);
  /* Folder edge lines — faint bottom border separating each folder */
  border-bottom: 1px solid rgba(0, 0, 0, 0.45);
  border-top: 1px solid rgba(255, 255, 255, 0.025);
  position: relative;
  transition: color 120ms ease, background 120ms ease, padding-left 140ms ease;
}
/* Left colour stripe — the folder's colour tab stuck to the spine */
.mobile-menu-link::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 6px;
  background: linear-gradient(180deg,
    rgba(var(--mc), 0.70) 0%,
    rgba(var(--mc), 0.42) 100%
  );
  box-shadow: 2px 0 10px rgba(var(--mc), 0.20);
  transition: background 120ms ease, box-shadow 120ms ease;
}
/* Right pull arrow — the file tab you grab to pull out the folder */
.mobile-menu-link::after {
  content: "›";
  position: absolute;
  right: 1.1rem;
  font-size: 1.1rem;
  line-height: 1;
  color: rgba(var(--mc), 0.25);
  transition: color 120ms ease, right 140ms ease;
}
/* Hover: folder pulls out of the drawer toward you */
.mobile-menu-link:hover {
  color: rgba(var(--mc), 0.95);
  background: rgba(var(--mc), 0.055);
  padding-left: 2rem;
}
.mobile-menu-link:hover::before {
  background: linear-gradient(180deg,
    rgba(var(--mc), 0.90) 0%,
    rgba(var(--mc), 0.60) 100%
  );
  box-shadow: 2px 0 14px rgba(var(--mc), 0.38);
}
.mobile-menu-link:hover::after {
  color: rgba(var(--mc), 0.65);
  right: 0.8rem;
}
/* Active: this folder is open */
.mobile-menu-link.is-active {
  color: rgba(var(--mc), 1);
  text-shadow: 0 0 12px rgba(var(--mc), 0.5);
  background: rgba(var(--mc), 0.08);
}
.mobile-menu-link.is-active::before {
  background: linear-gradient(180deg,
    rgba(var(--mc), 1)    0%,
    rgba(var(--mc), 0.72) 100%
  );
  box-shadow:
    2px 0 12px rgba(var(--mc), 0.55),
    3px 0 24px rgba(var(--mc), 0.25);
}
.mobile-menu-link.is-active::after {
  color: rgba(var(--mc), 0.55);
}
/* Metal drawer divider tab */
.mobile-menu-divider {
  height: 2px;
  margin: 0.3rem 0;
  background: linear-gradient(90deg,
    rgba(155, 95, 255, 0.22) 0%,
    rgba(155, 95, 255, 0.08) 60%,
    transparent              100%
  );
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.4);
}
/* ── Comprehensive mobile overrides ───────────────────── */
@media (max-width: 640px) {
  /* Base font size boost — all rem values scale with this */
  html { font-size: 20px; }

  /* Nav: hide desktop tabs, show hamburger + brand */
  .nav-bar {
    height: 2.6rem;
    padding: 5px 6px 0;
  }

  .cabinet-menu,
  .cabinet-menu-right {
    display: none;
  }

  .nav-hamburger {
    display: flex;
  }

  .nav-mobile-brand {
    display: flex;
  }

  /* Cart icon stays visible top-right, pushed past the hamburger + brand */
  .nav-cart {
    margin-left: auto;
    padding: 0 0.4rem;
  }
  .nav-cart-icon { width: 1.4rem; height: 1.4rem; }

  /* Viewport: match nav height */
  .page-viewport {
    padding-top: 2.8rem;
  }

  /* Page panel: tighter horizontal padding */
  .page-panel {
    padding: 1.5rem 1rem;
  }

  /* ── Home page ── */
  .home-panel {
    gap: 1rem;
  }

  .home-sticker {
    width: clamp(72px, 18vw, 110px);
  }

  .home-sticker-link {
    top: 0.8rem;
    right: 0.8rem;
  }

  .panel-copy {
    font-size: clamp(0.72rem, 3.5vw, 0.88rem);
    color: rgba(228, 208, 255, 0.95);
  }

  .home-desc {
    font-size: 0.7rem;
    color: rgba(210, 178, 255, 0.93);
    max-width: 32ch;
  }

  .boot-log {
    font-size: clamp(0.6rem, 3.5vw, 0.75rem);
    color: rgba(210, 178, 255, 0.9);
  }

  .boot-panel {
    padding: 1.6rem 1.2rem;
  }

  /* ── Shop ── */
  .shop-panel {
    padding-top: 1.5rem;
    gap: 1rem;
  }

  .shop-meta {
    font-size: 0.6rem;
    color: rgba(210, 178, 255, 0.87);
  }

  .shop-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.65rem;
    padding-bottom: 2rem;
  }

  /* ── Gloomopedia ── */
  .gpedia-cat-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.65rem;
  }

  .gpedia-spec-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.65rem;
  }

  /* ── Product cards ── */
  .product-name {
    font-size: 0.68rem;
    color: #dbbeff;
  }

  .product-sub {
    font-size: 0.5rem;
    color: rgba(196, 160, 255, 0.7);
  }

  .product-id {
    font-size: 0.44rem;
    color: rgba(155, 95, 255, 0.7);
  }

  .product-price {
    font-size: 0.72rem;
  }

  .product-status {
    font-size: 0.46rem;
    color: rgba(210, 178, 255, 0.87);
  }

  .product-info {
    padding: 0.6rem 0.6rem 0.65rem;
    gap: 0.25rem;
  }

  .filter-chip {
    font-size: 0.46rem;
    padding: 0.22rem 0.6rem;
  }

  /* ── Product detail page ── */
  .product-page-desc {
    font-size: 0.62rem;
    color: rgba(218, 190, 255, 0.88);
  }

  .product-page-acquire {
    font-size: 0.62rem;
    padding: 0.7rem 0.5rem;
  }

  .product-page-note {
    font-size: 0.5rem;
    color: rgba(210, 178, 255, 0.72);
  }

  .product-tab {
    font-size: 0.5rem;
    letter-spacing: 0.12em;
    padding: 0.55rem 0.4rem;
  }

  .admin-btn {
    font-size: 0.52rem;
  }

  /* ── Channel / AI chat ── */
  .channel-message {
    font-size: 0.6rem;
    line-height: 1.85;
  }

  .channel-message--creature {
    color: rgba(218, 190, 255, 0.9);
  }

  .channel-message--user {
    color: rgba(196, 160, 255, 0.87);
  }

  .channel-input {
    font-size: 0.62rem;
  }

  .channel-send-btn {
    font-size: 0.48rem;
    padding: 0.35rem 0.65rem;
  }

  .channel-auth-sub {
    font-size: 0.6rem;
    color: rgba(210, 178, 255, 0.87);
  }

  .channel-auth-label {
    font-size: 0.5rem;
    color: rgba(196, 160, 255, 0.93);
  }

  .channel-status-label {
    font-size: 0.48rem;
    color: rgba(196, 160, 255, 0.83);
  }

  .channel-counter {
    font-size: 0.44rem;
    color: rgba(196, 160, 255, 0.77);
  }

  .channel-connecting {
    font-size: 0.54rem;
    color: rgba(196, 160, 255, 0.9);
  }

  /* ── Blog ── */
  .blog-panel {
    padding-top: 1.5rem;
    gap: 1rem;
  }

  .blog-card-title {
    font-size: clamp(0.78rem, 4vw, 0.96rem);
    color: #dbbeff;
  }

  .blog-card-excerpt {
    font-size: 0.6rem;
    color: rgba(210, 178, 255, 0.85);
  }

  .blog-card-date {
    font-size: 0.5rem;
    color: rgba(196, 160, 255, 0.8);
  }

  .blog-card-read {
    font-size: 0.52rem;
    color: rgba(155, 95, 255, 0.75);
  }

  /* ── Blog post ── */
  .blog-post-body p {
    font-size: clamp(0.62rem, 3.5vw, 0.76rem);
    color: rgba(218, 192, 255, 0.88);
  }

  /* ── Lore / Gloomopedia ── */
  .lore-panel {
    padding-top: 0.4rem;
  }

  .lore-layout {
    grid-template-columns: 1fr;
    /* Single row — whichever panel is visible fills the full height */
    grid-template-rows: 1fr;
    flex: 1;
  }

  .lore-index {
    border-right: none;
    border-bottom: 1px solid rgba(155, 95, 255, 0.08);
  }

  .lore-index--hidden {
    display: none;
  }

  .lore-detail {
    display: none;
  }

  .lore-detail--visible {
    display: flex;
  }

  /* ── Contact ── */
  .contact-panel {
    gap: 1.8rem;
    padding: 1.2rem 1rem;
  }

  .contact-field-label {
    min-width: 5rem;
    font-size: 0.44rem;
    color: rgba(196, 160, 255, 0.8);
  }

  .contact-field-value {
    font-size: 0.55rem;
    color: rgba(210, 178, 255, 0.82);
  }

  .contact-note {
    font-size: 0.5rem;
    color: rgba(155, 95, 255, 0.68);
  }

  /* ── Account ── */
  .account-section-label {
    font-size: 0.48rem;
    color: rgba(196, 160, 255, 0.93);
  }

  /* ── Cart ── */
  .cart-item-name {
    font-size: 0.56rem;
  }

  .cart-item-price {
    font-size: 0.62rem;
  }

  .cart-total-amount {
    font-size: 0.72rem;
  }

  /* ── Claims ── */
  .claim-terminal {
    padding: 1.2rem 1.1rem 1.4rem;
  }

  .claim-line {
    font-size: 0.68rem;
  }

  .claim-step {
    font-size: 0.56rem;
  }

  /* ── Panel title sizing ── */
  .panel-title {
    font-size: clamp(1.6rem, 11vw, 2.4rem);
  }

  .admin-title {
    font-size: clamp(0.9rem, 5vw, 1.3rem);
  }

  /* ── Prevent iOS auto-zoom on input focus (requires font-size ≥ 16px) ── */
  input, textarea, select {
    font-size: 16px !important;
  }

  /* ── Boot sequence: shrink font to fit longest line on one row ── */
  .boot-log {
    font-size: 0.56rem;
  }

  .boot-panel {
    overflow: hidden;
  }

  /* ── Page transitions: simple fade instead of CRT static ── */
  .crt-screen.is-switching {
    animation: mobile-channel-jump 400ms linear both;
  }

  .channel-static.is-switching {
    animation: none;
    opacity: 0;
  }
}
@keyframes mobile-channel-jump {
  /* Overload flash */
  0%   { filter: brightness(1);    }
  8%   { filter: brightness(6);    }
  /* Snap black — content invisible while new page loads */
  20%  { filter: brightness(0.01); }
  /* Hold — content renders at 75% (300ms) */
  73%  { filter: brightness(0.01); }
  /* New channel: dot flash then settle */
  82%  { filter: brightness(4);    }
  100% { filter: brightness(1);    }
}
/* ── Lore ↔ Shop linking ──────────────────────────────────── */
/* Gloomopedia: acquire bar */
.lore-acquire-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  margin: 0.8rem 0;
  border: 1px solid rgba(155, 95, 255, 0.22);
  background: rgba(155, 95, 255, 0.05);
}
.lore-acquire-status {
  font-size: 0.38rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.8);
}
.lore-acquire-btn {
  font-size: 0.38rem;
  letter-spacing: 0.14em;
  padding: 0.38rem 0.9rem;
  color: rgba(120, 255, 172, 0.9);
  background: transparent;
  border: 1px solid rgba(120, 255, 172, 0.3);
  cursor: pointer;
  transition: color 160ms, border-color 160ms, background 160ms;
  white-space: nowrap;
}
.lore-acquire-btn:hover {
  color: rgba(120, 255, 172, 1);
  border-color: rgba(120, 255, 172, 0.6);
  background: rgba(120, 255, 172, 0.07);
}
/* Shop card: gloomopedia badge */
.product-lore-badge {
  position: absolute;
  top: 0.45rem;
  left: 0.45rem;
  font-size: 0.3rem;
  letter-spacing: 0.12em;
  padding: 0.18rem 0.4rem;
  color: rgba(155, 95, 255, 0.95);
  background: rgba(10, 10, 15, 0.82);
  border: 1px solid rgba(155, 95, 255, 0.35);
  pointer-events: none;
}
/* Product page: lore classification panel */
.product-lore-panel {
  margin: 0.8rem 0;
  border: 1px solid rgba(155, 95, 255, 0.2);
  background: rgba(155, 95, 255, 0.04);
}
.product-lore-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.45rem 0.75rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.15);
  gap: 0.5rem;
}
.product-lore-panel-label {
  font-size: 0.33rem;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.9);
}
.product-lore-panel-link {
  font-size: 0.3rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.6);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
  white-space: nowrap;
  transition: color 140ms;
}
.product-lore-panel-link:hover {
  color: rgba(196, 160, 255, 1);
}
.product-lore-panel-fields {
  padding: 0.4rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.product-lore-panel-row {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
}
.product-lore-panel-key {
  font-size: 0.3rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.45);
  flex-shrink: 0;
  min-width: 4.5rem;
}
.product-lore-panel-val {
  font-size: 0.32rem;
  letter-spacing: 0.08em;
  color: rgba(196, 160, 255, 0.85);
}
.product-lore-panel-val--threat[data-level="MINIMAL"],
.product-lore-panel-val--threat[data-level="LOW"] { color: rgba(120, 255, 172, 0.8); }
.product-lore-panel-val--threat[data-level="MODERATE"] { color: rgba(255, 200, 80, 0.85); }
.product-lore-panel-val--threat[data-level="HIGH"]    { color: rgba(255, 130, 50, 0.9); }
.product-lore-panel-val--threat[data-level="EXTREME"] { color: rgba(255, 70, 70, 0.95); }
.product-lore-panel-val--status[data-status="ACTIVE"]    { color: rgba(120, 255, 172, 0.85); }
.product-lore-panel-val--status[data-status="DORMANT"]   { color: rgba(255, 200, 80, 0.8); }
.product-lore-panel-val--status[data-status="EXTINCT"]   { color: rgba(255, 80, 80, 0.75); }
.product-lore-panel-val--status[data-status="CONTAINED"] { color: rgba(80, 180, 255, 0.8); }
.product-lore-panel-excerpt {
  font-size: 0.32rem;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: rgba(196, 160, 255, 0.55);
  padding: 0.4rem 0.75rem 0.55rem;
  border-top: 1px solid rgba(155, 95, 255, 0.1);
  margin: 0;
}
/* Public product page: lore panel */
.pub-lore-panel {
  margin: 1rem 0;
  border: 1px solid rgba(155, 95, 255, 0.22);
  background: rgba(155, 95, 255, 0.04);
}
.pub-lore-header {
  font-size: 0.55rem;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.85);
  padding: 0.5rem 0.9rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.15);
}
.pub-lore-fields {
  padding: 0.5rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.pub-lore-row {
  display: flex;
  gap: 0.8rem;
  align-items: baseline;
}
.pub-lore-key {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  color: rgba(196, 160, 255, 0.45);
  flex-shrink: 0;
  min-width: 5.5rem;
}
.pub-lore-val {
  font-size: 0.52rem;
  letter-spacing: 0.06em;
  color: rgba(196, 160, 255, 0.85);
}
.pub-lore-val--threat[data-level="MINIMAL"],
.pub-lore-val--threat[data-level="LOW"]    { color: rgba(120, 255, 172, 0.8); }
.pub-lore-val--threat[data-level="MODERATE"] { color: rgba(255, 200, 80, 0.85); }
.pub-lore-val--threat[data-level="HIGH"]   { color: rgba(255, 130, 50, 0.9); }
.pub-lore-val--threat[data-level="EXTREME"] { color: rgba(255, 70, 70, 0.95); }
.pub-lore-val--status[data-status="ACTIVE"]    { color: rgba(120, 255, 172, 0.85); }
.pub-lore-val--status[data-status="DORMANT"]   { color: rgba(255, 200, 80, 0.8); }
.pub-lore-val--status[data-status="EXTINCT"]   { color: rgba(255, 80, 80, 0.75); }
.pub-lore-val--status[data-status="CONTAINED"] { color: rgba(80, 180, 255, 0.8); }
.pub-lore-excerpt {
  font-size: 0.5rem;
  line-height: 1.65;
  letter-spacing: 0.03em;
  color: rgba(196, 160, 255, 0.5);
  padding: 0.5rem 0.9rem 0.65rem;
  border-top: 1px solid rgba(155, 95, 255, 0.1);
  margin: 0;
}
/* ── Whimsy / Toy-Ad public page ──────────────────────────── */
/*
 * Palette:
 *   Deep violet  #6b35a0  — header strip, channel header, sold stamp
 *   Soft lilac   #c49ee8  — borders, accents, decorative rule
 *   Bright lime  #7dff6e  — price badge, action button, available dot
 *   Dark forest  #1c4d2a  — image drop shadows (lilac frame + green shadow)
 *   Pale lavender #ede0f8 — body text throughout
 */
.pub-page--whimsy {
  background: radial-gradient(ellipse at top center, #160b24 0%, #0d0a0f 55%);
  min-height: 100dvh;
  overflow-x: hidden;
  position: relative;
}
/* Paper grain overlay */
.pub-page--whimsy::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.032;
  pointer-events: none;
  z-index: 0;
}
.whimsy-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 680px;
  margin: 0 auto;
  padding-bottom: 3rem;
}
/* ── Header strip ── */
.whimsy-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 1rem;
  background: #6b35a0;
  border-bottom: 3px solid #c49ee8;
  gap: 0.6rem;
}
.whimsy-header-left {
  display: flex;
  flex-direction: column;
  gap: 0.08rem;
}
.whimsy-brand-name {
  font-size: clamp(0.6rem, 2.8vw, 1rem);
  letter-spacing: 0.26em;
  color: #ede0f8;
  line-height: 1;
}
.whimsy-brand-sub {
  font-size: 0.3rem;
  letter-spacing: 0.22em;
  color: rgba(237, 224, 248, 0.55);
}
.whimsy-sku-badge {
  background: #7dff6e;
  color: #0d0a0f;
  font-size: 0.36rem;
  letter-spacing: 0.18em;
  padding: 0.18rem 0.55rem;
  border: 2px solid #0d0a0f;
  white-space: nowrap;
}
.whimsy-header-share-btn {
  background: #7dff6e;
  color: #0d0a0f;
  font-size: 0.36rem;
  letter-spacing: 0.18em;
  padding: 0.22rem 0.65rem;
  border: 2px solid #0d0a0f;
  white-space: nowrap;
  cursor: pointer;
  font-family: inherit;
  text-transform: uppercase;
  transition: background 140ms, color 140ms, transform 140ms;
  box-shadow: 2px 2px 0 #0d0a0f;
}
.whimsy-header-share-btn:hover {
  background: #a8ffA0;
  transform: translate(-1px, -1px);
  box-shadow: 3px 3px 0 #0d0a0f;
}
.whimsy-header-share-btn:active {
  transform: translate(1px, 1px);
  box-shadow: 1px 1px 0 #0d0a0f;
}
/* ── Three-image collage ── */
.whimsy-collage {
  position: relative;
  height: 280px;
  background: #0d0a0f;
  overflow: hidden;
  border-bottom: 3px solid #c49ee8;
}
.whimsy-img-frame {
  position: absolute;
  overflow: hidden;
  border: 3px solid #c49ee8;
}
.whimsy-img-frame img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}
.whimsy-img-frame--main {
  width: 160px;
  height: 214px;
  left: 22px;
  top: 24px;
  transform: rotate(-3deg);
  transform-origin: bottom right;
  box-shadow: 6px 6px 0 #1c4d2a;
  z-index: 3;
}
.whimsy-img-frame--secondary {
  width: 136px;
  height: 181px;
  left: 168px;
  top: 38px;
  transform: rotate(2.5deg);
  transform-origin: bottom left;
  box-shadow: 6px 6px 0 #1c4d2a;
  z-index: 2;
}
.whimsy-img-frame--tertiary {
  width: 110px;
  height: 147px;
  right: 22px;
  top: 20px;
  transform: rotate(-6deg);
  transform-origin: top center;
  box-shadow: 5px 5px 0 #1c4d2a;
  z-index: 1;
}
.whimsy-sold-stamp {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(1.5rem, 6vw, 2.5rem);
  letter-spacing: 0.22em;
  color: #ede0f8;
  background: rgba(13, 10, 15, 0.72);
  border: 4px solid #6b35a0;
  z-index: 10;
}
/* ── Info box ── */
.whimsy-info-box {
  margin: 0 1rem 1.1rem;
  border: 3px solid #c49ee8;
  border-top: none;
  background: rgba(196, 158, 232, 0.04);
  padding: 1rem 1.2rem 1.1rem;
  box-shadow: 5px 5px 0 #0d0a0f, 7px 7px 0 #c49ee8;
}
.whimsy-title {
  font-size: clamp(1rem, 4.5vw, 1.9rem);
  letter-spacing: 0.1em;
  color: #ede0f8;
  margin: 0 0 0.5rem;
  line-height: 1.12;
}
.whimsy-rule {
  height: 2px;
  background: linear-gradient(to right, #c49ee8, rgba(196, 158, 232, 0.15));
  border: none;
  margin: 0 0 0.75rem;
}
.whimsy-desc {
  font-size: 0.5rem;
  line-height: 1.65;
  letter-spacing: 0.05em;
  color: rgba(237, 224, 248, 0.78);
  margin: 0 0 0.9rem;
}
.whimsy-meta-row {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}
.whimsy-price {
  background: #7dff6e;
  color: #0d0a0f;
  font-size: 0.65rem;
  letter-spacing: 0.14em;
  padding: 0.28rem 0.7rem;
  border: 2px solid #0d0a0f;
  box-shadow: 3px 3px 0 #0d0a0f;
  white-space: nowrap;
}
.whimsy-status {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.4rem;
  letter-spacing: 0.14em;
  color: #ede0f8;
}
.whimsy-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #c49ee8;
  display: inline-block;
  flex-shrink: 0;
}
.whimsy-status--available .whimsy-status-dot { background: #7dff6e; }
.whimsy-status--sold      .whimsy-status-dot { background: #c87ab0; }
/* ── Lore box ── */
.whimsy-lore-box {
  margin: 0 1rem 1.1rem;
  border: 2px solid rgba(196, 158, 232, 0.4);
  border-left: 4px solid #c49ee8;
  background: rgba(196, 158, 232, 0.03);
  padding: 0.75rem 1rem;
}
.whimsy-lore-label {
  font-size: 0.33rem;
  letter-spacing: 0.18em;
  color: #c49ee8;
  margin-bottom: 0.5rem;
}
.whimsy-lore-fields {
  display: flex;
  flex-direction: column;
  gap: 0.22rem;
  margin-bottom: 0.5rem;
}
.whimsy-lore-row {
  display: flex;
  gap: 0.6rem;
  font-size: 0.38rem;
  letter-spacing: 0.06em;
}
.whimsy-lore-key {
  color: rgba(196, 158, 232, 0.6);
  min-width: 4.2rem;
  flex-shrink: 0;
  letter-spacing: 0.1em;
}
.whimsy-lore-val {
  color: #ede0f8;
}
.whimsy-lore-excerpt {
  font-size: 0.42rem;
  line-height: 1.6;
  color: rgba(237, 224, 248, 0.55);
  margin: 0;
  border-top: 1px solid rgba(196, 158, 232, 0.18);
  padding-top: 0.5rem;
}
/* ── CTA ── */
.whimsy-cta {
  text-align: center;
  font-size: 0.4rem;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.4);
  margin: 0 1rem 0.9rem;
}
.whimsy-cta-link {
  color: #c49ee8;
  text-decoration: none;
}
.whimsy-cta-link:hover { text-decoration: underline; }
/* ── Tab strip ── */
.whimsy-tabs {
  display: flex;
  margin: 0 1rem;
}
.whimsy-tab {
  flex: 1;
  padding: 0.55rem 0.4rem;
  font-size: 0.38rem;
  letter-spacing: 0.18em;
  cursor: pointer;
  border: 3px solid #c49ee8;
  border-bottom: none;
  background: rgba(196, 158, 232, 0.04);
  color: rgba(237, 224, 248, 0.45);
  transition: background 140ms, color 140ms;
}
.whimsy-tab + .whimsy-tab {
  border-left: none;
}
.whimsy-tab--active {
  background: #6b35a0;
  color: #ede0f8;
}
/* Channel tab gets a lime top-accent when active to draw the eye */
.whimsy-tab--channel.whimsy-tab--active {
  border-top-color: #7dff6e;
  border-top-width: 3px;
}
.whimsy-tab--closed {
  color: rgba(237, 224, 248, 0.25);
  cursor: default;
}
/* Pulse on the channel tab before it's been opened — draws the eye */
.whimsy-tab--pulse {
  animation: whimsy-tab-pulse 2.8s ease-in-out infinite;
}
@keyframes whimsy-tab-pulse {
  0%, 100% { border-top-color: #7dff6e; color: rgba(237, 224, 248, 0.45); }
  50%       { border-top-color: rgba(125, 255, 110, 0.25); color: rgba(125, 255, 110, 0.7); }
}
.whimsy-tab:hover:not(.whimsy-tab--active):not(.whimsy-tab--closed) {
  background: rgba(107, 53, 160, 0.25);
  color: rgba(237, 224, 248, 0.75);
}
/* ── Channel panel ── */
.whimsy-channel {
  margin: 0 1rem 1.1rem;
  border: 3px solid #c49ee8;
  border-top: none;
  box-shadow: 4px 4px 0 #0d0a0f;
}
.whimsy-channel-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.45rem 0.8rem;
  background: #6b35a0;
  border-bottom: 2px solid #c49ee8;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.whimsy-channel-title {
  font-size: 0.36rem;
  letter-spacing: 0.14em;
  color: #ede0f8;
}
.whimsy-channel-meta {
  display: flex;
  gap: 0.6rem;
  align-items: center;
}
.whimsy-channel-gate {
  padding: 1.5rem;
  text-align: center;
}
/* ── Footer ── */
.whimsy-footer {
  text-align: center;
  padding: 1rem;
  border-top: 1px solid rgba(196, 158, 232, 0.15);
  margin: 1rem 1rem 0;
}
.whimsy-footer-text {
  font-size: 0.36rem;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.3);
}
/* ── Mobile adjustments ── */
@media (max-width: 440px) {
  .whimsy-collage { height: 230px; }

  .whimsy-img-frame--main {
    width: 128px; height: 171px;
    left: 12px;   top: 18px;
  }

  .whimsy-img-frame--secondary {
    width: 110px; height: 147px;
    left: 130px;  top: 28px;
  }

  .whimsy-img-frame--tertiary {
    width: 88px;  height: 117px;
    right: 10px;  top: 15px;
  }
}
/* ── Accessories line ── */
.whimsy-accessories-line {
  margin: 0.6rem 0 0;
  font-size: 0.4rem;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.7);
  border-top: 1px solid rgba(196, 158, 232, 0.15);
  padding-top: 0.5rem;
}
.whimsy-accessories-line::before {
  content: "◈ ";
  color: #c49ee8;
}
/* ── Gallery strip (images 4+) ── */
.whimsy-gallery-strip {
  display: flex;
  gap: 4px;
  padding: 5px 12px 8px;
  background: #0d0a0f;
  overflow-x: auto;
  border-bottom: 3px solid #c49ee8;
  scrollbar-width: none;
}
.whimsy-gallery-strip::-webkit-scrollbar { display: none; }
.whimsy-gallery-strip-item {
  flex-shrink: 0;
  width: 70px;
  height: 93px;
  border: 2px solid #c49ee8;
  overflow: hidden;
  box-shadow: 3px 3px 0 #1c4d2a;
}
.whimsy-gallery-strip-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
/* ── Footer brand strip ── */
.whimsy-footer-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.8rem 1rem;
  margin-top: 0.5rem;
  border-top: 2px solid rgba(196, 158, 232, 0.18);
  background: rgba(107, 53, 160, 0.08);
}
.whimsy-footer-brand {
  font-size: 0.38rem;
  letter-spacing: 0.24em;
  color: rgba(196, 158, 232, 0.6);
}
.whimsy-footer-divider {
  color: rgba(196, 158, 232, 0.3);
  font-size: 0.5rem;
}
.whimsy-footer-tagline {
  font-size: 0.3rem;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.3);
}
/* ── Admin: gallery image grid ── */
.admin-gallery-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.35rem;
}
.admin-gallery-slot {
  position: relative;
  width: 72px;
  height: 96px;
  border: 2px solid rgba(155, 95, 255, 0.25);
  overflow: hidden;
  flex-shrink: 0;
}
.admin-gallery-thumb {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
.admin-gallery-remove {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 18px;
  height: 18px;
  background: rgba(0, 0, 0, 0.75);
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(196, 160, 255, 0.9);
  font-size: 0.45rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  line-height: 1;
}
.admin-gallery-slot--add {
  background: rgba(155, 95, 255, 0.05);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  border-style: dashed;
}
.admin-gallery-add-label {
  font-size: 0.38rem;
  letter-spacing: 0.12em;
  color: rgba(196, 160, 255, 0.55);
  pointer-events: none;
}
/* ── Rich Text Editor (TipTap) ───────────────────────────── */
.rte-wrap {
  border: 1px solid rgba(155, 95, 255, 0.3);
  background: rgba(10, 6, 20, 0.6);
}
/* Toolbar */
.rte-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.15rem;
  padding: 0.35rem 0.45rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  background: rgba(155, 95, 255, 0.06);
}
.rte-btn {
  font-size: 0.38rem;
  letter-spacing: 0.08em;
  padding: 0.22rem 0.45rem;
  color: rgba(196, 160, 255, 0.7);
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  line-height: 1;
  transition: color 120ms, background 120ms, border-color 120ms;
  font-family: inherit;
}
.rte-btn:hover {
  color: rgba(219, 190, 255, 1);
  border-color: rgba(155, 95, 255, 0.3);
  background: rgba(155, 95, 255, 0.1);
}
.rte-btn--active {
  color: rgba(155, 95, 255, 1);
  background: rgba(155, 95, 255, 0.15);
  border-color: rgba(155, 95, 255, 0.4);
}
.rte-sep {
  width: 1px;
  height: 1rem;
  background: rgba(155, 95, 255, 0.18);
  margin: 0 0.2rem;
  display: inline-block;
  flex-shrink: 0;
}
/* Editor content area */
.rte-content {
  padding: 0.6rem 0.75rem;
  min-height: 8rem;
  cursor: text;
}
.rte-content:focus-within {
  outline: 1px solid rgba(155, 95, 255, 0.35);
  outline-offset: -1px;
}
/* ProseMirror element — the actual editable div */
.rte-prosemirror {
  outline: none;
  min-height: 6rem;
  font-size: 0.48rem;
  line-height: 1.65;
  color: rgba(196, 160, 255, 0.9);
}
.rte-prosemirror.ProseMirror-focused { outline: none; }
.rte-prosemirror p { margin: 0 0 0.5em; }
.rte-prosemirror p:last-child { margin-bottom: 0; }
.rte-prosemirror h2 {
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  color: rgba(219, 190, 255, 1);
  margin: 0.8em 0 0.3em;
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  padding-bottom: 0.2em;
}
.rte-prosemirror h3 {
  font-size: 0.55rem;
  letter-spacing: 0.08em;
  color: rgba(219, 190, 255, 0.9);
  margin: 0.7em 0 0.25em;
}
.rte-prosemirror strong { color: rgba(219, 190, 255, 1); font-weight: bold; }
.rte-prosemirror em     { font-style: italic; color: rgba(196, 160, 255, 0.85); }
.rte-prosemirror u      { text-decoration: underline; }
.rte-prosemirror s      { text-decoration: line-through; opacity: 0.65; }
.rte-prosemirror a {
  color: rgba(155, 95, 255, 0.95);
  text-decoration: underline;
  cursor: pointer;
}
.rte-prosemirror ul,
.rte-prosemirror ol {
  margin: 0.3em 0 0.5em 1.2em;
  padding: 0;
}
.rte-prosemirror li { margin: 0.15em 0; }
.rte-prosemirror blockquote {
  border-left: 3px solid rgba(155, 95, 255, 0.4);
  margin: 0.5em 0;
  padding: 0.3em 0.7em;
  color: rgba(196, 160, 255, 0.65);
  font-style: italic;
}
.rte-prosemirror hr {
  border: none;
  border-top: 1px solid rgba(155, 95, 255, 0.25);
  margin: 0.7em 0;
}
.rte-prosemirror code {
  background: rgba(155, 95, 255, 0.1);
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 0.05em 0.3em;
  font-family: inherit;
  font-size: 0.9em;
}
/* Placeholder */
.rte-prosemirror.is-editor-empty:first-child::before,
.rte-prosemirror p.is-editor-empty:first-child::before {
  content: attr(data-placeholder);
  color: rgba(155, 95, 255, 0.3);
  pointer-events: none;
  float: left;
  height: 0;
}
/* ── Rich Text Display (public pages) ─────────────────────── */
.rte-display { }
.rte-display p  { margin: 0 0 0.75em; }
.rte-display p:last-child { margin-bottom: 0; }
.rte-display h2 {
  font-size: 1.15em;
  letter-spacing: 0.06em;
  margin: 1em 0 0.4em;
}
.rte-display h3 {
  font-size: 1em;
  letter-spacing: 0.05em;
  margin: 0.9em 0 0.35em;
}
.rte-display strong { font-weight: bold; }
.rte-display em     { font-style: italic; }
.rte-display u      { text-decoration: underline; }
.rte-display s      { text-decoration: line-through; }
.rte-display a {
  color: inherit;
  text-decoration: underline;
  opacity: 0.85;
}
.rte-display a:hover { opacity: 1; }
.rte-display ul,
.rte-display ol {
  margin: 0.3em 0 0.6em 1.4em;
  padding: 0;
}
.rte-display li { margin: 0.2em 0; }
.rte-display blockquote {
  border-left: 2px solid currentColor;
  margin: 0.6em 0;
  padding: 0.3em 0.8em;
  opacity: 0.7;
  font-style: italic;
}
.rte-display hr {
  border: none;
  border-top: 1px solid currentColor;
  opacity: 0.2;
  margin: 0.8em 0;
}
.rte-display code {
  background: rgba(0, 0, 0, 0.25);
  padding: 0.05em 0.3em;
  font-family: inherit;
  font-size: 0.9em;
}
/* ── Gloomopedia: skip boot button ──────────────────── */
.gloom-boot-skip {
  position: absolute;
  bottom: 1.5rem;
  right: 1.5rem;
  font-size: 0.38rem;
  letter-spacing: 0.16em;
  color: rgba(120, 255, 172, 0.5);
  background: transparent;
  border: 1px solid rgba(120, 255, 172, 0.2);
  padding: 0.3rem 0.7rem;
  cursor: pointer;
  transition: color 160ms, border-color 160ms;
}
.gloom-boot-skip:hover {
  color: rgba(120, 255, 172, 0.9);
  border-color: rgba(120, 255, 172, 0.5);
}
/* ── Blog: draft card visual distinction ──────────── */
.blog-card-wrap--draft {
  opacity: 0.6;
  position: relative;
}
.blog-card-wrap--draft::after {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px dashed rgba(155, 95, 255, 0.35);
  pointer-events: none;
}
/* ── Pub page: mobile whimsy collage tightening ────── */
@media (max-width: 420px) {
  .whimsy-collage { height: 210px; }

  .whimsy-img-frame--main {
    width: 118px; height: 157px;
    left: 8px;    top: 16px;
  }

  .whimsy-img-frame--secondary {
    width: 100px; height: 133px;
    left: 118px;  top: 24px;
  }

  .whimsy-img-frame--tertiary {
    width: 80px;  height: 107px;
    right: 6px;   top: 14px;
  }

  .whimsy-info-box,
  .whimsy-lore-box,
  .whimsy-accessories,
  .whimsy-cta,
  .whimsy-tabs,
  .whimsy-channel,
  .whimsy-footer-strip {
    margin-left: 0.6rem;
    margin-right: 0.6rem;
  }
}
/* ── Dimensional Link Entrance Animation ──────────────── */
.dim-link-overlay {
  position: fixed;
  inset: 0;
  background: #05020e;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  opacity: 1;
  transition: opacity 0.5s ease-out;
}
.dim-link-overlay--fading {
  opacity: 0;
  pointer-events: none;
}
.dim-link-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
}
.dim-link-scanlines {
  position: relative;
  width: 240px;
  height: 240px;
  border: 2px solid rgba(125, 255, 110, 0.3);
}
.dim-link-scanline--scanning,
.dim-link-scanline--locking {
  position: absolute;
  height: 2px;
  width: 100%;
  background: linear-gradient(90deg, transparent, rgba(125, 255, 110, 0.8), transparent);
  animation: scanline-sweep 0.4s ease-in-out infinite;
}
.dim-link-scanline--complete,
.dim-link-scanline--fading {
  position: absolute;
  height: 2px;
  width: 100%;
  background: linear-gradient(90deg, transparent, rgba(125, 255, 110, 0.5), transparent);
  animation: none;
  top: 100%;
}
@keyframes scanline-sweep {
  0%   { top: 0%; }
  100% { top: 100%; }
}
.dim-link-text {
  text-align: center;
}
.dim-link-label {
  font-size: 12px;
  letter-spacing: 0.14em;
  color: rgba(125, 255, 110, 0.9);
  margin: 0;
  text-shadow: 0 0 12px rgba(125, 255, 110, 0.4);
  animation: text-flicker 1.2s ease-in-out infinite;
}
.dim-link-coords {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 10px;
  letter-spacing: 0.12em;
  color: rgba(125, 255, 110, 0.5);
}
/* ── Scan Data Overlay ────────────────────────────────── */
.scan-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(125, 255, 110, 0.6);
  display: flex;
  align-items: flex-start;
  justify-content: flex-end;
  padding: 1.2rem;
  z-index: 50;
}
.scan-sweep {
  position: absolute;
  left: 0;
  width: 100%;
  height: 1px;
  background: linear-gradient(to bottom, transparent, rgba(125, 255, 110, 0.9), transparent);
  box-shadow: 0 0 8px rgba(125, 255, 110, 0.8);
}
.scan-corner {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 1px solid rgba(125, 255, 110, 0.7);
}
.scan-corner-tl { top: 6px;     left: 6px;     border-right: none; border-bottom: none; }
.scan-corner-tr { top: 6px;     right: 6px;    border-left: none;  border-bottom: none; }
.scan-corner-bl { bottom: 6px;  left: 6px;     border-right: none; border-top: none; }
.scan-corner-br { bottom: 6px;  right: 6px;    border-left: none;  border-top: none; }
.scan-data-panel {
  background: rgba(0, 0, 0, 0.8);
  border: 1px solid rgba(125, 255, 110, 0.5);
  padding: 0.8rem 1rem;
  max-width: 180px;
  animation: scan-data-slide-in 0.4s ease-out;
}
@keyframes scan-data-slide-in {
  0%   { transform: translateX(20px); opacity: 0; }
  100% { transform: translateX(0); opacity: 1; }
}
.scan-data-row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.3rem 0;
  font-size: 9px;
  letter-spacing: 0.1em;
}
.scan-label {
  color: rgba(125, 255, 110, 0.6);
}
.scan-value {
  color: rgba(125, 255, 110, 0.95);
  font-weight: bold;
  text-align: right;
}
.scan-signal {
  animation: blink 1s ease-in-out infinite;
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}
/* ── Image Pulse when streaming ──────────────────────── */
.pub-img--pulse,
.whimsy-img--pulse {
  animation: img-glow-pulse 1.4s ease-in-out infinite;
}
@keyframes img-glow-pulse {
  0%, 100% {
    filter: saturate(0.7) brightness(0.88) drop-shadow(0 0 0px rgba(125, 255, 110, 0));
  }
  50% {
    filter: saturate(0.8) brightness(1) drop-shadow(0 0 20px rgba(125, 255, 110, 0.5));
  }
}
/* ── Share Button ────────────────────────────────────── */
.pub-share-btn,
.whimsy-share-btn {
  font-size: 12px;
  letter-spacing: 0.16em;
  color: rgba(155, 95, 255, 0.7);
  background: transparent;
  border: 1px solid rgba(155, 95, 255, 0.3);
  padding: 0.4rem 0.9rem;
  cursor: pointer;
  margin-top: 0.4rem;
  transition: color 160ms, border-color 160ms, background 160ms;
}
.pub-share-btn:hover,
.whimsy-share-btn:hover {
  color: #b97fff;
  border-color: rgba(155, 95, 255, 0.6);
  background: rgba(155, 95, 255, 0.08);
}
/* ══════════════════════════════════════════════════════
   DOSSIER / SPECIES FILE LAYOUT
   ══════════════════════════════════════════════════════ */
.dossier-page {
  width: 100%;
  min-height: 100dvh;
  /* .page-viewport is a flex column — without this the dossier gets flex-shrunk
     to the viewport height and its content overflows ON TOP of the site footer. */
  flex-shrink: 0;
  background: radial-gradient(ellipse at top center, #160b24 0%, #0d0a0f 55%);
  color: #ede0f8;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 13px;
  line-height: 1.7;
  letter-spacing: 0.04em;
  display: flex;
  flex-direction: column;
}
/* Meta strip — sits below the whimsy-header bar */
.dossier-meta-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 2rem;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid rgba(196, 158, 232, 0.2);
  background: rgba(107, 53, 160, 0.08);
}
.dossier-meta-item {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.dossier-meta-key {
  font-size: 9px;
  letter-spacing: 0.18em;
  color: rgba(196, 158, 232, 0.75);
  text-transform: uppercase;
}
.dossier-meta-val {
  font-size: 12px;
  letter-spacing: 0.1em;
  color: #ede0f8;
}
.dossier-restricted-stamp {
  font-size: 11px;
  letter-spacing: 0.22em;
  color: rgba(255, 74, 110, 0.8);
  border: 1px solid rgba(255, 74, 110, 0.4);
  padding: 0.2rem 0.55rem;
  text-shadow: 0 0 8px rgba(255, 74, 110, 0.3);
}
.dossier-meta-right {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-left: auto;
  flex-shrink: 0;
}
.dossier-threat-badge {
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--threat-color, rgba(196, 158, 232, 0.8));
  border: 1px solid var(--threat-color, rgba(196, 158, 232, 0.4));
  padding: 0.22rem 0.65rem;
  text-shadow: 0 0 8px var(--threat-color, transparent);
  box-shadow: 0 0 10px -4px var(--threat-color, transparent);
}
.dossier-rule {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0 1rem;
  margin: 0;
}
.dossier-rule::before,
.dossier-rule::after {
  content: "";
  flex: 1;
  height: 1px;
  background: rgba(196, 158, 232, 0.2);
}
.dossier-rule-label {
  font-size: 10px;
  letter-spacing: 0.22em;
  color: rgba(196, 158, 232, 0.9);
  white-space: nowrap;
  padding: 0.7rem 0;
}
.dossier-photo {
  margin: 0;
  padding: 1.2rem 1rem;
}
.dossier-photo--small {
  padding: 1rem 1rem;
  max-width: 580px;
}
.dossier-photo-inner {
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(196, 158, 232, 0.3);
  background: #0a0710;
}
.dossier-photo-inner img {
  width: 100%;
  display: block;
  transition: transform 300ms ease-out;
}
.dossier-photo-img--pulse {
  animation: img-glow-pulse 1.4s ease-in-out infinite;
}
.dossier-photo-redacted {
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: repeating-linear-gradient(
    45deg,
    rgba(196, 158, 232, 0.04) 0px,
    rgba(196, 158, 232, 0.04) 10px,
    transparent 10px,
    transparent 20px
  );
}
.dossier-photo-redacted-text {
  font-size: 10px;
  letter-spacing: 0.22em;
  color: rgba(196, 158, 232, 0.3);
  text-align: center;
  padding: 1.5rem;
}
.dossier-photo-caption {
  display: block;
  margin-top: 0.4rem;
  font-size: 9px;
  letter-spacing: 0.18em;
  color: rgba(196, 158, 232, 0.7);
  text-transform: uppercase;
}
.dossier-designation {
  padding: 1.2rem 1rem 1rem;
}
.dossier-name {
  font-size: clamp(22px, 5vw, 36px);
  letter-spacing: 0.08em;
  color: #ede0f8;
  margin: 0 0 0.35rem;
  text-shadow: 0 0 28px rgba(196, 158, 232, 0.35);
  line-height: 1.2;
}
.dossier-taxonomy {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(196, 158, 232, 0.85);
  margin: 0 0 0.8rem;
  text-transform: uppercase;
}
.dossier-status-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.dossier-chip {
  font-size: 10px;
  letter-spacing: 0.14em;
  padding: 0.2rem 0.6rem;
  border: 1px solid rgba(237, 224, 248, 0.3);
  color: rgba(237, 224, 248, 0.85);
}
.dossier-chip--threat {
  border-color: var(--threat-color, rgba(196, 158, 232, 0.4));
  color: var(--threat-color, rgba(196, 158, 232, 0.85));
  text-shadow: 0 0 6px var(--threat-color, transparent);
}
.dossier-chip--available { border-color: rgba(125, 255, 110, 0.4); color: rgba(125, 255, 110, 0.85); }
.dossier-chip--sold      { border-color: rgba(237, 224, 248, 0.12); color: rgba(237, 224, 248, 0.35); }
/* ── Compact buy box — laptop/tablet left column (≥1024px, see
   17-responsive.css for the grid split). Renders inline in normal flow
   below 1024px, right after the designation section, so it needs no
   layout rules of its own at mobile widths — just the price styling. ── */
.dossier-buybox {
  padding: 0 1rem 1.2rem;
}
.dossier-buybox-price {
  display: block;
  font-size: 20px;
  letter-spacing: 0.04em;
  color: #ede0f8;
  text-shadow: 0 0 12px rgba(196, 158, 232, 0.4);
}
.dossier-body-section {
  padding: 0.4rem 1rem 0.8rem;
}
.dossier-body-pending {
  font-style: italic;
  color: rgba(237, 224, 248, 0.3) !important;
  letter-spacing: 0.1em;
}
.dossier-body-text {
  font-size: 13px;
  line-height: 1.85;
  color: rgba(237, 224, 248, 0.92);
  /* Public product copy is uppercase throughout — the shop cards
     (.product-sub) and the rest of the CRT shell already were, so the dossier
     field notes were the odd one out. Set on the container rather than per
     element so lists, quotes and h3 come along too; h2 already declares its
     own uppercase and is unaffected.
     Rendering-only: the stored HTML keeps its original casing, so this is
     reversible by deleting one line and nothing is lost in Firestore. */
  text-transform: uppercase;
}
.dossier-body-text p  { margin: 0 0 1em; }
.dossier-body-text p:last-child { margin-bottom: 0; }
.dossier-body-text h2 {
  font-size: 10px;
  letter-spacing: 0.22em;
  color: #c49ee8;
  margin: 1.6em 0 0.5em;
  padding-bottom: 0.3em;
  border-bottom: 1px solid rgba(196, 158, 232, 0.2);
  text-transform: uppercase;
}
.dossier-body-text h3 {
  font-size: 11px;
  letter-spacing: 0.14em;
  color: rgba(196, 158, 232, 0.8);
  margin: 1.2em 0 0.4em;
}
.dossier-body-text strong { color: #ede0f8; }
.dossier-body-text em     { font-style: italic; color: rgba(237, 224, 248, 0.65); }
.dossier-body-text a      { color: #c49ee8; text-decoration: underline; }
.dossier-body-text blockquote {
  border-left: 2px solid rgba(196, 158, 232, 0.35);
  padding: 0.3rem 0.8rem;
  margin: 0.6rem 0;
  color: rgba(237, 224, 248, 0.55);
  font-style: italic;
}
.dossier-acquisition {
  padding: 0.6rem 1rem 1.2rem;
}
.dossier-acq-grid {
  border: 1px solid rgba(196, 158, 232, 0.15);
  background: rgba(107, 53, 160, 0.05);
}
.dossier-acq-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid rgba(196, 158, 232, 0.08);
  font-size: 12px;
}
.dossier-acq-row:last-child { border-bottom: none; }
.dossier-acq-key {
  letter-spacing: 0.12em;
  color: rgba(196, 158, 232, 0.8);
  text-transform: uppercase;
  font-size: 9px;
  white-space: nowrap;
}
.dossier-acq-val { color: #ede0f8; text-align: right; }
.dossier-acq-val--available { color: rgba(125, 255, 110, 0.85); }
.dossier-acq-val--sold      { color: rgba(237, 224, 248, 0.35); }
.dossier-channel-section {
  padding: 0.8rem 1rem 1rem;
}
.dossier-channel-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}
.dossier-channel-btn {
  font-size: 12px;
  letter-spacing: 0.16em;
  color: rgba(125, 255, 110, 0.9);
  background: transparent;
  border: 1px solid rgba(125, 255, 110, 0.35);
  padding: 0.6rem 1.2rem;
  cursor: pointer;
  transition: background 160ms, border-color 160ms;
  font-family: inherit;
  text-transform: uppercase;
}
.dossier-channel-btn:hover {
  background: rgba(125, 255, 110, 0.06);
  border-color: rgba(125, 255, 110, 0.6);
}
.dossier-channel-hint {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.6);
  margin: 0;
}
.dossier-channel {
  border: 1px solid rgba(196, 158, 232, 0.2);
  display: flex;
  flex-direction: column;
}
.dossier-channel-hdr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.5rem 0.8rem;
  font-size: 10px;
  letter-spacing: 0.14em;
  color: rgba(196, 158, 232, 0.85);
  border-bottom: 1px solid rgba(196, 158, 232, 0.15);
  flex-wrap: wrap;
  gap: 0.4rem;
}
.dossier-channel-meta { display: flex; gap: 0.8rem; }
.dossier-channel-messages {
  min-height: 180px;
  height: 38vh;
  max-height: 480px;
}
.dossier-footer {
  margin-top: auto;
  padding: 1rem;
  border-top: 1px solid rgba(196, 158, 232, 0.12);
  font-size: 9px;
  letter-spacing: 0.16em;
  color: rgba(196, 158, 232, 0.3);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  text-transform: uppercase;
}
.dossier-footer-sep { opacity: 0.4; }
/* ── Internal-app additions (back btn, admin edit, acquire) ── */
.dossier-header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.dossier-back-btn {
  font-family: inherit;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.65);
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 0.22rem 0.6rem;
  cursor: pointer;
  transition: color 140ms, border-color 140ms;
}
.dossier-back-btn:hover {
  color: rgba(200, 160, 255, 0.9);
  border-color: rgba(155, 95, 255, 0.45);
}
/* Share button in the compact app bar */
.dossier-meta-share {
  font-family: inherit;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.65);
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 0.2rem 0.55rem;
  cursor: pointer;
  transition: color 140ms, border-color 140ms;
  white-space: nowrap;
}
.dossier-meta-share:hover {
  color: rgba(200, 160, 255, 0.9);
  border-color: rgba(155, 95, 255, 0.45);
}
.dossier-acq-actions {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 1.1rem;
}
/* ── Waitlist capture (sold specimens + sealed dossiers) ──────────────────── */
.waitlist {
  margin-top: 1.1rem;
  padding: 0.9rem 1rem;
  border: 1px solid rgba(155, 95, 255, 0.28);
  background: rgba(20, 11, 36, 0.55);
}
.waitlist--sealed { margin-top: 1rem; }
.waitlist-prompt {
  margin: 0 0 0.7rem;
  font-size: 0.62rem;
  line-height: 1.55;
  letter-spacing: 0.04em;
  color: rgba(214, 186, 255, 0.82);
}
.waitlist-prompt strong { color: rgba(232, 218, 252, 0.98); }
.waitlist-form { display: flex; gap: 0.4rem; }
.waitlist-input {
  flex: 1;
  min-width: 0;
  background: rgba(6, 3, 14, 0.7);
  border: 1px solid rgba(155, 95, 255, 0.35);
  color: rgba(232, 218, 252, 0.96);
  font: inherit;
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  padding: 0.5rem 0.6rem;
}
.waitlist-input:focus-visible { outline: 2px solid rgba(155, 95, 255, 0.75); outline-offset: 1px; }
.waitlist-btn {
  flex: 0 0 auto;
  background: rgba(155, 95, 255, 0.9);
  border: none;
  color: #0c0618;
  font: inherit;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  padding: 0.5rem 0.8rem;
  cursor: pointer;
  transition: background 140ms;
}
.waitlist-btn:hover:not(:disabled) { background: rgba(180, 130, 255, 1); }
.waitlist-btn:disabled { opacity: 0.55; cursor: default; }
.waitlist-done {
  margin: 0;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  color: rgba(120, 255, 172, 0.92);
}
.waitlist-done-sub {
  display: block;
  margin-top: 0.35rem;
  letter-spacing: 0.04em;
  color: rgba(196, 170, 240, 0.72);
  text-transform: none;
}
.waitlist-err {
  margin: 0.4rem 0 0;
  font-size: 0.58rem;
  letter-spacing: 0.06em;
  color: rgba(255, 122, 122, 0.9);
}
@media (prefers-reduced-motion: reduce) { .waitlist-btn { transition: none; } }
.dossier-acquire-btn {
  width: 100%;
  padding: 0.7rem 1.2rem;
  background: rgba(155, 95, 255, 0.1);
  border: 1px solid rgba(155, 95, 255, 0.5);
  color: rgba(210, 178, 255, 0.9);
  font-family: inherit;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms, border-color 140ms, color 140ms;
}
.dossier-acquire-btn:hover:not(:disabled) {
  background: rgba(155, 95, 255, 0.18);
  border-color: rgba(155, 95, 255, 0.75);
  color: #dbbeff;
}
.dossier-acquire-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
/* ── Scroll reveal ── */
.dossier-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.55s ease, transform 0.55s ease;
}
.dossier-reveal--visible {
  opacity: 1;
  transform: translateY(0);
}
@media (max-width: 600px) {
  .dossier-meta-strip      { padding: 0.6rem 0.8rem; gap: 0.8rem 1.4rem; }
  .dossier-rule            { padding: 0 0.8rem; }
  .dossier-photo           { padding: 0.8rem; }
  .dossier-photo--small    { padding: 0.6rem 0.8rem; }
  .dossier-designation     { padding: 1rem 0.8rem; }
  .dossier-body-section    { padding: 0.4rem 0.8rem 0.8rem; }
  .dossier-acquisition     { padding: 0.6rem 0.8rem 1rem; }
  .dossier-channel-section { padding: 0.8rem 0.8rem 1rem; }
  .dossier-footer          { padding: 0.8rem; }
  .dossier-meta-right      { flex-wrap: wrap; }
}
/* ── G.L.O.O.M. panel ───────────────────────────────── */
.glooom-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 32px; /* sit above the narrator bar */
  width: 400px;
  z-index: 499;
  display: flex;
  flex-direction: column;
  background: rgba(5, 2, 16, 0.98);
  border-left: 1px solid rgba(155, 95, 255, 0.6);
  box-shadow: -8px 0 48px rgba(100, 50, 200, 0.28), -3px 0 0 rgba(155, 95, 255, 0.18), inset 1px 0 0 rgba(155, 95, 255, 0.12);
  font-family: "Share Tech Mono", "Courier New", monospace;
  text-transform: uppercase;
  transform: translateX(100%);
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
  overflow: hidden;
}
.glooom-panel--open {
  transform: translateX(0);
  pointer-events: all;
  animation: glooom-flicker 14s ease-in-out infinite;
}
/* CRT power-flicker — dims the panel via brightness instead of opacity, so the
   page never shows through (opacity made the fixed panel see-through). */
@keyframes glooom-flicker {
  0%, 80%, 82.5%, 84%, 92%, 94%, 100% { filter: brightness(1); }
  81%    { filter: brightness(0.72); }  /* deep sudden dip */
  82%    { filter: brightness(0.94); }
  83%    { filter: brightness(0.8); }   /* second dip */
  83.5%  { filter: brightness(1); }
  93%    { filter: brightness(0.96); }  /* faint flutter */
  93.5%  { filter: brightness(1); }
}
@media (prefers-reduced-motion: reduce) {
  .glooom-panel--open { animation: none; }
}
@media (max-width: 600px) {
  .glooom-panel { width: 100%; border-left: none; }
}
.glooom-panel-hdr {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: 0.6rem 1rem 0.5rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.3);
  background: rgba(107, 53, 160, 0.15);
  flex-shrink: 0;
  cursor: pointer;
  user-select: none;
  transition: background 160ms;
}
.glooom-panel-hdr:hover { background: rgba(107, 53, 160, 0.24); }
.glooom-panel-hdr-main {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.glooom-panel-hdr-close {
  margin-left: auto;
  font-size: 10px;
  color: rgba(155, 95, 255, 0.72);
  transition: color 160ms;
}
.glooom-panel-hdr:hover .glooom-panel-hdr-close { color: rgba(218, 195, 248, 1); }
.glooom-panel-hdr-status {
  font-size: 7.5px;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.62);
  padding-left: 0.1rem;
}
.glooom-panel-hdr-brand {
  font-size: 9px;
  letter-spacing: 0.24em;
  color: rgba(255, 140, 55, 0.95);
  text-shadow: 0 0 8px rgba(255, 130, 50, 0.4);
}
.glooom-panel-hdr-sep {
  font-size: 9px;
  color: rgba(155, 95, 255, 0.75);
}
.glooom-panel-hdr-title {
  font-size: 9px;
  letter-spacing: 0.2em;
  color: rgba(218, 195, 248, 0.98);
  text-shadow: 0 0 8px rgba(155, 95, 255, 0.3);
}
.glooom-panel-messages {
  flex: 1;
  overflow-y: auto;
  padding: 0.8rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.25) transparent;
  position: relative;
}
/* CRT scan-line overlay on the message feed */
.glooom-panel-scanlines {
  position: absolute;
  inset: 0;
  background: repeating-linear-gradient(
    0deg,
    transparent,
    transparent 3px,
    rgba(0, 0, 0, 0.07) 3px,
    rgba(0, 0, 0, 0.07) 4px
  );
  pointer-events: none;
  z-index: 10;
}
.glooom-panel-msg {
  font-size: 11px;
  letter-spacing: 0.08em;
  line-height: 1.6;
  animation: glooom-msg-in 180ms ease both;
}
@keyframes glooom-msg-in {
  from { opacity: 0; transform: translateX(6px); }
  to   { opacity: 1; transform: translateX(0); }
}
.glooom-panel-msg--assistant {
  color: rgba(218, 195, 248, 1);
  text-shadow: 0 0 10px rgba(155, 95, 255, 0.45);
}
.glooom-panel-msg--user {
  display: flex;
  flex-direction: column;
  gap: 0.06rem;
  color: rgba(237, 224, 248, 0.95);
}
.glooom-panel-msg-row {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
}
/* Hover timestamp — shown on any chat turn on hover */
.glooom-panel-msg-ts {
  display: block;
  font-size: 7px;
  letter-spacing: 0.16em;
  color: transparent;
  margin-top: 0.08rem;
  transition: color 200ms;
  pointer-events: none;
}
.glooom-panel-msg:hover .glooom-panel-msg-ts {
  color: rgba(155, 95, 255, 0.5);
}
.glooom-panel-msg--streaming {
  min-height: 1em;
}
/* Passive nav/observation entry — amber tint, smaller, visually separated from conversation */
.glooom-panel-msg--nav {
  border-left: 2px solid rgba(255, 140, 55, 0.55);
  padding: 0.3rem 0.6rem;
  color: rgba(255, 190, 105, 0.95);
  font-size: 9px;
  line-height: 1.55;
  letter-spacing: 0.06em;
  text-shadow: 0 0 8px rgba(255, 130, 50, 0.3);
}
.glooom-panel-nav-label {
  display: block;
  font-size: 7.5px;
  letter-spacing: 0.22em;
  color: rgba(255, 140, 55, 0.75);
  margin-bottom: 0.2rem;
}
.glooom-panel-nav-ts {
  color: rgba(255, 140, 55, 0.52);
  letter-spacing: 0.12em;
}
.glooom-panel-prompt {
  color: rgba(255, 130, 50, 0.9);
  flex-shrink: 0;
}
.glooom-panel-input-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 1rem;
  border-top: 1px solid rgba(155, 95, 255, 0.3);
  flex-shrink: 0;
}
.glooom-panel-input {
  flex: 1;
  background: none;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 1);
  text-transform: uppercase;
  min-width: 0;
}
.glooom-panel-input::placeholder {
  color: rgba(196, 158, 232, 0.52);
  text-transform: none;
}
.glooom-panel-send {
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.58);
  color: rgba(210, 178, 255, 0.92);
  font-family: inherit;
  font-size: 9px;
  letter-spacing: 0.2em;
  padding: 0.28rem 0.65rem;
  cursor: pointer;
  text-transform: uppercase;
  transition: border-color 160ms, color 160ms;
  flex-shrink: 0;
}
.glooom-panel-send:hover:not(:disabled) {
  border-color: rgba(155, 95, 255, 0.9);
  color: rgba(218, 195, 248, 1);
}
.glooom-panel-send:disabled { opacity: 0.3; cursor: not-allowed; }
/* ── G.L.O.O.M. narrator bar ────────────────────────── */
.glooom-narrator {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 500;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.3rem 1rem;
  min-height: 32px;
  background: rgba(5, 2, 16, 0.97);
  border-top: 1px solid rgba(155, 95, 255, 0.32);
  font-size: 9px;
  letter-spacing: 0.14em;
  font-family: "Share Tech Mono", "Courier New", monospace;
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity 600ms ease, border-color 200ms ease;
  user-select: none;
}
.glooom-narrator:hover { border-top-color: rgba(155, 95, 255, 0.5); }
.glooom-narrator--idle { opacity: 0.65; }
.glooom-narrator--open {
  opacity: 1;
  border-top-color: rgba(155, 95, 255, 0.45);
}
.glooom-narrator-prefix {
  color: rgba(255, 145, 60, 0.98);
  flex-shrink: 0;
  text-shadow: 0 0 10px rgba(255, 130, 50, 0.5);
}
.glooom-narrator-sep {
  color: rgba(155, 95, 255, 0.7);
  flex-shrink: 0;
}
.glooom-narrator-msg {
  color: rgba(218, 195, 248, 0.95);
  flex: 1;
  min-width: 0;
  text-shadow: 0 0 8px rgba(155, 95, 255, 0.3);
}
.glooom-narrator-toggle {
  color: rgba(155, 95, 255, 0.72);
  font-size: 8px;
  flex-shrink: 0;
  margin-left: auto;
}
.glooom-narrator-cursor {
  width: 0.45em;
  height: 0.8em;
  flex-shrink: 0;
  background: rgba(196, 158, 232, 0.6);
}
/* Pulsing amber dot when new entries have arrived while the panel is closed */
.glooom-narrator--unread {
  border-top-color: rgba(255, 130, 50, 0.3);
}
.glooom-narrator-unread-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(255, 130, 50, 0.8);
  flex-shrink: 0;
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
}
@keyframes glooom-unread-pulse {
  0%, 100% { opacity: 0.8; transform: scale(1); }
  50%       { opacity: 0.3; transform: scale(0.6); }
}
/* push page content above the narrator bar */
.crt-page { padding-bottom: 56px; }
/* ── G.L.O.O.M. system strip (dossier) ──────────────── */
.glooom-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem 2rem;
  padding: 0.45rem 1rem;
  border-bottom: 1px solid rgba(255, 130, 50, 0.15);
  background: rgba(30, 12, 4, 0.55);
}
.glooom-strip-brand {
  width: 100%;
  font-size: 8px;
  letter-spacing: 0.2em;
  color: rgba(255, 130, 50, 0.55);
  padding-bottom: 0.25rem;
  border-bottom: 1px solid rgba(255, 130, 50, 0.1);
  margin-bottom: 0.15rem;
}
.glooom-strip-item {
  display: flex;
  flex-direction: column;
  gap: 0.08rem;
}
.glooom-strip-label {
  font-size: 8px;
  letter-spacing: 0.18em;
  color: rgba(196, 158, 232, 0.45);
}
.glooom-strip-val {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: rgba(237, 224, 248, 0.75);
}
.glooom-strip-val--ok     { color: rgba(125, 255, 110, 0.8); }
.glooom-strip-val--warn   { color: rgba(255, 150, 50, 0.85); }
.glooom-strip-val--danger { color: rgba(255, 74, 110, 0.85); }
/* ── G.L.O.O.M. 404 page ────────────────────────────── */
.glooom-404-panel {
  position: relative;
  overflow: hidden;
  justify-content: center;
  align-items: flex-start;
}
.glooom-404-inner {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  padding: 3rem 2rem 2rem;
  max-width: 520px;
  width: 100%;
}
.glooom-404-brand {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.26em;
  color: rgba(255, 130, 50, 0.75);
}
.glooom-404-brand-sub {
  margin: 0;
  font-size: 8px;
  letter-spacing: 0.18em;
  color: rgba(255, 130, 50, 0.4);
}
.glooom-404-rule {
  width: 100%;
  height: 1px;
  background: rgba(155, 95, 255, 0.2);
  margin: 0.6rem 0;
}
.glooom-404-code {
  margin: 0;
  font-size: clamp(0.7rem, 2.2vw, 0.95rem);
  letter-spacing: 0.12em;
  color: rgba(226, 207, 255, 0.92);
  text-shadow:
    -1px 0 rgba(255, 30, 100, 0.4),
    1px 0 rgba(80, 0, 255, 0.4);
}
.glooom-404-causes {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.glooom-404-causes-hdr {
  margin: 0 0 0.2rem;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: rgba(196, 158, 232, 0.5);
}
.glooom-404-cause {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: rgba(196, 158, 232, 0.8);
}
.glooom-404-cause--unsettling {
  color: rgba(255, 74, 110, 0.8);
  animation: text-flicker 4s 1.8s ease-in-out infinite;
}
.glooom-404-recovery-log {
  margin-top: 1.4rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-height: 5.5rem;
}
.glooom-404-recovery-line {
  margin: 0;
  font-size: 10px;
  letter-spacing: 0.14em;
  color: rgba(196, 158, 232, 0.6);
  animation: boot-line-in 60ms ease both;
}
.glooom-404-recovery-line--warn {
  color: rgba(255, 130, 50, 0.75);
}
.glooom-404-return {
  margin-top: 1.4rem;
  padding: 0.42rem 1rem;
  border: 1px solid rgba(155, 95, 255, 0.3);
  color: rgba(210, 178, 255, 0.85);
  text-decoration: none;
  font-size: 10px;
  letter-spacing: 0.14em;
  font-family: inherit;
  text-transform: uppercase;
  transition: border-color 160ms ease, color 160ms ease;
}
.glooom-404-return:hover {
  border-color: rgba(155, 95, 255, 0.85);
  color: #dbbeff;
}
@media (max-width: 600px) {
  .glooom-strip        { padding: 0.4rem 0.8rem; gap: 0.4rem 1.4rem; }
  .glooom-404-inner    { padding: 2rem 1.2rem 1.5rem; }
}
/* ── G.L.O.O.M. drawer tab bar ──────────────────────── */
.glooom-panel-tabs {
  display: flex;
  flex-shrink: 0;
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  background: rgba(5, 2, 16, 0.6);
}
.glooom-panel-tab {
  flex: 1;
  padding: 0.45rem 0;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  color: rgba(155, 95, 255, 0.62);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 160ms, border-color 160ms;
}
.glooom-panel-tab:hover {
  color: rgba(210, 178, 255, 0.88);
}
.glooom-panel-tab--active {
  color: rgba(226, 207, 255, 1);
  border-bottom-color: rgba(155, 95, 255, 0.85);
  text-shadow: 0 0 10px rgba(155, 95, 255, 0.45);
}
/* ── Specimen channel pane (CHANNELS tab) ───────────── */
/* Auth / empty / loading states */
.glooom-ch-auth,
.glooom-ch-empty {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 2rem 1rem;
}
.glooom-ch-state {
  margin: 0;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: rgba(155, 95, 255, 0.72);
  text-align: center;
}
.glooom-ch-state--closed {
  color: rgba(255, 74, 110, 0.75);
}
.glooom-ch-state-sub {
  margin: 0;
  font-size: 9px;
  letter-spacing: 0.1em;
  color: rgba(155, 95, 255, 0.52);
  text-align: center;
  text-transform: none;
}
/* Channel list */
.glooom-ch-list {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.2) transparent;
}
.glooom-ch-list-item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.7rem 1.1rem 0.7rem 1rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.1);
  cursor: pointer;
  transition: background 140ms;
}
.glooom-ch-list-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(155, 95, 255, 0.85);
  position: absolute;
  right: 1.6rem;
  top: 0.9rem;
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
  box-shadow: 0 0 6px rgba(155, 95, 255, 0.6);
}
.glooom-ch-list-item:hover {
  background: rgba(107, 53, 160, 0.14);
}
.glooom-ch-list-name {
  font-size: 11px;
  letter-spacing: 0.1em;
  color: rgba(226, 207, 255, 0.98);
}
.glooom-ch-list-meta {
  font-size: 9px;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.68);
}
.glooom-ch-list-arrow {
  position: absolute;
  right: 1rem;
  top: 50%;
  transform: translateY(-50%);
  font-size: 8px;
  color: rgba(155, 95, 255, 0.52);
  transition: color 140ms, transform 140ms;
}
.glooom-ch-list-item:hover .glooom-ch-list-arrow {
  color: rgba(155, 95, 255, 0.88);
  transform: translateY(-50%) translateX(2px);
}
/* Specimen conversation view */
.glooom-specimen-channel {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.glooom-specimen-hdr {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.45rem 0.75rem 0.45rem 0.6rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.18);
  background: rgba(107, 53, 160, 0.1);
}
.glooom-specimen-back {
  background: none;
  border: none;
  color: rgba(155, 95, 255, 0.78);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 8px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
  flex-shrink: 0;
  transition: color 140ms;
}
.glooom-specimen-back:hover { color: rgba(218, 195, 248, 1); }
.glooom-specimen-hdr-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.05rem;
  min-width: 0;
  overflow: hidden;
}
.glooom-specimen-name {
  font-size: 10px;
  letter-spacing: 0.1em;
  color: rgba(226, 207, 255, 0.9);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.glooom-specimen-sku {
  font-size: 8px;
  letter-spacing: 0.14em;
  color: rgba(155, 95, 255, 0.65);
}
.glooom-specimen-hdr-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.1rem;
  flex-shrink: 0;
  font-size: 8px;
  letter-spacing: 0.12em;
  color: rgba(155, 95, 255, 0.65);
}
.glooom-specimen-messages {
  flex: 1;
  overflow-y: auto;
  padding: 0.75rem 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 255, 0.2) transparent;
  position: relative;
}
.glooom-specimen-input-row {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.75rem;
  border-top: 1px solid rgba(155, 95, 255, 0.15);
  background: rgba(5, 2, 16, 0.6);
}
.glooom-specimen-input {
  flex: 1;
  background: none;
  border: none;
  border-bottom: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(226, 207, 255, 0.9);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.2rem 0.3rem;
  outline: none;
  transition: border-color 160ms;
}
.glooom-specimen-input:focus {
  border-bottom-color: rgba(155, 95, 255, 0.6);
}
.glooom-specimen-input::placeholder {
  color: rgba(155, 95, 255, 0.48);
  text-transform: uppercase;
}
.glooom-specimen-send {
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.48);
  color: rgba(210, 178, 255, 0.92);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 8px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
  transition: border-color 160ms, color 160ms;
  flex-shrink: 0;
}
.glooom-specimen-send:hover:not(:disabled) {
  border-color: rgba(155, 95, 255, 0.88);
  color: rgba(226, 207, 255, 1);
}
.glooom-specimen-send:disabled { opacity: 0.3; cursor: not-allowed; }
/* ── Jump-to-latest button ──────────────────────────── */
.glooom-panel-jump {
  flex-shrink: 0;
  align-self: center;
  margin: 0.3rem auto;
  padding: 0.22rem 0.75rem;
  background: rgba(107, 53, 160, 0.2);
  border: 1px solid rgba(155, 95, 255, 0.45);
  color: rgba(210, 178, 255, 0.9);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 8px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 140ms, border-color 140ms, color 140ms;
  animation: glooom-msg-in 160ms ease both;
}
.glooom-panel-jump:hover {
  background: rgba(107, 53, 160, 0.38);
  border-color: rgba(155, 95, 255, 0.8);
  color: rgba(226, 207, 255, 1);
}
/* ── New session link ────────────────────────────────── */
.glooom-panel-new-session {
  flex-shrink: 0;
  display: block;
  width: 100%;
  padding: 0.3rem 1rem;
  background: none;
  border: none;
  border-top: 1px solid rgba(155, 95, 255, 0.08);
  color: rgba(155, 95, 255, 0.35);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: 7.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-align: left;
  cursor: pointer;
  transition: color 160ms, border-color 160ms;
}
.glooom-panel-new-session:hover {
  color: rgba(255, 74, 110, 0.65);
  border-top-color: rgba(255, 74, 110, 0.15);
}
/* ── Channels tab activity dot ──────────────────────── */
.glooom-tab-dot {
  display: inline-block;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: rgba(155, 95, 255, 0.85);
  vertical-align: middle;
  margin-left: 0.4em;
  position: relative;
  top: -1px;
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
  box-shadow: 0 0 6px rgba(155, 95, 255, 0.6);
}
.glooom-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 14px;
  height: 14px;
  padding: 0 0.3em;
  margin-left: 0.4em;
  border-radius: 999px;
  background: rgba(155, 95, 255, 0.9);
  color: #fff;
  font-size: 8px;
  line-height: 1;
  vertical-align: middle;
  position: relative;
  top: -1px;
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
  box-shadow: 0 0 6px rgba(155, 95, 255, 0.6);
}
/* ── Admin: management hub ────────────────────────────── */
.admin-hub {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 0.7rem;
  width: 100%;
  max-width: 900px;
  margin: 0 auto 1.6rem;
}
.admin-hub-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.85rem 0.9rem;
  background: rgba(12, 6, 24, 0.6);
  border: 1px solid rgba(155, 95, 255, 0.22);
  text-decoration: none;
  transition: border-color 160ms ease, transform 160ms ease, background 160ms ease;
}
.admin-hub-card:hover {
  border-color: rgba(155, 95, 255, 0.6);
  background: rgba(107, 53, 160, 0.16);
  transform: translateY(-2px);
}
.admin-hub-card-title {
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: rgba(226, 207, 255, 0.96);
}
.admin-hub-card-meta {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.6);
}
/* ── Admin: product manager list ──────────────────────── */
.adm-prod-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 100%;
  max-width: 900px;
  margin: 1rem auto 0;
}
.adm-prod-row {
  display: grid;
  grid-template-columns: 48px 1fr auto auto;
  align-items: center;
  gap: 0.8rem;
  padding: 0.55rem 0.7rem;
  background: rgba(12, 6, 24, 0.55);
  border: 1px solid rgba(155, 95, 255, 0.16);
  transition: opacity 160ms ease;
}
.adm-prod-row--busy { opacity: 0.5; pointer-events: none; }
.adm-prod-thumb {
  width: 48px;
  height: 48px;
  background: #0a0518;
  border: 1px solid rgba(155, 95, 255, 0.18);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.adm-prod-thumb img { width: 100%; height: 100%; object-fit: cover; }
.adm-prod-thumb-empty { color: rgba(155, 95, 255, 0.4); font-size: 0.8rem; }
.adm-prod-main {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.adm-prod-name {
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  color: rgba(232, 218, 252, 0.96);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.adm-prod-meta {
  font-size: 0.52rem;
  letter-spacing: 0.08em;
  color: rgba(155, 95, 255, 0.6);
}
.adm-prod-stock {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
}
.adm-prod-badge {
  font-size: 0.46rem;
  letter-spacing: 0.14em;
  padding: 0.12rem 0.4rem;
  border: 1px solid currentColor;
  white-space: nowrap;
}
.adm-prod-badge--available { color: rgba(120, 255, 172, 0.85); }
.adm-prod-badge--low       { color: rgba(255, 200, 80, 0.9); }
.adm-prod-badge--out,
.adm-prod-badge--sold      { color: rgba(255, 90, 90, 0.85); }
.adm-prod-stepper {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.adm-prod-stepper button {
  width: 1.4rem;
  height: 1.4rem;
  background: rgba(107, 53, 160, 0.18);
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(226, 207, 255, 0.9);
  font-size: 0.8rem;
  line-height: 1;
  cursor: pointer;
  transition: background 140ms;
}
.adm-prod-stepper button:hover:not(:disabled) { background: rgba(107, 53, 160, 0.4); }
.adm-prod-stepper button:disabled { opacity: 0.3; cursor: not-allowed; }
.adm-prod-stock-num { min-width: 1.4rem; text-align: center; font-size: 0.7rem; color: rgba(232, 218, 252, 0.95); }
.adm-prod-toggle {
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(196, 158, 232, 0.85);
  font-family: inherit;
  font-size: 0.48rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.22rem 0.45rem;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 140ms, color 140ms;
}
.adm-prod-toggle:hover { border-color: rgba(155, 95, 255, 0.8); color: rgba(226, 207, 255, 1); }
.adm-prod-actions { display: flex; gap: 0.35rem; }
@media (max-width: 600px) {
  .adm-prod-row {
    grid-template-columns: 40px 1fr;
    grid-template-areas:
      "thumb main"
      "stock stock"
      "actions actions";
    row-gap: 0.5rem;
  }
  .adm-prod-thumb { grid-area: thumb; width: 40px; height: 40px; }
  .adm-prod-main { grid-area: main; }
  .adm-prod-stock { grid-area: stock; flex-direction: row; align-items: center; justify-content: space-between; }
  .adm-prod-actions { grid-area: actions; }
}
/* ── Cart quantity controls ───────────────────────────── */
.cart-qty {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.35rem;
}
.cart-qty-btn {
  width: 1.5rem;
  height: 1.5rem;
  background: rgba(107, 53, 160, 0.18);
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(226, 207, 255, 0.92);
  font-size: 0.9rem;
  line-height: 1;
  cursor: pointer;
  transition: background 140ms;
}
.cart-qty-btn:hover:not(:disabled) { background: rgba(107, 53, 160, 0.4); }
.cart-qty-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.cart-qty-num { min-width: 1.5rem; text-align: center; font-size: 0.78rem; color: rgba(232, 218, 252, 0.96); }
/* ── Checkout ─────────────────────────────────────────── */
.checkout-page { align-items: stretch; }
.checkout-layout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 1.5rem;
  width: 100%;
  max-width: 900px;
  margin: 0.5rem auto 0;
  align-items: start;
}
/* Numbered section headers (01 CONTACT / 02 ADDRESS / 03 DELIVERY) with a
   trailing rule — echoes the acquisition-steps strip at the top. */
.checkout-section-label {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 1.1rem 0 0.8rem;
  color: rgba(120, 255, 172, 0.8);
  letter-spacing: 0.18em;
  text-align: left;
  white-space: nowrap;
}
.checkout-form .checkout-section-label:first-of-type { margin-top: 0; }
.checkout-section-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, rgba(155, 95, 255, 0.3), transparent);
}
/* Left-align the form for scannability (the panel otherwise centers text) */
.checkout-form { text-align: left; }
.checkout-form .admin-label { text-align: left; justify-content: flex-start; }
.checkout-postcode { text-transform: uppercase; }
/* Delivery options embedded in the form — roomier hit targets */
.checkout-ship--form { margin: 0 0 0.4rem; }
.checkout-ship--form .checkout-ship-opt { padding: 0.55rem 0.65rem; }
.checkout-form {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.checkout-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.7rem;
}
.checkout-pay-btn { margin-top: 0.6rem; }
.checkout-summary {
  background: rgba(12, 6, 24, 0.55);
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 1rem;
  position: sticky;
  top: 1rem;
}
.checkout-summary-items { display: flex; flex-direction: column; gap: 0.5rem; }
.checkout-summary-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  color: rgba(214, 198, 240, 0.9);
}
.checkout-summary-thumb {
  width: 34px;
  height: 34px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid rgba(155, 95, 255, 0.25);
  background: #0a0616;
}
.checkout-summary-name { flex: 1; min-width: 0; }
/* ── Acquisition steps strip (01 DETAILS → 02 PAYMENT → 03 CONFIRMED) ── */
.checkout-steps {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0;
  margin: 0 0 1.1rem;
  padding: 0;
  font-size: 0.58rem;
  letter-spacing: 0.16em;
}
.checkout-steps--center { justify-content: center; margin-bottom: 0.4rem; }
.checkout-step {
  color: rgba(155, 95, 255, 0.45);
  white-space: nowrap;
}
.checkout-step:not(:last-child)::after {
  content: "▸";
  margin: 0 0.6rem;
  color: rgba(155, 95, 255, 0.3);
}
.checkout-step--active {
  color: rgba(120, 255, 172, 0.95);
  text-shadow: 0 0 10px rgba(120, 255, 172, 0.35);
}
/* ── Guest → account upsell on the order confirmation ── */
.order-upsell {
  width: 100%;
  max-width: 400px;
  margin: 0.5rem 0 0.7rem;
  padding: 0.9rem 1rem 1rem;
  border: 1px solid rgba(120, 255, 172, 0.35);
  background: rgba(120, 255, 172, 0.05);
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  text-align: left;
}
.order-upsell--done { border-color: rgba(120, 255, 172, 0.5); align-items: center; text-align: center; }
.order-upsell-title {
  margin: 0;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  color: rgba(120, 255, 172, 0.95);
}
.order-upsell-sub {
  margin: 0;
  font-size: 0.62rem;
  line-height: 1.55;
  color: rgba(214, 198, 240, 0.8);
}
.order-upsell-fields { display: flex; flex-direction: column; gap: 0.45rem; }
/* ── Payment step — embedded SumUp card widget ── */
.checkout-pay-shipto {
  font-size: 0.62rem;
  line-height: 1.5;
  letter-spacing: 0.03em;
  color: rgba(214, 198, 240, 0.7);
  margin: 0 0 0.9rem;
}
.sumup-widget-wrap { margin: 0.2rem 0 0.8rem; }
/* SumUp renders a light card form into #sumup-card; give it a calm plate that
   sits on the dark theme, and reserve height so the loading state doesn't jump. */
.sumup-widget {
  /* Floor near the card-form's natural height so the container doesn't visibly
     collapse when the widget briefly shrinks just before a 3DS redirect. */
  min-height: 280px;
  background: #f4f1ea;
  border: 1px solid rgba(155, 95, 255, 0.35);
  border-radius: 4px;
  padding: 0.6rem;
}
.sumup-widget:empty { display: none; }
.sumup-widget-wrap:has(.sumup-widget:empty) .checkout-ship-state { margin: 0.6rem 0; }
/* ── Trust signals under the pay button ── */
.checkout-trust {
  margin-top: 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.checkout-trust-line {
  margin: 0;
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  color: rgba(120, 255, 172, 0.75);
}
.checkout-trust-line--dim { color: rgba(214, 198, 240, 0.55); letter-spacing: 0.06em; text-transform: none; }
.checkout-trust-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}
.checkout-trust-badges span {
  font-size: 0.5rem;
  letter-spacing: 0.1em;
  padding: 0.16rem 0.4rem;
  border: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(214, 198, 240, 0.6);
  white-space: nowrap;
}
.checkout-summary-name { line-height: 1.4; }
.checkout-summary-price { white-space: nowrap; color: rgba(232, 218, 252, 0.95); }
.checkout-summary-warn { color: rgba(255, 150, 80, 0.9); font-size: 0.52rem; letter-spacing: 0.1em; }
.checkout-summary-rule { height: 1px; background: rgba(155, 95, 255, 0.18); margin: 0.8rem 0; }
.checkout-summary-row {
  display: flex;
  justify-content: space-between;
  font-size: 0.62rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(196, 158, 232, 0.85);
  margin-bottom: 0.35rem;
}
.checkout-summary-total {
  font-size: 0.82rem;
  color: rgba(232, 218, 252, 0.98);
  margin-bottom: 0;
}
.checkout-confirm {
  max-width: 480px;
  margin: 2rem auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.6rem;
}
.checkout-confirm-ref {
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.7);
}
.checkout-confirm-text {
  font-size: 0.72rem;
  line-height: 1.6;
  color: rgba(214, 198, 240, 0.85);
  margin-bottom: 0.6rem;
}
@media (max-width: 760px) {
  .checkout-layout { grid-template-columns: 1fr; }
  .checkout-summary { position: static; order: -1; }
}
/* ── Order return / confirmation page (/order/complete) ────────── */
.order-complete-title {
  font-size: clamp(1rem, 2.6vw, 1.6rem);
  margin: 0.25rem 0 0.1rem;
}
.order-complete-badge {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  padding: 0.3rem 0.75rem;
  border: 1px solid currentColor;
  border-radius: 2px;
}
.order-complete-badge--ok   { color: rgba(120, 255, 172, 0.9); }
.order-complete-lines {
  width: 100%;
  max-width: 380px;
  margin: 0.4rem 0 0.2rem;
  border: 1px solid rgba(155, 95, 255, 0.2);
  padding: 0.55rem 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.order-complete-line {
  display: flex;
  justify-content: space-between;
  gap: 0.8rem;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: rgba(214, 198, 240, 0.9);
}
.order-complete-line--meta { color: rgba(155, 95, 255, 0.75); font-size: 0.6rem; }
.order-complete-line-price { white-space: nowrap; }
.order-complete-badge--wait { color: rgba(255, 200, 80, 0.9); animation: order-pulse 1.4s ease-in-out infinite; }
.order-complete-badge--fail { color: rgba(255, 90, 90, 0.9); }
@keyframes order-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.45; } }
/* ── Admin: settings payment status ───────────────────── */
.admin-pay-status {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  margin: 0;
}
.admin-pay-status--on  { color: rgba(120, 255, 172, 0.9); }
.admin-pay-status--off { color: rgba(255, 200, 80, 0.9); }
/* ── Admin: orders ────────────────────────────────────── */
.adm-order-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  width: 100%;
  max-width: 900px;
  margin: 0 auto 1rem;
}
.adm-order-filter {
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(196, 158, 232, 0.7);
  font-family: inherit;
  font-size: 0.46rem;
  letter-spacing: 0.12em;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
  transition: border-color 140ms, color 140ms;
}
.adm-order-filter--active,
.adm-order-filter:hover {
  border-color: rgba(155, 95, 255, 0.7);
  color: rgba(226, 207, 255, 0.98);
}
.adm-order-list {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}
.adm-order-card {
  background: rgba(12, 6, 24, 0.55);
  border: 1px solid rgba(155, 95, 255, 0.18);
  padding: 0.8rem 0.9rem;
}
.adm-order-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.12);
}
.adm-order-ref { font-size: 0.6rem; letter-spacing: 0.06em; color: rgba(232, 218, 252, 0.95); }
.adm-order-date { font-size: 0.5rem; letter-spacing: 0.1em; color: rgba(155, 95, 255, 0.6); margin-left: 0.6rem; }
.adm-order-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  padding: 0.7rem 0;
}
.adm-order-col { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.adm-order-label {
  font-size: 0.46rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.6);
  margin-bottom: 0.15rem;
}
.adm-order-item { font-size: 0.6rem; letter-spacing: 0.02em; color: rgba(214, 198, 240, 0.88); line-height: 1.4; }
.adm-order-totals { font-size: 0.58rem; color: rgba(196, 158, 232, 0.9); margin-top: 0.3rem; }
.adm-order-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid rgba(155, 95, 255, 0.12);
}
.adm-order-select { width: auto; min-width: 160px; }
@media (max-width: 600px) {
  .adm-order-body { grid-template-columns: 1fr; }
}
/* ── Info / policy pages ──────────────────────────────── */
.info-page {
  align-items: stretch;
  justify-content: flex-start;
  text-align: left;
  padding: 1.4rem clamp(1rem, 4vw, 2.2rem) 2.5rem;
}
.info-header {
  max-width: 720px;
  margin: 0 auto 1.4rem;
  width: 100%;
  border-bottom: 1px solid rgba(155, 95, 255, 0.2);
  padding-bottom: 1rem;
}
.info-kicker {
  margin: 0 0 0.4rem;
  font-size: 0.56rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.72);
}
.info-title {
  margin: 0;
  font-size: clamp(1.4rem, 4.5vw, 2.1rem);
  letter-spacing: 0.04em;
  color: rgba(232, 218, 252, 0.98);
  text-shadow: 0 0 16px rgba(155, 95, 255, 0.3);
}
.info-intro {
  margin: 0.7rem 0 0;
  font-size: 0.78rem;
  letter-spacing: 0.02em;
  color: rgba(206, 186, 240, 0.85);
}
.info-body {
  max-width: 720px;
  margin: 0 auto;
  width: 100%;
  font-size: 0.82rem;
  line-height: 1.8;
  color: rgba(214, 198, 240, 0.92);
  letter-spacing: 0.01em;
}
.info-body h2 {
  margin: 1.8rem 0 0.6rem;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(196, 158, 232, 0.95);
}
.info-body p { margin: 0 0 1rem; }
.info-body ul { margin: 0 0 1rem; padding-left: 1.1rem; }
.info-body li { margin-bottom: 0.45rem; }
.info-body a { color: rgba(176, 130, 255, 0.95); text-decoration: underline; }
.info-body a:hover { color: rgba(216, 186, 255, 1); }
.info-body strong { color: rgba(232, 218, 252, 0.98); }
.info-note {
  margin-top: 1.6rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(155, 95, 255, 0.15);
  font-size: 0.74rem;
  color: rgba(196, 158, 232, 0.78);
}
.faq-list { display: flex; flex-direction: column; gap: 1.3rem; }
.faq-item { }
.faq-q {
  margin: 0 0 0.4rem;
  font-size: 0.86rem;
  letter-spacing: 0.02em;
  text-transform: none;
  color: rgba(226, 207, 255, 0.96);
}
.faq-a { margin: 0; color: rgba(206, 186, 240, 0.88); }
/* ── Global site footer (compact 3-zone) ──────────────── */
.site-footer {
  width: 100%;
  flex-shrink: 0;
  background: linear-gradient(180deg, rgba(8, 4, 18, 0) 0%, rgba(8, 4, 18, 0.6) 28%, rgba(6, 3, 14, 0.92) 100%);
  border-top: var(--line-soft);
  padding: 1.3rem clamp(1rem, 4vw, 2.4rem) 0;
}
/* Zone 1 — brand (left) + inline newsletter (right) */
.site-footer-top {
  max-width: 980px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.9rem 2rem;
}
.site-footer-brandcol { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.site-footer-brand {
  font-size: 0.95rem;
  letter-spacing: 0.14em;
  color: var(--ink-strong);
  text-shadow: 0 0 12px rgba(var(--violet-3), 0.3);
}
.site-footer-tagline {
  margin: 0;
  font-size: var(--fs-caption);
  line-height: 1.5;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
}
.site-footer-news { display: flex; flex-direction: column; gap: 0.3rem; min-width: 260px; }
.site-footer-news-form { display: flex; gap: 0.35rem; }
.site-footer-news-input {
  flex: 1;
  min-width: 190px;
  background: rgba(var(--violet-3), 0.06);
  border: 1px solid rgba(var(--violet-3), 0.3);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-caption);
  padding: 0.4rem 0.55rem;
  outline: none;
  transition: border-color var(--dur-fast) var(--ease);
}
.site-footer-news-input:focus { border-color: rgba(var(--violet-3), 0.65); }
.site-footer-news-input::placeholder { color: rgba(var(--violet-2), 0.4); }
.site-footer-news-btn {
  background: rgba(var(--violet-3), 0.16);
  border: 1px solid rgba(var(--violet-3), 0.45);
  color: var(--ink-strong);
  font-family: inherit;
  font-size: var(--fs-caption);
  letter-spacing: 0.14em;
  padding: 0 0.9rem;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
}
.site-footer-news-btn:hover:not(:disabled) { background: rgba(var(--violet-3), 0.3); box-shadow: 0 0 14px rgba(var(--violet-3), 0.25); }
.site-footer-news-done { font-size: var(--fs-caption); letter-spacing: 0.12em; color: rgba(var(--toxic), 0.85); margin: 0; }
.site-footer-news-err  { font-size: var(--fs-caption); color: rgba(var(--blood), 0.85); margin: 0; }
/* Zone 2 — one wrapping, ·-separated link row (no column headings) */
.site-footer-links {
  max-width: 980px;
  margin: 1rem auto 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.1rem;
  align-items: center;
}
.site-footer-link {
  position: relative;
  font-size: var(--fs-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}
.site-footer-link:hover { color: var(--ink-strong); }
.site-footer-link:not(:last-child)::after {
  content: "·";
  position: absolute;
  right: -0.62rem;
  color: rgba(var(--violet-3), 0.4);
}
/* Zone 3 — legal bar: © · social · privacy/terms */
.site-footer-bar {
  max-width: 980px;
  margin: 1rem auto 0;
  border-top: 1px solid rgba(var(--violet-3), 0.12);
  /* Bottom padding clears the fixed G.L.O.O.M. narrator bar (min 32px + its
     padding), which otherwise covers the Privacy/Terms line on every page. */
  padding: 0.8rem 0 calc(2.6rem + env(safe-area-inset-bottom, 0px));
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem 1.2rem;
  font-size: var(--fs-caption);
  letter-spacing: 0.1em;
  color: var(--ink-faint);
}
.site-footer-social { display: flex; gap: 1rem; }
.site-footer-social a { color: rgba(var(--violet-2), 0.8); text-decoration: none; transition: color var(--dur-fast) var(--ease); }
.site-footer-social a:hover { color: var(--ink-strong); }
.site-footer-bar-links { display: flex; gap: 0.5rem; align-items: center; }
.site-footer-bar-links a { color: var(--ink-faint); text-decoration: none; }
.site-footer-bar-links a:hover { color: var(--ink-strong); }
@media (max-width: 560px) {
  .site-footer-top { flex-direction: column; align-items: stretch; gap: 0.7rem; }
  .site-footer-news-input { min-width: 0; }
  .site-footer-bar { justify-content: center; text-align: center; }
}
/* ── The Claimed (sold archive) ───────────────────────── */
.claimed-page { align-items: stretch; justify-content: flex-start; text-align: left; padding: 1.4rem clamp(1rem, 4vw, 2.2rem) 2.5rem; }
.claimed-header { max-width: 900px; margin: 0 auto 1.2rem; width: 100%; }
.claimed-count {
  max-width: 900px; margin: 0 auto 1.1rem; width: 100%;
  font-size: 0.58rem; letter-spacing: 0.2em; text-transform: uppercase; color: rgba(255, 90, 90, 0.7);
}
.claimed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: clamp(0.7rem, 2vw, 1.2rem);
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
}
.claimed-card { display: flex; flex-direction: column; gap: 0.3rem; }
.claimed-card-plate {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #0a0518;
  border: 1px solid rgba(155, 95, 255, 0.16);
}
.claimed-card-plate img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(0.55) brightness(0.6) contrast(1.05);
}
.claimed-card-noimg { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; font-size: 0.5rem; letter-spacing: 0.16em; color: rgba(155, 95, 255, 0.4); }
.claimed-card-stamp {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-12deg);
  border: 2px solid rgba(255, 70, 70, 0.7);
  color: rgba(255, 90, 90, 0.85);
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  padding: 0.18rem 0.6rem;
  text-shadow: 0 0 8px rgba(255, 60, 60, 0.5);
  pointer-events: none;
}
.claimed-card-name { font-size: 0.68rem; letter-spacing: 0.04em; color: rgba(206, 186, 240, 0.8); }
.claimed-card-sku  { font-size: 0.5rem; letter-spacing: 0.1em; color: rgba(155, 95, 255, 0.5); }
.claimed-empty, .claimed-footer-cta { max-width: 900px; margin: 1.5rem auto 0; width: 100%; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0.8rem; }
.claimed-footer-cta { margin-top: 2.2rem; padding-top: 1.4rem; border-top: 1px solid rgba(155, 95, 255, 0.14); }
.claimed-footer-text { font-size: 0.7rem; color: rgba(196, 170, 240, 0.7); margin: 0; }
.claimed-cta {
  display: inline-block;
  padding: 0.5rem 1.1rem;
  border: 1px solid rgba(155, 95, 255, 0.45);
  color: rgba(218, 195, 248, 0.92);
  text-decoration: none;
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  transition: border-color 160ms, color 160ms;
}
.claimed-cta:hover { border-color: rgba(155, 95, 255, 0.85); color: rgba(232, 218, 252, 1); }
/* ── Home: CTA + featured strip ───────────────────────── */
.boot-panel--skippable { cursor: pointer; position: relative; }
.boot-skip-hint {
  position: absolute;
  bottom: 1.4rem;
  right: 1.6rem;
  font-size: 0.56rem;
  letter-spacing: 0.18em;
  color: rgba(155, 95, 255, 0.5);
  animation: glooom-unread-pulse 1.6s ease-in-out infinite;
}
.home-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  justify-content: center;
  margin-top: 0.4rem;
}
.home-cta {
  display: inline-block;
  padding: 0.55rem 1.3rem;
  border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(210, 185, 250, 0.9);
  text-decoration: none;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  transition: border-color 160ms, color 160ms, background 160ms, box-shadow 160ms;
}
.home-cta:hover { border-color: rgba(155, 95, 255, 0.85); color: rgba(232, 218, 252, 1); }
.home-cta--primary {
  background: rgba(107, 53, 160, 0.25);
  border-color: rgba(155, 95, 255, 0.6);
  color: rgba(232, 218, 252, 0.98);
}
.home-cta--primary:hover {
  background: rgba(107, 53, 160, 0.45);
  box-shadow: 0 0 22px rgba(140, 60, 255, 0.25);
}
.home-featured {
  width: 100%;
  max-width: 760px;
  margin: 1.6rem auto 0;
}
.home-featured-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.8rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid rgba(155, 95, 255, 0.16);
}
.home-featured-label { font-size: 0.56rem; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(120, 255, 172, 0.7); }
.home-featured-all { font-size: 0.56rem; letter-spacing: 0.1em; color: rgba(176, 130, 255, 0.8); text-decoration: none; }
.home-featured-all:hover { color: rgba(216, 186, 255, 1); }
.home-featured-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.8rem;
}
.home-featured-card { display: flex; flex-direction: column; gap: 0.25rem; text-decoration: none; }
.home-featured-img {
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background: #0a0518;
  border: 1px solid rgba(155, 95, 255, 0.16);
  transition: border-color 160ms, transform 160ms;
}
.home-featured-card:hover .home-featured-img { border-color: rgba(155, 95, 255, 0.55); transform: translateY(-2px); }
.home-featured-img img { width: 100%; height: 100%; object-fit: cover; }
.home-featured-noimg { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: rgba(155, 95, 255, 0.4); }
.home-featured-name { font-size: 0.6rem; letter-spacing: 0.03em; color: rgba(216, 196, 248, 0.92); text-transform: uppercase; }
.home-featured-price { font-size: 0.62rem; color: rgba(120, 255, 172, 0.85); }
@media (max-width: 600px) {
  .home-featured-grid { grid-template-columns: repeat(2, 1fr); }
}
/* ── Checkout guest note ──────────────────────────────── */
.checkout-guest-note {
  font-size: 0.6rem;
  line-height: 1.5;
  color: rgba(196, 170, 240, 0.78);
  background: rgba(155, 95, 255, 0.06);
  border: 1px solid rgba(155, 95, 255, 0.18);
  padding: 0.5rem 0.65rem;
  margin: 0 0 0.3rem;
}
.checkout-login-link {
  background: none; border: none; padding: 0;
  font-family: inherit; font-size: inherit;
  color: rgba(176, 130, 255, 0.95); text-decoration: underline; cursor: pointer;
}
.checkout-login-link:hover { color: rgba(216, 186, 255, 1); }
/* ── Product specs (admin) + dossier scarcity/trust ───── */
.admin-specs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; }
@media (max-width: 600px) { .admin-specs-grid { grid-template-columns: 1fr; } }
.dossier-scarcity {
  margin: 0.9rem 0 0;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255, 140, 60, 0.9);
  text-shadow: 0 0 10px rgba(255, 130, 50, 0.3);
}
.dossier-scarcity--unique { color: rgba(255, 90, 90, 0.92); text-shadow: 0 0 10px rgba(255, 60, 60, 0.3); }
.dossier-trust {
  margin-top: 1.3rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(155, 95, 255, 0.16);
}
.dossier-trust-title {
  display: block;
  font-size: 0.54rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.72);
  margin-bottom: 0.5rem;
}
.dossier-trust-list { margin: 0; padding-left: 1rem; list-style: none; }
.dossier-trust-list li {
  position: relative;
  font-size: 0.68rem;
  line-height: 1.7;
  color: rgba(210, 190, 244, 0.86);
  padding-left: 0.3rem;
}
.dossier-trust-list li::before {
  content: "▪";
  position: absolute;
  left: -0.8rem;
  color: rgba(120, 255, 172, 0.7);
}
/* ── Shop search + sort controls ──────────────────────── */
.shop-controls {
  display: flex;
  gap: 0.7rem;
  align-items: center;
  width: 100%;
  max-width: 820px;
  margin: 0 auto 0.4rem;
  flex-wrap: wrap;
}
.shop-search {
  flex: 1;
  min-width: 180px;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  background: rgba(155, 95, 255, 0.06);
  border: 1px solid rgba(155, 95, 255, 0.25);
  padding: 0.35rem 0.6rem;
}
.shop-search-icon { color: rgba(155, 95, 255, 0.6); font-size: 0.9rem; }
.shop-search-input {
  flex: 1;
  min-width: 0;
  background: none; border: none; outline: none;
  color: rgba(232, 218, 252, 0.95);
  font-family: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
}
.shop-search-input::placeholder { color: rgba(196, 158, 232, 0.45); }
.shop-sort { display: flex; align-items: center; gap: 0.4rem; flex-shrink: 0; }
.shop-sort-label { font-size: 0.54rem; letter-spacing: 0.18em; color: rgba(155, 95, 255, 0.6); }
.shop-sort-select {
  background: rgba(155, 95, 255, 0.06);
  border: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(216, 196, 248, 0.92);
  font-family: inherit;
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  padding: 0.35rem 0.5rem;
  cursor: pointer;
}
/* ── Route lazy-load fallback ─────────────────────────── */
.route-loading {
  width: 100%;
  min-height: 40vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.route-loading-dots {
  font-size: 1.4rem;
  letter-spacing: 0.4em;
  color: rgba(155, 95, 255, 0.6);
  animation: glooom-unread-pulse 1.4s ease-in-out infinite;
}
/* ── Gloomopedia bestiary — status bar, badges, search ── */
.gpedia-status-bar {
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
  max-width: 900px;
  margin: 0 auto 0.9rem;
  width: 100%;
}
.gpedia-status-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: none;
  border: 1px solid rgba(155, 95, 255, 0.25);
  color: rgba(196, 170, 240, 0.72);
  font-family: inherit;
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  padding: 0.32rem 0.7rem;
  cursor: pointer;
  transition: border-color 140ms, color 140ms, background 140ms;
}
.gpedia-status-tab:hover { color: rgba(226, 207, 255, 0.95); border-color: rgba(155, 95, 255, 0.5); }
.gpedia-status-tab--active {
  color: rgba(232, 218, 252, 1);
  border-color: rgba(155, 95, 255, 0.75);
  background: rgba(107, 53, 160, 0.2);
}
.gpedia-status-count {
  font-size: 0.5rem;
  padding: 0.02rem 0.32rem;
  border-radius: 7px;
  background: rgba(155, 95, 255, 0.25);
  color: rgba(232, 218, 252, 0.95);
  letter-spacing: 0.05em;
}
.gpedia-searchrow {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  max-width: 900px;
  margin: 0 auto 1rem;
  width: 100%;
}
.gpedia-search {
  flex: 1;
  background: rgba(155, 95, 255, 0.06);
  border: 1px solid rgba(155, 95, 255, 0.25);
  padding: 0.4rem 0.6rem;
  outline: none;
  color: rgba(232, 218, 252, 0.95);
  font-family: inherit;
  font-size: 0.68rem;
  letter-spacing: 0.04em;
}
.gpedia-search::placeholder { color: rgba(196, 158, 232, 0.45); }
.gpedia-searchrow .gpedia-count { margin: 0; white-space: nowrap; }
/* Status badges on dossier cards */
.gpedia-card-status {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.16rem 0.45rem;
  font-size: 0.5rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: rgba(8, 4, 18, 0.82);
  backdrop-filter: blur(2px);
  border: 1px solid currentColor;
}
.gpedia-card-status--available { color: rgba(120, 255, 172, 0.92); }
.gpedia-card-status--claimed   { color: rgba(255, 90, 90, 0.9); }
.gpedia-card-img--claimed { filter: grayscale(0.5) brightness(0.62) contrast(1.05); }
/* ── Lightbox ─────────────────────────────────────────── */
.lightbox {
  position: fixed; inset: 0; z-index: 600;
  background: rgba(3, 1, 8, 0.94);
  display: flex; align-items: center; justify-content: center;
  padding: 2rem;
  animation: glooom-msg-in 160ms ease both;
}
.lightbox-img { max-width: 92vw; max-height: 88vh; object-fit: contain; box-shadow: 0 0 60px rgba(120, 60, 220, 0.25); }
.lightbox-close {
  position: absolute; top: 1rem; right: 1.2rem;
  background: none; border: none; color: rgba(226, 207, 255, 0.85);
  font-size: 1.4rem; cursor: pointer; z-index: 2;
}
.lightbox-close:hover { color: #fff; }
.lightbox-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: rgba(107, 53, 160, 0.25); border: 1px solid rgba(155, 95, 255, 0.4);
  color: rgba(226, 207, 255, 0.9); font-size: 1.6rem; line-height: 1;
  width: 2.4rem; height: 2.4rem; cursor: pointer;
}
.lightbox-nav:hover { background: rgba(107, 53, 160, 0.5); }
.lightbox-prev { left: 1rem; }
.lightbox-next { right: 1rem; }
.lightbox-count { position: absolute; bottom: 1.2rem; left: 50%; transform: translateX(-50%); font-size: 0.62rem; letter-spacing: 0.16em; color: rgba(196, 170, 240, 0.7); }
/* ── Gloomopedia rich dossier ─────────────────────────── */
.gpedia-dossier { max-width: 720px; width: 100%; margin: 0 auto; display: flex; flex-direction: column; }
.gpedia-dossier-banner {
  font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase;
  padding: 0.5rem 0.8rem; margin-bottom: 0.9rem; border: 1px solid currentColor;
}
.gpedia-dossier-banner--available { color: rgba(120, 255, 172, 0.9); }
.gpedia-dossier-banner--owned     { color: rgba(var(--toxic), 0.95); text-shadow: 0 0 10px rgba(var(--toxic), 0.4); }
.gpedia-dossier-banner--claimed   { color: rgba(255, 90, 90, 0.85); }
.gpedia-dossier-banner--archive   { color: rgba(155, 95, 255, 0.7); }
.gpedia-dossier-plate {
  position: relative; width: 100%; max-height: 640px; aspect-ratio: 3 / 4;
  overflow: hidden; border: 1px solid rgba(155, 95, 255, 0.22);
  background: linear-gradient(135deg, #0d0a14 0%, #1a0f28 50%, #0d0a14 100%);
  background-size: 200% 200%;
  animation: img-shimmer 2s ease-in-out infinite;
}
.gpedia-dossier-plate .gpedia-entry-img { width: 100%; height: 100%; object-fit: cover; }
.gpedia-dossier-thumbs { display: flex; gap: 0.5rem; margin-top: 0.6rem; flex-wrap: wrap; }
.gpedia-dossier-thumb {
  width: 62px; height: 62px; padding: 0; overflow: hidden;
  background: #0a0518; border: 1px solid rgba(155, 95, 255, 0.25); cursor: zoom-in;
  transition: border-color 140ms;
}
.gpedia-dossier-thumb:hover { border-color: rgba(155, 95, 255, 0.7); }
.gpedia-dossier-thumb img { width: 100%; height: 100%; object-fit: cover; }
.gpedia-section-label {
  font-size: 0.54rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(155, 95, 255, 0.7); margin: 1.4rem 0 0.5rem;
}
.gpedia-specs { margin-top: 0.4rem; }
.gpedia-specs-grid { display: flex; flex-direction: column; gap: 0.3rem; }
.gpedia-spec-row { display: flex; justify-content: space-between; gap: 1rem; font-size: 0.7rem; border-bottom: 1px solid rgba(155, 95, 255, 0.1); padding-bottom: 0.3rem; }
.gpedia-spec-key { letter-spacing: 0.12em; color: rgba(155, 95, 255, 0.7); text-transform: uppercase; font-size: 0.58rem; }
.gpedia-spec-val { color: rgba(216, 196, 248, 0.92); text-align: right; }
.gpedia-dossier-acq {
  margin-top: 1.6rem; padding: 1.1rem; text-align: center;
  background: rgba(12, 6, 24, 0.5); border: 1px solid rgba(155, 95, 255, 0.2);
}
.gpedia-acq-price { font-size: 1.3rem; letter-spacing: 0.04em; color: rgba(120, 255, 172, 0.92); }
.gpedia-acq-note { font-size: 0.64rem; color: rgba(196, 170, 240, 0.78); margin: 0.5rem 0 0.9rem; }
.gpedia-acq-btn {
  display: inline-block; padding: 0.6rem 1.4rem;
  background: rgba(107, 53, 160, 0.28); border: 1px solid rgba(155, 95, 255, 0.6);
  color: rgba(232, 218, 252, 0.98); text-decoration: none;
  font-size: 0.7rem; letter-spacing: 0.14em; transition: background 160ms, box-shadow 160ms;
}
.gpedia-acq-btn:hover { background: rgba(107, 53, 160, 0.5); box-shadow: 0 0 22px rgba(140, 60, 255, 0.25); }
.gpedia-sealed { display: flex; flex-direction: column; align-items: center; gap: 0.3rem; }
.gpedia-sealed-stamp {
  display: inline-block; border: 2px solid rgba(255, 70, 70, 0.7); color: rgba(255, 90, 90, 0.9);
  font-size: 0.9rem; letter-spacing: 0.24em; padding: 0.2rem 0.8rem; transform: rotate(-4deg);
  text-shadow: 0 0 8px rgba(255, 60, 60, 0.4); margin-bottom: 0.4rem;
}
.gpedia-sealed-stamp--owned {
  border-color: rgba(var(--toxic), 0.7); color: rgba(var(--toxic), 0.95);
  text-shadow: 0 0 8px rgba(var(--toxic), 0.4);
}
.gpedia-sealed-by { font-size: 0.78rem; color: rgba(216, 196, 248, 0.9); margin: 0; }
.gpedia-sealed-by strong { color: rgba(232, 218, 252, 1); }
.gpedia-sealed-date { font-size: 0.6rem; letter-spacing: 0.1em; color: rgba(155, 95, 255, 0.65); margin: 0; }
.gpedia-sealed-note { font-size: 0.62rem; color: rgba(196, 170, 240, 0.7); margin: 0.4rem 0 0; }
.gpedia-channel-cta {
  margin-top: 1.3rem; padding-top: 1.1rem; border-top: 1px solid rgba(155, 95, 255, 0.16);
  display: flex; flex-direction: column; align-items: center; gap: 0.4rem;
}
.gpedia-channel-btn {
  background: rgba(155, 95, 255, 0.08); border: 1px solid rgba(155, 95, 255, 0.45);
  color: rgba(218, 195, 248, 0.95); font-family: inherit;
  font-size: 0.7rem; letter-spacing: 0.16em; padding: 0.5rem 1.2rem; cursor: pointer;
  transition: background 160ms, border-color 160ms;
}
.gpedia-channel-btn:hover { background: rgba(107, 53, 160, 0.3); border-color: rgba(155, 95, 255, 0.8); }
.gpedia-channel-hint { font-size: 0.6rem; color: rgba(196, 170, 240, 0.65); margin: 0; text-align: center; }
.gpedia-card-status--archive { color: rgba(155, 95, 255, 0.7); }
/* ── Item page elevation — gallery, zoom, dossier link, channel feature ── */
.dossier-hero-wrap { position: relative; }
.dossier-zoom-btn {
  position: absolute; bottom: 0.7rem; right: 0.7rem; z-index: 3;
  width: 2rem; height: 2rem;
  background: rgba(8, 4, 18, 0.7); border: 1px solid rgba(155, 95, 255, 0.45);
  color: rgba(218, 195, 248, 0.9); font-size: 0.9rem; cursor: zoom-in;
  backdrop-filter: blur(2px); transition: background 140ms;
}
.dossier-zoom-btn:hover { background: rgba(107, 53, 160, 0.5); }
.dossier-thumbs { display: flex; gap: 0.45rem; flex-wrap: wrap; padding: 0.6rem 0 0; }
.dossier-thumb {
  width: 58px; height: 58px; padding: 0; overflow: hidden; cursor: zoom-in;
  background: #0a0518; border: 1px solid rgba(155, 95, 255, 0.25); transition: border-color 140ms, transform 140ms;
}
.dossier-thumb:hover { border-color: rgba(155, 95, 255, 0.75); transform: translateY(-2px); }
.dossier-thumb img { width: 100%; height: 100%; object-fit: cover; }
.dossier-gloomopedia-link {
  display: inline-block; margin-top: 0.7rem;
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(176, 130, 255, 0.85); text-decoration: none;
  border-bottom: 1px solid rgba(176, 130, 255, 0.3); padding-bottom: 1px;
  transition: color 140ms, border-color 140ms;
}
.dossier-gloomopedia-link:hover { color: rgba(216, 186, 255, 1); border-color: rgba(216, 186, 255, 0.6); }
.dossier-channel-cta--feature {
  background: radial-gradient(ellipse at 50% 0%, rgba(120, 60, 220, 0.12), transparent 70%), rgba(12, 6, 24, 0.5);
  border: 1px solid rgba(155, 95, 255, 0.28);
  padding: 1.2rem 1rem; text-align: center;
}
.dossier-channel-teaser {
  font-size: 0.72rem; font-style: italic; letter-spacing: 0.04em;
  color: rgba(206, 178, 245, 0.82); margin: 0 0 0.7rem;
  animation: text-flicker 5s 2s ease-in-out infinite;
}
.dossier-channel-btn--feature {
  font-size: 0.72rem; letter-spacing: 0.12em; padding: 0.6rem 1.2rem;
  box-shadow: 0 0 20px rgba(140, 60, 255, 0.18);
}
/* ── Gloomopedia category landing ─────────────────────── */
.gpedia-cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: clamp(0.9rem, 2vw, 1.4rem);
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
}
.gpedia-cat-card {
  padding: 0; border: none; background: none; cursor: pointer;
  text-align: left; font-family: inherit;
}
.gpedia-cat-plate {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border: 1px solid rgba(155, 95, 255, 0.2);
  transition: border-color 200ms ease, transform 200ms ease, box-shadow 200ms ease;
  background: linear-gradient(135deg, #0d0a14 0%, #1a0f28 50%, #0d0a14 100%);
  background-size: 200% 200%;
  animation: img-shimmer 2s ease-in-out infinite;
}
.gpedia-cat-card:hover .gpedia-cat-plate {
  border-color: rgba(155, 95, 255, 0.6);
  transform: translateY(-3px);
  box-shadow: 0 12px 32px rgba(80, 30, 160, 0.3);
}
.gpedia-cat-plate img { width: 100%; height: 100%; object-fit: cover; filter: saturate(0.85) contrast(1.04); transition: transform 600ms ease; }
.gpedia-cat-card:hover .gpedia-cat-plate img { transform: scale(1.05); }
.gpedia-cat-wash {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(8,4,18,0.1) 0%, rgba(8,4,18,0.35) 45%, rgba(6,3,14,0.92) 100%);
}
.gpedia-cat-overlay {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.8rem 0.9rem;
}
.gpedia-cat-name {
  font-size: 0.95rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(236, 222, 255, 0.98); text-shadow: 0 0 14px rgba(155, 95, 255, 0.45);
}
.gpedia-cat-avail {
  font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(120, 255, 172, 0.92); text-shadow: 0 0 8px rgba(80, 255, 150, 0.3);
}
.gpedia-cat-total {
  position: absolute; top: 0.55rem; right: 0.55rem;
  font-size: 0.5rem; letter-spacing: 0.14em;
  color: rgba(216, 196, 248, 0.85);
  background: rgba(8, 4, 18, 0.7); border: 1px solid rgba(155, 95, 255, 0.3);
  padding: 0.14rem 0.42rem; backdrop-filter: blur(2px);
}
.gpedia-itembar {
  display: flex; align-items: center; gap: 0.7rem;
  max-width: 900px; margin: 0 auto 1rem; width: 100%; flex-wrap: wrap;
}
.gpedia-itembar .gpedia-back { margin: 0; flex-shrink: 0; }
.gpedia-itembar .gpedia-search { flex: 1; min-width: 140px; background: rgba(155,95,255,0.06); border: 1px solid rgba(155,95,255,0.25); padding: 0.4rem 0.6rem; }
.gpedia-itembar .gpedia-count { margin: 0; white-space: nowrap; }
/* ── Gloomopedia type dossier — specimen grid ─────────── */
.gpedia-spec-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 0.8rem;
  margin-top: 0.3rem;
}
.gpedia-spec-card {
  display: flex; flex-direction: column; gap: 0.25rem; text-decoration: none;
}
.gpedia-spec-img {
  position: relative; aspect-ratio: 3 / 4; overflow: hidden;
  border: 1px solid rgba(155, 95, 255, 0.2);
  transition: border-color 160ms, transform 160ms;
  background: linear-gradient(135deg, #0d0a14 0%, #1a0f28 50%, #0d0a14 100%);
  background-size: 200% 200%;
  animation: img-shimmer 2s ease-in-out infinite;
}
.gpedia-spec-card:hover .gpedia-spec-img { border-color: rgba(155, 95, 255, 0.6); transform: translateY(-2px); }
/* Claimed/owned records don't lead to a purchase — no lift, a quieter
   border-only hover so the affordance doesn't imply "buy this." */
.gpedia-spec-card--claimed:hover .gpedia-spec-img { border-color: rgba(155, 95, 255, 0.35); transform: none; }
.gpedia-spec-img img { width: 100%; height: 100%; object-fit: cover; }
.gpedia-spec-badge {
  position: absolute; top: 0.4rem; right: 0.4rem;
  font-size: 0.46rem; letter-spacing: 0.14em; padding: 0.12rem 0.36rem;
  background: rgba(8, 4, 18, 0.82); border: 1px solid currentColor; backdrop-filter: blur(2px);
}
.gpedia-spec-badge--available { color: rgba(120, 255, 172, 0.92); }
.gpedia-spec-badge--owned     { color: rgba(var(--toxic), 0.95); border-color: rgba(var(--toxic), 0.6); }
.gpedia-spec-badge--claimed   { color: rgba(255, 90, 90, 0.9); }
.gpedia-spec-name { font-size: 0.66rem; letter-spacing: 0.03em; color: rgba(216, 196, 248, 0.92); text-transform: uppercase; }
.gpedia-spec-price { font-size: 0.66rem; color: rgba(120, 255, 172, 0.85); }
.gpedia-spec-price--claimed { color: rgba(196, 170, 240, 0.7); font-size: 0.58rem; }
/* ── Login: reset link + notice ───────────────────────── */
.login-notice {
  font-size: 0.56rem;
  letter-spacing: 0.1em;
  color: rgba(120, 255, 172, 0.85);
  margin: 0;
}
.login-forgot {
  background: none;
  border: none;
  padding: 0.2rem 0;
  font-family: inherit;
  font-size: 0.56rem;
  letter-spacing: 0.06em;
  color: rgba(176, 130, 255, 0.85);
  text-decoration: underline;
  cursor: pointer;
  align-self: flex-start;
}
.login-forgot:hover { color: rgba(216, 186, 255, 1); }
.login-forgot:disabled { opacity: 0.5; cursor: default; }
/* ── Delayed loader — fades in only if a load is genuinely slow ─────── */
.delayed-loader {
  animation: delayed-loader-in 220ms ease both;
}
@keyframes delayed-loader-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* ═══════════════════════════════════════════════════════════════════════
   BUTTON SYSTEM — unified primary / secondary / ghost / danger.
   New markup should use .btn + a variant. The selector list below also
   retrofits the look onto the pre-existing CTA classes for consistency.
   ═══════════════════════════════════════════════════════════════════════ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.6rem 1.2rem;
  border: 1px solid rgba(var(--violet-3), 0.4);
  background: rgba(var(--violet-3), 0.06);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              box-shadow var(--dur-med) var(--ease),
              transform var(--dur-fast) var(--ease);
}
.btn:hover { border-color: rgba(var(--violet-3), 0.8); background: rgba(var(--violet-3), 0.12); color: var(--ink-strong); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: 0.42; cursor: not-allowed; transform: none; box-shadow: none; }
.btn--secondary { background: none; }
.btn--ghost { background: none; border-color: transparent; color: var(--ink-dim); }
.btn--ghost:hover { background: none; border-color: rgba(var(--violet-3), 0.3); color: var(--ink-strong); }
.btn--danger { border-color: rgba(var(--blood), 0.45); color: rgba(var(--blood), 0.92); background: none; }
.btn--danger:hover { border-color: rgba(var(--blood), 0.8); background: rgba(var(--blood), 0.08); color: rgba(var(--blood), 1); }
.btn--lg { padding: 0.75rem 1.6rem; font-size: var(--fs-body); }
.btn--block { width: 100%; }
/* Unified PRIMARY action — acquire, pay, enter, featured CTA.
   Retrofits the older bespoke classes so every primary button matches. */
.btn--primary,
.dossier-acquire-btn,
.home-cta--primary,
.gpedia-acq-btn,
.admin-btn--save {
  background: linear-gradient(180deg, rgba(var(--violet-3), 0.28), rgba(var(--violet-4), 0.32));
  border: 1px solid rgba(var(--violet-3), 0.62);
  color: var(--ink-strong);
}
.btn--primary:hover:not(:disabled),
.dossier-acquire-btn:hover:not(:disabled),
.home-cta--primary:hover:not(:disabled),
.gpedia-acq-btn:hover:not(:disabled),
.admin-btn--save:hover:not(:disabled) {
  background: linear-gradient(180deg, rgba(var(--violet-3), 0.46), rgba(var(--violet-4), 0.5));
  border-color: rgba(var(--violet-3), 0.9);
  box-shadow: 0 0 24px rgba(var(--violet-3), 0.3);
  color: #fff;
  transform: translateY(-1px);
}
.btn--primary:active:not(:disabled),
.dossier-acquire-btn:active:not(:disabled),
.home-cta--primary:active:not(:disabled),
.gpedia-acq-btn:active:not(:disabled),
.admin-btn--save:active:not(:disabled) { transform: translateY(0); }
/* ═══════════════════════════════════════════════════════════════════════
   CONSUMER FORMS — checkout / login / account / contact reuse the admin
   input markup, but here they get a larger, calmer, more premium treatment
   (scoped by page root so the admin back-office stays dense + utilitarian).
   ═══════════════════════════════════════════════════════════════════════ */
.checkout-page .admin-label,
.login-box .admin-label,
.account-section .admin-label,
.contact-panel .admin-label {
  font-size: var(--fs-caption);
  color: var(--ink-dim);
  margin-bottom: 0.1rem;
}
.checkout-page .admin-field,
.login-box .admin-field,
.account-section .admin-field,
.contact-panel .admin-field { gap: 0.4rem; }
.checkout-page .admin-input,
.login-box .admin-input,
.account-section .admin-input,
.contact-panel .admin-input,
.contact-panel .admin-textarea {
  font-size: var(--fs-body);
  letter-spacing: 0.04em;
  padding: 0.62rem 0.72rem;
  background: rgba(var(--surface-0), 0.92);
  border: 1px solid rgba(var(--violet-3), 0.22);
  color: var(--ink);
  transition: border-color var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}
.checkout-page .admin-input:focus,
.login-box .admin-input:focus,
.account-section .admin-input:focus,
.contact-panel .admin-input:focus,
.contact-panel .admin-textarea:focus {
  border-color: rgba(var(--violet-3), 0.7);
  box-shadow: 0 0 0 1px rgba(var(--violet-3), 0.22), inset 0 0 18px rgba(var(--violet-4), 0.08);
  background: rgba(var(--surface-1), 0.95);
}
.checkout-page .admin-input::placeholder,
.login-box .admin-input::placeholder,
.contact-panel .admin-input::placeholder,
.contact-panel .admin-textarea::placeholder { color: rgba(var(--violet-2), 0.4); }
/* ═══════════════════════════════════════════════════════════════════════
   PHASE 4 — card consistency + dossier acquire hierarchy
   ═══════════════════════════════════════════════════════════════════════ */
/* Unify the hover "violet glow lift" across shop + gloomopedia cards */
.product-card:hover {
  border-color: rgba(var(--violet-3), 0.65);
  box-shadow: 0 12px 30px rgba(var(--violet-4), 0.24), 0 0 0 1px rgba(var(--violet-3), 0.2);
}
.gpedia-card:hover {
  border-color: rgba(var(--violet-3), 0.65);
  transform: translateY(-3px);
  box-shadow: 0 12px 30px rgba(var(--violet-4), 0.28), 0 0 0 1px rgba(var(--violet-3), 0.2);
}
/* Catalogue price = the headline of the acquisition block */
.dossier-acq-val--price {
  font-size: clamp(1.25rem, 3.6vw, 1.7rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #fff;
  text-shadow: 0 0 16px rgba(var(--violet-3), 0.5);
  line-height: 1.1;
}
.dossier-acq-row:has(.dossier-acq-val--price) { align-items: center; }
/* Frame the acquisition panel + make the acquire button unmistakably the CTA */
.dossier-acquisition {
  border: 1px solid rgba(var(--violet-3), 0.24);
  box-shadow: inset 0 0 40px rgba(var(--violet-4), 0.06);
}
.dossier-acquire-btn {
  font-size: var(--fs-body);
  letter-spacing: 0.18em;
  padding: 0.85rem 1.3rem;
}
/* ═══════════════════════════════════════════════════════════════════════
   PHASE 5 — site-wide polish (scrollbar, footer micro-interaction, contrast)
   ═══════════════════════════════════════════════════════════════════════ */
/* Themed scrollbar everywhere (the cabinet menu keeps its own, more specific) */
* { scrollbar-color: rgba(155, 95, 255, 0.4) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: rgba(var(--surface-0), 0.6); }
::-webkit-scrollbar-thumb { background: rgba(var(--violet-3), 0.3); }
::-webkit-scrollbar-thumb:hover { background: rgba(var(--violet-3), 0.5); }
/* ═══════════════════════════════════════════════════════════════════════
   PRODUCT-PAGE ARCHIVAL HEADER — one compact band: name · buy · talk · share.
   ═══════════════════════════════════════════════════════════════════════ */
/* One gutter for the whole dossier. The header, the hero photograph and the
   related-specimens grid each used to set their own horizontal inset — the
   header a clamp(), the photo a flat 1rem (0.8rem under 600px) — so they
   only lined up by coincidence at some widths. On a Pixel 7 the image sat
   17px from each edge while the header's content started at 16px, which is
   what read as the picture being slightly off. */
.dossier-page { --dossier-gutter: clamp(0.8rem, 3vw, 1.4rem); }
/* Sticky band. It does not resize on scroll — see the note on the markup. */
.dah {
  position: sticky;
  /* Seat the band flush under the fixed .nav-bar with no live page content
     showing through between them. Two corrections are folded into --dah-top,
     which is measured in JS (DossierLayout) because both terms are dynamic:
       + the nav's real height, which differs per breakpoint
       − .page-viewport's padding-top, because a sticky element's `top`
         resolves against the PADDING box, not the border box
     Getting only the second one right slid the header UNDER the nav and hid
     the buttons; getting neither left a 2.4rem gap that content scrolled
     through. The fallback keeps it merely flush-ish if the effect is gone. */
  top: var(--dah-top, 0px);
  z-index: 460;

  /* ONE ROW, ONE SIZE — this is the whole design.
     The header used to be a four-row stack that collapsed to a single row on
     scroll, a ~4x height change. Keeping a dozen properties in sync across
     that collapse was never fully smooth, because two of them (flex-wrap,
     flex-basis→auto) are discrete by nature. The redesign made both states
     one row; this removes the second state altogether. The band is simply
     the condensed design, always — it was the better-looking of the two, and
     a header that never resizes cannot resize badly.

     Everything below is the resolved value the scrub used to arrive at, i.e.
     each old `calc(open - delta * collapse)` evaluated at collapse = 1. */
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: clamp(0.4rem, 1.6vw, 0.9rem);
  padding: 0.42rem var(--dossier-gutter);
  border-bottom: var(--line-soft);
  background: linear-gradient(180deg, rgba(var(--violet-4), 0.12), rgba(var(--violet-4), 0));

  /* Android hardening. A sticky element that is repainted rather than
     composited flickers or drops out entirely during a fling — the band
     would vanish for a few frames mid-scroll. Promoting it to its own layer
     keeps it stable, and backface-visibility suppresses the 1px seam Android
     leaves under the nav on fractional device pixel ratios (2.625 on a
     Pixel 7, 2.75 on a Pixel 5). */
  transform: translateZ(0);
  backface-visibility: hidden;
  /* The collapse is scrubbed from scroll position rather than run as a timed
     transition, so the header's size changes on scroll frames the compositor
     is already servicing. A standing `will-change` would pin a layer for the
     whole page life for no benefit. */
  will-change: auto;
}
/* The band's own border/background are off: ::before below paints the real
   ground, full-bleed, at all times. */
.dah {
  border-bottom-color: transparent;
  box-shadow: none;
  background: none;
}
/* The solid rail. Always on — the band no longer has an "arriving" state to
   fade in from, so this is simply the header's ground. */
.dah::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: -1px;
  /* Full-bleed without 100vw. On Android, 100vw is resolved against the
     LAYOUT viewport and does not track the visual viewport while the URL bar
     collapses, so the rail drifted sideways mid-scroll and could expose the
     page either side of it. Anchoring to the scroll container's own padding
     box with symmetric negative insets is exact at every width and immune to
     the URL-bar resize. --dah-bleed is the header's distance to each edge,
     measured in JS. */
  left: calc(-1 * var(--dah-bleed, 0px));
  right: calc(-1 * var(--dah-bleed, 0px));
  background:
    linear-gradient(180deg, rgba(14, 7, 28, 0.985), rgba(9, 4, 19, 0.96));
  border-bottom: 1px solid rgba(var(--violet-2), 0.55);
  /* A soft violet bloom under the edge instead of a hard black drop shadow —
     the band reads as lit from within, matching the rest of the CRT. */
  box-shadow:
    0 10px 26px rgba(0, 0, 0, 0.55),
    0 1px 0 rgba(var(--violet-1), 0.28),
    0 6px 30px -6px rgba(var(--violet-2), 0.4);
  /* NOTE: deliberately no backdrop-filter here. A negative-z-index pseudo
     with a backdrop-filter is a long-standing Android Chrome compositing
     failure — the filter samples the wrong layer or drops out entirely,
     which renders the whole band transparent and leaves the page scrolling
     visibly through the buttons. The gradient below is opaque enough
     (0.96–0.985) to do the job without a filter on any device. */
  z-index: -1;
  pointer-events: none;
}
/* A scanline sweep across the rail as it lands — the archive "acquiring" the
/* NOTE: two things that lived here are gone with the collapse they belonged
   to — the one-shot scanline sweep that fired as the band "arrived" (there
   is no arrival any more), and the read-progress hairline along its foot.
   The hairline answered "how much more is there?" for a header that changed
   as you scrolled; against a band that never moves it read as a stray
   scrollbar stuck under the chrome. Removing it also retires the last
   scroll listener on the page. */
/* A live tick before the name, so the band reads as an active readout rather
   than a browser toolbar. */
.dah-id { position: relative; padding-left: 0.95rem; }
.dah-id::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 6px;
  height: 6px;
  margin-top: -3px;
  background: rgb(var(--toxic));
  box-shadow: 0 0 8px rgba(var(--toxic), 0.9);
  animation: dah-tick 2.2s steps(1, end) infinite;
}
@keyframes dah-tick { 0%, 70% { opacity: 1; } 71%, 100% { opacity: 0.25; } }
/* A long specimen name truncates rather than pushing the buttons out. */
.dah-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (prefers-reduced-motion: reduce) {
  /* Only self-running decoration is left to suppress — the blinking tick.
     There is no collapse to silence any more. */
  .dah-id::before { animation: none; }
}
.dah-back { flex-shrink: 0; }
/* Single line — the record/SKU row it used to stack above was removed with
   the one-row redesign (the SKU is already in the photo caption). */
.dah-id { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; }
.dah-name {
  /* Resolved from the old scrub at collapse = 1. */
  font-size: clamp(0.85rem, 1.8vw, 1.05rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.05;
  color: var(--ink-strong);
  text-shadow: 0 0 14px rgba(var(--violet-3), 0.35);
}
/* align-items: stretch (the default) so the share icon can match the height
   of the labelled buttons beside it — see .dah-share--icon below. The two
   labelled buttons size themselves from their own padding, so stretch does
   not distort them. */
.dah-actions { display: flex; align-items: stretch; gap: 0.5rem; flex-shrink: 0; }
/* The hero photograph sits inside the shared gutter on ALL FOUR sides, so the
   space above its frame matches the space either side of it.
   Two things used to stack here: a margin-bottom on the header AND the
   photo's own padding-top, giving 30px above the frame against a 16px side
   inset on a phone (51 vs 31 on a laptop) — the doubled gap read as the
   picture floating too far down. The header margin is gone; the photo's own
   padding is the spacing, and it is now the same value in every direction. */
.dossier-page .dossier-photo { padding: var(--dossier-gutter); }
/* The buy box matches the horizontal inset — it sat at a flat 1rem/1.25rem,
   so on a phone its edges were 20px in against the photo's 16px. */
.dossier-page .dossier-buybox { padding-inline: var(--dossier-gutter); }
/* Shop-page dossier: the .dah header already carries the name, so the h1 is
   clipped rather than removed — it stays the page's real heading for screen
   readers and search engines while the duplicate stops reading as a mistake. */
.dossier-designation--compact .dossier-name {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* An empty designation block would otherwise leave a gap above the buy box. */
.dossier-designation--compact:not(:has(.dossier-taxonomy, .dossier-status-row, .dossier-gloomopedia-link)) {
  margin: 0;
  padding: 0;
}
/* ── INCOMING HAIL ────────────────────────────────────────────────────────
   Replaces the quiet dashed "talk to this specimen" button, which testers
   read straight past as page furniture. This is staged as a live unanswered
   transmission so it reads as an event, not a control. It is allowed to be
   loud — it's violet against the green buy button, so the two never compete
   for the same "primary action" slot. */
.dossier-hail {
  position: relative;
  margin-top: 0.7rem;
  padding: 0.7rem 0.85rem 0.8rem;
  background:
    linear-gradient(180deg, rgba(var(--violet-4), 0.34), rgba(var(--violet-4), 0.16));
  border: 1px solid rgba(var(--violet-2), 0.6);
  box-shadow: 0 0 0 rgba(var(--violet-2), 0.45);
  animation: hail-attract 3.4s var(--ease) infinite;
  overflow: hidden;
}
/* A slow breathing glow — enough to catch the eye in peripheral vision
   without the jitter of a flash. */
@keyframes hail-attract {
  0%, 100% { box-shadow: 0 0 0 rgba(var(--violet-2), 0);    border-color: rgba(var(--violet-2), 0.45); }
  50%      { box-shadow: 0 0 22px rgba(var(--violet-2), 0.4); border-color: rgba(var(--violet-2), 0.95); }
}
/* Signal sweep crossing the panel — the "carrier" of the transmission. */
.dossier-hail::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 40%, rgba(var(--violet-1), 0.16) 50%, transparent 60%);
  transform: translateX(-100%);
  animation: hail-sweep 4.2s linear infinite;
  pointer-events: none;
}
@keyframes hail-sweep { to { transform: translateX(100%); } }
.dossier-hail-head { display: flex; align-items: center; gap: 0.45rem; }
.dossier-hail-label {
  font-size: var(--fs-caption);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(var(--violet-1), 0.95);
}
/* Recording dot. */
.dossier-hail-live {
  width: 7px; height: 7px; border-radius: 50%;
  background: #ff4a6e;
  box-shadow: 0 0 8px #ff4a6e;
  animation: hail-blink 1.1s steps(1, end) infinite;
  flex-shrink: 0;
}
@keyframes hail-blink { 0%, 60% { opacity: 1; } 61%, 100% { opacity: 0.15; } }
/* Signal-strength bars, each on its own offset so they ripple. */
.dossier-hail-bars { margin-left: auto; display: flex; align-items: flex-end; gap: 2px; height: 11px; }
.dossier-hail-bars i {
  width: 3px;
  background: rgba(var(--violet-1), 0.85);
  animation: hail-bar 1.05s var(--ease) infinite;
}
.dossier-hail-bars i:nth-child(1) { height: 30%; animation-delay: 0s; }
.dossier-hail-bars i:nth-child(2) { height: 55%; animation-delay: 0.12s; }
.dossier-hail-bars i:nth-child(3) { height: 78%; animation-delay: 0.24s; }
.dossier-hail-bars i:nth-child(4) { height: 100%; animation-delay: 0.36s; }
@keyframes hail-bar { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
/* The specimen's own words — sentence case on purpose. The CRT shell
   uppercases globally, and a voice that shouts reads as system output
   rather than as something alive asking for your attention. */
.dossier-hail-line {
  margin: 0.5rem 0 0.7rem;
  min-height: 1.35em;
  font-size: var(--fs-body);
  line-height: 1.35;
  text-transform: none;
  letter-spacing: 0.01em;
  color: #fff;
  text-shadow: 0 0 12px rgba(var(--violet-1), 0.5);
}
.dossier-hail-caret {
  display: inline-block;
  width: 0.55em; height: 1em;
  margin-left: 2px;
  vertical-align: -0.15em;
  background: rgba(var(--violet-1), 0.9);
  animation: hail-blink 0.9s steps(1, end) infinite;
}
.dossier-hail-btn {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  padding: 0.7rem 1rem;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #fff;
  background: linear-gradient(180deg, rgba(var(--violet-3), 0.6), rgba(var(--violet-4), 0.6));
  border: 1px solid rgba(var(--violet-1), 0.75);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
}
.dossier-hail-btn:hover { background: linear-gradient(180deg, rgba(var(--violet-3), 0.85), rgba(var(--violet-4), 0.85)); box-shadow: 0 0 20px rgba(var(--violet-2), 0.6); }
.dossier-hail-btn:active { transform: translateY(1px); }
/* Motion here is decorative; the panel still reads fine static. */
@media (prefers-reduced-motion: reduce) {
  .dossier-hail,
  .dossier-hail::after,
  .dossier-hail-live,
  .dossier-hail-bars i,
  .dossier-hail-caret { animation: none; }
  .dossier-hail { border-color: rgba(var(--violet-2), 0.9); }
  .dossier-hail-bars i { opacity: 0.9; }
}
/* The compact buybox button sits only ~500px below the .dah header CTA
   (immediately under the hero photo), so the two read as the same button
   printed twice rather than as a second chance to buy. The header CTA and
   the full acquisition section near the foot of the page — which carries
   the scarcity copy and earns its own button — are the two that stay.
   The wishlist and channel teaser remain: neither is duplicated above. */
.dossier-buybox .dossier-acq-actions .dossier-acquire-btn { display: none; }
.dossier-buybox .dossier-acq-actions { margin-top: 0; }
/* Primary CTA in the specimen header. This is the first (often only) buy
   control a visitor sees without scrolling — before it existed the loudest
   thing on a product page was SHARE, and testers couldn't find how to buy. */
.dah-acquire {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* "ACQUIRE · £20.00" must stay on one line — see the note on .dah-talk. */
  white-space: nowrap;
  padding: 0.68rem 1.5rem;
  color: #0a0710;
  background: linear-gradient(180deg, rgba(var(--toxic), 1), rgba(var(--toxic), 0.82));
  border: 1px solid rgba(var(--toxic), 0.9);
  box-shadow: 0 0 20px rgba(var(--toxic), 0.35);
  cursor: pointer;
  transition: filter var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease), transform var(--dur-fast) var(--ease);
}
.dah-acquire:hover:not(:disabled) { filter: brightness(1.12); box-shadow: 0 0 28px rgba(var(--toxic), 0.55); }
.dah-acquire:active:not(:disabled) { transform: translateY(1px); }
.dah-acquire:disabled { opacity: 0.5; cursor: default; box-shadow: none; }
/* TALK — channel access inside the sticky header, so "speak to it" is
   reachable from anywhere on the page. Violet, matching the hail, so it
   never competes with the green buy button for the primary slot. */
.dah-talk {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* Never let the label break. Without this the ▶ and the word landed on
     separate lines, which doubled the button's height (74px for a 21px line
     on every phone) and made the whole open header a third taller than it
     needed to be. It also put a discrete step into the collapse: the wrap
     resolving is a single-frame height change no ratio can smooth over. */
  white-space: nowrap;
  padding: 0.5rem 0.95rem;
  color: #fff;
  background: linear-gradient(180deg, rgba(var(--violet-3), 0.5), rgba(var(--violet-4), 0.5));
  border: 1px solid rgba(var(--violet-2), 0.7);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
}
.dah-talk:hover { background: linear-gradient(180deg, rgba(var(--violet-3), 0.8), rgba(var(--violet-4), 0.8)); box-shadow: 0 0 18px rgba(var(--violet-2), 0.55); }
.dah-talk:active { transform: translateY(1px); }
.dah-talk-icon { font-size: 0.8em; opacity: 0.9; }
/* SHARE — was a large green button occupying the CTA slot; now a quiet icon
   so it stops competing with the buy button for the same attention. */
.dah-share {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.5rem 1rem;
  color: rgba(var(--toxic), 0.96);
  background: rgba(var(--toxic), 0.09);
  border: 1px solid rgba(var(--toxic), 0.5);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease), color var(--dur-fast) var(--ease);
}
.dah-share:hover { background: rgba(var(--toxic), 0.2); box-shadow: 0 0 18px rgba(var(--toxic), 0.4); color: #fff; }
.dah-share-icon { font-size: 1.1em; line-height: 1; }
/* Icon-only variant — a square the same height as the other two buttons. */
.dah-share--icon {
  padding: 0;
  justify-content: center;
  color: rgba(var(--toxic), 0.7);
  background: transparent;
  border-color: rgba(var(--toxic), 0.3);
}
.dah-share--icon .dah-share-icon { font-size: 1.05rem; }
/* ── Button sizing ────────────────────────────────────────────────────────
   Must sit AFTER the .dah-acquire / .dah-share--icon base rules above, which
   would otherwise win on source order.

   ACQUIRE and TALK share their vertical padding, so the pair are the same
   height by construction. Share then takes BOTH dimensions from that height:
   `align-self: stretch` matches the row (i.e. the taller of the two labelled
   buttons), and `aspect-ratio: 1` derives the width from it, so the square
   is exact at every breakpoint and type scale rather than a hard-coded rem
   that happened to be close. Previously it was 48px against 42px buttons on
   a laptop and 44px against 33px on a phone, and sat 3px proud of both. */
/* One control height for the whole row, declared once on the header so all
   three buttons resolve from the same numbers.
   --dah-btn-pad-y  vertical padding on the two labelled buttons
   --dah-btn-line   their line box (explicit, not `normal`: `normal` resolves
                    per font size, and the two carry slightly different sizes,
                    so their boxes differed by a pixel — 42px vs 41px, a
                    visible half-pixel misalignment on a fractional-DPR phone)
   --dah-btn-h      the resulting outer height, which the square share icon
                    uses for BOTH of its dimensions. */
.dah {
  --dah-btn-pad-y: 0.5rem;
  --dah-btn-line: 1.05rem;
  --dah-btn-h: calc(var(--dah-btn-pad-y) * 2 + var(--dah-btn-line) + 2px);
}
.dah-acquire,
.dah-talk { line-height: var(--dah-btn-line); }
.dah-acquire { padding: var(--dah-btn-pad-y) 1.05rem; }
.dah-talk    { padding: var(--dah-btn-pad-y) 0.75rem; }
/* An exact square at the buttons' own height, from the shared tokens above.
   Not aspect-ratio: that needs a resolved height to work from, and a
   stretched flex item's height is only known after layout, so the box
   collapsed to its 20px content width. Both dimensions come from --dah-btn-h
   instead, which is the same arithmetic the labelled buttons resolve to. */
.dah-share--icon {
  width: var(--dah-btn-h);
  height: var(--dah-btn-h);
  flex: 0 0 auto;
  align-self: center;
}
@media (max-width: 600px) {
  /* Phone: the same single row as everywhere else, just tighter. The old
     phone layout was a wrapping four-row stack that had to close up into one
     line, which is what needed the flex-basis scrubbing, the order swaps and
     the wrap flip — all deleted with the redesign.

     The name is NOT in the phone header. ACQUIRE + TALK + share need ~330px
     of a 412px row, so letting the name take the remainder rendered it as
     "F." — a truncation so severe it was noise rather than information. It
     is not lost: the <h1> in .dossier-designation sits directly below and is
     un-hidden at this width (see .dossier-designation--compact), so the name
     is the first thing under the band instead of a fragment inside it. */
  .dah-id { display: none; }
  .dah-actions { min-width: 0; flex: 1 1 auto; justify-content: stretch; }

  /* Sizes resolved from the old scrub at collapse = 1 — the condensed look,
     now permanent. The viewport cap stays: "ACQUIRE · £20.00" next to TALK
     and the share icon needs the type to yield on a 320px row.
     Note the endpoints are PLAIN LENGTHS with the cap applied to the result.
     Differencing two min()/clamp() expressions inside one calc() does not
     survive the vw terms — it silently evaluated to 0px, which shrank the
     buy button to 24px and hid its own label. */
  /* Retune the shared tokens rather than the individual buttons, so the
     square share icon tracks the new height automatically. */
  .dah {
    --dah-btn-pad-y: 0.46rem;
    --dah-btn-line: 0.95rem;
  }
  .dah-acquire {
    min-width: 0;
    letter-spacing: 0.08em;
    /* Grows to fill the row now that it is the only sizeable thing in it —
       the name has moved to the <h1> below at this width. */
    flex: 1 1 auto;
    padding-inline: 0.58rem;
    font-size: min(0.75rem, 3vw);
  }
  .dah-talk {
    flex: 0 0 auto;
    padding-inline: 0.5rem;
    font-size: min(0.7rem, 2.8vw);
  }

  /* ← CATALOG goes on phones — the nav and the OS back gesture both already
     do that job, and it was the least-used control in the band. That frees
     the width for share to stay at every size, which it now does. */
  .dah-back { display: none; }
  /* The header no longer prints the name at this width, so the real <h1>
     below stops being a duplicate and becomes visible again — it is the
     page's heading for screen readers and search engines either way. */
  .dossier-designation--compact .dossier-name {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
  }
}
/* Below ~340px even ACQUIRE + TALK + share won't fit: the share icon
   overflowed the S9+ (320px) by 14px. It's the least valuable of the three
   and the browser's own share sheet covers it, so it goes entirely rather
   than squeezing the two controls the band exists for. */
/* Share is kept at every width now. It used to be dropped below 340px, but
   that was to make room for ← CATALOG and a full-size buy button; with the
   back button gone from phones and the buttons at their compact size, all
   three controls fit a 320px row. */
/* ═══════════════════════════════════════════════════════════════════════
   SPECIMEN CHANNEL — conversation polish: speaker treatment, typing
   indicator (no more loading flash), readable type + message motion.
   Scoped to .glooom-specimen-messages so the inline dossier channel is
   left untouched.
   ═══════════════════════════════════════════════════════════════════════ */
.glooom-specimen-messages .channel-message {
  font-size: var(--fs-small);
  line-height: 1.7;
  letter-spacing: 0.03em;
  margin-bottom: 0.8rem;
  animation: ch-msg-in 240ms var(--ease) both;
}
@keyframes ch-msg-in { from { opacity: 0; transform: translateY(7px); } to { opacity: 1; transform: none; } }
/* Creature — left accent rail + speaker identity */
.glooom-specimen-messages .channel-message--creature {
  position: relative;
  padding-left: 0.75rem;
  border-left: 2px solid rgba(var(--violet-3), 0.4);
}
.glooom-specimen-messages .channel-message--creature .channel-msg-text {
  color: var(--ink);
  text-shadow: 0 0 10px rgba(var(--violet-4), 0.16);
}
.channel-speaker {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--fs-caption);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(var(--violet-3), 0.72);
  margin-bottom: 0.25rem;
}
.channel-speaker-av {
  width: 16px;
  height: 16px;
  object-fit: cover;
  border: 1px solid rgba(var(--violet-3), 0.4);
  border-radius: 50%;
  filter: saturate(0.85);
}
/* Observer — right-aligned, quieter, in a soft chip */
.glooom-specimen-messages .channel-message--user {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}
.glooom-specimen-messages .channel-message--user .channel-msg-text {
  color: rgba(var(--violet-2), 0.94);
  background: rgba(var(--violet-3), 0.08);
  border: 1px solid rgba(var(--violet-3), 0.16);
  padding: 0.3rem 0.55rem;
  max-width: 85%;
}
.channel-msg-who {
  font-size: var(--fs-caption);
  letter-spacing: 0.2em;
  color: var(--ink-faint);
  margin-top: 0.2rem;
}
/* Streaming cursor sits inline right after the streamed text */
.glooom-specimen-messages .channel-message--streaming::after { content: none; }
.glooom-specimen-messages .channel-message--streaming .channel-msg-text::after {
  content: "▋";
  margin-left: 2px;
  color: rgba(var(--violet-3), 0.85);
  animation: channel-blink 0.7s ease infinite;
}
/* Typing / connecting indicator */
.channel-typing-body { display: inline-flex; align-items: center; gap: 0.55rem; }
.channel-typing-dots { display: inline-flex; gap: 4px; align-items: center; }
.channel-typing-dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(var(--violet-3), 0.85);
  animation: ch-typing 1.1s ease-in-out infinite;
}
.channel-typing-dots i:nth-child(2) { animation-delay: 0.16s; }
.channel-typing-dots i:nth-child(3) { animation-delay: 0.32s; }
@keyframes ch-typing { 0%, 65%, 100% { opacity: 0.25; transform: translateY(0); } 32% { opacity: 1; transform: translateY(-3px); } }
.channel-typing-label {
  font-size: var(--fs-caption);
  letter-spacing: 0.14em;
  color: var(--ink-faint);
  font-style: italic;
}
/* Readable channel state lines */
.glooom-ch-state { font-size: var(--fs-small); color: var(--ink-dim); }
.glooom-ch-state-sub { font-size: var(--fs-caption); color: var(--ink-faint); }
/* ── Signal reveal — a seeded first-contact message breaking through, the
   first time it's seen. Self-contained (not scoped to .glooom-specimen-
   messages) since this bubble also renders inside the public dossier page's
   .dossier-channel-messages, which deliberately doesn't inherit the drawer's
   scoped chat styling. Technique borrowed from the Konami "breach" easter
   egg (static, scanlines, chromatic-aberration glitch) but in the site's
   own violet/toxic tokens, not that effect's hot-pink/teal. ── */
.channel-message--signal {
  position: relative;
  overflow: hidden;
}
.channel-message--signal::before {
  content: "";
  position: absolute; inset: -20%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.08;
  mix-blend-mode: screen;
  animation: signal-static 0.18s steps(4) 8;
  pointer-events: none;
}
.channel-message--signal::after {
  content: "";
  position: absolute; inset: 0;
  background: repeating-linear-gradient(180deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2px, rgba(0, 0, 0, 0.22) 3px);
  pointer-events: none;
  animation: signal-fade 1.6s ease-out forwards;
}
@keyframes signal-static {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-4%, 3%); }
  50%  { transform: translate(3%, -2%); }
  75%  { transform: translate(-2%, 2%); }
  100% { transform: translate(0, 0); }
}
@keyframes signal-fade { from { opacity: 1; } to { opacity: 0; } }
.channel-message--signal .channel-msg-text {
  position: relative;
  display: inline-block;
}
.channel-message--signal .channel-msg-text::before,
.channel-message--signal .channel-msg-text::after {
  content: attr(data-text);
  position: absolute; left: 0; top: 0; width: 100%;
  overflow: hidden;
  pointer-events: none;
}
.channel-message--signal .channel-msg-text::before {
  color: rgba(var(--violet-3), 0.6);
  clip-path: inset(0 0 55% 0);
  animation: signal-glitch-a 0.6s ease-out 3;
}
.channel-message--signal .channel-msg-text::after {
  color: rgba(var(--toxic), 0.55);
  clip-path: inset(55% 0 0 0);
  animation: signal-glitch-b 0.6s ease-out 3;
}
@keyframes signal-glitch-a {
  0% { transform: translate(-2px, -1px); } 25% { transform: translate(1px, 1px); }
  50% { transform: translate(-1px, 0); }   75% { transform: translate(2px, -1px); } 100% { transform: translate(0, 0); }
}
@keyframes signal-glitch-b {
  0% { transform: translate(2px, 1px); }  25% { transform: translate(-1px, -1px); }
  50% { transform: translate(1px, 1px); } 75% { transform: translate(-2px, 0); }   100% { transform: translate(0, 0); }
}
.channel-msg-caret {
  display: inline-block;
  margin-left: 2px;
  color: rgba(var(--violet-3), 0.85);
  animation: channel-blink 0.7s ease infinite;
}
@media (prefers-reduced-motion: reduce) {
  .channel-typing-dots i { animation: none; opacity: 0.7; }
  .glooom-specimen-messages .channel-message { animation: none; }
  .channel-message--signal::before,
  .channel-message--signal::after,
  .channel-message--signal .channel-msg-text::before,
  .channel-message--signal .channel-msg-text::after,
  .channel-msg-caret {
    animation-duration: 0.001s;
  }
}
/* ── Bottom surveillance log — readability + token pass ── */
.glooom-panel-msg { font-size: var(--fs-small); }
.glooom-panel-msg--assistant { color: var(--ink-strong); text-shadow: 0 0 10px rgba(var(--violet-3), 0.4); }
.glooom-panel-msg--nav { font-size: var(--fs-caption); color: rgba(255, 192, 112, 0.96); }
.glooom-panel-nav-label { font-size: 0.5rem; }
.glooom-panel-typing { padding: 0.15rem 0; }
/* ── Specimen channel — input/send + list readability (token pass) ── */
.glooom-specimen-input { font-size: var(--fs-small); }
.glooom-specimen-input:focus { border-bottom-color: rgba(var(--violet-3), 0.7); box-shadow: 0 1px 0 rgba(var(--violet-3), 0.3); }
.glooom-specimen-send {
  font-size: var(--fs-caption);
  background: rgba(var(--violet-3), 0.1);
  border-color: rgba(var(--violet-3), 0.5);
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
}
.glooom-specimen-send:hover:not(:disabled) { background: rgba(var(--violet-3), 0.2); box-shadow: 0 0 14px rgba(var(--violet-3), 0.25); }
.glooom-ch-list-name { font-size: var(--fs-small); }
.glooom-ch-list-meta { font-size: var(--fs-caption); color: rgba(var(--violet-3), 0.7); }
/* ═══════════════════════════════════════════════════════════════════════
   MOBILE — native-feel fixes: no focus-zoom, branded tap highlight,
   contained overscroll, and safe-area insets for the fixed bottom bar.
   ═══════════════════════════════════════════════════════════════════════ */
/* Branded tap highlight + no overscroll bounce/white edge */
* { -webkit-tap-highlight-color: rgba(155, 95, 255, 0.18); }
html { overscroll-behavior-y: none; }
/* iOS Safari zooms the page when a focused control is < 16px. Force >= 16px
   on phones so checkout / login / chat inputs never trigger the zoom jolt. */
@media (max-width: 600px) {
  input, select, textarea { font-size: 16px; }
}
/* The G.L.O.O.M. bar is position:fixed at the bottom on EVERY device, so
   every page needs the matching reserve — previously this only existed
   inside the @supports block below, which meant that on a laptop (or any
   non-notched phone) the bar sat on top of the last ~40px of the page and
   clipped whatever was there. On a product page that was the buy button. */
.crt-page { padding-bottom: 56px; }
/* Notched phones: keep the fixed G.L.O.O.M. bar + drawer above the home
   indicator, and grow the reserve to match. */
@supports (padding: env(safe-area-inset-bottom)) {
  .glooom-narrator { padding-bottom: calc(0.3rem + env(safe-area-inset-bottom)); }
  .glooom-panel    { bottom: calc(32px + env(safe-area-inset-bottom)); }
  .crt-page        { padding-bottom: calc(56px + env(safe-area-inset-bottom)); }
}
/* ── Checkout: Royal Mail delivery service picker ── */
.checkout-ship { display: flex; flex-direction: column; gap: 0.4rem; margin: 0.6rem 0; }
.checkout-ship-label {
  font-size: var(--fs-caption);
  letter-spacing: 0.18em;
  color: var(--ink-dim);
  text-transform: uppercase;
}
.checkout-ship-state { margin: 0.2rem 0; font-size: var(--fs-caption); color: var(--ink-faint); }
.checkout-ship-state--err { color: rgba(var(--blood), 0.85); }
.checkout-ship-opt {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  border: 1px solid rgba(var(--violet-3), 0.18);
  background: rgba(var(--violet-3), 0.04);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.checkout-ship-opt:hover { border-color: rgba(var(--violet-3), 0.4); }
.checkout-ship-opt--active {
  border-color: rgba(var(--violet-3), 0.7);
  background: rgba(var(--violet-3), 0.1);
  box-shadow: inset 0 0 14px rgba(var(--violet-4), 0.1);
}
.checkout-ship-opt input { accent-color: rgb(var(--violet-3)); flex-shrink: 0; }
.checkout-ship-opt-main { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; min-width: 0; text-align: left; }
.checkout-ship-opt-name { font-size: var(--fs-small); color: var(--ink); letter-spacing: 0.03em; }
.checkout-ship-opt-eta { font-size: var(--fs-caption); color: var(--ink-faint); }
.checkout-ship-opt-price { font-size: var(--fs-small); font-weight: 700; color: var(--ink-strong); white-space: nowrap; }
/* CHEAPEST / TRACKED marker on the two options shown up front, so the pair
   reads as a choice between two things rather than the top of a price list. */
.checkout-ship-opt-badge {
  display: inline-block;
  margin-left: 0.45rem;
  padding: 0.02rem 0.32rem;
  border: 1px solid rgba(var(--violet-3), 0.45);
  border-radius: 2px;
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: rgba(var(--violet-2), 0.95);
  vertical-align: 0.08em;
  white-space: nowrap;
}
.checkout-ship-opt--active .checkout-ship-opt-badge {
  border-color: rgba(var(--violet-3), 0.8);
  color: var(--ink-strong);
}
/* Discloses the remaining options. Deliberately quiet — it must not compete
   with the two real choices above it. */
.checkout-ship-more {
  align-self: flex-start;
  background: none;
  border: 1px dashed rgba(var(--violet-3), 0.35);
  color: var(--ink-faint);
  font-family: inherit;
  font-size: var(--fs-caption);
  letter-spacing: 0.1em;
  padding: 0.35rem 0.6rem;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.checkout-ship-more:hover { border-color: rgba(var(--violet-3), 0.6); color: var(--ink); }
.checkout-ship-retry {
  background: none; border: 1px solid rgba(var(--blood), 0.5); color: rgba(var(--blood), 0.95);
  font-family: inherit; font-size: var(--fs-caption); letter-spacing: 0.1em; padding: 0.1rem 0.4rem;
  cursor: pointer; margin-left: 0.3rem;
}
.checkout-ship-retry:hover { background: rgba(var(--blood), 0.1); }
/* Inline retry for transient load failures (shop / gloomopedia / product) */
.shop-retry-btn {
  background: none; border: 1px solid rgba(var(--violet-3), 0.5); color: rgba(var(--violet-3), 0.95);
  font-family: inherit; font-size: var(--fs-caption); letter-spacing: 0.14em; padding: 0.25rem 0.7rem;
  cursor: pointer; text-transform: uppercase;
}
.shop-retry-btn:hover { background: rgba(var(--violet-3), 0.12); }
/* ── Admin: product image manager (reorder / cover / bg-removal) ── */
.pim { width: 100%; }
.pim-head { display: flex; align-items: baseline; justify-content: space-between; gap: 0.5rem; margin-bottom: 0.5rem; flex-wrap: wrap; }
.pim-hint { font-size: var(--fs-caption); color: var(--ink-faint); }
.pim-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 0.6rem;
  padding: 0.6rem; border: 1px dashed rgba(var(--violet-3), 0.25); background: rgba(var(--surface-0), 0.5);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.pim-grid--drop { border-color: rgba(var(--violet-3), 0.7); background: rgba(var(--violet-3), 0.08); }
.pim-card {
  position: relative; aspect-ratio: 1 / 1; overflow: hidden; cursor: grab;
  border: 1px solid rgba(var(--violet-3), 0.25); background: #0a0518;
}
.pim-card--cover { border-color: rgba(var(--violet-3), 0.75); box-shadow: 0 0 0 1px rgba(var(--violet-3), 0.4); }
.pim-card--over { outline: 2px dashed rgba(var(--violet-3), 0.85); outline-offset: -2px; }
.pim-thumb {
  width: 100%; height: 100%; object-fit: cover; display: block;
  background-image: linear-gradient(45deg, #1a1228 25%, transparent 25%), linear-gradient(-45deg, #1a1228 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #1a1228 75%), linear-gradient(-45deg, transparent 75%, #1a1228 75%);
  background-size: 16px 16px; background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
.pim-cover-badge { position: absolute; top: 4px; left: 4px; font-size: 0.5rem; letter-spacing: 0.14em; background: rgba(var(--violet-3), 0.9); color: #fff; padding: 0.1rem 0.35rem; }
.pim-working { position: absolute; inset: 0; display: grid; place-items: center; background: rgba(2, 0, 6, 0.82); color: var(--ink-strong); font-size: var(--fs-caption); letter-spacing: 0.1em; }
.pim-actions { position: absolute; bottom: 0; left: 0; right: 0; display: flex; gap: 1px; opacity: 0; transition: opacity var(--dur-fast) var(--ease); }
.pim-card:hover .pim-actions { opacity: 1; }
.pim-actions button { flex: 1; background: rgba(2, 0, 6, 0.85); border: none; color: var(--ink); font-family: inherit; font-size: 0.56rem; letter-spacing: 0.06em; padding: 0.25rem 0; cursor: pointer; }
.pim-actions button:hover:not(:disabled) { background: rgba(var(--violet-3), 0.45); color: #fff; }
.pim-actions .pim-del:hover { background: rgba(var(--blood), 0.6); }
.pim-add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.15rem; aspect-ratio: 1 / 1; border: 1px dashed rgba(var(--violet-3), 0.4); background: rgba(var(--violet-3), 0.04); color: var(--ink-dim); cursor: pointer; font-family: inherit; }
.pim-add:hover { border-color: rgba(var(--violet-3), 0.7); background: rgba(var(--violet-3), 0.1); }
.pim-add-plus { font-size: 1.4rem; line-height: 1; }
.pim-add-label { font-size: var(--fs-caption); letter-spacing: 0.1em; }
.pim-add-sub { font-size: 0.5rem; color: var(--ink-faint); }
.pim-note { font-size: var(--fs-caption); color: var(--ink-faint); margin: 0.5rem 0 0; line-height: 1.4; }
/* ── Admin: crop / reframe modal ── */
.crop-overlay { position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center; background: rgba(2, 0, 6, 0.82); padding: 1rem; }
.crop-modal { width: min(420px, 95vw); background: rgba(var(--surface-1), 0.98); border: 1px solid rgba(var(--violet-3), 0.4); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6); padding: 1rem; }
.crop-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.7rem; }
.crop-x { background: none; border: none; color: var(--ink-dim); font-size: 1rem; cursor: pointer; }
.crop-x:hover { color: var(--ink-strong); }
.crop-stage { display: grid; place-items: center; padding: 0.4rem 0 0.8rem; }
.crop-frame { position: relative; overflow: hidden; background: #0a0518; border: 1px solid rgba(var(--violet-3), 0.5); cursor: grab; touch-action: none;
  background-image: linear-gradient(45deg, #1a1228 25%, transparent 25%), linear-gradient(-45deg, #1a1228 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #1a1228 75%), linear-gradient(-45deg, transparent 75%, #1a1228 75%);
  background-size: 18px 18px; background-position: 0 0, 0 9px, 9px -9px, -9px 0; }
.crop-frame:active { cursor: grabbing; }
.crop-frame img { user-select: none; -webkit-user-drag: none; }
.crop-loading { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink-faint); font-size: var(--fs-caption); }
.crop-grid { position: absolute; inset: 0; pointer-events: none; background-image: linear-gradient(rgba(255,255,255,0.12) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.12) 1px, transparent 1px); background-size: 33.33% 33.33%; }
.crop-aspects { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.6rem; }
.crop-aspect { background: rgba(var(--violet-3), 0.06); border: 1px solid rgba(var(--violet-3), 0.25); color: var(--ink-dim); font-family: inherit; font-size: var(--fs-caption); letter-spacing: 0.06em; padding: 0.3rem 0.5rem; cursor: pointer; }
.crop-aspect--active { border-color: rgba(var(--violet-3), 0.8); background: rgba(var(--violet-3), 0.16); color: var(--ink-strong); }
.crop-zoom { display: flex; align-items: center; gap: 0.6rem; font-size: var(--fs-caption); letter-spacing: 0.14em; color: var(--ink-dim); margin-bottom: 0.8rem; }
.crop-zoom input { flex: 1; accent-color: rgb(var(--violet-3)); }
.crop-foot { display: flex; gap: 0.6rem; }
.crop-foot .btn { flex: 1; }
/* ── Sticky buy bar on the product dossier ────────────────────────────────
   Present at every width and never fully removed. It used to slide away
   whenever another buy button was on screen, which left a dead zone between
   the two where nothing on screen could take money. It now minimises to a
   slim price rail instead: still visible, still clickable, but visually
   subordinate to the real button it duplicates. */
.dossier-buybar {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(40px + env(safe-area-inset-bottom, 0px)); /* sits above the G.L.O.O.M. bar */
  z-index: 480;
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem clamp(0.8rem, 4vw, 1.2rem);
  background: linear-gradient(180deg, rgba(12, 6, 24, 0.97), rgba(6, 3, 14, 0.98));
  border-top: 1px solid rgba(var(--violet-3), 0.4);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.5);
  transition: padding 240ms var(--ease), background 240ms var(--ease),
              box-shadow 240ms var(--ease), border-color 240ms var(--ease);
}
/* Minimised: a quiet rail. Height comes down, the name drops away, the
   button shrinks to a chip — but the price stays legible throughout. */
.dossier-buybar--min {
  padding-top: 0.22rem;
  padding-bottom: 0.22rem;
  background: linear-gradient(180deg, rgba(12, 6, 24, 0.86), rgba(6, 3, 14, 0.9));
  border-top-color: rgba(var(--violet-3), 0.22);
  box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.35);
}
.dossier-buybar--min .dossier-buybar-name { display: none; }
.dossier-buybar--min .dossier-buybar-price { font-size: var(--fs-small); color: var(--ink-dim); }
.dossier-buybar--min .dossier-buybar-btn {
  padding: 0.3rem 0.8rem;
  font-size: var(--fs-caption);
  background: transparent;
  border-color: rgba(var(--violet-3), 0.45);
  color: rgba(var(--violet-1), 0.9);
  box-shadow: none;
}
.dossier-buybar-info { display: flex; flex-direction: column; gap: 0.05rem; min-width: 0; flex: 1; }
.dossier-buybar-name { font-size: var(--fs-caption); color: var(--ink-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; letter-spacing: 0.04em; }
.dossier-buybar-price { font-size: var(--fs-body); font-weight: 700; color: var(--ink-strong); transition: font-size 240ms var(--ease), color 240ms var(--ease); }
.dossier-buybar-btn {
  flex-shrink: 0;
  font-family: "Share Tech Mono", "Courier New", monospace;
  font-size: var(--fs-small); font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 0.7rem 1.3rem;
  border: 1px solid rgba(var(--violet-3), 0.7);
  background: linear-gradient(180deg, rgba(var(--violet-3), 0.42), rgba(var(--violet-4), 0.44));
  color: #fff; cursor: pointer;
  transition: padding 240ms var(--ease), font-size 240ms var(--ease),
              background 240ms var(--ease), color 240ms var(--ease),
              border-color 240ms var(--ease);
}
.dossier-buybar-btn:disabled { opacity: 0.45; }
.dossier-buybar-btn:active:not(:disabled) { transform: translateY(1px); }
/* Desktop: the bar is centred to the content column rather than spanning the
   full width, so it reads as part of the dossier instead of a browser chrome
   bar pinned across a 2560px monitor. */
@media (min-width: 601px) {
  .dossier-buybar {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
    max-width: 720px;
    width: calc(100vw - 2rem);
    gap: 1rem;
    padding-left: 1.1rem;
    padding-right: 1.1rem;
    border: 1px solid rgba(var(--violet-3), 0.4);
  }
  .dossier-buybar--min { border-color: rgba(var(--violet-3), 0.22); }
}
@media (prefers-reduced-motion: reduce) {
  .dossier-buybar, .dossier-buybar-btn, .dossier-buybar-price { transition: none; }
}
/* The buy bar stacks on top of the G.L.O.O.M. bar, so a page carrying one
   needs more reserve than the global .crt-page value or the bar covers the
   foot of the dossier (the related-specimens grid). */
.crt-page:has(.dossier-buybar) { padding-bottom: 112px; }
@supports (padding: env(safe-area-inset-bottom)) {
  .crt-page:has(.dossier-buybar) { padding-bottom: calc(112px + env(safe-area-inset-bottom)); }
}
/* ── ADJACENT FILES — related specimens on the dossier ── */
.dossier-related { padding: 1rem var(--dossier-gutter) 1.4rem; }
.dossier-related-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 0.8rem; }
.dossier-related-card {
  display: flex; flex-direction: column; gap: 0.3rem; text-decoration: none;
  border: 1px solid rgba(var(--violet-3), 0.18); background: rgba(var(--surface-0), 0.6);
  padding: 0.45rem;
  transition: border-color var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease), box-shadow var(--dur-med) var(--ease);
}
.dossier-related-card:hover { border-color: rgba(var(--violet-3), 0.6); transform: translateY(-2px); box-shadow: 0 8px 22px rgba(var(--violet-4), 0.22); }
.dossier-related-img { aspect-ratio: 3 / 4; overflow: hidden; background: #0a0518; display: grid; place-items: center; }
.dossier-related-img img { width: 100%; height: 100%; object-fit: cover; }
.dossier-related-noimg { font-size: 0.5rem; letter-spacing: 0.14em; color: var(--ink-faint); }
.dossier-related-name { font-size: var(--fs-caption); color: var(--ink); letter-spacing: 0.05em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dossier-related-price { font-size: var(--fs-caption); font-weight: 700; color: rgba(var(--violet-2), 0.95); }
/* ── Containment toast — add-to-cart feedback ── */
.contain-toast {
  position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 16px); z-index: 600;
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.9rem; max-width: 92vw;
  background: rgba(var(--surface-1), 0.97);
  border: 1px solid rgba(var(--toxic), 0.5);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55), 0 0 18px rgba(var(--toxic), 0.18);
  font-size: var(--fs-caption); letter-spacing: 0.1em;
  color: var(--ink-strong); cursor: pointer;
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-med) var(--ease), transform var(--dur-med) var(--ease);
}
.contain-toast--show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.contain-toast-icon { color: rgba(var(--toxic), 0.95); animation: contain-pulse 1.2s ease-in-out infinite; }
@keyframes contain-pulse { 50% { opacity: 0.4; } }
.contain-toast-link { color: rgba(var(--toxic), 0.9); font-weight: 700; white-space: nowrap; }
/* ── Signal toast — the seeded first-contact message has actually landed.
   Same shape as .contain-toast, but violet-led (a "communication" moment,
   not an "acquisition" one) with entry-only glitch chrome borrowed from the
   in-channel signal reveal, settling to readable text after ~1.2s. ── */
.signal-toast {
  position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom, 0px));
  transform: translate(-50%, 16px); z-index: 600;
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.9rem; max-width: 92vw;
  background: rgba(var(--surface-1), 0.97);
  border: 1px solid rgba(var(--violet-3), 0.5);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55), 0 0 18px rgba(var(--violet-3), 0.2);
  font-size: var(--fs-caption); letter-spacing: 0.1em;
  color: var(--ink-strong); cursor: pointer;
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-med) var(--ease), transform var(--dur-med) var(--ease);
}
.signal-toast--show { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.signal-toast-icon { color: rgba(var(--violet-3), 0.95); animation: contain-pulse 1.2s ease-in-out infinite; }
.signal-toast-link { color: rgba(var(--toxic), 0.9); font-weight: 700; white-space: nowrap; }
.signal-toast-text {
  position: relative;
  display: inline-block;
}
.signal-toast--show .signal-toast-text::before,
.signal-toast--show .signal-toast-text::after {
  content: attr(data-text);
  position: absolute; left: 0; top: 0; width: 100%;
  overflow: hidden;
  pointer-events: none;
}
.signal-toast--show .signal-toast-text::before {
  color: rgba(var(--violet-3), 0.6);
  clip-path: inset(0 0 55% 0);
  animation: signal-glitch-a 0.5s ease-out 3;
}
.signal-toast--show .signal-toast-text::after {
  color: rgba(var(--toxic), 0.55);
  clip-path: inset(55% 0 0 0);
  animation: signal-glitch-b 0.5s ease-out 3;
}
@media (prefers-reduced-motion: reduce) {
  .signal-toast-icon,
  .signal-toast--show .signal-toast-text::before,
  .signal-toast--show .signal-toast-text::after {
    animation-duration: 0.001s;
  }
}
/* ── Shop: recently examined strip ── */
.shop-recent { width: 100%; max-width: 820px; margin: 0 auto 0.9rem; }
.shop-recent-label { display: block; font-size: var(--fs-caption); letter-spacing: 0.2em; color: var(--ink-faint); margin-bottom: 0.4rem; text-align: left; }
.shop-recent-row { display: flex; gap: 0.6rem; overflow-x: auto; scrollbar-width: none; }
.shop-recent-row::-webkit-scrollbar { display: none; }
.shop-recent-card {
  flex: 0 0 auto; display: flex; align-items: center; gap: 0.45rem;
  padding: 0.3rem 0.6rem 0.3rem 0.3rem; text-decoration: none;
  border: 1px solid rgba(var(--violet-3), 0.2); background: rgba(var(--violet-3), 0.05);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}
.shop-recent-card:hover { border-color: rgba(var(--violet-3), 0.55); background: rgba(var(--violet-3), 0.1); }
.shop-recent-card img { width: 30px; height: 30px; object-fit: cover; }
.shop-recent-name { font-size: var(--fs-caption); color: var(--ink-dim); letter-spacing: 0.05em; white-space: nowrap; }
@media (min-width: 1280px) { .shop-recent { max-width: 1180px; } }
/* ── Shop: loading skeleton cards ── */
.shop-skel { display: flex; flex-direction: column; gap: 0.45rem; border: 1px solid rgba(var(--violet-3), 0.12); background: rgba(var(--surface-0), 0.7); padding-bottom: 0.7rem; }
.shop-skel-img { aspect-ratio: 3 / 4; }
.shop-skel-img, .shop-skel-line {
  background: linear-gradient(100deg, rgba(var(--violet-3), 0.05) 40%, rgba(var(--violet-3), 0.12) 50%, rgba(var(--violet-3), 0.05) 60%);
  background-size: 200% 100%;
  animation: skel-sweep 1.4s ease-in-out infinite;
}
.shop-skel-line { height: 0.55rem; margin: 0 0.7rem; }
.shop-skel-line--w60 { width: 60%; }
.shop-skel-line--w40 { width: 40%; }
@keyframes skel-sweep { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .shop-skel-img, .shop-skel-line, .contain-toast-icon { animation: none; } }
/* ── Chat: whispers, surveillance flash, visible memory ── */
.channel-whisper {
  font-style: italic;
  font-size: 0.92em;
  color: rgba(var(--violet-2), 0.72);
  text-shadow: 0 0 8px rgba(var(--violet-4), 0.4);
  animation: whisper-flicker 2.6s ease-in-out infinite;
}
@keyframes whisper-flicker { 0%, 100% { opacity: 0.85; } 48% { opacity: 0.55; } 52% { opacity: 0.9; } }
.channel-monitoring {
  position: sticky;
  top: 0;
  z-index: 3;
  text-align: center;
  font-size: var(--fs-caption);
  letter-spacing: 0.2em;
  color: rgba(var(--amber), 0.95);
  background: linear-gradient(180deg, rgba(var(--amber), 0.12), rgba(var(--amber), 0.03));
  border: 1px solid rgba(var(--amber), 0.35);
  padding: 0.3rem 0.5rem;
  margin-bottom: 0.6rem;
  animation: monitor-blink 1.1s steps(2) infinite;
}
@keyframes monitor-blink { 50% { opacity: 0.55; } }
.channel-memory {
  font-size: var(--fs-caption);
  letter-spacing: 0.06em;
  color: var(--ink-faint);
  border-left: 2px solid rgba(var(--violet-3), 0.35);
  padding: 0.3rem 0.55rem;
  margin-bottom: 0.7rem;
  background: rgba(var(--violet-3), 0.04);
  font-style: italic;
}
.channel-memory-label { color: rgba(var(--violet-3), 0.8); font-style: normal; letter-spacing: 0.16em; }
/* ── Dossier: live vitals ── */
.dossier-vitals {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem 0.55rem;
  padding: 0.45rem var(--dossier-gutter);
  font-size: var(--fs-caption);
  /* 0.1em pushed the readout onto two lines in the right-hand column,
     orphaning "TEMP 11.9°C" on its own row under the rest of the strip. */
  letter-spacing: 0.06em;
  color: rgba(var(--toxic), 0.75);
}
.dossier-vitals-label { color: var(--ink-faint); letter-spacing: 0.2em; }
.dossier-vitals-item { display: inline-flex; align-items: center; gap: 0.35rem; }
.dossier-vitals-item b { color: rgba(var(--toxic), 0.98); font-weight: 700; }
.dossier-vitals-sep { color: rgba(var(--toxic), 0.3); }
.dossier-vitals-wave { width: 46px; height: 11px; color: rgba(var(--toxic), 0.9); }
.dossier-vitals-wave path { stroke-dasharray: 120; animation: vitals-trace 2.2s linear infinite; }
@keyframes vitals-trace { from { stroke-dashoffset: 240; } to { stroke-dashoffset: 0; } }
/* ── Dossier: sealed / transferred record ── */
.dossier-sealed-stamp {
  position: absolute;
  top: 50%; left: 50%;
  /* Width is capped to the photo it sits on (not the viewport), so the
     rotated stamp can never spill outside its own image — it wraps to a
     second line at narrow widths instead of overflowing sideways. */
  width: min(78%, 22rem);
  transform: translate(-50%, -50%) rotate(-9deg);
  text-align: center;
  font-size: clamp(0.68rem, 3.4vw, 1.5rem);
  font-weight: 700;
  letter-spacing: 0.2em;
  line-height: 1.3;
  color: rgba(var(--blood), 0.85);
  border: 3px double rgba(var(--blood), 0.7);
  padding: 0.4rem 0.7rem;
  background: rgba(2, 0, 6, 0.55);
  text-shadow: 0 0 14px rgba(var(--blood), 0.5);
  pointer-events: none;
  z-index: 3;
}
.dossier-sealed-line {
  text-align: center;
  font-size: var(--fs-caption);
  letter-spacing: 0.14em;
  color: rgba(var(--blood), 0.8);
  padding: 0.45rem var(--dossier-gutter);
}
/* ── Dossier: owner-exclusive treatment (never shown to non-owners) ── */
.dossier-owner-stamp {
  position: absolute;
  top: 0.7rem; right: 0.7rem;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.24em;
  color: rgba(var(--toxic), 0.95);
  border: 1px solid rgba(var(--toxic), 0.6);
  padding: 0.3rem 0.6rem;
  background: rgba(2, 0, 6, 0.6);
  text-shadow: 0 0 10px rgba(var(--toxic), 0.5);
  box-shadow: 0 0 12px rgba(var(--toxic), 0.25);
  pointer-events: none;
  z-index: 4;
}
.dossier-acq-val--owned {
  color: rgba(var(--toxic), 0.95);
  text-shadow: 0 0 8px rgba(var(--toxic), 0.35);
}
/* ── Gloomer companionship profile — the archive certifies cuteness ──
   Deliberately breaks the CRT's sharp grim vocabulary: rounded corners, warm
   pink, a wonky stamp. The joke is a corrupted horror archive filling in a
   pet-adoption card under protest. */
.gloomer-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  padding: 1.1rem 1.2rem 1.3rem;
  background:
    radial-gradient(ellipse at 85% 10%, rgba(255, 158, 210, 0.09), transparent 55%),
    rgba(20, 8, 26, 0.75);
  border: 1px solid rgba(255, 158, 210, 0.4);
  border-radius: 14px;
  box-shadow: 0 0 18px rgba(255, 158, 210, 0.12) inset, 0 0 14px rgba(255, 158, 210, 0.08);
  overflow: hidden;
}
.gloomer-card-hdr {
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.gloomer-card-face {
  font-size: 1.7rem;
  line-height: 1;
  color: rgba(255, 190, 225, 0.95);
  text-shadow: 0 0 12px rgba(255, 158, 210, 0.6);
  animation: gloomer-bob 2.6s ease-in-out infinite;
}
@keyframes gloomer-bob {
  0%, 100% { transform: translateY(0) rotate(-4deg); }
  50%      { transform: translateY(-3px) rotate(4deg); }
}
.gloomer-card-hdr-text { display: flex; flex-direction: column; gap: 0.2rem; }
.gloomer-card-title {
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: rgba(255, 190, 225, 0.96);
}
.gloomer-card-sub {
  font-size: 0.52rem;
  letter-spacing: 0.14em;
  color: var(--ink-faint);
}
.gloomer-card-rows { display: flex; flex-direction: column; gap: 0.55rem; }
.gloomer-card-row {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: 0.6rem;
  align-items: baseline;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
}
.gloomer-card-key {
  display: inline-flex;
  gap: 0.4rem;
  letter-spacing: 0.16em;
  font-size: 0.56rem;
  color: var(--ink-faint);
  /* long labels ("REFUSES TO SHARE A SHELF WITH") wrap inside their column */
  line-height: 1.5;
}
.gloomer-card-val { color: var(--ink); }
.gloomer-card-row--likes .gloomer-card-key span    { color: rgba(255, 120, 170, 0.95); }
.gloomer-card-row--likes .gloomer-card-val         { color: rgba(var(--toxic), 0.95); }
.gloomer-card-row--dislikes .gloomer-card-key span { color: rgba(var(--warn), 0.9); }
.gloomer-threat-meter { display: inline-flex; gap: 2px; margin-right: 0.55rem; vertical-align: middle; }
.gloomer-threat-cell {
  width: 8px; height: 10px;
  border: 1px solid rgba(var(--toxic), 0.5);
  border-radius: 2px;
  background: transparent;
}
.gloomer-threat-cell--on { background: rgba(var(--warn), 0.85); border-color: rgba(var(--warn), 0.9); }
.gloomer-threat-text { color: rgba(var(--toxic), 0.95); font-size: 0.6rem; letter-spacing: 0.08em; }
.gloomer-card-stamp {
  position: absolute;
  top: 0.9rem;
  right: -0.4rem;
  transform: rotate(8deg);
  font-size: 0.56rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  color: rgba(255, 120, 170, 0.95);
  border: 2px solid rgba(255, 120, 170, 0.7);
  border-radius: 6px;
  padding: 0.3rem 0.7rem;
  text-shadow: 0 0 8px rgba(255, 120, 170, 0.5);
  pointer-events: none;
}
.gloomer-card-footer {
  margin: 0;
  padding-top: 0.7rem;
  border-top: 1px dashed rgba(255, 158, 210, 0.3);
  font-size: 0.56rem;
  letter-spacing: 0.16em;
  color: rgba(255, 190, 225, 0.85);
}
/* Relationship chips — friends/enemies as linked pills */
.gloomer-chips { display: inline-flex; flex-wrap: wrap; gap: 0.35rem; }
.gloomer-chip {
  display: inline-block;
  padding: 0.18rem 0.55rem;
  border-radius: 999px;
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  border: 1px solid rgba(255, 158, 210, 0.5);
  color: rgba(255, 190, 225, 0.95);
  text-decoration: none;
}
.gloomer-chips--friend .gloomer-chip {
  border-color: rgba(var(--toxic), 0.55);
  color: rgba(var(--toxic), 0.95);
}
.gloomer-chips--enemy .gloomer-chip {
  border-color: rgba(var(--warn), 0.6);
  color: rgba(var(--warn), 0.95);
}
.gloomer-chip--link:hover {
  background: rgba(255, 158, 210, 0.12);
  text-shadow: 0 0 8px currentColor;
}
/* Speech bubble — the Gloomer gets a word in, in its own small voice */
.gloomer-bubble {
  position: relative;
  margin-top: 1.1rem;
  margin-left: 1.6rem;
  padding: 0.85rem 1rem;
  background: rgba(255, 158, 210, 0.06);
  border: 1px dashed rgba(255, 158, 210, 0.45);
  border-radius: 14px;
}
.gloomer-bubble::before {
  content: "";
  position: absolute;
  top: -0.55rem;
  left: 1.6rem;
  width: 0.9rem;
  height: 0.9rem;
  background: inherit;
  border-left: 1px dashed rgba(255, 158, 210, 0.45);
  border-top: 1px dashed rgba(255, 158, 210, 0.45);
  transform: rotate(45deg);
  background-color: #0d0618; /* solid so the seam doesn't show through */
}
.gloomer-bubble-label {
  display: block;
  margin-bottom: 0.35rem;
  font-size: 0.5rem;
  letter-spacing: 0.18em;
  color: var(--ink-faint);
}
.gloomer-bubble-text {
  margin: 0;
  font-size: 0.72rem;
  line-height: 1.6;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  color: rgba(255, 210, 235, 0.95);
}
.gloomer-bubble-text::before { content: "“"; }
.gloomer-bubble-text::after  { content: "”"; }
/* Time-in-containment counter — shelter-listing urgency */
.dossier-days-waiting {
  margin: 0.7rem 0 0;
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: rgba(255, 158, 210, 0.95);
  text-shadow: 0 0 10px rgba(255, 120, 170, 0.35);
}
@media (max-width: 560px) {
  .gloomer-card-row { grid-template-columns: 1fr; gap: 0.15rem; }
  .gloomer-card-stamp { position: static; align-self: flex-end; transform: rotate(-3deg); margin-top: -0.4rem; }
  .gloomer-bubble { margin-left: 0.4rem; }
}
@media (prefers-reduced-motion: reduce) {
  .channel-whisper, .channel-monitoring, .dossier-vitals-wave path, .gloomer-card-face { animation: none; }
}
/* ── Shop card: file-drawer treatment ── */
.product-card-wrap { --tc: 155, 95, 255; }
.product-card-wrap.tag-gloomers     { --tc: 110, 220, 80; }
.product-card-wrap.tag-gloomites    { --tc: 255, 140, 55; }
.product-card-wrap.tag-gloomybabies { --tc: 255, 90, 130; }
.product-card-wrap.tag-soulcollector{ --tc: 220, 55, 65; }
.product-card { position: relative; }
.product-card-stripe {
  position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 2;
  background: rgba(var(--tc), 0.85); box-shadow: 0 0 10px rgba(var(--tc), 0.5);
  transition: height var(--dur-fast) var(--ease);
}
.product-card:hover .product-card-stripe { height: 5px; }
.product-scan {
  position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, transparent, rgba(var(--tc), 0.16) 48%, rgba(var(--tc), 0.16) 52%, transparent);
  transform: translateY(-110%);
}
.product-card:hover .product-scan { animation: card-scan 0.7s ease-out; }
@keyframes card-scan { 0% { transform: translateY(-110%); opacity: 0.9; } 100% { transform: translateY(110%); opacity: 0; } }
.product-pill {
  display: inline-flex; align-items: center; gap: 0.3rem;
  font-size: 0.5rem; letter-spacing: 0.12em; padding: 0.12rem 0.42rem;
  border: 1px solid rgba(var(--violet-3), 0.28); white-space: nowrap;
}
.product-pill--available { color: rgba(var(--toxic), 0.95); border-color: rgba(var(--toxic), 0.4); }
.product-pill--low { color: rgba(var(--warn), 0.95); border-color: rgba(var(--warn), 0.4); }
.product-pill--sold, .product-pill--out { color: var(--ink-faint); border-color: rgba(var(--violet-3), 0.16); }
.product-sealed-stamp {
  position: absolute; top: 50%; left: 50%; z-index: 2;
  transform: translate(-50%, -50%) rotate(-8deg);
  font-size: clamp(0.55rem, 2.4vw, 0.7rem); font-weight: 700; letter-spacing: 0.22em;
  color: rgba(var(--blood), 0.92); border: 2px double rgba(var(--blood), 0.7);
  padding: 0.2rem 0.6rem; background: rgba(2, 0, 6, 0.62); text-shadow: 0 0 10px rgba(var(--blood), 0.5);
}
.product-btn { transition: color var(--dur-fast) var(--ease), letter-spacing var(--dur-fast) var(--ease); }
.product-card:hover .product-btn { color: rgba(var(--toxic), 0.95); letter-spacing: 0.18em; }
/* ── Dossier: price surfaced in the identity header ── */
.dah-price { display: flex; flex-direction: column; align-items: flex-end; line-height: 1; }
.dah-price-label { font-size: 0.5rem; letter-spacing: 0.18em; color: var(--ink-faint); }
.dah-price-val { font-size: var(--fs-body); font-weight: 700; color: #fff; text-shadow: 0 0 12px rgba(var(--violet-3), 0.55); }
/* Import-charges notice at checkout. Amber rather than violet: it's an
   advisory the shopper must actually read before paying, not page furniture. */
.checkout-customs {
  border: 1px solid rgba(245, 200, 66, 0.35);
  background: rgba(245, 200, 66, 0.05);
  padding: 0.7rem 0.8rem;
  margin-top: 0.9rem;
}
.checkout-customs-title {
  font-size: 0.46rem;
  letter-spacing: 0.16em;
  color: #f5c842;
  margin: 0 0 0.35rem;
}
.checkout-customs-body {
  font-size: 0.46rem;
  letter-spacing: 0.07em;
  line-height: 1.85;
  color: rgba(219, 190, 255, 0.9);
  margin: 0;
}
/* DDP variant — duty already collected. Toxic green rather than warning amber:
   this is reassurance, and it must not read as another thing to worry about. */
.checkout-customs--paid {
  border-color: rgba(120, 255, 172, 0.35);
  background: rgba(120, 255, 172, 0.05);
}
.checkout-customs--paid .checkout-customs-title { color: #78ffac; }
/* ═══════════════════════════════════════════════════════════════════════
   G.L.O.O.M. CORE BREACH — hidden easter egg (Konami code).
   Self-contained; only renders while .breach is mounted.
   ═══════════════════════════════════════════════════════════════════════ */
/* Whole-page shudder while the breach is live */
html.breach-live { animation: breach-shudder 0.18s steps(2) infinite; }
@keyframes breach-shudder {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-1px, 1px); }
  50%  { transform: translate(1px, -1px); }
  75%  { transform: translate(-1px, -1px); }
  100% { transform: translate(1px, 1px); }
}
.breach {
  position: fixed;
  inset: 0;
  z-index: 99999;
  overflow: hidden;
  background: radial-gradient(ellipse at 50% 40%, rgba(20, 4, 30, 0.92), rgba(2, 0, 6, 0.985) 70%);
  color: #d6ffe0;
  font-family: "Share Tech Mono", "Courier New", monospace;
  cursor: pointer;
  animation: breach-in 0.12s steps(2) both;
  display: grid;
  place-items: center;
  text-align: center;
  padding: clamp(1rem, 5vw, 3rem);
}
@keyframes breach-in {
  0%   { opacity: 0; filter: invert(1) brightness(3); }
  40%  { opacity: 1; filter: invert(0) brightness(2.4); }
  100% { opacity: 1; filter: none; }
}
/* Bright destabilising flash on wake */
.breach--wake::after {
  content: "";
  position: absolute; inset: 0;
  background: #fff;
  mix-blend-mode: overlay;
  animation: breach-flash 0.85s ease-out forwards;
  pointer-events: none;
}
@keyframes breach-flash {
  0%   { opacity: 0.9; }
  12%  { opacity: 0.1; }
  20%  { opacity: 0.7; }
  100% { opacity: 0; }
}
/* CRT power-off collapse on reseal */
.breach--collapse { animation: breach-collapse 0.72s cubic-bezier(0.5, 0, 0.2, 1) forwards; }
@keyframes breach-collapse {
  0%   { transform: scale(1, 1);       filter: brightness(1); }
  55%  { transform: scale(1.06, 0.012); filter: brightness(4); }
  70%  { transform: scale(1.2, 0.0018); filter: brightness(8); }
  100% { transform: scale(0, 0);        filter: brightness(14); opacity: 0; }
}
/* ── Layers ── */
.breach-static {
  position: absolute; inset: -20%;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  opacity: 0.10;
  mix-blend-mode: screen;
  animation: breach-static 0.16s steps(4) infinite;
  pointer-events: none;
}
@keyframes breach-static {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-6%, 4%); }
  50%  { transform: translate(5%, -5%); }
  75%  { transform: translate(-4%, 6%); }
  100% { transform: translate(6%, -3%); }
}
.breach-scan {
  position: absolute; inset: 0;
  background: repeating-linear-gradient(180deg, rgba(0, 0, 0, 0) 0, rgba(0, 0, 0, 0) 2px, rgba(0, 0, 0, 0.35) 3px);
  mix-blend-mode: multiply;
  pointer-events: none;
}
.breach-roll {
  position: absolute; left: 0; right: 0; height: 28%;
  background: linear-gradient(180deg, transparent, rgba(155, 95, 255, 0.10) 45%, rgba(46, 255, 213, 0.10) 55%, transparent);
  animation: breach-roll 2.4s linear infinite;
  pointer-events: none;
}
@keyframes breach-roll { 0% { top: -30%; } 100% { top: 100%; } }
/* ── Terminal text ── */
.breach-terminal {
  position: relative;
  z-index: 2;
  width: min(760px, 94vw);
  max-height: 86vh;
  overflow: hidden;
}
.breach-head {
  position: relative;
  margin: 0 0 1.2rem;
  font-size: clamp(1.1rem, 4.5vw, 2.2rem);
  letter-spacing: 0.18em;
  font-weight: 700;
  color: #fff;
  text-shadow: 0 0 18px rgba(155, 95, 255, 0.7);
}
.breach-head::before, .breach-head::after,
.breach-line--glitch::before, .breach-line--glitch::after {
  content: attr(data-text);
  position: absolute; left: 0; top: 0; width: 100%;
  overflow: hidden; pointer-events: none;
}
.breach-head::before { color: #ff2e88; clip-path: inset(0 0 55% 0); animation: glitch-a 1.7s infinite linear alternate-reverse; }
.breach-head::after  { color: #2effd5; clip-path: inset(55% 0 0 0); animation: glitch-b 1.3s infinite linear alternate-reverse; }
@keyframes glitch-a {
  0% { transform: translate(-3px, -1px); } 25% { transform: translate(2px, 1px); }
  50% { transform: translate(-2px, 0); }   75% { transform: translate(3px, -1px); } 100% { transform: translate(-1px, 1px); }
}
@keyframes glitch-b {
  0% { transform: translate(3px, 1px); } 25% { transform: translate(-2px, -1px); }
  50% { transform: translate(2px, 1px); } 75% { transform: translate(-3px, 0); } 100% { transform: translate(1px, -1px); }
}
.breach-log { display: flex; flex-direction: column; gap: 0.55rem; }
.breach-line {
  position: relative;
  margin: 0;
  font-size: clamp(0.72rem, 2.4vw, 0.95rem);
  letter-spacing: 0.05em;
  line-height: 1.5;
  color: rgba(214, 255, 224, 0.92);
  text-shadow: 0 0 8px rgba(46, 255, 213, 0.35);
  animation: breach-line-in 0.18s steps(2) both;
}
@keyframes breach-line-in { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }
.breach-line--glitch::before { color: #ff2e88; clip-path: inset(0 0 50% 0); animation: glitch-a 0.9s infinite linear alternate-reverse; }
.breach-line--glitch::after  { color: #2effd5; clip-path: inset(50% 0 0 0); animation: glitch-b 0.7s infinite linear alternate-reverse; }
.breach-line--big {
  font-size: clamp(1.1rem, 5vw, 2.1rem);
  font-weight: 700;
  letter-spacing: 0.24em;
  color: #fff;
  text-shadow: 0 0 22px rgba(255, 46, 136, 0.8), 0 0 40px rgba(155, 95, 255, 0.6);
  margin: 0.4rem 0;
}
.breach-line--typing { color: #fff; }
.breach-caret { color: #2effd5; animation: breach-blink 0.6s steps(1) infinite; }
@keyframes breach-blink { 50% { opacity: 0; } }
.breach-hint {
  margin: 1.6rem 0 0;
  font-size: 0.56rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(155, 95, 255, 0.55);
  animation: breach-blink 1.6s steps(1) infinite;
}
@media (prefers-reduced-motion: reduce) {
  html.breach-live { animation: none; }
  .breach, .breach-static, .breach-roll, .breach-head::before, .breach-head::after,
  .breach-line--glitch::before, .breach-line--glitch::after, .breach-caret { animation-duration: 0.001s; }
}
/* ═══════════════════════════════════════════════════════════════════════
   WIDE-SCREEN (laptop / desktop) LAYOUT — hybrid: use the width on grid &
   gallery pages, contain the over-stretched ones, scale the hero + titles,
   and frame the remaining margin as a CRT monitor. Text-heavy columns are
   left at a readable width on purpose.
   ═══════════════════════════════════════════════════════════════════════ */
@media (min-width: 1280px) {
  /* ── Grid / gallery containers spread out and gain columns ── */
  .shop-grid,
  .gpedia-cat-grid,
  .gpedia-grid,
  .claimed-grid,
  .shop-header,
  .shop-controls,
  .gpedia-masthead,
  .gpedia-itembar,
  .claimed-header,
  .claimed-count,
  .site-footer-top,
  .site-footer-links,
  .site-footer-bar {
    max-width: 1180px;
    margin-left: auto;
    margin-right: auto;
  }
  .shop-grid       { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }
  .gpedia-cat-grid { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); }
  .gpedia-grid     { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); }
  .claimed-grid    { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }

  /* ── Product dossier: contain the full-bleed giant into a centered document ── */
  .dossier-page { align-items: center; }
  .dossier-page > * { width: 100%; max-width: 1080px; }
  /* Show the photo at its true aspect ratio (no stretching), capped so a tall
     portrait shot doesn't become a full-screen wall; centred in its frame. */
  .dossier-hero-wrap .dossier-photo-inner { display: flex; justify-content: center; background: #0a0710; }
  .dossier-hero-wrap .dossier-photo-inner img {
    width: auto;
    max-width: 100%;
    max-height: 74vh;
    object-fit: contain;
  }

  /* ── Account: centred, comfortable (checkout is already capped at 900px) ── */
  .account-section { max-width: 880px; margin-left: auto; margin-right: auto; }

  /* ── Titles scale up to anchor the page ── */
  .gpedia-title  { font-size: clamp(2rem, 3.2vw, 3rem); }
  .admin-title   { font-size: clamp(1.4rem, 2.4vw, 2.1rem) !important; }

  /* ── Home hero: bigger, more cinematic ── */
  .app-logo.large { max-width: clamp(420px, 38vw, 600px); }
  .home-featured  { max-width: 1080px; }
  .home-tagline   { font-size: clamp(0.78rem, 1.25vw, 1rem); }

  /* ── Frame the remaining margin: deeper monitor bezel + vignette ── */
  .crt-screen {
    box-shadow:
      inset 0 0 140px rgba(0, 0, 0, 0.6),
      inset 0 0 56px rgba(160, 80, 255, 0.1),
      inset 0 0 0 1px rgba(155, 95, 255, 0.06);
  }
}
@media (min-width: 1600px) {
  .shop-grid,
  .gpedia-cat-grid,
  .gpedia-grid,
  .claimed-grid,
  .shop-header,
  .shop-controls,
  .gpedia-masthead,
  .gpedia-itembar,
  .claimed-header,
  .claimed-count,
  .site-footer-top,
  .site-footer-links,
  .site-footer-bar {
    max-width: 1360px;
  }
  .shop-grid     { grid-template-columns: repeat(auto-fill, minmax(245px, 1fr)); }
  .dossier-page > * { max-width: 1160px; }
  .home-featured    { max-width: 1200px; }
}
/* ═══════════════════════════════════════════════════════════════════════
   TABLET / LAPTOP LAYER — fills the 641–1279px gap that nothing else in
   this cascade addresses (see the responsive-overhaul plan for the full
   root-cause writeup).

   Rules:
   - min-width only. Every existing max-width query elsewhere is a mobile
     guard rail; this file never overrides anything below 641px, so mobile
     is structurally protected rather than merely carefully protected.
   - Breakpoint convention used throughout this file: 641 · 768 · 1024 ·
     1280 (matches 16-desktop.css's existing threshold) · 1600 (existing).
     CSS custom properties can't be used inside a media condition, and
     @custom-media needs a PostCSS plugin this project doesn't have, hence
     plain literals — kept to this one set rather than inventing new ones.
   - Legacy breakpoints elsewhere (600/601, 760, 779/780, 860) are left
     alone; they're load-bearing for specific components.
   - Appended as the last @import in index.css — nothing above is
     reordered, so the existing "DO NOT reorder" cascade contract holds.
   ═══════════════════════════════════════════════════════════════════════ */
/* ── Stage 3: fluid containers, 641px+ ──────────────────────────────────
   Same selector set 16-desktop.css caps at 1180/1360px, but via the fluid
   --w-* tokens instead of a fixed px — this is what actually closes the
   641–1279px dead zone (16-desktop.css only starts at 1280px). Because
   min() resolves to the same ceiling 16-desktop.css already uses, the two
   layers agree exactly at 1280px: no jump when dragging across it. */
@media (min-width: 641px) {
  .shop-grid, .shop-header, .shop-controls,
  .claimed-grid, .claimed-header, .claimed-count,
  .gpedia-cat-grid, .gpedia-grid, .gpedia-masthead, .gpedia-itembar,
  .site-footer-top, .site-footer-links, .site-footer-bar {
    max-width: var(--w-grid);
    margin-left: auto;
    margin-right: auto;
  }
  .home-featured  { max-width: var(--w-mid); }
  .blog-list      { max-width: var(--w-mid); }
  .gpedia-dossier { max-width: var(--w-prose); }
}
/* ── Stage 4: per-page fixes ─────────────────────────────────────────── */
/* Blog — worst offender: .blog-list was a fixed-width flex column at every
   size. Real columns from 1024px; .blog-card is internally flex-column so
   flipping the parent to grid doesn't touch its own layout algorithm.
   auto-fit (not auto-fill) collapses empty tracks instead of reserving
   them, so a sparse list (e.g. a single post) centers as one card instead
   of stretching/pinning left across a mostly-empty row — found live on a
   fresh blog with only one transmission published. */
@media (min-width: 1024px) {
  .blog-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 360px));
    gap: 1.2rem;
    justify-content: center;
  }
}
/* Shop — intermediate card density so cards don't balloon in the gap
   16-desktop.css doesn't cover (its own minmax(230px) only starts at 1280). */
@media (min-width: 641px) {
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
}
@media (min-width: 1024px) {
  .shop-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
}
/* Home hero — .app-logo.large only scales at ≥1280 today; a tablet gets the
   mobile 80vw-capped 320px logo under already-larger clamp() type. */
@media (min-width: 768px) {
  .app-logo.large { max-width: clamp(280px, 34vw, 420px); }
}
/* Claimed/archive grid — extra density once there's room. */
@media (min-width: 768px) {
  .claimed-grid { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}
/* Product dossier — single column below 1024px; containment kicks in at
   780px so the page doesn't run full-bleed on a tablet before the real
   two-column split below is wide enough to use. */
@media (min-width: 780px) {
  .dossier-page > * { max-width: var(--w-mid); }
}
/* Static info pages (About/FAQ/Shipping/Privacy/Terms — all share
   InfoPage.jsx) and the Account page — both were pinned to a flat 700/880px
   regardless of viewport (13-admin-checkout-info.css / 16-desktop.css),
   which reads fine at 700px real-world but leaves ~48% of a 1366px screen
   as pure dead margin either side. Found live during a full-site pass —
   outside the grid/shop/blog/dossier pages the original Stage 3/4 sweep
   covered. --w-prose is the right measure for both: long-form reading
   content, same as blog/gloomopedia entries. */
@media (min-width: 641px) {
  .info-header, .info-body, .account-section {
    max-width: var(--w-prose);
  }
}
/* Product dossier — real two-column layout, ≥1024px. .dossier-left (hero
   photo, name, compact buy box — see DossierLayout.jsx) sticks in view
   while .dossier-right (vitals, field notes, specs, full acquisition
   detail, channel, related) scrolls past it. Below this width both
   wrappers are unstyled block elements and stack in normal document
   order — the JSX split is a no-op on mobile/small-tablet by
   construction, same as everything else in this file. */
@media (min-width: 1024px) {
  .dossier-page {
    display: grid;
    grid-template-columns: minmax(320px, 38%) 1fr;
    column-gap: 2rem;
    align-items: start;
    /* The >* rule above caps every direct child (header, rule, left, right)
       at --w-mid individually; here the two columns need to share ONE
       centred measure instead, so it's overridden on the grid container. */
    max-width: var(--w-wide);
    margin: 0 auto;
  }

  /* Header and the bare top .dossier-rule stay full-width above the grid
     — grid-column: 1 / -1 spans both tracks without needing a wrapper. */
  .dossier-page > .dah,
  .dossier-page > .dah-sentinel,
  .dossier-page > .whimsy-header,
  .dossier-page > .dossier-meta-strip,
  .dossier-page > .glooom-strip,
  .dossier-page > .dossier-rule {
    grid-column: 1 / -1;
    max-width: none;
  }

  .dossier-left {
    grid-column: 1;
    position: sticky;
    /* Clears the sticky .dah header, which owns the top edge — without this
       offset the pinned photo/buy column slides underneath it while
       scrolling.
       The +1rem breathing space that used to be added here has gone: sticky
       `top` is honoured from the very first paint, not only once the element
       would scroll away, so it pushed the column 23px down its own grid row
       before the reader had scrolled at all. That stacked on the photo's own
       padding and left a 53px gap above the picture against a 31px inset
       either side of it. The photo's padding is the spacing now, in all four
       directions; this value only has to clear the band. */
    top: var(--dah-h, 3.5rem);
    align-self: start;
    max-width: none;
  }

  .dossier-right {
    grid-column: 2;
    min-width: 0;
    max-width: none;
  }
}
/* ── Stage 5: admin icon-rail sidebar, 861–1179px ───────────────────────
   Below 861px the sidebar goes off-canvas (see admin.css's own 860px
   query); above 1180px it's the full 232px label+icon sidebar. In between,
   the full sidebar was costing up to 244px of content width in a single
   pixel step at 861px — this rail recovers most of it without an
   off-canvas drawer on a screen that's plenty wide enough for a persistent
   sidebar. Markup is already <Icon/> + <span>label</span>, so hiding the
   span is enough; no structural change needed. */
@media (min-width: 861px) and (max-width: 1179px) {
  .admin-shell { --a-sidebar-w: 64px; }

  /* :not(.admin-nav-badge) — the badge is also a direct <span> child of
     .admin-nav-item (see AdminLayout.jsx); a bare > span selector here
     was hiding it outright, and no display:flex further down could undo
     that once display:none had already dropped its box entirely. Found
     via a real render: an order-count badge silently vanished in this
     exact width range instead of becoming the intended corner dot. */
  .admin-shell .admin-nav-item > span:not(.admin-nav-badge),
  .admin-shell .admin-sidebar-brand-text {
    display: none;
  }

  .admin-shell .admin-nav-item {
    justify-content: center;
    padding-inline: 0;
  }

  .admin-shell .admin-sidebar-brand {
    justify-content: center;
    padding-inline: 0.4rem;
  }

  /* .admin-nav-badge normally rides margin-left:auto next to the hidden
     label — with no label to push against it would center awkwardly, so
     it becomes a corner dot on the icon instead. */
  .admin-shell .admin-nav-item {
    position: relative;
  }
  .admin-shell .admin-nav-badge {
    display: block;
    position: absolute;
    top: 2px;
    right: 6px;
    margin-left: 0;
    min-width: 8px;
    width: 8px;
    height: 8px;
    padding: 0;
    font-size: 0;
  }
}
/* Order-detail fulfilment grid: 3-col base (admin.css), 1fr at ≤760px —
   nothing between, so it jumps straight to 1fr while the icon-rail range
   still has decent width. A 2-col middle step reads as a deliberate
   reflow instead of a premature collapse. */
@media (min-width: 761px) and (max-width: 1179px) {
  .admin-shell .adm-od-fulfil { grid-template-columns: 1fr 1fr; }
}
/* ── Stage 6: admin inline-style extraction ─────────────────────────────
   Only extracting styles a media query needs to reach — the ~90 purely
   cosmetic inline styles elsewhere in admin pages are left alone.
   admin.css is imported directly by AdminLayout.jsx, not via index.css, so
   its position relative to 07-admin-auth.css/13-admin-checkout-info.css
   depends on Vite chunking rather than source order — every rule here
   must win on .admin-shell specificity, not by assuming later load. */
.admin-shell .adm-col-narrow { max-width: 480px; margin: 0 auto; width: 100%; }
.admin-shell .adm-col-narrow--wide { max-width: 620px; }
/* min-width:0 on direct children — a 1fr grid track won't shrink below
   its content's intrinsic min-width by default, so a track can force the
   whole grid (and its card) wider than the viewport instead of wrapping.
   Same bug found and fixed in admin.css's .adm-od-grid/.adm-od-fulfil;
   applied here pre-emptively since these are the general-purpose grid
   utilities every admin form grid now reaches for. */
.admin-shell .adm-grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.admin-shell .adm-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 1rem; }
.admin-shell .adm-grid-2 > *,
.admin-shell .adm-grid-3 > * { min-width: 0; }
.admin-shell .adm-stack-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.6rem; }
@media (max-width: 640px) {
  .admin-shell .adm-grid-2,
  .admin-shell .adm-grid-3 {
    grid-template-columns: 1fr;
  }
}
/* .admin-form's 700px cap (07-admin-auth.css) also serves visitor-side auth
   screens, so it can't be edited directly — override under .admin-shell
   only, and only where a page actually wants the wider narrow-column
   treatment (AdminSettings below). */
.admin-shell .adm-col-narrow .admin-form { max-width: none; }
/* .adm-prod-row only reflows to two lines at ≤560px; between 561–860px the
   name column gets squeezed by the non-shrinking stock/actions groups on
   the same row. Wrap earlier so the name stays readable. */
@media (min-width: 561px) and (max-width: 860px) {
  .admin-shell .adm-prod-row { flex-wrap: wrap; row-gap: 0.55rem; }
  .admin-shell .adm-prod-main { flex: 1 1 100%; order: 1; }
  .admin-shell .adm-prod-thumb { order: 0; }
  .admin-shell .adm-prod-stock { order: 2; }
  .admin-shell .adm-prod-actions { order: 3; margin-left: auto; }
}
