/* --------------------------------------------------------------------------
   Fonts, self-hosted in ./fonts. Nothing is fetched from a third party at
   runtime — the files sit next to this stylesheet.

   Playfair Display is HERS: her own 2023 site loaded it, so this is her
   existing type identity rather than something picked for her.
   Figtree carries everything functional. Two families, three files.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Playfair Display";
  src: url("fonts/PlayfairDisplay-400.woff2") format("woff2");
  font-weight: 400 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Playfair Display";
  src: url("fonts/PlayfairDisplay-400i.woff2") format("woff2");
  font-weight: 400 900; font-style: italic; font-display: swap;
}
@font-face {
  font-family: "Figtree";
  src: url("fonts/Figtree-400.woff2") format("woff2");
  font-weight: 300 900; font-style: normal; font-display: swap;
}

/* ==========================================================================
   Local Ice — built on HER mark.

   The palette is measured off her actual logo (brand/logo-instagram-100.jpg),
   pixel by pixel, not chosen: cream field, burnt-orange sunburst, sage arc,
   dark brown outline. Every text/background pair below carries its measured
   contrast ratio.

   The sunburst motif through the page is her logo's own device, not an
   ornament somebody invented.
   ========================================================================== */

:root {
  /* --- her colours, off the badge ---------------------------------------- */
  --cream:    #faf3e4;   /* the badge field — the page */
  --paper:    #fffaf0;   /* a lighter card surface */
  --cream-b:  #f4ebd8;   /* second light ground, so two cream sections in a
                            row are never identical */
  --orange:   #d2781e;   /* the sun. FILL ONLY — 2.95 as text on cream */
  --orange-d: #a85c12;   /* the sun, dark enough to be a letter — 4.52 */
  --sage:     #96beaa;   /* the lower arc. FILL ONLY — 1.86 as text */
  --sage-d:   #4a7a64;
  --sage-dk:  #2f5646;   /* deep band — cream on it is 7.48 */
  --brown:    #483018;   /* the outline and wordmark — 11.10 on cream */
  --ink:      #2a1c0d;   /* body — 14.96 on cream */
  --muted:    #6f5c45;   /* secondary — 5.77 on cream */
  --hair:     #e4d8be;   /* rules only, never text */
  --hair-2:   #d8c7a6;   /* section EDGE hairline — the plain --hair vanishes
                            at a band boundary */
  --tint:     #f6e3c4;   /* second warm surface, 1.14x off cream. Every
                            premium reference has two off-whites this close:
                            Jeni's 1.10, Bi-Rite 1.09, Van Leeuwen 1.06 */
  --strip:    #a8431a;   /* the ONE loud full-bleed strip. Deepened from her
                            own orange, not a new colour. cream on it = 5.46 */

  /*  ink   on cream  14.96      brown on cream  11.10
      muted on cream   5.77      ink   on orange  5.07
      brown on sage    5.98      cream on sage-dk 7.48
      orange-d on cream 4.52     cream on brown  11.10   */

  /* --- space ------------------------------------------------------------- */
  --s1:4px; --s2:8px; --s3:16px; --s4:24px;
  --s5:32px; --s6:48px; --s7:64px; --s8:96px; --s9:128px;

  /* --- type: system stacks only, nothing is loaded from anywhere ----------

     Display is the "Antique" stack — a Clarendon/Ionic slab. That is the
     actual vernacular of American market signage and soda-fountain lettering,
     and the Original Farmers Market opened in 1934. Period-correct, and it is
     nothing like a default serif.
       macOS/iOS -> Superclarendon      Windows -> Bookman Old Style
       Linux     -> URW Bookman         everywhere else -> Georgia

     Body is a Humanist stack, deliberately NOT the operating system's own UI
     font. -apple-system resolves to San Francisco and "Segoe UI" to Windows'
     interface font — the loudest "this is a template" signal available. */

  --display: "Playfair Display", "Iowan Old Style", "Sitka Text", Charter,
             "Bitstream Charter", Georgia, "Liberation Serif", serif;
  --sans: Figtree, Seravek, "Gill Sans Nova", Ubuntu, Calibri,
          "DejaVu Sans", sans-serif;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
          "Liberation Mono", "DejaVu Sans Mono", monospace;
  /* OS UI font, for interface chrome only — never for her voice */
  --ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;

  --measure: 33rem;
  --frame: 64rem;
}

* { box-sizing: border-box; }

/* No faked bold, italic or small caps — synthesised faces are the cheap look. */
:root { font-synthesis: none; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font: 500 1.0625rem/1.72 var(--sans);
  letter-spacing: .15px;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.frame  { max-width: var(--frame); margin-inline: auto; padding-inline: var(--s4); }
.measure{ max-width: var(--measure); }
.mx     { margin-inline: auto; }
.center { text-align: center; }

h1,h2,h3 {
  font-family: var(--display);
  text-wrap: balance;
  font-weight: 400;
  color: var(--brown);
  line-height: 1.08;
  margin: 0;
  letter-spacing: -0.015em;
}

/* Big scale contrast — the single biggest thing separating a designed page
   from a plain one. The display sizes are deliberately much larger than the
   body, rather than one notch up. */
h1 { font-size: clamp(2.9rem, 11vw, 5.5rem); letter-spacing: -.022em; line-height: 1.04; }
h2 { font-size: clamp(2.1rem, 6vw, 3.25rem); }
h3 { font: 600 clamp(1.25rem, 3vw, 1.5rem)/1.3 var(--sans); letter-spacing: 0;
     color: var(--ink); }

p { margin: 0 0 var(--s4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

.lede { font-size: clamp(1.125rem, 2.4vw, 1.375rem); line-height: 1.55; color: var(--ink); }

.label {
  font: 500 0.6875rem/1.4 var(--mono);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--orange-d);
  margin: 0 0 var(--s4);
}
.label--quiet { color: var(--muted); }

/* --- sections: three real surfaces, so the page has rhythm --------------- */

/* Was --s9 (128px) top and bottom. Across fourteen bands that alone was
   nearly 3,600px of empty page. --s8 still reads as generous air between
   sections and takes roughly a screen and a half off the scroll.
   Tom, 2026-08-06: less scrolling the better. */
section { padding: var(--s8) 0; position: relative; }
@media (max-width: 700px) { section { padding: var(--s7) 0; } }

.s-cream { background: var(--cream); }
.s-creamb{ background: var(--cream-b); }
.s-sage  { background: var(--sage); }
.s-deep  { background: var(--sage-dk); }
.s-brown { background: var(--brown); }

/* MEASURED 2026-08-04, and three of these were wrong before.
   The sage band was the one surface nobody had checked:
     #3f4f45 on sage  = 4.24  FAILED    -> brown  #483018 on sage = 5.98
     #2f5646 on sage  = 4.03  FAILED    -> brown  #483018 on sage = 5.98
     sage on deep sage = 4.03 FAILED    -> cream  #faf3e4 on deep = 7.48
   Body text needs 4.5. Nothing on this page sits below it now. */
.s-sage { color: var(--brown); }                       /* 5.98 */
.s-sage h2, .s-sage h3 { color: var(--brown); }
.s-sage .label { color: var(--brown); }                /* was 4.03 */
.s-sage .menu p, .s-sage .caption { color: var(--brown); }

.s-deep, .s-brown { color: #f0e6d2; }
.s-deep h2, .s-deep h3, .s-brown h2, .s-brown h3 { color: var(--cream); }
.s-deep .label, .s-brown .label { color: var(--cream); }   /* was sage, 4.03 */
.s-deep a, .s-brown a { color: var(--cream); }

/* --- the sunburst, taken from her badge ---------------------------------- */

/* Rays, the same device as the sun on her badge. Drawn in CSS so it costs
   nothing to load and scales to any screen. Masked to fade out before the
   edges so it reads as light, not as a pattern. */
.burst {
  position: absolute;
  top: 50%; left: 50%;
  translate: -50% -50%;
  width: min(170vw, 1180px);
  aspect-ratio: 1;
  pointer-events: none;
  z-index: 0;
  opacity: .17;
  background: repeating-conic-gradient(
    from 0deg,
    var(--orange) 0deg 3.2deg,
    transparent 3.2deg 11deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 8%, rgba(0,0,0,.55) 42%, transparent 72%);
          mask-image: radial-gradient(closest-side, #000 8%, rgba(0,0,0,.55) 42%, transparent 72%);
}

.burst--sage { background: repeating-conic-gradient(
    from 0deg, var(--sage) 0deg 3.2deg, transparent 3.2deg 11deg); opacity: .22; }

section > .frame { position: relative; z-index: 1; }
section { overflow: hidden; }

/* --- the mark ------------------------------------------------------------ */

.mark { display: block; width: 84px; height: 84px; border-radius: 50%; margin: 0 auto; }
.mark--sm { width: 56px; height: 56px; }

.site-head { padding: var(--s6) 0 0; text-align: center; position: relative; z-index: 2; }

/* --- rules --------------------------------------------------------------- */

.rule { border: 0; height: 1px; background: var(--hair); margin: var(--s6) 0; }
.rule--short { width: 64px; margin-inline: auto; background: var(--orange); opacity: .8; }
.s-deep .rule--short, .s-brown .rule--short { background: var(--sage); }
.s-sage .rule--short { background: var(--brown); opacity: .5; }

/* --- buttons ------------------------------------------------------------- */

.actions { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s6); }
.actions--center { justify-content: center; }

.btn {
  display: inline-block;
  padding: 17px 34px;
  border: 2px solid var(--brown);
  border-radius: 999px;
  background: transparent;
  color: var(--brown);
  font: 600 0.8125rem/1.2 var(--sans);
  letter-spacing: 0.13em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background-color .16s ease, color .16s ease, transform .16s ease;
}
.btn:hover { background: var(--brown); color: var(--cream); transform: translateY(-1px); }

.btn--primary {
  background: var(--orange);
  border-color: var(--orange);
  color: var(--ink);              /* 5.07 */
}
.btn--primary:hover { background: var(--brown); border-color: var(--brown); color: var(--cream); }

/* The little brown one. Solid, and smaller than the rest, so it never
   competes with the gold button beside it — that one is still the only
   gold thing on the page. MEASURED, not guessed: cream on this brown is
   11.10:1 in the light theme and 11.92:1 in the dark one, so it clears
   AAA in both without the text having to be large — and the pill's own
   edge against the cream ground is the same figure, so the shape is
   visible without relying on the border. */
.btn--brown {
  padding: 13px 24px;
  font-size: 0.75rem;
  background: var(--brown);
  border-color: var(--brown);
  color: var(--cream);
}
.btn--brown:hover {
  background: transparent;
  color: var(--brown);
}

.s-deep .btn, .s-brown .btn { border-color: var(--sage); color: var(--cream); }
.s-deep .btn:hover, .s-brown .btn:hover { background: var(--sage); color: var(--ink); }

.btn:focus-visible { outline: 3px solid var(--orange-d); outline-offset: 3px; }

/* --- editorial two-column, so it is not one centred column all the way --- */

.split { display: grid; gap: var(--s7); align-items: start; }
@media (min-width: 860px) {
  .split { grid-template-columns: 1fr 1.25fr; gap: var(--s8); }
  .split--even { grid-template-columns: 1fr 1fr; }
}

/* --- the menu list, with oversized numerals ------------------------------ */

.menu { list-style: none; margin: 0; padding: 0; counter-reset: m; }

.menu li {
  counter-increment: m;
  display: grid;
  grid-template-columns: 3.25rem 1fr;
  gap: var(--s4);
  padding: var(--s5) 0;
  border-top: 1px solid var(--hair);
  align-items: baseline;
}
.menu li:last-child { border-bottom: 1px solid var(--hair); }

.menu li::before {
  content: counter(m, decimal-leading-zero);
  font-family: var(--display);
  font-size: 1.5rem;
  color: var(--orange-d);
  line-height: 1;
}
.menu h3 { margin-bottom: var(--s2); }
.menu p  { margin: 0; color: var(--muted); }

.s-sage .menu li { border-color: rgba(72,48,24,.22); }
.s-sage .menu li::before { color: var(--brown); }
.s-sage .menu p { color: #3f4f45; }

/* --- fact rows: one column, two real edges ------------------------------- */

.rows { margin: 0; padding: 0; }
.rows > div {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s5); padding: var(--s3) 0; border-bottom: 1px solid var(--hair);
}
.rows > div:first-child { border-top: 1px solid var(--hair); }
.rows dt { font-size: .9375rem; color: var(--muted); flex: 0 0 auto; }
.rows dd { margin: 0; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums lining-nums; }
.rows a  { color: var(--ink); }

.s-deep .rows > div, .s-brown .rows > div { border-color: rgba(240,230,210,.22); }
.s-deep .rows dt, .s-brown .rows dt { color: var(--sage); }
.s-deep .rows dd, .s-brown .rows dd { color: var(--cream); }

/* --- a pull quote, in her own voice -------------------------------------- */

.pull {
  font-family: var(--display);
  font-size: clamp(1.6rem, 4.2vw, 2.4rem);
  line-height: 1.22;
  color: var(--brown);
  margin-block: 0;          /* NOT `margin: 0` — the shorthand would zero the
                               inline margins too and stop .mx centring it */
  text-wrap: balance;
}
.s-deep .pull, .s-brown .pull { color: var(--cream); }

/* --- drop cap, one place only -------------------------------------------- */

.dropcap::first-letter {
  font-family: var(--display);
  float: left;
  font-size: 3.6rem;
  line-height: .82;
  padding: .06em .12em 0 0;
  color: var(--orange-d);
}

/* ==========================================================================
   PHOTOGRAPHS
   All sixteen are HERS — pulled from the Business Profile she owns, out of
   the set Google labels "uploaded by your business". Customers' photos are
   the customers' and are not used. Every file has a row in
   ../photo-credits.md; a photo with no row does not go on the site.
   ========================================================================== */

figure { margin: 0; }

.shot img {
  display: block;
  width: 100%; height: auto;
  border-radius: 3px;
  background: var(--hair);      /* a warm placeholder, never a grey flash */
}
/* ⚠ NO CAPTIONS UNDER PHOTOGRAPHS. Tom's rule, 2026-08-06.
   A photograph does not need a line of text telling you what you are looking
   at. It reads as filler and it is the fastest way to make a page look
   written by a machine. The styles are kept only so that a stray <figcaption>
   is INVISIBLE rather than silently ugly if one ever gets added back.
   Alt text is different and still required: a screen reader has no picture. */
.shot figcaption, figcaption { display: none; }

.shot--wide { margin-top: var(--s6); }

/* --- the flavours ------------------------------------------------------
   One name per line, each on its own rule, so the column has two real edges
   and the eye can run down it. No prices and no photographs: a picture of a
   scoop cannot honestly be labelled "Mint Chip" unless somebody who works
   there says it is, and nobody has. */
.flavours {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: 1fr; gap: 0;
  border-bottom: 1px solid rgba(72,48,24,.18);
}
.flavours li {
  border-top: 1px solid rgba(72,48,24,.18);
  padding: var(--s4) 0;
  font-family: var(--display);
  font-size: clamp(1.25rem, 2.4vw, 1.75rem);
  line-height: 1.25;
  color: var(--brown);
}
@media (min-width: 620px) {
  .flavours { grid-template-columns: 1fr 1fr; column-gap: var(--s8); }
}
@media (min-width: 1000px) {
  .flavours { grid-template-columns: repeat(3, 1fr); }
}

/* A strip of her own scoops under the flavour names. Square crops so the row
   reads as one band rather than a ragged edge. No captions by design. */
/* ⚠ NOT `.strip`. The orange bar at the top of the page already owns that
   class, so naming this one `.strip` turned the bar into a three column grid
   and wrapped its identity line down four lines. If you add a component here,
   grep the stylesheet for the class name first. */
.scoops {
  margin-top: var(--s7);
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
}
@media (min-width: 700px) { .scoops { grid-template-columns: repeat(6, 1fr); } }
/* align-self AND height:auto on the image itself, not just align-items on the
   parent. This is the same fix as .thumbs further down and it is needed for the
   same reason: a grid item's default stretch beats aspect-ratio on the block
   axis. Third time on this page. */
.scoops img {
  width: 100%; height: auto; align-self: start;
  aspect-ratio: 1/1; object-fit: cover;
  display: block;
}

/* THE CASE. A lot of photographs at once, so they are small, square and even:
   the grid is the subject, no single tile is. object-fit crops rather than
   squashes, and align-items:start keeps a grid child's default stretch from
   quietly overriding aspect-ratio, which has bitten this page twice. */
.gallery {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(2, 1fr);
  align-items: start;
}
@media (min-width: 560px)  { .gallery { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 860px)  { .gallery { grid-template-columns: repeat(5, 1fr); gap: var(--s4); } }
@media (min-width: 1200px) { .gallery { grid-template-columns: repeat(7, 1fr); } }
.gallery img {
  width: 100%; height: auto; align-self: start;
  aspect-ratio: 1/1; object-fit: cover;
  display: block;
}

/* --- ONE frame for every photograph on the page -------------------------
   Tom, 2026-08-06: the four in the hero are the look, so everything else
   follows them. A cream mat, a brown hairline, a soft warm shadow, rounded
   corners. Declared once here and applied everywhere rather than being
   re-typed per component, so the page cannot drift into two kinds of frame. */
.gallery img,
.scoops img,
.shot img,
.band img,
.hero__side img {
  border-radius: 16px;
  border: 5px solid var(--paper);
  box-shadow: 0 0 0 1px rgba(76,38,0,.28),
              0 10px 26px -12px rgba(76,38,0,.55);
}
/* The full bleed bands run edge to edge, so a frame and rounded corners on
   those would fight the whole point of them. */
.band img { border: 0; border-radius: 0; box-shadow: none; }

@media (max-width: 700px) {
  .gallery img, .scoops img { border-width: 3px; border-radius: 11px; }
}

/* What people said, sitting with the pictures it is about. */
.case-said { margin-top: var(--s8); }
.case-said .quotes { margin-top: 0; }

/* The flavours, now the second half of "What we make". */
.flavours-part { margin-top: var(--s9, var(--s8)); padding-top: var(--s8);
                 border-top: 1px solid var(--hair-2); }

/* Four photographs as a row, two-up on a tablet, stacking on a phone.
   Four rather than three since 2026-08-06: the fountain shot came off her
   own Instagram. A 3-column rule would leave the fourth alone on its own
   line, so the breakpoints are set by the count, not by habit. */
.grid-shots {
  display: grid; gap: var(--s4);
  grid-template-columns: 1fr;
  margin-top: var(--s8);
}
@media (min-width: 760px)  { .grid-shots { grid-template-columns: repeat(2, 1fr); gap: var(--s5); } }
@media (min-width: 1060px) { .grid-shots { grid-template-columns: repeat(4, 1fr); } }
.grid-shots img { aspect-ratio: 4/5; object-fit: cover; }

/* --- the hero, text and one photograph ---------------------------------- */

.hero__grid { display: grid; gap: var(--s7); align-items: center; }
@media (min-width: 900px) {
  .hero__grid { grid-template-columns: 1.15fr .85fr; gap: var(--s8); }
}
.hero__shot img {
  display: block; width: 100%; height: auto;
  border-radius: 4px;
  aspect-ratio: 1;
  object-fit: cover;
}

/* --- address and hours, straight under the name, the way a sign works --- */

.standfirst {
  display: flex; flex-direction: column; gap: var(--s2);
  margin: var(--s5) 0 var(--s4);
  font: 500 1rem/1.5 var(--sans);
  color: var(--ink);
}
.standfirst .today { color: var(--orange-d); font-weight: 700; }   /* 4.52 */

/* --- today's hours, set big; the week is one tap down ------------------- */

.big-hours {
  font-family: var(--display);
  font-size: clamp(2rem, 5.5vw, 2.9rem);
  line-height: 1.05;
  color: var(--brown);
  margin: 0;
  font-variant-numeric: tabular-nums lining-nums;
}
.big-hours__cap {
  font: 700 .6875rem/1.4 var(--ui);
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--brown);
  margin: var(--s2) 0 var(--s5);
}

/* --- a dropdown. Closed by default, always. ----------------------------- */

.drop { border-top: 1px solid rgba(72,48,24,.28); border-bottom: 1px solid rgba(72,48,24,.28); }
.drop > summary {
  cursor: pointer; list-style: none;
  padding: var(--s3) 0;
  font: 700 .75rem/1.4 var(--ui);
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--brown);
  display: flex; justify-content: space-between; align-items: center;
}
.drop > summary::-webkit-details-marker { display: none; }
/* Open and closed are the SAME plus sign, rotated 45 degrees into a cross.
   It used to swap in a minus sign (U+2212); no dashes anywhere on this page
   by Tom's instruction 2026-08-06, and a rotation reads as open/closed more
   clearly than +/− ever did. */
.drop > summary::after {
  content: "+"; font-size: 1.25rem; line-height: 1;
  display: inline-block; transition: transform .18s ease;
}
.drop[open] > summary::after { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) { .drop > summary::after { transition: none; } }
.drop > summary:focus-visible { outline: 3px solid var(--brown); outline-offset: 2px; }
.drop[open] > summary { border-bottom: 1px solid rgba(72,48,24,.28); }
.drop .rows { padding-block: var(--s3); }
.s-sage .drop .rows > div { border-color: rgba(72,48,24,.22); }
.s-sage .drop .rows dt, .s-sage .drop .rows dd { color: var(--brown); }

/* --- a dietary tag on a menu line --------------------------------------- */

.tag {
  display: inline-block;
  margin-top: var(--s2) !important;
  font: 700 .6875rem/1 var(--ui);
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--orange-d);
  border: 1px solid currentColor;
  border-radius: 2px;
  padding: .5em .7em;
}

/* --- what people actually said ------------------------------------------ */

.quotes { display: grid; gap: var(--s5); }
@media (min-width: 820px) { .quotes { grid-template-columns: 1fr 1fr; gap: var(--s6); } }

.quotes blockquote {
  margin: 0;
  padding: var(--s5);
  background: var(--tint);
  border-radius: 3px;
  border-left: 3px solid var(--orange);
}
.quotes blockquote p {
  font-family: var(--display);
  font-size: clamp(1.125rem, 2.2vw, 1.375rem);
  line-height: 1.4;
  color: var(--brown);
  margin: 0;
}
.quotes footer {
  margin-top: var(--s4);
  font: 700 .75rem/1.4 var(--ui);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink);
}
.quotes footer span { font-weight: 400; color: var(--muted); letter-spacing: .06em; }

.rating-line {
  margin-top: var(--s6);
  font: .9375rem/1.6 var(--sans);
  color: var(--muted);
}
.rating-line strong { color: var(--ink); }

/* --- skip link ----------------------------------------------------------- */

.skip {
  position: absolute; left: -9999px;
  background: var(--brown); color: var(--cream);
  padding: var(--s3) var(--s4); z-index: 60; text-decoration: none;
  font: 700 .8125rem/1 var(--ui);
}
.skip:focus { left: var(--s3); top: var(--s3); }

/* A heading the design does not need to show, but the page structure does.
   The giant 416 IS the heading visually; a screen reader jumping by heading
   found nothing here at all, and neither did a search engine. */
.sr-head {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}

/* ==========================================================================
   REVIEW MODE — off unless the address ends in #review.
   The list is counted from the page, never typed.
   ========================================================================== */

#review { display: none; }
body.reviewing #review {
  display: block; background: var(--ink); color: var(--cream);
  padding: var(--s4) 0; font: .9375rem/1.6 var(--sans); position: relative; z-index: 5;
}
body.reviewing #review strong { color: var(--orange); }
body.reviewing #review ul { margin: var(--s2) 0 0; padding-left: var(--s4); }

body.reviewing [data-unconfirmed] {
  outline: 2px dashed var(--orange-d); outline-offset: 4px;
  background: repeating-linear-gradient(45deg,#fff4e0,#fff4e0 6px,#ffe9c8 6px,#ffe9c8 12px);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}


/* ==========================================================================
   THE STALL NUMBER
   Inside a market the stall number is the thing nobody can find. Setting it
   huge makes it the wayfinding, the ornament and the stand-in for the logo
   all at once — which is what a page with no photography needs.
   ========================================================================== */

.stall {
  font-family: var(--display);
  font-size: clamp(5rem, 20vw, 12rem);
  line-height: .82;
  letter-spacing: -0.03em;
  color: var(--orange);
  display: block;
  margin: 0;
}
.s-brown .stall, .s-deep .stall { color: var(--sage); }

.stall-cap {
  font: 700 .6875rem/1.4 var(--ui);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
  display: block;
  margin-top: var(--s2);
}
.s-brown .stall-cap, .s-deep .stall-cap { color: var(--sage); }

/* --- open / closed, computed from one hours object ---------------------- */

.status {
  display: inline-flex; align-items: center; gap: .55em;
  font: 700 .8125rem/1 var(--ui);
  letter-spacing: .12em; text-transform: uppercase;
  padding: .7em 1.1em;
  border: 1.5px solid currentColor;
  border-radius: 2px;
  margin-bottom: var(--s5);
}
/* `hidden` alone loses to the display above — an author rule beats the
   user-agent one. Without this an empty bordered pill shows whenever the
   script has not run yet, or at all. */
.status[hidden] { display: none; }

.status::before {
  content: ""; width: .5em; height: .5em; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}

/* The three states differ in FORM, not only in hue. Measured, the old pair
   was open #2f5646 (luminance .0770) against closed #8a3a12 (.0847) — a
   ratio of 1.06 between them, which is the same grey twice. In sun on the
   patio, or to anyone colour-blind, they were one badge.
   Open is now solid, closing-soon is solid amber, closed is hollow. */
.status.is-open {
  background: #2f5646; border-color: #2f5646; color: var(--cream);   /* 7.48 */
}
.status.is-soon {
  background: #8a4b00; border-color: #8a4b00; color: var(--cream);   /* 7.06 */
}
.status.is-closed {
  background: transparent; border-color: var(--muted); color: var(--muted); /* 5.77 */
}
.status.is-closed::before { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }

/* --- an editorial caption: a second, quieter register ------------------- */

.caption {
  font: .8125rem/1.5 var(--ui);
  color: var(--muted);
  margin-top: var(--s3);
}
.s-sage .caption { color: #3f4f45; }
.s-brown .caption, .s-deep .caption { color: var(--sage); }

/* ==========================================================================
   MOBILE ACTION BAR
   Most people reading this are on a phone, standing in the market. The two
   things they can do stay in reach once the hero scrolls away.
   ========================================================================== */

.bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  display: none; gap: 1px;
  background: var(--brown);
  transform: translateY(100%);
  transition: transform .22s ease;
}
.bar.is-up { transform: none; }
.bar a {
  flex: 1 1 0; min-height: 56px;
  display: flex; align-items: center; justify-content: center;
  font: 700 .75rem/1 var(--ui); letter-spacing: .12em; text-transform: uppercase;
  text-decoration: none;
}
.bar .go   { background: var(--orange); color: var(--ink); }
.bar .call { background: var(--brown);  color: var(--cream); }

/* iPhones with a home indicator eat the bottom ~34px. Without this, more
   than half of a 56px tap target sits under the gesture area. */
.bar { padding-bottom: env(safe-area-inset-bottom, 0px); }

@media (max-width: 860px) {
  .bar { display: flex; }
  body { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
}

/* --- focus, everywhere, not just on buttons ----------------------------- */
a:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
  outline: 3px solid var(--orange-d);
  outline-offset: 3px;
  border-radius: 2px;
}
.s-deep a:focus-visible, .s-brown a:focus-visible, .bar a:focus-visible {
  outline-color: var(--cream);
}

/* --- print: a school office booking a party should get a clean sheet ---- */
@media print {
  .bar, .marquee, .strip, #review, .skip, .burst { display: none !important; }
  body { background: #fff; color: #000; padding-bottom: 0; }
  .s-sage, .s-deep, .s-brown, .s-tint, .s-creamb { background: #fff !important; color: #000 !important; }
  .s-deep h2, .s-brown h2, .s-deep h3, .s-brown h3,
  .s-deep .label, .s-brown .label, .s-deep .pull, .s-brown .pull { color: #000 !important; }
  .s-deep a, .s-brown a, .rows a { color: #000 !important; }
  section { padding: 18pt 0; page-break-inside: avoid; }
  .drop[open] > summary::after, .drop > summary::after { content: ""; }
  details { display: block; }
  details > *:not(summary) { display: revert !important; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 9pt; word-break: break-all; }
  a[href^="tel:"]::after, a[href^="#"]::after { content: ""; }
  img { max-width: 45% !important; }
}


/* --- the second warm surface + section edges ---------------------------- */
.s-tint { background: var(--tint); }

/* Every premium reference brackets a tinted band with a hairline. The edge
   does the work, not the lightness. */
.edged { border-top: 1px solid var(--hair-2); border-bottom: 1px solid var(--hair-2); }
.s-deep.edged, .s-brown.edged, .s-sage.edged { border-color: rgba(240,230,210,.22); }

/* --- the one loud strip -------------------------------------------------- */
.strip {
  background: var(--strip);
  color: var(--cream);                    /* 5.46 */
  padding: 11px 0;
  font: 500 .6875rem/1.4 var(--mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  text-align: center;
  position: relative; z-index: 3;
}

/* --- the marquee: a band that is nothing but her own words --------------- */
.marquee {
  background: var(--brown);
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  padding: 18px 0;
  overflow: hidden;
  position: relative; z-index: 2;
}
.marquee__track {
  display: flex; width: max-content;
  animation: slide 42s linear infinite;
}
.marquee__track span {
  font: 500 1.125rem/1 var(--display);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cream);
  padding: 0 1.4em;
  white-space: nowrap;
}
/* Footer contact links. Separated by a real gap rather than by dots, so they
   still read as three separate things. */
.foot-links {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: .6em 2.2em;
}

/* --- the maker's mark ----------------------------------------------------
   Logo on top, the words directly under it, the pair pinned into the
   bottom-left CORNER of the page — not the content column. It sits outside
   .frame for exactly that reason: on the frame it read as one more line of
   her footer instead of a signature on the work.
   Small on purpose, and dimmed until you look at it, because a signature
   that shouts is an advert on somebody else's shop. The tap target is still
   over 44px tall, so "small" never means "unusable".
   MEASURED, not guessed: cream at .62 opacity over the brown reads 5.32:1
   in the light theme and 5.53:1 in the dark; at full opacity on hover it
   is 11.10:1 and 11.92:1. The dimmed state is the one that has to pass,
   and it clears AA (4.5:1) in both without needing the hover. */
.madeby-wrap {
  /* Hard against the corner, but never touching it — the inset shrinks on a
     phone, where 26px of dead margin is a fifth of the screen. */
  padding-inline-start: clamp(12px, 1.6vw, 22px);
  margin-top: var(--s6);
}
.madeby {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 6px 0 2px;
  text-decoration: none;
  opacity: .62;
  transition: opacity .16s ease;
}
.madeby img {
  width: 38px; height: 38px;
  border-radius: 8px;
  display: block;
}
.madeby span {
  font: 600 0.6875rem/1 var(--sans);
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--cream);
}
.madeby:hover { opacity: 1; }
.madeby:hover span { text-decoration: underline; text-underline-offset: 3px; }
.madeby:focus-visible { opacity: 1; outline: 3px solid var(--sage); outline-offset: 4px; }

/* The separator was a middot. No dots on this page (Tom, 2026-08-06), so the
   phrases are held apart by space alone — the padding on the span plus this
   margin. Nothing is drawn. */
.marquee__track span::after { content: ""; margin-left: 2.6em; }
@keyframes slide { from { transform: none } to { transform: translateX(-50%) } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* --- the menu as a bordered grid, the way a printed card would be -------- */
@media (min-width: 860px) {
  .menu--grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0;
                border-top: 1px solid var(--hair-2); }
  .menu--grid li { border-top: 0; border-bottom: 1px solid var(--hair-2);
                   padding: var(--s5) var(--s5) var(--s5) 0; }
  .menu--grid li:nth-child(odd) { border-right: 1px solid var(--hair-2);
                                  padding-right: var(--s6); }
  .menu--grid li:nth-child(even) { padding-left: var(--s6); }
}


/* --- breathing room under headings --------------------------------------
   h1/h2/h3 all carry margin:0 so they can be composed freely. That means
   anything following one needs its own gap, or the two touch. */
h2 + p, h2 + .caption, h2 + dl, h2 + ol, h2 + .rows { margin-top: var(--s4); }
h1 + p { margin-top: var(--s5); }
.pull + p { margin-top: var(--s5); }
.stall-cap + p { margin-top: var(--s6); }


/* ==========================================================================
   WARMTH PASS — 2026-08-04
   The bones were right and the page read as organised, but cold: hard band
   edges, square photographs, no softness anywhere. Everything below makes it
   friendlier WITHOUT inventing a new brand — every device here is something
   that is physically on her stall.
   ========================================================================== */

/* --- her awning, as a divider -------------------------------------------
   The stall has a green and white striped canopy with a scalloped valance.
   It is the most recognisable thing about the counter and it was doing no
   work on the page. Stripes in her sage, valance beneath, exactly like the
   real one. Costs nothing to load and it is not an ornament somebody
   invented — it is a picture of her shopfront. */

.awning {
  position: relative;
  height: 15px;
  background: repeating-linear-gradient(90deg,
    var(--sage)  0 26px,
    var(--paper) 26px 52px);
  border-top: 1px solid rgba(72,48,24,.16);
  z-index: 2;
}
.awning::after {                       /* the scalloped valance */
  content: "";
  position: absolute; left: 0; right: 0; bottom: -12px; height: 12px;
  background-image: radial-gradient(circle at 13px 0, var(--sage) 12px, transparent 12.5px);
  background-size: 26px 26px;
  background-repeat: repeat-x;
}
.awning--alt::after { background-image: radial-gradient(circle at 13px 0, var(--paper) 12px, transparent 12.5px); }

/* The section under an awning needs room for the valance to hang into. */
.awning + section { padding-top: calc(var(--s9) + 12px); }
@media (max-width: 700px) { .awning + section { padding-top: calc(var(--s8) + 12px); } }


/* --- photographs: rounder, warmer, sitting ON the page ------------------
   Square corners and no shadow made every photo look pasted on. A soft
   warm shadow (brown, never grey — a grey shadow on a cream page is the
   fastest way to look like a template) and a generous radius. */

.shot img, .hero__shot img {
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(72,48,24,.10),
              0 8px 24px -8px rgba(72,48,24,.22);
}
.grid-shots img { border-radius: 14px; }

/* On the dark bands a shadow does nothing — a warm hairline does. */
.s-deep .shot img, .s-brown .shot img { box-shadow: 0 0 0 1px rgba(240,230,210,.18); }


/* --- softer cards -------------------------------------------------------- */

.quotes blockquote {
  border-radius: 14px;
  border-left-width: 4px;
  box-shadow: 0 1px 2px rgba(72,48,24,.06);
}

.drop { border-radius: 10px; padding-inline: var(--s4);
        background: rgba(255,250,240,.42); border-width: 0; margin-bottom: var(--s3); }
.drop > summary { padding-block: var(--s4); }
.drop[open] { background: rgba(255,250,240,.68); }
.drop[open] > summary { border-bottom-color: rgba(72,48,24,.16); }
.drop p { padding-block: var(--s3) 0; }

.tag { border-radius: 999px; }        /* a little pill, not a box */


/* --- the status badge, softened ----------------------------------------- */

.status { border-radius: 999px; }


/* --- the loud strip and the marquee, less shouty ------------------------- */

.strip { letter-spacing: .16em; padding: 13px 0; }
.marquee { border-top-color: rgba(42,28,13,.4); border-bottom-color: rgba(42,28,13,.4); }


/* --- section rhythm ------------------------------------------------------
   Alternating bands were switching colour AND weight at once, which read as
   stripes rather than as a page. The tinted surfaces now sit closer to the
   cream, so the two dark bands are the only real punctuation. */

.s-tint  { background: #f9ecd7; }      /* was #f6e3c4 — closer to the cream */
.s-creamb{ background: #f7f0e0; }

/* Hairline at every band change, so an edge always reads as deliberate. */
.s-sage, .s-deep, .s-brown { border-top: 1px solid rgba(72,48,24,.14); }
.s-deep, .s-brown { border-top-color: rgba(240,230,210,.14); }


/* --- the hero, a touch more generous ------------------------------------ */

.hero { padding-top: var(--s7); }
.hero__shot img { border-radius: 18px; }

/* The rays were competing with the photograph. Quieter behind text. */
.hero .burst { opacity: .12; }


/* --- headings sit closer to what follows them --------------------------- */

.big-hours { letter-spacing: -.015em; }


/* ==========================================================================
   FIXES FROM LOOKING AT IT RENDERED — 2026-08-04
   Three of these only show up on screen, which is the argument for looking.
   ========================================================================== */

/* 1. The stall caption was sitting ON TOP of the 416.
      .stall has line-height .82, so its box is shorter than its glyphs and
      the next element rides up into the numerals. */
.stall { padding-bottom: .06em; }
.stall-cap { margin-top: var(--s4); }

/* 2. The phone number was dark brown on the dark brown band.
      `.rows a` (ink) and `.s-brown a` (cream) have equal specificity, and
      `.rows a` comes later in the file, so it won — invisibly. */
.s-brown .rows a, .s-deep .rows a { color: var(--cream); }
.s-brown .rows a:hover, .s-deep .rows a:hover { color: var(--sage); }

/* 3. Two-column sections had ragged bottoms: a photo in one column and a
      shorter run of text in the other left a wedge of dead colour. Where a
      figure is its own grid cell, let it fill the row instead. */
@media (min-width: 860px) {
  .split { align-items: stretch; }
  /* COLUMN, not row. Without the direction the caption becomes a second
     flex item and sits BESIDE the photograph, outside the grid column. */
  .split > .shot { display: flex; flex-direction: column; }
  .split > .shot img { flex: 1 1 auto; min-height: 320px; height: 100%; object-fit: cover; }
  /* Anything that is not the picture still aligns to the top. */
  .split > *:not(.shot) { align-self: start; }
}

/* A figure that sits INSIDE a column, under a heading, keeps its own shape. */
.split > div > .shot img { height: auto; }

/* Text column wider than the picture column, for sections where the words
   are the point and the photograph is the evidence. */
@media (min-width: 860px) {
  .split--wide-first { grid-template-columns: 1.3fr 1fr; }
}


/* ==========================================================================
   MORE PRESENCE — 2026-08-04
   The sunburst was too small and too faint to read as her badge's device.
   It is now the size of the section it sits in, with a warm glow at its
   centre, and it appears on more than one band so the page feels like one
   thing rather than a stack of blocks.

   Contrast checked, not assumed: orange at 28% over cream lands near
   #eecea9, and brown #483018 on that is still about 8:1 — comfortably past
   the 4.5 body-text threshold. The rays never sit under small text anyway.
   ========================================================================== */

.burst {
  width: min(240vw, 2000px);
  opacity: .3;
  background:
    /* a warm glow at the centre, so the rays radiate FROM something */
    radial-gradient(closest-side, rgba(210,120,30,.55), rgba(210,120,30,0) 62%),
    repeating-conic-gradient(from 0deg,
      var(--orange) 0deg 4.6deg,
      transparent 4.6deg 13deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 14%, rgba(0,0,0,.62) 48%, transparent 78%);
          mask-image: radial-gradient(closest-side, #000 14%, rgba(0,0,0,.62) 48%, transparent 78%);
}

.burst--sage {
  background:
    radial-gradient(closest-side, rgba(150,190,170,.5), rgba(150,190,170,0) 62%),
    repeating-conic-gradient(from 0deg,
      var(--sage) 0deg 4.6deg,
      transparent 4.6deg 13deg);
  opacity: .34;
}

/* On the hero it sits behind the headline, so it rides a touch higher and
   anchors under the logo rather than the middle of the block. */
.hero .burst { opacity: .26; top: 34%; }

/* A quieter one for bands that are mostly text. */
.burst--soft { opacity: .16; }

/* --- the loud strip, louder ---------------------------------------------- */
.strip {
  font-weight: 600;
  letter-spacing: .2em;
  box-shadow: inset 0 -2px 0 rgba(0,0,0,.16);
}

/* --- the primary button, with some weight behind it ---------------------- */
.btn--primary {
  box-shadow: 0 2px 0 #8a4b0e, 0 6px 16px -6px rgba(72,48,24,.5);
}
.btn--primary:hover { box-shadow: 0 2px 0 #2a1c0d, 0 8px 20px -6px rgba(72,48,24,.55); }

/* --- a full-bleed photograph, edge to edge ------------------------------- */
.band {
  position: relative;
  height: clamp(220px, 34vw, 420px);
  overflow: hidden;
  background: var(--brown);
  z-index: 1;
}
.band img { width: 100%; height: 100%; object-fit: cover; display: block; }
.band__cap {
  position: absolute; inset: auto 0 0 0;
  padding: var(--s6) var(--s4) var(--s4);
  background: linear-gradient(to top, rgba(42,28,13,.82), rgba(42,28,13,0));
  color: var(--cream);
  font: 500 clamp(1.05rem, 2.4vw, 1.5rem)/1.3 var(--display);
  text-align: center;
}

/* --- what to order first ------------------------------------------------- */
.picks { display: grid; gap: var(--s5); margin-top: var(--s7); counter-reset: p; }
@media (min-width: 780px) { .picks { grid-template-columns: repeat(3, 1fr); gap: var(--s6); } }
.picks > div {
  counter-increment: p;
  padding-top: var(--s4);
  border-top: 3px solid var(--orange);
}
.picks h3 { margin-bottom: var(--s2); }
.picks p { margin: 0; color: var(--muted); }
.picks .pick-n {
  font-family: var(--display);
  font-size: 2.2rem; line-height: 1;
  color: var(--orange-d);
  display: block; margin-bottom: var(--s2);
}

/* --- the questions ------------------------------------------------------- */
.faq { margin-top: var(--s7); }
.faq .drop { background: var(--paper); border: 1px solid var(--hair); }
.faq .drop[open] { background: var(--paper); }
.faq .drop > summary {
  font: 600 1.0625rem/1.4 var(--sans);
  letter-spacing: 0; text-transform: none;
  color: var(--ink);
}
.faq .drop p { color: var(--muted); padding-bottom: var(--s4); }


/* --- the sunburst, properly this time -----------------------------------
   Still too polite. Bigger, denser rays, stronger glow, and anchored high
   so it reads as a sun rising behind her badge rather than a texture.

   Contrast re-measured at the new strength: orange at 42% over cream lands
   near #ebc499, and brown #483018 on that is 7.8:1 — still comfortably past
   the 4.5 body threshold, and the headline is 11:1 type sitting on it. */
.burst {
  width: min(280vw, 2600px);
  opacity: .42;
  background:
    radial-gradient(closest-side, rgba(210,120,30,.75), rgba(210,120,30,.12) 45%, rgba(210,120,30,0) 70%),
    repeating-conic-gradient(from 1.5deg,
      var(--orange) 0deg 5.6deg,
      transparent 5.6deg 12.4deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 20%, rgba(0,0,0,.72) 52%, transparent 82%);
          mask-image: radial-gradient(closest-side, #000 20%, rgba(0,0,0,.72) 52%, transparent 82%);
}
.burst--sage {
  background:
    radial-gradient(closest-side, rgba(150,190,170,.7), rgba(150,190,170,.1) 45%, rgba(150,190,170,0) 70%),
    repeating-conic-gradient(from 1.5deg,
      var(--sage) 0deg 5.6deg,
      transparent 5.6deg 12.4deg);
  opacity: .5;
}
/* A sun rising behind the badge, not a halo around the middle of the block. */
.hero .burst { opacity: .44; top: 20%; }
.burst--soft { opacity: .22; }

/* The brown band can take a much louder one — nothing there is small text. */
.s-brown .burst { opacity: .3; }

/* The badge now lives inside the hero, above the grid, on top of the rays. */
.hero { padding-top: var(--s6); }
.hero .site-head { padding: 0 0 var(--s6); }
.hero .mark {
  box-shadow: 0 0 0 6px var(--cream), 0 4px 14px -4px rgba(72,48,24,.45);
}
.hero .burst { top: 8%; }

/* --- the badge, big -------------------------------------------------------
   Vector, so it can be as large as it wants. The old 100px JPEG could not go
   past about 120px without going soft, which is why the mark was doing so
   little work on the page. */
.mark--big {
  width: clamp(190px, 27vw, 320px);
  height: auto;
  border-radius: 0;
  filter: drop-shadow(0 6px 18px rgba(72,48,24,.32));
}
.tagline {
  font: 500 .8125rem/1.4 var(--mono);
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--brown);
  text-align: center;
  margin: var(--s4) 0 0;
}
.hero .site-head { padding-bottom: var(--s7); }

/* The cream ring was written for the old round 84px JPEG. On the vector
   badge it painted a cream RECTANGLE around the whole SVG box. */
.hero .mark--big { box-shadow: none; }

/* Big, but not so big the headline is pushed off a laptop screen. */
.mark--big { width: clamp(180px, 23vw, 280px); }


/* ==========================================================================
   HER REAL PALETTE — 2026-08-04
   Tom found the original artwork: "local ice logo 2017.jpg", 1800x1500 CMYK,
   print resolution. Saved as brand/local-ice-logo-2017-original.jpg.

   Everything before this was measured off a 100x100 Instagram thumbnail.
   This supersedes it. Measured off the real file, by pixel share:

     #f9f3dd cream 28.8%   #4c2600 brown 28.5%   #56926b green 8.8%
     #de620b orange 6.7%   #deaf33 GOLD  3.0%    #98dfa6 mint  1.0%
     #bf9959 tan    1.4%

   The GOLD is new — the sunburst rays in her badge are gold, not orange,
   and the page had been drawing them in the wrong colour all along.

   Every pair below was computed, not eyeballed:
     ink   #2a1c0d on cream          14.87
     brown #4c2600 on cream          11.92
     cream on brown band             11.92
     brown on mint  #98dfa6           8.48   (was 5.98 on the old sage)
     cream on deep green #2f533a      7.81
     brown on gold  #deaf33           6.49
     ink   on orange #de620b          4.61   (button fill)
     green #3d6b4e as a letter        5.54
     dark orange #a8480a as a letter  5.25
   FILL ONLY, never letters: orange 3.23, gold 1.84, mint, tan.
   ========================================================================== */

:root {
  --cream:    #f9f3dd;
  --paper:    #fffdf2;
  --cream-b:  #f4edd4;
  --orange:   #de620b;
  --orange-d: #a8480a;
  --gold:     #deaf33;
  --sage:     #98dfa6;   /* her mint — brown on it is 8.48 */
  --sage-d:   #3d6b4e;
  --sage-dk:  #2f533a;   /* deep band — cream on it is 7.81 */
  --brown:    #4c2600;
  --ink:      #2a1c0d;
  --muted:    #6b4a2a;
  --hair:     #e6dcc0;
  --hair-2:   #d9caa6;
  --tint:     #f7ecd2;
  --strip:    #a8480a;   /* cream on it = 5.25 */
  --tan:      #bf9959;
}

/* The rays are GOLD, the way they are in her badge. */
.burst {
  background:
    radial-gradient(closest-side, rgba(222,175,51,.8), rgba(222,175,51,.14) 45%, rgba(222,175,51,0) 70%),
    repeating-conic-gradient(from 1.5deg,
      var(--gold) 0deg 5.6deg,
      transparent 5.6deg 12.4deg);
}
.burst--sage {
  background:
    radial-gradient(closest-side, rgba(152,223,166,.7), rgba(152,223,166,.1) 45%, rgba(152,223,166,0) 70%),
    repeating-conic-gradient(from 1.5deg,
      var(--sage) 0deg 5.6deg,
      transparent 5.6deg 12.4deg);
}


/* ==========================================================================
   THE HERO, REBUILT AROUND THE LOGO
   Her badge is the best asset she has, so it leads and everything else is
   sized under it. One centred column, and the photographs sit as small
   supporting thumbs so the mark, the words and the pictures are all there
   before anybody scrolls.
   ========================================================================== */

.hero__grid { display: block; text-align: center; }
.hero .site-head { padding: 0 0 var(--s4); }

.logo {
  display: block;
  width: min(92vw, 620px);
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 8px 22px rgba(76,38,0,.28));
}

.hero h1 {
  font-size: clamp(1.9rem, 4.4vw, 3rem);
  margin-top: var(--s4);
}
.hero .lede { margin-inline: auto; }
.hero .standfirst { align-items: center; }
.hero .actions { justify-content: center; }

/* The supporting pictures — deliberately much smaller than the mark. */
.thumbs {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s3);
  max-width: 620px;
  margin: var(--s6) auto 0;
}
.thumbs img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: 12px;
  box-shadow: 0 1px 2px rgba(76,38,0,.12), 0 6px 16px -8px rgba(76,38,0,.3);
}
@media (max-width: 560px) { .thumbs { gap: var(--s2); } }

/* Tighter hero so the mark, the words, the buttons and the pictures all
   land on the first screen. */
.hero { padding-top: var(--s5); padding-bottom: var(--s7); }
.hero .standfirst { margin-block: var(--s4) var(--s3); }
.hero .status { margin-bottom: var(--s4); }
.hero .actions { margin-top: var(--s4); }

/* --- the top bar, now carrying the three things people came for --------- */
.strip { padding: 0; }
.strip__in {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
  align-items: center; justify-content: space-between;
  padding-block: 10px;
}
.strip__who { opacity: .92; }
.strip__nav { display: flex; gap: var(--s4); flex-wrap: wrap; }
.strip__nav a {
  color: var(--cream);
  text-decoration: none;
  border-bottom: 1px solid rgba(249,243,221,.45);
  padding-bottom: 1px;
  white-space: nowrap;
}
.strip__nav a:hover { border-bottom-color: var(--cream); }
@media (max-width: 640px) {
  .strip__in { justify-content: center; text-align: center; }
  .strip__who { flex: 1 0 100%; }
}

/* --- the burst, dialled back --------------------------------------------
   With her real badge on the page, a strong page-wide sunburst doubles the
   rays that are already in the logo and the two fight. The background is
   support, not the subject: it now reads as a warm glow behind the mark
   rather than a wall of yellow. */
.burst { opacity: .18; }
.hero .burst { opacity: .16; top: 14%; }
.burst--sage { opacity: .2; }
.burst--soft { opacity: .1; }
.s-brown .burst { opacity: .16; }

/* --- fitting the first screen -------------------------------------------
   The mark, the words, the two buttons and the pictures all have to land
   before anybody scrolls. The logo still leads by a distance — it is about
   four times the width of a thumb — but it is no longer so tall that it
   pushes the photographs off the screen. */
.logo { width: min(88vw, 470px); }
.hero { padding-top: var(--s4); padding-bottom: var(--s6); }
.hero .site-head { padding-bottom: var(--s3); }
.hero h1 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); margin-top: var(--s3); }
.hero .standfirst { margin-block: var(--s3) var(--s2); font-size: .9375rem; }
.hero .status { margin-bottom: var(--s3); }
.hero .actions { margin-top: var(--s3); }
.hero .lede { display: none; }        /* the same ground is covered below */
.thumbs { max-width: 470px; margin-top: var(--s5); gap: var(--s2); }

@media (max-height: 800px) and (min-width: 900px) {
  .logo { width: min(80vw, 400px); }
}

/* --- the top bar, bigger --------------------------------------------------
   It carries the three things people came for, so it should read like a
   bar rather than a caption. */
.strip { font-size: .8125rem; letter-spacing: .13em; }
.strip__in { padding-block: 17px; gap: var(--s3) var(--s6); }
.strip__nav { gap: var(--s5); }
.strip__nav a { font-weight: 600; }
@media (max-width: 640px) {
  .strip { font-size: .75rem; }
  .strip__in { padding-block: 12px; }
}
/* claw back the extra height so the thumbs stay on the first screen */
.hero { padding-top: var(--s3); }
.logo { width: min(88vw, 440px); }

/* A grid item's default `align-self: stretch` beats `aspect-ratio` on the
   block axis, so the thumbs were being stretched to the row height instead
   of staying square. Start-align them and the ratio decides the height. */
.thumbs { align-items: start; }
.thumbs img { align-self: start; height: auto; aspect-ratio: 1; object-fit: cover; }

/* --- the light green band, corrected -------------------------------------
   #98dfa6 was the wrong pick: in her artwork that mint is a 1% HIGHLIGHT,
   not a surface, and used as a whole band it read as a bright spring green
   that matched nothing else on the page.

   The band is now a tint of her DOMINANT green #56926b (8.8% of the mark),
   mixed 52% toward her cream. Softer, unmistakably from the same family as
   the logo, and it blends out of the cream above it instead of jumping.
     brown #4c2600 on #abc4a6  =  7.05
     ink   #2a1c0d on #abc4a6  =  8.80
   Both were 5.98 and lower on the old sage, so this is more readable too. */
:root {
  --sage: #abc4a6;
  --mint: #98dfa6;   /* kept for small accents only, never a surface */
}
.burst--sage {
  background:
    radial-gradient(closest-side, rgba(86,146,107,.5), rgba(86,146,107,.08) 45%, rgba(86,146,107,0) 70%),
    repeating-conic-gradient(from 1.5deg,
      #56926b 0deg 5.6deg,
      transparent 5.6deg 12.4deg);
  opacity: .16;
}
.s-sage .drop { background: rgba(249,243,221,.5); }
.s-sage .drop[open] { background: rgba(249,243,221,.72); }

/* ==========================================================================
   THE HERO: pictures either side of the mark
   Left column, the badge and the words, right column. The photographs are
   deliberately about a third of the logo's width — present, never competing.
   ========================================================================== */

.hero__grid {
  display: grid;
  grid-template-columns: 1fr 2.3fr 1fr;
  gap: var(--s5);
  align-items: center;
  text-align: center;
}
.hero__side { display: grid; gap: var(--s4); }

/* Framed like a print: a cream mat, a brown hairline, soft warm shadow. */
.hero__side img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: 18px;
  border: 6px solid var(--paper);
  box-shadow: 0 0 0 1px rgba(76,38,0,.28),
              0 10px 26px -12px rgba(76,38,0,.55);
}

.hero__mid .site-head { padding: 0 0 var(--s3); }

/* Stack on smaller screens: the mark first, then the pictures as a row of
   four underneath, so they still land on the first screen. */
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; gap: var(--s5); }
  .hero__side { grid-template-columns: 1fr 1fr; gap: var(--s3); }
  .hero__side:first-child { order: 2; }
  .hero__side:last-child  { order: 3; }
  .hero__mid { order: 1; }
  .hero__side img { border-width: 4px; border-radius: 14px; }
}

/* --- the side pictures: square boxes ------------------------------------
   Two things were wrong. They were 4:5 portraits when Tom wanted boxes, and
   they were being stretched far taller than any ratio because a grid item's
   default `align-self: stretch` overrides `aspect-ratio` on the block axis.
   Start-aligning them lets the ratio decide the height — the same bug, and
   the same fix, as the thumbnail row. */
.hero__grid { grid-template-columns: 1fr 1.9fr 1fr; gap: var(--s5); }
.hero__side { align-items: start; align-content: center; }
.hero__side img {
  align-self: start;
  height: auto;
  aspect-ratio: 1 / 1;      /* boxes, not rectangles */
  object-fit: cover;
}
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__side { grid-template-columns: 1fr 1fr; align-content: start; }
}

/* --- let the hero run wider than the reading frame -----------------------
   The rest of the page is held to a 64rem column because that is a
   comfortable measure for text. The hero is not text — the pictures should
   sit out near the edges of the window, with the mark bigger between them. */
@media (min-width: 900px) {
  .hero .hero__grid {
    max-width: min(1640px, 95vw);
    grid-template-columns: 1fr 1.75fr 1fr;
    gap: var(--s6);
  }
  .logo { width: min(90%, 540px); }
}
@media (min-width: 1400px) {
  .hero .hero__grid { grid-template-columns: 1fr 1.6fr 1fr; }
  .logo { width: min(90%, 600px); }
}

/* --- pictures right out to the corners ---------------------------------- */
@media (min-width: 900px) {
  .hero .hero__grid {
    max-width: 100%;
    padding-inline: var(--s4);
    grid-template-columns: 1.15fr 1.5fr 1.15fr;
    gap: var(--s5);
  }
  .logo { width: min(94%, 620px); }
}
@media (min-width: 1400px) {
  .hero .hero__grid { grid-template-columns: 1.2fr 1.4fr 1.2fr; gap: var(--s6); }
  .logo { width: min(94%, 700px); }
}

/* A second, quieter button so Menu and Directions are both one tap. */
.btn--menu { background: var(--paper); }
.btn--menu:hover { background: var(--brown); color: var(--cream); }
.hero .actions { gap: var(--s3); }

/* --- the side pictures, stacked and tilted -------------------------------
   Two prints dropped on the counter rather than two cells in a table. Each
   pair overlaps slightly and sits a couple of degrees off square, mirrored
   left and right so the hero still reads as symmetrical overall. */
@media (min-width: 900px) {
  .hero__side { display: block; }
  .hero__side img {
    display: block;
    width: 86%;
    position: relative;
    transition: transform .25s ease, box-shadow .25s ease;
  }
  .hero__side img:nth-of-type(2) { margin-top: -14%; z-index: 2; }

  /* left pair leans out to the left, then back */
  .hero__side:first-of-type img:nth-of-type(1) { transform: rotate(-3.2deg); margin-left: 0; }
  .hero__side:first-of-type img:nth-of-type(2) { transform: rotate(2.4deg);  margin-left: 14%; }

  /* right pair mirrors it */
  .hero__side:last-of-type img:nth-of-type(1) { transform: rotate(3.2deg);  margin-left: 14%; }
  .hero__side:last-of-type img:nth-of-type(2) { transform: rotate(-2.4deg); margin-left: 0; }

  /* lift the one you point at, so the stack feels like real objects */
  .hero__side img:hover { transform: rotate(0deg) scale(1.04); z-index: 3;
                          box-shadow: 0 0 0 1px rgba(76,38,0,.3), 0 18px 34px -14px rgba(76,38,0,.7); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__side img { transition: none; }
}

/* The reviews block inside The case: one photograph, then what people said. */
@media (min-width: 860px) {
  .case-said { display: grid; grid-template-columns: 300px 1fr; gap: var(--s8); align-items: start; }
  .case-said .rating-line { grid-column: 2; }
}
.said-shot { margin: 0; }

/* --- inline text links ---------------------------------------------------
   There is no global `a` rule on this page: links are styled per component,
   which is fine until somebody adds one in prose and gets browser default
   blue. This catches those. Her brown, with an underline that sits off the
   baseline so descenders stay readable. */
.menu a,
.rating-line a,
.faq a,
.measure a,
p a:not(.btn):not(.btnlink) {
  color: var(--orange-d);
  text-decoration-color: rgba(168, 92, 18, .45);
  text-underline-offset: .18em;
  text-decoration-thickness: 1px;
}
.menu a:hover,
.rating-line a:hover,
.faq a:hover,
.measure a:hover,
p a:not(.btn):not(.btnlink):hover { text-decoration-color: currentColor; }
/* On the dark bands her brown would vanish, so those keep cream. */
.s-deep p a, .s-brown p a, .s-deep .measure a, .s-brown .measure a {
  color: var(--cream); text-decoration-color: rgba(250,243,228,.5);
}

/* --- the flavours: three columns, one band -------------------------------
   Was three stacked bands, which cost three screens of scrolling for eighteen
   words. Side by side the whole list is one screen and the three kinds can be
   compared at a glance.

   The ground is brown because all eighteen tints clear 3:1 on it with NO
   adjustment. On the deep green six had to be washed out first. The ground
   moved so the colours could stay true.

   Each name carries its tint in an inline --c, next to the name it belongs to,
   which is where somebody editing the list will look for it.
   Bold, 20px floor, so it counts as large text and the bar is 3:1. */
.flav { padding: var(--s8) 0; }

.flav-cols {
  display: grid; gap: var(--s7) var(--s6);
  grid-template-columns: 1fr;
}
@media (min-width: 720px)  { .flav-cols { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .flav-cols { grid-template-columns: repeat(3, 1fr); gap: var(--s5) var(--s7); } }

.flav-col h3 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 1.9rem);
  color: var(--cream);
  margin: 0 0 var(--s2);
}
/* The kicker sits under its heading on its own line: one thing per line, so
   the three columns read as three clean lists rather than a paragraph. */
.flav-col h3 span {
  display: block;
  font: 500 .6875rem/1.4 var(--mono);
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--sage); opacity: .85;
  margin-top: var(--s2);
}
.flav-col ul {
  list-style: none; margin: var(--s4) 0 0; padding: 0;
  border-bottom: 1px solid rgba(250,243,228,.2);
}
.flav-col li {
  color: var(--c);
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.25rem, 2.1vw, 1.5rem);   /* 20px floor keeps it "large" */
  line-height: 1.2;
  padding: var(--s3) 0;
  border-top: 1px solid rgba(250,243,228,.2);
}

/* --- What we make: photographs down both sides ---------------------------
   Tom, 2026-08-06. They were a row of four under the menu; they now flank it,
   two left and two right, the same shape as the hero. The frame widens for
   this one section so the middle column still holds the menu two up rather
   than squeezing it into one tall column, which would have added back the
   scrolling we just removed. */
.frame--wide { max-width: 82rem; }

.make-grid { display: grid; gap: var(--s6); align-items: center; }
.make__side { display: grid; gap: var(--s4); }
.make__side .shot { margin: 0; }
.make__side img { aspect-ratio: 4/5; object-fit: cover; height: auto; align-self: start; }

/* The middle has to hold the menu TWO up. At 3.1fr the text columns came out
   near 250px and every line wrapped after four words, which reads worse than
   no photographs at all. 3.6fr gives the menu about 360px a column and still
   leaves the sides wide enough to be photographs rather than stamps. */
@media (min-width: 1000px) {
  .make-grid { grid-template-columns: 1fr 3.6fr 1fr; gap: var(--s6); }
}
@media (min-width: 1240px) { .make-grid { gap: var(--s7); } }
/* Below that the sides become one row of four under the menu, which is the
   old arrangement and the only one that works in a single column. */
@media (max-width: 999px) {
  .make-grid { grid-template-columns: 1fr; }
  .make__mid { order: 1; }
  .make__side { order: 2; grid-template-columns: 1fr 1fr; }
}

/* The scoops run the full width of the window, not the text column, so six
   photographs are actually worth looking at instead of being thumbnails. */
.scoops--wide {
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  padding-inline: var(--s4);
  gap: var(--s4);
}
@media (min-width: 700px) { .scoops--wide { padding-inline: var(--s5); gap: var(--s5); } }

/* --- the review rail -----------------------------------------------------
   Push it sideways. Two cards today because two is all the real, named
   reviews we have quoted; her other 87 have not been read. It holds any
   number without changing, so adding more is a matter of adding blockquotes.

   tabindex="0" on the rail so somebody using a keyboard can scroll it with
   the arrow keys. A scroll box that only a mouse can move is a dead end. */
.said-head {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.4rem, 2.6vw, 1.75rem);
  color: var(--brown); margin: 0 0 var(--s5);
}
.rail {
  display: flex; gap: var(--s4);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  padding-bottom: var(--s4);
  scrollbar-color: var(--hair-2) transparent;
}
.rail > blockquote {
  flex: 0 0 min(84%, 26rem);
  scroll-snap-align: start;
  margin: 0;
  background: var(--paper);
  border: 1px solid var(--hair);
  border-radius: 14px;
  padding: var(--s5);
}
.rail > blockquote p { font-size: 1.0625rem; }
.rail:focus-visible { outline: 3px solid var(--brown); outline-offset: 4px; }
.rail::-webkit-scrollbar { height: 8px; }
.rail::-webkit-scrollbar-thumb { background: var(--hair-2); border-radius: 4px; }
.rail::-webkit-scrollbar-track { background: transparent; }
/* .case-said was a two column grid built around a photograph that has since
   moved into the gallery. The rail wants the full width. */
@media (min-width: 860px) { .case-said { display: block; } }
.case-said { margin-top: var(--s8); }

/* ==========================================================================
   THE SOCIALS, UNDER THE MARK
   Tom, 2026-08-14: the logo moves up a little and her socials sit directly
   under it. The mark is the best asset she has, and the three places she
   actually posts belong with it rather than only at the very bottom of the
   page — her Instagram has 1,437 followers and the page had been sending
   nobody to it until the footer.

   Deliberately quieter than the two buttons below: this is a "find her
   later" row, not the "walk to Stall 416" action, and the gold Get
   directions button stays the only loud thing on the screen.
   ========================================================================== */

.hero { padding-top: var(--s3); }        /* was --s5. The mark starts higher. */
.hero .site-head { padding-bottom: var(--s2); }

.hero-social {
  display: flex; flex-wrap: wrap; justify-content: center;
  /* 2.2em across, the same as the footer row. At 1.6em the three names read
     as one run of text rather than three separate links. */
  gap: .4em 2.2em;
  margin: var(--s2) 0 var(--s4);
  font-family: var(--sans);
  font-size: .9375rem;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.hero-social a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 2px solid var(--orange);
  padding: 6px 2px;          /* keeps the tap target over 44px with the gap */
  opacity: .82;
}

.hero-social a:hover,
.hero-social a:focus-visible { opacity: 1; border-bottom-color: var(--ink); }

@media (max-width: 700px) {
  .hero-social { font-size: .875rem; gap: .4em 1.1em; }
}

/* --- Get directions, directly under the headline -------------------------
   Tom, 2026-08-14. Direction requests were 189 of her 320 Google interactions
   last month, so the button that answers them should not be sitting under
   three paragraphs of prose. On its own line, centred, and still the only
   gold thing on the screen — the three remaining buttons below it stay in
   their quieter styles so this one does not have to compete. */
.hero-go {
  display: flex;
  justify-content: center;
  margin: var(--s4) 0 var(--s3);
}

/* On a phone it goes full width, because a thumb should not have to aim. */
@media (max-width: 560px) {
  .hero-go { margin: var(--s3) 0; }
  .hero-go .btn { width: 100%; text-align: center; }
}
