@charset "utf-8";
/* =========================================================================
   HATTI
   Chai, sold by the tin.

   Contents
   00  Fonts
   01  Tokens
   02  Reset & base
   03  Type
   04  Layout primitives
   05  Devices — plate, awning, ledger, ticket, arch
   06  Buttons & links
   07  Chrome — notice, nav, menu, cart, footer
   08  Illustration
   09  The tin & product furniture
   10  Photography slots
   11  Page sections
   12  Utilities, motion, print
   ========================================================================= */

/* 00  Fonts ------------------------------------------------------------- */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/fraunces-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
/* Logo only. Subset to the eight glyphs in "hatti"/"HATTI" — under 4 KB.
   Never used for running text. */
@font-face {
  font-family: 'Hatti Logo';
  font-style: normal;
  font-weight: 800 900;
  font-display: block;
  src: url('/assets/fonts/grenze-gotisch-logo.woff2') format('woff2');
  unicode-range: U+41, U+48-49, U+54, U+61, U+68-69, U+74;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/assets/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('/assets/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
    U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* 01  Tokens ------------------------------------------------------------ */

:root {
  /* Hatti's brand palette, as supplied by the client. These four are the
     whole system — every field, every rule, every piece of type. */
  --cream: #f7f3ec;   /* Cream        */
  --red: #c72222;     /* Primary Red  */
  --red-deep: #7a1113; /* Dark Red    */
  --black: #121212;   /* Black        */

  /* Working aliases and derived steps. Nothing new is introduced here — the
     greys are tints of the black, the paper steps are tints of the cream. */
  --paper: var(--cream);
  --paper-2: #efe9de;
  --paper-3: #e4dcce;
  --ink: var(--black);
  --ink-2: #4f4f4f;
  --ink-3: #6e6e6e;

  /* Illustration pigments only — chai is brown, and a drawing needs a mid
     tone to sit between the cream and the red. Never used for type or UI. */
  --chai: #7a4522;
  --chai-2: #c98a4b;

  /* Per-field colour roles. Sections re-point these; components never
     reference a hue directly. */
  --field: var(--paper);
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.22);

  --font-display: 'Fraunces', 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
  --font-logo: 'Hatti Logo', 'Fraunces', Georgia, serif;
  --font-text: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;

  /* The small end of the scale was the whole problem: two thirds of the text on
     a page sat at 13px or below, and 49 elements on the homepage alone were at
     11px — condensed, bold, uppercase and widely tracked all at once. Each step
     up here is one notch, applied at the token so every component follows. */
  /* Two clusters with a hole between them. Twelve distinct sizes rendered on
     one page and the middle — 17, 19, 22, 26, 30 — was doing most of the work,
     which is what made the page read as a document rather than a poster. The
     small end now spans 11-15px and the display end starts at 30. */
  --t-2xs: 0.6875rem;
  --t-xs: 0.75rem;
  --t-sm: 0.8125rem;
  --t-base: 0.9375rem;
  --t-lg: 0.9375rem;
  --t-xl: 1rem;

  /* Display type is sized to the sentence, never to the viewport. */
  /* The opening line only. Three words, so it can go large without wrapping
     badly — and it should not be the same size as a page title. */
  --d-0: clamp(3.4rem, 1.9rem + 6.2vw, 7rem);
  --d-1: clamp(2.4rem, 1.7rem + 3vw, 4rem);
  --d-2: clamp(1.9rem, 1.5rem + 1.7vw, 2.75rem);
  /* d-3 and d-4 were the middle. They collapse onto the body size and take
     their distinction from weight and case instead of scale. */
  --d-3: 0.9375rem;
  --d-4: 0.9375rem;

  --gutter: clamp(1.125rem, 0.6rem + 2.4vw, 3.25rem);
  --max: 82.5rem;
  --measure: 34rem;
  /* Sections used to be colour blocks, and 120px a side read as the space
     between them. On one light ground with dense rows it reads as a void —
     185px of nothing between a button and the next heading. */
  --sect: clamp(2.25rem, 1.5rem + 3vw, 3.75rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --dur: 0.32s;
}

/* Coloured fields. Applied to a section; everything inside inherits.
   Four grounds, four rhythms: cream, cream-2, red, dark red, black. Every
   pairing below clears WCAG AA — see the table in BRAND.md. */
.f-paper  { --field: var(--paper);   --on-field: var(--ink);   --on-field-2: var(--ink-2); --rule: rgba(18,18,18,.2); }
.f-paper2 { --field: var(--paper-2); --on-field: var(--ink);   --on-field-2: var(--ink-2); --rule: rgba(18,18,18,.22); }
.f-red    { --field: var(--red);     --on-field: var(--cream); --on-field-2: #f5e4e2;      --rule: rgba(247,243,236,.4); }
.f-deep   { --field: var(--red-deep);--on-field: var(--cream); --on-field-2: #efdad8;      --rule: rgba(247,243,236,.34); }
.f-ink    { --field: var(--ink);     --on-field: var(--cream); --on-field-2: #a5a5a5;      --rule: rgba(247,243,236,.28); }

[class*='f-'] {
  background: var(--field);
  color: var(--on-field);
}

/* 02  Reset & base ------------------------------------------------------ */

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

* { margin: 0; }

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-text);
  font-size: var(--t-base);
  line-height: 1.6;
  font-variation-settings: 'wdth' 100;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img,
svg,
video { display: block; max-width: 100%; }
img { height: auto; }

button,
input,
textarea { font: inherit; color: inherit; }

a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 3px;
  border-radius: 2px;
}
.f-red :focus-visible,
.f-red :focus-visible,
.f-deep :focus-visible,
.f-ink :focus-visible { outline-color: var(--cream); }

::selection { background: var(--red); color: var(--cream); }

.skip {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translate(-50%, -120%);
  z-index: 200;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  /* The footer used to be a black slab and every colour inside it was pinned
     to that. On the light ground it declares the field's own tokens instead. */
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.2);
  color: var(--on-field);
  padding: 0.75rem 1.25rem;
  font: 600 var(--t-sm) / 1 var(--font-text);
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
}
.skip:focus { transform: translate(-50%, 0); }

main:focus { outline: none; }

/* 03  Type -------------------------------------------------------------- */

/* WONK is off. Fraunces' wonky axis gives the f a swash whose terminal runs
   into the letter after it — "A few hours" collided on every page head — and
   because it is a variable axis it cannot be disabled for one glyph. It only
   changes f and g noticeably, so switching it off costs almost nothing and
   removes the collision everywhere. Loosening the tracking does not help; the
   overlap is in the glyph outline, not the spacing. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: 'SOFT' 40, 'WONK' 0, 'opsz' 96;
  line-height: 1.04;
  letter-spacing: -0.018em;
  text-wrap: balance;
}

p { text-wrap: pretty; }

.d1 { font-size: var(--d-1); }
.d2 { font-size: var(--d-2); }
.d3 { font-size: var(--d-3); }
.d4 { font-size: var(--d-4); }

/* The lede shares the body's measure rather than keeping a tighter one of
   its own. At 32ch it set 42 characters to a line against the 66 of the
   paragraph directly beneath it — a 251px step down the middle of one
   column, which read as a mistake once the lede ran to a full sentence. */
.lede {
  font-size: var(--t-xl);
  line-height: 1.45;
  color: var(--on-field);
  max-width: var(--measure);
}

.body p + p { margin-top: 1.1em; }
.body {
  max-width: var(--measure);
  color: var(--on-field-2);
}
.body--wide { max-width: 46rem; }

/* Small-caps condensed label — the site's only eyebrow. */
.lbl {
  display: inline-block;
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  line-height: 1;
  color: var(--on-field-2);
}
.lbl--strong { color: var(--on-field); }
.lbl--red { color: var(--red); }

.ast {
  color: var(--red);
  font-size: 0.7em;
  vertical-align: 0.45em;
  margin-inline-start: 0.15em;
}
.f-red .ast, .f-deep .ast, .f-ink .ast { color: var(--cream); }

.serifit { font-family: var(--font-display); font-style: italic; font-variation-settings: 'SOFT' 60, 'WONK' 0; }

/* The brand name inside running text, painted with the real logo artwork.
   The typeface is only an approximation of a custom logotype, so the mask is
   used here for the same reason it is used for the wordmark. */
.brandname__t {
  font-family: var(--font-logo);
  font-weight: 900;
  font-style: normal;
  font-size: 1.04em;
  letter-spacing: -0.005em;
}
@supports ((-webkit-mask-image: none) or (mask-image: none)) {
  .brandname {
    display: inline-block;
    /* 317 units of the artwork is ascender-to-baseline. Measured against the
       type it sits in: the ascender should clear the cap height slightly, the
       way a lowercase ascender does. 0.76em sat visibly short. */
    height: 0.95em;
    aspect-ratio: 595 / 317;
    vertical-align: baseline;
    background-color: currentColor;
    -webkit-mask: url('/assets/logo.svg') no-repeat center / contain;
    mask: url('/assets/logo.svg') no-repeat center / contain;
  }
  .brandname__t {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

/* 04  Layout primitives ------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--narrow { max-width: 62rem; }
.wrap--text { max-width: 44rem; }

.sect { padding-block: var(--sect); position: relative; }
.sect--tight { padding-block: calc(var(--sect) * 0.62); }
.sect--flush-b { padding-bottom: 0; }

.grid12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(1.25rem, 0.6rem + 2vw, 2.75rem);
}

.stack > * + * { margin-top: var(--s, 1rem); }

/* 05  Devices ----------------------------------------------------------- */

/* Enamel plate --------------------------------------------------------- */
.plate {
  --plate-bg: var(--ink);
  --plate-fg: var(--paper);
  display: inline-block;
  background: var(--plate-bg);
  color: var(--plate-fg);
  border-radius: 0;
  padding: 0.34rem;
  line-height: 1;
}
.plate__inner {
  display: block;
  border: 1px solid currentColor;
  border-radius: 0;
  padding: 0.4rem 0.7rem;
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  opacity: 0.98;
}
.plate--red { --plate-bg: var(--red); --plate-fg: var(--paper); }
.plate--deep { --plate-bg: var(--red-deep); --plate-fg: var(--cream); }
.plate--paper { --plate-bg: var(--paper); --plate-fg: var(--ink); }

/* Wordmark ------------------------------------------------------------- */
/* The mark is the word, in the logo face. No container: on paper it is red,
   on a coloured field it is paper. Matches the profile mark. */
.wordmark {
  --wm-fg: var(--red);
  display: inline-block;
  color: var(--wm-fg);
  text-decoration: none;
  line-height: 1;
}
.wordmark--paper { --wm-fg: var(--cream); }
/* Real logo artwork, painted through a mask so one file serves every field:
   the box is filled with currentColor and the SVG cuts the shape out of it. */
.wordmark__art { display: none; }
.wordmark .wordmark__text--fallback { display: block; }
@supports ((-webkit-mask-image: none) or (mask-image: none)) {
  .wordmark__art {
    display: block;
    height: 1.5em;
    aspect-ratio: 595 / 317;
    background-color: currentColor;
    -webkit-mask: url('/assets/logo.svg') no-repeat center / contain;
    mask: url('/assets/logo.svg') no-repeat center / contain;
    transition: transform var(--dur) var(--ease);
    transform-origin: 0 60%;
  }
  .wordmark .wordmark__text--fallback { display: none; }
  .wordmark--sm .wordmark__art { height: 1.2em; }
  .wordmark--lg .wordmark__art { height: clamp(1.9rem, 1.3rem + 2.2vw, 2.9rem); }
  .wordmark--xl .wordmark__art { height: clamp(3rem, 1.8rem + 5.4vw, 6.5rem); }
}
.wordmark__text {
  display: block;
  font-family: var(--font-logo);
  font-size: 1.95rem;
  font-weight: 900;
  letter-spacing: -0.005em;
  line-height: 0.82;
  padding-block: 0.14em;
  transition: transform var(--dur) var(--ease);
  transform-origin: 0 60%;
}
.wordmark--sm .wordmark__text { font-size: 1.4rem; }
.wordmark--lg .wordmark__text { font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.5rem); }
.wordmark--xl .wordmark__text { font-size: clamp(3.4rem, 2rem + 6vw, 7.4rem); }

/* Awning --------------------------------------------------------------- */
.awning {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  /* Half the scallop's own width, so every arc stays a semicircle. A fixed
     height flattened them into nubs past ~1500px, because the scallops keep
     widening with the viewport while the strip stopped growing. */
  height: clamp(0.7rem, calc(50vw / var(--scallops, 22)), 3.25rem);
  line-height: 0;
  pointer-events: none;
  z-index: 2;
}
.awning svg { width: 100%; height: 100%; }
.awning--flip { bottom: auto; top: -1px; }

/* Ledger rule ----------------------------------------------------------- */
.ledger {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
}
.ledger__label {
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.ledger__rule {
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.28;
}

/* Price ticket ---------------------------------------------------------- */
.ticket {
  --tk-bg: var(--red);
  --tk-fg: var(--cream);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  background: var(--tk-bg);
  color: var(--tk-fg);
  padding: 0.4em 0.75em 0.4em 0.6em;
  
  clip-path: polygon(0.55em 0, 100% 0, 100% 100%, 0.55em 100%, 0 50%);
}
.ticket--paper { --tk-bg: var(--paper); --tk-fg: var(--ink); }
.ticket--red { --tk-bg: var(--red); --tk-fg: var(--paper); }
.ticket--deep { --tk-bg: var(--red-deep); --tk-fg: var(--cream); }
.ticket--ink { --tk-bg: var(--ink); --tk-fg: var(--paper); }
.ticket__hole {
  width: 0.34em;
  height: 0.34em;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
  flex: none;
  margin-left: 0.15em;
}
.ticket__body {
  font-family: var(--font-text);
  font-size: var(--t-sm);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}

/* 06  Buttons & links --------------------------------------------------- */

.btn {
  /* Outlined, not filled. A solid slab was the heaviest object on a page that
     is otherwise one light ground and a hairline grid. */
  --btn-bg: transparent;
  --btn-fg: var(--ink);
  display: inline-block;
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 0;
  border-radius: 0;
  padding: 0.3rem;
  text-decoration: none;
  cursor: pointer;
}
.btn__face {
  display: block;
  border: 1px solid currentColor;
  border-radius: 0;
  padding: 0.62rem 1.15rem;
  font-family: var(--font-text);
  font-size: var(--t-xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  line-height: 1.1;
  white-space: nowrap;
}
.btn--sm .btn__face { padding: 0.45rem 0.85rem; font-size: var(--t-2xs); }
.btn--lg .btn__face { padding: 0.62rem 1.15rem; font-size: var(--t-xs); }
.btn--red { --btn-bg: transparent; --btn-fg: var(--red); }

.btn--paper { --btn-bg: transparent; --btn-fg: var(--on-field); }
.btn--deep { --btn-bg: transparent; --btn-fg: var(--red-deep); }
/* Ghost drew its outline on the outer element while every other tone draws it
   on the face, so a ghost sat a few pixels larger than the button beside it.
   Now that every button is an outline it just takes the muted ink. */
.btn--ghost { --btn-bg: transparent; --btn-fg: var(--on-field-2); }
.btn:hover .btn__face { text-decoration: underline; text-underline-offset: 3px; }


.btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none; }

.ulink {
  color: inherit;
  text-decoration: none;
  background-image: linear-gradient(var(--red), var(--red));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 100% 0.16em;
  padding-bottom: 0.06em;
  transition: background-size 0.2s var(--ease);
  font-weight: 500;
}
.ulink:hover { background-size: 100% 0.55em; }
.f-red .ulink,
.f-deep .ulink,
.f-ink .ulink { background-image: linear-gradient(var(--cream), var(--cream)); }

/* 07  Chrome ------------------------------------------------------------ */

/* Notice strip */
.notice {
  background: none;
  color: var(--ink-2);
  border-bottom: 1px solid var(--rule);
  text-align: center;
  padding: 0.5rem var(--gutter);
}
.notice__text {
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  line-height: 1.3;
}

/* Shop sign / nav */
.shopnav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  transition: padding var(--dur) var(--ease);
}
.shopnav__in {
  max-width: var(--max);
  margin-inline: auto;
  padding: 0.7rem var(--gutter);
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: clamp(0.5rem, 0.2rem + 1vw, 1.25rem);
  transition: padding var(--dur) var(--ease);
}
.shopnav.is-stuck .shopnav__in { padding-block: 0.42rem; }
.shopnav.is-stuck .wordmark__text { font-size: 1.6rem; }

.shopnav__links { margin-inline: auto; }
.shopnav__links ul {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 0.3rem + 1.7vw, 2.25rem);
  list-style: none;
  padding: 0;
}
.shopnav__link {
  position: relative;
  display: inline-block;
  text-decoration: none;
  font-size: var(--t-xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  padding-block: 0.35rem;
  white-space: nowrap;
}
.shopnav__link::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -0.05rem;
  height: 0.42em;
  background: var(--red);
  opacity: .18;
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 0.2s var(--ease);
  z-index: -1;
}
.shopnav__link:hover::after,
.shopnav__link.is-on::after { transform: scaleY(1); }
.shopnav__link.is-on { color: var(--red); }
.shopnav__link.is-on { font-variation-settings: 'wdth' 88; }

.shopnav__end {
  display: flex;
  flex: none;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
}
.wordmark { flex: none; }
@media (min-width: 62rem) {
  .shopnav__end { margin-left: 0; }
}

/* Instagram badge — the enamel plate, reused. It is the only outward link in
   the nav, so it gets the brand device rather than a platform-styled pill. */
/* The handle, as one more item in the nav rather than a sticker stuck to it.
   It used to be the button device — a red plate with an inset keyline — but at
   this size the ring crowded the type, and a red badge is a lot of emphasis for
   a link that sits beside five plain ones. Red carries the distinction now. */
.iglink {
  display: inline-flex;
  flex: none;
  align-items: center;
  color: var(--red);
  text-decoration: none;
}
.iglink__face {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 0.45rem;
  white-space: nowrap;
}
.iglink__face svg { flex: none; }
.iglink__word {
  font-size: var(--t-xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  white-space: nowrap;
}
.iglink:hover { text-decoration: underline; text-underline-offset: 4px; }
/* Below the mobile-menu breakpoint the handle would crowd the Menu button,
   so the badge falls back to the glyph alone. */
@media (max-width: 61.99rem) {
  /* Glyph only — the handle would crowd the Menu button. Padding gives it a
     real tap target without putting the chrome back; the negative margin keeps
     it optically aligned with the button beside it. */
  .iglink__word { display: none; }
  .iglink { padding: 0.7rem; margin-right: -0.45rem; }
  .iglink__face svg { width: 20px; height: 20px; }
}

.menubtn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  /* The footer used to be a black slab and every colour inside it was pinned
     to that. On the light ground it declares the field's own tokens instead. */
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.2);
  color: var(--on-field);
  border: 0;
  border-radius: 0;
  padding: 0.5rem 0.7rem;
  cursor: pointer;
}
.menubtn__word {
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
}
.menubtn__bars { display: grid; gap: 3px; width: 1rem; }
.menubtn__bars i { display: block; height: 2px; background: currentColor; }
@media (min-width: 62rem) {
  .menubtn { display: none; }
}
@media (max-width: 61.99rem) {
  .shopnav__links { display: none; }
}

/* Mobile menu */
.menu {
  position: fixed;
  inset: 0;
  z-index: 90;
}
.menu[hidden] { display: none; }
.menu__sheet {
  /* Declared as a field, the way the sections are, so the rule between the
     items and the footnote under them read the right tokens instead of
     carrying values picked for a dark ground. */
  --field: var(--paper);
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.2);
  position: absolute;
  inset: 0;
  background: var(--field);
  color: var(--on-field);
  padding: clamp(2rem, 1.2rem + 3vw, 2.9rem) var(--gutter) 3.5rem;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  transform: translateY(-100%);
  transition: transform 0.42s var(--ease);
}
.menu.is-open .menu__sheet { transform: translateY(0); }
.menu__top { display: flex; align-items: center; justify-content: space-between; }
.menu__close {
  background: transparent;
  border: 1.5px solid currentColor;
  border-radius: 0;
  color: inherit;
  padding: 0.5rem 0.8rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  cursor: pointer;
}
.menu__list { list-style: none; padding: 0; margin-top: 2.25rem; }
.menu__list li + li { border-top: 1px solid var(--rule); }
.menu__list a {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 0;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 1.3rem + 3.2vw, 2.9rem);
  font-weight: 600;
  font-variation-settings: 'SOFT' 40, 'WONK' 0, 'opsz' 100;
  letter-spacing: -0.02em;
}
.menu__n {
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  letter-spacing: 0.14em;
  opacity: 0.6;
}
.menu__foot { margin-top: auto; padding-top: 2.5rem; }
.menu__hours { font-size: var(--t-sm); color: var(--on-field-2); max-width: 22ch; }
.menu__mail {
  display: inline-block;
  margin-top: 0.5rem;
  font-size: var(--t-sm);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.menu .awning { z-index: 1; }

/* Touch targets ---------------------------------------------------------- */
/* Measured on a 390px viewport: the footer's link columns came out 35-53px
   wide by 14px tall, and the menu button, the header mark, the hero's
   next-pop-up line and the opening's two links were all under 40px on their
   short side. 44px is the figure both platform guidelines use. Scoped to
   coarse pointers and phone widths, so a mouse on a wide screen keeps the
   tighter setting the type was spaced for. */
@media (pointer: coarse), (max-width: 51.99rem) {
  .tinback__col ul { gap: 0; }
  .tinback__col a,
  .tinback__social a,
  .shopnav__in > .wordmark,
  .tinback__brand > .wordmark,
  .menu__top > .wordmark,
  .menu__mail {
    display: flex;
    align-items: center;
    min-height: 44px;
  }
  .menubtn,
  .menu__close,
  .iglink { min-height: 44px; }
  .heronext__d,
  .tinback__nextact a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* The margin above it was spacing the link's own box off the line before;
     the box is taller now and carries its own. */
  .tinback__nextact { margin-top: 0.25rem; }
  .open__acts { gap: 0.2rem 1.75rem; }
  .open__acts .ulink {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Footer — the back of the tin */
.tinback {
  position: relative;
  background: var(--paper);
  border-top: 1px solid var(--rule);
  /* The footer used to be a black slab and every colour inside it was pinned
     to that. On the light ground it declares the field's own tokens instead. */
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.2);
  color: var(--on-field);
  padding-top: clamp(3.5rem, 2rem + 5vw, 5.5rem);
  margin-top: 0;
}
.tinback__in {
  max-width: var(--max);
  margin-inline: auto;
  padding: 0 var(--gutter) 3rem;
  display: grid;
  gap: clamp(2rem, 1rem + 3vw, 3.5rem);
  grid-template-columns: 1fr;
}
@media (min-width: 50rem) {
  .tinback__in { grid-template-columns: 1.1fr 1.2fr; }
}
@media (min-width: 72rem) {
  .tinback__in { grid-template-columns: 1fr 1.15fr 0.95fr; }
}
/* A dictionary entry. The wordmark directly above it is the headword, so the
   entry carries no rule of its own — it hangs off the mark. */
.tinback__def {
  margin-top: 0.85rem;
  max-width: 32ch;
  font-family: var(--font-display);
  font-size: var(--t-base);
  line-height: 1.45;
  color: var(--on-field-2);
}
.tinback__def i { font-style: italic; }
.tinback__def span { font-style: normal; opacity: 0.85; }
.tinback__next {
  font-family: var(--font-display);
  font-size: var(--d-4);
  font-weight: 700;
  color: var(--on-field);
}
.tinback__nextmeta {
  font-size: var(--t-sm);
  color: var(--on-field-2);
  margin-top: 0.2rem;
}
.tinback__nextact { margin-top: 0.7rem; }
.tinback__nextact a {
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  text-underline-offset: 4px;
}
.tinback__line {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  margin-top: 1.1rem;
  max-width: 18ch;
}
.tinback__addr { font-size: var(--t-sm); color: var(--on-field-2); margin-top: 0.9rem; line-height: 1.55; }
.tinback__social { list-style: none; padding: 0; margin-top: 1.1rem; display: grid; gap: 0.3rem; }
.tinback__social a {
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.13em;
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  text-decoration: none;
}
.tinback__social a span { color: var(--on-field-2); font-variation-settings: 'wdth' 90; letter-spacing: 0.06em; text-transform: none; font-weight: 400; }
.tinback__social a:hover { color: var(--on-field); text-decoration: underline; text-underline-offset: 3px; }

.tinback__cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); gap: 2rem 1.5rem; }
.tinback__head {
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--on-field);
  padding-bottom: 0.55rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 0.8rem;
}
.tinback__col ul { list-style: none; padding: 0; display: grid; gap: 0.42rem; }
.tinback__col a { font-size: var(--t-sm); text-decoration: none; color: var(--on-field-2); }
.tinback__col a:hover { color: var(--on-field); text-decoration: underline; text-underline-offset: 3px; }

.tinback__panel { align-self: start; }
.tinback__method { list-style: none; padding: 0; display: grid; gap: 0.55rem; font-size: var(--t-sm); color: var(--on-field-2); }
.tinback__method li { display: grid; grid-template-columns: 1.35rem 1fr; gap: 0.6rem; align-items: baseline; }
.tinback__method span {
  font-size: var(--t-2xs);
  font-weight: 700;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
.tinback__hours { width: 100%; margin-top: 1.1rem; border-collapse: collapse; font-size: var(--t-xs); }
.tinback__hours th,
.tinback__hours td { text-align: left; padding: 0.32rem 0; border-top: 1px dotted var(--rule); font-weight: 400; color: var(--on-field-2); }
.tinback__hours td { text-align: right; color: var(--on-field); }

.tinback__base {
  border-top: 1px solid var(--rule);
  padding: 1.1rem var(--gutter);
  max-width: var(--max);
  margin-inline: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: space-between;
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: 0.13em;
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  color: var(--on-field-2);
}

/* 08  Illustration ------------------------------------------------------ */

.illus { width: 100%; height: auto; }
.ink-cream { fill: var(--paper); }
.ink-ink { fill: var(--ink); }
.ink-red { fill: var(--red); }
.ink-chai2 { fill: var(--chai-2); }
.ink-deep { fill: var(--red-deep); }
.ink-brown { fill: var(--chai); }
.ink-tan { fill: #a86a3c; }
.stroke-ink { stroke: var(--ink); }
.stroke-cream { stroke: var(--paper); }
.stroke-brown { stroke: var(--chai); }
.stroke-red { stroke: var(--red); }
.illus__sign {
  fill: var(--cream);
  font-family: var(--font-logo);
  font-size: 44px;
  font-weight: 900;
  letter-spacing: 0;
}
.spicemark { width: 100%; height: auto; color: currentColor; }

/* 10  Photography slots -------------------------------------------------- */

.photo { display: grid; gap: 0.7rem; }
.photo__frame {
  position: relative;
  overflow: hidden;
  background: var(--paper-2);
  aspect-ratio: 4 / 3;
}
.photo--tall .photo__frame { aspect-ratio: 3 / 4; }
.photo--wide .photo__frame { aspect-ratio: 16 / 9; }
.photo--arch .photo__frame { border-radius: 0; aspect-ratio: 4 / 5; }
/* The hands sit in the top third of the cart-build frames. A 4:3 crop of a
   933x1400 original cuts them off; a square keeps them and still stands
   250px shorter than the 3:4 it replaced. */
.photo--square .photo__frame { aspect-ratio: 1 / 1; }
.photo--t-paper .photo__frame { background: var(--paper); }
.photo--t-paper2 .photo__frame { background: var(--paper-2); }
.photo--t-deep .photo__frame { background: var(--red-deep); }
.photo--t-red .photo__frame { background: var(--red); }

.photo--t-brown .photo__frame { background: var(--chai); }
.photo__img { width: 100%; height: 100%; object-fit: cover; }

.photo__plate { position: relative; width: 100%; height: 100%; display: grid; place-items: center; }
/* Crop marks + keyline, so an unshot frame reads as a marked-up plate from a
   shot list rather than as a missing image. */
.photo__plate::before {
  content: '';
  position: absolute;
  inset: 0.85rem;
  border: 1px dashed currentColor;
  opacity: 0.25;
  pointer-events: none;
}
.photo__plate::after {
  content: '';
  position: absolute;
  inset: 0.85rem;
  background:
    linear-gradient(currentColor, currentColor) 0 0 / 1.4rem 2px no-repeat,
    linear-gradient(currentColor, currentColor) 0 0 / 2px 1.4rem no-repeat,
    linear-gradient(currentColor, currentColor) 100% 0 / 1.4rem 2px no-repeat,
    linear-gradient(currentColor, currentColor) 100% 0 / 2px 1.4rem no-repeat,
    linear-gradient(currentColor, currentColor) 0 100% / 1.4rem 2px no-repeat,
    linear-gradient(currentColor, currentColor) 0 100% / 2px 1.4rem no-repeat,
    linear-gradient(currentColor, currentColor) 100% 100% / 1.4rem 2px no-repeat,
    linear-gradient(currentColor, currentColor) 100% 100% / 2px 1.4rem no-repeat;
  opacity: 0.55;
  pointer-events: none;
}
.photo--t-paper .photo__plate,
.photo--t-paper2 .photo__plate { color: var(--ink); }
.photo--t-deep .photo__plate,
.photo--t-red .photo__plate,
.photo--t-brown .photo__plate { color: var(--cream); }
.photo__ghost {
  position: absolute;
  inset: 10% 12%;
  display: grid;
  place-items: center;
  color: var(--ink);
  opacity: 0.2;
}
/* Flatten the illustration to one colour so the plate reads as a marked-up
   crop, not as a small muddy picture. */
.photo__ghost [class^='ink-'],
.photo__ghost [class*=' ink-'] { fill: currentColor; }
.photo__ghost [class^='stroke-'],
.photo__ghost [class*=' stroke-'] { stroke: currentColor; }
.photo--t-deep .photo__ghost,
.photo--t-red .photo__ghost,
.photo--t-brown .photo__ghost { color: var(--cream); opacity: 0.22; }
.photo__ghost .illus { max-height: 100%; width: auto; max-width: 100%; }
.photo__note {
  position: relative;
  align-self: end;
  justify-self: start;
  margin: 1rem;
  max-width: 27ch;
  background: var(--paper);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  padding: 0.55rem 0.7rem;
  font-size: var(--t-xs);
  line-height: 1.35;
}
.photo__note-k {
  display: block;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.15em;
  color: var(--red);
  margin-bottom: 0.15rem;
}
.photo__cap {
  font-size: var(--t-xs);
  color: var(--on-field-2);
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem 0.5rem;
  align-items: baseline;
}
.photo__cap::before {
  content: '';
  flex: none;
  width: 1.5rem;
  height: 1px;
  background: currentColor;
  opacity: 0.5;
  transform: translateY(-0.3em);
}
.photo__cap-t { flex: 1 1 12rem; }
.photo__credit {
  font-size: var(--t-2xs);
  text-transform: uppercase;
  letter-spacing: 0.11em;
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  opacity: 0.75;
}
.photo__credit a { color: inherit; text-underline-offset: 2px; }

/* 11  Page sections ------------------------------------------------------ */

/* Section head */
.shead { display: grid; gap: 0.9rem; margin-bottom: clamp(1.5rem, 0.9rem + 2.4vw, 3rem); }
.shead__body { display: grid; gap: 1.1rem; align-items: end; }
@media (min-width: 56rem) {
  .shead__body { grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 2.5rem; }
}
.shead__title { font-size: var(--d-2); max-width: 18ch; }
.shead__aside { color: var(--on-field-2); max-width: 40ch; align-self: end; }
.shead__aside p + p { margin-top: 0.75rem; }
@media (max-width: 55.99rem) {
  .shead__aside {
    font-size: var(--t-sm);
    line-height: 1.5;
    padding-left: 0.9rem;
    border-left: 2px solid var(--rule);
  }
}

/* --- Opening ----------------------------------------------------------- */
.open { position: relative; padding-top: clamp(1.5rem, 0.6rem + 3.4vw, 4.5rem); padding-bottom: 0; overflow: hidden; }
.open__in { position: relative; z-index: 1; }
.open__grid { display: grid; gap: clamp(1.5rem, 1rem + 2.5vw, 3.5rem); align-items: center; }
/* One column: lead, then the picture, then the copy. The illustration should
   be the second thing you see, not the fifth. */
@media (max-width: 47.99rem) {
  .open__art {
    margin-inline: calc(var(--gutter) * -1);
    margin-block: 0;
  }
  .open__say { margin-top: 0.25rem; }
}
@media (min-width: 48rem) {
  .open__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
    grid-template-areas: 'lead art' 'say art';
    align-content: center;
    gap: clamp(1.75rem, 0.5rem + 3vw, 4rem);
  }
  .open__lead { grid-area: lead; align-self: end; }
  .open__say { grid-area: say; align-self: start; }
  .open__art { grid-area: art; align-self: center; }
}
@media (min-width: 68rem) {
  .open__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.94fr); }
}

.def { display: grid; gap: clamp(0.7rem, 0.4rem + 0.9vw, 1.15rem); }
.def__slogan {
  display: block;
  font-family: var(--font-display);
  font-size: var(--d-0);
  font-weight: 800;
  font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 144;
  line-height: 0.95;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
/* The plain-language line. It carries the what and the where so the opening
   does not have to spend its first screen on a dictionary entry. */
.def__what {
  display: block;
  font-family: var(--font-display);
  /* Its own size. It is the sentence that says what the business is, and it
     sits directly under a 112px line — at the collapsed body size it read as a
     caption. One deliberate step between the display end and the small end. */
  font-size: clamp(1.3rem, 0.95rem + 1.2vw, 1.75rem);
  font-weight: 400;
  line-height: 1.22;
  letter-spacing: -0.014em;
  max-width: 22ch;
  color: var(--on-field-2);
}
.open__eyebrow { color: var(--on-field-2); margin-bottom: 0.9rem; display: block; }

/* Next pop-up, in the opening. The single most useful thing on the page, so
   it sits above the fold on a phone rather than a screen and a half down. */
.heronext {
  display: grid;
  gap: 0.25rem;
  background: none;
  border: 1px solid var(--rule);
  padding: 1rem 1.15rem 1.05rem;
  max-width: 24rem;
  /* The card is a cream object sitting on the red field, so it re-declares the
     field tokens its children read. Without this they inherit the red field's
     cream text and the card is blank. */
  --on-field: var(--ink);
  --on-field-2: var(--ink-2);
  --rule: rgba(18, 18, 18, 0.2);
  color: var(--on-field);
}
.heronext__k {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 1.6rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  /* Follows the card's own tokens. This was pinned to cream when the card was
     an outline on the red field; once the card became cream it went invisible. */
  color: var(--on-field-2);
}
/* Stamped, not outlined. Inverted with the card: red ground, cream numeral. */
.heronext__no {
  margin-left: auto;
  background: var(--red);
  color: var(--cream);
  border-radius: 0;
  padding: 0.34em 0.7em;
  letter-spacing: 0.1em;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.heronext__d {
  display: block;
  margin-top: 0.15rem;
  font-family: var(--font-display);
  font-size: var(--d-4);
  font-weight: 700;
  line-height: 1.15;
  color: inherit;
  text-decoration: none;
}
.heronext__d::after { content: '→'; margin-left: 0.4em; opacity: 0.75; }
.heronext__d:hover { text-decoration: underline; text-underline-offset: 4px; }
.heronext__d:hover::after { margin-left: 0.55em; }
.heronext__m { font-size: var(--t-xs); color: var(--on-field-2); line-height: 1.45; }
/* Add to calendar. The one thing on the page that survives leaving it. */
.heronext__cal {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  justify-self: start;
  margin-top: 0.8rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
  width: 100%;
  color: inherit;
  text-decoration: none;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
}
.heronext__cal svg { flex: none; }
/* Underline on hover rather than a colour change — saffron text here would
   drop to 2.89:1. */
.heronext__cal:hover { text-decoration: underline; text-underline-offset: 4px; }

/* Primary and secondary action, under the pop-up card. */
.open__acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.9rem 1.75rem;
  margin-top: 1.6rem;
}
/* The secondary link was inheriting body size next to a small-caps button, so
   it read louder than the primary action. */
.open__acts .ulink {
  font-size: var(--t-sm);
  font-weight: 600;
  background-size: 100% 0.1em;
}
.open__acts .ulink:hover { background-size: 100% 0.4em; }

/* The definition, kept — but as the line you read on the way out of the
   opening rather than the one blocking your way into it. */

.open__art { position: relative; }
/* A hard rectangle, tight crop. The arch was the last shaped frame on the
   site; every reference Arman picked uses plain rectangles. It survives on
   /landing/ and the social card. */
.open__shot {
  display: block;
  width: 100%;
  max-width: 30rem;
  margin-inline: auto;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 40%;
}
.open__tin { position: absolute; left: 0; bottom: -1rem; z-index: 3; }
.open__tin .tin { --tin-w: clamp(6.5rem, 4.5rem + 8vw, 10.5rem); }
@media (min-width: 48rem) {
  .open__tin { left: -2.25rem; bottom: 0.5rem; }
  .open__tin .tin { --tin-w: clamp(5.75rem, 1.9rem + 7.5vw, 8.5rem); }
}
@media (min-width: 68rem) {
  .open__tin { left: -3.5rem; }
  .open__tin .tin { --tin-w: clamp(8.5rem, 4rem + 6vw, 10.5rem); }
}


/* --- Story ledger ------------------------------------------------------ */
.story__grid { display: grid; gap: clamp(2rem, 1rem + 3vw, 3.25rem); }
@media (min-width: 58rem) {
  .story__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  /* For a short column beside a tall one: split the difference above and
     below it rather than hanging it off the top with the gap all underneath. */
  .story__grid--mid { align-items: center; }
}
/* A landscape frame beside a portrait one. At equal widths a 4:3 and a 3:4
   differ in height by 16/9, which left a hole under the shorter one — so the
   columns are sized in that ratio instead and the two photographs come out
   exactly the same height, top and bottom aligned. Neither gets cropped to
   suit the other. */
/* Three frames, one row. 16 : 9 : 9 — at those widths a 4:3 frame and a 3:4
   frame come out exactly the same height, so all three tops and bottoms line
   up without cropping any of them to suit the others. On a phone the
   landscape one runs full width and the two portraits pair underneath it. */
.triptych {
  display: grid;
  gap: clamp(0.6rem, 0.3rem + 1.4vw, 2rem);
  grid-template-columns: 1fr 1fr;
  align-items: start;
}
.triptych > :first-child { grid-column: 1 / -1; }
@media (min-width: 52rem) {
  .triptych { grid-template-columns: 16fr 9fr 9fr; }
  .triptych > :first-child { grid-column: auto; }
}

/* Same idea for a pair: 16:9 puts a 4:3 frame and a 3:4 frame at one height.
   Stacked on a phone — at 390px the 9fr column is 126px, too small to read. */
.duo { display: grid; gap: clamp(0.6rem, 0.3rem + 1.4vw, 2rem); align-items: start; }
@media (min-width: 52rem) {
  .duo { grid-template-columns: 16fr 9fr; }
}

/* Three frames of the same ratio, so equal widths give equal heights. Rules
   follow .triptych's because they share its specificity: the landscape one
   leads there, here all three are portraits and it is the last that spans
   the pair of phone columns. */
.triptych--thirds > :first-child { grid-column: auto; }
@media (max-width: 51.99rem) {
  .triptych--thirds > :last-child { grid-column: 1 / -1; }
}
@media (min-width: 52rem) {
  .triptych--thirds { grid-template-columns: 1fr 1fr 1fr; }
}

.story__cols { columns: 1; }
@media (min-width: 34rem) and (max-width: 57.99rem) {
  .story__cols { columns: 2; column-gap: 2.25rem; }
}
.story__cols p { break-inside: avoid; margin-bottom: 1.05em; }
.story__art { position: relative; }
.story__facts { list-style: none; padding: 0; margin-top: 2rem; display: grid; gap: 0; }
.story__facts li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.9rem;
  align-items: baseline;
  padding: 0.7rem 0;
  border-top: 1px solid var(--rule);
  font-size: var(--t-sm);
}
.story__facts li:last-child { border-bottom: 1px solid var(--rule); }
.story__facts b {
  font-family: var(--font-text);
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}
.story__facts span:last-child { font-variant-numeric: tabular-nums; font-weight: 600; }
.story__facts i { height: 1px; background: currentColor; opacity: 0.2; align-self: center; font-style: normal; }

/* --- Anatomy diagram ---------------------------------------------------- */
/* The four things that decide whether it works. This used to be two mirrored
   columns flanking a drawn glass; the drawing read as clipart next to real
   photography, so the section is now what its neighbours already are —
   typography on a grid. */
.anat { display: grid; gap: clamp(1.75rem, 1rem + 2.5vw, 2.75rem); }
@media (min-width: 44rem) { .anat { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 68rem) { .anat { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.anat__item { display: grid; gap: 0.45rem; padding-top: 0.9rem; border-top: 1px solid var(--rule); }
.anat__head { display: flex; align-items: baseline; gap: 0.6rem; }
.anat__title { font-size: var(--d-4); }
.anat__body { font-size: var(--t-sm); color: var(--on-field-2); max-width: 34ch; }

/* Spice row */
/* Seven items, icon and name only. Each one used to carry a note as well,
   which put fourteen pieces of micro-text in a section that already has four
   numbered callouts above it. The summary line below covers the nuance. */
/* A line of names, not a row of icons. The icons were small brown silhouettes
   that did not read as the spice they named at the size they were shown. */
.spices {
  list-style: none;
  padding: 0;
  margin-top: clamp(1.5rem, 1rem + 2vw, 2.25rem);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0;
  border-top: 1px solid var(--rule);
  padding-top: 1rem;
}
.spices li { display: flex; align-items: baseline; }
.spices li + li::before { content: '·'; opacity: 0.45; margin: 0 0.7rem; }
.spices b {
  font-size: var(--t-xs);
  font-weight: 500;
  font-variation-settings: 'wdth' 96;
  letter-spacing: 0.01em;
}
.spices span { font-size: var(--t-xs); color: var(--on-field-2); font-variant-numeric: tabular-nums; }

/* --- Method ------------------------------------------------------------ */
.method { display: grid; gap: 0; counter-reset: step; }
.method__step {
  display: grid;
  gap: 0.3rem 1.5rem;
  padding: clamp(1.1rem, 0.7rem + 1.2vw, 1.75rem) 0;
  border-top: 1px solid var(--rule);
  align-items: baseline;
}
.method__step:last-child { border-bottom: 1px solid var(--rule); }
@media (min-width: 46rem) {
  .method__step { grid-template-columns: 3.5rem minmax(0, 1fr) minmax(0, 1.5fr) 4rem; }
}
.method__n {
  font-family: var(--font-display);
  font-size: var(--d-3);
  font-weight: 800;
  font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 120;
  line-height: 1;
  color: var(--red);
}
.method__t { font-family: var(--font-display); font-size: var(--d-4); font-weight: 600; }
.method__b { color: var(--on-field-2); font-size: var(--t-sm); max-width: 44ch; }
.method__time {
  font-size: var(--t-2xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  letter-spacing: 0.13em;
  font-variant-numeric: tabular-nums;
  color: var(--on-field-2);
  text-align: right;
}
@media (max-width: 45.99rem) {
  .method__time { text-align: left; }
}

/* --- The wall: pop-ups as an index ---------------------------------------
   One line per pop-up. Venue, date, note and place sit on a single baseline
   across five columns; stacked, each row ran to 92px and three of them filled
   a screen. Dense is the point — the reference lists are ~40px a row. */
.wall { display: grid; border-top: 1px solid var(--rule); counter-reset: pop; }
.flyer {
  display: grid;
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: 0.1rem 0.9rem;
  align-items: baseline;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
  counter-increment: pop;
}
.flyer::before {
  content: counter(pop, decimal-leading-zero);
  grid-row: 1 / span 4;
  font-size: var(--t-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--red);
}
/* Three columns, and the date gets room enough not to wrap. */
.flyer--compact { grid-template-columns: 2.25rem minmax(0, 1fr); }
@media (min-width: 46rem) {
  .flyer--compact { grid-template-columns: 2.25rem minmax(0, 22rem) minmax(0, 1fr); }
  .flyer--compact .flyer__venue { grid-column: 2; }
  .flyer--compact .flyer__when { grid-column: 3; }
}
@media (min-width: 60rem) {
  .flyer:not(.flyer--compact) {
    /* Every track is sized off the longest thing in it, so no row wraps and
       all of them stand the same height: "Procreations Brewing Company"
       needs 15rem, and "August 29th, 2026 · 10:00am – 2:00pm" needs 16rem.
       Proportional tracks rather than fixed ones: sized to content, four
       columns of short text ended 60% across and every rule trailed off
       into nothing.

       There was a fifth column for the location. Every row of it said
       "Fresno, CA" — the one word already in the page title, the tally and
       the footer. Only the host credit in it was ever different, so that is
       all that survives, folded in beside the note. */
    grid-template-columns: 2.25rem minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.3fr);
    gap: 0 1.25rem;
    padding: 0.62rem 0;
  }
  .flyer::before { grid-row: auto; }
  .flyer__venue { grid-column: 2; }
  .flyer__when  { grid-column: 3; }
  .flyer__note  { grid-column: 4; }
}
.flyer__venue {
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.008em;
}
.flyer__when,
.flyer__note {
  font-size: var(--t-xs);
  color: var(--on-field-2);
  line-height: 1.35;
}
.flyer__when { font-variant-numeric: tabular-nums; }
.flyer--more { counter-increment: none; }
.flyer--more::before { content: '—'; color: var(--on-field-2); }
.flyer--more .flyer__venue { font-size: var(--t-base); color: var(--on-field-2); }
.flyer__year { display: none; }

/* --- Next pop-up card ---------------------------------------------------- */
.nextgrid { display: grid; gap: clamp(1.75rem, 1rem + 3vw, 3.25rem); align-items: start; }
@media (min-width: 54rem) {
  .nextgrid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.68fr); }
}
.nextup {
  position: relative;
  /* One hairline. It carried a 2.5px border with a second keyline inset inside
     it — the printed-card device — which on a page of hairlines read as a
     drawing mistake rather than an object. */
  background: none;
  color: inherit;
  border: 1px solid var(--rule);
  padding: clamp(1.25rem, 0.9rem + 1.4vw, 2rem);
}
.nextup__tag {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
/* The run is thirteen long; numbering the next one says so without a sentence. */
.nextup__no {
  margin-left: auto;
  border: 1.5px solid currentColor;
  border-radius: 0;
  padding: 0.22em 0.6em;
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  opacity: 0.8;
}
.nextup__date {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.9rem);
  font-weight: 800;
  font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 120;
  line-height: 1;
  letter-spacing: -0.03em;
  margin-top: 0.6rem;
}
.nextup__venue {
  font-family: var(--font-display);
  font-size: var(--d-4);
  font-weight: 500;
  margin-top: 0.45rem;
}
.nextup__meta {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 0.85rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid currentColor;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.13em;
}
.nextup__meta li + li::before { content: '·'; margin-right: 0.85rem; opacity: 0.6; }
.nextup__where {
  font-size: var(--t-sm);
  margin-top: 0.6rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.7rem;
  align-items: baseline;
}
.nextup__map {
  color: inherit;
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-underline-offset: 3px;
}
.nextup__note { font-size: var(--t-sm); margin-top: 0.55rem; max-width: 38ch; opacity: 0.9; }
.nextup__act { display: flex; flex-wrap: wrap; gap: 0.6rem 0.75rem; margin-top: 1.1rem; }

.nextstrip__line {
  font-family: var(--font-display);
  font-size: var(--t-xl);
  margin-top: 0.6rem;
}

/* --- Tally: the run, in three numbers ------------------------------------ */
.tally {
  list-style: none;
  padding: 0;
  margin-top: clamp(1.5rem, 1rem + 1.6vw, 2.25rem);
  /* Sized to however many entries there are. It was a fixed three-column grid
     carrying two items, so each rule spanned a third of the width and the last
     third sat empty — the rules read as fragments rather than as measures. */
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem clamp(1.75rem, 1rem + 2.2vw, 3.25rem);
}
.tally li {
  display: grid;
  gap: 0.15rem;
  min-width: 6.5rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--rule);
}
.tally b {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.3rem + 1.8vw, 2.75rem);
  font-weight: 800;
  font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 120;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.tally span {
  font-size: var(--t-2xs);
  font-weight: 600;
  font-variation-settings: 'wdth' 90;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--on-field-2);
}

/* --- Pop-up ledger rows -------------------------------------------------- */
.poprow {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.9rem;
  align-items: baseline;
  padding: 0.75rem 0;
  border-top: 1px solid var(--rule);
  font-size: var(--t-sm);
}
.poprow__date { font-variant-numeric: tabular-nums; color: var(--on-field-2); }
.poprow__venue { font-weight: 600; }
.poprow__rule { height: 1px; background: currentColor; opacity: 0.2; align-self: center; }
.poprow__time { font-variant-numeric: tabular-nums; color: var(--on-field-2); }

.flyer__host { opacity: 0.72; white-space: nowrap; }
.flyer__host::before { content: ' · '; }

/* --- Pillars: chai / community / music ----------------------------------- */
.pillars { display: grid; gap: clamp(1.75rem, 1rem + 2.5vw, 3rem); }
@media (min-width: 52rem) { .pillars { grid-template-columns: repeat(3, 1fr); } }
/* The pillars are three cards and read fine side by side. The wall is a list
   of every pop-up so far, and as a shelf it showed one and a half rows with
   the second one sliced down the middle — venue, date and address all cut
   mid-word, and no edge to suggest there was more. A list stacks. */
@media (max-width: 51.99rem) {
  .pillars {
    grid-auto-flow: column;
    grid-auto-columns: minmax(13rem, 74%);
    gap: 1rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scroll-padding-inline: var(--gutter);
    margin-inline: calc(var(--gutter) * -1);
    padding: 1.1rem var(--gutter) 1.25rem;
    scrollbar-width: none;
  }
  .pillars::-webkit-scrollbar { display: none; }
  .pillars > * { scroll-snap-align: start; }
  .pillar { padding-top: 0.9rem; }
}
/* Spacing set deliberately rather than one uniform gap: the label sits close
   to its title, the body steps away from it. */
.pillar { display: grid; gap: 0; align-content: start; padding-top: 1rem; border-top: 2px solid var(--ink); }
.pillar__head { display: flex; align-items: baseline; gap: 0.6rem; }
.pillar__n {
  font-size: var(--t-2xs);
  font-weight: 700;
  font-variation-settings: 'wdth' 90;
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
  color: var(--red);
}
.pillar__title { font-size: var(--d-4); margin-top: 0.5rem; text-wrap: balance; }
/* A fixed measure, not a cap the copy may or may not reach — otherwise each
   column's block is only as wide as its own longest line and the three read
   as misaligned. The copy is written to the same length to match. */
.pillar__body {
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--on-field-2);
  max-width: 40ch;
  margin-top: 0.6rem;
  text-wrap: pretty;
}

/* --- What comes out of the pot -------------------------------------------
   Two hairline-topped columns, the way every other pair on the site is set.
   These were the last bordered boxes — one of them outlined in red, which made
   it the loudest object on a page that is otherwise rules and type. */
.pours { display: grid; gap: clamp(1.5rem, 1rem + 2vw, 2.75rem); }
@media (min-width: 46rem) { .pours { grid-template-columns: repeat(2, 1fr); } }
.pourcard { display: grid; gap: 0.4rem; padding-top: 0.9rem; border-top: 1px solid var(--rule); }
.pourcard--iced { border-top-color: var(--red); }
.pourcard__t { font-size: var(--d-4); }
.pourcard__b { font-size: var(--t-xs); color: var(--on-field-2); line-height: 1.45; max-width: 36ch; }

/* --- Sign-off ----------------------------------------------------------- */
.signoff { position: relative; text-align: center; overflow: hidden; }
.signoff__in { position: relative; z-index: 1; display: grid; justify-items: center; gap: 1rem; }
.signoff__steam { width: clamp(2.2rem, 1.6rem + 2vw, 3.2rem); color: var(--ink); opacity: 0.8; }
.signoff__title { font-size: var(--d-1); max-width: 14ch; }
.signoff__sub { max-width: 34ch; color: var(--on-field-2); }
.signup { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; width: min(30rem, 100%); }
.signup__field { flex: 1 1 14rem; display: grid; gap: 0.3rem; text-align: left; }
.signup input[type='email'] {
  width: 100%;
  background: var(--paper);
  border: 2px solid var(--ink);
  border-radius: 0;
  padding: 0.72rem 0.9rem;
  font-size: var(--t-sm);
}
.signup input::placeholder { color: var(--ink-3); }
.signup__msg { font-size: var(--t-xs); min-height: 1.2em; }
.signup__msg[data-state='ok'] { color: var(--red-deep); font-weight: 600; }
.signup__msg[data-state='err'] { color: var(--red-deep); font-weight: 600; }
.signoff__fine { font-size: var(--t-xs); color: var(--on-field-2); max-width: 32ch; }
.signoff__punjabi { font-size: var(--t-xl); color: var(--on-field-2); margin-top: 0.5rem; }

/* --- Editorial / journal ------------------------------------------------ */
.pagehead { position: relative; }
.pagehead__title { font-size: var(--d-1); max-width: 15ch; margin-top: 1.1rem; }
.pagehead__dek { margin-top: 1.1rem; font-size: var(--t-xl); color: var(--on-field-2); max-width: 40ch; line-height: 1.4; }

/* 404 */
.oops { text-align: center; display: grid; justify-items: center; gap: 1.25rem; padding-block: clamp(4rem, 2rem + 8vw, 8rem); }
.oops__num { font-family: var(--font-display); font-size: clamp(4rem, 2rem + 12vw, 8rem); font-weight: 800; line-height: 0.85; color: var(--red); font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 144; }

/* 12  Utilities, motion, print ------------------------------------------- */

.u-sr {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}
.u-center { margin-inline: auto; }
/* Keeps a date from breaking across lines mid-phrase. */
.u-nowrap { white-space: nowrap; }

/* Upcoming / past swap. Both states are in the markup; `.is-past` on <html>
   is set by the inline head script, so the right one paints first time.
   `display: contents` keeps these wrappers out of the layout entirely. */
.when--upcoming { display: contents; }
.when--past { display: none; }
.is-past .when--upcoming { display: none; }
.is-past .when--past { display: contents; }
.u-mt { margin-top: clamp(1.75rem, 1rem + 2.4vw, 3rem); }
.u-mt-sm { margin-top: 1.1rem; }
.u-hide-sm { display: none; }
@media (min-width: 48rem) { .u-hide-sm { display: revert; } }

/* Reveal: 8px, once, section-level only. This is the whole scroll budget. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  .js [data-reveal] { opacity: 1; transform: none; }
}

@media print {
  .notice, .shopnav, .menu, .awning { display: none !important; }
  body { background: #fff; color: #000; }
  [class*='f-'] { background: #fff !important; color: #000 !important; }
}

/* 13  Landing ----------------------------------------------------------- */
/* A standalone page: one photograph, the mark, the slogan. Rendered without
   the nav or footer, so the section owns the whole viewport. */
.is-lander { background: var(--ink); }
.lander {
  position: relative;
  min-height: 100svh;
  display: grid;
  place-items: center;
  overflow: hidden;
  isolation: isolate;
  padding: var(--gutter);
}
.lander__pic { position: absolute; inset: 0; z-index: -2; }
.lander__pic img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%; }
/* The photograph is bright and pale, so cream type needs a ground to sit on.
   A wash rather than a flat panel — the picture still reads through it. */
.lander::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 90% at 50% 55%, rgba(18, 18, 18, 0.68) 0%, rgba(18, 18, 18, 0.42) 55%, rgba(18, 18, 18, 0.58) 100%);
}
.lander__in {
  display: grid;
  justify-items: center;
  gap: clamp(1.25rem, 0.6rem + 2.4vw, 2.5rem);
  text-align: center;
  color: var(--cream);
}
.lander__slogan {
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 1.1rem + 4.6vw, 5.25rem);
  font-weight: 800;
  font-variation-settings: 'SOFT' 20, 'WONK' 0, 'opsz' 144;
  line-height: 0.98;
  letter-spacing: -0.03em;
  max-width: 12ch;
  text-wrap: balance;
}

/* 14  The bleeding word -------------------------------------------------- */
/* One word, set far larger than anything else, running off the edge of the
   page. It is the only thing on the site allowed to break the margin. */
.bleed {
  /* Declared here so the clip box can be sized against the same number. */
  --bleed-size: clamp(4rem, 19vw, 21rem);
  overflow: clip;
  line-height: 0;
  /* Aligned to the content column, not to the viewport. Flush against the edge
     of the screen reads as cut off even when the whole word is there, and
     floating between the two aligns with nothing. */
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
  /* Room for the ink. A line-height of 0.74 makes a box shorter than the
     glyphs it holds — "Pop-ups" runs 0.93em — so `overflow: clip` was cutting
     62px off the bottom of both p's at 1440 and 77px at 2000. The tails need
     0.24em under the box. The ascenders on "hatti" and "chai" reach past the
     top of it by a smaller amount and were losing 5-7px the same way, so the
     top gets 0.06em. Both are sized off the same clamp as the type, so they
     hold at every width, and both carry more than the measured overflow so a
     pixel of hinting variance cannot put a glyph back on the edge. */
  padding-block: calc(var(--bleed-size) * 0.06) calc(var(--bleed-size) * 0.26);
  margin-block: clamp(1.5rem, 0.5rem + 3vw, 3.5rem) clamp(2.5rem, 1rem + 4vw, 5rem);
}
.bleed__w {
  display: inline-block;
  font-family: var(--font-display);
  /* Sized so the longest word on the site — "Pop-ups", about 3.1x its own
     font size — still fits the content column. Any larger and it clips. */
  font-size: var(--bleed-size);
  font-weight: 800;
  font-variation-settings: 'SOFT' 0, 'WONK' 0, 'opsz' 144;
  line-height: 0.74;
  letter-spacing: -0.05em;
  color: var(--red);
  white-space: nowrap;
  user-select: none;
}
/* Flush to the page edge, not to the text column. No negative margin: it was
   meant to cancel the glyph's side bearing so the word sat optically flush, but
   `overflow: clip` then cut that much off the word — 33px at 1440, 41px at
   2000, which took a bite out of the first or last letter on every page.
   The alignment is set rather than inherited; on the homepage the word sits
   inside a centred sign-off and was picking up its text-align. */
.bleed { text-align: left; }
.bleed--right { text-align: right; }
.f-red .bleed__w, .f-deep .bleed__w { color: var(--cream); }
.f-ink .bleed__w { color: var(--red); }

/* 15  The fold ----------------------------------------------------------- */
/* Rows past the third, folded away. Native <details>, so it needs no script
   and keeps its keyboard behaviour. The summary is set as one more index row
   so the fold reads as part of the list rather than a control bolted to it. */
/* Not display:contents — that removes the <details> box, and the disclosure
   behaviour depends on it. The rows inside carry their own grid, so a plain
   block sits in the list without disturbing it. */
.fold { display: block; }
.fold__t {
  display: grid;
  /* Same track and gap as .flyer--compact, or the summary's label sits 6px
     off the venue column above it. */
  grid-template-columns: 2.25rem minmax(0, 1fr);
  gap: 0 1.25rem;
  align-items: baseline;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-weight: 600;
  color: var(--on-field);
}
.fold__t::-webkit-details-marker { display: none; }
.fold__t::before {
  content: '+';
  color: var(--red);
  font-family: var(--font-text);
  font-size: var(--t-2xs);
}
.fold[open] .fold__t::before { content: '–'; }
.fold__t:hover { text-decoration: underline; text-underline-offset: 4px; }
.fold__less { display: none; }
.fold[open] .fold__more { display: none; }
.fold[open] .fold__less { display: inline; }

/* 16  Notes -------------------------------------------------------------- */
/* A name and a note, on the same rules as the method table. */
.notes { display: grid; border-top: 1px solid var(--rule); margin: 0; }
.notes__row {
  display: grid;
  gap: 0.15rem;
  padding: 0.7rem 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 46rem) {
  .notes__row { grid-template-columns: minmax(0, 9rem) minmax(0, 1fr); gap: 0 1.25rem; align-items: baseline; }
}
.notes dt {
  font-family: var(--font-display);
  font-size: var(--t-base);
  font-weight: 600;
  letter-spacing: -0.008em;
}
.notes dd { margin: 0; font-size: var(--t-xs); color: var(--on-field-2); line-height: 1.45; }

/* 17  Gallery ------------------------------------------------------------ */
/* Four plates on an editorial grid: one tall, two small side by side, one wide.
   No frames, no captions — the sequence is the content. */
.gallery { display: grid; gap: clamp(1rem, 0.5rem + 2vw, 2.5rem); }
/* .plate is the label device in marks.mjs — a gallery figure using that name
   inherited its ink background and padding, which read as a black frame around
   every photograph. */
.shot { margin: 0; }
.method { list-style: none; padding: 0; margin: 0; }
.shot img { display: block; width: 100%; height: 100%; object-fit: cover; }
.shot--tall img { aspect-ratio: 4 / 5; }
.shot--small img { aspect-ratio: 4 / 5; }
.shot--wide img { aspect-ratio: 3 / 2; }

/* On a phone the two black-and-white frames pair rather than stacking. They
   are one shoot of one subject, and full width apiece they put 1300px of
   scroll between the title and the method. */
@media (max-width: 51.99rem) {
  .gallery { grid-template-columns: 1fr 1fr; }
  .shot--tall,
  .shot--wide { grid-column: 1 / -1; }
}
@media (min-width: 52rem) {
  .gallery {
    grid-template-columns: repeat(12, minmax(0, 1fr));
    align-items: start;
  }
  /* The colour pour leads, held to two thirds and offset from the margin so the
     page opens on an image rather than on a grid. */
  .shot--tall { grid-column: 1 / span 6; grid-row: 1 / span 2; }
  .shot--tall img { aspect-ratio: 3 / 4; height: 100%; }
  /* The two black-and-white frames sit beside it, one per row, so neither the
     column nor the row is left half empty.

     Their ratio is what makes the two columns end level. The tall frame is
     6 of 12 columns at 3:4, the pair are 5 of 12, so two of them plus the row
     gap have to equal the tall one's height: 13:10 lands within 2px of it at
     1440 and 1px at 2000. Letting them stretch to the row instead (ratio
     auto) reads as correct in a warm browser and renders at the image's own
     873px in a cold one, which drops the right-hand column half a page. */
  .shot--small:nth-of-type(2) { grid-column: 8 / span 5; grid-row: 1; }
  .shot--small:nth-of-type(3) { grid-column: 8 / span 5; grid-row: 2; }
  .shot--small img { aspect-ratio: 13 / 10; }
  /* Both originals are 845x1500 and a 13:10 window keeps 650px of that, so a
     centred crop takes the head off the top of each. The subject sits in the
     upper third of both frames. */
  .shot--small img { object-position: 50% 18%; }
  /* The last one runs the full measure. */
  .shot--wide { grid-column: 1 / -1; margin-top: clamp(1rem, 0.5rem + 2vw, 2.5rem); }
  .shot--wide img { aspect-ratio: 21 / 9; }
}
