/* ==========================================================================
   components.css — the static appearance of every named class the pages are
   composed out of. Nothing here moves: every transition and animation lives in
   motion.css behind a prefers-reduced-motion guard, and CssConventionTests
   fails the build if one leaks back in here.

   KÂĞIT ÜSTÜNDE CAM. One lavender sheet, and everything on it is an object
   lying on that sheet. Read the head of tokens.css first; this file is the
   composition built out of those names.

   Three rules hold the whole thing together, stated once here rather than
   forty times below:

   1. AN OBJECT IS WHITE, AND YOU CAN SEE UNDER IT — the whitest paper in the
      ramp, a lit hairline along its top edge, and a soft ink-tinted cast
      beneath it. Never a flat fill on a flat ground: the version this replaced
      printed everything INTO the sheet, so nothing on it read as an object at
      all, and the version before that dissolved the sheet entirely.

   2. DEPTH IS SHARED — every translateZ comes from --depth-1/2/3 and every
      turn from --tilt-a/b/c. A page where each component invents its own
      numbers reads as a pile of effects; one drawn from a single spatial scale
      reads as one table with things lying on it.

   3. PERSPECTIVE IS DECLARED WHERE IT IS NEEDED, AND NOWHERE ELSE. A group
      that must share a vanishing point — the module deck, the pinboard — gets
      the `perspective` PROPERTY on its immediate parent. A single object that
      turns on its own gets the `perspective()` transform FUNCTION instead.
      That distinction matters: the property only reaches direct children, and
      threading `transform-style: preserve-3d` down through a container and a
      grid to reach a grandchild breaks the moment anything in the chain gains
      an `overflow`, a `filter` or an `isolation` — all of which force the
      subtree flat, silently, with no warning anywhere.
   ========================================================================== */

/* ==========================================================================
   0 — LAYOUT PRIMITIVES
   ========================================================================== */

.container {
  position: relative;
  inline-size: 100%;
  max-inline-size: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-m);
}

@media (min-width: 40em) {
  .container { padding-inline: var(--space-xl); }
}

.container--narrow { max-inline-size: 58rem; }
.container--wide { max-inline-size: 92rem; }

/* A band of the room. Deliberately NOT `isolation: isolate` any more: that is a
   grouping property, and a grouping property forces `transform-style: flat` on
   the whole subtree — it would have quietly cancelled every 3D transform below. */
.section {
  position: relative;
  padding-block: var(--space-2xl);
  /* The ambient light is painted by enormous soft discs that deliberately run
     past the container, so each band clips its own. `clip`, not `hidden`:
     it creates no scroll container, so `position: sticky` still works inside and
     the perspective declared further down the tree is untouched. Without it the
     document measured 1455px wide at a 1440px viewport — invisible, because
     body clips it, but a real overflow one layout change away from becoming a
     horizontal scrollbar. */
  overflow-x: clip;
}

@media (min-width: 64em) {
  .section { padding-block: var(--space-3xl); }
}

.section--tight { padding-block: var(--space-xl); }

/* THE INK SLAB. Not a full-bleed band — an alternation of light and dark
   bands is the default shape of a template — but the page's single largest
   OBJECT: a rounded block of ink lying on the sheet, inset from both edges,
   carrying the same cast every white card carries. What makes the page read as
   one design is that the slab obeys the object rules rather than becoming a
   second ground.

   Everything inside it inverts to the paper family. That is written once, in
   typography.css, rather than as a colour override per component. */
.section--ink {
  position: relative;
  margin-inline: var(--space-m);
  border-radius: var(--radius-slab);
  background-color: var(--surface-ink);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-lift-ink);
  overflow: hidden;
}

@media (min-width: 64em) {
  .section--ink { margin-inline: var(--space-xl); }
}

/* The slab's own top-edge light. Ink is a dark material, so the edge that
   catches the light is struck from the paper rather than from the ink. */
.section--ink::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 1px;
  background-image: linear-gradient(
    90deg, transparent, var(--line-inverse) 22%, var(--line-inverse) 78%, transparent);
  pointer-events: none;
  z-index: 1;
}

.stack > * + * { margin-block-start: var(--space-m); }
.stack--2xs > * + * { margin-block-start: var(--space-3xs); }
.stack--s > * + * { margin-block-start: var(--space-2xs); }
.stack--m > * + * { margin-block-start: var(--space-s); }

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
}

.cluster--tight { gap: var(--space-2xs); }
.cluster--loose { gap: var(--space-m); }

.grid-editorial {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-m);
}

.grid-editorial--split { gap: var(--space-l); }

/* `auto / span N`, and the explicit `auto` is the whole point.

   `grid-column: span 2` is shorthand for `grid-column-start: span 2` with the
   END left auto — so a later `.start-6 { grid-column-start: 6 }` replaced the
   span rather than adding to it, and the element came out ONE track wide. That
   bug was live: every `.span-N .start-N` pair on the site — the three footer
   columns and the MatchAI teaser's phone — was rendering at 77px in a 1440px
   window, which is why "BİZİ TAKİP EDİN" was stacked three words deep and the
   navigation links were breaking mid-phrase.

   Written this way the span lives on the END longhand, so a start class moves
   the block without resizing it. Measured, not reasoned about: the footer
   columns are 197 / 197 / 296px now. */
.span-2, .span-3, .span-4, .span-5,
.span-6, .span-7, .span-8, .span-12 { grid-column: auto / span 12; }

@media (min-width: 48em) {
  .span-2 { grid-column: auto / span 2; }
  .span-3 { grid-column: auto / span 3; }
  .span-4 { grid-column: auto / span 4; }
  .span-5 { grid-column: auto / span 5; }
  .span-6 { grid-column: auto / span 6; }
  .span-7 { grid-column: auto / span 7; }
  .span-8 { grid-column: auto / span 8; }

  .start-6 { grid-column-start: 6; }
  .start-8 { grid-column-start: 8; }
  .start-9 { grid-column-start: 9; }
  .start-10 { grid-column-start: 10; }
}

.split { display: grid; gap: var(--space-l); }

@media (min-width: 56em) {
  .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
}

.split__lede { max-inline-size: 46ch; }
.area-lede { max-inline-size: 52ch; }
.area-body { max-inline-size: 62ch; }

/* The twelve column rules, drawn as hairlines behind the content — the grid
   the page is set on, left visible, which is a printer's habit rather than a
   decoration. Faint enough to be found and never read. */
.has-rules > .container::before {
  content: "";
  position: absolute;
  inset-block: calc(-1 * var(--space-l));
  inset-inline: var(--space-m);
  background-image: var(--grid-lines);
  background-size: calc(100% / 12) 100%;
  /* Faint, and faded out at both ends. At full strength these stopped reading
     as the drawing grid behind the content and started reading as a table the
     content had been dropped into — most obviously behind the four statistics,
     where the vertical rules lined up with the columns and produced a
     spreadsheet. */
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(to bottom, transparent, black 18%, black 82%, transparent);
  mask-image: linear-gradient(to bottom, transparent, black 18%, black 82%, transparent);
  pointer-events: none;
  z-index: -1;
}

@media (min-width: 40em) {
  .has-rules > .container::before { inset-inline: var(--space-xl); }
}

/* ==========================================================================
   1 — THE THREE SIGNATURES
   ========================================================================== */

/* §0.1 THE INDEX RULE — a hairline down the start edge of every section with a
   filled square at its head. Drawn in ink and fading as it falls: a register
   mark down the margin of a printed sheet.

   Desktop only; at phone width there is no gutter to put it in. `display:
   block` is stated INSIDE the query on purpose — the base rule is
   `display: none`, and a media block that sets position, size and colour but
   forgets to turn the element on renders nothing at all. That exact omission
   made this motif invisible on every page of the previous design. */
.index-line { display: none; }

@media (min-width: 48em) {
  .index-line {
    display: block;
    position: absolute;
    inset-block-start: var(--space-l);
    inset-inline-start: var(--space-m);
    inline-size: var(--index-hair);
    block-size: min(22rem, 60%);
    background-image: linear-gradient(
      to bottom, var(--ink) 0%, var(--line-strong) 45%, transparent 100%);
    pointer-events: none;
  }

  .index-line::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-start: calc(-0.5 * var(--index-mark) + 0.5 * var(--index-hair));
    inline-size: var(--index-mark);
    block-size: var(--index-mark);
    background-color: var(--ink-faint);
  }

  /* The section in view takes the full ink and grows a ring, the way a register
     mark is inked harder on the sheet you are actually looking at. site.js
     toggles .is-active through an IntersectionObserver; with JavaScript off
     every mark simply stays at full strength. */
  .section.is-active .index-line::before {
    background-color: var(--ink);
    box-shadow: 0 0 0 3px var(--accent-veil);
  }
}

/* §0.2 THE STAR — the only ornament on the site. Drawn as a sprite path rather
   than typed as a character: ✦ takes an emoji presentation on Windows, which
   puts a full-colour cartoon in the middle of an editorial page. */
.mark {
  display: inline-block;
  inline-size: 0.7em;
  block-size: 0.7em;
  color: var(--ink);
  vertical-align: 0.02em;
}

.mark svg { fill: currentcolor; stroke: none; inline-size: 100%; block-size: 100%; }

/* §0.3 THE STAMP — a small tilted mono label, pressed onto the page. */
.stamp {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.4em 0.9em;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  color: var(--ink-soft);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  rotate: var(--stamp-tilt);
  white-space: nowrap;
}

/* The stamp inked solid — the chip the comps pin over a portrait and over the
   closing call to action. One flood, no outline. */
/* The three variants below flood an object that is white by default, so each
   one has to take the ink shadow with it: the paper hairline the base rule
   carries is a #F9F9FE stroke at 92%, which on ink is the brightest line in the
   whole composition. Found by walking every page and comparing each dark
   element's background against the inset layers of its own box-shadow, rather
   than by reading down the file and hoping — the same check that missed nothing
   is worth re-running whenever a new `--accent`/`--ink` flood is added. */
.stamp--accent {
  box-shadow: var(--shadow-soft-ink);
  border-color: transparent;
  background-color: var(--ink);
  color: var(--ink-inverse);
}

.stamp--accent .mark { color: var(--ink-inverse); }

.stamp--tilt-b { rotate: var(--tilt-b); }

/* ==========================================================================
   2 — MATERIAL
   ========================================================================== */

/* 9:16 is the site's structural unit — the shape of the medium this academy
   teaches — and .frame is where it is stated. Every plate that holds artwork
   inherits from it, and the two hero screens restate the ratio explicitly
   because one of them is deliberately the other way round. */
.frame {
  aspect-ratio: 9 / 16;
}

.frame,
.media-frame {
  position: relative;
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

/* The lit edge. A masked inset pseudo-element rather than a gradient
   border-image: it keeps the radius honest and lets the light fall off ALONG
   the edge instead of running at one value all the way round, which is the
   difference between an edge catching light and a coloured outline. */
.frame::before,
.media-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background-image: linear-gradient(
    150deg, var(--glass-edge) 0%, transparent 40%, transparent 60%, var(--glass-edge) 100%);
  -webkit-mask-image: linear-gradient(black, black), linear-gradient(black, black);
  -webkit-mask-clip: content-box, border-box;
  -webkit-mask-composite: xor;
  mask-image: linear-gradient(black, black), linear-gradient(black, black);
  mask-clip: content-box, border-box;
  mask-composite: exclude;
  pointer-events: none;
  z-index: 2;
}

.media-frame--square { aspect-ratio: 1; }

.frame__art,
.media-frame img,
.media-frame svg {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* THE ICON TILE — the comps' most repeated object, and the one that carries
   the ink into every card: a rounded square flooded with ink, with a single
   drawn glyph in the paper colour standing in it. One flood per card, always
   this one, which is what stops eight cards from needing eight ideas. */
.icon-tile {
  display: grid;
  place-items: center;
  inline-size: 3rem;
  block-size: 3rem;
  flex: none;
  border-radius: 1rem;
  background-color: var(--ink);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-soft-ink);
}

.icon-tile .mark {
  inline-size: 1.35rem;
  block-size: 1.35rem;
  color: var(--ink-inverse);
}

.icon-tile--sm { inline-size: 2.25rem; block-size: 2.25rem; border-radius: 0.7rem; }
.icon-tile--sm .mark { inline-size: 1rem; block-size: 1rem; }

/* THE TILE CARRIES A NUMBER, NOT A PICTOGRAM. The deck used to cycle four
   stock marks by position, and the code said so out loud: they "never claim the
   symbol describes that specific module". A camera on the bot module and a
   chain-link on the content module is decoration wearing a meaning it does not
   have, and four marks on rotation across eight cards is the single clearest
   tell that a page was assembled rather than written.

   The number is TRUE. These modules have a published order, that order is what
   the drawn covers are keyed on, and the page already named them M-01 to M-08
   in the line above the title. Putting the numeral in the tile turns the label
   into the object, deletes a row from every card, and gives the spine something
   to run between. */
.icon-tile--no {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: 1.1875rem;
  line-height: 1;
  /* Tabular, so 08 and 11 are the same width and the column of tiles has one
     optical centre rather than eight. */
  font-variant-numeric: tabular-nums;
}

/* A tile inside an ink block inverts, or it disappears into the slab. */
.section--ink .icon-tile,
.on-ink .icon-tile {
  background-color: var(--surface-ink-2);
  box-shadow: inset 0 0 0 1px var(--line-inverse);
}

/* Anything standing on an ink flood flips its ink — the rest of that inversion
   is in typography.css, scoped to .section--ink and .on-ink. */
.on-light { color: var(--ink); }

/* ==========================================================================
   3 — CHROME
   ========================================================================== */

.skip-link {
  position: absolute;
  inset-block-start: var(--space-2xs);
  inset-inline-start: var(--space-2xs);
  z-index: 200;
  padding: var(--space-2xs) var(--space-s);
  border-radius: var(--radius-control);
  background-color: var(--ink);
  color: var(--ink-inverse);
  font-weight: 600;
  translate: 0 -250%;
}

.skip-link:focus { translate: 0 0; }

.site-header {
  position: sticky;
  inset-block-start: 0;
  /* Above .menu-overlay (150), because the overlay carries no chrome of its own
     and the header's real toggle is what closes it. */
  z-index: 160;
  view-transition-name: site-header;
  /* NOTHING at the top of the page. Both comps put the navigation straight onto
     the paper with no bar behind it at all, and they are right: a full-width
     rule under a header is the first thing that makes a page look like a
     template. The chrome only appears once the sheet has been moved. */
  background-color: transparent;
}

/* Scrolled: the bar condenses into a capsule of paper floating over the content
   — the same object every card on this page is, with the same cast under it.
   .is-scrolled is set by site.js; without script the header simply stays the
   clean version above, which is the better of the two states to be stuck in.

   SOLID, not frosted, and that is a correction. It was --surface-blur behind a
   20px backdrop-filter, and a translucent bar over a page whose ink measures
   14:1 against the paper leaves a legible ghost at any alpha short of opaque:
   with the hero scrolled under it, "622 TOPLULUK ÜYESİ" read straight through
   the navigation. Blur softens an edge; it does not lower contrast. And a solid
   capsule is the more honest object anyway — every other thing lying on this
   sheet is opaque. */
.site-header.is-scrolled .site-header__inner {
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
  border-radius: var(--radius-pill);
  padding-inline: var(--space-m);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  min-block-size: var(--header-h);
  /* The capsule is inset from the container's own padding rather than filling
     it, so the floating bar clears the page margin instead of butting into it. */
  margin-block-start: var(--space-2xs);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  text-decoration: none;
  flex: none;
}

.brand__mark {
  inline-size: 36px;
  block-size: 36px;
  border-radius: 12px;
  box-shadow: 0 0 0 1px var(--line);
}

/* The wordmark is the display face at its own weight, tight and small — the
   comps set the academy's name in the header as a compact two-line lockup, and
   what makes that read as a mark rather than as a sentence is the tracking. */
.brand__word {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: 1rem;
  line-height: 1.15;
  letter-spacing: -0.03em;
  max-inline-size: 11ch;
}

/* THE DISCLOSURE INVERSION, which the next forty lines all serve.

   The header renders every navigation link, and the language switcher renders
   every language, as plain visible markup. Nothing carries a `hidden`
   attribute. The collapsing is scoped to `.js` — a class an inline script in
   <head> sets before first paint — so a scripted visitor never sees the open
   state, and a visitor without JavaScript gets a working header rather than a
   toggle button that nothing can press.

   Stated as a rule: a thing may only be hidden where something is GUARANTEED to
   show it again. LayoutTests pins each of these selectors, because this is the
   kind of contract a redesign silently breaks. */
.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-m);
  margin-inline-start: auto;
}

.js .site-nav { display: none; }

@media (min-width: 62em) {
  .js .site-nav { display: flex; align-items: center; }
}

/* Not mono, and not tracked out. The comps set the navigation in the prose
   face at reading weight, which is what lets a six-item Turkish menu fit
   between the wordmark and the call to action without shrinking to 10px. The
   mono is still the site's label voice; a navigation is language, not a label. */
.site-nav a {
  position: relative;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: var(--weight-body);
  color: var(--ink-soft);
  text-decoration: none;
  padding-block: var(--space-3xs);
}

.site-nav a::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 1px;
  background-color: var(--ink);
  scale: 0 1;
  transform-origin: 0 50%;
}

.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current="page"] { color: var(--ink); }
.site-nav a[aria-current="page"]::after { scale: 1 1; }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  margin-inline-start: auto;
}

@media (min-width: 62em) {
  .site-header__actions { margin-inline-start: 0; }
}

/* Scoped to .site-header so this beats .btn's own `display: inline-flex`, which
   is declared later in the file and would otherwise win on source order —
   leaving a 123px button in a 390px header and pushing 68px of the page off the
   side. Measured at 390px, not reasoned about. */
.site-header .site-header__cta { display: none; }

@media (min-width: 75em) {
  .site-header .site-header__cta { display: inline-flex; }
}

/* ---------------------------------------------------------------- language */

.lang-switcher { position: relative; }

/* Hidden until script exists to operate it; without script the panel below is
   simply a row of language buttons and this button would do nothing. */
.lang-switcher__toggle { display: none; }

.js .lang-switcher__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  /* 2.5rem, matching the menu toggle beside it. Measured at 390px: this button
     was 47x25, which is under every touch-target minimum there is and looked
     like a chip that had been squashed next to a round one. */
  min-block-size: 2.5rem;
  padding: 0.45rem 0.8rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-soft);
}

.js .lang-switcher__toggle:hover { border-color: var(--line-strong); color: var(--ink); }

/* The flag chip. A real 4:3 drawing, rounded and hairlined so it reads as a
   small printed object on this sheet rather than as a sticker — every other
   image on the site is mounted, and this is the smallest one.

   Sized in ems so it tracks the label beside it, and `object-fit: cover` on a
   1.35:1 box because a 4:3 flag next to a line of text is too tall: the crop
   takes a sliver off the top and bottom of the field, which no flag here
   carries meaning in. */
.lang-switcher__flag {
  inline-size: 1.35em;
  block-size: 1em;
  flex: none;
  object-fit: cover;
  border-radius: 3px;
  box-shadow: 0 0 0 1px var(--line);
  /* The fallback path renders a <span> with the emoji in it, and a span is not
     replaced content — these two keep the two shapes the same size. */
  font-size: 0.75em;
  line-height: 1;
}

.lang-switcher__name { display: none; }

@media (min-width: 30em) {
  .js .lang-switcher__name { display: inline; }
}

.lang-switcher__chevron { inline-size: 0.7em; block-size: 0.7em; opacity: 0.7; }

/* Unscripted: a plain inline row of language buttons, sitting in the header. */
.lang-switcher__panel { display: block; }

.js .lang-switcher__panel {
  display: none;
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-end: 0;
  z-index: 120;
  min-inline-size: 12rem;
  padding: var(--space-3xs);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
}

.js .lang-switcher__panel.is-open { display: block; }

.lang-switcher__list { display: flex; flex-wrap: wrap; gap: 2px; }

.js .lang-switcher__list { display: grid; }

.lang-switcher__option {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  inline-size: 100%;
  padding: var(--space-2xs) var(--space-xs);
  border-radius: calc(var(--radius-control) - 4px);
  text-align: start;
  text-decoration: none;
  font-size: 0.875rem;
}

/* On the ink flood the hairline round a flag is invisible, so it is struck from
   the paper instead — the same inversion every other edge on this site makes. */
.lang-switcher__option[aria-current="true"] .lang-switcher__flag {
  box-shadow: 0 0 0 1px var(--line-inverse);
}

.lang-switcher__option:hover { background-color: var(--surface-dim); }

.lang-switcher__option[aria-current="true"] {
  background-color: var(--ink);
  color: var(--ink-inverse);
}

/* ------------------------------------------------------------- mobile menu */

/* Hidden without script, for the same reason as the language toggle: it opens
   a panel only script can close. The full .site-nav above is the unscripted
   navigation and stays visible at every width. */
.menu-toggle { display: none; }

.js .menu-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
}

@media (min-width: 62em) {
  .js .menu-toggle { display: none; }
}

/* TWO bars, not three. The markup renders two — see _Header — and the morph
   below is written for two: they cross into an X rather than one crossing while
   a third fades. The three-bar version of the morph was here against two-bar
   markup, which produced a single diagonal stroke as the close control. */
.menu-toggle__bars { display: grid; gap: 5px; inline-size: 1rem; }

.menu-toggle__bar {
  display: block;
  block-size: 1.5px;
  background-color: var(--ink);
  border-radius: 2px;
}

/* The overlay is a DUPLICATE of .site-nav, which is why hiding it outright is
   not a progressive-enhancement violation: nothing is lost when it is gone,
   and a full-screen fixed panel with no way to close it would be worse than
   useless. Collapsed by `display: none` rather than by a `hidden` attribute —
   the markup must stay attribute-free so the collapse is CSS's decision and
   not the server's. */
.menu-overlay { display: none; }

.js .menu-overlay.is-open {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  align-content: center;
  gap: var(--space-l);
  padding: var(--space-xl) var(--space-m);
  background-color: var(--surface-0);
  background-image: var(--blob-bright);
  background-size: 150% 130%;
  background-position: 80% -20%;
  background-repeat: no-repeat;
  overflow-y: auto;
}

/* Scroll lock while the overlay is open, set by site.js on <body>. */
.has-menu-open { overflow: hidden; }

/* The list had no rule of its own, so six display-sized links stacked at
   line-height 1.08 with no gap and the descenders of one ran into the caps of
   the next. A display face needs air between lines that a paragraph does not. */
.menu-overlay__list {
  display: grid;
  gap: var(--space-2xs);
}

/* .menu-overlay__link, not `.menu-overlay a`. The descendant selector also hit
   the call to action in the overlay's foot, so the primary button was being set
   in the display face at 3rem — which is why a 24-character Turkish label
   wrapped to three lines inside a pill and the whole capsule became a 260px
   lozenge. The Navigation view component gives every menu link this class
   precisely so the two kinds of link here can be told apart. */
.menu-overlay__link {
  display: inline-block;
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(1.875rem, 7vw, 3rem);
  line-height: 1.06;
  letter-spacing: var(--tracking-display);
  text-decoration: none;
}

.menu-overlay__foot {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--line);
}

/* ------------------------------------------------------------------ cookies */

.cookie-banner {
  position: fixed;
  inset-block-end: var(--space-s);
  inset-inline-end: var(--space-s);
  z-index: 140;
  max-inline-size: min(26rem, calc(100vw - 2 * var(--space-s)));
}

.cookie-banner__inner {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-s) var(--space-m);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
}

.cookie-banner__text { font-size: 0.8125rem; color: var(--ink-soft); }

/* ==========================================================================
   4 — CONTROLS
   ========================================================================== */

/* A PILL, everywhere. Both comps round every control to a full capsule and
   pair exactly two of them: an ink flood and a white one with a hairline. That
   pair is the whole button system — there is no third button, because a page
   with three button weights has no primary action. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  padding: 0.9rem 1.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: var(--weight-strong);
  line-height: 1.2;
  text-decoration: none;
  box-shadow: var(--shadow-soft);
  isolation: isolate;
}

/* The wipe. A pseudo-element scaled from the leading edge rather than a
   background-position animation, so it composites instead of repainting.
   `border-radius: inherit` INSTEAD OF `overflow: hidden` on the button, and the
   difference is visible: clipping a child against a 999px radius while a 1px
   border is drawn over the same curve makes Chrome antialias the two edges
   independently, and the seam shows as a pale scallop at both ends of every
   pill. Inheriting the radius means there is one curve, drawn once. It clamps
   to the pseudo-element's own smaller box on its own, which is what the pill
   radius does anyway. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-color: var(--ink);
  transform-origin: 0 50%;
  scale: 0 1;
  z-index: -1;
}

.btn:hover { border-color: var(--ink); color: var(--ink-inverse); }
.btn:hover::before { scale: 1 1; }

.btn__icon { inline-size: 1em; block-size: 1em; flex: none; }

/* The one flood. The page's single most important action is the only thing on
   it that is a solid block of ink at control size, which is what makes it
   findable without a colour nothing else uses. */
.btn--primary {
  background-color: var(--ink);
  border-color: var(--ink);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-soft-ink);
}

/* On hover the flood lifts rather than inverts: a primary button that turns
   white on hover reads as having been switched off. */
.btn--primary::before { background-color: var(--accent-bright); }
.btn--primary:hover { border-color: var(--accent-bright); color: var(--ink-inverse); }

/* Transparent, for the places a button sits on a card that is already white
   and a second white surface would double the edge. */
.btn--ghost {
  background-color: transparent;
  border-color: var(--line-strong);
  color: var(--ink);
  box-shadow: none;
}

/* Inside an ink block the two weights swap materials: the flood becomes paper
   and the outline is struck from the paper too. */
.section--ink .btn,
.on-ink .btn {
  background-color: transparent;
  border-color: var(--line-inverse);
  color: var(--ink-inverse);
  box-shadow: none;
}

.section--ink .btn::before,
.on-ink .btn::before { background-color: var(--ink-inverse); }

.section--ink .btn:hover,
.on-ink .btn:hover { color: var(--ink); border-color: var(--ink-inverse); }

.section--ink .btn--primary,
.on-ink .btn--primary {
  background-color: var(--ink-inverse);
  border-color: var(--ink-inverse);
  color: var(--ink);
}

.btn--lg { padding: 1.1rem 2rem; font-size: 1.0625rem; }
.btn--sm { padding: 0.6rem 1.05rem; font-size: 0.8125rem; }
.btn--block { inline-size: 100%; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.34em 0.8em;
  border-radius: var(--radius-pill);
  background-color: var(--ink);
  color: var(--ink-inverse);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  white-space: nowrap;
}

.pill--outline {
  background-color: transparent;
  border: 1px solid var(--line-strong);
  color: var(--ink-soft);
}

.text-link {
  color: var(--ink);
  text-decoration: none;
  background-image: linear-gradient(currentcolor, currentcolor);
  background-size: 100% 1px;
  /* The rule is held at the baseline while the padding grows the hit area
     downward — measured at 390px, these were 21px tall, and a standalone link
     that small is a target a thumb misses. padding-block on an inline box does
     not open up the line, so nothing moves. */
  background-position: 0 calc(100% - 0.3rem);
  background-repeat: no-repeat;
  padding-block: 0.35rem 0.3rem;
}

/* Underlined at rest and un-underlined on hover, not the other way round. A
   link that only announces itself when the pointer is already on it is not
   announcing itself at all — and on a page with no second colour, the rule IS
   the link. */
.text-link:hover { background-size: 0% 1px; }

/* -------------------------------------------------------------------- form */

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

.field__label {
  position: absolute;
  inset-block-start: 1.05rem;
  inset-inline-start: 1rem;
  color: var(--ink-faint);
  font-size: 0.9375rem;
  pointer-events: none;
  transform-origin: 0 0;
}

.field__input {
  inline-size: 100%;
  padding: 1.55rem 1rem 0.65rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-control);
  background-color: var(--surface-2);
  color: var(--ink);
  font-size: 1rem;
  box-shadow: var(--shadow-soft);
}

.field__input:focus { border-color: var(--ink); }

/* The floating label. `:has()` rather than a JS class: the browser already
   knows whether the field is empty and whether it is focused, and a class
   toggled by script would be wrong for the frame before the script runs.
   Every field carries `placeholder=" "` so `:placeholder-shown` can match. */
.field:has(.field__input:focus) .field__label,
.field:has(.field__input:not(:placeholder-shown)) .field__label {
  translate: 0 -0.62rem;
  scale: 0.78;
}

.field:has(.field__input:focus) .field__label { color: var(--ink); }

.field__error {
  display: block;
  margin-block-start: var(--space-3xs);
  color: var(--danger);
  font-size: 0.8125rem;
}

/* An invalid field is marked by a HEAVIER rule and a sentence, never by a hue:
   there is no red in this palette, and a red field was never the accessible
   answer in the first place. */
.field:has(.field__input[aria-invalid="true"]) .field__input {
  border-color: var(--danger);
  border-width: 2px;
}

.form-note {
  padding: var(--space-s) var(--space-m);
  border-radius: var(--radius-control);
  border: 1px solid var(--line);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  font-size: 0.9375rem;
}

/* The two states differ in the weight of their start rule rather than in hue.
   A note that is only distinguishable by colour is not distinguishable at all
   for a large share of readers, and this palette has no second colour to spend
   on it anyway. */
.form-note--success {
  background-color: var(--success-tint);
  border-inline-start: 3px solid var(--success);
}

.form-note--error {
  background-color: var(--danger-tint);
  border-inline-start: 6px solid var(--danger);
  font-weight: var(--weight-strong);
}

/* ==========================================================================
   5 — THE HERO

   The thesis of the whole page: two screens facing each other with the work
   floating in the space between them. That IS the product — a creator on one
   side, a brand on the other, an AI in the gap — so it is the hero, rather
   than a big number and a gradient. The composition recurs deliberately in the
   MatchAI section and again in the final call to action, which is what makes
   it a thesis and not an illustration.

   THE FLOATING SOLIDS are the comps' signature and the one thing neither
   previous round had: five glass objects turning very slowly around the two
   screens, at five different depths. They are what tells you the page has a
   third dimension before you have scrolled a pixel, and they are the reason
   the ambient light exists at all — a glass solid on a flat ground is just a
   rounded rectangle.
   ========================================================================== */

.hero {
  position: relative;
  /* Tighter on a phone than the section rhythm would give it. At --space-2xl
     the eyebrow started 230px below a 100px header, which on a 390x844 screen
     is a quarter of the first view spent on nothing. The desktop hero is
     vertically centred in a full viewport and does not have the problem. */
  padding-block: var(--space-l) var(--space-2xl);
  overflow: hidden;
}

@media (min-width: 48em) {
  .hero { padding-block: var(--space-2xl) var(--space-3xl); }
}

@media (min-width: 62em) {
  .hero {
    min-block-size: calc(100svb - var(--header-h));
    display: flex;
    align-items: center;
  }
}

/* The key light — three sources drifting behind everything else. */
.hero__mesh {
  position: absolute;
  inset: -25% -12%;
  z-index: -2;
  pointer-events: none;
  filter: blur(24px);
}

.hero__blob { position: absolute; border-radius: 50%; }

.hero__blob--1 {
  inline-size: 72%;
  aspect-ratio: 1;
  inset-block-start: -20%;
  inset-inline-end: -10%;
  background-image: var(--blob-accent);
}

.hero__blob--2 {
  inline-size: 54%;
  aspect-ratio: 1;
  inset-block-end: -24%;
  inset-inline-start: -14%;
  background-image: var(--blob-bright);
}

.hero__blob--3 {
  inline-size: 62%;
  aspect-ratio: 1;
  inset-block-start: 24%;
  inset-inline-start: 28%;
  background-image: var(--blob-dim);
}

.hero__grid { display: grid; gap: var(--space-xl); align-items: center; }

@media (min-width: 62em) {
  .hero__grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--space-l);
  }
}

/* 46ch below the split, where this column IS the page. Above it the grid
   column is the constraint and the ch cap has to come off: `ch` here resolves
   against the PROSE face at 1.125rem, so 46ch is about 414px — and a headline
   set at 68px in a 414px column breaks a Turkish compound in half. Measured at
   1440, where the column is 640px wide and the cap was throwing 226px of it
   away. The lead and the actions keep their own measures below. */
.hero__copy { position: relative; z-index: 2; max-inline-size: 46ch; }

@media (min-width: 62em) {
  .hero__copy { max-inline-size: none; }
}

.hero__title {
  margin-block: var(--space-s) var(--space-m);
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: var(--text-hero);
  line-height: var(--leading-hero);
  letter-spacing: var(--tracking-hero);
  text-wrap: balance;
}

/* The one stepped-down word. A weight contrast inside a single family, which
   is the grotesque's own way of emphasising: at 6rem the difference between
   800 and 400 is enormous, and it costs no second colour on a page that has
   none to spend. */
.hero__title .text-em {
  font-weight: var(--weight-body);
  letter-spacing: -0.02em;
}

.hero__lead {
  max-inline-size: 46ch;
  color: var(--ink-soft);
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
}

.hero__actions { margin-block-start: var(--space-l); }

/* In the flow, not absolutely positioned over the headline.

   It was pinned to the bottom of the copy column at 26% of its width, which was
   tuned against one headline in one language; with the type resized it landed
   on top of the primary button, and in German it would have landed somewhere
   else again. A tilted capsule sitting between the headline and the lead reads
   as stamped just as well and cannot collide with anything. */
.hero__stamp {
  align-self: flex-start;
  position: relative;
  z-index: 3;
  margin-inline-start: var(--space-2xs);
}

/* Sits ON the action row, so the number is read at the moment of deciding
   rather than after. No rule above it any more: it is one item in a flex
   cluster now, and a border-block-start on a flex child draws a line over
   nothing. */
.hero__proof {
  display: flex;
  align-items: baseline;
  gap: var(--space-2xs);
  margin-inline-start: var(--space-s);
  padding-inline-start: var(--space-m);
  border-inline-start: 1px solid var(--line);
}

.hero__proof-figure {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(2.25rem, 3.4vw, 3rem);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--ink);
}

/* ------------------------------------------ the stage: two screens, one light */

.hero__subject {
  position: relative;
  /* The stage is sized by ITS OWN aspect ratio rather than by a fixed height,
     so the two absolutely-positioned screens inside it scale together with the
     column instead of drifting apart as the viewport changes. */
  aspect-ratio: 5 / 6;
  min-block-size: 18rem;
  /* The property, not the function: the two screens are a GROUP and have to
     share one vanishing point, or they read as two unrelated objects. */
  perspective: var(--persp);
  perspective-origin: 50% 45%;
}

@media (min-width: 62em) {
  .hero__subject { aspect-ratio: 6 / 5; min-block-size: 26rem; }
}

/* The creator's screen — vertical, the shape UGC is actually made in, and
   mounted the way the comps mount every image: in a white card with a margin
   of paper showing all the way round it, so the picture reads as a print laid
   on the sheet rather than as a hole cut in it.

   Placed with logical insets and a percentage size rather than with a centred
   50%/50% anchor and negative margins: the margins were tuned against one
   viewport and slid the pair off the bottom of the stage at every other one. */
.hero__entrance {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  inline-size: 52%;
  aspect-ratio: 9 / 16;
  padding: 0.6rem;
  border-radius: var(--radius-screen);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
  transform: rotateY(var(--tilt-a)) translateZ(var(--depth-1));
}

/* The brand's screen — landscape, a dashboard, facing back the other way. The
   two turns are equal and opposite, which is what makes the gap between them
   read as a space rather than as a margin. */
.hero__entrance--brand {
  inset-block-start: 6%;
  inset-inline-end: 0;
  inset-block-end: auto;
  inset-inline-start: auto;
  inline-size: 64%;
  aspect-ratio: 16 / 11;
  transform: rotateY(var(--tilt-b)) translateZ(calc(-1 * var(--depth-1)));
}

.hero__entrance::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: var(--sheen);
  opacity: 0.6;
  pointer-events: none;
}

.hero__entrance img,
.hero__entrance svg {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-screen) - 0.6rem);
  background-image: var(--gradient-frame);
}

/* ------------------------------------------------------- THE FLOATING SOLIDS

   Five glass objects around the two screens. They share the stage's vanishing
   point, so they are laid out as siblings of the screens rather than in a
   container of their own — a wrapper here would need `transform-style:
   preserve-3d` threaded through it, and any overflow or filter on the way down
   silently flattens the whole group.

   Sized in percentages of the stage, so the whole arrangement scales with the
   column instead of coming apart at the first breakpoint. */
.prop {
  position: absolute;
  display: grid;
  place-items: center;
  pointer-events: none;
  border-radius: 1.4rem;
  border: 1px solid var(--line);
  background-image: linear-gradient(
    145deg, var(--surface-2) 0%, var(--glass) 60%, var(--surface-dim) 100%);
  backdrop-filter: blur(6px);
  box-shadow: var(--shadow-lift);
}

/* The specular face. Only on the solids: it is what makes them read as glass
   rather than as frosted plastic, and it is the reason --sheen exists. */
.prop::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: var(--sheen);
  pointer-events: none;
}

/* One of the five is inked rather than glazed — the comps put a single solid
   tile among the glass, and without it the group is five variations on one
   idea. It is the same icon tile the cards carry, at stage scale. */
.prop--tile {
  /* background-image, not just background-color: .prop paints a gradient body
     and an image always wins over a colour on the same element, so the inked
     tile came out as another pane of glass. */
  background-image: none;
  background-color: var(--ink);
  box-shadow: var(--shadow-lift-ink);
  border-color: transparent;
  backdrop-filter: none;
  color: var(--ink-inverse);
}

/* Full bleed, and the radius inherited so the mark takes the tile's corner
   rather than sitting as a square inside a rounded one. The asset's own ground
   is this same forest, so covering the tile with it leaves nothing to line up:
   the object simply IS the mark. `cover` because the file is square and the
   tile is not exactly, and a squashed wordmark is worse than a cropped
   margin. */
.prop--tile img {
  inline-size: 100%;
  block-size: 100%;
  border-radius: inherit;
  object-fit: cover;
}
.prop--tile::after { opacity: 0.18; }

/* The crystal. A clipped hexagon rather than a rounded box, so the group has
   one object that is not a rectangle — which is what stops the arrangement
   reading as a scatter of cards.

   `filter: drop-shadow` and not `box-shadow`: a clip-path cuts the box shadow
   away with the box, so a clipped solid with a box-shadow has no cast at all
   and floats nowhere. Measured on the first pass — both crystals were
   invisible against the paper, because a #DCDCEF hexagon on #E6E6FA with no
   shadow is a 1.1:1 shape. The gradient body is the second half of the fix:
   a solid is lit on one face and shaded on the other, and a flat fill is what
   made it read as a sticker. */
.prop--gem {
  border: 0;
  border-radius: 0;
  background-color: transparent;
  background-image: linear-gradient(
    145deg, var(--surface-2) 0%, var(--surface-dim) 55%, var(--surface-1) 100%);
  box-shadow: none;
  filter: drop-shadow(0 18px 22px var(--cast-2));
  clip-path: polygon(50% 0%, 100% 26%, 100% 74%, 50% 100%, 0% 74%, 0% 26%);
}

.prop--gem::after { border-radius: 0; opacity: 0.9; }

.prop--round { border-radius: 50%; }

/* The five placements. Percentages of the stage, and deliberately uneven: an
   evenly spaced ring of objects reads as a diagram. */
.prop--1 { inset-block-start: 2%; inset-inline-start: 4%; inline-size: 15%; aspect-ratio: 1; }
.prop--2 { inset-block-start: 12%; inset-inline-end: 4%; inline-size: 11%; aspect-ratio: 1; }
.prop--3 { inset-block-end: 16%; inset-inline-end: 1%; inline-size: 19%; aspect-ratio: 1; }
.prop--4 { inset-block-end: 4%; inset-inline-start: 44%; inline-size: 13%; aspect-ratio: 1; }
.prop--5 { inset-block-start: 42%; inset-inline-start: -2%; inline-size: 10%; aspect-ratio: 1; }

/* Below the large breakpoint the stage is half the size and five solids on it
   become clutter on top of the artwork rather than depth around it. Two
   survive — the inked tile and the crystal, which are the two that read at any
   size. */
@media (max-width: 61.99em) {
  .prop--2,
  .prop--4,
  .prop--5 { display: none; }
}

/* The light in the gap. This is the AI in the composition: not a glowing brain
   or a circuit board, just the thing that happens between the two screens. On
   paper it is the sheet lifted toward white rather than a glow — the same
   move the ambient light makes, at the scale of one object. */
.hero__subject::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 50%;
  inline-size: 18rem;
  aspect-ratio: 1;
  translate: -50% -50%;
  background-image: var(--glow-bright);
  filter: blur(14px);
  opacity: 0.75;
  pointer-events: none;
  z-index: -1;
}

.hero__scroll {
  display: none;
  position: absolute;
  inset-block-end: var(--space-l);
  inset-inline-start: var(--space-m);
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-faint);
}

@media (min-width: 62em) {
  .hero__scroll { display: flex; }
}

.hero__scroll-rule {
  display: block;
  inline-size: 1px;
  block-size: 2.5rem;
  background-image: linear-gradient(to bottom, var(--ink), transparent);
}

/* ==========================================================================
   6 — MASTHEAD (sub-page headers)
   ========================================================================== */

.masthead { position: relative; padding-block: var(--space-xl) var(--space-l); }

.masthead::before {
  content: "";
  position: absolute;
  inset-block-start: -70%;
  inset-inline-end: -10%;
  inline-size: min(48rem, 90%);
  aspect-ratio: 1;
  background-image: var(--blob-bright);
  filter: blur(30px);
  pointer-events: none;
  z-index: -1;
}

.masthead__title {
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
  max-inline-size: 18ch;
}

.masthead__lead {
  margin-block-start: var(--space-s);
  max-inline-size: 56ch;
  color: var(--ink-soft);
}

/* ==========================================================================
   7 — MARQUEE
   ========================================================================== */

.marquee {
  /* How many times _Marquee.cshtml renders the list. The keyframe in motion.css
     shifts the track by exactly one copy — `-100% / var(--marquee-copies)` — so
     the loop is seamless for any count and the two files cannot disagree about
     which count it is. */
  --marquee-copies: 4;

  position: relative;
  overflow: hidden;
  padding-block: var(--space-s);
  border-block: 1px solid var(--line);
  background-color: transparent;
  /* Fades the ends so the loop never shows a hard cut at the viewport edge. */
  -webkit-mask-image: linear-gradient(90deg, transparent, black 7%, black 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 7%, black 93%, transparent);
}

/* NO GAP BETWEEN COPIES, and the arithmetic is the reason.

   The loop shifts by one copy — `100% / --marquee-copies` — so it is only
   seamless when one copy's PITCH equals one Nth of the track. With a track gap
   the track is N copies plus N-1 gaps, so a quarter of it is one copy plus
   three quarters of a gap: ten pixels short, every cycle, forever. (The old
   two-copy version was twenty pixels short the same way.) Each copy carries its
   own trailing space instead, so the pitch is exactly the copy and the division
   is exact at any count. */
.marquee__track {
  display: flex;
  align-items: center;
  gap: 0;
  inline-size: max-content;
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-l);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-faint);
  white-space: nowrap;
  /* The space that used to be the track's gap, now owned by the copy — see the
     note above .marquee__track. */
  padding-inline-end: var(--space-l);
}

.marquee__item .mark { color: var(--ink); }

.marquee--echo { background-color: transparent; border-block: 0; }

/* The echo spans the footer slab rather than the text column inside it. It used
   to sit inside the footer's .container, so it started 128px in from the slab's
   edge and read as a paragraph that had been indented by mistake — which is
   what it was. It is a band, and a band that stops short of both edges is not
   one. Moved out of the container in the markup; nothing is needed here beyond
   saying so, because the slab is now its own containing block. */

/* ==========================================================================
   8 — THE MODULE DECK

   THE CURRICULUM RUNS SIDEWAYS, and that is the answer to the one thing this
   block kept getting wrong.

   It was a poster with the rest of the modules stacked down the page beside it.
   Nothing caps the featured set — a `take: 6` was rejected early because the
   seeded copy says "the eight tracks below are everything that opens up with
   your membership" — so the section grew a card taller for every module an
   admin featured. Eight was fine. Twenty measured 2987px: a third of the whole
   document, and most of that was empty paper beside a poster that had run out
   of things to sit next to. A two-column variant fixed the height and left the
   block with two layouts to keep working.

   A shelf has no such failure mode. Its height is ONE CARD at any count, the
   sequence still reads in order because the order is now left to right, and
   "there is more here" is something the reader can see instead of something
   they discover by scrolling. It is also the component this site already has:
   the student-results gallery runs on the same `.shelf` — native overflow, CSS
   snap, a focusable container, arrows that CSS hides until `.js` arrives.
   ========================================================================== */

/* `.shelf.deck-shelf`, not `.deck-shelf`. The base `.shelf` sets the snap and is
   declared in section 11, several hundred lines BELOW this one — same
   specificity, later in the file, so it won. Doubling the class here settles it
   on specificity instead of on which section happens to come first, which is
   not a thing this file should have to promise. */
.shelf.deck-shelf {
  /* NO SNAP ON THIS SHELF, and `proximity` is not a middle ground — measured,
     after assuming it was.

     Snapping resolves at the end of a scroll, and a drift is a scroll that ends
     sixty times a second: every one-pixel step the script wrote was immediately
     pulled back to the nearest snap point, which for the whole first card is
     zero. The shelf sat at 0 with the animation loop running perfectly at 60fps.
     Mandatory would have been worse, not different.

     Nothing is lost. The arrows move by exactly one card plus its gap, so a
     press still lands on a card edge; only a thrown finger is free to stop
     between two, which is what a shelf does everywhere else. */
  scroll-snap-type: none;
}

/* Every card the same height, so a two-line title does not leave the card
   beside it short. The lead is wider, never taller. */
.deck-shelf .shelf__track { align-items: stretch; }

.deck-shelf .shelf__item {
  position: relative;
  inline-size: min(19rem, 76vw);
}

.deck-shelf .shelf__item--lead { inline-size: min(30rem, 84vw); }

/* THE TRACK. Cards in a row with gaps between them are a shelf; the same cards
   with a line running through their numbers are a curriculum, which is what
   these actually are — a published order somebody is meant to work through.

   Each card owns the segment in the gap BEFORE it, rather than one line being
   drawn behind all of them. The line then ends exactly where the cards end, at
   any count, and a card cannot be wrong about where the track is. Struck at the
   tile centre line, measured down from the top of the card, and it flips with
   the document because both offsets are logical. */
.deck-shelf .shelf__item::before {
  content: "";
  position: absolute;
  inset-inline-end: 100%;
  inset-block-start: calc(var(--space-m) + 1.5rem);
  /* Exactly the track gap, so the segment spans it and touches both cards. */
  inline-size: var(--space-m);
  block-size: 1px;
  background-color: var(--line-strong);
}

/* Nothing before the first card to connect to. */
.deck-shelf .shelf__item:first-child::before { content: none; }

/* ---------------------------------------------------------------- the card

   A WHITE CARD, STANDING UP. It was a wide row while the deck ran down the
   page; on a shelf it is a column — the number at the head, the words in the
   middle, the level and the way through at the foot. The 1fr in the middle is
   what keeps every foot on the same line however the titles wrap. */
.folder {
  position: relative;
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-s);
  block-size: 100%;
  min-block-size: 17rem;
  padding: var(--space-m);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  /* One step stronger than the outer layers of --shadow-soft. #F9F9FE on
     #E6E6FA is four percent of lightness apart, so on this ground a card is not
     separated by its colour — it is separated entirely by what it casts. */
  box-shadow:
    inset 0 1px 0 0 var(--edge-lit),
    0 2px 6px -2px var(--cast-2),
    0 20px 40px -14px var(--cast-3);
  overflow: hidden;
  isolation: isolate;
}

.folder__body {
  display: grid;
  align-content: start;
  gap: var(--space-3xs);
  color: var(--ink-soft);
}

/* The level and the way through, on one line at the foot of the card. */
.folder__aside {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
}

.folder__go {
  inline-size: 1.1rem;
  block-size: 1.1rem;
  color: var(--ink-faint);
}

/* Three lines on a standing card — the descriptions run from one sentence to
   three, and a shelf of cards that each stop at a different place reads as a
   row that has not been set. */
.folder__summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  color: var(--ink-soft);
  font-size: 0.9375rem;
  line-height: 1.45;
}

.folder__title {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: 1.375rem;
  line-height: 1.15;
  letter-spacing: var(--tracking-display);
  color: var(--ink);
}

/* The whole card is the link. The anchor is on the title, so the accessible
   name is the module name and nothing else — a wrapper around the card would
   read the number, the summary and the level out as one run-on link. */
.folder__title a {
  text-decoration: none;
  color: inherit;
}

.folder__title a::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* The lit top edge every white object on this page carries. Inset rather than
   a border so it follows the radius, and struck from the whitest paper: this is
   the near edge catching the light, not an outline. */
.folder::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: var(--space-m);
  block-size: 1px;
  background-image: linear-gradient(
    90deg, transparent, var(--edge-lit) 40%, var(--edge-lit) 60%, transparent);
  z-index: 1;
}

.folder::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--sheen);
  opacity: 0;
  pointer-events: none;
  z-index: 1;
}

.folder:hover::after { opacity: 1; }

.folder__tab {
  display: flex;
  align-items: center;
  gap: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  color: var(--ink-faint);
}

/* ----------------------------------------------------------- the lead card

   The deck's one INK object — the discipline of one flood per composition — so
   the track opens on the module the academy opens on, and you can see it is
   different before you have read any of it.

   ONE OBJECT, and it used to be two: the artwork sat in a band across the top
   and the words in an ink block underneath, meeting on a hard line partway
   down. Neither half was the card. The drawing is the card ground now and the
   words stand on it. */
.folder--lead {
  grid-template-rows: 1fr auto;
  padding: 0;
  gap: 0;
  background-color: var(--surface-ink);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-lift-ink);
}

.folder--lead .folder__cover {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  background-image: none;
}

/* THE DRAWING IS TURNED INSIDE OUT IN THE BROWSER. All eight track covers are
   drawn as ink strokes on a paper ground, and this card is ink — so rather than
   draw eight more assets, the one that exists is inverted onto the slab.

   grayscale FIRST, and that ordering is the whole trick: inverting #152717
   channel by channel lands on a pale pink, and this palette has two colours.
   Flattening to luma before the inversion keeps every result on the paper-grey
   axis. Then `screen` drops the near-black ground the inversion produced back
   into the slab, so only the strokes survive — as light. */
.folder--lead .folder__cover--invert img {
  filter: grayscale(1) invert(1);
  mix-blend-mode: screen;
}

/* An ink-ground cover needs no inversion — only the same restraint, so the
   drawing stays a ground for the words rather than competing with them. */
.folder--lead .folder__cover img { opacity: 0.55; }

/* The words sit on the artwork, so they bring their own ground: the slab's own
   colour, opaque under the text and gone before it reaches the middle of the
   card. A scrim rather than a panel — a panel would put the hard line back. */
.folder--lead .folder__body {
  position: relative;
  align-content: end;
  gap: var(--space-2xs);
  padding: var(--space-2xl) var(--space-m) 0;
  color: var(--ink-inverse);
  background-image: linear-gradient(to top, var(--surface-ink) 62%, transparent);
}

.folder--lead .folder__aside {
  position: relative;
  padding: var(--space-s) var(--space-m) var(--space-m);
  background-color: var(--surface-ink);
}

.folder--lead .folder__tab { color: var(--ink-inverse-faint); }
.folder--lead .folder__title { color: var(--ink-inverse); }
.folder--lead .folder__summary { color: var(--ink-inverse-faint); }
.folder--lead .folder__go { color: var(--ink-inverse-faint); }

/* No lit edge and no sheen on the ink card. --edge-lit is a paper highlight and
   --sheen is a specular band built for glass and white paper; swept across an
   ink flood the sheen is a grey smear, and it lands straight over the title. */
.folder--lead::before { background-image: none; }
.folder--lead::after { background-image: none; }

/* The chip on an ink ground is struck from the paper, or it is a hairline
   nobody can find. Stated for both ink surfaces at once, so a chip anywhere in
   the footer slab or the MatchAI island inverts by being there. */
.folder--lead .pill--outline,
.section--ink .pill--outline,
.on-ink .pill--outline {
  border-color: var(--line-inverse);
  color: var(--ink-inverse);
}

.folder__cover {
  display: block;
  aspect-ratio: 4 / 3;
  background-image: var(--gradient-frame);
  overflow: hidden;
}

.folder__cover img,
.folder__cover svg { inline-size: 100%; block-size: 100%; object-fit: cover; }

/* ==========================================================================
   9 — FOUNDERS
   ========================================================================== */

.founder-list { display: grid; gap: var(--space-2xl); }

@media (min-width: 56em) {
  .founder-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-xl); }
  .founder-list > :nth-child(even) { margin-block-start: var(--space-2xl); }
}

.founder { position: relative; }

.founder__art { position: relative; }

/* The disc behind a portrait — the sheet lifted toward white in one round
   patch, which is what a real sheet does under a real light and what makes the
   plate in front of it read as standing off the page. */
.founder__blob {
  position: absolute;
  inset-block-start: -8%;
  inset-inline-start: -12%;
  inline-size: 108%;
  aspect-ratio: 1;
  background-image: var(--glow-bright);
  filter: blur(12px);
  opacity: 0.9;
  pointer-events: none;
  z-index: -1;
}

@media (max-width: 47.99em) {
  /* Constrained below 48em: the overhang pushed 32px of the page off the side
     at 360px, which turned the whole document into a horizontal scroller.
     Measured, not guessed. */
  .founder__blob { inset-inline-start: 0; inline-size: 100%; }
}

/* Capped rather than filling its column: at half of an 82rem container a 4:5
   plate is 640 wide and 800 tall, which made two placeholder portraits the
   largest objects on the page and left the founders' own words beside a wall of
   empty ground. */
/* Mounted the way the comps mount a portrait: a white card with a margin of
   paper showing all the way round the picture. */
.founder__plate {
  position: relative;
  max-inline-size: 24rem;
  aspect-ratio: 4 / 5;
  padding: 0.75rem;
  border-radius: var(--radius-organic);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}

/* Opposite turns, so the two portraits face each other across the gap the way
   the hero's two screens do. Not a scaleX mirror — that flips the monogram and
   would flip a real photograph the moment one arrives. */
@media (min-width: 56em) {
  .founder:nth-child(odd) .founder__plate {
    transform: perspective(var(--persp-near)) rotateY(var(--tilt-a));
  }
  .founder:nth-child(even) .founder__plate {
    transform: perspective(var(--persp-near)) rotateY(var(--tilt-b));
  }
}

/* Quarter strength. At full the diagonal sweep washed the portrait out, and a
   placeholder should be the last thing on the page competing for attention. */
.founder__plate::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: var(--sheen);
  opacity: 0.25;
  pointer-events: none;
  z-index: 2;
}

.founder__plate img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-organic) - 0.75rem);
  background-image: var(--gradient-frame);
}

/* A REAL PORTRAIT, once an admin uploads one in Ekip.

   The plate is 4:5 and an uploaded photograph is whatever shape the client had;
   `object-fit: cover` above already crops it to the frame, and `position: top`
   is what decides which end of the crop survives. Centre is the default and it
   is wrong for a person: on anything taller than 4:5 it takes the middle of the
   body and cuts the top of the head off. Faces sit high in a portrait.

   The sheen comes off. It is a specular band built for glass and drawn cards,
   and swept diagonally across a photograph of a face it reads as a scratch on
   the print rather than as light. */
.founder__plate--photo img {
  object-position: top;
  background-image: none;
}

.founder__plate--photo::after { background-image: none; }

/* The placeholder standing in until the client's portraits arrive. It reads as
   a card with a monogram pressed into it and deliberately not as a person: a
   stock face under a named founder is a lie that ships. */
.founder__initials {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(3rem, 9vw, 5rem);
  letter-spacing: -0.04em;
  color: var(--ink-faint);
  /* Raised from 0.35. On the dark ground this was drawn for, a faint monogram
     still read; on white it disappeared and both plates looked like empty
     glass panels somebody had forgotten to fill. */
  opacity: 0.6;
}

/* THE NAME CARD. The comps pin a small white capsule carrying the person's
   name over the bottom corner of the portrait, and it is a better answer than
   the outsized headline this used to be: it names the person AT the picture
   rather than beside it, it is the same object as every other white card on
   the page, and a drop shadow does the work a text-shadow was doing badly. */
.founder__name {
  position: relative;
  z-index: 2;
  display: inline-block;
  margin-block-start: calc(-1 * var(--space-l));
  margin-inline-start: var(--space-m);
  padding: 0.6rem 1.1rem;
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
  font-size: clamp(1.125rem, 1.8vw, 1.5rem);
  line-height: 1.1;
  letter-spacing: var(--tracking-display);
}

.founder__body { margin-block-start: var(--space-m); }
.founder__role { color: var(--ink-faint); }
.founder__bio { max-inline-size: 38ch; color: var(--ink-soft); }

/* ==========================================================================
   10 — MATCHAI
   ========================================================================== */

.matchai-hero { position: relative; }

.matchai-hero__grid { display: grid; gap: var(--space-xl); align-items: center; }

@media (min-width: 62em) {
  .matchai-hero__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); }
}

/* The pairing, stated a second time: two halves leaning toward each other. */
.two-sided { display: grid; gap: var(--space-m); }

@media (min-width: 56em) {
  .two-sided {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-l);
    perspective: var(--persp);
  }
}

.two-sided__half {
  position: relative;
  padding: var(--space-l);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

/* Inside the ink slab the two halves cannot be white — the slab is the object
   there, and a white card on it would be a second one. They become the ink one
   step lifted, with a paper hairline. */
.section--ink .two-sided__half,
.on-ink .two-sided__half {
  background-color: var(--surface-ink-2);
  box-shadow: inset 0 0 0 1px var(--line-inverse);
}

@media (min-width: 56em) {
  .two-sided__half:first-child { transform: rotateY(var(--tilt-a)); }
  .two-sided__half:last-child { transform: rotateY(var(--tilt-b)); }
}

.two-sided__half::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 3px;
  background-color: var(--ink);
}

.section--ink .two-sided__half::before,
.on-ink .two-sided__half::before { background-color: var(--ink-inverse); }

.two-sided__half li { color: var(--ink-soft); }

.section--ink .two-sided__half li,
.on-ink .two-sided__half li { color: var(--ink-inverse); }

/* --------------------------------------------------------------------- phone */

.phone-stage {
  position: relative;
  display: grid;
  place-items: center;
  perspective: var(--persp-near);
  padding-block: var(--space-l);
}

/* The device, mounted the way the comps mount it: a solid ink body with the
   screen inset, standing off the sheet on a long cast. The bezel is the ink
   rather than a metal gradient — the phone is an object in this palette, not a
   product photograph borrowed into it. */
.phone {
  position: relative;
  inline-size: min(17rem, 62vw);
  aspect-ratio: 9 / 19.5;
  padding: 10px;
  border-radius: var(--radius-screen);
  background-image: var(--gradient-plate);
  box-shadow: var(--shadow-lift), var(--shadow-deep);
  transform: rotateY(var(--tilt-b)) rotateX(2deg);
}

.phone::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: var(--sheen);
  pointer-events: none;
}

.phone__screen {
  inline-size: 100%;
  block-size: 100%;
  border-radius: calc(var(--radius-screen) - 8px);
  overflow: hidden;
  background-color: var(--surface-2);
}

.phone__screen img,
.phone__screen svg { inline-size: 100%; block-size: 100%; object-fit: cover; }

.matchai-stage { position: relative; }

/* ---------------------------------------------------------------- the film

   The one place on this page that actually turns something on, so it gets the
   page's biggest lit plate: 16:9, with the emerald bleeding out from behind it
   and the darkness pooled underneath.

   Square on, and the ONLY object in this room that is. Everything else here is
   turned a few degrees toward the light, but a film is a thing to be looked at
   rather than a thing standing in a room — a rotated player is harder to watch,
   and at a believable angle the turn is too slight to read as a decision anyway.
   The glow does the work the tilt would have done. */
.video-plate {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-card);
  background-color: var(--surface-ink);
  box-shadow: var(--shadow-lift-ink), var(--shadow-deep);
  overflow: hidden;
}

.video-plate__player,
.video-plate iframe {
  display: block;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
  background-color: var(--surface-ink);
}

/* The facade over a third-party embed. It is an anchor, not a button: with script
   off it opens the provider's own page, which is the honest fallback for a player
   we deliberately refuse to load until asked. */
.video-plate__launch {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: 100%;
  text-decoration: none;
  color: var(--ink-inverse);
}

.video-plate__poster {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  opacity: 0.55;
}

.video-plate__play {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: 5.5rem;
  block-size: 5.5rem;
  border: 0;
  border-radius: 50%;
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
}

.video-plate__play .mark {
  inline-size: 1.75rem;
  block-size: 1.75rem;
  color: var(--ink);
  /* Nudged off centre: a filled triangle's optical centre is left of its box. */
  margin-inline-start: 0.25rem;
}

.video-plate__label {
  position: relative;
  margin-block-start: var(--space-s);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}

.video-plate__launch:hover .video-plate__poster { opacity: 0.75; }

.video-plate__note { color: var(--ink-faint); }

.section--ink .video-plate__note,
.on-ink .video-plate__note { color: var(--ink-inverse-faint); }

/* ==========================================================================
   11 — RESULTS

   The gallery page runs SIDEWAYS. There will eventually be a great many proofs,
   and a vertical grid answers that badly: everything is the same size, so
   nothing is a highlight, and the page has no end anyone reaches.

   The shelf is native overflow with CSS snap. Script adds two arrows and nothing
   else — remove it and the shelf still scrolls with a trackpad, a finger, or the
   arrow keys once the container has focus.
   ========================================================================== */

/* Full bleed, because a shelf that stops at the text column does not read as
   longer than the window. The gutters keep the first and last card in line with
   the container above it, so the shelf is wider without being unaligned.

   margin-inline of a negative half-viewport rather than `100vw` width: this one
   composes with the section's own padding instead of fighting it, and it is the
   arrangement that survives a scrollbar being present. */
.shelf {
  /* The gutter has to be the container's OWN edge, which is the page margin plus
     the container's padding — not just the page margin. Measured with only the
     first: the shelf started 64px outboard of the heading above it, which reads
     as a misalignment rather than as a bleed. */
  --shelf-gutter: var(--space-m);
  --shelf-inset: calc(max(0px, 50vw - var(--container) / 2) + var(--shelf-gutter));

  margin-inline: calc(50% - 50vw);
  padding-inline: var(--shelf-inset);
  padding-block: var(--space-s);
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-inline-start: var(--shelf-inset);
  /* The scrollbar is a system control; left alone it draws a grey slab across
     the bottom of the shelf that belongs to no palette on this page. */
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}

/* The shelf takes keyboard focus — a scroll container holding only links cannot be
   reached or scrolled by keyboard otherwise — so it must show that it has it. */
@media (min-width: 40em) {
  .shelf { --shelf-gutter: var(--space-xl); }
}

.shelf:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: -2px;
}

.shelf__track {
  display: flex;
  align-items: flex-start;
  gap: var(--space-m);
  inline-size: max-content;
  padding: 0;
  margin: 0;
  list-style: none;
}

.shelf__item {
  scroll-snap-align: start;
  inline-size: min(19rem, 74vw);
  flex: 0 0 auto;
}

/* The head: what is on the shelf, and the two arrows that move it. */
.shelf-head {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  margin-block-end: var(--space-xs);
}

.shelf-head__count { color: var(--ink-faint); }

.shelf-head__count .numeric {
  color: var(--ink);
  font-size: 1.125rem;
  margin-inline-end: var(--space-3xs);
}

.shelf-head__of { text-transform: uppercase; letter-spacing: var(--tracking-meta); }

/* Hidden by default and shown only under `.js`, the same contract the menu
   toggle keeps: these two do nothing without script, and a dead control is
   worse than no control. The shelf itself never depends on them. */
.shelf-head__nav { display: none; }

.js .shelf-head__nav {
  display: flex;
  gap: var(--space-2xs);
  margin-inline-start: auto;
}

.shelf-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border: 0;
  border-radius: 50%;
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  color: var(--ink);
  cursor: pointer;
}

.shelf-btn:hover { background-color: var(--ink); color: var(--ink-inverse); }

.shelf-btn[disabled] { opacity: 0.35; cursor: default; }

.shelf-btn[disabled]:hover { background-color: var(--surface-2); color: var(--ink); }

.shelf-btn .mark { inline-size: 1.125rem; block-size: 1.125rem; }

/* ---------------------------------------------------------------- the plate */

.result-card { position: relative; }

.result-card__plate {
  position: relative;
  display: block;
  padding: 0.5rem;
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  text-decoration: none;
  color: inherit;
}

/* 4 : 5 rather than 9 : 16. A result is as likely to be a dashboard as a phone
   capture, and the taller crop throws away the half of a dashboard that carries
   the number. The uncropped file is one click away in the lightbox. */
.result-card__frame {
  display: block;
  aspect-ratio: 4 / 5;
  border-radius: calc(var(--radius-card) - 0.5rem);
  background-image: var(--gradient-frame);
  overflow: hidden;
}

.result-card__frame img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
}

/* The lit edge every panel in this room has, masked so it only draws along the
   two sides facing the light. */
.result-card__plate::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 1px solid var(--line-strong);
  opacity: 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(150deg, black 0 28%, transparent 62%);
  mask-image: linear-gradient(150deg, black 0 28%, transparent 62%);
}

.result-card__plate:hover::before,
.result-card__plate:focus-visible::before { opacity: 1; }

/* The tag pinned to a proof — the composition's one flood, the same object as
   the icon tile and the primary button. */
.result-card__tag {
  position: absolute;
  inset-block-start: var(--space-s);
  inset-inline-start: var(--space-s);
}

.result-card__body { padding: var(--space-s) var(--space-2xs) var(--space-2xs); }

.result__title {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: 1.125rem;
  line-height: 1.25;
  letter-spacing: var(--tracking-display);
}

.result-card__note {
  margin-block-start: var(--space-3xs);
  font-size: 0.9375rem;
}

/* The pinboard: screens pinned to the studio wall, each at its own small turn. */
.pinboard {
  display: grid;
  gap: var(--space-l);
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  /* The board is the answer to the question the copy above it asks, so it needs
     to read as a separate breath rather than as the next line of that
     paragraph. It was sitting 8px under the "see all" button — close enough
     that the first row looked attached to the control. */
  margin-block-start: var(--space-2xl);
}

@media (min-width: 48em) {
  .pinboard { perspective: var(--persp); }
}

.pin {
  position: relative;
  padding: var(--space-2xs) var(--space-2xs) var(--space-m);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
}

@media (min-width: 48em) {
  .pin:nth-child(3n + 1) { transform: rotateY(var(--tilt-b)); }
  .pin:nth-child(3n + 2) { transform: rotateY(var(--tilt-a)); }
  .pin:nth-child(3n + 3) { transform: rotateY(var(--tilt-c)); }
}

/* The tape. The one piece of physical vocabulary the studio idea inherits
   honestly — screens do get taped to a wall. */
.pin::before {
  content: "";
  position: absolute;
  inset-block-start: calc(-1 * var(--space-2xs));
  inset-inline-start: 50%;
  inline-size: 3.5rem;
  block-size: 1.1rem;
  translate: -50% 0;
  rotate: var(--stamp-tilt);
  background-color: var(--surface-dim);
  border-radius: 3px;
  opacity: 0.85;
}

.pin img,
.pin svg {
  inline-size: 100%;
  border-radius: calc(var(--radius-card) - 0.5rem);
  background-image: var(--gradient-frame);
}

/* Two lines, always. The admin writes these and they run from three words to a
   full sentence; unclamped, one long title makes its row taller than the three
   cards beside it and the board stops looking set. */
.pin__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-block-start: var(--space-s);
  padding-inline: var(--space-2xs);
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: 1.0625rem;
  line-height: 1.25;
  letter-spacing: var(--tracking-display);
}

.pin__meta {
  padding-inline: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-faint);
}

.masonry { columns: 1; column-gap: var(--space-m); }

@media (min-width: 40em) { .masonry { columns: 2; } }
@media (min-width: 64em) { .masonry { columns: 3; } }

.masonry > * { break-inside: avoid; margin-block-end: var(--space-m); }

/* ==========================================================================
   12 — STATS
   ========================================================================== */

.stat-strip { position: relative; display: grid; gap: var(--space-l); }

/* auto-fit, not `repeat(4, ...)`. The figures are rows in a table an admin adds
   to and deletes from — "Yeni istatistik" is a button in the panel — so a fixed
   four left a hole in the row the moment the client asked for one of them to go.
   The floor is what keeps it honest at the other end: a figure set at 6rem needs
   room, so a long list wraps to a second line rather than shrinking to fit. */
@media (min-width: 48em) {
  .stat-strip {
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--space-m);
  }
}

.stat-strip__heading { grid-column: 1 / -1; max-inline-size: 22ch; }

/* Four figures on the sheet with a rule over each — not four cards. The white
   card is spent on things you can act on: a module, a proof, a question. A
   statistic is a fact printed on the page, and giving it an object would make
   the page a wall of identical boxes. */
.stat {
  position: relative;
  padding: var(--space-m) var(--space-s);
  border-block-start: 1px solid var(--ink);
}

.stat__value {
  display: block;
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(2.75rem, 6vw, 4.5rem);
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}

/* The lead figure carries the claim, so it is the one that is bigger and the
   only one whose rule is drawn heavy. Hierarchy through size and weight of
   rule, because there is no second colour to spend on it — which is the
   constraint this whole design is built out of. */
.stat--lead {
  border-block-start-width: 4px;
}

.stat--lead .stat__value {
  font-size: clamp(3.5rem, 8vw, 6rem);
}

.stat__label {
  display: block;
  margin-block-start: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ==========================================================================
   13 — FAQ
   ========================================================================== */

.accordion { display: grid; gap: var(--space-2xs); }

.accordion__item {
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.accordion__item[open] { box-shadow: var(--shadow-lift); }

.accordion__trigger {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  inline-size: 100%;
  padding: var(--space-m);
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-strong);
  font-size: 1.125rem;
  line-height: 1.3;
  letter-spacing: -0.015em;
  text-align: start;
  list-style: none;
  cursor: pointer;
}

.accordion__trigger::-webkit-details-marker { display: none; }

.accordion__icon {
  margin-inline-start: auto;
  inline-size: 1rem;
  block-size: 1rem;
  flex: none;
  color: var(--ink);
}

.accordion__item[open] .accordion__icon { rotate: 45deg; }

.accordion__body { padding: 0 var(--space-m) var(--space-m); color: var(--ink-soft); }

/* ==========================================================================
   14 — MODULE PAGES
   ========================================================================== */

.module-list { display: grid; gap: var(--space-s); }

@media (min-width: 62em) {
  .module-list { perspective: var(--persp); perspective-origin: 30% 50%; }
}

.module-entry {
  position: relative;
  display: grid;
  gap: var(--space-m);
  padding: var(--space-s);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  text-decoration: none;
  overflow: hidden;
}

@media (min-width: 48em) {
  .module-entry { grid-template-columns: 12rem minmax(0, 1fr) auto; align-items: center; }
}

/* Half the deck's angle. These rows are the full width of the container, and a
   7° turn across 1300px throws one end of the row a long way further from the
   reader than the other — the title starts at one size and finishes at another,
   which reads as a rendering fault rather than as depth. The narrow cards in
   the home page's deck can carry the full turn because they are half as wide. */
@media (min-width: 62em) {
  .module-entry:nth-child(odd) { transform: rotateY(calc(var(--tilt-b) * 0.45)); }
  .module-entry:nth-child(even) {
    transform: rotateY(calc(var(--tilt-a) * 0.45)) translateZ(calc(-1 * var(--depth-1)));
  }
}

.module-entry:hover { box-shadow: var(--shadow-lift); }

/* The row's text column. Without this the four paragraphs inside it collapsed
   onto each other — base.css zeroes every margin on purpose, so a block that
   needs rhythm has to ask for it. */
.module-entry__body { display: grid; gap: var(--space-2xs); align-content: center; }

.module-entry__frame {
  aspect-ratio: 16 / 10;
  border-radius: calc(var(--radius-card) - var(--space-s));
  background-image: var(--gradient-frame);
  overflow: hidden;
}

.module-entry__frame img,
.module-entry__frame svg { inline-size: 100%; block-size: 100%; object-fit: cover; }

.module-entry__meta {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* An empty span used as a separator between the level and the topic count. */
.module-entry__dot {
  inline-size: 3px;
  block-size: 3px;
  border-radius: 50%;
  background-color: var(--ink-faint);
  flex: none;
}

.module-entry__title {
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: var(--text-title);
  line-height: 1.2;
  letter-spacing: var(--tracking-display);
}

.module-entry__title a { text-decoration: none; }

/* The whole row is one click target, without nesting interactive elements or
   repeating the href on a wrapper. */
.module-entry__title a::after { content: ""; position: absolute; inset: 0; }

/* The module's ordinal — "M-01" — not an icon. It was sized as one (1.25rem
   square) and clipped the label to "M-". */
.module-entry__edge {
  color: var(--ink-faint);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
}

.module-entry__summary { color: var(--ink-soft); max-inline-size: 60ch; }

/* A cover whose artwork wants the whitest paper under it rather than the
   tinted plate the rest of the frames carry. */
.frame--light { background-color: var(--screen-white); }

/* And its opposite: covers 02, 05 and 08 are drawn on an ink ground, so the
   plate behind them is ink too. Without it a rounded frame shows a sliver of
   pale paper along the corners of a dark drawing, which reads as a rendering
   fault rather than as a frame. */
.frame--ink {
  background-color: var(--surface-ink);
  box-shadow: var(--shadow-soft-ink);
}

.module-list__foot { margin-block-start: var(--space-l); }

.module-head__grid { display: grid; gap: var(--space-l); }

@media (min-width: 56em) {
  .module-head__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 0.8fr); align-items: center; }
}

.module-head__title {
  font-size: var(--text-display);
  line-height: var(--leading-display);
  letter-spacing: var(--tracking-display);
}

.module-head__cover {
  aspect-ratio: 4 / 3;
  padding: 0.6rem;
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
  transform: perspective(var(--persp-near)) rotateY(var(--tilt-b));
}

.module-head__cover img,
.module-head__cover svg {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-card) - 0.6rem);
  background-image: var(--gradient-frame);
}

.module-body { max-inline-size: 68ch; }

.topic-list { display: grid; gap: var(--space-2xs); }

.topic {
  display: flex;
  gap: var(--space-s);
  align-items: baseline;
  padding-block: var(--space-2xs);
  border-block-end: 1px solid var(--line);
  color: var(--ink-soft);
}

.topic::before {
  content: "";
  inline-size: var(--index-mark);
  block-size: var(--index-mark);
  flex: none;
  background-color: var(--ink);
  translate: 0 -0.15em;
}

.module-nav { margin-block-start: var(--space-2xl); }

.module-nav__grid { display: grid; gap: var(--space-s); }

@media (min-width: 48em) {
  .module-nav__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.module-nav__link {
  display: grid;
  gap: var(--space-3xs);
  padding: var(--space-m);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  text-decoration: none;
}

.module-nav__link:hover { box-shadow: var(--shadow-lift); }

.module-nav__link--next { text-align: end; }

/* ==========================================================================
   15 — CONTACT
   ========================================================================== */

.contact__grid { display: grid; gap: var(--space-xl); }

@media (min-width: 56em) {
  .contact__grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr); gap: var(--space-2xl); }
}

.contact-form {
  display: grid;
  gap: var(--space-m);
  padding: var(--space-l);
  border-radius: var(--radius-card);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-lift);
}

.contact-aside { display: grid; gap: var(--space-m); align-content: start; }

/* ==========================================================================
   16 — ODDS AND ENDS
   ========================================================================== */

.prose--page { max-inline-size: 70ch; }

/* Tone blocks are not blocks of colour — a flat rectangle behind content is a
   patch on the sheet. They are the sheet itself, lifted toward white in one
   place and dropped toward the ink in another, which is what a real sheet
   under a real light does. */
.tone-block {
  position: absolute;
  z-index: -1;
  pointer-events: none;
  border-radius: var(--radius-organic);
  filter: blur(24px);
}

.tone-block--a {
  inset-block-start: -12%;
  inset-inline-end: -6%;
  inline-size: min(34rem, 60%);
  aspect-ratio: 1;
  background-image: var(--blob-bright);
}

.tone-block--b {
  inset-block-end: -16%;
  inset-inline-start: -8%;
  inline-size: min(28rem, 55%);
  aspect-ratio: 1;
  background-image: var(--blob-dim);
}

.tone-block--c {
  inset-block-start: 18%;
  inset-inline-start: 32%;
  inline-size: min(22rem, 45%);
  aspect-ratio: 1;
  background-image: var(--blob-bright);
}

.tone-block--tint {
  inset-block-start: 8%;
  inset-inline-end: 10%;
  inline-size: min(18rem, 45%);
  aspect-ratio: 1;
  background-image: var(--blob-accent);
}

@media (max-width: 47.99em) {
  /* Same measurement as .founder__blob: 32px of horizontal overflow at 360px
     before these were constrained. */
  .tone-block { inset-inline: auto; inline-size: min(18rem, 80vw); }
}

/* The outline word drifting behind a section. -webkit-text-stroke rather than
   a fill, so it reads as an engraved plate rather than as pale text — and at
   this size a fill, at any strength, competes with the headline in front of
   it. */
.ghost-word {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: 0;
  translate: 0 -50%;
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(6rem, 18vw, 16rem);
  line-height: 0.85;
  letter-spacing: -0.05em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line);
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
  /* 0, not -1. A negative z-index paints the element behind the BACKGROUND of
     its nearest stacking context, and the ink slab has one — so the engraved
     word was being drawn underneath the very block it is engraved into and was
     invisible on the page. At 0 it sits above the slab and below .container,
     which follows it in the markup and therefore paints later. */
  z-index: 0;
}

/* On the ink slab the stroke has to be struck from the paper. --line is the ink
   at 12%, which on #152717 is nothing at all — the MatchAI island's own name was
   engraved into it in a colour one step from the slab and could not be seen. */
.section--ink .ghost-word,
.on-ink .ghost-word { -webkit-text-stroke-color: var(--line-inverse); }

.empty-state {
  display: grid;
  gap: var(--space-2xs);
  padding: var(--space-2xl) var(--space-m);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-card);
  text-align: center;
  color: var(--ink-faint);
}

.empty-state__line { max-inline-size: 46ch; margin-inline: auto; }

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-m);
  margin-block-start: var(--space-xl);
}

.pager__readout {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: var(--tracking-meta);
  color: var(--ink-faint);
}

.social-list { display: flex; flex-wrap: wrap; gap: var(--space-2xs); }

.social-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  padding: 0.5rem 0.9rem;
  border: 0;
  border-radius: var(--radius-pill);
  background-color: var(--surface-2);
  box-shadow: var(--shadow-soft);
  text-decoration: none;
  font-size: 0.8125rem;
}

.social-link:hover { background-color: var(--ink); color: var(--ink-inverse); }

/* Inside the footer slab the chips are the ink one step lifted, not white:
   four white capsules on a dark block would be the brightest thing on the
   page, sitting under the copyright line. */
.section--ink .social-link,
.on-ink .social-link {
  background-color: var(--surface-ink-2);
  box-shadow: inset 0 0 0 1px var(--line-inverse);
  color: var(--ink-inverse);
}

.section--ink .social-link:hover,
.on-ink .social-link:hover {
  background-color: var(--ink-inverse);
  color: var(--ink);
}

.social-link__icon { inline-size: 1rem; block-size: 1rem; }

.social-link__badge {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: var(--tracking-meta);
  color: inherit;
  opacity: 0.6;
}

.icon-sprite { display: none; }
.icon--directional { flex: none; }

/* Scroll reveal. Every rule is `.js `-scoped, so with JavaScript off nothing is
   ever hidden — the inversion this whole site's progressive enhancement rests
   on: a thing may only be hidden where something is guaranteed to show it
   again. The class site.js adds is `.is-visible`, and it also adds it to every
   target outright when IntersectionObserver is unavailable. */
/* NOTHING is declared here. The hidden state lives in motion.css, inside the
   prefers-reduced-motion guard, so a visitor who asked for less motion is given
   a finished page rather than one whose lower half is transparent until an
   observer they cannot see gets round to it. Measured: with the rule here, nine
   blocks sat at opacity 0 under reduced motion. */

/* The hero curtain. site.js measures where the browser broke the headline,
   wraps each rendered line in a clipped block, and motion.css slides the text
   up out from behind it. `.is-settled` releases the masks once every line has
   arrived, so a later resize cannot clip a rewrapped line in half. */
.hero__title .line { display: block; overflow: hidden; }
.hero__title.is-settled .line { overflow: visible; }

/* The staircase: lines two and three step in behind the first. Applied to the
   split lines only, so an unscripted heading is a plain flush setting rather
   than a staircase with no steps. */
@media (min-width: 48em) {
  .hero__title.is-split .line:nth-child(2) { padding-inline-start: 4%; }
  .hero__title.is-split .line:nth-child(n + 3) { padding-inline-start: 8%; }
}

/* ==========================================================================
   17 — FOOTER
   ========================================================================== */

/* THE FOOTER SLAB. The page's closing object: a block of ink lying on the
   sheet with its top corners cut, so the paper is still visible either side of
   it and it reads as the last card rather than as the page turning dark.

   The comps do exactly this, and it is the detail that stops a long page from
   ending on a hard horizon. */
.site-footer {
  position: relative;
  margin-block-start: var(--space-2xl);
  margin-inline: var(--space-m);
  padding-block: var(--space-2xl) var(--space-l);
  border-start-start-radius: var(--radius-slab);
  border-start-end-radius: var(--radius-slab);
  background-color: var(--surface-ink);
  color: var(--ink-inverse);
  box-shadow: var(--shadow-lift-ink);
  overflow: hidden;
  view-transition-name: site-footer;
}

@media (min-width: 64em) {
  .site-footer { margin-inline: var(--space-xl); }
}

/* Everything inside the slab takes the paper family. Same inversion as
   .section--ink, and it has to be restated because the footer is not one. */
.site-footer .text-meta,
.site-footer .eyebrow { color: var(--ink-inverse-faint); }

.footer__mega-wrap { position: relative; }

.footer__ghost {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: -2%;
  translate: 0 -50%;
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(5rem, 15vw, 13rem);
  line-height: 0.8;
  letter-spacing: -0.05em;
  color: transparent;
  -webkit-text-stroke: 1px var(--line-inverse);
  /* Half strength. At full the outline ran straight through the closing call to
     action set on top of it and the two competed at the same weight; this is a
     texture behind the page's last sentence, not a second headline. */
  opacity: 0.45;
  white-space: nowrap;
  pointer-events: none;
  user-select: none;
}

.footer__mega {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding-block-end: var(--space-m);
  border-block-end: 1px solid var(--line-inverse);
  font-family: var(--font-display);
  font-stretch: var(--display-width);
  font-weight: var(--weight-display);
  font-size: clamp(2rem, 6vw, 4.5rem);
  line-height: 1;
  letter-spacing: var(--tracking-hero);
  text-decoration: none;
}

.footer__mega-arrow {
  margin-inline-start: auto;
  inline-size: 1.6rem;
  block-size: 1.6rem;
  color: var(--ink-inverse);
  flex: none;
}

.footer__brand { display: grid; gap: var(--space-2xs); }

.footer__description {
  max-inline-size: 40ch;
  color: var(--ink-inverse-faint);
  font-size: 0.875rem;
}

.footer__heading {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--ink-inverse-faint);
  margin-block-end: var(--space-2xs);
}

.footer__links { display: grid; }

/* The prose face, for the same reason the navigation uses it: these are
   links, which are language, and the mono is this site's label voice.

   padding-block, because measured at 390px these rows were 19px tall — six
   links stacked four pixels apart, which on a thumb is one target. */
.footer__links a {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  padding-block: 0.35rem;
  color: var(--ink-inverse-faint);
  text-decoration: none;
}

.footer__links a:hover { color: var(--ink-inverse); }

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s) var(--space-m);
  align-items: baseline;
  margin-block-start: var(--space-l);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--line-inverse);
}

.footer__copyright,
.footer__disclaimer { font-size: 0.75rem; color: var(--ink-inverse-faint); }

.footer__disclaimer { max-inline-size: 60ch; }

.final-cta { position: relative; }
