/* ==========================================================================
   Cupagreen — The Cup Company
   Design system. Written by hand; no build step, no framework.

   The organising idea: a paper cup is defined by three numbers — top diameter,
   bottom diameter, height. That triple is this industry's vernacular, and it
   runs through the whole page as both a data device and a typographic motif.
   Product photography was shot on near-black seamless, so the dark sections
   let the cups float edgelessly rather than sit inside cards.
   ========================================================================== */

/* --- Fonts (variable, self-hosted) ---------------------------------------- */

@font-face {
  font-family: 'Newsreader';
  src: url('../fonts/newsreader-latin.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader';
  src: url('../fonts/newsreader-latin-ext.woff2') format('woff2');
  font-weight: 200 800;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Hanken Grotesk';
  src: url('../fonts/hanken-grotesk-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Hanken Grotesk';
  src: url('../fonts/hanken-grotesk-latin-ext.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/space-grotesk-latin.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Space Grotesk';
  src: url('../fonts/space-grotesk-latin-ext.woff2') format('woff2');
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

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

:root {
  /* Surface */
  --bone: #f6f7ef;
  --bone-sunk: #eef0e4;
  --pale: #ebf2dd;
  --paper: #fff;

  /* Ink */
  --ink: #1e2a20;
  --muted: #5c6b5a;
  --muted-soft: #7c8a7b;

  /* Brand */
  --teal: #15323b;
  --teal-deep: #11272e;
  --teal-soft: #1d4351;
  --leaf: #6fa82e;
  --leaf-deep: #4b7a1c; /* passes AA as link text on bone */
  --leaf-bright: #8dc63f; /* CTA on dark */
  --water: #3fafc9;

  /* Product tones, sampled from the kraft cups themselves */
  --kraft: #c9a175;
  --kraft-light: #e0c9a8;
  --kraft-rim: #f2e9db;

  /* Tinted section backgrounds — colour without noise */
  --water-tint: #e4f2f6;
  --kraft-tint: #f7edda;
  --water-deep: #20718b; /* AA text on water tint */

  /* On dark */
  --on-dark: #eaf1dc;
  --on-dark-muted: #a9bab2;
  --hairline: rgb(30 42 32 / 0.14);
  --hairline-dark: rgb(255 255 255 / 0.14);

  /* Type */
  --display: 'Newsreader', 'Iowan Old Style', Georgia, serif;
  --body: 'Hanken Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --data: 'Space Grotesk', ui-monospace, 'SF Mono', Menlo, monospace;

  --fs-display: clamp(2.35rem, 1.5rem + 3.4vw, 4.05rem);
  --fs-h2: clamp(1.95rem, 1.35rem + 2.3vw, 3.05rem);
  --fs-h3: clamp(1.25rem, 1.13rem + 0.5vw, 1.5rem);
  --fs-lead: clamp(1.05rem, 0.99rem + 0.3vw, 1.2rem);
  --fs-body: 1rem;
  --fs-small: 0.875rem;
  --fs-micro: 0.78rem;

  /* Space */
  --wrap: 1240px;
  --gutter: clamp(1.25rem, 5vw, 2.5rem);
  --section-y: clamp(3.75rem, 7vw, 6.5rem);
  --radius: 4px;
  --radius-lg: 10px;

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

/* --- Base ----------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* A safety net against accidental sideways scroll. `hidden` turns the body
     into a scroll container, which has historically broken `position: sticky`
     on iOS Safari — `clip` does the same job without that side effect, so use
     it wherever it is supported. */
  overflow-x: hidden;
}

@supports (overflow-x: clip) {
  body {
    overflow-x: clip;
  }
}

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

a {
  color: var(--leaf-deep);
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}

h1,
h2,
h3,
h4 {
  font-family: var(--display);
  font-weight: 400;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

:focus-visible {
  outline: 2.5px solid var(--leaf);
  outline-offset: 3px;
  border-radius: 2px;
}

.dark :focus-visible {
  outline-color: var(--leaf-bright);
}

::selection {
  background: var(--leaf-bright);
  color: var(--teal);
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 200;
  background: var(--teal);
  color: #fff;
  padding: 0.75rem 1.25rem;
  font-weight: 600;
}

.skip:focus {
  left: 0.5rem;
  top: 0.5rem;
}

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

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

/* Grid and flex children default to a min-content floor, so one long word or
   a wide table can push a whole column past the viewport. Reset it everywhere
   we lay out in columns. */
.hero__inner > *,
.split > *,
.estimator > *,
.cta-band > *,
.form-panel > *,
.section-head > *,
.range__card > *,
.facts > *,
.readout > * {
  min-width: 0;
}

.wrap--narrow {
  max-width: 900px;
}

.section {
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: calc(var(--section-y) * 0.6);
}

.dark {
  /* Two faint colour pools — leaf upper-right, water lower-left — so the teal
     bands read as lit space rather than flat panels. */
  background: radial-gradient(
      85% 70% at 88% 8%,
      rgb(141 198 63 / 0.13) 0%,
      transparent 60%
    ),
    radial-gradient(70% 65% at 6% 95%, rgb(63 175 201 / 0.11) 0%, transparent 60%),
    var(--teal);
  color: var(--on-dark);
}

.dark h1,
.dark h2,
.dark h3 {
  color: #fff;
}

.dark a {
  color: var(--leaf-bright);
}

.sunk {
  background: var(--bone-sunk);
}

.pale {
  background: var(--pale);
}

.tint-water {
  background: linear-gradient(180deg, var(--water-tint) 0%, #eef6f8 100%);
}

.tint-water .eyebrow {
  color: var(--water-deep);
}

.tint-kraft {
  background: linear-gradient(180deg, var(--kraft-tint) 0%, #f9f2e4 100%);
}

.tint-kraft .eyebrow {
  color: #9a6d33;
}

/* --- Typography roles ----------------------------------------------------- */

.eyebrow {
  font-family: var(--data);
  font-size: var(--fs-micro);
  font-weight: 500;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--leaf-deep);
  margin: 0 0 1.1rem;
}

.dark .eyebrow {
  color: var(--leaf-bright);
}

.display {
  font-size: var(--fs-display);
  line-height: 1.03;
  letter-spacing: -0.025em;
  font-weight: 400;
}

h2,
.h2 {
  font-size: var(--fs-h2);
  line-height: 1.08;
}

h3,
.h3 {
  font-size: var(--fs-h3);
  line-height: 1.25;
  font-weight: 500;
}

.lead {
  font-size: var(--fs-lead);
  line-height: 1.62;
  color: var(--muted);
  max-width: 34em;
}

.dark .lead {
  color: var(--on-dark-muted);
}

.small {
  font-size: var(--fs-small);
  line-height: 1.55;
  color: var(--muted);
}

.dark .small {
  color: var(--on-dark-muted);
}

/* The dimension triple — this industry's own notation, used as a motif. */
.dim {
  font-family: var(--data);
  font-size: var(--fs-small);
  font-weight: 400;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  white-space: nowrap;
}

.dim span {
  color: var(--leaf-deep);
  padding-inline: 0.15em;
}

.dark .dim {
  color: var(--on-dark-muted);
}

.dark .dim span {
  color: var(--leaf-bright);
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
  font-family: var(--body);
  font-size: 0.97rem;
  font-weight: 600;
  letter-spacing: 0.005em;
  line-height: 1;
  padding: 1.05rem 1.75rem;
  border: 1.5px solid transparent;
  border-radius: 100px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.2s var(--ease), border-color 0.2s var(--ease),
    color 0.2s var(--ease), transform 0.2s var(--ease);
}

.btn:hover {
  transform: translateY(-2px);
}

.btn--primary:hover {
  box-shadow: 0 10px 24px -10px rgb(21 50 59 / 0.55);
}

.dark .btn--primary:hover {
  box-shadow: 0 10px 26px -8px rgb(141 198 63 / 0.45);
}

.btn:active {
  transform: translateY(1px);
}

.btn--primary {
  background: var(--teal);
  border-color: var(--teal);
  color: #fff;
}

.btn--primary:hover {
  background: var(--teal-soft);
  border-color: var(--teal-soft);
}

.btn--ghost {
  background: transparent;
  border-color: rgb(30 42 32 / 0.32);
  color: var(--ink);
}

.btn--ghost:hover {
  border-color: var(--ink);
  background: rgb(30 42 32 / 0.04);
}

/* Inverted rule: on dark surfaces the bright leaf carries the action. */
.dark .btn--primary {
  background: var(--leaf-bright);
  border-color: var(--leaf-bright);
  color: var(--teal);
}

.dark .btn--primary:hover {
  background: #a2d75a;
  border-color: #a2d75a;
}

.dark .btn--ghost {
  border-color: rgb(255 255 255 / 0.38);
  color: var(--on-dark);
}

.dark .btn--ghost:hover {
  border-color: #fff;
  background: rgb(255 255 255 / 0.07);
}

.btn--block {
  width: 100%;
}

.btn[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

/* A quiet text link that still reads as an action. */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1.5px solid var(--leaf);
  padding-bottom: 3px;
  transition: gap 0.2s var(--ease), border-color 0.2s var(--ease);
}

.link-arrow:hover {
  gap: 0.7rem;
  border-bottom-color: var(--ink);
}

.dark .link-arrow {
  color: #fff;
  border-bottom-color: var(--leaf-bright);
}

.dark .link-arrow:hover {
  border-bottom-color: #fff;
}

/* --- Header --------------------------------------------------------------- */

.site-header::before {
  content: '';
  display: block;
  height: 3px;
  background: linear-gradient(90deg, var(--leaf) 0%, var(--leaf-bright) 35%, var(--water) 100%);
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgb(246 247 239 / 0.88);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid var(--hairline);
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.9rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.brand img {
  height: 40px;
  width: auto;
}

.nav {
  display: flex;
  align-items: center;
  gap: 1.9rem;
}

.nav a {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink);
  text-decoration: none;
  padding-block: 0.35rem;
  border-bottom: 1.5px solid transparent;
  transition: border-color 0.18s var(--ease), color 0.18s var(--ease);
}

.nav a:hover {
  border-bottom-color: var(--leaf);
}

.nav a[aria-current='page'] {
  border-bottom-color: var(--leaf);
  color: var(--leaf-deep);
}

.site-header .btn {
  padding: 0.8rem 1.35rem;
  font-size: 0.9rem;
}

.nav-toggle {
  display: none;
  background: none;
  border: 1.5px solid var(--hairline);
  border-radius: 100px;
  padding: 0.6rem 1rem;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

/* --- Hero ----------------------------------------------------------------- */

.hero {
  background: var(--teal);
  color: var(--on-dark);
  position: relative;
  overflow: hidden;
}

.hero::after {
  /* A single soft light source, roughly where the studio key light was. */
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    62% 58% at 76% 26%,
    rgb(111 168 46 / 0.16) 0%,
    transparent 70%
  );
  pointer-events: none;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 1.06fr 0.94fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(3.5rem, 7vw, 6rem);
}

.hero h1 {
  margin-bottom: 1.5rem;
  color: #fff;
}

.hero h1 em {
  font-style: italic;
  color: var(--leaf-bright);
}

.hero .lead {
  margin-bottom: 2.1rem;
  max-width: 30em;
}

.hero__meta {
  margin-top: 2.4rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hairline-dark);
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 2rem;
}

.hero__meta div {
  font-size: var(--fs-small);
  color: var(--on-dark-muted);
}

.hero__meta strong {
  display: block;
  font-family: var(--data);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--leaf-bright);
  margin-bottom: 0.3rem;
}

/* The photograph, floated. See .float below. */
.hero__figure {
  position: relative;
}

/* --- Floating photography ------------------------------------------------
   Every product photo was shot on near-black seamless. On a dark panel we
   fade the frame edge into the background so the object reads as floating in
   the page rather than pasted into a box. On light panels the same images get
   a soft plinth instead.
   ------------------------------------------------------------------------- */

.float {
  position: relative;
  display: block;
}

.float img {
  width: 100%;
  filter: contrast(1.04) saturate(1.02);
}

/* The photo backdrop and the teal panel sit at almost the same luminance, so a
   generous radial fade is enough to dissolve the frame — no blend mode needed,
   which also keeps the cup's own colour honest. */
.dark .float img {
  -webkit-mask-image: radial-gradient(
    ellipse 56% 58% at 50% 47%,
    #000 22%,
    transparent 72%
  );
  mask-image: radial-gradient(
    ellipse 56% 58% at 50% 47%,
    #000 22%,
    transparent 72%
  );
  filter: contrast(1.08) saturate(1.06);
}

/* Light surfaces: a plinth of soft shadow so the object still sits in space. */
.float--light img {
  border-radius: var(--radius-lg);
  box-shadow: 0 24px 50px -22px rgb(21 50 59 / 0.35);
}

/* A catalogue plate: artwork that carries its own background (like the
   wall-types cup) is shown whole on a rounded card — no edge fade, which
   would leave a halo of the artwork's background against the teal. */
.float--plate {
  position: relative;
  display: block;
}

.float--plate img {
  width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: 0 34px 70px -30px rgb(0 0 0 / 0.6);
}

.hero .float--plate {
  max-width: 470px;
  margin-inline: auto !important;
}

/* The artwork's cyan stripes continue out of the card and into the hero as a
   translucent halo at the same angle, so the plate belongs to the page rather
   than sitting on it. */
.hero .float--plate::before {
  content: '';
  position: absolute;
  inset: -34px -44px;
  border-radius: calc(var(--radius-lg) + 12px);
  background: repeating-linear-gradient(
    -32deg,
    transparent 0 46px,
    rgb(63 175 201 / 0.16) 46px 92px
  );
  -webkit-mask-image: radial-gradient(85% 85% at 50% 50%, #000 40%, transparent 78%);
  mask-image: radial-gradient(85% 85% at 50% 50%, #000 40%, transparent 78%);
  pointer-events: none;
}

.hero .float--plate img {
  position: relative;
  transform: rotate(-1.6deg);
  animation: plate-drift 8s ease-in-out infinite alternate;
}

@keyframes plate-drift {
  from {
    transform: rotate(-1.6deg) translateY(0);
  }
  to {
    transform: rotate(-1.6deg) translateY(-10px);
  }
}

/* --- The size ladder — the signature element -----------------------------
   Each cup is drawn from the real catalogue dimensions at one shared scale,
   so the row is a true side-by-side comparison rather than an illustration.
   The trapezoid comes from topD/bottomD; the height from height. Selecting a
   cup writes its full spec into the readout — this is the spec table, made
   physical.
   ------------------------------------------------------------------------- */

/* No min-height: without JavaScript the row has nothing in it and should
   collapse rather than leave a hole. The readout underneath carries the
   specification either way, so the section still reads. */
.ladder {
  display: flex;
  align-items: flex-end;
  gap: clamp(0.75rem, 2.2vw, 1.9rem);
  padding-top: 2.5rem;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

.ladder__item {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.85rem;
  background: none;
  border: 0;
  padding: 0 0 0.4rem;
  font: inherit;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Each cup is a photograph of the real product, its height set from the real
   height in millimetres at one shared scale. The photo was shot on near-black
   seamless, so on the dark panel the frame edge is masked away and the cup
   floats — the same treatment used for the hero. */
.cup {
  position: relative;
  display: block;
  /* height is set per item, in JS, from the real dimensions */
  transition: transform 0.28s var(--ease);
}

.cup__photo {
  height: 100%;
  width: auto;
  display: block;
  -webkit-mask-image: radial-gradient(
    ellipse 62% 64% at 50% 50%,
    #000 40%,
    transparent 80%
  );
  mask-image: radial-gradient(
    ellipse 62% 64% at 50% 50%,
    #000 40%,
    transparent 80%
  );
  filter: contrast(1.06) saturate(1.05) brightness(0.98);
  transition: filter 0.28s var(--ease);
}

.ladder__item:hover .cup,
.ladder__item:focus-visible .cup {
  transform: translateY(-8px);
}

.ladder__item[aria-pressed='true'] .cup {
  transform: translateY(-8px);
}

.ladder__item:hover .cup__photo,
.ladder__item[aria-pressed='true'] .cup__photo {
  filter: contrast(1.1) saturate(1.15) brightness(1.1);
}

/* The prompt that tells people the row is interactive. */
.ladder-hint {
  margin-top: 1.25rem;
  font-family: var(--data);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--leaf-bright);
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.ladder-hint span {
  font-size: 1rem;
  animation: nudge 2.4s var(--ease) infinite;
}

@keyframes nudge {
  0%, 70%, 100% { transform: translateY(0); }
  80% { transform: translateY(4px); }
  90% { transform: translateY(0); }
}

/* Tiny "tap" chip under the selected cup, so the affordance is unmistakable. */
.ladder__item::after {
  content: 'Tap';
  font-family: var(--data);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-bright);
  border: 1px solid rgb(141 198 63 / 0.4);
  border-radius: 100px;
  padding: 0.2rem 0.55rem;
  opacity: 0;
  transition: opacity 0.25s var(--ease);
}

.ladder__item:hover::after,
.ladder__item:focus-visible::after {
  opacity: 1;
}

.ladder__item[aria-pressed='true']::after {
  content: 'Shown below';
  opacity: 1;
  color: var(--teal);
  background: var(--leaf-bright);
  border-color: var(--leaf-bright);
}

.ladder__label {
  font-family: var(--data);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  transition: color 0.2s var(--ease);
}

.ladder__item:hover .ladder__label,
.ladder__item[aria-pressed='true'] .ladder__label {
  color: var(--ink);
}

/* Readout — driven by estimator-free JS in ladder.js */
.readout {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--hairline);
  margin-top: 1.75rem;
}

.readout div {
  padding: 1.4rem 1.5rem 0 0;
}

.readout div + div {
  border-left: 1px solid var(--hairline);
  padding-left: 1.5rem;
}

.readout dt {
  font-family: var(--data);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--muted-soft);
  margin-bottom: 0.5rem;
}

.readout dd {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.4rem, 1.15rem + 1vw, 1.95rem);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.readout dd small {
  display: block;
  font-family: var(--body);
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 0.35rem;
  letter-spacing: 0;
}

/* Ladder section sits on dark: hairlines and labels invert. */
.ladder-section .readout {
  border-top-color: var(--hairline-dark);
}

.ladder-section .readout div + div {
  border-left-color: var(--hairline-dark);
}

.ladder-section .readout dt {
  color: var(--on-dark-muted);
}

.ladder-section .readout dd {
  color: #fff;
}

.ladder-section .readout dd small {
  color: var(--on-dark-muted);
}

.ladder-section .ladder__label {
  color: var(--on-dark-muted);
}

.ladder-section .ladder__item:hover .ladder__label,
.ladder-section .ladder__item[aria-pressed='true'] .ladder__label {
  color: #fff;
}

/* --- Section headings ----------------------------------------------------- */

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 1.5rem 2.5rem;
  flex-wrap: wrap;
  margin-bottom: 2.75rem;
}

.section-head p.lead {
  margin-top: 1rem;
}

/* --- Product range grid --------------------------------------------------- */

/* Exactly three columns on desktop so the six cards fill two clean rows —
   auto-fit would leave dead cells at some widths. */
.range {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border-block: 1px solid var(--hairline);
}

.range__card {
  background: var(--bone);
  padding: 1.75rem 1.75rem 2rem;
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  transition: background-color 0.25s var(--ease);
}

.range__card:hover {
  background: var(--paper);
}

.range__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--teal-deep);
  margin-bottom: 1.4rem;
}

.range__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}

.range__card:hover .range__media img {
  transform: scale(1.035);
}

.range__card h3 {
  margin-bottom: 0.5rem;
  display: flex;
  align-items: center;
  gap: 0.55rem;
}

/* Each category gets its own colour — a small legend of the range. */
.range__card h3::before {
  content: '';
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: none;
  background: var(--leaf);
}

.range__card:nth-of-type(2) h3::before { background: var(--water); }
.range__card:nth-of-type(3) h3::before { background: var(--kraft); }
.range__card:nth-of-type(4) h3::before { background: var(--teal-soft); }
.range__card:nth-of-type(5) h3::before { background: var(--leaf-bright); }
.range__card:nth-of-type(6) h3::before { background: var(--water-deep); }

/* Cards arrive one after another, not as a block. */
.js .range[data-reveal] .range__card {
  opacity: 0;
  transform: translateY(16px);
}

.range[data-reveal].is-in .range__card {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}

.range[data-reveal].is-in .range__card:nth-of-type(2) { transition-delay: 0.07s; }
.range[data-reveal].is-in .range__card:nth-of-type(3) { transition-delay: 0.14s; }
.range[data-reveal].is-in .range__card:nth-of-type(4) { transition-delay: 0.21s; }
.range[data-reveal].is-in .range__card:nth-of-type(5) { transition-delay: 0.28s; }
.range[data-reveal].is-in .range__card:nth-of-type(6) { transition-delay: 0.35s; }

.range__card p {
  color: var(--muted);
  font-size: 0.94rem;
  line-height: 1.55;
  margin-bottom: 1.25rem;
}

.range__card .dim {
  margin-top: auto;
  font-size: 0.78rem;
}

/* --- Split band (image + copy) -------------------------------------------- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.split--reverse .split__media {
  order: -1;
}

/* --- Numbered process ----------------------------------------------------
   Numbered because it genuinely is a sequence: artwork, then proof, then
   print. The order is information the buyer needs.
   ------------------------------------------------------------------------- */

.steps {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.5rem;
}

.steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.1rem;
  align-items: start;
}

.steps b {
  font-family: var(--data);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--leaf-deep);
  padding-top: 0.3rem;
  font-variant-numeric: tabular-nums;
}

.steps h3 {
  font-size: 1.15rem;
  margin-bottom: 0.3rem;
}

.steps p {
  color: var(--muted);
  font-size: 0.95rem;
}

/* Steps slide in from the left in order — the motion mirrors the sequence. */
.js [data-reveal] .steps li {
  opacity: 0;
  transform: translateX(-12px);
}

[data-reveal].is-in .steps li {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s var(--ease), transform 0.55s var(--ease);
}

[data-reveal].is-in .steps li:nth-child(2) { transition-delay: 0.12s; }
[data-reveal].is-in .steps li:nth-child(3) { transition-delay: 0.24s; }

/* --- Fact grid ------------------------------------------------------------ */

.facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr));
  border-top: 1px solid var(--hairline);
}

.dark .facts {
  border-top-color: var(--hairline-dark);
}

.facts > div {
  padding: 1.9rem 1.75rem 0 0;
}

.facts > div + div {
  border-left: 1px solid var(--hairline);
  padding-left: 1.75rem;
}

.dark .facts > div + div {
  border-left-color: var(--hairline-dark);
}

.facts h3 {
  font-size: clamp(1.5rem, 1.2rem + 1.1vw, 1.95rem);
  font-weight: 400;
  margin-bottom: 0.6rem;
}

/* A short coloured rule above each fact — leaf, water, kraft in rotation. */
.facts > div::before {
  content: '';
  display: block;
  width: 30px;
  height: 3px;
  border-radius: 2px;
  margin-bottom: 1rem;
  background: var(--leaf);
}

.facts > div:nth-of-type(2)::before { background: var(--water); }
.facts > div:nth-of-type(3)::before { background: var(--kraft); }

.js .facts[data-reveal] > div {
  opacity: 0;
  transform: translateY(14px);
}

.facts[data-reveal].is-in > div {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}

.facts[data-reveal].is-in > div:nth-of-type(2) { transition-delay: 0.09s; }
.facts[data-reveal].is-in > div:nth-of-type(3) { transition-delay: 0.18s; }

.facts p {
  font-size: 0.93rem;
  line-height: 1.55;
  color: var(--muted);
}

.dark .facts p {
  color: var(--on-dark-muted);
}

/* --- Pull quote ----------------------------------------------------------- */

.pull {
  font-family: var(--display);
  font-size: clamp(1.5rem, 1.1rem + 1.7vw, 2.35rem);
  line-height: 1.28;
  letter-spacing: -0.015em;
  max-width: 22em;
  margin: 0;
}

/* --- Spec tables (products page) ------------------------------------------ */

.spec {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
  font-size: 0.93rem;
}

.spec caption {
  text-align: left;
  font-family: var(--data);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-soft);
  padding-bottom: 0.9rem;
}

.spec th,
.spec td {
  text-align: left;
  padding: 0.85rem 1rem 0.85rem 0;
  border-bottom: 1px solid var(--hairline);
}

.spec thead th {
  font-family: var(--data);
  font-size: 0.71rem;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--muted-soft);
  border-bottom-color: rgb(30 42 32 / 0.28);
  white-space: nowrap;
}

.spec tbody th {
  font-family: var(--body);
  font-weight: 600;
  white-space: nowrap;
}

.spec td {
  color: var(--muted);
  font-family: var(--data);
  font-size: 0.88rem;
}

.spec-wrap {
  overflow-x: auto;
  margin-top: 1.5rem;
}

/* The plastic-vs-paper table: our column reads as the green choice. */
.spec--compare td:last-child,
.spec--compare thead th:last-child {
  background: var(--pale);
  color: var(--leaf-deep);
  font-weight: 600;
  padding-left: 1rem;
}

.variant {
  padding-block: 2.5rem;
  border-top: 1px solid var(--hairline);
}

.variant:first-of-type {
  border-top: 0;
}

.variant__head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  align-items: baseline;
}

.variant p {
  color: var(--muted);
  font-size: 0.95rem;
  max-width: 46em;
  margin-top: 0.5rem;
}

/* Chips for non-dimensioned items (cutlery, boxes, lid styles). */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.25rem;
  padding: 0;
  list-style: none;
}

.chips li {
  font-size: 0.88rem;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--hairline);
  border-radius: 100px;
  background: var(--paper);
  color: var(--muted);
}

/* --- Category navigation (products page) ---------------------------------- */

.catnav {
  position: sticky;
  top: 68px;
  z-index: 40;
  background: rgb(246 247 239 / 0.92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--hairline);
}

.catnav ul {
  display: flex;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0.9rem 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.catnav ul::-webkit-scrollbar {
  display: none;
}

.catnav a {
  white-space: nowrap;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--muted);
  text-decoration: none;
  padding-block: 0.25rem;
  border-bottom: 1.5px solid transparent;
}

.catnav a:hover {
  color: var(--ink);
  border-bottom-color: var(--leaf);
}

/* --- Forms ---------------------------------------------------------------- */

.form-panel {
  display: grid;
  grid-template-columns: 1.08fr 0.92fr;
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: 0 30px 70px -40px rgb(21 50 59 / 0.5);
}

.form-panel__form {
  background: var(--paper);
  padding: clamp(1.75rem, 3.5vw, 3rem);
}

.form-panel__aside {
  background: var(--teal);
  color: var(--on-dark);
  padding: clamp(1.75rem, 3.5vw, 3rem);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2rem;
}

.field-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
  margin-top: 1.75rem;
}

.field {
  display: flex;
  flex-direction: column;
}

.field--wide {
  grid-column: 1 / -1;
}

.field label {
  font-size: 0.82rem;
  font-weight: 600;
  color: #3a473a;
  margin-bottom: 0.45rem;
}

.field .req {
  color: var(--leaf-deep);
}

.field input,
.field select,
.field textarea {
  font: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid #d7ddd0;
  border-radius: var(--radius);
  padding: 0.8rem 0.9rem;
  width: 100%;
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.field textarea {
  resize: vertical;
  min-height: 5.5rem;
}

.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 18px) calc(50% + 1px),
    calc(100% - 13px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 2.25rem;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--leaf);
  box-shadow: 0 0 0 3px rgb(111 168 46 / 0.16);
  outline: none;
}

.field input::placeholder,
.field textarea::placeholder {
  color: #9daa9c;
}

.field[data-invalid] input,
.field[data-invalid] select,
.field[data-invalid] textarea {
  border-color: #b4392f;
}

.field__error {
  font-size: 0.79rem;
  color: #a8352c;
  margin-top: 0.35rem;
  min-height: 0;
}

/* Honeypot — never shown, never announced. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form-status {
  margin-top: 1.1rem;
  font-size: 0.9rem;
  line-height: 1.55;
}

.form-status:empty {
  margin-top: 0;
}

.form-status--error {
  color: #a8352c;
}

.form-done {
  text-align: left;
  padding: 1rem 0;
}

.form-done h3 {
  font-size: 1.6rem;
  margin-bottom: 0.6rem;
}

.form-done p {
  color: var(--muted);
  max-width: 32em;
}

.form-note {
  font-size: 0.82rem;
  color: var(--muted);
  margin-top: 1rem;
}

/* Contact rows inside the aside panel */
.contact-list {
  display: grid;
  gap: 1.5rem;
  margin-top: 1.75rem;
}

.contact-list dt {
  font-family: var(--data);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-bright);
  margin-bottom: 0.4rem;
}

.contact-list dd {
  margin: 0;
  font-size: 1rem;
  color: #fff;
}

.contact-list dd a {
  color: #fff;
  text-decoration: none;
  border-bottom: 1px solid rgb(255 255 255 / 0.3);
}

.contact-list dd a:hover {
  border-bottom-color: var(--leaf-bright);
}

/* --- Sample estimator ----------------------------------------------------- */

.estimator {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

.kits {
  display: grid;
  gap: 0.85rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.kits legend {
  font-family: var(--data);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-soft);
  padding: 0;
  margin-bottom: 0.9rem;
}

.kit {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 0.9rem;
  align-items: start;
  padding: 1.15rem 1.25rem;
  border: 1.5px solid var(--hairline);
  border-radius: var(--radius-lg);
  background: var(--paper);
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.kit:hover {
  border-color: rgb(30 42 32 / 0.3);
}

.kit input {
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0.28rem 0 0;
  border: 1.5px solid #b9c2b4;
  border-radius: 50%;
  cursor: pointer;
  flex: none;
  transition: border-color 0.15s var(--ease), border-width 0.15s var(--ease);
}

.kit input:checked {
  border: 6px solid var(--leaf);
}

/* `:has()` only reached Firefox in December 2023, so estimator.js also sets
   data-selected. Either selector alone is enough to highlight the choice. */
.kit:has(input:checked),
.kit[data-selected] {
  border-color: var(--leaf);
  background: #fbfdf7;
}

.kit strong {
  display: block;
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.kit span {
  font-size: 0.87rem;
  color: var(--muted);
  line-height: 1.5;
}

.kit .dim {
  font-size: 0.78rem;
  align-self: center;
  text-align: right;
}

/* Result panel */
.quote {
  background: var(--teal);
  color: var(--on-dark);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  position: sticky;
  top: 90px;
}

.quote h3 {
  color: #fff;
  font-size: 1.3rem;
  margin-bottom: 1.25rem;
}

.quote__pin {
  margin-bottom: 1.5rem;
}

.quote__pin label {
  display: block;
  font-family: var(--data);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-bright);
  margin-bottom: 0.5rem;
}

.quote__pin input {
  font: inherit;
  font-family: var(--data);
  font-size: 1.15rem;
  letter-spacing: 0.16em;
  width: 100%;
  padding: 0.8rem 0.95rem;
  color: #fff;
  background: rgb(255 255 255 / 0.07);
  border: 1.5px solid rgb(255 255 255 / 0.22);
  border-radius: var(--radius);
  transition: border-color 0.18s var(--ease), background-color 0.18s var(--ease);
}

.quote__pin input::placeholder {
  color: rgb(255 255 255 / 0.34);
  letter-spacing: 0.16em;
}

.quote__pin input:focus {
  border-color: var(--leaf-bright);
  background: rgb(255 255 255 / 0.11);
  outline: none;
}

.quote__rows {
  margin: 0;
  border-top: 1px solid var(--hairline-dark);
}

.quote__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 0;
  border-bottom: 1px solid var(--hairline-dark);
}

.quote__row dt {
  font-size: 0.88rem;
  color: var(--on-dark-muted);
}

.quote__row dd {
  margin: 0;
  font-size: 0.95rem;
  color: #fff;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.quote__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  padding: 1.35rem 0 0.35rem;
}

.quote__total dt {
  font-family: var(--data);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--leaf-bright);
}

.quote__total dd {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(2rem, 1.5rem + 2vw, 2.9rem);
  line-height: 1;
  color: #fff;
  font-variant-numeric: tabular-nums;
}

.quote__hint {
  font-size: 0.83rem;
  line-height: 1.55;
  color: var(--on-dark-muted);
  margin-top: 1.1rem;
}

.quote .btn {
  margin-top: 1.5rem;
}

.quote[data-state='empty'] .quote__total dd {
  color: rgb(255 255 255 / 0.3);
}

/* --- Find us / map --------------------------------------------------------- */

.find {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: start;
}

.find > * {
  min-width: 0;
}

.find__addresses {
  display: grid;
  gap: 2.25rem;
}

/* One office: let it sit against the map rather than float at the top. */
.find__addresses--single {
  align-content: center;
  min-height: 100%;
}

.office h3 {
  font-size: 1.35rem;
  margin-bottom: 0.7rem;
}

.office address {
  font-style: normal;
  font-size: 0.97rem;
  line-height: 1.65;
  color: var(--muted);
}

/* The facade. Sized to the final embed so nothing shifts when it loads. */
.map {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--teal);
  box-shadow: 0 24px 50px -30px rgb(21 50 59 / 0.5);
}

.map iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.map__load {
  position: absolute;
  inset: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 2rem;
  background: radial-gradient(
      120% 100% at 50% 0%,
      rgb(111 168 46 / 0.18) 0%,
      transparent 65%
    ),
    var(--teal);
  border: 0;
  font: inherit;
  color: var(--on-dark);
  cursor: pointer;
  text-align: center;
  transition: background-color 0.25s var(--ease);
}

.map__load:hover {
  background-color: var(--teal-soft);
}

/* A map pin, drawn rather than fetched. */
.map__pin {
  width: 26px;
  height: 26px;
  border-radius: 50% 50% 50% 0;
  transform: rotate(-45deg);
  background: var(--leaf-bright);
  box-shadow: 0 6px 18px -4px rgb(0 0 0 / 0.45);
  position: relative;
}

.map__pin::after {
  content: '';
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--teal);
}

.map__label {
  font-family: var(--body);
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
}

.map__note {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--on-dark-muted);
  max-width: 30ch;
}

/* --- Footer --------------------------------------------------------------- */

.site-footer {
  background: var(--teal-deep);
  color: var(--on-dark-muted);
}

.site-footer__grid {
  display: grid;
  grid-template-columns: 1.5fr repeat(3, 1fr);
  gap: 2.5rem;
  padding-block: clamp(3rem, 5vw, 4.25rem) 2.5rem;
  border-bottom: 1px solid var(--hairline-dark);
}

.site-footer__brand img {
  height: 38px;
  width: auto;
  margin-bottom: 1.1rem;
}

.site-footer__brand p {
  font-size: 0.92rem;
  line-height: 1.6;
  max-width: 30ch;
}

.site-footer h2 {
  font-family: var(--body);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #fff;
  margin-bottom: 1.1rem;
}

.site-footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
}

.site-footer a {
  color: inherit;
  text-decoration: none;
  font-size: 0.92rem;
  transition: color 0.18s var(--ease);
}

.site-footer a:hover {
  color: #fff;
}

.site-footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  padding-block: 1.5rem 2rem;
  font-size: 0.82rem;
  color: var(--muted-soft);
}

/* --- Closing call to action ----------------------------------------------- */

.cta-band {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem;
  align-items: center;
}

/* --- Partners --------------------------------------------------------------
   A slow, continuous band of client names. It moves on its own because a
   static logo wall reads as a list, and a moving one reads as a roster that
   keeps going — but it is deliberately slow enough to read while it moves.
   --------------------------------------------------------------------------- */

.partners__title {
  text-align: center;
  max-width: 18em;
  margin-inline: auto;
  font-size: clamp(1.55rem, 1.2rem + 1.5vw, 2.3rem);
}

/* The roster. Without JavaScript it is a plain wrapped list of every client;
   the script turns it into a fixed set of slots that rotate through the full
   roster, so a long client list fits in a calm, constant amount of space. */
.roster {
  list-style: none;
  margin: clamp(2.25rem, 4vw, 3.25rem) 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1rem 2.5rem;
}

.roster li {
  font-family: var(--display);
  font-size: clamp(1.05rem, 0.95rem + 0.5vw, 1.4rem);
  font-weight: 500;
  color: #55654f;
}

/* Once the script takes over it becomes a grid of equal slots. */
.roster[data-ready] {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border-block: 1px solid var(--hairline);
  perspective: 800px;
}

.roster[data-ready] .slot {
  background: var(--bone);
  min-height: clamp(96px, 11vw, 132px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem 1rem;
  transform-style: preserve-3d;
  transition: transform 0.42s var(--ease), opacity 0.42s var(--ease);
  backface-visibility: hidden;
}

/* Mid-flip: edge-on and invisible, which is when the content is swapped. */
.roster[data-ready] .slot[data-flipping] {
  transform: rotateX(90deg);
  opacity: 0;
}

.slot__name {
  font-family: var(--display);
  font-size: clamp(1rem, 0.9rem + 0.45vw, 1.3rem);
  font-weight: 500;
  color: #55654f;
  text-align: center;
  line-height: 1.25;
}

/* Logos are desaturated to the weight of the surrounding type so the wall
   stays calm, and come back to full colour on hover. Multiply drops the white
   box that many downloaded logos carry, without touching transparent ones. */
.slot__logo {
  max-height: clamp(34px, 4vw, 52px);
  max-width: 100%;
  width: auto;
  object-fit: contain;
  /* Multiply drops the white box that many supplied logos carry. No opacity()
     in the filter — it would leave that box as a grey rectangle instead.
     brightness/contrast darken pale marks so they still read on the cream. */
  mix-blend-mode: multiply;
  filter: grayscale(1) brightness(0.62) contrast(1.35);
  transition: filter 0.35s var(--ease);
}

.roster[data-ready] .slot:hover .slot__logo {
  filter: none;
}

.partners__note {
  text-align: center;
  font-size: 0.92rem;
  color: var(--muted);
  max-width: 42ch;
  margin-inline: auto;
}

/* --- Motion --------------------------------------------------------------- */

/* Gated on .js so that if the script never runs, the content is simply there
   rather than stuck at zero opacity. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.55s var(--ease), transform 0.55s var(--ease);
}

/* Hero entrance — one orchestrated sequence on load rather than scattered
   effects. Children rise in reading order, the photograph settles in behind. */
.js [data-enter] > * {
  opacity: 0;
  transform: translateY(18px);
  animation: enter 0.75s var(--ease) forwards;
}

.js [data-enter] > *:nth-child(1) { animation-delay: 0.05s; }
.js [data-enter] > *:nth-child(2) { animation-delay: 0.14s; }
.js [data-enter] > *:nth-child(3) { animation-delay: 0.24s; }
.js [data-enter] > *:nth-child(4) { animation-delay: 0.34s; }
.js [data-enter] > *:nth-child(5) { animation-delay: 0.44s; }

.js [data-enter-figure] {
  opacity: 0;
  transform: scale(0.965);
  animation: enter-figure 1.1s var(--ease) 0.2s forwards;
}

@keyframes enter {
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes enter-figure {
  to {
    opacity: 1;
    transform: none;
  }
}

/* The ladder grows up from its baseline, shortest first — the motion says the
   same thing the section does, that these are real relative sizes. */
.js .ladder__item {
  opacity: 0;
  transform: translateY(16px);
  transform-origin: bottom center;
}

.ladder.is-in .ladder__item {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s var(--ease), transform 0.65s var(--ease);
}

/* Grids stagger their children instead of arriving as one block. */
[data-reveal] > .range__card,
[data-reveal].range > * {
  transition-delay: inherit;
}

/* Header lifts off the page once you leave the top. */
.site-header {
  transition: box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}

.site-header[data-scrolled] {
  box-shadow: 0 6px 24px -12px rgb(30 50 32 / 0.28);
  border-bottom-color: rgb(30 42 32 / 0.16);
}

/* --- Responsive ----------------------------------------------------------- */

@media (max-width: 1080px) {
  .range {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .roster[data-ready] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (max-width: 700px) {
  .roster[data-ready] {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 960px) {
  .hero__inner,
  .split,
  .estimator,
  .form-panel,
  .cta-band {
    grid-template-columns: 1fr;
  }

  .split--reverse .split__media {
    order: 0;
  }

  .hero__figure {
    max-width: 460px;
    margin-inline: auto;
  }

  .quote {
    position: static;
  }

  .cta-band {
    gap: 1.75rem;
  }

  .site-footer__grid {
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
  }

  .site-footer__brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 820px) {
  .nav,
  .site-header .btn {
    display: none;
  }

  .nav-toggle {
    display: inline-block;
  }

  .site-header[data-open] .nav {
    position: absolute;
    inset: 100% 0 auto;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--bone);
    border-bottom: 1px solid var(--hairline);
    padding: 0.5rem var(--gutter) 1.25rem;
  }

  .site-header[data-open] .nav a {
    padding: 0.85rem 0;
    border-bottom: 1px solid var(--hairline);
  }

  .site-header[data-open] .btn {
    display: inline-flex;
    margin: 1rem var(--gutter) 0;
    position: absolute;
    inset: auto 0 -3.5rem;
    width: calc(100% - (2 * var(--gutter)));
  }

  .readout {
    grid-template-columns: 1fr;
  }

  .readout div + div {
    border-left: 0;
    border-top: 1px solid var(--hairline);
    padding-left: 0;
    padding-top: 1.4rem;
    margin-top: 1.4rem;
  }

  .facts > div + div {
    border-left: 0;
    border-top: 1px solid var(--hairline);
    padding-left: 0;
  }

  .dark .facts > div + div {
    border-top-color: var(--hairline-dark);
  }
}

@media (max-width: 620px) {
  .range {
    grid-template-columns: 1fr;
  }
}

/* iOS Safari zooms the whole page when a focused field is under 16px. On
   touch screens, hold every control at 16px so tapping into the form never
   jerks the layout. */
@media (hover: none) and (pointer: coarse) {
  .field input,
  .field select,
  .field textarea,
  .quote__pin input {
    font-size: 16px;
  }
}

@media (max-width: 560px) {
  .field-grid {
    grid-template-columns: 1fr;
  }

  .kit {
    grid-template-columns: auto 1fr;
  }

  .kit .dim {
    grid-column: 2;
    text-align: left;
  }

  .btn-row .btn {
    width: 100%;
  }

  .site-footer__grid {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }

  /* Everything arrives already in place: no rise, no stagger, no marquee. */
  .js [data-reveal],
  .js [data-enter] > *,
  .js [data-enter-figure],
  .js .ladder__item,
  .js .range[data-reveal] .range__card,
  .js .facts[data-reveal] > div,
  .js [data-reveal] .steps li {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }

  /* Slots stop flipping; the script shows the whole roster at once instead. */
  .roster[data-ready] .slot {
    transform: none !important;
    opacity: 1 !important;
  }
}

@media print {
  .site-header,
  .catnav,
  .cta-band,
  .btn {
    display: none;
  }
}
