/* ═══════════════════════════════════════════════════════════════════════════
   HERO + PIE OF THE MONTH · 14-09-2026
   Loaded last, so everything here is additive and the previous stylesheets are
   untouched. Reverting is a matter of deleting the <link> and the two markup
   blocks it styles.

   Two changes:
   1. The split hero is replaced by the bakery's own mark centred over a
      photograph of the racks. The mark is the traced SVG, so it stays sharp at
      any size, and the photo is sign-free so the wordmark never appears twice.
   2. A Pie of the Month section, the plain layout, sat between the range and
      the catering band.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Aleo is the face the logo itself was built from: Aleo Bold, squeezed to about
   79% and arched. Self-hosted rather than linked, so the site makes no
   third-party font request. Used ONLY at its natural width; the squeeze belongs
   to the mark, because scaling live text distorts the stroke weights. */
@font-face{
  font-family:'Aleo';
  src:url('fonts/Aleo-700.woff2') format('woff2');
  font-weight:700;font-style:normal;font-display:swap;
}

/* ── Hero ──────────────────────────────────────────────────────────────────
   Full-bleed photograph, an even wash and a vignette, the mark centred. The
   wash is even rather than bottom-weighted because the content is centred and
   needs contrast across the middle of the frame, not just along one edge. */
.jt-hero{
  position:relative;
  min-height:100svh;
  display:flex;align-items:center;justify-content:center;
  overflow:hidden;
  background:var(--ink);
}
.jt-hero-bed{position:absolute;inset:0;}
.jt-hero-bed img{width:100%;height:100%;object-fit:cover;display:block;}
.jt-hero-bed::before{
  content:'';position:absolute;inset:0;z-index:2;
  background:rgba(21,17,16,.52);
}
.jt-hero-bed::after{
  content:'';position:absolute;inset:0;z-index:3;
  background:radial-gradient(120% 100% at 50% 46%,
    rgba(21,17,16,0) 30%, rgba(21,17,16,.32) 66%, rgba(21,17,16,.78) 100%);
}

.jt-hero-in{
  position:relative;z-index:10;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(20px,2.6vw,30px);
  text-align:center;
  padding:120px var(--gut) 72px;
  max-width:960px;
}
.jt-hero-mark{
  width:auto;height:clamp(130px,26vw,340px);
  display:block;
}
.jt-hero-sub{
  margin:0;
  font-size:clamp(17px,1.5vw,22px);line-height:1.55;
  color:#F3ECE2;
}
.jt-hero .btn{align-self:center;}

/* ── Pie of the Month ──────────────────────────────────────────────────────
   Deliberately plain. No panel, no border, no kicker above the heading, no
   stat row. The section is named in the words a customer would expect, and the
   pie's name sits beneath it as the subject. */
.pom{
  padding:clamp(64px,7vw,110px) var(--gut);
  background:var(--warm);
}
.pom-in{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(32px,5vw,64px);
  align-items:center;
}
.pom-shot img{
  width:100%;height:clamp(300px,38vw,470px);object-fit:cover;display:block;
}
.pom h2{
  font-family:'Aleo',Georgia,serif;font-weight:700;
  font-size:clamp(34px,5vw,64px);line-height:1.02;letter-spacing:-.02em;
  color:var(--cream);margin:0 0 14px;
}
.pom-name{
  margin:0 0 16px;
  font-family:'Work Sans',system-ui,sans-serif;font-weight:500;
  font-size:clamp(20px,2vw,26px);line-height:1.2;color:var(--muted);
}
.pom-desc{
  margin:0 0 26px;max-width:460px;
  font-size:clamp(16px,1.2vw,19px);line-height:1.62;color:var(--muted);
}
.pom-link{
  color:var(--cream);font-size:16px;
  text-underline-offset:5px;text-decoration-thickness:1px;
}
.pom-link:hover{color:var(--red-lite);}

@media (max-width:860px){
  .pom-in{grid-template-columns:1fr;}
  .jt-hero-in{padding-top:96px;}
}

/* The light theme the site currently ships in. The hero keeps its dark ground
   because the photograph is behind it either way; only the pie band flips. */
:root[data-theme="light"] .pom{background:var(--ink-2);}
:root[data-theme="light"] .pom h2{color:var(--cream);}

/* ── Nav mark size ─────────────────────────────────────────────────────────
   site-v3.css sizes the mark at clamp(132px,12vw,176px) via
   :root[data-theme="light"] .pagetop .brand img, which is (0,4,1). That was set
   for the round roundel; the wide shield needs far less. Matched at the same
   specificity and loaded later so it wins without !important. */
:root[data-theme] .pagetop .brand img{
  width:clamp(88px,8vw,120px);height:auto;object-fit:contain;
}
:root[data-theme] .pagetop.is-stuck .brand img{
  width:clamp(70px,6.4vw,92px);height:auto;
}
@media (max-width:900px){
  :root[data-theme] .pagetop .brand img{width:88px;}
}

/* ── Contrast fix: parking list on the red band ────────────────────────────
   .fp-park dd inherits --muted (#64584E in light), which is a dark brown. The
   block sits inside .warmband, whose ground is red-deep #8E2A18, so the text
   was dark-on-red and effectively unreadable. Only the copy on the band is
   changed; the same list on a pale ground keeps its muted colour. */
.warmband .fp-park dd{
  color:rgba(246,239,230,.86);
}
.warmband .fp-park dt{
  color:var(--on-accent,#fff);
}
/* Any other muted body copy that lands on the red band has the same problem. */
.warmband p,
.warmband li{
  color:rgba(246,239,230,.88);
}
.warmband a:not(.btn){
  color:#fff;
}

/* ── Pie band into the catering wave ───────────────────────────────────────
   The wave SVG is only the red shape; everything above that curve inside its
   60px box is transparent and shows the page ground. With the pie band sitting
   directly above it on a different tone, that read as a pale strip between the
   two. Carrying the band's own colour onto the wave closes it, so the pie
   section runs straight into the curve. */
.pom + svg.wave{background-color:var(--warm);}
:root[data-theme="light"] .pom + svg.wave{background-color:var(--ink-2);}

/* ── Catering, rebuilt 14-09-2026 ──────────────────────────────────────────
   The page's job is to get someone to ring with the right notice, so the phone
   is the largest thing on it and the notice periods sit immediately beside it. */
.cat-order-in{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:1.3fr 1fr;gap:clamp(32px,5vw,72px);
  align-items:start;
}
.cat-lede{font-size:clamp(17px,1.4vw,20px);line-height:1.6;margin:0 0 18px;}
.cat-phone{
  display:inline-block;
  font-family:'Aleo',Georgia,serif;font-weight:700;
  font-size:clamp(34px,4.6vw,58px);line-height:1;letter-spacing:-.02em;
  color:var(--red);text-decoration:none;margin:0 0 16px;
}
.cat-phone:hover{text-decoration:underline;text-underline-offset:6px;}
.cat-note{font-size:16px;line-height:1.6;color:var(--muted);margin:0;max-width:44ch;}

.cat-notice h3{font-size:18px;margin:0 0 14px;}
.cat-dl{margin:0;border-top:1px solid var(--rule);}
.cat-dl dt{padding:14px 0 2px;font-weight:500;}
.cat-dl dd{margin:0;padding:0 0 14px;border-bottom:1px solid var(--rule);
  color:var(--red);font-family:'Aleo',Georgia,serif;font-weight:700;font-size:20px;}

.cat-what-lede{font-size:17px;color:var(--muted);margin:0 0 28px;max-width:56ch;}
.cat-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:2px;}
.cat-card{margin:0;}
.cat-card img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block;}
.cat-card figcaption{padding:12px 2px 0;font-size:16px;font-weight:500;}

.cat-menu-in{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,56px);align-items:center;
}
.cat-menu-cta{margin:22px 0 0;}
.cat-menu-shots{display:grid;grid-template-columns:1fr 1fr;gap:12px;}
.cat-menu-shots img{width:100%;height:auto;display:block;}
.cat-link{color:var(--red);text-underline-offset:5px;}

@media (max-width:860px){
  .cat-order-in,.cat-menu-in{grid-template-columns:1fr;}
  .cat-grid{grid-template-columns:repeat(2,1fr);}
}

/* Delivery reuses the catering ordering block. Its list mixes figures with
   sentences, so the sentence rows opt out of the large red numeral styling. */
.cat-dl dd.dd-plain{
  font-family:'Work Sans',system-ui,sans-serif;font-weight:400;font-size:16px;
  color:var(--muted);line-height:1.5;
}
.del-alt-in{
  max-width:var(--maxw);margin:0 auto;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,64px);align-items:start;
}
.del-alt-in h3{margin:0 0 10px;font-size:19px;}
@media (max-width:860px){.del-alt-in{grid-template-columns:1fr;}}

/* ── Lane alignment ────────────────────────────────────────────────────────
   The product card grid carried margin-left:88px and max-width:1120px, so it
   sat inset from the section's own lane while the heading and intro above it
   ran the full 1320px. The cards now share the lane, so the first card's left
   edge lines up with the text above it. */
:root .sec .cards{
  /* margin-inline:auto, not 0. Setting the margins to zero fixed the 88px
     indent at 1440 but pinned the grid left on anything wider, so the heading
     centred while the cards hugged the edge. Auto centres it in the same lane
     as .range-head at every width. */
  margin-inline:auto;max-width:var(--maxw);
}

/* ── Hollow heading ────────────────────────────────────────────────────────
   The outline was 1.08px. "Catch up" had no diagonal junctions; "Follow" does,
   and at that weight the W's two vertices closed up and read as a blot. A
   heavier stroke with paint-order set keeps the counters open. */
:root .hollow-h .hw-out{
  -webkit-text-stroke-width:1.8px;
  paint-order:stroke fill;
  letter-spacing:.005em;
}

/* ── Display face consolidation, 14-09-2026 ────────────────────────────────
   The page carried three heading faces: Bricolage Grotesque on the card
   headings, Plus Jakarta Sans on the section headings, and Aleo on the pie
   band. Bricolage is retired here. Archivo takes the card and sub headings at
   500, the weight already approved, and Aleo stays for the display moment
   because it is the face the logo itself is built from.

   Self-hosted. Overriding by family rather than per-selector, so nothing that
   used Bricolage is missed. Revert by deleting this block.               */
@font-face{
  font-family:'Archivo';src:url('fonts/Archivo-500.woff2') format('woff2');
  font-weight:500;font-style:normal;font-display:swap;
}
@font-face{
  font-family:'Archivo';src:url('fonts/Archivo-600.woff2') format('woff2');
  font-weight:600;font-style:normal;font-display:swap;
}

/* Archivo sits a little wider than Bricolage at the same size, so the card
   headings lose a touch of tracking to keep the two-line ones on two lines. */
:root .card h3,
:root .cards h3{letter-spacing:-.02em;}

/* Every selector styles.css set in Bricolage, moved to Archivo. Listed rather
   than aliased because the original @font-face covers 300-800 and is declared
   first, so a same-family alias never wins the weight match. */
:root h1, :root h2, :root h3,
:root .band-big, :root .band-in .band-big,
:root .care-list dt, :root .ctaband-in>p:first-child,
:root .faq-item summary, :root .find-tel a, :root .foot-cols b,
:root .fp-label, :root .fp-park dt, :root .fp-tel a,
:root .morelinks a, :root .morelinks h2,
:root .range-group h3, :root .rev-num, :root .rgroup h3,
:root .sec-kicker, :root .sec-head>p.sec-kicker,
:root .tickerstrip span, :root .kicker,
:root .banner .crumb, :root .banner .crumb a{
  font-family:'Archivo',system-ui,sans-serif;
}
/* The pie band keeps Aleo, the logo's own face, as the one display moment. */
:root .pom h2{font-family:'Aleo',Georgia,serif;}
:root .cat-phone{font-family:'Aleo',Georgia,serif;}

/* ── One nav bar, everywhere ───────────────────────────────────────────────
   Light bar, red type. The colour is the measured average of the 88%-cream
   frosted version, #DCCEC2, taken as a solid: same tone, but it cannot shift
   with whatever photograph happens to sit behind it and it works on the inner
   pages, which have no hero for a transparent bar to sit over.
   Specificity matches the :root[data-theme="light"] rules it has to beat. */
:root[data-theme] .pagetop,
:root[data-theme] .pagetop.is-stuck{
  /* #E7DCCC, the Pie of the Month band's own colour, so the bar belongs to the
     palette rather than being a one-off tone.
     The hairline matters: the pie band is this exact colour, so without an edge
     the bar and that section merge into one shape when you scroll to it. */
  background:#E7DCCC;
  border-bottom:1px solid rgba(33,26,21,.16);
  box-shadow:none;
}
:root[data-theme] .pagetop .nav a,
:root[data-theme] .pagetop.is-stuck .nav a,
:root[data-theme] .pagetop .themetoggle,
:root[data-theme] .pagetop.is-stuck .themetoggle{
  color:var(--red-deep);
}
:root[data-theme] .pagetop .themetoggle{border-color:rgba(179,53,32,.35);}
:root[data-theme] .pagetop .topcall,
:root[data-theme] .pagetop.is-stuck .topcall{
  background:var(--red-deep);color:#fff;
}
/* The dark cut of the mark, because the bar is light now. */
:root[data-theme] .pagetop .brand img,
:root[data-theme] .pagetop.is-stuck .brand img{filter:none;}

/* On the home page the hero already carries the wordmark, so the bar drops its
   own rather than showing it twice. Every other page keeps it, since there it
   is the only mark and the way back to the home page. */
:root body[data-page="home"] .pagetop .brand{visibility:hidden;}

/* ── The bar does not resize on scroll ─────────────────────────────────────
   It was 88px tall with a 115x65 mark at rest and 75px with a 92x52 mark once
   stuck, so the whole header shifted as you scrolled. One height, one mark
   size, no shadow change. */
:root[data-theme] .pagetop .topbar,
:root[data-theme] .pagetop.is-stuck .topbar{
  padding-top:11px;padding-bottom:11px;
}
:root[data-theme] .pagetop.is-stuck .brand img{
  width:clamp(88px,8vw,120px);height:auto;
}
:root[data-theme] .pagetop,
:root[data-theme] .pagetop.is-stuck{
  box-shadow:none;
}
:root[data-theme] .pagetop .brand img{transition:none;}

/* ── Nav links: match the F mock, and actually centre them ─────────────────
   Live was Work Sans 500 / 14px / 30px gap and sat 279px right of centre,
   because the brand still reserves its width even when hidden and
   space-between then divides what is left. Absolutely centring the list makes
   it independent of whatever sits either side of it. */
:root[data-theme] .pagetop .topbar{
  position:relative;
  padding-left:72px;padding-right:72px;
}
:root[data-theme] .pagetop .nav{
  position:absolute;left:50%;transform:translateX(-50%);
  gap:32px;
}
:root[data-theme] .pagetop .nav a{
  font-family:'Work Sans',system-ui,sans-serif;
  font-weight:600;font-size:15px;letter-spacing:normal;
}
:root[data-theme] .pagetop .topcall{
  font-size:15px;font-weight:600;padding:12px 24px;
}
@media (max-width:900px){
  :root[data-theme] .pagetop .topbar{padding-left:20px;padding-right:20px;}
  :root[data-theme] .pagetop .nav{position:static;transform:none;}
}

/* site-v3.css sets :root[data-theme="light"] .pagetop .topbar .nav to static at
   (0,5,1), and only the home page loads that sheet, so the links centred
   everywhere except there. Matched at the same specificity, later in the
   cascade, inside the same breakpoint it uses. */
/* 17-09-2026: this opened at 901px, but the hamburger owns the nav all the way
   up to 1080px (styles.css:115 hides .nav, :643 shows .navtoggle, and :424
   fences its own copy of this centring at 1081). So between 901 and 1080 the
   OPEN panel was being absolutely centred on the bar and dragged above it:
   measured at 1000px it sat at y=-71 with all 11 links failing hit-testing, and
   the header offered no other route to any page. Fenced where it belongs. */
@media (min-width:1081px){
  :root[data-theme] .pagetop .topbar .nav{
    position:absolute;left:50%;top:50%;
    transform:translate(-50%,-50%);
    gap:32px;
  }
}

/* ── Find us, two columns ──────────────────────────────────────────────────
   Address and hours on the left, the phone and the way there on the right,
   with the map spanning both beneath. Previously everything stacked in one
   column with the map alongside, which pushed the phone a long way down. */
:root .fp-map-wide{grid-column:1 / -1;}
:root .fp-map-wide iframe{aspect-ratio:21/7;margin-bottom:0;}
@media (max-width:860px){
  :root .fp-map-wide iframe{aspect-ratio:4/3;}
}

/* ── Bar height, exact ─────────────────────────────────────────────────────
   Padding-driven height landed at 87.875 + 1px border = 88.875. Fixing the
   topbar height makes the total 88 including the rule, matching the mock. */
:root[data-theme] .pagetop .topbar{
  height:87px;padding-top:0;padding-bottom:0;align-items:center;
}

/* ── The hollow heading ────────────────────────────────────────────────────
   It was still Plus Jakarta Sans, whose W has very tight inner counters: at a
   1.8px outline the two vertices closed up and the letter read as a blot.
   Archivo's W is wider and survives being outlined. */
:root .hollow-h,
:root .hollow-h .hw-out,
:root .hollow-h .hw-solid{
  font-family:'Archivo',system-ui,sans-serif;
  font-weight:600;
}
:root .hollow-h .hw-out{
  -webkit-text-stroke-width:1.5px;
  paint-order:stroke fill;
  letter-spacing:.01em;
}

/* ── Home Find us, two columns ─────────────────────────────────────────────
   Matches the find-us page: address and hours left, phone and directions
   right, rather than one long stack. */
:root .find-split{
  max-width:var(--maxw);margin-inline:auto;
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,4vw,72px);
  align-items:start;
}
:root .find-split .find-col:last-child{padding-top:clamp(8px,2.6vw,58px);}
@media (max-width:860px){
  :root .find-split{grid-template-columns:1fr;}
  :root .find-split .find-col:last-child{padding-top:0;}
}

/* ── Text on the red band ──────────────────────────────────────────────────
   Full cream rather than 86%, so nothing on the band relies on opacity to
   clear contrast. Covers find-us parking and the delivery band alike. */
:root .warmband .fp-park dd,
:root .warmband p,
:root .warmband li,
:root .warmband dd{
  color:#F6EFE6;
}
:root .warmband .fp-park dt,
:root .warmband dt,
:root .warmband h2,
:root .warmband h3{
  color:#FFFFFF;
}
:root .warmband a:not(.btn){color:#FFFFFF;}

/* ── Products page: the two closing blocks were touching ───────────────────
   "Ring us, any hour" and "Reheating and storage" sit in the same <p>, a button
   next to a text link with nothing between them. */
:root .fp-cta{
  display:flex;align-items:center;gap:clamp(20px,2.4vw,34px);flex-wrap:wrap;
}

/* ── Hero band ─────────────────────────────────────────────────────────────
   A band behind the shield carrying the two things a customer checks first.
   It is inset rather than full bleed so the words stay near the mark instead
   of drifting into the corners on a wide screen.

   On load the two halves are clipped to nothing behind the mark and open
   outwards, so the band appears to slide out from under it. clip-path rather
   than scaleX, because scaling would stretch the type. CSS only, so there is
   no script to fail and the animation always completes. */
.jt-lockup{
  position:relative;display:flex;align-items:center;justify-content:center;
  width:min(1080px,88vw);
}
.jt-hero .jt-hero-mark{position:relative;z-index:3;}

.jt-band{
  position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);z-index:1;
  display:flex;height:clamp(40px,4.2vw,56px);
}
.jt-half{
  flex:1;display:flex;align-items:center;
  background:var(--red-deep);
  font-family:'Archivo',system-ui,sans-serif;font-weight:600;
  font-size:clamp(11px,1.05vw,14px);letter-spacing:.2em;text-transform:uppercase;
  color:#fff;white-space:nowrap;
}
.jt-half-l{justify-content:flex-start;padding-left:clamp(16px,3vw,38px);
  animation:jtBandL 780ms cubic-bezier(.22,.61,.36,1) 420ms both;}
.jt-half-r{justify-content:flex-end;padding-right:clamp(16px,3vw,38px);
  animation:jtBandR 780ms cubic-bezier(.22,.61,.36,1) 420ms both;}
.jt-half span{animation:jtBandText 520ms ease 700ms both;}

@keyframes jtBandL{ from{clip-path:inset(0 0 0 100%);} to{clip-path:inset(0 0 0 0);} }
@keyframes jtBandR{ from{clip-path:inset(0 100% 0 0);} to{clip-path:inset(0 0 0 0);} }
@keyframes jtBandText{ from{opacity:0;} to{opacity:1;} }

@media (prefers-reduced-motion: reduce){
  .jt-half,.jt-half span{animation:none;clip-path:inset(0 0 0 0);opacity:1;}
}
@media (max-width:600px){
  .jt-band{height:36px;}
  .jt-half{font-size:10px;letter-spacing:.14em;}
}

/* The nav mark is the wordmark with the shield removed: same lettering, same
   arch, same plate, just no dark shape behind it. Sized by width since it is
   now a wide lockup rather than a badge, and the home page shows it too — it
   is no longer the same object as the shield in the hero. */
:root[data-theme] .pagetop .brand img{
  width:clamp(132px,11vw,168px);height:auto;
}
:root[data-theme] .pagetop.is-stuck .brand img{
  width:clamp(132px,11vw,168px);height:auto;
}
:root body[data-page="home"] .pagetop .brand{visibility:visible;}

/* Letters-only mark: smaller, and the artboard is trimmed to the artwork so
   the size is the artwork rather than the artwork plus dead space. */
:root[data-theme] .pagetop .brand img,
:root[data-theme] .pagetop.is-stuck .brand img{
  width:clamp(96px,7.6vw,122px);height:auto;
}
@media (max-width:900px){
  :root[data-theme] .pagetop .brand img{width:96px;}
}

/* ── Hero sub-line ─────────────────────────────────────────────────────────
   It was Work Sans 20px in the muted grey, which is the body voice and sat
   oddly under a lockup set in tracked caps. Matched to the band instead, one
   step smaller and a touch quieter, so the three lines read as one family. */
:root .jt-hero .jt-hero-sub{
  font-family:'Archivo',system-ui,sans-serif;
  font-weight:600;
  font-size:clamp(11px,1.05vw,13px);
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--cream);
}

/* ── Hero sub-line: bigger and solid ───────────────────────────────────────
   At 13px tracked caps it was too small to read over a photograph. */
:root .jt-hero .jt-hero-sub{
  font-size:clamp(14px,1.3vw,17px);
  letter-spacing:.16em;
  color:var(--cream);
}

/* ── Banner: the photograph is gone, so the band carries its own ground ──── */
:root .banner{background:var(--warm);min-height:0;}
:root .banner .banner-inner{padding-top:clamp(96px,9vw,132px);padding-bottom:clamp(28px,3vw,44px);}
:root .banner h1,:root .banner p,:root .banner .crumb a{color:var(--cream);}
:root .banner .crumb a{opacity:.8;}

/* ── Banner content onto the page lane ─────────────────────────────────────
   Banner text sat at x=125 while every section below it sits at x=72. */
:root .banner .banner-inner{
  max-width:var(--maxw);margin-inline:auto;
  padding-left:var(--gut);padding-right:var(--gut);
}

/* ── Products: the closing pair sat off the lane ───────────────────────── */
:root .fp-know{max-width:var(--maxw);margin-inline:auto;}
:root .fp-know .fp-cta{justify-content:flex-start;}

/* The address sits wherever the photograph happens to be pale, so it carries
   its own shadow rather than relying on the scrim. */
:root .jt-hero .jt-hero-sub{
  text-shadow:0 1px 3px rgba(21,17,16,.55), 0 2px 14px rgba(21,17,16,.75);
}

/* Banner content onto the same lane as every section below it. site-v3.css
   pads .banner-inner at (0,4,1), so this matches and loads later. */
:root[data-theme] .banner .banner-inner{
  max-width:var(--maxw);
  margin-left:auto;margin-right:auto;
  padding-left:var(--gut);padding-right:var(--gut);
  box-sizing:content-box;
}

/* ── Banner without a photograph ───────────────────────────────────────────
   The banner still carried the scrim gradient built for the image behind it,
   so with the photo gone it read as a grey-to-brown fade. Solid ground now. */
:root[data-theme] .banner{background:var(--warm);}
:root[data-theme] .banner::before,
:root[data-theme] .banner::after{display:none;}
:root[data-theme] .banner h1{color:var(--cream);}
:root[data-theme] .banner .crumb a{color:var(--cream);opacity:.75;background:none;padding:0;}

/* ── Catering / delivery ordering block ────────────────────────────────────
   The phone was set at display scale and dominated the section, and the notice
   list read as a price list because the figures were in the accent red with a
   rule under every row. Both pulled back so the block is one quiet panel. */
:root .cat-phone{
  font-size:clamp(26px,2.6vw,36px);
}
:root .cat-order-in{align-items:center;}
:root .cat-notice h3{
  font-size:15px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);font-weight:600;margin-bottom:4px;
}
:root .cat-dl dt{padding:12px 0 0;font-size:16px;}
:root .cat-dl dd{
  font-family:'Work Sans',system-ui,sans-serif;font-weight:500;
  font-size:16px;color:var(--muted);padding-bottom:12px;
}
/* --cream is the "text on the ground" token and flips with the theme, so it is
   the correct one here. --ink is the ground itself, which in light mode is the
   same cream the text sits on: invisible. */
:root .cat-dl dd:not(.dd-plain){color:var(--cream);}
:root .cat-dl{border-top:0;}
:root .cat-dl dd{border-bottom:1px solid var(--rule);}

/* The notice list reads better as label-and-value on one line than as a stack. */
:root .cat-dl{display:grid;grid-template-columns:1fr auto;column-gap:24px;}
:root .cat-dl dt{grid-column:1;padding:12px 0;border-bottom:1px solid var(--rule);}
:root .cat-dl dd{grid-column:2;padding:12px 0;text-align:right;white-space:nowrap;}
:root .cat-dl dd.dd-plain{white-space:normal;max-width:32ch;}

/* ── Contrast fixes, 14-09-2026 ────────────────────────────────────────────
   Measured, not eyeballed: a contrast sweep over all twelve pages found the
   banner sub-line failing at 1.10:1 on every inner page, which is the
   "Over 200 things, all made and baked on the premises, around the clock."
   line on Products and its equivalent on Catering, Delivery, Find us and Care.

   Cause: styles.css line 1141 paints .banner-inner p with --on-photo (#F3ECE2),
   a token that only makes sense when a photograph sits behind the banner. The
   photographs were removed and the banner became a flat --warm panel, so a
   near-white sat on a near-white ground. --cream is the text token and flips
   with the theme, so it is correct on both grounds. The rule below is (0,4,1)
   against that rule's (0,3,1), so it wins on specificity rather than order. */
/* SUPERSEDED 17-09-2026. The reasoning above was right for a flat --warm
   banner; the banner is now #A8371C, so --cream (which is #211A15 in the light
   theme) put dark ink on orange and measured 2.64:1 on the catering sub-line.
   Same selector, same (0,4,1), light text instead. */
:root[data-theme] .banner .banner-inner p,
:root[data-theme] .banner .banner-inner .crumb,
:root[data-theme] .banner .banner-inner .crumb a,
:root[data-theme] .banner .banner-inner li{
  color:#FFF7F0;
}

/* Inline links carried one fixed red on both themes, and no single red can
   work on both grounds: the accent #D2452B measures 3.87:1 on cream and the
   deeper #B33520 measures 2.94:1 on the dark ground. So the link red is now a
   token that flips like every other colour here. Both values measured against
   their own ground: 5.20:1 light, 4.86:1 dark. */
:root[data-theme="light"]{--link:#B33520;}
:root[data-theme="dark"]{--link:#E05A3E;}
:root .cat-link,
:root .sec a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root .sec .more a,
:root .sec .cat-phone a{
  color:var(--link);
}

/* ── Nav: stop the 8px jump between pages ──────────────────────────────────
   The nav is centred with left:50% on .topbar, so it centres on the content
   box, not the window. A page long enough to scroll loses 15px to the
   scrollbar and a short one does not, which moved the whole nav 8px sideways
   when you clicked from a long page to a short one. Reserving the gutter on
   every page makes the measurement identical everywhere: 506px at 1440,
   whether the page scrolls or not. */
html{scrollbar-gutter:stable;}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE, 14-09-2026
   Most of this bakery's traffic is phones, and the bar was broken on every
   page. Measured at 390px before any of this: the logo computed to 0x0, the
   phone button was 98px tall inside an 88px bar and hung 1px off the right
   edge, and on the home page the toggle sat at x=517 on a 375px viewport
   with 79 elements overflowing.

   One cause for all of it. styles.css takes the closed mobile menu out of
   flow with position:absolute, and a rule of mine further up set
   .pagetop .nav{position:static} inside a max-width:900px block to undo the
   desktop centring. That put a 110px hidden panel back into the flex row, so
   flexbox shrank .brand to zero and pushed everything after it off-screen.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:900px){

  /* The closed menu is a dropdown hanging off the bar, not a flex child. */
  :root[data-theme] .pagetop .nav,
  :root[data-theme] .pagetop .topbar .nav{
    position:absolute;left:0;right:0;top:100%;
    transform:translateY(-6px);
    width:auto;
  }
  :root[data-theme] .pagetop .nav.is-open,
  :root[data-theme] .pagetop .topbar .nav.is-open{transform:none;}

  /* Belt and braces: the mark must never be the thing that gives way when
     the row runs out of room. */
  :root[data-theme] .pagetop .brand{flex:0 0 auto;}

  /* The dropdown inherited the dark-theme panel colour, which floated a dark
     sheet under a cream bar. It is the bar continuing downwards instead. */
  :root[data-theme] .pagetop .nav{
    background:#E7DCCC;
    border-bottom:1px solid rgba(33,26,21,.16);
    box-shadow:0 12px 24px rgba(33,26,21,.10);
    padding:4px 20px 10px;
  }
  :root[data-theme] .pagetop .nav a{
    display:block;
    padding:15px 2px;                    /* 48px tall with the 17px line */
    font-size:17px;
    color:var(--link);
    border-bottom:1px solid rgba(33,26,21,.12);
  }
  :root[data-theme] .pagetop .nav a:last-child{border-bottom:0;}

  /* 98px tall in an 88px bar. Sized to sit inside it with room either side. */
  :root[data-theme] .pagetop .topcall{
    padding:11px 16px;font-size:14px;line-height:1.2;
    white-space:nowrap;
  }
  :root[data-theme] .pagetop .navtoggle{margin-left:12px;}
}

/* ── Hero on a phone ───────────────────────────────────────────────────────
   The band runs behind the mark and shows past it either side. That works
   while the mark is narrower than the band. At 390px the mark is 231px of a
   330px lockup, leaving 49px of band on each side, so "Open 24/7" and
   "North Adelaide" ran straight under the shield and were sliced in half.

   Below 700px the band stops sitting behind the mark and becomes a full
   width strip under it: nothing overlaps, and the two facts get their own
   line at a size you can actually read. */
@media (max-width:700px){
  :root .jt-lockup{flex-direction:column;gap:18px;width:100%;}
  :root .jt-hero-mark{width:min(300px,78vw);height:auto;}

  :root .jt-band{
    position:static;transform:none;
    height:auto;
  }
  :root .jt-half{
    padding:11px 14px;
    font-size:12px;letter-spacing:.16em;
    justify-content:center;
  }
  :root .jt-half-l{justify-content:flex-end;}
  :root .jt-half-r{justify-content:flex-start;}

  /* The reveal still runs, it just opens a strip rather than wings. */
  :root .jt-hero-sub{font-size:13px;letter-spacing:.16em;}
  :root .jt-hero .btn{padding:15px 26px;font-size:15px;}
}

/* ── Tap targets ───────────────────────────────────────────────────────────
   Apple and Google both put the floor at 44px. Measured at 390px, the
   "other cabinets" links on the six product pages were 17px tall, the footer
   links 36px, and inline links 18 to 19px. Padding rather than font size, so
   nothing about the type changes. */
@media (max-width:900px){
  :root .morelinks li a,
  :root .foot a,
  :root .band-link,
  :root .pom-link,
  :root .cat-link,
  :root .fp-doc,
  :root .cat-doc,
  :root .crumb a{
    display:inline-block;
    padding-top:13px;padding-bottom:13px;
  }
  :root .morelinks ul{display:flex;flex-direction:column;}
  :root .morelinks li a{display:block;}
  :root .foot-cols a{padding-top:12px;padding-bottom:12px;}

  /* The two display-size phone numbers are links, and at 26 to 28px tall they
     were the smallest targets on the page that someone actually needs to hit. */
  :root .cat-phone,
  :root .fp-tel a{display:inline-block;padding:10px 0;}
}

/* ── Two things only the home page had ────────────────────────────────────
   It loads site-v3.css, which the other eleven do not, and that sheet sets
   .pagetop .nav{display:flex}. On a phone that turned the dropdown into a
   horizontal row that ran 91px past the panel. It stacks like everywhere else.

   The band strip also broke out with width:100vw, and 100vw counts the
   scrollbar gutter, so it sat 15px wider than the page. Anchored to the hero
   instead, which is the element it is supposed to span. */
@media (max-width:900px){
  :root[data-theme] .pagetop .nav{display:block;}
  :root[data-theme] .pagetop .nav.is-open{display:block;}
}
@media (max-width:700px){
  /* 100vw counts the scrollbar gutter, so the strip sat 15px wider than the
     page. It is a block in the column now, as wide as the column, and DOM
     order puts it before the mark so it is ordered back underneath. */
  :root .jt-band{width:100%;margin-left:0;order:2;}
  :root .jt-hero-mark{order:1;}
  :root .jt-lockup{width:100%;}
}

/* ── Hero type is always on a photograph, so it never flips with the theme ──
   --cream is the "text on the page ground" token, and in light theme that is
   #211A15, a near-black. The hero ground is not the page, it is a scrimmed
   photograph, so the address line was rendering dark charcoal over a pale
   patch of pastry and became the hardest thing on the page to read. On a phone
   that line is the address, which is the single most useful fact in the hero.
   Fixed light, both themes, with the shadow it already carried. */
:root[data-theme] .jt-hero .jt-hero-sub{
  color:#F6EFE6;
}
:root[data-theme] .jt-hero .jt-half,
:root[data-theme] .jt-hero .jt-half span{
  color:#FFFFFF;
}

/* Tighten the stack on a phone: the mark, the strip and the address belong
   together, and the button wants clear air rather than the same gap. */
@media (max-width:700px){
  :root .jt-hero-in{gap:0;}
  :root .jt-hero .jt-lockup{margin-bottom:14px;}
  :root .jt-hero .jt-hero-sub{margin:0 0 22px;}
}

/* The menu opened but could not be seen: .pagetop and .topbar both carry
   overflow:hidden, and the dropdown hangs below the bar at top:100%, so it was
   being clipped to nothing. Measured 375x309 at y=86, visible, opacity 1, and
   still invisible on screen. Overflow is released only at mobile widths, where
   the dropdown is the only thing that needs to escape the bar. */
@media (max-width:900px){
  :root[data-theme] .pagetop,
  :root[data-theme] .pagetop .topbar,
  :root[data-theme] .pagetop.is-stuck,
  :root[data-theme] .pagetop.is-stuck .topbar{overflow:visible;}
  :root[data-theme] .pagetop .nav{z-index:70;}
}

/* The reserved scrollbar gutter is there to stop the nav shifting 8px between
   a page that scrolls and one that does not. That is a desktop problem: phones
   draw overlay scrollbars and lose no width, so the gutter buys nothing and
   would cost 15px of a 390px screen on any browser that honoured it. */
@media (pointer:coarse), (max-width:900px){
  html{scrollbar-gutter:auto;}
}

@media (max-width:900px){
  :root[data-theme] .pagetop .nav{padding-bottom:16px;}
}

/* Last of the small targets, measured at 360/390/430. The bar's phone button
   was 39px, the breadcrumb 25px and the two body-copy phone numbers 26 to 32px.
   44px is the floor Apple and Google both publish. */
@media (max-width:900px){
  :root[data-theme] .pagetop .topcall{
    padding-top:14px;padding-bottom:14px;
  }
  /* line 566 sets padding:0 on this at (0,4,1), so this has to match it. */
  :root[data-theme] .banner .crumb a,
  :root[data-theme] .crumb a{
    display:inline-block;padding-top:13px;padding-bottom:13px;
  }
  :root .find-tel a,
  :root .foot p a[href^="tel:"],
  :root .fp-tel a,
  :root .cat-phone{
    display:inline-block;padding-top:11px;padding-bottom:11px;
  }
}

/* The mark is 96x41, the last thing on any page under the 44px floor. Padding
   the link rather than growing the artwork, so the logo itself is unchanged. */
@media (max-width:900px){
  :root[data-theme] .pagetop .brand{padding-top:2px;padding-bottom:2px;}
}

/* ── Everything on one lane, left aligned ──────────────────────────────────
   Measured across seven pages at 390 and 1440. Every heading on the site sits
   at the lane's left edge except four, which were centred or floating:

     products     "Worth knowing"     centred
     find us      "Good to know"      centred
     six product  "The menu"          centred, and at 1440 it started at
                  pages               x=303 against the lane's x=71
     care         "Common questions"  x=303, off the lane

   One centred block in a left-aligned page reads as a mistake rather than a
   choice, and the two at x=303 are the indent Josh has flagged three times.
   All four join the lane. */
:root .fp-know,
:root .menusheet,
:root .faq{
  max-width:var(--maxw);
  margin-inline:auto;
  text-align:left;
}
:root .fp-know h2, :root .fp-know p,
:root .menusheet h2, :root .menusheet p,
:root .faq h2, :root .faq h3, :root .faq p{
  text-align:left;
}
:root .menusheet .btn,
:root .fp-know .btn{margin-left:0;}

/* ── Catering, the ordering block ──────────────────────────────────────────
   Measured, one column, four different type treatments stacked:

     h2   "Ordering"    Archivo 400  24px    #211A15
     p    lede          Work Sans    20px    #211A15
     a    phone         Aleo 700     36px    #B33520
     p    note          Work Sans    16px    #64584E

   Three body sizes and three colours in one short column, plus Aleo, which is
   the logo's own face and is used nowhere else as UI type. Two sizes now, one
   ink and one muted, and the phone moves onto the heading face so it belongs to
   the same family as everything around it. */
:root .cat-order-main .cat-lede{
  font-size:17px;line-height:1.6;color:var(--cream);
  max-width:46ch;margin:0 0 22px;
}
:root .cat-order-main .cat-phone{
  font-family:'Archivo',system-ui,sans-serif;
  font-weight:600;font-size:clamp(26px,2.4vw,32px);line-height:1.1;
  letter-spacing:-.01em;color:var(--link);
  display:inline-block;margin:0 0 10px;
}
:root .cat-order-main .cat-note{
  font-size:17px;line-height:1.6;color:var(--muted);
  max-width:46ch;margin:0;
}

/* The two columns started 33px apart, h2 at y=408 against h3 at y=441, because
   one is a section heading and the other a tracked-caps label. Pinned to the
   same top edge. */
:root .cat-order-in{align-items:start;}
:root .cat-notice h3{margin-top:0;padding-top:6px;}
:root .cat-order-main h2{margin-top:0;}

/* Each notice row drew two separate rules with a 24px gap between them, one
   under the label ending at x=1260 and a short one under the value starting at
   1284. Closing the column gap and moving it to the label's padding makes the
   two cell borders meet, which gives one continuous rule per row without any
   pseudo-element arithmetic that has to guess the value column's width. */
:root .cat-dl{column-gap:0;row-gap:0;}
:root .cat-dl dt{padding-right:24px;}

/* ── Cards: line the bottoms up ────────────────────────────────────────────
   "See the range" sat at three different heights across one row because the
   descriptions are different lengths. The card becomes a column and the link is
   pushed to the bottom of it, so the row reads as a row. */
:root .cards .card{display:flex;flex-direction:column;}
:root .cards .card .card-more{margin-top:auto;padding-top:10px;}

/* ── Nav: the current-page underline on the home page ──────────────────────
   site-v3.css paints it #FFF, which was right when that bar was red. Only the
   home page loads that sheet, so Home's underline was white on cream, i.e.
   invisible, whilst the other four were #2E2119. All five now agree. */
:root[data-theme] .pagetop .nav a::after,
:root[data-theme] .pagetop .nav a[aria-current="page"]::after{
  background:#2E2119;
}

/* The social links on the home page measured 4.26:1 on the dark ground, just
   under the 4.5 floor. They inherit --link, which is tuned for body copy on the
   page ground; these sit on the darker follow strip. One step lighter, measured
   at 5.1:1 there. */
:root[data-theme="dark"] .socials-links a,
:root[data-theme="dark"] .socials-links span{color:#EE8067;}

/* ── The hero band was not centred on a phone ──────────────────────────────
   Measured at 390: the band spans x=38..338, so its centre is 188, but the two
   halves met at 177. They are flex:1 1 0, which should make them equal, except
   a flex item's default min-width is auto and it cannot shrink below its own
   content. "North Adelaide" is 133px against "Open 24/7" at 78px, so the right
   half was forced to 161px and the left got whatever was left, 139px. The
   whole lockup read as shifted left.

   min-width:0 lets both halves take a true 50%, so the two labels sit the same
   distance either side of the mark. */
:root .jt-half{min-width:0;}

/* ── Product cards on a phone ──────────────────────────────────────────────
   One card per row at 335px wide made each photo 335x251 and the Products page
   4,217px long. Two up halves both: the pictures stop dominating and the six
   categories fit in three rows you can take in at once. */
@media (max-width:700px){
  :root .cards,
  :root .cards-lg{
    grid-template-columns:1fr 1fr;
    gap:14px;
  }
  :root .cards .card h3{font-size:17px;line-height:1.25;}
  :root .cards .card p{font-size:14.5px;line-height:1.45;}
  :root .cards .card .card-more{font-size:14px;}
}
@media (max-width:420px){
  :root .cards,
  :root .cards-lg{gap:12px;}
  :root .cards .card h3{font-size:16px;}
}

/* ── The Instagram strip ───────────────────────────────────────────────────
   The three embeds did not work. Measured on the deployed site at 390px: one
   post rendered as a 335x429 empty box and the two reels collapsed to 0x0,
   because styles.css hides posts 2 and 3 below 620px and Instagram's /embed
   route needs their script to post a height back, which never arrives in a
   plain iframe. The result on a phone was one grey rectangle 429px tall.

   Three of the bakery's own photos instead, each linking to the profile. It
   always renders, costs no third-party request, needs no CSP widening, and
   cannot go stale when they delete a post. Also gives the owner three more
   photo slots to swap. */
:root .ig-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:10px;
  list-style:none;margin:0;padding:0;max-width:none;
}
:root .ig-grid > li{display:block;position:relative;aspect-ratio:1/1;overflow:hidden;}
:root .ig-grid > li:nth-child(n+2){display:block;}
:root .ig-grid a{display:block;width:100%;height:100%;}
:root .ig-grid img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .35s ease;
}
:root .ig-grid a:hover img,
:root .ig-grid a:focus-visible img{transform:scale(1.04);}
@media (prefers-reduced-motion:reduce){:root .ig-grid img{transition:none;}}
@media (max-width:620px){
  :root .ig-grid{grid-template-columns:repeat(3,1fr);gap:8px;}
}

/* ── The photo strip, softened ─────────────────────────────────────────────
   The marquee met the hero above it and the products below with two dead
   straight edges, which is what made it read as a band bolted on rather than
   part of the page. The same wave the catering band uses, on both sides, so
   the site has one language for a section change rather than two.

   The entering wave carries the strip's own brown BELOW its curve, and above
   the curve it is transparent. Left in normal flow that transparency would
   show the page ground, not the photograph, so it is pulled up over the bottom
   of the hero by its own height and the hero shows through instead.

   The leaving wave is the standard .wave-up: flipped so the brown sits above
   the curve and the cream of the products section shows beneath. */
:root .wave-marq{
  height:clamp(28px,3.4vw,52px);
  position:relative;z-index:2;
}
:root .wave-marq-out{
  margin-top:-1px;margin-bottom:0;
}

/* The marquee's own rules would cut straight across the curve, and its vertical
   margin (9.975px, measured) showed as a strip of page cream between each wave
   and the strip it is supposed to be joined to. */
:root .marquee{border-top:0;border-bottom:0;margin-top:0;margin-bottom:0;}

/* The curve dips lowest at the left edge, and with the strip's margin gone the
   photographs sat almost against it there. A little padding inside the brown
   keeps a consistent band of colour between the curve and the pictures at every
   point across the width. */
:root .marquee{padding-top:clamp(10px,1.4vw,22px);padding-bottom:clamp(10px,1.4vw,22px);}
@media (max-width:700px){
  /* The phone version was reading as TWO thin horizontal lines under the photos
     rather than one transition: 10px of brown padding made the first edge, and a
     20px wave right underneath it made the second, with almost no brown between
     them to tie the pair together. At 390px a 20px wave is also too shallow to
     read as a curve at all, so it looked like a straight rule.
     Giving the band more brown and the wave more amplitude makes it one shape
     again. Measured at 390px: 18px padding + a 34px wave. */
  :root .wave-marq{height:clamp(30px,9vw,44px);}
  :root .marquee{padding-top:18px;padding-bottom:18px;}
}

/* ── The wave was not the same brown as the strip ──────────────────────────
   Measured off the rendered pixels: the strip paints rgb(59,42,30) and the
   entering wave painted rgb(48,34,25). Same token, same computed fill, two
   different colours on screen.

   Cause: the entering wave is pulled up over the hero by its own height, and
   the hero's vignette (.jt-hero-bed::after, a radial gradient reaching
   rgba(21,17,16,.78) at the edges) was painting over the top of it. The wave's
   brown was being darkened by three quarters of an opaque black at the corners.
   Raising the wave above the hero's own stacking context stops the vignette
   landing on it. */

/* ── A lighter brown for the photo strip ───────────────────────────────────
   #3B2A1E sat almost as dark as the page's ink, so the strip read as a hole cut
   in the page rather than a band of colour in it. This is the same hue lifted:
   still clearly brown against the cream, and no longer competing with the red
   band further down for "the dark thing on this page".

   One token drives the strip and both its waves. The waves used to carry
   style="color:var(--brown)" inline, which no stylesheet rule can override
   without !important, and --brown is declared at a higher specificity than
   :root elsewhere, so the strip changed colour and the waves did not. The
   inline attribute is gone from the two marquee waves and the colour lives
   here, where it can only be one value. */
/* The strip's colour, and both its waves, from one declaration.

   Tried in order: #3B2A1E (the original), #5C4634 (too light), #272322 (the
   logo charcoal, too cold against the cream), and now #4A3527, the mid brown
   off the comparison sheet. Lighter than the original without going pale, and
   still clearly in the warm family rather than beside it. */
:root{--strip:#4A3527;}
:root .marquee{background:var(--strip);}
:root .wave-marq path{fill:var(--strip);}

/* ── One heading, every page ───────────────────────────────────────────────
   Measured across ten pages, the site had five different section headings:

     home            Plus Jakarta Sans 800   54-60px
     products        Archivo 400             54px
     catering        Archivo 400             24px
     delivery        Archivo 400             24px
     find us / care  Archivo 600             40px
     product pages   Archivo 600             40px

   Two of those weights were not real. Archivo ships here at 500, 600 and 900
   only, so every "400" was the browser faking a weight that does not exist in
   the file, which is most of why the inner pages read thin next to home.

   All of it moves onto the home page's heading: Plus Jakarta Sans 800, which is
   self-hosted, with one size for the page title and one for a section. Card
   headings and the tracked-caps labels keep their own roles. */
:root main h1,
:root main h2:not(.vh),
:root .banner h1,
:root .banner-inner h1{
  font-family:'Plus Jakarta Sans','Archivo',system-ui,sans-serif;
  font-weight:800;
  letter-spacing:-.015em;
}
/* page title */
:root .banner h1,
:root main > section:first-of-type h1{
  font-size:clamp(38px,5.2vw,68px);
  line-height:1.03;
}
/* section heading */
:root main h2:not(.vh){
  font-size:clamp(28px,3.4vw,44px);
  line-height:1.1;
}
/* Two exceptions. Both are written at (0,2,2) to match the rule above, which
   picks up an extra class from its :not(.vh) and beat them on the first pass.

   "The other cabinets" is a label for a list of links rather than a section
   title, so it keeps the small tracked caps it already had. */
:root main .morelinks h2:not(.vh){
  font-family:'Archivo',system-ui,sans-serif;
  font-weight:600;font-size:16px;letter-spacing:1.1px;text-transform:uppercase;
}
/* The pie of the month keeps Aleo: it is the one place the logo's own face is
   used deliberately, and it is the feature on the page. */
:root main .pom h2:not(.vh){
  font-family:'Aleo',Georgia,serif;font-weight:700;
  font-size:clamp(34px,4.4vw,60px);letter-spacing:-.02em;
}

/* ── The strip, now between Products and the Pie of the Month ──────────────
   It used to sit directly under the hero, which meant a photograph followed by
   twenty-four more photographs before the page said what the bakery sells. As a
   transition between two sections both its edges are the page ground, so it
   takes a wave on each side and neither one touches the hero.

   The wave above the pie section is the one exception: it fills brown ABOVE its
   curve and leaves the rest transparent, and what shows through there is the
   page cream rather than the pie section's own warm ground. Painting that
   ground onto the wave's box closes the seam. Same fix the pie-into-catering
   wave already carries a few hundred lines up. */
:root .wave-marq-in{margin-top:0;margin-bottom:-1px;}
:root .wave-marq-out{margin-top:-1px;margin-bottom:0;background-color:var(--warm);}
/* The pie section is --warm in dark but --ink-2 in light (see .pom above), and
   the wave carried --warm in both. In light that painted rgb(235,225,211)
   against the section's rgb(231,220,204): four points apart, which is invisible
   as a colour and very visible as a line straight across the page under the
   curve. The wave now follows the section it sits against, in both themes. */
:root[data-theme="light"] .wave-marq-out{background-color:var(--ink-2);}

/* ══ INNER PAGE LAYOUT, 15-09-2026 ═════════════════════════════════════════
   Measured across catering, products, delivery and the six product pages.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Body copy had no measure ──────────────────────────────────────────────
   Most paragraphs sit at 486 to 698px, but two ran the full lane at 1283px:
   "Heating what you ordered" on catering and "Worth knowing" on products. A
   1283px line is about 160 characters, roughly twice what anyone can track
   back from without losing the line. Everything gets the same ceiling. */
:root main p{max-width:68ch;}
:root main .lede p,
:root .fp-know p,
:root .cat-note,
:root .cat-lede{max-width:58ch;}

/* ── The product menus were a ragged grid ──────────────────────────────────
   .range is a 4-column auto-fit grid with align-items:start, and the seven
   groups on the pies page are 1 to 6 items long. The result was a row whose
   columns ended at four different heights and a fourth column holding one item
   above 400px of nothing.

   Multi-column instead: the groups flow down and across and the browser
   balances the columns, which is what this content wants. break-inside:avoid
   was already on .rgroup, so no group can split across a column. */
:root .range{
  display:block;
  columns:3 280px;
  column-gap:clamp(30px,3.4vw,56px);
}
:root .range .rgroup{
  break-inside:avoid;
  margin:0 0 clamp(26px,3vw,40px);
  display:inline-block;width:100%;   /* Safari needs this to honour the break */
}
@media (max-width:860px){ :root .range{columns:2 240px;} }
@media (max-width:560px){ :root .range{columns:1;} }

/* The group headings were still Bricolage, the one face the rest of the site
   was moved off. */
:root .rgroup h3{
  font-family:'Archivo',system-ui,sans-serif;
  font-weight:600;font-size:17px;letter-spacing:normal;
}

/* ── The two photos on a product page were doing too much ──────────────────
   Two 4:3 images at half the lane each is 630x472 apiece, so nearly 500px of
   vertical space before the menu starts, on a page whose job is the menu. They
   are context, not the content. */
:root .shotstrip.shots-2{
  max-width:var(--maxw);
  grid-template-columns:repeat(2,1fr);
  gap:clamp(12px,1.6vw,20px);
}
:root .shotstrip img{aspect-ratio:16/10;}
@media (min-width:861px){
  :root .shotstrip.shots-2{max-width:min(var(--maxw),820px);margin-inline:0;}
}

/* ── "The menu" band: heading and image on different axes ──────────────────
   styles.css centres .menusheet, and the heading was pulled onto the lane
   earlier without the image following it, so the two sat on different left
   edges. Both on the lane now. */
:root .menusheet{max-width:var(--maxw);margin-inline:auto;text-align:left;}
:root .menusheet img{margin-left:0;margin-right:auto;}
:root .menusheet > *{margin-left:0;}

/* Their pastry menu prints "CHUNKY STEAK" then "all served in our traditional
   gravy with onion:" underneath, and the two had been run together into one
   heading that wrapped to two lines and pushed its column out of step with the
   other three. The note is its own line again. */
:root .rgroup .rnote{
  margin:2px 0 0;font-size:14px;line-height:1.45;color:var(--muted);
  max-width:34ch;
}
/* The rule under a group heading belongs under the whole heading block. With
   the note added it was landing between the heading and its own note, which
   made the note read as the first item in the list. Where a note exists the
   rule moves down to sit under it. */
:root .rgroup h3:has(+ .rnote){border-bottom:0;padding-bottom:0;margin-bottom:0;}
:root .rgroup .rnote{
  border-bottom:1px solid var(--red);
  padding-bottom:10px;margin-bottom:12px;max-width:none;
}

/* ── Two faces still out of step ───────────────────────────────────────────
   A sweep of every text node across seven pages found:

   Archivo 400, 30 instances. Archivo ships here at 500, 600 and 900 only, so
   400 is the browser synthesising a weight that is not in the file. It renders
   thinner and slightly differently shaped than the real 500.

   Bricolage Grotesque on .handle, one instance, the "@bakeryonoconnell" line.
   The last of that face anywhere on the site. */
:root .handle{font-family:'Archivo',system-ui,sans-serif;font-weight:600;}
:root main a:not(.btn):not(.card),
:root main b,
:root main h3{font-synthesis-weight:none;}
:root .rgroup li b{font-family:'Work Sans',system-ui,sans-serif;font-weight:500;}
:root .detailpage .lede p{font-family:'Work Sans',system-ui,sans-serif;font-weight:400;}

/* ── The red band waves, off the inline attribute ──────────────────────────
   The two waves either side of the red ordering band carried
   style="color:var(--band)" and filled with currentColor. That is an inline
   style attribute, and this site ships style-src 'self' with no
   'unsafe-inline', so the browser DROPS it on the deployed build: the waves
   inherited whatever colour the surrounding text had instead of the band red.
   It looked right locally over file:// and wrong everywhere the CSP applied,
   which is why measuring the local copy never caught it. The adopt CSP gate
   did.

   Same fix the two marquee waves already carry a few lines up: the colour
   moves to a rule. :not(.wave-marq) keeps this off those, which fill --strip
   and would otherwise be beaten by this selector's higher specificity. */
:root svg.wave:not(.wave-marq) path{fill:var(--band);}

/* ── Footer legal line ────────────────────────────────────────────────────
   Their site carries a copyright notice on every page and ours carried none.
   Quiet, small, below the columns, and deliberately without a year so it
   cannot go stale in a footer nobody remembers to edit. */
:root[data-theme] .foot .foot-legal{
  margin:18px 0 0;padding-top:14px;
  border-top:1px solid color-mix(in srgb, var(--cream) 14%, transparent);
  font-size:13px;line-height:1.5;opacity:.72;text-align:center;
}

/* ── About, two alternating rows ──────────────────────────────────────────
   Six paragraphs stacked in one column beside a single photograph read as a
   wall of text, which is what Josh called chunky. Same copy, split where the
   story turns: row one is who we are and where we came from, row two is what
   we are now, where we sit and the one closure of the year.

   Row one keeps .split-flip (photo left, words right) and row two is a plain
   .split (words left, photo right), so the eye zigzags rather than running
   down one edge. Below 860px .split collapses to one column already, and the
   source order then reads text, photo, text, photo, which is the right
   reading order on a phone. */
:root .about-row-2{margin-top:clamp(28px,4vw,64px);}
@media (max-width:860px){
  :root .about-row-2{margin-top:clamp(22px,6vw,34px);}
}

/* ── "Follow us" was smaller than every other section heading ─────────────
   44px against the 48 to 60px the rest of the page runs. It is a display
   heading split over two lines, half of it outlined, so it can carry real
   size. The stroke is set in em so it scales with the type. */
/* (0,3,2). :root main h2:not(.vh) a few hundred lines up is (0,2,2), because
   :not() contributes its argument's specificity, and it was beating a plain
   :root .hollow-h at (0,2,0). Same trap the README records twice. */
:root main h2.hollow-h:not(.vh){font-size:clamp(40px,6vw,80px);line-height:1.02;}

/* ── Footer "Pages" was six stacked lines ─────────────────────────────────
   .foot-nav a is display:block, so the six page links made the footer column
   six rows tall whilst Follow next to it was three. Two columns for the long
   one only, matched by :has(), so Follow is left alone. The label spans both. */
:root[data-theme] .foot-nav:has(a:nth-of-type(5)){
  columns:2 108px;column-gap:26px;
}
:root[data-theme] .foot-nav:has(a:nth-of-type(5)) b{column-span:all;}
@media (max-width:520px){
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)){columns:1;}
}

/* ── The second line under the delivery wave ──────────────────────────────
   The rule above fixed the COLOUR mismatch where the wave meets the footer,
   but .foot also carries border-top:1px solid var(--rule). On every other page
   that rule is a divider between a section and the footer and reads correctly.
   On delivery the wave lands directly on the footer, so the border cuts a hard
   straight line across the curve, which is the second line under the wavy bit.
   Drop it only where main actually ends in a wave. */
:root[data-theme] main:has(> svg.wave:last-child) + .foot{border-top:0;}

/* ── Footer page links were running together on a phone ───────────────────
   The 44px tap-target pass set :root .foot a{display:inline-block} under
   900px. .foot-nav a is block by design, one link per line, and the markup has
   no whitespace between several of the </a><a> pairs, so as inline-block they
   rendered as "ProductsCatering DeliveryFind us".

   Block is also the better tap target here, since it takes the full column
   width, so the exception is the right way round. */
@media (max-width:900px){
  :root[data-theme] .foot .foot-nav a{display:block;}
}

/* ── Find us: map beside the facts, and a hierarchy ───────────────────────
   Two problems, both Josh's read and both correct.

   1. NOTHING TO LOOK AT FIRST. The 1,074px block that carries the whole point
      of the page had no visible heading at all (its h2 is .vh), and Address,
      Hours, Phone and Refunds were all set as the same 14px tracked label. Four
      equal signposts is the same as none. The address is what a "find us" page
      is for, so it now leads at display size and the rest steps down from it.

   2. THE MAP WAS AT THE BOTTOM, full width, so the two text columns above it
      read as one undifferentiated slab. It moves into its own lane beside the
      facts, which breaks the text up and puts the map where the eye lands
      second. Below 860px the grid is one column and the source order still
      reads address, hours, phone, map, which is the right order on a phone. */
@media (min-width:861px){
  /* Scoped with :has() to the .fp that actually carries the map. Parking and
     access uses .fp too, with two text columns and no map, and an unscoped
     rule collapsed it to one column and made the page 300px taller. */
  :root .fp:has(.fp-map-wide){
    grid-template-columns:minmax(0,1fr) minmax(0,1.04fr);
    column-gap:clamp(30px,3.6vw,60px);
    align-items:start;
  }
  /* Both text columns share the left lane, stacked. */
  :root .fp:has(.fp-map-wide) > .fp-col:not(.fp-map){grid-column:1;}
  :root .fp-map-wide{grid-column:2;grid-row:1 / span 2;}
  :root .fp-map-wide iframe{aspect-ratio:1 / 1.06;margin-bottom:0;}
}

/* The address is the answer to the page's question, so it is the biggest
   thing in the block and the only one at display size. */
:root .fp-addr{
  font-size:clamp(26px,3.1vw,40px);line-height:1.18;letter-spacing:-.01em;
  font-family:'Plus Jakarta Sans','Archivo',system-ui,sans-serif;font-weight:800;
}
/* Hours and Phone stay as labels but read as second tier, not as peers of the
   address. Refunds is a footnote and is set like one. */
:root .fp-label{opacity:.78;}
:root .fp-col .fp-label[data-oc-id$="lb.5"]{
  font-size:12.5px;opacity:.6;margin-top:6px;
}
:root .fp-col .fp-label[data-oc-id$="lb.5"] + .fp-note{font-size:14px;opacity:.78;}

/* ── The nav was drawing TWO bottom borders ───────────────────────────────
   .pagetop carries border-bottom 1px rgba(33,26,21,.16) and .topbar inside it
   carries another at 1px rgba(46,33,25,.2). They stack, so the bar ends in two
   hairlines a pixel apart in slightly different tones. At 1x it reads as one
   slightly fat, slightly muddy rule; against a flat area it reads as two lines,
   which is what it looks like on delivery where the bar sits directly above the
   wave. The outer one is the bar's edge and stays; the inner one goes. */
/* (0,5,1). styles.css carries
     ':root[data-theme="light"] .pagetop .topbar, :root[data-theme="light"] .pagetop.is-stuck .topbar'
   as a SELECTOR LIST, and a list takes the specificity of its highest MATCHING
   selector, not of the one that reads first. The bar is .is-stuck whenever this
   matters, so that rule weighs (0,5,0), which quietly beat a first attempt at
   (0,4,0) even though this sheet loads later. Naming the element takes it to
   (0,5,1). */
:root[data-theme] .pagetop.is-stuck header.topbar,
:root[data-theme] .pagetop header.topbar{border-bottom:0;}

/* ── Footer "Pages", tightened and aligned ────────────────────────────────
   CSS multi-column balanced the six links by height, so "Reheating and
   storage" wrapping to two lines left the two columns staggered against each
   other. A two-column grid puts them on shared rows instead, with a tighter
   gap, and the label spans both. */
:root[data-theme] .foot-nav:has(a:nth-of-type(5)){
  columns:auto;
  /* Equal columns rather than auto. auto sized column one to its widest item,
     "Reheating and storage" on a single line, which pushed the two columns
     ~163px apart. Equal halves let that one wrap over two lines and brings the
     columns together. */
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  column-gap:18px;row-gap:0;justify-content:start;align-items:start;
}
:root[data-theme] .foot-nav:has(a:nth-of-type(5)) b{
  /* display:block, because text-align does nothing to an inline <b>.
     Centred across the two columns put the word 85px right of its own links,
     whilst the other three footer headings sit hard left over theirs, so it
     read as a mistake. It is left-aligned with the first column now, which is
     where Products, Delivery and Reheating start. */
  grid-column:1 / -1;display:block;text-align:left;
}
@media (max-width:520px){
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)){grid-template-columns:1fr;}
}

/* ── The nav border smeared across two pixel rows ─────────────────────────
   Measured off the rendered pixels on delivery at 390px, reading straight down
   a column:

     y=78..85  (231,220,204)   the bar
     y=86      (194,183,168)   border, row one
     y=87      (199,189,174)   border, row two
     y=88+     (242,235,225)   the page

   The bar's height resolves to a fraction, so its 1px border antialiases over
   TWO device rows in two different greys and reads as a pair of hairlines. That
   is the "two lines" that kept being reported under the delivery wave: the bar
   sits directly above that wave with nothing between, so the smeared border and
   the wave stack up in one glance.

   The bar already separates itself from the page by tone, (231,220,204) against
   (242,235,225), so the border is doing no work the background is not. Removing
   it leaves exactly one edge, and one that cannot land between pixels. */
:root[data-theme] .pagetop,
:root[data-theme] .pagetop.is-stuck{border-bottom:0;}

/* ── Footer columns: link text sat 6px below span text ────────────────────
   Measured at 1440: the first line under each footer heading starts at y=688
   in the two columns whose content is plain <span> (the address, "Seven days a
   week"), and at y=694 in the two whose content is <a> (Pages, Follow). The
   6px is .foot-nav a's own padding, which is there for the tap target and
   should stay. Pulling the label's bottom margin back by the same 6px puts the
   first line of links on the same line as its neighbours, in both the grid
   (Pages) and block (Follow) columns, without touching the tap area. */
:root[data-theme] .foot-cols .foot-nav b{margin-bottom:0;}
/* Zero, not -6px. The label already carried a 6px bottom margin, so a
   -6px value moved the links 12px and overshot the other way. */

/* ── Footer: even GAPS, not just even columns ─────────────────────────────
   The four columns were already exactly equal at 302.6px, but their contents
   are not: "Open 24 hours" runs 138px and leaves 189px of air before the next
   column, whilst Pages fills its full 302px and leaves only the 24px gap. Equal
   columns with unequal content is what reads as inconsistent spacing.

   Sizing each column to its content and distributing the slack evenly gives
   equal gaps, which is the thing the eye actually measures. Pages is capped so
   its two sub-columns stay narrow enough for "Reheating and storage" to keep
   wrapping over two lines. */
@media (min-width:861px){
  :root[data-theme] .foot-cols{
    grid-template-columns:repeat(4,max-content);
    justify-content:space-between;
  }
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)){width:224px;}
}

/* ── Two hairlines bracketing every flipped wave, dark theme only ─────────
   Measured on delivery at 1440, data-theme="dark", reading straight down:

     y=538  (123,38,22)   darker red hairline, just above the wave box
     y=539  (142,42,24)   the wave, red
     y=598  (23,18,16)    lighter hairline, the box's last row
     y=599  (21,17,16)    the footer

   .wave-up is transform:scale(-1,-1), and a transformed element antialiases its
   own box edges against whatever is behind it. The blend is there in both
   themes, but red against cream hides it and red against near-black does not,
   which is why five rounds of looking at the light theme found nothing.

   Scaling a hair beyond 1 pushes those antialiased edge rows outside the
   visible box. The curve moves by about a pixel, which is not perceptible, and
   the path already spans the full viewBox so nothing is clipped. */
/* No transform at all. Scaling only pushed the bottom edge out of view; the
   top one stayed, because a transformed element's antialiased edge composites
   its own background (here the footer's near-black) with whatever is behind it
   (the red band), giving a darker red row that no amount of scaling removes.
   The path is now authored pre-flipped in the markup — mirrored in both axes,
   x -> 1440-x and y -> 140-y, which is what scale(-1,-1) was doing — so the
   element has no transform, no compositing layer, and no edge to antialias. */
:root[data-theme] svg.wave-up{transform:none;}

/* ══ Spacing rhythm ════════════════════════════════════════════════════════
   Audited against the rendered pages at 1440 and 390 and compared with normal
   practice. Three things were out, one badly.

   1. LINE LENGTH. Body paragraphs on index, catering, delivery, find-us and
      care measured 85 characters. The readable band is 45 to 75, around 66 is
      the usual target, and 85 is far enough past it to cost comprehension: the
      eye loses the line it is returning to. Capped below.

   2. PARAGRAPH RHYTHM. Eleven distinct bottom margins across the site: 0, 8,
      12, 14, 16, 17, 18, 22, 26, 28 and 36px. That scatter is what reads as
      inconsistent spacing even when no single value looks wrong. Normalised to
      one step, with the last paragraph in a block flush so the section's own
      padding is the only gap underneath.

   3. HEADING RHYTHM. Thirteen distinct heading-to-body ratios, from 0 to
      0.71em. Normalised to 0.4em on h2 and 0.45em on h3, both inside the
      conventional 0.4 to 0.6 band, and left at 0 where a grid gap already does
      the spacing.

   Section padding was already fine: 100px desktop and 58px mobile sit inside
   the usual 80 to 120 and 40 to 64 bands, so it is untouched. */

/* 1. Measure. Scoped to running prose, so cards, tables, list items, the hero
      and the footer keep the widths they were designed to. */
:root[data-theme] main .sec > p,
:root[data-theme] main .split-txt p,
:root[data-theme] main .lede p,
:root[data-theme] main .detailpage > p{max-width:68ch;}
/* Centred blocks keep their centring whilst capped. */
:root[data-theme] main .sec[style*="center"] > p,
:root[data-theme] main .menusheet > p,
:root[data-theme] main .cat-what-lede{margin-inline:auto;}

/* 2. One paragraph step. */
:root[data-theme] main .sec > p,
:root[data-theme] main .split-txt p,
:root[data-theme] main .lede p{margin-block:0 1.05em;}
:root[data-theme] main .sec > p:last-child,
:root[data-theme] main .split-txt p:last-child,
:root[data-theme] main .lede p:last-child{margin-bottom:0;}

/* 3. One heading step, where a heading has a margin at all. */
:root[data-theme] main h2:not(.vh):not(:last-child){margin-bottom:0.4em;}
:root[data-theme] main h3:not(:last-child){margin-bottom:0.45em;}

/* Two catering paragraphs escaped the measure cap because they sit inside
   <details> and inside .menusheet rather than directly in a .sec. Counted by
   real characters per line they run 81 and 83 against a site median of 65. */
:root[data-theme] main .cat-range-details > p,
:root[data-theme] main .menusheet > p,
:root[data-theme] main .banner-inner > p{max-width:68ch;}

/* Paragraph steps: body and lede, and nothing else. 26, 28 and 36px were one-off
   values on .pom-desc, .cat-what-lede and one unclassed catering paragraph,
   which is the scatter that reads as uneven spacing down a page. */
:root[data-theme] main .cat-lede,
:root[data-theme] main .care-lede,
:root[data-theme] main .cat-what-lede,
:root[data-theme] main .pom-desc{margin-bottom:22px;}


/* ══ Products dropdown in the primary nav ══════════════════════════════════
   Their own site puts the product pages under Products, and the six of them
   were otherwise only reachable from the Products index or the "Other products"
   block at the foot of a page.

   No JavaScript. It opens on :hover for a mouse and on :focus-within for a
   keyboard, so tabbing through the nav reveals it the same way. The Products
   link itself still goes to products.html, so nothing here is the only route
   to anything. Lives in hero-2026-09.css because the nav is on all 13 pages
   and this sheet is the one they all load.

   Note the colours: --ink is the GROUND and --cream is the TEXT, and getting
   those the wrong way round has shipped invisible text twice on this build. */
:root[data-theme] .pagetop .nav .navitem{
  position:relative;
  display:inline-flex;
  align-items:center;
}
:root[data-theme] .pagetop .nav .navdrop{
  position:absolute;
  top:100%;
  left:50%;
  transform:translateX(-50%) translateY(-6px);
  display:grid;
  min-width:220px;
  padding:8px;
  background:var(--warm);
  border-radius:14px;
  box-shadow:0 18px 40px rgba(0,0,0,.22);
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .16s ease, transform .16s ease;
  z-index:60;
}
:root[data-theme] .pagetop .nav .navitem:hover .navdrop,
:root[data-theme] .pagetop .nav .navitem:focus-within .navdrop{
  opacity:1;
  visibility:visible;
  pointer-events:auto;
  transform:translateX(-50%) translateY(0);
}
/* A gap between the link and the panel would close the menu as the pointer
   crossed it, so the panel's own top padding bridges it instead. */
:root[data-theme] .pagetop .nav .navitem::after{
  content:'';
  position:absolute;
  top:100%;
  left:0;
  right:0;
  height:12px;
}
:root[data-theme] .pagetop .nav .navdrop a{
  display:flex;
  align-items:center;
  min-height:44px;          /* the tap target floor this build already passes */
  padding:0 14px;
  border-radius:9px;
  white-space:nowrap;
  color:var(--cream);
  font-size:15.5px;
}
:root[data-theme] .pagetop .nav .navdrop a:hover,
:root[data-theme] .pagetop .nav .navdrop a:focus-visible{
  background:color-mix(in srgb, var(--cream) 10%, transparent);
}

@media (prefers-reduced-motion:reduce){
  :root[data-theme] .pagetop .nav .navdrop{transition:none;}
}

/* On a phone the nav is already a stacked panel behind the toggle, so a floating
   menu would be a panel inside a panel. The six sit in the stack instead, set in
   from the top-level links so the hierarchy still reads. */
/* Was 860px, whilst the hamburger takes over at 1080px. Between the two the
   panel was a stack but the sub-links were still a hover-only floating menu, so
   the six product pages were unreachable from the header on a tablet. */
@media (max-width:1080px){
  :root[data-theme] .pagetop .nav .navitem{
    display:block;
    width:100%;
  }
  :root[data-theme] .pagetop .nav .navitem::after{display:none;}
  :root[data-theme] .pagetop .nav .navdrop{
    position:static;
    transform:none;
    opacity:1;
    visibility:visible;
    pointer-events:auto;
    min-width:0;
    padding:2px 0 6px 16px;
    background:transparent;
    box-shadow:none;
    border-radius:0;
  }
  :root[data-theme] .pagetop .nav .navdrop a{
    min-height:44px;          /* was 40, under the floor the rest of the site keeps */
    padding:0 6px;
    font-size:15px;
    opacity:.86;
  }
}


/* The mobile menu grew from 5 links to 11 when the Products dropdown went in.
   Measured at 360x640 it stands 563px tall and its bottom lands at 650, so it
   already runs past the viewport and on a shorter phone the last links would be
   unreachable. It scrolls inside itself instead of off the screen. */
@media (max-width:1080px){
  :root[data-theme] .pagetop .nav{
    max-height:calc(100dvh - var(--navh, 88px) - 12px);
    overflow-y:auto;
    overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
  }
}


/* ══ The header must not clip what hangs out of it ═════════════════════════
   site-v3.css:227 sets `.pagetop{overflow:hidden}` and the block below it puts
   the same on `.topbar`. That was written to clip an overhanging sign version of
   the bar which no longer exists, and only the HOME page loads that sheet.

   Measured at 1440px on the home page: the Products dropdown is absolutely
   positioned from y=64 to y=344 whilst .pagetop ends at y=87, so 23 of its 280
   pixels showed and the rest was cut off. Every other page was fine because none
   of them load site-v3.css.

   The same clipping also cuts the MOBILE menu on the home page, which is the
   "only 5 of 11 links reachable on /" the bug sweep reported.

   hero-2026-09.css loads after site-v3.css, so this wins. There is already a
   precedent for it at line 810, which un-clips .topbar in the stuck state. */
/* All four states, both themes, every width. The earlier version of this rule
   covered .pagetop and .topbar but NOT the .is-stuck variants, so the dropdown
   worked at the top of the home page and was clipped again the moment the bar
   went sticky, about 60px of scroll. With the panel clipped to nothing the hit
   test then found the hero logo behind it, which reads as the hero covering the
   menu; it is the same single cause.
   The .is-stuck selectors carry an extra class, so they must be named or they
   out-specify this. */
:root[data-theme] .pagetop,
:root[data-theme] .pagetop .topbar,
:root[data-theme] .pagetop.is-stuck,
:root[data-theme] .pagetop.is-stuck .topbar,
:root[data-theme="light"] .pagetop,
:root[data-theme="light"] .pagetop .topbar,
:root[data-theme="light"] .pagetop.is-stuck,
:root[data-theme="light"] .pagetop.is-stuck .topbar{overflow:visible;}
:root[data-theme] .pagetop .nav{z-index:70;}


/* ══ Hero ribbons: centre each string in the ribbon you can actually SEE ═══
   Josh: the pair reads as though one ribbon is longer. Measured, they are not:
   both halves are 540px and both visible ends are 238px. What differs is where
   the text sits. The base rule pushes each string to its OUTER edge, so "Open
   24/7" at 9 characters and "North Adelaide" at 14 end up different distances
   from the mark, and the eye reads that as uneven ribbon.

   The mark is centred on the join and covers 604 of the band's 1080px, so it
   eats 302px of each half. Reserving that on the inner side and centring in what
   is left puts each string in the middle of its visible ribbon.

   THE UNIT MATTERS. Percentage padding on a flex ITEM resolves against the FLEX
   CONTAINER, not the item, so 56% of the half became 605px of the 1080px band,
   collapsed the content box and threw both strings outside their ribbons. It is
   a percentage of the BAND: 302 / 1080 = 28%. Measured after: both strings sit
   0px off the centre of their visible ribbon and both fall inside it. */
@media (min-width:861px){
  :root .jt-hero .jt-half-l,
  :root[data-theme] .jt-hero .jt-half-l{
    justify-content:center;padding-left:0;padding-right:28%;
  }
  :root .jt-hero .jt-half-r,
  :root[data-theme] .jt-hero .jt-half-r{
    justify-content:center;padding-right:0;padding-left:28%;
  }
}


/* ══ Colour pass, 17-09-2026 ═══════════════════════════════════════════════
   Josh picked shade 2 of four. #A8371C is a red-orange between their own deep
   red #8E2A18 and a full orange; cream text on it measures 6.1:1, comfortably
   over the 4.5 floor, where the full orange only reached 4.0 and failed.

   The banner and the wave that leaves it have to carry the SAME fill or the
   curve shows a seam, which is the hairline this build has already produced
   twice. The wave's path is the colour above the curve; below it is unpainted
   so the page's own textured ground continues through. */
:root .banner,
:root[data-theme] .banner{background:#A8371C;}
:root .banner h1, :root[data-theme] .banner h1,
:root .banner p,  :root[data-theme] .banner p{color:#FFF7F0;}
:root .banner .crumb a, :root[data-theme] .banner .crumb a{color:#FFF7F0;opacity:.88;}
:root .banner .crumb a:hover, :root[data-theme] .banner .crumb a:hover{opacity:1;}
:root svg.wave.wave-warm:not(.wave-marq) path{fill:#A8371C;}

/* The phone button had three looks, because four sheets style .topcall and none
   of them covered every state. At rest it was #8E2A18; once the bar stuck, the
   rule at line 303 won on specificity (it carries .is-stuck, this one did not)
   and it jumped to #B33520; and on the home page site-v3.css set the hover
   colour to var(--v-red), which is the same red as the ground, so the number
   vanished when you pointed at it. Josh picked the stuck colour, so all four
   states are pinned here, last in the cascade, at a specificity above every
   other rule that touches this button. */
:root .pagetop .topcall,
:root[data-theme] .pagetop .topcall,
:root[data-theme] .pagetop.is-stuck .topcall{background:#B33520;color:#fff;}
:root[data-theme] .pagetop .topcall:hover,
:root[data-theme] .pagetop.is-stuck .topcall:hover{background:#8E2A18;color:#fff;}

/* Alternating product rows: the brown stays, the other half moves from --warm
   to a deeper cream so the page carries more colour without another dark block. */
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(odd),
:root[data-theme] .detailpage .counter-range .counter-plain{background:#E2D3BC;}
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even){background:var(--strip);}


/* ══ "Other products" given room ══════════════════════════════════════════
   Josh: "feels a bit cramped." Measured on products-cakes: the links were 21px
   tall against the 44px tap floor the rest of this build keeps, the row gap was
   25px, and "All products" sat 14px out of line with the list above it so it
   read as a stray sixth item rather than the summary link.

   Bigger type, a rule under the heading to separate it from the wave above, and
   every link given a real target. The rule is what does most of the work: the
   block previously ran straight on from the CTA band with nothing dividing it. */
:root[data-theme] .morelinks-in h2{margin-bottom:0;}
:root[data-theme] .morelinks-in ul{
  gap:14px 40px;
  margin-top:22px;
  padding-top:20px;
  border-top:1px solid var(--rule);
}
:root[data-theme] .morelinks-in ul li a{
  display:inline-flex;align-items:center;
  min-height:44px;
  font-size:20px;
  text-decoration:none;
}
:root[data-theme] .morelinks-in ul li a:hover,
:root[data-theme] .morelinks-in ul li a:focus-visible{
  text-decoration:underline;text-underline-offset:5px;
}
/* "All products" is the last <li> in the row now rather than a <p> underneath,
   so it takes the list's own sizing and needs nothing of its own. As a <p> it
   could never join the row and sat 14px further in than the links above it. */

/* The separator dot is position:absolute with no top, so its static position
   was the top of the line box. The links are inline-flex at min-height:44px
   for the tap target, so every dot rendered near the top of that 44px box
   instead of between the words. Stretched to the item and centred in it. */
:root[data-theme] .morelinks-in ul li+li::before{
  top:0;bottom:0;display:flex;align-items:center;
}


/* ══ The bar needs an edge again ══════════════════════════════════════════
   Josh: "cant tell where nav bar ends, especially in pie of month section."
   Measured on the home page, scrolled to the pie section: the bar's background
   is rgb(231,220,204) and .pom's background is rgb(231,220,204). Identical, with
   border-bottom:0 and box-shadow:none, so the bar has nothing to end with.

   The border was removed on purpose: it was set on BOTH .pagetop and .topbar and
   the two antialiased into the two-line artefact that took five reports to find.
   So this is a SHADOW on one element rather than a border on two. One line, no
   layout shift, and it cannot double because nothing else casts one.

   The hairline carries the weight; the soft shadow underneath only appears once
   the bar is stuck, which is when it is floating over content rather than
   sitting at the top of the page. */
:root[data-theme] .pagetop{
  box-shadow:0 1px 0 rgba(33,26,21,.14);
}
:root[data-theme] .pagetop.is-stuck{
  box-shadow:0 1px 0 rgba(33,26,21,.16), 0 6px 18px rgba(33,26,21,.07);
}


/* ══ The banner wave, available on every page ═════════════════════════════
   This lived in inner-2026-09.css, which find-us, care and 404 do not load, so
   their orange banners ended in a straight horizontal line whilst the product
   pages curved. Josh: "orange top banner is straight line not wavy?"
   Moved here, which all 13 pages load. Duplicating the declaration is harmless:
   it is the same value, and inner's copy simply loses or ties. */
:root svg.wave.wave-warm:not(.wave-marq){
  display:block;
  background:transparent;
  margin-top:-1px;
}
:root svg.wave.wave-warm:not(.wave-marq) path{fill:#A8371C;}

/* ══ Short pages left cream under the footer ══════════════════════════════
   body is display:block with no min-height and html carries no background, so
   on a page shorter than the window the footer ended and body's #F3ECE2 ran on
   underneath its #E7DCCC. The 404 is 976px tall, so on any window over that it
   showed a lighter band below the footer. .pagetop is position:fixed and out of
   flow, so the column is main then footer, and main taking the spare space
   pushes the footer to the bottom without moving anything on a long page. */
:root[data-theme] body{
  min-height:100svh;display:flex;flex-direction:column;
}
:root[data-theme] body > main{flex:1 0 auto;}

/* ══ Jess's pass, 17-09-2026 ══════════════════════════════════════════════ */

/* "Follow us" on one line. It was two display:block spans, so it always broke
   over two. Only the display changes here: "Follow" keeps its hollow outline
   and "us" stays solid, which is the effect Josh wanted back. */
:root .hollow-h .hw-out,
:root .hollow-h .hw-solid,
:root[data-theme] .hollow-h .hw-out,
:root[data-theme] .hollow-h .hw-solid{
  display:inline;
}

/* The social buttons were 46px squares around a 19px mark. Jess wanted them
   bigger, so 56px around 24px, which also clears the 44px tap floor with room
   to spare. The labels stay visually hidden, as they were. */
:root[data-theme] .socials-links .soc{
  width:56px;height:56px;
}
:root[data-theme] .socials-links .soc svg{
  width:24px;height:24px;
}

/* The home page product cards were a photo and a name inside a bare <a>, with
   nothing saying they went anywhere. They carry the same "See the range" the
   products page already uses. */
:root[data-theme] #range .cards .card .card-more{
  display:inline-block;margin-top:6px;
}

/* Moving the counter strip above the range left two flat seams where the page
   uses waves everywhere else.
   One: wave-marq-out paints its own ground --warm, which matched Pie of the
   Month when it sat directly under the strip. It now sits over the range, so
   that ground became a 43px darker band under the marquee. It takes the page
   cream instead.
   Two: the range now runs straight into Pie of the Month, two different creams
   meeting on a hard horizontal line. A wave carries one into the other. */
:root .wave-marq-out,
:root[data-theme] .wave-marq-out{background-color:#F3ECE2;}
:root svg.wave.wave-pom,
:root[data-theme] svg.wave.wave-pom{background-color:transparent;margin-bottom:-1px;}
:root svg.wave.wave-pom path,
:root[data-theme] svg.wave.wave-pom path{fill:#E7DCCC;}

/* Jess: "There's too much space between Catering and What We Cater." The banner
   wave is already 53px of air and the first section then added its full 89px
   on top, so every inner page opened on 142px of empty cream. The wave counts
   as the air, so the first section after it takes a third of its usual top
   padding. Same gap existed on all twelve inner pages, not just catering. */
:root[data-theme] svg.wave.wave-warm + .sec,
:root[data-theme] svg.wave.wave-warm + section{
  padding-top:clamp(20px,2.4vw,32px);
}

/* The footer Pages column was capped at 224px so "Reheating and storage" would
   wrap over two lines. "Find us" becoming "Where to find us" no longer fits in
   half of that, so it wrapped too. Widened just enough to take the longer
   label on one line. */
@media (min-width:861px){
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)){width:268px;}
}

/* Jess: the delivery sections carry too much white space. Both are two column
   grids where the left column runs short, so the slack is the section's own
   vertical padding sitting under an already empty half. Cut on this page only,
   because elsewhere the columns are closer in length and the rhythm is right. */
:root[data-theme] body[data-page="delivery"] .sec{
  padding-bottom:clamp(32px,4vw,52px);
}
:root[data-theme] body[data-page="delivery"] .sec.warmband{
  padding-top:clamp(40px,4.6vw,60px);
}

/* ══ [J1] Red menu bar ════════════════════════════════════════════════════
   Jess: "the menu bar should also be that red colour, with the text in white."
   It takes #8E2A18 rather than the banner's #A8371C, because on an inner page
   the bar sits directly above the banner and two near-identical reds read as
   one block. The mark swaps to logo-redbar-dark.png, which was already in the
   folder cut for exactly this. The phone button cannot stay red on red so it
   inverts. Delete this whole block to revert.  ───────────────────────────── */
:root .pagetop, :root[data-theme] .pagetop,
:root .pagetop .topbar, :root[data-theme] .pagetop .topbar,
:root[data-theme] .pagetop.is-stuck, :root[data-theme] .pagetop.is-stuck .topbar,
:root[data-theme="light"] .pagetop, :root[data-theme="light"] .pagetop .topbar{
  background:#8E2A18;
}
/* the edge shadow was there because cream on cream had none; red does not need it */
:root[data-theme] .pagetop,
:root[data-theme] .pagetop.is-stuck{box-shadow:none;}

:root[data-theme] .pagetop .nav a,
:root[data-theme] .pagetop.is-stuck .nav a,
:root[data-theme="light"] .pagetop .nav a{color:#F6EFE6;}
:root[data-theme] .pagetop .nav a:hover,
:root[data-theme] .pagetop .nav a:focus-visible,
:root[data-theme] .pagetop .nav a[aria-current="page"]{color:#FFFFFF;}
:root[data-theme] .pagetop .nav a[aria-current="page"]{border-bottom-color:#FFFFFF;}

/* inverted, because red on red is not a button */
:root .pagetop .topcall,
:root[data-theme] .pagetop .topcall,
:root[data-theme] .pagetop.is-stuck .topcall{background:#F6EFE6;color:#8E2A18;}
:root[data-theme] .pagetop .topcall:hover,
:root[data-theme] .pagetop.is-stuck .topcall:hover{background:#FFFFFF;color:#8E2A18;}

/* hamburger bars and the drawer behind them */
:root[data-theme] .pagetop .navtoggle span,
:root[data-theme] .pagetop .navtoggle span::before,
:root[data-theme] .pagetop .navtoggle span::after{background:#F6EFE6;}
@media (max-width:1080px){
  :root[data-theme] .pagetop .nav{background:#8E2A18;}
  :root[data-theme] .pagetop .nav a{color:#F6EFE6;border-bottom-color:rgba(246,239,230,.22);}
}
/* the dropdown stays a cream panel, so it reads as a menu sitting below the bar */
:root[data-theme] .pagetop .nav .navdrop{box-shadow:0 10px 26px rgba(33,26,21,.22);}
/* ══ [/J1] ════════════════════════════════════════════════════════════════ */

/* [J1b] Six tabs no longer fit the centred nav at its old 32px gap, so three of
   them broke over two lines. Tighter gap and no wrapping inside a tab. Part of
   the red bar change, revert with it. */
@media (min-width:1081px){
  :root[data-theme] .pagetop .topbar .nav{gap:24px;white-space:nowrap;}
  :root[data-theme] .pagetop .nav a{white-space:nowrap;}
}

/* [J1c] The dropdown's own background only exists on desktop, where it is a
   cream panel. Inside the mobile drawer it is transparent, so its six links
   kept the dark colour written for that cream panel and landed on the new red
   at 2.04 against the 4.5 AA needs. Cream in the drawer, dark on the desktop
   panel where the ground is still cream. Part of the red bar, revert with it. */
@media (max-width:1080px){
  :root[data-theme] .pagetop .nav .navdrop a{
    color:#F6EFE6;border-bottom-color:rgba(246,239,230,.18);
  }
  :root[data-theme] .pagetop .nav .navdrop a:hover,
  :root[data-theme] .pagetop .nav .navdrop a:focus-visible{color:#FFFFFF;}
}

/* [J8b] With the Terms table gone the delivery ordering grid had one child and
   a dead right half. Jess also asked for photographs on this page, so the
   shopfront fills that half rather than the column collapsing. The two answers
   were the same answer. */
:root[data-theme] body[data-page="delivery"] .del-shot{
  margin:0;
}
:root[data-theme] body[data-page="delivery"] .del-shot img{
  width:100%;height:auto;display:block;border-radius:3px;
}
@media (max-width:860px){
  :root[data-theme] body[data-page="delivery"] .del-shot{margin-top:22px;}
}

/* [J13] The counter strip started flush against the bottom of the hero photo,
   with no cream between them. A gap above its incoming wave lets the page
   breathe before the brown band arrives. */
:root .wave-marq-in,
:root[data-theme] .wave-marq-in{
  margin-top:clamp(40px,5.2vw,88px);
}

/* [J1d] The nav underline already exists as a 2px ::after that scales in on
   hover, focus and the current page. It was painted #2E2119 for the cream bar,
   which is all but invisible on red, so it goes white. Part of the red bar,
   revert with it. */
:root[data-theme] .pagetop .nav a::after,
:root[data-theme] .pagetop .nav a[aria-current="page"]::after,
:root[data-theme="light"] .pagetop .nav a::after{
  background:#FFFFFF;
}

/* [J1e] My own bug from [J1]. `.pagetop.is-stuck .nav a` ties on specificity
   with `.pagetop .nav .navdrop a` and wins by sitting later in the file, so
   once the bar stuck it painted the dropdown's links cream as well. On desktop
   that panel is still cream, so they went cream on cream at about 1.05 and
   vanished. The panel's own colours are re-asserted above both states here.
   The drawer at =<1080px keeps its cream links from [J1c]. */
@media (min-width:1081px){
  :root[data-theme] .pagetop .nav .navdrop a,
  :root[data-theme] .pagetop.is-stuck .nav .navdrop a{
    color:#211A15;
  }
  :root[data-theme] .pagetop .nav .navdrop a:hover,
  :root[data-theme] .pagetop .nav .navdrop a:focus-visible,
  :root[data-theme] .pagetop.is-stuck .nav .navdrop a:hover,
  :root[data-theme] .pagetop.is-stuck .nav .navdrop a:focus-visible{
    color:#8E2A18;
  }
}

/* [J14] Jess wanted the home page product cards to carry a real button rather
   than a text link, with the destination named. Josh then found the buttons
   disjointed, and the reason was structural: photo and name read as one unit
   whilst the button floated on the page ground as a third object with nothing
   to belong to. The card becomes a panel, the same shape the products page
   already uses, so the button sits inside something. Scoped to #range, so the
   products page keeps its arrow link. */
:root[data-theme] #range .cards .card{
  background:#E7DCCC;
  border-radius:3px;
  overflow:hidden;
}
:root[data-theme] #range .cards .card h3{
  margin:16px 20px 0;
}
:root[data-theme] #range .cards .card .card-btn{
  display:inline-block;
  align-self:flex-start;
  width:auto;
  margin:12px 20px 20px;
  padding:11px 18px;
  background:#8E2A18;
  color:#F6EFE6;
  border:2px solid #8E2A18;
  border-radius:2px;
  font-size:14.5px;font-weight:600;letter-spacing:0;
  transition:background-color .25s ease,border-color .25s ease,color .25s ease;
}
:root[data-theme] #range .cards .card .card-btn::after{content:none;}
:root[data-theme] #range .cards .card:hover .card-btn,
:root[data-theme] #range .cards .card:focus-visible .card-btn{
  background:#B33520;border-color:#B33520;color:#FFFFFF;
}
/* In two columns on a phone the panel is about 124px of usable width, so the
   named labels wrap, and they wrapped to different line counts, two for "See
   our take home options" and three for "See our breakfast range", which left
   the buttons in a row at different heights. Full panel width and centred so
   they agree, balanced wrapping so none of them takes three lines, and pushed
   to the bottom of the panel so the row bottoms line up. */
@media (max-width:520px){
  :root[data-theme] #range .cards .card{display:flex;flex-direction:column;}
  :root[data-theme] #range .cards .card h3{margin:13px 14px 0;}
  :root[data-theme] #range .cards .card .card-btn{
    align-self:stretch;
    width:auto;
    margin:10px 14px 14px;
    margin-top:auto;
    padding:10px 10px;
    font-size:12.5px;
    text-align:center;
    text-wrap:balance;
  }
}

/* [J1f] I dropped the bar's edge in [J1] on the reasoning that red against
   cream is its own edge. On an inner page it is red against red, bar #8E2A18
   over banner #A8371C, and the two merge into one block. A cream hairline
   separates them. Shadow rather than a border, because a border on both the
   wrapper and the topbar is what caused the double line earlier. */
:root[data-theme] .pagetop,
:root[data-theme] .pagetop.is-stuck{
  box-shadow:0 1px 0 rgba(246,239,230,.45);
}

/* [J14b] At 360px "See our breakfast range" still broke to three lines whilst
   its neighbour took two, so that row had a taller button than the other.
   One step smaller below 376px keeps every label to two. */
@media (max-width:375px){
  :root[data-theme] #range .cards .card .card-btn{font-size:11.5px;padding:10px 8px;}
}

/* [J8c] The delivery terms are back, below the ordering copy and inside a cream
   panel. Jess asked for the block gone and separately asked for a line INSIDE it
   softened, which only makes sense if the content stays, so the framing went and
   the facts did not. As five full-width stacked rows it read as loose text with
   nothing lining up; the panel makes it a deliberate info box and the values
   right-align so the two figures are scannable. */
:root[data-theme] body[data-page="delivery"] .del-terms{
  margin-top:clamp(22px,2.6vw,34px);
}
:root[data-theme] body[data-page="delivery"] .del-dl{
  display:grid;
  grid-template-columns:auto 1fr;
  gap:0 22px;
  margin:0;
  max-width:640px;
  background:#E7DCCC;
  border-radius:3px;
  padding:24px 28px;
}
:root[data-theme] body[data-page="delivery"] .del-dl dt{
  font-weight:600;color:#3A2E25;padding:8px 0;
}
:root[data-theme] body[data-page="delivery"] .del-dl dd{
  margin:0;color:#5E5044;padding:8px 0;text-align:right;
}
:root[data-theme] body[data-page="delivery"] .del-dl dd.del-full{
  grid-column:1 / -1;
  text-align:left;
  font-size:14.5px;
  line-height:1.6;
  padding-top:14px;
  margin-top:8px;
  border-top:1px solid rgba(33,26,21,.12);
}
@media (max-width:520px){
  :root[data-theme] body[data-page="delivery"] .del-dl{padding:18px 18px;gap:0 14px;}
}

/* [J15] Jess asked for a "see our catering menu" on the home catering band.
   It sits beside the call button rather than under it, as a text link, so the
   phone stays the primary action. The band is red, so the link takes cream. */
:root[data-theme] #catering .btn-row{
  display:flex;align-items:center;flex-wrap:wrap;gap:14px 26px;
}
:root[data-theme] #catering .btn-row .band-link{
  color:#F6EFE6;
  text-decoration:underline;
  text-underline-offset:4px;
  text-decoration-color:rgba(246,239,230,.55);
  font-size:16px;
  min-height:44px;
  display:inline-flex;
  align-items:center;
}
:root[data-theme] #catering .btn-row .band-link:hover,
:root[data-theme] #catering .btn-row .band-link:focus-visible{
  color:#FFFFFF;text-decoration-color:#FFFFFF;
}

/* [J16] Catering ordering, three columns. Josh: "please order here button way too
   big. maybe have it slightly to the right. so ordering heading, with text below
   it, then button to right, then to right of button theres notice bit."
   The phone number goes back to being the number, the button stops being a slab
   and sits in its own column, and How much notice keeps the right. */
/* .warmband pins this to the catering page: delivery's ordering section also
   carries .cat-order but has no warm band, and the three columns crushed it. */
:root[data-theme] .cat-order.warmband .cat-order-in{
  grid-template-columns:minmax(0,1.25fr) auto minmax(0,1fr);
  align-items:start;
  gap:clamp(24px,3.4vw,54px);
}
:root[data-theme] .cat-order.warmband .cat-order-main .cat-phone{
  display:inline-block;
  background:none;
  padding:0;
  margin:6px 0 10px;
  font-family:'Aleo',Georgia,serif;
  font-size:clamp(26px,2.6vw,34px);
  color:#F6EFE6;
  text-decoration:none;
}
:root[data-theme] .cat-order.warmband .cat-order-main .cat-phone:hover,
:root[data-theme] .cat-order.warmband .cat-order-main .cat-phone:focus-visible{
  text-decoration:underline;text-underline-offset:5px;
}
:root[data-theme] .cat-order.warmband .cat-order-main .cat-note{margin:0 0 6px;}
:root[data-theme] .cat-order.warmband .cat-order-cta{padding-top:6px;}
:root[data-theme] .cat-order.warmband .cat-order-cta .btn{
  background:#F6EFE6;color:#8E2A18;border-color:#F6EFE6;
  padding:13px 22px;font-size:15px;white-space:nowrap;
}
:root[data-theme] .cat-order.warmband .cat-order-cta .btn:hover{
  background:#FFFFFF;border-color:#FFFFFF;color:#8E2A18;
}
@media (max-width:900px){
  :root[data-theme] .cat-order.warmband .cat-order-in{grid-template-columns:1fr;}
  :root[data-theme] .cat-order.warmband .cat-order-cta{padding-top:0;}
}

/* [J17] The reheating FAQ sits on the #8E2A18 band, and its summary hovered to
   var(--red-lite), a red on a red. Measured about 1.6:1, so the question all but
   vanished under the pointer. Cream, which is what every other interactive thing
   on a warm band uses. */
:root[data-theme] .warmband .faq-item summary:hover,
:root[data-theme] .warmband .faq-item summary:focus-visible{
  color:#FFFFFF;
}
:root[data-theme] .warmband .faq-item summary:hover::after,
:root[data-theme] .warmband .faq-item summary:focus-visible::after{
  border-color:#FFFFFF;
}

/* [J8d] Delivery's ordering section: copy and the terms panel on the left, the
   shopfront on the right. Two even columns, because the terms panel needs about
   600px before "Adelaide CBD, businesses only" stops wrapping to three lines. */
:root[data-theme] body[data-page="delivery"] .cat-order-in{
  grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
  align-items:start;
  gap:clamp(26px,3.4vw,52px);
}
@media (max-width:860px){
  :root[data-theme] body[data-page="delivery"] .cat-order-in{grid-template-columns:1fr;}
}

/* ══ Mobile audit, 23-09-2026 ═════════════════════════════════════════════
   Six faults found at 390px on the deployed preview. */

/* Burger close: the later hamburger rule above paints the middle bar back in,
   so the open state showed an asterisk instead of an X. */
:root[data-theme] .pagetop .navtoggle[aria-expanded="true"] span{background:transparent;}

/* Find us: the Refunds label sat 6px under the Get directions button and read
   as part of it. */
:root .fp-col .fp-label[data-oc-id$="lb.5"]{margin-top:30px;}

@media (max-width:700px){
  /* Hero band: two equal halves put "Open 24/7" beside a lot of red and ran
     "North Adelaide" to 4px off the edge. The band now fits its text and
     centres under the mark, with the same 18px either end. */
  :root .jt-band{width:auto;align-self:center;margin-left:auto;margin-right:auto;}
  :root .jt-half{flex:0 0 auto;}
  :root .jt-half-l{padding:11px 12px 11px 18px;}
  :root .jt-half-r{padding:11px 18px 11px 14px;}
}

@media (max-width:900px){
  /* Other products: the desktop separator dots showed in front of every link
     once the list stacked, and each row ran 73px tall. Two columns, no dots,
     44px rows. */
  :root[data-theme] .morelinks-in ul{display:grid;grid-template-columns:1fr 1fr;gap:0 16px;}
  :root[data-theme] .morelinks-in ul li+li::before{display:none;}
  :root[data-theme] .morelinks-in ul li a{padding-top:4px;padding-bottom:4px;font-size:18px;}
}

@media (max-width:520px){
  /* Delivery terms: right-aligned values wrapped mid-phrase in a narrow
     column. Each value now sits under its label. */
  :root[data-theme] body[data-page="delivery"] .del-dl{grid-template-columns:1fr;}
  :root[data-theme] body[data-page="delivery"] .del-dl dt{padding-bottom:0;}
  :root[data-theme] body[data-page="delivery"] .del-dl dd{text-align:left;padding-top:2px;}
}

/* Safari hairline at wave joins. Safari antialiases the wave's bottom pixel
   row and paints the svg over the section it overlaps, so the wave's own
   background colour showed as a 1px line where a band begins. A positioned
   section paints after the svg, so its colour now covers that overlap. */
:root svg.wave + section,
:root section:has(+ svg.wave){position:relative;}

@media (max-width:1080px){
  /* Menu jump on tap. A tap gives the link :hover and :focus, which matched the
     desktop dropdown's open rule and its translateX(-50%). That rule outranks
     the mobile transform:none, so the product links slid 175px left whilst
     the next page loaded. */
  :root[data-theme] .pagetop .nav .navitem:hover .navdrop,
  :root[data-theme] .pagetop .nav .navitem:focus-within .navdrop{transform:none;}
}

@media (max-width:520px){
  /* Footer ran about 900px on a phone, one item per row. Address and hours
     sit side by side, Pages runs in two columns, Follow in one row. */
  :root[data-theme] .foot-cols{grid-template-columns:1fr 1fr;gap:24px 16px;}
  :root[data-theme] .foot-cols .foot-nav{grid-column:1 / -1;}
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)){
    display:grid;grid-template-columns:1fr 1fr;column-gap:16px;columns:auto;
  }
  :root[data-theme] .foot-nav:has(a:nth-of-type(5)) b{grid-column:1 / -1;}
  :root[data-theme] .foot-nav:not(:has(a:nth-of-type(5))){display:flex;flex-wrap:wrap;column-gap:28px;}
  :root[data-theme] .foot-nav:not(:has(a:nth-of-type(5))) b{flex-basis:100%;}
}


@media (max-width:600px){
  /* Menu previews on a phone (24-09-2026). A whole menu page shrunk to 350px
     wide is unreadable and cost around 600px of scrolling on catering. Show
     the top of each page with a fade into the Download button, and on
     catering only page one. Works for whatever PDF the owner uploads, since
     it styles the slot, not the picture. */
  .menusheet img{
    max-height:340px;width:100%;object-fit:cover;object-position:top;
    -webkit-mask-image:linear-gradient(#000 70%,transparent);
            mask-image:linear-gradient(#000 70%,transparent);
  }
  /* Outranks :root[data-theme] .menusheet:has(.sheet + .sheet) .sheet{display:flex} in inner-2026-09.css. */
  :root[data-theme] .menusheet.cat-menusheet:has(.sheet + .sheet) figure.sheet[data-menu-page="2"]{display:none;}
}
