:root {
  /* Operator-locked tokens (2026-05-23T22:22:15Z) */
  --bg: #0F0F0F;
  --bg-deep: #0A0A0A;
  --surface: #1F1815;
  --surface-2: #2A211B;
  --ink: #F5EFE2;
  --ink-soft: #C9BBA9;
  --ink-mute: #8A7C6E;
  --accent: #E04E5C;
  --accent-deep: #B33846;
  --accent-soft: #F2A3AB;
  --accent-on: #0F0F0F;
  --border: rgba(245, 239, 226, 0.10);
  --border-strong: rgba(245, 239, 226, 0.22);
  --radius: 4px;
  --radius-lg: 8px;
  --radius-xl: 16px;
  --heading-font: "Oswald", "Impact", system-ui, sans-serif;
  --body-font: "Source Serif Pro", "Lora", Georgia, serif;
  --max-w: 1240px;
  --pad-x: clamp(20px, 4vw, 64px);
  --section-y: clamp(72px, 9vw, 130px);
}

*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body-font);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
html { overflow-x: hidden; }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
.container { max-width: var(--max-w); margin: 0 auto; padding-left: var(--pad-x); padding-right: var(--pad-x); }

.skip-link {
  position: absolute; left: -9999px; top: 12px;
  background: var(--ink); color: var(--bg);
  padding: 10px 16px; border-radius: var(--radius); z-index: 100; font-size: 14px;
}
.skip-link:focus { left: 12px; }

/* ========== Tartan strip (signature) ========== */
.tartan-strip {
  height: 14px;
  background-image: url("images/plaid-pattern.jpg");
  background-size: 320px auto;
  background-repeat: repeat-x;
  background-position: center;
  position: relative;
  z-index: 1;
}
.tartan-strip::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(15,15,15,0) 0%, rgba(15,15,15,0.55) 100%);
  pointer-events: none;
}
/* Pinned-to-top variant: stays fixed so it never disappears with scroll */
.tartan-strip--top {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 52;
}
/* Footer variant: full-width inside footer, no special bleed */
.footer-tartan {
  margin: 32px 0 24px;
}

/* ========== Site header (fixed, transparent at top, solid on scroll) ========== */
.site-header {
  position: fixed;
  top: 14px; left: 0; right: 0;
  z-index: 50;
  /* Default state is fully transparent so the first paint matches the
     hero photo cleanly — no dark bar / border flicker before JS gets a
     chance to set the at-top class. JS adds .is-scrolled when the user
     scrolls past the threshold and the dark backdrop fades in. */
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom: 1px solid transparent;
  transition: background 0.3s ease, top 0.3s ease, backdrop-filter 0.3s ease, border-bottom-color 0.3s ease;
}
.site-header.is-scrolled {
  background: rgba(15, 15, 15, 0.86);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--border);
}
.site-header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding-top: 14px; padding-bottom: 14px;
}
.site-logo {
  display: inline-flex; align-items: center; gap: 6px;
  text-decoration: none; color: var(--ink);
  font-family: var(--heading-font); font-weight: 700;
  font-size: 20px; letter-spacing: 0.18em; text-transform: uppercase;
}
.site-logo-mark { color: var(--ink); }
.site-logo-sep { color: var(--accent); padding: 0 2px; }
/* Logo image — site-wide. Uses the pre-tinted cream + gold asset so the
   wordmark reads cream on the dark theme while the crown and flourishes
   keep their original gold. No inversion filter needed. */
.site-logo-img {
  display: block;
  height: 38px;
  width: auto;
}
.footer-brand .footer-logo .site-logo-img { height: 56px; }
@media (max-width: 940px) {
  .site-logo-img { height: 32px; }
}
.site-nav { display: flex; align-items: center; gap: 26px; }
.site-nav a {
  text-decoration: none; color: var(--ink-soft);
  font-family: var(--body-font);
  font-size: 14px; letter-spacing: 0.02em;
  transition: color 0.15s ease;
}
.site-nav a:hover, .site-nav a:focus-visible { color: var(--ink); }
.nav-social { display: inline-flex; gap: 10px; margin-left: 4px; }
.nav-social a {
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid var(--border-strong);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-soft);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.nav-social a:hover { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.nav-social svg { width: 16px; height: 16px; }
.nav-cta {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on);
  text-decoration: none;
  font-family: var(--heading-font); font-weight: 600;
  font-size: 13px; letter-spacing: 0.1em; text-transform: uppercase;
  border-radius: var(--radius);
  transition: filter 0.15s ease, transform 0.1s ease;
  margin-left: 4px;
  box-shadow: 0 6px 18px -8px rgba(224, 78, 92, 0.6);
}
.nav-cta:hover { filter: brightness(1.08); }
.nav-cta:active { transform: translateY(1px); }

.nav-mobile-toggle {
  display: none;
  background: none; border: 1px solid var(--border-strong);
  color: var(--ink); width: 44px; height: 44px;
  border-radius: var(--radius); cursor: pointer;
  align-items: center; justify-content: center; padding: 0;
}
.nav-mobile-panel {
  display: none; flex-direction: column;
  padding: 8px var(--pad-x) 24px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.nav-mobile-panel a {
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
  text-decoration: none; color: var(--ink); font-size: 17px;
}
.nav-mobile-panel a:last-child { border-bottom: none; }
.nav-mobile-panel.open { display: flex; }
.nav-mobile-socials {
  display: flex; gap: 14px; padding-top: 16px;
}
.nav-mobile-socials a {
  border: 1px solid var(--border-strong);
  padding: 10px 14px; border-radius: var(--radius);
  font-size: 14px; text-decoration: none;
}
@media (max-width: 940px) {
  .site-nav { display: none; }
  .nav-mobile-toggle { display: inline-flex; }
}

/* ========== Hero ========== */
/* Tall enough that the marquee sits ~1.25 inches off the bottom of the fold,
   trust strip stays below the fold (counter holds at 0 on load). Hero content
   offset 70px from top to visually center past the fixed tartan-strip + header
   overlap (~90px). The hero-overlay gradient + a translateY on the bg image
   pushes the lighthouse down so it sits behind the "PLAID COFFEE" headline,
   not at the very top crowding the nav. */
.hero {
  position: relative;
  min-height: clamp(740px, 98vh, 1020px);
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  text-align: center; isolation: isolate;
  padding-top: 70px;
}
.hero-bg { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero-bg-video,
.hero-bg img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 50%;
  filter: saturate(85%) brightness(0.62);
}
/* The fallback <img> only renders when the video is hidden (reduced-motion
   or video failure). Defaults hidden so the video gets the active slot. */
.hero-bg-fallback { display: none; }
@media (prefers-reduced-motion: reduce) {
  .hero-bg-video    { display: none; }
  .hero-bg-fallback { display: block; }
}
.hero-overlay {
  position: absolute; inset: 0; z-index: -1;
  /* Home hero overlay only — lightened ~8% relative to the subpage
     .page-hero-overlay so the misty drone footage reads more clearly.
     Operator review on a 13" MBP outdoors at full brightness: the
     previous level was too dim to make out the landscape. */
  background:
    linear-gradient(180deg,
      rgba(15,15,15,0.46) 0%,
      rgba(15,15,15,0.52) 14%,
      rgba(15,15,15,0.32) 42%,
      rgba(15,15,15,0.62) 100%),
    radial-gradient(ellipse 60% 70% at center 56%, rgba(15,15,15,0.02) 0%, rgba(15,15,15,0.39) 100%);
}
.hero-ghost {
  position: absolute;
  top: 50%; left: 50%;
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(8rem, 22vw, 18rem);
  color: var(--ink);
  line-height: 0.9; letter-spacing: -0.04em;
  text-transform: uppercase;
  pointer-events: none; user-select: none; z-index: -1;
  /* Cream watermark over the dark cliffs photo + overlay. No blend mode —
     mix-blend-mode: overlay was making the cream text darken into the base
     and the watermark effectively vanished. Straight opacity reads as a
     soft cream ghost. */
  /* Cinematic entrance — full 5.6s arc:
       0s   → 1.4s : linear rise from 0 → 0.40 (atmosphere phase)
       1.4s → 2.4s : HOLD at peak 0.40 (1.0s)
       2.4s → 5.6s : linear dim 0.40 → 0.08 (3.2s settle phase) */
  opacity: 0;
  transform: translate(-50%, -50%) scale(1.4);
  /* No blur filter on the ghost: filter: blur() on a 250-400px-tall
     text element forces re-rasterization every frame and stuttered the
     scale ramp. Scale + opacity alone carry the cinematic feel and
     stay buttery on the compositor. */
  animation: heroGhostReveal 5.6s linear 0s forwards;
  will-change: opacity, transform;
}
/* Pause every hero animation until the browser has actually painted
   the page. body.is-pre-load is set in the HTML; scripts.js removes
   it on DOMContentLoaded + double rAF so the animations only begin
   AFTER the first paint. Without this gate, CSS animations start
   firing the moment the elements are parsed — by the time the user
   sees the page, ~700ms of the ghost's 1.4s rise has already elapsed
   and they only see the tail end of the climb. */
body.is-pre-load .hero-ghost,
body.is-pre-load .hero .hero-eyebrow,
body.is-pre-load .hero h1 .hero-h1-main,
body.is-pre-load .hero h1 .hero-h1-italic,
body.is-pre-load .hero .hero-sub-stat,
body.is-pre-load .hero .hero-sub-tag,
body.is-pre-load .hero .hero-ctas {
  animation-play-state: paused;
}
@keyframes heroGhostReveal {
  /* Peak opacity dialed back to 0.22 (was 0.40) so the ambient
     watermark doesn't compete with the brand logo at peak luminance.
     Top-tier sites keep background watermarks at 0.06–0.15; 0.22 is
     a slight lift on that range to honor the Plaid brand confidence
     while still ceding focal weight to the logo. */
  0% {
    opacity: 0.10;
    transform: translate(-50%, -50%) scale(1.4);
    /* Linear on the rise so the climb from 0.10 → 0.40 is a steady
       visible ramp instead of an ease-out that hits 80% of peak in
       the first 280ms and then crawls. */
    animation-timing-function: linear;
  }
  25% {
    /* 1.4s into the animation: atmosphere fully resolved. */
    opacity: 0.40;
    transform: translate(-50%, -50%) scale(1);
    animation-timing-function: linear;
  }
  42.86% {
    /* 2.4s: hold ends (1.0s hold from the 1.4s peak), dim begins. */
    opacity: 0.40;
    transform: translate(-50%, -50%) scale(1);
    animation-timing-function: linear;
  }
  100% {
    /* 5.6s: settled into the ambient backdrop opacity. */
    opacity: 0.08;
    transform: translate(-50%, -50%) scale(1);
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-ghost {
    opacity: 0.08;
    transform: translate(-50%, -50%) scale(1);
    animation: none;
  }
}
.hero-inner {
  position: relative;
  padding: clamp(80px, 14vh, 140px) var(--pad-x);
  max-width: 920px;
}
.hero-eyebrow {
  font-family: var(--heading-font); font-weight: 500;
  font-size: 12.5px; letter-spacing: 0.32em;
  text-transform: uppercase; color: var(--ink-soft);
  margin: 0 0 32px;
}
.hero h1 { margin: 0 0 28px; }
.hero-h1-main {
  display: block;
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(3.4rem, 9vw, 7rem);
  line-height: 0.96; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--ink);
}
/* When the h1 main slot holds the brand logo image instead of text,
   size it to match the visual weight the text used to carry and apply
   the same cream-on-dark inversion the header logo uses. The text
   shadow on .hero h1 (defined earlier) becomes a drop-shadow filter
   so the logo lifts off the photo without that hard 1-2px text shadow
   that only makes sense on glyphs. */
.hero-h1-logo-img {
  display: block;
  margin: 0 auto;
  width: auto;
  height: clamp(78px, 13.5vw, 168px);
  max-width: 90%;
  /* Pre-tinted asset: PlaidLogo-cream-gold.png has the PLAID COFFEE +
     ROASTERS wordmark already recolored to cream while the crown and
     flourishes keep their original gold. No inversion filter needed —
     only the drop-shadows lift it off the photo. */
  filter:
    drop-shadow(0 2px 6px rgba(0, 0, 0, 0.6))
    drop-shadow(0 8px 26px rgba(0, 0, 0, 0.45));
}
.hero-h1-italic {
  display: block;
  font-family: var(--heading-font); font-weight: 300; font-style: italic;
  font-size: clamp(1.6rem, 4.5vw, 3rem);
  line-height: 1.1; letter-spacing: 0.04em;
  color: var(--accent-soft);
  margin-top: 14px;
  text-transform: none;
}
.hero-sub {
  max-width: 720px;
  margin: 0 auto 38px;
  color: var(--ink-soft);
}
.hero-sub-stat {
  display: block;
  font-family: var(--heading-font);
  font-weight: 500;
  font-size: clamp(0.95rem, 1.25vw, 1.1rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 14px;
}
.hero-sub-tag {
  display: block;
  font-family: var(--body-font);
  font-style: italic;
  font-size: clamp(1.2rem, 1.9vw, 1.55rem);
  line-height: 1.4;
  color: var(--ink-soft);
}

/* ========== Hero text-shadow lift ==========
   Subtle multi-layer text-shadows so hero copy reads cleanly against the
   photo bg without resorting to heavier overlays. Tight 1-3px shadow
   handles letterform separation, a softer 18-22px glow grounds the type
   on darker areas of the photo. Applied to home hero and any subpage
   hero that carries a photo (.page-hero.has-photo). */
.hero h1,
.hero .hero-eyebrow,
.hero .hero-sub-stat,
.hero .hero-sub-tag,
.page-hero.has-photo h1,
.page-hero.has-photo .eyebrow,
.page-hero.has-photo .lede {
  text-shadow:
    0 1px 2px rgba(0, 0, 0, 0.55),
    0 6px 22px rgba(0, 0, 0, 0.42);
}

/* ========== Hero cinematic cascade ==========
   On page load the user sees only the photo, the nav, and the PLAID
   ghost watermark resolving. After a 0.4s breath at peak (1.4s → 1.8s)
   the type cascade plays: each line slides up 14px with a soft blur
   clearing, ease-out, 220ms stagger. Reserved scale for the brand
   mark (the ghost) — type uses translateY for a poetic line-of-prose
   feel rather than a "popped-in" snap. */
@keyframes heroReveal {
  to {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
  }
}
.hero .hero-eyebrow,
.hero h1 .hero-h1-main,
.hero h1 .hero-h1-italic,
.hero .hero-sub-stat,
.hero .hero-sub-tag,
.hero .hero-ctas {
  opacity: 0;
  filter: blur(6px);
  transform: translateY(14px);
  animation: heroReveal 1.0s cubic-bezier(0.22, 1, 0.36, 1) forwards;
  will-change: opacity, filter, transform;
}
/* Ghost: rise 0 → 1.4s, hold 1.4 → 4.4s, dim 4.4 → 5.6s. Cascade
   starts at 1.80s (a 0.4s breath after the ghost lands at peak), with
   220ms stagger. Last element completes at 1.80 + 5*0.22 + 1.0 = 3.90s.
   Ghost continues to hold at 0.22 ambient through the cascade and for
   ~0.5s of "fullness" afterward, then begins its dim. */
.hero .hero-eyebrow         { animation-delay: 1.80s; }
.hero h1 .hero-h1-main      { animation-delay: 2.02s; }
.hero h1 .hero-h1-italic    { animation-delay: 2.24s; }
.hero .hero-sub-stat        { animation-delay: 2.46s; }
.hero .hero-sub-tag         { animation-delay: 2.68s; }
.hero .hero-ctas            { animation-delay: 2.90s; }

@media (prefers-reduced-motion: reduce) {
  .hero .hero-eyebrow,
  .hero h1 .hero-h1-main,
  .hero h1 .hero-h1-italic,
  .hero .hero-sub-stat,
  .hero .hero-sub-tag,
  .hero .hero-ctas {
    opacity: 1;
    filter: none;
    transform: none;
    animation: none;
  }
}
.hero-ctas { display: inline-flex; gap: 12px; flex-wrap: wrap; justify-content: center; }

/* ========== Buttons ========== */
.btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 14px 26px; border-radius: var(--radius);
  font-family: var(--heading-font);
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.12em; text-transform: uppercase;
  text-decoration: none; cursor: pointer; border: none;
  transition: background 0.15s, color 0.15s, transform 0.1s, border-color 0.15s, filter 0.15s, box-shadow 0.15s;
}
.btn-primary {
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on);
  box-shadow: 0 8px 22px -10px rgba(224, 78, 92, 0.7);
}
.btn-primary:hover { filter: brightness(1.08); box-shadow: 0 12px 28px -10px rgba(224, 78, 92, 0.85); }
.btn-primary:active { transform: translateY(1px); }
.btn-outline-light {
  background: transparent; color: var(--ink);
  border: 1.5px solid rgba(245, 239, 226, 0.55);
}
.btn-outline-light:hover { background: rgba(245, 239, 226, 0.10); border-color: var(--ink); }
.btn-block { width: 100%; justify-content: center; margin-top: 14px; }

/* ========== Hero bag shelf (featured group photo, clean dark backdrop with coral glow) ========== */
.hero-bag-shelf {
  position: relative;
  background-color: var(--bg-deep);
  background-image:
    radial-gradient(ellipse 55% 65% at center 45%, rgba(224, 78, 92, 0.10) 0%, transparent 60%),
    radial-gradient(ellipse 90% 75% at center, rgba(20, 20, 20, 0) 0%, var(--bg-deep) 80%);
  padding: clamp(48px, 7vw, 96px) var(--pad-x) clamp(56px, 8vw, 110px);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.hero-bag-shelf::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--border);
}
.hero-bag-frame {
  max-width: 1100px; margin: 0 auto;
  background: transparent;
  border: none;
  padding: 0;
  filter: drop-shadow(0 36px 60px rgba(224, 78, 92, 0.18))
          drop-shadow(0 24px 80px rgba(0, 0, 0, 0.55));
}
.hero-bag-frame img { width: 100%; height: auto; display: block; }
.hero-bag-cap {
  text-align: center;
  font-family: var(--heading-font);
  font-size: 11.5px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-soft);
  margin: 32px auto 0; max-width: 760px;
  line-height: 1.7;
}
.hero-bag-cap strong { color: var(--accent); font-weight: 600; }

/* ========== Trust strip ========== */
.trust-strip {
  padding: clamp(40px, 5vw, 56px) 0;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.trust-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
  text-align: center;
}
.trust-item {
  font-family: var(--body-font);
  font-size: 13px; color: var(--ink-soft);
  letter-spacing: 0.04em;
  position: relative;
  padding-top: 18px;
}
.trust-item::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 32px;
  height: 2px;
  background: var(--accent);
}
.trust-item strong {
  display: block;
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(2.4rem, 4vw, 3.4rem);
  color: var(--accent);
  line-height: 1; margin-bottom: 6px;
  letter-spacing: 0.02em;
}
@media (max-width: 720px) {
  .trust-grid { grid-template-columns: repeat(2, 1fr); gap: 32px 16px; }
}

/* ========== Marquee ========== */
.marquee {
  background: var(--bg-deep);
  color: var(--ink);
  overflow: hidden;
  padding: 16px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.marquee-track {
  display: flex;
  /* No outer gap: the seam between the two duplicate marquee-items needs
     the SAME visual spacing as the seam between spans WITHIN an item, or
     the translateX(-50%) loop visibly snaps each cycle. The ::after glyph
     on .marquee-item (✦ + margin-left: 56px) provides that buffer for both
     the within-item flow AND the wraparound. */
  white-space: nowrap;
  animation: marquee 60s linear infinite;
  font-family: var(--heading-font);
  font-size: 13px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 500;
}
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee-item { display: inline-flex; align-items: center; gap: 56px; }
.marquee-item::after {
  content: "✦";
  color: var(--accent);
  margin-left: 56px;
  font-size: 11px;
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; justify-content: center; flex-wrap: wrap; gap: 24px; }
  .marquee-item::after { display: none; }
}
/* On mobile the marquee track has the same absolute width as desktop
   (same text content, same gaps), so a 60s animation moves at the
   same px/sec — but on a 375px viewport that reads as a fraction of
   the speed it feels on a 1440px viewport. Scale the duration down
   so the perceived speed matches: 60s → 24s at ≤880px. */
@media (max-width: 880px) {
  .marquee-track { animation-duration: 24s; }
  .marquee-item { gap: 32px; }
  .marquee-item::after { margin-left: 32px; }
}

/* ========== Section base ========== */
.section { padding: var(--section-y) 0; background: var(--bg); }
.section-tight { padding: clamp(48px, 6vw, 80px) 0; }
.section-head { margin-bottom: clamp(40px, 5vw, 64px); max-width: 740px; }
.section-head.centered { margin-left: auto; margin-right: auto; text-align: center; }
.eyebrow {
  font-family: var(--heading-font); font-weight: 600;
  font-size: 12px; letter-spacing: 0.28em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 16px;
}
.section h2, .display-h2 {
  font-family: var(--heading-font);
  margin: 0 0 22px; letter-spacing: 0.02em;
  color: var(--ink);
}
.h2-main {
  display: block;
  font-weight: 700; text-transform: uppercase;
  font-size: clamp(2.1rem, 4.6vw, 3.2rem);
  line-height: 1.05;
}
.h2-italic {
  display: block;
  font-weight: 300; font-style: italic;
  font-size: clamp(1.4rem, 3vw, 2rem);
  line-height: 1.15; letter-spacing: 0.04em;
  color: var(--accent);
  margin-top: 8px;
  text-transform: none;
}
.section-lede {
  font-family: var(--body-font);
  font-size: clamp(1.02rem, 1.2vw, 1.12rem);
  color: var(--ink-soft);
  line-height: 1.7;
  /* margin auto so the lede BLOCK centers inside .section-head, not just
     the text inside the block. Without auto margins the 68ch max-width
     left-anchored the paragraph under a centered heading. */
  margin: 0 auto; max-width: 68ch;
}
.centered-cta { text-align: center; margin-top: clamp(32px, 4vw, 48px); }

/* ========== Roast reel (4-up) ========== */
.roast-reel {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 22px;
}
.roast-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  display: flex; flex-direction: column;
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.roast-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 30px 60px -28px rgba(224, 78, 92, 0.55), 0 12px 24px -16px rgba(0, 0, 0, 0.45);
}
.roast-card-photo {
  aspect-ratio: 1 / 1;
  background: var(--bg-deep);
  padding: clamp(16px, 2vw, 28px);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.roast-card-photo img {
  max-width: 100%; max-height: 100%; object-fit: contain;
  transition: transform 0.4s ease;
}
.roast-card:hover .roast-card-photo img { transform: scale(1.07); }
.roast-card-body { padding: 22px 22px 26px; }
.roast-card-level {
  display: inline-block;
  font-family: var(--heading-font); font-weight: 600;
  font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 10px;
}
.roast-card-name {
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(1.6rem, 2vw, 2rem);
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink);
  margin: 0 0 12px;
  line-height: 1.05;
}
.roast-card-origin,
.roast-card-brew {
  font-family: var(--body-font);
  font-size: 13.5px; color: var(--ink-soft);
  margin: 0 0 6px; line-height: 1.5;
}
.roast-card-notes {
  font-family: var(--body-font);
  font-style: italic;
  font-size: 14.5px;
  color: var(--accent-soft);
  margin: 8px 0 6px;
  letter-spacing: 0.02em;
}
@media (max-width: 1100px) { .roast-reel { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px)  { .roast-reel { grid-template-columns: 1fr; } }

/* ========== Split layout (image + body) ========== */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 6vw, 72px);
  align-items: center;
}
.split-text-first .split-media { order: 2; }
.split-media {
  position: relative;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  box-shadow: 0 30px 70px -36px rgba(0, 0, 0, 0.7);
  border: 1px solid var(--border);
}
.split-media img { width: 100%; height: 100%; object-fit: cover; }
.split-media-cap {
  position: absolute;
  bottom: 14px; left: 14px;
  background: rgba(15, 15, 15, 0.88);
  color: var(--ink);
  padding: 6px 12px;
  font-family: var(--heading-font);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  border-radius: var(--radius);
  border: 1px solid var(--border);
}
.split-body p {
  font-family: var(--body-font);
  font-size: clamp(1.02rem, 1.2vw, 1.1rem);
  line-height: 1.75; color: var(--ink-soft);
  margin: 0 0 18px;
  max-width: 64ch;
}
.split-body p:last-of-type { margin-bottom: 0; }
.story-link { color: var(--accent); text-decoration: none; border-bottom: 1px solid var(--accent); }
.story-link:hover { color: var(--accent-soft); border-bottom-color: var(--accent-soft); }
.story-cta { margin-top: 28px; }
@media (max-width: 940px) {
  .split { grid-template-columns: 1fr; }
  .split-text-first .split-media { order: 0; }
  .split-media { aspect-ratio: 4 / 3; max-height: 480px; }
}

/* ========== Bean origins grid (flexbox so last row of 3 centers) ========== */
.origins-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 18px;
}
.origin-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px 22px 26px;
  position: relative;
  overflow: hidden;
  flex: 0 1 calc(25% - 14px);
  min-width: 220px;
}
.origin-card::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: var(--accent);
  opacity: 0;
  transition: opacity 0.2s ease;
}
.origin-card:hover::before { opacity: 1; }
.origin-flag {
  display: inline-block;
  font-family: var(--heading-font); font-weight: 700;
  font-size: 11px; letter-spacing: 0.18em;
  color: var(--accent);
  border: 1px solid var(--border-strong);
  padding: 3px 8px; border-radius: 3px;
  margin-bottom: 14px;
}
.origin-card h3 {
  font-family: var(--heading-font); font-weight: 700;
  font-size: 1.45rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink); margin: 0 0 14px; line-height: 1.1;
}
.origin-card dl { margin: 0; }
.origin-card dt {
  font-family: var(--heading-font); font-weight: 500;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute); margin-top: 12px;
}
.origin-card dt:first-of-type { margin-top: 0; }
.origin-card dd {
  font-family: var(--body-font);
  font-size: 14px; color: var(--ink-soft);
  margin: 3px 0 0; line-height: 1.5;
}
@media (max-width: 1100px) { .origin-card { flex-basis: calc(50% - 9px); } }
@media (max-width: 540px)  { .origin-card { flex-basis: 100%; } }

/* ========== Pull quote ========== */
.pull-quote {
  max-width: 920px; margin: 0 auto;
  text-align: center; padding: 0 var(--pad-x);
}
.pull-quote-mark {
  display: block;
  font-family: var(--body-font); font-style: italic;
  color: var(--accent); font-size: clamp(5rem, 10vw, 8rem);
  line-height: 0.5; margin: 0 0 4px;
}
.pull-quote-text {
  font-family: var(--body-font); font-style: italic;
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  line-height: 1.4; color: var(--ink);
  margin: 0 0 28px;
}
.pull-quote-cite {
  font-family: var(--heading-font); font-weight: 600;
  font-size: 12.5px; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--ink-mute);
  font-style: normal;
}

/* Cinematic pull-quote reveal — supersedes the basic fade for the three
   inner elements. The opening quote glyph scales in from a tight, low
   position. The body text resolves from a soft blur into focus. The author
   cite tightens its letter-spacing as it fades. The sequence stages over
   ~1.8s so it reads as a deliberate, filmic reveal rather than a snap. */
.pull-quote .pull-quote-mark,
.pull-quote .pull-quote-text,
.pull-quote .pull-quote-cite {
  opacity: 0;
  will-change: opacity, transform, filter, letter-spacing;
}
.pull-quote .pull-quote-mark {
  transform: scale(0.55) translateY(8px);
  transform-origin: 50% 70%;
  transition: opacity 1.0s cubic-bezier(0.22, 1, 0.36, 1) 0.10s,
              transform 1.0s cubic-bezier(0.22, 1, 0.36, 1) 0.10s;
}
.pull-quote .pull-quote-text {
  filter: blur(10px);
  transform: scale(0.985);
  transition: opacity 1.35s cubic-bezier(0.22, 1, 0.36, 1) 0.40s,
              filter 1.35s cubic-bezier(0.22, 1, 0.36, 1) 0.40s,
              transform 1.35s cubic-bezier(0.22, 1, 0.36, 1) 0.40s;
}
.pull-quote .pull-quote-cite {
  letter-spacing: 0.46em;
  transition: opacity 0.85s ease 1.05s,
              letter-spacing 0.85s cubic-bezier(0.22, 1, 0.36, 1) 1.05s;
}

[data-reveal-quote="seen"] .pull-quote .pull-quote-mark {
  opacity: 1;
  transform: scale(1) translateY(0);
}
[data-reveal-quote="seen"] .pull-quote .pull-quote-text {
  opacity: 1;
  filter: blur(0);
  transform: scale(1);
}
[data-reveal-quote="seen"] .pull-quote .pull-quote-cite {
  opacity: 1;
  letter-spacing: 0.18em;
}

@media (prefers-reduced-motion: reduce) {
  .pull-quote .pull-quote-mark,
  .pull-quote .pull-quote-text,
  .pull-quote .pull-quote-cite {
    opacity: 1; transform: none; filter: none;
    letter-spacing: 0.18em;
    transition: none;
  }
}

/* ========== Wholesale block ========== */
.wholesale-block { background: var(--bg-deep); }
.wholesale-ctas {
  display: flex; gap: 12px; flex-wrap: wrap; margin-top: 28px;
}

/* ========== Cross-brand 222 feature card ==========
   A single section that wears 222 Artisan Bakery's visual identity
   inside the Plaid site. Reads as 222 stepping onto the page rather
   than a generic mention — cream background, warm ink, terracotta
   accent, Cormorant heading, Source Serif body. Logo + buttons all
   recolored. Mirrors the inverse treatment built on 222's story page
   so the two sister brands consistently host each other. */
.b222-feature {
  /* 222 palette — scoped local vars so nothing leaks elsewhere. The
     "surface" was originally #FFFCF5 (warm white) which blasted too
     hard against Plaid's near-black page. New surface is a deeper
     muted parchment that keeps 222's warm cream feel while softening
     the contrast against the dark page. The on-accent variable holds
     the bright cream for button text on the terracotta gradient so
     that legibility doesn't track with the surface dim. */
  --b222-surface:      #C9B79A;
  --b222-on-accent:    #FFFCF5;
  --b222-ink:          #2A1F14;
  --b222-ink-soft:     #5C4A36;
  --b222-accent:       #B85C3A;
  --b222-accent-deep:  #8E4226;
  --b222-border:       rgba(42, 31, 20, 0.20);

  max-width: 880px;
  margin: 0 auto;
  text-align: center;
  padding: clamp(44px, 6vw, 80px) clamp(24px, 4vw, 56px);
  background:
    radial-gradient(ellipse 90% 60% at 50% 0%, rgba(184, 92, 58, 0.16) 0%, rgba(184, 92, 58, 0) 70%),
    var(--b222-surface);
  border: 1px solid var(--b222-border);
  border-radius: var(--radius-lg);
  /* Add a soft terracotta halo so the card "emerges" from the dark
     page rather than sitting on top of it as a hard rectangle. */
  box-shadow:
    0 0 0 1px rgba(184, 92, 58, 0.22),
    0 0 90px -20px rgba(184, 92, 58, 0.22),
    0 28px 80px -32px rgba(0, 0, 0, 0.55);
  color: var(--b222-ink);
}
.b222-feature-logo {
  display: block;
  height: clamp(54px, 7vw, 88px);
  width: auto;
  margin: 0 auto clamp(22px, 3vw, 32px);
  /* The 222 logo file is dark-on-transparent — sits naturally on the
     cream surface without filtering. Soft drop shadow grounds it. */
  filter: drop-shadow(0 4px 14px rgba(42, 31, 20, 0.18));
}
.b222-feature .b222-eyebrow {
  font-family: "Cormorant Garamond", "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-style: italic;
  font-size: clamp(0.95rem, 1.1vw, 1.05rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--b222-accent);
  margin: 0 0 14px;
}
.b222-feature h2 {
  font-family: "Cormorant Garamond", "Playfair Display", Georgia, serif;
  font-weight: 600;
  color: var(--b222-ink);
  margin: 0 0 22px;
  letter-spacing: 0.01em;
}
.b222-feature h2 .b222-h2-main {
  display: block;
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  line-height: 1.05;
}
.b222-feature h2 .b222-h2-italic {
  display: block;
  font-weight: 400;
  font-style: italic;
  font-size: clamp(1.25rem, 2.6vw, 1.85rem);
  color: var(--b222-accent);
  margin-top: 6px;
}
.b222-feature p {
  font-family: "Source Serif Pro", "Lora", Georgia, serif;
  font-size: clamp(1.02rem, 1.2vw, 1.12rem);
  color: var(--b222-ink-soft);
  line-height: 1.7;
  max-width: 620px;
  margin: 0 auto 32px;
}
.b222-feature a.b222-link {
  color: var(--b222-accent);
  border-bottom: 1px solid var(--b222-accent);
  text-decoration: none;
}
.b222-feature a.b222-link:hover {
  color: var(--b222-accent-deep);
  border-bottom-color: var(--b222-accent-deep);
}
.b222-feature-ctas {
  display: flex;
  gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
}
.b222-btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 14px 26px;
  border-radius: var(--radius);
  font-family: "Cormorant Garamond", "Playfair Display", Georgia, serif;
  font-weight: 600;
  font-size: 14.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.1s ease, box-shadow 0.18s ease;
}
.b222-btn-primary {
  background: linear-gradient(135deg, var(--b222-accent) 0%, var(--b222-accent-deep) 100%);
  color: var(--b222-on-accent);
  border: 1px solid var(--b222-accent);
  box-shadow: 0 10px 24px -10px rgba(184, 92, 58, 0.5);
}
.b222-btn-primary:hover {
  background: linear-gradient(135deg, var(--b222-accent-deep) 0%, var(--b222-accent) 100%);
  box-shadow: 0 14px 32px -10px rgba(184, 92, 58, 0.65);
  transform: translateY(-1px);
  color: var(--b222-on-accent);
}
.b222-btn-outline {
  background: transparent;
  color: var(--b222-ink);
  border: 1px solid rgba(42, 31, 20, 0.32);
}
.b222-btn-outline:hover {
  background: rgba(42, 31, 20, 0.06);
  border-color: var(--b222-ink);
}

/* ========== Visit grid (where to buy) ========== */
.visit-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 18px;
}
.visit-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px 22px;
  display: flex; flex-direction: column;
  /* Center the small visit-cards (year-round + seasonal) so they
     don't read as cramped left-aligned blocks. The full-width
     visit-card-soon already overrides with its own centering rules. */
  text-align: center;
  align-items: center;
}
.visit-card dl { width: 100%; }
.visit-card-soon {
  border-color: var(--accent);
  background: linear-gradient(180deg, var(--surface) 0%, var(--surface-2) 100%);
  /* The Vandalia-shop coming-soon card is the focal point of where-to-buy;
     span the full row width on desktop so it reads as the headline destination,
     not a small footnote next to the four retail cards. */
  grid-column: 1 / -1;
  /* Center all content inside the full-width focal card (text + form). */
  text-align: center;
  align-items: center;
  box-shadow: 0 0 0 0 rgba(224, 78, 92, 0); /* baseline for animated halo on :hover */
  transition: transform 0.25s ease, box-shadow 0.3s ease, border-color 0.2s ease;
}
@media (max-width: 1100px) {
  .visit-card-soon { grid-column: 1 / -1; }
}
/* Constrain the inner text + form blocks to a narrow centered column inside
   the full-width focal card — the card stretches across the row, but the
   prose, dl, and CTA cap at ~560px so it reads like a centered statement
   rather than a wall of text. */
.visit-card-soon .visit-tag,
.visit-card-soon > h3,
.visit-card-soon > p {
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}
.visit-card-soon > h3 { line-height: 1.2; }
.visit-card-soon > p { line-height: 1.6; }
/* Two-column dl layout — each name/value pair stacks vertically within its
   own column. On the homepage card (2 pairs) this gives Address | Status
   side by side. On the visit page card (4 pairs) it gives a 2x2 grid. */
.visit-card-soon dl {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px 36px;
  max-width: 580px;
  margin: 20px auto;
  text-align: center;
}
.visit-card-soon dl .dl-pair { display: flex; flex-direction: column; gap: 4px; }
.visit-card-soon dl .dl-pair dt {
  margin-top: 0;
}
@media (max-width: 540px) {
  .visit-card-soon dl { grid-template-columns: 1fr; gap: 14px; }
}
/* Footer CTA inside the focal card — regular-sized, not full-width. The
   .btn-block class is no longer applied; the button is auto-sized and centered. */
.visit-card-soon > .btn { display: inline-flex; margin: 18px auto 0; }
/* Hover state: keep the solid coral border (do not fade per the global
   .visit-card:hover rule) and bloom an outer coral halo for excitement. */
.visit-card-soon:hover {
  border-color: var(--accent);
  box-shadow:
    0 0 0 2px rgba(224, 78, 92, 0.35),
    0 0 56px -8px rgba(224, 78, 92, 0.45),
    0 32px 64px -32px rgba(224, 78, 92, 0.55),
    0 12px 26px -14px rgba(0, 0, 0, 0.4);
}
/* The DTC waitlist form inside the focal card: side-by-side input + button,
   centered in the card, regular-sized button (not full-width). */
.visit-card-soon .visit-card-form {
  flex-direction: row;
  flex-wrap: wrap;
  max-width: 520px;
  margin: 0 auto;
  justify-content: center;
  align-items: stretch;
  gap: 10px;
}
.visit-card-soon .visit-card-form input[type="email"] {
  flex: 1 1 240px;
  min-width: 220px;
}
.visit-card-soon .visit-card-form button {
  width: auto;
  flex: 0 0 auto;
}
@media (max-width: 540px) {
  .visit-card-soon .visit-card-form { flex-direction: column; align-items: stretch; }
}
.visit-tag {
  font-family: var(--heading-font); font-weight: 600;
  font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-mute);
  margin-bottom: 12px;
}
.visit-tag-accent { color: var(--accent); }
.visit-card h3 {
  font-family: var(--heading-font); font-weight: 700;
  font-size: 1.35rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink); margin: 0 0 12px; line-height: 1.15;
}
.visit-card p {
  font-family: var(--body-font); font-size: 14.5px;
  color: var(--ink-soft); margin: 0 0 14px; line-height: 1.55;
}
.visit-card dl { margin: 4px 0 14px; flex-grow: 1; }
.visit-card dt {
  font-family: var(--heading-font); font-weight: 500;
  font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-mute); margin-top: 10px;
}
.visit-card dt:first-of-type { margin-top: 0; }
.visit-card dd {
  font-family: var(--body-font); font-size: 14px;
  color: var(--ink); margin: 3px 0 0; line-height: 1.5;
}
.visit-card dd a { color: var(--accent); text-decoration: none; }
.visit-card dd a:hover { color: var(--accent-soft); }
.visit-card-form {
  display: flex; flex-direction: column; gap: 10px; margin-top: 8px;
}
.visit-card-form input[type="email"] {
  padding: 11px 14px;
  font-family: var(--body-font);
  font-size: 14.5px;
  background: var(--bg);
  color: var(--ink);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
}
.visit-card-form input[type="email"]:focus {
  outline: 2px solid var(--accent); outline-offset: 2px;
  border-color: var(--accent);
}
@media (max-width: 1100px) { .visit-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 540px)  { .visit-grid { grid-template-columns: 1fr; } }

/* ========== FAQ ========== */
.faq-list { max-width: 800px; margin: 0 auto; }
.faq-item { border-top: 1px solid var(--border); padding: 22px 0; }
.faq-item:last-child { border-bottom: 1px solid var(--border); }
.faq-item summary {
  cursor: pointer; list-style: none;
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 24px;
  font-family: var(--heading-font); font-weight: 600;
  font-size: 1.15rem; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink); line-height: 1.35;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
  content: "+";
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px;
  border: 1px solid var(--accent); border-radius: 50%;
  color: var(--accent);
  font-family: var(--body-font); font-size: 20px; line-height: 0;
  transition: transform 0.2s, background 0.2s, color 0.2s;
}
.faq-item summary:hover::after { background: var(--accent); color: var(--accent-on); }
.faq-item[open] summary::after { transform: rotate(45deg); background: var(--accent); color: var(--accent-on); }
.faq-item-body {
  padding-top: 16px;
  font-family: var(--body-font);
  color: var(--ink-soft);
  font-size: 16px; line-height: 1.7;
  max-width: 720px;
}

/* ========== Newsletter ========== */
.newsletter {
  background: var(--bg-deep);
  padding: clamp(56px, 7vw, 96px) 0;
  border-top: 1px solid var(--border);
}
.newsletter-inner {
  max-width: 680px; margin: 0 auto;
  text-align: center; padding: 0 var(--pad-x);
}
.newsletter h2 { margin-bottom: 14px; }
.newsletter p {
  font-family: var(--body-font);
  color: var(--ink-soft);
  font-size: 16px; line-height: 1.6;
  margin: 0 0 28px;
}
.newsletter-form {
  display: flex; gap: 10px; max-width: 460px; margin: 0 auto;
}
.newsletter-form input[type="email"] {
  flex: 1; padding: 14px 16px;
  font-family: var(--body-font); font-size: 15.5px;
  background: var(--surface); color: var(--ink);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
}
.newsletter-form input[type="email"]:focus {
  outline: 2px solid var(--accent); outline-offset: 2px;
  border-color: var(--accent);
}
.newsletter-form button {
  padding: 14px 24px;
  font-family: var(--heading-font); font-weight: 600;
  font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase;
  background: linear-gradient(180deg, var(--accent) 0%, var(--accent-deep) 100%);
  color: var(--accent-on);
  border: none; border-radius: var(--radius);
  cursor: pointer;
  box-shadow: 0 8px 22px -10px rgba(224, 78, 92, 0.7);
  transition: filter 0.15s;
}
.newsletter-form button:hover { filter: brightness(1.08); }
.newsletter-tiny {
  font-size: 12.5px; color: var(--ink-mute); margin-top: 12px;
}
@media (max-width: 540px) { .newsletter-form { flex-direction: column; } }

/* ========== Footer ========== */
.site-footer {
  background: var(--bg-deep);
  color: var(--ink-soft);
  padding: clamp(60px, 8vw, 96px) 0 28px;
  border-top: 1px solid var(--border);
}
.site-footer-top {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr 1.2fr;
  gap: 40px;
  padding-bottom: 40px;
}
.footer-brand .footer-logo {
  font-family: var(--heading-font); font-weight: 700;
  font-size: 24px; letter-spacing: 0.18em; text-transform: uppercase;
  margin: 0 0 16px;
  display: inline-flex; gap: 6px;
}
.footer-brand p {
  font-family: var(--body-font);
  font-size: 14.5px; line-height: 1.65;
  margin: 0 0 18px; max-width: 320px;
  color: var(--ink-soft);
}
.footer-brand a { color: var(--ink); border-bottom: 1px solid var(--accent); text-decoration: none; }
.footer-brand a:hover { color: var(--accent-soft); }
.footer-socials { display: flex; gap: 10px; }
.footer-socials a {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--border-strong);
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink-soft);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.footer-socials a:hover { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.footer-socials svg { width: 16px; height: 16px; }
.footer-col h4 {
  font-family: var(--heading-font); font-weight: 600;
  font-size: 11.5px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent); margin: 0 0 16px;
}
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.footer-col a {
  color: var(--ink-soft); text-decoration: none;
  font-family: var(--body-font); font-size: 14.5px;
}
.footer-col a:hover { color: var(--accent); }
.footer-col p {
  font-family: var(--body-font); font-size: 14.5px;
  margin: 0 0 10px; color: var(--ink-soft); line-height: 1.55;
}
.site-footer-bottom {
  padding-top: 16px;
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 14px;
}
.footer-copy {
  font-family: var(--body-font);
  font-size: 12.5px; color: var(--ink-mute); margin: 0;
}
.footer-copy a { color: var(--ink-soft); text-decoration: underline; }
@media (max-width: 940px) {
  .site-footer-top { grid-template-columns: 1fr 1fr; gap: 32px 24px; }
}
@media (max-width: 540px) {
  .site-footer-top { grid-template-columns: 1fr; text-align: center; }
  .footer-brand .footer-logo,
  .footer-socials,
  .footer-col ul { justify-content: center; align-items: center; }
  .footer-brand p { margin-left: auto; margin-right: auto; }
  .site-footer-bottom { justify-content: center; text-align: center; }
}

/* Sticky mobile CTA bar + desktop floating CTA pill removed per
   operator: "this site should not have any sticky CTAs." Conversion
   surfaces live in the header (Wholesale nav CTA), the hero CTA row,
   and per-page in-flow CTAs. */

/* ========== A11y ========== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
a:focus-visible, button:focus-visible, .btn:focus-visible, summary:focus-visible,
input:focus-visible, textarea:focus-visible, select:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 4px;
}

/* ========== Subpage hero variant — expansive, photo-led, matches home ========== */
.page-hero {
  position: relative;
  /* Match the home hero's min-height so every subpage opens with the
     same cinematic vertical breathing room — no truncated short heroes. */
  min-height: clamp(740px, 98vh, 1020px);
  padding: 90px var(--pad-x) 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  isolation: isolate;
  overflow: hidden;
  background: var(--bg-deep);
  border-bottom: 1px solid var(--border);
}
.page-hero > .container { width: 100%; max-width: var(--max-w); }
.page-hero-bg { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.page-hero-bg img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 30%;
  /* Lifted to match the home hero (0.58 → 0.66, 82% → 86%) so subpage
     heroes don't read darker than the homepage hero. */
  filter: saturate(86%) brightness(0.66);
}
.page-hero-overlay {
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg,
      rgba(15,15,15,0.54) 0%,
      rgba(15,15,15,0.60) 14%,
      rgba(15,15,15,0.40) 42%,
      rgba(15,15,15,0.70) 100%),
    radial-gradient(ellipse 60% 70% at center 56%, rgba(15,15,15,0.04) 0%, rgba(15,15,15,0.47) 100%);
}
.page-hero-ghost {
  position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(7rem, 18vw, 14rem);
  color: var(--ink); opacity: 0.10;
  line-height: 0.9; letter-spacing: -0.04em;
  text-transform: uppercase;
  pointer-events: none; user-select: none; z-index: -1;
  mix-blend-mode: overlay;
}
/* Per-page hero photo focal points — each image needs its own object-position
   to show the right area. The bag group is centered, beans-bowls + roaster
   crops both sit slightly below middle to keep the focal element visible
   under the overlay. The stag silhouette needs to anchor low so the antlers
   land just under the headline rather than getting cropped at the top. */
body.page-roasts .page-hero-bg img { object-position: center 50%; }
/* Beans: cover (full width) with the visible window shifted slightly
   up (object-position: center 40%) so the top row of bowls is no longer
   cropped on 13" MBP-class viewports where the container is roughly 1.63
   aspect (image is 1.45 — ~110px of vertical overflow with center-50%
   shaving the top by ~55px). 40% trades ~16px of bottom-edge visibility
   for ~16px more top-edge visibility. */
body.page-beans   .page-hero-bg img { object-position: center 40%; }
body.page-story   .page-hero-bg img { object-position: center 70%; }
body.page-wholesale .page-hero-bg img { object-position: center 35%; }
body.page-visit   .page-hero-bg img { object-position: center 30%; }
.page-hero h1 { margin: 0 0 18px; }
.page-hero h1 .hero-h1-main {
  font-size: clamp(2.6rem, 6.5vw, 4.6rem);
  line-height: 1.05;
}
.page-hero h1 .hero-h1-italic {
  font-size: clamp(1.4rem, 3.6vw, 2.4rem);
  margin-top: 8px;
}
.page-hero p.eyebrow,
.page-hero h1,
.page-hero p.lede {
  text-align: center;
}
.page-hero p.lede {
  font-family: var(--body-font);
  font-size: clamp(1.05rem, 1.3vw, 1.18rem);
  color: var(--ink-soft);
  max-width: 620px;
  margin-left: auto;
  margin-right: auto;
  line-height: 1.65;
}
.page-hero-ctas {
  margin-top: clamp(28px, 3.5vw, 40px);
  display: inline-flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Breadcrumb styles removed — markup was dropped from all subpages per operator
   request ("not a complex site, breadcrumbs just add confusion"). */

/* ========== Roast detail list (full /roasts/ page) ========== */
.roast-detail-list {
  display: flex; flex-direction: column;
  gap: clamp(36px, 5vw, 56px);
}
.roast-detail {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: clamp(24px, 3vw, 40px);
  position: relative;
  overflow: hidden;
}
.roast-detail::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--accent);
  opacity: 0;
  transition: opacity 0.25s ease;
}
.roast-detail:hover::before { opacity: 1; }
.roast-detail:nth-child(even) { grid-template-columns: 1.4fr 1fr; }
.roast-detail:nth-child(even) .roast-detail-photo { order: 2; }
.roast-detail-photo {
  aspect-ratio: 1 / 1.05;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-deep);
  border-radius: var(--radius);
  padding: clamp(16px, 2vw, 28px);
  border: 1px solid var(--border);
}
.roast-detail-photo img {
  max-width: 100%; max-height: 100%; object-fit: contain;
}
.roast-detail-body { min-width: 0; }
.roast-detail-level {
  display: inline-block;
  font-family: var(--heading-font); font-weight: 600;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 14px;
}
.roast-detail-name {
  font-family: var(--heading-font); font-weight: 700;
  font-size: clamp(2.2rem, 4vw, 3.2rem);
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--ink);
  margin: 0 0 16px; line-height: 1;
}
.roast-detail-prose {
  font-family: var(--body-font);
  font-size: clamp(1rem, 1.15vw, 1.08rem);
  color: var(--ink-soft);
  line-height: 1.65; margin: 0 0 22px;
  max-width: 56ch;
}
.roast-detail-specs {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 8px 18px;
  align-items: baseline;
  border-top: 1px solid var(--border);
  padding-top: 18px;
}
.roast-detail-specs dt {
  font-family: var(--heading-font); font-weight: 500;
  font-size: 10.5px; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--ink-mute);
}
.roast-detail-specs dd {
  font-family: var(--body-font); font-size: 14.5px;
  color: var(--ink); margin: 0; line-height: 1.5;
}
.roast-detail-specs dd.notes {
  font-style: italic;
  color: var(--accent-soft);
}
@media (max-width: 880px) {
  .roast-detail,
  .roast-detail:nth-child(even) {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .roast-detail:nth-child(even) .roast-detail-photo { order: 0; }
  .roast-detail-photo { aspect-ratio: 4 / 3; max-height: 360px; }
}

/* ========== Contact form (for visit / wholesale pages) ========== */
/* Wave 7.1: gradient top accent bar via ::before. Same Highland Coral gradient
   as the hero primary button + page-hero halo, so the form reads as a primary
   conversion surface, not a generic content block. */
.contact-form {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: clamp(28px, 4vw, 44px);
  overflow: hidden;
}
/* Centered form in its own section on /wholesale/. The form sits alone,
   constrained to a reading width, so the inquiry block above (image +
   intro copy) and the form below each read as their own moment. */
.wholesale-form-wrap {
  max-width: 680px;
  margin: 0 auto;
}
.wholesale-form-section {
  padding-top: 0;
}
.contact-form::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--accent) 0%, var(--accent-deep) 100%);
  pointer-events: none;
}
/* Wave 7.1: expectation-setter block above the form fields. Three brief lines
   in Plaid's craft-confident voice. The block sits inside .contact-form so it
   inherits the gradient accent bar above it. */
.contact-form-expect {
  margin: 0 0 22px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--border);
  display: grid;
  gap: 8px;
}
.contact-form-expect p {
  margin: 0;
  font-family: var(--body-font);
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--ink-soft);
}
.contact-form-expect p strong {
  font-family: var(--heading-font);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 11.5px;
  color: var(--accent);
  display: block;
  margin-bottom: 2px;
}
.contact-form .field { margin-bottom: 18px; }
.contact-form label {
  display: block;
  font-family: var(--heading-font); font-weight: 500;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 6px;
}
.contact-form input,
.contact-form textarea {
  width: 100%; padding: 12px 14px;
  font-family: var(--body-font); font-size: 16px;
  color: var(--ink); background: var(--bg);
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
}
.contact-form input:focus,
.contact-form textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}
.contact-form textarea { resize: vertical; min-height: 130px; }
.contact-form-actions { margin-top: 24px; }
.contact-form-status {
  margin-top: 14px; font-size: 14.5px;
  color: var(--accent);
}

/* ========== Entrance reveals ==========
   Default to visible. The IntersectionObserver in scripts.js still
   sets data-reveal="seen" but the visible-by-default approach means
   content always renders even if the IO never fires for some
   structural reason (the observer was stranding below-fold sections
   at opacity 0 in a way that defied normal cascade rules). The
   pull-quote and counter delights run on their own dedicated
   observers, so dropping the generic reveal animation only costs
   the subtle section fade-in. */
[data-reveal],
[data-reveal="seen"] {
  opacity: 1;
  transform: none;
}

/* ========== Wave 1: Hero phone tap-line (above eyebrow) ========== */
.hero-phone-line {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 auto 22px;
  padding: 11px 18px;
  min-height: 44px;
  background: rgba(31, 24, 21, 0.55);
  backdrop-filter: blur(6px) saturate(140%);
  -webkit-backdrop-filter: blur(6px) saturate(140%);
  border: 1px solid rgba(245, 239, 226, 0.22);
  border-radius: 999px;
  font-family: var(--body-font);
  font-size: 14.5px;
  letter-spacing: 0.04em;
  color: rgba(245, 239, 226, 0.95);
  text-decoration: none;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.hero-phone-line:hover {
  background: rgba(31, 24, 21, 0.75);
  border-color: rgba(224, 78, 92, 0.55);
}
.hero-phone-line svg { width: 14px; height: 14px; flex: none; color: var(--accent); }
.hero-phone-line strong { font-weight: 600; letter-spacing: 0.02em; }

/* ========== Wave 1: Glass testimonial card (in hero) ========== */
.hero-glass-quote {
  display: inline-flex;
  flex-direction: column;
  gap: 8px;
  max-width: 480px;
  margin: 36px auto 0;
  padding: 18px 22px;
  background: rgba(245, 239, 226, 0.08);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(245, 239, 226, 0.22);
  border-radius: var(--radius-lg);
  box-shadow: 0 22px 60px -28px rgba(0, 0, 0, 0.65);
  text-align: left;
}
.hero-glass-quote-stars {
  font-size: 14px;
  letter-spacing: 0.25em;
  color: #F4C36A;
}
.hero-glass-quote-text {
  font-family: var(--body-font);
  font-style: italic;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
  font-weight: 500;
}
.hero-glass-quote-cite {
  font-family: var(--heading-font);
  font-weight: 500;
  font-size: 11.5px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(245, 239, 226, 0.72);
  font-style: normal;
  margin: 0;
}
@media (max-width: 540px) {
  .hero-glass-quote {
    margin-top: 28px;
    padding: 14px 16px;
  }
  .hero-glass-quote-text { font-size: 1rem; }
  .hero-phone-line { font-size: 13.5px; padding: 10px 16px; }
}

/* ========== Wave 2: Typography & editorial polish ========== */
/* 2.8: Cap remaining prose blocks at ≤75ch so line lengths stay readable. */
.newsletter p { max-width: 56ch; margin-left: auto; margin-right: auto; }
.footer-brand p { max-width: 38ch; }
.hero-bag-cap { max-width: 70ch; }
.faq-item-body { max-width: 70ch; }
.section-lede { max-width: 68ch; }
/* 2.3 nuance: only the homepage trust strip needs accent bar; the strong-only
   numeral above keeps centered alignment under the bar. */

/* ========== Wave 1: Mobile sanity (keep hero copy inside the viewport) ========== */
@media (max-width: 540px) {
  .hero-inner, .page-hero .container, .page-hero-inner {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
  }
  .hero-h1-main {
    font-size: 2rem !important;
    letter-spacing: 0.01em;
    word-break: break-word;
    overflow-wrap: anywhere;
    line-height: 1.05;
  }
  .hero-h1-italic {
    font-size: 1.25rem !important;
  }
  .hero-sub, .page-hero .lede, .lede {
    max-width: 100%;
    word-wrap: break-word;
    overflow-wrap: anywhere;
  }
  /* Inner page hero (used by roasts/beans/story/wholesale/visit) */
  .page-hero h1 .hero-h1-main {
    font-size: 1.9rem !important;
    word-break: break-word;
    overflow-wrap: anywhere;
    line-height: 1.05;
  }
  .page-hero h1 .hero-h1-italic {
    font-size: 1.2rem !important;
  }
  /* Belt-and-suspenders horizontal-overflow guard on hero containers */
  .hero, .page-hero {
    overflow-x: clip;
  }
  /* Mobile eyebrow: drop letter-spacing so the line wraps inside viewport */
  .hero-eyebrow {
    letter-spacing: 0.18em;
    font-size: 11px;
    margin-bottom: 22px;
    line-height: 1.5;
  }
  /* Mobile hero-sub: tighten the stat-line letter-spacing so the three
     facts fit on one row at narrow viewports. The tagline reflows naturally. */
  .hero-sub-stat {
    letter-spacing: 0.12em;
    font-size: 0.82rem;
    margin-bottom: 12px;
  }
  .hero-sub-tag {
    font-size: 1.05rem;
    line-height: 1.45;
  }
  .hero-glass-quote {
    max-width: calc(100vw - 36px);
  }
  .hero-glass-quote-cite {
    font-size: 10.5px;
    letter-spacing: 0.1em;
    line-height: 1.4;
  }
}

/* ========== Wave 3: Depth, hover, focus, micro-interactions ========== */

/* 3.1 Uniform card lift on hover for .origin-card and .visit-card
   .roast-card already bumped to -6px + intensified shadow + scale(1.07) inline above. */
.origin-card {
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.2s ease;
}
.origin-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 28px 56px -32px rgba(224, 78, 92, 0.45), 0 10px 22px -14px rgba(0, 0, 0, 0.4);
  border-color: rgba(224, 78, 92, 0.35);
}
.visit-card {
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.2s ease;
}
.visit-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 28px 56px -32px rgba(224, 78, 92, 0.45), 0 10px 22px -14px rgba(0, 0, 0, 0.4);
  border-color: rgba(224, 78, 92, 0.35);
}

/* 3.3 Hero H1 subtle radial-gradient halo. Painted on a ::before behind the H1 main glyph so it tracks the type, not the section frame. */
.hero h1,
.page-hero h1 {
  position: relative;
  isolation: isolate;
}
.hero h1::before,
.page-hero h1::before {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: min(110%, 1100px);
  aspect-ratio: 2.4 / 1;
  transform: translate(-50%, -55%);
  background: radial-gradient(ellipse at center, rgba(224, 78, 92, 0.22) 0%, rgba(224, 78, 92, 0.10) 38%, rgba(224, 78, 92, 0) 70%);
  filter: blur(8px);
  z-index: -1;
  pointer-events: none;
}

/* 3.4 Harmonize form-field focus rings to the universal 4px offset.
   The earlier 2px offset on .visit-card-form, .newsletter-form, .contact-form is overridden here to match the global :focus-visible at L898. */
.visit-card-form input[type="email"]:focus,
.newsletter-form input[type="email"]:focus,
.contact-form input:focus,
.contact-form textarea:focus {
  outline-offset: 4px;
}

/* 3.8 Belt-and-suspenders: any future bare outline:none on a focusable element will inherit the universal 2px+4px replacement. No bare outline:none exists today (sweep returned 0 hits). */

@media (prefers-reduced-motion: reduce) {
  .roast-card:hover,
  .origin-card:hover,
  .visit-card:hover { transform: none; }
  .roast-card:hover .roast-card-photo img { transform: none; }
}

/* ========== Wave 4: Imagery & art direction ========== */

/* 4.6 Inner-border ring + outer drop-glow on every framed image.
   .hero-bag-frame keeps its existing dual drop-shadow; we layer an inset hairline
   ring on the image itself via a wrapping rule. .split-media, .page-hero-bg,
   .roast-detail-photo get an inset ring + warm outer glow. */
.split-media {
  box-shadow:
    inset 0 0 0 1px rgba(245, 239, 226, 0.08),
    0 30px 70px -36px rgba(0, 0, 0, 0.7),
    0 18px 50px -32px rgba(224, 78, 92, 0.18);
}
.page-hero-bg::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgba(245, 239, 226, 0.06);
  pointer-events: none;
  z-index: 0;
}
.roast-detail-photo {
  box-shadow:
    inset 0 0 0 1px rgba(245, 239, 226, 0.08),
    0 18px 40px -26px rgba(224, 78, 92, 0.22),
    0 8px 22px -14px rgba(0, 0, 0, 0.5);
}
.hero-bag-frame {
  /* Existing dual drop-shadow already provides outer glow. Add a hairline inner
     ring on the image so the frame reads as a deliberate object rather than a
     free-floating PNG. */
  position: relative;
}
.hero-bag-frame::after {
  content: "";
  position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px rgba(245, 239, 226, 0.05);
  pointer-events: none;
  border-radius: 2px;
}

/* 4.7 Gradient bottom-fade on .split-media so the caption pill reads cleanly
   over any image. Hero + page-hero already carry their own overlays. */
.split-media::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 40%;
  background: linear-gradient(180deg, rgba(15,15,15,0) 0%, rgba(15,15,15,0.55) 100%);
  pointer-events: none;
  z-index: 1;
}
.split-media-cap {
  z-index: 2; /* sit above the new bottom-fade */
}

/* ========== Wave 5: Cross-page distinctiveness ========== */

/* 5.3 Hero rhythm varies per page. Index already runs the full .hero with the
   matte-black bag-shelf composition; subpages share .page-hero, so without
   per-page overrides every subpage hero feels identical. Each subpage gets a
   subtle rhythm shift: slightly different padding cadence, a different H1
   main-line scale floor, a different lede width. The shifts are small enough
   to stay restrained, large enough that the six page-heroes read as siblings
   rather than copies.

   The metaphor:
   - roasts (the catalogue): tightest hero, biggest H1, the lineup speaks first
   - beans (the portfolio): standard rhythm, wider lede; sourcing is a paragraph, not a slogan
   - story (origin narrative): tallest hero, smallest H1; give the prose room to breathe
   - wholesale (b2b): standard cadence, longer lede width; buyers read more copy
   - visit (locations): tightest hero, narrow lede; get the address above the fold fast
*/

body.page-roasts .page-hero {
  padding: clamp(150px, 18vh, 220px) 0 clamp(48px, 6vw, 76px);
}
body.page-roasts .page-hero h1 .hero-h1-main {
  font-size: clamp(2.8rem, 6.8vw, 4.8rem);
}
body.page-roasts .page-hero p.lede {
  max-width: 580px;
}

body.page-beans .page-hero p.lede {
  max-width: 680px;
}

body.page-story .page-hero {
  padding: clamp(180px, 22vh, 260px) 0 clamp(60px, 7.5vw, 92px);
}
body.page-story .page-hero h1 .hero-h1-main {
  font-size: clamp(2.5rem, 6.2vw, 4.3rem);
}
body.page-story .page-hero h1 .hero-h1-italic {
  font-size: clamp(1.5rem, 3.8vw, 2.55rem);
}
body.page-story .page-hero p.lede {
  max-width: 660px;
}

/* Story hero is the only page with atmospheric content in the photo (a
   rainbow arc behind the stag silhouette). The standard radial-gradient
   in .page-hero-overlay creates its own visible ellipse, and the ghost
   STORY text with mix-blend-mode: overlay reacts unpredictably against
   the rainbow's color bands. Together the three layers compound into
   visible arc-shaped edges. Replace the overlay with a pure linear
   fade and drop the ghost's blend mode for this page only. */
body.page-story .page-hero-overlay {
  background: linear-gradient(180deg,
    rgba(15, 15, 15, 0.58) 0%,
    rgba(15, 15, 15, 0.40) 38%,
    rgba(15, 15, 15, 0.42) 62%,
    rgba(15, 15, 15, 0.72) 100%);
}
body.page-story .page-hero-ghost {
  mix-blend-mode: normal;
  opacity: 0.07;
}

body.page-wholesale .page-hero p.lede {
  max-width: 700px;
}

/* Visit hero lede width: tightened slightly to balance the larger photo. */
body.page-visit .page-hero p.lede {
  max-width: 580px;
}

/* ========== Wave 8: Final blemish hunt + wow moments ========== */

/* 8.2 Handwritten-script signature flourish: Caveat on story (after pull
   quote) and on wholesale (after expectation-setter). Pulled from Google
   Fonts only on those two pages so the font payload stays scoped. */
.signature-script {
  display: block;
  font-family: "Caveat", "Brush Script MT", cursive;
  font-weight: 600;
  font-size: clamp(2.4rem, 4.5vw, 3.4rem);
  line-height: 1;
  color: var(--accent-soft);
  margin-top: 22px;
  letter-spacing: 0.01em;
  text-align: center;
  user-select: none;
}
.signature-script-sm {
  font-size: clamp(1.9rem, 3vw, 2.5rem);
  margin-top: 14px;
  text-align: right;
  padding-right: 4px;
}

/* 8.3 Per-page delights. ONE delight per major page, scoped via body.page-{slug}.
   Each is restrained, accessible (reduced-motion guarded), and pulls from the
   page's established visual vocabulary (Highland Coral, Oswald, the tartan).

   Inventory:
   - home (page-home):       animated stat counters on .trust-item strong (JS, see scripts.js)
   - roasts (page-roasts):   bag-rotate-on-hover, each .roast-card-bag tilts 2deg on card hover
   - beans (page-beans):     origin-card top-bar fills from left-to-right with eased ease-out
   - story (page-story):     tartan-strip "weave-in" on first paint via clip-path animation
   - wholesale (page-wholesale): form field gains accent ink line that scales from left on focus
   - visit (page-visit):     visit-cards stagger in with a 1deg micro-rotation when revealed
*/

/* 8.3 home: count-up animation is JS-driven (see scripts.js). Add a subtle
   warm wash behind each numeral so the count-up reads as deliberate. */
body.page-home .trust-item strong {
  transition: color 0.3s ease;
}

/* 8.3 roasts: bag rotates 2deg on card hover. Existing .roast-card-photo img
   already carries scale(1.07) on hover; add rotation alongside it. */
body.page-roasts .roast-card .roast-card-photo img {
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
body.page-roasts .roast-card:hover .roast-card-photo img {
  transform: scale(1.07) rotate(2deg);
}
body.page-roasts .roast-card:nth-child(even):hover .roast-card-photo img {
  transform: scale(1.07) rotate(-2deg);
}

/* 8.3 beans: origin-card top accent bar fills left-to-right on hover with
   eased ease-out (override Wave 3's opacity fade for a more deliberate
   "ink drawing in" effect). */
body.page-beans .origin-card::before {
  opacity: 1;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}
body.page-beans .origin-card:hover::before {
  transform: scaleX(1);
  opacity: 1;
}

/* 8.3 story: tartan strip "weave-in" on first paint. The top strip clip-paths
   in left-to-right over 1.2s. Footer strip held static so the effect bookends
   the page without doubling. Honors reduced-motion. */
@keyframes tartan-weave-in {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
body.page-story .tartan-strip--top {
  animation: tartan-weave-in 1.2s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* 8.3 wholesale: form-field accent ink line scales from left on focus. Each
   .field gets an underline pseudo that draws in as the user lands on it. */
body.page-wholesale .contact-form .field {
  position: relative;
}
body.page-wholesale .contact-form .field::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  height: 2px; width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
  border-radius: 0 0 var(--radius) var(--radius);
}
body.page-wholesale .contact-form .field:focus-within::after {
  transform: scaleX(1);
}

/* Visit-card reveal removed: the data-reveal mechanism was stranding
   cards 2-5 at opacity 0 even after data-reveal="seen" was set by the
   IntersectionObserver. Live-debugged in the browser; the !important
   override worked but isolating the root cause cost more time than it
   was worth. Force visible state, no entrance animation. */
body.page-visit .visit-card[data-reveal],
body.page-visit .visit-card[data-reveal="seen"] {
  opacity: 1 !important;
  transform: none !important;
}

/* 8.4 Tap-target floor 44×44px on mobile. Bumps:
   - .btn padding 14→14 (font 13→14 raises content height to ~44)
   - .sticky-cta a: min-height 48 (was ~36, mobile critical)
   - .faq-item summary: min-height 44 (was ~25)
   - .footer-socials a: 44×44 (was 38×38)
   - .nav-mobile-socials a: 44×44
   - .visit-card-form input: min-height 44 (was ~36)
   - .newsletter-form button: font 13→14 + same padding raises content
   - .nav-mobile-panel a: padding stays (already 14+17+14 = 45)
   - .nav-cta: bumped padding to clear 44 (was 33)
   Conversion-surface font-size raised in 8.6 below; that interacts with 8.4. */
.faq-item summary { min-height: 44px; }
.footer-socials a { width: 44px; height: 44px; }
.nav-mobile-socials a { min-height: 44px; padding: 12px 16px; }
.visit-card-form input[type="email"] { min-height: 44px; }
.contact-form input,
.contact-form textarea { min-height: 44px; }
.btn { min-height: 44px; }
.nav-cta { min-height: 40px; padding: 12px 20px; }
.newsletter-form button { min-height: 44px; }

/* 8.6 No text under 14px in any conversion surface. Helper labels and footer
   fine-print (Oswald tracked uppercase eyebrows) keep their existing micro-
   typography per Wave 2.7. Conversion-surface bumps: */
.btn { font-size: 14px; letter-spacing: 0.1em; }       /* primary + outline buttons */
.btn-primary, .btn-outline-light { font-size: 14px; }   /* explicit reinforcement */
.nav-cta { font-size: 14px; letter-spacing: 0.1em; }   /* desktop nav CTA */
.newsletter-form button { font-size: 14px; letter-spacing: 0.1em; }
@media (max-width: 540px) {
  .hero-phone-line { font-size: 14px; padding: 11px 16px; }
}

/* 8.7 Sticky CTA never overlaps a primary CTA. Body padding-bottom already
   clears the bar at 70px on ≤880px; bump to 80px to cover the 48px sticky cell
   + 16px breathing space + a 16px shadow allowance. */
@media (max-width: 880px) {
  body { padding-bottom: 80px; }
}

/* Wave 8 reduced-motion guards: skip all per-page delights (counter, bag
   rotation, beans ink-fill, story tartan weave-in, wholesale field-line,
   visit stagger). Honors prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) {
  body.page-roasts .roast-card:hover .roast-card-photo img,
  body.page-roasts .roast-card:nth-child(even):hover .roast-card-photo img {
    transform: none;
  }
  body.page-beans .origin-card::before {
    opacity: 1;
    transform: scaleX(0);
    transition: none;
  }
  body.page-beans .origin-card:hover::before {
    transform: scaleX(1);
    transition: none;
  }
  body.page-story .tartan-strip--top {
    animation: none;
  }
  body.page-wholesale .contact-form .field::after {
    transition: none;
  }
  body.page-visit .visit-card[data-reveal],
  body.page-visit .visit-card[data-reveal="seen"] {
    transform: none;
    transition: opacity 0.2s ease;
  }
}

