/* Local Roots: a farmhouse notebook. Oat paper, ink line-work, a good serif. */

:root {
  /* two families, kitchen-garden greens and fired clay, on linen */
  --paper: #F6F0E6;
  --oat: #EDE4D4;
  --oat-deep: #DED0B8;
  --bone: #EEE4D3;
  --ink: #2A2621;
  --ink-soft: #60584C;

  --forest: #2E4A39;
  --forest-deep: #233A2C;
  --leaf: #567A4E;
  --sage: #A3B994;
  --sage-light: #D3DEC6;
  --sage-tint: #E0E8D5;

  --terra: #C0603D;
  --terra-deep: #9A4A2E;
  --clay: #EFBE9E;
  --clay-soft: #F5E0D1;

  --river: #84A9B7;
  --line: #DCCDB4;

  /* Fraunces with its "soft" axis turned up rounds every serif; Nunito has rounded stroke ends */
  --serif: "Fraunces", Georgia, serif;
  --sans: "Nunito", ui-rounded, ui-sans-serif, sans-serif;
  /* the accent face carries the playful bits: tagline, hours, prices, captions, map labels */
  --accent: var(--serif);
  --accent-style: italic;
  --accent-weight: 500;
  --accent-scale: 1;
  --head-scale: 1;

  /* five sizes, and only five */
  --fs-l: clamp(2.25rem, 5vw, 3.25rem);   /* section titles, the hours */
  --fs-m: 1.45rem;                        /* tagline, card titles, names, prices */
  --fs-body: 1.0625rem;
  --fs-s: .875rem;                        /* labels and fine print */

  --gutter: clamp(1rem, 4.5vw, 3rem);
  --max: 76rem;
  --ease: cubic-bezier(.22, .8, .24, 1);

  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .3 0 0 0 0 .24 0 0 0 0 .16 0 0 0 .5 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* a pen-drawn wave, used for link hovers */
  --wave: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='8' viewBox='0 0 24 8'%3E%3Cpath d='M0 4Q6 0 12 4T24 4' fill='none' stroke='%23C0603D' stroke-width='1.4'/%3E%3C/svg%3E");
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; scroll-padding-top: 5rem; -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 var(--fs-body)/1.6 var(--sans);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  font-variation-settings: "SOFT" 100, "WONK" 0;
}
/* paper grain over everything, very faint */
body::before {
  content: ""; position: fixed; inset: 0; z-index: 100; pointer-events: none;
  background: var(--grain); opacity: .16;
}

img { display: block; max-width: 100%; height: auto; }
figure { margin: 0; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--forest); outline-offset: 4px; border-radius: 4px; }
::selection { background: var(--sage-light); }

h1, h2, h3 { font-family: var(--serif); font-weight: var(--head-weight, 400); line-height: 1; margin: 0; letter-spacing: -.02em; }
h2 { font-size: calc(var(--fs-l) * var(--head-scale)); margin-bottom: .35em; text-wrap: balance; }
h3 { font-size: calc(var(--fs-m) * var(--accent-scale)); font-family: var(--accent); font-style: var(--accent-style); font-weight: var(--accent-weight); }
p { margin: 0 0 1em; }

.wrap { max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.lede { max-width: 30em; }

.skip { position: absolute; left: -999px; top: .5rem; z-index: 50; background: var(--ink); color: var(--paper); padding: .5rem 1rem; }
.skip:focus { left: .5rem; }

/* ---------- links and buttons ---------- */

/* links draw a little wave underneath on hover: the wave repeats at its own size and is wiped in, never stretched */
.ulink { position: relative; text-decoration: none; padding-bottom: 5px; }
.ulink::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 7px;
  background: var(--wave) left center / 21px 7px repeat-x;
  clip-path: inset(0 100% 0 0); transition: clip-path .45s var(--ease);
}
.ulink:hover::before, .ulink:focus-visible::before { clip-path: inset(0); }

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 3rem; padding: .75rem 1.6rem;
  font: 500 1rem/1.1 var(--sans);
  color: var(--paper); background: var(--forest);
  border: 1px solid var(--forest); border-radius: 999px;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background-color .25s ease, color .25s ease, border-color .25s ease;
}
.btn:hover { background: var(--terra); border-color: var(--terra); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn--ghost:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn--small { min-height: 2.5rem; padding: .45rem 1.15rem; }
.btn--light { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.btn--light:hover { background: var(--clay); border-color: var(--clay); }
.btn--ghost-light { background: transparent; color: var(--paper); border-color: rgb(244 237 225 / .55); }
.btn--ghost-light:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.actions { display: flex; flex-wrap: wrap; gap: .75rem; }

.linkish { font: inherit; color: inherit; background-color: transparent; border: 0; padding: 0 0 5px; cursor: pointer; }

/* ---------- picture frames ---------- */

.frame { overflow: hidden; }
.frame img { width: 100%; height: 100%; object-fit: cover; }
.frame--arch { border-radius: 999px 999px 8px 8px; aspect-ratio: 3 / 4.1; }

/* ---------- nav ---------- */

/* the header holds the name. It starts tall with the name large, and settles to a slim bar once you scroll.
   It's fixed, so the page never shifts as it shrinks; the bar's height and the name's scale are the only things that move. */
:root { --nav-h: 4.05rem; --nav-tall: 9rem; --mark-big: 2.15; }
@media (max-width: 959px) { :root { --nav-tall: 5.75rem; --mark-big: 1.3; } }

.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20;
  display: flex; align-items: center; gap: 2rem;
  height: var(--nav-tall); padding: 0 var(--gutter);
  background: rgb(244 237 225 / .88);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: height .45s var(--ease), border-color .3s;
}
.scrolled .nav { height: var(--nav-h); border-bottom-color: rgb(214 200 174 / .6); }
.nav + main { padding-top: var(--nav-tall); }
.nav__mark {
  display: flex; align-items: center; gap: .45rem;
  font: var(--head-weight, 400) calc(1.6rem * var(--head-scale))/1 var(--serif); text-decoration: none; letter-spacing: -.01em; white-space: nowrap;
  scale: var(--mark-big); transform-origin: left center;
  transition: scale .45s var(--ease);
}
.scrolled .nav__mark { scale: 1; }
.nav__mark .logo { height: 2.1em; margin-block: -.4em; color: var(--forest); }
.nav__name span { font-style: var(--accent-style); color: var(--leaf); font-variation-settings: "SOFT" 100, "WONK" 1; }
.nav nav { display: none; gap: 2rem; margin-left: auto; }
.nav .btn { margin-left: auto; }
@media (min-width: 760px) {
  .nav nav { display: flex; }
  .nav .btn { margin-left: 0; }
}

/* one-off stall news, e.g. a missed week: a small flagged line at the top of the hero */
.notice {
  display: inline-flex; align-items: center; gap: .55rem;
  margin: 0 0 1rem; padding: .4rem 1rem .4rem .5rem;
  background: var(--clay-soft); color: var(--terra-deep);
  border-radius: 999px;
  font-size: var(--fs-s); font-weight: 700; line-height: 1.3;
}
.notice__icon { flex: none; width: 1.15rem; height: 1.15rem; fill: var(--terra); }
.notice__icon path { stroke: var(--paper); }
.notice__icon circle + path + circle { fill: var(--paper); }

/* ---------- hero: the name, the promise and a card for the stall on the left; hand-drawn Oxford on the right ---------- */

/* the whole hero fits the first screen, under the sticky nav */
.hero { display: grid; grid-template-rows: auto minmax(5rem, 1fr); min-height: calc(100svh - var(--nav-tall)); }
.hero__text {
  position: relative; z-index: 1;
  padding: clamp(1.25rem, 3.5svh, 2.5rem) var(--gutter) 1rem;
  container-type: inline-size;
}

/* while the stall is new, a small line over the promise says so */
.hero__eyebrow {
  display: flex; align-items: center; gap: .6rem;
  margin: 0 0 .7rem;
  font: 700 .8rem/1 var(--sans); letter-spacing: .14em; text-transform: uppercase;
  color: var(--terra-deep);
}
.hero__eyebrow::before { content: ""; width: 1.75rem; height: 1.5px; background: currentColor; }

/* the promise leads the hero; the name lives in the header */
.hero__promise {
  font: var(--head-weight, 400) min(calc(2.75rem * var(--head-scale)), 9.5cqi, 5svh)/1 var(--serif);
  letter-spacing: -.01em; color: var(--ink); text-wrap: balance;
  margin: 0;
}
.hero__intro { max-width: 40ch; margin: .9rem 0 0; font-size: 1.08rem; line-height: 1.5; color: var(--ink-soft); }

/* the stall callout: when and where, and how to get there */
.hero__stall {
  position: relative;
  max-width: 26rem; margin-top: clamp(1.5rem, 4svh, 2.25rem);
  padding: clamp(.9rem, 3cqi, 1.25rem) clamp(1rem, 4cqi, 1.75rem);
  background: #FBF8F2;
  border: 1px solid var(--line); border-radius: 22px;
  box-shadow: 0 22px 40px -28px rgb(42 38 33 / .45);
}

/* when and where */
.when { min-width: 0; container-type: inline-size; }
.when p { margin: 0; }
.when__time {
  position: relative; width: fit-content;
  font: var(--accent-style) var(--accent-weight) min(calc(2rem * var(--accent-scale)), 14cqi)/.95 var(--accent);
  color: var(--forest); letter-spacing: -.01em; white-space: nowrap;
}
/* underlined with the same squiggle as every link, a size up to suit the lettering, wiped in with the map's roads */
.when__time::after {
  content: ""; position: absolute; left: 0; right: 0; top: calc(100% + .1em); height: 9px;
  background: var(--wave) left center / 27px 9px repeat-x;
  animation: wipe 1.1s var(--ease) both 1.1s;
}
.when__where { margin-top: 1.3rem !important; line-height: 1.4; }
.when .status { margin-top: .35rem; }
.when__actions { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem 1.25rem; margin-top: 1.1rem; }
/* a standing squiggle here, since it's the only way to tell it's a link; it slips away on hover */
.when__cal { font-weight: 600; }
.when__cal::before { clip-path: inset(0); }
.when__cal:hover::before, .when__cal:focus-visible::before { clip-path: inset(0 0 0 100%); }

.status:empty { display: none; }
.status { display: flex; align-items: center; gap: .5rem; font-size: .92rem; line-height: 1.35; color: var(--ink-soft); }
.status::before { content: ""; flex: none; width: .5rem; height: .5rem; border-radius: 50%; background: var(--sage); }
.status[data-open] { color: var(--terra-deep); font-weight: 700; }
.status[data-open]::before { background: var(--terra); animation: breathe 2.4s ease-in-out infinite; }

.btn--clay { background: var(--clay); border-color: var(--clay); color: var(--ink); }
.btn--clay:hover { background: var(--paper); border-color: var(--paper); }
.btn--ink { background: var(--ink); border-color: var(--ink); }
.btn--terra { background: var(--terra-deep); border-color: var(--terra-deep); }
.btn--terra:hover { background: var(--forest); border-color: var(--forest); }

/* narrow cards: the button and its link stack, and the button shrinks */
@container (max-width: 13rem) {
  .when__actions .btn { min-height: 2.6rem; padding: .5rem 1.15rem; font-size: .95rem; }
}

/* the plate: hand-drawn Oxford on the page's own colour, dissolving at its edge; only the paper texture sets it apart */
.hero__plate {
  position: relative; isolation: isolate; overflow: hidden;
  /* a long, eased fade: soft at both ends so there's no line where the map begins */
  --fade: rgb(0 0 0 / 0) 0%, rgb(0 0 0 / 0.028) 5%, rgb(0 0 0 / 0.104) 10%, rgb(0 0 0 / 0.216) 15%, rgb(0 0 0 / 0.352) 20%, rgb(0 0 0 / 0.500) 25%, rgb(0 0 0 / 0.648) 30%, rgb(0 0 0 / 0.784) 35%, rgb(0 0 0 / 0.896) 40%, rgb(0 0 0 / 0.972) 45%, rgb(0 0 0 / 1) 50%;
}
/* only the drawing and the paper fade; the chard laid on top stays solid */
.hero__plate .map, .hero__plate::before {
  -webkit-mask-image: linear-gradient(var(--fade));
          mask-image: linear-gradient(var(--fade));
}
.hero__plate .map { position: absolute; inset: 0; width: 100%; height: 100%; }
/* a crumpled sheet showing faintly through, under the drawing (photo by SJ Objio on Unsplash) */
.hero__plate::before { content: ""; position: absolute; inset: 0; z-index: -1; background: url(/images/brand/paper.jpg) center / cover; opacity: .3; animation: appear 1.8s ease both .2s; }

/* from tablets up, the words and card share a column with a tall arch of chard: it stands beside the intro and the card,
   and the card is laid over its edge, so the colour sits with the words and the map stays clear */
@media (min-width: 760px) {
  .hero__text {
    --chard-w: clamp(6.5rem, 11vw, 12.5rem);
    display: grid; grid-template-columns: minmax(0, 26rem) var(--chard-w); justify-content: start;
    /* the notice's and eyebrow's rows are simply empty when there's nothing to say */
    grid-template-areas: "notice notice" "eyebrow eyebrow" "promise promise" "intro photo" "stall photo";
  }
  .notice { grid-area: notice; justify-self: start; }
  .hero__eyebrow { grid-area: eyebrow; }
  .hero__promise { grid-area: promise; }
  .hero__intro { grid-area: intro; max-width: min(40ch, 100% - 3rem); }
  .hero__stall { grid-area: stall; z-index: 1; }
  .hero__photo {
    grid-area: photo; align-self: stretch;
    margin: .75rem 0 -1.5rem -3rem; aspect-ratio: auto;
    outline: 1px solid var(--sage); outline-offset: 8px;
  }
}

/* phones and tablets: the map is the picture, so the words and the card pack in tight and the map takes the rest of the first screen */
@media (max-width: 959px) {
  .hero { grid-template-rows: auto minmax(min(40svh, 24rem), 1fr); }
  .hero__text { padding-top: clamp(.9rem, 2.5svh, 1.5rem); padding-bottom: .25rem; }
  .hero__promise { font-size: min(calc(1.9rem * var(--head-scale)), 8cqi, 4.5svh); }
  .hero__intro { font-size: 1rem; margin-top: .6rem; }
  .hero__stall { margin-top: 1.4rem; padding: .8rem 1rem .9rem; border-radius: 18px; }
  /* the day and the hours on one line */
  .when__time { font-size: min(calc(1.6rem * var(--accent-scale)), 9cqi); }
  .when__time br { display: none; }
  .when__where { margin-top: .9rem !important; }
  .when__actions { margin-top: .75rem; }
  .when__actions .btn { min-height: 2.6rem; padding: .5rem 1.15rem; font-size: .95rem; }
}
/* on phones the map is the picture, so no chard; the map is zoomed in there, so the pin's words come back down a size */
@media (max-width: 759px) {
  .hero__photo { display: none; }
  .map__pin-label { font-size: 30px; }
}

@media (min-width: 960px) {
  /* the words get a little more room than the map, so the card and the chard fit side by side */
  .hero { grid-template-columns: minmax(0, 55fr) minmax(0, 45fr); grid-template-rows: none; }
  /* the words start a short way under the header rather than floating mid-screen */
  .hero__text {
    align-self: start;
    padding: clamp(2rem, 7svh, 4rem) 2rem 1.75rem max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter)));
  }
  .hero__plate {
    --fade: rgb(0 0 0 / 0) 0%, rgb(0 0 0 / 0.028) 4.5%, rgb(0 0 0 / 0.104) 9%, rgb(0 0 0 / 0.216) 13.5%, rgb(0 0 0 / 0.352) 18%, rgb(0 0 0 / 0.500) 22.5%, rgb(0 0 0 / 0.648) 27%, rgb(0 0 0 / 0.784) 31.5%, rgb(0 0 0 / 0.896) 36%, rgb(0 0 0 / 0.972) 40.5%, rgb(0 0 0 / 1) 45%;
  }
  .hero__plate .map, .hero__plate::before {
    -webkit-mask-image: linear-gradient(90deg, var(--fade));
            mask-image: linear-gradient(90deg, var(--fade));
  }
}

/* the one orchestrated moment: the words settle, the chard is set down, and the card lands on it */
.hero__eyebrow, .hero__promise, .hero__intro, .hero__stall { animation: rise 1s var(--ease) both; }
.hero__promise { animation-delay: .1s; }
.hero__intro { animation-delay: .28s; }
.hero__stall { animation-delay: .45s; }
.hero__photo { animation: rise 1s var(--ease) both .32s; }

/* ---------- the hand-drawn map ---------- */

/* drawn in a warm sepia ink, like an old survey sheet */
.map { --map-ink: #4E3D2C; --map-ink-soft: #6F5B46; --tree: #6F8A5C; color: var(--map-ink); }
.map__road path { stroke: var(--map-ink); opacity: .5; }
.map__footpath { stroke: var(--map-ink); opacity: .35; }
.map__street path { stroke: var(--map-ink); opacity: .3; }
.map__water path { stroke: var(--river); opacity: .85; }
.map__ripples path { stroke: var(--river); stroke-width: .7; }
.map__ripple-1 { opacity: .75; }
.map__ripple-2 { opacity: .5; }
.map__ripple-3 { opacity: .28; }
.map__green path { fill: rgb(163 185 148 / .2); stroke: var(--sage); stroke-width: .9; opacity: .9; }
.map__trees path { stroke: var(--tree); stroke-width: .7; }
.map__tree-crown { fill: rgb(163 185 148 / .55); }
.map__tree-shade { stroke: var(--map-ink) !important; opacity: .22; stroke-width: .9 !important; }
.map__hachures path { stroke: var(--map-ink); stroke-width: .8; opacity: .32; }
.map__pencil path { stroke: #8C857C; opacity: .28; }
.map__blots { fill: var(--map-ink); opacity: .45; }
.map__house-rows { fill: rgb(78 61 44 / .06); stroke: var(--map-ink); stroke-width: .45; stroke-opacity: .26; }
.map__house-walls { stroke: var(--map-ink); stroke-width: .35; opacity: .2; }
.map__sights { stroke: var(--map-ink); stroke-width: .8; }
.map__sight-fill { fill: var(--paper); }
.map__sight-solid { fill: var(--map-ink); stroke: none; }
.map__cows path { fill: #8A5A3B; stroke: none; }
.map__horns path { stroke: var(--map-ink); stroke-width: .6; }
.map__wake { stroke: var(--river); }
.map__oars { stroke: var(--map-ink); stroke-width: .55; }
.map__label text { font: var(--accent-style) var(--accent-weight) calc(24px * var(--accent-scale)) var(--accent); fill: var(--map-ink-soft); }
.map__label .map__label--small { font-size: 17px; }
.map__label .map__label--tiny { font-size: 13px; }
/* water is lettered the cartographer's way: spaced italic capitals */
.map__label .map__label--water { font: italic 400 11.5px Georgia, "Times New Roman", serif; letter-spacing: .3em; text-transform: uppercase; fill: #5A8292; }
.map__compass { color: var(--map-ink-soft); stroke: var(--map-ink-soft); opacity: .8; }
.map__compass text { font: italic 400 13px Georgia, "Times New Roman", serif; fill: currentColor; stroke: none; }
.map__scale { color: var(--map-ink-soft); stroke: var(--map-ink-soft); opacity: .85; }
.map__scale text { font: italic 400 10px Georgia, "Times New Roman", serif; fill: currentColor; stroke: none; letter-spacing: .05em; }
.map__scale .map__scale-note { font-size: 11px; }

.map__drop path { fill: var(--terra); }
.map__pulse { fill: var(--terra); opacity: 0; transform-box: fill-box; transform-origin: center; }
.map__pin-label { font: var(--accent-style) var(--accent-weight) calc(30px * var(--accent-scale)) var(--accent); fill: var(--ink); }

@media (max-width: 959px) {
  /* zoomed out on phones, so the pin's words are drawn larger */
  .map__pin-label { font-size: 40px; }
  .map__label--minor { display: none; }
}

/* roads draw in under the words, the detail is inked in after, and the pin drops once the prices are on */
.map__road path[pathLength], .map__water path[pathLength] {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: draw 2.2s var(--ease) forwards .2s;
}
.map__water path[pathLength] { animation-duration: 2.8s; }
.map__road path:nth-child(3n+2) { animation-delay: .4s; }
.map__road path:nth-child(3n) { animation-delay: .6s; }
.map__street, .map__label, .map__green, .map__compass, .map__footpath, .map__houses, .map__trees, .map__ripples, .map__hachures, .map__sights, .map__scale, .map__pencil, .map__blots { opacity: 0; animation: fade 1.2s ease forwards 1.1s; }
.map__drop { animation: pin-drop .7s cubic-bezier(.3, 1.6, .5, 1) both 1.8s; transform-box: fill-box; transform-origin: 50% 100%; }
.map__pin text { opacity: 0; animation: fade .8s ease forwards 2.2s; }
.map__pulse { animation: pulse 2.8s ease-out infinite 2.5s; }

@keyframes draw { to { stroke-dashoffset: 0; } }
@keyframes appear { from { opacity: 0; } }
@keyframes wipe { from { clip-path: inset(0 100% 0 0); } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise { from { opacity: 0; translate: 0 18px; } }
@keyframes pin-drop { from { opacity: 0; translate: 0 -40px; } 60% { opacity: 1; } }
@keyframes pulse { 0% { opacity: .35; scale: .6; } 100% { opacity: 0; scale: 3.2; } }
@keyframes breathe { 50% { box-shadow: 0 0 0 5px rgb(239 190 158 / .35); } }

/* ---------- the logo: Maryam's carrot and turnip drawing, used as a mask so it takes any colour ---------- */

.logo {
  display: inline-block; flex: none;
  aspect-ratio: 403 / 488; height: 1em;
  background: currentColor;
  -webkit-mask: url(/images/brand/logo-mark.png) center / contain no-repeat;
          mask: url(/images/brand/logo-mark.png) center / contain no-repeat;
}
.logo--footer { height: 1.15em; color: var(--forest); }
.logo--thanks { height: 9rem; color: var(--forest); margin: 0 auto 1.5rem; display: block; }

/* ---------- on the stall ---------- */

.stall { padding-block: clamp(3rem, 7vw, 4.5rem) clamp(2rem, 5vw, 3rem); }
.stall__head { display: grid; gap: .5rem 3rem; align-items: end; }
.stall__head h2 { margin: 0; }
@media (min-width: 760px) { .stall__head { grid-template-columns: auto 1fr; } .stall__head p { justify-self: end; text-align: right; } }

/* the photos drift past in a loop; the list is printed twice so the seam never shows */
.strip { overflow: hidden; margin-top: 1.75rem; padding-block: .5rem 1.5rem; }
.strip__track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: flex-start; width: max-content;
  animation: drift 70s linear infinite;
}
.strip button { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; border-radius: 1rem; }
.strip li { flex: none; width: clamp(8.5rem, 30vw, 11rem); margin-right: clamp(1rem, 2.4vw, 1.75rem); text-align: center; }
/* each photo gets its own lumpy bubble, like a squashed pebble */
.strip img {
  width: 100%; aspect-ratio: 1; object-fit: cover;
  border-radius: 58% 42% 55% 45% / 47% 56% 44% 53%;
  /* only scale on hover: the strip never stops, so items slide under the cursor all the time, and morphing the shape would repaint the photo every frame */
  transition: scale .6s var(--ease);
}
.strip .bubble-1 img { border-radius: 42% 58% 46% 54% / 58% 44% 56% 42%; }
.strip .bubble-2 img { border-radius: 52% 48% 38% 62% / 42% 52% 48% 58%; }
.strip .bubble-3 img { border-radius: 63% 37% 52% 48% / 52% 62% 38% 48%; }
.strip .low { margin-top: 1.25rem; }
.strip li:hover img, .strip button:focus-visible img { scale: 1.04; }
.strip__name { display: block; font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1.2 var(--accent); margin-top: .7rem; }

/* veg with a recipe card show a label in the middle of the bubble on hover; touch screens can't hover, so there it always shows */
.strip__pic { display: block; position: relative; }
.strip__tag {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%;
  padding: .3em .85em .35em;
  font: var(--accent-style) var(--accent-weight) calc(.95rem * var(--accent-scale))/1.1 var(--accent);
  color: var(--paper); background: var(--terra); border-radius: 999px;
  white-space: nowrap; will-change: opacity, scale;
  transition: opacity .3s var(--ease), scale .3s var(--ease);
}
@media (hover: hover) {
  .strip__tag { opacity: 0; scale: .9; }
  .strip button:hover .strip__tag, .strip button:focus-visible .strip__tag { opacity: 1; scale: 1; }
}
/* the name gets the same wavy underline as the links */
.strip button .strip__name { position: relative; width: fit-content; margin-inline: auto; padding-bottom: 5px; }
.strip button .strip__name::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 7px;
  background: var(--wave) left center / 21px 7px repeat-x;
  /* faded in rather than wiped like the links: the strip never stops, so hovers start constantly, and a wipe repaints every frame */
  opacity: 0; transition: opacity .4s var(--ease);
}
.strip button:hover .strip__name::before, .strip button:focus-visible .strip__name::before { opacity: 1; }
@keyframes drift { to { translate: -50% 0; } }

/* ---------- fair to you, fair to the farm: prices and suppliers side by side ---------- */

.fair { background: var(--clay-soft); padding-block: clamp(2.25rem, 5vw, 3.25rem); }
.fair__grid { display: grid; gap: 3rem; }
.fair .lede { color: var(--ink-soft); margin-bottom: 1.25rem; }
@media (min-width: 900px) {
  .fair__grid { grid-template-columns: 1fr 1fr; gap: 0; }
  .fair__prices { padding-right: clamp(2rem, 4vw, 3.5rem); }
  .fair__farms { padding-left: clamp(2rem, 4vw, 3.5rem); border-left: 1px solid rgb(192 96 61 / .22); }
}

/* the farms: a band each, its own photo behind and the name laid over it */
.farms { list-style: none; margin: .5rem 0 0; padding: 0; display: grid; gap: .5rem; }
.farm {
  position: relative; isolation: isolate; overflow: hidden;
  display: grid; align-content: center; justify-items: start; gap: .15rem;
  min-height: 4.25rem; padding: .8rem 1.1rem;
  border-radius: 14px; background: var(--forest); color: var(--paper);
}
.farm img { position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%; object-fit: cover; transition: scale .6s var(--ease); }
/* darker on the left where the name sits, so it reads over any photo */
.farm::before { content: ""; position: absolute; inset: 0; z-index: -1; background: linear-gradient(90deg, rgb(28 34 26 / .82), rgb(28 34 26 / .45) 65%, rgb(28 34 26 / .2)); }
/* farms without a photo yet get a plain colour band */
.farm--plain::before { display: none; }
.farm--plain:nth-child(odd) { background: var(--terra-deep); }
.farm p { margin: 0; }
.farm__name { font: var(--head-weight) calc(1.35rem * var(--head-scale))/1.1 var(--serif); }
.farm__name a { color: inherit; text-decoration: none; background: var(--wave) left bottom / 21px 7px repeat-x; padding-bottom: 5px; }
/* the whole band is the link */
.farm__name a::after { content: ""; position: absolute; inset: 0; }
.farm:has(a:hover) img { scale: 1.05; }
.farm__name a:focus-visible { outline: none; }
.farm:has(a:focus-visible) { outline: 2px solid var(--forest); outline-offset: 3px; }
.farm__grows { font-size: .88rem; opacity: .85; }

.menu {
  position: relative;
  background: var(--paper);
  padding: clamp(1.25rem, 3vw, 1.75rem) clamp(1.25rem, 3vw, 2rem);
  outline: 1px solid var(--line); outline-offset: -10px;
  box-shadow: 0 24px 50px -30px rgb(120 80 20 / .35);
}
.menu__item { font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1.2 var(--accent); text-align: center; color: var(--ink-soft); margin-bottom: .9rem; }
.menu__item::before, .menu__item::after { content: "~"; color: var(--clay); margin: 0 .6rem; font-style: normal; }
.menu__rows { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.menu__line { display: flex; align-items: baseline; gap: .6rem; }
.menu__line h3 { font-family: var(--serif); font-style: normal; font-weight: var(--head-weight); font-size: calc(var(--fs-m) * var(--head-scale)); }
.menu__dots { flex: 1; border-bottom: 2px dotted var(--clay); translate: 0 -.3em; min-width: 1rem; }
.menu__price { font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1 var(--accent); color: var(--forest); font-variant-numeric: oldstyle-nums; }
.menu__rows p { margin: .15rem 0 0; color: var(--ink-soft); max-width: 30em; font-size: .92rem; line-height: 1.4; }
.menu__rows li:nth-child(2) .menu__price { color: var(--ink); }
.menu__rows li:nth-child(3) .menu__price { color: var(--terra); }

/* ---------- how far it travels: the supermarket's veg crosses a globe, ours fits on a dot ---------- */

.miles { padding-block: clamp(3rem, 7vw, 5rem); }
.miles__grid { display: grid; gap: 2rem; align-items: center; }
.miles .lede { color: var(--ink-soft); }
@media (min-width: 900px) {
  /* the globe keeps its place as the panel's words change length */
  .miles__grid { grid-template-columns: minmax(0, 27rem) minmax(0, 1fr); gap: clamp(2rem, 5vw, 4.5rem); align-items: start; }
}
/* phones: the globe comes straight after the picker, so a tap shows its trip without scrolling */
@media (max-width: 899px) {
  .miles__grid { gap: 0; }
  .miles__text { display: contents; }
  .miles__globe { order: 1; margin-bottom: 1.5rem; }
  .miles__tally, .miles__times, .miles__note { order: 2; }
  /* one row of pebbles that scrolls sideways, running to the screen's edges */
  /* each label sits over its number, leaving the farm list the full width */
  .miles .miles__row { grid-template-columns: 1fr; gap: .2rem; }
  .miles .miles__pick { min-width: 0; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(var(--gutter) * -1); padding: .4rem var(--gutter); }
  .miles__pick label { flex: none; }
}

/* the chooser: a row of pills, the picked one filled in */
.miles__pick { border: 0; margin: 1.5rem 0 1.75rem; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem; }
.miles__pick label { position: relative; cursor: pointer; }
.miles__pick input { position: absolute; opacity: 0; pointer-events: none; }
.miles__pick span {
  display: block; padding: .45rem 1.05rem .5rem; border: 1.5px solid var(--ink); border-radius: 999px;
  font: 600 .95rem/1.2 var(--sans); white-space: nowrap;
  transition: background-color .3s ease, color .3s ease, border-color .3s ease;
}
.miles__pick label:hover span { border-color: var(--terra); color: var(--terra-deep); }
.miles__pick input:checked + span { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.miles__pick input:focus-visible + span { outline: 2px solid var(--forest); outline-offset: 3px; }

/* the two distances, theirs over ours */
.miles__tally { margin: 0; display: grid; gap: 1rem; }
.miles__row { display: grid; grid-template-columns: 7.5rem 1fr; align-items: baseline; gap: 1rem; padding-bottom: 1rem; border-bottom: 2px dotted var(--clay); }
.miles__row dt { font-size: var(--fs-s); font-weight: 700; color: var(--ink-soft); }
.miles__row dd { margin: 0; font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1.1 var(--accent); }
.miles__num { font-size: 1.9em; font-variant-numeric: tabular-nums; }
.miles__row--theirs .miles__num { color: var(--terra-deep); }
.miles__row--ours .miles__num { color: var(--forest); }
.miles__how { display: block; margin-top: .25rem; font: 400 .92rem/1.4 var(--sans); color: var(--ink-soft); }
/* our farms, numbered to match their pins on the close-up, priced up like the menu */
.miles__farms { list-style: none; margin: .9rem 0 0; padding: 0; display: grid; gap: .3rem; font: 400 .95rem/1.3 var(--sans); }
.miles__farms li { display: flex; align-items: baseline; gap: .55rem; }
.miles__farm-num {
  flex: none; display: inline-grid; place-items: center; width: 1.35rem; height: 1.35rem; translate: 0 -.05rem;
  border-radius: 50%; background: var(--forest); color: var(--paper); font-size: .72rem; font-weight: 800;
}
.miles__farm-dots { flex: 1; min-width: 1rem; border-bottom: 2px dotted var(--sage); translate: 0 -.3em; }
.miles__farm-miles { color: var(--forest); font-weight: 700; white-space: nowrap; }
.miles__times { min-height: 1.3em; margin: 1.1rem 0 .5rem; font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1.2 var(--accent); color: var(--ink); }
.miles__note { max-width: 34em; margin: 0; font-size: var(--fs-s); color: var(--ink-soft); }

.miles__globe { width: 100%; max-width: 40rem; justify-self: center; }

/* whose journey is showing: the supermarket's, then ours. The caption over the globe says so in that side's
   colour, and the other side's row in the panel steps back */
.miles__caption {
  display: grid; justify-items: center; margin: 0 0 .5rem; text-align: center;
  font: var(--accent-style) var(--accent-weight) calc(1.7rem * var(--accent-scale))/1.15 var(--accent);
}
.miles__caption span { grid-area: 1 / 1; opacity: 0; translate: 0 .3em; transition: opacity .5s ease, translate .5s var(--ease); }
[data-caption-them] { color: var(--terra-deep); }
[data-caption-us] { color: var(--forest); }
.miles[data-side="them"] [data-caption-them], .miles[data-side="us"] [data-caption-us] { opacity: 1; translate: 0 0; }
.miles__row { transition: opacity .5s ease; }
.miles[data-side="them"] .miles__row--ours, .miles[data-side="us"] .miles__row--theirs { opacity: .4; }

/* the farm this item comes from stands out in the list of suppliers */
.miles__farms li { transition: opacity .4s ease; }
.miles__farms li:not(.is-from) { opacity: .5; }
.miles__farms li.is-from { font-weight: 700; }

/* the globe, drawn in the hero map's ink: blue-washed sea, paper land, pencilled lines of latitude */
.globe { --k: 1; --map-ink: #4E3D2C; display: block; width: 100%; height: auto; overflow: visible; }
.globe__sea { fill: rgb(132 169 183 / .3); }
.globe__ripple { fill: none; stroke: var(--river); stroke-width: .8; }
.globe__ripple-1 { opacity: .6; }
.globe__ripple-2 { opacity: .38; }
.globe__ripple-3 { opacity: .2; }
.globe__grid { fill: none; stroke: #8C857C; stroke-width: .6; stroke-dasharray: 2 4; opacity: .45; }
.globe__land { fill: #FBF7EF; stroke: rgb(78 61 44 / .7); stroke-width: 1; stroke-linejoin: round; }
.globe__rim { fill: none; stroke: var(--map-ink); stroke-width: 1.4; opacity: .8; }
/* the whole route pencilled in, then inked over as the trip is made */
.globe__plan { fill: none; stroke: var(--terra); stroke-width: 1.4; stroke-dasharray: .5 5; stroke-linecap: round; opacity: .8; }
.globe__trail { fill: none; stroke: var(--terra-deep); stroke-width: 2.4; stroke-dasharray: 8 5; stroke-linecap: round; stroke-linejoin: round; }
.globe__origin { fill: var(--paper); stroke: var(--terra-deep); stroke-width: 2.5; }
.globe__label {
  font: var(--accent-style) var(--accent-weight) calc(22px * var(--accent-scale) * var(--k)) var(--accent);
  fill: var(--ink); paint-order: stroke; stroke: #FBF7EF; stroke-width: 5px; stroke-linejoin: round;
}
.globe__vehicle path { fill: var(--paper); stroke: var(--ink); stroke-width: 1.4; stroke-linejoin: round; }
.globe__home { fill: var(--terra); stroke: var(--paper); stroke-width: 2; }

/* names fade in once the view has settled, and out before it moves again */
.close-names, .still-names { opacity: 0; transition: opacity .45s ease; }
.is-close .close-names, .is-still .still-names { opacity: 1; }

/* the close-up round Oxford, in the hero map's inks */
.shire { --map-ink-soft: #6F5B46; }
.shire__river { fill: none; stroke: var(--river); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.shire__river--main { stroke-width: 2.8; }
.shire__road { fill: none; stroke: var(--map-ink); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; opacity: .4; }
.shire__label {
  font: var(--accent-style) var(--accent-weight) calc(14px * var(--accent-scale) * var(--k)) var(--accent);
  fill: var(--map-ink-soft); paint-order: stroke; stroke: #FBF7EF; stroke-width: 4px; stroke-linejoin: round;
}
.shire__label--town { font-size: calc(17px * var(--accent-scale) * var(--k)); }
.shire__label--city { font-size: calc(21px * var(--accent-scale) * var(--k)); fill: var(--ink); }

/* zoomed in: our farms, each with its straight line in to Cowley */
.farms-near__route { fill: none; stroke: var(--forest); stroke-width: 2.6; stroke-linecap: round; }
.farms-near__pin circle { fill: var(--forest); stroke: var(--paper); stroke-width: 2; }
.farms-near__pin { opacity: .45; transition: opacity .4s ease; }
.farms-near__pin.is-from { opacity: 1; }
.farms-near__pin text { font: 800 12px/1 var(--sans); fill: var(--paper); }
.farms-near__home { font-size: calc(20px * var(--accent-scale) * var(--k)); fill: var(--terra-deep); }
.farms-near__theirs { font-size: calc(17px * var(--accent-scale) * var(--k)); fill: var(--terra-deep); }
.farms-near__ours { font-size: calc(19px * var(--accent-scale) * var(--k)); fill: var(--forest); }


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

/* ---------- maryam ---------- */

.maryam { background: var(--forest); color: var(--paper); padding-block: clamp(3.5rem, 8vw, 5.5rem); }
.maryam__grid { display: grid; gap: 3.5rem; align-items: center; }
.maryam__photo { width: min(62%, 17rem); margin-inline: auto; outline: 1px solid var(--sage); outline-offset: 14px; }
.maryam h2 { font-family: var(--accent); font-style: var(--accent-style); font-weight: var(--accent-weight); font-size: calc(var(--fs-l) * var(--accent-scale)); color: var(--clay); }
.maryam p { max-width: 34em; margin: 0; }
@media (min-width: 820px) {
  .maryam__grid { grid-template-columns: 17rem minmax(0, 34rem); gap: 5rem; justify-content: center; }
  .maryam__photo { width: 100%; }
}

/* ---------- get involved: three tinted cards, the forms fold out ---------- */

.help { padding-block: clamp(3.5rem, 8vw, 5.5rem); }
.help__grid { display: grid; gap: 1rem; margin-top: .75rem; align-items: start; }
.pitch { border-radius: 22px; padding: 1.6rem 1.6rem 1.75rem; display: flex; flex-direction: column; }
.pitch > .btn, .pitch summary { margin-top: auto; }
.pitch summary { display: flex; flex-direction: column; align-items: flex-start; flex: 1; }
.pitch--clay { background: var(--clay-soft); }
.pitch--sage { background: var(--sage-tint); }
.pitch--bone { background: var(--bone); }
.pitch h3 { margin-bottom: .45rem; }
.pitch p, .pitch__text { display: block; color: var(--ink-soft); margin: 0 0 1.25rem; flex: 1; }
.pitch > .btn { align-self: flex-start; }
.pitch summary { list-style: none; cursor: pointer; }
.pitch summary::-webkit-details-marker { display: none; }
.pitch summary .btn { pointer-events: none; }
.pitch summary:focus-visible { outline: none; }
.pitch summary:focus-visible .btn { outline: 2px solid var(--forest); outline-offset: 3px; }
.pitch[open] summary .btn { display: none; }
.pitch[open] .form { animation: rise .5s var(--ease); }
.help__share { margin: 1.5rem 0 0; color: var(--ink-soft); }
.help__share .linkish { color: var(--ink); font-weight: 500; }
@media (min-width: 860px) {
  /* closed cards line up; once a form is open the others keep their own height */
  .help__grid { grid-template-columns: repeat(3, 1fr); gap: 1.25rem; align-items: stretch; }
  .help__grid:has(.pitch[open]) { align-items: start; }
}

.form { display: grid; gap: 1rem; align-content: start; }
.form > p { margin: 0; }
.form label { display: grid; gap: .2rem; font-size: var(--fs-s); font-weight: 500; color: var(--ink-soft); }
.form input:not([type="checkbox"]), .form select, .form textarea {
  font: 400 var(--fs-body)/1.4 var(--sans); color: var(--ink);
  width: 100%; padding: .5rem 0 .55rem;
  background: transparent; border: 0; border-bottom: 1px solid var(--ink-soft); border-radius: 0;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.form textarea { resize: vertical; border: 1px solid rgb(103 92 77 / .35); border-radius: 10px; padding: .6rem .75rem; background: rgb(255 255 255 / .45); }
.form select { appearance: none; background: var(--wave) right .2rem center / 20px 7px no-repeat; cursor: pointer; }
.form input:focus, .form select:focus, .form textarea:focus { outline: none; border-color: var(--forest); box-shadow: 0 1px 0 var(--forest); }
.form textarea:focus { box-shadow: 0 0 0 1px var(--forest); }
.form fieldset { border: 0; margin: 0; padding: 0; display: grid; gap: .4rem; }
.form legend { font-size: var(--fs-s); font-weight: 500; color: var(--ink-soft); margin-bottom: .5rem; padding: 0; }
.form .check { display: flex; gap: .65rem; align-items: center; font-weight: 400; color: var(--ink); cursor: pointer; }
.form .check input { width: 1.1rem; height: 1.1rem; margin: 0; accent-color: var(--forest); }
.form .btn { justify-self: start; margin-top: .25rem; }
.hp { position: absolute; left: -9999px; }


/* ---------- visit ---------- */

/* a striped market awning hangs over the visit block, from a dark rail; the same line runs along the foot like a counter edge */
.visit {
  --awning: 3.25rem; --rail: #6E3420;
  position: relative;
  background: linear-gradient(var(--paper), var(--paper)) top / 100% var(--awning) no-repeat, var(--terra-deep);
  color: var(--paper);
  border-block: 4px solid var(--rail);
  padding-block: calc(var(--awning) + clamp(2.5rem, 7vw, 4rem)) clamp(3rem, 7vw, 4.5rem);
}
.visit::before {
  content: ""; position: absolute; inset: 0 0 auto; height: calc(var(--awning) + 1.4rem);
  background: repeating-linear-gradient(90deg, var(--terra) 0 2.75rem, var(--clay-soft) 2.75rem 5.5rem);
  /* scalloped hem: a solid band, then a half-circle under every stripe */
  -webkit-mask: linear-gradient(#000, #000) top / 100% var(--awning) no-repeat,
                radial-gradient(circle 1.375rem at 1.375rem var(--awning), #000 98%, transparent) 0 0 / 2.75rem 100% repeat-x;
          mask: linear-gradient(#000, #000) top / 100% var(--awning) no-repeat,
                radial-gradient(circle 1.375rem at 1.375rem var(--awning), #000 98%, transparent) 0 0 / 2.75rem 100% repeat-x;
  filter: drop-shadow(0 6px 6px rgb(0 0 0 / .15));
}
.visit__grid { display: grid; gap: 2.5rem; align-items: center; justify-content: center; }
.visit__when { font: var(--accent-style) var(--accent-weight) calc(var(--fs-m) * var(--accent-scale))/1 var(--accent); color: var(--clay-soft); margin: 0 0 1.25rem; }
.visit address { font-style: normal; margin-bottom: 1rem; }
.visit__notes { color: var(--paper); }
.visit .actions { margin-top: 1.5rem; }
.visit__map { width: 100%; aspect-ratio: 4 / 3; border: 0; border-radius: 16px; }
.visit__photo { width: min(78%, 18rem); aspect-ratio: 1 / 1.05; margin-inline: auto; outline: 1px solid rgb(205 212 182 / .5); outline-offset: 12px; }
@media (min-width: 860px) {
  .visit__grid { grid-template-columns: minmax(0, 24rem) minmax(0, 18rem); gap: clamp(3rem, 6vw, 5rem); }
  .visit__photo { width: 100%; }
}

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

.footer { padding-block: clamp(2.5rem, 6vw, 3.5rem); }
.footer__grid { display: grid; gap: 1.5rem; }
.footer__name { display: flex; align-items: flex-end; gap: .4rem; font: var(--head-weight, 400) calc(var(--fs-l) * var(--head-scale))/1 var(--serif); margin: 0; }
.footer__links { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .75rem 2rem; }
.footer__small { color: var(--ink-soft); font-size: var(--fs-s); margin: 0; }
@media (min-width: 860px) {
  .footer__grid { grid-template-columns: auto 1fr; align-items: end; }
  .footer__links { justify-content: flex-end; }
  .footer__small { grid-column: 1 / -1; padding-top: 1.5rem; border-top: 1px solid var(--line); }
}

/* ---------- share dialog ---------- */

.share {
  border: 0; padding: 0; max-width: min(27rem, calc(100vw - 2rem));
  background: var(--paper); color: var(--ink);
  border-radius: 24px; box-shadow: 0 30px 80px rgb(47 42 34 / .35);
}
.share[open] { animation: rise .45s var(--ease); }
.share::backdrop { background: rgb(47 42 34 / .45); backdrop-filter: blur(3px); }
.share form { padding: 2.25rem 1.75rem 1.75rem; position: relative; }
.share h2 { font-size: calc(2.4rem * var(--accent-scale)); font-family: var(--accent); font-style: var(--accent-style); font-weight: var(--accent-weight); margin-bottom: 1.25rem; }
.share__list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .6rem; }
.share__done { margin: 1rem 0 0; font-weight: 500; color: var(--forest); }
.share__close, .recipe__close {
  position: absolute; top: .75rem; right: .75rem;
  width: 2.5rem; height: 2.5rem; border: 0; background: none;
  font: 1.8rem/1 var(--sans); color: var(--ink); cursor: pointer; border-radius: 50%;
}
.share__close:hover, .recipe__close:hover { background: var(--oat); }

/* ---------- "What do I do with this?": an index card from the kitchen drawer ---------- */

.recipe {
  border: 0; padding: 0; width: min(30rem, calc(100vw - 2rem)); max-height: calc(100svh - 2rem);
  color: var(--ink); border-radius: 6px; background: #FCF9F3;
  box-shadow: 0 30px 80px rgb(47 42 34 / .35);
  rotate: -1deg;
}
.recipe[open] { animation: rise .45s var(--ease); }
/* the card takes focus when it opens, rather than ringing the Save button */
.recipe:focus-visible { outline: none; }
.recipe::backdrop { background: rgb(47 42 34 / .45); backdrop-filter: blur(3px); }
.recipe form { padding: 1.25rem 1.5rem 1.75rem; position: relative; }
/* a red rule under the kicker, then faint blue lines under every row of text, like a ruled card */
.recipe__kicker {
  margin: 0 -1.5rem; padding: 0 4.5rem 0 1.5rem; height: 2.6rem; display: flex; align-items: center;
  border-bottom: 1.5px solid var(--terra);
  font: var(--accent-style) var(--accent-weight) calc(1.05rem * var(--accent-scale))/1.1 var(--accent); color: var(--terra-deep);
}
.recipe__head { display: flex; align-items: center; gap: 1rem; margin: 1rem 0 .6rem; }
.recipe__photo { flex: none; width: 4.5rem; aspect-ratio: 1; object-fit: cover; border-radius: 58% 42% 55% 45% / 47% 56% 44% 53%; }
.recipe h2 { margin: 0; font-size: calc(2.2rem * var(--head-scale)); }
.recipe__lines {
  margin: 0; line-height: 1.7rem;
  background: repeating-linear-gradient(transparent 0 calc(1.7rem - 1px), rgb(132 169 183 / .4) calc(1.7rem - 1px) 1.7rem);
}
.recipe__lines dt { margin-top: 1.7rem; font: var(--accent-style) var(--accent-weight) calc(1.15rem * var(--accent-scale))/1.7rem var(--accent); color: var(--forest); }
.recipe__lines dt:first-child { margin-top: 0; }
.recipe__lines dd { margin: 0; }
.recipe__save { display: flex; align-items: center; gap: 1rem; margin: 1.5rem 0 0; }
.recipe__save [role="status"] { font-weight: 500; color: var(--forest); }

/* ---------- thanks page ---------- */

.thanks { min-height: 100svh; display: grid; place-items: center; text-align: center; padding: var(--gutter); }
.thanks__inner { max-width: 28rem; }
.thanks h1 { font-size: calc(clamp(3.5rem, 12vw, 5rem) * var(--accent-scale)); font-family: var(--accent); font-style: var(--accent-style); font-weight: var(--accent-weight); margin-bottom: .75rem; }
.thanks p { color: var(--ink-soft); font-size: 1.1rem; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .strip { overflow-x: auto; }
  .strip__track { padding-inline: var(--gutter); }
  .strip li[aria-hidden] { display: none; }
  .map__road path[pathLength], .map__water path[pathLength] { stroke-dashoffset: 0; }
  .map__street, .map__label, .map__green, .map__compass, .map__footpath, .map__houses, .map__trees, .map__ripples, .map__hachures, .map__sights, .map__scale, .map__pencil, .map__blots, .map__pin text { opacity: 1; }
}

/* ---------- /fonts/: a page for choosing the font pairing ---------- */

.specimens { padding-block: 3rem 5rem; }
.specimens__head { max-width: 40rem; margin-bottom: 2.5rem; }
.specimens__head h1 { font-size: clamp(3rem, 8vw, 4.5rem); margin-bottom: .5rem; }
.specimens__head p { color: var(--ink-soft); }
.specimens__head code { font-size: .9em; background: var(--oat); padding: .1em .35em; border-radius: 4px; }
.specimens__grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.25rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 21rem), 1fr)); }
.specimen { font-family: var(--sans); background: #fffaf3; border: 1px solid var(--line); border-radius: 22px; padding: 1.5rem 1.5rem 1.75rem; display: flex; flex-direction: column; align-items: flex-start; }
.specimen--current { border-color: var(--terra); box-shadow: 0 0 0 2px var(--terra); }
.specimen__meta { font: 600 .95rem/1.35 var(--sans); margin-bottom: 1.25rem; }
.specimen__meta small { font-weight: 400; color: var(--ink-soft); font-size: .85rem; }
.specimen__num { display: inline-grid; place-items: center; width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--forest); color: var(--paper); font-size: .8rem; margin-right: .3rem; }
.specimen__now { font-size: .75rem; background: var(--terra); color: var(--paper); padding: .1rem .5rem; border-radius: 999px; margin-left: .3rem; }
.specimen__name { font-size: calc(3.4rem * var(--head-scale)); line-height: .9; letter-spacing: -.03em; margin: 0; }
.specimen__name { white-space: nowrap; }
.specimen__name span { display: inline-block; }
.specimen__name span + span { font-style: var(--accent-style); color: var(--leaf); }
.specimen__tagline { font: var(--accent-style) var(--accent-weight) calc(1.35rem * var(--accent-scale))/1.2 var(--accent); color: var(--terra-deep); margin: .75rem 0 1.1rem; }
.specimen__when .when__time { font-size: 2.2rem; }
.specimen__when .when__where { margin-top: .5rem !important; }
.specimen__body { color: var(--ink-soft); font-size: .98rem; margin: 1.1rem 0 1.25rem; flex: 1; }

/* the "previewing a font" note shown on the home page with ?font=N */
.font-preview {
  position: fixed; z-index: 30; left: 50%; bottom: 1rem; translate: -50% 0;
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; justify-content: center;
  width: max-content; max-width: calc(100vw - 2rem);
  padding: .6rem .7rem .6rem 1.2rem; border-radius: 999px;
  background: var(--ink); color: var(--paper); font: 500 .92rem/1.3 var(--sans);
  box-shadow: 0 14px 40px rgb(0 0 0 / .3);
}
.font-preview a { color: var(--clay); }
.font-preview nav { display: flex; gap: .4rem; }
.font-preview nav a { display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: 50%; background: rgb(255 255 255 / .1); color: var(--paper); text-decoration: none; }
.font-preview nav a:hover { background: var(--terra); }
