﻿:root, [data-theme="dark"] {
  --rail-w: 104px;          /* width of the fixed left brand/nav rail (desktop) */
  --bg: #0d0f12;       /* gunmetal near-black (Obsidian Flat) — the deep stage the palette needs */
  --panel: #14171b;
  --panel2: #1c2026;
  --border: #23282f;
  --text: #e8edf2;
  --text2: #c3ccd6;
  --muted: #8a97a6;
  --accent: #0e9070;   /* deep emerald — matches the Obsidian hybrid + strain-orb palette */
  /* accent used AS TEXT (active tab/footer label, Patient Sign-In, nav logo).
     Defaults to --accent; themes whose accent is too light to read on their own
     light panels override this to a darker shade that clears WCAG AA (≥4.5:1). */
  --accent-text: var(--accent);
  --header: linear-gradient(90deg, #121519, #0d0f12);
  /* Brand gradient — leaf-green → DNA-teal → violet (ties the logo + CTAs together).
     Defined once; inherits across all themes so brand CTAs read on light & dark alike.
     A faint dark scrim is layered on top to keep white text legible over the light
     teal mid-stop (where centered button text lands). */
  --brand-grad: linear-gradient(rgba(0,0,0,.14), rgba(0,0,0,.14)), linear-gradient(105deg, #2ea36d 0%, #14b8a6 48%, #7458e6 100%);
  --brand-grad-soft: linear-gradient(rgba(0,0,0,.15), rgba(0,0,0,.15)), linear-gradient(105deg, rgba(46,163,109,.95), rgba(20,184,166,.92) 48%, rgba(116,88,230,.95) 100%);
  --brand-grad-soft-rev: linear-gradient(rgba(0,0,0,.15), rgba(0,0,0,.15)), linear-gradient(285deg, rgba(46,163,109,.95), rgba(20,184,166,.92) 48%, rgba(116,88,230,.95) 100%);
  --brand-grad-hover: linear-gradient(rgba(0,0,0,.06), rgba(0,0,0,.06)), linear-gradient(105deg, #35b87b 0%, #19cebd 48%, #856bf0 100%);
  --brand-glow: rgba(20,184,166,.42);
  /* ── Brand "glass fill" ───────────────────────────────────────────────
     The RENDERED deep-wet emerald — lit shoulder → body → shaded base — for
     ANY solid brand-green surface (toggles, pills, badges, active tabs).
     RULE: a brand-green fill ALWAYS pairs colour WITH this rendering; never a
     flat `background: var(--accent)`. Put white text on it (never --accent-text,
     which is the same emerald and vanishes). Source of truth:
     branding/tampee-strain-gem-palette.html (Option 1 "Deep Wet"). */
  --brand-fill: radial-gradient(120% 150% at 30% 16%,
    color-mix(in srgb, var(--accent) 54%, #fff) 0%,
    var(--accent) 42%,
    color-mix(in srgb, var(--accent) 30%, #000) 100%);
  --brand-fill-shadow: inset 0 1px 0 rgba(255,255,255,.34), inset 0 -5px 10px rgba(0,0,0,.45);
  /* pop-glow: makes bold dashboard text/SVG stand out — light halo on dark, dark on light */
  --pop-glow: rgba(255,255,255,.30);
}
[data-theme="light"] {
  --pop-glow: rgba(0,0,0,.34);
  --bg: #f4f6f8;
  --panel: #ffffff;
  --panel2: #eef1f5;
  --border: #d9e0e7;
  --text: #1a2129;
  --text2: #3a444f;
  --muted: #616d7a;
  --accent: #0e9070;          /* deep emerald brand accent (matches dark theme) */
  --accent-text: #0a6f4f;     /* darker emerald so small active labels clear AA on white */
  --header: linear-gradient(90deg, #e3f1ec, #ffffff);
}
[data-theme="natural"] {
  --bg: #f1ece0;
  --panel: #fbf8f1;
  --panel2: #ece4d4;
  --border: #d9cdb6;
  --text: #2c2a21;
  --text2: #4c4737;
  --muted: #6b634d;   /* was #7c7359 — 4.3:1 on the cream panels failed AA; darkened */
  --accent: #0e9070;          /* emerald brand accent on the warm cream surfaces */
  --accent-text: #0a6644;     /* darker emerald so active labels clear AA on cream */
  --header: linear-gradient(90deg, #e6ede0, #fbf8f1);
  --pop-glow: rgba(0,0,0,.30);
}
* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, sans-serif;
  background-color: var(--bg);
  background-repeat: no-repeat;
  background-position: right -30px bottom -30px;
  background-size: min(60vh, 520px);
  background-attachment: fixed;
  color: var(--text);
  height: 100vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding-left: var(--rail-w);   /* leave room for the fixed left rail */
}
/* let the Natural leaf watermark show through the main panel */
.detail { background: transparent; }

/* Animated brand background — the windloadcalc login "smoke/waves" video,
   recolored from blue to brand green via hue-rotate + a themed tint overlay.
   Sits behind everything and shows through the transparent .detail panel. */
.bg-animation {
  position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  background: radial-gradient(ellipse at 30% 20%, #12161b, #07090c 70%); /* fallback if video can't load */
}
.bg-video {
  position: absolute; top: 50%; left: 50%; min-width: 100%; min-height: 100%;
  width: auto; height: auto; transform: translate(-50%, -50%); object-fit: cover;
  /* green/teal brand tint, kept bright so the animated background reads clearly */
  filter: hue-rotate(-115deg) saturate(1.2) brightness(.9);
}
/* tint overlay — dark green-teal on dark theme (light text reads), light tint on
   light/natural themes (dark text reads). The video shimmers through underneath. */
.bg-overlay { position: absolute; inset: 0;
  background: linear-gradient(135deg, rgba(9,12,16,.50) 0%, rgba(7,10,14,.60) 100%); }
[data-theme="light"] .bg-overlay {
  background: linear-gradient(135deg, rgba(231,243,234,.30) 0%, rgba(240,245,249,.40) 100%); }
[data-theme="natural"] .bg-overlay {
  background: linear-gradient(135deg, rgba(231,239,224,.30) 0%, rgba(245,240,229,.40) 100%); }
/* keep the swirl bright & colorful under the lighter veil on the light themes */
[data-theme="light"] .bg-video, [data-theme="natural"] .bg-video {
  filter: hue-rotate(-115deg) saturate(1.35) brightness(1.08); }

/* Per-theme background videos (tie-dye, groovy, rasta, …): show the footage in its
   TRUE colors — drop the brand green hue-rotate — under a balanced neutral tint so
   text + cards stay readable while the motion shows clearly through. Toggled by JS
   setting data-bgvideo on .bg-animation when the active theme has its own clip. */
.bg-animation[data-bgvideo] .bg-video { filter: saturate(1.06) brightness(.96); }
.bg-animation[data-bgvideo] .bg-overlay {
  background: linear-gradient(135deg, rgba(7,9,13,.50) 0%, rgba(7,9,13,.62) 100%); }
/* Natural is a light theme (dark text) — keep a light wash over its cannabis clip. */
[data-theme="natural"] .bg-animation[data-bgvideo] .bg-overlay {
  background: linear-gradient(135deg, rgba(244,246,248,.34) 0%, rgba(238,243,235,.44) 100%); }
@media (prefers-reduced-motion: reduce) { .bg-video { display: none; } }
header {
  padding: 16px 24px;
  border-bottom: 1px solid var(--border);
  background: var(--header);
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  /* Above the search/Recreational-Medical row (.topbar z-index 2, sticky 6) and the
     mobile back bar (z-index 8) so the account sign-in popover (.acct-pop, which drops
     down OUT of the header into that row) layers ON TOP of them instead of behind.
     Stays below the nav scrim/drawer (85/90) and modals (9000). */
  z-index: 20;
  flex: none;
}
/* name + tagline ~1.5× larger now that the logo lives in the rail */
header h1 { font-size: 32px; margin: 0; font-weight: 800; line-height: 1.1; }
header .leaf { color: var(--accent); }
/* Brand wordmark — lime→teal gradient (same as the splash), so the name "Tampee"
   reads identically across splash, header and deck. On the light/cream themes a light
   gradient would wash out, so fall back to a solid deep emerald there. */
#brand-name {
  width: fit-content; max-width: 100%;   /* shrink to the word so the gradient maps to the text — matches the splash */
  /* RENDERED wordmark (like our orbs): a top sheen layer over the lime->teal hue gives
     glossy, lit-from-above letters; drop-shadows add edge definition, depth + a teal glow. */
  background:
    linear-gradient(180deg, rgba(255,255,255,.55) 0%, rgba(255,255,255,.08) 40%, rgba(0,0,0,.16) 100%),
    linear-gradient(92deg, #b6f24a, #2fe6a8 50%, #25dcdc);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 1px 0 rgba(0,0,0,.45)) drop-shadow(0 3px 6px rgba(0,0,0,.4)) drop-shadow(0 0 12px rgba(37,220,220,.38));
}
[data-theme="light"] #brand-name, [data-theme="natural"] #brand-name {
  background:
    linear-gradient(180deg, rgba(255,255,255,.4) 0%, rgba(255,255,255,.05) 42%, rgba(0,0,0,.14) 100%),
    linear-gradient(95deg, #2ea36d 0%, #0e9070 50%, #0c7d72 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.22));
}
header .tagline { color: var(--muted); font-size: 14.5px; }

/* clean brand lockup: logo + (name over tagline) */
.brand-lockup { display: flex; align-items: center; gap: 16px; min-width: 0; }

/* ── Full-height left rail = a "binder" of the brand marks ────────────
   A fixed vertical bar down the left edge holding one uniform slot per
   logo version, evenly filling the rail — no hero, no divider, no
   scrollbar. Each slot flexes to share the height equally, so however
   many versions there are, they always fit. Filled by rail-binder.js,
   which keeps every slot rotating to a different version. Page content
   is inset by --rail-w (on body). The hamburger lives top-right in the
   header. On phones the rail is hidden (menu = bottom tab bar). */
.rail {
  position: fixed; left: 0; top: 0; bottom: 0; width: var(--rail-w);
  display: flex; flex-direction: column; align-items: center;
  padding: 8px; z-index: 40;
  background: var(--panel); border-right: 1px solid var(--border);
  overflow: hidden;
}
/* the Orbit mark — our main brand logo, shown in the header; click → Explore Strains */
#brand-logo { display: block; flex: none; width: 52px; height: 52px; cursor: pointer; }
#brand-logo:hover { filter: drop-shadow(0 0 6px rgba(34,211,238,.4)); }
/* Until logo.js mounts the Orbit (#brand-logo is empty), hide the slot so the old
   ❧ glyph never flashes. In "off" mode app.v2.js fills it with a glyph → visible. */
#brand-logo:empty { visibility: hidden; }
/* The Orbit is neon-on-dark artwork; on the light-background themes (light, natural,
   hippie) its colours wash out and the glow halo blends into the pale header. Give it
   the dark stage it's designed for — a deep gunmetal "coin" (rendered, not flat) — so
   its ORIGINAL colours pop on any theme instead of fading. */
[data-theme="light"] header #brand-logo,
[data-theme="natural"] header #brand-logo,
[data-theme="hippie"] header #brand-logo {
  border-radius: 50%;
  background: radial-gradient(120% 120% at 38% 28%, #20262d 0%, #14171b 46%, #0b0d10 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10),
              inset 0 -6px 12px rgba(0,0,0,.55),
              0 2px 8px rgba(0,0,0,.26);
}

.rail-binder {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: flex; flex-direction: column; align-items: center;
  overflow: hidden;
}
.rail-binder .tl-logo {
  flex: 1 1 0; min-height: 0; width: 66px; height: auto;
  opacity: .9; transition: opacity .3s ease, transform .15s;
}
.rail-binder .tl-logo:hover { opacity: 1; transform: scale(1.08); }    /* ← binder mark width dial */

@media (max-width: 860px) {
  .rail { display: none; }          /* phones use the bottom tab bar for the menu */
  body { padding-left: 0; }
}

.brand-text { display: flex; flex-direction: column; min-width: 0; }

/* push the account pill + hamburger together to the far right as a group
   (the auto-margin lives here, not on .nav-toggle, so the Sign-in pill rides
   next to the hamburger instead of being stranded by the brand text) */
header .acct-slot { margin-left: auto; }

/* hamburger button */
.nav-toggle {
  flex: none; width: 42px; height: 42px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--panel2);
  display: grid; place-items: center; cursor: pointer; transition: border-color .15s, background .15s;
}
.nav-toggle:hover { border-color: var(--accent); }
.nav-toggle .bars,
.nav-toggle .bars::before,
.nav-toggle .bars::after { content: ""; display: block; width: 18px; height: 2px; background: var(--text); border-radius: 2px; }
.nav-toggle .bars { position: relative; }
.nav-toggle .bars::before { position: absolute; left: 0; top: -6px; }
.nav-toggle .bars::after { position: absolute; left: 0; top: 6px; }

/* slide-in navigation drawer */
.nav-scrim {
  position: fixed; inset: 0; background: rgba(0,0,0,.45);
  opacity: 0; pointer-events: none; transition: opacity .25s ease; z-index: 85;
}
/* drawer sits ABOVE the fixed bottom tab bar (z-index 70) so its lower items aren't
   hidden behind it; safe-area bottom padding keeps the last item reachable */
.nav-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; left: auto; width: 320px; max-width: 86vw; z-index: 90;
  transform: translateX(104%); transition: transform .3s cubic-bezier(.2,.8,.2,1);
  background: var(--panel); border-left: 1px solid var(--border);
  padding: 18px 16px calc(28px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: 6px; overflow-y: auto;
  box-shadow: -24px 0 60px -28px rgba(0,0,0,.6);
  overscroll-behavior: contain;
}
body.nav-open .nav-drawer { transform: none; }
body.nav-open .nav-scrim { opacity: 1; pointer-events: auto; }
.nav-head { display: flex; align-items: center; gap: 10px; font-size: 18px; font-weight: 800;
  padding: 4px 6px 14px; border-bottom: 1px solid var(--border); margin-bottom: 8px; }
/* drawer-header brand mark: the Orbit logo (mounted by logo.js). Sized down to
   sit beside "Tampee Menu"; overrides the .tl-logo default 40×50 box. */
.nav-head .nav-logo { width: 30px; height: 30px; margin: 0; flex: none; }
.nav-close {
  margin-left: auto; width: 34px; height: 34px; border-radius: 9px;
  border: 1px solid var(--border); background: var(--panel2); color: var(--text);
  font-size: 15px; line-height: 1; cursor: pointer; display: grid; place-items: center;
}
.nav-close:hover { border-color: var(--accent); color: var(--accent); }
.nav-list { display: flex; flex-direction: column; gap: 6px; }
.nav-item {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; text-decoration: none;
  padding: 13px 14px; border-radius: 12px; font-size: 15px; font-weight: 600;
  color: var(--text); background: transparent; border: 1px solid transparent; cursor: pointer;
}
.nav-item:hover { background: var(--panel2); border-color: var(--border); }
.nav-label { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin: 14px 6px 6px; }
/* Drawer sections (Browse / For You / Filters / Appearance) — collapsible groups
   styled identically to the Filters groups (.fgroup), so every section header is
   consistent: uppercase, muted, with a ▸ chevron. Default open (in markup). */
.nav-group { border-bottom: 1px solid var(--border); }
.nav-group:last-child { border-bottom: none; }
.nav-group > summary {
  cursor: pointer;
  padding: 9px 4px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
}
.nav-group > summary::-webkit-details-marker { display: none; }
.nav-group > summary::before { content: "▸"; font-size: 10px; transition: transform .15s; }
.nav-group[open] > summary::before { transform: rotate(90deg); }
.nav-group > summary:hover { color: var(--text); }
.nav-group[open] > summary { margin-bottom: 6px; }
/* the section divider is now owned by .nav-group; drop #filters' own bottom rule */
.nav-group #filters { border-bottom: none; padding-left: 4px; padding-right: 4px; }
.nav-drawer .theme-switch { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.nav-drawer .theme-switch button {
  flex: none; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 11px 4px; border-radius: 12px;
}
/* relocated browse controls fit the drawer cleanly */
.nav-drawer #tabs { padding: 0; border-bottom: none; margin-bottom: 6px; }
.nav-drawer .palate-btn { margin: 0 0 6px; }

/* header buttons: Dashboard (primary, the app's own home) + Patient Sign In (secondary, external) */
.header-btn {
  background: var(--brand-grad);
  border: 1px solid rgba(255, 255, 255, .25);
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .28);
  border-radius: 8px;
  padding: 6px 13px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 6px 16px -8px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .3);
  transition: filter .15s, box-shadow .2s;
}
.header-btn:hover { filter: brightness(1.06); box-shadow: 0 8px 20px -8px var(--brand-glow), inset 0 1px 0 rgba(255, 255, 255, .4); }

.patient-signin {
  background: transparent;
  border: 1px solid var(--accent);
  color: var(--accent-text);
  border-radius: 7px;
  padding: 6px 12px;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  line-height: 1;
}
.patient-signin:hover { background: var(--accent); color: #fff; }

/* theme switcher */
.theme-switch { display: flex; gap: 4px; }
.theme-switch button {
  background: var(--panel2);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 7px;
  padding: 5px 9px;
  font-size: 13px;
  cursor: pointer;
  line-height: 1;
}
.theme-switch button:hover { color: var(--text); border-color: var(--accent); transform: translateY(-1px); }
.theme-switch button.on { background: var(--panel); border-color: var(--accent); color: var(--text);
  box-shadow: 0 0 0 1px var(--accent), 0 5px 16px -8px var(--brand-glow); }
.theme-switch .th-ico { display: block; width: 28px; height: 28px; overflow: visible; }
.theme-switch .th-name { font-size: 10px; font-weight: 700; letter-spacing: .01em; line-height: 1; }

/* ---- animated theme icons ---- */
@keyframes i-spin { to { transform: rotate(360deg); } }
@keyframes i-sway { 0%,100% { transform: rotate(-7deg); } 50% { transform: rotate(7deg); } }
@keyframes i-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(.85); } }
@keyframes i-twinkle { 0%,100% { opacity: .25; } 50% { opacity: 1; } }
@keyframes i-huespin { to { transform: rotate(360deg); filter: hue-rotate(360deg); } }
@keyframes i-huepulse { 0% { transform: scale(.92); filter: hue-rotate(0); } 50% { transform: scale(1.05); } 100% { transform: scale(.92); filter: hue-rotate(360deg); } }
@keyframes i-glitch { 0%,44%,100% { transform: translate(0,0); filter: none; }
  50% { transform: translate(-1.2px,0); filter: drop-shadow(2px 0 #ff2bd0) drop-shadow(-2px 0 #19e3ff); }
  56% { transform: translate(1px,0); filter: drop-shadow(-1.5px 0 #ff2bd0); } }
.i-spin     { transform-box: fill-box; transform-origin: center; animation: i-spin 9s linear infinite; }
.i-spinslow { transform-box: fill-box; transform-origin: center; animation: i-spin 16s linear infinite; }
.i-sway     { transform-box: fill-box; transform-origin: 50% 100%; animation: i-sway 3.6s ease-in-out infinite; }
.i-sway-soft{ transform-box: fill-box; transform-origin: 50% 50%;  animation: i-sway 5s ease-in-out infinite; }
.i-pulse    { transform-box: fill-box; transform-origin: center; animation: i-pulse 2.6s ease-in-out infinite; }
.i-twinkle  { animation: i-twinkle 2.4s ease-in-out infinite; }
.i-huespin  { transform-box: fill-box; transform-origin: center; animation: i-huespin 6s linear infinite; }
.i-huepulse { transform-box: fill-box; transform-origin: center; animation: i-huepulse 5s ease-in-out infinite; }
.i-glitch   { transform-box: fill-box; transform-origin: center; animation: i-glitch 3.4s steps(1) infinite; }

.layout {
  display: grid;
  grid-template-columns: 300px 1fr;
  flex: 1;
  min-height: 0;
  position: relative;
  z-index: 1;
}

/* full-width search bar across the top of the main screen */
.topbar {
  flex: none; display: flex; align-items: center; gap: 10px 12px; flex-wrap: wrap;
  padding: 10px 18px; border-bottom: 1px solid var(--border);
  background: var(--header); position: relative; z-index: 2;
}
/* search keeps a usable width and the Rec/Medical toggle wraps below it when the
   row gets too tight — so what you're typing is never crushed off-screen */
.topbar .search-box { flex: 1 1 260px; position: relative; min-width: 0; }
.topbar .search-box #search { width: 100%; }
.topbar-meta { flex: none; display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted); white-space: nowrap; }
/* strain-list header — the title + the hide control live WITH the list */
.list-head {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 9px 10px 9px 14px; border-bottom: 1px solid var(--border);
  background: var(--panel);
}
.list-head-title { font-size: 12px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.list-head-n { color: var(--text); font-weight: 800; }
/* brand-glass fill + white chevron so the show/hide control is unmistakable */
.list-toggle {
  flex: none; width: 30px; height: 30px; border-radius: 8px; border: none;
  background: var(--brand-fill); color: #fff; cursor: pointer; display: grid; place-items: center;
  box-shadow: var(--brand-fill-shadow), 0 3px 10px -5px var(--brand-glow);
}
.list-toggle:hover { filter: brightness(1.08); }
/* chevron points left = collapse the list toward the edge */
.list-toggle .lt-ico { width: 7px; height: 7px; border-top: 2px solid #fff; border-right: 2px solid #fff; transform: rotate(-135deg); }

/* slim floating handle to bring the list back — only while collapsed */
.list-reopen {
  display: none; position: absolute; left: 12px; top: 12px; z-index: 3;
  align-items: center; gap: 7px; padding: 8px 14px 8px 11px; border: none;
  border-radius: 999px; background: var(--brand-fill); color: #fff; cursor: pointer;
  box-shadow: var(--brand-fill-shadow), 0 6px 18px -8px var(--brand-glow);
}
body.list-collapsed .list-reopen { display: inline-flex; }
.list-reopen:hover { filter: brightness(1.08); }
.list-reopen .lt-ico { width: 7px; height: 7px; border-top: 2px solid #fff; border-right: 2px solid #fff; transform: rotate(45deg); }  /* points right = expand */
.list-reopen .lr-label { font-size: 12px; font-weight: 800; letter-spacing: .03em; }

/* Rec/Medical segment now sits inline in the search row */
.topbar .menu-mode-seg { flex: none; }

/* ---- Recreational ⇄ Medical menu mode ----
   A segmented Rec/Medical toggle that sits inline in the search row (.topbar).
   Same strain library either way; maps to Dutchie's menuType. */
.menu-mode-seg {
  display: inline-flex; padding: 3px; gap: 3px; border-radius: 999px;
  background: var(--panel2); border: 1px solid var(--border);
}
.mm-opt {
  display: inline-flex; align-items: center; gap: 6px; padding: 7px 16px;
  border: none; border-radius: 999px; background: none; cursor: pointer;
  color: var(--muted); font-size: 13px; font-weight: 700; white-space: nowrap;
  transition: background .15s, color .15s;
}
.mm-opt .mm-i { display: inline-flex; align-items: center; justify-content: center; }
.mm-opt .mm-i svg { width: 14px; height: 14px; display: block; }
.mm-opt:hover { color: var(--text); }
/* active segment: rendered brand glass + WHITE text (readable on the emerald) */
.mm-opt.on { color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.45);
  background: var(--brand-fill);
  box-shadow: var(--brand-fill-shadow), 0 4px 12px -6px var(--brand-glow); }

/* ---- Dutchie commerce facts (price / stock / sizes) ----
   Only present on menu-connected strains (?dataset=dutchie-demo or a live store);
   the curated demo library renders none of this. */
.li-price { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; }
.stock-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; }
.stock-dot.in { background: #36c98e; box-shadow: 0 0 0 3px rgba(54,201,142,.16); }
.stock-dot.out { background: #e0683c; }

.commerce {
  margin: 14px 0 4px; padding: 14px 16px; border: 1px solid var(--border);
  border-radius: 14px; background: var(--panel2);
}
.commerce.oos { opacity: .9; }
.cm-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; }
.cm-price { display: flex; align-items: baseline; gap: 8px 10px; flex-wrap: wrap; }
.cm-amt { font-size: 28px; font-weight: 800; color: var(--text); line-height: 1; }
.cm-amt.na { font-size: 17px; font-weight: 700; color: var(--muted); }
.cm-mode { font-size: 11px; font-weight: 800; color: var(--accent-text); background: var(--accent); padding: 3px 9px; border-radius: 999px; letter-spacing: .01em; }
.cm-alt { font-size: 13px; color: var(--muted); text-decoration: line-through; }
.cm-save { font-size: 12px; font-weight: 800; color: #36c98e; }
.cm-stock { font-size: 13px; font-weight: 700; white-space: nowrap; }
.cm-stock.in { color: #36c98e; }
.cm-stock.out { color: #e0683c; }
.cm-meta { margin-top: 8px; font-size: 12.5px; color: var(--muted); }
.cm-actions { margin-top: 12px; }
.order-btn {
  font-size: 15px; font-weight: 700; padding: 12px 22px; min-height: 46px;
  border: none; border-radius: 12px; background: var(--accent); color: var(--accent-text);
  cursor: pointer; transition: filter .15s;
}
.order-btn:hover { filter: brightness(1.07); }
.cm-oos-note { font-size: 13px; color: var(--muted); }

/* collapsed strain list → detail takes the full width */
body.list-collapsed .sidebar { display: none; }
body.list-collapsed .layout { grid-template-columns: 1fr; }

/* cinematic entrance — the detail sections stagger in on each selection */
@keyframes tl-detail-in {
  from { opacity: 0; transform: translateY(10px); filter: blur(3px); }
  to   { opacity: 1; transform: none; filter: none; }
}
#detail > * { animation: tl-detail-in .42s cubic-bezier(.22,.61,.36,1) both; }
#detail > *:nth-child(1) { animation-delay: 0ms; }
#detail > *:nth-child(2) { animation-delay: 45ms; }
#detail > *:nth-child(3) { animation-delay: 90ms; }
#detail > *:nth-child(4) { animation-delay: 135ms; }
#detail > *:nth-child(5) { animation-delay: 180ms; }
#detail > *:nth-child(6) { animation-delay: 220ms; }
#detail > *:nth-child(n+7) { animation-delay: 260ms; }

/* ===== Side-by-side comparison ===== */
.compare-btn, .share-btn {
  background: var(--panel2); border: 1px solid var(--border); color: var(--text);
  border-radius: 7px; padding: 6px 13px; font-size: 13px; font-weight: 600; cursor: pointer;
  white-space: nowrap; line-height: 1;
}
.compare-btn:hover, .share-btn:hover { border-color: var(--accent); color: var(--accent); }

/* ===== Share modal (per-strain QR + link) ===== */
.share-modal { position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center; padding: 20px;
  background: rgba(0,0,0,.6); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.share-card { position: relative; width: 100%; max-width: 340px; text-align: center;
  background: var(--panel); border: 1px solid var(--border); border-radius: 18px; padding: 24px 22px;
  box-shadow: 0 34px 80px -30px #000; }
.share-close { position: absolute; top: 12px; right: 12px; width: 32px; height: 32px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--panel2); color: var(--text); cursor: pointer; font-size: 14px; }
.share-close:hover { border-color: var(--accent); color: var(--accent); }
.share-title { font-size: 18px; margin-bottom: 4px; }
.share-sub { font-size: 12.5px; color: var(--muted); margin-bottom: 16px; }
.share-qr { display: inline-block; background: #fff; border-radius: 14px; padding: 12px; box-shadow: 0 10px 26px -14px #000; }
.share-qr svg { display: block; border-radius: 6px; }
.share-link { display: flex; gap: 8px; margin-top: 16px; }
.share-link input { flex: 1; min-width: 0; background: var(--panel2); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); padding: 9px 10px; font-size: 12px; }
.share-copy { flex: none; background: var(--brand-grad); color: #fff; border: 1px solid rgba(255,255,255,.2);
  border-radius: 8px; padding: 9px 14px; font-weight: 600; cursor: pointer; font-size: 13px; text-shadow: 0 1px 2px rgba(0,0,0,.28); }
.share-actions { margin-top: 12px; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.share-native, .share-sms { background: var(--panel2); border: 1px solid var(--border); color: var(--text);
  border-radius: 8px; padding: 10px 16px; font-size: 13px; font-weight: 600; cursor: pointer; text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px; }
.share-native:hover, .share-sms:hover { border-color: var(--accent); color: var(--accent); }

/* ===== "How it works" info popover (reuses .share-modal scrim + .share-card shell) ===== */
.info-card { max-width: 400px; text-align: left; }
.info-title { font-size: 18px; font-weight: 700; margin-bottom: 12px; padding-right: 28px; }
.info-body { font-size: 14px; line-height: 1.55; color: var(--text); }
.info-body p { margin: 0 0 12px; }
.info-steps { margin: 0 0 12px; padding-left: 20px; display: grid; gap: 6px; }
.info-steps li { padding-left: 2px; }
.info-note { font-size: 13px; color: var(--muted); background: var(--panel2);
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; margin: 0; }
.info-ok { margin-top: 16px; width: 100%; background: var(--brand-grad); color: #fff;
  border: 1px solid rgba(255,255,255,.2); border-radius: 10px; padding: 11px 16px;
  font-weight: 600; font-size: 14px; cursor: pointer; text-shadow: 0 1px 2px rgba(0,0,0,.28); }
.info-ok:hover { filter: brightness(1.06); }
/* the small ⓘ help affordance — used inline (.info-i) and as a standalone dot (.info-dot) */
.info-i { font-size: 12px; opacity: .65; vertical-align: 1px; }
.info-dot { flex: none; width: 34px; padding: 0; background: var(--panel2);
  border: 1px solid var(--border); border-radius: 8px; color: var(--muted);
  font-size: 14px; cursor: pointer; }
.info-dot:hover { border-color: var(--accent); color: var(--accent); }
.lab-badge.tappable { cursor: pointer; }

/* mobile-first chrome — hidden on desktop, activated in the ≤860px media query */
.mobile-tabs { display: none; }
.m-back { display: none; }

.cmp-top { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.cmp-exit { background: var(--panel2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 8px 14px; cursor: pointer; font-size: 13px; }
.cmp-exit:hover { border-color: var(--accent); color: var(--accent); }
.cmp-title { margin: 0; font-size: 18px; }

.cmp-vs { display: flex; align-items: center; justify-content: center; gap: 18px; margin: 6px 0 22px; }
.cmp-strain { flex: 1; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; min-width: 0; }
/* Compare-page strain orbs are clickable → open that strain's detail */
.cmp-orb-open { cursor: pointer; transition: transform .14s ease, box-shadow .14s ease; }
.cmp-orb-open:hover { transform: scale(1.05); box-shadow: 0 6px 18px -6px rgba(0,0,0,.6); }
.cmp-orb-open:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(255,255,255,.5); }
.cmp-name { font-size: 17px; font-weight: 700; }
.cmp-meta { font-size: 12.5px; color: var(--muted); }
.cmp-select { margin-top: 8px; max-width: 100%; background: var(--panel2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13px; cursor: pointer; }
.cmp-select:hover { border-color: var(--accent); }
.cmp-score { flex: none; text-align: center; }
.cmp-pct { font-size: 42px; font-weight: 800; line-height: 1; background: linear-gradient(92deg, #0e9070, #0e8a8a 55%, #7a34b0); -webkit-background-clip: text; background-clip: text; color: transparent; }
.cmp-pct span { font-size: 22px; }
.cmp-pct-lbl { font-size: 11px; letter-spacing: .18em; text-transform: uppercase; color: var(--muted); margin-top: 4px; }

.cmp-breakdown { display: grid; gap: 8px; max-width: 520px; margin: 0 auto 24px; }
.cmp-donuts { display: flex; justify-content: center; gap: 30px; margin-bottom: 14px; flex-wrap: wrap; }

.cmp-venn { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; margin: 8px 0 22px; }
.venn-col { background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 12px; }
.venn-col.v-shared { border-color: #14b8a6; box-shadow: 0 0 0 1px #14b8a6, 0 10px 24px -14px var(--brand-glow); }
.venn-h { font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 9px; font-weight: 700; }
.venn-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.venn-none { color: var(--muted); opacity: .55; }
.chip.shared { background: var(--brand-grad); color: #fff; border-color: transparent; text-shadow: 0 1px 1px rgba(0,0,0,.25); }

/* ---- the +/✓ "add to compare" pill (list rows, rec cards, detail) ---- */
.cmp-add {
  flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: 50%; border: 1px solid var(--border); background: var(--panel2);
  color: var(--muted); font-size: 13px; font-weight: 700; line-height: 1; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s, transform .12s;
}
.cmp-add:hover { border-color: var(--accent); color: var(--accent); transform: scale(1.1); }
.cmp-add.on { color: #fff; border-color: rgba(0,0,0,.28);
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow), 0 4px 12px -5px var(--brand-glow); }
.fav-add .ti, .cmp-add .ti { width: 13px; height: 13px; display: block; }
.li-cmp { margin-left: 6px; }

/* ---- the ♥/♡ favorite toggle (list rows, rec cards, explore cards) ----
   Pink so it reads as "favorite", not the green "add to compare" pill. */
.fav-add {
  flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: 50%; border: 1px solid var(--border); background: var(--panel2);
  color: #e8557a; font-size: 14px; line-height: 1; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s, transform .12s;
}
.fav-add:hover { border-color: #e8557a; transform: scale(1.1); }
.fav-add.on { color: #fff; border-color: rgba(0,0,0,.25);
  background: radial-gradient(120% 150% at 30% 16%, color-mix(in srgb, #ff6fae 62%, #fff) 0%, #ec4d86 46%, color-mix(in srgb, #ec4d86 32%, #000) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.42), inset 0 -4px 8px rgba(0,0,0,.32), 0 4px 13px -4px rgba(236,77,134,.6); }
.li-fav { margin-left: 6px; }

.rec-actions { display: inline-flex; align-items: center; gap: 8px; }
.compare-btn.on { color: #fff; border-color: rgba(0,0,0,.28);
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow), 0 5px 14px -7px var(--brand-glow); }

/* "Go to Compare →" shortcut — appears beside the compare toggle once a strain
   is queued, so you can jump straight to the Compare page. */
.cmp-go-btn {
  border: 1px solid #0e9070; border-radius: 7px; padding: 6px 13px;
  font-size: 13px; font-weight: 700; cursor: pointer; white-space: nowrap; line-height: 1;
  color: #06210f; background: linear-gradient(135deg, #0c8a5f, #0e9070 55%, #12a079);
}
.cmp-go-btn:hover { filter: brightness(1.06); }
.cmp-go-btn[hidden] { display: none; }

/* ---- compare tray: floating bar that collects strains to compare ---- */
.compare-tray {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 75;
  background: var(--panel); border-top: 1px solid var(--border);
  box-shadow: 0 -12px 34px -20px rgba(0,0,0,.65);
  padding: 10px 18px calc(10px + env(safe-area-inset-bottom, 0px));
}
body.tray-open { padding-bottom: 84px; }
.tray-inner { max-width: 1100px; margin: 0 auto; display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
/* the lead doubles as a collapse toggle so the whole tray can fold to a thin bar */
.tray-collapse { flex: none; display: inline-flex; align-items: center; gap: 9px;
  background: none; border: none; color: var(--text); font: inherit; cursor: pointer; padding: 4px 2px; }
.tray-lead { font-weight: 800; font-size: 14px; display: flex; align-items: center; gap: 8px; }
.tray-count { font-size: 11px; color: var(--muted); font-weight: 700; }
.tray-chev { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; font-size: 12px; color: #fff;
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow); transition: transform .2s; }
.compare-tray.is-collapsed .tray-chev { transform: rotate(180deg); }
.compare-tray.is-collapsed .tray-chips,
.compare-tray.is-collapsed .tray-actions { display: none; }
.tray-chips { flex: 1 1 auto; min-width: 0; display: flex; gap: 8px; flex-wrap: wrap; }
.tray-chip { display: inline-flex; align-items: center; gap: 7px; background: var(--panel2);
  border: 1px solid var(--border); border-radius: 999px; padding: 4px 6px 4px 8px; font-size: 13px; cursor: pointer; }
/* lined-up (active) chip — brand glass so the chosen 2–4 read as selected */
.tray-chip.on { background: var(--brand-fill); border-color: transparent; color: #fff; box-shadow: var(--brand-fill-shadow); }
.tray-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 12px;
  line-height: 1; padding: 2px 5px; border-radius: 50%; }
.tray-x:hover { color: var(--text); background: var(--border); }
.tray-chip.on .tray-x { color: rgba(255,255,255,.85); }
.tray-actions { flex: none; display: flex; gap: 8px; }
.tray-go { border: none; border-radius: 10px; padding: 9px 16px; font-size: 14px; font-weight: 800; cursor: pointer;
  color: #06210f; background: linear-gradient(135deg, #0c8a5f, #0e9070 55%, #12a079); }
.tray-go:disabled { opacity: .45; cursor: not-allowed; filter: grayscale(.35); }
.tray-clear { background: transparent; border: 1px solid var(--border); color: var(--muted);
  border-radius: 10px; padding: 9px 14px; font-size: 13px; cursor: pointer; }
.tray-clear:hover { border-color: var(--accent); color: var(--text); }
.compare-tray.shake { animation: trayShake .4s; }
@keyframes trayShake { 0%,100%{transform:none} 20%,60%{transform:translateX(-7px)} 40%,80%{transform:translateX(7px)} }

/* compare-view selector strip — your saved list; tap a chip to choose the 2–4 to line up */
.cmp-selector { margin: 4px 0 18px; padding: 12px 14px; border: 1px solid var(--border);
  border-radius: 14px; background: var(--panel2); }
.cmp-sel-head { font-size: 12.5px; font-weight: 800; margin-bottom: 10px; }
.cmp-sel-head .muted { font-weight: 600; }
.cmp-sel-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.cmp-sel-chip { display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--border); border-radius: 999px;
  padding: 4px 6px 4px 8px; font-size: 13px; font-weight: 600; color: var(--text); }
.cmp-sel-chip.on { background: var(--brand-fill); border-color: transparent; color: #fff; box-shadow: var(--brand-fill-shadow); }
.cmp-sel-x { background: none; border: none; color: var(--muted); cursor: pointer; font-size: 12px;
  line-height: 1; padding: 2px 5px; border-radius: 50%; }
.cmp-sel-chip.on .cmp-sel-x { color: rgba(255,255,255,.85); }
.cmp-sel-x:hover { color: var(--text); background: var(--border); }
.cmp-sel-full { margin-top: 10px; font-size: 12.5px; color: var(--muted); }
.cmp-pick-more { padding: 18px 2px; }

/* toast — brief auto-dismissing message (e.g. compare list full) */
.tl-toast { position: fixed; left: 50%; bottom: 96px; transform: translate(-50%, 12px);
  z-index: 200; max-width: min(92vw, 420px); padding: 11px 16px; border-radius: 12px;
  background: var(--panel); border: 1px solid var(--border); color: var(--text);
  font-size: 13.5px; font-weight: 600; text-align: center;
  box-shadow: 0 14px 40px -16px rgba(0,0,0,.7);
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; }
.tl-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ---- 3–4 strain comparison: header cards, match matrix, shared/distinct grid ---- */
.cmpm-head { display: grid; gap: 12px; margin: 6px 0 16px; }
.cmpm-card { position: relative; background: var(--panel); border: 1px solid var(--border);
  border-radius: 14px; padding: 16px 8px 12px; display: flex; flex-direction: column; align-items: center;
  gap: 5px; text-align: center; min-width: 0; }
.cmpm-card .cmp-name { font-size: 14px; overflow-wrap: anywhere; }
.cmpm-x { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--border); background: var(--panel2); color: var(--muted); cursor: pointer; font-size: 11px; line-height: 1; }
.cmpm-x:hover { border-color: #e8557a; color: #e8557a; }

.cmp-addbar { display: flex; align-items: center; gap: 10px; margin: 2px 0 20px; flex-wrap: wrap; }
.cmp-addbar label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

/* typeable strain picker (replaces the native <select> in the compare view) */
.cmp-combo { position: relative; display: inline-block; max-width: 100%; margin-top: 8px; }
.cmp-addbar .cmp-combo { margin-top: 0; }
.cmp-combo-input { width: 240px; max-width: 100%; box-sizing: border-box; background: var(--panel2); border: 1px solid var(--border); color: var(--text); border-radius: 8px; padding: 9px 32px 9px 11px; font-size: 16px; }
.cmp-combo-input::placeholder { color: var(--muted); }
.cmp-combo-input:focus { outline: none; border-color: var(--accent); }
.cmp-combo-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 20px; height: 20px; display: flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 12px; line-height: 1; padding: 0; }
.cmp-combo-clear:hover { color: var(--text); }
.cmp-combo-list { position: absolute; top: calc(100% + 4px); left: 0; z-index: 60; width: 260px; max-width: 86vw; margin: 0; padding: 4px; list-style: none; background: var(--panel2); border: 1px solid var(--border); border-radius: 10px; max-height: 280px; overflow-y: auto; box-shadow: 0 12px 34px rgba(0,0,0,.5); }
.cmp-combo.combo-right .cmp-combo-list { left: auto; right: 0; }
.cmp-combo-opt { display: flex; align-items: center; gap: 9px; padding: 9px 10px; border-radius: 7px; cursor: pointer; font-size: 13px; }
.cmp-combo-opt:hover, .cmp-combo-opt.active { background: rgba(255,255,255,.07); }
.cco-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.cco-name { flex: 1; min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cco-type { font-size: 11px; color: var(--muted); flex: none; }
.cmp-combo-empty { padding: 10px; font-size: 13px; color: var(--muted); text-align: center; }

/* empty-state picker (nav → Compare with fewer than 2 strains queued) */
.compare-empty .cmp-hint { color: var(--muted); font-size: 14px; line-height: 1.55; max-width: 52ch; margin: 0 0 18px; }
.cmp-picks { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
.cmp-pick { display: inline-flex; align-items: center; gap: 8px; padding: 7px 10px 7px 12px; border: 1px solid var(--border); border-left-width: 3px; border-radius: 999px; background: var(--panel2); font-size: 13px; font-weight: 600; }
.cmp-pick-x { cursor: pointer; color: var(--muted); font-size: 12px; line-height: 1; padding: 2px; border-radius: 50%; }
.cmp-pick-x:hover { color: var(--text); }

/* one-tap "Your favorites" quick-add row on the Compare page */
.cmp-favs { margin: 0 0 16px; }
.cmp-favs label { display: block; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.cmp-favs-hint { text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--muted); opacity: .8; margin-left: 6px; }
.cmp-fav-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.cmp-fav-chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border: 1px solid var(--border); border-left-width: 3px; border-radius: 999px; background: var(--panel2); font-size: 13px; font-weight: 600; cursor: pointer; color: var(--text); }
.cmp-fav-chip:hover { border-color: var(--accent); color: var(--accent); }
.cmp-fav-chip.in { cursor: default; color: #0e9070; border-color: #0e9070; opacity: .9; }
.cmp-fav-chip.dis { cursor: not-allowed; color: var(--muted); opacity: .5; border-left-color: var(--border); }
.cmp-fav-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.cmp-matrix-wrap, .cmp-grid-wrap { overflow-x: auto; margin: 0 0 22px; }
.cmp-matrix, .cmp-grid { border-collapse: collapse; width: 100%; font-size: 13px; }
.cmp-matrix th, .cmp-matrix td, .cmp-grid th, .cmp-grid td {
  border: 1px solid var(--border); padding: 8px 10px; text-align: center; vertical-align: middle; }
.cmp-matrix th, .cmp-grid tr:first-child th { color: var(--muted); font-weight: 700; background: var(--panel); }
/* the empty top-left corner cell isn't a header — drop its box so it reads as blank */
.cmp-matrix tr:first-child th:first-child,
.cmp-grid tr:first-child th:first-child { background: transparent; border: none; }
.cmp-matrix .mx-row, .cmp-grid th:first-child { text-align: left; white-space: nowrap; }
.cmp-grid th:first-child { color: var(--text); }
.cmp-matrix .mx-self { color: var(--muted); opacity: .5; background: var(--panel2); }
.cmp-matrix .mx-cell { font-weight: 800; color: var(--text);
  background: linear-gradient(90deg, color-mix(in srgb, #0e9070 calc(var(--v) * 1%), transparent), transparent); }
.cmp-matrix .mx-cell span { font-size: 10px; color: var(--muted); }
.cmp-grid .ag-no { color: var(--muted); opacity: .4; }
.cmp-grid tr.ag-shared { background: color-mix(in srgb, #14b8a6 13%, transparent); }
.cmp-grid tr.ag-shared th:first-child { color: #12a079; }

@media (max-width: 860px) {
  .compare-tray { bottom: calc(56px + env(safe-area-inset-bottom, 0px)); padding-bottom: 10px; }
}
@media (max-width: 700px) {
  .cmp-venn { grid-template-columns: 1fr; }
  .cmp-vs { gap: 10px; }
  .cmp-pct { font-size: 32px; }
  .cmp-donuts { gap: 16px; }
  .cmp-name { font-size: 15px; }
  .tray-lead { font-size: 13px; }
  .tray-chip { font-size: 12px; }
  .tray-go, .tray-clear { padding: 8px 12px; font-size: 13px; }
}

/* sidebar */
.sidebar {
  border-right: 1px solid var(--border);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.search-wrap { padding: 14px; border-bottom: 1px solid var(--border); }
#search {
  width: 100%;
  padding: 10px 12px;
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 14px;
}
.search-box { position: relative; }
#search { padding-right: 34px; }
#search:focus { outline: none; border-color: var(--accent); }
.search-clear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: var(--border);
  color: var(--text);
  font-size: 12px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.search-clear:hover { background: var(--accent); color: #fff; }

.filter-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 10px;
  font-size: 12px;
  color: var(--muted);
}
.clear-btn {
  background: none;
  border: none;
  color: var(--accent);
  cursor: pointer;
  font-size: 12px;
  padding: 0;
}
.clear-btn:hover { text-decoration: underline; }

/* Browse — clean vertical nav rows (matches .nav-item / Filters, not pills) */
#tabs {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
}
.tab {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  padding: 13px 14px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 12px;
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.tab:hover { background: var(--panel2); border-color: var(--border); }
.tab.on { background: var(--panel2); border-color: var(--accent); color: var(--accent-text); }
.tab-n {
  margin-left: auto;
  background: var(--accent);
  color: #fff;
  border-radius: 9px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 700;
}

/* For You — clean vertical nav rows, consistent with Browse & Filters */
.palate-btn {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  margin: 0 0 6px;
  padding: 13px 14px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 12px;
  color: var(--text);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, border-color .15s;
}
.palate-btn:hover { background: var(--panel2); border-color: var(--border); }
.palate-btn:active { background: var(--panel2); transform: translateY(1px); }
.palate-btn .tab-n { margin-left: auto; }
.palate-empty { padding: 30px 4px; }
.palate-empty h2 { font-size: 24px; margin: 0 0 8px; }

#filters {
  flex-shrink: 0;
  max-height: 36vh;
  overflow-y: auto;
  border-bottom: 1px solid var(--border);
  padding: 6px 10px;
}
.fgroup { border-bottom: 1px solid var(--border); }
.fgroup:last-child { border-bottom: none; }
.fgroup > summary {
  cursor: pointer;
  padding: 9px 4px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  user-select: none;
}
.fgroup > summary::-webkit-details-marker { display: none; }
.fgroup > summary::before { content: "▸"; font-size: 10px; transition: transform .15s; }
.fgroup[open] > summary::before { transform: rotate(90deg); }
.fgroup > summary:hover { color: var(--text); }
.fcount {
  background: var(--accent);
  color: #fff;
  border-radius: 9px;
  padding: 1px 7px;
  font-size: 11px;
  letter-spacing: 0;
}
.fchips { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 2px 12px; }
.fchip {
  background: linear-gradient(180deg, color-mix(in srgb, #fff 9%, var(--panel2)), var(--panel2));
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: 12px;
  padding: 5px 11px;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 2px 6px -3px rgba(0,0,0,.5);
  transition: background .12s, border-color .12s, box-shadow .12s, transform .1s;
}
.fchip:hover { border-color: var(--accent); transform: translateY(-1px); }
.fchip.on { color: #fff; border-color: rgba(0,0,0,.22);
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow), 0 4px 12px -6px var(--brand-glow); }

/* personalize panel */
/* Personalize uses the reversed brand gradient — subtly distinct from "Your Terpene DNA",
   still cohesive. White text + glass sheen carry across all themes. */
/* My Dashboard now matches the clean nav rows (was a reversed-gradient button) */
.profile-btn { background: transparent; }
.profile-btn:hover { background: var(--panel2); }
.emoji-thumb { display: flex; align-items: center; justify-content: center; font-size: 34px; }
.phead-actions { display: flex; gap: 8px; flex-shrink: 0; }
.pbtn {
  background: var(--accent); border: 1px solid var(--accent); color: #fff;
  border-radius: 8px; padding: 7px 12px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.pbtn.ghost { background: transparent; color: var(--muted); border-color: var(--border); }
.pbtn:disabled { opacity: .4; cursor: default; }
.pbtn:not(:disabled):hover { filter: brightness(1.08); }
.pgroup { margin: 28px 0; max-width: 820px; }
.pgroup > h4 { margin: 0 0 9px; font-size: 13px; font-weight: 600; color: var(--text); }
.pgroup h4 .muted { font-weight: 400; }
.puse-sub { margin: 10px 0; }
.puse-sub h5 { margin: 0 0 7px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 600; }
.pchips { display: flex; flex-wrap: wrap; gap: 7px; }
.pchip {
  background: linear-gradient(180deg, color-mix(in srgb, #fff 9%, var(--panel2)), var(--panel2));
  border: 1px solid var(--border); border-radius: 999px;
  color: var(--text); font-size: 12.5px; padding: 6px 13px; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 2px 6px -3px rgba(0,0,0,.5);
  transition: background .12s, border-color .12s, box-shadow .12s, transform .1s;
}
.pchip:hover { border-color: var(--accent); transform: translateY(-1px); }
/* per-terpene swatch inside an avoid chip — same rounded-square shape as the donut legend */
.terp-chip-dot { display: inline-block; width: 9px; height: 9px; border-radius: 3px;
  margin-right: 6px; vertical-align: middle; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
.pchip.on { color: #fff; border-color: rgba(0,0,0,.22);
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow), 0 4px 12px -6px var(--brand-glow); }
/* Selected chips have a bright green fill, so green-tinted glyphs — the Pre-roll
   leaf, ☘️🌲🧃🌿🍃🧪💚❇️ and green terpene dots (pinene/camphene/borneol) — would
   otherwise vanish into it. A dark contrast halo around each glyph restores
   legibility WITHOUT recolouring the emoji or losing the brand-green leaf.
   Three vehicles, one effect: text-shadow (emoji), drop-shadow (inline SVG),
   a heavier ring (terpene dots). Scoped to .on so unselected chips are untouched. */
.pchip.on { text-shadow: 0 0 2px rgba(0,0,0,.55), 0 0 4px rgba(0,0,0,.3); }
.pchip.on svg { filter: drop-shadow(0 0 .8px rgba(0,0,0,.6)) drop-shadow(0 0 1.4px rgba(0,0,0,.45)); }
.pchip.on .terp-chip-dot { box-shadow: 0 0 0 1px rgba(0,0,0,.55), 0 0 0 2.5px rgba(255,255,255,.22); }

/* Saved setups — named profile presets (the chip row at the top of Personalize) */
.pset-bar { margin-top: 4px; }
.pset-bar > h4 { display: flex; align-items: center; gap: 8px; }
.pset-bar .pset-info { width: 22px; height: 22px; min-height: 0; font-size: 12px; border-radius: 6px; line-height: 1; }
.pset-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch; }
.pset-wrap { display: inline-flex; align-items: stretch; }
.pset-chip {
  background: linear-gradient(180deg, color-mix(in srgb, #fff 9%, var(--panel2)), var(--panel2));
  border: 1px solid var(--border); border-radius: 14px;
  color: var(--text); font-size: 13px; font-weight: 600; padding: 7px 14px; cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 2px 6px -3px rgba(0,0,0,.5);
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.pset-chip:hover { border-color: var(--accent); }
.pset-chip.on { background: var(--brand-grad); color: #fff; border-color: transparent; box-shadow: 0 4px 14px -6px var(--brand-glow); }
.pset-wrap.active .pset-chip.on { border-radius: 14px 0 0 14px; }
.pset-new { border-style: dashed; color: var(--muted); }
.pset-new:hover { color: var(--text); }
.pset-mini {
  background: var(--panel2); border: 1px solid var(--border); border-left: none;
  color: var(--muted); font-size: 12px; padding: 0 9px; cursor: pointer;
  display: inline-flex; align-items: center; transition: color .12s, border-color .12s;
}
.pset-mini { border-radius: 0; }
.pset-mini.pset-del { border-radius: 0 14px 14px 0; }
.pset-mini:hover { color: var(--text); border-color: var(--accent); }
.pset-save { margin-top: 12px; }
.pset-name-row { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; align-items: center; }
.pset-name-input {
  flex: 1 1 200px; min-width: 0; background: var(--panel2); border: 1px solid var(--accent);
  border-radius: 10px; color: var(--text); font-size: 14px; padding: 9px 12px; outline: none;
}
.pset-name-input::placeholder { color: var(--muted); }

/* the Explore scope ⓘ gets the brand accent so it reads as a tappable hint */
.exp-scopes .info-dot { color: var(--accent); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, var(--panel2)); }
.exp-scopes .info-dot:hover { color: var(--accent); background: color-mix(in srgb, var(--accent) 26%, var(--panel2)); }

#list { overflow-y: auto; flex: 1; padding: 8px; }
.list-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  font-size: 14px;
}
.list-item:hover { background: var(--panel2); }
.list-item.active { background: var(--panel2); box-shadow: inset 3px 0 0 var(--accent); }
/* Row pinned to the top because the selection is far down the (virtualised) list. */
.list-item.list-pinned { border-bottom: 1px solid var(--line, rgba(255,255,255,.08)); }
.li-main { flex: 1; display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.li-hint { font-size: 11px; color: var(--accent); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dots { display: inline-flex; gap: 3px; flex-shrink: 0; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }

/* aroma-bloom spheres */
.thumb {
  display: inline-flex;
  flex-shrink: 0;
  border-radius: 50%;
  line-height: 0;
  box-shadow: 0 1px 4px rgba(0,0,0,.35);
}
.thumb .bloom, .thumb-img { display: block; border-radius: 50%; object-fit: cover; }
.thumb.sm { vertical-align: middle; margin-right: 7px; }
.head-id { display: flex; align-items: center; gap: 16px; }
.li-name { flex: 1; }
.li-type { font-size: 12px; }
.star-sm, .star { color: #e8557a; }
.empty { color: var(--muted); padding: 16px; font-size: 13px; line-height: 1.5; }

/* identity / type swatches in the detail header */
.swatch {
  display: inline-block;
  width: 13px; height: 13px;
  border-radius: 4px;
  margin-right: 5px;
  vertical-align: middle;
}
.swatch.sm { width: 9px; height: 9px; border-radius: 3px; margin-right: 4px; }

/* detail action buttons (Save favorite / Notify) */
.detail-actions { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }
.fav-btn, .notify-btn {
  background: var(--panel2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  padding: 8px 12px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
.fav-btn:hover, .notify-btn:hover { border-color: var(--accent); }
.fav-btn.on { color: #fff; border-color: rgba(0,0,0,.25);
  background: radial-gradient(120% 150% at 30% 16%, color-mix(in srgb, #ff6fae 62%, #fff) 0%, #ec4d86 46%, color-mix(in srgb, #ec4d86 32%, #000) 100%);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), inset 0 -4px 9px rgba(0,0,0,.32), 0 6px 16px -6px rgba(236,77,134,.55); }

/* detail */
.detail {
  overflow-y: auto;
  /* side padding grows on wide screens to centre a ~1040px content column (keeps natural
     left-aligned flow + readable line lengths); the video shows through on either side */
  padding: 24px max(30px, calc((100% - 1040px) / 2)) 60px;
  min-height: 0;
}
.detail-head {
  border-left: 4px solid var(--accent);
  padding-left: 14px;
  margin-bottom: 6px;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.detail-head h2 { margin: 0; font-size: 26px; }
.star { font-size: 12px; vertical-align: middle; margin-left: 8px; font-weight: 600; }
.sub { color: var(--muted); margin-top: 4px; font-size: 14px; }
.desc { color: var(--text2); line-height: 1.6; max-width: 760px; font-size: 14px; }
.source { color: var(--muted); font-size: 12px; margin: 6px 0 0; font-style: italic; }

/* Real specimen photo — framed display on the strain detail page */
.specimen { margin: 18px 0 6px; width: max-content; max-width: 100%; }
.specimen-frame {
  position: relative;
  padding: 10px;
  border-radius: 16px;
  background: linear-gradient(160deg, rgba(255,255,255,.10), rgba(255,255,255,.02));
  border: 1px solid color-mix(in srgb, var(--frame, var(--accent)) 55%, transparent);
  box-shadow:
    0 0 0 1px rgba(0,0,0,.35) inset,
    0 14px 40px rgba(0,0,0,.45),
    0 0 26px color-mix(in srgb, var(--frame, var(--accent)) 30%, transparent);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  backdrop-filter: blur(10px) saturate(1.3);
}
.specimen-img {
  display: block;
  max-width: 420px;
  width: 100%;
  height: auto;
  border-radius: 9px;
  border: 1px solid rgba(0,0,0,.4);
}
.specimen figcaption {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text2);
  text-align: center;
  letter-spacing: .02em;
}
@media (max-width: 640px) {
  .specimen { width: 100%; }
  .specimen-img { max-width: 100%; }
}

.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 32px 64px; margin: 10px 0 24px; padding-top: 32px; border-top: 1px solid var(--border); max-width: 1040px; }
.terp-section { margin: 18px 0 8px; }
h3 { font-size: 14px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 0 0 12px; }

.bar-row { display: flex; align-items: center; gap: 10px; margin-bottom: 9px; font-size: 13px; }
.bar-label { width: 130px; flex-shrink: 0; }
.bar-label i { color: var(--muted); font-style: normal; font-size: 11px; }
.bar-track { flex: 1; height: 8px; background: var(--panel2); border-radius: 5px; overflow: hidden; }
.bar-fill { display: block; height: 100%; border-radius: 5px;
  /* glass tube: vertical specular band + dark rounded edges over a deepened color */
  background:
    linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 17%, rgba(255,255,255,.45) 32%, rgba(255,255,255,0) 52%, rgba(0,0,0,0) 76%, rgba(0,0,0,.5) 100%),
    linear-gradient(color-mix(in srgb,#000 16%,var(--c, var(--accent))), color-mix(in srgb,#000 16%,var(--c, var(--accent)))); }
.bar-val { width: 26px; text-align: right; color: var(--muted); }

.tags { display: flex; flex-direction: column; gap: 18px; margin: 16px 0 8px; max-width: 760px; }
.tag-label { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; margin-right: 8px; }
.chip {
  display: inline-block;
  padding: 5px 12px;
  margin: 3px 4px 3px 0;
  background: linear-gradient(180deg, color-mix(in srgb, #fff 9%, var(--panel2)), var(--panel2));
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 12px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 2px 6px -3px rgba(0,0,0,.5);
}
.chip.help { border-color: #2d5a44; color: #9fe3c0; }

.rec-title { margin-top: 32px; font-size: 15px; color: var(--text); }
.rec-title .muted { color: var(--muted); text-transform: none; letter-spacing: 0; font-weight: 400; }
.rec-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; max-width: 1040px; }
.rec-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px;
  cursor: pointer;
  transition: border-color .15s, transform .15s;
}
.rec-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.rec-top { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.rec-name { font-weight: 600; font-size: 15px; }
/* one consistent, bright pill with dark text — high contrast, no washed-out grey/white */
.match-badge { display: inline-flex; align-items: center; justify-content: center; text-align: center;
  min-width: 62px; padding: 4px 11px; border-radius: 999px; border: 1px solid rgba(0,0,0,.22);
  font-size: 12px; font-weight: 800; letter-spacing: .2px; color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.35);
  background: var(--brand-fill); box-shadow: var(--brand-fill-shadow), 0 4px 12px -6px var(--brand-glow); }
.rec-meta { color: var(--muted); font-size: 12px; margin-bottom: 10px; }
.rec-bars { display: flex; flex-direction: column; gap: 5px; }
.mini { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--muted); }
.mini > span:first-child { width: 56px; }
.mini-track { flex: 1; height: 5px; background: var(--panel2); border-radius: 3px; overflow: hidden; }
.mini-fill { display: block; height: 100%; border-radius: 3px;
  background:
    linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 17%, rgba(255,255,255,.45) 32%, rgba(255,255,255,0) 52%, rgba(0,0,0,0) 76%, rgba(0,0,0,.5) 100%),
    linear-gradient(color-mix(in srgb,#000 16%,var(--accent)), color-mix(in srgb,#000 16%,var(--accent))); }
.mini-val { width: 20px; text-align: right; }

/* animated bar fill */
.bar-fill { transition: width .85s cubic-bezier(.2,.7,.2,1); }

/* ===== Similarity Galaxy ===== */
.galaxy-block {
  margin: 14px 0 6px;
  /* Deep space — essentially black, with the faintest cosmic tint near the top so it reads as depth, not a flat panel. */
  background: radial-gradient(ellipse at 50% 34%, #0a0e1a 0%, #02030a 50%, #000 100%);
  border: 1px solid var(--border);
  border-radius: 12px;
  overflow: hidden;
}
.galaxy-block > summary {
  cursor: pointer;
  padding: 12px 16px;
  font-size: 13px;
  font-weight: 600;
  /* Galaxy panel is always dark, so the caption is always light — independent of theme. */
  color: #eaf2f8;
  list-style: none;
  user-select: none;
}
.galaxy-block > summary::-webkit-details-marker { display: none; }
.galaxy-block > summary .muted { font-weight: 400; color: #aebccb; }
/* narrow + centered so the dark side gutters are scroll-safe grab zones */
.galaxy-host { padding: 0 8px 10px; position: relative; display: flex; justify-content: center; }
.galaxy-svg { width: 100%; max-width: 560px; height: auto; display: block; margin: 0 auto; max-height: 54vh; }

/* pan-y = a vertical finger SCROLLS THE PAGE; horizontal still rotates (no scroll-trap).
   Mouse drag rotates fully; tap selects. Deep one-finger control lives in full screen. */
.galaxy-svg { touch-action: pan-y; cursor: grab; }
.galaxy-svg:active { cursor: grabbing; }

/* full-screen launcher (top-right over the galaxy) */
.galaxy-expand {
  position: absolute; top: 8px; right: 14px; z-index: 2;
  background: rgba(0,0,0,.45); border: 1px solid rgba(255,255,255,.2); color: #eaf2f8;
  border-radius: 8px; padding: 7px 11px; font-size: 12px; font-weight: 600; cursor: pointer;
  backdrop-filter: blur(4px);
}
.galaxy-expand:hover { border-color: var(--accent); }

/* immersive full-screen galaxy */
body.gfs-open { overflow: hidden; }
.galaxy-fs {
  position: fixed; inset: 0; z-index: 100;
  /* Full-screen = the deepest black, pure universe behind the orbs. */
  background: radial-gradient(ellipse at 50% 40%, #07090f 0%, #010206 55%, #000 100%);
  display: flex; flex-direction: column;
  padding-top: env(safe-area-inset-top);
}
.gfs-bar { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; gap: 10px; }
.gfs-title { color: #eaf2f8; font-weight: 700; font-size: 14px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gfs-tools { display: flex; align-items: center; gap: 8px; flex: none; }
.gfs-zoom, .gfs-close {
  width: 42px; height: 42px; border-radius: 11px; border: 1px solid rgba(255,255,255,.2);
  background: rgba(255,255,255,.08); color: #fff; font-size: 17px; cursor: pointer;
  display: grid; place-items: center;
}
.gfs-zoom { font-size: 24px; font-weight: 600; line-height: 1; }
.gfs-zoom:active { background: rgba(255,255,255,.2); }
.gfs-zoom:hover, .gfs-close:hover { border-color: var(--accent); }
.gfs-stage { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.gfs-stage .galaxy-svg { width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; touch-action: none; }
.gfs-hint { text-align: center; color: #aebccb; font-size: 12px; padding: 8px 16px calc(8px + env(safe-area-inset-bottom)); }
.gstars { pointer-events: none; }
.gstar { animation: twinkle var(--dur) ease-in-out var(--d) infinite; opacity: var(--o0); }
@keyframes twinkle { 0%, 100% { opacity: var(--o0); } 50% { opacity: var(--o1); } }
/* every sphere is clickable now (incl. the dimmed background strains) */
.gnode { cursor: pointer; transition: opacity .4s; }
.gbloom { pointer-events: none; transition: filter .15s; }
/* hover any sphere → it brightens to full + its name appears */
.gnode:hover { opacity: 1 !important; }
.gnode:hover .gbloom, .gnode:hover circle { filter: brightness(1.3); }
/* touch: first tap "arms" a background sphere (shows its name); tap again to open */
.gnode.preview { opacity: 1 !important; }
.gnode.preview .glabel { opacity: 1; }
.gnode.preview .gbloom, .gnode.preview circle { filter: brightness(1.35); }
/* Labels are sized in SVG viewBox units (1000-wide). On a phone the SVG scales
   to ~0.4×, so these need to be generous to stay readable on mobile. */
.glabel.show { font-size: 26px; font-weight: 700; }
.gnode .glabel {
  fill: #cdd7e1;
  font-size: 22px;
  opacity: 0;
  transition: opacity .3s;
  pointer-events: none;
  paint-order: stroke;
  stroke: #0d141b;
  stroke-width: 5px;
}
.gnode:hover .glabel, .gnode .glabel.show { opacity: 1; }
.gnode.sel .glabel { fill: #fff; font-weight: 800; font-size: 30px; }
.gedge { transition: opacity .5s; }
.gpulse { transform-origin: center; animation: galaxyPulse 1.8s ease-out infinite; }
@keyframes galaxyPulse {
  0%   { opacity: .9; transform: scale(.7); }
  70%  { opacity: 0;  transform: scale(2.4); }
  100% { opacity: 0;  transform: scale(2.4); }
}

/* lab badge */
.lab-badge {
  font-size: 11px;
  background: #1f3a2c;
  color: #7fe3b0;
  border: 1px solid #2d5a44;
  padding: 2px 8px;
  border-radius: 10px;
  vertical-align: middle;
  margin-left: 8px;
  font-weight: 600;
}

/* KPI row (animated count-up) */
.kpis { display: flex; flex-wrap: wrap; gap: 12px; margin: 16px 0 4px; max-width: 1040px; }
.kpi {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
  min-width: 110px;
}
.kpi-num { display: block; font-size: 24px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.kpi-lbl { display: block; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-top: 2px; }
.kpi-missing { opacity: .65; }
.kpi-missing .kpi-num { color: var(--muted); font-weight: 600; }

/* terpene donut */
.donut-wrap { position: relative; width: 200px; height: 200px; }
.donut { width: 200px; height: 200px; transform: rotate(0deg); filter: drop-shadow(0 0 7px rgba(20,184,166,.30)); }
.donut .seg { transition: stroke-dasharray .9s cubic-bezier(.2,.7,.2,1); }
.donut-center {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  pointer-events: none;
}
.dc-num { font-size: 28px; font-weight: 700; color: var(--text); }
.dc-num.sm { font-size: 17px; }
.dc-lbl { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }

/* full-width terpene band: helix | donut | leaf in one clean row, legend across the bottom */
/* no panel — the three visuals sit directly on the video background, each with a soft brand glow */
.terp-band {
  padding: 14px 4px 4px;
  max-width: 1040px;
}

.legend { display: flex; flex-flow: row wrap; justify-content: center; gap: 8px 26px; margin-top: 20px; }
.leg { display: flex; align-items: center; gap: 8px; font-size: 12.5px; flex: 0 0 auto; }
.leg-dot { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.leg-name { color: var(--text); }
.leg-val { color: var(--muted); font-variant-numeric: tabular-nums; }

/* Terpene DNA helix */
.dna-hero {
  display: flex;
  align-items: center;
  gap: 26px;
  background: radial-gradient(ellipse at 20% 50%, #14202c, #0d141b 70%);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px 22px;
  margin: 14px 0;
  flex-wrap: wrap;
}
.dna-host { flex-shrink: 0; }
.dna-svg { width: 110px; height: 230px; display: block; }
.dna-cap { flex: 1; min-width: 240px; }
.dna-cap h3 { color: var(--text); margin: 0 0 8px; text-transform: none; letter-spacing: 0; font-size: 17px; }
.dna-cap p { color: var(--text2); font-size: 13.5px; line-height: 1.6; margin: 0 0 12px; max-width: 520px; }
.dna-legend { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 18px; max-width: 440px; }
/* The helix renders + spins itself via the shared tlHelix rAF engine (nav-icons.js);
   it just needs a soft glow + a fixed box so the spin doesn't reflow the layout. */
.dna-svg { overflow: visible; filter: drop-shadow(0 0 8px rgba(37,220,220,.28)); }

.dna-kpi { display: flex; flex-direction: column; align-items: center; }
.dna-kpi .dna-svg { width: auto; height: 200px; }

.terp-viz { display: flex; align-items: center; justify-content: center; gap: 52px; flex-wrap: wrap; }
.leaf-kpi { display: flex; flex-direction: column; align-items: center; }
.leaf-svg { width: auto; height: 200px; display: block; filter: drop-shadow(0 0 7px rgba(20,184,166,.30)); }
.leaf-cap { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-top: 4px; }
.leaf-rise {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: leafRise 1s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes leafRise { from { transform: scaleY(0); } to { transform: scaleY(1); } }

.terp-missing {
  background: var(--panel);
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 16px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text2);
}
.tags.compact { margin-top: 18px; }

::-webkit-scrollbar { width: 10px; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 5px; }

/* ===========================================================
   MOBILE-FIRST RESPONSIVE — phones (iPhone / Android / Galaxy)
   Single column, locked viewport with an inner scroll region, touch-friendly.
   =========================================================== */
@media (max-width: 860px) {
  /* Locked-viewport app shell: the document itself NEVER scrolls (overflow-y:hidden),
     so two iOS Safari bugs go away —
       1) the fixed bottom tab bar can't be re-parented mid-scroll and drift to
          mid-screen (that bug only fires when <body> is the scroller), and
       2) there's no phantom empty screen below the content from the document's
          scroll height running taller than the viewport.
     Height: --app-h is the TRUE visible height, measured from window.visualViewport
     in app.v2.js (initViewportLock) and updated on every toolbar/keyboard change.
     We prefer it over 100dvh because iOS Safari's dvh goes stale in this exact
     setup — the document never scrolls (overflow:hidden below), so dvh never gets
     the scroll signal it needs to recompute, and the footer floats up with dead
     space below it. The cascade falls back 100vh → 100dvh → var(--app-h): each later
     line wins only where supported, so browsers without dvh or the Visual Viewport
     API still get a sane height. overflow-x:clip contains stray horizontal width
     WITHOUT turning <body> into a scroll container. The ONE scroll region is
     .layout (below). */
  html { height: 100vh; height: 100dvh; height: var(--app-h, 100dvh); }
  body {
    height: 100vh; height: 100dvh; height: var(--app-h, 100dvh);
    overflow-y: hidden; overflow-x: clip;
    -webkit-text-size-adjust: 100%;
  }

  /* mobile header: brand mark far-left, bigger name, hamburger top-right — one row */
  header { flex-wrap: nowrap; align-items: center; padding: 12px 14px; gap: 11px; }
  header #brand-logo { display: block; flex: none; width: 50px; height: 50px; }
  header .brand-text { flex: 1 1 auto; min-width: 0; }
  header h1 { font-size: 28px; line-height: 1.1; }
  header .tagline { font-size: 13px; }
  header .nav-toggle { align-self: flex-start; }

  /* the ONE scroll region — fills the gap between the fixed header/topbar above and
     the fixed bottom tab bar below. overscroll-behavior:contain stops a scroll that
     reaches the list's end from chaining out and rubber-banding the whole page. */
  .layout {
    display: block; flex: 1 1 auto; min-height: 0;
    overflow-y: auto; overflow-x: clip;   /* clip-x: never let the page shift sideways on a phone */
    -webkit-overflow-scrolling: touch; overscroll-behavior: contain;
  }

  /* sidebar becomes a top section that scrolls with the page */
  .sidebar { border-right: none; border-bottom: 1px solid var(--border); }
  #filters { max-height: none; }
  #list { max-height: 50vh; }

  .detail { height: auto; overflow: visible; padding: 18px 16px 56px; }

  /* stack the two-column areas */
  .cols { grid-template-columns: 1fr; gap: 18px; }
  .detail-head { flex-direction: column; align-items: stretch; }
  .detail-actions { width: 100%; flex-wrap: wrap; }
  .detail-actions .fav-btn, .detail-actions .compare-btn, .detail-actions .share-btn, .detail-actions .cmp-go-btn { flex: 1 1 calc(50% - 5px); text-align: center; }
  .detail-actions .notify-btn { flex: 1 1 100%; text-align: center; }   /* primary CTA spans the row */
  .detail-actions .info-dot { flex: 0 0 auto; }
  .head-id { gap: 12px; }
  .detail-head h2 { font-size: 21px; }

  .kpis { gap: 8px; }
  .kpi { min-width: 0; flex: 1 1 30%; padding: 10px 12px; }
  .kpi-num { font-size: 20px; }

  .terp-band { padding: 14px 8px 4px; }
  /* phones: donut on its own line, helix + leaf share the line below — equal height, tighter */
  .terp-viz { justify-content: center; gap: 18px 32px; }
  .terp-viz .donut-wrap { flex-basis: 100%; display: flex; justify-content: center; }
  .donut-wrap, .donut { width: 170px; height: 170px; }
  .dna-kpi .dna-svg, .leaf-svg { height: 170px; }
  .legend { gap: 7px 18px; }
  .dna-hero { flex-direction: column; align-items: center; text-align: center; padding: 16px; }
  .dna-legend { grid-template-columns: 1fr; text-align: left; }
  .rec-list { grid-template-columns: 1fr 1fr; }

  /* compact in-page preview on phones — scroll past it easily; tap ⛶ for the real thing */
  .galaxy-svg { max-height: 44vh; }
  .gfs-stage .galaxy-svg { max-height: none; }
  .galaxy-block > summary { font-size: 13px; }
  .galaxy-expand { top: 6px; right: 10px; padding: 9px 13px; font-size: 13px; min-height: 40px; }
  .gx-hint { display: none; } /* the drag/scroll hint is desktop-oriented; mobile uses full screen */

  /* ---- Mobile-friendly buttons & legibility ----
     Bigger, thumb-sized tap targets (≥44px per Apple HIG) and larger,
     higher-contrast text — easy on the eyes, easy to hit. */

  /* 16px inputs stop iOS Safari from auto-zooming the page on focus */
  #search { font-size: 16px; padding: 13px 40px 13px 14px; }
  .search-clear { width: 30px; height: 30px; font-size: 15px; }
  .filter-summary { font-size: 13px; }
  .clear-btn { font-size: 14px; padding: 8px 4px; }

  .header-btn, .patient-signin {
    font-size: 15px; padding: 11px 16px; min-height: 44px;
    display: inline-flex; align-items: center;
  }

  .theme-switch { gap: 6px; }
  .theme-switch button {
    font-size: 17px; padding: 10px 14px; min-height: 44px; min-width: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }

  .tab { font-size: 15px; padding: 14px 8px; min-height: 48px; gap: 8px; }
  .tab-n { font-size: 13px; padding: 2px 9px; }

  .palate-btn, .profile-btn {
    font-size: 16px; padding: 15px; min-height: 52px; margin: 0 12px 10px; gap: 8px;
  }

  /* filter chips — readable & tappable while you explore */
  .fgroup > summary { font-size: 14px; padding: 14px 4px; }
  .fchips { gap: 9px; padding: 6px 2px 14px; }
  .fchip {
    font-size: 14px; padding: 10px 16px; min-height: 42px;
    border-radius: 21px; display: inline-flex; align-items: center;
  }

  .pbtn { font-size: 15px; padding: 13px 18px; min-height: 48px; }

  /* detail action buttons (favorite / notify) */
  .detail-actions .fav-btn,
  .detail-actions .notify-btn,
  .detail-actions .compare-btn,
  .detail-actions .cmp-go-btn,
  .detail-actions .share-btn { font-size: 15px; padding: 14px 16px; min-height: 50px; }
  .detail-actions .info-dot { font-size: 16px; min-height: 50px; width: 50px; }

  /* ---- mobile-first: list ⇄ detail as separate full-screen views + bottom tab bar ---- */
  .topbar { position: sticky; top: 0; z-index: 6; }   /* sticky search in the list view */
  #list { max-height: none; padding-bottom: 16px; }   /* tab bar is in-flow below .layout now — no overlap to clear */
  .detail { padding-bottom: 24px; }

  /* show one view at a time (default = list) */
  body:not(.m-detail) .detail { display: none; }
  body.m-detail .sidebar { display: none; }
  body.m-detail .topbar { display: none; }

  /* search gets its own full row; the Rec/Medical toggle wraps beneath it, centered.
     The filter-status slot takes its own row too, so the toggle sits alone and the
     auto margins center it exactly (an empty slot collapses to no height). */
  .topbar .search-box { flex: 1 1 100%; }
  .topbar .menu-mode-seg { margin-inline: auto; }
  .topbar .topbar-meta { flex: 1 1 100%; justify-content: center; }
  /* collapsing the list on mobile reveals the detail/Explore beneath it
     (the toggle stays visible — it's a useful "hide the list" control here too) */
  body.list-collapsed .detail { display: block; }

  /* Explore landing: keep the search bar (with its inline Rec/Medical toggle) on
     top — no "← Strains" back bar (it's home) — so you see the KPIs and can search
     any strain from the same screen. */
  body.m-explore .topbar { display: flex; position: static; }
  body.m-explore.m-detail .m-back { display: none; } /* beats the m-detail back-bar rule below */

  /* sticky back bar, only in the detail view (fixed height so the Explore
     control panel can pin directly beneath it — see .explore .exp-sticky) */
  body.m-detail .m-back {
    display: inline-flex; align-items: center; gap: 8px; position: sticky; top: 0; z-index: 8;
    width: 100%; height: var(--m-back-h, 47px); padding: 0 16px; background: var(--header); border: none;
    border-bottom: 1px solid var(--border); color: var(--text); font-size: 15px; font-weight: 600; cursor: pointer;
  }
  body.m-detail .m-back:active { background: var(--panel2); }

  /* Bottom tab bar — IN-FLOW flex footer, NOT position:fixed.
     iOS Safari anchors `fixed; bottom:0` to the toolbar-retracted *layout*
     viewport, which is taller than the live visible (dvh) area while the
     toolbars are showing — so a fixed bar floats mid-screen with empty page
     below it (the bug in the screenshots). As the last child of the 100dvh
     flex-column <body>, with .layout (flex:1) absorbing the slack, this docks
     to the true visible bottom and tracks the toolbars exactly. */
  .mobile-tabs {
    display: flex; flex: none; position: static; z-index: 70;
    background: var(--panel); border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -8px 24px -16px rgba(0,0,0,.5);
  }
  .mtab {
    flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 6px 2px;
    background: none; border: none; color: var(--muted); font-size: 11px; font-weight: 600; cursor: pointer;
  }
  .mtab .mt-i { font-size: 19px; line-height: 1; }
  .mtab.on { color: var(--accent-text); }

  /* Compare tray — same fix: in-flow, sits just above the tab bar (its DOM
     order), not fixed. When empty it's [hidden] → takes no space and the tab
     bar docks straight under .layout; tray-open no longer needs reserved padding. */
  .compare-tray { position: static; flex: none; }
  body.tray-open { padding-bottom: 0; }
}

@media (max-width: 480px) {
  .rec-list { grid-template-columns: 1fr; }
  .kpi { flex: 1 1 45%; }
  .detail { padding: 16px 12px 56px; }
  .detail-head h2 { font-size: 19px; }
  header h1 { font-size: 24px; }
  header #brand-logo { width: 44px; height: 44px; }
  .dna-cap p { font-size: 13px; }
}

/* respect users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ===========================================================
   STRAIN EXPLORER — landing discovery view (dual sliders +
   live animated KPI dashboard). Vanilla SVG, reuses .kpis.
   =========================================================== */
.explore { max-width: 1040px; margin-inline: auto; }
.exp-note { color: var(--muted); font-weight: 600; }

.exp-scopes { display: flex; gap: 8px; flex-wrap: wrap; margin: 14px 0 20px; }
.exp-scope {
  background: var(--panel2); border: 1px solid var(--border); color: var(--text2);
  border-radius: 20px; padding: 8px 16px; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: border-color .15s, color .15s;
}
.exp-scope:hover { border-color: var(--accent); color: var(--text); }
.exp-scope.on { background: var(--brand-grad); color: #fff; border-color: transparent; box-shadow: 0 4px 14px -6px var(--brand-glow); }

.exp-slider { max-width: 680px; margin: 20px 0; }
.exp-slider-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.exp-axis { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; }
.exp-range { font-size: 13px; color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }
/* THC histogram — flex bars that fill the card height (so they grow tall and
   scale on resize). Each bar is STACKED by strain type: indica (purple) / hybrid
   (green) / sativa (yellow). Bars outside the selected THC range dim back. */
.hist-wrap { height: 34px; margin-bottom: 2px; }   /* base (detail view); explore overrides below */
.hbar {
  position: relative;
  flex: 1 1 0; min-width: 0; align-self: flex-end;
  /* padding:0 guards against the generic empty-state `.empty { padding:16px }`
     rule — an empty bar (sparse pool, e.g. Favorites) carries class "empty" and
     would otherwise inherit 32px of side padding, blowing the histogram (and the
     whole control panel) off the right of the screen. */
  padding: 0;
  display: flex; flex-direction: column;
  border-radius: 5px 5px 2px 2px; overflow: hidden;
  opacity: .34;
  transition: height .3s cubic-bezier(.2,.7,.2,1), opacity .25s ease, filter .25s ease;
}
.hbar.on { opacity: 1; }
.hbar.empty { background: rgba(255,255,255,.10); }
/* each type-segment is a glossy tube: bright sheen at top, the vivid color, a touch
   of shade at the base — the same lit, candy-gloss read as the strain orbs */
.hbar i {
  display: block; width: 100%;
  /* 3D GLASS TUBE — same material as the orbs: a rounded-cylinder cross-section
     (dark left/right edges + a bright vertical specular just left of center) painted
     over a deepened color. Whole-bar top sheen + base shadow are added via ::before/::after. */
  background:
    linear-gradient(90deg,
      rgba(0,0,0,.55) 0%, rgba(0,0,0,0) 23%,
      rgba(255,255,255,.38) 38%, rgba(255,255,255,0) 53%,
      rgba(0,0,0,0) 77%, rgba(0,0,0,.55) 100%),
    linear-gradient(color-mix(in srgb, #000 22%, var(--c)), color-mix(in srgb, #000 22%, var(--c)));
}
.hbar i + i { box-shadow: inset 0 1.5px 0 rgba(0,0,0,.34); }   /* crisp seam between types */
/* small wet sheen at the very top + a soft outer color-glow on the in-range bars */
.hbar::before {   /* glossy top cap of the whole glass tube */
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 22%; z-index: 2;
  border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(255,255,255,.34), rgba(255,255,255,0) 92%);
}
.hbar::after {    /* deep shaded base of the whole glass tube */
  content: ""; position: absolute; inset: 0; z-index: 2;
  border-radius: inherit; pointer-events: none;
  background: linear-gradient(180deg, rgba(0,0,0,0) 52%, rgba(0,0,0,.5) 100%);
}
/* in-range bars read by full opacity alone — no neon outer glow (matches the deep mockup) */
.spec-grad { height: 8px; border-radius: 4px; margin-bottom: 4px; opacity: .92; }

/* dual-thumb range: two transparent native sliders over a shared track+fill */
.dr { position: relative; height: 34px; }
.dr-track { position: absolute; left: 0; right: 0; top: 14px; height: 6px; border-radius: 4px; background: var(--panel2); }
.dr-fill { position: absolute; top: 14px; height: 6px; border-radius: 4px;
  background:
    linear-gradient(180deg, rgba(0,0,0,.4) 0%, rgba(0,0,0,0) 18%, rgba(255,255,255,.45) 34%, rgba(255,255,255,0) 54%, rgba(0,0,0,0) 78%, rgba(0,0,0,.45) 100%),
    linear-gradient(color-mix(in srgb,#000 14%,var(--accent)), color-mix(in srgb,#000 14%,var(--accent))); }
.dr-input { position: absolute; left: 0; top: 0; width: 100%; height: 34px; margin: 0; background: transparent; pointer-events: none; -webkit-appearance: none; appearance: none; }
.dr-input:focus { outline: none; }
.dr-input::-webkit-slider-runnable-track { background: transparent; border: none; height: 34px; }
.dr-input::-moz-range-track { background: transparent; border: none; }
/* knob = the strain-orb material (bloomInner): solid teal base + dark vignette pushed to
   the bottom-right + one tight top-left specular, NO ring — identical to the Indica→Sativa
   knob (.spec-sld-knob) so both Explore sliders render and grab the same. */
.dr-input::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; pointer-events: auto;
  width: 22px; height: 22px; border-radius: 50%; cursor: grab; margin-top: 6px;
  background:
    radial-gradient(42% 42% at 33% 25%, rgba(255,255,255,.92) 0%, rgba(255,255,255,.07) 34%, rgba(255,255,255,0) 100%),
    radial-gradient(82% 82% at 64% 78%, rgba(0,0,0,0) 40%, rgba(0,0,0,.6) 100%),
    #0fae80;
  box-shadow: 0 3px 8px rgba(0,0,0,.5);
}
.dr-input::-webkit-slider-thumb:active { cursor: grabbing; }
.dr-input::-moz-range-thumb {
  pointer-events: auto; width: 22px; height: 22px; border-radius: 50%; border: none; cursor: grab;
  background:
    radial-gradient(42% 42% at 33% 25%, rgba(255,255,255,.92) 0%, rgba(255,255,255,.07) 34%, rgba(255,255,255,0) 100%),
    radial-gradient(82% 82% at 64% 78%, rgba(0,0,0,0) 40%, rgba(0,0,0,.6) 100%),
    #0fae80;
  box-shadow: 0 3px 8px rgba(0,0,0,.5);
}
.dr-input:focus-visible::-webkit-slider-thumb { box-shadow: 0 3px 8px rgba(0,0,0,.5), 0 0 0 3px rgba(255,255,255,.55); }
.dr-input:focus-visible::-moz-range-thumb { box-shadow: 0 3px 8px rgba(0,0,0,.5), 0 0 0 3px rgba(255,255,255,.55); }
.dr-scale { display: flex; justify-content: space-between; font-size: 11px; color: var(--muted); margin-top: 2px; }
.spec-scale span { flex: 1; text-align: center; font-size: 10px; }
.spec-scale span:first-child { text-align: left; }
.spec-scale span:last-child { text-align: right; }

.exp-kpis { margin-top: 24px; }
.exp-row { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 16px; }
.exp-card { flex: 1 1 280px; background: var(--panel); border: 1px solid var(--border); border-radius: 12px; padding: 16px 18px; }
.exp-card-h { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 700; margin-bottom: 8px; }
.tilt-card { display: flex; flex-direction: column; }
.tilt-gauge { width: 100%; max-width: 230px; height: auto; display: block; margin: 4px auto 0; }
.gauge-needle { transform-origin: 100px 100px; transform-box: view-box; transition: transform .55s cubic-bezier(.2,.7,.2,1); }
.tilt-label { font-size: 15px; font-weight: 700; color: var(--text); text-align: center; margin-top: 4px; }
.exp-topterp { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600; color: var(--text); }
.exp-card .mini { margin: 5px 0; }

@media (max-width: 860px) {
  .explore { max-width: none; }
  .exp-row { flex-direction: column; }
  .dr-input::-webkit-slider-thumb { width: 24px; height: 24px; margin-top: 5px; }
  .dr-input::-moz-range-thumb { width: 24px; height: 24px; }
  .spec-sld-knob { width: 24px; height: 24px; } /* keep both Explore knobs the same size on mobile */
}

/* ===========================================================
   EXPLORE — center the dashboard content symmetrically
   (the strain detail stays left-aligned for reading; this is
   a control panel, so it reads better centered).
   =========================================================== */
.explore { display: flex; flex-direction: column; align-items: center; }
.explore > * { width: 100%; }
.explore .detail-head { border-left: none; padding-left: 0; justify-content: center; text-align: center; }
.explore .head-id { justify-content: center; }
.explore .sub { max-width: 640px; }
.exp-scopes { justify-content: center; }
.exp-slider { margin-left: auto; margin-right: auto; }
.exp-kpis { justify-content: center; }
.exp-row { justify-content: center; }
.explore .rec-title { text-align: center; width: 100%; }
.explore .rec-list { justify-content: center; }

/* gauge end/mid labels — Indica · Hybrid · Sativa, colored to the spectrum */
.gauge-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .02em; }

/* ===========================================================
   EXPLORE — WOW-factor cards: big, bold, glowing, glanceable
   (readable at a glance — and, yes, while elevated).
   =========================================================== */
.tilt-gauge { width: 100%; max-width: 300px; margin: 4px auto 0; display: block;
  filter: drop-shadow(0 0 4px var(--pop-glow)); }
.gauge-lbl { font-size: 12px; font-weight: 800; letter-spacing: .07em; }
.gauge-needle { transform-origin: 100px 100px; transform-box: view-box;
  transition: transform .55s cubic-bezier(.2,.7,.2,1); }
#tilt-knob { transition: fill .3s; }

.tilt-word {
  font-size: 40px; font-weight: 800; line-height: 1; text-align: center; margin-top: 8px;
  text-transform: uppercase; letter-spacing: .01em;
}
.tilt-split { text-align: center; font-size: 14px; color: var(--muted); margin-top: 8px; }
.tilt-split b { font-size: 17px; font-weight: 800; }

.terp-hero { display: flex; align-items: center; gap: 18px; margin-top: 4px; }
.terp-orb {
  width: 66px; height: 66px; border-radius: 50%; flex: 0 0 auto; position: relative;
  /* deep glass gem: lit shoulder -> body -> shaded base, with a dark bottom-right vignette */
  background:
    radial-gradient(circle at 64% 78%, rgba(0,0,0,.5), transparent 60%),
    radial-gradient(circle at 35% 28%,
      color-mix(in srgb, var(--c) 45%, #fff) 0%,
      var(--c) 34%,
      color-mix(in srgb, var(--c) 30%, #000) 100%);
  box-shadow: inset 0 -6px 12px rgba(0,0,0,.5), inset 0 4px 8px rgba(255,255,255,.14), 0 8px 20px -6px rgba(0,0,0,.7);
}
.terp-orb::after {   /* tight specular hotspot */
  content: ""; position: absolute; left: 24%; top: 12%; width: 30%; height: 22%; border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.92), rgba(255,255,255,0) 70%);
}
.terp-name { font-size: 32px; font-weight: 800; line-height: 1.02; text-shadow: 0 0 16px var(--pop-glow); }
.terp-sub { font-size: 14px; color: var(--muted); margin-top: 4px; }
.terp-sub b { color: var(--text); font-weight: 800; }

.effbar { display: flex; align-items: center; gap: 12px; margin: 12px 0; }
.effbar-name { flex: 0 0 100px; font-size: 15px; font-weight: 700; color: var(--text); }
.effbar-track { flex: 1; height: 13px; background: var(--panel2); border-radius: 7px; overflow: hidden; }
.effbar-fill { display: block; height: 100%; border-radius: 7px;
  background:
    linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 16%, rgba(255,255,255,.46) 32%, rgba(255,255,255,0) 52%, rgba(0,0,0,0) 76%, rgba(0,0,0,.5) 100%),
    linear-gradient(color-mix(in srgb,#000 16%,var(--accent)), color-mix(in srgb,#000 16%,var(--accent)));
  transition: width .55s cubic-bezier(.2,.7,.2,1); }
.effbar-val { flex: 0 0 34px; text-align: right; font-size: 15px; font-weight: 800;
  color: var(--text); font-variant-numeric: tabular-nums; }

/* the two WOW cards get a touch more presence */
.exp-row .exp-card { padding: 20px 22px; }
.tilt-card { align-items: center; }
.tilt-card .exp-card-h { align-self: flex-start; }

@media (max-width: 860px) {
  .tilt-word { font-size: 34px; }
  .terp-name { font-size: 28px; }
  .terp-orb { width: 58px; height: 58px; }
}

/* ---- balance the two WOW cards + give the KPI strip the same boldness ---- */
.exp-row .exp-card { display: flex; flex-direction: column; justify-content: center; }
.tilt-card .exp-card-h, #exp-terpeff .exp-card-h { align-self: flex-start; }

.exp-kpis { gap: 14px; }
.exp-kpis .kpi {
  padding: 16px 22px; min-width: 124px;
  border-color: #34465a;
  box-shadow: 0 6px 22px -12px var(--brand-glow), inset 0 1px 0 rgba(255,255,255,.05);
}
.exp-kpis .kpi-num { font-size: 32px; letter-spacing: -.01em; text-shadow: 0 0 14px var(--pop-glow); }
.exp-kpis .kpi-lbl { font-size: 11px; }
/* the headline count gets the brand-green accent so the eye lands there first */
.exp-kpis .kpi:first-child .kpi-num { color: var(--accent); text-shadow: 0 0 18px rgba(14,144,112,.5); }

/* ===========================================================
   EXPLORE — live console layout: sticky controls on top,
   strain list + stat cards side-by-side, so dragging a slider
   updates KPIs + gauge + the re-sorting list all at once.
   =========================================================== */
.exp-sticky {
  position: sticky; top: 0; z-index: 6; width: 100%;
  background: rgba(13, 19, 26, .93); backdrop-filter: blur(10px);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 16px 14px; margin-bottom: 18px;
  box-shadow: 0 10px 30px -16px rgba(0,0,0,.7);
}
.exp-sticky .exp-scopes { margin: 0 0 8px; }
/* minmax(0,1fr) — not bare 1fr — so a track can't be forced wider than the panel
   by a child's min-content. A sparse THC histogram (mostly empty bars, e.g. on the
   Favorites scope with a tiny pool) otherwise blows the track past the screen and
   the cards spill off the right edge on phones. */
.exp-sliders { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 18px; align-items: stretch; }
/* Each control sits in its own glass card of equal height. The header is pinned
   to the TOP; the body fills the rest — so the THC histogram grows tall to use
   the space instead of floating with dead air above & below. */
.exp-sticky .exp-slider {
  margin: 0; max-width: none;
  display: flex; flex-direction: column; justify-content: flex-start; gap: 10px;
  padding: 15px 20px 14px;
  background: color-mix(in srgb, var(--panel2) 38%, transparent);
  border: 1px solid rgba(255,255,255,.07);
  border-radius: 14px;
}
/* killer header: bright axis label + a pill-style live readout, on a hairline rule */
.exp-sticky .exp-slider-top {
  margin-bottom: 0; padding-bottom: 9px; gap: 10px;
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.exp-sticky .exp-axis { color: var(--text); font-size: 12.5px; letter-spacing: .1em; font-weight: 800; }
.exp-sticky .exp-range {
  flex: none; font-size: 12.5px; font-weight: 700; color: var(--text);
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent);
  padding: 3px 11px; border-radius: 999px; white-space: nowrap;
}
/* histogram fills the card height → tall bars that scale with the panel */
.exp-sticky .hist-wrap {
  flex: 1 1 auto; height: auto; min-height: 72px; margin: 2px 0 0;
  display: flex; align-items: flex-end; gap: 3px;
}
/* the THC card's slider + scale stay pinned at the bottom, under the histogram */
.exp-sticky .exp-slider .dr { flex: none; }
.exp-sticky .exp-slider .dr-scale { flex: none; }

/* KPI stats ribbon: one balanced row of equal-width tiles (count set in JS via
   --kpi-n) — no more orphaned, centre-floated tiles on a wrapped second row. */
.exp-sticky .exp-kpis {
  margin-top: 16px;
  display: grid;
  grid-template-columns: repeat(var(--kpi-n, 5), minmax(0, 1fr));
  gap: 12px;
}
.exp-sticky .exp-kpis .kpi { min-width: 0; padding: 15px 12px; }
.exp-sticky .exp-kpis .kpi-num { font-size: clamp(22px, 2.3vw, 31px); }

/* center the stat-card values + labels */
.exp-kpis .kpi { text-align: center; }

/* Signature — all-tiles stat row: Top terpene (wide tile) + one stat tile per
   top effect, in the same ribbon style as the KPIs, lifted into the controls
   container right under them. */
.exp-sticky .exp-signature {
  margin-top: 12px;
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: 12px;
}
.sig-tile {
  min-width: 0;
  background: var(--panel); border: 1px solid #34465a; border-radius: 12px;
  padding: 14px 16px;
  box-shadow: 0 6px 22px -12px var(--brand-glow), inset 0 1px 0 rgba(255,255,255,.05);
}
.sig-tile-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 700; }
.terp-tile { display: flex; align-items: center; gap: 14px; }
.terp-orb.sm { width: 46px; height: 46px; }
.terp-tile .terp-tile-txt { min-width: 0; }
.terp-tile .terp-name { font-size: 22px; margin-top: 2px; }
.terp-tile .terp-sub { font-size: 12px; margin-top: 2px; }
.eff-tile { display: flex; flex-direction: column; justify-content: center; }
.eff-tile-val { font-size: 28px; font-weight: 800; letter-spacing: -.01em; color: var(--text);
  text-shadow: 0 0 14px var(--pop-glow); margin-top: 2px; font-variant-numeric: tabular-nums; }
.eff-tile-track { display: block; height: 9px; background: var(--panel2); border-radius: 6px; overflow: hidden; margin-top: 9px; }
.eff-tile-fill { display: block; height: 100%; border-radius: 6px;
  background:
    linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 16%, rgba(255,255,255,.46) 32%, rgba(255,255,255,0) 52%, rgba(0,0,0,0) 76%, rgba(0,0,0,.5) 100%),
    linear-gradient(color-mix(in srgb,#000 16%,var(--accent)), color-mix(in srgb,#000 16%,var(--accent)));
  transition: width .55s cubic-bezier(.2,.7,.2,1); }

.exp-body { text-align: left; }
.exp-results-pane { min-width: 0; }
.exp-results-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.exp-res-title { font-size: 16px; font-weight: 800; color: var(--text); }
.exp-res-count { font-size: 14px; font-weight: 700; color: var(--accent); }
/* matches: full-width, three even columns */
.exp-results-pane .rec-list { max-width: none; grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* cards animate in as the list re-sorts → you SEE the change */
.exp-results-pane .rec-card { animation: cardIn .35s ease both; }
@keyframes cardIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ── Favorites = the "Your Taste" launchpad ── taste fingerprint + section labels
   span the whole match grid; cards stay in their columns. */
.rec-list.is-taste .taste-hero,
.rec-list.is-taste .taste-sec-lbl,
.rec-list.is-taste .taste-viewtog,
.rec-list.is-taste .taste-galaxy,
.rec-list.is-taste > .empty { grid-column: 1 / -1; }

/* grid ⇄ galaxy segmented toggle */
.taste-viewtog { display: inline-flex; align-self: start; margin: 2px 0; padding: 3px;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.10);
  border-radius: 999px; width: max-content; }
.tvt { border: none; background: none; color: var(--muted); font: inherit; font-size: 12.5px;
  font-weight: 700; padding: 5px 14px; border-radius: 999px; cursor: pointer;
  transition: color .15s, background .15s; }
.tvt.on { color: #fff; background: var(--brand-fill, var(--accent)); box-shadow: var(--brand-fill-shadow, none); }
.taste-galaxy { margin-top: 4px; }
.taste-galaxy-cap { font-size: 11.5px; color: var(--muted); text-align: center; margin: 8px 0 0; }

/* "📍 In stock near you" chip on a match card — dormant until stock.js is wired
   to a live dispensary menu (renders nothing before then). Rendered-glass brand pill. */
.stock-chip { display: inline-flex; align-items: center; gap: 5px; margin-top: 8px;
  font-size: 11.5px; font-weight: 700; color: #fff; text-decoration: none;
  padding: 4px 10px; border-radius: 999px;
  background: var(--brand-fill, var(--accent)); box-shadow: var(--brand-fill-shadow, none);
  border: 1px solid rgba(255,255,255,.14); }
.stock-chip:hover { filter: brightness(1.06); }
.stock-more { opacity: .82; font-weight: 800; }
.taste-hero {
  display: flex; align-items: center; gap: 14px; padding: 13px 16px; border-radius: 14px;
  background: color-mix(in srgb, var(--panel2) 55%, transparent);
  border: 1px solid rgba(255,255,255,.10);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.taste-orb {
  display: inline-flex; width: 60px; height: 60px; border-radius: 50%; overflow: hidden;
  flex-shrink: 0; box-shadow: 0 3px 10px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.08);
}
.taste-orb .bloom { display: block; width: 100%; height: 100%; }
.taste-title { font-size: 15px; font-weight: 800; letter-spacing: .2px; color: var(--text); }
.taste-sub { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.taste-sec-lbl {
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
  color: var(--text); margin: 8px 2px 0; padding-top: 4px;
}
.taste-sec-lbl .muted { text-transform: none; letter-spacing: 0; font-weight: 600; }

/* compact "Tried it? 👍 😐 👎" control inside a match card (base .feel-btn from feedback.js) */
.feel-row.fm { margin: 8px 0 0; padding: 5px 8px; gap: 7px; font-size: 12px; border-radius: 10px; }
.feel-row.fm .fm-q { opacity: .68; font-weight: 600; }
.feel-btn.fm { padding: 2px 8px; font-size: 14px; }

/* "Taste read" confidence meter in the fingerprint hero — climbs as you save + rate */
.taste-meter { display: flex; align-items: center; gap: 8px; margin-top: 9px; max-width: 320px; }
.taste-meter-lbl { font-size: 11px; font-weight: 700; color: var(--muted); white-space: nowrap; }
.taste-meter-track { position: relative; flex: 1; height: 7px; border-radius: 5px;
  background: rgba(255,255,255,.10); overflow: hidden; box-shadow: inset 0 1px 2px rgba(0,0,0,.5); }
.taste-meter-fill { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 5px;
  background: var(--brand-fill, linear-gradient(90deg, var(--accent), #16f5a7));
  box-shadow: var(--brand-fill-shadow, 0 0 8px rgba(22,245,167,.5));
  transition: width .55s cubic-bezier(.2,.7,.2,1); }
.taste-meter-pct { font-size: 12px; font-weight: 800; color: var(--text); white-space: nowrap; }

/* tablets: matches drop to two columns; signature tiles wrap to 2-up */
@media (max-width: 980px) {
  .exp-results-pane .rec-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .exp-sticky .exp-signature { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .exp-sticky .exp-signature .terp-tile { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
  .exp-sliders { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  /* phones: wrap the KPI tiles into an even grid (2-up) instead of a fixed-width
     horizontal scroll strip — the old strip overflowed and clipped the last tile
     (e.g. CBD-rich) off the right edge on narrow scopes like Favorites. */
  .exp-sticky .exp-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; overflow: visible; }
  .exp-sticky .exp-kpis .kpi { min-width: 0; padding: 13px 10px; }
  .exp-sticky .exp-kpis .kpi-num { font-size: clamp(22px, 7vw, 30px); }
  /* signature tiles likewise wrap 2-up with the terpene tile spanning the row */
  .exp-sticky .exp-signature { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}
@media (max-width: 620px) {
  .exp-results-pane .rec-list { grid-template-columns: 1fr; }
}

/* ===========================================================
   APPEARANCE THEMES — palettes + animated psychedelic backdrops
   =========================================================== */
[data-theme="blacklight"]{--bg:#0a0612;--panel:#160a24;--panel2:#1f1133;--border:#3a1f5c;--text:#f3e9ff;--text2:#cdb3ff;--muted:#8f74b8;--accent:#b026ff;--header:linear-gradient(90deg,#1a0a2e,#160a24);--brand-glow:rgba(176,38,255,.55);--pop-glow:rgba(224,170,255,.55);}
[data-theme="trippy"]{--bg:#10071a;--panel:#1c0e2e;--panel2:#27143f;--border:#46256b;--text:#ffffff;--text2:#ffd6f5;--muted:#b58fd0;--accent:#ff3bd0;--header:linear-gradient(90deg,#1c0a2e,#10071a);--brand-grad:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),linear-gradient(105deg,#ff3bd0,#7b5cff 50%,#19e3ff);--brand-glow:rgba(255,59,208,.5);--pop-glow:rgba(255,255,255,.45);}
[data-theme="tiedye"]{--bg:#141026;--panel:#201a3a;--panel2:#2b234d;--border:#473a70;--text:#ffffff;--text2:#e6dcff;--muted:#ada0cc;--accent:#ff5ea8;--header:linear-gradient(90deg,#241a3d,#141026);--brand-grad:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),linear-gradient(100deg,#ff5ea8,#ffd23b 35%,#3bd6ff 65%,#b06bff);--brand-glow:rgba(255,94,168,.5);--pop-glow:rgba(255,255,255,.4);}
[data-theme="hippie"]{--bg:#f3e3c4;--panel:#fbf0d6;--panel2:#ecd7ad;--border:#d8b87f;--text:#3d2410;--text2:#6b4420;--muted:#755831;--accent:#e0561f;--accent-text:#a13e16;--header:linear-gradient(90deg,#eccf9c,#fbf0d6);--brand-grad:linear-gradient(rgba(0,0,0,.08),rgba(0,0,0,.08)),linear-gradient(105deg,#e0561f,#d63a8a 45%,#1f9e8a);--brand-glow:rgba(224,86,31,.4);--pop-glow:rgba(0,0,0,.26);}
[data-theme="groovy"]{--bg:#2a1c0c;--panel:#3a2912;--panel2:#48351b;--border:#6a4f26;--text:#f8e7c2;--text2:#e6c88f;--muted:#bfa068;--accent:#cc5500;--header:linear-gradient(90deg,#3a2710,#2a1c0c);--brand-grad:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),linear-gradient(105deg,#cc5500,#d4a017 50%,#6b8e23);--brand-glow:rgba(204,85,0,.45);--pop-glow:rgba(255,210,140,.4);}
[data-theme="rasta"]{--bg:#0c1410;--panel:#13201a;--panel2:#1b2c22;--border:#2f4a39;--text:#f6f0d8;--text2:#dce3c0;--muted:#9aab85;--accent:#f2c029;--header:linear-gradient(90deg,#14241a,#0c1410);--brand-grad:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),linear-gradient(105deg,#d33a2c,#f2c029 50%,#3a9d3a);--brand-glow:rgba(242,192,41,.45);--pop-glow:rgba(246,240,216,.35);}
/* Gangsta = gunmetal black (Obsidian Flat surfaces) + gold accent — premium gun-metal-&-gold, not brown */
[data-theme="gangsta"]{--bg:#0d0f12;--panel:#14171b;--panel2:#1c2026;--border:#23282f;--text:#e8edf2;--text2:#c3ccd6;--muted:#8a97a6;--accent:#d4af37;--header:linear-gradient(90deg,#121519,#0d0f12);--brand-grad:linear-gradient(rgba(0,0,0,.15),rgba(0,0,0,.15)),linear-gradient(105deg,#bf9b30,#f5d676 50%,#bf9b30);--brand-glow:rgba(212,175,55,.5);--pop-glow:rgba(245,214,118,.45);}
[data-theme="vaporwave"]{--bg:#140a24;--panel:#1f1140;--panel2:#2a1a52;--border:#4a2f80;--text:#fde6ff;--text2:#c6b3ff;--muted:#a08fcf;--accent:#ff5ea8;--header:linear-gradient(90deg,#241040,#140a24);--brand-grad:linear-gradient(rgba(0,0,0,.12),rgba(0,0,0,.12)),linear-gradient(105deg,#ff5ea8,#7b5cff 50%,#3bd6ff);--brand-glow:rgba(255,94,168,.5);--pop-glow:rgba(123,200,255,.45);}
[data-theme="cyberpunk"]{--bg:#070a0d;--panel:#0e1418;--panel2:#151d22;--border:#2a3a44;--text:#eafdff;--text2:#9fe9ff;--muted:#5f8a99;--accent:#f6ff3b;--header:linear-gradient(90deg,#0c1418,#070a0d);--brand-grad:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1)),linear-gradient(105deg,#ff2bd0,#f6ff3b 55%,#19e3ff);--brand-glow:rgba(246,255,59,.45);--pop-glow:rgba(25,227,255,.5);}

/* each theme gets its OWN distinct backdrop (no shared rainbow) */
@keyframes tl-hue  { from { filter: hue-rotate(0) saturate(1.7) brightness(.9); } to { filter: hue-rotate(360deg) saturate(1.7) brightness(.9); } }
@keyframes tl-veil { to { filter: hue-rotate(360deg); } }
@keyframes tl-pulse{ 0%,100% { opacity:.82; } 50% { opacity:1; } }

/* BLACKLIGHT — near-black with a pulsing UV-purple glow (no rainbow) */
[data-theme="blacklight"] .bg-video { filter: hue-rotate(-150deg) saturate(2.2) brightness(.5); }
[data-theme="blacklight"] .bg-overlay {
  background: radial-gradient(circle at 50% 38%, rgba(150,40,230,.34), rgba(6,2,12,.92) 68%);
  animation: tl-pulse 6s ease-in-out infinite;
}

/* TRIPPY — full hue-cycling rainbow swirl (the wild one) */
[data-theme="trippy"] .bg-video { animation: tl-hue 9s linear infinite; }
[data-theme="trippy"] .bg-overlay {
  background:
    linear-gradient(rgba(8,3,18,.40), rgba(8,3,22,.46)),
    conic-gradient(from 0deg at 50% 50%, #ff3bd0, #7b5cff, #19e3ff, #ffd23b, #3aff9d, #ff3bd0);
  animation: tl-veil 11s linear infinite;
}

/* TIE-DYE — concentric rainbow rings (bullseye swirl), cycling */
[data-theme="tiedye"] .bg-video { filter: saturate(1.7) brightness(.82) hue-rotate(20deg); }
[data-theme="tiedye"] .bg-overlay {
  background:
    linear-gradient(rgba(8,4,16,.36), rgba(8,4,16,.42)),
    repeating-radial-gradient(circle at 50% 42%, #ff5ea8 0 6%, #ffd23b 6% 12%, #34d399 12% 18%, #3bd6ff 18% 24%, #b06bff 24% 30%);
  animation: tl-veil 16s linear infinite;
}

/* VAPORWAVE — 80s sunset gradient + faint grid (static) */
[data-theme="vaporwave"] .bg-video { filter: hue-rotate(40deg) saturate(1.9) brightness(.8); }
[data-theme="vaporwave"] .bg-overlay {
  background:
    repeating-linear-gradient(transparent 0 36px, rgba(59,214,255,.06) 36px 38px),
    linear-gradient(180deg, rgba(18,6,38,.62) 0%, rgba(123,92,255,.34) 48%, rgba(255,94,168,.40) 78%, rgba(59,214,255,.34) 100%);
}

/* CYBERPUNK — dark with neon yellow/cyan glows + scanlines */
[data-theme="cyberpunk"] .bg-video { filter: hue-rotate(150deg) saturate(1.7) brightness(.55); }
[data-theme="cyberpunk"] .bg-overlay {
  background:
    repeating-linear-gradient(transparent 0 3px, rgba(0,0,0,.16) 3px 4px),
    radial-gradient(circle at 72% 28%, rgba(246,255,59,.12), transparent 50%),
    radial-gradient(circle at 24% 76%, rgba(25,227,255,.14), transparent 55%),
    linear-gradient(135deg, rgba(4,8,11,.78), rgba(4,10,14,.84));
}

/* HIPPIE — warm flower-power glows on cream (light, NOT green) */
[data-theme="hippie"] .bg-video { filter: hue-rotate(-60deg) saturate(1.3) brightness(1.05); }
[data-theme="hippie"] .bg-overlay {
  background:
    radial-gradient(circle at 28% 30%, rgba(224,86,31,.22), transparent 45%),
    radial-gradient(circle at 72% 68%, rgba(214,58,138,.20), transparent 48%),
    linear-gradient(135deg, rgba(243,227,196,.80), rgba(251,240,214,.85));
}

/* GROOVY — 70s sunburst in burnt-orange / gold / avocado */
[data-theme="groovy"] .bg-video { filter: hue-rotate(-95deg) saturate(1.5) brightness(.8); }
[data-theme="groovy"] .bg-overlay {
  background:
    linear-gradient(rgba(24,14,4,.34), rgba(24,14,4,.40)),
    repeating-radial-gradient(circle at 50% 118%, #cc5500 0 26px, #d4a017 26px 52px, #6b8e23 52px 78px, #7a4a1f 78px 104px);
}

/* RASTA — red / gold / green bands (reggae tricolor) */
[data-theme="rasta"] .bg-video { filter: hue-rotate(-30deg) saturate(1.5) brightness(.85); }
[data-theme="rasta"] .bg-overlay {
  background:
    linear-gradient(rgba(6,12,8,.50), rgba(6,12,8,.56)),
    linear-gradient(180deg, #d33a2c 0 33%, #f2c029 33% 66%, #2fae46 66% 100%);
}

/* GANGSTA — keep it dark, but the smoke goes light grey */
[data-theme="gangsta"] .bg-video { filter: grayscale(1) brightness(1.3) contrast(1.05); }
[data-theme="gangsta"] .bg-overlay { background: linear-gradient(135deg, rgba(10,10,10,.50), rgba(2,2,2,.58)); }

/* ---- rec-card flavor chips (replaces the always-0 flavor similarity bar) ---- */
.rec-flavs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.rflav { font-size: 12px; border-radius: 999px; padding: 4px 10px; color: var(--text2); white-space: nowrap; line-height: 1.4;
  background: linear-gradient(180deg, color-mix(in srgb, #fff 9%, var(--panel2)), var(--panel2));
  border: 1px solid var(--border); box-shadow: inset 0 1px 0 rgba(255,255,255,.14), 0 2px 6px -3px rgba(0,0,0,.5); }

/* ---- mobile safety: nothing escapes the screen horizontally; no dead space ---- */
@media (max-width: 860px) {
  /* clip, not hidden — see the note at the top of the 860px block: `overflow-x:hidden`
     would force overflow-y to `auto` and turn <body> into a scroll container, which
     re-parents the fixed tab bar on iOS. */
  html, body { max-width: 100%; overflow-x: clip; overscroll-behavior-y: contain; }
  .detail, .explore, .layout, .sidebar, #list { max-width: 100%; }
  .sidebar, #list { overflow-x: hidden; }
  /* clip (not hidden): clipping still contains stray width, but unlike
     overflow:hidden it does NOT make these a scroll container — so the
     Explore control panel can stay position:sticky relative to the page */
  .detail, .explore, .layout { overflow-x: clip; }
  /* long names/words wrap instead of pushing the card wide */
  .rec-name, .rec-meta, .detail-head h2, .sub, .desc, .exp-res-title { overflow-wrap: anywhere; }
  .rec-name { min-width: 0; }
  /* the centered-column padding trick can overflow on phones — pin side padding flat */
  .detail { padding-left: 16px; padding-right: 16px; }
}

/* ===========================================================
   ULTRA-WIDE detail: 2 columns — terpene profile + effects on
   the left, the Similarity Galaxy on the right (fills big screens,
   less scrolling). Narrow screens keep the single-column stack.
   =========================================================== */
@media (min-width: 1500px) {
  .detail { padding: 24px max(30px, calc((100% - 1320px) / 2)) 60px; }
  .detail-mid {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    column-gap: 36px;
    align-items: start;
    max-width: 1320px;
  }
  .detail-mid .terp-section { grid-column: 1; grid-row: 1; }
  .detail-mid .cols { grid-column: 1; grid-row: 2; max-width: none; }
  .detail-mid .desc { grid-column: 1; grid-row: 3; }
  /* galaxy fills the right column, sticky so it stays in view while you read */
  .detail-mid .galaxy-block {
    grid-column: 2; grid-row: 1 / 4;
    align-self: start; position: sticky; top: 8px; margin: 14px 0 0;
  }
  .detail-mid .galaxy-svg { max-width: none; max-height: 70vh; }
  .detail-mid .cols { grid-template-columns: 1fr 1fr; }
}

/* ===========================================================
   INDICA↔SATIVA LEAF KPI  (one leaf coloured by the mix + range slider)
   =========================================================== */
/* the card is a flex column (inherits .exp-slider card styling): header pinned to
   the TOP, the LEAF grows to fill the middle so it sits at the same height as the
   THC histogram next to it, then the readout + slider + axis sit at the bottom. */
.spec-leaf-wrap { display: flex; flex-direction: column; }
.spec-leaf-stage {
  flex: 1 1 auto; min-height: 96px; margin: 4px 0 0;
  display: flex; align-items: center; justify-content: center;
}
.spec-leaf-svg {
  width: auto; height: 100%; max-height: 168px; max-width: 84%; display: block; overflow: visible;
  filter: drop-shadow(0 12px 20px rgba(0,0,0,.5));
}
/* keyboard/screen-reader handles, visually hidden but focusable */
.sr-only-range { position: absolute; left: 0; bottom: 0; width: 100%; height: 16px; opacity: 0; pointer-events: none; margin: 0; }
/* readout: the BIG tilt word centered, the indica/hybrid/sativa counts below it */
.spec-readout-row { display: flex; flex-direction: column; align-items: center; gap: 5px; justify-content: center; margin-top: 8px; }
.spec-word { font-size: 21px; font-weight: 800; letter-spacing: .03em; text-transform: uppercase; line-height: 1; text-align: center; }
.spec-split { font-size: 13px; color: var(--muted); text-align: center; }
.spec-split b { font-size: 15px; font-weight: 800; }

/* ── dual-handle range slider on the Indica→Sativa axis ── */
.spec-sld { position: relative; height: 30px; margin: 16px 9px 0; touch-action: none; cursor: pointer; }
.spec-sld-rail {
  position: absolute; top: 50%; left: 0; right: 0; height: 9px; transform: translateY(-50%);
  border-radius: 6px;
  background: linear-gradient(90deg, #6a3fd0 0%, #386b9c 27%, #0e9070 50%, #649049 74%, #c2901e 100%);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.6), inset 0 -1px 0 rgba(255,255,255,.06);
}
.spec-sld-dim { position: absolute; top: 50%; height: 9px; transform: translateY(-50%); background: rgba(8,10,12,.62); border-radius: 6px; }
.spec-sld-sel { position: absolute; top: 50%; height: 9px; transform: translateY(-50%); border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14), 0 0 9px rgba(14,144,112,.35); }
/* knob = the strain-orb material (bloomInner): solid teal base + dark vignette pushed to
   the bottom-right + one tight top-left specular, NO ring — identical to the THC knob. */
.spec-sld-knob {
  position: absolute; top: 50%; width: 22px; height: 22px; border-radius: 50%;
  transform: translate(-50%, -50%); cursor: grab; z-index: 3;
  background:
    radial-gradient(42% 42% at 33% 25%, rgba(255,255,255,.92) 0%, rgba(255,255,255,.07) 34%, rgba(255,255,255,0) 100%),
    radial-gradient(82% 82% at 64% 78%, rgba(0,0,0,0) 40%, rgba(0,0,0,.6) 100%),
    #0fae80;
  box-shadow: 0 3px 8px rgba(0,0,0,.5);
  transition: box-shadow .15s;
}
.spec-sld-knob:active { cursor: grabbing; }
.spec-sld-knob:focus-visible { outline: none; box-shadow: 0 3px 8px rgba(0,0,0,.5), 0 0 0 3px rgba(255,255,255,.55); }
/* 5 snap stops on the rail (Indica · Indica-Hybrid · Hybrid · Sativa-Hybrid · Sativa) */
.spec-sld-ticks { position: absolute; inset: 0; pointer-events: none; }
.spec-sld-ticks i { position: absolute; top: 50%; width: 2px; height: 15px; transform: translate(-50%, -50%);
  background: rgba(255,255,255,.28); border-radius: 1px; z-index: 2; }
.spec-sld-axis { position: relative; min-height: 24px; margin: 10px 9px 0; }
.spec-tick-lbl { position: absolute; top: 0; transform: translateX(-50%); width: 58px; text-align: center;
  font-size: 9px; font-weight: 700; letter-spacing: .02em; line-height: 1.08; text-transform: uppercase; }
.spec-tick-lbl.edge-l { left: 0 !important; transform: none; width: auto; text-align: left; white-space: nowrap; }
.spec-tick-lbl.edge-r { transform: translateX(-100%); width: auto; text-align: right; white-space: nowrap; }

/* ===========================================================
   EXPLORE — electric + glassmorphism finish (theme-adaptive via
   color-mix on the panel vars; electric neon accents + glow)
   =========================================================== */
.explore .exp-sticky {
  background: color-mix(in srgb, var(--panel) 64%, transparent);
  border-color: color-mix(in srgb, #7c3aed 40%, var(--border));
  -webkit-backdrop-filter: blur(16px) saturate(1.45); backdrop-filter: blur(16px) saturate(1.45);
  box-shadow: 0 16px 50px -22px rgba(124,58,237,.5), inset 0 1px 0 rgba(255,255,255,.07);
}
.explore .exp-card,
.explore .exp-results-pane .rec-card {
  background: color-mix(in srgb, var(--panel) 58%, transparent);
  border: 1px solid rgba(255,255,255,.10);
  -webkit-backdrop-filter: blur(12px) saturate(1.3); backdrop-filter: blur(12px) saturate(1.3);
  box-shadow: 0 12px 34px -18px rgba(0,0,0,.75), inset 0 1px 0 rgba(255,255,255,.07);
}
.explore .exp-card:hover,
.explore .exp-results-pane .rec-card:hover {
  border-color: rgba(22,245,167,.55);
  box-shadow: 0 16px 40px -16px rgba(22,245,167,.32), inset 0 1px 0 rgba(255,255,255,.1);
}
.explore .exp-kpis .kpi {
  background: color-mix(in srgb, var(--panel2) 55%, transparent);
  border: 1px solid rgba(255,255,255,.09);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
}
.explore .exp-kpis .kpi-num { text-shadow: 0 0 18px color-mix(in srgb, var(--accent) 55%, transparent); }
.explore .exp-scope.on { box-shadow: 0 0 16px -2px rgba(22,245,167,.6); }

/* Collapse toggle: shown at ALL widths so the tall Explore panel (filters + KPIs)
   can always be folded to a thin pinned bar — otherwise it overlaps the match
   cards as you scroll (desktop) or eats the whole screen (mobile). */
.exp-collapse {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 14px 16px; background: none; border: none; color: var(--text);
  font: inherit; cursor: pointer;
}
.exp-collapse-txt { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 700; }
/* gear: enlarged + brightened to the brand mint so the "tap to filter" affordance reads */
.exp-collapse-ic { flex: none; font-size: 19px; line-height: 1; opacity: 1; color: color-mix(in srgb, var(--accent) 50%, #fff); }
#exp-collapse-sum { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* caret: a labeled brand-glass pill ("Edit ⌄") instead of a tiny lone glyph, so the
   "tap to open the filters" affordance is unmistakable — even on a phone. */
.exp-collapse-chev {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px; border-radius: 999px; line-height: 1;
  font-size: 13px; font-weight: 800; letter-spacing: .02em; color: #fff;
  /* Amber/gold glass — deliberately OFF the brand emerald so this "tap to edit
     filters" pill pops out instead of blending into the green Medical toggle.
     Same rendered-glass recipe as --brand-fill, just a honey-gold hue. */
  background: radial-gradient(120% 150% at 30% 16%,
    color-mix(in srgb, #f5a623 58%, #fff) 0%,
    #f5a623 44%,
    color-mix(in srgb, #f5a623 34%, #000) 100%);
  text-shadow: 0 1px 2px rgba(80,40,0,.45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.42), inset 0 -5px 10px rgba(80,40,0,.40),
              0 4px 16px -3px rgba(245,166,35,.62);
}
.exp-chev-lbl { line-height: 1; }
.exp-chev-ic { flex: none; transition: transform .2s ease; }
/* rotate only the arrow when open — rotating the whole pill would flip the label */
.exp-sticky:not(.is-collapsed) .exp-collapse-chev .exp-chev-ic { transform: rotate(180deg); }

/* Collapse behavior — ALL widths. A tall `position: sticky` panel would pin itself
   and overlap the match cards as you scroll (and eat the whole screen on mobile).
   So: EXPANDED → the panel scrolls inline (static, no sticky overlap); COLLAPSED →
   it folds to a thin summary bar pinned at the top, so the matches stay reachable
   and the filters are one tap away. Defaults: open on desktop, collapsed on mobile
   (set per-viewport in renderExplore). */
.exp-sticky.is-collapsed .exp-controls { display: none; }
.explore .exp-sticky.is-collapsed { position: sticky; top: 0; padding: 0; }
.explore .exp-sticky:not(.is-collapsed) { position: static; }

@media (max-width: 860px) {
  /* mobile: when Explore is reached from the detail view there's a back bar to clear;
     on the Explore landing (m-explore) there isn't, so pin to the very top. */
  .explore .exp-sticky.is-collapsed { top: var(--m-back-h, 47px); }
  body.m-explore .explore .exp-sticky.is-collapsed { top: 0; }
}
