/* ═══════════════════════════════════════════════════════════════════
   BEANERY CAFE
   Ankawa, Erbil

   DIRECTION: green is a brand colour, not a subject.
   It is used the way a brand uses its colour — as flat printed fields
   you set type on. Structure is carried by colour blocking, photography
   and type.

   There IS an illustration layer (see the bottom of this file), but its
   vocabulary is the drink — beans, steam, splashes, cups, swirls — plus
   abstract blobs and squiggles. "Organic" describes the SHAPE LANGUAGE:
   loose, wobbly, hand-drawn. It never means foliage. No leaves, no
   branches, no plants anywhere in this stylesheet.

   Every hex below was SAMPLED from a real photo, not invented:
     --green      the actual painted wall
     --olive      images/hero.png — that photo's own lit ground
     --char       the real interior walls
     --gold       the printed board / signage

   The reference photos these were sampled from were context only and are
   no longer in the repo; --olive is the one still checkable in-tree.
   ═══════════════════════════════════════════════════════════════════ */


/* ── Tokens ─────────────────────────────────────────────────────── */

:root {
  /* Paper */
  --cream:      #F4EFE4;
  --cream-2:    #EAE3D4;
  --cream-3:    #DDD4C0;

  /* Brand green, three steps.
     #5FA366 is the true paint colour, but cream on it measures only
     2.6:1 — a shape, not a word. So the paint is the BRIGHT step used
     for accents, and large fields use the DEEP step (cream on deep
     measures 6.3:1). The ink step is for green text on cream, 8.5:1. */
  --green:      #5FA366;   /* bright — accents, rules, the live dot   */
  --green-deep: #2F6136;   /* deep   — large grounds                  */
  --green-ink:  #234B29;   /* ink    — small green text on cream      */
  --green-dark: #1E4423;   /* deepest — footer                        */

  /* The hero photograph's own ground. NOT the brand green — it is a
     warmer, lit olive. Kept separate on purpose so the two are never
     asked to blend. Re-sample from the photo's edge pixels if it
     changes, or the hero seam will show a mismatched strip. */
  --olive:      #46662F;

  /* Charcoal — the real walls */
  --char:       #1C1C1A;
  --char-2:     #26261F;

  /* Gold — from the signage. Passes on dark grounds only.
     On cream, small text must use --gold-ink (5.3:1). */
  --gold:       #D2A63A;   /* large text / rules on dark only          */
  --gold-soft:  #EFCE7A;   /* small text on --green-deep — 4.8:1       */
  --gold-ink:   #7A5C12;   /* small text on cream — 5.3:1              */

  /* Muted body grey. The obvious pick (#7C7C70) measures 3.6:1 on cream
     — it fails, and fails invisibly, because it still reads as "grey
     text". Darkened until it passes.

     Darkened AGAIN when the marble arrived. The texture multiplies the
     cream, so the real background under this text is not #F4EFE4 but
     cream x the darkest marble pixel (0.906) = rgb(221,217,207). The
     previous #66665C measured 4.89:1 on flat cream but only 4.09:1 in
     a vein — a fail that appears in some places on the page and not
     others, which is the worst kind. #5E5E54 holds 4.6:1 in the
     worst case. Re-measure if images/marble.* is regenerated darker. */
  --muted:      #5E5E54;

  /* Type */
  --display: "Fraunces", Georgia, "Times New Roman", serif;
  --text:    "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Arabic slogan face. Tajawal is geometric like Manrope, so the two
     halves of the slogan read as one voice rather than as a translation
     bolted on. The fallbacks are the faces Windows and macOS actually
     ship with Arabic coverage. */
  --arabic:  "Tajawal", "Segoe UI", "Geeza Pro", Tahoma, sans-serif;

  /* Layout */
  --gutter: clamp(1.25rem, 4.5vw, 4.5rem);
  --maxw:   1200px;

  /* Motion */
  --ease: cubic-bezier(.16, .84, .3, 1);
}


/* ── Reset ──────────────────────────────────────────────────────── */

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

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

body {
  margin: 0;
  background: var(--cream);
  color: var(--char);
  font-family: var(--text);
  font-size: clamp(1rem, .97rem + .16vw, 1.0625rem);
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, picture { display: block; max-width: 100%; }

/* Every photograph on this page is wrapped in <picture> for the webp
   source. <picture> is a wrapper with auto height, so an img sized with
   height:100% resolves against the WRAPPER, not the styled box — and
   silently falls back to the file's intrinsic pixel height. That bit
   the drink stage once (a 339px image overflowing a 260px box upward
   into the heading). Any box that sizes its img by HEIGHT must size the
   picture too.

   The hero is deliberately NOT in this list any more: it sizes its
   cutout by width and lets the height follow the artwork's own ratio,
   so forcing the wrapper to 100% height would squash it. */
.dcard__shot picture { height: 100%; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3 { margin: 0; }
p  { margin: 0; }
dl, dd { margin: 0; }

a { color: inherit; }

:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
  border-radius: 1px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--char);
  color: var(--cream);
  padding: .9rem 1.4rem;
  font-weight: 700;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* Read but not seen. Used where a visual layout is not a sentence —
   the #dollar equation is three terms and two operators on screen, and
   a plain sentence to a screen reader. Not `display:none`, which would
   hide it from assistive tech as well. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}


/* ── Texture ────────────────────────────────────────────────────────
   Two real materials, both applied with background-blend-mode so the
   COLOUR still comes from the token underneath. That is the whole
   trick: the texture modulates the ground, it never replaces it, so
   every contrast ratio measured against the flat token still holds.

   1. WHITE MARBLE — images/marble.webp, generated procedurally (see
      images/marble.svg for the source and why it is drawn, not
      photographed). Multiplied over cream, so cream stays cream and
      only picks up stone veining. It is deliberately near-white: it
      sits under type everywhere it is used.

   2. GREEN NOISE — images/green-noise.webp, supplied. It is a LIGHT
      texture (green through to near-cream), so it can never be used as
      a straight background behind cream text — the pale corner would
      drop contrast through the floor. Multiplied over a deep green
      token instead, it can only ever darken:
        #2F6136 x its palest pixel  -> rgb(47,96,47)   still dark
        #2F6136 x its greenest pixel -> rgb(11,67,19)  darker again
      So the grain arrives and the text stays safe.

   `cover` + `no-repeat`, never `repeat`: neither file is seamless, and
   a tiled non-seamless texture shows a hard grid.
   ─────────────────────────────────────────────────────────────────── */

.hero,
.counter,
.board,
.visit {
  background-color: var(--cream);
  background-image: url("images/marble.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
  /* `fixed` sizes the slab against the VIEWPORT rather than the
     element. Without it, `cover` on a 3000px-tall section stretches one
     1400px square to that height and every vein turns into a smear.
     It also means the stone stays put while the page moves over it,
     which is what a real counter top does. */
  background-attachment: fixed;
}

/* `fixed` backgrounds are repainted on every scroll frame and are a
   known jank source on mobile GPUs — and iOS has historically ignored
   it anyway. Below the breakpoint the slab scrolls with the section;
   the sections are short enough there that the stretch is not visible. */
@media (max-width: 760px) {
  .hero, .counter, .board, .visit { background-attachment: scroll; }
}

.dcard--green {
  background-color: var(--green-deep);
  background-image: url("images/green-noise.webp");
  background-size: cover;
  background-position: 32% 38%;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
}

.site-foot {
  background-image: url("images/green-noise.webp");
  background-size: cover;
  background-position: 70% 30%;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
}

/* Different crop from the footer's on purpose — the same texture at the
   same offset twice on one page reads as a repeated tile rather than as
   material. */
.dollar {
  background-image: url("images/green-noise.webp");
  background-size: cover;
  background-position: 12% 70%;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
}

/* Belt and braces for the two grounds that carry cream text on top of
   a texture: if the image 404s or is still in flight, the flat token
   is what paints, and that token is the one the contrast was measured
   against. */
.dcard--green { color: var(--cream); }


/* ── Shared ─────────────────────────────────────────────────────── */

.wrap {
  width: min(100% - (var(--gutter) * 2), var(--maxw));
  margin-inline: auto;
}

/* Small wide-tracked caps. The one recurring "voice" of the system —
   it appears above every section and nowhere else. */
.label {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 1.1rem;
}
.label-on-green { color: var(--cream); opacity: .82; }
.label-gold     { color: var(--gold-soft); }

h1, h2, h3 {
  font-family: var(--display);
  font-optical-sizing: auto;
  font-weight: 600;
  line-height: .98;
  letter-spacing: -.025em;
  text-wrap: balance;
  color: var(--green-ink);
}
h2 { font-size: clamp(2rem, 1.2rem + 3.4vw, 3.5rem); }

h2.on-green, h2.on-dark { color: var(--cream); }

.lede {
  font-size: clamp(1.02rem, .98rem + .38vw, 1.22rem);
  line-height: 1.55;
  max-width: 44ch;
  color: #4A4A42;
}
.lede-on-green { color: rgba(244, 239, 228, .88); }
.lede-on-dark  { color: rgba(244, 239, 228, .80); }


/* ── Buttons ────────────────────────────────────────────────────────
   Pills. The whole system is built on soft organic shape now — blobs,
   rounded cards, chip bars — and a square button was the one hard
   corner left fighting it.

   The solid button lifts on a soft shadow instead of the old hard
   offset block: an offset block is a print-registration gesture and it
   reads as a mistake next to a rounded shape.
   ─────────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .7em;
  padding: .95em 1.7em;
  border: 2px solid transparent;
  border-radius: 999px;
  font-family: var(--text);
  font-size: .8rem;
  font-weight: 800;
  letter-spacing: .13em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition:
    transform .2s var(--ease),
    box-shadow .2s var(--ease),
    background-color .2s var(--ease),
    color .2s var(--ease),
    border-color .2s var(--ease);
}
.btn-sm { padding: .7em 1.2em; font-size: .7rem; }

/* The circular arrow badge inside a pill, as in the reference. It is a
   <span> in the markup so it never gets read out as content. */
.btn-arrow {
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  margin-right: -.75em;   /* sits snug in the pill's right end */
  margin-left: .15em;
  border-radius: 50%;
  background: rgba(244, 239, 228, .16);
  flex: none;
  transition: transform .2s var(--ease), background-color .2s var(--ease);
}
.btn-arrow svg {
  width: .95em;
  height: .95em;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.btn:hover .btn-arrow { transform: translateX(3px); }

.btn-solid {
  background: var(--green-deep);
  border-color: var(--green-deep);
  color: var(--cream);
  box-shadow: 0 6px 18px -8px rgba(35, 75, 41, .55);
}
.btn-solid:hover,
.btn-solid:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 14px 28px -12px rgba(35, 75, 41, .6);
}
.btn-solid:active { transform: translateY(0); }

.btn-line {
  background: transparent;
  border-color: var(--green-ink);
  color: var(--green-ink);
}
.btn-line .btn-arrow { background: rgba(35, 75, 41, .12); }
.btn-line:hover,
.btn-line:focus-visible {
  background: var(--green-ink);
  color: var(--cream);
  transform: translateY(-2px);
}
.btn-line:hover .btn-arrow { background: rgba(244, 239, 228, .18); }

/* White pill on a green ground — the "JOIN NOW" treatment. */
.btn-cream {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--green-ink);
  box-shadow: 0 6px 18px -8px rgba(16, 40, 20, .45);
}
.btn-cream .btn-arrow { background: rgba(35, 75, 41, .12); }
.btn-cream:hover,
.btn-cream:focus-visible {
  transform: translateY(-2px);
  box-shadow: 0 14px 28px -12px rgba(16, 40, 20, .5);
}

/* On green and charcoal grounds the outline button inverts */
.counter .btn-line, .visit .btn-line {
  border-color: rgba(244, 239, 228, .5);
  color: var(--cream);
}
.counter .btn-line:hover, .visit .btn-line:hover {
  background: var(--cream);
  color: var(--green-ink);
  border-color: var(--cream);
}


/* ── Header ─────────────────────────────────────────────────────── */

.site-head {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--cream);
  border-bottom: 1px solid var(--cream-3);
}
.head-in {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 3vw, 2.5rem);
  min-height: 68px;
}

.brand {
  display: flex;
  align-items: center;
  gap: .65rem;
  text-decoration: none;
  margin-right: auto;
}
/* ── Visual rhymes ──────────────────────────────────────────────────
   Written for the first, monoline redraw of the logo. The mark is now the
   owner's own vector (2026-09-14): it keeps the broken stem (a), but it
   is FILLED, so (b)-(d) below describe the old drawing, not this one. An earlier pass rhymed on a guess at the
   B's shape and got one of them backwards — see rhyme 2.

   What is actually distinctive about the mark, in order:

     a. THE DELIBERATE GAP. The B has no left stem; all that is left of
        it is a short floating bar with clear air above and below. That
        interruption is the signature move of this logo, more than the
        letter or the sprout.
     b. MONOLINE. One constant stroke weight for everything — letter,
        stalk and leaves alike.
     c. OUTLINED, NEVER FILLED. Even the leaves are open counters.
     d. BUTT CAPS. Every terminal is a flat cut, not a round one.

   Rhyming on the sprout is avoided everywhere EXCEPT inside the mark
   itself: green here is ink, not foliage, and repeating leaves around
   the page would turn a coffee bar into a plant shop.

     1. .brand-mark — the tile is square on the open side and round on
        the bowl side, echoing the B's own asymmetry.
     2. .every-rule — bar, gap, short tick: the broken stem (a). It was
        previously a bar with a ROUND terminal, which contradicted (d)
        — the logo has no round ends anywhere. Now butt-cut, like the
        mark. Appears under the hero tagline and again in the footer,
        which is what makes it read as a system rather than a flourish.
     3. #i-blob — the lobed cloud behind the deck and the map is a run
        of round masses, the same soft geometry as the bowls and the
        leaf bodies, at page scale.
   ─────────────────────────────────────────────────────────────────── */

.brand-mark {
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  background: var(--green-deep);
  /* --gold-soft lands at 4.47:1 here — three hundredths short. The mark
     gets its own brighter gold rather than lifting the token everywhere. */
  color: #F3D68C;
  /* Rhyme 1: flat on the stem side, round on the bowl side. */
  border-radius: 5px 15px 15px 5px;
}

/* The monogram, filled with .brand-mark's gold `color`. The size keeps
   the mark's own 504.47:658.02 proportion, so it is never squashed. */
.brand-logo {
  width: 17px;
  height: 22px;
  display: block;
  fill: currentColor;
  stroke: none;
}
.brand-name { display: grid; line-height: 1.05; }
.brand-word {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.22rem;
  letter-spacing: -.02em;
  color: var(--green-ink);
}
.brand-sub {
  font-size: .56rem;
  font-weight: 700;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--gold-ink);
}

.nav { display: flex; gap: clamp(1rem, 2.2vw, 2rem); }
.nav a {
  position: relative;
  font-size: .82rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--char);
  padding-block: .35rem;
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 2px;
  background: var(--green);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .22s var(--ease);
}
.nav a:hover::after, .nav a:focus-visible::after { transform: scaleX(1); }

@media (max-width: 640px) {
  .nav { display: none; }   /* the two CTAs in the hero cover the same ground */
}


/* ── Hero ───────────────────────────────────────────────────────────
   Two blocks, hard seam. See the note in index.html about why the
   photo's olive ground and the brand green are never blended.
   ─────────────────────────────────────────────────────────────────── */

.hero {
  display: grid;
  grid-template-columns: 1fr;
  background-color: var(--cream);   /* NOT the shorthand — it would reset the marble background-image set in the Texture block */
}

/* Single column on a phone: headline, photo, then the supporting copy.
   The two-column pairing only starts at 900px (below).

   `order` is doing real work here. The DOM order is head → sub → shot,
   because that is what the 900px grid-template-areas needs. Left alone
   on a phone that puts the photograph AFTER the buttons and the
   address, stranded at the bottom. Ordering pulls it back between the
   headline and its supporting copy, where it belongs.

   Above 900px the items are placed by named grid areas, which ignores
   `order` entirely — so this costs nothing there. */
.hero-head { order: 1; padding-top: clamp(2.2rem, 6vw, 3.2rem); }
.hero-shot { order: 2; }
.hero-sub  { order: 3; padding-bottom: clamp(2.5rem, 6vw, 4rem); }

.hero-head,
.hero-sub {
  padding-inline: var(--gutter);
  max-width: 40rem;
  margin-inline: auto;
  width: 100%;
}

/* Brought down from a 5.6rem ceiling. Beside the photograph rather
   than above a tall text column, the old size pushed "lifts your mood." into
   the artwork and forced the two apart; smaller lets them sit close,
   which is the whole point of the pairing. */
.hero-h1 {
  font-size: clamp(2.35rem, 1.4rem + 3.7vw, 3.95rem);
  font-weight: 600;
  line-height: .92;
  letter-spacing: -.035em;
  color: var(--green-ink);
}
.hero-h1 em {
  display: block;
  font-style: italic;
  font-weight: 500;
  color: var(--green-deep);
}

.every {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .55rem .8rem;
  margin-top: 1.1rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-ink);
}
/* Rhyme 2: the broken stem. A bar, a gap, then a short tick — the same
   interruption the B makes where its stem should be.

   Square ends, no border-radius: the mark is butt-capped throughout,
   and a rounded rule quietly contradicts it. The gap is ~0.65x the
   logo's own stroke-to-gap ratio, scaled to this size. */
.every-rule {
  position: relative;
  display: block;
  width: clamp(38px, 7vw, 74px);
  height: 2px;
  background: var(--gold);
  flex: none;
}
.every-rule::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  width: 7px;
  height: 2px;
  background: var(--gold);
  transform: translateX(calc(100% + 4px));
}

.hero .lede { margin-top: 1.8rem; }

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: .8rem;
  margin-top: 2.2rem;
}

/* The catchphrase. Set in display type at near-lede size so it reads as
   a second line of the headline rather than as a caption — it was 15px
   sans below the buttons and nobody was going to see it.

   The coin is type in a circle, not an image: at this size a drawn coin
   would be mud, and the number is the whole point. */
.hero-kicker {
  display: flex;
  align-items: center;
  gap: .8rem;
  margin-top: 1.7rem;
}

.kicker-coin {
  display: grid;
  place-items: center;
  width: 3.05rem;
  height: 3.05rem;
  flex: none;
  border-radius: 50%;
  background: var(--gold);
  /* A struck-coin edge rather than a flat disc. Both rings are gold at
     different lightness, so this stays one colour, not a new one. */
  box-shadow:
    inset 0 0 0 2px rgba(255, 255, 255, .34),
    inset 0 0 0 3px rgba(122, 92, 18, .22),
    0 4px 12px -4px rgba(122, 92, 18, .5);
}
.kicker-coin-face {
  font-family: var(--display);
  font-size: 1.16rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.03em;
  /* --char ON gold, not gold on cream: 8.9:1, safe at any size. */
  color: var(--char);
}

.kicker-text {
  font-family: var(--display);
  font-size: clamp(1.12rem, 1rem + .5vw, 1.42rem);
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: -.02em;
  color: var(--green-ink);
  text-wrap: balance;
}
/* The payoff, in the same italic the tagline uses. */
.kicker-text em {
  font-style: italic;
  font-weight: 600;
  color: var(--green-deep);
  white-space: nowrap;
}

.hero-where {
  margin-top: 1.6rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--muted);
}

/* The cutout. No panel, no ground, no crop: hero-3-trim.png has real alpha
   and brings its own green blob, so it is laid on the cream as a
   free-standing object.

   object-fit is deliberately NOT used. `cover` on a transparent cutout
   crops the drink; `contain` inside a ratio box leaves dead air that
   throws the optical centre off. Letting the image keep its own
   intrinsic ratio is the only version where the blob lands where the
   artwork intends. */
.hero-shot {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-inline: var(--gutter);
}
.hero-img {
  width: 100%;
  height: auto;
  /* Bleeds slightly past the column on wide screens so the blob runs
     off the right edge the way it does in the reference. */
  max-width: none;
  filter: drop-shadow(0 26px 34px rgba(30, 68, 35, .18));
}

@media (min-width: 900px) {
  /* The headline sits BESIDE the photograph, and everything that
     supports it — catchphrase, lede, buttons, location — runs
     underneath both. Previously the whole text stack was one tall
     column next to the image, which left the headline stranded at the
     top and a lot of dead cream beside the buttons.

     `head` is deliberately bottom-aligned and `shot` centred: the
     headline should sit ON the photo's optical centre line, not float
     above it. */
  .hero {
    /* `auto` on the shot column, not a percentage. Trimming the alpha
       padding changed the artwork's aspect from 1.78 to 1.21, so a
       percentage column made it render very tall and swamp the
       headline. The image is sized by HEIGHT below and this column
       simply shrinks to whatever width that needs. */
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "head shot"
      "sub  sub";
    align-items: center;
    column-gap: clamp(1rem, 2.5vw, 2.5rem);
    padding-inline: max(var(--gutter), calc((100vw - var(--maxw)) / 2));
    padding-block: clamp(1.6rem, 3.5vw, 2.6rem) clamp(2.4rem, 5vw, 4rem);
  }

  .hero-head {
    grid-area: head;
    align-self: center;
    padding: 0;
    max-width: none;
    margin-inline: 0;
  }

  .hero-sub {
    grid-area: sub;
    padding: 0;
    max-width: none;
    margin-inline: 0;
    margin-top: clamp(1.4rem, 3vw, 2.2rem);
  }

  .hero-shot {
    grid-area: shot;
    padding-inline: 0;
    width: auto;
  }

  /* Sized by height so the pairing stays balanced: the headline sets
     the row, and the artwork matches it instead of dictating it. */
  .hero-img {
    height: clamp(250px, 27vw, 380px);
    width: auto;
    max-width: none;
  }
}

/* The supporting copy runs full width once it is under the photo, so it
   needs its own measure or the lede stretches to 90 characters. */
@media (min-width: 900px) {
  .hero-sub {
    display: grid;
    grid-template-columns: minmax(0, 30rem) minmax(0, 1fr);
    column-gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
  }
  .hero-sub .hero-kicker { grid-column: 1; margin-top: 0; }
  .hero-sub .lede        { grid-column: 1; }
  .hero-sub .hero-cta    { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
  .hero-sub .hero-where  { grid-column: 1 / -1; }
}

/* Below 900px the cutout sits between the headline and the supporting
   copy at its natural ratio. Nothing crops because nothing is boxed. */


/* ── On the counter — chip bar over a horizontal rail ──────────────
   Cream ground now, not the green wall. The green has moved onto ONE
   card — the signature — which is what makes it read as featured
   without needing a badge, a border or a "featured" label.

   Card radius is 34px and the shot well inside it is 26px. They are
   deliberately unequal: concentric rounded shapes need the inner
   radius smaller than the outer minus the padding, or the corners
   look pinched.
   ─────────────────────────────────────────────────────────────────── */

.counter {
  background-color: var(--cream);   /* NOT the shorthand — it would reset the marble background-image set in the Texture block */
  /* Tight at the top: the hero already ends on cream, so a big pad
     here just reads as the page having stalled. The bottom keeps its
     room because the board section below starts with type. */
  padding-block: clamp(1.5rem, 3vw, 2.5rem) clamp(3rem, 7vw, 5rem);
  overflow: hidden;   /* the blobs run off the edges */
}

.counter-head {
  display: grid;
  gap: clamp(1.4rem, 3vw, 2.5rem);
  align-items: end;
  margin-bottom: clamp(1.8rem, 4vw, 2.6rem);
}
@media (min-width: 860px) {
  .counter-head { grid-template-columns: 1fr auto; }
  .counter-side {
    display: grid;
    gap: 1.2rem;
    justify-items: end;
    text-align: right;
  }
  .counter-side .lede { max-width: 32ch; margin-left: auto; }
}


/* ── The deck ─────────────────────────────────────────────────────
   Five cards on a turntable, three of them visible: centre, left,
   right. script.js writes ONE transform per card whenever the deck
   moves and the browser eases it home — nothing runs per frame, which
   is why it settles cleanly instead of drifting.

   The slot table lives in script.js (FAN / ROW), not here. CSS owns
   what a card looks like; JS owns where it sits.
   ─────────────────────────────────────────────────────────────────── */

/* The stage is only as wide as it needs to be, so the arrows land just
   clear of the deck. Side cards bleed past it and are clipped by the
   section's own overflow. */
.stage {
  position: relative;
  /* CONTAINS the deck's z-indexes. script.js writes z-index 4-40 inline
     on the cards, and .site-head is z-index 40 — `position: relative`
     with no z-index does NOT create a stacking context, so the front
     card's 40 was competing with the header's 40 in the ROOT context.
     Later in the DOM wins, so the card painted over the sticky header
     while scrolling. `overflow: hidden` on .counter does not help,
     because the header overlaps the counter's box on the way past.

     z-index: 0 makes a stacking context, so the whole 4-40 range is now
     local to the stage and can never outrank the header. Do not remove
     this to "clean up a zero". */
  z-index: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(.5rem, 3vw, 2rem);
  max-width: min(720px, 100% - var(--gutter));
  height: clamp(380px, 88vw, 460px);
  margin: clamp(1rem, 3vw, 2rem) auto 0;
}

.deck {
  position: relative;
  width: clamp(216px, 61vw, 290px);
  height: clamp(310px, 78vw, 380px);
  flex: none;
  cursor: grab;
  /* Vertical scrolling still belongs to the page — without this a
     downward swipe on the deck would be swallowed. */
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}
.deck.is-grabbing { cursor: grabbing; }
.deck:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 14px;
  border-radius: 30px;
}

.dcard {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  padding: 1.1rem 1.15rem 1.2rem;
  border-radius: 28px;
  background-image: linear-gradient(166deg, var(--tint, #F2ECE0) 0%, var(--tint-2, #E6DECE) 100%);
  color: var(--char);
  box-shadow: 0 18px 34px -20px rgba(30, 68, 35, .55);
  /* Only the front card is transformed to identity, so this transition
     is what makes the whole deck turn. */
  transition:
    transform .62s cubic-bezier(.22, .78, .3, 1),
    opacity   .42s var(--ease),
    box-shadow .42s var(--ease);
  will-change: transform;
}

.dcard.is-front {
  box-shadow: 0 30px 56px -24px rgba(30, 68, 35, .6);
}

/* The signature card. Green ground, so its type inverts.

   NOTE: the ground itself is set in the Texture block near the top of
   this file (green noise multiplied over --green-deep). Do not add a
   background-image here — this rule is later in the cascade and would
   silently win, dropping the texture. */
.dcard--green { color: var(--cream); }

.dcard__tag {
  align-self: flex-start;
  padding: .4em .9em;
  border-radius: 999px;
  background: rgba(255, 255, 255, .62);
  color: var(--green-ink);
  font-size: .6rem;
  font-weight: 800;
  letter-spacing: .14em;
  text-transform: uppercase;
}
/* Gold-on-charcoal, not gold-on-green: --gold on the green card
   measures 2.9:1, which is a shape rather than a word at this size. */
.dcard__tag--gold   { background: var(--gold); color: var(--char); }
.dcard__tag--purple { background: #E4DAF0; color: #4A3369; }

.dcard__shot {
  flex: 1;
  min-height: 0;          /* lets the figure actually shrink in a flex column */
  margin: .85rem 0 .9rem;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
/* <picture> is an auto-height wrapper: an img at height:100% resolves
   against the WRAPPER and silently falls back to intrinsic pixel
   height, overflowing the card. The wrapper has to be sized too. */
.dcard__shot picture { height: 100%; display: flex; align-items: flex-end; }
.dcard__shot img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 14px rgba(30, 42, 28, .22));
}
/* The illustrated stand-ins are square artwork rather than alpha
   cutouts, so they centre instead of sitting on the card's floor. */
.dcard__shot--illo { align-items: center; }
.dcard__shot--illo img { height: auto; width: 88%; }

.dcard__body { flex: none; }

.dcard__name {
  font-family: var(--display);
  font-size: clamp(1.25rem, 1rem + 1vw, 1.55rem);
  font-weight: 600;
  line-height: 1.06;
  letter-spacing: -.025em;
  color: var(--green-ink);
}
.dcard--green .dcard__name { color: var(--cream); }

.dcard__desc {
  margin-top: .45rem;
  font-size: .82rem;
  line-height: 1.45;
  color: var(--muted);
}
.dcard--green .dcard__desc { color: rgba(244, 239, 228, .85); }

.dcard__foot {
  flex: none;
  margin-top: .9rem;
  padding-top: .8rem;
  border-top: 1px solid rgba(35, 75, 41, .16);
}
.dcard--green .dcard__foot { border-top-color: rgba(244, 239, 228, .24); }

.dcard__price {
  font-family: var(--display);
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1;
  color: var(--green-ink);
  font-variant-numeric: tabular-nums;
}
.dcard--green .dcard__price { color: var(--gold-soft); }
.dcard__price i {
  font-family: var(--text);
  font-style: normal;
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: .16em;
  vertical-align: .45em;
  margin-left: .3em;
  opacity: .75;
}

/* ── No-JS fallback ───────────────────────────────────────────────
   script.js adds `is-live` to the stage once it has taken over. Until
   then — and forever, if JS is off — no transform is ever written, so
   absolutely positioned cards would stack on top of one another.

   So the default state in CSS is NOT the deck: it is a plain wrapped
   row where all five drinks are readable, and the arrows (which would
   do nothing) are hidden. The deck is the enhancement.
   ─────────────────────────────────────────────────────────────────── */
.stage:not(.is-live) {
  height: auto;
  max-width: min(100% - var(--gutter), var(--maxw));
}
.stage:not(.is-live) .deckbtn { display: none; }
.stage:not(.is-live) .deck {
  width: 100%;
  height: auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem;
  cursor: default;
}
.stage:not(.is-live) .dcard {
  position: static;
  width: clamp(220px, 80vw, 260px);
  height: auto;
  min-height: 340px;
}
/* The dots are written by JS too, so with no JS there is nothing in
   the container to space away from. */
.stage:not(.is-live) ~ .dots { display: none; }

/* The round arrows either side of the deck. */
.deckbtn {
  width: 48px;
  height: 48px;
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--cream-3);
  border-radius: 50%;
  background: #FFFDF8;
  color: var(--green-ink);
  cursor: pointer;
  box-shadow: 0 6px 18px -8px rgba(30, 68, 35, .35);
  transition: transform .2s var(--ease), background-color .2s var(--ease),
              color .2s var(--ease);
}
.deckbtn svg {
  width: 21px;
  height: 21px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.deckbtn:hover {
  background: var(--green-deep);
  color: var(--cream);
  transform: translateY(-2px);
}


/* ── Dots ─────────────────────────────────────────────────────────
   Built by script.js from the cards the current filter leaves in play,
   so the count follows the filter. Decorative and aria-hidden: each
   one duplicates a move the deck already supports from the keyboard.
   ─────────────────────────────────────────────────────────────────── */

.dots {
  display: flex;
  justify-content: center;
  gap: .5rem;
  margin-top: clamp(1rem, 3vw, 1.8rem);
}
.dots button {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--cream-3);
  cursor: pointer;
  transition: width .25s var(--ease), background-color .25s var(--ease);
}
.dots button.is-on {
  width: 26px;
  border-radius: 999px;
  background: var(--green-deep);
}



/* ── The dollar ─────────────────────────────────────────────────────
   Deep green with the supplied noise texture over it — the one colour
   block between the hero and the footer, so the scroll gets a beat
   instead of running cream the whole way down.

   Texture is multiplied over --green-deep in the Texture block near the
   top of this file, the same way the signature card and the footer are.
   That is what keeps cream type safe on it: a light texture multiplied
   over a dark token can only ever darken.
   ─────────────────────────────────────────────────────────────────── */

.dollar {
  background-color: var(--green-deep);
  color: var(--cream);
  padding-block: clamp(3.2rem, 7vw, 5.5rem);
  overflow: hidden;
}

.dollar-in { display: grid; gap: clamp(2rem, 4.5vw, 3rem); }

.dollar-type h2 { color: var(--cream); }

/* The equation reads DOWN, not across.

   Laid out as a row first, it wrapped: "One espresso" is far too long
   to sit beside two other display-size terms in the space this column
   has, so the last operator ended up stranded at the end of a line
   with nothing after it. Stacking removes the problem outright — and a
   vertical equation is the stronger read anyway, because each term
   lands on its own beat. */
.equation {
  display: grid;
  justify-items: start;
  gap: clamp(.5rem, 1.4vw, .9rem);
}

.eq-term {
  display: grid;
  gap: .25rem;
}

.eq-value {
  font-family: var(--display);
  font-size: clamp(2rem, 1.2rem + 3.4vw, 3.6rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}
/* The last term is the payoff, so it takes the gold. */
.eq-term--last .eq-value { color: var(--gold-soft); }

.eq-unit {
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(244, 239, 228, .72);
}

/* ≈ and = . Deliberately lighter than the terms: they are punctuation,
   not content, and at display size they otherwise shout louder than
   the numbers they join. Indented so they sit under the terms rather
   than starting a new left edge of their own. */
.eq-op {
  font-family: var(--display);
  font-size: clamp(1.2rem, .9rem + 1.2vw, 1.8rem);
  font-weight: 500;
  line-height: 1;
  color: rgba(244, 239, 228, .45);
  margin-left: .15em;
}

.eq-cup {
  width: 24px;
  height: 30px;
  margin-bottom: .35rem;
  fill: none;
  stroke: var(--gold-soft);
  stroke-width: 3.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Sits with the heading, not under the equation. Under the equation it
   left the left-hand column empty for the equation's whole height and
   made the section far taller than it needed to be. */
.dollar-note {
  margin-top: clamp(1.2rem, 3vw, 1.8rem);
  max-width: 40ch;
  font-size: .92rem;
  line-height: 1.55;
  color: rgba(244, 239, 228, .78);
}

@media (min-width: 900px) {
  .dollar-in {
    grid-template-columns: minmax(0, 26rem) minmax(0, 1fr);
    align-items: center;
    column-gap: clamp(2.5rem, 7vw, 6rem);
  }
}

/* ── The board ──────────────────────────────────────────────────────
   Printed-board typography: name, leader dots, count, price. This is
   how breadth gets shown when 46 photographs do not exist — and it is
   more honest than 46 stand-in illustrations would be.
   ─────────────────────────────────────────────────────────────────── */

.board {
  background-color: var(--cream);   /* NOT the shorthand — it would reset the marble background-image set in the Texture block */
  padding-block: clamp(3.5rem, 8vw, 7rem);
}
.board-head {
  display: grid;
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
@media (min-width: 860px) {
  .board-head { grid-template-columns: 1.1fr 1fr; align-items: end; }
  .board-head .lede { padding-bottom: .4rem; }
}

.index {
  border-top: 2px solid var(--green-ink);
  column-gap: clamp(2rem, 5vw, 4.5rem);
}
@media (min-width: 780px) { .index { columns: 2; } }

.index li {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  padding-block: .95rem;
  border-bottom: 1px solid var(--cream-3);
  break-inside: avoid;
}
.ix-name {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -.015em;
  color: var(--green-ink);
  flex: none;
}
.ix-dots {
  flex: 1 1 auto;
  height: 1px;
  min-width: 1.5rem;
  align-self: center;
  background-image: radial-gradient(circle, var(--cream-3) 1px, transparent 1px);
  background-size: 6px 2px;
  background-repeat: repeat-x;
  background-position: 0 center;
}
.ix-n {
  font-size: .78rem;
  font-weight: 800;
  color: var(--gold-ink);
  font-variant-numeric: tabular-nums;
  flex: none;
  min-width: 1.4em;
  text-align: right;
}
.ix-p {
  font-size: .78rem;
  font-weight: 600;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  flex: none;
  min-width: 6.2em;
  text-align: right;
}
.index .ix-star .ix-name { color: var(--gold-ink); }
.index .ix-star .ix-name::after {
  content: "";
  display: inline-block;
  width: 5px; height: 5px;
  background: var(--gold);
  margin-left: .5em;
  vertical-align: .28em;
}

.board-cta {
  position: relative;   /* anchors .deco-arrow */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem 1.8rem;
  /* Deepened so .deco-arrow has clear air above the row to sit in. */
  margin-top: clamp(3rem, 6vw, 5rem);
}
.board-note { font-size: .82rem; color: var(--muted); }


/* ── Visit ──────────────────────────────────────────────────────────
   The reference's closing block: a soft-masked map on one side, the
   address and an OPEN DAILY pill on the other, on cream.

   It used to be a charcoal band. Charcoal was the colour of the real
   walls, but it cut the page in half right where it should be opening
   out, and the reference closes on light.
   ─────────────────────────────────────────────────────────────────── */

.visit {
  background-color: var(--cream);   /* NOT the shorthand — it would reset the marble background-image set in the Texture block */
  color: var(--char);
  padding-block: clamp(3rem, 7vw, 6rem);
  overflow: hidden;
}
.visit-in {
  display: grid;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (min-width: 880px) {
  .visit-in { grid-template-columns: 1.05fr .95fr; }
}

/* The map, wearing the same lobed mask as the blobs so it reads as
   part of the shape language instead of as a pasted widget.

   An iframe cannot be clipped by `clip-path` on itself reliably across
   engines — the composited frame ignores it in some builds. So the
   MASK lives on the wrapper and the iframe just fills it. */
/* A plain rectangle. The map was masked to the logo silhouette and it
   read badly — a solid B at that size stops looking like a letter.

   Dropping the mask also removes the problem it created: Google's Maps
   terms require their attribution logo (bottom-left of the embed) to
   stay visible, and every shaped mask was clipping that corner. An
   unmasked rectangle shows the whole embed, so there is nothing left
   to work around.

   The corner radius is modest and matches the drink cards, so it still
   belongs to the page's rounded language. Set it to 0 for a hard
   rectangle — nothing else depends on it. */
.visit-map {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: clamp(18px, 2.5vw, 28px);
  overflow: hidden;
  background: var(--cream-2);
}
.visit-map iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The watermark above the footer. This was the lobed cloud; it is now
   the logo silhouette, so the two shapes in this section are the mark
   twice over rather than the mark next to a generic blob.

   It MUST set `color` — .blobfill fills with currentColor, and with
   nothing set it inherits the section's near-black body colour and
   lands as a black splat.

   Kept quiet on purpose: the map beside it is already a large B, and
   two loud copies of the same shape would fight. Low opacity and a
   tilt make this read as a watermark under the map, not a second logo. */
.blob-visit {
  bottom: -10%; left: -11%;
  width: min(30vw, 330px);
  aspect-ratio: 504.47 / 658.02;
  color: var(--green);
  opacity: .16;
  transform: rotate(-13deg);
}

.visit-type .lede { margin-bottom: clamp(1.6rem, 3.5vw, 2.2rem); }

.visit-name {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1rem + .6vw, 1.4rem);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--green-ink);
}
.visit-addr {
  margin-top: .45rem;
  font-size: .96rem;
  line-height: 1.55;
  color: var(--muted);
}

/* The OPEN DAILY pill from the reference: a green capsule holding the
   label, with the hours sitting outside it on the cream. */
.openpill {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  margin-top: 1.2rem;
}
.openpill-tag {
  padding: .5em 1.05em;
  border-radius: 999px;
  background: var(--green-deep);
  color: var(--cream);
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.openpill-hrs {
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--green-ink);
  font-variant-numeric: tabular-nums;
}

.facts {
  margin-top: clamp(1.6rem, 3.5vw, 2.2rem);
  border-top: 1px solid var(--cream-3);
}
.fact {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  gap: 1rem;
  padding-block: .9rem;
  border-bottom: 1px solid var(--cream-3);
}
.fact dt {
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-ink);
  padding-top: .28rem;
}
.fact dd { font-size: .96rem; line-height: 1.5; color: var(--char); }
.fact dd a {
  color: var(--green-ink);
  text-decoration-color: rgba(35, 75, 41, .4);
  text-underline-offset: 3px;
}
.fact dd a:hover { color: var(--green-deep); }

@media (max-width: 460px) {
  .fact { grid-template-columns: 1fr; gap: .3rem; }
}

.visit-cta { margin-top: clamp(1.5rem, 3.5vw, 2rem); }

/* Real placeholder, marked as one. Better than an invented address.
   Gold-on-charcoal — the gold ground needs dark ink on cream now that
   the section is light.

   NOTHING USES THIS RIGHT NOW (2026-09-05): the street address was
   supplied and the phone placeholder was removed at the owner's
   request, so both instances are gone. Kept because it is the
   convention this page uses for unknown facts — mark them, never
   invent them — and the next one should look the same. */
.todo {
  display: inline-block;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--char);
  background: var(--gold-soft);
  padding: .1em .5em;
}
/* ── Footer ─────────────────────────────────────────────────────── */

.site-foot {
  /* background-COLOR, not the `background` shorthand: the shorthand
     resets background-image to none and would wipe the green noise
     texture set in the Texture block near the top of this file. */
  background-color: var(--green-dark);
  color: var(--cream);
  padding-block: clamp(3rem, 6vw, 5rem) 1.5rem;
}
.foot-in {
  display: grid;
  gap: clamp(2.2rem, 5vw, 4rem);
  padding-bottom: clamp(2rem, 4vw, 3rem);
}
@media (min-width: 760px) {
  .foot-in { grid-template-columns: 1fr auto; align-items: start; }
}

.foot-tag {
  font-family: var(--display);
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.6rem);
  font-weight: 600;
  font-style: italic;
  line-height: 1;
  letter-spacing: -.03em;
  color: var(--cream);
}
.foot-every {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .55rem .8rem;
  margin-top: 1rem;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-soft);
}
.foot-every .every-rule { background: var(--gold); }

/* ═══════════════════════════════════════════════════════════════════
   THE ARABIC SLOGAN

   بينيري كافيه — نكهة تِعدل المزاج / "A flavor that lifts your mood."

   Three rules, one shape. Each of them:

   • sets font-family explicitly — the Latin stack has no Arabic glyphs,
     so without this the browser silently substitutes a system face and
     the line stops matching the rest of the page;
   • leaves letter-spacing alone. Arabic is a joined script; tracking it
     pulls the connectors apart and the word visibly breaks. Every
     tracked rule on this page is Latin-only for that reason;
   • runs a taller line-height. The script's marks sit above and below
     the baseline (the kasra under تِعدل is exactly this), and 1.2 clips
     them against the line above.

   dir="rtl" lives on the element in the HTML, not here — direction is
   content, and it has to survive the stylesheet failing to load.
   ═══════════════════════════════════════════════════════════════════ */
.slogan-ar {
  margin-top: 1.45rem;
  /* dir="rtl" orders the glyphs; it must not drag the block to the
     right-hand edge as well. The page is a left-aligned layout and the
     Arabic is a sibling of the headline, not a caption floated opposite
     it — so alignment is set here, independently of direction. */
  text-align: left;
  font-family: var(--arabic);
  font-size: clamp(1.15rem, .95rem + .8vw, 1.5rem);
  font-weight: 500;
  line-height: 1.75;
  color: var(--green-deep);
}

.visit-name-ar {
  margin-top: .15rem;
  font-family: var(--arabic);
  font-size: clamp(1rem, .95rem + .35vw, 1.15rem);
  font-weight: 500;
  line-height: 1.7;
  color: var(--gold-ink);
}

.foot-tag-ar {
  margin-top: .75rem;
  font-family: var(--arabic);
  font-size: clamp(1rem, .9rem + .5vw, 1.25rem);
  font-weight: 400;
  line-height: 1.75;
  color: var(--gold-soft);
}

.foot-nav { display: flex; gap: clamp(2.5rem, 6vw, 5rem); }
.foot-nav div { display: grid; gap: .6rem; align-content: start; }
.foot-nav h2 {
  font-family: var(--text);
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: .3rem;
}
.foot-nav a {
  font-size: .9rem;
  text-decoration: none;
  color: rgba(244, 239, 228, .82);
  width: fit-content;
}
.foot-nav a:hover { color: var(--cream); text-decoration: underline; text-underline-offset: 4px; }

.foot-fine {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: .5rem 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(244, 239, 228, .16);
  font-size: .76rem;
  color: rgba(244, 239, 228, .6);
}


/* ── Motion ─────────────────────────────────────────────────────────
   Headings and ledes only. Body copy that fades in is body copy you
   cannot start reading.
   ─────────────────────────────────────────────────────────────────── */

/* Scoped to .js (set by an inline script during parse) so that with
   JavaScript off nothing is ever left at opacity 0. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
.js .reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  /* Remove motion, do not slow it down. */
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  /* Must match the .js scope above or it loses on specificity. */
  .js .reveal { opacity: 1; transform: none; }
  .drink:hover .drink-shot img { transform: none; }
}


/* ── Print ──────────────────────────────────────────────────────── */

@media print {
  .site-head, .hero-shot, .hero-cta, .board-cta, .skip { display: none; }
  body { background: #fff; color: #000; }
  .counter, .visit, .site-foot { background: #fff; color: #000; }
}


/* ═══════════════════════════════════════════════════════════════════
   ILLUSTRATION LAYER

   Loose vector line art, drawn from the drink: beans, steam, splashes,
   cups, swirls, sparkles. Organic in SHAPE — wobbly strokes and soft
   blobs — not in subject. Nothing botanical.

   Three rules hold the whole layer together:

     1. It is decoration and behaves like it. Every mark is
        aria-hidden, pointer-events:none, and sits at z-index 0 behind
        content at z-index 1. It cannot be tabbed to, clicked, read by
        a screen reader, or selected along with the text.

     2. It never lands under running text. Positions are hand-placed in
        the margins and gutters and checked at 390 / 768 / 1280 / 1600.
        Anything that would collide at a small width is REMOVED at that
        width rather than shrunk into confetti.

     3. It never changes contrast. Marks sit behind text, never over
        it, and blob fills stay in the same hue family as their ground
        so the effective background under any glyph is unchanged.
   ═══════════════════════════════════════════════════════════════════ */

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* PRESENTATION MUST BE SET ON THE INSTANCE, NOT ON `.sprite path`.
   A <use> clones its symbol into a shadow tree that outside selectors
   cannot reach — `.sprite path {…}` styles the ORIGINAL in <defs>,
   which is never rendered, and the clone falls back to SVG's default
   `fill: black; stroke: none`. The symptom is line art arriving as
   solid black blobs.

   Only INHERITED properties cross the shadow boundary. fill, stroke,
   stroke-width, stroke-linecap and stroke-linejoin all inherit, so
   setting them on the instance reaches the cloned geometry.
   `vector-effect` does NOT inherit, so it is deliberately absent here;
   every symbol is instead rendered near 1:1 with its viewBox, which
   keeps the stroke weight visually even without it. */
.deco, .seal-bean {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* The sparkle is the one solid mark — it needs mass to read at 20px. */
.deco-spark-a, .deco-spark-b, .deco-spark-c { fill: currentColor; stroke: none; }

/* The underline is inlined rather than <use>d, because it is the one
   mark that must stretch to the width of the words above it. Inline
   geometry is a real descendant, so `vector-effect` works here and
   stops preserveAspectRatio="none" from fattening the stroke. */
.deco-under path {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.deco {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  overflow: visible;
}

/* Soft abstract fields. Asymmetric radii on purpose — an even ellipse
   reads as a shape tool, an uneven one reads as drawn. Kept for the
   small background washes; anything that has to READ as a shape uses
   .blobfill instead. */
.blob {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  border-radius: 58% 42% 47% 53% / 44% 56% 44% 56%;
}

/* The lobed cloud (#i-blob), filled. It deliberately opts out of the
   .deco stroke rules below — those set fill:none, which would render
   this as nothing at all. Colour comes from `color`, so one symbol
   serves every tint on the page.

   `fill` is set on the INSTANCE, not on `.blobfill path` — a <use>
   clones its symbol into a shadow tree that outside selectors cannot
   reach, and only inherited properties cross that boundary. `fill`
   inherits; a descendant selector would style the unrendered original
   in <defs> and the clone would fall back to solid black. */
.blobfill {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  overflow: visible;
  fill: currentColor;
  stroke: none;
}

/* Sections become positioning contexts; their content lifts above the
   illustration. */
.hero, .counter, .board, .visit, .site-foot, .signature { position: relative; }
.hero > .hero-head,
.hero > .hero-sub,
.hero > .hero-shot,
.counter > .wrap,
.board > .wrap,
.visit > .wrap,
.site-foot > .wrap,
.site-foot > .foot-fine,
.signature > .sig-type,
.signature > .sig-price { position: relative; z-index: 1; }


/* ── Hero ───────────────────────────────────────────────────────── */

/* The squiggle under "lifts your mood." — the one mark allowed near text,
   because it sits deliberately below the descenders and uses the gold
   that already passes on cream. */
.hero-em { position: relative; display: inline-block; }
.deco-under {
  left: 0;
  bottom: -.18em;
  width: 100%;
  height: .24em;
  color: var(--gold);
  opacity: .9;
}

.blob-hero {
  top: -8%;
  left: -14%;
  width: min(46vw, 520px);
  aspect-ratio: 1 / .86;
  background: var(--green);
  opacity: .07;
}

.deco-bean-a {
  --r: -18deg;
  top: 15%; right: 6%;
  width: 42px; height: 29px;
  color: var(--green-ink);
  opacity: .34;
  transform: rotate(var(--r));
  animation: bob 7s var(--ease) infinite;
}
.deco-bean-b {
  --r: 24deg;
  bottom: 13%; left: 3%;
  width: 30px; height: 21px;
  color: var(--gold-ink);
  opacity: .32;
  transform: rotate(var(--r));
  animation: bob 9s var(--ease) infinite reverse;
}
.deco-spark-a {
  top: 29%; right: 3%;
  width: 20px; height: 20px;
  color: var(--gold);
  opacity: .55;
  animation: twinkle 4.5s ease-in-out infinite;
}

/* The seal. It used to straddle the hard seam between the cream column
   and the photo panel — but that seam is gone with the cutout, and left:0
   left it stranded in open cream halfway across the page.

   Now it sits low and left, clear of the cup. Once the artwork was
   trimmed of its transparent padding the old 12%/78% put the seal
   squarely on top of the drink — the percentages are relative to the
   shot box, and that box got much tighter. */
.seal {
  position: absolute;
  z-index: 2;
  left: -6%;
  top: 84%;
  width: clamp(96px, 12vw, 148px);
  height: clamp(96px, 12vw, 148px);
  transform: translate(-50%, -50%);
  pointer-events: none;
  overflow: visible;
}
.seal-ring    { fill: var(--cream); stroke: none; }
.seal-ring-in { fill: var(--green-deep); }
.seal-text {
  font-family: var(--text);
  font-size: 15px;
  font-weight: 800;
  /* The legend lost six characters when the tagline changed. Tracking
     is what refills the ring — at .16em the text stopped short of its
     own start and left a visible bald patch on the arc. */
  letter-spacing: .355em;
  fill: var(--green-ink);
  animation: spin 26s linear infinite;
  transform-origin: 100px 100px;
}
.seal-bean { color: var(--gold-soft); }

/* Below 900px the hero stacks and the seam it straddles stops
   existing. Move it onto the corner of the photograph instead. */
@media (max-width: 899px) {
  .seal { left: auto; right: 5%; top: auto; bottom: -5%; transform: none; }
  .blob-hero { display: none; }
  .deco-bean-a { top: 8%; right: 5%; }
}
@media (max-width: 520px) {
  /* At phone width the gutters are too narrow to hold marks beside
     text without crowding it. Keep the seal, drop the scatter. */
  .deco-bean-a, .deco-bean-b, .deco-spark-a { display: none; }
}


/* ── Counter ────────────────────────────────────────────────────── */

.counter { overflow: hidden; }

/* The deck's own backdrop. These are the one pair of shapes allowed to
   be BOLD: the cards on top are opaque, so nothing is reading text off
   the tint, and a pale wash at this size just reads as a stray circle.

   Pinned to the deck's band (top 34%) rather than to the section top,
   so neither ever slides under .counter-head, where the heading and
   the lede DO read off the cream. */
/* Sized so the LOBES are inside the frame. At 700px with the shape
   half off-canvas you only ever see one smooth arc, and a big enough
   arc is indistinguishable from a circle — which defeats the whole
   reason for using a path instead of border-radius. */
.blob-counter-a {
  top: 26%; right: -7%;
  width: min(40vw, 440px);
  aspect-ratio: 200 / 172;
  color: var(--green);
  opacity: .34;
  transform: rotate(-14deg);
}
.blob-counter-b {
  bottom: 3%; left: -8%;
  width: min(31vw, 340px);
  aspect-ratio: 200 / 172;
  color: #7FBF86;
  opacity: .32;
  transform: rotate(22deg);
}

.deco-steam-a {
  top: 6%; right: 13%;
  width: 46px; height: 52px;
  color: var(--cream);
  opacity: .30;
  animation: rise 6s var(--ease) infinite;
}
.deco-drops-a {
  top: 46%; left: 1.5%;
  width: 62px; height: 42px;
  color: var(--gold-soft);
  opacity: .34;
  transform: rotate(-12deg);
}
.deco-swirl-a {
  bottom: 4%; right: 4%;
  width: 62px; height: 62px;
  color: var(--cream);
  opacity: .18;
}

.deco-spark-b {
  top: -14px; right: 44px;
  width: 26px; height: 26px;
  color: var(--gold); opacity: .9;
  animation: twinkle 3.6s ease-in-out infinite;
}
.deco-spark-c {
  bottom: -10px; left: 38px;
  width: 17px; height: 17px;
  color: var(--gold); opacity: .7;
  animation: twinkle 5.2s ease-in-out .8s infinite;
}

@media (max-width: 760px) {
  .deco-steam-a, .deco-drops-a, .deco-swirl-a { display: none; }
  /* On a phone the section is narrow enough that these two blobs meet
     behind the deck and stack into a much darker field than either one
     alone. Backed off so the pair still reads as two shapes. */
  .blob-counter-a, .blob-counter-b { opacity: .18; }
}


/* ── Board ──────────────────────────────────────────────────────── */

.board { overflow: hidden; }

.deco-cup {
  top: 8%; right: 4%;
  width: 58px; height: 72px;
  color: var(--green-ink);
  opacity: .22;
  transform: rotate(8deg);
}
.deco-wave {
  bottom: 3%; left: 0;
  width: min(100%, 460px); height: 22px;
  color: var(--green);
  opacity: .3;
}

/* Points from the note across to the button. Removed on small screens
   where the two stack and the arrow would point at nothing. */
.deco-arrow {
  position: absolute;
  left: 178px; top: -70px;
  width: 68px; height: 50px;
  color: var(--gold-ink);
  opacity: .55;
  transform: scaleX(-1) rotate(14deg);
}
@media (max-width: 900px) { .deco-cup { display: none; } }
@media (max-width: 660px) { .deco-arrow { display: none; } }


/* ── Visit ──────────────────────────────────────────────────────── */

.visit { overflow: hidden; }

/* Both sit in the outer margin, clear of the 1200px content column
   (which starts at x≈112 on a 1425px viewport). */
.deco-steam-b {
  bottom: 11%; left: 2.5%;
  width: 54px; height: 62px;
  color: var(--gold);
  opacity: .3;
  animation: rise 7.5s var(--ease) infinite;
}
.deco-swirl-b {
  top: 11%; right: 4%;
  width: 54px; height: 54px;
  color: var(--gold);
  opacity: .18;
}
@media (max-width: 880px) { .deco-steam-b, .deco-swirl-b { display: none; } }


/* ── Footer ─────────────────────────────────────────────────────── */

.site-foot { overflow: hidden; }

.deco-bean-d {
  top: 17%; right: 5%;
  width: 40px; height: 27px;
  color: var(--gold-soft);
  opacity: .26;
  transform: rotate(16deg);
}
.deco-drops-b {
  bottom: 13%; left: 2.5%;
  width: 54px; height: 36px;
  color: var(--green);
  opacity: .5;
  transform: rotate(8deg);
}
@media (max-width: 760px) { .deco-bean-d, .deco-drops-b { display: none; } }


/* ── Illustration motion ────────────────────────────────────────────
   Slow, small, transform/opacity only. It should read as the page
   breathing, never as something asking for attention.

   Each bob instance re-declares its angle through --r, because the
   keyframes set `transform` wholesale and would otherwise drop the
   rotation the moment the animation starts.
   ─────────────────────────────────────────────────────────────────── */

@keyframes bob {
  0%, 100% { transform: translateY(0)    rotate(var(--r, 0deg)); }
  50%      { transform: translateY(-9px) rotate(var(--r, 0deg)); }
}
@keyframes rise {
  0%, 100% { transform: translateY(0)    scaleY(1);    opacity: .30; }
  50%      { transform: translateY(-7px) scaleY(1.05); opacity: .16; }
}
@keyframes twinkle {
  0%, 100% { transform: scale(1)   rotate(0deg);  opacity: .85; }
  50%      { transform: scale(.72) rotate(28deg); opacity: .35; }
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  /* Removed, not slowed. The seal stops where it stands and stays
     legible; nothing else moves at all. */
  .deco, .blob, .seal, .seal-text { animation: none !important; }
}


/* ── Dollar decoration ────────────────────────────────────────────── */

.dollar { position: relative; }
.dollar > .wrap { position: relative; z-index: 1; }

.blob-dollar {
  top: -26%; right: -10%;
  width: min(40vw, 460px);
  aspect-ratio: 200 / 172;
  color: #7FBF86;
  opacity: .16;
  transform: rotate(16deg);
}

.deco-bean-e {
  bottom: 12%; right: 8%;
  width: 34px; height: 23px;
  color: var(--gold-soft);
  opacity: .38;
  transform: rotate(-22deg);
  animation: bob 8s var(--ease) infinite;
}
/* Kept clear of the equation column — parked next to an operator it
   read as part of the maths. */
.deco-spark-d {
  top: 12%; right: 6%;
  width: 18px; height: 18px;
  color: var(--gold);
  opacity: .6;
  animation: twinkle 5s ease-in-out infinite;
}

@media (max-width: 760px) {
  .deco-bean-e, .deco-spark-d { display: none; }
}


/* ═══════════════════════════════════════════════════════════════════
   FOLIAGE RESTYLE — 2026-09-05

   Layered on top of the sheet above rather than cut into it, so the
   original design survives underneath: delete this block and the page
   returns to what it was.

   Three new things carry the look:

     .field   flat pale-green colour fields behind the type
     .leaf    photographic leaf cutouts in the margins
     .script  gold handwriting, set in Sacramento

   The rule that governs all three: DECORATION NEVER TOUCHES READING.
   Every one of them is aria-hidden, pointer-events:none, and sits at a
   z-index below the content layer, which the sheet above already pins
   to z-index 1. Nothing here may reduce the contrast of a word.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  /* Pale steps of the brand green, for colour fields only — they are
     grounds, never type colours. Cream text on either of these would
     be illegible, so nothing is ever set on top of them directly. */
  --green-pale:  #DEE8D2;
  --green-pale-2:#CBDCBC;

  --script: "Sacramento", "Segoe Script", "Brush Script MT", cursive;
}


/* ── Colour fields ──────────────────────────────────────────────────
   The mockup's soft green sweeps. Same lobed radii the .blob shapes
   already use, so they read as one family. Sized in vw so they scale
   with the viewport rather than the section's content height. */

.field {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  border-radius: 58% 42% 47% 53% / 44% 56% 44% 56%;
  background: var(--green-pale);
}

.field--hero-a {
  width: 86vw;
  height: 44vw;
  left: -26vw;
  top: -16vw;
  opacity: .75;
}

.field--hero-b {
  width: 54vw;
  height: 30vw;
  right: -18vw;
  top: 20vw;
  background: var(--green-pale-2);
  opacity: .5;
  border-radius: 46% 54% 62% 38% / 55% 42% 58% 45%;
}


/* ── Leaves ─────────────────────────────────────────────────────────
   Cut out of the supplied sheet (16 on one transparent PNG) by
   connected-component labelling on the alpha channel, each masked to
   its own component so a neighbour overlapping the bounding box does
   not ride along. The monstera on that sheet was dropped: wrong plant,
   and the one silhouette that would have read as houseplant rather
   than coffee.

   The drop shadow is CSS rather than baked into the files, because the
   same leaf is used on cream and on deep green and a baked shadow only
   suits one of them. */

.leaf {
  position: absolute;
  z-index: 0;
  display: block;
  height: auto;
  pointer-events: none;
  user-select: none;
  filter: drop-shadow(0 16px 20px rgba(24, 54, 28, .18));
}


/* ── Gold handwriting ───────────────────────────────────────────────
   Real text in a real webfont, not lettering exported as pictures.

   aria-hidden on purpose: every one of these repeats a line the page
   already says out loud somewhere else, and read in DOM order they
   would interrupt the sentence they are pinned beside. They are
   marginalia, so they are hidden from the accessibility tree the same
   way .deco is.

   Colour is the two tokens that were measured: --gold-ink on cream
   (5.3:1), --gold-soft on --green-deep (4.8:1). Never the raw --gold,
   which fails on both. */

.script {
  position: absolute;
  z-index: 1;
  margin: 0;
  font-family: var(--script);
  font-weight: 400;
  font-size: clamp(1.3rem, 2vw, 1.95rem);
  line-height: 1.02;
  color: var(--gold-ink);
  pointer-events: none;
  user-select: none;
}

.script--dollar-a,
.script--dollar-b { color: var(--gold-soft); }


/* Sideways in the right margin of the hero. writing-mode does the
   rotation, which keeps it as selectable, translatable text rather
   than a transformed block. */
.vert {
  position: absolute;
  z-index: 1;
  margin: 0;
  writing-mode: vertical-rl;
  font-family: var(--text);
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--muted);
  pointer-events: none;
  user-select: none;
}


/* ── Leaf sizes ─────────────────────────────────────────────────────
   Three steps, all fluid, and every cap is set by the SOURCE FILE, not
   by taste. The current set is cut from the supplied sheet and the
   individual leaves come off it at 97–199px on the long edge — much
   smaller than the previous set's 250–360px. Pushed past native, a
   photographic cutout goes soft, and soft foliage reads as cheap stock
   rather than as art direction, so --leaf-lg stops at 195px (about
   1.15x on the largest file, which is as far as these go before the
   edges mush).

   The apparent size comes from bleed instead: every large leaf is
   positioned to run off its section's edge, so a 195px leaf reads as a
   branch entering the frame rather than as a 195px sticker. If truly
   bigger leaves are wanted, they need re-cutting from a larger sheet —
   raising these numbers will only blur what is here. */
:root {
  --leaf-lg: clamp(120px, 13.5vw, 195px);
  --leaf-md: clamp(96px,  10.5vw, 155px);
  --leaf-sm: clamp(70px,  8vw,    115px);
}


/* ── Hero placements ────────────────────────────────────────────────
   Four leaves in two gestures: a CLUSTER in the top-right corner
   (hero-1 over hero-2, overlapping, at opposing angles) and a quieter
   answer down the left margin (hero-3, hero-4).

   The cluster is the part worth preserving. The reference does not
   space its leaves evenly — it overlaps two or three of them at one
   corner so they read as a single branch coming into frame, and leaves
   the rest of the edge empty. Evenly spaced single leaves at the same
   count read as wallpaper.

   The old constraint still holds: none of these passes behind running
   text. The content column is 1200px inside a 1440px page, leaving
   only ~8% of margin each side, so anything that comes inward does it
   over the PHOTOGRAPH (which is where the reference puts its leaves
   too) or in a vertical gap — never beside the words. Measured
   positions of everything in this section are in the comment at the
   foot of this block. */

/* The left-hand offsets are max(), not a plain percentage, and that is
   the fix for a bug you only see on a big monitor. A percentage bleed
   keeps GROWING with the viewport while the leaf itself stops growing
   at its clamp — so past about 1500px the leaf walked entirely off the
   left edge and simply vanished. max() pins the bleed once it reaches
   the pixel value, so the sliver that shows is roughly constant from
   1100px up instead of shrinking to nothing. */
.leaf--hero-1 { width: var(--leaf-lg); right: -5%; top: -6%;                     transform: rotate(-26deg); }
.leaf--hero-2 { width: var(--leaf-md); right: 5%;  top: 8%;                      transform: rotate(24deg); }
/* hero-3 sits ABOVE the headline, not beside it. The h1's first line
   starts at 17% of the hero, so a leaf whose bottom stops short of
   that clears the text COMPLETELY and is then free to come inboard on
   x — which is what makes it visible at all. Bled sideways instead, the
   only part of it inside the viewport was the empty corner of a
   34deg-rotated bounding box, i.e. nothing. */
.leaf--hero-3 { width: var(--leaf-md); left: -8%; top: -20%;                     transform: rotate(-52deg); }
.leaf--hero-4 { width: var(--leaf-sm); left: max(-6%, -80px);   bottom: 0%;      transform: rotate(-16deg); }

.script--hero { right: 2.5%; top: 26%; text-align: center; }
.vert--hero   { right: 1.5%; top: 52%; }


/* ── Counter placements ─────────────────────────────────────────────
   Two, and both are edge notes. .counter is overflow-x: clip already,
   so anything hanging past the side is trimmed rather than widening
   the page.

   counter-1 is the sprig behind the deck. Its top sits ABOVE the
   section box (top: -6%) so it appears to grow up out of the cards
   from behind them — the cards paint over it because the leaves come
   earlier in the DOM at the same z-index. */

.leaf--counter-1 { width: var(--leaf-sm); left: 56%;  top: -8%;    transform: rotate(16deg); }
.leaf--counter-2 { width: var(--leaf-sm); left: max(-6%, -80px); bottom: 3%; transform: rotate(26deg); }


/* ── The green band ─────────────────────────────────────────────────
   The section itself now carries the same cream + marble as its
   neighbours, and the GREEN is a separate layer inside it. That split
   is what lets the wave exist: .dollar-ground is clipped, .dollar is
   not, so leaves can sit half on the green and half on the cream the
   way they do in the mockup.

   The padding has to clear the wave. The clip takes up to 7% off the
   top and 5.3% off the bottom of the ground, so at a ~700px section
   that is ~49px and ~37px of green removed — the padding below is
   comfortably past both, which is why no heading ever lands in the
   trough of a wave. */

.dollar {
  position: relative;
  background-color: var(--cream);
  background-image: url("images/marble.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
  background-attachment: fixed;
  padding-block: clamp(6rem, 12vw, 9.5rem);
  overflow: hidden;
}

.dollar-ground {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-color: var(--green-deep);
  background-image: url("images/green-noise.webp");
  background-size: cover;
  background-position: 12% 70%;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
  clip-path: url(#wave-band);
}

/* The band's own content has to clear both the ground and the leaves. */
.dollar > .wrap { position: relative; z-index: 2; }

/* Three, in two gestures again: a pair coming in from the left edge
   and one answering on the right. dollar-1 and dollar-2 overlap for
   the same reason the hero pair does.

   These two are the BRIGHT and the SPRIG files on purpose — see the
   note in the markup. The band is the only dark ground on the page and
   the near-black leaves disappear into it. dollar-3 may be the dark
   pair because it is placed to straddle the top edge, half on the
   green and half on the cream above it. */

.leaf--dollar-1 { width: var(--leaf-md); left: -3%;  top: -12%;   transform: rotate(150deg); }
.leaf--dollar-2 { width: var(--leaf-md); left: -3%;  bottom: -8%; transform: rotate(14deg); }
.leaf--dollar-3 { width: var(--leaf-lg); right: -6%;  top: 45%;    transform: rotate(30deg); }

.script--dollar-a { left: 12%;  bottom: 12%; }
.script--dollar-b { right: 12%; top: 30%; text-align: right; }


/* ── Board placements ───────────────────────────────────────────────
   There are none, and that is the rule rather than an omission. See
   the note in index.html: this section is a 46-line price table, the
   densest type on the page, and the reference keeps it completely
   clear. The foliage elsewhere reads as decoration BECAUSE it stops
   here. The scripts stay — they are words, not ornament. */

.script--board-a { right: 3%;  top: 8%;    text-align: right; }
.script--board-b { right: 4%;  bottom: 8%; text-align: right; }


/* ── Visit placements ───────────────────────────────────────────────
   One leaf, in the right margin. The section already has a map and the
   footer under it opens on a full-bleed photograph, so this is only
   here to carry the motif over that gap.

   Nothing is allowed into the map's bottom-left corner: Google's terms
   require their attribution stay visible, and a leaf over it is the
   same violation as masking it. This one is on the opposite side. */

.leaf--visit-1 { width: var(--leaf-md); right: -5%; top: 3%; transform: rotate(28deg); }

.script--visit { right: 4%; bottom: 4%; text-align: right; }


/* ── Small screens ──────────────────────────────────────────────────
   Below 760px the margins the leaves live in do not exist, so most of
   them would land behind text. Three survive, in the corners, and the
   rest are display:none — which also means the browser never fetches
   them, since they are loading="lazy". The colour fields go too: at
   phone width they cover the whole hero rather than sweeping across it.

   Which three, and where, is set in the mobile foliage block near the
   foot of this file — this list only says what goes away.

   .dollar also drops the fixed attachment here, matching the rule the
   other sections already have — fixed backgrounds repaint every scroll
   frame and are a known jank source on mobile GPUs. */

/* ── The margin runs out at 1100px ──────────────────────────────────
   Six of the ten leaves hang off a side edge, and every one of them is
   positioned to stop short of the content column. That column is
   1200px wide, so above ~1330px there is a real margin either side and
   they sit in it comfortably. Below that the page falls back to the
   gutter — 4.5vw, about 50px at 1100px — and the leaves' own bleed is
   a percentage of the SECTION, not of the margin, so they cross into
   the text before the gutter does.

   Chasing that with per-breakpoint offsets is what produced the pile
   of contradictory correction blocks this file used to carry. The
   honest fix is that the side leaves do not belong at a width with no
   sides: below 1100px the set drops to the four that hang off the top
   or sit over a picture, and none of them is anchored to a margin.

   Same 1100px as the counter layout and the deck's SLOT table. Three
   things now turn on that number. */

@media (max-width: 1099.98px) {
  .leaf--hero-2, .leaf--hero-3, .leaf--hero-4,
  .leaf--counter-2,
  .leaf--dollar-1, .leaf--dollar-3 { display: none; }
}

@media (max-width: 760px) {
  .dollar { background-attachment: scroll; padding-block: clamp(4rem, 14vw, 6rem); }

  .field--hero-b,
  .leaf--counter-1,
  .script--board-a, .script--board-b,
  .vert--hero { display: none; }

  .script--hero     { right: 3%; top: 20%; font-size: 1.15rem; }
  .script--dollar-a { left: 6%; bottom: 4%; font-size: 1.15rem; }
  .script--dollar-b { display: none; }
  /* padding-inline is not decoration here. This <p> is a direct child of
     <section class="visit">, NOT of the .wrap inside it — which is fine
     while it is absolutely positioned, and wrong the moment this rule
     returns it to the flow: the section has no inline padding of its
     own, so "Good space, good people" set flush against x=0 and the
     first glyph of each line was touching the edge of the screen.
     Measured at 390px: ink ran 0..78px. */
  .script--visit    {
    position: static;
    margin-top: 1.5rem;
    padding-inline: var(--gutter);
    text-align: left;
  }
}


/* ── Corrections after the first pass on screen ─────────────────────

   Measured with a script that walks every .leaf / .script / .field and
   every text node and reports overlap, then read back against a
   full-page screenshot. Bounding-box overlap ALONE over-reports badly
   here: a rotated cutout's box is much bigger than its ink, and the
   full-width <p> elements report their box, not their line. So the box
   test was used to find candidates and the screenshot to confirm.

   The one real collision it caught: .leaf--counter-1 sat on top of
   "Seven of forty-six. The rest hang on the board", which is grey body
   text — the exact thing decoration is not allowed to touch.

   THE COUNTER FIXES THAT USED TO SIT HERE ARE GONE. They pinned the
   old leaf set to positions in the old one-column counter, and both
   have since been replaced — the section is a two-column hero now and
   the leaves are a different set of files at a different scale. The
   method above is still the method; the numbers it produced no longer
   describe anything. Current placements are in the Counter block. */

/* The counter's original pale circles were drawn to carry an otherwise
   empty section. The colour fields and the leaves now do that, and at
   full strength all three together turned the section into soup. */
.blob-counter-a { opacity: .16; }
.blob-counter-b { opacity: .16; }

/* Was a hard-edged ellipse parked in the middle of the right-hand side,
   which read as a mistake rather than as a sweep. Pushed mostly
   off-canvas and widened so only the leading edge shows. */
.field--hero-b {
  width: 68vw;
  height: 38vw;
  right: -34vw;
  top: 12vw;
  opacity: .45;
}

/* Both were tight against the right edge — the vertical line was
   clipping. The hero column ends at 91.6%, so there is only ~8% of
   margin to sit in; these now sit inside it rather than on its edge. */
.script--hero { right: 3.5%; top: 21%; }
.vert--hero   { right: 2.2%; top: 50%; }

/* Was landing on the line-art cup in the corner. */
.script--board-a { right: 11%; top: 6%; }

/* The cup is the board's one illustration and the mockup shows it
   clearly; at .22 it was barely on the page. */
.deco-cup { opacity: .4; }


/* .hero was the one section left at overflow:visible — the others were
   already hidden. The pale field sweeping off the right edge therefore
   widened the DOCUMENT by 490px instead of being trimmed, which on a
   phone is a page that scrolls sideways. Everything the hero puts past
   its own edge (the off-canvas leaves, both colour fields) is meant to
   be cut off at that edge. */
.hero { overflow: hidden; }


/* ── The deck as a row ──────────────────────────────────────────────
   Paired with the ROW slot table in script.js, which spreads the three
   visible cards side by side above 1100px. At that spread the outer
   cards land on top of the prev/next buttons, which used to flank the
   deck — so above the same breakpoint the buttons restack underneath
   it. Both halves must move together: change the breakpoint here and
   the one in script.js goes with it.

   The stage keeps its 720px max-width. The cards are absolutely
   positioned inside .deck and deliberately overflow that box; it is
   .counter's overflow:hidden that bounds them, not the stage. Only the
   BUTTONS need to stay inside the stage, and centred under a 720px box
   is exactly where they belong. */

@media (min-width: 1100px) {
  .stage {
    display: grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto auto;
    justify-content: center;
    align-content: center;
    height: auto;
    min-height: clamp(380px, 88vw, 460px);
    column-gap: 1rem;
    row-gap: clamp(1.2rem, 2.5vw, 2rem);
  }

  .deck { grid-column: 1 / -1; grid-row: 1; justify-self: center; }

  .deckbtn--prev { grid-column: 1; grid-row: 2; justify-self: end; }
  .deckbtn--next { grid-column: 2; grid-row: 2; justify-self: start; }
}


/* The hero's gold line and its sideways line were both landing on
   .leaf--hero-1, which is the darkest thing in that corner. Neither is
   clipped — they were painting ON TOP of the leaf, which is gold-ink on
   near-black: the one thing the colour tokens were chosen to prevent.

   The corner is genuinely crowded (photograph + big leaf + two pieces
   of marginalia), so rather than shuffle them around each other the
   gold line now sits under the photograph, where it reads as a caption
   to it, and the sideways line takes the clear strip of right margin
   beside it. */
.script--hero { right: 3%;   top: 60%; }
.vert--hero   { right: 1.8%; top: 40%; }


/* Second attempt, and the reason the first one failed: the hero's right
   margin is only ~121px wide (a 1200px column in a 1442px page) and
   FOUR things wanted it — the photograph, a large leaf, the gold line
   and the sideways line. Moving the two pieces of text around inside it
   just swapped which leaf they landed on.

   Third attempt, and this one gives up on the margin for the gold line
   rather than shuffling anything else. The hero's foliage is now a
   CLUSTER in the top-right corner — that is the one gesture the
   reference is built around and it needs the whole corner, so the
   third thing in that margin had to leave.

   It goes UNDER the photograph instead: the picture ends at 58% of the
   hero and the $1 line starts at 62% but only reaches x=42%, which
   leaves a clear band at x 59–92%, y 59–70% with nothing in it. Set
   right-aligned there the line reads as a caption to the photograph,
   which is a better job than it was doing wedged in a 121px margin.

   The sideways line keeps the margin — it is 2 characters wide and
   sits below the cluster, at y 52–78%. Do not put a leaf there. */
.script--hero { right: 6%;   top: 60%; text-align: right; }
.vert--hero   { right: 1.5%; top: 52%; }


/* ── Small screens, corrected ───────────────────────────────────────
   Measured at 486px against every heading, paragraph, table cell and
   button. At this width the page has no margins left — the content
   column IS the screen — so a leaf placed by percentage lands on type
   rather than beside it. Four were doing exactly that:

     leaf--hero-1     27% of the h1, and 67% of the Full menu button
     leaf--hero-2     16% of the h1
     leaf--dollar-1   25% of "The maths" AND 25% of its heading
     leaf--counter-2  22% of a card's price

   So on mobile the leaves stop being margin decoration and go where
   the layout is genuinely empty: over the photograph (which has no
   text on it), and in the vertical padding above and below a section's
   content. Everything else is dropped — and because they are
   loading="lazy", display:none also means they are never fetched, so
   a phone downloads four leaves instead of fifteen.

   Vertical bands that are free at this width, measured:
     .hero     photo occupies 23–64%; head 0–23%; sub 64–100%
     .counter  head 3–28%, cards 32–90%  → only the ends are clear
     .dollar   content 11–89%            → the padding at both ends
     .visit    content 10–96%            → the top strip only          */

/* The three @media blocks that used to sit here — a hide list, a set of
   phone positions, and a correction to one of them — have been folded
   into the single mobile foliage block at the foot of this file. They
   were written against the previous leaf set and had already started
   contradicting each other (dollar-2 was positioned twice, on opposite
   sides of the band). One block, one set of numbers. */


/* ═══════════════════════════════════════════════════════════════════
   ONE PIECE — 2026-09-05, second pass

   The page read as five stacked panels. The reference reads as one
   continuous sheet that the sections happen to sit on. Three changes
   do that:

   1. THE GROUND MOVED TO <body>. Each section used to paint its own
      cream + marble. Because that marble was already
      background-attachment: fixed it LOOKED continuous, but each
      section was still an opaque rectangle — so nothing could ever
      cross a section boundary; whatever spilled out was painted over
      by the next section's own background. One ground on the body,
      transparent sections, and the boundaries stop existing.

   2. overflow-x: clip INSTEAD OF overflow: hidden. `clip` is the only
      overflow value that may pair with `visible` on the other axis, so
      the sections still cannot scroll sideways — the thing that broke
      the page earlier — while shapes and leaves are free to run past
      the top and bottom edges into their neighbours.

   3. .dollar TAKES A STACKING CONTEXT. With sections transparent and
      spilling into each other, paint order is decided by DOM order,
      and .board comes after .dollar — so the board's pale field was
      landing ON TOP of the green band. z-index:1 lifts the whole band,
      contents and all, above the fields either side of it.
   ═══════════════════════════════════════════════════════════════════ */

body {
  background-color: var(--cream);
  background-image: url("images/marble.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-blend-mode: multiply;
  background-attachment: fixed;
}

.hero,
.counter,
.board,
.visit,
.dollar {
  background-color: transparent;
  background-image: none;
  overflow-x: clip;
  overflow-y: visible;
}

.dollar { position: relative; z-index: 1; }

@media (max-width: 760px) {
  body { background-attachment: scroll; }
}


/* ── The brighter paint ─────────────────────────────────────────────
   #5DC683 is a colour-FIELD green, not a type green: cream on it is
   1.9:1 and white 2.1:1, both far under any threshold. So it is used
   the way --green already was — as shapes, washes and accents — and
   never set as a text colour on a light ground. Charcoal ON it clears
   8:1, which is why the deck's tag pill can use it as a background.

   The washes below are the same hue at low alpha rather than a
   pre-mixed pastel, so they tint whatever they cross — cream here,
   marble there — and stay in-family with the band. */
:root { --green-bright: #5DC683; }


/* ── Fields that ignore the section edges ───────────────────────────
   Each of these lives in one section and deliberately hangs out of it,
   which is what stitches the page together now that the sections no
   longer paint over each other. Kept at low alpha because body text
   crosses them: at .22 over cream the grey body colour still measures
   ~5:1, and that is the number that sets the ceiling here. Raise the
   alpha and you are spending contrast. */

.field--flow-a,
.field--flow-b,
.field--flow-c,
.field--flow-d {
  background: var(--green-bright);
  border-radius: 54% 46% 58% 42% / 48% 52% 48% 52%;
}

/* Bridges hero → counter. */
.field--flow-a {
  width: 96vw;
  height: 40vw;
  left: -30vw;
  top: -22vw;
  opacity: .16;
}

/* Runs out of the counter and under the green band. */
.field--flow-b {
  width: 74vw;
  height: 34vw;
  right: -30vw;
  bottom: -16vw;
  opacity: .2;
  border-radius: 46% 54% 40% 60% / 56% 44% 56% 44%;
}

/* Rises out of the board and up behind the band's lower wave. */
.field--flow-c {
  width: 88vw;
  height: 34vw;
  left: -34vw;
  top: -15vw;
  opacity: .17;
}

/* Carries the visit section and runs down toward the footer. */
.field--flow-d {
  width: 80vw;
  height: 36vw;
  right: -32vw;
  top: 30%;
  opacity: .18;
  border-radius: 60% 40% 46% 54% / 42% 58% 42% 58%;
}

/* The hero's two original fields join the same family. */
.field--hero-a { background: var(--green-bright); opacity: .19; }
.field--hero-b { background: var(--green-bright); opacity: .17; }


/* ═══════════════════════════════════════════════════════════════════
   ON THE COUNTER — two columns

   The reference puts the heading, the lede and the two arrows in a
   narrow left column and gives the deck the whole right-hand side.
   The section's three children (.counter-head, .stage, .dots) are
   direct siblings, so .counter itself becomes the grid rather than
   wrapping them in something new.

   .counter-head also carries .wrap, which sets a max-width and
   margin-inline:auto — inside a grid column that centres it in the
   column instead of filling it, so both are reset here.
   ═══════════════════════════════════════════════════════════════════ */

.deckctl {
  display: grid;
  gap: .95rem;
  margin-top: clamp(1.3rem, 2.6vw, 1.9rem);
}

.deckctl__hint {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin: 0;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
}

.deckctl__arrow {
  width: 15px;
  height: 15px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.deckctl__btns { display: flex; gap: .7rem; }

@media (min-width: 1100px) {
  .counter {
    display: grid;
    grid-template-columns: minmax(0, .62fr) minmax(0, 1fr);
    grid-template-areas:
      "head deck"
      "head dots";
    align-items: center;
    column-gap: clamp(1.5rem, 3vw, 2.75rem);
    padding-inline: var(--gutter);
  }

  .counter-head {
    grid-area: head;
    grid-template-columns: 1fr;     /* undoes the 1fr auto set at 860px */
    align-items: start;
    align-self: center;
    width: auto;
    max-width: none;
    margin-inline: 0;
    margin-bottom: 0;
  }

  .counter-side { display: block; }

  .stage {
    grid-area: deck;
    max-width: none;
    margin-top: 0;
  }

  .dots { grid-area: dots; }

  /* Narrower than the single-column deck: three of these plus their
     gutters have to fit the right column, not the whole page. */
  .deck { width: clamp(216px, 18vw, 258px); }

  /* Supersedes the earlier rule that restacked the arrows underneath
     the deck. They are not in .stage any more — they moved into
     .counter-head — so the stage is just the deck now. */
  .stage {
    display: flex;
    grid-template-columns: none;
    grid-template-rows: none;
  }
}


/* ── The cards ──────────────────────────────────────────────────────
   The tag is absolutely positioned on EVERY card, not just the green
   one. That looks like an odd way to centre one badge, and it is the
   point: taking it out of the flow on only the signature card would
   have given that card more room for its .dcard__shot, and the drink
   inside it would have rendered larger than the other four — the exact
   mismatch that was just fixed in the image files themselves. Out of
   flow on all five keeps one inner layout, so every cup stays the same
   size. The padding-top below is the room the badge used to take. */

.dcard { padding-top: 2.55rem; }

.dcard__tag {
  position: absolute;
  top: .95rem;
  left: 1.15rem;
  align-self: auto;
}

.dcard--green .dcard__tag {
  top: -.75rem;
  left: 50%;
  transform: translateX(-50%);
  background: var(--gold-soft);
  color: var(--green-dark);
  white-space: nowrap;
  box-shadow: 0 8px 16px -8px rgba(20, 48, 24, .7);
}

.dcard__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
}

.dcard__go {
  width: 38px;
  height: 38px;
  flex: none;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--green-deep);
  color: var(--cream);
  text-decoration: none;
  transition: transform .22s var(--ease), background-color .22s var(--ease);
}

.dcard__go svg {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.dcard--green .dcard__go { background: var(--cream); color: var(--green-deep); }

.dcard__go:hover { transform: translateX(2px); }

.dcard__go:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 3px;
}

/* Only the front card's arrow is live — see the note in script.js
   render(). On a side card a tap means "bring this one round", and a
   link would hijack that and navigate instead. */
.dcard:not(.is-front) .dcard__go { pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .dcard__go { transition: none; }
  .dcard__go:hover { transform: none; }
}


/* ── The washes, redrawn as sweeps ──────────────────────────────────
   First attempt used border-radius blobs. On screen they read as four
   pale BUBBLES sitting on the page — the opposite of the intent, since
   the whole point was to stop the page looking like separate parts.

   The fix is shape, not opacity: each wash is now a wide, shallow band
   clipped to #wave-soft / #wave-soft-b, running wider than the viewport
   so both ends are cut off by the screen. A shape whose ends you cannot
   see reads as something passing THROUGH the page rather than an object
   placed on it. Alternating the two clips keeps consecutive sweeps from
   rhyming.

   These stay well clear of the type contrast budget: the strongest is
   .20 of #5DC683 over cream, which leaves the grey body colour at
   ~5:1. */

.field--flow-a,
.field--flow-b,
.field--flow-c,
.field--flow-d,
.field--hero-a,
.field--hero-b {
  border-radius: 0;
  background: var(--green-bright);
}

.field--flow-a, .field--flow-c, .field--hero-a { clip-path: url(#wave-soft); }
.field--flow-b, .field--flow-d, .field--hero-b { clip-path: url(#wave-soft-b); }

.field--hero-a {
  width: 132vw; height: 34vw;
  left: -16vw; top: -9vw;
  opacity: .20;
}

.field--hero-b {
  width: 128vw; height: 26vw;
  left: -14vw; top: auto; right: auto; bottom: -6vw;
  opacity: .15;
}

/* Bridges hero → counter. */
.field--flow-a {
  width: 136vw; height: 30vw;
  left: -18vw; right: auto; top: -13vw;
  opacity: .17;
}

/* Runs out of the counter and under the green band. */
.field--flow-b {
  width: 132vw; height: 26vw;
  left: -16vw; right: auto; bottom: -11vw;
  opacity: .20;
}

/* Rises out of the board, up behind the band's lower wave. */
.field--flow-c {
  width: 138vw; height: 28vw;
  left: -20vw; top: -11vw;
  opacity: .17;
}

/* Carries the visit section down toward the footer. */
.field--flow-d {
  width: 134vw; height: 32vw;
  left: -17vw; right: auto; top: 34%;
  opacity: .17;
}


/* ── Counter decoration, re-placed for the two-column grid ──────────
   Every percentage in this section moved when .counter became a grid:
   the head is now x 4.5–38.2%, the deck x 41.7–95%, and between them
   there is a 50px gap that nothing fits in. Measured free bands:

     y  0–11%    across the top     (leaves hang up into the hero)
     y 76–100%   left of x 42%      (under the arrows)
     y 87–100%   across the bottom  (under the dots)

   The leaf placements that lived here are gone with the set they were
   written for. The measured free bands above still hold and are still
   the reason the current counter-1 hangs off the TOP edge (it runs up
   into the hero) and counter-2 sits at the bottom-left, so the notes
   are kept even though the numbers under them are not.

   Because .counter is overflow-y visible, a leaf anchored above the
   section's top edge runs up into the hero rather than being clipped —
   that is the stitching doing its job, not a mistake. */

/* The old pale circles are redundant now the sweeps run through this
   section, and at any strength they read as bubbles next to a band. */
.blob-counter-a,
.blob-counter-b { display: none; }


/* ── Contrast corrections ───────────────────────────────────────────
   Measured, not estimated: every text run on the page was screenshotted
   with the glyphs turned transparent, the background behind each one
   sampled from the actual pixels (median of a 7x7 patch, so a marble
   vein or a leaf edge cannot decide it), and the ratio computed against
   the flattened text colour. 126 runs, four failures.

   TWO WERE MINE, from the green washes:

     "Ankawa · Erbil"  4.49  — --muted where two hero washes overlap.
                                Stacked alpha made the tint stronger than
                                either field alone.

     "="               2.75  — the equation operator on the band. It is
                                inside an aria-hidden block with an
                                .sr-only equivalent, so it is decorative,
                                but it is still visible text.

   TWO WERE ALREADY THERE and the audit simply surfaced them:

     "Visit"           1.33  — .label-gold is --gold-soft, which was
                                measured for DARK grounds. In .dollar it
                                sits on green and is fine; in .visit it
                                sits on cream, where it is close to
                                invisible. This predates the redesign.

     "Every day · …"   4.48  — --gold-ink on cream that the marble has
                                multiplied down to rgb(221,219,204). The
                                sheet already warns about this exact trap
                                for --muted; --gold-ink had the same
                                problem, two hundredths under.

   All four now clear their threshold with headroom rather than sitting
   on it, because the marble texture means the true background varies
   by a few points depending on where a line lands. */

:root {
  --muted:    #59594F;   /* was #5E5E54 — L .1104 -> .0986 */
  --gold-ink: #765810;   /* was #7A5C12 — L .1185 -> .1084 */
}

/* --gold-soft is a dark-ground colour. On cream it needs the ink step. */
.visit .label-gold { color: var(--gold-ink); }

.eq-op { color: rgba(244, 239, 228, .62); }

/* The two hero washes overlap; at .20 + .15 the combined tint was
   pushing body text under 4.5:1. The lower one carries less now. */
.field--hero-b { opacity: .10; }


/* ── The monogram watermark ─────────────────────────────────────────
   The filled mark, coloured by the instance's `color` and kept faint by
   its opacity. Its box keeps the mark's own proportion. */

.wmark {
  position: absolute;
  z-index: 0;
  display: block;
  pointer-events: none;
  user-select: none;
  aspect-ratio: 504.47 / 658.02;
  fill: currentColor;
  stroke: none;
}

/* Left margin of the green band, vertically centred on it — where the
   reference puts it. It runs slightly off the page edge on purpose:
   .dollar clips horizontally, so the mark is cropped rather than
   floating, which stops it reading as a sticker. */
.wmark--dollar {
  left: -1.5%;
  top: 50%;
  transform: translateY(-50%);
  width: clamp(126px, 15vw, 218px);
  color: var(--cream);
  opacity: .15;
}

@media (max-width: 760px) {
  /* At phone width the band has no left margin — the heading starts at
     the gutter — so the mark would sit under "What a dollar still
     buys." rather than beside it. */
  .wmark--dollar { left: auto; right: -8%; top: 8%; transform: none; width: clamp(96px, 30vw, 150px); opacity: .11; }
}

/* Shifted inboard: at left:-1.5% the crop was taking the B's stem, and
   without the stem the mark stopped reading as the letter and became an
   abstract shape. It now sits far enough in that the whole monogram is
   legible, which means it also passes further behind the heading —
   re-measured after the move, and cream on the band still clears its
   threshold there. */
.wmark--dollar { left: 0.5%; opacity: .17; }

/* Sampling the real glyph line boxes (Range.getClientRects) rather than
   the element box found what the coarser pass had missed: the watermark
   lightens the band from rgb(47,97,54) to about rgb(76,120,70) exactly
   where .dollar-note sits, and the note was riding at 4.65:1 to begin
   with — cream at 78% on deep green. Lightening the ground under it
   dropped it to 3.41.

   Both ends of that get fixed: the mark carries less, and the note is
   full-strength cream. It is body copy on the page's darkest ground;
   there was never a good reason for it to be translucent. */
.wmark--dollar { opacity: .13; }
.dollar-note   { color: var(--cream); }


/* ── The hero → counter transition, simplified ──────────────────────
   Measured page positions showed the problem: .field--hero-b ran
   514–889 and .field--flow-a ran 615–1047, so two wave-clipped bands
   overlapped across the hero/counter boundary. Each band has a wavy top
   AND a wavy bottom, which put FOUR undulating edges inside ~530px —
   read as stripes, not as a sweep. Worse, .field--hero-a ended at 429,
   leaving a bare gap and then a doubled band: a stutter exactly where
   the page most needs to feel continuous.

   One band now carries that transition. .field--hero-b is gone
   entirely, and .field--flow-a is pulled up to overlap the bottom of
   .field--hero-a so the two read as one continuous wash handing off
   rather than as two shapes with a seam between them. */

.field--hero-b { display: none; }

.field--flow-a {
  top: -26vw;
  height: 40vw;
}


/* ── The washes below the hero: removed ─────────────────────────────
   Collapsing the doubled band helped but did not fix it. The deeper
   problem is that a wave stretched to 136vw has its curvature stretched
   with it: one period spans most of the screen, so what is a wave in
   the abstract renders as a near-horizontal LINE ruled across the page.
   Three of them, at the counter and the board, banded straight through
   "The ones people come back for." and "Forty-six drinks." — tonal
   steps behind headings, which is the opposite of continuous.

   Going back to the reference settles it: its counter and its board are
   plain cream. The large green shapes live in the hero and in the band,
   and nowhere else. So these three go.

   The page does NOT lose its continuity by dropping them — that comes
   from the ground moving to <body>, the sections being transparent and
   overflow-y visible, the band's wave, and the leaves crossing section
   edges. The washes were an addition on top of that, and below the hero
   they were costing more than they paid for. */

.field--flow-a,
.field--flow-b,
.field--flow-c { display: none; }

/* The visit section keeps one, because the reference does have green
   down there — but moved hard left, behind the map, where it backs an
   image instead of ruling a line across the contact rows. */
.field--flow-d {
  width: 78vw;
  height: 30vw;
  left: -34vw;
  right: auto;
  top: 26%;
  opacity: .16;
}

/* The watermark comes off entirely on small screens. Measured at 486px
   it covered 100% of "The maths", 85% of "still buys." and 40% of the
   note: at phone width the band's content runs 11–89% of its height,
   which leaves ~72px of clear space, and the mark is ~187px tall. There
   is no position for it here — shrinking it to fit would make it a logo
   bug rather than a watermark. The band still has the leaves and the
   gold line at this size. */
@media (max-width: 760px) {
  .wmark--dollar { display: none; }
}

/* The Instagram handle is @the.beanerycafeerbil — 21 characters and, to a
   browser, one unbreakable token about 161px wide. It fits every current
   breakpoint (below 460px .fact already stacks to one column and hands the
   value the full width), but a token that cannot break has no fallback: if
   the column is ever narrower than the word — a larger default font size,
   page zoom, a longer handle later — it would be CLIPPED rather than wrap,
   because the sections are overflow-x: clip. Letting it break is free and
   changes nothing at any size where it already fits. */
.fact dd { overflow-wrap: anywhere; }


/* ═══════════════════════════════════════════════════════════════════
   THE COUNTER, SIDE BY SIDE ALL THE WAY DOWN — 2026-09-06

   The two-column treatment used to start at 1100px and below that the
   section fell back to a stack: heading, lede, arrows, then a 380px
   deck underneath. On a phone that ran 781px tall, and most of it was
   the gap between the arrows and the cards — the deck's own box is
   sized off vw, so the narrower the screen the more empty room it
   reserved around a card that was not getting any bigger.

   So the hero arrangement now runs the whole way down: words in the
   left column, deck in the right, at every width. What changes with
   the breakpoint is only HOW MUCH ROOM THE DECK ASKS FOR and how the
   card is drawn inside it — not whether the two sit together.

   Three things this depends on, all of them already true:

   1. The deck is a FAN below 1100px (script.js SLOT = FAN). One card
      in front, one peeking. A three-card ROW would never fit a phone's
      right-hand column — which is exactly why the 1100px switch in
      script.js exists, and why it stays where it is. Do not raise this
      media query past 1099px without moving that one too.

   2. .counter is overflow-x: clip, so the peeking card may run off the
      right edge and be trimmed rather than widen the page. That bleed
      is the point: a card cut by the screen edge reads as "there are
      more of these", which is the job the dots and arrows are also
      doing.

   3. script.js positions cards in PERCENTAGES of the card's own width,
      not pixels. Shrinking .deck therefore shrinks the whole
      arrangement — fan spread included — with no JS change.
   ─────────────────────────────────────────────────────────────────── */

/* 1099.98, not 1099, and this is not a nicety. The counterpart rule
   is min-width: 1100px, and a viewport can land BETWEEN the two: at
   browser zoom, on a fractional device pixel ratio, or on a 1099px
   window that Chrome measures as 1099.5. At that width max-width:1099
   is false and min-width:1100 is false, so the section got NEITHER
   grid — .counter fell back to display:block and the layout came apart
   into a stack. Caught at exactly 1099px in Chrome, where both queries
   reported false. Any 'max: n / min: n+1' pair on this page has the
   same hole; use the .98 form. */
@media (max-width: 1099.98px) {
  /* THREE ROWS, NOT TWO. The heading used to share the left column
     with the lede and the arrows, all three stacked beside the deck.
     That column was 113-158px wide on a phone, which is not a measure
     — it is a gutter with words in it, and the heading broke across
     four lines in it no matter how the type was sized.

     So the heading comes OUT of the column and takes the full content
     width as its own row. Only the lede and the arrows stay beside the
     deck, and they are the two things that genuinely do not mind being
     narrow: one short sentence and a pair of buttons. The column they
     sit in can then be much narrower than a heading would ever allow,
     and all of that width goes to the card.

     The heading also gets its normal size back — the h2 rule at the
     top of this file, unmodified — because a full-width row is exactly
     what that scale was drawn for. */
  .counter {
    display: grid;
    /* The floor is not decoration: the two 48px arrows plus their gap
       need 107px, and a pure fraction drops below that around 340px,
       which would push a button out of the column. */
    grid-template-columns: minmax(112px, .55fr) minmax(0, 1fr);
    grid-template-areas:
      "title title"
      "side  deck"
      "dots  dots";
    align-items: center;
    column-gap: clamp(.6rem, 2.5vw, 1.6rem);
    row-gap: clamp(.9rem, 3.2vw, 1.7rem);
    padding-inline: var(--gutter);
  }

  /* display:contents dissolves this box so its two children become grid
     items of .counter directly. That is what lets the heading and the
     lede land in different ROWS while still being siblings in the
     markup — no wrapper moved, no duplicate heading.

     It also drops the .wrap width this element carries, which is
     correct and not a loss: .counter's own padding-inline is the same
     gutter, so the content edge does not move. */
  .counter-head { display: contents; }

  .counter-title { grid-area: title; }

  /* The label sits right on top of the heading it introduces. */
  .counter-title .label { margin-bottom: .35rem; }

  /* align-self:start, against the grid's align-items:center. The deck
     is 300-400px tall and it sets the height of this row; left centred,
     the lede floated in the middle of that space with ~100px of nothing
     between it and the heading it belongs to, reading as an unrelated
     caption rather than as the line under the title. Pinned to the top
     of the row it sits directly under the heading, and the empty space
     collects at the BOTTOM of the column where it is just margin beside
     the lower half of the card. */
  .counter-side {
    grid-area: side;
    align-self: start;
    display: block;
    text-align: left;
    justify-items: start;
  }
  .counter-side .lede {
    max-width: none;
    margin-left: 0;
  }

  .stage {
    grid-area: deck;
    display: flex;
    max-width: none;
    /* Was clamp(380px, 88vw, 460px) — a vw height for a box that is no
       longer a share of the viewport. The deck sets its own height now. */
    height: auto;
    margin: 0;
    /* NOT bled into the right gutter, though it was at one point and
       the reason it is not is worth keeping. Pulling the stage over
       the gutter bought the card ~20px of width, and the price was the
       peek: with the front card's right edge ON the screen edge, the
       leading card behind it — offset 52% of a card's width — lands
       entirely off screen, so the deck reads as one lonely card that
       happens to be cropped. Leaving the gutter alone puts the front
       card's edge at the content edge and lets the leading card show
       as a ~20px sliver in the gutter, which is the whole 'there are
       more of these' cue the arrows and dots are also giving. The
       column above was widened instead to win the width back. */
  }

  /* Fills its column. The HEIGHT is set outright rather than by an
     aspect ratio, and that is the whole lesson of this layout: at
     390px the column is ~190px wide, and 190 x (380/290) is a 249px
     card. The card's fixed parts — the 2.55rem badge inset, two lines
     of name, three of description, the price rule — already come to
     ~200px, so .dcard__shot (flex: 1, and the only part that gives)
     was squeezed to LITERALLY ZERO and the drink photograph vanished.
     A card with no drink on it is not a smaller card, it is a broken
     one.

     So the card keeps a height that its contents actually fit in and
     gets narrower rather than shorter as the screen shrinks. It ends
     up a taller, slimmer card on a phone than on a desktop, which is
     the correct direction for a portrait screen anyway. */
  .deck {
    width: 100%;
    height: clamp(302px, 42vw + 148px, 380px);
  }

  .dots {
    grid-area: dots;
    margin-top: clamp(.9rem, 3vw, 1.5rem);
  }
}


/* ── The counter at phone width ─────────────────────────────────────
   The split above holds its proportion all the way down, which means
   below ~700px both columns are genuinely narrow — ~175px each on a
   390px screen. Type cut for a full-width measure does not survive
   that: the h2 was setting three words to a line and the card's name
   and description were running past the bottom of the card.

   Everything here is a size, not a layout. The arrangement is the one
   set above; this only makes the words fit inside it. */

@media (max-width: 700px) {
  /* NO font-size override on the heading any more, and that is the
     point of the layout change above. Every previous version of this
     block shrank the h2 to survive a 113-158px column — first to
     1.5rem, then to 1.16rem — and each one traded presence for fit.
     On its own full-width row the heading needs neither: the site's
     ordinary h2 scale sets it on two lines at every phone width, on
     the hard break the copy was written for, at the same size as
     "What a dollar still buys." further down the page. */

  /* The lede DOES stay small, because it is the one thing still in the
     narrow column — which is what it is there to do: hold the words in
     as little width as they will go, so the card gets the rest. */
  .counter-side .lede {
    font-size: .8rem;
    line-height: 1.4;
  }
  /* .66rem, and it is a floor rather than a fitted size. The first cut
     of this block took the three uppercase labels down to .54–.62rem
     to fit the narrow column, which worked and was wrong: tracked-out
     caps under 10px stop being words and become a texture. Measured at
     8.6px for the card tag. These are the smallest that still read,
     and they still fit at 320px, where the column is narrowest. */
  .counter-head .label { font-size: .66rem; }

  /* "Swipe to explore" comes off on a phone. Tracked-out uppercase in a
     118px column broke it across THREE lines at 320px, and shrinking it
     to fit would have put it back under the 10px floor this file keeps
     for caps. It is also the least necessary line on the page here:
     swiping is the native gesture on a touch screen, the two arrows
     stay, and the dots underneath already say there is more than one
     card. It returns above 700px, where the column is wide enough to
     hold it on one line and where a mouse actually needs the prompt. */
  .deckctl__hint { display: none; }
  .deckctl { gap: .5rem; margin-top: clamp(.9rem, 3vw, 1.3rem); }

  /* Card interior. The shot keeps the largest share it can: it is the
     only part of the card a passer-by reads at a glance. */
  .dcard { padding: 2.15rem .85rem .95rem; }
  .dcard__name { font-size: 1.12rem; }
  .dcard__desc {
    margin-top: .3rem;
    font-size: .72rem;
    line-height: 1.35;
  }
  .dcard__foot {
    margin-top: .6rem;
    padding-top: .55rem;
  }
  .dcard__price { font-size: 1.1rem; }
  .dcard__tag {
    top: .7rem;
    left: .85rem;
    font-size: .62rem;
  }
}


/* ── The deck column, once there is room ────────────────────────────
   The proportional split above is right for a phone, where both
   columns have to give ground together. Carried up to 1099px it is
   not: the deck column keeps taking its share of a widening page, and
   because .deck's height is capped at 380px the card just gets WIDER —
   499 x 380 at 1099px, measured. These cards are portrait (290 x 380
   native); a landscape one is not a bigger card, it is a different
   card, and the drink inside it floats in the middle of a field of
   tint.

   So above 760px the deck stops growing with the page and the words
   take the extra room instead. The cap is 320px — a little over the
   native 290 — and .stage anchors the deck to the RIGHT of its track,
   so the slack opens up between the text and the card rather than
   between the card and the screen edge. That keeps the leading card's
   peek where it belongs: near the edge, where it reads as more cards
   waiting rather than as a gap in the middle of the section. */

@media (min-width: 761px) and (max-width: 1099.98px) {
  /* The card stops growing here — see the cap below — so past ~760px
     the extra width has to go somewhere that can use it. The lede
     column takes it and stops being a narrow strip, because on a
     tablet there is no longer any need to squeeze it. */
  .counter { grid-template-columns: minmax(0, 1fr) minmax(0, .78fr); }

  .stage { justify-content: flex-end; }

  .deck {
    max-width: 320px;
    margin-left: auto;
  }
}


/* ═══════════════════════════════════════════════════════════════════
   FEWER, AND OUT OF THE WAY — mobile foliage, 2026-09-06

   Three leaves survive to phone width out of the eighteen on the desk-
   top page, which was already the intent. What was NOT intended is
   where two of them landed once the type around them reflowed:

     leaf--hero-1   covered 89% of the gold "More than coffee"
     leaf--visit-1  covered 15% of "Good space, good people"

   Both were measured at 390px, and the hero one is why that piece of
   handwriting is simply missing from the phone layout — it is behind a
   leaf. Neither is a sizing problem, so neither is fixed by shrinking:
   they are both sitting in the one part of their section that has ink
   in it.

   The rule these follow — the same one the desktop placements follow —
   is that a leaf goes in a margin or over a photograph, never over
   type. Sizes come down a step as well, which is the "a bit less leaf"
   half of the request; the count stays at three, because at two the
   phone layout stops looking like the same site as the desktop one.
   ═══════════════════════════════════════════════════════════════════ */

/* The four that survive 1100px. Both of these were anchored to a LEFT
   margin that does not exist below it, so they swap sides: the green
   band's equation and the visit section's handwriting are both
   left-aligned at these widths, which leaves the right-hand edge as
   the genuinely empty one in each. */
@media (max-width: 1099.98px) {
  .leaf--dollar-2 {
    left: auto; right: -7%; top: auto; bottom: 2%;
    transform: rotate(18deg);
  }

  .leaf--visit-1 {
    right: -8%; top: 2%;
    transform: rotate(24deg);
  }
}

@media (max-width: 760px) {
  /* HERO — over the photograph, below the handwriting. The gold sits at
     33–37% of the hero and the picture runs to 53%, so this drops into
     the band between the two. The photograph is the only large area up
     here carrying no words, and at this width the hero has no margin
     left to hang anything in. */
  .leaf--hero-1 {
    right: -6%; top: 40%; left: auto;
    width: clamp(76px, 23vw, 116px);
    transform: rotate(-20deg);
  }

  /* Anchoring the leaf's BOTTOM to the section and keeping it small is
     what stops it climbing into "One espresso", which an earlier,
     larger version covered 30% of. */
  .leaf--dollar-2 {
    right: -8%; bottom: 1%;
    width: clamp(64px, 18vw, 92px);
  }

  .leaf--visit-1 {
    right: -11%; top: 1%;
    width: clamp(72px, 21vw, 108px);
  }
}


/* ═══════════════════════════════════════════════════════════════════
   THE SHOPFRONT BAND — 2026-09-06

   Full-bleed photograph across the top of the footer, with the footer's
   own green picking up where it ends.

   Two things make it a band rather than a picture sitting in a box:

   1. It is the FIRST child of .site-foot, and the section's top padding
      moves onto .foot-in instead. Left on the footer, that padding put
      a strip of green above the photograph and the whole thing read as
      an inset image with a margin.

   2. It fades out at the bottom into --green-dark rather than stopping
      on a hard edge. The photograph is a night shot whose lower third
      is already close to the footer's green, so the gradient lands on
      colours that were nearly touching anyway — the seam disappears
      instead of being covered up.

   The crop is height-driven, not aspect-driven: the source is 16:9,
   and 16:9 across a 390px phone is a 219px letterbox with the shopfront
   too small to read. Fixing a MINIMUM height and letting object-fit
   crop the sides keeps the doorway and the signage at a legible size
   all the way down. object-position sits slightly above centre because
   the bottom of the frame is pavement.
   ═══════════════════════════════════════════════════════════════════ */

.site-foot { padding-block: 0 1.5rem; }

.foot-shot {
  position: relative;
  z-index: 1;   /* over .deco-bean-d and .deco-drops-b, which are absolute */
  margin: 0 0 clamp(2.4rem, 5vw, 4rem);
}

.foot-shot img {
  display: block;
  width: 100%;
  height: clamp(260px, 34vw, 500px);
  object-fit: cover;
  /* 30%, not centre. The source is 1672x941 and the band is far
     shallower than that, so most of the frame's HEIGHT is discarded on
     a wide screen — at 1440px only about half of it survives. Centring
     that window put the cut straight through the illuminated
     'THE BEANERY CAFE' sign, which is the one part of the photograph
     that identifies the place. Biasing the window upward keeps the
     signage and the lit interior and throws away pavement instead.

     This has no effect below ~700px: there the forced height is
     GREATER than the natural height of the image at that width, so
     cover scales up and crops the sides rather than the top and
     bottom. */
  object-position: center 30%;
}

/* The fade. A pseudo-element rather than a gradient on the figure
   itself, because the <img> paints over the figure's own background. */
.foot-shot::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 38%;
  background: linear-gradient(to bottom,
    rgba(30, 68, 35, 0) 0%,
    rgba(30, 68, 35, .72) 62%,
    var(--green-dark) 100%);
  pointer-events: none;
}

/* The top padding the footer gave up, handed to the content instead so
   the photograph can reach the section's top edge. */
.foot-in { padding-top: 0; }

@media (max-width: 760px) {
  /* Taller share of a narrow screen. At 390px the 16:9 source would
     otherwise be a 219px strip; this keeps the shopfront readable
     while still cropping to the middle of the frame. */
  .foot-shot img { height: clamp(230px, 62vw, 300px); }
  .foot-shot { margin-bottom: clamp(1.8rem, 6vw, 2.6rem); }
}


/* ── The dots, as something you can actually hit ────────────────────
   They were 8x8 px. That is the DOT, and the dot was also the button,
   so the whole target was 8x8 — a third of the 24x24 minimum, on a
   control that sits in the counter's most reachable corner on a phone.
   The arrows next to them are 44px; the dots were not close.

   The dot stays 8px. What changes is that it is now drawn by a
   pseudo-element inside a 26px button, so the target grows and the
   design does not move. The negative inline margin pulls the boxes
   back together until the dots sit 8px apart again, exactly as they
   did — the boxes overlap by 10px doing it, which is a real trade and
   the right way round: the ambiguous strip is between two dots that do
   the same KIND of thing (jump to a card), so the worst case of a
   sloppy tap is landing on card 3 instead of card 4, not silence.

   26px rather than 24px because .is-on grows to a 26px pill, and the
   box has to hold it. */

.dots { gap: 0; }

.dots button {
  width: 26px;
  height: 26px;
  margin-inline: -5px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: none;
}

.dots button::before {
  content: "";
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--cream-3);
  transition: width .25s var(--ease), background-color .25s var(--ease);
}

.dots button.is-on {
  width: 26px;
  background: none;
}
.dots button.is-on::before {
  width: 26px;
  border-radius: 999px;
  background: var(--green-deep);
}


/* ── Footer links, tall enough to hit ───────────────────────────────
   Six links at .9rem sat 23px tall — one pixel under the 24px target
   minimum, and stacked 0.6rem apart in a column, which is the shape
   most likely to get a mis-tap on a phone.

   The padding goes on the link and comes back off the column's gap, so
   each target grows to ~29px while the list keeps the spacing it was
   drawn with. width: fit-content stays: the target should be the width
   of the WORD, not of the column, or "Hours" would take a tap from
   halfway across the footer. */

.foot-nav div { gap: .35rem; }

.foot-nav a { padding-block: .16rem; }

/* Same one pixel, same reason. This one is a single link in a
   definition list rather than a nav column. */
.fact dd a { display: inline-block; padding-block: .16rem; }


/* ── "More than coffee", somewhere it can be read ───────────────────
   At phone width this sat at top: 20%, which put it at x 316–386 on a
   390px screen — and the hero photograph runs x 20–370 through the
   same band. The picture is later in the DOM, so it painted over the
   handwriting and left about 16px of letter-tails sticking out past
   its right edge. Not a leaf problem: moving the leaf off it (above)
   only revealed that the photograph was covering it too.

   The hero has exactly one region below the fold with no ink in it and
   no picture over it: the strip beside the two buttons, which are
   left-aligned and stop at x=231. The handwriting goes there, in the
   right margin at 87%, and reads at full size for the first time on a
   phone. */

@media (max-width: 760px) {
  .script--hero {
    right: 4%;
    top: 87%;
    text-align: right;
  }
}


/* ── The no-JavaScript counter ──────────────────────────────────────
   The two-column arrangement is only right when the deck is a DECK —
   one card in front and the rest behind it. With no JavaScript there
   is no deck: .stage never gets .is-live, and the block up at
   ".stage:not(.is-live)" unstacks the cards into a plain wrapped row
   of all five. Five cards do not go in a half-width column; they came
   out as a single 174px-wide ribbon down the right-hand side with the
   heading pushed off the top.

   So when the stage is not live the section drops back to one column
   and the row gets the whole page, which is what that fallback was
   written against.

   :has() is doing the work because the condition lives on a
   DESCENDANT of the element being restyled. If it is ever unsupported
   the page does not break — it degrades to the squeezed column, which
   is still readable, and only for someone who has both an old browser
   and JavaScript off. */

.counter:has(.stage:not(.is-live)) {
  display: block;
  padding-inline: var(--gutter);
}

.counter:has(.stage:not(.is-live)) .counter-head {
  margin-bottom: clamp(1.8rem, 4vw, 2.6rem);
}

/* Undoes the cap and the right-hand anchoring from the 761–1099 block:
   both are about a single card sitting in a column, and this is a row
   of five sitting in a section. */
.stage:not(.is-live) .deck {
  max-width: none;
  margin-left: 0;
}

/* The arrows and the swipe hint go with it. There is a rule further up
   — ".stage:not(.is-live) .deckbtn { display: none }" — that was
   written to do this, and it stopped working the day the arrows moved
   out of .stage and into .counter-head: the selector still describes
   where they used to live. With no JavaScript they are two buttons
   wired to nothing, above a hint telling you to swipe a deck that is
   not there. */
.counter:has(.stage:not(.is-live)) .deckctl { display: none; }
