/* ============================================================
   HOUSEPLANT HAVEN

   Design tokens lifted from Katie's live Square Online theme
   (preset "friendly-earthy-deep-green"):

     primary        #274b3a    secondary set  #f3f2ef  #141c0e
     badge gold     #d2c159                   #598384  #73806e
     badge green    #255b42                   #797142  #ffffff
     type           Recoleta 600 / Larsseit 400-700
     scale          18px base, 1.25 modular
     radii          card 8  ·  image 16  ·  button 32
     spacing        wide site width, 32px margins

   Recoleta and Larsseit are licensed retail fonts, so the web build
   substitutes the closest free equivalents - Fraunces for the soft
   slab serif, Figtree for the geometric body - and names the
   originals first so any machine that has them installed uses them.
   ============================================================ */

:root {
  /* --- colour ---

     Dark, at Katie's request: "easier on the eyes". The grounds are her own
     brand-kit charcoal (#323a3b) taken down a few steps and warmed towards
     green, so this is not a new palette — it is the half of her kit the
     light theme never used. Cream (#eeebea) and gold (#d2c159) come
     straight off the kit and do the work that ink and forest used to.

     Every colour on the site comes from this block — including the sticky
     header's translucent ground and the rgb the shadows are mixed from,
     which are tokens here for exactly that reason. Swapping the palette
     back to light is a change to these values and nothing else.

     The shapes are a separate question: the circles and the shorter hero
     are structural and live with their components. */

  --paper:      #191f1e;   /* site ground */
  --paper-2:    #212827;   /* alternating band */
  --surface:    #29302e;   /* cards, panels, anything raised */
  --white:      #ffffff;   /* literal white: text on a colour fill */

  /* Interactive green, lifted until it reads on a dark ground — #274b3a
     is invisible down here. Text on top of it goes dark, not white. */
  --forest:     #8fb08a;   /* brand primary */
  --forest-2:   #6f9d7f;   /* badge green */
  --deep:       #1f2e26;   /* feature bands — the old forest, kept deep */
  --on-primary: #141a13;   /* text on a --forest fill */
  --night:      #0f1412;   /* footer / deepest ground */
  --on-night:   #eeebea;   /* text on --night */

  --sage:       #93a48c;
  --teal:       #7aa3a4;
  --olive:      #b9ae63;
  --gold:       #d2c159;
  --terracotta: #dd8551;   /* brand kit, lifted; form errors */

  --ink:        #eeebea;   /* headings */
  --body:       #c3cabf;   /* paragraphs */
  --muted:      #8e9689;
  --line:       #3a423f;
  --line-soft:  #2e3634;
  --header-bg:  rgba(25, 31, 30, 0.92);   /* sticky header, translucent */
  --shadow-ink: 0, 0, 0;                  /* rgb the shadows are built from */

  /* --- type --- */
  --font-display: "Recoleta", "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:    "Larsseit", "Figtree", -apple-system, "Segoe UI", sans-serif;

  /* 18px base on a 1.25 modular scale, fluid from phone to laptop */
  --step--1: clamp(0.86rem, 0.83rem + 0.15vw, 0.94rem);
  --step-0:  clamp(1rem,    0.96rem + 0.2vw,  1.125rem);
  --step-1:  clamp(1.15rem, 1.08rem + 0.34vw, 1.4rem);
  --step-2:  clamp(1.35rem, 1.2rem  + 0.7vw,  1.75rem);
  --step-3:  clamp(1.6rem,  1.32rem + 1.3vw,  2.2rem);
  --step-4:  clamp(1.95rem, 1.45rem + 2.3vw,  3rem);
  --step-5:  clamp(2.35rem, 1.5rem  + 3.9vw,  4.2rem);
  --step-6:  clamp(2.4rem,  1.35rem + 5.6vw,  5.6rem);

  /* --- shape --- */
  --r-card: 8px;
  --r-img:  16px;
  --r-btn:  32px;

  /* --- space --- */
  --gutter:   clamp(20px, 4.5vw, 56px);
  --wrap:     1320px;
  --wrap-mid: 1060px;
  --section:  clamp(64px, 8.5vw, 132px);
  --shadow:      0 1px 2px rgba(var(--shadow-ink), 0.30), 0 12px 32px rgba(var(--shadow-ink), 0.34);
  --shadow-lift: 0 2px 4px rgba(var(--shadow-ink), 0.34), 0 22px 48px rgba(var(--shadow-ink), 0.48);
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  background: var(--paper);
  color: var(--body);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { max-width: 100%; display: block; }
::selection { background: var(--gold); color: var(--night); }

a { color: var(--forest); text-decoration: none; }
a:hover { color: var(--olive); }

:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; border-radius: 4px; }

.wrap     { width: 100%; max-width: var(--wrap);     margin-inline: auto; padding-inline: var(--gutter); }
.wrap-mid { width: 100%; max-width: var(--wrap-mid); margin-inline: auto; padding-inline: var(--gutter); }

section { padding-block: var(--section); position: relative; }

.band       { background: var(--paper-2); }
.band-white { background: var(--surface); }
/* A feature band goes deeper than the page, not brighter: --forest is
   the lifted interactive green now and would glare here. */
.band-forest { background: var(--deep); color: rgba(255, 255, 255, 0.84); }
.band-forest h2, .band-forest h3, .band-forest .section-title { color: var(--white); }
.band-forest .kicker { color: var(--gold); }
.band-forest .lede { color: rgba(255, 255, 255, 0.84); }
.band-forest a { color: var(--gold); }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 300;
  background: var(--forest); color: var(--on-primary);
  padding: 14px 22px; border-radius: 0 0 var(--r-card) 0;
}
.skip-link:focus { left: 0; color: var(--white); }

/* ---------- type ---------- */

h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 600;
  color: var(--ink);
  line-height: 1.1;
  letter-spacing: -0.015em;
  /* Fraunces defaults to a high-contrast display cut at large sizes. Pinning
     a low optical size and a high SOFT axis gives the rounded, low-contrast
     shapes Recoleta has. */
  font-optical-sizing: none;
  font-variation-settings: "opsz" 16, "SOFT" 80, "WONK" 1;
}

.section-head { max-width: 62ch; }
.section-head.center { margin-inline: auto; text-align: center; }

.kicker {
  display: inline-block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--step--1);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--forest);
  margin-bottom: 18px;
}

.section-title { font-size: var(--step-4); margin-bottom: 18px; }
.section-title .accent { color: var(--forest); font-style: italic; }

.lede { font-size: var(--step-1); color: var(--body); max-width: 58ch; line-height: 1.5; }

.prose > * + * { margin-top: 1.05em; }
.prose p { max-width: 68ch; }
.prose strong { color: var(--ink); font-weight: 700; }
.prose .callout { color: var(--forest); font-weight: 700; }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 1rem;               /* Square: button text = Larsseit 700 / 16px */
  line-height: 1;
  color: var(--on-primary);
  background: var(--forest);
  border: 2px solid var(--forest);
  border-radius: var(--r-btn);
  padding: 17px 34px;
  cursor: pointer;
  text-align: center;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease,
              transform 0.18s ease, box-shadow 0.18s ease;
}
.btn:hover { background: var(--night); border-color: var(--night); color: var(--on-night); transform: translateY(-2px); box-shadow: var(--shadow-lift); }

.btn.outline { background: transparent; color: var(--forest); }
.btn.outline:hover { background: var(--forest); color: var(--on-primary); }

/* This one lives on top of a photograph, so it is deliberately NOT a
   theme surface — it stays a bright pill in either palette. */
.btn.light { background: var(--ink); border-color: var(--ink); color: var(--night); }
.btn.light:hover { background: var(--gold); border-color: var(--gold); color: var(--night); }

.btn.ghost-photo { background: transparent; border-color: rgba(255, 255, 255, 0.72); color: var(--white); }
.btn.ghost-photo:hover { background: rgba(255, 255, 255, 0.16); border-color: var(--white); color: var(--white); }

.btn.sm { padding: 12px 22px; font-size: 0.92rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 32px; }

/* ---------- announcement bar ---------- */

.announce {
  background: var(--deep);
  color: rgba(255, 255, 255, 0.9);
  font-size: var(--step--1);
  letter-spacing: 0.03em;
  text-align: center;
  padding: 11px var(--gutter);
}
.announce strong { color: var(--gold); font-weight: 700; }

/* ---------- header ---------- */

.site-header {
  position: sticky; top: 0; z-index: 120;
  background: var(--header-bg);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line-soft);
}

.header-inner {
  max-width: var(--wrap); margin-inline: auto;
  padding: 14px var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}

.brand { display: flex; align-items: center; gap: 14px; color: var(--ink); }
/* The logo PNGs are pre-cropped to the edge of the circle, so the box size
   here is the size the mark actually renders at — no cover/round needed. */
.brand img { width: 64px; height: 64px; }
.brand span {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.3rem; letter-spacing: -0.01em; line-height: 1.05;
}

.nav { display: flex; align-items: center; gap: clamp(18px, 2.4vw, 36px); }
.nav a:not(.btn) {
  font-weight: 500; font-size: 1rem; color: var(--body);
  padding-block: 6px; position: relative;
}
.nav a:not(.btn)::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--forest);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.22s ease;
}
.nav a:not(.btn):hover { color: var(--forest); }
.nav a:not(.btn):hover::after { transform: scaleX(1); }

.nav-toggle {
  display: none;
  width: 46px; height: 46px;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--line);
  border-radius: var(--r-btn); cursor: pointer;
  position: relative; z-index: 140;
}
.nav-toggle span,
.nav-toggle span::before,
.nav-toggle span::after {
  content: ""; display: block; width: 20px; height: 2px;
  background: var(--ink); border-radius: 2px;
  transition: transform 0.24s ease, opacity 0.18s ease;
}
.nav-toggle span::before { transform: translateY(-6px); }
.nav-toggle span::after  { transform: translateY(4px); }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after  { transform: rotate(-45deg) translateY(-1px); }

/* ---------- hero ---------- */

.hero {
  position: relative;
  /* Was min(78vh, 720px) — a full screen of photograph before a word of
     hers was visible. Katie asked for smaller imagery and a calmer page. */
  min-height: min(56vh, 520px);
  display: grid; align-items: end;
  padding: clamp(64px, 9vh, 110px) 0 clamp(40px, 5vh, 60px);
  isolation: isolate;
  color: var(--white);
}
.hero::before {
  content: ""; position: absolute; inset: 0; z-index: -2;
  background-color: var(--sage);
  background-size: cover; background-position: center 60%;
}
/* Hero art lives here rather than in an inline custom property: a url()
   carried through a var() is resolved against this stylesheet, not the
   page, so an inline --hero-img would look for css/images/... */
.hero--home::before { background-image: url("../images/hero.jpg"); }
/* inventory.jpg carries baked-in caption text that collides with the
   headline, so the shop banner reuses the room shot on a tighter crop */
.hero--shop::before { background-image: url("../images/hero.jpg"); background-position: center 42%; }
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(100deg,
    rgba(20, 28, 14, 0.76) 0%,
    rgba(20, 28, 14, 0.54) 44%,
    rgba(20, 28, 14, 0.18) 100%);
}
/* The mark over the hero photo: the site's loudest piece of branding. It
   sits above the kicker and scales with the headline. */
.hero-mark {
  display: block;
  width: clamp(74px, 7.5vw, 104px); height: auto;
  margin-bottom: clamp(18px, 2.4vw, 30px);
  filter: drop-shadow(0 6px 20px rgba(20, 28, 14, 0.45));
}
.hero .kicker { color: var(--gold); }
.hero h1 {
  color: var(--white);
  font-size: var(--step-5);
  line-height: 1.05;
  max-width: 16ch;
}
.hero p {
  margin-top: 22px; max-width: 46ch;
  font-size: var(--step-1); color: rgba(255, 255, 255, 0.92);
}

.hero-slim { min-height: 0; padding: clamp(76px, 11vw, 130px) 0 clamp(56px, 8vw, 96px); }
.hero-slim h1 { font-size: var(--step-5); max-width: 20ch; }

/* ---------- promise strip ---------- */

.promises {
  display: grid; gap: clamp(24px, 4vw, 56px);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.promise .ico { width: 40px; height: 40px; margin-bottom: 16px; color: var(--forest); }
.promise h3 { font-size: var(--step-1); margin-bottom: 8px; }
.promise p { font-size: var(--step--1); line-height: 1.6; max-width: 34ch; }

/* ---------- category tiles ---------- */

.cat-grid {
  display: grid; gap: clamp(20px, 3vw, 40px);
  grid-template-columns: repeat(3, 1fr);   /* six tiles read best as 3 + 3 */
  margin-top: 44px;
}
/* Her four departments: 4 across on a laptop, 2 + 2 on a tablet. */
.cat-grid--four { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) {
  .cat-grid--four { grid-template-columns: repeat(2, 1fr); }
}
/* Katie's four departments, as circles rather than photo tiles. Her note:
   she likes circles on product pages, and "mixing up the norm" — and a
   circle is also the honest shape for these, because the photo is a token
   for the department, not a picture of a thing you can buy. Smaller, too,
   at her request: the old 4/5 tiles ate most of a laptop screen. */
.cat-tile {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; color: var(--body);
}
.cat-tile img {
  width: 100%; max-width: 190px; aspect-ratio: 1 / 1;
  border-radius: 50%; object-fit: cover;
  background: var(--surface);
  /* The ring does the work the old drop shadow did — on a dark ground a
     shadow under a circle is invisible. */
  box-shadow: 0 0 0 1px var(--line), 0 0 0 7px var(--paper-2);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.cat-tile:hover img {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px var(--forest), 0 0 0 7px var(--paper-2);
}
.cat-label { margin-top: 20px; }
.cat-label b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-1); line-height: 1.15; letter-spacing: -0.01em;
  color: var(--ink);
}
.cat-tile:hover .cat-label b { color: var(--forest); }
.cat-label small { display: block; margin-top: 5px; font-size: var(--step--1); color: var(--muted); }

/* ---------- split layouts ---------- */

.split {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(32px, 5.5vw, 88px);
  align-items: start;
}
.split.reverse { grid-template-columns: 0.85fr 1.15fr; }
.split.even { grid-template-columns: 1fr 1fr; align-items: center; }

/* Katie's family collage (16 Sept 2026). It is NOT a split column: at the
   ~420px a column allows, the caption on each tile was unreadable, and the
   whole point of the thing is that you can read them. Full width, centred,
   with the paragraph above it rather than beside it.

   No border-radius and no box-shadow, unlike .figure and .neon-banner. The
   image has transparent gaps between its tiles, so both would draw a
   rounded box around a shape that is not a box. */
.collage {
  width: 100%; max-width: 900px; height: auto;
  display: block; margin-inline: auto;
  margin-top: clamp(26px, 3.4vw, 42px);
}
.clan-lede { max-width: 64ch; margin-inline: auto; text-align: center; }

.card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: clamp(26px, 3.4vw, 40px);
  box-shadow: var(--shadow);
}
.card h3 { font-size: var(--step-2); margin-bottom: 20px; }

.hours-table { width: 100%; border-collapse: collapse; }
.hours-table td { padding: 12px 0; border-bottom: 1px solid var(--line-soft); font-size: var(--step--1); }
.hours-table tr:last-child td { border-bottom: 0; }
.hours-table td:last-child { text-align: right; font-weight: 600; color: var(--ink); }
.hours-table tr.open td:first-child { color: var(--forest); font-weight: 700; }
.hours-table tr.open td:last-child { color: var(--forest); }
.hours-note { margin-top: 20px; font-size: var(--step--1); color: var(--muted); line-height: 1.55; }

.figure { border-radius: var(--r-img); overflow: hidden; box-shadow: var(--shadow); }
.figure img { width: 100%; height: 100%; object-fit: cover; }
.figure.tall { aspect-ratio: 4 / 5; }
/* Capped so a portrait photo can't set the height of a whole section. */
.split .figure { max-width: 420px; margin-inline: auto; }

/* ---------- benefits ---------- */

.benefits {
  display: grid; gap: clamp(14px, 1.6vw, 20px);
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  margin-top: 52px;
}
.benefit {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: 30px 26px;
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}
.benefit:hover { transform: translateY(-4px); border-color: var(--sage); box-shadow: var(--shadow); }
.benefit .num {
  display: block; margin-bottom: 10px;
  font-family: var(--font-display); font-weight: 600;
  color: var(--gold); font-size: var(--step-2);
}
.benefit strong { display: block; color: var(--ink); font-size: var(--step-0); margin-bottom: 6px; }
.benefit p { font-size: var(--step--1); line-height: 1.6; }

/* ---------- green index (plant care) ---------- */

.plant-list { margin-top: 48px; }

.plant-row {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  margin-bottom: 12px;
  overflow: hidden;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.plant-row[open] { border-color: var(--sage); box-shadow: var(--shadow); }

.plant-row summary {
  list-style: none; cursor: pointer;
  display: grid;
  grid-template-columns: auto 1.1fr 1fr auto;
  gap: clamp(14px, 2vw, 32px);
  align-items: center;
  padding: clamp(20px, 2.4vw, 28px) clamp(20px, 2.6vw, 32px);
}
.plant-row summary::-webkit-details-marker { display: none; }
.plant-row summary:hover { background: var(--paper-2); }

.plant-row .pthumb {
  width: clamp(62px, 6.4vw, 88px);
  aspect-ratio: 1;
  border-radius: var(--r-card);
  overflow: hidden;
  background: var(--paper-2);
  border: 1px solid var(--line-soft);
}
.plant-row .pthumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform 0.5s ease;
}
.plant-row summary:hover .pthumb img { transform: scale(1.06); }

.plant-row .pname {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-2); color: var(--ink); line-height: 1.15;
}
.plant-row .pname small {
  display: block; margin-top: 4px;
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--step--1); color: var(--muted);
}
.plant-row .ptag { color: var(--olive); font-style: italic; font-size: var(--step-0); }

.plant-row .chev {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%; background: var(--paper-2); color: var(--forest);
  font-size: 1.2rem; line-height: 1;
  transition: transform 0.26s ease, background 0.2s ease, color 0.2s ease;
}
.plant-row[open] .chev { transform: rotate(45deg); background: var(--forest); color: var(--on-primary); }

.plant-detail {
  padding: 4px clamp(20px, 2.6vw, 32px) clamp(24px, 3vw, 34px);
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 0 clamp(24px, 4vw, 56px);
}
.plant-detail .love {
  grid-column: 1 / -1;
  border-left: 3px solid var(--gold);
  padding-left: 18px;
  margin-bottom: 24px;
  color: var(--ink);
  font-size: var(--step-0);
}
.plant-detail dt {
  font-weight: 700; font-size: 0.75rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--forest); margin-bottom: 5px;
}
.plant-detail dd { font-size: var(--step--1); line-height: 1.6; margin-bottom: 18px; }

.care-source {
  grid-column: 1 / -1;
  margin-top: 6px; font-size: 0.8rem; color: var(--muted);
}

/* ---------- story ---------- */

.photo-frame { position: relative; }
.photo-frame img { border-radius: var(--r-img); box-shadow: var(--shadow-lift); }

/* The neon sign is a 4:1 strip, never cropped. Capped rather than full
   width — at 1300px it was the biggest thing on the page. */
.neon-banner {
  width: 100%; max-width: 840px; height: auto;
  display: block; margin-inline: auto;
  border-radius: var(--r-img);
  box-shadow: var(--shadow);
  margin-top: clamp(40px, 5vw, 64px);
}

.pull-quote {
  max-width: 24ch;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-3); line-height: 1.18; color: var(--white);
  letter-spacing: -0.015em;
}

.club-collage { display: grid; gap: clamp(16px, 2vw, 24px); }
.club-mosaic {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(10px, 1.4vw, 16px);
  padding-bottom: 18px;
}
.club-mosaic img {
  width: 100%; aspect-ratio: 1; object-fit: cover; display: block;
  border-radius: var(--r-img);
}
.club-mosaic img:nth-child(even) { transform: translateY(18px); }
.club-collage .pull-quote { max-width: none; font-size: var(--step-1); line-height: 1.4; }

/* ---------- contact form ---------- */

.contact-grid {
  display: grid; grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(32px, 5vw, 80px); align-items: start;
}

.field { margin-bottom: 18px; }
.field label { display: block; font-weight: 700; font-size: var(--step--1); color: var(--ink); margin-bottom: 7px; }
.field input, .field textarea {
  width: 100%;
  font-family: var(--font-body); font-size: var(--step-0); color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 14px 16px;
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus, .field textarea:focus {
  border-color: var(--forest); outline: none;
  box-shadow: 0 0 0 3px rgba(39, 75, 58, 0.12);
}

.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }

.chip-row { display: flex; flex-wrap: wrap; gap: 10px; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: inline-block; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 10px 20px; font-size: var(--step--1); font-weight: 500;
  background: var(--surface); color: var(--body);
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.chip:hover span { border-color: var(--sage); }
.chip input:checked + span { background: var(--forest); border-color: var(--forest); color: var(--on-primary); font-weight: 700; }
.chip input:focus-visible + span { outline: 3px solid var(--teal); outline-offset: 3px; }

/* ---------- shop ---------- */

.filter-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 36px; }
.filter-btn {
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 500;
  background: var(--surface); color: var(--body);
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 10px 20px; cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.filter-btn:hover { border-color: var(--sage); }
.filter-btn[aria-pressed="true"] { background: var(--forest); border-color: var(--forest); color: var(--on-primary); font-weight: 700; }

/* Second tier: the categories inside the chosen group. Deliberately quieter
   than the group row above it, so the four departments stay the primary
   choice and this reads as narrowing rather than a competing menu. */
.filter-bar--sub { margin-top: 14px; gap: 8px; }
.filter-bar--sub .filter-btn {
  background: transparent;
  border-color: transparent;
  color: var(--body);
  padding: 7px 14px;
  font-size: 0.84rem;
}
.filter-bar--sub .filter-btn:hover { border-color: var(--line); }
.filter-bar--sub .filter-btn[aria-pressed="true"] {
  background: var(--surface);
  border-color: var(--line);
  color: var(--forest);
}

.inv-meta { margin-top: 22px; font-size: var(--step--1); color: var(--muted); }

.inv-grid {
  display: grid; gap: clamp(18px, 2.2vw, 30px);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  margin-top: 26px;
}

/* Full-width rule between the in-stock run and the sold-out run. */
.inv-seam {
  grid-column: 1 / -1;
  margin: clamp(14px, 2vw, 26px) 0 2px;
  padding-top: clamp(20px, 2.4vw, 32px);
  border-top: 1px solid var(--line);
}
.inv-seam h3 {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-1); color: var(--ink); letter-spacing: -0.01em;
}
.inv-seam p {
  margin-top: 6px; max-width: 52ch;
  font-size: var(--step--1); color: var(--muted); line-height: 1.55;
}

.inv-card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}
.inv-card:hover { transform: translateY(-5px); border-color: var(--sage); box-shadow: var(--shadow-lift); }

.inv-media { position: relative; background: var(--paper-2); }
.inv-art { aspect-ratio: 1 / 1; width: 100%; object-fit: cover; }

.badge {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 7px 14px; border-radius: var(--r-btn);
  background: var(--gold); color: var(--night);
}
.badge.green { background: var(--forest-2); color: var(--on-primary); border-radius: 6px; }
.badge.last  { background: var(--olive); color: var(--white); }
.badge.sold  { background: var(--night); color: var(--white); }

.inv-body { padding: 22px 22px 24px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.inv-name { font-size: var(--step-1); line-height: 1.2; }
.inv-tag { font-size: var(--step--1); color: var(--muted); flex: 1; line-height: 1.55; }
.inv-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; }
.inv-price { font-family: var(--font-display); font-weight: 600; font-size: var(--step-2); color: var(--ink); }

.inv-empty { grid-column: 1 / -1; padding: 56px 0; text-align: center; color: var(--muted); }

.inv-media { cursor: pointer; }
.inv-care {
  align-self: start;
  background: none; border: 0; padding: 0;
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 700;
  color: var(--forest); cursor: pointer;
  border-bottom: 1px solid var(--sage);
}
.inv-care:hover { color: var(--forest-2); border-bottom-color: var(--forest-2); }
/* Escaped, not a literal glyph: this rule held an emoji that had been
   mangled into a control character plus "92", and shipped that way. */
.inv-care::after { content: " \2192"; }

/* genus-level care advice, flagged as such rather than passed off as this
   plant's own write-up */
.care-scope {
  font-size: var(--step--1); font-weight: 700;
  color: var(--olive); margin-top: 6px;
}

/* freshness line under the item count. Silent-failure insurance: if Square
   can't be reached the shop still renders from a saved copy, and without
   this nobody would know the shelves on screen were stale. */
.inv-freshness {
  font-size: var(--step--1);
  color: var(--muted);
  margin-top: 6px;
}
.inv-freshness.stale {
  color: var(--olive);
  font-weight: 700;
  background: #fbf6e3;
  border-left: 4px solid var(--gold);
  border-radius: 0 8px 8px 0;
  padding: 10px 14px;
  margin-top: 12px;
  max-width: 62ch;
}

/* ---------- plant care detail ---------- */

.care-dialog {
  /* the global reset zeroes margins, which is what a native <dialog>
     uses to centre itself - put it back explicitly */
  margin: auto;
  width: min(880px, calc(100vw - 32px));
  max-height: min(88vh, 780px);
  padding: 0; border: 0;
  border-radius: var(--r-img);
  background: var(--surface);
  color: var(--body);
  box-shadow: 0 30px 80px rgba(20, 28, 14, 0.4);
  overflow: hidden;
}
.care-dialog::backdrop { background: rgba(20, 28, 14, 0.62); }

.care-close {
  position: absolute; top: 12px; right: 14px; z-index: 2;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, 0.9); color: var(--ink);
  font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.care-close:hover { background: var(--paper-2); }

.care-inner {
  display: grid; grid-template-columns: 0.85fr 1fr;
  max-height: min(88vh, 780px);
}
.care-figure { background: var(--paper-2); }
.care-figure img { width: 100%; height: 100%; object-fit: cover; display: block; }

.care-body {
  padding: clamp(26px, 3vw, 40px);
  overflow-y: auto;
}
.care-name {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-3); line-height: 1.12; color: var(--ink);
  letter-spacing: -0.015em;
}
.care-common {
  font-size: var(--step--1); color: var(--muted);
  margin-top: 4px;
}
.care-love {
  border-left: 3px solid var(--gold);
  padding-left: 18px;
  margin: 22px 0 26px;
  color: var(--ink); font-size: var(--step-0); line-height: 1.5;
}
.care-notes dt {
  font-weight: 700; font-size: 0.75rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--forest); margin-bottom: 5px;
}
.care-notes dd { font-size: var(--step--1); line-height: 1.6; margin-bottom: 18px; }
/* Katie writes her care sections as short one-point lines, so they render
   as a list rather than a run-on paragraph. */
.care-lines { list-style: none; }
.care-lines li { margin-bottom: 3px; }
.care-lines li:last-child { margin-bottom: 0; }

.care-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-top: 8px;
  padding-top: 20px; border-top: 1px solid var(--line-soft);
}

/* Sold out, but askable. Sits between the care notes and the footer so the
   offer reads before the price does. */
.care-ask {
  margin: 22px 0 14px;
  padding: 16px 18px;
  background: var(--paper-2);
  border-radius: 8px;
  font-size: var(--step--1); line-height: 1.55; color: var(--ink);
}
.care-ask-row {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-bottom: 4px;
}
.care-ask-row .btn { text-decoration: none; }

@media (max-width: 720px) {
  .care-inner { grid-template-columns: 1fr; }
  .care-figure { max-height: 34vh; }
}

/* ---------- the second photo, on hover ----------

   Ed's Plant Shop cross-fades a card to its second photo when the mouse
   is over it. Both images are laid on top of each other so nothing
   reflows, and the effect only exists on cards that got the extra <img> -
   i.e. only where Katie has actually uploaded a second photo in Square. */

.inv-media.has-hover .inv-art--hover {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.inv-card:hover .inv-art--hover,
.inv-card:focus-within .inv-art--hover { opacity: 1; }

/* Old Yew captions each card with one trait, above the name. */
.inv-caption {
  font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--teal);
}

/* ---------- save for later ---------- */

.inv-save {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  color: var(--sage);
  cursor: pointer;
  /* Most of her photos are shot on white, where a white disc is invisible.
     The ring is what keeps the heart findable on any of them. */
  box-shadow: 0 1px 3px rgba(20, 28, 14, 0.1), 0 0 0 1px rgba(20, 28, 14, 0.07);
  transition: color 0.18s ease, background 0.18s ease, transform 0.18s ease;
}
.inv-save svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.inv-save:hover { background: var(--surface); color: var(--forest); transform: scale(1.08); }
.inv-save.on { color: var(--forest); }
.inv-save.on svg { fill: currentColor; stroke: currentColor; }
.inv-save:focus-visible { outline: 2px solid var(--forest); outline-offset: 2px; }

/* In the panel it sits in the footer row, not over a photo. */
.inv-save.care-save {
  position: static; margin-right: auto; margin-left: 14px;
  background: var(--paper-2);
}

.filter-btn--saved { margin-left: auto; }

.saved-panel {
  grid-column: 1 / -1;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-left: 4px solid var(--gold);
  border-radius: var(--r-card);
  padding: clamp(20px, 2.4vw, 30px);
  box-shadow: var(--shadow);
}
.saved-panel h3 {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-1); color: var(--ink); letter-spacing: -0.01em;
}
.saved-panel p {
  margin-top: 8px; max-width: 60ch;
  font-size: var(--step--1); color: var(--body); line-height: 1.6;
}
.saved-actions {
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: 20px;
}
.saved-actions .btn { text-decoration: none; }

.btn.ghost {
  background: transparent; border-color: var(--line); color: var(--muted);
}
.btn.ghost:hover { background: var(--paper-2); border-color: var(--sage); color: var(--ink); transform: none; box-shadow: none; }
.btn.ghost.armed { border-color: var(--olive); color: var(--olive); }

/* ---------- sort ---------- */

.inv-search-wrap {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 14px 20px;
}
.inv-search { flex: 1 1 260px; }
.inv-sort-wrap { display: flex; align-items: center; gap: 9px; }
.inv-sort-label {
  font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted);
}
.inv-sort {
  font-family: var(--font-body); font-size: var(--step--1); color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 11px 18px; cursor: pointer;
}
.inv-sort:focus-visible { outline: none; border-color: var(--forest); box-shadow: 0 0 0 3px rgba(39, 75, 58, 0.12); }

/* ---------- extra photos in the panel ---------- */

/* Hover is a mouse gesture, so on a phone the other photos need tapping. */
.care-strip {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; gap: 8px;
  padding: 12px;
  background: linear-gradient(to top, rgba(20, 28, 14, 0.55), transparent);
  overflow-x: auto;
}
.care-figure { position: relative; }
.care-thumb {
  flex: 0 0 auto;
  width: 54px; height: 54px;
  padding: 0; border: 2px solid transparent; border-radius: 6px;
  background: var(--paper-2); overflow: hidden; cursor: pointer;
}
.care-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.care-thumb.on { border-color: var(--white); }
.care-thumb:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- goes well with ---------- */

.care-suggest {
  margin-top: 26px; padding-top: 22px;
  border-top: 1px solid var(--line-soft);
}
.care-suggest h3 {
  font-weight: 700; font-size: 0.75rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--forest); margin-bottom: 14px;
}
/* Four across, always: an auto-fill track wrapped the fourth onto its own
   row and left the prices at three different heights. */
.care-suggest-row {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}
.suggest-card {
  display: flex; flex-direction: column; gap: 4px;
  padding: 0; border: 0; background: none;
  text-align: left; cursor: pointer;
}
.suggest-card img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 6px; background: var(--paper-2);
  transition: transform 0.2s ease;
}
.suggest-card:hover img { transform: scale(1.03); }
.suggest-name {
  font-size: 0.78rem; line-height: 1.3; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
  /* Two lines' worth whether or not the name needs them, so the prices
     underneath sit on one line as a row. */
  min-height: 2.6em;
}
.suggest-price { font-size: 0.78rem; font-weight: 700; color: var(--sage); margin-top: auto; }
.suggest-card:focus-visible { outline: 2px solid var(--forest); outline-offset: 3px; border-radius: 6px; }

@media (prefers-reduced-motion: reduce) {
  .inv-media.has-hover .inv-art--hover { transition: none; }
  .suggest-card img { transition: none; }
  .inv-save { transition: none; }
}

.store-shell {
  margin-top: 44px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: clamp(20px, 3vw, 36px);
  box-shadow: var(--shadow);
}
.demo-badge {
  display: inline-block; margin-bottom: 18px;
  background: var(--gold); color: var(--night);
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 7px 16px; border-radius: var(--r-btn);
}
/* shown in place of the storefront until a real store ID is configured */
.store-pending { padding: clamp(8px, 1.6vw, 20px) 0; }
.store-pending p { font-size: var(--step-0); line-height: 1.6; max-width: 56ch; }
.store-pending p + p { margin-top: 10px; color: var(--body); }
.store-pending strong { color: var(--ink); }

/* handoff to the Square store, where the cart and the full range live */
.store-handoff { padding: clamp(8px, 1.6vw, 20px) 0; }
.store-handoff p { font-size: var(--step-0); line-height: 1.6; max-width: 56ch; }
.store-handoff p + p { margin-top: 12px; color: var(--body); }
.store-handoff strong { color: var(--ink); }
.store-handoff .btn { margin-top: 6px; }
.store-handoff .store-alt { font-size: var(--step--1); color: var(--sage); }

/* search: a chip row stops being enough at a few hundred plants */
.inv-search-wrap { margin-top: 30px; }
.inv-search {
  font-family: var(--font-body); font-size: var(--step-0);
  width: 100%; max-width: 420px;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 13px 20px;
}
.inv-search::placeholder { color: var(--sage); }
.inv-search:focus {
  outline: none; border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(39, 75, 58, 0.12);
}

/* ---------- a plant's own page ---------- */

.crumbs { padding: 22px 0 0; }
.crumbs .wrap { display: flex; gap: 9px; flex-wrap: wrap; align-items: center;
  font-size: var(--step--1); color: var(--muted); }
.crumbs a { color: var(--muted); }
.crumbs a:hover { color: var(--forest); }
.crumbs [aria-current] { color: var(--ink); font-weight: 700; }

.plant { padding-block: clamp(28px, 4vw, 48px) clamp(56px, 8vw, 96px); }
.plant-loading { color: var(--muted); padding-block: 60px; }
.plant-missing { padding-block: 40px; max-width: 48ch; }
.plant-missing h1 { font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-4); color: var(--ink); margin-bottom: 14px; }

.plant-top {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(24px, 4vw, 56px);
  align-items: start;
}

/* Circular, at Katie's request — she likes the product pages doing this,
   and it "mixes up the norm". It also solves a real problem on the dark
   theme: her photos are shot on white, and a square of them is a glaring
   block. The crop loses only the corners of a square the image already
   filled, so nothing of the plant goes with it. */
.plant-photo {
  width: 100%; max-width: 460px; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 50%; background: var(--surface);
  display: block; margin-inline: auto;
  box-shadow: 0 0 0 1px var(--line), 0 0 0 9px var(--paper-2);
}
.plant-strip { display: flex; gap: 10px; margin-top: 26px; flex-wrap: wrap; justify-content: center; }
.plant-thumb {
  width: 62px; height: 62px; padding: 0; cursor: pointer;
  border: 2px solid transparent; border-radius: 50%;
  background: var(--paper-2); overflow: hidden;
}
.plant-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plant-thumb.on { border-color: var(--forest); }

.plant-name {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-4); line-height: 1.08; color: var(--ink);
  letter-spacing: -0.015em; margin-top: 6px;
}
.plant-common { color: var(--muted); font-size: var(--step--1); margin-top: 6px; }

.plant-price {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin-top: 18px;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-2); color: var(--ink);
}
.plant-stock {
  font-family: var(--font-body); font-weight: 700;
  font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 6px 13px; border-radius: var(--r-btn);
  background: var(--paper-2); color: var(--body);
}
.plant-stock.low { background: var(--olive); color: var(--white); }
.plant-stock.out { background: var(--night); color: var(--white); }

.plant-blurb { margin-top: 18px; font-size: var(--step-0); line-height: 1.6; }

.plant-actions { display: flex; align-items: center; gap: 14px; margin-top: 26px; }
.plant-pickup { margin-top: 18px; font-size: var(--step--1); color: var(--muted); line-height: 1.6; }

/* ---- tabs ----
   The Sill's move, and the reason Katie pointed at it: the buy box stays
   short, and everything worth reading sits under it rather than being
   hidden behind a modal. */

.plant-tabs {
  display: flex; gap: 4px; flex-wrap: wrap;
  margin-top: clamp(44px, 6vw, 72px);
  border-bottom: 1px solid var(--line-soft);
}
.plant-tab {
  border: 0; background: none; cursor: pointer;
  font: inherit; font-weight: 700; font-size: var(--step--1); color: var(--muted);
  padding: 14px 20px; border-bottom: 3px solid transparent;
  margin-bottom: -1px;
}
.plant-tab:hover { color: var(--ink); }
.plant-tab.on { color: var(--forest); border-bottom-color: var(--forest); }

.plant-panel { padding-top: 30px; max-width: 68ch; }
.plant-scope {
  border-left: 3px solid var(--gold); padding-left: 16px;
  color: var(--ink); font-size: var(--step--1); margin-bottom: 24px;
}
.plant-care dt {
  font-weight: 700; font-size: 0.75rem; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--forest); margin-bottom: 7px;
}
.plant-care dd { margin-bottom: 24px; }
.plant-care dd p { font-size: var(--step-0); line-height: 1.65; margin-bottom: 4px; }
.plant-care dd:last-child { margin-bottom: 0; }

/* ---- goes well with ---- */

.plant-also { margin-top: clamp(56px, 8vw, 92px); }
.plant-also .section-title { font-size: var(--step-3); margin-bottom: 26px; }
.plant-also-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
  gap: 18px;
}
.plant-also-card {
  display: flex; flex-direction: column; gap: 4px;
  color: var(--body);
}
.plant-also-card img {
  width: 100%; aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 50%; background: var(--surface);
  box-shadow: 0 0 0 1px var(--line);
  margin-bottom: 12px;
}
.plant-also-name { font-weight: 700; font-size: var(--step--1); color: var(--ink); }
.plant-also-card:hover .plant-also-name { color: var(--forest); }
.plant-also-price { font-size: var(--step--1); color: var(--muted); }

/* The heart is built for a card photo, where it floats top-right. In the
   plant page's action row it is just a button standing next to another. */
.inv-save.plant-save {
  position: static;
  width: 48px; height: 48px;
}

/* the "read the whole thing" link out of the quick modal */
.care-full { font-weight: 700; font-size: var(--step--1); color: var(--forest); }

@media (max-width: 780px) {
  .plant-top { grid-template-columns: 1fr; }
  .plant-name { font-size: var(--step-3); }
  .plant-tab { padding: 12px 14px; }
}

/* ---------- services ribbon ----------

   Katie: "I would like to see movement. Scrolling photos with different
   services." One continuous ribbon under the hero.

   The loop works by rendering the run twice and translating the track
   exactly -50%: at the halfway point the second copy sits precisely where
   the first began, so the reset is invisible. Both runs must therefore be
   identical, and the duplicate is aria-hidden so a screen reader hears the
   services once. */

.ticker-band { padding-block: clamp(40px, 5vw, 64px); overflow: hidden; }

.ticker {
  /* Fades the ribbon out at both edges rather than cutting it off, so it
     reads as continuing past the screen instead of ending there. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.ticker-track {
  display: flex;
  width: max-content;
  animation: ticker 46s linear infinite;
}

/* Slow enough to read a label as it goes past — a ribbon you can't read is
   just noise. */
@keyframes ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Stop it while someone is reading or tabbing through it. */
.ticker:hover .ticker-track,
.ticker:focus-within .ticker-track { animation-play-state: paused; }

.ticker-run { display: flex; }

.svc {
  flex: 0 0 auto;
  width: 210px;
  margin-inline: 14px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center; color: var(--body);
}
.svc img {
  width: 132px; height: 132px;
  border-radius: 50%; object-fit: cover;
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--line), 0 0 0 6px var(--paper-2);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.svc:hover img, .svc:focus-visible img {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px var(--forest), 0 0 0 6px var(--paper-2);
}
.svc b {
  display: block; margin-top: 16px;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-0); line-height: 1.2; color: var(--ink);
}
.svc:hover b { color: var(--forest); }
.svc small {
  display: block; margin-top: 6px;
  font-size: var(--step--1); line-height: 1.45; color: var(--muted);
}

@media (max-width: 560px) {
  .svc { width: 168px; margin-inline: 9px; }
  .svc img { width: 104px; height: 104px; }
  .svc small { display: none; }
}

/* Movement was the request, but not at the cost of anyone who has asked
   their machine to stop animating things. They get the same ribbon as a
   row they can swipe themselves. */
@media (prefers-reduced-motion: reduce) {
  .ticker { overflow-x: auto; }
  .ticker-track { animation: none; }
  .ticker-run[aria-hidden="true"] { display: none; }
}

/* ---------- google reviews ---------- */

.reviews-summary {
  display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap;
  margin-top: 14px;
}
.reviews-count { font-size: var(--step--1); color: var(--muted); font-weight: 700; }

.stars { display: inline-flex; gap: 2px; line-height: 1; }
.star { color: var(--line); font-size: 1.05rem; }
.star.on { color: var(--gold); }

/* Five cards is Google's hard ceiling, so this never has to page or
   virtualise — it lays out as a row and scrolls sideways when the
   screen runs out, rather than squeezing five columns onto a phone. */
.reviews-track {
  display: grid;
  /* min() keeps the track from overflowing a narrow screen; the 340px
     floor is what holds it to three columns on a laptop rather than
     four-plus-one. Google caps this at five, so it never grows. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: 18px;
  margin-top: 36px;
}
.review {
  scroll-snap-align: start;
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-img);
  padding: 24px 24px 20px;
}
.review blockquote {
  margin: 12px 0 18px;
  font-size: var(--step--1); line-height: 1.65; color: var(--body);
}
.review blockquote::before { content: "“"; }
.review blockquote::after  { content: "”"; }

/* pushes the credit to the bottom so cards of different lengths line up */
.review figcaption, .review-credit { margin-top: auto; }

.review figcaption { display: flex; align-items: center; gap: 12px; }
.review-credit { display: block; color: inherit; }
.review-credit:hover .review-who strong { color: var(--forest); }

.review-face { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.review-who { display: flex; flex-direction: column; min-width: 0; }
.review-who strong { font-size: var(--step--1); color: var(--ink); }
.review-who small { font-size: 0.8rem; color: var(--muted); }

@media (max-width: 700px) {
  /* Five stacked cards is a long scroll on a phone, so it becomes a
     swipe row instead — one quote at a time. */
  .reviews-track {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(255px, 86%);
    overflow-x: auto;
    padding-bottom: 6px;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
  }
}

/* ---------- welcome coupon ---------- */

/* Shares the care dialog's shape so it reads as part of the same site:
   same radius, same backdrop, same close button. Deliberately no photo —
   the catalogue shots are white-background cutouts that fight the card,
   and the mark does more for her than a stock plant would. */
.coupon {
  margin: auto;
  width: min(440px, calc(100vw - 32px));
  padding: 0; border: 0;
  border-radius: var(--r-img);
  background: var(--surface);
  color: var(--body);
  box-shadow: 0 30px 80px rgba(20, 28, 14, 0.4);
  overflow: hidden;
  text-align: center;
}
.coupon::backdrop { background: rgba(20, 28, 14, 0.62); }

.coupon[open] { animation: coupon-in 0.32s cubic-bezier(0.22, 1, 0.36, 1); }
@keyframes coupon-in {
  from { opacity: 0; transform: translateY(14px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}

.coupon-crown {
  background: var(--deep);
  padding: 26px 24px 22px;
}
/* Sage on forest is a soft pairing, so the mark sits on a paper disc and
   reads as a seal rather than fading into the band. */
.coupon-crown img {
  width: 82px; height: 82px; display: inline-block;
  background: var(--ink);
  border-radius: 50%;
  padding: 9px;
}

/* The close button sits on the green crown, so it takes the light treatment
   rather than the care dialog's white pill. */
.coupon .care-close {
  background: rgba(255, 255, 255, 0.16);
  color: var(--white);
}
.coupon .care-close:hover { background: rgba(255, 255, 255, 0.3); }

.coupon-body { padding: clamp(24px, 4vw, 34px); }

.coupon-head {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-3); line-height: 1.1; color: var(--ink);
  letter-spacing: -0.015em;
  margin: 8px 0 12px;
}
.coupon-head .accent { color: var(--forest); font-style: italic; }
.coupon-body p { font-size: var(--step--1); line-height: 1.6; }

.coupon-form { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }
.coupon-form input[type="email"] {
  flex: 1 1 100%; min-width: 0;
  font-family: var(--font-body); font-size: var(--step-0); color: var(--ink);
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 14px 16px;
}
.coupon-form input[type="email"]:focus {
  border-color: var(--forest); outline: none;
  box-shadow: 0 0 0 3px rgba(39, 75, 58, 0.12);
}
.coupon-form .btn { flex: 1 1 100%; }

/* the honeypot — off-screen rather than display:none, which some bots skip */
.coupon-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.coupon-error { color: var(--terracotta); font-weight: 700; margin-top: 12px; }
.coupon-note { color: var(--muted); margin-top: 14px; }

.coupon-decline {
  display: inline-block; margin-top: 18px; padding: 0;
  border: 0; background: none; cursor: pointer;
  font: inherit; font-size: var(--step--1);
  color: var(--muted); text-decoration: underline;
}
.coupon-decline:hover { color: var(--ink); }

.coupon-code {
  display: flex; align-items: center; justify-content: center;
  gap: 12px; flex-wrap: wrap;
  margin-top: 20px;
}
.coupon-code code {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-2); letter-spacing: 0.08em; color: var(--forest);
  background: var(--paper-2);
  border: 2px dashed var(--forest);
  border-radius: var(--r-card);
  padding: 12px 22px;
}
.coupon-code + .coupon-note { margin-top: 12px; }
.coupon [data-coupon-step="done"] .btn:not(.sm) { margin-top: 22px; width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .coupon[open] { animation: none; }
}

/* toast */
.toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 400;
  transform: translateX(-50%) translateY(140px);
  background: var(--forest); color: var(--on-primary);
  font-weight: 700; font-size: var(--step--1);
  padding: 15px 28px; border-radius: var(--r-btn);
  box-shadow: var(--shadow-lift);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  max-width: calc(100vw - 32px); text-align: center;
}
.toast.show { transform: translateX(-50%) translateY(0); }

/* ---------- footer ---------- */

.site-footer {
  background: var(--night);
  color: rgba(255, 255, 255, 0.72);
  padding-block: clamp(56px, 7vw, 96px) 36px;
}
.site-footer h3 {
  color: var(--white); font-family: var(--font-body); font-weight: 700;
  font-size: 0.8rem; letter-spacing: 0.16em; text-transform: uppercase; margin-bottom: 18px;
}
.site-footer a { color: rgba(255, 255, 255, 0.78); }
.site-footer a:hover { color: var(--gold); }
.site-footer ul { list-style: none; }
.site-footer li { margin-bottom: 9px; font-size: var(--step--1); }
.site-footer p { font-size: var(--step--1); line-height: 1.65; }

.foot-top {
  display: grid; grid-template-columns: 1.2fr 0.9fr;
  gap: clamp(32px, 5vw, 72px); align-items: end;
  padding-bottom: clamp(40px, 5vw, 64px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}
.foot-top h2 { color: var(--white); font-size: var(--step-4); max-width: 14ch; }

.newsletter { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }
.newsletter input {
  flex: 1 1 220px;
  font-family: var(--font-body); font-size: var(--step-0); color: var(--white);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--r-btn);
  padding: 15px 22px;
}
.newsletter input::placeholder { color: rgba(255, 255, 255, 0.5); }
.newsletter input:focus { outline: none; border-color: var(--gold); }

/* Replaces the form once js/newsletter.js has posted it, so the visitor
   stays on the page instead of being thrown to Netlify's success screen.
   Sits where the form sat, so nothing below it jumps. */
.nl-done { color: var(--gold); margin-top: 18px; font-weight: 600; }

.foot-grid {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr;
  gap: clamp(28px, 4vw, 56px);
  padding-block: clamp(40px, 5vw, 64px);
}
.foot-brand { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.foot-brand img { width: 76px; height: 76px; }
.foot-brand span { font-family: var(--font-display); font-weight: 600; font-size: 1.32rem; line-height: 1.15; color: var(--white); }

.social { display: flex; gap: 12px; margin-top: 18px; }
.social a {
  width: 42px; height: 42px; display: grid; place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 50%;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.social a:hover { background: var(--gold); border-color: var(--gold); color: var(--night); }
.social svg { width: 18px; height: 18px; }

.foot-legal {
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  padding-top: 26px;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-size: 0.8rem; color: rgba(255, 255, 255, 0.5);
}

/* ============================================================
   Holiday pre-orders (preorder.html)

   Follows the paper prebook sheet it replaces — one row per size, one
   box per pickup week — but the photos are the point: the online form
   it was modelled on used 46px thumbnails, too small to choose by. Here
   each plant gets a full card-width photo.
   ============================================================ */

.pb [hidden], .pb-bar[hidden] { display: none !important; }

/* THE SHOP IS THE ONE THING CUSTOMERS DON'T SEE YET (Katie, 11 Sept 2026).
   The rest of the site — plant care, about us, visit, events, the holiday
   pre-order — is open; the inventory pages (shop.html and the plant pages)
   are not, because the stock behind them isn't settled. Every link into
   them carries class="shop-only", and this one rule hides the lot.

   This replaced the old class="standalone" on preorder.html, which hid the
   whole menu back when the pre-order was the only public page.

   TO OPEN THE SHOP: delete this rule. Every link is already in place and
   comes straight back. Her domain also bounces /shop and /plant to the home
   page — that block is at the top of _redirects and goes at the same time. */
.shop-only { display: none !important; }

/* THE PLANT CARE GUIDE IS HIDDEN TOO (Katie, 16 Sept 2026). She asked for
   "Plant Care" to come out of the menu, then for the section itself to go:
   care notes belong on each plant's own page, shown when a customer opens a
   product, and she is working to bring that inventory online. A long
   duplicate list on the home page would only drift out of step with it.

   So the whole "Meet the residents" section on the home page, and every link
   into it (the hero's Plant Care Guide button, the footer's Explore entry on
   all five pages), carries class="care-hidden".

   NOTE: the guide is only hidden, not deleted, and `care.json` is untouched —
   it is what fills in the care notes on the plant pages, and that is the
   feature this defers to.

   TO BRING IT BACK: delete this rule. Everything is still in place. */
.care-hidden { display: none !important; }

/* the spend-and-save offer, above the terms */
.pb-promo {
  background: var(--gold); color: var(--night);
  border-radius: var(--r-card);
  padding: 18px 24px;
  margin-bottom: clamp(14px, 1.6vw, 20px);
  font-size: var(--step-0); line-height: 1.5;
}
.pb-promo b {
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-2); margin-right: 8px;
}
.pb-promo code {
  font-family: var(--font-body); font-weight: 700; letter-spacing: 0.08em;
  background: var(--night); color: var(--gold);
  padding: 2px 9px; border-radius: 6px;
}

.pb-sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* the terms, as a row of short cards */
.pb-terms {
  list-style: none;
  display: grid; gap: clamp(12px, 1.6vw, 20px);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  margin-bottom: clamp(48px, 6vw, 80px);
}
.pb-terms li {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: 20px 22px;
  font-size: var(--step--1); line-height: 1.55; color: var(--body);
}
.pb-terms b {
  display: block; margin-bottom: 6px;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-1); line-height: 1.2; color: var(--gold);
}

.pb-closed { max-width: 62ch; }

.pb-step + .pb-step { margin-top: clamp(56px, 7vw, 96px); }

.pb-details {
  display: grid; grid-template-columns: 1fr 1fr; column-gap: 18px;
  max-width: 820px; margin-top: 26px;
}
.pb-notes { grid-column: 1 / -1; }
.pb-optional { font-weight: 400; color: var(--muted); }
.pb-hint { margin: -2px 0 9px; font-size: var(--step--1); color: var(--muted); max-width: 64ch; }
.pb-details .field textarea { min-height: 96px; }

/* jump links to each group */
.pb-jump { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 30px; }
.pb-jump .filter-btn { text-decoration: none; }

/* A group heading in the manner of the sheet's letter-spaced bands:
   spaced capitals between two rules. */
.pb-section { scroll-margin-top: 110px; margin-top: clamp(44px, 5vw, 64px); }
.pb-section-title {
  display: flex; align-items: center; gap: 18px;
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--step--1); letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 24px;
}
.pb-section-title::before,
.pb-section-title::after { content: ""; flex: 1; height: 1px; background: var(--line); }

.pb-grid {
  display: grid; gap: clamp(18px, 2.2vw, 28px);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: start;
}

.pb-card {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  overflow: hidden;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.pb-card.has-qty { border-color: var(--forest); box-shadow: 0 0 0 1px var(--forest); }
.pb-card.is-sold { opacity: 0.55; }

/* The grower shoots on white, so the frame is white too and the photo is
   contained, never cropped: a poinsettia keeps its pot and its top. */
.pb-photo { position: relative; background: #fff; }
/* height:auto matters: the img's height attribute would otherwise win over
   aspect-ratio and stretch the frame to 640px tall. */
.pb-photo img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: contain; }

.pb-body { padding: 20px 20px 22px; }
.pb-name { font-size: var(--step-1); line-height: 1.2; }
.pb-sub { margin-top: 4px; font-size: var(--step--1); color: var(--muted); }
/* a selling point under the name, e.g. the Norfolk pine for students */
.pb-note {
  margin-top: 12px; padding: 10px 14px;
  border-left: 3px solid var(--gold); background: var(--paper-2);
  border-radius: 0 var(--r-card) var(--r-card) 0;
  font-size: var(--step--1); line-height: 1.5; color: var(--body);
}

.pb-table { width: 100%; border-collapse: collapse; margin-top: 16px; table-layout: fixed; }
.pb-table th, .pb-table td { padding: 5px 3px; text-align: center; vertical-align: middle; }
.pb-table thead th {
  font-size: 0.8rem; font-weight: 700; color: var(--ink); line-height: 1.15;
  padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
.pb-table thead th:first-child { text-align: left; vertical-align: bottom; width: 31%; }
.pb-table tbody th { text-align: left; font-weight: 400; line-height: 1.2; }
.pb-table tbody th b { font-family: var(--font-display); font-weight: 600; font-size: var(--step-0); color: var(--ink); }
.pb-table tbody th small { display: block; font-size: 0.74rem; color: var(--muted); }
.pb-table tbody tr + tr > * { border-top: 1px solid var(--line-soft); }
.pb-price { display: block; margin-top: 2px; font-weight: 700; font-size: 0.8rem; color: var(--gold); }

.pb-flag {
  display: inline-block; margin-top: 3px;
  font-size: 0.6rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--night); background: var(--gold);
  padding: 2px 7px; border-radius: var(--r-btn);
}

.pb-qty {
  width: 100%; max-width: 62px; height: 44px;
  font-family: var(--font-body); font-size: 1.05rem; font-weight: 700;
  text-align: center; color: var(--ink);
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}
.pb-qty:hover { border-color: var(--sage); }
.pb-qty:focus { outline: none; border-color: var(--forest); box-shadow: 0 0 0 3px rgba(143, 176, 138, 0.25); }
.pb-qty.has { background: var(--deep); border-color: var(--forest); color: var(--white); }

.pb-na { color: var(--line); font-weight: 700; }

/* review */
.pb-summary { margin-top: 26px; }
.pb-empty { color: var(--muted); max-width: 52ch; }
.pb-weeks {
  display: grid; gap: clamp(14px, 1.8vw, 22px);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.pb-week {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: 20px 22px;
}
.pb-week h4 { font-size: var(--step-1); margin-bottom: 12px; }
.pb-week ul { list-style: none; }
.pb-week li {
  display: flex; gap: 12px; align-items: baseline;
  padding: 7px 0; font-size: var(--step--1); line-height: 1.4;
}
.pb-week li + li { border-top: 1px solid var(--line-soft); }
.pb-week li b {
  flex: 0 0 auto; min-width: 2.2em; text-align: right;
  font-family: var(--font-display); font-weight: 600; font-size: var(--step-0); color: var(--gold);
}
.pb-line-name { flex: 1; }
.pb-line-cost { flex: 0 0 auto; font-weight: 700; color: var(--ink); }
.pb-week-cost {
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line);
  text-align: right; font-size: var(--step--1); font-weight: 700; color: var(--ink);
}
.pb-week-note { margin-top: 12px; font-size: var(--step--1); color: var(--muted); }
.pb-estimate {
  margin-top: 6px;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-2); color: var(--gold);
}
.pb-promo-line {
  margin-top: 8px; max-width: 62ch;
  font-size: var(--step--1); font-weight: 700; color: var(--body);
}
.pb-promo-line.met { color: var(--forest); }
.pb-fee-note { margin-top: 8px; font-size: var(--step--1); font-weight: 700; color: var(--body); max-width: 62ch; }
.pb-deliver {
  margin-top: 26px; max-width: 820px;
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r-card); padding: 22px 24px 8px;
}
.pb-deliver h3 { font-size: var(--step-1); margin-bottom: 6px; }
.pb-deliver .pb-details { margin-top: 14px; }
.pb-asked { margin-bottom: 18px; max-width: 62ch; }
.pb-asked p { font-size: var(--step--1); white-space: pre-line; }
.pb-how { margin-top: 14px; }
.pb-total { margin-top: 18px; font-weight: 700; color: var(--ink); }
.pb-fine { margin-top: 14px; font-size: var(--step--1); color: var(--muted); }

.pb-review .btn-row { margin-top: 26px; }
.pb-review .coupon-error { margin-top: 20px; }

.pb-done { scroll-margin-top: 120px; }   /* clear the sticky header */
.pb-done:focus { outline: none; }

/* the running count, pinned to the bottom while the list is on screen */
.pb-bar {
  position: fixed; left: 50%; bottom: 18px; z-index: 110;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: 18px;
  max-width: calc(100vw - 32px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-btn);
  padding: 8px 8px 8px 24px;
  box-shadow: var(--shadow-lift);
}
.pb-bar-count { font-weight: 700; font-size: var(--step--1); color: var(--ink); white-space: nowrap; }
.pb-bar .btn { text-decoration: none; }

@media (max-width: 560px) {
  .pb-details { grid-template-columns: 1fr; }
  .pb-grid { grid-template-columns: 1fr; }
  .pb-body { padding: 16px 14px 18px; }
  .pb-bar { left: 16px; right: 16px; transform: none; justify-content: space-between; padding-left: 18px; }
}

@media print {
  .announce, .hero, .pb-terms, .pb-bar, .site-footer, .pb-done .btn-row { display: none !important; }
  .pb-week { border-color: #999; background: #fff; break-inside: avoid; }
  .pb-done, .pb-done * { color: #000 !important; }
}

/* ============================================================
   Events (events.html)

   Katie teaches at other people's venues, so a card is really a
   signpost: when, where, what it costs, and the host's own booking
   link — she never takes the money for these. The date rail is the
   first thing read, so it gets the display face and its own column.

   js/events.js hides a card once its date has passed, which is what
   keeps the page honest between visits. Add and remove events in the
   markup of events.html; nothing here needs touching.
   ============================================================ */

.ev-list { display: grid; gap: clamp(20px, 2.6vw, 32px); }

.ev-card {
  display: grid;
  grid-template-columns: 128px 1fr;
  gap: clamp(20px, 3vw, 40px);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-card);
  padding: clamp(24px, 3vw, 38px);
  box-shadow: var(--shadow);
}
.ev-list[hidden], .ev-card[hidden] { display: none !important; }

.ev-when {
  text-align: center;
  border-right: 1px solid var(--line-soft);
  padding-right: clamp(14px, 2vw, 26px);
}
.ev-month {
  display: block;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--forest);
}
.ev-day {
  display: block; margin-top: 2px;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--step-4); line-height: 1; color: var(--ink);
}
.ev-dow { display: block; margin-top: 8px; font-size: var(--step--1); color: var(--muted); }

.ev-name { font-size: var(--step-2); line-height: 1.2; }
.ev-venue { margin-top: 8px; font-size: var(--step-0); color: var(--body); }
.ev-venue b { color: var(--ink); }

/* time and price, side by side, the two facts people scan for */
.ev-facts {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: 10px;
  margin-top: 20px;
}
.ev-facts li {
  border: 1px solid var(--line); border-radius: var(--r-btn);
  padding: 8px 18px;
  font-size: var(--step--1); color: var(--body);
}
.ev-facts li.price { background: var(--gold); border-color: var(--gold); color: var(--night); font-weight: 700; }

.ev-body { margin-top: 20px; font-size: var(--step--1); line-height: 1.65; }
.ev-body p + p, .ev-body ul + p { margin-top: 0.9em; }
.ev-body b { color: var(--ink); }

/* what you go home with */
.ev-includes {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: 8px 10px;
  margin-top: 12px;
}
.ev-includes li {
  font-size: var(--step--1); color: var(--muted);
}
/* Every item gets the dot, not just the ones after the first: the list
   wraps, and a line that begins with a bare separator reads as a mistake. */
.ev-includes li::before { content: "·"; margin-right: 10px; color: var(--forest); }

.ev-note { margin-top: 16px; font-size: var(--step--1); color: var(--muted); }

.ev-card .btn-row { margin-top: 26px; }

.ev-empty {
  text-align: center; padding: clamp(40px, 6vw, 72px) 0; color: var(--muted);
}

@media (max-width: 640px) {
  .ev-card { grid-template-columns: 1fr; gap: 18px; }
  .ev-when {
    display: flex; align-items: baseline; gap: 10px; text-align: left;
    border-right: 0; border-bottom: 1px solid var(--line-soft);
    padding: 0 0 16px;
  }
  .ev-day { font-size: var(--step-2); margin-top: 0; }
  .ev-dow { margin-top: 0; }
  .ev-card .btn-row .btn { flex: 1 1 100%; }
}

/* ============================================================
   Responsive
   ============================================================ */

@media (max-width: 1180px) {
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 980px) {
  .split, .split.reverse, .split.even, .contact-grid, .foot-top { grid-template-columns: 1fr; }
  .foot-top { align-items: start; }
  .split.reverse .figure { order: -1; }
  .plant-row summary { grid-template-columns: auto 1fr auto; }
  .plant-row .ptag { display: none; }
}

@media (max-width: 860px) {
  /* The closed drawer is parked a full viewport to the right, which used to
     leave the page a screen too wide and scrollable sideways. `clip` stops
     that without making the root a scroll container, so the sticky header
     still sticks. (The pre-order page used to dodge this by hiding the menu
     altogether — class="standalone" — which it no longer does.) */
  html { overflow-x: clip; }

  .nav-toggle { display: inline-flex; }
  .nav {
    position: fixed; top: 0; left: 0; right: 0;
    height: 100dvh;
    flex-direction: column; align-items: stretch; justify-content: flex-start;
    gap: 0;
    background: var(--paper);
    padding: 96px var(--gutter) 40px;
    transform: translateX(100%);
    /* Out of the tab order and off the screen reader's map while closed;
       the delay lets it finish sliding out before it goes. */
    visibility: hidden;
    transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1),
                visibility 0s linear 0.3s;
    overflow-y: auto;
    z-index: 130;
  }
  .nav.open {
    transform: translateX(0);
    visibility: visible;
    transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), visibility 0s;
  }
  .nav a:not(.btn) {
    font-family: var(--font-display); font-weight: 600;
    font-size: var(--step-2); color: var(--ink);
    padding: 18px 0; border-bottom: 1px solid var(--line-soft);
  }
  .nav a:not(.btn)::after { display: none; }
  .nav .btn { margin-top: 28px; width: 100%; }
  body.nav-open { overflow: hidden; }

  .cat-grid { grid-template-columns: 1fr 1fr; }
  .hero { min-height: min(74vh, 580px); }
  .hero h1 { max-width: 100%; }
  .plant-detail { grid-template-columns: 1fr; }
  .foot-grid { grid-template-columns: 1fr; }
  .foot-legal { flex-direction: column; }
}

@media (max-width: 560px) {
  .cat-grid { grid-template-columns: 1fr 1fr; gap: 22px; }
  .cat-tile img { max-width: 132px; }
  .cat-label { margin-top: 14px; }
  .cat-label b { font-size: var(--step-0); }
  .cat-label small { display: none; }
  .inv-grid { grid-template-columns: 1fr 1fr; gap: 12px; }
  .inv-body { padding: 16px 16px 18px; }
  .inv-foot { flex-direction: column; align-items: stretch; gap: 10px; }
  .inv-foot .btn { width: 100%; }
  .field-pair { grid-template-columns: 1fr; gap: 0; }
  .btn { padding: 15px 26px; }
  .btn-row .btn { flex: 1 1 100%; }
  .announce { font-size: 0.78rem; }
  /* Keep the bigger mark from crowding the burger on narrow phones. */
  .brand img { width: 54px; height: 54px; }
  .brand span { font-size: 1.16rem; }
  .foot-brand img { width: 64px; height: 64px; }
}

@media (max-width: 380px) {
  .inv-grid { grid-template-columns: 1fr; }
}

@media print {
  .site-header, .announce, .nav-toggle, .toast, .btn { display: none !important; }
  body { background: #fff; color: #000; }
}
