/* ============================================================
   ALWAYS SOMETHING SAUCE — "From the Foothills" prototype
   Shared stylesheet. Design system from the homepage mockup,
   externalized and extended for the full multi-page prototype.
   Palette: forest greens, dawn mist, harvest gold, chili red, cream.
   ============================================================ */
:root{
  --forest-900:#16291f; --forest-700:#244536; --forest-600:#2f5a44; --forest-500:#3c7155;
  --mist:#d6e4e1; --sky-1:#cfe0e2; --sky-2:#e9ede2;
  --gold:#d8a23f; --gold-deep:#8a5f16; /* 4.5:1+ on paper/white/cream-2 (was #bd8526 = 3.0:1) */
  --chili:#c0392b; --chili-deep:#9c2b1f;
  --cream:#f8f3e8; --cream-2:#f1e9d8; --paper:#fbf7ee;
  --ink:#23302a; --ink-soft:#4f5e54; --line:#e2d8c4;
  /* Edges of things you type into or tap (the ZIP box, the quantity steppers). --line is a
     divider tone at 1.41:1 on white, which vanishes in sun; a control's edge needs 3:1
     (WCAG 1.4.11). #7c8168 is 4.04:1 on white and 3.78:1 on paper. */
  --field-edge:#7c8168;
  --maxw:1120px; --r:14px; --shadow:0 10px 30px rgba(22,41,31,.10); --shadow-sm:0 4px 14px rgba(22,41,31,.08);
  --serif:Georgia,'Times New Roman',serif;
  --sans:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* The header is sticky (64px + its 1px rule), so anything the browser scrolls into view for
   keyboard focus or an in-page jump has to stop below it, or it lands underneath (WCAG 2.2
   2.4.11). One offset here serves every anchor; targets must not add scroll-margin on top. */
html{scroll-padding-top:80px}
body{margin:0;font-family:var(--sans);color:var(--ink);background:var(--paper);line-height:1.6;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:var(--serif);line-height:1.15;margin:0 0 .4em;font-weight:700}
h2{font-size:1.9rem;color:var(--forest-700)}
p{margin:0 0 1em}
a{color:var(--forest-600);text-decoration:none}
/* body-copy links carry an underline (colour alone was 1.2-1.8:1 against the text); buttons never do */
.prose a:not(.btn),.qa a,.callout a:not(.btn),.post a:not(.btn),.pspec a,.pshort a,main p a:not(.btn){text-decoration:underline;text-underline-offset:.15em;text-decoration-thickness:1px}
.btn{text-decoration:none}
img{max-width:100%;height:auto;display:block}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
.section{padding:60px 0}
.eyebrow{font-family:var(--sans);text-transform:uppercase;letter-spacing:.14em;font-size:.74rem;font-weight:700;color:var(--gold-deep);margin-bottom:10px}
.center{text-align:center}
.lead{font-size:1.12rem;color:var(--ink-soft);max-width:62ch}
.center .lead{margin-left:auto;margin-right:auto}
.skip{position:absolute;left:-999px}
.skip:focus{left:8px;top:8px;background:#fff;padding:10px 14px;border-radius:8px;z-index:100}

/* buttons */
.btn{display:inline-block;border:0;cursor:pointer;font-family:var(--sans);font-weight:700;font-size:1rem;padding:14px 24px;border-radius:999px;transition:transform .15s ease,box-shadow .15s ease,background .15s ease;min-height:48px;text-align:center}
.btn-primary{background:var(--chili);color:#fff;box-shadow:var(--shadow-sm)}
.btn-primary:hover{background:var(--chili-deep);transform:translateY(-2px)}
.btn-ghost{background:transparent;color:#fff;border:2px solid rgba(255,255,255,.8)}
.btn-ghost:hover{background:rgba(255,255,255,.14);transform:translateY(-2px)}
.btn-dark{background:var(--forest-600);color:#fff}
.btn-dark:hover{background:var(--forest-700);transform:translateY(-2px)}
/* A sauce that is sold out. Flat and neutral so it never reads as a live buy button: --ink-soft on
   --cream-2 is about 5.8:1, and the inset ring (not a border) keeps the button the same size as
   its Add to Cart sibling. Scoped to .btn-soldout on purpose: no global :disabled rule, which
   would also restyle the cart's Checkout button while it is redirecting. */
.btn-soldout{background:var(--cream-2);color:var(--ink-soft);box-shadow:inset 0 0 0 1px var(--field-edge);cursor:not-allowed}

/* prototype banner */
.proto{background:repeating-linear-gradient(45deg,#2f5a44,#2f5a44 14px,#28503c 14px,#28503c 28px);color:#fff;text-align:center;font-size:.82rem;padding:8px 14px;font-weight:600;letter-spacing:.02em}
.proto b{color:var(--gold)}

/* header / nav */
header.site{position:sticky;top:0;z-index:40;background:rgba(251,247,238,.94);backdrop-filter:saturate(140%) blur(8px);border-bottom:1px solid var(--line)}
.nav{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:64px;position:relative}
.brand{display:flex;align-items:center;gap:10px;font-family:var(--serif);font-weight:700;color:var(--forest-700);font-size:clamp(.9rem,3.6vw,1.02rem);line-height:1.2;letter-spacing:.01em}
.brand img{width:38px;height:38px;border-radius:50%;object-fit:cover}
.menu{display:none;gap:22px;align-items:center}
.menu a{color:var(--ink);font-weight:600;font-size:.95rem}
.menu a:hover,.menu a.active{color:var(--chili)}
.nav-right{display:flex;align-items:center;gap:14px}
.cart{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:44px;min-height:44px;color:var(--forest-700);font-weight:700;background:none;border:0;cursor:pointer;font-size:.95rem}
.hamb{background:none;border:0;cursor:pointer;color:var(--forest-700);padding:6px;min-height:44px;min-width:44px}
@media(min-width:860px){.menu{display:flex}.hamb{display:none}}
/* mobile dropdown */
.menu.open{display:flex;flex-direction:column;align-items:stretch;gap:0;position:absolute;top:100%;left:0;right:0;background:var(--paper);border-bottom:1px solid var(--line);box-shadow:var(--shadow);padding:6px 20px 12px}
.menu.open a{padding:14px 2px;border-bottom:1px solid var(--line);font-size:1rem}
.menu.open a:last-child{border-bottom:0}

/* generic page hero (interior pages) */
.page-hero{position:relative;color:#fff;background:linear-gradient(180deg,#1c3a2c,#16291f);overflow:hidden}
.page-hero .wrap{position:relative;z-index:2;padding:54px 20px}
.page-hero .eyebrow{color:var(--gold)}
.page-hero h1{font-family:var(--serif);font-size:2.1rem;max-width:20ch;margin:0 0 .3em;color:#fff}
.page-hero p{color:#cdded3;max-width:60ch;margin:0}
.page-hero .pinerow{position:absolute;left:0;right:0;bottom:0;z-index:1;opacity:.5}
@media(min-width:760px){.page-hero h1{font-size:2.7rem}}

/* breadcrumb */
.crumb{font-size:.82rem;color:var(--ink-soft);padding:14px 0 0}
.crumb a{color:var(--forest-600)}

/* Homepage: real bottles, real farmers, and a direct route to the lineup. */
.home-hero{background:var(--cream);border-bottom:1px solid var(--line);overflow:hidden}
.home-hero-grid{display:grid;grid-template-columns:1fr;gap:16px;padding-top:40px;padding-bottom:32px}
.home-hero-copy{position:relative;z-index:2}
.home-hero-copy .eyebrow{font-size:.69rem;letter-spacing:.12em;margin-bottom:24px}
.hero-category{font-size:.8rem;font-weight:700;text-transform:uppercase;letter-spacing:.1em;color:var(--forest-700);margin-bottom:12px}
.home-hero h1{font-size:clamp(3.6rem,8vw,6rem);line-height:.96;letter-spacing:-.065em;color:var(--forest-900);max-width:10ch;margin:0 0 24px}
.home-hero h1 strong{display:block;color:var(--chili);font-weight:700;font-style:italic}
.home-hero .sub{font-size:1.05rem;max-width:42ch;color:var(--ink-soft);margin:0 0 28px}
.hero-cta{display:flex;align-items:center;flex-wrap:wrap;gap:12px 24px}
.text-link{display:inline-flex;align-items:center;gap:12px;min-height:48px;font-size:.94rem;font-weight:700;text-decoration:underline;text-underline-offset:5px}
.home-hero .btn{border-radius:4px;box-shadow:none;padding:15px 24px}
.home-hero .btn span{margin-left:24px}
.hero-collage{position:relative;min-height:380px;margin:12px -4px 0}
.hero-bottle-photo{position:absolute;top:10px;left:10%;width:65%;max-width:350px;aspect-ratio:3/4;transform:rotate(-7deg);border:8px solid var(--paper);box-shadow:0 16px 28px rgba(22,41,31,.16);background:var(--paper);overflow:hidden}
.hero-bottle-photo img{width:100%;height:100%;object-fit:cover}
.hero-farm-photo{position:absolute;right:0;bottom:6px;width:45%;max-width:250px;margin:0;transform:rotate(6deg);background:var(--paper);border:6px solid var(--paper);box-shadow:0 8px 18px rgba(22,41,31,.16)}
.hero-farm-photo img{width:100%;aspect-ratio:4/3;object-fit:cover}
.hero-farm-photo figcaption{font-size:.6rem;text-align:center;padding:7px 0 3px;font-weight:700;color:var(--forest-900)}
.farm-stamp{position:absolute;right:0;top:0;margin:0;width:110px;height:110px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;background:var(--forest-700);color:var(--cream);border-radius:50%;transform:rotate(10deg);border:1px solid var(--cream);outline:4px solid var(--forest-700)}
.farm-stamp>span{font-size:.49rem;text-transform:uppercase;letter-spacing:.07em;text-align:center;max-width:90%}
.farm-stamp strong{font-family:var(--serif);font-size:1.75rem;line-height:1}
.farm-stamp strong span{font-size:.8rem;margin-left:3px}
.photo-caption{position:absolute;bottom:0;left:5%;font-family:var(--serif);font-size:.85rem;font-style:italic;transform:rotate(-7deg)}
.origin-strip{background:var(--forest-900);color:var(--cream)}
.origin-strip .wrap{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 16px;padding-top:16px;padding-bottom:16px}
.origin-strip span{font-family:var(--serif);font-size:1.1rem}
.origin-strip a{color:var(--cream);font-size:.82rem;display:inline-flex;gap:10px;align-items:center;text-decoration:underline;text-underline-offset:4px;min-height:44px}
.origin-strip .wrap>span{display:flex;align-items:center;min-height:44px}
.section-heading{display:flex;flex-direction:column;gap:12px;margin-bottom:26px}
.section-heading h2{font-size:clamp(2rem,3.5vw,2.8rem);letter-spacing:-.04em;margin-bottom:0}
.section-heading .lead{font-size:1rem;margin:0}
.sauce-filters{display:flex;gap:8px;flex-wrap:wrap;margin:20px 0 24px}
.sauce-filters[hidden],.card[hidden]{display:none}
.sauce-filters button{font:600 .86rem var(--sans);color:var(--forest-700);background:transparent;border:1px solid var(--forest-700);border-radius:3px;min-height:44px;padding:10px 20px;cursor:pointer}
.sauce-filters button[aria-pressed="true"]{color:var(--paper);background:var(--forest-700)}
.sauce-filters button:hover{border-color:var(--chili);box-shadow:inset 0 -3px var(--chili)}
.filter-status{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.lineup-footnote{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;padding-top:24px;margin-top:24px;border-top:1px solid var(--line)}
.lineup-footnote p{font-size:.9rem;color:var(--ink-soft);max-width:54ch;margin:0}
.process-section{background:var(--cream-2)}
.process-section .lead{margin-left:auto;margin-right:auto}
.process-section h2{font-size:clamp(2rem,3.5vw,2.8rem);letter-spacing:-.035em}
.process-section .steps{gap:32px}
.process-section .step{border:0;border-top:1px solid #cbbf9f;border-radius:0;box-shadow:none;background:transparent;padding:24px 0}
.process-section .step .num{background:none;color:var(--chili);border:1px solid var(--chili);font-family:var(--sans);font-size:.85rem;margin-bottom:20px}
:focus-visible{outline:3px solid var(--chili);outline-offset:4px}
/* Chili is 2.82:1 on forest-900 and 2.28:1 on the band's #1c3a2c; a focus ring needs 3:1
   against what is next to it (WCAG 1.4.11). Gold is 6.68:1 and 5.42:1. Gold on white is
   only 2.29:1, so this stays scoped to the dark surfaces. */
footer.site :focus-visible,.origin-strip :focus-visible,.foot-band :focus-visible,.page-hero :focus-visible{outline-color:var(--gold)}
@media(min-width:760px){
  .home-hero-grid{grid-template-columns:1.05fr 1fr;align-items:center;gap:30px;padding-top:60px;padding-bottom:70px}
  .hero-collage{min-height:480px;margin:0}
  .hero-bottle-photo{left:4%;top:22px;width:74%}
  .hero-farm-photo{width:53%;bottom:18px}
  .farm-stamp{width:126px;height:126px;right:-3%;top:0}
  .farm-stamp>span{font-size:.56rem}
  .farm-stamp strong{font-size:2rem}
  .photo-caption{bottom:-14px;left:0}
  .section-heading{flex-direction:row;align-items:end;justify-content:space-between;gap:30px}
  .section-heading .lead{max-width:34ch}
}
@media(min-width:1000px){
  .hero-collage{min-height:500px}
  .hero-bottle-photo{left:7%;width:70%}
  .hero-farm-photo{right:0;bottom:6px}
  .farm-stamp{right:3%;top:4px}
}
@media(max-width:359px){
  .home-hero h1{font-size:3.3rem}
  .hero-collage{min-height:340px}
  .farm-stamp{width:96px;height:96px}
  .farm-stamp>span{font-size:.43rem}
  .hero-cta{gap:10px}
  .origin-strip .wrap{column-gap:8px}
  .origin-strip span{font-size:.92rem}
}

/* sauce grid + cards */
.grid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(min-width:760px){.grid{grid-template-columns:repeat(5,1fr)}}
.grid.shop{gap:20px}
@media(min-width:760px){.grid.shop{grid-template-columns:repeat(3,1fr)}}
.card{background:var(--paper);border:1px solid var(--line);border-radius:4px;overflow:hidden;box-shadow:none;transition:transform .18s ease,box-shadow .18s ease;display:flex;flex-direction:column}
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow)}
.card .pic{position:relative;aspect-ratio:3/4;background:var(--cream-2);display:flex;align-items:center;justify-content:center;padding:12px}
.card .pic img{width:100%;height:100%;object-fit:contain;transition:transform .25s ease}
.card:hover .pic img{transform:scale(1.04)}
.badge{position:absolute;top:8px;left:8px;z-index:2;background:rgba(20,41,31,.82);color:#fff;font-size:.7rem;font-weight:700;padding:4px 8px;border-radius:999px;letter-spacing:.02em}
.card .body{padding:16px 12px;display:flex;flex-direction:column;gap:4px;flex:1}
.card h3{font-size:1.04rem;margin:0;color:var(--forest-700)}
.card .meta{font-size:.82rem;color:var(--ink-soft)}
.card .price{font-size:1.1rem;font-weight:700;color:var(--ink);margin:8px 0}
.card-flavor{font-family:var(--serif);font-size:1rem;line-height:1.4;color:var(--forest-900);margin:8px 0 2px}
.card-pairing{font-size:.72rem;line-height:1.5;color:var(--ink-soft);margin:0 0 10px}
.peppers{font-size:.8rem;letter-spacing:1px;line-height:1}
.pep-on{filter:none}.pep-off{opacity:.22;filter:grayscale(1)}
.card .btn{margin-top:auto;width:100%;padding:11px;font-size:.86rem;border-radius:3px;box-shadow:none}
.confirm{color:#b8341f;font-size:.72rem;font-weight:600}

/* heat scale */
.heat{background:var(--cream-2)}
.heat-rows{max-width:680px;margin:0 auto;display:flex;flex-direction:column;gap:10px}
.hrow{display:grid;grid-template-columns:1.3fr 2.2fr auto;align-items:center;gap:12px;background:#fff;border:1px solid var(--line);border-radius:12px;padding:12px 14px}
.hrow .nm{font-weight:700;color:var(--forest-700)}
.meter{display:flex;gap:5px}
.dot{width:100%;height:12px;border-radius:4px;background:#e7ddc8}
.meter.lv .dot.on{background:linear-gradient(90deg,var(--gold),var(--chili))}
.hrow .lvl{font-size:.8rem;font-weight:700;color:var(--chili-deep);white-space:nowrap}

/* process steps */
.steps{display:grid;grid-template-columns:1fr;gap:18px;margin-top:24px}
@media(min-width:760px){.steps{grid-template-columns:repeat(3,1fr)}}
.steps.four{}
@media(min-width:760px){.steps.four{grid-template-columns:repeat(2,1fr)}}
.step{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:22px;box-shadow:var(--shadow-sm)}
.step .num{width:38px;height:38px;border-radius:50%;background:var(--forest-600);color:#fff;display:flex;align-items:center;justify-content:center;font-family:var(--serif);font-weight:700;margin-bottom:12px}
.step h3{color:var(--forest-700);font-size:1.2rem}

/* foothills band */
.foot-band{position:relative;color:#eaf2ec;background:linear-gradient(180deg,#1c3a2c,#16291f);overflow:hidden}
.foot-band .wrap{position:relative;z-index:2}
.foot-band h2{color:#fff}
.foot-band .lead{color:#cdded3}
.pinerow{position:absolute;left:0;right:0;bottom:0;z-index:1;opacity:.5}
.grid2{display:grid;grid-template-columns:1fr;gap:24px;align-items:center}
@media(min-width:820px){.grid2{grid-template-columns:1.1fr .9fr}}
.statline{display:flex;gap:26px;flex-wrap:wrap;margin-top:18px}
.stat .big{font-family:var(--serif);font-size:1.7rem;color:var(--gold)}
.stat .lab{font-size:.76rem;text-transform:uppercase;letter-spacing:.08em;color:#bcd0c4}
.band-photo{border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow);aspect-ratio:4/3;background:#234538}
.band-photo img{width:100%;height:100%;object-fit:cover}

/* markets */
.mk{display:grid;grid-template-columns:1fr;gap:16px;margin-top:8px}
@media(min-width:680px){.mk{grid-template-columns:1fr 1fr}}
.mcard{border:1px solid var(--line);border-radius:var(--r);padding:20px;background:#fff;box-shadow:var(--shadow-sm);position:relative}
.mcard.next{border-color:var(--gold);box-shadow:0 0 0 2px rgba(216,162,63,.35),var(--shadow-sm)}
.mcard .tag{position:absolute;top:-11px;left:16px;background:var(--gold);color:#3a2c08;font-size:.7rem;font-weight:800;padding:3px 10px;border-radius:999px;letter-spacing:.04em}
/* Heading LEVEL varies by page depth (ledger W3-7); the look must not. font-size is
   pinned to the 1.17em an <h3> gets from the UA sheet, so the homepage h3 and the
   /markets h2 render the same. */
.mcard h2,.mcard h3{font-size:1.17em;color:var(--forest-700);margin-bottom:2px}
.mcard .day{color:var(--chili-deep);font-weight:700}

/* notes / blog cards */
.notes{display:grid;grid-template-columns:1fr;gap:18px;margin-top:10px}
@media(min-width:760px){.notes{grid-template-columns:repeat(3,1fr)}}
.note{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-sm);transition:transform .18s;display:flex;flex-direction:column}
.note:hover{transform:translateY(-4px)}
.note .pic{aspect-ratio:16/10;background:linear-gradient(160deg,#eef3ec,#e2eadd);position:relative;overflow:hidden}
.note .pic img{width:100%;height:100%;object-fit:cover}
.note .nb{padding:14px}
.note .k{font-size:.72rem;text-transform:uppercase;letter-spacing:.08em;color:var(--gold-deep);font-weight:700}
.note h2,.note h3{font-size:1.05rem;color:var(--forest-700);margin:4px 0 6px}
.note p{font-size:.9rem;color:var(--ink-soft);margin:0}

/* app teaser */
.app{background:var(--forest-600);color:#eaf2ec}
.app .wrap{display:grid;grid-template-columns:1fr;gap:20px;align-items:center}
@media(min-width:820px){.app .wrap{grid-template-columns:1.3fr .7fr}}
.app h2{color:#fff}.app .lead{color:#d6e6db}
.phone{justify-self:center;width:200px;height:330px;border-radius:26px;border:8px solid #0f2017;background:linear-gradient(180deg,#2f5a44,#1c3a2c);box-shadow:var(--shadow);display:flex;align-items:center;justify-content:center;color:#cfe;font-size:.8rem;text-align:center;padding:16px}

/* newsletter */
.news{background:var(--cream-2);text-align:center}
.fineprint{font-size:.78rem;color:var(--ink-soft)}

/* prose (content pages) */
.prose{max-width:74ch;margin:0 auto}
.prose h2{font-size:1.5rem;margin-top:1.4em}
.prose h3{font-size:1.15rem;color:var(--forest-700);margin-top:1.3em}
.prose h2.ship-sec{font-size:1.15rem;color:var(--forest-700);margin-top:1.3em}
.prose p,.prose li{font-size:1.04rem;color:#33433b}
.prose ul{padding-left:1.2em}
.prose li{margin-bottom:.4em}
.qa{border-top:1px solid var(--line);padding:18px 0}
.qa h2,.qa h3{font-size:1.15rem;color:var(--forest-700);margin:0 0 .3em}
.callout{background:var(--cream-2);border-left:4px solid var(--gold);border-radius:8px;padding:14px 18px;margin:18px 0}

/* product page */
.product{display:grid;grid-template-columns:1fr;gap:28px;margin-top:18px}
@media(min-width:820px){.product{grid-template-columns:1fr 1fr;gap:40px;align-items:start}}
.gallery .main{aspect-ratio:1/1;background:linear-gradient(160deg,#f4efe2,#e7efe2);border:1px solid var(--line);border-radius:var(--r);display:flex;align-items:center;justify-content:center;padding:24px;overflow:hidden}
.gallery .main img{width:100%;height:100%;object-fit:contain}
.thumbs{display:flex;gap:10px;margin-top:10px}
.thumb{flex:1;aspect-ratio:1/1;border:1px solid var(--line);border-radius:10px;background:linear-gradient(160deg,#f4efe2,#e7efe2);display:flex;align-items:center;justify-content:center;padding:8px;font-size:.66rem;color:#6b5a33;text-align:center}
.thumb img{width:100%;height:100%;object-fit:contain}
.pinfo h1{font-family:var(--serif);font-size:2rem;color:var(--forest-700);margin:0 0 .15em}
.pinfo .pmeta{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.pinfo .pprice{font-size:1.5rem;font-weight:700;color:var(--ink)}
.heatbadge{display:inline-flex;align-items:center;gap:6px;background:var(--cream-2);border:1px solid var(--line);border-radius:999px;padding:6px 12px;font-weight:700;font-size:.85rem;color:var(--forest-700)}
.pshort{font-size:1.1rem;color:#33433b}
.addbar{display:flex;gap:10px;flex-wrap:wrap;margin:16px 0}
.addbar .btn{flex:1;min-width:180px}
.trustlist{list-style:none;padding:0;margin:10px 0 0;font-size:.92rem;color:var(--ink-soft)}
.trustlist li{padding:3px 0}
.pspec{border-top:1px solid var(--line);margin-top:22px;padding-top:16px}
.pspec h2{font-size:1.15rem;margin:0 0 .4em}
.stickybar{position:sticky;bottom:0;z-index:30;background:rgba(251,247,238,.96);backdrop-filter:blur(6px);border-top:1px solid var(--line);padding:10px 0;display:none}
.stickybar .wrap{display:flex;align-items:center;justify-content:space-between;gap:12px}
.stickybar .sb-name{font-weight:700;color:var(--forest-700)}
/* While the bar is up (app.js sets body.has-sticky), keyboard focus has to stop above it
   too, or Tab parks a link underneath (WCAG 2.2 2.4.11), and the toast lifts clear of it.
   scroll-padding only works on the root scroller, hence html:has(). The bar measures 69px
   at 390px wide and 85px at 320px, where "Add to Cart" wraps onto two lines; 96px clears
   both with a gap. The toast's own 24px plus a 72px lift = 96px (see #toast). */
@media(max-width:819px){.stickybar.on{display:block}
  html:has(>body.has-sticky){scroll-padding-bottom:96px}
  body.has-sticky #toast{--toast-lift:calc(72px + env(safe-area-inset-bottom, 0px))}}

/* blog post */
.post{max-width:72ch;margin:0 auto}
.post .meta{color:var(--ink-soft);font-size:.9rem;margin-bottom:6px}
.post .feat{border-radius:var(--r);overflow:hidden;aspect-ratio:16/9;background:#234538;margin:8px 0 22px}
.post .feat img{width:100%;height:100%;object-fit:cover}
.post p,.post li{font-size:1.06rem;color:#33433b}

/* footer */
footer.site{background:var(--forest-900);color:#cdded3}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:26px 20px;padding:46px 20px 24px}
@media(min-width:760px){.fgrid{grid-template-columns:2fr 1fr 1fr 1fr}}
/* Was `footer h4`. The three column headings are now <h2 class="fh"> so the outline
   never skips a level (ledger W3-7 = W4-7, lane S4-4). line-height is stated because an
   <h4> inherited body's 1.6 while h1,h2,h3 above sets 1.15 — without it the columns
   would shift a pixel or two. */
footer .fh{color:#fff;font-family:var(--sans);font-size:.78rem;line-height:1.6;text-transform:uppercase;letter-spacing:.12em;margin:0 0 4px}
footer a{color:#cdded3;display:block;padding:10px 0;min-height:44px;font-size:.92rem}
footer a:hover{color:var(--gold)}
.fbrand{font-family:var(--serif);color:#fff;font-size:1.2rem;margin-bottom:8px}
.tagline{border-top:1px solid rgba(255,255,255,.12);text-align:center;padding:16px;font-size:.82rem;letter-spacing:.04em;color:#adc3b4}

/* reveal animation (JS + motion allowed only) */
.js .reveal{opacity:0;transform:translateY(18px);transition:opacity .6s ease,transform .6s ease}
.js .reveal.in{opacity:1;transform:none}

/* homepage intro pixel-reveal — only rendered on the homepage when show_intro_animation is true.
   Decorative overlay layered above the hero photo but below the scrim/text (z-index:1), so it
   never blocks the CTAs; pure CSS, plays once and settles transparent; disabled under reduced motion. */
/* intro — the logo dissolves to reveal the site. Homepage only, once a session.
   The curtain animation ends in visibility:hidden, so the page is revealed by CSS
   alone even if the JS never runs; pointer-events:none keeps it click-through. */
/* The full-bleed cream field clears via background-color (not opacity), so the mark keeps
   its own alpha instead of fading with the layer. A soft cream halo stays under the mark
   while it dissolves — the logo never breaks up directly over the photo — then the halo
   itself evaporates last. */
/* Timing lives in one place, and it now has a CEILING: --settle + the curtain duration
   must stay at or under 1s. This overlay is position:fixed over the whole viewport, so
   every millisecond it is up is a millisecond the homepage is blank to a first-time
   visitor — the market-QR and Instagram landing page. Audit S3-1 measured the old
   sequence at 2982ms on a 4x-throttled phone (SI 6.8s on live / vs 1.6s on /shop, which
   ships 148KB MORE). The knobs below total exactly 1.00s:
       mark-at = .18 + .04 + (.25 * .4)                       = .32s
       settle  = mark-at + .16 + .16 + .24 - .18 (overlap)    = .70s
       curtain = .30s                                          -> 1.00s
   What was traded: the dogs-to-mark convergence now reads as one quick pass instead of
   a held beat. --hold is still the beat that matters — if the ceiling ever moves, spend
   the new budget there first. --overlap is how far the mark's dissolve runs into the
   field clearing; it is what keeps this one motion rather than two at this speed. */
.intro{--photo-in:.18s;--photo-hold:.04s;--morph:.25s;--in:.16s;--hold:.16s;--out:.24s;--overlap:.18s;
  --mark-at:calc(var(--photo-in) + var(--photo-hold) + var(--morph) * .4);
  --settle:calc(var(--mark-at) + var(--in) + var(--hold) + var(--out) - var(--overlap));
  position:fixed;inset:0;z-index:120;display:grid;place-items:center;background-color:var(--cream);pointer-events:none;
  animation:asf-curtain .30s cubic-bezier(.4,0,.2,1) var(--settle) forwards}
/* The dogs become the mark. Not a true morph — that needs frame-by-frame art or video —
   but a convergence: the photo desaturates toward the badge's palette and shrinks to the
   mark's exact size while the mark fades up underneath it. The composition does the rest,
   because the crop puts two faces turned toward each other where the badge puts two
   wolves. If the photo is missing the markup omits it and the intro is the mark alone. */
.intro-photo{position:absolute;width:clamp(190px,48vw,320px);aspect-ratio:1;border-radius:50%;object-fit:cover;
  box-shadow:0 10px 40px rgba(22,41,31,.26);opacity:0;will-change:opacity,transform,filter;
  animation:asf-photo-in var(--photo-in) cubic-bezier(.2,.7,.3,1) forwards,
            asf-photo-out var(--morph) cubic-bezier(.4,0,.2,1) calc(var(--photo-in) + var(--photo-hold)) forwards}
@keyframes asf-photo-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}
@keyframes asf-photo-out{from{opacity:1;transform:scale(1);filter:saturate(1) brightness(1)}
  to{opacity:0;transform:scale(.42);filter:saturate(.15) brightness(.8)}}
.intro-halo{position:absolute;width:min(74vw,430px);aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,var(--cream) 33%,rgba(248,243,232,.72) 52%,rgba(248,243,232,0) 72%);animation:asf-halo .34s ease-out var(--settle) forwards}
/* The mark lightens as it breaks up (brightness), evaporating toward the cream rather
   than darkening into a smudge, and it finishes before the field starts clearing — the
   hero photo has faces near centre, and a blurred mark lingering there reads as a
   redaction. Dissolve first, then reveal; the 60ms overlap keeps it one motion. */
.intro-mark{width:clamp(96px,19vw,140px);height:auto;border-radius:50%;opacity:0;will-change:opacity,transform,filter;
  animation:asf-mark-in var(--in) cubic-bezier(.2,.7,.3,1) var(--mark-at) forwards,
            asf-mark-out var(--out) cubic-bezier(.4,0,.7,.4) calc(var(--mark-at) + var(--in) + var(--hold)) forwards}
@keyframes asf-mark-in{from{opacity:0;transform:scale(.94)}to{opacity:1;transform:scale(1)}}
@keyframes asf-mark-out{0%{opacity:1;transform:scale(1) translateY(0);filter:blur(0) brightness(1)}100%{opacity:0;transform:scale(1.2) translateY(-10px);filter:blur(10px) brightness(1.6)}}
@keyframes asf-halo{to{opacity:0;transform:scale(1.3)}}
@keyframes asf-curtain{0%{background-color:var(--cream)}86%{background-color:rgba(248,243,232,0)}100%{background-color:rgba(248,243,232,0);visibility:hidden}}
html:not(.js) .intro,.no-intro .intro{display:none}
@media(prefers-reduced-motion:reduce){.intro{display:none}}

/* toast. It only reports, so it never takes a tap: without pointer-events:none it sat on
   the sticky Add to Cart for 2.6s and swallowed a quick second tap. width:max-content stops
   left:50% from capping it at half the screen and wrapping "Habanero added to cart" onto two
   lines; max-width still holds it inside the screen. On product pages the SHOWN position
   lifts above the sticky bar by --toast-lift (see .stickybar). The lift lives in the shown
   transform, not in bottom: the hidden toast keeps its text after it slides away, and with a
   raised bottom the 100%+40px slide no longer cleared the screen, so it parked on the bar. */
#toast:empty{display:none}
#toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%) translateY(calc(100% + 40px));background:var(--ink);color:#fff;padding:12px 18px;border-radius:999px;font-size:.9rem;font-weight:600;box-shadow:var(--shadow);z-index:90;transition:transform .3s ease;width:max-content;max-width:90vw;text-align:center;pointer-events:none}
#toast.show{transform:translateX(-50%) translateY(calc(-1 * var(--toast-lift, 0px)))}

/* reduced motion */
@media(prefers-reduced-motion:reduce){
  .js .reveal{opacity:1!important;transform:none!important;transition:none!important}
  .card,.card .pic img,.note,.btn{transition:none!important}
  html{scroll-behavior:auto}
  #toast{transition:none}
}

/* ---------- cart ---------------------------------------------------------- */
/* Tap targets stay >=44px throughout: this is used one-handed, outdoors, often
   with cold or dirty hands (AGENTS.md accessibility bar). */
.cart{position:relative}
.cart-count{position:absolute;top:2px;right:0;min-width:18px;height:18px;padding:0 5px;
  border-radius:999px;background:var(--chili);color:#fff;font-size:.72rem;line-height:18px;
  font-weight:700;text-align:center}
.cart-lines{margin-top:22px}
.cart-line{display:grid;grid-template-columns:72px 1fr auto;gap:14px;align-items:center;
  padding:16px 0;border-bottom:1px solid var(--line)}
.cart-thumb{border-radius:var(--r);object-fit:cover;background:var(--mist)}
.cart-info{min-width:0}
.cart-name{font-weight:700;color:var(--forest-700);text-decoration:none;font-size:1.05rem}
.cart-name:hover{text-decoration:underline}
.cart-meta{font-size:.9rem;color:var(--ink-soft);margin-top:3px}
.qty{display:inline-flex;align-items:center;gap:2px;border:1px solid var(--field-edge);
  border-radius:999px;background:var(--paper)}
.qty-btn{min-width:44px;min-height:44px;border:0;background:none;cursor:pointer;
  font-size:1.25rem;line-height:1;color:var(--forest-700);border-radius:999px}
.qty-btn:hover{background:var(--mist)}
.qty-n{min-width:2ch;text-align:center;font-weight:700;font-variant-numeric:tabular-nums}
.cart-line-total{font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap}
.cart-remove{grid-column:2/-1;justify-self:start;min-height:44px;border:0;background:none;
  cursor:pointer;color:var(--ink-soft);font-size:.9rem;text-decoration:underline;padding:0}
.cart-remove:hover{color:var(--chili-deep)}
.cart-summary{margin-top:26px;background:var(--paper);border:1px solid var(--line);
  border-radius:var(--r);padding:20px}
.cart-subtotal-row{display:flex;justify-content:space-between;align-items:baseline;
  font-size:1.15rem}
.cart-subtotal-row strong{font-size:1.5rem;font-variant-numeric:tabular-nums}
/* USPS shipping under Subtotal (SITE-UX-1). Display only — cart.js fills it from
   window.ASF_SHIP_TIERS; the server still picks the charge. Quieter than Subtotal on purpose:
   it is the price IF they ship, and pickup is free. */
.cart-ship{margin-top:10px}
.cart-ship[hidden]{display:none}
.cart-ship-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px}
.cart-ship-row strong{font-size:1.15rem;font-variant-numeric:tabular-nums;white-space:nowrap}
.cart-ship-note{font-size:.9rem;color:var(--ink-soft);margin-top:4px}
/* The USPS rates on /shop and the product pages: keep "$24 for 5–6" on one line — at 320px the
   en dash otherwise breaks "5–" from "6". */
.ship-rate{white-space:nowrap}
.cart-note{font-size:.9rem;color:var(--ink-soft);margin-top:10px}
.cart-error{margin-top:14px;padding:12px 14px;border-radius:var(--r);
  background:#fdecec;color:#8a1c1c;border:1px solid #f3c9c9;font-size:.95rem}
.btn-checkout{width:100%;margin-top:16px}
.cart-secure{font-size:.85rem;color:var(--ink-soft);margin-top:10px;text-align:center}
@media (min-width:600px){
  .cart-line{grid-template-columns:72px 1fr auto auto auto;gap:18px}
  .cart-remove{grid-column:auto;justify-self:end}
  .btn-checkout{width:auto;min-width:220px}
}
.pickup-box{margin-top:18px;padding-top:16px;border-top:1px solid var(--line)}
.pickup-label{display:block;font-weight:700;color:var(--forest-700);margin-bottom:8px}
/* Text fields. The 16px font-size is load-bearing, not taste: iOS Safari zooms the whole
   page when a focused field computes under 16px, and /cart has no maximum-scale to stop it,
   so the ZIP box used to throw the customer into a pinch-back mid-checkout (audit S7-1 —
   measured 11px in WebKit, 13.3px in Chromium/Firefox, from the UA default alone). */
.asf-input{font-family:var(--sans);font-size:16px;line-height:1.3;color:var(--ink);
  background:#fff;border:1px solid var(--field-edge);border-radius:10px;padding:10px 12px;
  min-height:44px;width:100%;-webkit-appearance:none;appearance:none}
/* opacity:1 overrides Firefox's default placeholder fade; --ink-soft is 6.86:1 on white.
   The hint itself is words ("5-digit ZIP"), so it cannot be mistaken for a typed value. */
.asf-input::placeholder{color:var(--ink-soft);opacity:1}
.asf-input:focus-visible{outline:2px solid var(--forest-600);outline-offset:2px;
  border-color:var(--forest-600)}
.pickup-zip{max-width:180px}
.pickup-msg{font-size:.9rem;margin-top:8px;min-height:1.2em}
.pickup-msg.is-yes{color:var(--forest-600);font-weight:700}
.pickup-msg.is-no{color:var(--ink-soft)}

/* ---------- farm stand (weekly produce, live from Stripe) ------------------ */
.farmstand-loading{color:var(--ink-soft);font-size:.95rem}
/* auto-fit COLLAPSES empty tracks, so a single produce item was stretching to the full
   row width — a lone bag of kale rendered as a billboard. Below 760px a full-width card
   is correct on a phone; at desktop the grid matches .grid.shop exactly (repeat(3,1fr)),
   so one produce card is the same size as one sauce card no matter how many there are. */
.produce-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:16px;margin-top:18px}
@media(min-width:760px){.produce-grid{grid-template-columns:repeat(3,1fr);gap:20px}}
.produce-card{background:var(--paper);border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;display:flex;flex-direction:column}
.produce-pic{width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--mist)}
.produce-body{padding:14px 16px 16px;display:flex;flex-direction:column;gap:8px;flex:1}
.produce-name{font-size:1.05rem;color:var(--forest-700);margin:0}
.produce-meta{font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.produce-note{font-size:.88rem;color:var(--ink-soft);margin:0;flex:1}
.produce-body .btn{margin-top:4px;width:100%}
.tag-pickup{display:inline-block;margin-left:6px;padding:2px 8px;border-radius:999px;
  background:var(--mist);color:var(--forest-700);font-size:.72rem;font-weight:700;
  text-transform:uppercase;letter-spacing:.03em;vertical-align:middle}
.cart-thumb-veg{width:72px;height:96px;border-radius:var(--r);background:var(--mist);
  display:flex;align-items:center;justify-content:center}

/* ---------- forced colors (Windows High Contrast) --------------------------- */
/* The solid buttons declare border:0 and carry their shape entirely in the
   background. Forced-colors mode replaces every background with a system colour,
   so Checkout and Add to Cart render as plain text with no edge at all — on the
   money path, for the users who most need edges (audit S4-3). A system-coloured
   border restores the shape while leaving the user's own palette in charge; that
   is also why forced-color-adjust is deliberately NOT set on any of these. */
@media (forced-colors: active){
  .btn{border:1px solid ButtonText}
  .cart-count{border:1px solid ButtonText}
  .asf-input{border:1px solid FieldText}
}
