/* ═══════════════════════════════════════════════════════════════════════════
   INNER PAGES · 16-09-2026
   Loaded last, after hero-2026-09.css, so everything here is additive and the
   three earlier sheets are untouched. Reverting is deleting the <link> and the
   markup moves listed below.

   Scope: products.html, the six product sub-pages, catering.html,
   delivery.html. The home page and Find us load none of this.

   Markup moves, nothing else changed and no data-oc-id touched:
     1. .lede and .shotstrip wrapped in .detail-top, on the ONE page with two
        photographs (pies). Three and four-photo pages keep a full-width strip
        and get .shots-wide instead.
     2. .range carries .range-cols-N, N = its number of groups, capped at 3.
     3. the menu section's .warmband swapped for .warmpanel, so each page
        carries one red band rather than two.
     4. .wave / .wave-up either side of the band section, the same pair the
        home page uses between the pie section and catering.
     5. catering: "What we cater" moved above "Ordering", and the two menu
        page-renders removed in favour of the download button alone.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The one ground shift, without the red ─────────────────────────────────
   .warmband is the red band. The menu sheet used it too, which gave every
   sub-page two red sections with cream between them. Same section on --warm,
   so the page's own ink and muted tokens still apply and the red is spent
   once, on the call. */
:root .warmpanel{background:var(--warm);}

/* ── Two photographs: beside the lede, not above the menu ──────────────────
   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. */
:root .detail-top{
  max-width:var(--maxw);margin-inline:auto;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,460px);
  gap:clamp(28px,4vw,52px);align-items:start;
}
:root .detail-top .lede{margin:0;}
:root .detail-top .shotstrip{margin:0;max-width:none;}
:root .detail-top .shotstrip img{aspect-ratio:4/3;}
@media (max-width:980px){
  :root .detail-top{grid-template-columns:1fr;}
  :root .detail-top .shotstrip{margin-top:clamp(20px,3vw,32px);}
}

/* ── Three and four photographs: one strip, equal heights ──────────────────
   These pages carry the range in pictures, so the strip keeps the full lane.
   16:10 rather than 4:3 returns about 80px a row and matches the crop the
   category cards now use, so a photograph is the same shape everywhere. */
:root .shotstrip.shots-wide{max-width:var(--maxw);margin-inline:auto;}
:root .shotstrip.shots-wide img{aspect-ratio:16/10;}

/* ── The range: as many columns as there are groups ────────────────────────
   hero-2026-09.css balances every page at columns:3. On Donuts, which has one
   group of ten names, that left two empty columns and about 400px of blank
   page; on Cafe the same. The column count now follows the content, and a
   single group spreads its own list instead. */
:root .range.range-cols-1{columns:auto;}
:root .range.range-cols-1 .rgroup{margin-bottom:0;}
:root .range.range-cols-1 .rgroup ul{columns:3 190px;column-gap:clamp(30px,3.4vw,56px);}
:root .range.range-cols-1 .rgroup li{break-inside:avoid;}
:root .range.range-cols-2{columns:2 300px;}
:root .range.range-cols-3{columns:3 280px;}
@media (max-width:860px){
  :root .range.range-cols-2,
  :root .range.range-cols-3{columns:2 240px;}
  :root .range.range-cols-1 .rgroup ul{columns:2 170px;}
}
@media (max-width:560px){
  :root .range.range-cols-1 .rgroup ul,
  :root .range.range-cols-2,
  :root .range.range-cols-3{columns:1;}
}

/* Name and description ran together at the same leading, so a six-item group
   read as twelve lines rather than six entries. */
:root .range .rgroup ul{margin:0;padding:0;list-style:none;}
:root .range .rgroup li{margin:0 0 11px;}
:root .range .rgroup li b{display:block;font-size:16px;line-height:1.35;}
:root .range .rgroup li i{
  display:block;font-style:normal;
  font-size:14.5px;line-height:1.45;color:var(--muted);
}

/* ── The closing call, on the band ─────────────────────────────────────────
   styles.css zeroes .ctaband's padding because it used to be a ruled strip
   between two cream sections. As a band it needs its own room, and the two
   rules that drew that strip would now cut across the colour. */
:root .ctaband-band{
  padding-top:clamp(40px,5vw,64px);
  padding-bottom:clamp(40px,5vw,64px);
}
:root .ctaband-band .ctaband-in{border-top:0;border-bottom:0;padding:0;align-items:center;}
:root .ctaband-band .ctaband-in>p:first-child{
  font-family:'Work Sans',system-ui,sans-serif;font-weight:400;
  font-size:clamp(18px,1.7vw,21px);line-height:1.6;letter-spacing:normal;
  max-width:46ch;
}

/* ══ CONTRAST ON THE RED BANDS ═════════════════════════════════════════════
   The band ground is --band #8E2A18. Three kinds of string land on it and all
   three inherit a colour chosen for the cream ground, so each one has to be
   beaten at its own specificity — the trap README-for-redesign documents.

   1. A red .btn on a red band is invisible. Cream fill, band-coloured type:
      measured 8.9:1.                                                        */
:root .warmband .btn{background:var(--ink);color:var(--band);}
:root .warmband .btn:hover{background:#FFFFFF;color:var(--band);}

/* 2. hero-2026-09.css paints .cat-lede with --cream and .cat-note with
      --muted at (0,3,0), which outranks `.warmband p`. In light theme those
      are #211A15 on red (1.9:1) and #64584E on red (1.4:1). Matched one class
      deeper. Full cream, not an opacity, so nothing relies on blending. */
:root .warmband .cat-order-main .cat-lede,
:root .warmband .cat-order-main .cat-note,
:root .warmband .cat-order-main .cat-note span{color:#F6EFE6;}

/* 3. Inline links are painted by a (0,6,1) selector carrying var(--link)
      #B33520, which on the band measures 1.35:1 — this is the "Reheating and
      storage" link on all six sub-pages and the catering link on delivery.
      Overridden at the same shape plus one class. */
:root .warmband .ctaband-in a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root .warmband .cat-order-main a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root .warmband .del-alt-in a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root .warmband p a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc){
  color:#FFFFFF;
}
/* The phone is the exception: it is a cream chip, so it takes the band colour
   as its type. Same six-class shape, plus the element, so it wins. */
:root .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc){
  background:var(--ink);color:var(--band);
  padding:14px 24px;text-decoration:none;
  font-variant-numeric:tabular-nums;
}
:root .warmband .cat-order-main a.cat-phone:hover{background:#FFFFFF;text-decoration:none;}
/* The notice list: label, figure and rule all sat at cream-ground values. */
:root .warmband .cat-notice h3{color:#F6EFE6;}
:root .warmband .cat-dl dt,
:root .warmband .cat-dl dd{border-bottom-color:rgba(246,239,230,.35);}
:root .warmband .cat-dl dt{color:#F6EFE6;}
:root .warmband .cat-dl dd:not(.dd-plain){color:#FFFFFF;}
:root .warmband .cat-dl dd.dd-plain{color:#F6EFE6;}

/* ── Products: the call-ahead sentence gets the band ───────────────────────
   It was the second half of a two-column section head, muted grey at 16px,
   which is where a caption goes rather than the one instruction on the page. */
:root .ringband-in{
  max-width:var(--maxw);margin-inline:auto;
  display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:clamp(24px,4vw,56px);align-items:center;
}
:root .ringband-in p{margin:0;font-size:clamp(18px,1.7vw,21px);line-height:1.6;max-width:50ch;}
:root .ringband-tel{justify-self:end;}
:root .ringband-tel a{
  display:inline-block;
  background:var(--ink);color:var(--band);
  font-family:'Archivo',system-ui,sans-serif;font-weight:600;
  font-size:clamp(20px,2.2vw,26px);letter-spacing:-.01em;
  padding:14px 24px;text-decoration:none;font-variant-numeric:tabular-nums;
}
:root .ringband-tel a:hover{background:#FFFFFF;}
@media (max-width:860px){
  :root .ringband-in{grid-template-columns:1fr;}
  :root .ringband-tel{justify-self:start;}
}

/* ── Category cards ────────────────────────────────────────────────────────
   4:3 at a third of the lane is a 315px-tall photograph per card, so the six
   categories ran past two screens. */
:root .cards .card-shot{aspect-ratio:16/10;}

/* ── Catering: what we cater, then how to order ────────────────────────────
   Four 4:3 photographs butted together with a 2px gap read as one contact
   sheet, and each caption belonged to whichever picture you guessed. */
:root .cat-grid{gap:clamp(10px,1.2vw,14px);}
:root .cat-card img{aspect-ratio:16/10;}
:root .cat-card figcaption{padding-top:12px;font-size:15.5px;line-height:1.4;}

/* The menu is a download, not a picture. Two 990px PDF renders were the
   tallest thing on the page and unreadable at any size that fitted, so the
   section is the heading, the sentence and the button. */
:root .cat-menu-download{grid-template-columns:minmax(0,1fr);max-width:var(--maxw);}
:root .cat-menu-download>div{max-width:62ch;}

/* ── Addendum, 16-09-2026: two chips that only worked in one theme ─────────
   Measured on the redesign before it was applied.

   The cream-chip pattern is written `background:var(--ink); color:var(--band)`.
   --ink is the GROUND token and it flips: #F3ECE2 in light, #1C1614 in dark. So
   in dark theme the chip turned near-black and kept its dark red type, which
   measured 2.12:1 on the catering phone and on every "Ring us, any hour" and
   "Ring an order through" button.

   These chips sit on a red band that does not flip, so their colours should not
   either. Fixed values rather than ground tokens.

   Separately, .ringband-tel a sets color:var(--band) at (0,2,1) and loses to the
   white-link rule above it at (0,7,1), so in LIGHT theme it painted white type
   on the cream chip: 1.17:1, invisible, on the default theme. Matched deeper. */
:root[data-theme] .warmband .btn,
:root[data-theme] .warmband .btn:hover,
:root[data-theme] .warmband .cat-order-main a.cat-phone,
:root[data-theme] .warmband .cat-order-main a.cat-phone:hover,
:root[data-theme] .warmband .fp-cta .btn,
:root[data-theme] .ctaband .btn{
  background:#F6EFE6;
  color:#8E2A18;
}
:root[data-theme] .ringband-tel a,
:root[data-theme] .warmband .ringband-tel a:not(.btn):not(.card):not(.cat-doc):not(.fp-doc){
  background:#F6EFE6;
  color:#8E2A18;
}
:root[data-theme] .ringband-tel a:hover,
:root[data-theme] .warmband .btn:hover,
:root[data-theme] .warmband .cat-order-main a.cat-phone:hover{
  background:#FFFFFF;
  color:#8E2A18;
}

/* The catering phone's own rule carries four :not(.class) tests, which puts it
   at (0,8,1). The rule above is (0,5,1) and lost. Same chain, plus [data-theme]. */
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc):hover{
  background:#F6EFE6;
  color:#8E2A18;
}

/* ── A wave that lands on the footer ───────────────────────────────────────
   The last wave on delivery leaves the red band, so it fills red ABOVE its
   curve and is transparent below. What showed through there was the page
   ground, #F3ECE2, and the footer beneath it is #E7DCCC. Four points apart,
   which reads as a hard straight line right where the curve was supposed to
   dissolve into the footer.

   The wave's own box takes the footer's colour instead, so below the curve it
   IS the footer and the two meet with no edge. --ink-2 is the footer's token
   and it flips with the theme, so this is correct in both. */
:root[data-theme] main > svg.wave:last-child{
  background-color:var(--ink-2);
  margin-bottom:0;
}
/* The footer then has to start flush against it. */
:root[data-theme] main > svg.wave:last-child + .foot,
:root[data-theme] main + .foot{margin-top:0;}

/* ── The menu block, centred ───────────────────────────────────────────────
   I pulled .menusheet onto the left lane earlier because the heading sat at
   x=71 whilst the image was centred, and the two axes disagreed. Centring all
   three is the better answer: the heading, the page image and the download
   button now share one centre line rather than one left edge. */
:root[data-theme] .menusheet{
  max-width:min(var(--maxw),860px);
  margin-inline:auto;
  text-align:center;
}
:root[data-theme] .menusheet h2,
:root[data-theme] .menusheet > p{text-align:center;}
:root[data-theme] .menusheet figure{margin:0;}
:root[data-theme] .menusheet img{margin-inline:auto;display:block;}
:root[data-theme] .menusheet figcaption{text-align:center;}
:root[data-theme] .menusheet .btn{margin-inline:auto;}

/* ── Two menus on one page sit side by side ────────────────────────────────
   Sandwiches, coffee and drinks carries two sheets, the 24/7 breakfast menu
   and the cold drinks menu, and they were stacking one above the other. That
   is a lot of page for two downloads, and it reads as two separate sections
   rather than one menu block with two parts.

   The block becomes a two-column grid when, and only when, it holds more than
   one sheet, so the single-menu pages are untouched. :has() is already used
   elsewhere in this build. */
:root[data-theme] .menusheet:has(.sheet + .sheet){
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:clamp(20px,2.6vw,40px);
  align-items:start;
  max-width:min(var(--maxw),980px);
}
:root[data-theme] .menusheet:has(.sheet + .sheet) > h2,
:root[data-theme] .menusheet:has(.sheet + .sheet) > p{
  grid-column:1 / -1;
}
/* Each sheet keeps its own column centred on itself rather than on the page. */
:root[data-theme] .menusheet:has(.sheet + .sheet) .sheet{
  display:flex;flex-direction:column;align-items:center;gap:14px;
}
/* The two scans are different orientations: the breakfast menu is landscape,
   the cold drinks menu portrait. Left at natural proportions the right column
   ran 755px against the left's 423 and the two download buttons sat 330px
   apart. Both are capped to one height and contained rather than cropped, so
   the whole page of each stays readable and the pair balances. */
:root[data-theme] .menusheet:has(.sheet + .sheet) .sheet img{
  width:auto;max-width:100%;
  height:clamp(260px,30vw,420px);
  object-fit:contain;
}
/* The two buttons carry different labels and so different widths. Pinning them
   to the bottom keeps the pair on one line rather than stepped. */
:root[data-theme] .menusheet:has(.sheet + .sheet) .sheet figcaption{margin-top:auto;}

@media (max-width:700px){
  :root[data-theme] .menusheet:has(.sheet + .sheet){grid-template-columns:1fr;}
}

/* ── Photographs among the item groups ────────────────────────────────────
   The four photos used to sit in one strip above the lists, where they were
   decoration: nothing tied a picture to the group it showed. Their own product
   pages pair a photograph with each block of items, and that is the better
   pattern, because the picture is what you scan for before you read a name.

   We have fewer photos than groups on most pages, so they are spaced through
   the grid rather than one per group. A photo takes a grid cell the same width
   as a group and is capped in height so a tall portrait shot cannot stretch its
   row. */
:root[data-theme] .range .rphoto{
  margin:0;align-self:start;border-radius:10px;overflow:hidden;
  background:var(--ink-2);
}
:root[data-theme] .range .rphoto img{
  display:block;width:100%;height:clamp(180px,17vw,260px);
  object-fit:cover;border-radius:10px;
}
/* On a phone the grid is one column, so a full-width photo between two short
   lists reads as a break rather than an illustration. Keep it shorter. */
@media (max-width:700px){
  :root[data-theme] .range .rphoto img{height:clamp(140px,38vw,190px);}
}

/* ── The catering range, folded under the menu ────────────────────────────
   Those nine groups are a transcription of the same two menu pages now shown
   above them. The text earns its place because a photograph of a menu is
   invisible to Google and to an AI asked "how much is a platter", and it is
   the only reason any price here is machine readable. But 2,211px of dense
   list is not what somebody opening a catering page wants to meet, so the
   menu leads and this folds away. <details> keeps it in the DOM and indexed. */
:root[data-theme] .cat-range-details{
  max-width:var(--maxw);margin-inline:auto;
  border-top:1px solid var(--rule);padding-top:clamp(18px,2vw,28px);
}
:root[data-theme] .cat-range-details > summary{
  cursor:pointer;list-style:none;display:flex;align-items:baseline;
  gap:14px;flex-wrap:wrap;padding:6px 0;min-height:44px;
}
:root[data-theme] .cat-range-details > summary::-webkit-details-marker{display:none;}
:root[data-theme] .cat-range-details > summary h2{margin:0;}
:root[data-theme] .cat-range-hint{
  font-family:'Archivo',system-ui,sans-serif;font-size:14px;letter-spacing:.08em;
  text-transform:uppercase;opacity:.72;
}
/* The disclosure triangle, drawn rather than relying on the default marker,
   which is inconsistent across browsers and cannot be coloured. */
:root[data-theme] .cat-range-details > summary::after{
  content:'';width:10px;height:10px;margin-left:auto;align-self:center;
  border-right:2px solid currentColor;border-bottom:2px solid currentColor;
  transform:rotate(45deg);transition:transform .18s ease;
}
:root[data-theme] .cat-range-details[open] > summary::after{transform:rotate(-135deg);}
:root[data-theme] .cat-range-details .range{margin-top:clamp(18px,2.4vw,32px);}
/* Two catering menu pages, side by side on a wide screen like the two-menu
   product pages already do. */
:root[data-theme] .menusheet:has(.sheet + .sheet) .cat-menu-cta{grid-column:1 / -1;}

/* ── "The other cabinets" was 213px of box for 33px of links ──────────────
   A one-line row of five links was taking a full section's padding top and
   bottom. Halved, and the rule above it does the separating instead. */
:root[data-theme] .morelinks{
  padding-top:clamp(14px,1.6vw,22px);padding-bottom:clamp(14px,1.6vw,22px);
}
:root[data-theme] .morelinks-in{padding-top:clamp(14px,1.6vw,20px);}
:root[data-theme] .morelinks h2{margin-bottom:8px;}
:root[data-theme] .morelinks ul{margin-bottom:0;}
/* "All products" is a real <li> at the end of the list now, so the two rules
   that used to drag the old <p> up onto the row have gone with it. */


/* ── The catering menu pages, big enough to read ──────────────────────────
   The two-menu rule caps sheet height at 420px, which is right for the cold
   drinks and breakfast menus but rendered these two A4 catering pages at 298px
   wide, where the prices are illegible. A menu you cannot read is worse than
   no menu. Here they take the full column width instead, and each one opens
   the PDF so it can be read at any size. */
:root[data-theme] .cat-menusheet .sheet img{
  width:100%;max-width:100%;height:auto;object-fit:contain;
  border-radius:8px;
}
:root[data-theme] .cat-menusheet .sheet a{display:block;border-radius:8px;}
:root[data-theme] .cat-menusheet .sheet a:focus-visible{
  outline:3px solid var(--link);outline-offset:3px;
}

/* ── The catering menu pages were still 298px wide ────────────────────────
   The earlier sizing rule did nothing, because the generic two-menu rule
   ':root[data-theme] .menusheet:has(.sheet + .sheet) .sheet img' weighs (0,6,1)
   — :has() contributes its argument's specificity — against (0,4,1) here. It
   kept height-capping these at 420px, which on an A4 page is 298px wide, and
   the leftover space inside each 471px column is what read as a big gap
   between the two menus. Naming both classes takes this to (0,7,1). */
:root[data-theme] .menusheet.cat-menusheet:has(.sheet + .sheet) .sheet img{
  width:100%;max-width:100%;height:auto;object-fit:contain;border-radius:8px;
}
/* The lede and the download button are text-align:center, but they were capped
   at 698px inside a 980px sheet with no auto margin, so they were centred
   inside a box that itself sat hard left. */
:root[data-theme] .cat-menusheet > p{margin-inline:auto;}

/* ── A straight line above "The catering menu" ────────────────────────────
   No border involved. The wave above it leaves the red band and is transparent
   below its curve, so that strip shows the page ground rgb(243,236,226), and
   the panel underneath is --warm rgb(235,225,211). Eight points apart, which
   reads as a hard rule exactly where the curve should dissolve into the panel.
   Same fix the pie-into-catering wave already carries: the wave's own box takes
   the colour of what it flows into. */
:root[data-theme] section.warmpanel{position:relative;}
:root[data-theme] svg.wave + section.warmpanel,
:root[data-theme] main > svg.wave:has(+ section.warmpanel){background-color:var(--warm);}
/* And the mirror. On the cafe page the menu panel is followed by a wave, so the
   strip above that wave's curve showed the page ground against the panel's
   --warm and read as a hard rule. A wave takes the colour of whatever it flows
   out of just as it takes the colour of what it flows into. */
:root[data-theme] section.warmpanel + svg.wave{background-color:var(--warm);}

/* ══ Product pages: showcase first, reference second ═══════════════════════
   "It looks like a blog. So much text. I don't know where to look. Photos are
   randomly placed." All three come from the same shape: 702 characters of lede
   before the first product, groups that were a bare <h3> plus <ul> with no
   container so they read as continuous prose, and photographs interleaved at a
   computed step, which is arbitrary by construction.

   The page now reads: title, one line, PHOTOGRAPHS, then the range as CARDS,
   then the ordering notes. The eye lands on the photographs, and the cards give
   it somewhere to land after that. */

/* 1. The showcase. One row, full width of the measure, large enough to be the
      first thing seen rather than decoration. */
:root[data-theme] .shotrow{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));
  gap:clamp(10px,1.2vw,18px);
  max-width:var(--maxw);margin:clamp(22px,3vw,40px) auto clamp(30px,4vw,52px);
}
:root[data-theme] .shotrow .shot{margin:0;border-radius:10px;overflow:hidden;}
:root[data-theme] .shotrow .shot img{
  display:block;width:100%;height:clamp(200px,20vw,290px);object-fit:cover;
}

/* 2. The range as cards. A surface is what stops a list of names reading as an
      essay: you see five blocks, not one column of text. */
:root[data-theme] .range{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,290px),1fr));
  gap:clamp(14px,1.6vw,22px);align-items:start;
}
:root[data-theme] .range .rgroup{
  background:color-mix(in srgb, var(--cream) 5%, transparent);
  border:1px solid color-mix(in srgb, var(--cream) 12%, transparent);
  border-radius:12px;
  padding:clamp(18px,1.8vw,26px) clamp(16px,1.6vw,24px);
  margin:0;
}
:root[data-theme] .range .rgroup h3{
  margin:0 0 .55em;padding-bottom:.5em;
  border-bottom:1px solid color-mix(in srgb, var(--cream) 14%, transparent);
}
:root[data-theme] .range .rgroup ul{margin:0;padding:0;list-style:none;}
:root[data-theme] .range .rgroup li{padding:5px 0;}
:root[data-theme] .range .rgroup li b{display:block;}
:root[data-theme] .range .rgroup li i{
  display:block;font-style:normal;font-size:.9em;opacity:.72;margin-top:1px;
}

/* 3. Notes, demoted. These are ordering conditions, not an introduction, so
      they sit under the range where somebody who has decided what they want
      goes looking for how to get it. */
:root[data-theme] .rnotes{
  max-width:var(--maxw);margin:clamp(26px,3.4vw,44px) auto 0;
  padding-top:clamp(18px,2vw,26px);
  border-top:1px solid color-mix(in srgb, var(--cream) 14%, transparent);
}
:root[data-theme] .rnotes p{
  max-width:68ch;margin:0 0 .9em;font-size:.95em;opacity:.8;
}
:root[data-theme] .rnotes p:last-child{margin-bottom:0;}

/* Three columns rather than auto-fit. auto-fit gave four at 1440, so a page
   with five groups left one card alone on a second row beside a large empty
   area. Three columns divide 5, 6 and 7 groups far more evenly. */
@media (min-width:861px){
  :root[data-theme] .range{grid-template-columns:repeat(3,minmax(0,1fr));}
}
@media (min-width:601px) and (max-width:860px){
  :root[data-theme] .range{grid-template-columns:repeat(2,minmax(0,1fr));}
}

/* ── Cards pack, rather than line up in ragged rows ───────────────────────
   Grid aligns cards into rows, so every row is as tall as its tallest card and
   the short ones leave a hole beneath them. On pies, row two ran Lamb at 186px
   beside Other at 443px, a 257px hole, and row three held one card alone with
   two empty columns beside it.

   Multi-column flows the cards instead: each column fills to roughly equal
   height and a short card is followed immediately by the next one. Reading
   order becomes top-to-bottom per column rather than left-to-right, which for
   a set of independent product groups is fine and is what a menu does anyway. */
:root[data-theme] .range{
  display:block;
  columns:3;
  column-gap:clamp(14px,1.6vw,22px);
}
:root[data-theme] .range .rgroup{
  break-inside:avoid;
  -webkit-column-break-inside:avoid;
  margin:0 0 clamp(14px,1.6vw,22px);
  display:inline-block;width:100%;   /* Safari needs this to honour the break */
}
@media (max-width:980px){ :root[data-theme] .range{columns:2;} }
@media (max-width:640px){ :root[data-theme] .range{columns:1;} }

/* One radius for every photograph on the site, so breakfast's squares and the
   rounded corners elsewhere stop disagreeing. */
:root[data-theme] .shotrow .shot,
:root[data-theme] .shotrow .shot img{border-radius:10px;}
:root[data-theme] .shotrow .shot img{
  display:block;width:100%;height:clamp(200px,20vw,290px);object-fit:cover;
  aspect-ratio:auto;
}

/* Photographs the same size on every page. auto-fit divided the row by however
   many photos a page had, so two on pies rendered 633px wide against 308px on
   cakes and 243px on cafe — the same component at three sizes. A fixed track
   range with the row centred keeps every photograph inside one band whatever
   the count, and a page with two simply shows two. */
:root[data-theme] .shotrow{
  grid-template-columns:repeat(auto-fit,minmax(230px,308px));
  justify-content:center;
}

/* The breadcrumb chip was a box with no padding ─────────────────────────────
   styles.css gives .banner .crumb a a 1px border and inline-block, which was
   meant to read as a chip, but padding is 0, so the rule draws a hairline box
   tight against the word and reads as a stray outline instead. It is on every
   page, not only breakfast. A breadcrumb does not need a chip; the tracked caps
   already mark it as navigation. */
/* `padding:0` here also wiped the 13px top and bottom that hero-2026-09.css
   :828 adds under 900px to hold the breadcrumb at the 44px tap floor. Same
   selector, same specificity, no media query, so it won at every width and
   the link measured 23.1px on a phone. Only the border and the sides are
   reset now; the vertical padding is left to whoever set it. */
:root[data-theme] .banner .crumb a{border:0;padding-left:0;padding-right:0;}
:root[data-theme] .banner .crumb a:hover,
:root[data-theme] .banner .crumb a:focus-visible{text-decoration:underline;text-underline-offset:3px;}

/* Four photographs across, not three and an orphan ──────────────────────────
   The lane is 1283px and the gap 17.3px, so four 308px tracks need 1286px and
   the fourth wrapped to a row of its own. 300px fits: 4x300 + 3x17.3 = 1252. */
:root[data-theme] .shotrow{
  grid-template-columns:repeat(auto-fit,minmax(224px,300px));
}

/* The red rule under a group note ──────────────────────────────────────────
   hero-2026-09.css sets border-bottom:1px solid var(--red) on .rgroup .rnote.
   That dated from before the groups were cards, when the note needed its own
   separator. The card now rules under its h3, so this drew a SECOND line a few
   millimetres below the first, in red. */
:root[data-theme] .rgroup .rnote{border-bottom:0;padding-bottom:0;margin-bottom:10px;}

/* Two photographs should be two halves, not two of four ─────────────────────
   A fixed 300px track is right for four, but a page with two showed them at
   300px each, centred in a 1283px lane, which reads as leftovers rather than a
   decision. Sized by count instead: two fill the lane as halves, three as
   thirds, four as quarters. */
:root[data-theme] .shotrow:has(.shot:nth-child(2):last-child){
  grid-template-columns:repeat(2,minmax(0,1fr));
}
:root[data-theme] .shotrow:has(.shot:nth-child(3):last-child){
  grid-template-columns:repeat(3,minmax(0,1fr));
}
:root[data-theme] .shotrow:has(.shot:nth-child(2):last-child) .shot img,
:root[data-theme] .shotrow:has(.shot:nth-child(3):last-child) .shot img{
  height:clamp(220px,24vw,340px);
}

/* ── Warmer, softer, less of a spreadsheet ────────────────────────────────
   "Doesn't feel on theme, want it to feel kind of homely." The cards were a 5%
   tint with a 12% hairline border: correct, systematic, and cold. A bakery
   should read warm. The fill now carries real warmth off --warm, the hairline
   goes entirely, and the corners soften. Nothing about contrast changes,
   because the text colour and the fill's luminance are both unmoved. */
:root[data-theme] .range .rgroup{
  background:color-mix(in srgb, var(--warm) 62%, var(--ink) 38%);
  border:0;
  border-radius:18px;
  box-shadow:0 1px 2px rgba(0,0,0,.04);
}
:root[data-theme] .range .rgroup h3{
  border-bottom-color:color-mix(in srgb, var(--cream) 18%, transparent);
}
:root[data-theme] .shotrow .shot,
:root[data-theme] .shotrow .shot img{border-radius:16px;}

/* ══ Counter rows ══════════════════════════════════════════════════════════
   GPT-5.6 Sol's proposal, applied to the real markup. Its reading of why the
   product pages felt wrong was sharper than mine: the photographs were
   "collected by quantity rather than meaning", a gallery that ends before the
   first product begins, so a custard-tart photograph is not visibly attached to
   "Tarts, buns and pastries". And every group got the same box, so the page
   offers no clue which cabinet should lead.

   So: a photographed group becomes a broad split, photo one side and the list
   the other, alternating left and right the way the home page's .split and
   .split-flip already do. A group with no photograph becomes an open list with
   a red rule and an uneven column span. The composition varies down the page
   instead of repeating, which is what the home page does and what the card grid
   did not. */
:root[data-theme] .detailpage .counter-range{
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  columns:auto;
  gap:clamp(26px,3vw,44px) clamp(18px,2.4vw,34px);
  max-width:var(--maxw);margin-inline:auto;
}
/* undo the card treatment from the previous pass */
:root[data-theme] .detailpage .counter-range .counter-group{
  box-sizing:border-box;break-inside:auto;display:block;width:auto;
  margin:0;padding:0;background:transparent;border:0;border-radius:0;box-shadow:none;
}
:root[data-theme] .detailpage .counter-range .counter-feature{
  grid-column:1 / -1;
  display:grid;grid-template-columns:minmax(260px,.82fr) minmax(0,1.18fr);
  align-items:stretch;overflow:hidden;
  background:var(--warm);border-radius:clamp(18px,2.2vw,30px);
}
:root[data-theme] .detailpage .counter-range .counter-feature-photo-right{
  grid-template-columns:minmax(0,1.18fr) minmax(260px,.82fr);
}
:root[data-theme] .detailpage .counter-feature-photo-right .counter-photo{order:2;}
:root[data-theme] .detailpage .counter-feature-photo-right .counter-copy{order:1;}
:root[data-theme] .detailpage .counter-photo{
  min-width:0;margin:0;overflow:hidden;background:var(--ink-2);
}
:root[data-theme] .detailpage .counter-photo img{
  display:block;width:100%;height:100%;
  min-height:clamp(270px,27vw,390px);object-fit:cover;border-radius:0;
}
:root[data-theme] .detailpage .counter-copy{
  display:flex;flex-direction:column;justify-content:center;min-width:0;
  padding:clamp(24px,3.5vw,52px);
}
:root[data-theme] .detailpage .counter-range .counter-group h3{
  margin:0 0 .7em;padding:0 0 .55em;border:0;border-bottom:3px solid var(--band);
  font-family:'Archivo',system-ui,sans-serif;
  font-size:clamp(20px,2vw,28px);font-weight:600;line-height:1.15;
  letter-spacing:-.02em;
}
:root[data-theme] .detailpage .counter-range .counter-group ul{
  margin:0;padding:0;list-style:none;
}
:root[data-theme] .detailpage .counter-feature ul{
  columns:2 190px;column-gap:clamp(24px,3vw,46px);
}
:root[data-theme] .detailpage .counter-range .counter-group li{
  break-inside:avoid;margin:0;padding:7px 0;
}
:root[data-theme] .detailpage .counter-range .counter-group li b{
  display:block;font-family:'Work Sans',system-ui,sans-serif;
  font-size:16px;font-weight:500;line-height:1.38;
}
:root[data-theme] .detailpage .counter-range .counter-group li i{
  display:block;margin-top:2px;font-family:'Work Sans',system-ui,sans-serif;
  font-size:14.5px;font-style:normal;line-height:1.45;opacity:.72;
}
/* A group with no photograph is not a lesser group. Whilst these carried only a
   top rule on flat ground, they read as the leftovers under the photographed
   rows rather than as part of the same set. Same warm ground, same radius, same
   padding as .counter-feature, just no photo column, so the page shows one
   component at two widths instead of two different things. */
:root[data-theme] .detailpage .counter-range .counter-plain{
  align-self:start;
  background:var(--warm);
  border-radius:clamp(18px,2.2vw,30px);
  border-top:0;
  padding:clamp(24px,3.5vw,44px) clamp(22px,3vw,40px);
}
:root[data-theme] .detailpage .counter-range .counter-plain-wide{grid-column:span 7;}
:root[data-theme] .detailpage .counter-range .counter-plain-narrow{grid-column:span 5;}
:root[data-theme] .detailpage .counter-range .counter-plain h3{
  border-bottom:0;padding-bottom:0;margin-bottom:.65em;
}
@media (max-width:760px){
  :root[data-theme] .detailpage .counter-range{grid-template-columns:minmax(0,1fr);gap:30px;}
  :root[data-theme] .detailpage .counter-range .counter-feature,
  :root[data-theme] .detailpage .counter-range .counter-feature-photo-right{
    grid-column:1;grid-template-columns:minmax(0,1fr);
  }
  :root[data-theme] .detailpage .counter-feature-photo-right .counter-photo,
  :root[data-theme] .detailpage .counter-feature-photo-right .counter-copy{order:initial;}
  :root[data-theme] .detailpage .counter-photo img{min-height:0;height:clamp(210px,62vw,300px);}
  :root[data-theme] .detailpage .counter-copy{padding:24px 20px 28px;}
  :root[data-theme] .detailpage .counter-feature ul{columns:1;}
  :root[data-theme] .detailpage .counter-range .counter-plain-wide,
  :root[data-theme] .detailpage .counter-range .counter-plain-narrow{grid-column:1;margin-top:0;}
}


/* ══ Cafe: copy on the left, three tall photographs on the right ═══════════
   Built on the home page's own .split / .split-txt / .split-shots so it reads
   as the same site. .split-shots already sets aspect-ratio:3/4 on its images;
   the only change here is three columns instead of two, and letting the photo
   half take slightly more width because three portraits need it. */
:root[data-theme] .detailpage .cafe-split{
  align-items:center;
  gap:clamp(26px,3.4vw,52px);
  grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
}
:root[data-theme] .detailpage .cafe-split .split-txt p{max-width:44ch;}
:root[data-theme] .detailpage .cafe-shots{
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(8px,1vw,14px);
}
:root[data-theme] .detailpage .cafe-shots .shot{margin:0;border-radius:10px;overflow:hidden;}
:root[data-theme] .detailpage .cafe-shots .shot img{
  display:block;width:100%;height:auto;aspect-ratio:3/4;object-fit:cover;border-radius:10px;
}
/* The cross-reference sits under the copy, not floating in the photo column. */
:root[data-theme] .detailpage .cafe-split .cat-what-lede{margin:1.1em 0 0;}

@media (max-width:860px){
  :root[data-theme] .detailpage .cafe-split{grid-template-columns:minmax(0,1fr);gap:26px;}
}


/* ══ All products: cards that match the product pages ══════════════════════
   Josh: "looks so condensed and weird." Three 403px cards of bare photo and
   text on flat cream read as thumbnails next to the big warm rows every
   product page now uses. Same component instead: warm ground, same radius,
   photo flush to the edge, copy padded. Two across rather than three, because
   six of them at 403px was the condensed part.
   Scoped to .cards-lg, which only products.html carries, so the home page's
   own .cards grid is untouched. */
:root[data-theme] .sec .cards.cards-lg{
  max-width:var(--maxw);
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(20px,2.4vw,34px);
}
:root[data-theme] .cards-lg .card{
  background:var(--warm);
  border-radius:clamp(18px,2.2vw,30px);
  overflow:hidden;
  gap:0;
}
:root[data-theme] .cards-lg .card .card-shot{
  aspect-ratio:16/10;
  border-radius:0;
}
/* the copy sits inside the panel, so it needs the padding the photo does not */
:root[data-theme] .cards-lg .card h3{
  margin:clamp(20px,2.2vw,28px) clamp(20px,2.2vw,30px) .3em;
  font-size:clamp(23px,2.1vw,30px);
  line-height:1.1;
}
:root[data-theme] .cards-lg .card p{
  margin:0 clamp(20px,2.2vw,30px);
  max-width:46ch;
  font-size:16.5px;
  line-height:1.55;
}
:root[data-theme] .cards-lg .card .card-more{
  margin:.9em clamp(20px,2.2vw,30px) clamp(20px,2.2vw,28px);
}
/* 29-09-2026, Josh: the cards were too big on a laptop. Two across made each
   one 624px wide and the six ran 1,825px, two screens of scrolling. Three
   across on wide screens puts all six in two rows (909px). The warm panels
   above stay, since they, not the column count, fixed "condensed". Tablets and
   phones keep two across, which Josh said already looks right. */
@media (min-width:941px){
  :root[data-theme] .sec .cards.cards-lg{grid-template-columns:repeat(3,minmax(0,1fr));}
  :root[data-theme] .cards-lg .card h3{font-size:clamp(20px,1.7vw,25px);}
  :root[data-theme] .cards-lg .card p{font-size:15.5px;}
}

/* Worth knowing was widened to --maxw and left aligned, which left the whole
   right half of the section empty under a 46ch paragraph. The call to action
   moves into that space instead of sitting under the text. */
@media (min-width:861px){
  :root[data-theme] .sec .fp-know{
    display:grid;
    grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
    column-gap:clamp(30px,4vw,64px);
    align-items:end;
  }
  :root[data-theme] .sec .fp-know h2{grid-column:1;}
  :root[data-theme] .sec .fp-know p:not(.fp-cta){grid-column:1;margin-bottom:0;}
  :root[data-theme] .sec .fp-know .fp-cta{
    grid-column:2;grid-row:2;margin:0;justify-content:flex-start;
  }
}

@media (max-width:940px){
  :root[data-theme] .sec .cards.cards-lg{grid-template-columns:minmax(0,1fr);}
}
/* 29-09-2026, Josh: one card per row was too large on a tablet, 720px wide and
   about 600px tall at 800. Two across between phone and laptop widths. Phones
   (560px and below, and the largest phone is about 430) keep one per row,
   which Josh said looks right. */
@media (min-width:561px) and (max-width:940px){
  :root[data-theme] .sec .cards.cards-lg{grid-template-columns:repeat(2,minmax(0,1fr));}
}


/* Photoless pages: close the holes the stagger opened ─────────────────────
   Vegan is five open panels with no photograph to break them up. The narrow
   column carried a top margin to look deliberately uneven, but with panels of
   different heights that read as four random voids rather than a composition,
   and the fifth panel sat alone against an empty half. Rows line up now, and an
   odd last panel takes the full width instead of leaving a gap beside it. */
:root[data-theme] .detailpage .counter-range .counter-plain:last-child:nth-child(odd){
  grid-column:1 / -1;
}


/* ══ A wave under the banner ═══════════════════════════════════════════════
   The banner is --warm and the page under it is --ink, so there was already a
   ground change at the top of every inner page, drawn as a hard horizontal
   edge. The wave's own box carries the colour ABOVE the curve and the path
   carries the colour below, the same way the pie-into-catering wave works.

   Token trap, for anyone reading this later: --ink is the GROUND and --cream is
   the TEXT. The path is filled with the ground, not the text.

   hero-2026-09.css sets `:root svg.wave:not(.wave-marq) path{fill:var(--band)}`
   at (0,3,2), which would paint this one red. :not() contributes its argument's
   specificity, so the selector below is (0,4,2) and wins outright rather than
   relying on which sheet loads last. */
/* The wave-warm block that lived here moved to hero-2026-09.css on
   17-09-2026, because find-us, care and 404 never load this sheet and their
   banners had no curve. Leaving a copy here meant this one won on those
   pages that DO load it and kept filling the wave with the old --warm cream
   against an orange banner. One source of truth, in the sheet all 13 load. */


/* ══ Colour back in the product rows ══════════════════════════════════════
   Every row was the same --warm panel, so a page read as one tone repeated five
   times whilst the home page moves through cream, brown, dark and red. Alternate
   rows now take --strip, which is #4A3527, the exact brown the home page's photo
   marquee runs on, with --on-brown for the text on it.

   Nothing new is invented: both tokens already ship and both already appear on
   the home page. Red is deliberately NOT used here. On this site red is reserved
   for calls and bands, and spreading it onto every second product group is what
   would actually make these pages look cheap. */
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even){
  background:var(--strip);
}
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even) h3,
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even) li b{
  color:var(--on-brown);
}
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even) li i,
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even) p{
  color:var(--on-brown-mute);      /* 5.6:1 on --brown, per styles.css */
}
/* The heading rule is --band red on cream. On the brown it has to lift, so it
   takes the cream at low alpha rather than a second red that would vibrate. */
:root[data-theme] .detailpage .counter-range .counter-group:nth-of-type(even) h3{
  border-bottom-color:color-mix(in srgb, var(--on-brown) 38%, transparent);
}

/* ══ Vegan: even rows ══════════════════════════════════════════════════════
   The panels were align-self:start, so two panels in a row ended at different
   heights and the page read as ragged. Stretching them to the row height is what
   makes a two column list look deliberate. */
:root[data-theme] .detailpage .counter-range .counter-plain{align-self:stretch;}

/* [J16b] The catering phone is the number again, set as type rather than a slab,
   with "Please order here" carrying the button job in its own column. Written
   here rather than in hero-2026-09.css because inner-2026-09.css loads after it
   on every inner page, so a hero rule of the same weight loses. The section also
   ran ~140px past its content, because the left column is short now. */
/* the existing rules carry four chained :not() selectors, which makes them
   (0,9,1), so matching that weight is the only way to beat them */
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc),
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc):hover{
  background:none;
  color:#F6EFE6;
  padding:0;
  margin:4px 0 12px;
  font-family:'Aleo',Georgia,serif;
  font-size:clamp(26px,2.6vw,34px);
  line-height:1.15;
  display:inline-block;
}
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc):hover,
:root[data-theme] .warmband .cat-order-main a.cat-phone:not(.btn):not(.card):not(.cat-doc):not(.fp-doc):focus-visible{
  color:#FFFFFF;text-decoration:underline;text-underline-offset:5px;
}
:root[data-theme] .cat-order.warmband{
  padding-bottom:clamp(40px,4.4vw,58px);
}


/* ── Delivery: the terms run under both columns (29-09-2026) ───────────────
   Josh: the ordering section "just doesn't look right". The photo sat at the
   top of its column with about 110px of empty cream beneath it, and the terms
   panel belonged to the left column only, so the section read lopsided. The
   terms block now follows the photo in the markup and spans the full lane, the
   photo crops to the height of the copy beside it, and the four facts sit in
   one row, label above value. Phones keep text, terms, photo. */
@media (min-width:861px){
  :root[data-theme] body[data-page="delivery"] .cat-order-in{align-items:stretch;}
  :root[data-theme] body[data-page="delivery"] .del-shot{position:relative;min-height:260px;}
  :root[data-theme] body[data-page="delivery"] .del-shot img{position:absolute;inset:0;height:100%;object-fit:cover;}
  :root[data-theme] body[data-page="delivery"] .del-terms{grid-column:1 / -1;margin-top:clamp(8px,1vw,14px);}
  :root[data-theme] body[data-page="delivery"] .del-dl{
    max-width:none;
    grid-template-columns:repeat(4,minmax(0,1fr));grid-template-rows:auto auto;grid-auto-flow:column;
    gap:0 28px;
  }
  :root[data-theme] body[data-page="delivery"] .del-dl dt{padding:0 0 4px;font-size:13px;letter-spacing:.08em;text-transform:uppercase;}
  :root[data-theme] body[data-page="delivery"] .del-dl dd:not(.del-full){text-align:left;padding:0;font-size:17px;color:#3A2E25;}
  :root[data-theme] body[data-page="delivery"] .del-dl dd.del-full{grid-row:3;grid-column:1 / -1;margin-top:18px;text-align:center;}
}
@media (max-width:860px){
  :root[data-theme] body[data-page="delivery"] .del-terms{order:1;}
  :root[data-theme] body[data-page="delivery"] .del-shot{order:2;}
}


/* ── Product rows: one height, lists that read like a menu (29-09-2026) ─────
   Josh: the spacing looked weird and the rows were too big. Each row took its
   height from the photograph, so a group of two prices sat in a 400px panel of
   mostly empty cream, and the two-column list pushed the second price to the
   far edge. Now the photo crops to the row instead of setting it, every row is
   one height (fit to the fullest, Pies "Other", about 348px at 1440) so the
   page is uniform, and a group of three items or fewer is a single column.
   Tablets let the fullest rows run taller rather than making every row empty;
   phones are untouched. */
@media (min-width:761px){
  :root[data-theme] .detailpage .counter-photo{position:relative;min-height:clamp(220px,18vw,270px);}
  :root[data-theme] .detailpage .counter-photo img{position:absolute;inset:0;height:100%;min-height:0;}
  :root[data-theme] .detailpage .counter-copy{padding:clamp(22px,2.8vw,40px) clamp(24px,3.2vw,48px);}
  :root[data-theme] .detailpage .counter-feature ul:not(:has(li:nth-child(4))){columns:1;}
}
@media (min-width:1025px){:root[data-theme] .detailpage .counter-range .counter-feature{min-height:360px;}}
@media (min-width:761px) and (max-width:1024px){:root[data-theme] .detailpage .counter-range .counter-feature{min-height:340px;}}
/* "Serve it with" was a list item, so it read as a product with a price. It is
   a note under the prices now, the label bold and the suggestion beside it. */
:root[data-theme] .detailpage .counter-copy .counter-note{
  margin:14px 0 0;padding-top:12px;border-top:1px solid rgba(33,26,21,.14);
  font-size:14.5px;line-height:1.5;
}
:root[data-theme] .detailpage .counter-copy .counter-note b{font-weight:600;}
:root[data-theme] .detailpage .counter-copy .counter-note i{font-style:normal;opacity:.78;}
