/* ---------- The Wine Curriculum: multi-theme system ----------
   Every color a component uses flows through these custom properties (plus
   --wine-rgb/--gold-rgb, the same colors as bare "r, g, b" triples for the
   handful of spots that need rgba() at a specific opacity) — no component
   below hardcodes a theme color, so switching themes is just switching
   which [data-theme] block is active on <html>. Applied by theme-switcher.js
   (reads/writes localStorage, no reload needed) and mirrored by a tiny
   inline script in every page's <head> that sets the attribute before first
   paint, so there's no flash of the wrong theme on load.

   "cellar-app" (below, also the bare :root fallback) is the live default.
   "cellar-journal" is the original warm parchment-and-oxblood theme this
   app shipped with — kept fully intact and selectable, just no longer the
   default. "midnight" and "glass-pour" are its modern-app siblings. */

:root, :root[data-theme="cellar-app"] {
  --wine: #8c1f3d;
  --wine-dark: #6e1830;
  --wine-rgb: 140, 31, 61;
  --gold: #96751f;
  --gold-rgb: 150, 117, 31;
  --gold-light: #c2a34f;
  --accent-2: #b5527a;
  --map-sea: #f3eef0;
  --map-land: #d7c3cb;
  --map-stroke: #b89aa3;
  --map-dot-idle: #ffffff;
  --cream: #faf9f7;
  --paper: #ffffff;
  --ink: #1a1a1a;
  --muted: #6b6b68;
  --border: #ece9e4;
  --good: #3f7d4f;
  --bad: #b4483a;
  --radius: 14px;
  --radius-lg: 20px;
  --btn-radius: 14px;
  --shadow: 0 20px 40px -18px rgba(26, 26, 26, 0.18);
  --shadow-sm: 0 6px 18px -8px rgba(26, 26, 26, 0.1);
  --font-display: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-accent: "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

:root[data-theme="cellar-journal"] {
  --wine: #4a1220;
  --wine-dark: #2e0a13;
  --wine-rgb: 74, 18, 32;
  --gold: #ab8a41;
  --gold-rgb: 171, 138, 65;
  --gold-light: #d9c48c;
  --accent-2: #ab8a41;
  --map-sea: #0a0e24;
  --map-land: #3a4568;
  --map-stroke: #1a2050;
  --map-dot-idle: #faf6ef;
  --cream: #faf6ef;
  --paper: #fffefc;
  --ink: #241c18;
  --muted: #746656;
  --border: #e7dcc9;
  --good: #3f7d4f;
  --bad: #b4483a;
  --radius: 10px;
  --radius-lg: 16px;
  --btn-radius: 999px;
  --shadow: 0 10px 30px -8px rgba(36, 24, 20, 0.18);
  --shadow-sm: 0 3px 14px rgba(36, 24, 20, 0.08);
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-accent: "Cormorant Garamond", Georgia, serif;
}

:root[data-theme="midnight"] {
  --wine: #e0335f;
  --wine-dark: #b8264a;
  --wine-rgb: 224, 51, 95;
  --gold: #b8901f;
  --gold-rgb: 184, 144, 31;
  --gold-light: #d4b04a;
  --accent-2: #f0759a;
  --map-sea: #17151a;
  --map-land: #3a2530;
  --map-stroke: #4a2f3c;
  --map-dot-idle: #e8e6e2;
  --cream: #121113;
  --paper: #1c1a1d;
  --ink: #f0eee8;
  --muted: #8f8a8e;
  --border: #2a272b;
  --good: #4fae70;
  --bad: #d9695a;
  --radius: 14px;
  --radius-lg: 18px;
  --btn-radius: 14px;
  --shadow: 0 20px 45px -16px rgba(0, 0, 0, 0.6);
  --shadow-sm: 0 6px 18px -6px rgba(0, 0, 0, 0.45);
  --font-display: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-accent: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

:root[data-theme="glass-pour"] {
  --wine: #a8375c;
  --wine-dark: #7f2945;
  --wine-rgb: 168, 55, 92;
  --gold: #a67c2e;
  --gold-rgb: 166, 124, 46;
  --gold-light: #d9b874;
  --accent-2: #d98fac;
  --map-sea: rgba(255, 255, 255, 0.22);
  --map-land: rgba(255, 255, 255, 0.55);
  --map-stroke: rgba(255, 255, 255, 0.75);
  --map-dot-idle: #ffffff;
  --cream: #f6d9de;
  --paper: rgba(255, 255, 255, 0.4);
  --ink: #3a2430;
  --muted: #7a6470;
  --border: rgba(255, 255, 255, 0.55);
  --good: #3f7d4f;
  --bad: #b4483a;
  --radius: 18px;
  --radius-lg: 22px;
  --btn-radius: 14px;
  --shadow: 0 20px 40px -18px rgba(58, 36, 48, 0.25);
  --shadow-sm: 0 8px 20px -10px rgba(58, 36, 48, 0.18);
  --font-display: "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-accent: "Outfit", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-body);
  background: var(--cream);
  color: var(--ink);
  line-height: 1.6;
  position: relative;
  min-height: 100vh;
}

body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--gold) 0%, var(--wine) 50%, var(--gold) 100%);
  z-index: 50;
}

/* faint climbing "rungs" behind everything — thin evenly-spaced hairlines,
   like a ladder laid flat across the page, at low enough opacity to read as
   texture rather than a literal graphic. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: repeating-linear-gradient(
    180deg,
    transparent 0,
    transparent 63px,
    rgba(var(--gold-rgb), 0.1) 63px,
    rgba(var(--gold-rgb), 0.1) 64px
  );
}

.wrap {
  position: relative;
  z-index: 1;
  max-width: 640px;
  margin: 0 auto;
  padding: 24px 20px 80px;
}

a {
  color: var(--wine);
}

/* One keyboard focus ring for the whole app. Before this only the tasting
   sheet's own textareas/inputs had a visible :focus style, so tabbing
   through a roadmap, the hero nav or any button was completely invisible —
   nothing on screen said where you were. :focus-visible rather than :focus
   so a mouse click doesn't leave a ring behind on a button. */
:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Tiles, roadmap nodes and badge chips are large blocks with their own
   radius — a 4px ring on a 20px-radius card looks like a mistake. */
.tile:focus-visible,
.roadmap-node:focus-visible,
.card:focus-visible,
.come-back-chip:focus-visible,
.trophy-link-wrap:focus-visible,
.btn:focus-visible {
  border-radius: var(--radius-lg);
  outline-offset: 3px;
}

/* Honor the OS "reduce motion" setting: the app animates a fair amount
   (smooth step scrolling, tile hover lifts, progress-bar fills), and for
   anyone who gets motion sick that's not a nicety to opt out of. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
}

/* ---------- Homepage ---------- */

.home {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  padding: 64px 20px 80px;
  background: radial-gradient(ellipse 700px 360px at 50% 0%, rgba(var(--gold-rgb), 0.1), transparent 70%);
}

.hero {
  position: relative;
  max-width: 480px;
  margin: 0 auto 44px;
  text-align: center;
}

/* three climbing rungs behind the wordmark — the one literal nod to the
   name, kept small and faint enough to read as a flourish, not a graphic */
.hero::before {
  content: "";
  position: absolute;
  top: -18px;
  left: 50%;
  width: 120px;
  height: 46px;
  transform: translateX(-50%);
  background-image:
    linear-gradient(90deg, transparent, var(--gold-light), transparent),
    linear-gradient(90deg, transparent, var(--gold-light), transparent),
    linear-gradient(90deg, transparent, var(--gold-light), transparent);
  background-repeat: no-repeat;
  background-size: 60% 1.5px, 84% 1.5px, 100% 1.5px;
  background-position: top center, center, bottom center;
  opacity: 0.5;
}

.logo {
  position: relative;
  display: flex;
  justify-content: center;
  margin-bottom: 8px;
}

.home h1 {
  font-size: clamp(2rem, 5vw + 1rem, 2.8rem);
  margin: 0 0 14px;
  color: var(--wine-dark);
  letter-spacing: -0.01em;
}

.tagline {
  font-family: var(--font-accent);
  font-style: italic;
  color: var(--muted);
  font-size: clamp(1.05rem, 2vw + 0.8rem, 1.2rem);
  margin: 0 0 18px;
}

.hero-rule {
  width: 56px;
  height: 2px;
  margin: 0 auto 18px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}

.howitworks-link {
  display: inline-block;
  font-size: 0.85rem;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid var(--border);
  padding-bottom: 1px;
}

.howitworks-link:hover {
  color: var(--gold);
  border-color: var(--gold);
}

.hero-continue {
  margin-bottom: 22px;
}

.hero-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Wraps rather than overflowing: five items and four separator dots at
     0.85rem run past the viewport on a narrow phone, and the row had no
     wrap set, so the last link simply fell off the right edge. */
  flex-wrap: wrap;
  gap: 6px 10px;
  font-size: 0.85rem;
}

.hero-nav a {
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 1px;
}

.hero-nav a:hover {
  color: var(--gold);
  border-color: var(--gold);
}

.hero-nav-dot {
  color: var(--border);
}

/* Sign in / your username — its own row under the nav, set apart as a
   small outlined pill so it reads as an account control rather than a
   fifth page link. */
.hero-account {
  margin-top: 12px;
  text-align: center;
}

.hero-account a {
  display: inline-block;
  font-size: 0.8rem;
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 14px;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.hero-account a:hover {
  color: var(--wine);
  border-color: var(--wine);
}

.hero-account a.is-signed-in {
  color: var(--wine);
  border-color: rgba(var(--wine-rgb), 0.35);
  background: rgba(var(--wine-rgb), 0.06);
}

.btn {
  display: inline-block;
  background: var(--wine);
  color: #fff;
  border: none;
  padding: 14px 30px;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  border-radius: var(--btn-radius, 999px);
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 10px 24px -8px rgba(var(--wine-rgb), 0.5);
  transition: transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease;
}

.btn:hover {
  background: var(--wine-dark);
  transform: translateY(-1px);
  box-shadow: 0 14px 28px -8px rgba(var(--wine-rgb), 0.6);
}

.btn:active {
  transform: translateY(0);
}

.btn.secondary {
  background: transparent;
  color: var(--gold);
  border: 1.5px solid var(--gold-light);
  padding: 12.5px 28.5px;
  box-shadow: none;
}

.btn.secondary:hover {
  background: var(--gold);
  color: var(--cream);
  border-color: var(--gold);
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

/* ---------- Roadmap ---------- */

.roadmap {
  position: relative;
  max-width: 460px;
  margin: 0 auto;
}

.roadmap-node {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 15px 10px;
  border-radius: var(--radius);
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease;
}

.roadmap-node[href]:hover {
  background: rgba(var(--wine-rgb), 0.08);
}

.roadmap-marker {
  position: relative;
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
  color: var(--muted);
}

/* Connector dashes belong to the node, not the marker — a node's real
   height depends on its title/blurb text, which is almost always taller
   than the 40px circle, so anchoring to the marker alone (its bottom edge
   moves with content height) left the "below" segment stopping well short
   of the next node. The circle's own position never moves though (always
   15px padding + 40px), so top:58px is a safe constant; bottom:0 then
   stretches to whatever the node's actual height turns out to be. Each
   segment stays inside its own node's space (never behind a circle), so
   nothing shows through a translucent locked marker, and it's centered on
   the circle via the same left offset the marker itself sits at
   (10px node padding + 20px half-marker-width). */
.roadmap-node::before,
.roadmap-node::after {
  content: "";
  position: absolute;
  left: 30px;
  width: 1px;
  transform: translateX(-50%);
  background: repeating-linear-gradient(180deg, var(--border) 0 3px, transparent 3px 4px);
}

.roadmap-node::before {
  top: 0;
  height: 12px;
}

.roadmap-node::after {
  top: 58px;
  bottom: 0;
}

.roadmap-node:first-child::before,
.roadmap-node:last-child::after {
  display: none;
}

.roadmap-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 5px;
}

.roadmap-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
}

.roadmap-blurb {
  font-size: 0.85rem;
  color: var(--muted);
}

.roadmap-node.is-completed .roadmap-marker {
  background: var(--good);
  border-color: var(--good);
  color: var(--cream);
}

.roadmap-node.is-completed .roadmap-title {
  color: var(--good);
}

.roadmap-node.is-current {
  background: var(--paper);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--gold-light);
}

.roadmap-node.is-current .roadmap-marker {
  background: var(--wine);
  border-color: var(--wine);
  color: #fff;
  box-shadow: 0 0 14px 2px rgba(var(--wine-rgb), 0.4);
}

.roadmap-node.is-current .roadmap-title {
  color: var(--gold);
}

.roadmap-node.is-pending {
  background: rgba(var(--gold-rgb), 0.1);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--gold);
}

.roadmap-node.is-pending .roadmap-marker {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--cream);
}

.roadmap-node.is-pending .roadmap-title {
  color: var(--gold);
}

.roadmap-node.is-locked {
  opacity: 0.6;
}

.roadmap-node.is-locked .roadmap-marker {
  font-size: 1.1rem;
}

.roadmap-soon {
  opacity: 0.5;
}

.roadmap-soon .roadmap-marker {
  border-style: dashed;
}

/* ---------- Chapter units (homepage roadmap) ---------- */

.units-wrap {
  max-width: 640px;
  margin: 0 auto;
}

.unit {
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin-bottom: 22px;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

.unit-head {
  background: var(--wine);
  color: #fff;
  padding: 16px 20px;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}

.unit-head.is-soon {
  background: var(--muted);
}

.unit-head.is-mastery {
  background: var(--gold-light);
}

.unit-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1rem;
}

.unit-frac {
  font-size: 0.8rem;
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.unit-body {
  background: var(--paper);
  padding: 18px;
}

.tile-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin-bottom: 10px;
}

.tile-row:last-child {
  margin-bottom: 0;
}

.tile {
  display: block;
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 8px;
  text-align: center;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease;
}

.tile[href]:hover {
  border-color: var(--gold-light);
}

.tile-num {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--border);
  color: var(--muted);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.78rem;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 7px;
}

.tile.is-current .tile-num {
  background: var(--wine);
  border-color: var(--wine);
  color: #fff;
  box-shadow: 0 0 14px 2px rgba(var(--wine-rgb), 0.4);
}

.tile.is-completed .tile-num {
  background: var(--good);
  border-color: var(--good);
  color: var(--cream);
}

.tile.is-pending .tile-num {
  background: var(--gold);
  border-color: var(--gold);
  color: var(--cream);
}

.tile.is-pending .tile-label {
  color: var(--gold);
}

.tile.is-soon {
  opacity: 0.55;
}

.tile.is-soon .tile-num {
  border-style: dashed;
}

.tile-label {
  display: block;
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--muted);
  line-height: 1.25;
}

.tile.is-current .tile-label,
.tile.is-completed .tile-label {
  color: var(--ink);
}


/* ---------- Lesson layout ---------- */

.lesson-header {
  position: sticky;
  top: 3px;
  background: rgba(250, 246, 239, 0.88);
  backdrop-filter: blur(6px);
  padding: 14px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  z-index: 10;
}

.lesson-header .home-link {
  flex: none;
  font-size: 0.9rem;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}

.lesson-title {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--wine-dark);
  /* Three items in a sticky header on a phone: the title is the one that
     should give, not the back link or the account chip. min-width:0 is
     what actually lets a flex item shrink below its text width. */
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 0 10px;
}

/* Injected by account-nav.js — the header's "who am I" chip. */
.account-nav {
  flex: none;
  font-size: 0.82rem;
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 11px;
  max-width: 9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.account-nav:hover {
  color: var(--wine);
  border-color: var(--wine);
}

.account-nav.is-signed-in {
  color: var(--wine);
  border-color: rgba(var(--wine-rgb), 0.35);
  background: rgba(var(--wine-rgb), 0.06);
}

.progress-track {
  height: 3px;
  background: var(--border);
  overflow: hidden;
  position: relative;
  z-index: 1;
}

.progress-fill {
  height: 100%;
  width: 20%;
  background: linear-gradient(90deg, var(--gold), var(--wine));
  transition: width 0.3s ease;
}

.step {
  display: none;
  animation: fade 0.25s ease;
}

.step.active {
  display: block;
}

@keyframes fade {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.step-label {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  color: var(--gold);
  font-weight: 700;
  margin: 28px 0 8px;
}

h2 {
  color: var(--wine-dark);
  margin: 0 0 14px;
  font-size: clamp(1.35rem, 3vw + 0.8rem, 1.7rem);
  letter-spacing: -0.005em;
}

.card {
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  box-shadow: var(--shadow-sm);
  margin-bottom: 18px;
}

.card h3 {
  font-size: 1.15rem;
  color: var(--wine-dark);
}

.wine-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 18px 0;
}

@media (max-width: 560px) {
  .wine-pair {
    grid-template-columns: 1fr;
  }
}

.wine-pair.single {
  grid-template-columns: 1fr;
  max-width: 480px;
}

.wine-box {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  background: var(--paper);
}

.wine-box.white {
  border-top: 3px solid var(--gold-light);
}

.wine-box.oaked {
  border-top: 3px solid var(--gold);
}

.wine-box h3 {
  margin: 0 0 6px;
  font-size: 1.1rem;
  color: var(--ink);
}

.wine-box p {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: 0.92rem;
}

.wine-box p:last-child {
  margin-bottom: 0;
}

.wine-box p.wine-examples {
  font-size: 0.82rem;
  font-style: italic;
}

.cant-find-wine {
  grid-column: 1 / -1;
  text-align: center;
  font-size: 0.85rem;
  margin: 4px 0 0;
}

.cant-find-wine a {
  color: var(--muted);
  text-decoration: underline;
}

.cant-find-wine.is-pending {
  background: rgba(var(--gold-rgb), 0.14);
  border-radius: var(--radius-lg);
  padding: 8px 12px;
  margin-top: 10px;
}

.cant-find-wine.is-pending a {
  color: var(--gold);
  font-weight: 700;
  text-decoration: none;
}

/* ---------- "Come back to these" homepage shelf ---------- */

.come-back-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin: 14px 0 0;
}

.come-back-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(var(--gold-rgb), 0.14);
  border: 1px solid rgba(var(--gold-rgb), 0.4);
  border-radius: 999px;
  padding: 7px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
}

.come-back-chip:hover {
  background: rgba(var(--gold-rgb), 0.22);
}

/* ---------- Region locator map ---------- */

.region-map-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--map-sea);
  margin: 14px 0;
}

.region-map-loading {
  padding: 40px 0;
  text-align: center;
  font-size: 0.85rem;
  color: var(--muted);
}

.lesson-video-wrap {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 */
  border-radius: var(--radius-lg);
  overflow: hidden;
  margin: 14px 0;
  border: 1px solid var(--border);
}

.lesson-video-wrap iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.region-map-svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
}

/* --map-sea/--map-land/--map-stroke (set per [data-theme] block above) —
   the map needs its own dedicated tokens rather than reusing --paper/
   --border directly: those are tuned for hairlines and card fills, not for
   a filled shape that needs to read clearly against its own sea color. */
.region-map-svg .country {
  fill: var(--map-land) !important;
  stroke: var(--map-stroke);
  stroke-width: 0.15;
}

.region-map-dot {
  fill: var(--gold);
}

.region-map-pulse {
  fill: var(--gold);
  opacity: 0.5;
  transform-box: fill-box;
  transform-origin: center;
  animation: regionPulse 2s ease-out infinite;
}

@keyframes regionPulse {
  0% { transform: scale(1); opacity: 0.5; }
  100% { transform: scale(4.5); opacity: 0; }
}

.region-map-label {
  padding: 8px 14px;
  font-size: 0.8rem;
  color: var(--muted);
  text-align: center;
  border-top: 1px solid var(--border);
  background: var(--paper);
}

.region-map-world-svg {
  aspect-ratio: 2 / 1;
}

.region-map-world-dot {
  fill: var(--map-dot-idle);
  stroke: var(--muted);
  stroke-width: 0.4;
  opacity: 0.4;
}

.region-map-world-dot.done {
  fill: var(--gold);
  stroke: var(--gold);
  stroke-width: 0.6;
  opacity: 1;
  filter: drop-shadow(0 0 1.5px var(--gold)) drop-shadow(0 0 3px rgba(var(--gold-rgb), 0.7));
}

.color-compare {
  display: flex;
  gap: 18px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.color-swatch-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
  color: var(--muted);
}

.color-swatch {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.25);
  display: inline-block;
  flex: 0 0 auto;
}

/* ---------- Range scale — the shared tasting-scale control (Foundations'
   3-point scales, World Tour's 5-point scales, and the color picker) built
   in lesson-engine.js via rangeScaleHtml()/initRangeScales(). Originally
   prototyped in isolation in slider-demo.html before rollout. ---------- */

.range-scale {
  margin: 14px 0 20px;
}

.range-scale-value {
  text-align: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--gold);
  margin-bottom: 12px;
  min-height: 1.4em;
  transition: color 0.15s ease, opacity 0.15s ease;
}

/* Shows the slider's real default value rather than a "—" placeholder, but
   muted — visually unconfirmed until the learner actually moves it, so an
   untouched default never reads as an answer they chose. */
.range-scale-value.is-untouched {
  color: var(--muted);
  opacity: 0.7;
}

.range-scale-track-wrap {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 44px;
}

/* The dots' own boxes are 36x36 (a real touch target) with a small visual
   circle centered inside via ::before — position: absolute + left:X% (set
   inline by JS from each dot's value) keeps the *visual* dot exactly on the
   track regardless of hit-box size. The ticks layer ignores pointer events
   except on the dots themselves, so clicks between dots fall through to the
   input underneath and use its native (also enlarged) click-to-jump.
   .range-scale-track-line is a sibling, not a child, of this — it needs to
   sit *below* the thumb (z-index 1), while the dots need to sit *above* it,
   so the two can't share one stacking context. */
.range-scale-ticks {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.range-scale-tick-dot {
  position: absolute;
  top: 50%;
  width: 36px;
  height: 36px;
  margin-left: -18px;
  margin-top: -18px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: transparent;
  border: none;
  cursor: pointer;
  pointer-events: auto;
}

.range-scale-tick-dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--paper);
  border: 1.5px solid var(--border);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.range-scale-tick-dot:hover::before {
  border-color: var(--gold);
}

/* The thumb itself is the "you are here" indicator once a dot is selected —
   its own small dot hides rather than trying to sit pixel-perfect behind
   the (bigger, native-rendered) thumb. */
.range-scale-tick-dot.active::before {
  opacity: 0;
}

/* The input itself is a generous 44px tall (a real touch target for
   "click/tap anywhere near the track" to jump the value there) — only its
   pseudo-track is styled thin, so the click/tap area is much bigger than
   what's visually painted. */
.range-scale-input {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 44px;
  background: transparent;
  position: relative;
  z-index: 1;
  margin: 0;
  cursor: pointer;
}

/* The native track pseudo-element spans the input's full width — but the
   thumb (and the dots, matching it) is inset by half its own width at each
   end, so a full-width line would visibly poke out past the outer dots.
   The native track stays transparent (still needed for layout/hit-testing)
   and .range-scale-track-line, inset by that same half-thumb-width, is the
   only visible line. */
.range-scale-input::-webkit-slider-runnable-track {
  height: 2px;
  background: transparent;
  border-radius: 999px;
}

.range-scale-input::-moz-range-track {
  height: 2px;
  background: transparent;
  border-radius: 999px;
}

.range-scale-track-line {
  position: absolute;
  top: 50%;
  left: 15px;
  right: 15px;
  height: 2px;
  background: var(--border);
  border-radius: 999px;
  transform: translateY(-50%);
  pointer-events: none;
  z-index: 0;
}

.range-scale-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--wine);
  border: 2px solid var(--ink);
  box-shadow: 0 2px 10px -1px rgba(var(--wine-rgb), 0.65);
  cursor: pointer;
  margin-top: -14px;
}

.range-scale-input::-moz-range-thumb {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--wine);
  border: 2px solid var(--ink);
  box-shadow: 0 2px 10px -1px rgba(var(--wine-rgb), 0.65);
  cursor: pointer;
}

.range-scale-endlabels {
  display: flex;
  justify-content: space-between;
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 8px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.tip {
  background: linear-gradient(135deg, rgba(var(--gold-rgb), 0.12), rgba(var(--wine-rgb), 0.05)), var(--paper);
  border: 1px solid rgba(var(--gold-rgb), 0.35);
  border-radius: var(--radius-lg);
  padding: 15px 18px;
  font-size: 0.92rem;
  color: var(--ink);
  margin: 14px 0;
}

fieldset {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px;
  margin: 0 0 18px;
  background: var(--paper);
}

legend {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
  padding: 0 8px;
  color: var(--gold);
}

.scale {
  display: flex;
  gap: 8px;
  margin: 10px 0 14px;
  flex-wrap: wrap;
}

.scale label {
  flex: 1 1 30%;
  min-width: 90px;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 6px;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--ink);
  background: rgba(36, 28, 24, 0.015);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.scale label:hover {
  border-color: var(--gold);
}

.scale input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.scale input:checked + span {
  font-weight: 700;
}

.scale label:has(input:checked) {
  background: var(--wine);
  color: #fff;
  border-color: var(--wine);
  transform: translateY(-1px);
  box-shadow: 0 4px 14px -2px rgba(var(--wine-rgb), 0.55);
}

label.text-label {
  display: block;
  font-size: 0.88rem;
  color: var(--muted);
  margin-bottom: 6px;
}

textarea, input[type="text"] {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  font-family: inherit;
  font-size: 0.95rem;
  resize: vertical;
  min-height: 44px;
  background: var(--cream);
  color: var(--ink);
}

textarea::placeholder, input[type="text"]::placeholder {
  color: var(--muted);
  opacity: 0.7;
}

textarea:focus, input[type="text"]:focus {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

/* ---------- Auth forms ----------
   Sign in, sign up and reset password all render through
   CloudSync.renderAuthForm/renderSignUpForm, which used to build their
   fields with an inline style string. Real classes instead, so the fields
   pick up theme tokens the same way everything else does and the four
   themes don't have to be kept in sync with a JS literal. */

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 340px;
  margin-top: 14px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.field-label {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}

.field-input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 8px;
  /* 16px keeps iOS Safari from zooming the whole page in on focus, which
     it does for any font-size below that in a text field. */
  font-size: 16px;
  font-family: inherit;
  padding: 10px 12px;
  min-height: 44px;
  background: var(--cream);
  color: var(--ink);
}

.field-input:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.field-hint {
  font-size: 0.78rem;
  color: var(--muted);
}

.auth-form .btn {
  align-self: flex-start;
  margin-top: 2px;
}

.auth-alt {
  font-size: 0.9rem;
  margin: 10px 0 0;
}

.auth-status {
  font-size: 0.88rem;
  color: var(--muted);
  margin: 10px 0 0;
  min-height: 1.2em;
}

.auth-status.is-bad {
  color: var(--bad);
}

.auth-status.is-good {
  color: var(--good);
}

/* The narrow, centered card sign-in.html / sign-up.html / reset-password.html
   sit inside — a full-width 640px column around a 340px form reads as a
   layout bug rather than a page. */
.auth-page {
  max-width: 420px;
  margin: 0 auto;
}

.flavor-wheel {
  margin: 8px 0 16px;
}

.flavor-wheel-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 2px 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--wine);
  cursor: pointer;
}

.flavor-wheel-toggle:hover {
  text-decoration: underline;
}

.flavor-wheel-toggle.is-open::before {
  content: "▾ ";
}

.flavor-wheel-toggle:not(.is-open)::before {
  content: "▸ ";
}

.flavor-wheel-panel:not([hidden]) {
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--cream);
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.flavor-wheel-cat {
  border-bottom: 1px solid var(--border);
}

.flavor-wheel-cat:last-child {
  border-bottom: none;
}

.flavor-wheel-cat-toggle {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 8px 2px;
  font-family: var(--font-display);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--gold);
  cursor: pointer;
}

.flavor-wheel-groups:not([hidden]) {
  padding: 0 2px 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.flavor-wheel-group-label {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 4px;
}

.flavor-wheel-terms {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.flavor-wheel-term {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 0.82rem;
  color: var(--ink);
  background: var(--paper);
  cursor: pointer;
  transition: transform 0.1s ease, border-color 0.15s ease, background 0.15s ease;
}

.flavor-wheel-term:hover {
  border-color: var(--gold);
  transform: translateY(-1px);
}

/* ---------- "Compare to another wine you've tasted" ----------
   Same collapsed-by-default toggle pattern as the flavor wheel above --
   off by default so it never competes with the primary radar. */
.compare-wine {
  margin-top: 18px;
}

.compare-wine-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  padding: 2px 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--wine);
  cursor: pointer;
}

.compare-wine-toggle:hover {
  text-decoration: underline;
}

.compare-wine-toggle.is-open::before {
  content: "▾ ";
}

.compare-wine-toggle:not(.is-open)::before {
  content: "▸ ";
}

.compare-wine-panel:not([hidden]) {
  margin-top: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--cream);
  padding: 12px 14px;
}

.compare-wine-panel select {
  display: block;
  width: 100%;
  max-width: 340px;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 10px;
  font-size: 16px;
  font-family: inherit;
  background: var(--paper);
  color: var(--ink);
  margin-top: 4px;
}

.compare-wine-panel select:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.flavor-wheel-term.is-picked {
  background: var(--wine);
  border-color: var(--wine);
  color: #fff;
}

.actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 8px;
}

.feedback-box {
  border-radius: var(--radius-lg);
  padding: 20px;
  margin-bottom: 18px;
  border: 1px solid var(--border);
  background: var(--paper);
}

.feedback-box.correct {
  background: rgba(95, 201, 138, 0.1);
  border-color: rgba(95, 201, 138, 0.4);
}

.feedback-box.incorrect {
  background: rgba(226, 120, 106, 0.1);
  border-color: rgba(226, 120, 106, 0.4);
}

.feedback-box h3 {
  margin: 0 0 6px;
  font-size: 1.15rem;
}

.feedback-box.correct h3 {
  color: var(--good);
}

.feedback-box.incorrect h3 {
  color: var(--bad);
}

.quiz-q {
  margin-bottom: 20px;
}

.quiz-q p.q-text {
  font-weight: 600;
  margin: 0 0 10px;
  color: var(--ink);
}

.quiz-options label {
  display: block;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  font-size: 0.94rem;
  color: var(--ink);
  transition: all 0.15s ease;
}

.quiz-options label:has(input:checked) {
  border-color: var(--wine);
  background: rgba(var(--wine-rgb), 0.15);
}

.quiz-options input {
  margin-right: 8px;
}

.quiz-options label.q-correct {
  border-color: var(--good) !important;
  background: rgba(95, 201, 138, 0.18) !important;
}

.quiz-options label.q-wrong {
  border-color: var(--bad) !important;
  background: rgba(226, 120, 106, 0.18) !important;
}

.quiz-score {
  text-align: center;
  padding: 28px 16px;
}

.quiz-score .score-num {
  font-family: var(--font-display);
  font-size: 2.8rem;
  font-weight: 700;
  color: var(--wine-dark);
}

.done-actions {
  text-align: center;
  margin-top: 20px;
}

.badge-chip {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--paper);
}

.badge-chip svg {
  flex: 0 0 auto;
}

.badge-info {
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.4;
}

.badge-info strong {
  display: block;
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--ink);
  margin-bottom: 2px;
}

.badge-apprentice {
  border-color: rgba(var(--gold-rgb), 0.4);
}

.badge-adept {
  border-color: rgba(200, 210, 235, 0.5);
  background: linear-gradient(135deg, rgba(200, 210, 235, 0.08), rgba(var(--wine-rgb), 0.06)), var(--paper);
}

.badge-sommelier {
  border: 1.5px solid var(--gold);
  box-shadow: var(--shadow-sm);
  background: linear-gradient(135deg, rgba(var(--gold-rgb), 0.14), rgba(var(--wine-rgb), 0.06)), var(--paper);
}

.badges-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin: 14px 0 0;
}

.badges-row .badge-chip {
  flex: 0 1 260px;
}

.badge-chip.is-locked {
  opacity: 0.5;
  filter: grayscale(0.7);
}

.trophy-earned-date {
  color: var(--gold);
  font-size: 0.78rem;
}

.trophy-locked-hint {
  font-style: italic;
}

a.trophy-link-wrap {
  display: flex;
  flex: 0 1 260px;
  text-decoration: none;
  color: inherit;
}

a.trophy-link-wrap .badge-chip {
  flex: 1 1 auto;
  transition: border-color 0.15s ease;
}

a.trophy-link-wrap:hover .badge-chip {
  border-color: var(--gold-light);
}

.hint {
  font-size: 0.85rem;
  color: var(--muted);
  margin-top: -6px;
  margin-bottom: 14px;
}

/* ---------- Tasting Radar ---------- */

.radar-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.radar-svg {
  width: 100%;
  max-width: 420px;
  height: auto;
  overflow: visible;
}

.radar-grid {
  fill: none;
  stroke: var(--border);
  stroke-width: 1;
}

.radar-spoke {
  stroke: var(--border);
  stroke-width: 1;
}

.radar-expected-fill {
  fill: var(--accent-2);
  fill-opacity: 0.18;
  stroke: none;
}

.radar-expected-line {
  fill: none;
  stroke: var(--accent-2);
  stroke-width: 2.5;
  stroke-dasharray: 7 5;
}

.radar-user-fill {
  fill: var(--wine);
  fill-opacity: 0.28;
  stroke: none;
}

.radar-user-line {
  fill: none;
  stroke: var(--wine);
  stroke-width: 3;
}

.radar-expected-dot {
  fill: var(--accent-2);
}

.radar-user-dot {
  fill: var(--wine);
}

.radar-label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink);
}

.radar-legend {
  display: flex;
  gap: 20px;
  font-size: 0.85rem;
  color: var(--muted);
}

.radar-legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.radar-swatch {
  width: 22px;
  height: 3px;
  display: inline-block;
  border-radius: 2px;
}

.radar-swatch-user {
  background: var(--wine);
}

.radar-swatch-expected {
  background-image: repeating-linear-gradient(90deg, var(--accent-2) 0 6px, transparent 6px 10px);
}

.descriptor-compare {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.descriptor-compare:first-of-type {
  border-top: none;
  padding-top: 0;
}

.descriptor-compare h4 {
  font-family: var(--font-display);
  color: var(--gold);
  margin: 0 0 8px;
  font-size: 1.05rem;
}

.descriptor-row {
  margin-bottom: 6px;
  font-size: 0.92rem;
}

.descriptor-row .descriptor-tag {
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  margin-right: 8px;
}

.descriptor-row.expected .descriptor-tag {
  color: var(--accent-2);
}

.descriptor-row.actual .descriptor-tag {
  color: var(--wine);
}

.descriptor-row .descriptor-text {
  font-style: italic;
  color: var(--ink);
}

.radar-breakdown {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.breakdown-row {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px 14px;
  background: rgba(36, 28, 24, 0.015);
}

.breakdown-head {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.breakdown-tag {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

.breakdown-row.spot-on .breakdown-tag {
  background: rgba(95, 201, 138, 0.18);
  color: var(--good);
}

.breakdown-row.close .breakdown-tag {
  background: rgba(var(--gold-rgb), 0.18);
  color: var(--gold);
}

.breakdown-row.off .breakdown-tag {
  background: rgba(226, 120, 106, 0.18);
  color: var(--bad);
}

.breakdown-cat {
  font-weight: 700;
  color: var(--ink);
}

.breakdown-note {
  margin: 8px 0 0;
  font-size: 0.9rem;
  color: var(--muted);
}

/* ---------- My Wine Profile ---------- */

.profile-summary {
  font-size: 0.96rem;
  line-height: 1.55;
}

.profile-stats {
  display: flex;
  gap: 10px;
}

.profile-stat {
  flex: 1;
  text-align: center;
  padding: 6px 4px;
}

.profile-stat-num {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--wine-dark);
}

.profile-stat-label {
  display: block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-top: 2px;
}

.profile-bar-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}

.profile-bar-row:last-child {
  margin-bottom: 0;
}

.profile-bar-label {
  flex: 0 0 auto;
  min-width: 110px;
  font-size: 0.88rem;
  color: var(--ink);
}

.profile-bar-track {
  flex: 1;
  height: 8px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}

.profile-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--gold), var(--wine));
}

.profile-bar-value {
  flex: 0 0 auto;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted);
  width: 28px;
  text-align: right;
}

.profile-wine-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}

.profile-wine-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.profile-wine-row:first-child {
  padding-top: 0;
}

/* =========================================================================
   Theme-specific overrides — "cellar-journal" needs none of this (every
   rule above already renders it correctly); these three patch the modern
   themes onto the same markup: no rung motif (that's a cellar-journal
   flourish), a filled slider track instead of the editorial tick-dot line
   (initRangeScales in lesson-engine.js sets --fill-pct on .range-scale-
   track-line as the value changes), and glass-pour's frosted-card look.
   ========================================================================= */

:root[data-theme="cellar-app"] body::after,
:root[data-theme="midnight"] body::after,
:root[data-theme="glass-pour"] body::after,
:root[data-theme="cellar-app"] .hero::before,
:root[data-theme="midnight"] .hero::before,
:root[data-theme="glass-pour"] .hero::before {
  display: none;
}

:root[data-theme="cellar-app"] .tagline,
:root[data-theme="midnight"] .tagline,
:root[data-theme="glass-pour"] .tagline {
  font-style: normal;
}

:root[data-theme="cellar-app"] .lesson-header {
  background: rgba(255, 255, 255, 0.88);
}
:root[data-theme="midnight"] .lesson-header {
  background: rgba(18, 17, 19, 0.85);
}
:root[data-theme="glass-pour"] .lesson-header {
  background: rgba(255, 255, 255, 0.35);
}

/* Filled slider track — a gradient split at --fill-pct reads as "progress
   filled in" the way a modern app's slider does, instead of a thin line
   with tick-dot markers. The dots stay in the DOM and stay clickable
   (removing them would remove the click-to-jump target); only their small
   visible circle is hidden. */
:root[data-theme="cellar-app"] .range-scale-track-line,
:root[data-theme="midnight"] .range-scale-track-line,
:root[data-theme="glass-pour"] .range-scale-track-line {
  height: 5px;
  background: linear-gradient(
    to right,
    var(--wine) var(--fill-pct, 50%),
    var(--border) var(--fill-pct, 50%)
  );
}
:root[data-theme="cellar-app"] .range-scale-tick-dot::before,
:root[data-theme="midnight"] .range-scale-tick-dot::before,
:root[data-theme="glass-pour"] .range-scale-tick-dot::before {
  opacity: 0;
}

/* ---------- Glass Pour: frosted cards over a soft rose gradient ---------- */

:root[data-theme="glass-pour"] body {
  background: linear-gradient(160deg, #f6d9de 0%, #f1c9d3 45%, #dba9c0 100%);
}
:root[data-theme="glass-pour"] .card,
:root[data-theme="glass-pour"] fieldset,
:root[data-theme="glass-pour"] .wine-box,
:root[data-theme="glass-pour"] .feedback-box,
:root[data-theme="glass-pour"] .badge-chip,
:root[data-theme="glass-pour"] .region-map-wrap,
:root[data-theme="glass-pour"] .roadmap-node.is-current,
:root[data-theme="glass-pour"] .lesson-header,
:root[data-theme="glass-pour"] .theme-switcher-toggle,
:root[data-theme="glass-pour"] .theme-switcher-panel {
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

/* ---------- Theme switcher widget (floating, every page) ---------- */

.theme-switcher {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 100;
  font-family: var(--font-body);
}

.theme-switcher-toggle {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--paper);
  box-shadow: var(--shadow-sm);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.theme-switcher-panel {
  position: absolute;
  bottom: 58px;
  right: 0;
  background: var(--paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 168px;
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.theme-switcher.open .theme-switcher-panel {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.theme-switcher-swatch {
  display: flex;
  align-items: center;
  gap: 10px;
  border: none;
  background: transparent;
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 0.85rem;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
}

.theme-switcher-swatch:hover {
  background: rgba(var(--wine-rgb), 0.08);
}

.theme-switcher-swatch.theme-switcher-active {
  background: rgba(var(--wine-rgb), 0.12);
  font-weight: 700;
}

.theme-switcher-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  flex: 0 0 auto;
  box-shadow: 0 0 0 2px var(--paper), 0 0 0 3px var(--border);
}
