/* ============================================================================
   Dough of Enchantment — site layer.

   Loads after design-system.css. Everything here is either (a) the bakery's
   colourway, or (b) the page layouts, lifted from the Claude Design artboards
   and turned from inline styles into named classes.

   Colourway: "Oxblood & apricot" palette on the "Paper white" ground — the
   combination Home.dc.html was set to, applied to all four pages.
   ========================================================================= */

:root {
  /* ---- Ground (Paper white) ------------------------------------------- */
  --color-bg: #fdfcfa;
  --color-surface: #f5f2ec;
  --color-divider: #e7e3da;

  /* ---- Palette (Oxblood & apricot) ------------------------------------ */
  --color-text: #211c17;
  --color-accent: #8c2f2a;
  --color-accent-600: #762520;
  --color-accent-200: #efd8d3;
  --color-accent-700: #722521;
  --color-accent-800: #571c19;
  --color-accent-900: #3a1210;
  --color-accent-2: #d98c3f;
  --color-accent-2-100: #fbecd8;
  --color-accent-2-200: #f5dcba;
  --color-accent-2-800: #8a5216;
  --gold: #c9a24a;
  --band: #2a1d1a;

  /* ---- Site additions -------------------------------------------------- */
  /* Hairline dividers sit at 1.25:1 against the page, which is fine for
     decorative rules but too faint to bound a control. Interactive borders
     (inputs, secondary buttons) use this instead — 3.26:1, clearing the
     WCAG 1.4.11 non-text minimum on both the page and the surface. */
  --color-border-strong: color-mix(in srgb, var(--color-text) 50%, transparent);
  /* Caption ink: light enough to read as secondary, dark enough for AA. */
  --color-caption: color-mix(in srgb, var(--color-text) 66%, transparent);

  --measure: 1160px;
  --gutter: clamp(20px, 5vw, 56px);
}

/* ---------------------------------------------------------------- shell -- */

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  text-wrap: pretty;
  overflow-x: clip;
}

a { color: var(--color-accent-700); text-underline-offset: 3px; }
a:hover { color: var(--color-accent-800); }

::selection { background: color-mix(in srgb, var(--color-accent) 24%, transparent); }

.wrap { max-width: var(--measure); margin: 0 auto; padding: 0 var(--gutter); }

.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 50;
  background: var(--color-accent); color: #fff;
  padding: 10px 18px; border-radius: var(--radius-md);
  font-size: 14px; text-decoration: none;
  transition: top 120ms ease-out;
}
.skip-link:focus { top: 8px; color: #fff; }

[hidden] { display: none !important; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* --------------------------------------------------------------- header -- */

.site-header {
  border-bottom: 1px solid var(--color-divider);
  padding: 16px var(--gutter);
}
.site-header__inner {
  max-width: var(--measure); margin: 0 auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 28px;
}
.brand { display: block; margin-right: auto; line-height: 0; }
.brand picture { display: block; }
.brand img { height: 62px; width: auto; }

.site-nav {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 26px;
  font-size: 13px; letter-spacing: 0.14em; text-transform: uppercase;
}
.site-nav a { text-decoration: none; }
.site-nav a[aria-current="page"] {
  /* Apricot at #d98c3f reaches only 2.63:1 on the paper-white ground, so the
     current-page rule uses the darker step of the same hue (6.21:1). */
  border-bottom: 2px solid var(--color-accent-2-800);
  padding-bottom: 2px;
}

/* --------------------------------------------------------------- footer -- */

.site-footer {
  background: var(--band); color: #f2e8da;
  padding: clamp(32px, 4vw, 56px) var(--gutter);
}
.site-footer__inner {
  max-width: var(--measure); margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 28px 48px;
  align-items: center; justify-content: space-between;
}
/* The <picture> is the flex item, so it carries the width; a percentage on the
   <img> inside it would resolve against an indefinite box. */
.site-footer__inner > picture { display: block; width: min(300px, 60%); }
.site-footer__mark {
  width: 100%; height: auto;
  /* The wordmark ships as black ink on transparency, so a straight invert
     turns it white on the dark band — no blend mode needed. */
  filter: invert(1);
}
.site-footer__links {
  display: flex; flex-direction: column; gap: 8px;
  font-size: 14px; line-height: 26px;
}
.site-footer__links a { color: var(--gold); text-decoration: none; }
.site-footer__links a:hover { color: #e0bd6c; text-decoration: underline; }
.site-footer__links a:focus-visible { outline-color: var(--gold); }
.site-footer__meta {
  margin: 0; font-size: 13px; line-height: 26px;
  color: #c4b4a2; max-width: 28ch;
}

/* ----------------------------------------------------------- primitives -- */

.pill {
  margin: 0 0 16px;
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--color-accent-2-800); background: var(--color-accent-2-100);
  padding: 8px 16px; border-radius: 999px;
}

.display {
  font-family: var(--font-heading); font-weight: 400;
  line-height: 1.04; letter-spacing: -0.015em; margin: 0 0 18px;
  font-size: clamp(40px, 5.6vw, 74px);
}
.display--hero { font-size: clamp(44px, 6.2vw, 84px); line-height: 1.02; margin-bottom: 22px; }
.display em { font-style: italic; color: var(--color-accent-2-800); }

.section-title {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(30px, 3.8vw, 48px); line-height: 1.08; margin: 0;
}
.section-title--sm { font-size: clamp(26px, 3vw, 36px); line-height: 1.1; }
.section-title--md { font-size: clamp(28px, 3.6vw, 46px); line-height: 1.08; }

.lede {
  margin: 0; font-size: 17px; line-height: 32px; max-width: 54ch;
  color: color-mix(in srgb, var(--color-text) 82%, transparent);
}
.lede--hero { font-size: 18px; line-height: 33px; max-width: 48ch; margin-bottom: 30px; }

.kicker {
  margin: 0 0 8px; font-size: 12px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--color-accent-700);
}
.kicker--warm { color: var(--color-accent-2-800); }
.kicker--tight { font-size: 11px; margin-bottom: 6px; }

.prose { margin: 0; font-size: 16px; line-height: 30px; color: color-mix(in srgb, var(--color-text) 80%, transparent); }
.prose--sm { font-size: 15px; line-height: 28px; color: color-mix(in srgb, var(--color-text) 74%, transparent); }

/* A blank line in a CMS box becomes a real paragraph now, everywhere the client
   can type prose. The single-paragraph versions of these all sit at margin: 0
   by design, so a stack of them needs its own air; a lone paragraph is
   unchanged. The blocks whose paragraphs already carry a bottom margin —
   .faq p, .closer p, .policy__body p — are deliberately absent. */
.lede + .lede { margin-top: 20px; }
.prose + .prose { margin-top: 18px; }
.note-box p + p { margin-top: 12px; }
.special__body + .special__body,
.pricelist__body + .pricelist__body,
.orderitem__body + .orderitem__body { margin-top: 10px; }

.btn-row { display: flex; gap: 14px; flex-wrap: wrap; }
.btn-row--center { justify-content: center; }

/* The design system's secondary button borrows the hairline divider for its
   border; on this ground that is not enough to read as a control edge. */
.btn-secondary { border-color: var(--color-border-strong); }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

.link-more {
  font-size: 13px; letter-spacing: 0.14em; text-transform: uppercase;
  white-space: nowrap;
}

/* --------------------------------------------- photo frames + fallbacks -- */

/*  Every photograph on the site is wired up the same way:
 *
 *      <figure class="plate">
 *        <div class="frame" style="--ratio: 4 / 5">
 *          <img … onerror="…">          ← the real photo, once it exists
 *          <span class="frame__hint">…</span>   ← what belongs there
 *        </div>
 *      </figure>
 *
 *  Drop a file into assets/photos/ under the name in the <img> src and it
 *  takes over the frame; until then the inline onerror strips the missing
 *  <img> and the hint underneath shows through. No markup edits either way.
 *  assets/photos/README.md lists every filename the site looks for. */

.frame {
  position: relative;
  aspect-ratio: var(--ratio, 1);
  background: var(--color-surface);
  overflow: hidden;
  display: grid;
}
.frame > img {
  grid-area: 1 / 1;
  width: 100%; height: 100%;
  object-fit: cover;
  position: relative; z-index: 1;
}
.frame__hint {
  grid-area: 1 / 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 18px; text-align: center;
  font-size: 13px; line-height: 20px;
  color: var(--color-caption);
  background:
    repeating-linear-gradient(
      135deg,
      transparent 0 11px,
      color-mix(in srgb, var(--color-text) 3%, transparent) 11px 22px
    );
}
.frame__hint::before {
  content: "";
  width: 26px; height: 22px;
  border: 1.5px solid currentColor; border-radius: 3px;
  opacity: 0.55;
  background:
    radial-gradient(circle at 30% 34%, currentColor 0 2.5px, transparent 2.6px),
    linear-gradient(to top right, transparent 45%, currentColor 45% 58%, transparent 58%);
}

/* The system's plate treatment is a photo filter — with no photo in the frame
   it only muddies the placeholder, so it applies once a photo is present. */
.plate:not(:has(img)) { filter: none; }

/* The per-photo "Color" setting in the CMS, for the shot the global grade
   above still leaves flat. These compound with .plate rather than replacing
   it, so a boosted photo still reads as part of the same set. "Normal" writes
   no class at all, which is what nearly every photo wants - reach for these
   when a specific picture looks wrong on the page, not as a habit. */
.frame--brighter > img { filter: saturate(1.16) contrast(1.03); }
.frame--brightest > img { filter: saturate(1.34) contrast(1.05) brightness(1.03); }
.plate { display: block; }

/* ---------------------------------------------------------- home: hero --- */

.hero {
  display: flex; flex-wrap: wrap; gap: clamp(28px, 5vw, 68px);
  align-items: center; padding: clamp(36px, 5vw, 76px) 0 clamp(32px, 4vw, 60px);
}
.hero__text { flex: 1 1 400px; min-width: 0; }
.hero__media { flex: 1 1 340px; min-width: 0; max-width: 520px; position: relative; }
.hero__hours {
  margin: 0; font-size: 15px; line-height: 26px;
  color: color-mix(in srgb, var(--color-text) 68%, transparent);
}

.blob { position: absolute; border-radius: 50%; z-index: 0; }
.blob--gold { top: -18px; right: -10px; width: 84px; height: 84px; background: var(--gold); }
.blob--rose { bottom: -22px; left: -18px; width: 56px; height: 56px; background: var(--color-accent-200); }
.hero__media .plate { position: relative; z-index: 1; }

/* ------------------------------------------------------- home: marquee --- */

.marquee {
  /* One number, used both between the phrases and inside a phrase either side
     of its star, so the wide row stays evenly spaced however the stars are
     switched on and off below. */
  --marquee-gap: 40px;
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  padding: 22px 0;
  display: flex; flex-wrap: wrap; gap: 14px var(--marquee-gap); justify-content: center;
  font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 72%, transparent);
}
.marquee__item { display: inline-flex; align-items: center; gap: var(--marquee-gap); }
/* Sized by its own width/height attributes; these keep a flex row from
   stretching or shrinking it, and sit it on the text's centre line rather
   than its baseline. */
.marquee__star { color: var(--gold); flex: none; align-self: center; display: block; }
/* index.html emits a star either side of every phrase; these decide which are
   drawn. Wide: none of the leading ones, and none on the last phrase - which
   leaves exactly one star between each pair, the layout the site has always
   had. The phone override is in the 720px block at the foot of this file. */
.marquee__starslot { display: none; flex: none; line-height: 0; }
.marquee__item:not(:last-child) .marquee__starslot--trail { display: block; }

/* ------------------------------------------------------ home: featured --- */

.band { padding: clamp(36px, 5vw, 72px) 0 clamp(20px, 3vw, 36px); }
.band__head {
  display: flex; flex-wrap: wrap; gap: 12px 32px;
  align-items: baseline; justify-content: space-between;
  margin-bottom: clamp(20px, 3vw, 36px);
}

.grid-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
  gap: clamp(18px, 2.5vw, 30px);
}
.feature { display: flex; flex-direction: column; gap: 14px; }
.feature h3 {
  font-family: var(--font-heading); font-weight: 600; font-size: 24px;
  line-height: 1.2; margin: 0 0 6px; letter-spacing: -0.01em;
}
/* Given a class rather than matched as "the last p in the card": a description
   the client wrote as two paragraphs is two p's, and only one of them would
   have been the last one. */
.feature__body {
  margin: 0 0 12px; font-size: 15px; line-height: 27px;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}
.feature__body:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------- home: shop --- */

.shop-card {
  background: var(--color-accent-2-100);
  border-radius: var(--radius-md);
  padding: clamp(28px, 4vw, 56px);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: clamp(24px, 4vw, 52px);
  margin-bottom: clamp(36px, 5vw, 72px);
}
.shop-card .kicker { margin-bottom: 14px; }
.shop-card address { font-style: normal; margin: 0; font-size: 17px; line-height: 32px; }

/* Three equal thirds gave the hours column about 277px at full width, and
   "Saturday-Sunday  7:00am – 10:00am" needs about 310 — so the time broke
   after the dash. Once there is room for three columns, the hours column is
   sized to what it holds and the address and pickup columns share the rest,
   except that the address never gives up so much that a line of it wraps (at
   960px it has about 3px to spare); the pickup paragraph takes any squeeze.
   Narrower than this, the auto-fit rule above stands and .hours__row wraps. */
@media (min-width: 960px) {
  .shop-card { grid-template-columns: minmax(max-content, 1fr) fit-content(40%) minmax(0, 1fr); }
}

/* Opening hours, one row per entry: the days, then the times.
   The times are a single unbreakable unit — "7:00am –" on one line and
   "10:00am" on the next is what the client asked to have fixed. When a column
   is too narrow for both side by side, the times drop under the days in one
   piece instead. That is decided by the words themselves rather than by a
   breakpoint, because the day labels are the client's and can be any length.
   Only a time range is kept on one line; a "closed" note she writes wraps
   normally. */
.hours {
  margin: 0; display: grid; gap: 8px;
  font-size: 16px; line-height: 28px; font-feature-settings: 'tnum';
}
.hours__row { display: flex; flex-wrap: wrap; column-gap: 26px; }
.hours dt { color: color-mix(in srgb, var(--color-text) 68%, transparent); }
.hours dd { margin: 0; }
.hours__time { white-space: nowrap; }
.hours--compact { gap: 6px; font-size: 15px; line-height: 26px; }
.hours--compact .hours__row { column-gap: 20px; }

/* --------------------------------------------------------------- menu ---- */

.page-head {
  display: flex; flex-wrap: wrap; gap: clamp(24px, 5vw, 64px);
  align-items: flex-end; padding: clamp(32px, 5vw, 64px) 0 clamp(24px, 3vw, 40px);
}
/* 999 to 1 against .page-head__aside: while the two share a line the text
   takes all the spare room and the aside stays at its 300px, and once the
   aside wraps under the text it is alone on its line and spreads across it.
   The other pages' right-hand boxes do not grow at all, so for them this is
   no change. */
.page-head__text { flex: 999 1 400px; min-width: 0; }
.page-head--start { align-items: flex-start; }
/* The menu page's right-hand column: the cutoff box, then the weekly email
   sign-up. Stacked while it is a 300px column beside the headline; side by
   side once it has wrapped underneath and has the width (a tablet), and
   stacked again on a phone. */
.page-head__aside {
  flex: 1 1 300px; min-width: 0;
  display: grid; gap: 16px; align-content: start;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
}

/* The menu page's head, tightened 2026-09-12 at the client's request: she
   wanted the ordering-cutoff box, the weekly-email box and "This week's
   specials" all further up the page.

   The thing to understand before changing any of this is that the ASIDE is the
   taller of the two columns — the headline and the opening paragraph run out
   well above the bottom of the two boxes — so the height of this whole section,
   and therefore how far down the page the specials begin, is decided by the
   boxes. Everything here takes space out of them: less room above and below the
   section, less between the boxes, less inside each one, and a line height that
   is still comfortable at 15px but no longer luxurious. Together that is about
   80px; shortening the sign-up note itself was worth another 90. */
.page-head--tight {
  padding-top: clamp(20px, 3vw, 36px);
  padding-bottom: clamp(16px, 2vw, 28px);
}
.page-head--tight .page-head__aside { gap: 12px; }
.page-head--tight .note-box,
.page-head--tight .signup-box { padding: 18px 20px; }
.page-head--tight .note-box .kicker,
.page-head--tight .signup-box > h2.kicker { margin-bottom: 8px; }
.page-head--tight .note-box p,
.page-head--tight .signup-box__note { line-height: 24px; }
.page-head--tight .signup-box__text { margin-bottom: 12px; }

/* ------------------------------------------------ weekly email sign-up --- */

/* The box on the menu page. Apricot, like the shop card on the home page, so
   it reads as an invitation rather than as one more notice. */
.signup-box {
  padding: 22px 24px;
  background: var(--color-accent-2-100);
  border: 1px solid var(--color-accent-2-200);
}
/* A real heading for screen readers, dressed as the kicker it sits beside —
   design-system.css gives every h2 the display face. */
.signup-box > h2.kicker {
  font-family: var(--font-body); font-weight: 400;
  line-height: normal; margin-bottom: 10px;
  color: var(--color-accent-2-800);
}
.signup-box__text { margin-bottom: 14px; }
.signup-box__note {
  margin: 0; font-size: 15px; line-height: 27px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.signup-box__note + .signup-box__note { margin-top: 10px; }

/* The form itself, shared by the box above and by any contact-page answer
   with {signup form} in it. The address box and the button share a line when
   there is room and the button drops underneath, full width, when there is
   not — 999 to 1 means the box takes all the spare room on a shared line, and
   a button alone on its own line takes all of it. */
.signup-form { display: grid; gap: 8px; }
.signup-form__row { display: flex; flex-wrap: wrap; gap: 8px; }
.signup-form__row .input {
  flex: 999 1 190px; min-width: 0; min-height: 40px;
  border-color: var(--color-border-strong); background: var(--color-bg);
}
.signup-form__row .btn { flex: 1 0 auto; min-height: 40px; }
.faq .signup-form { margin: 0 0 22px; max-width: 460px; }
/* Inside an answer, ".faq p" would otherwise dress the form's own status line
   (and its hidden honeypot) as answer paragraphs. */
.faq .signup-form p { margin: 0; font-size: 15px; line-height: 26px; color: var(--color-accent-2-800); }
.faq .signup-form p.form-status--error { color: var(--color-accent-700); }
/* The thank-you that replaces the form once it has gone. */
.faq > .form-status { margin: -4px 0 22px; color: var(--color-accent-2-800); }

.note-box {
  border: 1px solid var(--color-divider); padding: 22px 24px;
}
.note-box .kicker { margin-bottom: 10px; }
.note-box p {
  margin: 0; font-size: 15px; line-height: 27px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}

.stack { padding-bottom: clamp(32px, 4vw, 56px); }
.stack > h2 { margin-bottom: 8px; }
.stack__note { margin: 0 0 26px; }

.special h3 {
  /* 24px, the same as the home page's cards (.feature h3) - the client asked
     for the menu's names to match (2026-10-12). Was 23px. */
  font-family: var(--font-heading); font-weight: 600; font-size: 24px;
  line-height: 1.2; margin: 0; letter-spacing: -0.01em;
}
.special__row { display: flex; gap: 12px; align-items: baseline; justify-content: space-between; }
.special__price {
  font-size: 15px; color: var(--color-accent-700);
  white-space: nowrap; font-feature-settings: 'tnum';
}
.special__body {
  margin: 6px 0 0; font-size: 15px; line-height: 27px;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}

.pricelist {
  /* 460px keeps this to two columns at the site's measure. The name row below
     relies on that: "Zucchini Bread Mini Loaf" plus its leader and price needs
     ~400px on one line, and .pricelist h3 is deliberately nowrap above 720px. */
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(460px, 100%), 1fr));
  gap: 0 clamp(36px, 6vw, 80px);
}
.pricelist article { padding: 18px 0; border-bottom: 1px solid var(--color-divider); }
.pricelist h3 {
  font-family: var(--font-heading); font-weight: 600; font-size: 22px;
  line-height: 1.2; margin: 0; white-space: nowrap; letter-spacing: -0.01em;
}
.pricelist__row { display: flex; align-items: baseline; gap: 10px; }
.pricelist__leader {
  /* Leader dots want to be readable, not decorative — the hairline divider
     tone disappears entirely on the paper-white ground. */
  flex: 1 1 auto; min-width: 12px;
  border-bottom: 1px dotted color-mix(in srgb, var(--color-text) 30%, transparent);
  transform: translateY(-5px);
}
.pricelist__body {
  margin: 6px 0 0; font-size: 15px; line-height: 27px; font-style: italic;
  color: color-mix(in srgb, var(--color-text) 76%, transparent);
}

/* Each item carries a small square photo, set beside the description rather
   than beside the whole item: the name / leader / price row keeps the full
   column width it was designed for, so nothing is pushed off the end. The
   plate is a fixed width, not a fraction, so a list mixing filled and
   still-empty slots keeps one straight edge down the left. */
.pricelist__detail {
  display: grid; grid-template-columns: var(--thumb, 110px) minmax(0, 1fr);
  gap: 16px; align-items: start;
}
.pricelist__plate { margin: 6px 0 0; }         /* matches .pricelist__body */
.pricelist__detail .pricelist__body { min-width: 0; }
.pricelist__text { min-width: 0; }
/* The placeholder's caption cannot fit at 110px and does not need to — the
   item's own name sits directly above it. Keep the hatching and the icon. */
.pricelist__plate .frame__hint { padding: 8px; gap: 0; font-size: 0; }

.closer {
  border-top: 1px solid var(--color-divider);
  padding: clamp(32px, 4vw, 60px) 0; text-align: center;
}
.closer h2 { margin: 0 0 14px; }
.closer p {
  margin: 0 auto 26px; font-size: 16px; line-height: 30px; max-width: 52ch;
  color: color-mix(in srgb, var(--color-text) 78%, transparent);
}

/* -------------------------------------------------------------- album ---- */

.filters {
  display: flex; flex-wrap: wrap; gap: 10px 12px;
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  padding: 16px 0;
}
.filter {
  background: none; color: var(--color-text);
  border: 1px solid var(--color-border-strong); border-radius: 999px;
  padding: 9px 20px;
  font-family: var(--font-body); font-size: 13px;
  letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer;
}
.filter:hover { border-color: var(--color-accent); }
.filter[aria-pressed="true"] {
  background: var(--color-accent-200);
  border-color: var(--color-accent);
  color: var(--color-accent-800);
}
/* Without scripting the buttons cannot filter anything, so they are hidden
   rather than left as dead controls; every photo is in the DOM already. */
.no-js .filters { display: none; }

/* A grid, not CSS columns.
   Columns pack top-to-bottom and only then move right, so the order the client
   dragged her photos into came out reading down the left-hand column first —
   which is not how anyone reads a gallery, and not the order she arranged. A
   grid fills left to right, row by row. The rows are ragged because the photos
   have different shapes; `align-items: start` keeps each one at the top of its
   row rather than stretching it. */
.album-grid {
  display: grid; gap: clamp(16px, 2vw, 26px);
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  align-items: start;
}
.album-grid figure { margin: 0; }
.album-grid figcaption {
  display: flex; gap: 12px; justify-content: space-between; align-items: baseline;
  padding-top: 10px; margin-top: 0; font-size: 15px; line-height: 24px;
  color: var(--color-caption);
}
.album-grid figcaption b {
  font-weight: 400; font-size: 11px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--color-accent-700); white-space: nowrap;
}

/* The column beside the album headline. It was empty space with a button
   floating in it; now it carries a photo, with the button under it. */
.album-head__media { flex: 0 1 380px; min-width: min(280px, 100%); }
.album-head__media .plate { margin: 0 0 18px; }
.album-empty { margin: 0; padding: 28px 0; color: var(--color-caption); }

.album-cta {
  border-top: 1px solid var(--color-divider);
  padding: clamp(32px, 4vw, 60px) 0;
  display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 56px);
  align-items: center; justify-content: space-between;
}
.album-cta > div:first-child { flex: 1 1 380px; }
.album-cta h2 { margin: 0 0 14px; }
.album-cta p { max-width: 48ch; }

/* ------------------------------------------------------------ contact ---- */

.contact-head {
  display: flex; flex-wrap: wrap; gap: clamp(28px, 5vw, 68px);
  padding: clamp(32px, 5vw, 68px) 0 clamp(28px, 4vw, 48px);
  align-items: flex-start;
}
.contact-head__text { flex: 1 1 420px; min-width: 0; }
.contact-head__text .lede { max-width: 48ch; margin-bottom: 28px; }

.contact-facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  gap: 20px 32px; border-top: 1px solid var(--color-divider); padding-top: 24px;
}
.contact-facts p:last-child,
.contact-facts address { margin: 0; font-size: 16px; line-height: 30px; font-style: normal; }

/* An email address is one unbreakable token; in a 200px grid track it would
   otherwise push the page sideways. */
a[href^="mailto:"] { overflow-wrap: anywhere; }

/* Lora's parentheses descend well below the baseline and straight through a
   3px underline, so skip-ink carves a gap around the opening "(" — and the
   sliver of underline left to its left reads as a stray period in front of
   the area code. It is not a character, so it cannot be selected or deleted;
   the only fix is to stop the underline breaking. Scoped to tel: links so
   the email beside it keeps skipping its descenders, where it looks right. */
a[href^="tel:"] { text-decoration-skip-ink: none; }

.order-card {
  flex: 1 1 380px; min-width: 0; max-width: 520px;
  border: 1px solid var(--color-divider);
  padding: clamp(22px, 3vw, 36px);
  background: var(--color-surface);
}
.order-card h2 {
  font-family: var(--font-heading); font-weight: 400;
  font-size: clamp(24px, 2.6vw, 32px); line-height: 1.1; margin: 0 0 6px;
}
.order-card__note {
  margin: 0 0 24px; font-size: 15px; line-height: 26px;
  color: color-mix(in srgb, var(--color-text) 74%, transparent);
}
.order-form { display: grid; gap: 18px; }
.order-form__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); gap: 18px; }
.order-form .input { border-color: var(--color-border-strong); }
.order-form select.input { appearance: none; padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
.order-form .required { color: var(--color-accent); }
.form-status {
  margin: 0; font-size: 15px; line-height: 26px; color: var(--color-accent-2-800);
}
.form-error { margin: 0; font-size: 14px; line-height: 24px; color: var(--color-accent-700); }

.finding {
  padding-bottom: clamp(36px, 5vw, 72px);
  display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 56px); align-items: center;
}
.finding__text { flex: 1 1 340px; min-width: 0; }
.finding__text h2 { margin: 0 0 14px; }
.finding__text p { max-width: 42ch; margin-bottom: 20px; }
.finding .plate { flex: 1 1 380px; max-width: 620px; }

/* The drawn map. Deliberately NOT a .plate: that class carries the sepia
   warm-up that every photograph on the site gets, and a flat-colour diagram
   put through it just looks dirty. The border matches the plate's mat so the
   two still read as the same family. */
.findingmap {
  flex: 1 1 380px; max-width: 620px; min-width: 0;
  padding: 6px; background: var(--color-surface); outline: 1px solid var(--color-divider);
}
.findingmap__svg { display: block; width: 100%; height: auto; }
/* Sized in viewBox units, so these scale with the drawing: the map is between
   about 360 and 620px wide in practice, which puts the road labels between
   roughly 8.6px and 14.8px on the page. */
.findingmap__svg text {
  font-family: var(--font-body);
  fill: var(--color-text);
  text-anchor: middle;
  dominant-baseline: middle;
}
.findingmap__road { font-size: 11px; fill: #6b625a; letter-spacing: 0.02em; }
.findingmap__place { font-size: 12px; fill: #574f45; }
.findingmap__cue { font-size: 10.5px; fill: #7a7167; }
.findingmap__us { font-size: 13px; font-weight: 600; fill: var(--color-accent); }

.faq-section {
  border-top: 1px solid var(--color-divider);
  padding: clamp(32px, 4vw, 56px) 0;
  display: flex; flex-wrap: wrap; gap: clamp(24px, 5vw, 72px); align-items: flex-start;
}
.faq-section__intro { flex: 1 1 280px; max-width: 330px; }
.faq-section__intro h2 { margin: 0 0 12px; }
.faq-list { flex: 2 1 400px; min-width: 0; border-bottom: 1px solid var(--color-divider); }

.faq { border-top: 1px solid var(--color-divider); }
.faq > summary {
  list-style: none; cursor: pointer;
  padding: 20px 0; display: flex; gap: 20px;
  justify-content: space-between; align-items: baseline;
  font-family: var(--font-body); font-size: 17px; line-height: 27px;
  font-weight: 600; color: var(--color-text);
}
.faq > summary::-webkit-details-marker { display: none; }
.faq > summary:hover { color: var(--color-accent-700); }
.faq > summary:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.faq__sign {
  color: var(--color-accent-2-800); font-size: 20px; line-height: 20px; flex: none;
}
.faq__sign::after { content: "+"; }
.faq[open] .faq__sign::after { content: "\2013"; }
.faq p {
  margin: -4px 0 22px; font-size: 16px; line-height: 30px; max-width: 64ch;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}

/* -------------------------------------------------------------- order ---- */

/* Fieldsets are here for the grouping a screen reader announces, not for the
   browser's default box. */
.orderform fieldset { border: 0; margin: 0; padding: 0; min-width: 0; }
.orderform legend { padding: 0; margin-bottom: 6px; }
.orderform { gap: 26px; }

.how-steps {
  margin: 0; padding-left: 1.1em; font-size: 15px; line-height: 26px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.how-steps li { margin-bottom: 8px; }
.how-steps li:last-child { margin-bottom: 0; }

.note-box--warn { border-color: var(--color-accent); background: var(--color-accent-200); }
.note-box--warn p { margin: 0; }

.field-note {
  margin: -14px 0 0; font-size: 13px; line-height: 22px; color: var(--color-caption);
}

.orderitems__group { margin: 22px 0 10px; }
.orderitems__group:first-of-type { margin-top: 10px; }

.orderitems__list { list-style: none; margin: 0; padding: 0; }

.orderitem {
  display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: flex-start;
  padding: 16px 0; border-top: 1px solid var(--color-divider);
}
.orderitem:last-child { border-bottom: 1px solid var(--color-divider); }
.orderitem__text { flex: 1 1 260px; min-width: 0; }
.orderitem__title { margin: 0 0 4px; font-size: 19px; line-height: 1.2; }
.orderitem__body {
  margin: 0; font-size: 14px; line-height: 24px; max-width: 56ch;
  color: var(--color-caption);
}

/* The buy column is a fixed width so the dropdowns line up down the page
   however long the names above them are. Two rows inside it: the each-price and
   the running line total face each other, and the dropdown spans both columns
   underneath — it has to be wide, because its options carry their own prices
   ("6 cookies for $17"), and a control that wide does not belong on the same
   line as anything else. */
.orderitem__buy {
  flex: 0 0 auto; margin-left: auto;
  width: 236px; max-width: 100%;
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px 12px; align-items: baseline;
}
.orderitem__price {
  margin: 0; min-width: 0;
  font-family: var(--font-heading); font-size: 17px; line-height: 1.2;
  color: var(--color-accent-2-800); white-space: nowrap;
}
.orderitem__line {
  margin: 0; min-width: 0; text-align: right; font-size: 15px; line-height: 1.2;
  font-family: var(--font-heading); white-space: nowrap;
  color: var(--color-text);
}
.qty__select { grid-column: 1 / -1; width: 100%; min-height: 40px; text-overflow: ellipsis; }

/* The item's photo, between the words and the price. The text column stops
   growing at its measure, so the slack that used to open up in the middle of
   a wide row lands on this instead and the auto margins centre the picture in
   it. An item with no photo emits no .orderitem__plate at all, and :has()
   hands the slack back to the buy column so that row looks exactly as it did
   before. */
.orderitem__text { max-width: 58ch; }
.orderitem__plate { flex: 0 0 auto; margin: 0 auto; width: 150px; max-width: 100%; }
.orderitem:has(.orderitem__plate) .orderitem__buy { margin-left: 0; }
.orderitem__body--detail { font-size: 13px; line-height: 22px; }

/* The plus/minus counter, for a bake that is simply counted rather than sold
   in sizes. Full size for the item, small for its upgrade - the same three
   controls either way. 44px is the touch target it has to clear: most of
   these orders are placed one-handed, on a phone, in a kitchen. */
.stepper {
  grid-column: 1 / -1;
  display: flex; align-items: stretch;
  width: 100%; max-width: 100%;
  border: 1px solid var(--color-border-strong);
  background: var(--color-surface);
}
.stepper__btn {
  flex: 0 0 44px;
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0; border: 0; background: none;
  font-family: var(--font-heading); font-size: 20px; line-height: 1;
  color: var(--color-accent-2-800); cursor: pointer;
}
.stepper__btn:hover { background: color-mix(in srgb, var(--gold) 16%, transparent); }
.stepper__btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.stepper__count {
  flex: 1 1 auto; min-width: 0; width: 100%;
  border: 0;
  border-left: 1px solid var(--color-divider);
  border-right: 1px solid var(--color-divider);
  background: none; text-align: center;
  font-family: var(--font-heading); font-size: 17px; line-height: 1;
  color: var(--color-text);
  -moz-appearance: textfield; appearance: textfield;
}
/* The native spinners are a second, tinier set of the same two buttons. */
.stepper__count::-webkit-outer-spin-button,
.stepper__count::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.stepper__count:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.stepper--sm { max-width: 148px; margin-left: auto; }
.stepper--sm .stepper__btn { flex-basis: 38px; min-height: 38px; font-size: 17px; }
.stepper--sm .stepper__count { font-size: 15px; }

/* The upgrade row. Hidden until the item above it has a quantity - there is
   nothing to put a glaze on until then - which is why the [hidden] rule is
   written out: `display: flex` would otherwise win over it. */
.upgrade {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  padding-top: 10px; border-top: 1px dashed var(--color-divider);
}
.upgrade[hidden] { display: none; }
.upgrade__name {
  flex: 1 1 110px; margin: 0;
  font-size: 14px; line-height: 20px; color: var(--color-text);
}
.upgrade__price { display: block; font-size: 13px; color: var(--color-caption); }
/* Revealed when "More than N — ask us" is chosen. Nothing goes in the basket;
   this is the way out of the checkout, not a step in it. */
.orderitem__more {
  grid-column: 1 / -1; margin: -2px 0 0;
  font-size: 13px; line-height: 20px; color: var(--color-caption);
}
.orderitem[data-active] { background: color-mix(in srgb, var(--gold) 9%, transparent); }
.orderitem[data-active] .orderitem__title { color: var(--color-accent-800); }

/* A bake's name doubles as the control that reveals its ingredients - on the
   order page, the menu page and the home page alike (_includes/ingredients.njk)
   - so it has to read as a heading and behave as a button. Everything below
   undoes the button defaults; size and weight come from the heading around it.

   The arrow is the client's request of 2026-10-01: back, and "bigger than
   before, so it looks like an arrow and not a period". The old one was an 11px
   ▾ in the caption grey. This one is a chevron in a small round button that
   scales with the heading it sits in, never smaller than 22px, in the accent
   colour, and turns over when the ingredients are open. */
.itemname {
  display: inline; margin: 0; padding: 0; border: 0; background: none;
  font: inherit; color: inherit; letter-spacing: inherit; line-height: inherit;
  text-align: left; cursor: pointer;
}
.itemname__last { white-space: nowrap; }
.itemname__arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.05em; height: 1.05em; min-width: 22px; min-height: 22px;
  margin-left: 0.32em; vertical-align: -0.16em;
  border-radius: 50%;
  color: var(--color-accent-700);
  background: color-mix(in srgb, var(--color-accent) 11%, transparent);
  transition: transform 160ms ease, background-color 160ms ease;
}
.itemname__arrow svg { display: block; width: 74%; height: 74%; }
.itemname[aria-expanded="true"] .itemname__arrow { transform: rotate(180deg); }
.itemname:hover { color: var(--color-accent-700); }
.itemname:hover .itemname__arrow { background: color-mix(in srgb, var(--color-accent) 22%, transparent); }
.itemname:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }

/* Ingredient lists, required on anything sold online. Hidden behind the item's
   name rather than sitting under every description, and set off by a rule so
   it is obvious which item just opened. */
.ingredients {
  margin-top: 10px; max-width: 60ch;
  padding-left: 12px; border-left: 2px solid var(--color-divider);
}
.ingredients__label {
  margin: 0 0 4px;
  font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--color-caption);
}
.ingredients > p { margin: 0; font-size: 13px; line-height: 22px; color: var(--color-caption); }
.ingredients > .ingredients__missing { color: var(--color-accent-700); }

/* The weekly-menu opt-in. Deliberately not styled to look pre-selected.
   Written as `.field > label.check` because design-system.css lays every
   `.field > label` out as a block caption above its input, and this one is a
   row with the control inside it. */
.field > label.check {
  display: flex; align-items: flex-start; gap: 10px; margin-bottom: 0;
  font-size: 15px; line-height: 24px; color: var(--color-text); cursor: pointer;
}
.check__box {
  flex: 0 0 auto; width: 18px; height: 18px; margin: 3px 0 0;
  accent-color: var(--color-accent); cursor: pointer;
}
.check__box:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.check__note {
  margin: 6px 0 0 28px; font-size: 13px; line-height: 22px; color: var(--color-caption);
}

/* The weekly-email tool. The preview is a sandboxed iframe so the email is
   shown on its own terms rather than wearing this site's stylesheet. */
.emailtool__subject {
  margin: 0 0 18px; padding: 12px 16px;
  border: 1px solid var(--color-border-strong); background: var(--color-surface);
  font-family: var(--font-heading); font-size: 18px; line-height: 26px;
}
.emailtool__preview {
  display: block; width: 100%; height: 900px;
  border: 1px solid var(--color-divider); background: #fdfcfa;
}

/* Shown in place of the order form on a weekend with no pickup. */
/* The closing countdown, above the pickup dropdowns.
   Quiet while the deadline is still a couple of hours out. The grace version —
   shown only to someone who already had something in the basket when the
   cutoff passed — is the one that has to be noticed, so it borrows the
   oxblood the rest of the site keeps for things that matter. */
.orderclock {
  margin: 0 0 22px; padding: 12px 16px;
  border: 1px solid var(--color-accent-2);
  background: var(--color-accent-2-100);
  color: var(--color-accent-2-800);
  font-size: 15px; line-height: 24px;
}
.orderclock--grace {
  border-color: var(--color-accent);
  background: var(--color-accent-200);
  color: var(--color-accent-800);
  font-weight: 600;
}

.orderclosed { margin-bottom: clamp(32px, 4vw, 56px); }
.orderclosed [data-closed-note] { margin-top: 12px; }
.orderclosed [data-closed-note] p + p { margin-top: 12px; }
.orderclosed__links a { white-space: nowrap; }

.foodact {
  margin-top: 4px; padding: 16px 18px;
  border: 1px solid var(--color-divider); background: var(--color-surface);
}
.foodact .kicker { margin-bottom: 8px; }
/* No max-width: the box runs the full width of the form, and the client asked
   for the writing to run with it rather than stopping halfway across. */
.foodact__statement {
  margin: 0 0 8px; font-size: 14px; line-height: 24px;
}
.foodact__producer {
  margin: 0; font-size: 13px; line-height: 22px; color: var(--color-caption);
}

.ordertotal {
  border-top: 2px solid var(--color-text); padding-top: 14px;
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
.ordertotal__row {
  display: flex; align-items: baseline; gap: 18px; margin: 0;
  font-family: var(--font-heading); font-size: clamp(22px, 2.4vw, 28px); line-height: 1.1;
}
.ordertotal__row > span:first-child { color: var(--color-caption); font-size: 0.7em; }
.ordertotal__note { margin: 0; font-size: 13px; line-height: 22px; color: var(--color-caption); }
/* Subtotal and the tax line above the Total (2026-10-12, tax on top): the
   same right-aligned pair, a size down, so the Total is still the figure the
   eye lands on. Tabular figures keep the three amounts' digits in columns. */
.ordertotal__row--part { font-size: clamp(16px, 1.6vw, 19px); color: var(--color-text); }
.ordertotal__row--part > span:first-child { font-size: 0.85em; }
.ordertotal__row > span:last-child { font-feature-settings: 'tnum'; }

/* btn-block is right inside the narrow contact card, but stretched across the
   full measure it reads as a bar rather than a button. Cap it and let it sit
   under the total it follows. */
.orderform > [data-order-submit] { max-width: 340px; margin-left: auto; }
.orderform > .form-status { max-width: 46ch; margin-left: auto; text-align: right; }

.form-status:empty { display: none; }
.form-status--error { color: var(--color-accent-700); }

/* Honeypot: a field a person never sees and a bot fills in. Kept out of the
   accessibility tree and out of the tab order rather than display:none, which
   some bots check for. */
.gotcha {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.customorder {
  display: flex; flex-wrap: wrap; gap: clamp(24px, 4vw, 56px);
  align-items: flex-start; padding-top: clamp(20px, 3vw, 36px);
  border-top: 1px solid var(--color-divider);
}
.customorder__intro { flex: 1 1 320px; min-width: 0; }
.customorder__intro h2 { margin: 0 0 14px; }
.customorder__intro .prose { max-width: 46ch; }
.customorder .order-card { flex: 1 1 400px; }

/* The reference is a footnote on a normal confirmation, and the single most
   important thing on the page when the order has to be recovered by phone. */
.thanks-ref { margin: 0 0 18px; font-size: 15px; line-height: 26px; color: var(--color-caption); }
.thanks-ref--loud {
  /* Needs to read as its own thing, not the tail of the paragraph above it -
     this is the number the customer will be asked for on the phone. */
  margin-top: 20px; padding: 10px 14px; display: inline-block;
  font-family: var(--font-heading); font-size: 20px; line-height: 1.3;
  color: var(--color-accent-800); letter-spacing: 0.01em;
  background: var(--color-surface); border: 1px solid var(--color-divider);
}
.thanks-call { margin: 4px 0 22px; }
/* The one filled button on the site. Everything else is outlined, which is
   right when the choices are equal - here they are not, and this is the only
   action that recovers a paid order. White on oxblood is 8.2:1. */
.thanks-call .btn {
  background: var(--color-accent); border-color: var(--color-accent);
  color: #fff; font-size: 16px; padding: 12px 22px;
}
.thanks-call .btn:hover { background: var(--color-accent-800); border-color: var(--color-accent-800); }
/* With a filled call-to-action above them, the wayfinding links below should
   step back rather than compete. */
.thanks--unfiled .btn-row .btn-primary { color: var(--color-text); border-color: var(--color-border-strong); }

/* ----------------------------------------------------------- policies ---- */

.policies {
  max-width: 68ch; padding-bottom: clamp(36px, 5vw, 72px);
}
.policy { padding: clamp(20px, 3vw, 30px) 0; border-top: 1px solid var(--color-divider); }
.policy:first-child { border-top: 0; padding-top: 0; }
.policy h2 { margin: 0 0 14px; scroll-margin-top: 24px; }
.policy__body p {
  margin: 0 0 16px; font-size: 16px; line-height: 30px;
  color: color-mix(in srgb, var(--color-text) 80%, transparent);
}
.policy__body p:last-child { margin-bottom: 0; }
.policy__updated {
  margin: 8px 0 0; padding-top: 20px; border-top: 1px solid var(--color-divider);
  font-size: 13px; line-height: 22px; color: var(--color-caption);
}

/* --------------------------------------------------------- 404 / misc ---- */

.centered-page {
  min-height: 46vh; display: flex; flex-direction: column;
  justify-content: center; align-items: flex-start;
  padding: clamp(48px, 8vw, 96px) 0;
}

/* -------------------------------------------------------- responsive ----- */

@media (max-width: 720px) {
  .brand img { height: 48px; }
  /* The client asked for the phrases centred with a star either side on a
     phone. One phrase per row, so "a star either side" is what it reads as;
     the wide row is untouched above 720px. */
  .marquee { flex-direction: column; gap: 14px; }
  .marquee__item { justify-content: center; gap: 14px; }
  .marquee__starslot { display: block; }
  .orderitem__buy { margin-left: 0; width: 100%; }
  .orderitem:has(.orderitem__plate) .orderitem__buy { margin-left: 0; }
  .orderitem__text { max-width: none; }
  .orderitem__plate { margin: 0; width: 84px; }
  .orderform > [data-order-submit],
  .orderform > .form-status { max-width: none; }
  .orderform > .form-status { text-align: left; }
  .site-nav { gap: 10px 18px; font-size: 12px; width: 100%; }
  .site-header__inner { gap: 12px 20px; }
  .pricelist h3 { white-space: normal; }
  .site-footer__inner { justify-content: flex-start; }
}

@media (max-width: 480px) {
  .album-grid { grid-template-columns: 1fr; }
  .pricelist__detail { --thumb: 84px; gap: 14px; }
  .btn-row .btn { flex: 1 1 auto; }
}

/* --------------------------------------------------------------- print --- */

@media print {
  :root { --color-bg: #fff; --color-surface: #fff; }
  body { font-size: 12px; }
  .site-header, .site-footer, .filters, .btn-row, .closer, .album-cta,
  .order-card, .orderform, .customorder, .skip-link, .link-more,
  .signup-box, .signup-form { display: none !important; }
  .frame__hint { display: none; }
  .plate { border: 0; outline: 0; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 10px; }
  .album-grid { grid-template-columns: 1fr 1fr; }
}

/* ------------------------------------------------------ reduced motion --- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ------------------------------------------------------- 2026-09-14 --- */

/* Which part of a photo survives the crop. The album's "Keep the…" box in
   the CMS sets --focus on the frame; the default is the middle, which is
   what every photo did before the setting existed. */
.frame > img { object-position: var(--focus, 50% 50%); }

/* Bold inside a description — **like this** in the CMS. The descriptions
   are set in the body face at a weight the site already loads. */
.special__body strong, .pricelist__body strong, .orderitem__body strong, .feature p strong { font-weight: 600; color: var(--color-text); }

/* The neighbourhood map on the contact page: Google's embed, in the frame
   the drawn map used to have, so the page keeps its shape. */
.areamap {
  flex: 1 1 380px; max-width: 620px; min-width: 0;
  padding: 6px; background: var(--color-surface); outline: 1px solid var(--color-divider);
}
.areamap { position: relative; }
.areamap iframe { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
/* "Around here": a soft oxblood circle over the middle of the map, which is
   centred on site.mapPin. pointer-events: none so the map still pans. */
/* Sized between 150 and 200px rather than as a bare percentage: the map's
   scale is fixed, so a circle that shrank with the screen also shrank the
   area it marks, and on a phone it stopped reaching the house (2026-10-01). */
.areamap__circle {
  position: absolute; left: 50%; top: 50%; width: clamp(150px, 38%, 200px); aspect-ratio: 1;
  transform: translate(-50%, -50%); pointer-events: none; border-radius: 50%;
  background: rgba(140, 47, 42, 0.16); border: 2.5px solid rgba(140, 47, 42, 0.55);
  box-shadow: 0 0 0 6px rgba(140, 47, 42, 0.08);
}
/* The private orders page. */
.orders-login { max-width: 460px; margin: 0 auto clamp(36px, 5vw, 72px); }
.orders { padding-bottom: clamp(36px, 5vw, 72px); }
.orders__bar {
  display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: center; justify-content: space-between;
  padding: 14px 0; border-top: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider);
}
.orders__nav, .orders__tools { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.orders__range { margin: 0 6px; font-weight: 600; font-size: 17px; }
.orders__summary { margin: 16px 0 4px; font-size: 15px; color: var(--color-caption); }
.orders__day { padding: 20px 0 8px; }
.orders__day .section-title { margin-bottom: 4px; }
.orders__list { display: grid; gap: 14px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); margin-top: 14px; }
.orders__foot { margin-top: 28px; color: var(--color-caption); }
.ordercard {
  display: flex; flex-direction: column; gap: 6px;
  padding: 16px 18px; background: var(--color-surface); outline: 1px solid var(--color-divider);
  border-left: 4px solid var(--color-accent);
}
.ordercard--ready { border-left-color: #6b8f5e; background: color-mix(in srgb, #6b8f5e 7%, var(--color-surface)); }
.ordercard__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
.ordercard__time { margin: 0; font-size: 26px; font-weight: 600; line-height: 1.1; color: var(--color-accent); }
.ordercard--ready .ordercard__time { color: #4e6f43; }
.ordercard__name { margin: 0; font-size: 20px; line-height: 1.2; flex: 1 1 auto; }
.ordercard__ref { margin: 0; flex-basis: 100%; font-size: 12px; letter-spacing: 0.06em; color: var(--color-caption); }
.ordercard__items { margin: 4px 0 0; padding-left: 20px; font-size: 16px; line-height: 26px; }
.ordercard__total { margin: 0; font-weight: 600; }
.ordercard__contact, .ordercard__pref { margin: 0; font-size: 14px; line-height: 22px; color: var(--color-caption); overflow-wrap: anywhere; }
.ordercard__notes { margin: 4px 0 0; padding: 8px 10px; background: #fff8e8; border-left: 3px solid #d9b45c; font-size: 15px; line-height: 23px; }
.ordercard__warn { margin: 4px 0 0; padding: 8px 10px; background: #fbeaea; border-left: 3px solid var(--color-accent); font-size: 14px; line-height: 21px; }
.ordercard__tick { display: flex; align-items: center; gap: 10px; margin-top: 8px; font-size: 17px; font-weight: 600; cursor: pointer; }
.ordercard__tick .check__box { width: 24px; height: 24px; }
.ordercard__state { margin: 0; font-size: 14px; color: #4e6f43; min-height: 0; }
.ordercard__actions { display: flex; flex-wrap: wrap; gap: 8px; }
.ordercard__actions:empty { display: none; }
.ordercard .form-status:empty { display: none; }

@media print {
  .orders__bar, .ordercard__actions, .ordercard__tick, .orders__foot, .form-status { display: none !important; }
  .orders__list { grid-template-columns: 1fr 1fr; gap: 8px; }
  .ordercard { break-inside: avoid; outline: 1px solid #999; }
}

/* Text-or-email on the order form, and the preview banner. */
.notify { border: 0; padding: 0; margin: 0 0 18px; min-width: 0; }
.notify__legend { padding: 0; margin-bottom: 8px; font-size: 15px; line-height: 24px; color: var(--color-text); }
.notify__options { display: flex; flex-wrap: wrap; gap: 8px 22px; }
.notify__option {
  display: flex; align-items: center; gap: 10px;
  font-size: 15px; line-height: 24px; color: var(--color-text); cursor: pointer;
}
.notify__option .check__box { margin: 0; }
.notify .check__note { margin: 8px 0 0; }
.previewbar { margin-bottom: clamp(20px, 3vw, 32px); }

/* ------------------------------------------------------- 2026-10-01 --- */

/* A bake's photo on the home and menu pages goes to that bake on the order
   page. The lift on hover and the "Order this" tab say so; on a phone, where
   there is no hover, the tab simply stays in view, because that is where most
   of these orders are placed and a photo that is secretly a button is a photo
   nobody presses. */
.platelink { display: block; position: relative; color: inherit; text-decoration: none; }
.platelink > .plate { transition: transform 160ms ease, box-shadow 160ms ease; }
.platelink:hover > .plate,
.platelink:focus-visible > .plate { transform: translateY(-2px); box-shadow: 0 8px 18px rgba(33, 28, 23, 0.14); }
.platelink:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; }
.platelink__cue {
  position: absolute; left: 14px; bottom: 14px; z-index: 2;
  padding: 7px 13px 6px; border-radius: 999px;
  background: var(--color-accent); color: #fff;
  font-size: 11px; line-height: 1; letter-spacing: 0.14em; text-transform: uppercase;
  opacity: 0; transform: translateY(4px);
  transition: opacity 160ms ease, transform 160ms ease;
  pointer-events: none;
}
.platelink__cue::after { content: " \203A"; }
.platelink:hover .platelink__cue,
.platelink:focus-visible .platelink__cue { opacity: 1; transform: none; }
@media (hover: none) {
  .platelink__cue { opacity: 1; transform: none; }
}

/* Where one of those links lands: the bake's row, picked out for a moment so
   it is obvious which one was meant. */
.orderitem { scroll-margin-top: 16px; }
.orderitem:target { background: color-mix(in srgb, var(--gold) 16%, transparent); }

/* "Photo coming soon" is artwork rather than a photograph of food, so it does
   not get the warm grade every photo goes through. */
.plate:has(.frame--soon) { filter: none; }

/* The ingredients panel inside the home page's cards and the menu's lists. */
.feature .ingredients, .pricelist__text .ingredients { margin-top: 12px; }
.feature__title { margin: 0 0 6px; }

/* The price beside a special's name.
   2026-10-12: "$3.25 each" was breaking onto two lines ("$3.25" / "each")
   next to "Green Chile Chocolate Chip", because the 2026-10-01 rule below let
   the price shrink as readily as the name. Now the price keeps the width it
   needs (flex-shrink: 0) and the NAME gives way, wrapping under itself - a
   name reads fine on two lines, a price split in half does not. Only a price
   wider than half the card wraps, so a long one like "$3 each - buy more,
   save more!" still cannot squeeze the name into a column one word wide, the
   thing the 2026-10-01 rule was for. At three cards across, the name alone is
   wider than the card minus the price, so on a laptop "Green Chile Chocolate
   Chip" takes two lines; on a phone or tablet it all fits on one. */
.special__price { flex: 0 0 auto; max-width: 50%; white-space: normal; text-align: right; }

/* /email-preview.html: what customers receive. Each email sits in the same
   sandboxed frame the weekly-email tool uses, grown to the email's height by
   js/site.js so there is one scroll bar rather than two. */
.emailpreview__note { max-width: 70ch; }
.emailpreview__note p + p, .emailpreview__note p + ul { margin-top: 10px; }
.emailpreview__note ul { margin: 6px 0 0; padding-left: 20px; }
.emailpreview__note li { margin-bottom: 4px; }
.emailpreview .emailtool__preview { height: 640px; }
.emailpreview__smslabel { margin: 28px 0 10px; }

/* The ready text, drawn as a message bubble so it reads as a text and not as
   more of the page. */
.smsbubble {
  max-width: min(420px, 100%); padding: 12px 16px;
  border-radius: 20px 20px 20px 6px;
  background: #e9e9eb; color: #111;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif; font-size: 16px; line-height: 22px;
}
.smsbubble p { margin: 0; white-space: pre-line; overflow-wrap: anywhere; }

/* The weekly-email page's "Show a photo with each special" box. */
.emailtool__photos { margin: 0 0 18px; }

/* ----------------------------------------------- Ice Wolves (2026-10-01) --- */

/* /icewolves: cookies for hockey practice. Built from the order page's parts
   (.orderform, .orderitem, .stepper, .foodact, .ordertotal), with three
   things of its own: the line saying whether there are cookies right now,
   the pack cards, and the short price list. */
.iw__notice { margin: clamp(20px, 3vw, 32px) 0; }
.iw__notice .kicker { margin-bottom: 8px; }
.iw__notice p { margin: 0; }
.iw__notice p + p { margin-top: 8px; }
.iw__notice:focus { outline: none; }

.iw__status {
  margin: 0 0 24px; padding: 14px 18px;
  border-left: 4px solid var(--color-accent); background: var(--color-surface);
  font-size: 16px; line-height: 26px;
}
.iw__status p { margin: 0; }
.iw__status p + p { margin-top: 8px; }
.iw__status .btn { margin-top: 12px; }

/* The packs: big cards, because "6" and its price are the whole decision and
   they are tapped with a thumb. The radio is inside each card, out of sight
   but still the thing a keyboard or a screen reader uses. */
.iwpacks__grid {
  display: grid; gap: 10px; margin-top: 8px; max-width: 560px;
  grid-template-columns: repeat(auto-fit, minmax(min(96px, 100%), 1fr));
}
.iwpack {
  position: relative;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 14px 8px 12px; text-align: center; cursor: pointer;
  border: 1px solid var(--color-border-strong); background: var(--color-surface);
}
.iwpack__radio { position: absolute; top: 0; left: 0; width: 1px; height: 1px; opacity: 0; margin: 0; }
.iwpack__count { font-family: var(--font-heading); font-size: 46px; line-height: 1; color: var(--color-accent); }
.iwpack__noun { font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--color-caption); }
.iwpack__price { margin-top: 2px; font-family: var(--font-heading); font-size: 22px; line-height: 1.2; }
.iwpack__short { margin-top: 4px; font-size: 12px; line-height: 16px; color: var(--color-accent-700); }
.iwpack:has(.iwpack__radio:checked) {
  border-color: var(--color-accent); box-shadow: inset 0 0 0 1px var(--color-accent);
  background: color-mix(in srgb, var(--gold) 14%, var(--color-surface));
}
.iwpack:has(.iwpack__radio:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 3px; }
.iwpack--short { opacity: 0.55; cursor: not-allowed; }

/* The mix: each cookie a row like the order page's, with what is left of it
   under its name and a counter on the right. */
.iwmix__tally { margin: 4px 0 12px; font-size: 16px; line-height: 26px; color: var(--color-accent-2-800); }
.iwmix__tally--done { color: #4e6f43; font-weight: 600; }
.iwmix__left { margin: 0 0 2px; font-size: 14px; line-height: 22px; color: var(--color-accent-2-800); }
.iwmix__row--out .iwmix__left { color: var(--color-accent-700); }
.iwmix__row--out .itemname { color: var(--color-caption); }
.iwmix__buy { flex: 0 0 auto; margin-left: auto; width: 168px; max-width: 100%; }
.iwmix__buy .stepper__btn:disabled { opacity: 0.35; cursor: default; }
.iwmix__buy .stepper__btn:disabled:hover { background: none; }
.iwmix__tools { margin: 12px 0 0; }
.iwform__submit { max-width: 340px; margin-left: auto; }

/* Packs and prices: a short list, free delivery last and in green. */
.iwinfo__packs { list-style: none; margin: 8px 0 18px; padding: 0; max-width: 460px; }
.iwinfo__pack {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 10px 0; border-bottom: 1px solid var(--color-divider); font-size: 17px; line-height: 1.3;
}
.iwinfo__price { font-family: var(--font-heading); font-size: 20px; color: var(--color-accent-2-800); white-space: nowrap; }
.iwinfo__pack--free .iwinfo__price { color: #4e6f43; font-weight: 600; }
.iwinfo__text { max-width: 60ch; }
.iwsignup .order-card { max-width: 640px; }

/* The orders page: the next Ice Wolves practice, above the weekend. */
.orders__ice { padding-bottom: 24px; border-bottom: 1px solid var(--color-divider); }
.orders__iceleft { margin: 4px 0 12px; font-weight: 600; }
.orders__icetools { margin: 4px 0 8px; }
.orders__icetext { margin: 0 0 8px; max-width: 70ch; font-size: 14px; line-height: 22px; font-style: italic; color: var(--color-caption); }
.ordercard--ice { border-left-color: #3d6a8a; }

/* "How it works" sits beside the headline on a wide screen. On a phone it
   would push the order form a screen and a half down, and the parent reading
   it has usually just been sent the link to order - so there it moves below
   the form (the same list, rendered in both places, one hidden). */
.iw__howfoot { display: none; }
@media (max-width: 700px) {
  .iw__howhead { display: none; }
  .iw__howfoot { display: block; margin-bottom: clamp(32px, 4vw, 56px); }
}

/* Room between the fields of an order's details. They are not all in one
   grid - a two-up row, then single fields, then the text-or-email choice -
   so the grid's gap only ever spaced the fields inside a row, and the rest
   sat almost touching (the order page had this too). */
.orderform .orderdetails > :not(legend) + :not(legend) { margin-top: 18px; }

/* /grt.html - the monthly gross receipts tax report (2026-10-12). A plain
   two-column list of sums with the figure for TAP picked out, the download
   under it, then the payments behind the number. Tables scroll sideways on a
   phone rather than squeezing the references into one-word columns. */
.grt { display: grid; gap: 28px; padding-bottom: clamp(32px, 4vw, 56px); }
.grt__form { max-width: 720px; }
.grt__hint { margin: 4px 0 14px; color: var(--color-caption); }
.grt__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.grt__rate { max-width: 360px; margin-bottom: 16px; }
.grt__sums {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 6px 24px;
  max-width: 640px; margin: 0 0 20px; font-size: 16px; line-height: 26px;
}
.grt__sums dt { margin: 0; color: color-mix(in srgb, var(--color-text) 80%, transparent); }
.grt__sums dd { margin: 0; text-align: right; font-feature-settings: 'tnum'; white-space: nowrap; }
.grt__sums .grt__sumnote {
  grid-column: 1 / -1; text-align: left; white-space: normal;
  margin-top: -4px; font-size: 13px; line-height: 20px; color: var(--color-caption);
}
.grt__sums .grt__key {
  font-family: var(--font-heading); font-size: 22px; line-height: 30px; font-weight: 600;
  color: var(--color-text); border-top: 1px solid var(--color-border-strong); padding-top: 8px;
}
.grt__download { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }
.grt__notes p { margin: 0 0 8px; max-width: 70ch; }
.grt__subhead { font-family: var(--font-heading); font-size: 20px; margin: 24px 0 8px; }
.grt__tablewrap { overflow-x: auto; }
.grt__table { border-collapse: collapse; min-width: 560px; width: 100%; font-size: 14px; line-height: 20px; }
.grt__table th, .grt__table td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--color-border-strong); vertical-align: top; }
.grt__table th { font-weight: 600; font-size: 12px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--color-caption); }
.grt__table .grt__num { text-align: right; white-space: nowrap; font-feature-settings: 'tnum'; }
.grt__how { max-width: 720px; }
.grt__how p + p { margin-top: 10px; }
@media print { .grt__form, .grt__download, .site-header, .site-footer { display: none !important; } }
