/* ==========================================================================
   Villa Breakfast · base: fallback faces, reset, type, layout, a11y, motion
   ========================================================================== */
/* Self-hosted variable fonts (SIL OFL 1.1, licences in assets/fonts). Latin subset.
   Bricolage is instanced to opsz 96 · wght 600–800 · wdth 75–100 (70KB instead of 131KB). */
@font-face{font-family:"Bricolage Grotesque";src:url(../fonts/bricolage-grotesque-latin-var.woff2) format("woff2");font-weight:600 800;font-stretch:75% 100%;font-display:swap}
@font-face{font-family:"Manrope";src:url(../fonts/manrope-latin-var.woff2) format("woff2");font-weight:200 800;font-display:swap}
/* Heading max-widths are in em, not ch: ch follows whichever face is showing and would re-wrap on swap.
   Metric-matched local fallbacks so the font swap does not re-wrap lines. Widths measured against Bricolage at
   wdth ~78: a narrow system face at 88%, or (no narrow face installed) Arial Bold at 72%. Overrides keep the line box. */
@font-face{font-family:"CB Display Fallback";src:local("Arial Narrow Bold"),local("ArialNarrow-Bold"),local("Liberation Sans Narrow Bold"),local("Roboto Condensed Bold");font-weight:800;size-adjust:88%;ascent-override:100%;descent-override:26%}
@font-face{font-family:"CB Display Fallback Wide";src:local("Arial Bold"),local("Arial-BoldMT"),local("Helvetica Bold"),local("Roboto Bold");font-weight:800;size-adjust:72%;ascent-override:123%;descent-override:32%}
@font-face{font-family:"CB Body Fallback";src:local("Arial"),local("Helvetica"),local("Roboto");size-adjust:104%;ascent-override:96%;descent-override:27%}

*,*::before,*::after{box-sizing:border-box}
/* The tap highlight is off for the whole document, and it has to be off here rather than
   on the buttons. Every tap on this site is read by a listener on the document - one
   listener for a category of twenty rows instead of twenty - and iOS takes a document
   with a click listener on it to mean the document is the thing being tapped, so it
   paints its grey highlight over that element's box: the page, header to footer, from one
   tap on a 48px plus. Nothing else on the site wants the native highlight either; what
   the buttons want instead is their own pressed state, which is in components.css. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:96px;-webkit-tap-highlight-color:transparent}
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{margin:0;min-height:100vh;background:var(--bg);color:var(--ink);font:500 var(--fs-body)/var(--lh-body) var(--font-body);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:clip}
img,svg,picture,video{display:block;max-width:100%}
img{height:auto}
svg{flex-shrink:0}
a{color:inherit;text-decoration-thickness:.08em;text-underline-offset:.18em}
button,input,select,textarea{font:inherit;color:inherit;letter-spacing:inherit}
button{cursor:pointer}
button:disabled,[aria-disabled="true"]{cursor:not-allowed}
h1,h2,h3,h4,.h1,.h2,.h3,.h4{margin:0;font-family:var(--font-display);font-weight:800;font-variation-settings:"wdth" var(--wdth-display),"opsz" 96;letter-spacing:var(--track-head);line-height:var(--lh-head);text-wrap:balance}
h1,.h1{font-size:var(--fs-h1)}
h2,.h2{font-size:var(--fs-h2)}
h3,.h3{font-size:var(--fs-h3);letter-spacing:-.015em}
h4,.h4{font-size:var(--fs-h4);letter-spacing:-.01em;line-height:1.1}
p{margin:0 0 1em;text-wrap:pretty}
p:last-child{margin-bottom:0}
ul,ol{margin:0;padding:0}
dialog{padding:0;border:0;color:inherit;max-width:none;max-height:none}
dialog::backdrop{background:rgba(42,27,20,.55)}
summary{cursor:pointer}
table{border-collapse:collapse}
[hidden]{display:none!important}
strong,b{font-weight:800}

/* ---- Focus: brand ring, visible on every surface ---- */
:focus-visible{outline:3px solid var(--focus);outline-offset:3px;border-radius:6px}
.on-dark{--focus:var(--sun)}
.on-dark :focus-visible{outline-color:var(--sun)}

/* ---- Accessibility helpers ---- */
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:fixed;left:12px;top:-80px;z-index:100;padding:12px 20px;border-radius:var(--r-pill);background:var(--espresso);color:var(--paper);font-weight:800;text-decoration:none;transition:top var(--dur-2)}
.skip-link:focus{top:12px}

/* ---- Layout ---- */
.cb-wrap{width:100%;max-width:calc(var(--maxw) + var(--gutter)*2);margin-inline:auto;padding-inline:var(--gutter)}
.cb-wrap--narrow{max-width:calc(880px + var(--gutter)*2)}
.cb-section{padding-block:var(--section);position:relative}
.cb-section--tight{padding-block:calc(var(--section)*.6)}
.bg-sun{background:var(--sun)}
.bg-sun-soft{background:var(--sun-soft)}
.bg-cream{background:var(--cream)}
.bg-paper{background:var(--paper)}
.bg-pool{background:var(--pool)}
.bg-espresso{background:var(--espresso);color:var(--cream)}
.bg-olive-soft{background:var(--olive-soft)}
.stack>*+*{margin-top:var(--stack,var(--s2))}
.prose{max-width:var(--maxw-text);font-size:1.0625rem}
.prose h2{font-size:var(--fs-h3);margin:1.6em 0 .5em}
.prose h3{font-size:1.5rem;margin:1.4em 0 .4em}
.prose ul{padding-left:1.2em;margin:0 0 1em}
.prose li+li{margin-top:.35em}

/* ---- Type utilities ---- */
.display{font-family:var(--font-display);font-weight:800;font-variation-settings:"wdth" var(--wdth-tight),"opsz" 96;letter-spacing:var(--track-display);line-height:var(--lh-tight)}
.eyebrow{display:inline-flex;align-items:center;gap:8px;margin:0 0 var(--s2);font-size:var(--fs-xs);font-weight:800;letter-spacing:var(--track-eyebrow);text-transform:uppercase}
.eyebrow svg{width:18px;height:18px;color:var(--terracotta)}
.on-dark .eyebrow svg{color:var(--sun)}
.lead{font-size:var(--fs-lead);line-height:1.5;font-weight:500;max-width:46ch}
.muted{color:var(--ink-2)}
.small{font-size:var(--fs-sm)}
.nowrap{white-space:nowrap}
.tnum{font-variant-numeric:tabular-nums}

/* ---- Reveal on scroll (JS adds .is-in; no-JS and reduced motion show everything) ---- */
.js [data-reveal]{opacity:0;transform:translateY(24px);transition:opacity var(--dur-3) var(--ease-out),transform var(--dur-3) var(--ease-out);transition-delay:calc(var(--i,0)*70ms)}
.js [data-reveal].is-in{opacity:1;transform:none}

@keyframes cb-pop{0%{transform:scale(.6)}60%{transform:scale(1.15)}100%{transform:scale(1)}}
/* The nudge the sticky bar gives when something lands in the basket. It plays on the bar's
   button and not on the bar, because the bar's own transform is what slides it into view. */
@keyframes cb-bump{0%{transform:none}30%{transform:translateY(-5px) scale(1.025)}62%{transform:translateY(2px) scale(.995)}100%{transform:none}}
@keyframes cb-spin{to{transform:rotate(360deg)}}
@keyframes cb-marquee{to{transform:translateX(-50%)}}
@keyframes cb-pulse{0%{box-shadow:0 0 0 0 rgba(196,70,31,.55)}100%{box-shadow:0 0 0 14px rgba(196,70,31,0)}}
@keyframes cb-shimmer{to{background-position:-200% 0}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .js [data-reveal]{opacity:1;transform:none}
}
figure{margin:0}
