/* The landing page — the six sections of the Ink & Gilt build, in order.

   Overture → Hero → The basket (anatomy) → The care → Five yields → Footer.
   Anatomy sits second on purpose: the name is explained before anything is
   sold, which is the whole argument for the price.

   Source: design_handoff_corbicula_site/.../Corbicula Landing Royal.html */


/* --- the shared section shell -------------------------------------------- */

.chapter {
  position: relative;
  padding: var(--section-y) var(--gutter);
}
/* one gilt hairline at every boundary — the only structural line in the system */
.chapter + .chapter,
.chapter--anatomy,
.chapter--care { border-top: 1px solid var(--hairline); }

.chapter__inner {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

/* a section head: title on the left, its standfirst on the right */
.chapter__head {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
  gap: clamp(26px, 4vw, 74px);
  align-items: end;
}
.chapter__head-col { display: flex; flex-direction: column; gap: 16px; }
.chapter__headline {
  font-size: var(--fs-section);
  line-height: var(--lh-section);
  letter-spacing: var(--ls-section);
  max-width: var(--measure-head);
}
.chapter__body {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--sage);
  max-width: 38em;
  text-wrap: pretty;
}

/* the block the reveal script fades up, 26px over 1150ms */
[data-reveal] { will-change: opacity, transform; }


/* ========================================================================== */
/* 00 · Overture — the full-screen wordmark splash                            */
/* ========================================================================== */
/* Section 01 in Corbicula Landing Royal.dc.html. Nothing is sold here: the
   mark, the wordmark, the gilt rule and the tagline arrive before any price
   does, which is the whole argument for what follows. */

/* 100svh, not 100vh: on iOS the address bar makes 100vh taller than the
   window at rest, which pushed the foot below the fold on exactly the screen
   where the cue to scroll matters most. The vh line stays first for anything
   that doesn't know svh.

   The bottom padding is large because the foot is absolutely positioned and
   the centred stack has to clear it. It also pushes the wordmark above the
   true centre, which is where it wants to sit optically. */
.overture {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(26px, 4vh, 44px);
  padding: clamp(104px, 13vh, 160px) var(--gutter) clamp(124px, 17vh, 196px);
  overflow: hidden;
  /* 0 at rest, 1 by the time the overture is a third of the way off screen.
     Set by landing.js; see "the departure" at the foot of this section. */
  --depart: 0;
}

/* the gilt breath — centred behind everything, and softer than the hero's:
   this one sits under type rather than beside it */
.overture__glow {
  position: absolute;
  left: 50%;
  top: 44%;
  width: min(900px, 86vw);
  height: min(900px, 86vw);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-image: var(--breath-overture);
  opacity: var(--sun);
  animation: gilt-breathe var(--dur-breath) ease-in-out infinite;
  pointer-events: none;
}

/* the bee mark, settling over 11s */
.overture__mark {
  position: relative;
  z-index: 2;
  display: block;
  width: clamp(84px, 8vw, 124px);
  height: auto;
  opacity: .95;
  animation: settle 11s ease-in-out infinite;
}

.overture__centre {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(16px, 2.2vh, 24px);
}

/* text-indent matches the tracking: letter-spacing hangs a trailing space off
   the last letter, and without it the tracked wordmark centres off-axis */
.overture__wordmark {
  font-family: var(--font-display);
  font-size: clamp(38px, 6.2vw, 82px);
  line-height: 1;
  letter-spacing: 0.22em;
  text-indent: 0.22em;
  color: var(--cream-hi);
  text-align: center;
}

/* line · diamond · line. Both halves take .foil, so the sheen that runs along
   the hero eyebrow rule runs along this one too — same gradient, same 7s loop.
   The background comes from .foil in base.css; only the geometry is set here. */
.overture__rule {
  display: flex;
  align-items: center;
  gap: 14px;
  width: min(560px, 74vw);
}
.overture__rule-line {
  flex: 1;
  height: 1px;
}
/* mirrored, so the pair reads symmetrically about the gem — and the sheen,
   mirrored with it, travels out to both ends at once instead of sweeping
   left to right across the whole rule */
.overture__rule-line--rtl { transform: scaleX(-1); }
.overture__rule-gem {
  width: 6px;
  height: 6px;
  background: var(--copper);
  transform: rotate(45deg);
}

.overture__tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(20px, 2vw, 30px);
  line-height: 1.35;
  color: var(--gilt-light);
  text-align: center;
}

/* The design sets this at #77806F and 0.3em. At that value the line is
   technically present and practically gone: Nino Mtavruli is a light,
   uniform-height face, and 0.3em pulls the fourteen letters far enough apart
   that they stop reading as a word.

   It is a real string — it says "the bee's basket" — so it now takes --sage,
   the body colour, at 13–15px with the tracking pulled back to 0.2em. That is
   legible at arm's length and still two steps below the tagline, which is
   larger, italic and gilt. The order the eye takes is unchanged:
   CORBICULA → Nature, gathered by bees → ფუტკრის კალათა. */
.overture__ka {
  font-size: clamp(13px, 1.15vw, 15px);
  letter-spacing: 0.2em;
  text-indent: 0.2em;
  line-height: 1.5;
  color: var(--sage);
  text-align: center;
}

/* --- the foot of the overture -------------------------------------------- */
/* Two lines pinned to the bottom edge: the harvest provenance, and under it
   the invitation to keep going. They are deliberately not one block — the
   provenance is a fact about this batch and the cue is a piece of navigation,
   and merging them into a single link made the whole harvest line clickable
   for no reason.

   Neither of them is a call to action. There is no pill, no fill and no
   border: a mono line at 11px, letter-spaced, one step above the ground, and
   a hairline falling away from it. The negative space above stays empty. */
.overture__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(26px, 3.6vh, 44px);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(14px, 2vh, 20px);
}

.overture__provenance {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-meta);
  text-transform: uppercase;
  color: var(--sage-faint);
  text-align: center;
}

.overture__scroll {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: var(--sage-meta);
}
.overture__scroll:hover,
.overture__scroll:focus-visible { color: var(--copper-lit); }

.overture__scroll-line {
  display: inline-flex;
  align-items: baseline;
  gap: 0.85em;
}
.overture__scroll-text {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
/* the arrow rides a little low and a little faint, so the line reads as type
   with a mark after it rather than as a button with an icon */
.overture__scroll-arrow {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  line-height: 1;
  opacity: .72;
  transform: translateY(1px);
  transition: transform var(--dur-hover) var(--ease);
}
.overture__scroll:hover .overture__scroll-arrow,
.overture__scroll:focus-visible .overture__scroll-arrow { transform: translateY(4px); }

.overture__scroll-bar {
  width: 1px;
  height: 34px;
  background-image: var(--cue-bar);
  animation: settle 6s ease-in-out infinite;
}


/* --- the departure -------------------------------------------------------- */
/* The overture does not cut to the hero; it withdraws. landing.js writes
   --depart from 0 to 1 across the first half-screen of scroll, and the three
   foreground layers leave at three speeds — the foot first, then the
   wordmark, then the mark. The glow and the motes are left alone: the breath
   keeps breathing and the motes keep rising, so what the hero scrolls up into
   is the same air, not a new section.

   This is not parallax. Nothing moves faster than the page — the largest
   travel is 40px against a 50vh scroll — and everything is driven off one
   variable, so there is one style recalc per frame and no layout.

   --depart stays 0 under prefers-reduced-motion, which leaves the whole
   section at rest. */
.overture__mark,
.overture__centre,
.overture__foot { will-change: opacity, transform; }

/* the mark is on the 11s settle, and an animation beats a declaration, so it
   leaves on opacity alone rather than fighting the keyframe for transform */
.overture__mark { opacity: calc(.95 - var(--depart) * .82); }

.overture__centre {
  opacity: calc(1 - var(--depart) * .88);
  transform: translate3d(0, calc(var(--depart) * -40px), 0);
}

/* opacity clamps at 0, so the 2x multiplier is just "gone by --depart .5":
   the invitation stops being on screen as soon as it has been taken */
.overture__foot {
  opacity: calc(1 - var(--depart) * 2);
  transform: translate3d(0, calc(var(--depart) * -16px), 0);
}


/* --- the overture on a phone ---------------------------------------------- */
@media (max-width: 700px) {
  .overture { gap: clamp(22px, 3vh, 34px); }
  /* 0.22em on nine tracked capitals is most of a narrow viewport */
  .overture__wordmark { letter-spacing: 0.16em; text-indent: 0.16em; }
  .overture__rule { width: min(320px, 68vw); }
  .overture__foot { gap: 14px; }
  .overture__scroll-bar { height: 26px; }
}


/* ========================================================================== */
/* 01 · Hero                                                                  */
/* ========================================================================== */

.hero {
  position: relative;
  min-height: 100vh;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(430px, 1fr));
  align-items: center;
  gap: clamp(30px, 4vw, 64px);
  /* no right gutter: the plate is meant to bleed off the right edge */
  padding: clamp(112px, 14vh, 168px) 0 clamp(48px, 7vh, 86px) var(--gutter);
  overflow: hidden;
}

/* the gilt breath, 16s, behind everything */
.hero__glow {
  position: absolute;
  right: -8%;
  top: -16%;
  width: min(820px, 76vw);
  height: min(820px, 76vw);
  border-radius: 50%;
  background-image: var(--breath-hero);
  opacity: var(--sun);
  animation: gilt-breathe var(--dur-breath) ease-in-out infinite;
  pointer-events: none;
}

/* a single gilt hairline frame, inset left/top/bottom and deliberately left
   open on the right so the bleed reads as intended */
.hero__frame {
  position: absolute;
  left: clamp(10px, 1.2vw, 20px);
  top: clamp(88px, 11vh, 124px);
  bottom: clamp(14px, 1.6vw, 26px);
  right: 0;
  border: 1px solid var(--hairline-soft);
  border-right: 0;
  pointer-events: none;
  z-index: 3;
}

.hero__copy {
  position: relative;
  z-index: 4;
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 3vh, 34px);
  max-width: 690px;
  padding-left: clamp(18px, 2vw, 34px);
}
.hero__headline {
  font-size: var(--fs-hero);
  line-height: var(--lh-hero);
  letter-spacing: var(--ls-hero);
  max-width: 14em;
}
.hero__standfirst {
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--sage);
  max-width: var(--measure);
  text-wrap: pretty;
}
.hero__actions {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2vw, 30px);
  flex-wrap: wrap;
}
.hero__figures { margin-top: 6px; }

.hero__stage {
  position: relative;
  z-index: 2;
  align-self: stretch;
  display: flex;
  align-items: center;
  min-height: clamp(400px, 64vh, 760px);
}
.hero__plate {
  width: 100%;
  height: clamp(400px, 68vh, 780px);
  border-radius: 290px 290px 0 0;
  border-right: 0;
}
.hero__plate .plate__brief { left: 30px; top: 46px; max-width: 17em; }

/* the caption card, sitting proud of the plate's left edge */
.hero__card {
  position: absolute;
  left: clamp(-14px, -1vw, 0px);
  bottom: 38px;
  z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 272px;
  padding: 19px 23px;
  background: var(--forest-raise);
  border: 1px solid var(--hairline-firm);
}
.hero__card-label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--copper-lit);
}
.hero__card-line {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 19.5px;
  line-height: 1.36;
  color: var(--cream);
}
.hero__card-coords {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.1em;
  color: var(--sage-faint);
}

/* --- the motes ------------------------------------------------------------ */
/* Pollen and dust in the air of the two dark full-screen sections, 2–7px,
   rising over 46–96s. The ceiling is fourteen in the overture and eight in
   the hero; the old ceiling of five was set when they all shared one path.

   A mote is not a dot with a soft edge — it is a radial gradient with no edge
   at all, which is what a speck slightly out of focus looks like and what
   keeps a 7px mote from reading as a bullet. --core decides how much of it is
   solid before the falloff begins: 0% is a diffuse smudge, 60% a near-pinpoint
   with a halo. No filter: blur() anywhere, because a filter re-rasterises the
   element every frame and these have to be free.

   Every mote sits behind the type (z-index 2 on .overture__centre and
   .hero__copy) — in front of the gilt breath, never over a letterform. */
.mote {
  position: absolute;
  left: var(--x);
  bottom: var(--y);
  width: var(--size);
  height: var(--size);
  background-image: radial-gradient(circle closest-side,
    var(--tone) var(--core, 0%), var(--mote-out) 100%);
  opacity: 0;
  animation: var(--path, mote-a) var(--dur) linear var(--delay) infinite;
  pointer-events: none;
}

/* The percentage x-positions get denser as the viewport narrows, so a third
   of them are dropped on a phone rather than letting the air get crowded.
   Which third is chosen by hand in seed.py, not by :nth-child — an every-other
   rule would leave exactly the even spacing the whole set exists to avoid. */
@media (max-width: 700px) {
  .mote--wide { display: none; }
}


/* ========================================================================== */
/* 02 · The basket — anatomy                                                  */
/* ========================================================================== */

.chapter--anatomy { background: var(--forest-deep); }
.chapter--anatomy .chapter__inner { gap: clamp(40px, 6vh, 72px); }
.chapter--anatomy .chapter__headline { max-width: 15em; }

.anatomy__gloss {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 38em;
}
.anatomy__gloss p {
  font-size: var(--fs-body-sm);
  line-height: var(--lh-body);
  color: var(--sage);
}
.anatomy__latin {
  font-family: var(--font-display);
  font-style: italic;
  color: var(--gilt-light);
}

.anatomy__body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: clamp(26px, 3.4vw, 58px);
  align-items: stretch;
  border-top: 1px solid var(--hairline);
  padding-top: clamp(30px, 4vh, 50px);
}

.anatomy__plate { min-height: clamp(360px, 56vh, 560px); }
.anatomy__plate .plate__brief { left: 22px; top: 22px; font-size: 11px; }
.anatomy__plate .plate__spec { left: 22px; bottom: 22px; }

/* five numbered gilt pins, positioned by percentage over the macro.
   Percentages assume the shot is framed leg-diagonal, tibia at 30/34. */
.pin {
  position: absolute;
  left: var(--x);
  top: var(--y);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 27px;
  height: 27px;
  margin: -13px 0 0 -13px;
  padding: 0;
  border: 1px solid var(--gilt);
  border-radius: 50%;
  background: var(--pin-well);
  color: var(--gilt-light);
  font-family: var(--font-mono);
  font-size: 11.5px;
  cursor: pointer;
  transition: background var(--dur-pin) ease, border-color var(--dur-pin) ease,
              color var(--dur-pin) ease, transform var(--dur-pin) var(--ease);
  animation: pin-pulse 4s ease-out infinite var(--delay);
}
.pin[aria-pressed="true"],
.pin:hover,
.pin:focus-visible {
  background: var(--copper);
  border-color: var(--copper);
  color: var(--ink-metal);
  transform: scale(1.22);
}

.legend { display: flex; flex-direction: column; }
.legend__row {
  display: grid;
  grid-template-columns: 34px 1fr;
  gap: 16px;
  align-items: start;
  border-top: 1px solid var(--hairline-soft);
  padding: 16px 4px;
  padding-left: 4px;
  background: transparent;
  transition: padding-left var(--dur-row) var(--ease), background var(--dur-row) ease;
}
.legend__row.is-lit,
.legend__row:hover {
  padding-left: 18px;
  background: var(--copper-wash);
}
.legend__no {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  color: var(--gilt);
  transition: color var(--dur-row) ease;
}
.legend__text { display: flex; flex-direction: column; gap: 6px; }
.legend__term {
  font-family: var(--font-display);
  font-size: var(--fs-term);
  line-height: 1.2;
  color: var(--sage-lit);
  transition: color var(--dur-row) ease;
}
.legend__row.is-lit .legend__no,
.legend__row:hover .legend__no { color: var(--copper-lit); }
.legend__row.is-lit .legend__term,
.legend__row:hover .legend__term { color: var(--cream-hi); }
.legend__body {
  font-size: var(--fs-legend);
  line-height: 1.72;
  color: var(--sage-body);
  max-width: 34em;
}
.legend .figures {
  border-top: 1px solid var(--hairline-soft);
  padding-top: 20px;
  margin-top: 4px;
  gap: clamp(18px, 2.4vw, 40px);
}
.legend .figure__n { font-size: 28px; }
.legend .figure__k { font-size: var(--fs-micro); }

.anatomy__ka {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  border-top: 1px solid var(--hairline);
  padding-top: 24px;
}
.anatomy__ka-word { font-size: 15px; color: var(--gilt); }
.anatomy__ka-gloss {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  letter-spacing: var(--ls-meta);
  text-transform: uppercase;
  color: var(--sage-faint);
}


/* ========================================================================== */
/* 03 · The care                                                              */
/* ========================================================================== */

.chapter--care { background: var(--forest); }
.chapter--care .chapter__inner { gap: clamp(52px, 7vh, 92px); }

.movement {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: clamp(26px, 4vw, 70px);
  align-items: center;
  border-top: 1px solid var(--hairline);
  padding-top: clamp(30px, 4vh, 50px);
}
.movement__text {
  display: flex;
  flex-direction: column;
  gap: 18px;
  order: 1;
}
.movement__plate {
  height: clamp(280px, 44vh, 440px);
  order: 2;
  border-color: var(--hairline-edge);
  transition: transform 1200ms var(--ease);
}
.movement__plate .plate__brief { left: 22px; bottom: 22px; font-size: 11px; max-width: 22em; }
@media (hover: hover) {
  .movement__plate:hover { transform: translateY(-8px); }
}
/* the rows alternate: even movements put the plate first */
.movement--flipped .movement__text { order: 2; }
.movement--flipped .movement__plate { order: 1; }

.movement__mark { display: flex; align-items: baseline; gap: 16px; }
.movement__no {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: var(--fs-numeral);
  line-height: 0.86;
  color: var(--gilt);
}
.movement__label {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sage-meta);
}
.movement__title {
  font-size: var(--fs-sub);
  line-height: var(--lh-sub);
  max-width: 20em;
}
.movement__body {
  font-size: clamp(14.5px, 1.05vw, 16.5px);
  line-height: 1.82;
  color: var(--sage);
  max-width: var(--measure);
  text-wrap: pretty;
}
.movement__facts {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  padding-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--sage-faint);
}

.pull {
  display: flex;
  justify-content: center;
  border-top: 1px solid var(--hairline);
  padding-top: clamp(40px, 6vh, 72px);
}
.pull__figure {
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
  max-width: 24em;
  text-align: center;
}
.pull__mark {
  width: 46px;
  opacity: .7;
  animation: settle 9s ease-in-out infinite;
}
.pull__quote {
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-size: var(--fs-quote);
  line-height: var(--lh-quote);
  color: var(--cream-hi);
  text-wrap: pretty;
}
.pull__by {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--sage-faint);
}


/* ========================================================================== */
/* 04 · Five yields — the ivory ground                                        */
/* ========================================================================== */

.chapter--yields {
  background: var(--ivory);
  border-top: 0;
}
.chapter--yields .chapter__inner { gap: var(--block-y); }
.chapter--yields .chapter__headline {
  color: var(--ink);
  max-width: 15em;
}
.chapter--yields .chapter__body { color: var(--ink-body); }

.rail {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(298px, 1fr));
  gap: var(--rail-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}
.rail > li { display: flex; }

.card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--ivory-card);
  border: 1px solid var(--ivory-rule);
  overflow: hidden;
  transition: transform var(--dur-card) var(--ease),
              box-shadow var(--dur-card) ease,
              border-color var(--dur-card) ease;
}
@media (hover: hover) {
  .card:hover,
  .card:focus-within {
    transform: translateY(-7px);
    box-shadow: var(--card-cast);
    border-color: var(--copper);
  }
}

.card__plate { height: clamp(230px, 27vh, 290px); }
.card__plate .plate__brief {
  left: 16px;
  bottom: 16px;
  font-size: var(--fs-micro);
  line-height: 1.55;
  color: var(--ink-meta);
  max-width: 19em;
}
.card__left {
  position: absolute;
  right: 14px;
  top: 14px;
  padding: 5px 10px;
  background: var(--ivory-veil);
  border: 1px solid var(--ivory-rule);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--copper-ink);
}

.card__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 22px 22px 20px;
  flex: 1;
}
.card__name {
  font-size: 27px;
  line-height: 1.14;
  color: var(--ink);
}
.card__latin {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--ink-meta);
}
.card__note {
  font-size: var(--fs-card);
  line-height: var(--lh-card);
  color: var(--ink-body);
  flex: 1;
}
.card__take {
  display: flex;
  gap: 10px;
  align-items: baseline;
  border-top: 1px solid var(--ivory-rule-in);
  padding-top: 12px;
}
.card__take-k {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--gilt-ink);
  white-space: nowrap;
}
.card__take-v {
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-body);
}
.card__buy {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  border-top: 1px solid var(--ivory-rule-in);
  padding-top: 14px;
  margin-top: 2px;
}
.card__price-col { display: flex; flex-direction: column; gap: 4px; }
.card__unit {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--ink-meta);
}
.card__price {
  font-family: var(--font-display);
  font-size: 27px;
  line-height: 1;
  color: var(--copper-ink);
}
.card__add {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 17px;
  background: transparent;
  border: 1px solid var(--ivory-rule-firm);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-hover) ease, border-color var(--dur-hover) ease,
              color var(--dur-hover) ease;
}
.card__add:hover,
.card__add:focus-visible {
  background: var(--copper-deep);
  border-color: var(--copper-deep);
  color: var(--ivory);
}

/* the dark sixth cell — what stops the grid reading as a generic shop */
.season {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 28px;
  width: 100%;
  padding: 30px 28px;
  background: var(--forest);
  border: 1px solid var(--copper-line);
  color: var(--cream);
}
.season__head { display: flex; flex-direction: column; gap: 14px; }
.season__label {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--copper-lit);
}
.season__count { display: flex; align-items: baseline; gap: 14px; }
.season__n {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(54px, 5.2vw, 80px);
  line-height: 0.9;
  color: var(--gilt);
}
.season__k {
  font-family: var(--font-mono);
  font-size: var(--fs-meta);
  letter-spacing: var(--ls-micro);
  text-transform: uppercase;
  color: var(--sage-meta);
  max-width: 8em;
}
.season__note {
  font-size: var(--fs-card);
  line-height: 1.78;
  color: var(--sage);
}
.season .arrow-link {
  border-top: 1px solid var(--copper-line-soft);
  padding-top: 16px;
}


/* --- the add-to-basket announcement -------------------------------------- */
/* One polite live region for every mutation; the header count is the
   persistent fallback. PLAN.md §9. */
.basket-say {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
