/* ===========================================================================
   Mercado — homepage.

   Eight sections, each with one job. The page alternates between only two
   surfaces (paper / paper-2) plus a single night section at the close, so the
   eye never has to re-orient.
   =========================================================================== */

/* ---- 01 · HERO -----------------------------------------------------------
   One product, one headline, one CTA.

   Two columns: the copy holds the reading edge, the product takes the rest
   and runs the full height of the viewport so it is unmistakably the subject.
   A single stacked column was tried first and left the phone at 306px tall
   with the headline eating the screen — the product has to dominate.
   --------------------------------------------------------------------------- */
/* overflow-x: clip keeps the oversized glow from widening the page on a
   phone; clip (unlike hidden) leaves the vertical axis alone. */
.hero {
  position: relative;
  isolation: isolate;
  overflow-x: clip;
  --hero-light-x: 28%; /* the product column: inline-end, i.e. left in RTL */
}

[dir="ltr"] .hero { --hero-light-x: 72%; }

/* Depth, not colour. Paper stays the ground; a warm haze sits where the
   product is lit and the lower edge settles into the faintest neutral. Both
   are a few percent strong — you should not be able to point at them. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(48% 62% at var(--hero-light-x) 52%, color-mix(in srgb, var(--brand) 5%, transparent), transparent 72%),
    radial-gradient(80% 45% at 50% 108%, color-mix(in srgb, var(--ink) 3.5%, transparent), transparent 70%);
}

.hero__inner {
  min-block-size: 100svh;
  display: grid;
  align-items: center;
  gap: var(--s6);
  padding-block: calc(var(--header-h) + var(--s6)) var(--s6);
}

@media (min-width: 900px) {
  .hero__inner {
    /* The copy column is sized so the headline holds one line per row at the
       display size; wider and the product shrinks, narrower and the Arabic
       breaks mid-phrase. */
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    gap: var(--s7);
  }
}

.hero__copy { display: grid; gap: var(--s5); align-content: center; }

.hero__title {
  font-size: var(--t-display);
  font-weight: 600;
  line-height: var(--lh-display);
  letter-spacing: normal;
  margin: 0;
}

/* The second line steps back so the headline carries hierarchy on its own —
   no second typeface, no colour. */
.hero__title .wipe + .wipe { color: var(--ink-2); }

.hero__lede { max-inline-size: 38ch; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s5); align-items: center; }

.hero__caption {
  display: grid;
  gap: var(--s2);
  padding-block-start: var(--s5);
  border-block-start: 1px solid var(--line);
  max-inline-size: 44ch;
}

.hero__caption-name { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

/* The image is taken out of flow: at 1080px intrinsic height it otherwise
   drives the row taller than the viewport. */
.hero__media {
  position: relative;
  block-size: min(74svh, 660px);
}

/* ---- hero atmosphere -------------------------------------------------------
   Studio light around the product. Everything below is a few percent of the
   brand orange or the ink on paper; the motion is in scenes.js. If a visitor
   notices the effect before the phone, these numbers are too high. */
.hero__atmos,
.hero__dust,
.hero__float,
.hero__lean,
.hero__bob {
  position: absolute;
  inset: 0;
}

.hero__atmos,
.hero__dust { pointer-events: none; }

/* Warm key light behind the device: large, soft, mostly hidden by it. The
   box is far bigger than the product and the gradient is gone well before
   its edge, so it never reads as a disc. */
.hero__glow {
  position: absolute;
  inset: -22% -26%;
  /* Dense near the device (where the phone covers most of it), then a long,
     nearly flat tail: a steep falloff is what turns a glow into a disc. */
  background: radial-gradient(
    46% 48% at 50% 48%,
    color-mix(in srgb, var(--brand) 11%, transparent) 0%,
    color-mix(in srgb, var(--brand) 5%, transparent) 30%,
    color-mix(in srgb, var(--brand) 2.2%, transparent) 58%,
    color-mix(in srgb, var(--brand) 0.8%, transparent) 80%,
    transparent 100%
  );
  will-change: transform, opacity;
}

/* A soft band of warm light that crosses the product area now and then.
   The mask fades its ends so it never shows a hard edge while it travels. */
.hero__sweep {
  position: absolute;
  inset: -6% -45%;
  background: linear-gradient(
    102deg,
    transparent 36%,
    color-mix(in srgb, var(--brand) 7%, transparent) 46%,
    color-mix(in srgb, var(--paper) 55%, transparent) 50%,
    color-mix(in srgb, var(--brand) 7%, transparent) 54%,
    transparent 64%
  );
  -webkit-mask: radial-gradient(50% 50% at 50% 50%, black 35%, transparent 100%);
  mask: radial-gradient(50% 50% at 50% 50%, black 35%, transparent 100%);
  opacity: 0;
  will-change: transform, opacity;
}

/* Contact shadow on the floor under the device. Breathes with the float. */
.hero__shadow {
  position: absolute;
  inset-inline: 24%;
  inset-block-end: 1%;
  block-size: 7%;
  background: radial-gradient(50% 50% at 50% 50%, color-mix(in srgb, var(--ink) 9%, transparent), transparent 100%);
  will-change: transform, opacity;
}

/* Dust in the light. scenes.js creates 8–16 of these around the product. */
.hero__mote {
  position: absolute;
  inline-size: var(--mote, 3px);
  block-size: var(--mote, 3px);
  margin: calc(var(--mote, 3px) / -2);
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--brand) 85%, var(--paper)) 0%, transparent 70%);
  opacity: 0;
  will-change: transform, opacity;
}

.hero__mote--neutral {
  background: radial-gradient(circle, var(--ink-3) 0%, transparent 70%);
}

.hero__float,
.hero__lean,
.hero__bob { will-change: transform; }

/* The photograph has a solid white ground. Multiplied over the warm light it
   loses its white box and the product sits inside the glow like the 3D
   device does. The blend is on the outermost wrapper because every
   transformed wrapper is its own isolation group. */
.hero__float--photo { mix-blend-mode: multiply; }

.hero__media img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  padding-block: 4%;
  transition: opacity var(--d-slow) var(--ease);
}

/* The WebGL device and the photograph occupy the same box. The photograph is
   what paints first and what stays when WebGL is unavailable; once the
   renderer has drawn a frame the stage takes over and the photo steps aside. */
.hero__media canvas {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  opacity: 0;
  transition: opacity 900ms var(--ease-out);
  pointer-events: none;
}

.hero__media.is-live canvas { opacity: 1; }
.hero__media.is-live img { opacity: 0; }

/* The live device can be turned by hand (stage.js). pan-y keeps a vertical
   swipe on a phone scrolling the page; only a sideways drag turns it. */
.hero__media.is-live {
  cursor: grab;
  touch-action: pan-y;
  -webkit-user-select: none;
  user-select: none;
}

.hero__media.is-dragging { cursor: grabbing; }
.hero__media.is-static canvas { display: none; }

@media (max-width: 899px) {
  .hero__inner { padding-block-end: var(--s7); }
  .hero__media { order: -1; block-size: min(44svh, 380px); }
  .hero__caption { max-inline-size: none; }

  /* The product sits on top in one column, so the haze moves up with it. */
  .hero::before {
    background:
      radial-gradient(70% 34% at 50% 26%, color-mix(in srgb, var(--brand) 5%, transparent), transparent 72%),
      radial-gradient(90% 30% at 50% 104%, color-mix(in srgb, var(--ink) 3%, transparent), transparent 70%);
  }
}

/* ---- 01 · HERO, launch -----------------------------------------------------
   The way a product launch page opens: everything centred on a quiet grey
   ground, a small eyebrow in the brand colour, a large headline, one line of
   copy, two pill actions, and the device standing below. No beams, no glow,
   no grain: the product and the type do the work.

   The grey is chosen for the photograph as much as for the look: multiplied
   over it, the photo's white background turns into the same grey, so the
   still and the 3D device sit on the stage identically.
   --------------------------------------------------------------------------- */
.hero--launch {
  --launch-bg: #F5F5F7;
  background: var(--launch-bg);
}

/* The atmosphere of the earlier hero is not used here. */
.hero--launch::before { content: none; }

.hero--launch .hero__inner {
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: start;
  gap: var(--s6);
  min-block-size: 100svh;
  padding-block: calc(var(--header-h) + var(--s6)) var(--s4);
  text-align: center;
}

.hero--launch .hero__copy {
  justify-items: center;
  gap: var(--s3);
  max-inline-size: 980px;
}

.hero__eyebrow {
  margin: 0;
  font-size: var(--t-lede);
  font-weight: 600;
  color: var(--brand-ink);
}

/* One line on a wide screen: the two wiped phrases sit side by side. */
.hero--launch .hero__title {
  font-size: clamp(2.5rem, 1rem + 4.6vw, 4.75rem);
  font-weight: 700;
  color: var(--ink);
}

.hero--launch .hero__title .wipe { display: inline-block; }
.hero--launch .hero__title .wipe + .wipe { color: #6E6E73; }

.hero__lede {
  margin: 0;
  max-inline-size: 48ch;
  font-size: clamp(1.1rem, 0.95rem + 0.6vw, 1.45rem);
  line-height: var(--lh-head);
  color: #6E6E73;
}

.hero--launch .hero__actions {
  justify-content: center;
  gap: var(--s3);
  margin-block-start: var(--s2);
}

.hero--launch .hero__actions .btn { min-height: 48px; padding-inline: var(--s6); }
.hero--launch .btn--ghost { border-color: rgb(17 17 17 / 0.18); background: transparent; }
.hero--launch .btn--ghost:hover { border-color: var(--ink); background: var(--ink); color: var(--paper); }

.hero__from {
  margin: 0;
  font-size: var(--t-sm);
  color: #6E6E73;
}

.hero__from a {
  font-weight: 600;
  color: var(--ink);
  border-block-end: 1px solid transparent;
  transition: border-color var(--d-fast) var(--ease);
}

.hero__from a:hover { border-block-end-color: var(--ink); }
.hero__from span[aria-hidden] { margin-inline: var(--s1); }

/* The device takes the rest of the first screen.

   The box carries the ground colour itself: the entrance tween transforms
   it, which makes it its own blend group, and the photograph's multiply can
   then only reach what is painted inside the box. */
.hero--launch .hero__media {
  inline-size: min(100%, 880px);
  block-size: clamp(300px, calc(100svh - 440px), 640px);
  background: var(--launch-bg);
}

/* A soft contact shadow; nothing else behind the device. */
.hero--launch .hero__shadow {
  inset-inline: 30%;
  inset-block-end: 2%;
  block-size: 6%;
  background: radial-gradient(50% 50% at 50% 50%, rgb(17 17 17 / 0.14), transparent 100%);
}

@media (max-width: 899px) {
  .hero--launch .hero__inner { padding-block: calc(var(--header-h) + var(--s6)) var(--s6); gap: var(--s5); }
  .hero--launch .hero__media { order: 0; inline-size: 100%; block-size: clamp(280px, 46svh, 420px); }
  .hero--launch .hero__title .wipe { display: block; }
}

/* ---- 01 · HERO, launch on a dark ground -------------------------------------
   The same layout on near-black, lit by a faint warm glow around the device.
   Remove .hero--dark in the template to return to the grey ground.

   The photograph has a white background, which no blend can hide on black.
   So while the 3D device loads, and once it is live, the photograph stays
   hidden and the device fades in on its own. Where there is no 3D (no WebGL,
   reduced motion, Save-Data, no JavaScript) the photograph shows, multiplied
   over a pale spot that falls off into the dark ground.
   --------------------------------------------------------------------------- */
.hero--dark {
  --launch-bg: #0A0A0B;
  color: #F5F5F7;
}

/* The glow is painted inside the device box, whose edges are the flat
   ground colour, so the box never shows. */
.hero--dark .hero__media {
  background:
    radial-gradient(closest-side, rgb(246 145 29 / 0.16), rgb(246 145 29 / 0.05) 55%, transparent 100%),
    var(--launch-bg);
}

.hero--dark .hero__media[data-stage]:not(.is-static) .hero__float--photo { opacity: 0; }

.hero--dark .hero__media.is-static,
.hero--dark .hero__media:not([data-stage]),
.no-js .hero--dark .hero__media {
  background: radial-gradient(closest-side, #F1EEEA 0%, #D9D4CE 42%, #2A2826 80%, var(--launch-bg) 100%);
}

.no-js .hero--dark .hero__media[data-stage] .hero__float--photo { opacity: 1; }

.hero--dark .hero__shadow {
  background: radial-gradient(50% 50% at 50% 50%, rgb(0 0 0 / 0.6), transparent 100%);
}

.hero--dark .hero__eyebrow { color: var(--brand); }
.hero--dark .hero__title { color: #F5F5F7; }
.hero--dark .hero__title .wipe + .wipe { color: #86868B; }
.hero--dark .hero__lede { color: #A1A1A6; }
.hero--dark .hero__from { color: #86868B; }
.hero--dark .hero__from a { color: #F5F5F7; }
.hero--dark .hero__from a:hover { border-block-end-color: #F5F5F7; }

.hero--dark .hero__actions .btn:not(.btn--ghost) {
  background: #F5F5F7;
  border-color: #F5F5F7;
  color: #0A0A0B;
}

.hero--dark .hero__actions .btn:not(.btn--ghost):hover {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--on-brand);
}

.hero--dark .btn--ghost { border-color: rgb(255 255 255 / 0.3); color: #F5F5F7; }
.hero--dark .btn--ghost:hover { border-color: #F5F5F7; background: #F5F5F7; color: #0A0A0B; }

.hero--dark :focus-visible { outline-color: #F5F5F7; }

/* ---- 01b · CATEGORIES ----------------------------------------------------
   The store's categories drift sideways under the hero, toward the end of the
   reading direction. Hover or focus stops the strip; a tile opens its
   category. The track holds two identical groups and moves by exactly one of
   them, so the loop has no seam — which is why items are spaced with a
   margin rather than a flex gap: the two halves must be exactly equal.
   --------------------------------------------------------------------------- */
.cats { padding-block: var(--s8); }
.cats .section__open { margin-block-end: var(--s6); }

.cats__viewport {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.cats__track {
  --cats-shift: -50%;
  display: flex;
  inline-size: max-content;
  animation: cats-drift var(--cats-duration, 40s) linear infinite;
  will-change: transform;
}

[dir="rtl"] .cats__track { --cats-shift: 50%; }

.cats__track:hover,
.cats__track:focus-within { animation-play-state: paused; }

@keyframes cats-drift {
  to { transform: translateX(var(--cats-shift)); }
}

/* The padding gives the lifted tile room inside the clipped viewport. */
.cats__track { padding-block: var(--s3) var(--s2); }

.cats__item { flex: 0 0 auto; margin-inline-end: var(--s5); }

/* minmax(0, 1fr): the padded photo would otherwise widen the track past the
   tile. */
.cat {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  gap: var(--s1);
  inline-size: 220px;
  text-align: center;
}

/* Product shots are on solid white, so the default tile is white with a
   hairline and the photo sits inside it. */
.cat__media {
  display: grid;
  place-items: center;
  inline-size: 100%;
  aspect-ratio: 6 / 5;
  margin-block-end: var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: clip;
  background: var(--paper);
  transition: transform var(--d) var(--ease-out), border-color var(--d-fast) var(--ease);
}

.cat__media img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  padding: 10%;
  transition: transform var(--d-slow) var(--ease-out);
}

/* Brand banners are drawn for this shape: they fill the tile. The slight
   zoom trims the hairlines some of them carry along their edges. */
.cat__media--cover { border-color: transparent; }
.cat__media--cover img { object-fit: cover; padding: 0; transform: scale(1.04); }

/* A category without an image shows its name in the frame. */
.cat__media--text {
  padding: var(--s4);
  border-color: transparent;
  background: var(--paper-2);
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--ink-2);
}

.cat__name { font-weight: 600; line-height: var(--lh-head); }
.cat__count { font-size: var(--t-micro); color: var(--ink-3); }

.cat:hover .cat__media,
.cat:focus-visible .cat__media { transform: translateY(-4px); border-color: var(--line-2); }
.cat:hover .cat__media--cover,
.cat:focus-visible .cat__media--cover,
.cat:hover .cat__media--text { border-color: transparent; }
.cat:hover .cat__media img { transform: scale(1.06); }
.cat:hover .cat__media--cover img { transform: scale(1.1); }

@media (max-width: 760px) {
  .cats { padding-block: var(--s7); }
  .cats__item { margin-inline-end: var(--s4); }
  .cat { inline-size: 150px; }
}

/* Reduced motion: no drift. The repeats go and the strip scrolls by hand. */
@media (prefers-reduced-motion: reduce) {
  .cats__viewport {
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .cats__track { animation: none; padding-inline: var(--gutter); }
  .cats__item { scroll-snap-align: start; }
  .cats__item.is-dup { display: none; }
}

/* ---- 02 · PRODUCT STORY --------------------------------------------------
   Editorial: image one side, a short line and real spec figures the other.
   --------------------------------------------------------------------------- */
.story__grid {
  display: grid;
  gap: var(--s7);
  align-items: center;
}

@media (min-width: 900px) {
  .story__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s9); }
}

/* White, edge to edge — see the note on .card__media. */
.story__media { background: var(--paper); }
.story__media img { inline-size: 100%; aspect-ratio: 1; object-fit: contain; padding: 7%; }

.story__title { margin-block: var(--s4) var(--s5); max-inline-size: 16ch; }

/* Specs sit on a rule grid — architectural, no boxes. */
.specs {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--s6) var(--s5);
  margin-block-start: var(--s7);
  padding-block-start: var(--s6);
  border-block-start: 1px solid var(--line);
}

@media (min-width: 1100px) { .specs { grid-template-columns: repeat(3, 1fr); } }

/* ---- 03 · SHOPPING -------------------------------------------------------
   .shop-grid is the two-up grid the brand and landing sections use.
   .shop-grid--editorial is the homepage line-up: it carries the catalogue, so
   it is denser — two cards on a phone, three on a tablet, four on a desktop —
   with the first product held in a block of its own so the grid still has a
   subject.

   The --editorial rules sit below the .shop-grid rules on purpose: the two
   selectors tie on specificity, so source order is what settles them.
   --------------------------------------------------------------------------- */
.shop-grid {
  display: grid;
  gap: var(--s8) var(--gutter);
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
}

@media (min-width: 900px) {
  .shop-grid { grid-template-columns: repeat(2, 1fr); gap: var(--s9) var(--s8); }
}

.shop-grid--editorial {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s6) var(--s4);
  align-items: start;
}

@media (min-width: 700px) {
  .shop-grid--editorial { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7) var(--s5); }
}

@media (min-width: 1100px) {
  .shop-grid--editorial { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s8) var(--s6); }
}

/* The subject. On a phone it takes the full width, where half of two columns
   would make it no larger than its neighbours; from a tablet up it holds a
   2 x 2 block at the head of the grid. */
.shop-grid--editorial > .card--feature { grid-column: span 2; }

@media (min-width: 700px) {
  .shop-grid--editorial > .card--feature { grid-row: span 2; align-self: stretch; }

  /* Its frame fills the two rows instead of keeping the square every other
     card uses: a square here is shorter than the block it sits in and leaves
     a hole in the grid. The photo still shows whole — it is centred inside
     the taller frame, on the same white the page is. */
  .shop-grid--editorial > .card--feature .card__media {
    aspect-ratio: auto;
    flex: 1 1 auto;
    min-block-size: 0;
  }
}

/* The way on to the rest of the catalogue, under the grid. */
.shop-grid__more {
  display: flex;
  justify-content: center;
  margin-block-start: var(--s7);
}

/* ---- 04 · MODEL SELECTOR -------------------------------------------------
   Typography carries this section. Hovering a model swaps the image beside
   it. Built from the real catalogue line-up, not from invented categories.
   --------------------------------------------------------------------------- */
.models__grid { display: grid; gap: var(--s7); }

@media (min-width: 900px) {
  .models__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); gap: var(--s9); align-items: center; }
}

.models__list { display: grid; }

.model {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s5);
  padding-block: var(--s5);
  border-block-end: 1px solid var(--line);
  color: var(--ink-3);
  transition: color var(--d) var(--ease), padding-inline-start var(--d) var(--ease-out);
}

.model:first-child { border-block-start: 1px solid var(--line); }

.model__name {
  font-size: clamp(1.5rem, 0.9rem + 2.4vw, 2.6rem);
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.2;
}

.model__from { font-size: var(--t-sm); font-weight: 500; white-space: nowrap; }

.model.is-active, .model:hover, .model:focus-visible {
  color: var(--ink);
  padding-inline-start: var(--s4);
}

/* The image panel holds every model's shot stacked; only the active one is
   visible, so switching is a cross-fade with no layout shift. */
.models__preview {
  position: relative;
  aspect-ratio: 1;
  background: var(--paper);
}

.models__shot {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: contain;
  padding: 8%;
  opacity: 0;
  transition: opacity var(--d-slow) var(--ease);
}

.models__shot.is-active { opacity: 1; }

@media (max-width: 899px) { .models__preview { display: none; } }

/* ---- 05 · BRAND ---------------------------------------------------------- */
.brandblock + .brandblock { margin-block-start: var(--section); }

.brandblock__name {
  font-size: clamp(3rem, 1rem + 11vw, 9rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: normal;
  margin: 0 0 var(--s7);
}

/* ---- 06 · INSTALLMENTS ---------------------------------------------------- */
.steps {
  display: grid;
  gap: var(--s6);
  counter-reset: step;
  margin-block-start: var(--s8);
}

@media (min-width: 760px) { .steps { grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: var(--s7); } }

.step { padding-block-start: var(--s4); border-block-start: 1px solid var(--line); }

.step__num {
  display: block;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: var(--track-latin);
  color: var(--brand-ink);
  margin-block-end: var(--s4);
}

.step__title { font-size: var(--t-h3); font-weight: 600; margin-block-end: var(--s2); }
.step__text { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

/* ---- 07 · WHY ------------------------------------------------------------
   Typography only. No icons. */
.why { display: grid; gap: var(--s6); }

@media (min-width: 760px) { .why { grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: var(--s7); } }

.why__item { padding-block-start: var(--s4); border-block-start: 1px solid var(--line); }

.why__title {
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  margin-block-end: var(--s3);
}

.why__text { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

/* ---- 08 · CLOSING MOMENT -------------------------------------------------
   One product, large, minimal text, single CTA.

   This was drafted as the page's one dark section. It cannot be: the product
   photography is shot on solid white, so on a near-black panel the image
   reads as a white rectangle rather than as a phone. The page therefore stays
   light throughout and the footer carries the only dark surface — which also
   keeps the surface count down, as the brief asks.
   --------------------------------------------------------------------------- */
.closer { position: relative; overflow: hidden; }

.closer__grid { display: grid; gap: var(--s7); align-items: center; }

@media (min-width: 900px) {
  .closer__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s9); }
}

.closer__title { font-size: var(--t-h1); margin-block: var(--s4) var(--s5); max-inline-size: 14ch; }

.closer__media img {
  inline-size: 100%;
  max-block-size: 70svh;
  object-fit: contain;
  margin-inline: auto;
  padding: 5%;
}
