  :root{
    --svh: 1svh; /* JS-off fallback; JS freezes this to px at load */
    --ink:#2a2620; --bg:#faf6ee; --paper:#fffdf9; --cream:#f2ebdb;
    --olive:#525937; --olive-d:#3c4127; --olive-l:#6f7847;
    --terra:#c4623a; --terra-d:#a84f2c;
    --muted:#6f6959; --rule:#e7ddc8; --tan:#d8cdb6;
    --display:"Cormorant Garamond",Georgia,serif;
    --caps:"Marcellus",Georgia,serif;
    --body:"Jost",system-ui,sans-serif;
  }
  *{box-sizing:border-box}
  html{-webkit-text-size-adjust:100%;overflow-x:clip}
  body{margin:0;background:var(--bg);color:var(--ink);font-family:var(--body);font-weight:300;font-size:18px;line-height:1.7;overflow-x:clip;max-width:100%}
  .lenis.lenis-smooth{scroll-behavior:auto}
  h1,h2,h3{font-family:var(--display);font-weight:600;line-height:1.04;margin:0}
  a{color:inherit;text-decoration:none}
  img{max-width:100%;display:block}
  .wrap{max-width:1180px;margin:0 auto;padding:0 clamp(20px,5vw,32px)}
  .eyebrow{font-family:var(--caps);letter-spacing:.32em;text-transform:uppercase;font-size:.74rem;color:var(--terra-d)}
  .skip{position:absolute;left:-999px;top:0;background:var(--olive);color:#fff;padding:.7rem 1.1rem;z-index:400;border-radius:0 0 4px 0}
  .skip:focus{left:0}
  .vh{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
  :focus-visible{outline:3px solid var(--terra-d);outline-offset:3px}
  /* Olive/dark surfaces need the light ring; terra-d on olive is 1.34:1. */
  .ctaband :focus-visible,.reserve :focus-visible,.feature-grid .txt :focus-visible,
  .formcard :focus-visible,footer :focus-visible,.phero :focus-visible,.hero :focus-visible,
  .btn:focus-visible{outline-color:#e6c39f}
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:.6rem;min-height:50px;padding:0 2.1rem;border-radius:999px;font-family:var(--caps);letter-spacing:.16em;text-transform:uppercase;font-size:.76rem;border:1px solid var(--olive);background:var(--olive);color:#f7f4ea;cursor:pointer;transition:background .35s,color .35s,transform .35s,border-color .35s,box-shadow .35s}
  .btn:hover{background:var(--terra);border-color:var(--terra);color:#fff;transform:translateY(-3px);box-shadow:0 12px 26px -12px rgba(196,98,58,.6)}
  .btn.ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.6)}
  .btn.ghost:hover{background:#fff;color:var(--olive);border-color:#fff}

  /* progress + dots */
  .progress{position:fixed;top:0;left:0;height:3px;width:100%;background:var(--terra);transform:scaleX(0);transform-origin:0 50%;z-index:350}
  .dots{position:fixed;right:22px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:13px;z-index:180}
  .dots button{width:9px;height:9px;border-radius:50%;border:1px solid var(--olive);background:transparent;padding:0;cursor:pointer;transition:transform .3s,background .3s}
  .dots button.active{background:var(--olive);transform:scale(1.4)}
  @media(max-width:860px){.dots{display:none}}
  html:not(.js) .progress,html:not(.js) .dots{display:none}

  /* intro curtain */
  .intro{position:fixed;inset:0;z-index:300;background:var(--bg);display:flex;align-items:center;justify-content:center}
  html:not(.js) .intro{display:none}
  .intro-inner{display:flex;flex-direction:column;align-items:center;gap:1.6rem;text-align:center;padding:2rem}
  .intro-eyebrow{font-family:var(--caps);letter-spacing:.34em;text-transform:uppercase;font-size:.74rem;color:var(--muted);opacity:0}
  .intro-word{font-family:var(--display);font-weight:600;font-size:clamp(3.6rem,13vw,10rem);line-height:.9;letter-spacing:.005em;color:var(--ink);overflow:hidden}
  .intro-word .i{font-style:italic;color:var(--terra)}
  .intro-bar{display:block;width:clamp(120px,22vw,240px);height:2px;background:var(--rule);overflow:hidden}
  .intro-bar-fill{display:block;height:100%;width:0;background:var(--olive)}

  /* nav */
  header.nav{position:fixed;inset:0 0 auto 0;z-index:200;transition:background .4s,box-shadow .4s,border-color .4s;border-bottom:1px solid transparent}
  /* NO backdrop-filter here (removed 2026-09-09). The background is 94% opaque,
     so a blur behind it has almost nothing left to show — screenshots of the
     header strip mid-scroll on a 390x844@3 phone, with the blur live and with it
     forced to none, came back PIXEL-IDENTICAL (ImageMagick RMSE 0, AE 0, with the
     computed style verified as blur(10px) then none, the nav .solid, and a photo
     behind it). It is not a design element; it is an invisible full-width
     backdrop re-blur on every scroll frame. Do not put it back without a
     screenshot diff showing it does something. */
  header.nav.solid{background:rgba(250,246,238,.94);border-color:var(--rule);box-shadow:0 6px 24px -18px rgba(42,38,32,.4)}
  .nav .wrap{display:flex;align-items:center;justify-content:space-between;min-height:74px;gap:.6rem;flex-wrap:wrap}
  /* At 2x text the bar cannot fit one line, and html{overflow-x:clip} means
     the overflow is not even scrollable — the hamburger was half off-screen.
     Wrapping lets it drop to a second row instead of vanishing. Paired with
     the tighter pill below so it does NOT wrap at normal size on a 320px
     phone, where the row would otherwise need 344px. */
  @media(max-width:420px){.nav .wrap .btn{padding:0 1.1rem;letter-spacing:.1em}}
  .brand{display:inline-flex;align-items:center}
  /* flex-shrink:0 — at 320px the header row wants 344px (logo 84 + Reserve pill
     128 + toggle 44 + gaps), so flex stole the 24px shortfall from the LOGO and
     squashed the brand 28% out of aspect. Measured 60.2x30 against an intrinsic
     84.1x30. The pill and toggle may compress; the brand mark may not. */
  .brand-img{height:30px;width:auto;display:block;flex-shrink:0;transition:filter .4s}
  /* The logo artwork is near-white, for the transparent-over-hero state. Both
     the solid header AND the open mobile menu put it on cream, where white on
     cream is invisible — the brand mark vanished on the nav screen itself.
     Reported independently by two auditors 2026-08-10. */
  header.nav.solid .brand-img,
  body.menu-open .brand-img{filter:invert(1) brightness(.28) sepia(.35) saturate(1.5) hue-rotate(35deg)}
  .nav nav{display:flex;gap:2rem;align-items:center}
  .nav nav a.lnk{position:relative;font-family:var(--caps);font-size:.76rem;letter-spacing:.18em;text-transform:uppercase;color:#f3ecdb;transition:color .25s}
  header.nav.solid nav a.lnk{color:var(--ink)}
  .nav nav a.lnk::after{content:"";position:absolute;left:0;bottom:-6px;width:0;height:1px;background:var(--terra);transition:width .3s}
  .nav nav a.lnk:hover{color:var(--terra-d)}.nav nav a.lnk:hover::after{width:100%}
  @media(max-width:860px){.nav nav a.lnk{display:none}}

  /* ACT 1 — sticky hero */
  .act1{position:relative;height:calc(122 * var(--svh))}
  .hero{position:sticky;top:0;height:calc(100 * var(--svh));display:flex;align-items:center;justify-content:center;text-align:center;color:#fbf6ec;overflow:hidden}
  .hero__bg{position:absolute;inset:0;z-index:0}
  .hero__bg img{width:100%;height:100%;object-fit:cover;animation:kenburns 22s ease-in-out infinite alternate}
  .hero__veil{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(42,38,32,.34) 0%,rgba(42,38,32,.2) 38%,rgba(60,65,39,.64) 100%)}
  /* Text over photography needs BOTH a veil and a shadow: a veil alone cannot
     cover a bright highlight landing behind one word. Measured 2026-08-10. */
  .hero-eyebrow,.hero-tagline,.hero-lede,.wordmark,.scrollcue{text-shadow:0 2px 20px rgba(0,0,0,.6)}
  @keyframes kenburns{from{transform:scale(1.02)}to{transform:scale(1.13)}}
  .hero-inner{position:relative;z-index:2;padding:118px 28px 92px}
  .hero-mark{width:74px;height:auto;margin:0 auto 1.4rem;filter:drop-shadow(0 6px 18px rgba(0,0,0,.4))}
  .hero-eyebrow{color:#f0d9bf;margin-bottom:1.2rem;display:block;font-family:var(--caps);letter-spacing:.32em;text-transform:uppercase;font-size:.74rem}
  .wordmark{font-family:var(--display);font-size:clamp(4.2rem,16vw,11.5rem);font-weight:600;letter-spacing:.01em;line-height:.86;text-shadow:0 2px 40px rgba(0,0,0,.35)}
  .wordmark .i{font-style:italic;color:#e9bd96;font-weight:500}
  .hero-tagline{font-family:var(--caps);letter-spacing:.32em;text-transform:uppercase;font-size:clamp(.78rem,2.3vw,1.05rem);margin-top:1.5rem;color:#f2ead7}
  .hero-lede{font-family:var(--display);font-style:italic;font-size:clamp(1.1rem,2.6vw,1.5rem);margin-top:.9rem;color:#f0e6d2}
  .hero-cta{margin-top:2.4rem;display:flex;gap:1rem;justify-content:center;flex-wrap:wrap}
  .scrollcue{position:absolute;bottom:24px;left:50%;transform:translateX(-50%);z-index:2;font-family:var(--caps);letter-spacing:.3em;text-transform:uppercase;font-size:.62rem;color:#ecdcc4;display:flex;flex-direction:column;align-items:center;gap:.5rem}
  .scrollcue i{width:1px;height:42px;background:linear-gradient(#ecdcc4,transparent);animation:cue 2.4s ease-in-out infinite;transform-origin:top}
  @keyframes cue{0%,100%{transform:scaleY(.4);opacity:.4}50%{transform:scaleY(1);opacity:1}}
  /* OFF SCREEN IS IDLE. app.js hangs `.is-idle` on every `data-idle` element the
     moment it leaves the viewport (+150px), which parks its keyframes instead of
     compositing them at nobody. Measured 2026-09-07: kenburns was still running
     9,980px above the fold at the bottom of the home page, and the scroll cue
     with it. !important because the `animation` SHORTHAND above resets
     animation-play-state to `running`, and it wins on specificity otherwise.
     The selector reaches DESCENDANTS AND PSEUDO-ELEMENTS on purpose: on
     hagawebb.com the same cue is a `::after` two levels down, and a bare
     `.is-idle` would have matched nothing there while looking fixed. One idiom
     on both sites, so neither can drift. */
  .is-idle,.is-idle *,.is-idle::before,.is-idle::after,
  .is-idle *::before,.is-idle *::after{animation-play-state:paused!important}

  /* manifesto — pinned word-fill */
  .manifesto{position:relative;height:calc(200 * var(--svh));background:var(--paper)}
  .manifesto-sticky{position:sticky;top:0;height:calc(100 * var(--svh));display:flex;align-items:center;justify-content:center;background:var(--paper);overflow:hidden}
  .manifesto-sticky .wrap{max-width:1000px}
  [data-manifesto]{font-family:var(--display);font-weight:600;font-size:clamp(2rem,5.4vw,4.4rem);line-height:1.18;letter-spacing:.005em;color:var(--ink)}
  [data-manifesto] .hl{color:var(--terra);font-style:italic}
  html:not(.js) .manifesto{height:auto}html:not(.js) .manifesto-sticky{height:auto;position:static;padding:calc(14 * var(--svh)) 0}

  /* marquee */
  .marquee{background:var(--olive);color:#eadfae;overflow:hidden;white-space:nowrap}
  /* No will-change: the Web-Animations transform promotes this row while it
     runs, and app.js now pauses it off screen so the layer can be released.
     Parked here it was a permanent layer (measured 2026-09-07). */
  .marquee-inner{display:flex;width:max-content}
  .mseg{display:inline-flex;align-items:center;flex:0 0 auto}
  .mseg>span{font-family:var(--display);font-style:italic;font-size:clamp(1.5rem,3.4vw,2.6rem);padding:.85rem 1.3rem}
  .mseg>span.dot{color:#c7b888;font-style:normal}

  section{position:relative}
  .pad{padding:clamp(78px,11vw,140px) 0}
  /* NO will-change here. It used to sit on [data-anim] unconditionally, i.e. 26
     elements on the home page held a compositor layer for the life of the page
     and nothing ever released it — will-change is a hint to promote BEFORE an
     animation and drop AFTER, not a speed switch. app.js now sets it on the
     tween and clears it onComplete. Diagnosed 2026-08-10 (mobile jank). */

  .zoom{overflow:hidden}
  .zoom img{transition:transform 1s cubic-bezier(.2,.7,.2,1)}
  .zoom:hover img{transform:scale(1.06)}

  /* intro/story */
  .intro-grid{display:grid;grid-template-columns:1.02fr .98fr;gap:clamp(2.4rem,6vw,5.5rem);align-items:center}
  .story h2{font-size:clamp(2.6rem,6vw,4.4rem);font-weight:600}
  .story h2 em{font-style:italic;color:var(--terra)}
  .story p{max-width:46ch;color:#5a5346;margin:1.4rem 0 0}
  .eyebrow-row{display:flex;align-items:center;gap:1rem;margin-bottom:1.4rem}
  .eyebrow-row .ln{width:46px;height:1px;background:var(--terra)}
  .figure{position:relative;border-radius:3px;box-shadow:0 30px 60px -34px rgba(42,38,32,.45)}
  .figure img{width:100%;height:clamp(420px,56vw,620px);object-fit:cover;border-radius:3px}
  .figure figcaption{position:absolute;left:16px;bottom:14px;font-family:var(--caps);letter-spacing:.16em;text-transform:uppercase;font-size:.64rem;color:#fff;background:rgba(60,65,39,.86);padding:.4rem .7rem;border-radius:2px;backdrop-filter:blur(3px)}
  .pillars{display:flex;gap:2.2rem;margin-top:2.4rem;flex-wrap:wrap}
  .pillars div{flex:1;min-width:140px}
  .pillars .n{font-family:var(--display);font-style:italic;font-size:2.3rem;color:var(--olive);line-height:1}
  .pillars .t{display:block;margin-top:.4rem;font-size:.94rem;color:#5a5346}
  @media(max-width:820px){.intro-grid{grid-template-columns:1fr}.figure{order:-1}}

  /* menu — alternating editorial rows on dark olive */
  .menu{background:var(--olive-d);color:#f1ead7}
  .menu .head{text-align:center;margin-bottom:clamp(3rem,6vw,4.6rem)}
  .menu .head .eyebrow{color:#f2dcc2}
  .menu h2{font-size:clamp(2.6rem,6vw,4.4rem);color:#fbf5e6}
  .menu .sub{color:#cfc6ac;max-width:50ch;margin:1rem auto 0}
  .menu-rows{display:flex;flex-direction:column;gap:clamp(2.4rem,4.5vw,4rem)}
  .mrow{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(2.2rem,5vw,5rem);align-items:center;background:#efede3;border:1px solid rgba(42,38,32,.08);border-radius:14px;padding:clamp(1.6rem,3vw,3rem);box-shadow:0 40px 90px -55px rgba(0,0,0,.6)}
  .mrow__img{border-radius:8px;overflow:hidden;box-shadow:0 30px 56px -30px rgba(42,38,32,.4)}
  .mrow__img img{width:100%;height:clamp(460px,50vw,700px);object-fit:cover}
  .mrow:nth-of-type(even) .mrow__img{order:2}
  .mrow__num{font-family:var(--display);font-style:italic;font-size:clamp(3.6rem,6.5vw,5.4rem);color:var(--terra);line-height:.9;display:block}
  .mrow__body{padding:clamp(.4rem,2vw,1.4rem)}
  .mrow__body .eyebrow{color:var(--olive);display:block;margin:.7rem 0 .25rem}
  .mrow__body h3{font-size:clamp(2.6rem,5vw,3.6rem);color:var(--ink);margin-bottom:1.2rem}
  .menu .dish{padding:.95rem 0;border-bottom:1px dotted var(--rule)}
  .menu .dish:last-child{border-bottom:0}
  .menu .dish .nm{font-family:var(--display);font-size:1.55rem;font-weight:600;color:var(--ink)}
  .menu .dish .ds{display:block;font-size:.95rem;color:#7a7263;margin-top:.18rem;line-height:1.55}
  .menu-note{text-align:center;margin-top:clamp(3rem,6vw,4.6rem);font-family:var(--caps);letter-spacing:.2em;text-transform:uppercase;font-size:.72rem;color:#b3a986}
  @media(max-width:780px){.mrow{grid-template-columns:1fr;gap:1.6rem;padding:1.3rem}.mrow:nth-of-type(even) .mrow__img{order:0}.mrow__img img{height:clamp(320px,72vw,460px)}}

  /* feature */
  .feature{background:var(--bg)}
  .feature-grid{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;border-radius:4px;overflow:hidden;box-shadow:0 30px 60px -34px rgba(42,38,32,.4)}
  .feature-grid .img{min-height:460px;overflow:hidden}
  /* will-change is set by the parallax tween and cleared when it leaves — see
     feature() in app.js. Parked here it also promoted a layer on TOUCH,
     where that tween never even runs. */
  .feature-grid .img img{width:100%;height:118%;object-fit:cover}
  .feature-grid .txt{background:var(--olive);color:#f3ecd6;padding:clamp(2.4rem,5vw,4rem);display:flex;flex-direction:column;justify-content:center}
  .feature-grid .txt .eyebrow{color:#f2dcc2}
  .feature-grid h2{font-size:clamp(2.4rem,5.5vw,3.8rem);color:#fbf5e6;margin:.8rem 0}
  .feature-grid h2 em{font-style:italic;color:#e6c39f}
  .feature-grid p{color:#e2dcc6;margin:0 0 1.8rem}
  .feature-grid .btn{align-self:flex-start;background:var(--terra);border-color:var(--terra);color:#fff}
  .feature-grid .btn:hover{background:#fff;color:var(--olive);border-color:#fff}
  @media(max-width:760px){.feature-grid{grid-template-columns:1fr}.feature-grid .img{min-height:300px}}

  /* gallery — auto-scrolling band (smooth, no scroll-jack / no tilt) */
  .work{background:var(--bg)}
  .ghead2{text-align:center;margin-bottom:clamp(2rem,4vw,3rem)}
  .ghead2 .eyebrow{display:block;margin-bottom:.6rem}
  .ghead2 h2{font-size:clamp(2.6rem,6vw,4.4rem)}
  .ghead2 p{color:#6b6353;margin:1rem auto 0;max-width:46ch}
  .gmarquee{overflow-x:auto;overflow-y:hidden;width:100%;scrollbar-width:none;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  .gmarquee::-webkit-scrollbar{display:none}
  .gtrack{display:flex;width:max-content}
  .gseg{display:inline-flex;gap:18px;padding-right:18px;flex:0 0 auto}
  .gseg figure{flex:0 0 auto;width:clamp(260px,26vw,360px);margin:0;border-radius:4px;overflow:hidden;box-shadow:0 22px 46px -26px rgba(42,38,32,.45)}
  .gseg figure img{width:100%;height:clamp(340px,40vw,470px);object-fit:cover;transition:transform 1s cubic-bezier(.2,.7,.2,1)}
  .gseg figure:hover img{transform:scale(1.05)}

  /* locations */
  .loc{background:var(--paper)}.loc .head{text-align:center}
  .loc-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.4rem,4vw,2.4rem);margin-top:2.8rem}
  @media(max-width:780px){.loc-grid{grid-template-columns:1fr}}
  .card{background:var(--bg);border:1px solid var(--rule);border-radius:4px;overflow:hidden;display:flex;flex-direction:column;transition:transform .4s,box-shadow .4s}
  .card:hover{transform:translateY(-5px);box-shadow:0 26px 50px -28px rgba(42,38,32,.4)}
  .card .ph{height:250px}.card .ph img{width:100%;height:100%;object-fit:cover}
  .card .body{padding:1.7rem 1.9rem 2rem}
  .card .caps{font-family:var(--caps);letter-spacing:.16em;text-transform:uppercase;color:var(--olive);font-size:.66rem;display:block;margin-bottom:.5rem}
  .card h3{font-size:2rem;margin-bottom:.6rem}
  .card p{margin:.15rem 0;color:#5a5346;font-size:.97rem}
  .card .ln{margin:1.1rem 0;height:1px;background:var(--rule)}
  .card a.tel{color:var(--terra-d);font-family:var(--caps);letter-spacing:.06em}
  .card .hours{font-size:.85rem;color:#6f6959;margin-top:.4rem}

  /* reserve */
  /* end-cap: reservation + footer together fill exactly one viewport, same dark olive */
  .endcap{min-height:calc(100 * var(--svh));display:flex;flex-direction:column}
  .reserve{background:var(--olive);color:#f3ecd6;text-align:center;flex:1 1 auto;display:flex;flex-direction:column;justify-content:center;padding:clamp(40px,calc(6 * var(--svh)),72px) 0}
  .reserve h2{font-size:clamp(2.6rem,6vw,4.2rem);color:#fbf5e6}.reserve h2 em{font-style:italic;color:#e6c39f}
  .reserve p{max-width:520px;margin:1.1rem auto 2.2rem;color:#dfd9c2}
  .resform{display:grid;grid-template-columns:1fr 1fr;gap:.9rem;max-width:620px;margin:0 auto}
  .resform .full{grid-column:1/-1}
  .resform input,.resform select{width:100%;min-height:52px;font-size:1rem;font-family:var(--body);padding:0 1.1rem;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.28);color:#fbf6ec;border-radius:6px}
  .resform select{appearance:none}.resform input::placeholder{color:#cdc7b3}
  .resform input:focus-visible,.resform select:focus-visible{outline:3px solid #e6c39f;outline-offset:2px}
  .reserve .btn{background:var(--terra);border-color:var(--terra);color:#fff}.reserve .btn:hover{background:#fff;color:var(--olive);border-color:#fff}
  .reserve .or{margin-top:1.5rem;font-size:.92rem;color:#dfd9c2}
  .reserve .or a{color:#f1d2b4;border-bottom:1px solid rgba(241,210,180,.5)}
  /* clause 1 booking terms — the colophon links here from all 17 pages.
     ⚠️ THIS BLOCK SITS ON THE LIGHT SECTION, not in .reserve. It was first
     written with .reserve's cream-on-olive palette and rendered pale grey on
     cream, which every automated check passed and one screenshot caught. */
  .bookterms{max-width:60ch;margin:2.4rem auto 0;text-align:left;color:#5a5346}
  .bookterms h3{font-family:var(--caps);letter-spacing:.08em;font-size:1rem;color:var(--terra-d);margin:0 0 .9rem;text-transform:uppercase}
  .bookterms ul{list-style:none;margin:0;padding:0}
  .bookterms li{margin:0 0 .7rem;padding-left:1.1rem;position:relative;font-size:.95rem;line-height:1.6}
  .bookterms li::before{content:"";position:absolute;left:0;top:.62em;width:5px;height:5px;border-radius:50%;background:var(--terra)}
  .bookterms li b{color:var(--ink);font-weight:600}
  .bookterms .note{color:var(--muted);font-size:.9rem;margin-top:1.1rem}
  .bookterms:target h3{outline:3px solid var(--terra);outline-offset:6px}
  @media(max-width:560px){.resform{grid-template-columns:1fr}}

  footer{background:var(--olive-d);color:#cfc7ad;padding:clamp(40px,calc(6 * var(--svh)),72px) 0 clamp(26px,calc(4 * var(--svh)),44px);font-size:.9rem}
  footer .top{display:flex;justify-content:space-between;gap:2.4rem;flex-wrap:wrap;align-items:flex-start}
  footer .brand img{height:clamp(34px,calc(4 * var(--svh)),46px);width:auto}
  footer .soc{display:flex;gap:.7rem}
  footer .soc a{width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;border:1px solid rgba(230,195,159,.35);border-radius:50%;color:#cfc7ad;transition:background .25s,color .25s,border-color .25s,transform .25s}
  footer .soc a:hover{background:#e6c39f;color:var(--olive-d);border-color:#e6c39f;transform:translateY(-2px)}
  footer .soc svg{width:18px;height:18px;display:block}
  /* clause 1 email sign-up — its own row between the columns and the colophon */
  footer .signup{display:flex;justify-content:space-between;align-items:flex-end;gap:1.6rem 2.4rem;flex-wrap:wrap;
    margin-top:2.6rem;padding-top:2rem;border-top:1px solid rgba(230,195,159,.22)}
  footer .signup b{font-family:var(--caps);letter-spacing:.06em}
  footer .signup .resform{grid-template-columns:minmax(0,1fr) auto;max-width:440px;margin:0;width:100%;gap:.7rem}
  footer .signup .resform .btn{min-height:52px;padding:0 1.4rem;white-space:nowrap;background:var(--terra);border-color:var(--terra);color:#fff}
  footer .signup .resform .btn:hover{background:#fff;color:var(--olive-d);border-color:#fff}
  footer .signup .formstatus{text-align:left;color:#cfc7ad}
  @media(max-width:560px){footer .signup .resform{grid-template-columns:1fr}}
  footer .cols{display:flex;gap:3rem;flex-wrap:wrap}
  footer .cols p{margin:0}
  footer .cols p a{display:inline-block;padding:.42rem 0;min-height:24px}
  footer .cols b{font-family:var(--caps);text-transform:uppercase;letter-spacing:.16em;font-size:.68rem;color:#e3dcc4;display:block;margin-bottom:.6rem;font-weight:400}
  footer .colophon{margin-top:2.4rem;padding-top:1.4rem;border-top:1px solid rgba(255,255,255,.12);font-size:.74rem;color:#c2b9a0}

  /* MOBILE: drop the sticky/pinned scroll scenes — they jolt when the address
     bar collapses (svh-pinned regions vs a growing viewport). Native flow scroll
     is smooth. (Reveal animations still fire on enter.)

     ⚠️ THIS CONDITION MUST STAY IDENTICAL TO `isTouch` IN app.js, which is
     `(pointer:coarse) || innerWidth < 861`. It was width-only until 2026-09-07,
     so a coarse-pointer device WIDER than 860px got the worst of both: measured
     at 900x500 (a phone held sideways) and 1024x768, `body.touch` was set — so
     the JS ran the touch path with its early-finishing manifesto scrub — while
     the CSS kept `.hero` sticky and `.manifesto` at 1000px/1536px of pinned
     scroll. The pinned scenes this block exists to remove were still there, on
     exactly the devices whose address bar does the collapsing. */
  @media(max-width:860px),(pointer:coarse){
    .act1{height:auto}
    .hero{position:relative;height:auto;min-height:calc(100 * var(--svh))}
    .manifesto{height:auto}
    .manifesto-sticky{position:static;height:auto;min-height:0;padding:calc(16 * var(--svh)) 0}
  }
  /* mobile polish */
  @media(max-width:560px){
    body{font-size:16px}
    .hero-inner{padding:104px 22px 80px}
    .hero-mark{width:60px}
    .wordmark{font-size:clamp(3.4rem,20vw,5.6rem)}
    .hero-tagline{letter-spacing:.22em}
    .hero-lede{font-size:1.05rem}
    [data-manifesto]{font-size:clamp(1.7rem,7vw,2.4rem);line-height:1.22}
    .marquee-inner span,.mseg>span{font-size:1.5rem;padding:.7rem 1rem}
    .mrow{padding:1.1rem}
    .mrow__img img{height:clamp(240px,64vw,360px)}
    .mrow__num{font-size:clamp(3rem,12vw,4rem)}
    .mrow__body{padding:.4rem 0 0}
    .mrow__body h3{font-size:clamp(2rem,8.5vw,2.7rem)}
    .menu .dish .nm{font-size:1.35rem}
    .gseg figure{width:80vw}
    .gseg figure img{height:64vw;min-height:300px}
    .feature-grid .img{min-height:240px}
    .reserve h2,.menu h2,.story h2,.loc .head h2,.ghead2 h2{font-size:clamp(2.2rem,9vw,3rem)}
    footer .top{gap:1.6rem}
    footer .cols{gap:2rem}
  }
  @media (prefers-reduced-motion: reduce){
    *{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
    .marquee-inner,.hero__bg img,.scrollcue i{animation:none}
    .wordmark{visibility:visible}
  }

/* ============================================================
   Multi-page additions (production site) — subpage hero, nav
   dropdown + hamburger, blog article, gallery grid, reels.
   ============================================================ */

/* nav: current page */
.nav nav a.lnk.on{color:var(--terra-d)}
.nav nav a.lnk.on::after{width:100%}

/* nav: menus dropdown (desktop) */
.navdrop{position:relative;display:inline-flex;align-items:center}
.navdrop>a.lnk{padding-bottom:2px}
.navdrop .drop{position:absolute;top:calc(100% + 14px);left:50%;transform:translate(-50%,8px);background:var(--paper);border:1px solid var(--rule);border-radius:6px;box-shadow:0 24px 48px -24px rgba(42,38,32,.35);padding:.6rem 0;min-width:210px;opacity:0;visibility:hidden;transition:opacity .25s,transform .25s,visibility .25s}
.navdrop:hover .drop,.navdrop:focus-within .drop{opacity:1;visibility:visible;transform:translate(-50%,0)}
.navdrop .drop a{display:block;padding:.55rem 1.3rem;font-family:var(--caps);font-size:.72rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink);transition:color .2s,background .2s}
.navdrop .drop a:hover{color:var(--terra-d);background:var(--bg)}
.navdrop .drop::before{content:"";position:absolute;top:-14px;left:0;right:0;height:14px}

/* nav: hamburger (mobile) */
.navtoggle{display:none;width:44px;height:44px;background:transparent;border:0;cursor:pointer;padding:10px;z-index:260;flex-direction:column;justify-content:center;gap:6px}
.navtoggle span{display:block;height:2px;width:100%;background:#f3ecdb;transition:transform .35s,opacity .35s,background .4s}
header.nav.solid .navtoggle span,body.menu-open .navtoggle span{background:var(--ink)}
body.menu-open .navtoggle span:nth-child(1){transform:translateY(8px) rotate(45deg)}
body.menu-open .navtoggle span:nth-child(2){opacity:0}
body.menu-open .navtoggle span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
.mnav{position:fixed;inset:0;z-index:250;background:var(--bg);display:flex;flex-direction:column;justify-content:center;padding:2rem clamp(24px,8vw,48px);opacity:0;visibility:hidden;transition:opacity .35s,visibility .35s}
body.menu-open .mnav{opacity:1;visibility:visible}
/* The links were direct flex children of .mnav until the a11y pass wrapped
   them in a <nav> landmark (2026-08-10) — which left the anchors as INLINE
   children of a plain block, so they reflowed horizontally instead of
   stacking. The landmark now carries the column layout itself. */
.mnav > nav{display:flex;flex-direction:column;width:100%}
/* The toggle lives INSIDE header.nav, so its own z-index cannot lift it above
   the .mnav overlay — a child never escapes its parent's stacking context.
   That is why the open menu had no visible X. Raise the HEADER while open. */
body.menu-open header.nav{z-index:260}
.mnav a{font-family:var(--display);font-weight:600;font-size:clamp(1.6rem,6.6vw,2.1rem);line-height:1.34;letter-spacing:.004em;color:var(--ink);padding:.28rem 0}
/* Sub-items: body face, sentence case, indented under Menus. The old treatment
   (1.15rem Marcellus, .18em tracking, uppercase) shouted louder than the
   parent items it sat beneath and made the stack hard to scan. */
.mnav a.sub{font-family:var(--body);font-weight:300;font-size:1rem;letter-spacing:.03em;text-transform:none;color:var(--muted);line-height:1.45;padding:.34rem 0 .34rem 1.05rem;border-left:1px solid var(--rule);margin-left:.2rem}
.mnav a.sub:first-of-type{margin-top:.15rem}
.mnav a.on{color:var(--terra-d)}
/* .mnav a wins on specificity over .btn, so the CTA inherited a 2.1rem display
   face inside a pill sized for .78rem caps — the text broke out of the button.
   Restore button typography explicitly. */
.mnav .mnav-cta{margin-top:1.9rem;align-self:flex-start;font-family:var(--caps);font-weight:400;font-size:.78rem;line-height:1;letter-spacing:.16em;text-transform:uppercase;padding:0 2.1rem;color:#f7f4ea}
@media(max-width:860px){.navtoggle{display:flex}}
@media(min-width:861px){.mnav{display:none}}

/* Native fallback for hash targets (JS goTo() handles the smooth case, this
   catches a plain browser jump before app.js runs). Matches navOffset(). */
[id]{scroll-margin-top:106px}

/* subpage hero (short) */
.phero{position:relative;min-height:calc(62 * var(--svh));display:flex;align-items:flex-end;color:#fbf6ec;overflow:hidden}
.phero.tall{min-height:calc(74 * var(--svh))}
.phero__bg{position:absolute;inset:0}
.phero__bg img{width:100%;height:100%;object-fit:cover}
.phero__veil{position:absolute;inset:0;background:linear-gradient(180deg,rgba(42,38,32,.42) 0%,rgba(42,38,32,.18) 45%,rgba(60,65,39,.72) 100%)}
.phero .eyebrow,.phero h1,.phero .lede{text-shadow:0 2px 20px rgba(0,0,0,.55)}
.phero .wrap{position:relative;z-index:2;padding-top:130px;padding-bottom:clamp(40px,7vw,72px);width:100%}
.phero .eyebrow{color:#f0d9bf;display:block;margin-bottom:.9rem}
.phero h1{font-size:clamp(2.8rem,7.5vw,5.4rem);color:#fbf5e6;max-width:18ch}
.phero h1 em{font-style:italic;color:#e9bd96}
.phero .lede{font-family:var(--display);font-style:italic;font-size:clamp(1.05rem,2.4vw,1.4rem);color:#f0e6d2;margin:.9rem 0 0;max-width:52ch}

/* light menu list (subpage, cream paper) */
.menulist{max-width:760px;margin:0 auto}
.menulist .dish{padding:1.15rem 0;border-bottom:1px dotted var(--rule)}
.menulist .dish:last-child{border-bottom:0}
.menulist .dish .nm{font-family:var(--display);font-size:1.55rem;font-weight:600;color:var(--ink)}
.menulist .dish .ds{display:block;font-size:.95rem;color:#7a7263;margin-top:.18rem;line-height:1.55}
.menulist h2.cat{font-size:clamp(1.9rem,4vw,2.6rem);margin:2.8rem 0 .6rem;color:var(--ink)}
.menulist h2.cat:first-child{margin-top:0}
.mnote{font-family:var(--display);font-style:italic;color:var(--muted);font-size:1.05rem}

/* menus landing cards */
.catgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(1.2rem,3vw,2rem)}
@media(max-width:700px){.catgrid{grid-template-columns:1fr}}
.catcard{position:relative;border-radius:6px;overflow:hidden;min-height:340px;display:flex;align-items:flex-end;color:#fbf6ec;box-shadow:0 26px 52px -30px rgba(42,38,32,.5)}
.catcard img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform 1.1s cubic-bezier(.2,.7,.2,1)}
.catcard:hover img{transform:scale(1.06)}
.catcard::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(42,38,32,0) 30%,rgba(42,38,32,.72) 100%)}
.catcard .cc{position:relative;z-index:2;padding:1.6rem 1.8rem}
.catcard .caps{font-family:var(--caps);letter-spacing:.2em;text-transform:uppercase;font-size:.66rem;color:#e9bd96;text-shadow:0 1px 10px rgba(0,0,0,.75);display:block;margin-bottom:.3rem}
.catcard h2{font-size:2.1rem;color:#fbf5e6}

/* blog */
.postgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:clamp(1.4rem,3vw,2.2rem)}
.article{max-width:720px;margin:0 auto}
.article .lead-img{border-radius:6px;overflow:hidden;box-shadow:0 30px 60px -34px rgba(42,38,32,.45);margin:0 0 2.6rem}
.article .lead-img img{width:100%;height:clamp(300px,44vw,460px);object-fit:cover}
.article h2{font-size:clamp(1.9rem,4.4vw,2.7rem);margin:2.6rem 0 1rem;line-height:1.12}
.article h2 em{font-style:italic;color:var(--terra)}
picture{display:contents}
.article p{color:#4e4739;margin:1.15rem 0}
.article h3{font-size:clamp(1.2rem,2.6vw,1.45rem);margin:1.9rem 0 .5rem}
.article ul{color:#4e4739;margin:1.15rem 0;padding-left:1.35rem}
.article li{margin:.4rem 0}
.article .meta{font-family:var(--caps);letter-spacing:.2em;text-transform:uppercase;font-size:.68rem;color:var(--muted);margin-bottom:2rem;display:block}

/* gallery grid + reels */
.ggrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}
.ggrid figure{margin:0;aspect-ratio:4/5;border-radius:4px;overflow:hidden;box-shadow:0 22px 46px -26px rgba(42,38,32,.4)}
.ggrid img{width:100%;height:100%;object-fit:cover;display:block;transition:transform 1s cubic-bezier(.2,.7,.2,1)}
.ggrid figure:hover img{transform:scale(1.04)}
.reels{display:grid;grid-template-columns:repeat(3,minmax(0,340px));gap:clamp(1.2rem,3vw,2rem);justify-content:center}
@media(max-width:860px){.reels{grid-template-columns:minmax(0,360px)}}
.reel{position:relative;aspect-ratio:9/16;border-radius:10px;overflow:hidden;background:var(--olive-d);box-shadow:0 30px 60px -34px rgba(42,38,32,.55)}
.reel video{width:100%;height:100%;object-fit:cover;display:block}
/* The poster used to be a `poster=""` attribute, which the browser fetches
   EAGERLY however far below the fold it sits: 214 KB of the gallery page's
   716 KB first viewport was three poster JPEGs for reels nobody had scrolled
   to (measured 2026-09-07). As a real <img> it lazy-loads, it gets the webp
   ladder from build.py for free, and it still renders with JS off — which the
   `poster` attribute would not have done once the src moved to data-src. */
.reel .rposter{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:1;transition:opacity .45s}
.reel.playing .rposter{opacity:0}
.reel .rplay{z-index:2}
.reel .rplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(42,38,32,.18);cursor:pointer;border:0;padding:0;transition:opacity .3s}
.reel .rplay .ring{width:74px;height:74px;border-radius:50%;background:rgba(250,246,238,.92);display:flex;align-items:center;justify-content:center;transition:transform .3s}
.reel .rplay:hover .ring{transform:scale(1.08)}
.reel .rplay svg{width:26px;height:26px;margin-left:4px;color:var(--olive-d)}
/* visibility:hidden as well as opacity:0 — opacity alone leaves the button in
   the TAB ORDER, so a keyboard or switch user landed on an invisible control.
   Measured 2026-08-10: opacity 0, pointerEvents none, but focusable true. */
.reel.playing .rplay{opacity:0;pointer-events:none;visibility:hidden}
.reel .rmute{position:absolute;right:12px;bottom:12px;z-index:3;width:40px;height:40px;border-radius:50%;border:0;background:rgba(42,38,32,.55);color:#f3ecdb;display:none;align-items:center;justify-content:center;cursor:pointer}
.reel.playing .rmute{display:inline-flex}

/* breadcrumb-ish back link */
.crumb{font-family:var(--caps);letter-spacing:.2em;text-transform:uppercase;font-size:.68rem;color:var(--muted);display:inline-block;padding:.5rem 0;min-height:24px}
.crumb a:hover{color:var(--terra)}

/* CTA band reused on subpages */
.ctaband{background:var(--olive);color:#f3ecd6;text-align:center}
.ctaband h2{font-size:clamp(2.2rem,5.5vw,3.6rem);color:#fbf5e6}
.ctaband h2 em{font-style:italic;color:#f0d6b8}
.ctaband .eyebrow{color:#f2dcc2}
.ctaband p{max-width:520px;margin:1rem auto 1.8rem;color:#dfd9c2}
.ctaband .btn{background:var(--terra);border-color:var(--terra);color:#fff}
.ctaband .btn:hover{background:#fff;color:var(--olive);border-color:#fff}

/* dish-name columns (client menu lists — headings only, no prices) */
.dishcols{list-style:none;margin:.6rem 0 0;padding:0;columns:2 280px;column-gap:2.6rem}
.dishcols li{font-family:var(--display);font-size:1.4rem;font-weight:600;color:var(--ink);padding:.6rem 0;border-bottom:1px dotted var(--rule);break-inside:avoid}
.dishcols .ds-i{font-family:var(--body);font-weight:300;font-size:.85rem;color:#6f6959}

/* ============================================================
   Client feedback batch (Ebru 2026-07-15): fuller top nav +
   Reserve dropdown, gallery hero contrast, footer location link,
   contact / reserve / vouchers pages.
   ============================================================ */

/* nav now carries Contact + Private Hire + a Reserve dropdown, give it more
   room before collapsing to the hamburger (was 860px) */
.nav nav{gap:1.5rem}
@media(max-width:1024px){.nav nav a.lnk{display:none}.navtoggle{display:flex}}
@media(min-width:1025px){.mnav{display:none}}

/* Reserve dropdown: right-aligned so a rightmost trigger can't overflow the edge */
.navdrop.res>.btn{padding:0 1.7rem}
.navdrop.res .drop{left:auto;right:0;transform:translate(0,8px)}
.navdrop.res:hover .drop,.navdrop.res:focus-within .drop{transform:translate(0,0)}

/* mobile nav grew: let it scroll if it exceeds the screen */
.mnav{justify-content:flex-start;padding-top:clamp(84px,13vh,130px);overflow-y:auto}

/* footer "Get directions" link */
.loclink{border-bottom:1px solid rgba(230,195,159,.4);transition:color .25s;display:inline-block;padding:.32rem 0;min-height:24px}
.loclink:hover{color:#e6c39f}

/* gallery hero: stronger veil so the overlay text reads (was washed out) */
.phero.contrast .phero__veil{background:linear-gradient(180deg,rgba(28,25,20,.64) 0%,rgba(28,25,20,.5) 45%,rgba(45,49,30,.84) 100%)}
.phero.contrast .eyebrow,.phero.contrast h1,.phero.contrast .lede{text-shadow:0 2px 20px rgba(0,0,0,.55)}

/* contact page */
.contact-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(2.2rem,5vw,4rem);align-items:start}
@media(max-width:820px){.contact-grid{grid-template-columns:1fr}}
.cinfo h3{font-size:1.5rem;margin:1.9rem 0 .5rem}
.cinfo h3:first-child{margin-top:0}
.cinfo p{margin:.2rem 0;color:#5a5346}
.cinfo a{color:var(--terra-d)}
.cinfo .soc{display:flex;gap:.7rem;margin-top:1rem}
.cinfo .soc a{width:44px;height:44px;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--rule);border-radius:50%;color:var(--olive);transition:background .25s,color .25s,border-color .25s,transform .25s}
.cinfo .soc a:hover{background:var(--olive);color:#fbf6ec;border-color:var(--olive);transform:translateY(-2px)}
.cinfo .soc svg{width:18px;height:18px;display:block}
.formcard{background:var(--olive);border-radius:12px;padding:clamp(1.6rem,3.4vw,2.4rem);color:#f3ecd6}
.formcard h3{font-size:1.7rem;color:#fbf5e6;margin-bottom:1.2rem}
.formcard .resform{max-width:none}
.formcard textarea{width:100%;min-height:120px;font-size:1rem;font-family:var(--body);padding:.9rem 1.1rem;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.28);color:#fbf6ec;border-radius:6px;resize:vertical}
.formcard textarea::placeholder{color:#cdc7b3}
.formcard textarea:focus-visible{outline:3px solid #e6c39f;outline-offset:2px}
.formcard .btn{background:var(--terra);border-color:var(--terra);color:#fff}
.formcard .btn:hover{background:#fff;color:var(--olive);border-color:#fff}

/* reserve location page */
.resv{max-width:760px;margin:0 auto;text-align:center}
.resv .lede2{color:#5a5346;max-width:60ch;margin:1.4rem auto 0;font-size:1.08rem}
.resv .btn{margin-top:2.2rem}
.resv .note{margin-top:1.6rem;color:var(--muted);font-size:.95rem}
.soon-badge{display:inline-block;font-family:var(--caps);letter-spacing:.2em;text-transform:uppercase;font-size:.7rem;color:var(--terra);border:1px solid var(--terra);border-radius:999px;padding:.35rem .9rem;margin-bottom:1.2rem}

/* inline Reserve button uses the SAME dropdown as the navbar (.navdrop),
   centred under the trigger. Hover-reveal, identical card styling. */
.navdrop.hero-res{display:inline-flex}
.navdrop.hero-res .drop{min-width:220px}

/* menus landing: tighter, more zoomed brunch card crop */
.catcard img.zoomin{width:122%;height:122%;inset:-11% auto auto -11%;object-position:center 48%}

/* find-us cards are fully clickable (to Reserve); tel/mail stay clickable above */
.loc .card{position:relative}
.loc .card .stretch{position:absolute;inset:0;z-index:1}
.loc .card .body a:not(.stretch){position:relative;z-index:2}

/* ============================================================
   Client feedback batch (Marina + Ebru 2026-07-16): Watford
   hidden, menu buttons up top, footer MK header, gallery reels.
   ============================================================ */

/* menu subpage: single consistent "View the Full Menu" button, sits directly
   under the hero (the copy below it is SEO, read after the CTA) */
.menu-cta{text-align:center;margin:0 0 clamp(2rem,4vw,3rem)}

/* Find Us: single Milton Keynes venue while Watford is hidden — centre the card */
.loc-grid.loc-solo{grid-template-columns:minmax(0,540px);justify-content:center}

/* footer: "Milton Keynes" venue header above the address, with a location pin */
.footloc{display:flex;align-items:center;gap:.45rem;margin:0 0 .5rem;color:#e6c39f;font-family:var(--caps);letter-spacing:.08em;font-size:.95rem}
.footloc svg{width:15px;height:15px;flex:0 0 auto}

/* select fields (location etc.) get a caret back — .resform select strips the native one */
.resform select{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23cdc7b3' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 1rem center;background-size:18px;padding-right:2.8rem}

/* honeypot (off-screen; bots fill it, humans don't) + AJAX form status line */
.resform .hp{position:absolute!important;left:-9999px;width:1px;height:1px;overflow:hidden;opacity:0}
.formstatus{margin:.2rem 0 0;text-align:center;font-size:.95rem;min-height:1.2em;color:#e2dcc6}
.formstatus.ok{color:#dbe6c0}
.formstatus.err{color:#f3c9b3}

/* 200% text zoom: an unbroken address like bookings@fabricerestaurant.com
   forced its grid track wider than the viewport, and overflow-x:clip meant
   the overflow could not be scrolled to — the text was simply gone. */
.cinfo a,.resv .note a,.card a.tel,footer a,.article a{overflow-wrap:anywhere}

/* Standalone links whose hit box is the ANCHOR, not the styled wrapper.
   .crumb is a <span> around an <a>, so padding on .crumb left the tappable
   area at 14px; the contact card's phone/email sit alone in their own <p>
   at 23px, one pixel under. Padding only — no colour, no type change. */
.crumb a{display:inline-block;padding:.5rem 0}
.cinfo p > a,.card p > a,.card a.tel{display:inline-block;padding:.22rem 0;min-height:24px}

/* ---------- Lightbox (native <dialog>, top layer) ----------
   A <dialog> was chosen over a hand-rolled overlay for three reasons that all
   cost real time on this site already: it renders in the browser's TOP LAYER,
   so it cannot lose a z-index fight with the fixed header the way the mobile
   overlay did on 2026-08-10; it traps focus and closes on Esc natively; and
   ::backdrop needs no extra element.
   The dialog is sized by the VIEWPORT and the image by its own natural size —
   see .lb-fig img. Never upscale: an enlarged photo that is soft reads worse
   than a smaller one that is sharp, which is the whole lesson of the 400w rung. */
.lb{border:0;padding:0;max-width:100vw;max-height:100dvh;width:100vw;height:100dvh;
    background:transparent;overflow:hidden;color:#f7f2e6}
/* .97 + blur, not .94. At .94 the page ghosted through hard enough to read the
   headings, and on a phone the site's own hamburger showed through DIRECTLY
   UNDER the lightbox close button — measured 2026-08-11, .lb-close at (330,17)
   against .navtoggle at (326,15). Two X's stacked on the same 3mm of glass is
   not something to leave in front of a client's customers. The tap itself was
   always correct (the dialog is in the top layer); it just looked broken. */
.lb::backdrop{background:rgba(24,21,17,.97);backdrop-filter:blur(6px)}
.lb[open]{display:flex;align-items:center;justify-content:center}
.lb-fig{margin:0;display:flex;flex-direction:column;align-items:center;gap:.9rem;
        max-width:92vw;max-height:90dvh}
/* width:auto + the natural-size cap set inline by app.js. object-fit is NOT
   used: the box is the image, so there is nothing to fit into. */
/* touch-action:pan-y is LOAD-BEARING, not tidiness. Without it the browser
   claims the horizontal gesture for its own panning and fires pointerCANCEL
   instead of pointerup, so the swipe handler never runs and the photo never
   advances — measured on an emulated phone 2026-08-11, where a full-width drag
   left the counter on "1 / 25". pan-y keeps vertical gestures with the browser. */
.lb-fig img{display:block;max-width:92vw;max-height:82dvh;width:auto;height:auto;
            border-radius:4px;box-shadow:0 40px 90px -40px rgba(0,0,0,.8);
            background:var(--olive-d);touch-action:pan-y}
.lb-cap{font-size:.92rem;letter-spacing:.02em;color:#e8e0cd;text-align:center;
        max-width:60ch;margin:0;text-shadow:0 1px 3px rgba(0,0,0,.55)}
.lb-count{font-family:var(--caps);letter-spacing:.28em;text-transform:uppercase;
          font-size:.7rem;color:#c9c0a8}
/* Controls sit ON the backdrop, not on the photo — a 44px circle over a plate
   of food is the one thing guaranteed to cover the subject. */
.lb-btn{position:absolute;border:0;cursor:pointer;display:flex;align-items:center;
        justify-content:center;width:48px;height:48px;border-radius:50%;
        background:rgba(250,246,238,.1);color:#f7f2e6;transition:background .2s,transform .2s}
.lb-btn:hover{background:rgba(250,246,238,.22)}
.lb-btn:focus-visible{outline:2px solid var(--tan);outline-offset:3px}
.lb-btn svg{width:24px;height:24px}
.lb-prev{left:max(12px,2vw)}
.lb-next{right:max(12px,2vw)}
.lb-close{top:max(12px,2vh);right:max(12px,2vw)}
.lb-prev,.lb-next{top:50%;transform:translateY(-50%)}
.lb-prev:hover,.lb-next:hover{transform:translateY(-50%) scale(1.06)}
@media(max-width:640px){
  /* On a phone the arrows would sit over the photo's edges, so they go under it
     as a row; swipe is the primary gesture there anyway. */
  .lb-prev,.lb-next{top:auto;bottom:max(14px,2vh);transform:none}
  .lb-prev:hover,.lb-next:hover{transform:none}
  .lb-fig img{max-height:70dvh}
}
/* The zoomable image is a button in the markup: strip the button chrome. */
.lb-open{display:contents;background:none;border:0;padding:0;margin:0;font:inherit;color:inherit}
.ggrid figure,.gseg figure{cursor:zoom-in}
.ggrid figure:focus-within{outline:2px solid var(--terra);outline-offset:3px}
@media(prefers-reduced-motion:reduce){.lb-btn{transition:none}}
