@import url("https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,700&family=Instrument+Sans:wght@400;500&display=swap");

:root {
  --cocoa: #1C120B; --cream: #F4EADA; --cream-soft: #C9B9A2; --cocoa-soft: #6B584A;
  --mango: #E39B2F; --okra: #4B6B3C; --pepper: #B23A24;
  --cocoa-rgb: 28 18 11; --cream-rgb: 244 234 218;
  --sc-canvas: var(--cocoa); --sc-surface: #26190F;
  --sc-ink: var(--cream); --sc-ink-soft: var(--cream-soft);
  --sc-accent: var(--mango); --sc-accent-ink: var(--cocoa);
  --sc-font-display: "Fraunces", Georgia, serif;
  --sc-font-text: "Instrument Sans", system-ui, sans-serif;
  --sc-shadow-color: 24 40% 4%;
  --dock-w: 288px; --dock-h: 162px; --dock-gap: 20px; --dock-top: 84px;
}
html { background: var(--cocoa); }
body { margin: 0; }

/* Two grounds, hard cuts. No drift. */
.ground--cocoa { background: var(--cocoa); color: var(--cream); --sc-ink: var(--cream); --sc-ink-soft: var(--cream-soft); --sc-surface: #26190F; }
.ground--cream { background: var(--cream); color: var(--cocoa); --sc-ink: var(--cocoa); --sc-ink-soft: var(--cocoa-soft); --sc-surface: #FBF5EA;
  --sc-edge: inset 0 1px 0 rgba(255,255,255,0.6); --sc-shadow-color: 30 30% 20%; }
.ground--cream .sc-scrim { background: linear-gradient(to top, rgb(var(--cream-rgb) / 0.92), rgb(var(--cream-rgb) / 0)); }

/* Bar: wordmark and the one action. */
.bar { position: fixed; inset: 0 0 auto 0; z-index: var(--sc-z-chrome); display: flex; justify-content: space-between; align-items: center;
  padding: calc(18px + env(safe-area-inset-top)) var(--sc-gutter) 18px; pointer-events: none; }
.bar > * { pointer-events: auto; }
/* The bar's own scrim: a sibling sized to the bar, so the wordmark and Talk to us hold contrast
   when the land tilts and pale sky comes up behind them. Not a full-frame overlay. */
.bar-scrim { position: fixed; inset: 0 0 auto 0; height: calc(118px + env(safe-area-inset-top)); z-index: calc(var(--sc-z-chrome) - 2); pointer-events: none;
  background: linear-gradient(to bottom, rgb(var(--cocoa-rgb) / 0.62), rgb(var(--cocoa-rgb) / 0.28) 55%, rgb(var(--cocoa-rgb) / 0)); }
.bar__mark { display: grid; }
.bar__mark img { grid-area: 1 / 1; height: 42px; width: auto; display: block; transition: opacity 150ms var(--sc-ease-out); }
.bar__talk { color: var(--cream); text-decoration: none; font: 500 var(--sc-t-sm)/1 var(--sc-font-text); letter-spacing: 0.06em; text-transform: uppercase;
  border-bottom: 1px solid currentColor; padding-bottom: 4px; transition: color 150ms var(--sc-ease-out); }
@media (hover: hover) and (pointer: fine) { .bar__talk:hover { color: var(--mango); } }

/* Dock: the Estate Table. #dock is a plain wrapper; .dock__view is the fixed layer that is
   full-bleed in the hero and clipped and scaled into the corner after. The label and the list
   are fixed on their own at chrome height, outside the clip. */
.dock__view { position: fixed; inset: 0; z-index: calc(var(--sc-z-chrome) - 1); pointer-events: none; clip-path: inset(0 0 0 0 round 0px); }
.dock.is-hero .dock__view { z-index: 0; }
.dock .hero__sky { position: absolute; inset: 0; opacity: var(--sky, 1); transform: translateY(var(--sky-ty, 0)); }
.dock .hero__sky img { position: absolute; width: 100%; height: 100%; object-fit: cover; max-width: none; }
.dock__frame { position: absolute; left: 50%; top: 50%; width: var(--frame-w, 100vw); height: var(--frame-h, 56.25vw);
  transform: translate(-50%, -50%) translate(var(--tx, 0px), var(--ty, 0px)) scale(var(--s, 1)); transform-origin: center; will-change: transform; }
.dock__frame > canvas, .dock__frame > svg, .dock__frame > picture, .dock__poster { position: absolute; inset: 0; width: 100%; height: 100%; display: block; max-width: none; }
.dock__poster { object-fit: cover; transition: opacity 400ms var(--sc-ease-out); }
.dock.is-docked .dock__frame { pointer-events: auto; cursor: pointer; }
.dock__label { position: fixed; z-index: var(--sc-z-chrome); margin: 0; padding: var(--sc-1) var(--sc-2); border-radius: var(--sc-r-sm);
  background: rgb(var(--cocoa-rgb) / 0.78); color: var(--cream); font: 500 var(--sc-t-xs)/1.2 var(--sc-font-text); letter-spacing: 0.08em; text-transform: uppercase;
  opacity: 0; pointer-events: none; transition: opacity 300ms var(--sc-ease-out); }
.dock.is-docked .dock__label { opacity: 1; }
/* Visually hidden until a link inside it has focus. Then only the focused link shows, as a pill
   beside the docked map (left of it on desktop, above it on phones), never on top of it. */
.dock__list { position: fixed; z-index: calc(var(--sc-z-chrome) + 1); margin: 0; padding: 0; list-style: none;
  top: calc(var(--dock-top) + env(safe-area-inset-top)); right: calc(var(--dock-gap) + var(--dock-w) + 12px);
  width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.dock__list:focus-within { width: auto; height: auto; overflow: visible; clip: auto; clip-path: none; }
.dock__list a { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); }
.dock__list a:focus-visible { position: static; display: block; width: auto; height: auto; overflow: visible; clip: auto; clip-path: none;
  background: var(--cream); color: var(--cocoa); padding: 10px 14px; border-radius: 6px; text-decoration: none;
  font: 500 var(--sc-t-sm)/1.2 var(--sc-font-text); box-shadow: 0 6px 18px rgb(var(--cocoa-rgb) / 0.35); outline: 2px solid var(--mango); outline-offset: 3px; }

/* Hero */
.hero, .hero [data-sc-stage] { background: transparent; }
.hero__plane { position: absolute; inset: 0; overflow: hidden; }
.hero__mist { z-index: 2; background: linear-gradient(to top, rgb(var(--cream-rgb) / 0.18), rgb(var(--cream-rgb) / 0) 38%); mix-blend-mode: screen; }
/* The corner scrim, densified for this hero only: the headline rises through this corner while the
   land tilts behind it. Density sits where the copy travels; the right half stays untouched. */
.hero .sc-scrim--dense { z-index: 2; --scrim-w: 90%; --scrim-h: 84%; --scrim-y: 82%; --scrim-a0: 0.88; --scrim-a1: 0.74; --scrim-a2: 0.42; }
/* Branch: the leaves start clear of the wordmark at any width; sized by height too, so it never
   hangs into the headline on short screens. It drifts up while the headline rises. */
.hero__branch { --branch-w: min(58vw, 900px, 82vh); position: absolute; z-index: 4; width: var(--branch-w); height: auto;
  left: calc(var(--sc-gutter) + 175px - 0.144 * var(--branch-w)); top: -8vh; }
.hero__branch img { width: 100%; height: auto; max-width: none; display: block; }
/* Copy. The cue writes transform on .hero__copy and on .hero__sub, so the motion lives on the h1
   and on .hero__subwrap. The sub line follows the headline's foot: it moves by the headline's rise
   minus what the headline's height loses to the scale (--h1-h is measured in hero.js). */
.hero__copy { z-index: 3; max-width: min(64rem, 86vw); --h1-rise: -24vh; }
.hero__copy .sc-display { width: fit-content; text-wrap: balance;
  transform: translateY(calc(var(--sc-p) * var(--h1-rise))) scale(calc(1 - var(--sc-p) * 0.35)); transform-origin: left top; }
.hero__subwrap { transform: translateY(calc(var(--sc-p) * var(--h1-rise) - var(--sc-p) * 0.35 * var(--h1-h, 0px))); }
.hero__sub { max-width: 34ch; margin-top: var(--sc-4); color: var(--cream); }
.hero__leaf { display: none; }
/* The static hero (reduced motion, or no WebGL: html.sc-static from js/hero.js): the Table is docked
   from the start, so the estate itself stands behind the headline as a still, dimmed plane under the
   scrim. The same files as the Table's poster, so it costs no extra request. */
.hero__ground { display: none; position: absolute; inset: 0; z-index: 1; opacity: 0.62; }
.sc-static .hero__ground { display: block; }
@media (prefers-reduced-motion: reduce) { .hero__ground { display: block; } }
.hero__ground img { width: 100%; height: 100%; object-fit: cover; max-width: none; display: block; }
.hero__floor { position: absolute; inset: auto 0 0 0; height: 220px; z-index: 2; background: linear-gradient(to bottom, rgb(var(--cocoa-rgb) / 0), var(--cocoa)); pointer-events: none; }

@media (max-width: 860px) {
  :root { --dock-w: 144px; --dock-h: 81px; --dock-gap: 12px; }
  .hero .sc-display--xl { font-size: var(--sc-t-2xl); }
  .hero__copy { --h1-rise: -10vh; }
  /* Copy spans the width here, so the density is a band, not a corner. */
  .hero .sc-scrim--dense { background: linear-gradient(to top, rgb(var(--cocoa-rgb) / 0.92) 0%, rgb(var(--cocoa-rgb) / 0.85) 34%, rgb(var(--cocoa-rgb) / 0.55) 52%, rgb(var(--cocoa-rgb) / 0) 72%);
    /* The relief: as the Table lifts and leaves, the band lets go of the land, full until p 0.45 and
       down to 0.45 by 0.75. Below that the headline drops under 3:1 on the lit land (0.35 measured 2.8:1),
       so 0.45 is the floor: the land comes up and the headline still holds 3:1 at the glyph. */
    opacity: calc(1 - 0.55 * clamp(0, (var(--sc-p, 0) - 0.45) / 0.3, 1)); }
  .hero__branch { display: none; }
  /* The leaf hangs upper right, above the copy block, and drifts up away from it. */
  .hero__leaf { display: block; position: absolute; right: -4vw; top: 16vh; width: 40vw; max-width: none; height: auto; z-index: 4; }
  .dock__label { font-size: 0.7rem; }
  .dock__list { top: auto; right: var(--dock-gap); bottom: calc(var(--dock-gap) + var(--dock-h) + 12px + env(safe-area-inset-bottom)); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__copy .sc-display, .hero__subwrap { transform: none; }
}

.eyebrow { margin: 0 0 var(--sc-3); font: 500 var(--sc-t-xs)/1 var(--sc-font-text); letter-spacing: 0.1em; text-transform: uppercase; color: var(--okra); }

/* Docked frame: the view is clipped, so its lift is a plate behind it at the docked corner. */
.dock::before { content: ""; position: fixed; z-index: calc(var(--sc-z-chrome) - 1); pointer-events: none;
  top: calc(var(--dock-top) + env(safe-area-inset-top)); right: var(--dock-gap); width: var(--dock-w); height: var(--dock-h);
  border-radius: 10px; box-shadow: var(--sc-e2); opacity: 0; transition: opacity 300ms var(--sc-ease-out); }
.dock.is-docked::before { opacity: 1; }
@media (max-width: 860px) {
  .dock::before { top: auto; bottom: calc(var(--dock-gap) + env(safe-area-inset-bottom)); }
}

/* Dense scrim: a corner of density sized by --scrim-w / --scrim-h, anchored on the copy's side.
   Phones get a tall band instead, because the copy spans the width there. */
.sc-scrim--dense { --scrim-x: 0%; --scrim-y: 100%; --scrim-w: 72%; --scrim-h: 100%; --scrim-a0: 0.94; --scrim-a1: 0.88; --scrim-a2: 0.6;
  background: radial-gradient(ellipse var(--scrim-w) var(--scrim-h) at var(--scrim-x) var(--scrim-y),
    rgb(var(--cocoa-rgb) / var(--scrim-a0)) 0%, rgb(var(--cocoa-rgb) / var(--scrim-a1)) 42%, rgb(var(--cocoa-rgb) / var(--scrim-a2)) 68%, rgb(var(--cocoa-rgb) / 0) 100%); }
.sc-scrim--trail.sc-scrim--dense { --scrim-x: 100%; }
@media (max-width: 860px) {
  .sc-scrim--dense { background: linear-gradient(to top,
    rgb(var(--cocoa-rgb) / 0.88) 0%, rgb(var(--cocoa-rgb) / 0.78) 34%, rgb(var(--cocoa-rgb) / 0.42) 52%, rgb(var(--cocoa-rgb) / 0) 66%); }
}

/* Copy over the two clip scenes: a readable measure, and the stack gap so the display
   descenders clear the first line of body. Trail copy is right-aligned, so its measure hugs the right. */
.scene-copy .sc-display { text-wrap: balance; }
.scene-copy .sc-body { max-width: 44ch; }
.scene-copy .sc-body + .sc-body { margin-top: var(--sc-3); }
.sc-copy--trail.scene-copy .sc-body { margin-left: auto; }
@media (max-width: 860px) {
  .scene-copy .sc-display--lg { font-size: var(--sc-t-2xl); }
  /* The docked Table and its label sit bottom right here: the copy's last line stands clear above them. */
  .scene-copy.sc-copy { bottom: calc(var(--dock-h) + var(--dock-gap) + 20px + env(safe-area-inset-bottom)); }
}
/* Short phones: the copy block reaches higher up the frame, into the clip's sun, so the band does too. */
@media (max-width: 860px) and (max-height: 700px) {
  .sc-scrim--dense { background: linear-gradient(to top,
    rgb(var(--cocoa-rgb) / 0.9) 0%, rgb(var(--cocoa-rgb) / 0.84) 42%, rgb(var(--cocoa-rgb) / 0.62) 62%, rgb(var(--cocoa-rgb) / 0) 84%); }
}

/* Orchards: a stacked head, the row full width, then a two-up whose bottoms align. */
.orchards { padding-block: calc(var(--sc-section) * 0.7) calc(var(--sc-section) * 0.5); }
.orchards__head { margin-bottom: var(--sc-7); }
.orchards__head .sc-display { max-width: 18ch; text-wrap: balance; }
.orchards figure { margin: 0; }
.orchards figure img { width: 100%; height: auto; display: block; border-radius: var(--sc-r-sm); object-fit: cover; }
.orchards figcaption { margin-top: var(--sc-2); font-size: var(--sc-t-xs); color: var(--sc-ink-soft); }
.orchards__hero img { aspect-ratio: 16 / 9; }
.orchards__two { display: grid; grid-template-columns: 5fr 7fr; gap: var(--sc-7); margin-top: var(--sc-8); align-items: stretch; }
.orchards__a img { aspect-ratio: 4 / 5; object-position: 30% 50%; }
.orchards__col { display: flex; flex-direction: column; justify-content: space-between; gap: var(--sc-6); }
.orchards__col .sc-body { max-width: 44ch; }
.orchards__b img { aspect-ratio: 3 / 2; }
@media (max-width: 860px) {
  .orchards__two { grid-template-columns: 1fr; gap: var(--sc-6); margin-top: var(--sc-6); }
  .orchards__a { width: 78%; }
  .orchards__b { width: 78%; margin-left: auto; }
}

/* Fields: the rail. Every card stands on one ground line; the hairline rides on the heading. */
.rail { display: flex; align-items: flex-end; gap: var(--sc-4); padding: 0 var(--sc-gutter) 22vh; height: 100vh; box-sizing: border-box; }
.rail__lead { flex: 0 0 clamp(18rem, 26vw, 24rem); }
.rail__end { flex: 0 0 clamp(14rem, 18vw, 16rem); color: var(--cocoa-soft); }
/* Sized so the rail overflows about 3,900px at 1440: 2.2px of travel per px of scroll over a 3.0 span. */
.crop { flex: 0 0 clamp(12rem, 15.5vw, 14rem); container-type: inline-size; }
.crop h3 { margin: 0 0 var(--sc-2); padding-top: var(--sc-4); border-top: 1px solid var(--okra); font: 700 var(--sc-t-lg)/1.1 var(--sc-font-display); }
.crop p { margin: 0; min-height: 3lh; font-size: var(--sc-t-sm); color: var(--cocoa-soft); }
.crop--photo { flex-basis: clamp(14rem, 17vw, 15rem); }
.crop--photo img { width: 100%; height: auto; display: block; border-radius: var(--sc-r-sm); margin-bottom: var(--sc-4); aspect-ratio: 4 / 5; object-fit: cover; }
/* Cards without a photograph carry the crop's name in the photograph's place: one display word sized
   to the card at 21.5cqi (two-word names wrap to two lines; Watermelon, the one single word too long
   for it, steps down to 18.1cqi to sit flush). The hairline moves under the word, so every card still stands on one ground
   line: the uses line's box takes the small heading's height too, and short lines leave the slack below. */
.crop:not(.crop--photo) h3 { margin: 0 0 calc(var(--sc-4) + var(--lift, 0em)); padding: 0; border: 0; font: 500 var(--fit, 21.5cqi)/0.98 var(--sc-font-display);
  letter-spacing: var(--sc-track-tight); color: var(--cocoa); text-wrap: balance; }
.crop--long { --fit: 18.1cqi; }
.crop:not(.crop--photo) p { padding-top: var(--sc-4); border-top: 1px solid var(--okra);
  min-height: calc(1px + var(--sc-4) + 1.1 * var(--sc-t-lg) + var(--sc-2) + 3lh); }
/* A planted row, not a repeated label: the words stand at three heights in turn, and the step also keeps
   two neighbouring words from reading as one phrase when the rail crops them at the viewport edge. */
.crop:not(.crop--photo):nth-child(3n + 1) h3 { --lift: 0.55em; }
.crop:not(.crop--photo):nth-child(3n + 2) h3 { --lift: 1.2em; }
/* Cards settle in sequence, leading the travel by a card and a half. */
@media (prefers-reduced-motion: no-preference) {
  .crop { opacity: calc(0.7 + 0.3 * clamp(0, var(--sc-p) * 22 - var(--i, 0) + 1.5, 1)); }
}
@media (max-width: 860px) {
  .crop { flex-basis: 60vw; } .crop--photo { flex-basis: 66vw; }
}

.silence { height: 40vh; }

/* Chrome over the cream grounds. js/bar.js sets html.on-cream while a cream section is under the
   bar's midline; the bar re-inks and its scrim turns cream, a hard cut like the grounds themselves. */
.bar__mark-ink, .on-cream .bar__mark-light { opacity: 0; }
.on-cream .bar__mark-ink { opacity: 1; }
.on-cream .bar__talk { color: var(--cocoa); }
@media (hover: hover) and (pointer: fine) { .on-cream .bar__talk:hover { color: var(--okra); } }
.on-cream .bar-scrim { background: linear-gradient(to bottom, rgb(var(--cream-rgb) / 0.9), rgb(var(--cream-rgb) / 0.5) 55%, rgb(var(--cream-rgb) / 0)); }
/* Mango is 2.2:1 on cream; the focus ring in the bar takes okra there. */
.on-cream .bar :focus-visible { outline-color: var(--okra); }

/* 6 · The processing house: the peak. Centred at 1280px and up, the only centred act on the page.
   The engine's cue writes transform and opacity on the title, the captions and the closing line,
   so none of those is centred with a transform: the title and the caption centre with auto margins,
   and the parts carry their own travel on the figure (translate) and the image (rotate, scale), never
   on the cued figcaption. js/peak.js writes from the act's progress: --e per part (its travel out of
   the assembled plant), --dim (the parts leaving for the jar), --jar and --sweep. */
.peak__stage { display: grid; place-items: center; }
.peak__ground { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.35; max-width: none; }
/* One line between the docked Table and its mirror on the left: the docked map sits top right at
   chrome height, so the title's size is capped by the room left of it (Fraunces widens as it shrinks:
   the line measures 9.2 to 9.9 times its size). */
.peak__title { position: absolute; left: 0; right: 0; top: 14vh; z-index: 3; margin: 0 auto; width: max-content; max-width: 90vw; text-align: center; text-wrap: balance;
  font-size: clamp(2.2rem, calc((100vw - 2 * (var(--dock-w) + var(--dock-gap) + 24px)) / 10), var(--sc-t-4xl)); }
/* Narrow desktops: there is no room for one centred line beside the docked map, so the title sets
   left at the gutter, two lines, and stops short of the map. */
@media (min-width: 861px) and (max-width: 1279px) {
  .peak__title { right: auto; left: var(--sc-gutter); margin: 0; text-align: left; font-size: var(--sc-t-3xl);
    width: auto; max-width: calc(100vw - var(--sc-gutter) - var(--dock-w) - 2 * var(--dock-gap)); top: 12vh; }
  .peak .part--kernels { --vy: -4vh; }
}
.plant { position: absolute; inset: 0; z-index: 2; opacity: calc(1 - var(--dim, 0)); }
/* Each part lerps out of a home pose (--hx/--hy/--hr/--hs) into its exploded pose (--vx/--vy/--rot, scale 1)
   with its own --e (the scale runs on --es, the first half of the same window, so a part is back to
   its own size before it is far from the centre). At home the four make one plant: the stalk upright on the centre line, the husk
   angled off it at mid-height with the cob and the kernels nested in it. Home offsets are in --hz vh and
   home scale is --k (viewport height over part width, from js/peak.js) times --hsf, so the assembled
   plant is the same share of the frame at any width. --e falls back to --explode (1 under reduced motion). */
.part { --e: var(--explode, 0); --hz: 1; position: absolute; left: 50%; top: 52%; margin: 0; width: clamp(140px, 22vw, 320px);
  transform: translate(-50%, -50%)
    translate(calc(var(--hx) * var(--hz) * 1vh * (1 - var(--e)) + var(--vx) * var(--e)),
              calc(var(--hy) * var(--hz) * 1vh * (1 - var(--e)) + var(--vy) * var(--e) - var(--lift, 0vh) * var(--jar, 0))); }
.part img { width: 100%; height: auto; display: block; max-width: none;
  transform: rotate(calc(var(--hr) * (1 - var(--e)) + var(--rot) * var(--e))) scale(calc(var(--k, 1) * var(--hsf) * var(--hz) * (1 - var(--es, var(--e))) + var(--es, var(--e))));
  filter: drop-shadow(0 18px 24px rgb(0 0 0 / 0.45)); }
/* The cutouts sit in a square with wide transparent margins top and bottom (the subject fills roughly
   28% to 73% of the height), so the caption hangs from the subject's foot, not from the box. */
.part figcaption { position: absolute; top: var(--cap-top, 76%); left: 0; width: 26ch; margin: 0; font: 500 var(--sc-t-sm)/1.4 var(--sc-font-text); color: var(--cream); text-wrap: pretty; }
.part--stalk   { z-index: 1; --hx: 0;   --hy: 7;  --hr: -70deg; --hsf: 0.757; --vx:  28vw; --vy:  22vh; --rot:  -8deg; }
.part--husk    { z-index: 2; --hx: 6.5; --hy: 0;  --hr: -61deg; --hsf: 0.3;   --vx:  30vw; --vy:  -5vh; --rot:  12deg; }
.part--cob     { z-index: 3; --hx: 5.5; --hy: 0.5; --hr: -44deg; --hsf: 0.28; --vx: -28vw; --vy:  20vh; --rot:   9deg; }
.part--kernels { z-index: 4; --hx: 6;   --hy: 0;  --hr: -55deg; --hsf: 0.165; --vx: -30vw; --vy: -15vh; --rot: -14deg; }
.part--husk figcaption, .part--stalk figcaption { left: auto; right: 0; text-align: right; }

/* The jar: the photographic cutout with the emblem composited on its blank label, a contact shadow
   that stays on the ground, and a light sweep masked to the jar's own alpha. It rises 8vh, grows from
   0.9 and settles out of a 2.5deg tilt over beat B; reduced motion keeps the opacity only. */
.jar { position: absolute; left: 50%; top: 50%; width: min(27vh, 40vw); aspect-ratio: 486 / 820; z-index: 4;
  transform: translate(-50%, -50%); opacity: var(--jar, 0); }
.jar__body { position: absolute; inset: 0; transform-origin: 50% 100%;
  transform: translateY(calc((1 - var(--jar, 0)) * var(--jar-rise, 8vh))) scale(calc(0.9 + 0.1 * var(--jar, 0))) rotate(calc((1 - var(--jar, 0)) * -2.5deg)); }
.jar__img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; max-width: none; }
/* Measured on the cutout: the blank label spans x 4.5% to 95% and y 34.5% to 82% of the image. */
.jar__emblem { position: absolute; left: 49.6%; top: 58.4%; width: 56%; height: auto; max-width: none; transform: translate(-50%, -50%); mix-blend-mode: multiply; opacity: 0.92; }
.jar__sweep { position: absolute; inset: 0; overflow: hidden; mix-blend-mode: screen; opacity: 0.35;
  -webkit-mask-image: url(assets/jar.webp); mask-image: url(assets/jar.webp); -webkit-mask-size: 100% 100%; mask-size: 100% 100%; }
.jar__sweep i { position: absolute; top: 0; bottom: 0; left: -100%; width: 100%;
  background: linear-gradient(105deg, rgb(var(--cream-rgb) / 0) 20%, rgb(var(--cream-rgb) / 0.95) 50%, rgb(var(--cream-rgb) / 0) 80%);
  transform: translateX(calc(var(--sweep, 0) * 200%)); }
.jar__shadow { position: absolute; left: 50%; bottom: -3%; width: 130%; height: 10%; transform: translateX(-50%) scaleX(calc(0.9 + 0.1 * var(--jar, 0)));
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgb(0 0 0 / 0.6), rgb(0 0 0 / 0.3) 45%, rgb(0 0 0 / 0) 100%); }
.peak__caption { position: absolute; left: 0; right: 0; bottom: 10vh; z-index: 5; margin: 0 auto; width: min(38ch, 100% - 2 * var(--sc-gutter)); text-align: center; color: var(--cream); }
@media (max-width: 860px) {
  .peak__title { font-size: var(--sc-t-2xl); top: 10vh; width: 90vw; }
  /* --lift: on a phone the leaving parts rise a little as the jar arrives, clearing the closing line. */
  .part { width: 34vw; --lift: 10vh; --hz: 0.8; }
  /* Four corners of the band between the title and the docked Table, kept clear of both. */
  .part--kernels { --vx: -26vw; --vy: -22vh; } .part--husk { --vx: 26vw; --vy: -14vh; } .part--cob { --vx: -26vw; --vy: 9vh; } .part--stalk { --vx: 26vw; --vy: 13vh; }
  .part figcaption { width: 15ch; font-size: 0.875rem; }
  .jar { width: min(25vh, 40vw); top: 46%; }
  /* The docked Table sits bottom right here, so the closing line stands clear above it. */
  .peak__caption { bottom: calc(var(--dock-h) + var(--dock-gap) + 36px + env(safe-area-inset-bottom)); }
}
@media (max-width: 860px) and (max-height: 700px) {
  .jar { width: min(23vh, 38vw); top: 44%; --jar-rise: 3vh; }
}
/* Reduced motion: no travel anywhere in the act. The parts sit apart, the jar only fades in. */
@media (prefers-reduced-motion: reduce) {
  .part { --lift: 0vh; }
  .jar__body { transform: none; }
  .jar__shadow { transform: translateX(-50%); }
  .jar__sweep { display: none; }
}
@media (prefers-reduced-motion: reduce) and (max-width: 860px) {
  .part--cob { --vy: -1vh; } .part--stalk { --vy: 3vh; }
}

/* 7 · The people: cream, quiet, documentary */
.people__grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sc-6) var(--sc-7); }
.people__copy { grid-column: 1 / -1; max-width: 60ch; }
.people figure { margin: 0; }
/* The right column sits a step lower. A translate moves both even figures together, so figure 4 keeps
   its full gap under figure 2's caption; the grid's foot makes room for the step. */
.people figure:nth-of-type(even) { translate: 0 var(--sc-8); }
.people__grid { padding-bottom: var(--sc-8); }
.people img { width: 100%; height: auto; display: block; border-radius: var(--sc-r-sm); }
.people figcaption { margin-top: var(--sc-2); font-size: var(--sc-t-xs); color: var(--cocoa-soft); }

/* 8 · The gate: the close. A flow act at least a viewport tall; js/close.js flies the docked Table into
   #landing as the section enters and keeps it on the rect after. The content sits on the foot of the
   frame when it fits and the stage grows when it does not; the top padding clears the bar either way. */
.gate { min-height: 100svh; }
.gate__stage { position: relative; min-height: 100svh; display: grid; align-content: end; overflow: clip; }
.gate__ground { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; max-width: none; }
.gate__inner { position: relative; z-index: 2; display: grid; grid-template-columns: 6fr 5fr; gap: var(--sc-8); padding: calc(96px + env(safe-area-inset-top)) var(--sc-gutter) 0; align-items: end; }
/* Wide screens: the visit sits on the right, under the trail corner scrim and under the docked corner,
   so the Table drops straight down into it and never crosses the form on the way. It holds no
   controls, so the focus order is unchanged; the reading order (visit, then the form) is the source's. */
.gate__visit { order: 2; }
/* Wide screens: the frame flies down across the heading on its way to #landing, so the heading arrives
   with it over the last eighth of the flight (--land, written by js/close.js; 1 without script).
   On phones the flight rises from below and never crosses it, so it simply shows. */
@media (min-width: 861px) {
  .gate__visit > h2 { opacity: clamp(0, (var(--land, 1) - 0.88) * 8.4, 1); }
}
/* Wide screens: a column of density under the visit column on the right, fading out above it, so the
   sky and the gate keep their light. Phones replace it with a band at the head (below). */
.gate .sc-scrim--trail { background: linear-gradient(to left, rgb(var(--cocoa-rgb) / 0.86) 0%, rgb(var(--cocoa-rgb) / 0.8) 38%, rgb(var(--cocoa-rgb) / 0.45) 48%, rgb(var(--cocoa-rgb) / 0) 60%);
  -webkit-mask-image: linear-gradient(to bottom, transparent 8%, #000 30%); mask-image: linear-gradient(to bottom, transparent 8%, #000 30%); }
.gate__landing { width: 100%; aspect-ratio: 16 / 9; margin-top: var(--sc-4); border-radius: 10px; }
.gate__itinerary { margin: var(--sc-4) 0 0; padding-left: 1.2em; columns: 2; font-size: var(--sc-t-sm); color: var(--cream-soft); }
.talk { display: grid; gap: var(--sc-3); background: rgb(var(--cocoa-rgb) / 0.84); padding: var(--sc-6); border-radius: var(--sc-r-md); box-shadow: var(--sc-e2); }
.talk label { display: grid; gap: 6px; font: 500 var(--sc-t-xs)/1 var(--sc-font-text); letter-spacing: 0.06em; text-transform: uppercase; color: var(--cream-soft); }
.talk input, .talk select, .talk textarea { font: 400 var(--sc-t-base)/1.4 var(--sc-font-text); color: var(--cream); background: rgb(var(--cream-rgb) / 0.06); border: 1px solid var(--sc-hairline-strong); border-radius: var(--sc-r-sm); padding: 10px 12px; min-height: 44px; }
.talk input:focus-visible, .talk select:focus-visible, .talk textarea:focus-visible { outline: 2px solid var(--mango); outline-offset: 2px; }
.cta { justify-self: start; font: 500 var(--sc-t-base)/1 var(--sc-font-text); background: var(--mango); color: var(--cocoa); border: 0; border-radius: var(--sc-r-pill); padding: 16px 28px; cursor: pointer; min-height: 48px; }
.cta:disabled { background: var(--cocoa-soft); color: var(--cream); cursor: not-allowed; }
.talk__note { margin: 0; font-size: var(--sc-t-xs); color: var(--cream-soft); }
.foot { position: relative; z-index: 2; display: flex; gap: var(--sc-4); align-items: center; padding: var(--sc-6) var(--sc-gutter) var(--sc-5); font-size: var(--sc-t-xs); color: var(--cream-soft); }
.foot a { color: inherit; }
/* The Table while the close owns it: the corner's label and shadow plate stay behind. */
.dock.is-away .dock__label, .dock.is-away::before { opacity: 0; }
/* Short desktops: the close fits one screen. A smaller heading, name and organisation side by side,
   three message rows and a tighter plate. */
@media (min-width: 861px) and (max-height: 820px) {
  .gate__inner { padding-top: calc(84px + env(safe-area-inset-top)); }
  .talk { grid-template-columns: 1fr 1fr; gap: var(--sc-2) var(--sc-4); padding: var(--sc-5) var(--sc-6); }
  .talk > * { grid-column: 1 / -1; }
  .talk > label:nth-of-type(1), .talk > label:nth-of-type(2) { grid-column: auto; }
  .talk .sc-display--lg { font-size: var(--sc-t-2xl); letter-spacing: var(--sc-track-snug); }
  .talk textarea { height: calc(3 * 1.4em + 22px); }
  .foot { padding-block: var(--sc-4); }
}
@media (max-width: 860px) {
  .people__grid { grid-template-columns: 1fr; padding-bottom: 0; } .people figure:nth-of-type(even) { translate: none; }
  .gate__inner { grid-template-columns: 1fr; gap: var(--sc-5); }
  .gate__visit { order: 0; }
  /* The close runs taller than a phone, so the density sits under the visit block at the head of the
     stage (sized in px, as the block is). The form below carries its own plate. */
  .gate .sc-scrim--trail { -webkit-mask-image: none; mask-image: none; background: linear-gradient(to bottom, rgb(var(--cocoa-rgb) / 0.9) 0, rgb(var(--cocoa-rgb) / 0.88) 560px, rgb(var(--cocoa-rgb) / 0.5) 650px, rgb(var(--cocoa-rgb) / 0) 760px); }
  .gate__itinerary { columns: 1; }
  .talk { padding: var(--sc-5); }
}
