/* Misses Bee Garden — app.css
   Mobile-first. Calm and clean. Sage / cream / honey. */

/* ── Self-hosted serif (Lora variable) ───────────────────────────────── */
/* Lora is shipped as a variable font — one file covers all weights. */
@font-face {
  font-family: 'Lora';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: local('Lora'),
       url('../fonts/lora-variable.woff2') format('woff2-variations'),
       url('../fonts/lora-variable.woff2') format('woff2');
}

/* ── Design tokens ───────────────────────────────────────────────────── */
:root {
  /* palette */
  --cream:        #FAF7F2;
  --cream-warm:   #F4EFE6;
  --cream-edge:   #E8E0D2;
  --sage-soft:    #C5D1C0;
  --sage:         #8FA68E;
  --sage-deep:    #5C7355;
  --moss:         #4A5D43;
  --honey:        #D4A574;
  --terracotta:   #C4856E;
  --text:         #2D3328;
  --text-muted:   #5C6359;   /* WCAG AA on cream */
  --text-faint:   #8A8F82;
  --danger:       #A24533;
  --success:      #5C7355;

  /* type */
  --font-serif: 'Lora', Georgia, 'Times New Roman', serif;
  --font-sans:  -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;

  /* spacing scale */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px;
  --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;

  /* radii / shadow */
  --r-1: 6px; --r-2: 10px; --r-3: 14px; --r-4: 20px;
  --shadow-sm: 0 1px 2px rgba(45, 51, 40, .06);
  --shadow-md: 0 4px 16px rgba(45, 51, 40, .08);

  /* layout */
  --bottom-nav-h: 64px;
  --topbar-h: 56px;
  --max-w: 720px;
}

/* ── Reset ───────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.5;
  color: var(--text);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  padding-bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom));
}
img, svg { max-width: 100%; height: auto; display: block; }
a { color: var(--sage-deep); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; cursor: pointer; }

h1, h2, h3 { font-family: var(--font-serif); font-weight: 600; line-height: 1.25; margin: 0 0 var(--s-3); color: var(--moss); }
h1 { font-size: 28px; }
h2 { font-size: 22px; }
h3 { font-size: 18px; }
p  { margin: 0 0 var(--s-3); }
small, .muted { color: var(--text-muted); }

/* ── Top bar ─────────────────────────────────────────────────────────── */
.topbar {
  position: sticky; top: 0; z-index: 10;
  height: var(--topbar-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--s-4);
  background: var(--cream);
  border-bottom: 1px solid var(--cream-edge);
}
.topbar-brand { display: flex; align-items: center; gap: var(--s-2); color: var(--moss); }
.topbar-brand:hover { text-decoration: none; }
.topbar-mark { font-size: 20px; }
.topbar-name { font-family: var(--font-serif); font-size: 18px; font-weight: 600; }
.topbar-account { color: var(--text-muted); font-size: 14px; }
.topbar-avatar {
  display: inline-flex;
  align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border-radius: 50%;
  background: var(--sage-deep);
  color: var(--cream);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  flex: 0 0 auto;
}
.topbar-firstname { font-size: 14px; font-weight: 500; }
.topbar-caret { color: var(--text-faint); margin-left: 2px; }

/* ── Page container ──────────────────────────────────────────────────── */
.page {
  max-width: var(--max-w);
  margin: 0 auto;
  padding: var(--s-5) var(--s-4);
}

/* ── Auth split (centered card on its own background) ────────────────── */
body.auth { background: var(--cream-warm); }
body.auth .topbar { background: transparent; border-bottom: 0; }
.auth-shell {
  min-height: calc(100vh - var(--topbar-h));
  display: flex; align-items: flex-start; justify-content: center;
  padding: var(--s-5) var(--s-4);
}
.auth-card {
  width: 100%; max-width: 420px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-4);
  padding: var(--s-6);
  box-shadow: var(--shadow-md);
}
.auth-card h1 { margin-bottom: var(--s-2); }
.auth-card .lede { color: var(--text-muted); margin-bottom: var(--s-5); }
.auth-foot { margin-top: var(--s-5); font-size: 14px; color: var(--text-muted); text-align: center; }

/* ── Auth splash layout (signup) ─────────────────────────────────────── */
body.auth-splash { background: var(--cream); padding-bottom: 0; }
body.auth-splash .topbar { display: none; }
body.auth-splash .page { padding: 0; max-width: none; margin: 0; }

.auth-grid {
  min-height: 100vh; min-height: 100svh;
  display: grid;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .auth-grid { grid-template-columns: 1.1fr 1fr; }
}

.auth-poster {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: var(--moss);
  color: var(--cream);
  aspect-ratio: 16 / 9;
  min-height: 220px;
  max-height: 320px;
}
@media (min-width: 900px) {
  .auth-poster { aspect-ratio: auto; max-height: none; min-height: 100svh; }
}
.auth-poster::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(45,51,40,.2) 0%, rgba(45,51,40,.7) 100%),
    radial-gradient(80% 60% at 30% 30%, rgba(45,51,40,.18), transparent 70%);
  z-index: -1;
}
.auth-poster img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: -2;
  filter: saturate(.95);
}
.auth-poster-content {
  display: flex; flex-direction: column;
  justify-content: space-between;
  padding: clamp(20px, 3vw, 56px);
  height: 100%;
  gap: 16px;
}
.auth-poster .brand-line {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--cream);
  font-family: var(--font-serif); font-weight: 600;
  font-size: 18px; text-decoration: none;
}
.auth-poster .brand-line:hover { text-decoration: none; color: var(--cream); }
.auth-poster .brand-line .icon { width: 22px; height: 22px; color: var(--sage-soft); }

.auth-poster .poster-pitch { margin-top: auto; display: none; }
@media (min-width: 900px) { .auth-poster .poster-pitch { display: block; } }

.auth-poster .eyebrow {
  font-family: var(--font-serif); font-style: italic;
  font-size: 18px;
  color: rgba(250,247,242,.9);
  margin: 0 0 12px;
}
.auth-poster h2 {
  font-size: clamp(28px, 3vw, 42px);
  color: var(--cream);
  text-shadow: 0 2px 18px rgba(0,0,0,.3);
  margin: 0 0 16px;
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.18;
}
.auth-poster .quote {
  font-style: italic; font-family: var(--font-serif);
  font-size: clamp(15px, 1.6vw, 17px);
  color: rgba(250,247,242,.92);
  margin: 0 0 24px;
  max-width: 32em;
  line-height: 1.5;
}

.auth-checks {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 10px;
}
.auth-checks li {
  display: flex; gap: 12px; align-items: flex-start;
  font-size: 15px;
  color: rgba(250,247,242,.92);
  line-height: 1.5;
}
.auth-checks .check {
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(197,209,192,.25);
  color: var(--cream);
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 22px;
  margin-top: 1px;
}

.auth-poster-foot {
  margin-top: 24px;
  font-size: 13px;
  color: rgba(250,247,242,.85);
  display: none;
}
@media (min-width: 900px) { .auth-poster-foot { display: block; } }
.auth-poster-foot a { color: var(--cream); text-decoration: underline; text-underline-offset: 3px; }

.auth-form-pane {
  display: flex; align-items: center; justify-content: center;
  padding: clamp(28px, 5vw, 56px);
  background: var(--cream);
}
.auth-form-pane .form-card {
  width: 100%;
  max-width: 420px;
}
.auth-form-pane h1 {
  font-size: clamp(28px, 4vw, 36px);
  margin: 0 0 8px;
}
.auth-form-pane .lede {
  color: var(--text-muted);
  margin-bottom: 24px;
  font-size: 16px;
}
.auth-form-pane .btn-block { margin-top: 4px; }

.auth-fineprint {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 18px;
  text-align: center;
}
.auth-altlink {
  font-size: 14px;
  color: var(--text-muted);
  margin-top: 12px;
  text-align: center;
}

/* ──────────────────────────────────────────────────────────────────────
   AUTH INVITATION (signup) — editorial single-screen experience.
   Cinematic video background, cream invitation card centered on top.
   ────────────────────────────────────────────────────────────────────── */
body.auth-invitation {
  background: var(--moss);
  min-height: 100svh;
  margin: 0; padding: 0;
}
body.auth-invitation .topbar { display: none; }
body.auth-invitation .page { padding: 0; max-width: none; margin: 0; }

.invitation-stage {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 3vw, 32px);
  overflow: hidden;
  isolation: isolate;
}
.invitation-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: -2;
  filter: saturate(.88) contrast(.94);
}
.invitation-veil {
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(80% 60% at 30% 30%, rgba(45,51,40,.30) 0%, rgba(45,51,40,.58) 100%),
    linear-gradient(180deg, rgba(45,51,40,.10) 0%, rgba(45,51,40,.50) 100%);
}

.invitation-card {
  background: var(--cream);
  border-radius: 24px;
  padding: clamp(32px, 5vw, 56px) clamp(26px, 4vw, 48px);
  width: 100%;
  max-width: 520px;
  max-height: calc(100svh - 32px);
  overflow-y: auto;
  box-shadow:
    0 30px 80px rgba(0,0,0,.30),
    0 4px 12px rgba(0,0,0,.12),
    inset 0 0 0 1px rgba(255,255,255,.45);
  position: relative;
  animation: invitation-rise .6s cubic-bezier(.2,.65,.2,1) both;
}
@keyframes invitation-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.invitation-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 24px;
}
.invitation-mark {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--sage-deep);
  text-decoration: none;
  font-family: var(--font-serif);
  font-weight: 600; font-size: 15px;
}
.invitation-mark:hover { text-decoration: none; color: var(--moss); }
.invitation-mark svg { width: 22px; height: 22px; }
.invitation-eyebrow {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 15px;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: 0.02em;
}

.invitation-title {
  font-family: var(--font-serif);
  font-size: clamp(36px, 5.5vw, 54px);
  font-weight: 600;
  color: var(--moss);
  line-height: 1.04;
  letter-spacing: -0.01em;
  margin: 0 0 18px;
  text-wrap: balance;
}
.invitation-sub {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(15px, 1.8vw, 18px);
  line-height: 1.55;
  color: var(--text-muted);
  margin: 0 0 28px;
  max-width: 32em;
}

.invitation-divider {
  display: flex; align-items: center; justify-content: center;
  margin: 0 0 28px;
  color: var(--sage);
  opacity: .35;
}
.invitation-divider::before, .invitation-divider::after {
  content: ""; height: 1px; background: currentColor; flex: 1;
}
.invitation-divider svg { width: 18px; height: 18px; margin: 0 14px; flex: 0 0 auto; }

.invitation-alert {
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
  border: 1px solid color-mix(in srgb, var(--danger) 28%, transparent);
  border-radius: 12px;
  padding: 12px 16px;
  font-size: 14px;
  margin-bottom: 20px;
}
.invitation-alert + .invitation-alert { margin-top: -10px; }

/* Elegant underline-only fields */
.field-elegant {
  display: block;
  margin-bottom: 22px;
}
.field-elegant > label {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: var(--text-muted);
  letter-spacing: 0.06em;
  margin-bottom: 6px;
}
.invitation-label-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px;
}
.invitation-label-row > label { margin-bottom: 0; }
.invitation-side-link {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 12px;
  color: var(--sage-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.invitation-side-link:hover { color: var(--moss); }
.field-elegant > label .opt {
  font-size: 12px; opacity: .75;
}
.field-elegant input {
  width: 100%;
  border: 0;
  border-bottom: 1.5px solid color-mix(in srgb, var(--sage-deep) 22%, transparent);
  background: transparent;
  padding: 10px 0 12px;
  font-family: var(--font-sans);
  font-size: 17px;
  color: var(--text);
  -webkit-appearance: none;
  appearance: none;
  border-radius: 0;
  transition: border-color .25s, border-width .15s;
}
.field-elegant input::placeholder { color: var(--text-faint); font-style: italic; }
.field-elegant input:focus {
  outline: 0;
  border-bottom-color: var(--sage-deep);
  border-bottom-width: 2px;
  padding-bottom: 11px;
}
.field-elegant.has-error input { border-bottom-color: var(--danger); }
.field-elegant .field-error {
  font-size: 12px; color: var(--danger);
  margin-top: 6px;
  font-style: italic;
  font-family: var(--font-serif);
}

/* Password strength (paper-thin) */
.strength { margin-top: 10px; }
.strength-bar {
  height: 2px; border-radius: 2px;
  background: color-mix(in srgb, var(--cream-edge) 70%, transparent);
  overflow: hidden;
  position: relative;
}
.strength-bar::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--pct, 0%);
  background: var(--clr, var(--sage));
  border-radius: 2px;
  transition: width .3s, background .3s;
}
.strength-label {
  display: block;
  margin-top: 6px;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 12px;
  color: var(--text-muted);
  letter-spacing: 0.02em;
}

/* The "Begin" button — pill, generous, restrained */
.btn-begin {
  width: 100%;
  background: var(--moss);
  color: var(--cream);
  border: 0;
  padding: 18px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  margin-top: 12px;
  min-height: 56px;
  transition: background .25s, transform .15s, box-shadow .25s;
}
.btn-begin:hover {
  background: var(--sage-deep);
  transform: translateY(-1px);
  box-shadow: 0 12px 28px rgba(45,51,40,.25);
}
.btn-begin:active { transform: translateY(0); }
.btn-begin:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

.invitation-foot {
  margin-top: 28px;
  text-align: center;
  font-size: 13px;
  color: var(--text-muted);
}
.invitation-foot .trust {
  font-family: var(--font-serif); font-style: italic;
  margin: 0 0 8px;
  letter-spacing: 0.02em;
}
.invitation-foot .switch { margin: 0; }
.invitation-foot a {
  color: var(--sage-deep);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.invitation-foot a:hover { color: var(--moss); }

/* Mobile tightening */
@media (max-width: 520px) {
  .invitation-card { border-radius: 18px; }
  .invitation-stage { padding: 12px; }
  .invitation-head { margin-bottom: 18px; }
}

/* Reduced motion / no autoplay */
@media (prefers-reduced-motion: reduce) {
  .invitation-video { display: none; }
  .invitation-card { animation: none; }
}

/* ── Password strength meter ────────────────────────────────────────── */
.pwd-strength { margin-top: 8px; }
.pwd-strength-bar {
  height: 4px; border-radius: 4px;
  background: var(--cream-edge);
  overflow: hidden;
  position: relative;
}
.pwd-strength-bar::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0;
  width: var(--pct, 0%);
  background: var(--clr, var(--sage));
  border-radius: 4px;
  transition: width .25s, background .25s;
}
.pwd-strength-label {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
  display: block;
  letter-spacing: .01em;
}

/* ── Forms ───────────────────────────────────────────────────────────── */
.field { display: block; margin-bottom: var(--s-4); }
.field > label { display: block; font-size: 14px; font-weight: 600; color: var(--moss); margin-bottom: var(--s-1); }
.input, select, textarea {
  width: 100%;
  padding: 12px 14px;
  /* Don't use `font: inherit` shorthand — some browsers leave the dropdown
     option list at their default user-agent size when the shorthand is used.
     Set the long-hand properties explicitly so the closed control AND the
     dropdown popup both render at a comfortable size. 16px also keeps iOS
     Safari from auto-zooming when the input takes focus. */
  font-family: inherit;
  font-size: 16px;
  line-height: 1.4;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-2);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
  /* Hint to native UI that the option list should follow our color/font, not
     be a bare OS menu. Browsers are free to ignore this; explicit option
     styling below catches the rest. */
  appearance: auto;
}
.input:focus, select:focus, textarea:focus {
  border-color: var(--sage);
  box-shadow: 0 0 0 3px rgba(143, 166, 142, .25);
}
textarea { min-height: 120px; resize: vertical; }
/* Native <select> popup: explicit size + breathing room. Inherits fail on
   Chromium-based browsers where the dropdown popup ignores CSS on the parent. */
select option {
  font-family: inherit;
  font-size: 15px;
  padding: 8px 12px;
  background: #fff;
  color: var(--text);
}
.help { font-size: 13px; color: var(--text-muted); margin-top: 4px; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: 12px 18px;
  font-weight: 600;
  border-radius: var(--r-2);
  border: 1px solid transparent;
  background: var(--sage-deep);
  color: var(--cream);
  text-decoration: none;
  transition: background .15s, transform .05s;
  min-height: 44px;
}
.btn:hover { background: var(--moss); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn.btn-block { display: flex; width: 100%; }
.btn.btn-ghost { background: transparent; color: var(--sage-deep); border-color: var(--cream-edge); }
.btn.btn-ghost:hover { background: var(--cream-warm); }
.btn.btn-danger { background: var(--danger); }
.btn.btn-link { background: transparent; color: var(--sage-deep); padding: 4px 0; min-height: 0; }

/* ── Alerts ──────────────────────────────────────────────────────────── */
.alert { padding: var(--s-3) var(--s-4); border-radius: var(--r-2); margin-bottom: var(--s-4); font-size: 14px; display: flex; gap: var(--s-2); align-items: flex-start; }
.alert::before { font-size: 16px; line-height: 1.4; flex: 0 0 auto; }
.alert.alert-error   { background: #F8E5DF; color: var(--danger); border: 1px solid #EFC9BD; }
.alert.alert-error::before   { content: "⚠"; }
.alert.alert-success { background: #E2EBDD; color: var(--moss);   border: 1px solid #C9DCC1; }
.alert.alert-success::before { content: "✓"; font-weight: 700; }
.alert.alert-info    { background: var(--cream-warm); color: var(--text); border: 1px solid var(--cream-edge); }
.alert.alert-info::before    { content: "ⓘ"; color: var(--sage-deep); }

/* ── Cards / list ────────────────────────────────────────────────────── */
.card {
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-5);
  box-shadow: var(--shadow-sm);
  margin-bottom: var(--s-4);
}
.card h2 { margin-top: 0; }

.row { display: flex; gap: var(--s-3); align-items: center; }
.row.between { justify-content: space-between; }
.stack > * + * { margin-top: var(--s-3); }
.stack-lg > * + * { margin-top: var(--s-5); }

.empty {
  padding: var(--s-7) var(--s-5);
  text-align: center;
  color: var(--text-muted);
  font-style: italic;
}
.empty .empty-mark { font-size: 32px; opacity: .5; margin-bottom: var(--s-3); }

/* ── Bottom nav ──────────────────────────────────────────────────────── */
.bottom-nav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  height: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: #fff;
  border-top: 1px solid var(--cream-edge);
}
.tab, .tab-button {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  color: var(--text-muted);
  font-size: 12px; font-weight: 600;
  text-decoration: none;
  background: transparent; border: 0;
  cursor: pointer;
  padding: 4px;
}
.tab:hover, .tab-button:hover { text-decoration: none; color: var(--sage-deep); }
.tab.is-active, .tab-button.is-active { color: var(--sage-deep); }
.tab-icon { font-size: 20px; line-height: 1; }
.tab-label { letter-spacing: .02em; }

.nav-item.is-active { color: var(--sage-deep); }

/* ── Toast (flash messages) ─────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; top: calc(var(--topbar-h) + 12px);
  transform: translateX(-50%);
  z-index: 50;
  background: var(--moss); color: var(--cream);
  padding: 12px 18px; border-radius: var(--r-2);
  box-shadow: var(--shadow-md);
  font-size: 14px; font-weight: 500;
  max-width: calc(100% - 32px);
  animation: toast-in .25s ease-out;
}
.toast.is-leaving { animation: toast-out .25s ease-in forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translate(-50%, -8px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes toast-out { from { opacity: 1; transform: translate(-50%, 0); }    to { opacity: 0; transform: translate(-50%, -8px); } }

/* ── Dialogs (custom confirm + more sheet) ───────────────────────────── */
dialog.dialog, dialog.sheet {
  border: 0; padding: 0; background: transparent;
  color: var(--text);
  max-width: 100%; max-height: 100%;
}
dialog::backdrop { background: rgba(45, 51, 40, .35); backdrop-filter: blur(2px); }
dialog.dialog[open], dialog.sheet[open] { display: flex; }

/* Centered confirmation dialog */
.dialog .dialog-card {
  background: #fff;
  border-radius: var(--r-3);
  padding: var(--s-5);
  max-width: 440px; width: calc(100vw - 32px);
  box-shadow: var(--shadow-md);
  margin: auto;
  animation: dialog-in .18s ease-out;
}
.dialog .dialog-msg { margin: 0 0 var(--s-4); font-size: 16px; line-height: 1.5; }
@keyframes dialog-in { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }

/* Bottom sheet — a floating card pinned near the bottom of the viewport.
   Rounded on all four corners (was only top), with a small inset from the
   screen edges so it reads as an intentional floating panel rather than
   "drawer that didn't quite reach the bottom". */
.sheet {
  align-items: flex-end !important;
  justify-content: center;
  padding: 0 10px 10px;
}
.sheet .sheet-card {
  background: #fff;
  width: 100%; max-width: 560px;
  border-radius: var(--r-4);
  padding: var(--s-3) var(--s-5) calc(var(--s-5) + env(safe-area-inset-bottom));
  box-shadow: var(--shadow-md);
  animation: sheet-in .22s ease-out;
}
@keyframes sheet-in { from { transform: translateY(100%); } to { transform: none; } }
.sheet-handle {
  width: 40px; height: 4px; border-radius: 4px;
  background: var(--cream-edge);
  margin: 0 auto var(--s-3);
}
.sheet-list { list-style: none; margin: 0; padding: 0; }
.sheet-list li + li { border-top: 1px solid var(--cream-edge); }
.sheet-list a {
  display: flex; align-items: center; gap: var(--s-3);
  padding: var(--s-4) 0;
  color: var(--text); text-decoration: none;
  font-weight: 500;
  min-height: 44px;
}
.sheet-list a:hover { text-decoration: none; color: var(--sage-deep); }
.sheet-icon { font-size: 18px; width: 28px; text-align: center; opacity: .85; }
.sheet-list .meta { margin-left: auto; color: var(--text-faint); font-size: 13px; }

/* ── Quick Action sheet (dashboard FAB) ─────────────────────────────── */
/* A polished version of the bottom sheet used for "what do I want to log?".
   Hierarchy: serif eyebrow + title, primary card for the most-common
   action (harvest), then a quiet list for the rest. Each row has a tinted
   icon badge, label, and one-sentence subtitle so the action is obvious
   without reading twice. Close is a quiet text button, not a heavy block. */
.qa-sheet { padding-top: 12px; padding-inline: var(--s-4); }
.qa-head {
  margin: 4px 4px var(--s-4);
}
.qa-eyebrow {
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
  color: var(--sage-deep);
  font-size: 13px;
  letter-spacing: 0.04em;
  margin: 0 0 4px;
}
.qa-title {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 500;
  font-size: 22px;
  line-height: 1.15;
  margin: 0;
  color: var(--ink, #2c2a25);
}

/* Row — used for both primary + secondary; primary adds the gradient bg. */
.qa-row {
  display: flex; align-items: center;
  gap: 14px;
  padding: 12px 12px;
  border-radius: 14px;
  text-decoration: none;
  color: var(--text);
  transition: background 0.15s ease, transform 0.15s ease;
  min-height: 60px;
}
.qa-row:hover { text-decoration: none; color: var(--text); background: var(--cream-warm); }
.qa-row:active { transform: scale(0.99); }

.qa-row-primary {
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 35%, white) 0%,
      color-mix(in srgb, var(--honey) 14%, white) 100%);
  border: 1px solid color-mix(in srgb, var(--sage-soft) 55%, transparent);
  margin-bottom: 10px;
  box-shadow: 0 1px 0 rgba(60, 80, 50, 0.04);
}
.qa-row-primary:hover {
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 45%, white) 0%,
      color-mix(in srgb, var(--honey) 22%, white) 100%);
}
.qa-row-primary .qa-text strong { font-size: 16px; }

.qa-list { list-style: none; padding: 0; margin: 0; }
.qa-list li + li { margin-top: 2px; }

/* Tinted icon badge — 40×40 rounded square. Each variant uses a different
   warm/cool wash so the actions feel distinct without being loud. */
.qa-icon {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 11px;
  background: var(--cream-warm);
  color: var(--sage-deep);
}
.qa-icon .icon { width: 22px; height: 22px; }
.qa-icon-honey  { background: color-mix(in srgb, var(--honey) 32%, white);     color: #7a4f1c; }
.qa-icon-water  { background: color-mix(in srgb, #BFD3DC 60%, white);          color: #4a7390; }
.qa-icon-ink    { background: color-mix(in srgb, var(--cream-edge) 80%, white); color: #6e5e44; }
.qa-icon-sprout { background: color-mix(in srgb, var(--sage-soft) 55%, white); color: var(--moss); }
.qa-icon-leaf   { background: color-mix(in srgb, var(--sage-soft) 38%, white); color: var(--sage-deep); }

.qa-text { flex: 1 1 auto; min-width: 0; line-height: 1.3; }
.qa-text strong {
  display: block;
  font-weight: 600;
  font-size: 15px;
  color: var(--ink, #2c2a25);
}
.qa-text small {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--text-muted);
  font-weight: 400;
  line-height: 1.35;
}

.qa-arrow {
  flex: 0 0 auto;
  color: var(--sage);
  font-size: 18px;
  font-weight: 300;
  transition: transform 0.15s ease, color 0.15s ease;
  padding-right: 4px;
}
.qa-row:hover .qa-arrow { transform: translateX(3px); color: var(--sage-deep); }

.qa-close { margin: 14px 0 4px; text-align: center; }
.qa-close-btn {
  background: none; border: none;
  color: var(--text-muted);
  font-size: 14px;
  padding: 12px 22px;
  cursor: pointer;
  font-family: inherit;
  border-radius: 8px;
  font-style: italic;
  font-family: var(--font-serif, Georgia, serif);
}
.qa-close-btn:hover { color: var(--sage-deep); background: var(--cream-warm); }

/* ── Plant color chips + picker ─────────────────────────────────────── */
/* Small color chip rendered next to plant names everywhere they appear:
   plant detail header, plant library list, "Currently growing" rows on
   bed.php. Helps the gardener scan multiple plants at a glance. */
.plant-chip {
  display: inline-block;
  width: 14px; height: 14px;
  border-radius: 4px;
  vertical-align: -2px;
  flex: 0 0 auto;
  border: 1px solid color-mix(in srgb, currentColor 25%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.plant-chip-lg {
  width: 22px; height: 22px;
  border-radius: 6px;
  vertical-align: middle;
}

/* Color picker on plant edit form — preset chip row + native picker */
.color-picker {
  display: flex; align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.color-swatches {
  display: flex; gap: 6px; flex-wrap: wrap;
}
.color-swatch {
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 2px solid color-mix(in srgb, #000 8%, transparent);
  cursor: pointer;
  padding: 0;
  transition: transform 0.1s, border-color 0.15s, box-shadow 0.15s;
  -webkit-tap-highlight-color: transparent;
}
.color-swatch:hover {
  transform: scale(1.1);
  border-color: color-mix(in srgb, #000 30%, transparent);
}
.color-swatch:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}
.color-picker input[type="color"] {
  width: 56px; height: 36px;
  padding: 2px;
  border: 1px solid var(--cream-edge);
  border-radius: 8px;
  cursor: pointer;
  background: #fff;
}
.color-picker input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.color-picker input[type="color"]::-webkit-color-swatch { border: 0; border-radius: 5px; }

/* Inline-checkbox row used on the plant edit form (afternoon shade /
   wind sensitive) — bigger tap target, prose layout. */
.check-row {
  display: flex; align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  cursor: pointer;
  border-bottom: 1px solid var(--cream-edge);
}
.check-row:last-child { border-bottom: 0; }
.check-row input[type="checkbox"] {
  margin-top: 3px;
  width: 18px; height: 18px;
  accent-color: var(--sage-deep);
  flex: 0 0 auto;
}
.check-row strong {
  display: block;
  font-weight: 600;
  font-size: 14.5px;
  color: var(--ink, #2c2a25);
}
.check-row small {
  display: block;
  font-size: 12.5px;
  margin-top: 2px;
  line-height: 1.4;
}

/* ── Plot grid (square-foot bed layout) ─────────────────────────────── */
/* The grid renders one CSS-grid cell per square foot. Filled cells
   route to the planting edit form; empty cells route to "+ plant here"
   pre-filled with the cell coordinates. Multi-cell plantings span via
   inline grid-column/grid-row span attributes. */
.plot-card { padding: var(--s-4); }
.plot-card-prompt {
  text-align: center;
  padding: var(--s-5) var(--s-4);
  background: linear-gradient(180deg, var(--cream-warm) 0%, #fff 100%);
  border-style: dashed;
}
.plot-grid {
  display: grid;
  gap: 4px;
  background: var(--cream-warm);
  padding: 6px;
  border-radius: 10px;
  border: 1px solid var(--cream-edge);
  /* Ensures every cell is square regardless of bed dimensions */
}
.plot-cell {
  position: relative;
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  border-radius: 6px;
  text-decoration: none;
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 500;
  font-size: 16px;
  user-select: none;
  transition: transform 0.08s ease, box-shadow 0.12s ease, background 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}
.plot-cell:hover { text-decoration: none; }
.plot-cell:active { transform: scale(0.96); }
.plot-cell-empty {
  background: #fff;
  border: 1px dashed color-mix(in srgb, var(--sage-soft) 60%, transparent);
  color: var(--sage);
}
.plot-cell-empty:hover { background: color-mix(in srgb, var(--sage-soft) 25%, white); border-style: solid; }
.plot-cell-plus {
  font-size: 18px; font-weight: 300; opacity: 0.5; line-height: 1;
}
.plot-cell-empty:hover .plot-cell-plus { opacity: 1; }
.plot-cell-continuation {
  background: color-mix(in srgb, var(--sage-soft) 35%, white);
  border-radius: 6px;
  /* Spacer for multi-cell continuation so the grid math stays clean */
}
.plot-cell-filled {
  color: var(--ink, #2c2a25);
  box-shadow: 0 1px 0 rgba(60, 80, 50, 0.06);
}
.plot-cell-filled:hover { box-shadow: 0 2px 6px rgba(60, 80, 50, 0.12); }

/* When the cell carries a --plant-color (set inline by bed.php), the tile
   tints with that color. Otherwise the lifecycle classes below provide a
   muted fallback. The plant-color tint at 28% over white reads as a clear
   signal without overpowering the bed-level layout. */
.plot-cell-filled[style*="--plant-color"] {
  background: color-mix(in srgb, var(--plant-color) 28%, #fff);
  border-color: color-mix(in srgb, var(--plant-color) 60%, transparent);
}
/* Lifecycle fallback (when --plant-color isn't set) */
.plot-cell-annual    { background: color-mix(in srgb, var(--honey) 22%, #fff); border: 1px solid color-mix(in srgb, var(--honey) 35%, transparent); }
.plot-cell-perennial { background: color-mix(in srgb, var(--sage-soft) 55%, #fff); border: 1px solid color-mix(in srgb, var(--sage-deep) 25%, transparent); }
.plot-cell-biennial  { background: color-mix(in srgb, var(--sage-soft) 35%, #fff); border: 1px solid color-mix(in srgb, var(--sage-deep) 18%, transparent); }

.plot-cell-label {
  font-size: 15px; font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--moss);
  pointer-events: none;
}
.plot-cell-count {
  position: absolute; bottom: 2px; right: 5px;
  font-size: 10px; font-weight: 600;
  color: color-mix(in srgb, var(--moss) 70%, transparent);
  font-family: inherit;
  letter-spacing: 0;
}

.plot-legend {
  display: flex; gap: 16px;
  flex-wrap: wrap;
  margin: 12px 0 0;
  font-size: 12px;
  align-items: center;
}
.plot-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.plot-legend-spacer { color: var(--text-faint); }
.plot-swatch {
  width: 14px; height: 14px;
  border-radius: 3px;
  display: inline-block;
}

.plot-unplaced {
  margin-top: 14px;
  border-top: 1px solid var(--cream-edge);
  padding-top: 12px;
}
.plot-unplaced summary {
  cursor: pointer;
  font-size: 13px;
  color: var(--sage-deep);
  list-style: none;
  font-style: italic;
  font-family: var(--font-serif, Georgia, serif);
}
.plot-unplaced summary::-webkit-details-marker { display: none; }
.plot-unplaced summary::before { content: '▸ '; opacity: 0.6; }
.plot-unplaced[open] summary::before { content: '▾ '; }

/* ── Cell context pill on planting form ──────────────────────────────── */
.cell-context {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px;
  margin-bottom: var(--s-4);
  background: color-mix(in srgb, var(--sage-soft) 30%, #fff);
  border: 1px solid color-mix(in srgb, var(--sage-deep) 20%, transparent);
  border-radius: 10px;
  font-size: 14px;
}
.cell-context-pill {
  background: var(--sage-deep);
  color: #fff;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12.5px;
  letter-spacing: 0.02em;
}
.cell-context-span {
  color: var(--sage-deep);
  font-weight: 500;
  font-size: 13px;
}
.cell-context a { color: var(--sage-deep); text-decoration: underline; text-underline-offset: 2px; }

/* ── Companion feedback under the plant picker ──────────────────────── */
.companion-feedback {
  margin-top: 8px;
  padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.companion-friend, .companion-foe {
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13.5px;
  line-height: 1.4;
}
.companion-friend {
  background: color-mix(in srgb, var(--sage-soft) 35%, #fff);
  color: var(--moss);
  border-left: 3px solid var(--sage-deep);
}
.companion-foe {
  background: color-mix(in srgb, var(--terracotta, #C97B5E) 18%, #fff);
  color: #8a4434;
  border-left: 3px solid var(--terracotta, #C97B5E);
}

/* ── Plant warnings (afternoon shade / wind sensitive) ─────────────── */
/* Pill-style chips on plant.php detail header. */
.plant-warnings {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 10px 0;
}
.plant-warning {
  display: inline-flex; align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 500;
  border: 1px solid;
}
.plant-warning-icon {
  font-size: 14px;
  line-height: 1;
}
.plant-warning-shade {
  background: color-mix(in srgb, var(--honey) 20%, #fff);
  color: #7A4F1C;
  border-color: color-mix(in srgb, var(--honey) 55%, transparent);
}
.plant-warning-wind {
  background: color-mix(in srgb, #BFD3DC 50%, #fff);
  color: #2C5673;
  border-color: color-mix(in srgb, #4A7390 50%, transparent);
}

/* Inline form-feedback variant — same colors, full-row treatment, used
   in the planting form's #companion-feedback panel. */
.plant-warning-inline {
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 13.5px;
  line-height: 1.4;
  border-left: 3px solid;
}
.plant-warning-shade-inline {
  background: color-mix(in srgb, var(--honey) 16%, #fff);
  color: #7A4F1C;
  border-left-color: var(--honey);
}
.plant-warning-wind-inline {
  background: color-mix(in srgb, #BFD3DC 30%, #fff);
  color: #2C5673;
  border-left-color: #4A7390;
}

/* ── Garden layout (top-down map) ────────────────────────────────────── */
/* A canvas that scales to fit the page. Each foot of the garden becomes a
   1fr CSS-grid track, so beds positioned in feet land at the right spot
   regardless of viewport width. Beds are absolute-positioned over the grid
   using --bx/--by/--bw/--bh in feet. */
.garden-canvas-card {
  padding: 12px;
  background: linear-gradient(180deg, #fff 0%, var(--cream-warm) 100%);
}

/* ── Satellite underlay (Leaflet + Esri World Imagery) ──────────────── */
/* The garden-stage wraps the map and the canvas-wrap so the map can sit
   behind via absolute positioning. Toggled on/off via the 🛰 button. */
.garden-stage {
  position: relative;
}
.garden-map {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: 10px;
  overflow: hidden;
  /* Hidden by default — toggle adds .garden-map-visible to fade in. */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
  --map-opacity: 1;
}
.garden-map.garden-map-visible {
  opacity: var(--map-opacity);
  pointer-events: auto;
}
/* When the map is on, make the canvas-wrap background transparent so the
   map shows through. Beds + markers remain solid AND keep pointer events;
   the canvas/wrap themselves pass clicks through so Leaflet zoom controls
   and map panning underneath are clickable. */
body.garden-map-on .garden-canvas-wrap {
  background: transparent;
  border-color: rgba(0, 0, 0, 0.18);
  pointer-events: none;            /* clicks fall through to the map */
}
body.garden-map-on .garden-canvas {
  pointer-events: none;            /* same — empty cells don't capture */
  background-image:
    linear-gradient(to right,  rgba(255, 255, 255, 0.35) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.35) 1px, transparent 1px);
}
body.garden-map-on .garden-bed,
body.garden-map-on .garden-marker,
body.garden-map-on .garden-tray-bed {
  pointer-events: auto;            /* but bed/marker tiles still take clicks */
}
/* Style the Leaflet zoom buttons to match our palette. We intentionally
   do NOT override Leaflet's pane z-indexes — Leaflet manages its own
   internal stacking (tiles 200 → controls 800 → top/bottom 1000). */
.garden-map .leaflet-control-zoom a {
  background: rgba(255, 255, 255, 0.94);
  color: var(--moss);
  border-color: var(--cream-edge);
}
.garden-map .leaflet-control-attribution {
  font-size: 9px;
  background: rgba(255, 255, 255, 0.7);
  color: var(--text-muted);
}
/* Rotate compass — give it the same opaque palette as the zoom buttons
   and a slightly larger hit target so the gardener can actually grab it. */
.garden-map .leaflet-control-rotate {
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--cream-edge);
  border-radius: 6px;
  margin: 10px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}
.garden-map .leaflet-control-rotate a {
  width: 32px;
  height: 32px;
  display: block;
  cursor: grab;
  border-radius: 5px;
}
.garden-map .leaflet-control-rotate a:active { cursor: grabbing; }

/* The canvas-wrap sits ABOVE the map in the stage stacking order */
.garden-stage .garden-canvas-wrap {
  position: relative;
  z-index: 1;
}

/* ── Map toggle button in toolbar ───────────────────────────────────── */
.garden-map-toggle {
  display: inline-flex; align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.garden-map-toggle:hover {
  background: var(--cream-warm);
  color: var(--sage-deep);
}
.garden-map-toggle.is-active {
  background: var(--sage-deep);
  color: #fff;
  border-color: var(--sage-deep);
}
.garden-map-toggle-icon { font-size: 13px; line-height: 1; }

/* Map-related toolbar controls — inline next to the Satellite toggle.
   All hidden by default; shown when the map underlay is active. */
.garden-map-control {
  display: inline-flex; align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  transition: background 0.15s ease, color 0.15s ease;
}
.garden-map-control[hidden] { display: none; }
.garden-map-control:hover { background: var(--cream-warm); color: var(--sage-deep); }
.garden-map-control-icon { font-size: 13px; line-height: 1; }

.garden-map-opacity-group {
  display: inline-flex; align-items: center;
  gap: 8px;
  padding: 4px 12px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  font-size: 11px;
  color: var(--text-muted);
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
}
.garden-map-opacity-group[hidden] { display: none; }
.garden-map-opacity-group label {
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  font-size: 10px;
}
.garden-map-opacity {
  width: 96px;
  accent-color: var(--sage-deep);
  cursor: pointer;
  height: 18px;
}
.garden-toolbar {
  display: flex; align-items: center; justify-content: flex-start;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
  padding: 0 4px;
}
.garden-compass {
  display: inline-flex; align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  color: var(--sage-deep);
  letter-spacing: 0.04em;
}
.garden-compass-arrow { line-height: 1; font-size: 14px; }
.garden-size {
  display: inline-flex; align-items: baseline;
  gap: 2px;
  padding: 4px 10px;
  background: color-mix(in srgb, var(--honey) 14%, #fff);
  border: 1px solid color-mix(in srgb, var(--honey) 45%, transparent);
  border-radius: 999px;
  font-size: 12px;
  color: var(--moss);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  transition: background 0.15s ease;
}
.garden-size-num {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  font-size: 13px;
  color: var(--ink, #2c2a25);
}
.garden-size-x { opacity: 0.5; padding: 0 2px; }
.garden-size-unit {
  font-size: 11px;
  margin-left: 3px;
  color: var(--text-muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.garden-toolbar-hint {
  margin-left: auto;
  font-size: 12px;
}

.garden-canvas-wrap {
  width: 100%;
  /* Cap viewport occupancy and allow both-direction scroll for large
     gardens. Mobile users can pan/pinch within this region without
     scrolling the whole page. */
  max-height: 70vh;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 10px;
  background: color-mix(in srgb, var(--sage-soft) 18%, #fff);
  border: 1px solid color-mix(in srgb, var(--sage-soft) 50%, transparent);
  /* Center small canvases inside a wider wrap so they don't hug the corner. */
  display: flex;
  align-items: flex-start;
  justify-content: flex-start;
}
.garden-canvas {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--gw), 1fr);
  grid-template-rows:    repeat(var(--gh), 1fr);
  /* Fixed pixel-per-foot scale × user zoom multiplier.
     Mobile: 20 px/ft × zoom · Desktop: 28 px/ft × zoom.
     Zoom defaults to 1.0 and can range 0.4–2.5 via the zoom toolbar. */
  --garden-zoom: 1;
  --garden-px-per-ft: 20px;
  width:  calc(var(--gw) * var(--garden-px-per-ft) * var(--garden-zoom));
  height: calc(var(--gh) * var(--garden-px-per-ft) * var(--garden-zoom));
  flex: 0 0 auto;
  background-image:
    linear-gradient(to right,  color-mix(in srgb, var(--sage-deep) 12%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--sage-deep) 12%, transparent) 1px, transparent 1px);
  background-size: calc(var(--garden-px-per-ft) * var(--garden-zoom)) calc(var(--garden-px-per-ft) * var(--garden-zoom));
  touch-action: pan-x pan-y pinch-zoom;
}
@media (min-width: 600px) {
  .garden-canvas { --garden-px-per-ft: 28px; }
}

.garden-bed {
  position: absolute;
  left: calc(var(--bx) * (100% / var(--gw)));
  top:  calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 50%, #fff) 0%,
      color-mix(in srgb, var(--sage-soft) 35%, #fff) 100%);
  border: 1.5px solid var(--sage-deep);
  border-radius: 6px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 4px 6px;
  cursor: grab;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  box-shadow: 0 1px 0 rgba(60, 80, 50, 0.08);
  transition: box-shadow 0.12s ease, transform 0.08s ease;
  text-align: center;
  overflow: hidden;
  /* Block default touch handling on the tile so single-finger drag isn't
     hijacked by the parent canvas's pan-x/pan-y touch-action. */
  touch-action: none;
}
.garden-bed:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 2px;
}
.garden-bed:hover { box-shadow: 0 2px 8px rgba(60, 80, 50, 0.16); }
.garden-bed.garden-dragging {
  cursor: grabbing;
  z-index: 10;
  box-shadow: 0 6px 18px rgba(60, 80, 50, 0.25);
  transform: scale(1.02);
}
.garden-bed.garden-bed-ghost {
  opacity: 0.85;
}
.garden-bed-stub {
  background: color-mix(in srgb, var(--honey) 25%, #fff);
  border-color: color-mix(in srgb, var(--honey) 80%, transparent);
}
.garden-bed-name {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  font-size: 13px;
  color: var(--moss);
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
.garden-bed-size {
  font-size: 10.5px;
  color: var(--sage-deep);
  margin-top: 2px;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.garden-scale {
  margin: 10px 4px 0;
  font-size: 12px;
  text-align: center;
}

/* Bed tray (unplaced beds) ────────────────────────────────────────── */
.garden-tray-card { padding: var(--s-4); }
.garden-tray {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 8px;
}
.garden-tray-bed {
  display: flex; flex-direction: column;
  padding: 10px 14px;
  background: color-mix(in srgb, var(--sage-soft) 30%, #fff);
  border: 1.5px dashed var(--sage-deep);
  border-radius: 10px;
  cursor: grab;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  font-size: 14px;
  min-width: 100px;
  touch-action: none;
}
.garden-tray-bed:hover { background: color-mix(in srgb, var(--sage-soft) 45%, #fff); }
.garden-tray-bed.garden-dragging {
  cursor: grabbing;
  border-style: solid;
  background: color-mix(in srgb, var(--honey) 25%, #fff);
}
.garden-tray-bed strong {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  color: var(--moss);
  font-size: 14.5px;
  line-height: 1.2;
}
.garden-tray-bed small { margin-top: 2px; font-size: 11.5px; }

/* ── Unplace × button on placed canvas beds ─────────────────────────── */
/* Tiny round X in the top-right of every placed bed. Hidden on hover-capable
   devices until you hover the tile (keeps the canvas clean), persistent on
   touch-only devices since hover doesn't exist there. */
.garden-bed-unplace {
  position: absolute;
  top: 3px; right: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--text-muted, #7a7367);
  border: 1px solid var(--cream-edge);
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease, transform 0.12s ease;
  opacity: 0;
  /* Make sure clicks land on the button, not the underlying drag handler */
  z-index: 2;
  /* Accessibility: ensure no touch-action conflicts with the bed */
  touch-action: manipulation;
}
.garden-bed:hover .garden-bed-unplace,
.garden-bed:focus-within .garden-bed-unplace { opacity: 1; }
.garden-bed-unplace:hover {
  background: var(--terracotta, #C97B5E);
  color: #fff;
  transform: scale(1.08);
}
.garden-bed-unplace:focus-visible {
  outline: 2px solid var(--sage-deep);
  outline-offset: 1px;
  opacity: 1;
}
@media (hover: none) {
  /* Touch-only devices: persistent at low opacity so it's discoverable */
  .garden-bed-unplace { opacity: 0.85; }
}
/* Hide the unplace button on very small bed tiles where it would crowd
   the label out (1×1 ft stub beds). Users can still unplace via the form. */
.garden-bed-stub .garden-bed-unplace { display: none; }

/* ── Plant color dots inside bed tiles on the garden layout ───────── */
/* A row of small chromatic dots at the bottom of each bed tile shows
   what's currently growing inside. Picked from the user's plant.color
   override (when set) or the curated default per plant. Dedupes by
   color so 12 lettuces show as one green dot. */
.garden-bed-plant-dots {
  position: absolute;
  bottom: 5px; left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 3px;
  align-items: center;
  pointer-events: none;
  max-width: calc(100% - 12px);
  overflow: hidden;
}
.garden-bed-plant-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, 0.22);
  flex: 0 0 auto;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.55);
}
.garden-bed-plant-more {
  font-size: 9px;
  font-weight: 600;
  color: var(--moss);
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  margin-left: 1px;
}
/* On stub beds (no dimensions / hydroponic) the tile is too tiny to fit
   even a few dots. They're hidden via the !isStub PHP gate already, but
   this CSS keeps the safety net in case the gate slips. */
.garden-bed-stub .garden-bed-plant-dots { display: none; }

/* ── "Just placed" pulse — confirmation the drop saved ──────────────── */
.garden-bed-just-placed {
  animation: garden-bed-placed 0.7s ease-out;
}
@keyframes garden-bed-placed {
  0%   { transform: scale(1.06); box-shadow: 0 8px 22px rgba(60, 80, 50, 0.35); }
  60%  { transform: scale(0.99); box-shadow: 0 3px 10px rgba(60, 80, 50, 0.18); }
  100% { transform: scale(1);    box-shadow: 0 1px 0 rgba(60, 80, 50, 0.08); }
}

/* ── Garden toast (transient feedback) ──────────────────────────────── */
.garden-toast {
  position: fixed;
  left: 50%; bottom: 88px;
  transform: translateX(-50%) translateY(20px);
  background: var(--ink, #2c2a25);
  color: #fff;
  padding: 12px 18px;
  border-radius: 24px;
  font-size: 14px;
  font-weight: 500;
  z-index: 1000;
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s ease;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  pointer-events: none;
  max-width: 86vw;
  text-align: center;
}
.garden-toast.visible { opacity: 1; transform: translateX(-50%) translateY(0); }
.garden-toast-error { background: #8a4434; }

/* ── Yard outline ────────────────────────────────────────────────────── */
/* Soft green outline showing the gardener's declared garden boundary
   (set in settings.php as yard_width_ft × yard_length_ft). Sits under
   beds + markers visually so the active layout stays the focus. */
.garden-yard {
  position: absolute;
  left:   calc(var(--bx) * (100% / var(--gw)));
  top:    calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  border: 2px dashed color-mix(in srgb, var(--sage-deep) 60%, transparent);
  border-radius: 8px;
  background: color-mix(in srgb, var(--sage-soft) 12%, transparent);
  pointer-events: none;
  z-index: 0;
}
.garden-yard-label {
  position: absolute;
  top: 6px; left: 8px;
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
  font-size: 11px;
  font-weight: 500;
  color: color-mix(in srgb, var(--sage-deep) 75%, transparent);
  letter-spacing: 0.04em;
  background: color-mix(in srgb, #fff 75%, transparent);
  padding: 1px 6px;
  border-radius: 999px;
}

/* ── Garden markers (trees, structures, etc.) ───────────────────────── */
/* Same positioning math as beds, but a softer translucent style so they
   read as context rather than primary content. Sits between the yard and
   bed layers (z-index 1). */
.garden-marker {
  position: absolute;
  left:   calc(var(--bx) * (100% / var(--gw)));
  top:    calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 2px 4px;
  border-radius: 6px;
  cursor: grab;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  text-align: center;
  overflow: hidden;
  transition: box-shadow 0.12s ease, transform 0.08s ease, opacity 0.12s ease;
  z-index: 1;
  touch-action: none;
}
.garden-marker:active { transform: scale(0.97); cursor: grabbing; }
.garden-marker.garden-dragging {
  cursor: grabbing;
  z-index: 12;
  box-shadow: 0 6px 18px rgba(60, 80, 50, 0.25);
  transform: scale(1.02);
}

/* Per-kind tints — leans muted so beds stay the visual focus */
.garden-marker-tree         { background: color-mix(in srgb, #5C8A50 32%, #fff); border: 1px solid #5C8A50; color: #2C4A22; }
.garden-marker-shrub        { background: color-mix(in srgb, #7BA771 30%, #fff); border: 1px solid #7BA771; color: #3D5C36; }
.garden-marker-structure    { background: color-mix(in srgb, #B8A48A 35%, #fff); border: 1px solid #8C7A60; color: #5A4A36; }
.garden-marker-water        { background: color-mix(in srgb, #BFD3DC 60%, #fff); border: 1px solid #4A7390; color: #2C5673; }
.garden-marker-compost      { background: color-mix(in srgb, #A88860 35%, #fff); border: 1px solid #7A5C36; color: #4A3622; }
.garden-marker-gate         { background: color-mix(in srgb, var(--honey) 40%, #fff); border: 1px dashed #7A4F1C; color: #7A4F1C; }
.garden-marker-path         { background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--cream-edge) 80%, transparent) 0 4px, transparent 4px 8px); border: 1px dashed var(--cream-edge); color: var(--text-muted); }
.garden-marker-note         { background: color-mix(in srgb, var(--cream-warm) 90%, #fff); border: 1px dashed var(--cream-edge); color: var(--text-muted); }
.garden-marker-potted_plant { background: color-mix(in srgb, #C97B5E 28%, #fff); border: 1px solid #A6573D; color: #6E3A22; }

.garden-marker-icon {
  flex: 0 0 auto;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.garden-marker-icon svg { width: 22px; height: 22px; }
.garden-marker-label {
  font-size: 10.5px;
  font-weight: 600;
  font-family: var(--font-serif, Georgia, serif);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  margin-top: 2px;
  pointer-events: none;
}

/* The marker delete form is a child of .garden-marker, but should be a
   floating × button visually. Override default form styling. */
.garden-marker-delete-form {
  position: absolute;
  top: 2px; right: 2px;
  margin: 0; padding: 0;
  display: inline;
}
/* Mirror form for the duplicate ⧉ button — top-left corner so it pairs
   with delete (top-right). */
.garden-marker-duplicate-form {
  position: absolute;
  top: 2px; left: 2px;
  margin: 0; padding: 0;
  display: inline;
  z-index: 3;
}
/* Rotate/duplicate button reuses the same base style; CSS below makes
   it visible on .garden-marker hover too (not just .garden-bed). */
.garden-marker:hover .garden-bed-rotate,
.garden-marker:focus-within .garden-bed-rotate { opacity: 1; }
/* And the × delete button — the original visibility rule only matched
   .garden-bed:hover, leaving the marker × invisible on desktop (where
   `@media (hover: none)` does NOT apply). Without this rule users
   couldn't delete a marker on a non-touch device. */
.garden-marker:hover .garden-bed-unplace,
.garden-marker:focus-within .garden-bed-unplace { opacity: 1; }
/* Markers don't rotate — they only duplicate. So the rotate styling on
   marker children renders the ⧉ glyph instead of ↻ via textContent. */
.garden-marker-duplicate-btn:hover {
  background: var(--honey);
  color: #fff;
  transform: scale(1.08);
}

/* ── Bed rotation ↻ button (paired with × unplace) ──────────────────── */
.garden-bed-rotate {
  position: absolute;
  top: 3px; left: 3px;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  color: var(--sage-deep);
  border: 1px solid var(--cream-edge);
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  transition: background 0.15s ease, color 0.15s ease, opacity 0.15s ease, transform 0.12s ease;
  opacity: 0;
  z-index: 3;
  touch-action: manipulation;
}
.garden-bed:hover .garden-bed-rotate,
.garden-bed:focus-within .garden-bed-rotate { opacity: 1; }
.garden-bed-rotate:hover {
  background: var(--sage-deep);
  color: #fff;
  transform: scale(1.08) rotate(45deg);
}
.garden-bed-rotate:focus-visible { outline: 2px solid var(--sage-deep); outline-offset: 1px; opacity: 1; }
@media (hover: none) { .garden-bed-rotate { opacity: 0.85; } }
.garden-bed-stub .garden-bed-rotate { display: none; }

/* ── Zoom controls in toolbar ───────────────────────────────────────── */
.garden-zoom {
  display: inline-flex;
  margin-left: auto;
  border: 1px solid var(--cream-edge);
  border-radius: 999px;
  overflow: hidden;
  background: #fff;
}
.garden-zoom-btn {
  appearance: none;
  background: #fff;
  border: 0;
  padding: 5px 10px;
  font-size: 14px;
  font-weight: 600;
  color: var(--sage-deep);
  cursor: pointer;
  font-family: -apple-system, BlinkMacSystemFont, sans-serif;
  transition: background 0.15s ease, color 0.15s ease;
  min-width: 32px;
  line-height: 1;
}
.garden-zoom-btn + .garden-zoom-btn { border-left: 1px solid var(--cream-edge); }
.garden-zoom-btn:hover { background: var(--cream-warm); color: var(--moss); }
.garden-zoom-btn:active { transform: scale(0.97); }
.garden-zoom-fit {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
}

/* ── Marker picker on marker.php ────────────────────────────────────── */
.marker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
  margin-top: 4px;
}
.marker-tile {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px;
  padding: 14px 8px 10px;
  border: 1.5px solid var(--cream-edge);
  border-radius: 12px;
  background: #fff;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.marker-tile input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.marker-tile:hover { border-color: var(--sage-soft); background: var(--cream-warm); }
.marker-tile:has(input:checked) {
  border-color: var(--sage-deep);
  background: color-mix(in srgb, var(--sage-soft) 30%, #fff);
}
.marker-tile-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--sage-soft) 40%, #fff);
  color: var(--sage-deep);
  margin-bottom: 4px;
}
.marker-tile-icon svg { width: 22px; height: 22px; }
.marker-tile-label {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  font-size: 13px;
  color: var(--moss);
}
.marker-tile-size {
  font-size: 10.5px;
  color: var(--text-muted);
}

/* ── Dashboard garden preview ────────────────────────────────────────── */
/* Read-only thumbnail of the garden layout. Same grid math as garden.php
   but smaller, no drag handlers, and the whole canvas is one clickable
   link to the full layout page. */
.dash-garden h3 {
  margin: 0;
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 500;
}
.garden-preview {
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--gw), 1fr);
  grid-template-rows:    repeat(var(--gh), 1fr);
  aspect-ratio: var(--gw) / var(--gh);
  width: 100%;
  /* Soft cap so a tall, narrow garden doesn't dominate the dashboard */
  max-height: 280px;
  background: color-mix(in srgb, var(--sage-soft) 18%, #fff);
  border: 1px solid color-mix(in srgb, var(--sage-soft) 50%, transparent);
  border-radius: 12px;
  background-image:
    linear-gradient(to right,  color-mix(in srgb, var(--sage-deep) 8%, transparent) 1px, transparent 1px),
    linear-gradient(to bottom, color-mix(in srgb, var(--sage-deep) 8%, transparent) 1px, transparent 1px);
  background-size: calc(100% / var(--gw)) calc(100% / var(--gh));
  text-decoration: none;
  cursor: pointer;
  transition: box-shadow 0.15s ease, transform 0.12s ease;
  overflow: hidden;
}
.garden-preview:hover {
  text-decoration: none;
  box-shadow: 0 4px 14px rgba(60, 80, 50, 0.12);
}
.garden-preview:active { transform: scale(0.995); }

.garden-preview-bed {
  position: absolute;
  left:   calc(var(--bx) * (100% / var(--gw)));
  top:    calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  background: linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 60%, #fff) 0%,
      color-mix(in srgb, var(--sage-soft) 40%, #fff) 100%);
  border: 1px solid var(--sage-deep);
  border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  padding: 2px 4px;
  text-align: center;
  overflow: hidden;
  pointer-events: none;
}
.garden-preview-bed-stub {
  background: color-mix(in srgb, var(--honey) 25%, #fff);
  border-color: color-mix(in srgb, var(--honey) 70%, transparent);
}
.garden-preview-name {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  font-size: 11px;
  color: var(--moss);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  line-height: 1.1;
}

/* Yard outline in dashboard preview — soft sage dashed rect, sits behind
   markers and beds so they stay the visual focus. */
.garden-preview-yard {
  position: absolute;
  left:   calc(var(--bx) * (100% / var(--gw)));
  top:    calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  border: 1.5px dashed color-mix(in srgb, var(--sage-deep) 50%, transparent);
  border-radius: 6px;
  background: color-mix(in srgb, var(--sage-soft) 10%, transparent);
  pointer-events: none;
  z-index: 0;
}

/* Marker dots in dashboard preview — colored boxes per kind. We skip the
   icon at this scale (most thumbs are < 24px tall per cell — icons would
   be unreadable) in favor of distinct color washes. */
.garden-preview-marker {
  position: absolute;
  left:   calc(var(--bx) * (100% / var(--gw)));
  top:    calc(var(--by) * (100% / var(--gh)));
  width:  calc(var(--bw) * (100% / var(--gw)));
  height: calc(var(--bh) * (100% / var(--gh)));
  border-radius: 3px;
  pointer-events: none;
  z-index: 1;
  border: 1px solid;
}
.garden-preview-marker-tree      { background: color-mix(in srgb, #5C8A50 38%, #fff); border-color: #5C8A50; border-radius: 50%; }
.garden-preview-marker-shrub     { background: color-mix(in srgb, #7BA771 38%, #fff); border-color: #7BA771; border-radius: 50%; }
.garden-preview-marker-structure { background: color-mix(in srgb, #B8A48A 50%, #fff); border-color: #8C7A60; }
.garden-preview-marker-water     { background: color-mix(in srgb, #BFD3DC 75%, #fff); border-color: #4A7390; border-radius: 50%; }
.garden-preview-marker-compost   { background: color-mix(in srgb, #A88860 50%, #fff); border-color: #7A5C36; }
.garden-preview-marker-gate      { background: color-mix(in srgb, var(--honey) 55%, #fff); border-color: #7A4F1C; border-style: dashed; }
.garden-preview-marker-path      { background: repeating-linear-gradient(90deg, color-mix(in srgb, var(--cream-edge) 80%, transparent) 0 3px, transparent 3px 6px); border-color: var(--cream-edge); border-style: dashed; }
.garden-preview-marker-note      { background: color-mix(in srgb, var(--cream-warm) 90%, #fff); border-color: var(--cream-edge); border-style: dashed; }
.garden-preview-marker-potted_plant { background: color-mix(in srgb, #C97B5E 40%, #fff); border-color: #A6573D; border-radius: 50%; }

/* Beds layer on top so labels stay readable */
.garden-preview-bed { z-index: 2; }

.dash-garden-foot {
  margin: 8px 4px 0;
  font-size: 12.5px;
  font-style: italic;
  font-family: var(--font-serif, Georgia, serif);
}

/* Empty state — when user has beds but none placed yet */
.garden-preview-empty {
  display: flex; align-items: center;
  gap: 14px;
  padding: 18px 20px;
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 22%, #fff) 0%,
      color-mix(in srgb, var(--honey) 10%, #fff) 100%);
  border: 1px dashed color-mix(in srgb, var(--sage-deep) 35%, transparent);
  border-radius: 12px;
  text-decoration: none;
  color: var(--ink, #2c2a25);
  transition: background 0.15s ease;
}
.garden-preview-empty:hover {
  text-decoration: none;
  color: var(--ink, #2c2a25);
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--sage-soft) 35%, #fff) 0%,
      color-mix(in srgb, var(--honey) 18%, #fff) 100%);
}
.garden-preview-empty-icon {
  flex: 0 0 auto;
  width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px;
  background: #fff;
  color: var(--sage-deep);
  border: 1px solid var(--cream-edge);
}
.garden-preview-empty-text {
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.garden-preview-empty-text strong {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  font-size: 15px;
  color: var(--moss);
}
.garden-preview-empty-text small {
  color: var(--text-muted);
  font-size: 12.5px;
}

/* ── Onboarding card ─────────────────────────────────────────────────── */
.onboarding {
  background: linear-gradient(135deg, #fff 0%, var(--cream-warm) 100%);
  border-color: var(--sage-soft);
}
.onboarding h3 { margin-top: 0; }
.onboarding-steps {
  list-style: none; padding: 0; margin: 0;
}
.onboarding-steps li {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--cream-edge);
  display: flex; align-items: center; gap: var(--s-3);
}
.onboarding-steps li:last-child { border-bottom: 0; }
.onboarding-steps .step-mark {
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cream-warm);
  color: var(--sage-deep); font-weight: 700;
  flex: 0 0 28px;
}
.onboarding-steps li.done .step-mark { background: var(--sage-deep); color: var(--cream); }
.onboarding-steps li.done a { color: var(--text-faint); text-decoration: line-through; }
.onboarding-steps a { color: var(--text); font-weight: 500; flex: 1; }

/* ── Skip-to-content (a11y) ─────────────────────────────────────────── */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0,0,0,0); border: 0;
}
.sr-only-focusable:focus, .sr-only-focusable:active {
  position: static; width: auto; height: auto;
  margin: 0; overflow: visible; clip: auto;
  display: inline-block;
  padding: 8px 12px; background: var(--moss); color: var(--cream);
  border-radius: var(--r-2); text-decoration: none;
  z-index: 100;
}

/* ── Form field error state ─────────────────────────────────────────── */
.field.has-error .input,
.field.has-error select,
.field.has-error textarea {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(162, 69, 51, .12);
}
.field-error { color: var(--danger); font-size: 13px; margin-top: 4px; }

/* Required marker — auto-applied via :has() */
.field:has(:required) > label::after {
  content: " *";
  color: var(--danger);
  font-weight: 700;
}

/* ── Sticky save bar (long forms) ───────────────────────────────────── */
.form-actions-sticky {
  position: sticky;
  bottom: calc(var(--bottom-nav-h) + env(safe-area-inset-bottom));
  background: var(--cream);
  margin: var(--s-4) calc(var(--s-4) * -1) calc(var(--s-4) * -1);
  padding: var(--s-3) var(--s-4);
  border-top: 1px solid var(--cream-edge);
  z-index: 5;
  display: flex; gap: 8px;
}
.form-actions-sticky .btn { flex: 1; }
.form-actions-sticky .btn-ghost { flex: 0 0 auto; }
.card .form-actions-sticky { margin-bottom: calc(var(--s-5) * -1); border-bottom-left-radius: var(--r-3); border-bottom-right-radius: var(--r-3); }

/* ── Topbar account menu ────────────────────────────────────────────── */
.topbar-menu { position: relative; }
.topbar-trigger {
  display: inline-flex; align-items: center; gap: 4px;
  background: transparent; border: 0;
  color: var(--text-muted); font: inherit; cursor: pointer;
  padding: 8px; border-radius: var(--r-1);
  font-size: 14px;
}
.topbar-trigger:hover { color: var(--sage-deep); }
.topbar-dropdown {
  position: absolute; right: 0; top: calc(100% + 4px);
  background: #fff; border: 1px solid var(--cream-edge);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-md);
  padding: 6px;
  min-width: 200px;
  display: none;
  z-index: 30;
}
.topbar-dropdown.is-open { display: block; }
.topbar-dropdown a, .topbar-dropdown button {
  display: block; width: 100%; text-align: left;
  padding: 10px 12px;
  color: var(--text); text-decoration: none;
  border-radius: var(--r-1);
  background: transparent; border: 0;
  font: inherit; cursor: pointer;
}
.topbar-dropdown a:hover, .topbar-dropdown button:hover { background: var(--cream-warm); text-decoration: none; }
.topbar-dropdown .menu-divider { height: 1px; background: var(--cream-edge); margin: 4px 6px; }
.topbar-dropdown .menu-danger { color: var(--danger); }

/* ── Photo lightbox ─────────────────────────────────────────────────── */
.lightbox {
  position: fixed; inset: 0;
  background: rgba(45, 51, 40, .92);
  z-index: 60;
  display: none;
  align-items: center; justify-content: center;
  padding: 16px;
}
.lightbox.is-open { display: flex; }
.lightbox img {
  max-width: 100%; max-height: 100%;
  border-radius: var(--r-2);
  box-shadow: 0 20px 60px rgba(0,0,0,.4);
  animation: lightbox-in .18s ease-out;
}
.lightbox-close {
  position: absolute; top: 16px; right: 16px;
  background: rgba(255,255,255,.15); color: var(--cream);
  border: 0; border-radius: 50%;
  width: 40px; height: 40px;
  font-size: 24px; line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,.25); }
@keyframes lightbox-in { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }

.photo-thumb {
  display: block; cursor: zoom-in;
  border: 0; padding: 0; background: transparent;
  border-radius: var(--r-1);
  overflow: hidden;
}
.photo-thumb img { display: block; }

/* ── Greeting block (dashboard) ─────────────────────────────────────── */
.greeting {
  margin-bottom: var(--s-4);
}
.greeting h1 {
  font-family: var(--font-serif);
  font-size: clamp(22px, 4vw, 28px);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -.005em;
  margin: 0 0 4px;
}
.greeting-meta {
  font-size: 14px;
  color: var(--text-muted);
  margin: 0;
  letter-spacing: .005em;
}

/* ── Quick-action CTA (dashboard hero) ─────────────────────────────── */
.quick-capture-cta {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 14px 16px;
  background: linear-gradient(135deg, var(--moss) 0%, var(--sage-deep) 100%);
  color: var(--cream);
  border-radius: var(--r-3);
  text-decoration: none;
  margin-bottom: var(--s-4);
  box-shadow: var(--shadow-md);
  transition: transform .2s ease-out, box-shadow .2s;
  border: 0;
  width: 100%;
  cursor: pointer;
  text-align: left;
  font: inherit;
}
.quick-capture-cta:hover {
  text-decoration: none;
  color: var(--cream);
  transform: translateY(-1px);
  box-shadow: 0 12px 32px rgba(45,51,40,.18);
}
.quick-capture-cta .qcc-icon {
  flex: 0 0 44px;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: rgba(250,247,242,.15);
  display: flex; align-items: center; justify-content: center;
  color: var(--cream);
}
.quick-capture-cta .qcc-body { flex: 1 1 auto; min-width: 0; }
.quick-capture-cta .qcc-title {
  display: block;
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 600;
  line-height: 1.15;
}
.quick-capture-cta .qcc-help {
  display: block;
  font-size: 12px;
  color: rgba(250,247,242,.82);
  margin-top: 2px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.quick-capture-cta .qcc-chevron {
  font-size: 24px; color: rgba(250,247,242,.7);
  flex: 0 0 auto;
}

/* ── Dashboard sections (lighter cards, tighter rhythm) ────────────── */
.dash-section {
  background: var(--cream-warm);
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-4);
  margin-bottom: var(--s-4);
}
.dash-section > h3 {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 600;
  margin: 0 0 var(--s-3);
  color: var(--moss);
  letter-spacing: -.005em;
}

/* ── Recent (no card — section title + list with separators) ───────── */
.dash-recent {
  margin-bottom: var(--s-4);
}
.dash-recent .dash-recent-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: var(--s-2);
}
.dash-recent h3 {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 600;
  margin: 0;
  color: var(--moss);
}
.dash-recent .all-link {
  font-size: 13px; color: var(--sage-deep);
}

/* ── Row list (used in dash-section + dash-recent) ─────────────────── */
.row-list { list-style: none; margin: 0; padding: 0; }
.row-list .row-item {
  border-bottom: 1px solid color-mix(in srgb, var(--cream-edge) 65%, transparent);
}
.row-list .row-item:last-child { border-bottom: 0; }
.row-list .row-item > a,
.row-list .row-item {
  display: flex; align-items: center; gap: var(--s-3);
  padding: 10px 0;
  color: inherit; text-decoration: none;
  min-height: 44px;
}
.row-list .row-item > a { width: 100%; }
.row-list .row-item > a:hover { color: var(--sage-deep); text-decoration: none; }
.row-list .row-body { flex: 1 1 auto; min-width: 0; font-size: 15px; line-height: 1.4; }
.row-list .row-trail { flex: 0 0 auto; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: 14px; }
.row-list .row-chevron { color: var(--text-faint); flex: 0 0 auto; font-size: 22px; line-height: 1; }
.row-list .row-icon {
  flex: 0 0 14px;
  color: var(--sage-deep);
  font-weight: 700;
  text-align: center;
}
.row-list .row-item-hint .row-body {
  font-style: italic;
  font-family: var(--font-serif);
  color: var(--moss);
  font-size: 14px;
}

/* ── Footer stats (single muted line) ──────────────────────────────── */
.dash-stats {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: var(--text-faint);
  margin: var(--s-5) 0 0;
  text-align: center;
  letter-spacing: .01em;
}

/* ── Memory cards (year ago, likely ready, today's care) ────────────── */
.memory-stack {
  display: grid; gap: var(--s-3);
  margin-bottom: var(--s-4);
}
.memory-card {
  background: linear-gradient(135deg, #fff 0%, var(--cream-warm) 100%);
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-4);
  box-shadow: var(--shadow-sm);
}
.memory-card .memory-eyebrow {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 13px;
  color: var(--sage-deep);
  letter-spacing: .04em;
  margin-bottom: var(--s-2);
}
.memory-list {
  list-style: none; margin: 0; padding: 0;
}
.memory-list li {
  padding: 6px 0;
  font-size: 15px;
  color: var(--text);
  line-height: 1.5;
  border-bottom: 1px solid color-mix(in srgb, var(--cream-edge) 70%, transparent);
}
.memory-list li:last-child { border-bottom: 0; }
.memory-list a { color: inherit; text-decoration: none; }
.memory-list a:hover { color: var(--sage-deep); text-decoration: none; }
.memory-card.memory-care .memory-list li {
  font-style: italic;
  color: var(--moss);
  font-family: var(--font-serif);
  font-size: 15px;
}

/* ── Queue banner (offline write notice) ────────────────────────────── */
.queue-banner {
  display: flex; align-items: center; gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  background: color-mix(in srgb, var(--honey) 22%, var(--cream-warm));
  border: 1px solid color-mix(in srgb, var(--honey) 45%, var(--cream-edge));
  border-radius: var(--r-2);
  font-size: 14px;
  color: var(--moss);
  margin-bottom: var(--s-3);
}
.queue-banner .queue-icon { font-size: 16px; flex: 0 0 auto; }
.queue-banner .queue-text { flex: 1 1 auto; }
.queue-banner .queue-clear {
  flex: 0 0 auto;
  background: transparent;
  border: 0;
  color: var(--moss);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: var(--r-1);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.queue-banner .queue-clear:hover { color: var(--sage-deep); background: rgba(255,255,255,.4); }

/* ── Quick capture page ─────────────────────────────────────────────── */
.capture-stage {
  margin-bottom: var(--s-4);
}
.capture-stage > input[type="file"] {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  opacity: 0;
}
.capture-button {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  width: 100%;
  min-height: 220px;
  padding: var(--s-6) var(--s-5);
  background: linear-gradient(160deg, var(--cream) 0%, var(--cream-warm) 100%);
  border: 2px dashed color-mix(in srgb, var(--sage-deep) 35%, transparent);
  border-radius: var(--r-4);
  cursor: pointer;
  color: var(--moss);
  transition: border-color .2s, background .2s, transform .15s;
}
.capture-button:hover, .capture-button:focus-within {
  border-color: var(--sage-deep);
  background: linear-gradient(160deg, var(--cream-warm) 0%, var(--cream) 100%);
}
.capture-button:active {
  transform: scale(.99);
}
.capture-button .capture-icon {
  margin-bottom: var(--s-3);
  color: var(--sage-deep);
}
.capture-button .capture-headline {
  font-family: var(--font-serif);
  font-size: 22px; font-weight: 600;
  margin-bottom: 4px;
}
.capture-button .capture-help {
  font-size: 14px;
  font-style: italic;
  font-family: var(--font-serif);
}
.capture-preview {
  position: relative;
  border-radius: var(--r-3);
  overflow: clip;
  background: var(--cream-warm);
}
.capture-preview img {
  width: 100%; max-height: 60vh; object-fit: cover; display: block;
  border-radius: var(--r-3);
}
.capture-preview .btn-link {
  display: block; margin: var(--s-3) 0 0; text-align: center;
}
.capture-skip {
  text-align: center;
  margin: var(--s-3) 0 0;
  font-size: 14px;
}
.capture-skip .btn-link {
  background: transparent; border: 0; padding: 4px 8px;
  color: var(--text-muted);
  font: inherit;
  font-size: 14px;
  font-style: italic;
  font-family: var(--font-serif);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.capture-skip .btn-link:hover { color: var(--sage-deep); }

/* ── Weather strip (dashboard) ──────────────────────────────────────── */
.weather-strip {
  display: flex; align-items: center; gap: var(--s-3);
  background: linear-gradient(135deg, #fff 0%, var(--cream-warm) 100%);
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-3) var(--s-4);
  margin-bottom: var(--s-4);
  box-shadow: var(--shadow-sm);
}
.weather-strip .weather-icon {
  flex: 0 0 44px;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--cream);
  border: 1px solid var(--cream-edge);
  color: var(--sage-deep);
  display: flex; align-items: center; justify-content: center;
}
.weather-strip .weather-icon .icon { width: 24px; height: 24px; }
.weather-strip .weather-text { flex: 1 1 auto; min-width: 0; }
.weather-strip .weather-line-1 {
  font-family: var(--font-serif);
  font-size: 19px; font-weight: 600;
  color: var(--moss);
  line-height: 1.2;
  margin-bottom: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.weather-strip .weather-line-2 {
  font-size: 13px;
  color: var(--text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.weather-invitation {
  flex-direction: column; align-items: stretch;
  gap: var(--s-3);
  background: linear-gradient(135deg, #fff 0%, var(--cream-warm) 100%);
}
.weather-invitation > div:first-child h3 { margin: 0 0 4px; font-size: 17px; }
.weather-invitation > div:first-child p { margin: 0; font-size: 14px; line-height: 1.5; }
@media (min-width: 560px) {
  .weather-invitation { flex-direction: row; align-items: center; justify-content: space-between; }
}

/* ── List card with thumbnail (beds, plants) ────────────────────────── */
.list-card {
  display: flex; align-items: center; gap: var(--s-4);
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-3);
  box-shadow: var(--shadow-sm);
  text-decoration: none; color: inherit;
  transition: transform .15s ease-out, box-shadow .15s;
  margin-bottom: var(--s-3);
}
.list-card:hover { text-decoration: none; transform: translateY(-1px); box-shadow: var(--shadow-md); }
.list-card .thumb {
  flex: 0 0 80px;
  width: 80px; height: 80px;
  border-radius: var(--r-2);
  overflow: hidden;
  background: var(--cream-warm);
  display: flex; align-items: center; justify-content: center;
  color: var(--sage);
}
.list-card .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.list-card .thumb .icon { width: 32px; height: 32px; opacity: .55; }
.list-card .body { flex: 1 1 auto; min-width: 0; }
.list-card .body h3 { margin: 0 0 4px; font-size: 17px; }
.list-card .body small { display: block; }
.list-card .chevron { color: var(--text-faint); flex: 0 0 auto; padding-right: 4px; font-size: 22px; line-height: 1; }

/* ── Hero photo on bed/plant pages ──────────────────────────────────── */
.hero-photo {
  width: 100%; aspect-ratio: 16 / 9;
  background: var(--cream-warm);
  border-radius: var(--r-3);
  overflow: hidden;
  margin-bottom: var(--s-4);
}
.hero-photo img { width: 100%; height: 100%; object-fit: cover; }

/* ── Focus visibility (a11y) ────────────────────────────────────────── */
:focus-visible { outline: 2px solid var(--sage-deep); outline-offset: 2px; border-radius: 4px; }
.btn:focus-visible { outline-offset: 3px; }

/* ── SVG icons ──────────────────────────────────────────────────────── */
.icon {
  width: 1.25em; height: 1.25em;
  display: inline-block; vertical-align: -0.2em;
  flex: 0 0 auto;
}
.icon-lg { width: 48px; height: 48px; vertical-align: middle; }
.tab-icon .icon { width: 22px; height: 22px; vertical-align: middle; }
.topbar-mark .icon { width: 22px; height: 22px; }
.empty .icon-lg { color: var(--sage); opacity: .5; margin-bottom: var(--s-3); }

/* ── Bar charts (reports) ───────────────────────────────────────────── */
.bar-row { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) 0; }
.bar-row .bar-label { flex: 0 0 auto; min-width: 0; }
.bar-row .bar-value { flex: 0 0 auto; min-width: 80px; text-align: right; color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 13px; }
.bar-track {
  flex: 1 1 auto;
  height: 8px;
  background: var(--cream-warm);
  border-radius: 4px;
  overflow: hidden;
}
.bar-fill {
  height: 100%;
  background: var(--sage-deep);
  border-radius: 4px;
  transition: width .3s ease-out;
}
.bar-fill.is-honey { background: var(--honey); }
.bar-fill.is-terracotta { background: var(--terracotta); }

/* ── Botanical divider ──────────────────────────────────────────────── */
.botanical-divider {
  display: flex; align-items: center; justify-content: center;
  gap: var(--s-3);
  margin: var(--s-6) 0;
  color: var(--sage);
  opacity: .35;
}
.botanical-divider::before, .botanical-divider::after {
  content: ""; flex: 1; height: 1px; background: currentColor;
}
.botanical-divider .icon { width: 18px; height: 18px; }

/* ── Reduced motion ─────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* ── Utilities ───────────────────────────────────────────────────────── */
.center { text-align: center; }
.spaced { margin-bottom: var(--s-5); }
.divider { height: 1px; background: var(--cream-edge); margin: var(--s-5) 0; }
.kbd-list { list-style: none; padding: 0; margin: 0; }
.kbd-list li { padding: var(--s-3) 0; border-bottom: 1px solid var(--cream-edge); }
.kbd-list li:last-child { border-bottom: 0; }

/* breakpoint just for nicer reading on tablets+ */
@media (min-width: 720px) {
  h1 { font-size: 32px; }
  .page { padding: var(--s-6) var(--s-5); }
}

/* ── Welcome wizard ─────────────────────────────────────────────────── */
/* Shown once after first email verification, between signup and dashboard.
   Mirrors the auth shell so it feels like part of the same first journey. */
body.welcome-page { background: var(--cream-warm); }
body.welcome-page .topbar { background: transparent; border-bottom: 0; }
body.welcome-page .bottom-nav { display: none; } /* keep the wizard focused */
body.welcome-page .page { padding-bottom: var(--s-5); }
.welcome-shell {
  min-height: calc(100vh - 64px);
  padding: var(--s-5) var(--s-4);
  display: flex; align-items: flex-start; justify-content: center;
  background: var(--cream);
}
.welcome-card {
  width: 100%;
  max-width: 540px;
  background: #fff;
  border: 1px solid var(--cream-edge);
  border-radius: var(--r-3);
  padding: var(--s-6) var(--s-5) var(--s-5);
  margin-top: var(--s-4);
  box-shadow: 0 1px 0 rgba(0,0,0,0.02), 0 8px 24px rgba(60, 80, 50, 0.06);
}
.welcome-head {
  text-align: center;
  margin-bottom: var(--s-5);
}
.welcome-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--sage-soft) 40%, transparent);
  color: var(--sage-deep);
  margin-bottom: var(--s-3);
}
.welcome-mark .icon { width: 26px; height: 26px; }

/* ── Two-tone brand mark (brand_color() helper) ─────────────────────── */
/* The colorful leaf+bee SVG uses fixed colors and is sized via inline
   width/height attributes. These rules override the catch-all svg sizing
   rules in invitation-mark / invitation-divider so the bee stays legible. */
.brand-color { display: inline-block; vertical-align: middle; }
.topbar-mark .brand-color        { width: 26px; height: 26px; }
.invitation-mark .brand-color    { width: 30px; height: 30px; }
.invitation-divider .brand-color { width: 36px; height: 36px; margin: 0 14px; flex: 0 0 auto; }
.welcome-mark .brand-color       { width: 32px; height: 32px; }
.welcome-eyebrow {
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
  color: var(--sage-deep);
  letter-spacing: 0.02em;
  margin: 0 0 var(--s-2);
  font-size: 14px;
}
.welcome-head h1 {
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 500;
  letter-spacing: -0.01em;
  margin: 0 0 var(--s-2);
}
.welcome-form .welcome-step {
  border: none;
  padding: 0;
  margin: 0 0 var(--s-5);
}
.welcome-form .welcome-step + .welcome-step {
  border-top: 1px solid var(--cream-edge);
  padding-top: var(--s-5);
}
.welcome-form legend {
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
  color: var(--sage-deep);
  font-size: 14px;
  letter-spacing: 0.02em;
  margin-bottom: var(--s-3);
  padding: 0;
}
.welcome-form .label-as-legend {
  display: block;
  font-weight: 500;
  margin-bottom: var(--s-2);
  font-size: 14px;
}
.welcome-form .help {
  font-size: 12.5px;
  color: var(--ink-soft, #7a7367);
  margin-top: 6px;
}
.welcome-form .opt {
  font-weight: normal;
  color: var(--ink-soft, #7a7367);
  font-size: 12.5px;
}

/* Pill-style radio rows used in the wizard ─────────────────────────── */
.pill-row {
  display: flex; gap: 8px;
  flex-wrap: nowrap;
}
.pill-row-wrap { flex-wrap: wrap; }
.pill {
  flex: 1 1 auto;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 12px 14px;
  border: 1.5px solid var(--cream-edge);
  border-radius: 999px;
  background: #fff;
  cursor: pointer;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
  font-size: 14px;
  text-align: center;
  user-select: none;
  min-width: 0;
}
.pill input[type="radio"] {
  position: absolute;
  opacity: 0; pointer-events: none;
}
.pill:hover { border-color: var(--sage-soft); }
.pill-active,
.pill:has(input:checked) {
  border-color: var(--sage-deep);
  background: color-mix(in srgb, var(--sage-soft) 30%, transparent);
  color: var(--sage-deep);
  font-weight: 500;
}
.pill-row-wrap .pill { flex: 0 1 auto; padding: 10px 16px; }

.welcome-actions {
  margin-top: var(--s-5);
  display: flex; flex-direction: column; align-items: center;
  gap: var(--s-3);
}
.welcome-skip {
  background: none;
  border: none;
  color: var(--sage);
  text-decoration: underline;
  text-underline-offset: 3px;
  font-size: 14px;
  font-family: var(--font-serif, Georgia, serif);
  font-style: italic;
  cursor: pointer;
  padding: 6px;
}
.welcome-skip:hover { color: var(--sage-deep); }

/* ── Garden geek details panel ──────────────────────────────────────── */
/* Sits inside plant.php as a <details> element so it's collapsed by
   default — keeps the calm read for users who don't want the data. */
.geek-panel { padding: 0; }
.geek-panel summary {
  list-style: none;
  cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4) var(--s-4);
  font-weight: 500;
  user-select: none;
}
.geek-panel summary::-webkit-details-marker { display: none; }
.geek-summary-text {
  display: inline-flex; align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.geek-summary-toggle {
  color: var(--sage);
  transition: transform .2s ease;
  font-size: 18px;
  line-height: 1;
}
.geek-panel[open] .geek-summary-toggle { transform: rotate(180deg); }
.geek-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 10px 16px;
  margin: 0;
  padding: 0 var(--s-4) var(--s-3);
  font-size: 14.5px;
}
.geek-grid dt {
  color: var(--ink-soft, #7a7367);
  font-size: 13px;
  letter-spacing: 0.01em;
}
.geek-grid dd {
  margin: 0;
  color: var(--ink, #2c2a25);
}
.geek-foot {
  padding: 0 var(--s-4) var(--s-4);
  margin: 0;
  font-size: 12.5px;
}
.geek-tip {
  margin: 0 var(--s-4) var(--s-3);
  padding: 12px 14px;
  background: color-mix(in srgb, var(--honey) 14%, transparent);
  border-left: 3px solid var(--honey);
  border-radius: 6px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink, #2c2a25);
}
.geek-tip-label {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--honey);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  vertical-align: middle;
}
.geek-panel[data-empty] summary { font-weight: normal; }

/* Zone badges inside the geek panel summary ───────────────────────── */
.zone-pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
  border: 1px solid currentColor;
}
.zone-pill-match {
  color: var(--sage-deep);
  background: color-mix(in srgb, var(--sage-soft) 35%, transparent);
}
.zone-pill-stretch {
  color: var(--honey);
  background: color-mix(in srgb, var(--honey) 18%, transparent);
}

/* ════════════════════════════════════════════════════════════════════
   DESKTOP LAYOUT
   ──────────────────────────────────────────────────────────────────
   Mobile-first remains the source of truth (everything above this
   block is the unmodified mobile UX). The breakpoints below layer on
   desktop affordances at 720px and 1024px without changing any of the
   mobile-default rules.

   Two breakpoints:
     720px+ — tablets and small laptops; widen the page, swap bottom
              nav for a top nav, list pages become 2-column.
     1024px+ — full desktop; widen further, list pages become 3-column,
               garden canvas gets more px-per-foot.
   ════════════════════════════════════════════════════════════════════ */

/* Top navigation links — present in markup but hidden on mobile (the
   bottom-nav handles primary nav there). Shown at 720px+ as a horizontal
   row inside the topbar. */
.topbar-nav { display: none; }

/* ── 720px+ ────────────────────────────────────────────────────────── */
@media (min-width: 720px) {
  /* Wider page */
  .page {
    max-width: 880px;
    padding-block: var(--s-6);
  }

  /* Bottom nav becomes top nav */
  body { padding-bottom: 0; }
  .bottom-nav { display: none; }

  .topbar { padding: 0 var(--s-5); height: 64px; }
  .topbar-name { font-size: 19px; }

  .topbar-nav {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
    margin-right: var(--s-4);
  }
  .topbar-nav a {
    display: inline-flex; align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 999px;
    color: var(--text-muted);
    font-size: 14px;
    font-weight: 500;
    transition: background 0.15s ease, color 0.15s ease;
  }
  .topbar-nav a:hover { background: var(--cream-warm); color: var(--sage-deep); text-decoration: none; }
  .topbar-nav a.is-active {
    background: color-mix(in srgb, var(--sage-soft) 30%, transparent);
    color: var(--sage-deep);
    font-weight: 600;
  }
  .topbar-nav .icon { width: 18px; height: 18px; }

  /* Sheet dialogs (Quick action / More) sit above bottom-nav on mobile;
     on desktop they live without that offset. */
  #quick-action-sheet, #more-sheet { padding-bottom: var(--s-4); }
  .sheet { padding-bottom: var(--s-4); }

  /* Multi-column lists for beds + plants */
  .list-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-4);
  }
  /* Single-column list pages keep their existing layout — the .list-grid
     wrapper is only applied where we want columns. */

  /* Larger garden canvas */
  .garden-canvas-wrap { max-height: 78vh; }
  .garden-canvas { --garden-px-per-ft: 28px; }

  /* Forms can use horizontal pairs — this is opt-in via .field-row */
  .field-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-4);
  }

  /* Headings get a touch more breathing room */
  h1 { font-size: 32px; }
  h2 { font-size: 26px; }
}

/* ── 1024px+ ───────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  .page { max-width: 1200px; }

  /* 3-column list grids on full desktop */
  .list-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* Garden canvas: more px per foot for crisp tiles */
  .garden-canvas { --garden-px-per-ft: 32px; }
  .garden-canvas-wrap { max-height: 82vh; }
}

/* ── 1280px+ ───────────────────────────────────────────────────────── */
@media (min-width: 1280px) {
  /* Garden editor gets a little extra room when the screen has it */
  .page { max-width: 1280px; }
}
