/* ── Gather — Community Game Platform ── */
/* Display font: Cabinet Grotesk, SELF-HOSTED (no CDN — local-first).
   Re-enabled 2026-06-02 with the design-system refresh (Jeremy approved).
   The variable woff2 lives at public/fonts/ (served at /fonts/…). Headings,
   wordmark + hero use --font-display (set to Cabinet Grotesk by the active
   theme, gather-earth); body + UI stay on the system stack. Declared here
   (static, first-paint) so it's available before the theme CSS loads;
   falls back cleanly to the system stack if the file is ever removed. */
@font-face {
  font-family: "Cabinet Grotesk";
  src: url("/fonts/CabinetGrotesk-Variable.woff2") format("woff2-variations"),
       url("/fonts/CabinetGrotesk-Variable.woff2") format("woff2");
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
}

/* Bootstrap fallbacks — full token set provided by active theme via
   /api/themes/active.css. Plugins MUST consume tokens via
   var(--token-name) — see docs/architecture/plugin-design-checklist.md §11.
   These ~20 tokens are the minimum needed to render the page legibly
   in the brief window before the theme stylesheet loads. Theme tokens
   then take over via cascade. Migrated 2026-05-21 — token contract
   now lives in plugins/themes/themes/{id}/theme.json (v2). */
:root {
  /* Essential colours */
  --green:        #2B5F2B;
  --sage-700:     #2B5F2B;
  --terra-700:    #C4652A;
  --cream:        #FAF6F0;
  --neutral-100:  #F5F2EC;
  --neutral-800:  #2C2C2C;
  --neutral-900:  #1A1A1A;
  --text:         #2C2C2C;
  --white:        #FFFFFF;
  --surface-page: #FAF6F0;
  --surface-card: #FFFFFF;
  --border-subtle:#EAE5DA;

  /* Typography (body = system stack; display = Cabinet Grotesk with system fallback) */
  --font-body:    -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --font-display: 'Cabinet Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --fs-base:      1rem;

  /* Spacing fallback */
  --space-sm:     8px;
  --space-md:     12px;
  --space-lg:     16px;

  /* Radius fallback */
  --radius-md:    10px;
  --radius-full:  9999px;
  --radius:       10px;          /* legacy alias */

  /* Shadow fallback */
  --shadow-sm:    0 1px 2px rgba(76,55,30,0.04), 0 1px 3px rgba(76,55,30,0.06);

  /* Motion fallback */
  --duration-fast: 150ms;
  --ease-out:      cubic-bezier(0.16, 1, 0.3, 1);
  --transition:    250ms cubic-bezier(0.16, 1, 0.3, 1);

  /* Layout — touch-min is referenced everywhere on mobile */
  --touch-min:    48px;
}

/* Display font on headings — falls back to system-bold if Cabinet Grotesk fails to load */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: var(--tracking-tight);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  background: var(--cream);
  color: var(--text);
  line-height: 1.5;
  min-height: 100vh;
  overflow-x: hidden;
}

/* ── Layout ── */
.container {
  max-width: 900px;
  margin: 0 auto;
  padding: 1.5rem;
}

.container--wide {
  max-width: 1200px;
}

.screen {
  display: none;
  animation: fadeIn 0.4s ease;
}
.screen.active { display: block; }

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

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

@keyframes pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.05); }
}

@keyframes grow {
  from { width: 0%; }
}

/* ── Typography ── */
h1 {
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--green);
  letter-spacing: -0.02em;
  line-height: 1.2;
}

h2 {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--green);
  margin-bottom: 0.5rem;
}

h3 {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--brown);
}

.subtitle {
  color: var(--text-light);
  font-size: 1.05rem;
  margin-top: 0.3rem;
}

.tagline {
  font-size: 1.15rem;
  color: var(--brown);
  font-weight: 500;
  margin-top: 0.5rem;
}

/* ── Header ── */
.header {
  text-align: center;
  padding: 2.5rem 1rem 1.5rem;
}

.header .logo {
  font-size: 3rem;
  margin-bottom: 0.3rem;
}

.header h1 {
  font-size: 2.8rem;
}

/* ── Cards ── */
.card {
  background: var(--surface-card, #fff);
  border-radius: 12px;
  padding: 1.5rem;
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-subtle);  /* warm beige — never grey (design refresh 2026-06-02) */
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.card--flat {
  box-shadow: none;
  border: 2px solid var(--green-pale);
}

.card--highlight {
  border-left: 4px solid var(--green);
}

/* ── Buttons ──
   HTML: <button class="btn btn--primary btn--md">Save</button>
   Variants: --primary / --secondary / --outline / --ghost / --danger
   Sizes: --sm (32px) / default (40-48px) / --large (56px)
   Sentence-case is the new default — uppercase ONLY where intentional
   (e.g. game host screen). Old uppercase look was 2018-era.
*/
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  padding: var(--space-md) var(--space-xl);
  border: none;
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
  text-decoration: none;
  line-height: 1.3;
  min-height: var(--touch-min);
  font-family: inherit;
  letter-spacing: 0;          /* sentence-case modern default */
  position: relative;
  overflow: hidden;
}
.btn:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.btn--sm { min-height: 32px; padding: var(--space-xs) var(--space-md); font-size: var(--fs-sm); }
.btn--md { min-height: 40px; padding: var(--space-sm) var(--space-lg); font-size: var(--fs-base); }
.btn--lg { min-height: var(--touch-min); padding: var(--space-md) var(--space-xl); font-size: var(--fs-lg); }
.btn--ghost {
  background: transparent;
  color: var(--neutral-800);
}
.btn--ghost:hover { background: var(--neutral-100); }
.btn--danger {
  background: var(--error-fg);
  color: var(--white);
}
.btn--danger:hover { background: #9a3838; }
.btn--danger:focus-visible { box-shadow: 0 0 0 3px rgba(181,67,67,0.22); }
/* Premium / paid CTA — terracotta is the PREMIUM accent semantic (UX-ACCENT-1) */
.btn--premium {
  background: var(--terra-700);
  color: var(--white);
}
.btn--premium:hover { background: var(--terra-800); }
.btn--premium:focus-visible { box-shadow: var(--focus-ring-terra); }

/* Primary = grad-leaf fill, cream text, soft warm shadow, hover lifts
   (design refresh 2026-06-02 — flattened the old chunky 3D bottom-edge to
   match the prototype's soft buttons). */
.btn--primary {
  background: linear-gradient(135deg, #2B5F2B, #4A8C3F);
  color: var(--white);
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover {
  background: linear-gradient(135deg, #1f4620, #3a7535);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(76,55,30,0.14);
}
.btn--primary:active {
  transform: translateY(0);
  box-shadow: var(--shadow-sm);
}

.btn--secondary {
  background: var(--terracotta);
  color: var(--white);
}
.btn--secondary:hover { background: var(--terracotta-light); transform: translateY(-1px); }

.btn--outline {
  background: transparent;
  color: var(--green);
  border: 2px solid var(--green);
}
.btn--outline:hover { background: var(--green); color: var(--white); }

.btn--large {
  padding: 1.2rem 2.5rem;
  font-size: 1.2rem;
  border-radius: var(--radius-lg);
  width: 100%;
  max-width: 360px;
}

.btn--answer {
  width: 100%;
  padding: 1rem 1.5rem;
  font-size: 1.1rem;
  font-weight: 700;
  border-radius: 16px;
  margin-bottom: 0.6rem;
  text-align: left;
  background: white;
  color: var(--text);
  border: 3px solid var(--green-pale);
  min-height: 56px;
  transition: all 0.2s;
  animation: slideUp 0.3s ease backwards;
}
.btn--answer:nth-child(1) { animation-delay: 0s; }
.btn--answer:nth-child(2) { animation-delay: 0.05s; }
.btn--answer:nth-child(3) { animation-delay: 0.1s; }
.btn--answer:nth-child(4) { animation-delay: 0.15s; }
.btn--answer:hover {
  border-color: var(--green);
  background: var(--green-pale);
  transform: scale(1.02);
}
.btn--answer:active { transform: scale(0.98); }
.btn--answer.selected {
  background: var(--green);
  color: white;
  border-color: var(--green);
  animation: bounceIn 0.3s;
}
.btn--answer.correct {
  border-color: var(--green-light);
  background: #d4edda;
  color: var(--green);
}
.btn--answer.incorrect {
  border-color: #c0392b;
  background: #fde8e8;
  color: #c0392b;
}

.btn--this-or-that {
  flex: 1;
  padding: 1.5rem 1rem;
  font-size: 1.1rem;
  font-weight: 700;
  border-radius: 16px;
  transition: all 0.2s;
  text-align: center;
}
.btn--this-or-that:first-child {
  background: var(--green-pale);
  border: 3px solid var(--green);
  color: var(--green);
}
.btn--this-or-that:last-child {
  background: #fef0e8;
  border: 3px solid var(--terracotta);
  color: var(--terracotta);
}
.btn--this-or-that:first-child:hover,
.btn--this-or-that:first-child.selected {
  background: var(--green);
  color: white;
}
.btn--this-or-that:last-child:hover,
.btn--this-or-that:last-child.selected {
  background: var(--terracotta);
  color: white;
}

.btn-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  margin-top: 1.5rem;
}

.btn-group--row {
  flex-direction: row;
  justify-content: center;
}

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

/* ── Inputs ──
   HTML: <label class="field"><span class="field__label">Email</span><input class="input"></label>
   States: .is-error / .is-success
   Critical change: :focus-visible now adds a focus RING (box-shadow), not just
   a border colour change — keyboard accessibility win.
*/
.input {
  width: 100%;
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  font-family: inherit;
  background: var(--white);
  color: var(--neutral-800);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
  min-height: var(--touch-min);
}
.input::placeholder { color: var(--neutral-400); }
.input:hover { border-color: var(--border-strong); }
.input:focus,
.input:focus-visible {
  outline: none;
  border-color: var(--sage-700);
  box-shadow: var(--focus-ring);
}
.input.is-error {
  border-color: var(--error-fg);
  background: var(--error-bg);
}
.input.is-error:focus-visible {
  box-shadow: 0 0 0 3px rgba(181,67,67,0.22);
}

/* Field wrapper (semantic label + input pairing) */
.field { display: block; margin-bottom: var(--space-md); }
.field__label {
  display: block;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--neutral-600);
  margin-bottom: var(--space-xs);
}
.field__hint {
  display: block;
  font-size: var(--fs-xs);
  color: var(--neutral-500);
  margin-top: var(--space-xs);
}
.field__error {
  display: block;
  font-size: var(--fs-xs);
  color: var(--error-fg);
  margin-top: var(--space-xs);
}

.input--large {
  font-size: 1.8rem;
  text-align: center;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  font-weight: 700;
  padding: 1rem;
}

.input-group {
  margin-bottom: 1rem;
}

.input-group label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.4rem;
  color: var(--brown);
  font-size: 0.95rem;
}

/* ── Room code display ── */
.room-code {
  font-size: 3.5rem;
  font-weight: 900;
  letter-spacing: 0.15em;
  color: var(--green);
  padding: 0.5rem 1rem;
  background: var(--green-pale);
  border-radius: 16px;
  display: inline-block;
  margin: 0.5rem 0;
  animation: bounceIn 0.5s ease;
  font-family: 'Courier New', monospace;
}

.room-code--small {
  font-size: 1.5rem;
  padding: 0.4rem 0.8rem;
  display: inline-block;
}

/* ── QR Code ── */
.qr-container {
  text-align: center;
  padding: 1rem;
}

.qr-container img, .qr-container svg {
  max-width: 200px;
  border-radius: var(--radius);
  background: var(--cream);
}

/* ── Player list ── */
.player-list {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0;
}

.player-list li {
  background: var(--green-pale);
  color: var(--green);
  padding: 0.4rem 1rem;
  border-radius: 2rem;
  font-weight: 600;
  font-size: 0.95rem;
  animation: slideUp 0.3s ease;
}

/* ── Game list ── */
.game-list {
  display: grid;
  gap: 1rem;
}

.game-card {
  position: relative;
  border: 2px solid var(--green-pale);
  border-radius: 16px;
  padding: 1.2rem;
  background: white;
  cursor: pointer;
  transition: all 0.25s;
  margin-bottom: 0.8rem;
}
.game-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}
.game-card.selected {
  border-color: var(--green);
  background: var(--green-pale);
  box-shadow: 0 4px 20px rgba(43, 95, 43, 0.2);
  animation: glow 2s infinite;
}

.game-card .game-type {
  display: inline-block;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--terracotta);
  background: #fdf0e6;
  padding: 0.2rem 0.6rem;
  border-radius: 1rem;
  margin-bottom: 0.5rem;
}

.game-card h3 { margin-bottom: 0.3rem; }
.game-card p { font-size: 0.92rem; color: var(--text-light); }
.game-card .meta { font-size: 0.82rem; color: var(--text-light); margin-top: 0.5rem; }

/* ── Progress bar ── */
.progress-bar {
  height: 6px;
  background: var(--green-pale);
  border-radius: 3px;
  overflow: hidden;
}

.progress-bar__fill {
  height: 100%;
  background: linear-gradient(90deg, var(--green), var(--green-light));
  border-radius: 3px;
  transition: width 0.4s ease;
}

/* ── Timer ── */
.timer {
  text-align: center;
  font-size: 2.5rem;
  font-weight: 800;
  color: var(--terracotta);
  font-variant-numeric: tabular-nums;
}

.timer.warning { color: #c0392b; animation: pulse 0.5s ease infinite; }

/* ── Results ── */
.result-bar {
  margin-bottom: 0.8rem;
}

.result-bar__label {
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.3rem;
  font-weight: 500;
}

.result-bar__track {
  height: 36px;
  background: var(--green-pale);
  border-radius: 18px;
  overflow: hidden;
  position: relative;
}

.result-bar__fill {
  height: 100%;
  border-radius: 18px;
  display: flex;
  align-items: center;
  padding: 0 1rem;
  font-weight: 700;
  font-size: 0.85rem;
  color: white;
  animation: grow 0.8s ease;
  transition: width 0.6s ease;
}

.result-bar__fill--a { background: linear-gradient(135deg, #2B5F2B, #4A8C3F); }
.result-bar__fill--b { background: linear-gradient(135deg, #C4652A, #e07a3a); }
.result-bar__fill--correct { background: linear-gradient(135deg, #2B5F2B, #4A8C3F); }
.result-bar__fill--default { background: linear-gradient(135deg, #5C3D2E, #8b6b5a); }

/* ── Scoreboard ── */
.scoreboard {
  list-style: none;
  counter-reset: rank;
}

.scoreboard li {
  display: flex;
  align-items: center;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--green-pale);
  animation: slideInLeft 0.3s ease backwards;
  font-weight: 600;
}

.scoreboard li:nth-child(1) {
  font-size: 1.1rem;
  background: linear-gradient(135deg, #ffd700, #ffec80);
  border-radius: 12px;
  border-bottom: none;
  margin-bottom: 0.3rem;
}

.scoreboard li:nth-child(2) {
  background: #f0f0f0;
  border-radius: 12px;
  border-bottom: none;
  margin-bottom: 0.3rem;
}

.scoreboard li:nth-child(3) {
  background: #fff0e6;
  border-radius: 12px;
  border-bottom: none;
  margin-bottom: 0.3rem;
}

.scoreboard .rank {
  min-width: 2rem;
  font-weight: 800;
  color: var(--green);
}

.scoreboard .name { flex: 1; }
.scoreboard .score { font-weight: 800; color: var(--terracotta); font-size: 1.1rem; }
.scoreboard .delta { font-size: 0.8rem; color: var(--green-light); margin-left: 0.3rem; }

/* ── Question display (host/projector) ── */
.question-display {
  text-align: center;
  padding: 2rem 1rem;
}

.question-display h2 {
  font-size: 2rem;
  margin-bottom: 1rem;
  color: var(--text);
}

.question-number {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--terracotta);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}

.answer-count {
  text-align: center;
  font-size: 1.3rem;
  color: var(--text-light);
  margin-top: 1rem;
}

.answer-count strong {
  color: var(--green);
  font-size: 1.8rem;
}

/* ── Waiting animation ── */
.waiting {
  text-align: center;
  padding: 2rem;
}

.dots {
  display: flex;
  gap: 0.3rem;
  justify-content: center;
}

.dots span {
  width: 12px;
  height: 12px;
  background: var(--green);
  border-radius: 50%;
  animation: dotBounce 1.4s infinite ease-in-out;
}

.dots span:nth-child(1) { animation-delay: 0s; }
.dots span:nth-child(2) { animation-delay: 0.16s; }
.dots span:nth-child(3) { animation-delay: 0.32s; }

@keyframes bounce {
  0%, 80%, 100% { transform: translateY(0); }
  40% { transform: translateY(-15px); }
}

/* ── Fun Jackbox-inspired animations ── */
@keyframes bounceIn {
  0% { transform: scale(0.3); opacity: 0; }
  50% { transform: scale(1.05); }
  70% { transform: scale(0.9); }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes slideInLeft {
  from { transform: translateX(-30px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

@keyframes slideInRight {
  from { transform: translateX(30px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); }
  20%, 40%, 60%, 80% { transform: translateX(4px); }
}

@keyframes confetti {
  0% { transform: translateY(0) rotate(0); opacity: 1; }
  100% { transform: translateY(-20px) rotate(360deg); opacity: 0; }
}

@keyframes glow {
  0%, 100% { box-shadow: 0 0 5px rgba(43, 95, 43, 0.3); }
  50% { box-shadow: 0 0 20px rgba(43, 95, 43, 0.5); }
}

@keyframes dotBounce {
  0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
  40% { transform: scale(1); opacity: 1; }
}

/* ── This-or-that layout ── */
.tot-choices {
  display: flex;
  gap: 1rem;
  margin-top: 1rem;
}

.tot-vs {
  font-size: 1.2rem;
  font-weight: 800;
  color: var(--text-light);
  padding: 0 0.5rem;
}

/* ── Word cloud ── */
.word-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  justify-content: center;
  padding: 1rem;
}

.word-cloud span {
  background: linear-gradient(135deg, var(--green-pale), #d4e8d0);
  padding: 0.4rem 0.8rem;
  border-radius: 20px;
  font-weight: 600;
  color: var(--green);
  animation: bounceIn 0.5s ease backwards;
}

/* ── Status badges ── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.8rem;
  border-radius: 2rem;
  font-size: 0.82rem;
  font-weight: 700;
}

.badge--green { background: var(--green-pale); color: var(--green); }
.badge--orange { background: #fdf0e6; color: var(--terracotta); }

/* ── Spectator bar ── */
.spectator-bar {
  background: var(--green);
  color: var(--white);
  text-align: center;
  padding: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
}

/* ── Explanation callout ── */
.explanation {
  background: linear-gradient(135deg, #f0f8f0, var(--green-pale));
  border-left: 4px solid var(--green);
  padding: 1rem 1.2rem;
  border-radius: 0 12px 12px 0;
  margin-top: 1rem;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text);
}

/* ── Footer ── */
.footer {
  text-align: center;
  padding: 2rem 1rem;
  color: var(--text-light);
  font-size: 0.85rem;
}

/* ── Error message ── */
.error-msg {
  background: #fef0e8;
  color: var(--terracotta);
  padding: 0.8rem 1rem;
  border-radius: 12px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 1rem;
  display: none;
  animation: shake 0.5s;
}
.error-msg.visible { display: block; }

/* ── Responsive ── */
@media (max-width: 600px) {
  .header h1 { font-size: 2rem; }
  .room-code { font-size: 2.8rem; }
  .question-display h2 { font-size: 1.4rem; }
  .btn--large { max-width: 100%; }
  .container { padding: 1rem; }
  .tot-choices { flex-direction: column; }
  .tot-vs { width: auto; }
  .card { padding: 1.2rem; }
}

/* ── Host projector mode — big text ── */
@media (min-width: 1200px) {
  .question-display h2 { font-size: 2.8rem; }
  .room-code { font-size: 5rem; }
  .answer-count strong { font-size: 3rem; }
  .timer { font-size: 4rem; }
  .result-bar__track { height: 48px; }
}

/* ── Print hide ── */
@media print { .btn, .input, .qr-container { display: none; } }

/* ══════════════════════════════════════════
   Side Nav — shared styles (used via nav.js)
   ══════════════════════════════════════════ */

.side-nav-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.3);
  z-index: 199;
  opacity: 0; pointer-events: none;
  transition: opacity 0.25s ease;
}
.side-nav-overlay.open { opacity: 1; pointer-events: auto; }

.side-nav {
  position: fixed; top: 0; left: 0; bottom: 0;
  width: 240px;
  background: var(--surface-rail, #EFEADE);  /* recessed cream rail (design refresh) */
  border-right: 1px solid var(--border-subtle);
  z-index: 200;
  display: flex; flex-direction: column;
  transform: translateX(-100%);
  transition: transform 0.3s ease;
  overflow-y: auto;
}
.side-nav.open { transform: translateX(0); }

.side-nav-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 20px;
  border-bottom: 1px solid var(--border-subtle);
  flex-shrink: 0;
}
.side-nav-brand { font-size: 18px; font-weight: 700; color: var(--green); display: flex; align-items: center; gap: 8px; font-family: var(--font-display); letter-spacing: -0.01em; text-decoration: none; transition: opacity .15s; }
.side-nav-brand:hover { opacity: 0.8; }
.side-nav-brand b { font-weight: 800; }
.g-brand-mark { width: 24px; height: 24px; flex-shrink: 0; }
/* Brand SVG nav icons (design refresh 2026-06-02) — self-coloured; do NOT tint */
.g-svg-ico { width: 19px; height: 19px; display: inline-block; vertical-align: middle; flex-shrink: 0; }
.bottom-nav-icon .g-svg-ico { width: 22px; height: 22px; }
.side-nav-close {
  width: 32px; height: 32px; border: none; background: none;
  cursor: pointer; border-radius: 6px; font-size: 16px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-light);
}
.side-nav-close:hover { background: var(--green-pale); color: var(--green); }

.side-nav-links { flex: 1; padding: 8px 8px; overflow-y: auto; }

.side-nav-link {
  display: flex; align-items: center; gap: 10px;
  margin: 1px 0;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--text); text-decoration: none; font-size: 14px;
  transition: background 0.15s, box-shadow 0.15s;
}
.side-nav-link:hover { background: var(--surface-2, rgba(76,55,30,0.05)); color: var(--green); }
/* Active = white chip + soft shadow on the recessed cream rail (design refresh) */
.side-nav-link.active { color: var(--green); background: var(--surface-card, #fff); font-weight: 600; box-shadow: var(--shadow-sm); }
.side-nav-link-icon { font-size: 16px; width: 22px; text-align: center; flex-shrink: 0; }

.side-nav-divider { height: 1px; background: var(--border-subtle); margin: 6px 16px; }

.side-nav-section {
  padding: 6px 20px 2px; font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text-light);
}

/* Side nav profile — Cowork-style sticky bottom */
.side-nav-profile {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid #f0f0f0;
  flex-shrink: 0;
  text-decoration: none;
  color: inherit;
  transition: background 0.15s;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  width: 100%;
}
.side-nav-profile:hover { background: var(--green-pale); }
@media (max-width: 899px) {
  .side-nav-profile { padding-bottom: max(12px, env(safe-area-inset-bottom, 12px)); }
}
.side-nav-profile-avatar {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--green); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; flex-shrink: 0;
  line-height: 1;
}
.side-nav-profile-avatar:not(.has-initial) { font-size: 16px; background: #d4cfc7; color: var(--text-light); }
.side-nav-profile-info {
  display: flex; flex-direction: column;
  min-width: 0; /* allow text truncation */
}
.side-nav-profile-name {
  font-size: 13px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.3;
}
.side-nav-profile-role {
  font-size: 11px; color: var(--text-light);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.3;
}
.side-nav-profile-chevron {
  font-size: 0.7rem; color: #999; transform: rotate(180deg); display: inline-block;
  margin-left: auto; flex-shrink: 0;
}

/* ── Connection status dot (overlaid on profile avatar) ── */
.connection-dot {
  position: absolute; bottom: 0; right: 0;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--green, #2B5F2B);
  border: 2px solid white;
  transition: background 0.3s;
}
.connection-dot.offline {
  background: #E65100;
}
.connection-dot.updating {
  background: #F9A825;
}

/* ── Side nav footer (vault/profile split) ── */
.side-nav-footer {
  display: flex; flex-direction: row; align-items: stretch;
  border-top: 1px solid #E8E0D5;
  flex-shrink: 0;
}
.side-nav-footer .side-nav-profile {
  flex: 1; border-top: none;
}

/* ── Update toast ── */
.gather-update-toast {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%);
  background: var(--green, #2B5F2B); color: #fff;
  padding: 10px 20px; border-radius: 10px;
  font-size: 13px; font-weight: 600;
  box-shadow: 0 4px 16px rgba(0,0,0,0.2);
  cursor: pointer; z-index: 99999;
  animation: toastSlideUp 0.3s ease;
  display: flex; align-items: center; gap: 8px;
}
.gather-update-toast:hover { opacity: 0.9; }
@keyframes toastSlideUp {
  from { transform: translateX(-50%) translateY(20px); opacity: 0; }
  to { transform: translateX(-50%) translateY(0); opacity: 1; }
}

/* ── Global Toast Notifications ── */
.gather-toast-container {
  position: fixed; bottom: 80px; left: 50%; transform: translateX(-50%);
  z-index: 99998; display: flex; flex-direction: column-reverse;
  gap: 8px; pointer-events: none; max-width: 90vw; width: 400px;
}
.gather-toast {
  pointer-events: auto;
  padding: 12px 16px; border-radius: 10px;
  font-size: 0.85rem; font-weight: 500; line-height: 1.4;
  box-shadow: 0 4px 16px rgba(0,0,0,0.15);
  animation: toastSlideUp 0.3s ease;
  display: flex; align-items: center; gap: 10px;
  cursor: pointer;
}
.gather-toast--error {
  background: var(--terracotta, #C4652A); color: #fff;
}
.gather-toast--success {
  background: var(--green, #2B5F2B); color: #fff;
}
.gather-toast--warning {
  background: #d4920a; color: #fff;
}
.gather-toast--info {
  background: var(--text, #2C2C2C); color: #fff;
}
.gather-toast.fade-out {
  animation: toastFadeOut 0.3s ease forwards;
}
@keyframes toastFadeOut {
  to { opacity: 0; transform: translateY(10px); }
}

/* ── Skeleton Loaders ── */
.skeleton {
  background: linear-gradient(90deg, #eee 25%, #e0e0e0 50%, #eee 75%);
  background-size: 200% 100%;
  animation: skeletonShimmer 1.5s infinite;
  border-radius: var(--radius);
}
.skeleton-text { height: 1em; margin-bottom: 0.5em; width: 80%; }
.skeleton-text:last-child { width: 55%; }
.skeleton-block { height: 80px; margin-bottom: 1rem; }
.skeleton-card { height: 120px; margin-bottom: 1rem; }
@keyframes skeletonShimmer {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ── Empty / Error States ── */
.gather-empty-state {
  text-align: center; padding: 2rem 1rem; color: var(--text-light);
}
.gather-empty-state-icon { font-size: 2rem; margin-bottom: 0.5rem; }
.gather-empty-state-text { font-size: 0.9rem; }
.gather-error-state {
  text-align: center; padding: 1.5rem 1rem;
  background: #fdf0ec; border-radius: var(--radius);
  color: var(--terracotta); font-size: 0.88rem;
}
.gather-error-state-icon { font-size: 1.5rem; margin-bottom: 0.3rem; }

/* ── Confirm Modal ── */
.gather-confirm-backdrop {
  display: none; position: fixed; inset: 0;
  background: rgba(0,0,0,0.45); z-index: 10000;
  align-items: center; justify-content: center;
  backdrop-filter: blur(2px);
}
.gather-confirm-backdrop.open { display: flex; }
.gather-confirm {
  background: var(--white); border-radius: var(--radius-lg);
  padding: 1.8rem 1.5rem 1.5rem; max-width: 380px; width: 90%;
  box-shadow: var(--shadow-lg); text-align: center;
  animation: fadeIn 0.2s ease;
}
.gather-confirm h3 { font-size: 1.1rem; margin-bottom: 0.5rem; color: var(--text); }
.gather-confirm p { font-size: 0.88rem; color: var(--text-light); margin-bottom: 1.3rem; line-height: 1.5; }
.gather-confirm-actions { display: flex; gap: 0.75rem; justify-content: center; }
.gather-confirm-actions .btn { min-width: 100px; }
.gather-confirm .btn--danger {
  background: var(--terracotta); color: #fff; border: none;
  padding: 0.6rem 1.2rem; border-radius: var(--radius);
  font-weight: 600; cursor: pointer; font-family: inherit; font-size: 0.9rem;
}
.gather-confirm .btn--danger:hover { background: #a8531f; }
.gather-confirm .btn--cancel {
  background: none; border: 1.5px solid var(--beige);
  padding: 0.6rem 1.2rem; border-radius: var(--radius);
  font-weight: 600; cursor: pointer; color: var(--text-light);
  font-family: inherit; font-size: 0.9rem;
}
.gather-confirm .btn--cancel:hover { background: var(--cream); }

/* ── Join Mode Messaging ── */
.join-mode-notice {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.82rem; color: var(--text-light);
  padding: 0.4rem 0.8rem; background: var(--green-pale);
  border-radius: var(--radius); margin-top: 0.5rem;
}

/* ── Shared compact header (injected by nav.js standardiseHeader) ── */
.gather-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--white);
  border-bottom: 1px solid #f0f0f0;
  padding: 0 16px;
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 52px;
  flex-shrink: 0;
}
.gather-header-title {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  margin: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 899px) {
  .gather-header { min-height: 48px; padding: 0 12px; }
  .gather-header-title { font-size: 0.95rem; }
}

/* Desktop — pinned open */
@media (min-width: 900px) {
  .side-nav {
    transform: translateX(0);
    border-right: 1px solid #f0f0f0;
    box-shadow: none;
  }
  .side-nav-overlay { display: none !important; }
  .side-nav-close { display: none; }

  /* Push ALL page content right so it clears the pinned nav.
     Sticky headers inherit this offset automatically. */
  body.has-side-nav {
    padding-left: 240px;
  }

  /* Menu button hidden on desktop — side nav is pinned */
  body.has-side-nav .menu-btn,
  body.has-side-nav #menuBtn { display: none; }
}

/* Mobile — menu button */
.menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 20px;
  padding: 0;
  color: var(--text);
  line-height: 1;
  border-radius: 8px;
  flex-shrink: 0;
}
.menu-btn:hover { background: var(--green-pale); }

/* ══════════════════════════════════════════
   Bottom Nav — mobile only
   ══════════════════════════════════════════ */
.bottom-nav {
  display: none;
  position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--white);
  border-top: 1px solid #e8e4de;
  z-index: 150;
  padding: 4px 0 env(safe-area-inset-bottom, 4px);
}
.bottom-nav-inner {
  display: flex;
  justify-content: space-around;
  align-items: center;
  max-width: 500px;
  margin: 0 auto;
}
.bottom-nav-item {
  display: flex; flex-direction: column; align-items: center;
  padding: 6px 8px;
  text-decoration: none; color: var(--text-light);
  font-size: 10px; font-weight: 500;
  min-width: 48px; min-height: 48px;
  justify-content: center;
  transition: color 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.bottom-nav-item:hover, .bottom-nav-item:active { color: var(--green); }
.bottom-nav-item.active { color: var(--green); font-weight: 700; }
/* 2026-05-23: Jeremy directive — icons were visually too large in
   Capacitor v16 (1.0.11) smoke test. Reduced font-size 20px → 16px
   (~20%, near the requested ~25%). The label below stays at 10px so
   the icon-to-label visual ratio improves. Tappable area is UNCHANGED:
   .bottom-nav-item still carries min-width / min-height: 48px so this
   is purely a visual shrink, not an accessibility regression. */
.bottom-nav-icon { font-size: 16px; margin-bottom: 2px; }

@media (max-width: 899px) {
  .bottom-nav { display: block; }
  body.has-side-nav { padding-bottom: 64px; }
}
@media (min-width: 900px) {
  .bottom-nav { display: none !important; }
}

/* ══════════════════════════════════════════
   Profile Sheet — vault/profile switcher
   ══════════════════════════════════════════ */
.profile-sheet-backdrop {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.4);
  z-index: 1999; backdrop-filter: blur(2px);
}
.profile-sheet-backdrop.open { display: block; }

.profile-sheet {
  position: fixed; top: auto; bottom: 0; left: 0; right: 0; z-index: 2000;
  background: white; border-radius: 20px 20px 0 0;
  padding: 0 0 env(safe-area-inset-bottom, 0);
  transform: translateY(100%); transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
  box-shadow: 0 -4px 30px rgba(0,0,0,0.15);
  max-height: 80vh; display: flex; flex-direction: column;
  visibility: hidden;
}
.profile-sheet.open { transform: translateY(0); visibility: visible; }

.profile-sheet-handle {
  width: 36px; height: 4px; background: #E0D9D0; border-radius: 2px;
  margin: 10px auto 0;
}

.profile-sheet-header {
  display: flex; align-items: center; padding: 0.9rem 1.1rem 0.6rem;
  border-bottom: 1px solid #F0EAE0;
}

.profile-sheet-title {
  font-size: 0.88rem; font-weight: 700; color: #2C2C2C; flex: 1;
  text-transform: uppercase; letter-spacing: 0.06em;
}

.profile-sheet-close {
  background: none; border: none; font-size: 1rem; cursor: pointer;
  padding: 6px; border-radius: 50%; width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center; color: #888;
}
.profile-sheet-close:hover { background: #F0EAE0; }

.profile-sheet-list {
  flex: 1; overflow-y: auto; padding: 0.5rem 0;
}

.profile-sheet-loading {
  padding: 1.5rem; text-align: center; color: #888; font-size: 0.85rem;
}

.profile-sheet-item {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.75rem 1.1rem; cursor: pointer; border: none; background: none;
  width: 100%; text-align: left; transition: background 0.15s;
  font-family: inherit;
}
.profile-sheet-item:hover, .profile-sheet-item:active { background: #FAF6F0; }
.profile-sheet-item.active { background: #F0EAE0; }

.profile-sheet-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 1.1rem; font-weight: 700; color: white; flex-shrink: 0;
  position: relative;
}

.profile-sheet-avatar .vault-type-badge {
  position: absolute; bottom: -2px; right: -2px;
  width: 18px; height: 18px; border-radius: 50%; background: white;
  border: 2px solid white; font-size: 10px;
  display: flex; align-items: center; justify-content: center; line-height: 1;
}

.profile-sheet-info {
  flex: 1; min-width: 0;
}

.profile-sheet-name {
  font-size: 0.9rem; font-weight: 600; color: #2C2C2C;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.profile-sheet-meta {
  font-size: 0.75rem; color: #888; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.profile-sheet-check {
  font-size: 1.1rem; color: var(--green); flex-shrink: 0;
}

.profile-sheet-lock {
  font-size: 0.95rem; color: #999; flex-shrink: 0;
}

.profile-sheet-actions {
  padding: 0.75rem 1.1rem 1rem; border-top: 1px solid #F0EAE0;
  display: flex; flex-direction: column; gap: 0.5rem;
}

.profile-sheet-new-btn {
  display: flex; align-items: center; gap: 0.6rem;
  background: var(--green); color: white; border: none; border-radius: 12px;
  padding: 0.8rem 1.1rem; font-size: 0.9rem; font-weight: 600;
  text-decoration: none; cursor: pointer; font-family: inherit;
  transition: background 0.15s;
}
.profile-sheet-new-btn:hover { background: #1f4620; }

.profile-sheet-new-icon {
  font-size: 1.1rem; font-weight: 400;
}

.profile-sheet-manage {
  text-align: center; font-size: 0.8rem; color: #888;
  text-decoration: none; padding: 0.25rem;
}
.profile-sheet-manage:hover { color: var(--green); }

/* ════════════════════════════════════════════════════════════════════
   §10. COMPONENT LIBRARY — the 12 atomic components per UI design plan
   §5 (2026-05-21). Every page consumes these instead of bespoke CSS.
   ──────────────────────────────────────────────────────────────────── */

/* ──────────────────────────────────────────────────────────────────
   .card — grouped content block
   HTML: <article class="card card--elevated"><h3>Title</h3>...</article>
   Variants: --flat (hairline border, no shadow)
             --elevated (shadow-sm at rest, shadow-md on hover)
             --clickable (cursor pointer, lifts on hover)
             --accent (4px left border in terra-700 — premium highlight)
   ──────────────────────────────────────────────────────────────── */
/* Note: the legacy .card rule near the top of this file is preserved for
   back-compat. New code prefers .card--elevated / .card--flat which
   override it cleanly via specificity + class composition. */
.card--elevated {
  background: var(--surface-card);
  border-radius: var(--radius-lg);
  padding: var(--space-xl);
  box-shadow: var(--shadow-sm);
  border: 1px solid var(--border-subtle);
  transition: box-shadow var(--duration-fast) var(--ease-out),
              transform var(--duration-fast) var(--ease-out);
}
.card--elevated:hover {
  box-shadow: var(--shadow-md);
}
.card--clickable {
  cursor: pointer;
}
.card--clickable:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
/* Premium accent stripe — terracotta is the PREMIUM semantic (UX-ACCENT-1) */
.card--premium {
  border-left: 4px solid var(--terra-700);
}

/* ──────────────────────────────────────────────────────────────────
   .badge — inline status / count / label
   HTML: <span class="badge badge--accent">Plugin</span>
   Variants: --default (neutral), --accent (sage), --premium (terra — PAID),
             --muted, --success / --warn / --error / --info
   Replaces the 7 ad-hoc badge styles in marketplace/shop/admin-commerce.
   ──────────────────────────────────────────────────────────────── */
.badge--default {
  background: var(--neutral-100);
  color: var(--neutral-800);
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  line-height: 1.2;
}
.badge--accent  { background: var(--sage-50);   color: var(--sage-800); }
.badge--muted   { background: var(--neutral-100); color: var(--neutral-500); }
.badge--success { background: var(--success-bg); color: var(--success-fg); }
.badge--warn    { background: var(--warn-bg);    color: var(--warn-fg); }
.badge--error   { background: var(--error-bg);   color: var(--error-fg); }
.badge--info    { background: var(--info-bg);    color: var(--info-fg); }
/* PREMIUM / PAID — terra is the paid-accent semantic (UX-ACCENT-1) */
.badge--premium { background: var(--terra-50);  color: var(--terra-800); }
.badge--featured { background: var(--sage-700); color: var(--white); }

/* Apply the new defaults to the legacy .badge as well so existing markup
   inherits the modern look without HTML changes. */
.badge {
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  line-height: 1.2;
}

/* ──────────────────────────────────────────────────────────────────
   .avatar — user / vault / member representation
   HTML: <div class="avatar avatar--md" style="--avatar-bg:var(--sage-700)">J</div>
   Sizes: --xs (22) / --sm (32) / --md (40) / --lg (64) / --xl (96)
   Consumes the single avatar-size token scale (fixes "7 ad-hoc sizes" bug).
   ──────────────────────────────────────────────────────────────── */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-full);
  background: var(--avatar-bg, var(--sage-700));
  color: var(--white);
  font-weight: 700;
  flex-shrink: 0;
  line-height: 1;
  overflow: hidden;
}
.avatar--xs { width: var(--avatar-xs); height: var(--avatar-xs); font-size: 0.65rem; }
.avatar--sm { width: var(--avatar-sm); height: var(--avatar-sm); font-size: 0.85rem; }
.avatar--md { width: var(--avatar-md); height: var(--avatar-md); font-size: 1rem; }
.avatar--lg { width: var(--avatar-lg); height: var(--avatar-lg); font-size: 1.6rem; }
.avatar--xl { width: var(--avatar-xl); height: var(--avatar-xl); font-size: 2.4rem; }

/* ──────────────────────────────────────────────────────────────────
   .nav-item — sidebar / header tabs / bottom-nav variants
   HTML: <a class="nav-item nav-item--sidebar is-active">...</a>
   States: .is-active (3px terra left-accent on sidebar, terra underline on header)
   The terra left-accent is the missing visual identity from §6.6 of the plan.
   ──────────────────────────────────────────────────────────────── */
.nav-item--sidebar {
  position: relative;
}
.nav-item--sidebar.is-active::before,
.side-nav-link.active::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--terra-700);
  border-radius: 0 2px 2px 0;
}

/* ──────────────────────────────────────────────────────────────────
   .stat — single metric (number + label)
   HTML: <div class="stat"><div class="stat__value">3</div><div class="stat__label">Today</div></div>
   ──────────────────────────────────────────────────────────────── */
.stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-lg);
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.stat__value {
  font-family: var(--font-display);
  font-size: var(--fs-3xl);
  font-weight: 700;
  line-height: 1;
  color: var(--neutral-900);
  letter-spacing: var(--tracking-tight);
}
.stat__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--neutral-500);
}
.stat__trend {
  font-size: var(--fs-xs);
  color: var(--neutral-500);
}
.stat--overdue .stat__value { color: var(--error-fg); }
.stat--today   .stat__value { color: var(--sage-700); }
.stat--week    .stat__value { color: var(--neutral-800); }

/* ──────────────────────────────────────────────────────────────────
   .empty — empty-state for lists/grids
   HTML: <div class="empty"><div class="empty__icon">📭</div>
           <h3 class="empty__title">No products</h3>
           <p class="empty__sub">Add your first.</p>
           <a class="btn btn--primary">Add</a></div>
   ──────────────────────────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: var(--space-2xl) var(--space-lg);
  color: var(--neutral-500);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
}
.empty__icon { font-size: 2.5rem; opacity: 0.6; }
.empty__title {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--neutral-800);
  margin: 0;
}
.empty__sub {
  font-size: var(--fs-sm);
  color: var(--neutral-500);
  margin: 0;
  max-width: 360px;
}

/* ──────────────────────────────────────────────────────────────────
   .table — tabular data (products, orders, members, audit log)
   HTML: <table class="table table--hoverable"><thead>...</thead><tbody>...</tbody></table>
   Mobile pattern: <768px each row becomes a stacked card via data-label
   attributes on <td>. Standard responsive technique. Use the
   .table--mobile-cards modifier on the table for the stacking variant.
   ──────────────────────────────────────────────────────────────── */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
.table th {
  text-align: left;
  font-weight: 600;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--neutral-500);
  padding: var(--space-md) var(--space-md);
  border-bottom: 1px solid var(--border-subtle);
  background: var(--neutral-50);
}
.table td {
  padding: var(--space-md);
  border-bottom: 1px solid var(--border-subtle);
  color: var(--neutral-800);
  vertical-align: middle;
}
.table tbody tr { transition: background var(--duration-fast) var(--ease-out); }
.table--hoverable tbody tr:hover { background: var(--neutral-50); }
.table--striped tbody tr:nth-child(odd) { background: var(--neutral-50); }
@media (max-width: 768px) {
  .table--mobile-cards thead { display: none; }
  .table--mobile-cards tr {
    display: block;
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-md);
    padding: var(--space-md);
  }
  .table--mobile-cards td {
    display: block;
    border: none;
    padding: var(--space-xs) 0;
  }
  .table--mobile-cards td::before {
    content: attr(data-label) ': ';
    font-weight: 600;
    color: var(--neutral-500);
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: var(--tracking-wide);
    margin-right: var(--space-sm);
  }
}

/* ──────────────────────────────────────────────────────────────────
   .tabs — switching between views in same surface
   HTML: <div class="tabs tabs--underline" role="tablist">
           <button class="tab is-active" role="tab">Browse</button>
           <button class="tab" role="tab">Installed</button>
         </div>
   Variants: --underline (terra-700 underline on active — default for nav tabs)
             --pill     (sage-700 filled pill on active — for filter chips)
   ──────────────────────────────────────────────────────────────── */
.tabs {
  display: flex;
  gap: 0;
  align-items: stretch;
  margin-bottom: var(--space-lg);
}
.tabs--underline {
  border-bottom: 1px solid var(--border-subtle);
}
.tabs--underline .tab {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: var(--space-md) var(--space-lg);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--neutral-500);
  cursor: pointer;
  min-height: var(--touch-min);
  transition: color var(--duration-fast) var(--ease-out),
              border-color var(--duration-fast) var(--ease-out);
  margin-bottom: -1px;
}
.tabs--underline .tab:hover { color: var(--neutral-800); }
.tabs--underline .tab.is-active {
  color: var(--neutral-900);
  border-bottom-color: var(--terra-700);   /* terra underline = active */
}
.tabs--underline .tab:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}
.tabs--pill {
  gap: var(--space-sm);
  flex-wrap: wrap;
}
.tabs--pill .tab {
  background: var(--neutral-100);
  border: none;
  border-radius: var(--radius-full);
  padding: var(--space-sm) var(--space-lg);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--neutral-600);
  cursor: pointer;
  min-height: 32px;
  transition: background var(--duration-fast) var(--ease-out),
              color var(--duration-fast) var(--ease-out);
}
.tabs--pill .tab:hover { background: var(--neutral-200); }
.tabs--pill .tab.is-active {
  background: var(--sage-700);
  color: var(--white);
}

/* Mobile horizontal-scroll tab strip (for the profile-page tabs etc.) */
.tabs--scroll {
  overflow-x: auto;
  scrollbar-width: none;
  flex-wrap: nowrap;
  -webkit-overflow-scrolling: touch;
}
.tabs--scroll::-webkit-scrollbar { display: none; }
.tabs--scroll .tab { white-space: nowrap; flex-shrink: 0; }

/* ──────────────────────────────────────────────────────────────────
   .toast — already exists as .gather-toast; alias .toast for the
   modern name without breaking existing call-sites.
   ──────────────────────────────────────────────────────────────── */
.toast { /* alias — see .gather-toast above */ }

/* ══════════════════════════════════════════════════════════════════
   §11. ICON SYSTEM — emoji default, SVG opt-in toggle
   UX-ICON-1 LOCKED: toggle. Body-class swap. See icons.js for the JS.
   Pattern in markup:
     <span class="icon-emoji">📅</span>
     <svg class="icon-svg"><use href="/icons/lucide-sprite.svg#calendar"/></svg>
   Both render in DOM; one is hidden via body class.
   ────────────────────────────────────────────────────────────────── */
body.icon-style-svg   .icon-emoji { display: none; }
body.icon-style-emoji .icon-svg   { display: none; }
.icon-svg {
  width: 1.1em;
  height: 1.1em;
  vertical-align: -0.15em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ══════════════════════════════════════════════════════════════════
   §12. GLOBAL FOCUS-VISIBLE — keyboard accessibility baseline
   Modern UIs need a visible focus ring for keyboard-only users.
   Today many inputs just change border colour on focus — broken.
   ────────────────────────────────────────────────────────────────── */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
[tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
  border-radius: var(--radius-sm);
}

/* ══════════════════════════════════════════════════════════════════
   §13. MOBILE TOUCH-TARGET enforcement (§7.2 of the plan)
   Bump small ad-hoc buttons to a finger-friendly size on phones.
   ────────────────────────────────────────────────────────────────── */
@media (max-width: 899px) {
  .menu-btn { min-width: 44px; min-height: 44px; }
  .tag-add-btn,
  .task-modal-priority-btn,
  .vault-widget-btn {
    min-height: 40px;
  }
}

/* ══════════════════════════════════════════════════════════════════
   §14. iOS SAFE-AREA top inset for Capacitor native (notch handling)
   Added now so iOS doesn't need a separate fix when it ships.
   ────────────────────────────────────────────────────────────────── */
@supports (padding-top: env(safe-area-inset-top)) {
  body.is-capacitor .gather-header {
    padding-top: env(safe-area-inset-top, 0);
    min-height: calc(52px + env(safe-area-inset-top, 0));
  }
}
