/* ============================================================================
   MAKİNE — public stylesheet.

   Design language: CALIBRATION.
   A machine is sold on measurement. Every recurring device here is an
   instrument: the page edge is a caliper, section headings carry dimension
   lines with real catalogue data, images resolve from draft to finished
   plate. Nothing decorative repeats — if a mark appears twice it is because
   it is measuring something.

   Contract with the JS layer:
     [data-enter]        animates in once on entering the viewport
     [data-enter-group]  children stagger
     .is-in              added by JS when the element has entered
     html.js             set inline in <head>; everything is visible without it
   ========================================================================= */

/* ============================================================================
   1. Layout primitives
   ========================================================================= */

.container {
  inline-size: min(100% - var(--gutter) * 2, var(--container));
  margin-inline: auto;
}

.container--narrow { max-inline-size: var(--container-narrow); }

/* On wide screens the caliper rail owns the leading edge, so content is
   pushed off it rather than sitting underneath. */
@media (min-width: 80em) {
  .container {
    inline-size: min(100% - var(--gutter) * 2 - var(--rail-w), var(--container));
    margin-inline-start: max(var(--rail-w), (100% - var(--container)) / 2);
  }
}

.band {
  position: relative;
  padding-block: var(--section-block);
  isolation: isolate;
}

.band--tight { padding-block: clamp(3rem, 4vw, 4.5rem); }

.band--dark {
  background: var(--surface-dark);
  color: var(--text-on-dark);
}

.band--dark-alt {
  background: var(--surface-dark-alt);
  color: var(--text-on-dark);
}

.band--light {
  background: var(--surface-light);
  color: var(--text-on-light);
}

.band--fog {
  background: var(--surface-light-alt);
  color: var(--text-on-light);
}

/* A hairline seam wherever two bands of the same family meet. */
.band--seam { border-block-start: var(--hairline) solid var(--line); }
.band--seam-light { border-block-start: var(--hairline) solid var(--line-light); }

.stack > * + * { margin-block-start: var(--space-4); }

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  inset-block-start: var(--space-3);
  inset-inline-start: var(--space-3);
  z-index: 100;
  padding: var(--space-3) var(--space-5);
  background: var(--flame-500);
  color: var(--text-on-flame);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  transform: translateY(-200%);
  transition: transform var(--dur-micro) var(--ease-micro);
}

.skip-link:focus-visible { transform: translateY(0); }

/* ============================================================================
   2. Typography
   ========================================================================= */

.display-1 { font-size: var(--t-hero); }
.display-2 { font-size: var(--t-h2); }
.display-3 { font-size: var(--t-h3); }

.display-1,
.display-2 { font-variation-settings: "wdth" var(--display-width-wide); }

.lead {
  font-size: var(--t-lead);
  line-height: var(--leading-snug);
  max-inline-size: 46ch;
}

.band--dark .lead,
.band--dark-alt .lead { color: var(--text-on-dark-muted); }

.band--light .lead,
.band--fog .lead { color: var(--text-on-light-muted); }

.prose { max-inline-size: var(--measure); }
.prose > * + * { margin-block-start: var(--space-4); }
.prose h2, .prose h3 { margin-block-start: var(--space-7); font-size: var(--t-h3); }
.prose li { position: relative; padding-inline-start: var(--space-5); }

.prose li::before {
  content: "";
  position: absolute;
  inset-block-start: 0.72em;
  inset-inline-start: 0;
  inline-size: var(--space-3);
  block-size: var(--hairline);
  background: var(--flame-500);
}

.prose ul > li + li,
.prose ol > li + li { margin-block-start: var(--space-2); }

/* The mono utility face carries every measured value on the site. */
.cap {
  font: 500 var(--t-cap) / 1.3 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
}

.eyebrow {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--flame-500);
}

.eyebrow::before {
  content: "";
  inline-size: var(--space-6);
  block-size: var(--hairline);
  background: currentColor;
  flex: none;
}

.muted { color: var(--text-on-light-muted); }
.band--dark .muted { color: var(--text-on-dark-muted); }

/* ============================================================================
   3. Calibration language — the signature devices
   ========================================================================= */

/* --- 3a. The caliper rail --------------------------------------------------
   A fixed measuring edge. Ticks are the scale; the markers on it sit at each
   section's true position in the document, so the rail maps the page rather
   than merely reporting progress through it. */

.rail {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: var(--rail-w);
  z-index: var(--z-rail);
  pointer-events: none;
  display: none;
  color: var(--fume-500);
}

@media (min-width: 80em) {
  .js .rail { display: block; }
}

/* The rail crosses both dark and light bands; JS reports which. */
.rail[data-ground="dark"] { color: var(--fume-600); }

/* The scale hugs the content edge so the jaw reads as measuring the page,
   and the readout has the whole rail width to its left to sit in. */
.rail__scale {
  position: absolute;
  inset-block: calc(var(--header-h) + var(--space-6)) var(--space-8);
  inset-inline-start: calc(var(--rail-w) - 14px);
  inline-size: 1px;
  background: currentColor;
  opacity: 0.55;
}

/* Millimetric ticks: minor every 8px, major every 40px. */
.rail__scale::before {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 1px;
  inline-size: 5px;
  background: repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 8px);
  opacity: 0.55;
}

.rail__scale::after {
  content: "";
  position: absolute;
  inset-block: 0;
  inset-inline-start: 1px;
  inline-size: 11px;
  background: repeating-linear-gradient(to bottom, currentColor 0 1px, transparent 1px 40px);
}

/* Section markers — appended to the scale, so they are offset from the scale
   line itself rather than from the rail. */
.rail__mark {
  position: absolute;
  inset-inline-start: -4px;
  inline-size: 9px;
  block-size: 9px;
  margin-block-start: -4px;
  border: 1px solid currentColor;
  background: var(--surface-light);
  transform: rotate(45deg);
  transition: background-color var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

.rail[data-ground="dark"] .rail__mark { background: var(--surface-dark); }

.rail__mark[data-passed="true"] {
  background: var(--flame-500);
  border-color: var(--flame-500);
}

/* The caliper jaw: the moving read-head. */
.rail__jaw {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  inline-size: var(--rail-w);
  will-change: transform;
}

.rail__jaw::before {
  content: "";
  position: absolute;
  inset-inline-start: calc(var(--rail-w) - 26px);
  inline-size: 26px;
  block-size: 2px;
  background: var(--flame-500);
  box-shadow: 0 0 12px rgb(255 107 18 / 0.5);
}

/* The readout hangs off the jaw on the outboard side, right up against the
   scale, so it can never reach into the content column. */
.rail__readout {
  position: absolute;
  inset-inline: 0 22px;
  inset-block-start: 8px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  text-align: end;
  font: 500 var(--t-cap-sm) / 1.25 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.rail__index {
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The section name needs room the narrow rail does not have, so it only
   appears once the layout has widened the rail to hold it. */
.rail__label {
  display: none;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-on-light-muted);
}

.rail[data-ground="dark"] .rail__label { color: var(--fume-200); }

@media (min-width: 100em) {
  :root { --rail-w: 9.5rem; }
  .rail__label { display: block; }
}

/* --- 3b. Dimension lines ---------------------------------------------------
   Always carries a real value from the catalogue or the company record.
   Never an invented number. */

.dim {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

.band--dark .dim,
.band--dark-alt .dim { color: var(--fume-500); }

.dim__rule {
  position: relative;
  flex: 1 1 auto;
  min-inline-size: 2.5rem;
  max-inline-size: 12rem;
  block-size: 1px;
  background: currentColor;
  transform-origin: left center;
}

/* Arrowheads, the way a drawing marks a span. */
.dim__rule::before,
.dim__rule::after {
  content: "";
  position: absolute;
  inset-block-start: 50%;
  inline-size: 5px;
  block-size: 5px;
  border-block-start: 1px solid currentColor;
  border-inline-start: 1px solid currentColor;
}

.dim__rule::before {
  inset-inline-start: 0;
  transform: translateY(-50%) rotate(-45deg);
}

.dim__rule::after {
  inset-inline-end: 0;
  transform: translateY(-50%) rotate(135deg);
}

.dim__value {
  flex: none;
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.dim--tight .dim__rule { max-inline-size: 4rem; }

.js .dim[data-enter]:not(.is-in) .dim__rule { transform: scaleX(0); }
.js .dim .dim__rule { transition: transform 520ms var(--ease-entry) 120ms; }

/* --- 3c. Plates: draft resolving to finished ------------------------------
   Product imagery arrives as a draft — grid overlaid, flattened — and a
   calibration sweep passes over it, after which the finished plate remains.
   Only opacity and transform move. */

/* block, explicitly: on the home page the plate is an <a>, and an inline box
   ignores aspect-ratio and overflow both. It took photographs of real machines
   to expose that — the placeholder artwork was all one shape, so the box
   happened to match whatever it contained. */
.plate {
  display: block;
  position: relative;
  overflow: hidden;
  background: var(--fume-800);
  isolation: isolate;
}

.band--light .plate,
.band--fog .plate { background: var(--white); }

.plate > img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform 600ms var(--ease-entry);
}

.plate__draft {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(to right, var(--grid) 1px, transparent 1px) 0 0 / 28px 28px,
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px) 0 0 / 28px 28px,
    rgb(18 19 22 / 0.55);
  opacity: 0;
  transition: opacity 450ms var(--ease-entry);
}

.band--light .plate__draft,
.band--fog .plate__draft {
  background:
    linear-gradient(to right, var(--draft-light) 1px, transparent 1px) 0 0 / 28px 28px,
    linear-gradient(to bottom, var(--draft-light) 1px, transparent 1px) 0 0 / 28px 28px,
    rgb(241 242 244 / 0.72);
}

/* Before entry the plate is a draft. Without JS the draft never appears. */
.js .plate[data-plate]:not(.is-in) .plate__draft { opacity: 1; }

.plate__sweep {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 40%;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    to right,
    transparent,
    rgb(255 154 82 / 0.06) 45%,
    var(--flame-500) 50%,
    rgb(255 154 82 / 0.06) 55%,
    transparent
  );
  opacity: 0;
  transform: translateX(-120%);
}

.js .plate[data-plate].is-in .plate__sweep {
  animation: plate-sweep 720ms var(--ease-entry) forwards;
}

@keyframes plate-sweep {
  0%   { opacity: 0; transform: translateX(-120%); }
  12%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { opacity: 0; transform: translateX(320%); }
}

/* Register brackets, as on a drawing sheet. */
.plate__mark {
  position: absolute;
  z-index: 4;
  inline-size: 14px;
  block-size: 14px;
  border: 1px solid var(--flame-500);
  opacity: 0.75;
  pointer-events: none;
}

.plate__mark--tl {
  inset-block-start: 10px;
  inset-inline-start: 10px;
  border-inline-end: 0;
  border-block-end: 0;
}

.plate__mark--br {
  inset-block-end: 10px;
  inset-inline-end: 10px;
  border-inline-start: 0;
  border-block-start: 0;
}

/* Sheet number, like a drawing's part code. */
.plate__code {
  position: absolute;
  z-index: 4;
  inset-block-end: 0;
  inset-inline-start: 0;
  padding: var(--space-2) var(--space-3);
  background: var(--flame-500);
  color: var(--text-on-flame);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
}

/* --- 3d. Object plates: matted machines on a studio ground -----------------
   The product frames were shot on white paper and arrive here matted off it,
   so the plate has to supply a ground of its own. It is a pale sweep rather
   than the band colour, for a reason that is worth writing down: the matte
   deliberately stops at the paper and leaves the machine's cast shadow in the
   file. Any rule loose enough to follow that shadow down to its core also
   walks straight through a stainless lid, which is the same neutral grey —
   tried, and it hollowed the DS-1500 out. On a near-white ground the leftover
   shadow reads as exactly what it is.

   contain, not cover: these are whole machines, and cropping a millimetre off
   a machine to fill a box is the one thing a catalogue must not do. */

.plate--object { background: var(--studio); }

.band--light .plate--object,
.band--fog .plate--object { background: var(--studio); }

.plate--object > img {
  object-fit: contain;
  padding: 7%;
  transform: none;
}

.card:hover .plate--object > img { transform: scale(1.04); }

/* --- 3d. Technical ground grid -------------------------------------------- */

.ground {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to right, var(--grid) 1px, transparent 1px) 0 0 / 96px 96px,
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px) 0 0 / 96px 96px;
  opacity: 0.5;
  mask-image: radial-gradient(120% 90% at 18% 0%, #000 22%, transparent 72%);
}

.band--light .ground,
.band--fog .ground {
  background:
    linear-gradient(to right, var(--grid-light) 1px, transparent 1px) 0 0 / 96px 96px,
    linear-gradient(to bottom, var(--grid-light) 1px, transparent 1px) 0 0 / 96px 96px;
}

/* ============================================================================
   4. Buttons and links
   ========================================================================= */

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-6);
  min-block-size: 2.875rem;
  border: var(--hairline) solid transparent;
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  /* Labels are short by design; a wrapped button is a layout bug, not a
     long label, so it should show up as overflow rather than reflow. */
  white-space: nowrap;
  transition: color var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro),
              background-color var(--dur-micro) var(--ease-micro);
}

.btn svg { flex: none; }

.btn__arrow { transition: transform var(--dur-micro) var(--ease-micro); }
.btn:hover .btn__arrow { transform: translateX(3px); }

.btn--primary {
  background: var(--flame-500);
  color: var(--text-on-flame);
  border-color: var(--flame-500);
}

.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--flame-300);
  border-color: var(--flame-300);
}

.btn--ghost {
  color: inherit;
  border-color: var(--line-strong);
}

.band--light .btn--ghost,
.band--fog .btn--ghost,
.card .btn--ghost { border-color: var(--line-light-strong); }

.btn--ghost:hover,
.btn--ghost:focus-visible {
  color: var(--flame-500);
  border-color: var(--flame-500);
}

.btn--sm {
  padding: var(--space-3) var(--space-4);
  min-block-size: 2.375rem;
  font-size: var(--t-cap-sm);
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  padding-block-end: var(--space-2);
  border-block-end: var(--hairline) solid currentColor;
  transition: color var(--dur-micro) var(--ease-micro);
}

.link-arrow:hover { color: var(--flame-500); }
.link-arrow:hover .btn__arrow { transform: translateX(3px); }

/* ============================================================================
   5. Header
   ========================================================================= */

.site-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-header);
  block-size: var(--header-h);
  display: flex;
  align-items: center;
  color: var(--text-on-dark);
  border-block-end: var(--hairline) solid transparent;
  transition: background-color 320ms var(--ease-micro),
              border-color 320ms var(--ease-micro);
}

.site-header.is-scrolled {
  background: rgb(18 19 22 / 0.93);
  backdrop-filter: saturate(140%) blur(10px);
  border-block-end-color: var(--line);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  inline-size: min(100% - var(--gutter) * 2, var(--container));
  margin-inline: auto;
}

/* Both gaps open up at 84em, not before. 1280px is the tightest width on the
   whole site: the rail reservation below takes 88px out of the row exactly
   when the quote button has just appeared, so the header is narrower at
   1280 than it is at 1248. Six Spanish nav labels plus "Solicitar
   presupuesto" need every pixel of that. */
@media (min-width: 84em) {
  .site-header__inner { gap: var(--space-6); }
}

@media (min-width: 80em) {
  .site-header__inner {
    inline-size: min(100% - var(--gutter) * 2 - var(--rail-w), var(--container));
    margin-inline-start: max(var(--rail-w), (100% - var(--container)) / 2);
  }
}

.brand {
  display: block;
  margin-inline-end: auto;
  flex: none;
}

/* Sized by width, not height: the lockup is 1.96:1, so a height rule would
   have to be re-derived every time the header height changes. These two
   widths put it at 55px in the 68px header and 69px in the 84px one — a
   logo that nearly fills its bar, which is what a lockup this wide needs in
   order for "MAKİNE" to stay legible at all. */
.brand__logo {
  display: block;
  inline-size: 6.75rem;
  block-size: auto;
}

@media (min-width: 64em) {
  .brand__logo { inline-size: 8.5rem; }
}

.footer-logo {
  display: block;
  inline-size: min(13rem, 60%);
  margin-block-end: var(--space-5);
}

.footer-logo img {
  inline-size: 100%;
  block-size: auto;
}

.nav { display: none; }

@media (min-width: 64em) {
  .nav { display: block; }
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}

@media (min-width: 84em) {
  .nav__list { gap: var(--space-6); }
}

.nav__link {
  position: relative;
  display: block;
  padding-block: var(--space-2);
  white-space: nowrap;
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--fume-200);
  transition: color var(--dur-micro) var(--ease-micro);
}

.nav__link::after {
  content: "";
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: 1px;
  background: var(--flame-500);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 240ms var(--ease-entry);
}

.nav__link:hover,
.nav__link[aria-current="page"] { color: var(--white); }

.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* Collapsing the language switcher into a dropdown gave 100px back, but not
   enough: at 1024px the Spanish header is brand 182 + nav 469 + switcher 91 +
   gaps 96 = 838 of 951, and "Solicitar presupuesto" is 205 wide. Measured
   again after the switcher changed; 78em is still the first width where the
   longest label honestly fits. Below it the drawer and the docked quote bar
   both still offer the same action. */
.header-cta { display: none; }

@media (min-width: 78em) {
  .header-cta { display: inline-flex; }
}

/* --- language switcher ----------------------------------------------------
   A <details> disclosure. Five codes laid out in a row cost about 190px of
   header, which is what pushed the row over at 1024px in the long-label
   languages and forced the switcher out of the mobile header entirely; the
   closed toggle costs 64px, so it now sits in the header at every width. */

.lang {
  position: relative;
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  flex: none;
}

.lang__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: var(--hairline) solid var(--line-strong);
  color: var(--fume-200);
  cursor: pointer;
  list-style: none;                 /* Firefox */
  transition: color var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

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

.lang__toggle:hover,
.lang[open] > .lang__toggle {
  color: var(--white);
  border-color: var(--flame-500);
}

.lang__flag {
  display: block;
  inline-size: 20px;
  block-size: auto;
  flex: none;
}

.lang__chevron {
  transition: transform 200ms var(--ease-micro);
  opacity: 0.7;
}

.lang[open] .lang__chevron { transform: rotate(180deg); }

.lang__menu {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2));
  inset-inline-end: 0;
  z-index: var(--z-header);
  min-inline-size: 12.5rem;
  padding: var(--space-2);
  background: var(--fume-900);
  border: var(--hairline) solid var(--line-strong);
  box-shadow: 0 18px 40px rgb(0 0 0 / 0.45);
}

/* The panel is not animated open: <details> toggles display, and there is no
   height to transition from. It gets the entry easing on the way in only. */
.lang[open] .lang__menu {
  animation: lang-open 180ms var(--ease-entry) both;
}

@keyframes lang-open {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}

.lang__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  color: var(--fume-200);
  transition: background-color var(--dur-micro) var(--ease-micro),
              color var(--dur-micro) var(--ease-micro);
}

.lang__item:hover { background: var(--fume-800); color: var(--white); }

.lang__name {
  /* The option labels are the languages' own names, so they are set in the
     body face at sentence case — "Türkçe", not "TÜRKÇE". Uppercasing Cyrillic
     and Arabic here would be wrong in one script and impossible in the other. */
  font-family: var(--font-body);
  font-size: 0.8125rem;
  letter-spacing: 0;
  text-transform: none;
  margin-inline-end: auto;
}

.lang__item .lang__code { color: var(--fume-500); }

.lang__item[aria-current="true"] {
  color: var(--flame-500);
  background: rgb(255 107 18 / 0.08);
}

.lang__item[aria-current="true"] .lang__code { color: var(--flame-500); }

/* Nothing below the footer to open into. */
.site-footer .lang__menu {
  inset-block-start: auto;
  inset-block-end: calc(100% + var(--space-2));
}

/* Below 26em the code label is the first thing to go: the flag and the
   chevron already say "language" and "there is a list here". */
@media (max-width: 25.99em) {
  .lang__toggle > .lang__code { display: none; }
}

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

.menu-toggle {
  display: grid;
  place-content: center;
  gap: 5px;
  inline-size: 44px;
  block-size: 44px;
  margin-inline-end: calc(var(--space-3) * -1);
}

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

.menu-toggle span {
  display: block;
  inline-size: 22px;
  block-size: 2px;
  background: currentColor;
  transition: transform 260ms var(--ease-entry), opacity 160ms linear;
}

.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.drawer {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  z-index: var(--z-drawer);
  inline-size: min(24rem, 100%);
  padding: calc(var(--header-h) + var(--space-6)) var(--gutter) var(--space-7);
  background: var(--fume-950);
  color: var(--text-on-dark);
  border-inline-start: var(--hairline) solid var(--line);
  overflow-y: auto;
  transform: translateX(100%);
  visibility: hidden;
  transition: transform 380ms var(--ease-entry), visibility 380ms;
}

[dir="rtl"] .drawer { transform: translateX(-100%); }

.drawer[data-open="true"] {
  transform: translateX(0);
  visibility: visible;
}

@media (min-width: 64em) {
  .drawer,
  .drawer-scrim { display: none; }
}

.drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-4);
  border-block-end: var(--hairline) solid var(--line);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.375rem;
  font-variation-settings: "wdth" var(--display-width);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 320ms var(--ease-entry), transform 320ms var(--ease-entry),
              color var(--dur-micro) var(--ease-micro);
}

.drawer[data-open="true"] .drawer__link { opacity: 1; transform: none; }

/* 60ms steps, per the motion spec. */
.drawer[data-open="true"] .drawer__link:nth-child(1) { transition-delay: 80ms; }
.drawer[data-open="true"] .drawer__link:nth-child(2) { transition-delay: 140ms; }
.drawer[data-open="true"] .drawer__link:nth-child(3) { transition-delay: 200ms; }
.drawer[data-open="true"] .drawer__link:nth-child(4) { transition-delay: 260ms; }
.drawer[data-open="true"] .drawer__link:nth-child(5) { transition-delay: 320ms; }

.drawer__link:hover,
.drawer__link[aria-current="page"] { color: var(--flame-500); }

.drawer__foot {
  margin-block-start: var(--space-7);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  align-items: flex-start;
}

.drawer-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-drawer) - 1);
  background: rgb(18 19 22 / 0.6);
  opacity: 0;
  visibility: hidden;
  transition: opacity 320ms var(--ease-micro), visibility 320ms;
}

body[data-menu-open="true"] .drawer-scrim { opacity: 1; visibility: visible; }
body[data-menu-open="true"] { overflow: hidden; }

/* ============================================================================
   6. Hero
   ========================================================================= */

.hero {
  position: relative;
  min-block-size: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: calc(var(--header-h) + var(--space-7)) var(--space-7);
  background: var(--fume-950);
  color: var(--text-on-dark);
  overflow: hidden;
  isolation: isolate;
}

.hero__ground {
  position: absolute;
  inset: -10%;
  z-index: -2;
  background:
    linear-gradient(to right, var(--grid) 1px, transparent 1px) 0 0 / 72px 72px,
    linear-gradient(to bottom, var(--grid) 1px, transparent 1px) 0 0 / 72px 72px;
  mask-image: radial-gradient(115% 85% at 20% 15%, #000 20%, transparent 70%);
  opacity: 0.6;
  will-change: transform;
}

/* The only gradient on the site, and it means heat coming off metal. */
.hero__heat {
  position: absolute;
  z-index: -1;
  inset-block-start: 10%;
  inset-inline-end: -12%;
  inline-size: min(46rem, 70vw);
  aspect-ratio: 1;
  background: radial-gradient(circle at 50% 50%,
    rgb(255 107 18 / 0.20), rgb(226 90 0 / 0.06) 45%, transparent 68%);
  pointer-events: none;
}

.hero__inner {
  display: grid;
  gap: var(--space-7);
  align-items: center;
  flex: 1 1 auto;
}

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

.hero__copy { max-inline-size: 40rem; }

.hero__index {
  display: flex;
  align-items: baseline;
  gap: var(--space-3);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--fume-500);
}

.hero__index b {
  color: var(--flame-500);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.hero__title {
  margin-block-start: var(--space-5);
  font-size: var(--t-hero);
  font-variation-settings: "wdth" var(--display-width-wide);
  line-height: var(--leading-tight);
  text-transform: uppercase;
}

/* Each word sits in a slot so the reveal can mask it. Latin only — rtl.css
   explains why Arabic drops the mask. */
.word {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
}

.word > span { display: inline-block; }

.hero__title .accent { color: var(--flame-500); }

.hero__rule {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-block-start: var(--space-6);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--fume-200);
}

.hero__rule::before {
  content: "";
  inline-size: clamp(3rem, 9vw, 8rem);
  block-size: 1px;
  background: var(--flame-500);
  flex: none;
  transform-origin: left center;
}

.hero__lead {
  margin-block-start: var(--space-5);
  font-size: var(--t-lead);
  line-height: var(--leading-snug);
  color: var(--fume-200);
  max-inline-size: 42ch;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-start: var(--space-7);
}

.hero__art { position: relative; justify-self: stretch; }

.hero__art svg { inline-size: 100%; block-size: auto; }

/* Technical callouts inside the drawing are numeric and must not mirror. */
.hero-machine { direction: ltr; }

.hero__scroll {
  position: absolute;
  bottom: var(--space-7);
  right: var(--gutter);
  display: none;
  writing-mode: vertical-rl;
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--fume-500);
}

@media (min-width: 64em) {
  .hero__scroll { display: block; }
}

/* --- opening sequence -------------------------------------------------------
   0ms    an orange line draws across the middle of the screen
   380ms  the line rises to become the header's lower edge, and fades
   420ms  the headline words leave their slots, 60ms apart
   640ms  the machine drawing arrives
   740ms  the remaining copy and the calls to action
   ends inside 1.2s.

   This is deliberately CSS rather than GSAP. A script-driven sequence cannot
   start until GSAP has been fetched, parsed and run, which on a cold cache
   left the hero blank for the better part of a second — worse than no
   sequence at all. CSS animations start at the first paint, so the sequence
   is over before a script-driven one would have begun. animations.js only
   clears up afterwards.
*/

.opener {
  position: fixed;
  inset-block-start: 50%;
  inset-inline: 0;
  z-index: calc(var(--z-header) + 5);
  block-size: 1px;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
}

.opener__line {
  display: block;
  block-size: 1px;
  background: var(--flame-500);
  box-shadow: 0 0 14px rgb(255 107 18 / 0.6);
  transform-origin: left center;
  transform: scaleX(0);
}

[dir="rtl"] .opener__line { transform-origin: right center; }

/* A session that has already seen the line does not get it again; its hero
   still animates, just without the overture. */
.js.is-opening:not(.is-returning) .opener {
  opacity: 1;
  visibility: visible;
  animation: opener-lift 700ms var(--ease-micro) forwards;
}

.js.is-opening:not(.is-returning) .opener__line {
  animation: opener-draw 380ms var(--ease-micro) forwards;
}

@keyframes opener-draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes opener-lift {
  0%, 54% { transform: translateY(0); opacity: 1; }
  100%    { transform: translateY(calc(var(--header-h) - 50vh)); opacity: 0; }
}

/* The hero is held from the first paint (the class is written server-side
   into the <html> tag) and released by these animations. */
.js.is-opening .hero__copy > *,
.js.is-opening .hero__art { opacity: 0; }

.js.is-opening .hero__title { animation: hero-hold 1ms linear 420ms forwards; }
.js.is-returning .hero__title { animation-delay: 40ms; }

@keyframes hero-hold { to { opacity: 1; } }

.js.is-opening .hero__title .word > span {
  transform: translateY(115%);
  animation: word-rise 460ms var(--ease-entry) forwards;
}

/* Arabic drops the slot mask (see rtl.css), so its words fade up instead —
   the mask permanently clips the script's descenders. */
[dir="rtl"].js.is-opening .hero__title .word > span {
  transform: translateY(0.3em);
  opacity: 0;
  animation-name: word-fade;
}

@keyframes word-rise {
  from { transform: translateY(115%); }
  to   { transform: translateY(0); }
}

@keyframes word-fade {
  from { transform: translateY(0.3em); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

.js.is-opening .hero__title .word:nth-child(1) > span { animation-delay: 420ms; }
.js.is-opening .hero__title .word:nth-child(2) > span { animation-delay: 480ms; }
.js.is-opening .hero__title .word:nth-child(3) > span { animation-delay: 540ms; }
.js.is-opening .hero__title .word:nth-child(4) > span { animation-delay: 600ms; }
.js.is-opening .hero__title .word:nth-child(5) > span { animation-delay: 660ms; }
.js.is-opening .hero__title .word:nth-child(6) > span { animation-delay: 700ms; }
.js.is-opening .hero__title .word:nth-child(n + 7) > span { animation-delay: 740ms; }

.js.is-opening .hero__art {
  animation: hero-art 400ms var(--ease-entry) 640ms forwards;
}

@keyframes hero-art {
  from { opacity: 0; transform: scale(0.985); }
  to   { opacity: 1; transform: none; }
}

.js.is-opening .hero__copy > *:not(.hero__title) {
  animation: hero-copy 340ms var(--ease-entry) forwards;
}

@keyframes hero-copy {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

.js.is-opening .hero__copy > *:nth-child(1) { animation-delay: 400ms; }
.js.is-opening .hero__copy > *:nth-child(3) { animation-delay: 740ms; }
.js.is-opening .hero__copy > *:nth-child(4) { animation-delay: 790ms; }
.js.is-opening .hero__copy > *:nth-child(5) { animation-delay: 840ms; }
.js.is-opening .hero__copy > *:nth-child(n + 6) { animation-delay: 880ms; }

/* Returning visitors skip the overture, so everything shifts forward. */
.js.is-returning .hero__title .word > span,
.js.is-returning .hero__art,
.js.is-returning .hero__copy > *:not(.hero__title) { animation-delay: 60ms; }

.js.is-returning .hero__title .word:nth-child(2) > span { animation-delay: 120ms; }
.js.is-returning .hero__title .word:nth-child(3) > span { animation-delay: 180ms; }
.js.is-returning .hero__title .word:nth-child(4) > span { animation-delay: 240ms; }
.js.is-returning .hero__title .word:nth-child(5) > span { animation-delay: 300ms; }
.js.is-returning .hero__title .word:nth-child(n + 6) > span { animation-delay: 340ms; }
.js.is-returning .hero__art { animation-delay: 260ms; }
.js.is-returning .hero__copy > *:nth-child(3) { animation-delay: 360ms; }
.js.is-returning .hero__copy > *:nth-child(4) { animation-delay: 410ms; }
.js.is-returning .hero__copy > *:nth-child(n + 5) { animation-delay: 460ms; }

/* ============================================================================
   7. Metric strip
   ========================================================================= */

.metrics {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

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

.metric {
  padding: var(--space-6) var(--space-5);
  border-inline-end: var(--hairline) solid var(--line);
  border-block-end: var(--hairline) solid var(--line);
}

.metric:nth-child(2n) { border-inline-end: 0; }

@media (min-width: 48em) {
  .metric,
  .metric:nth-child(2n) { border-inline-end: var(--hairline) solid var(--line); border-block-end: 0; }
  .metric:last-child { border-inline-end: 0; }
}

.metric__value {
  display: flex;
  align-items: baseline;
  gap: 2px;
  font-family: var(--font-display);
  font-weight: 800;
  font-variation-settings: "wdth" var(--display-width-wide);
  font-size: clamp(2.25rem, 4.5vw, 3.75rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--white);
}

.metric__unit {
  font-size: 0.38em;
  color: var(--flame-500);
  font-family: var(--font-mono);
  font-weight: 500;
}

.metric__label {
  margin-block-start: var(--space-3);
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fume-500);
}

/* ============================================================================
   8. Section heads
   ========================================================================= */

.head {
  display: grid;
  gap: var(--space-5);
  margin-block-end: var(--space-8);
}

@media (min-width: 64em) {
  .head--split {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: end;
    gap: var(--space-8);
  }
}

.head__title {
  font-size: var(--t-h2);
  font-variation-settings: "wdth" var(--display-width-wide);
  text-transform: uppercase;
}

.head__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  align-items: flex-start;
}

/* ============================================================================
   9. Category rail — horizontal, never a card grid
   ========================================================================= */

.catrail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(15rem, 20rem);
  gap: var(--space-5);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x proximity;
  padding-block-end: var(--space-5);
  margin-inline: calc(var(--gutter) * -1);
  padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: var(--fume-600) transparent;
}

@media (min-width: 64em) {
  .catrail { grid-auto-columns: minmax(17rem, 22rem); }
}

.catrail::-webkit-scrollbar { block-size: 3px; }
.catrail::-webkit-scrollbar-thumb { background: var(--fume-600); }

.cat {
  position: relative;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  border: var(--hairline) solid var(--line);
  background: var(--fume-900);
  transition: border-color var(--dur-micro) var(--ease-micro);
}

.band--light .cat,
.band--fog .cat {
  border-color: var(--line-light);
  background: var(--white);
}

.cat:hover { border-color: var(--flame-500); }

.cat .plate { aspect-ratio: 4 / 3; }

.cat__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  flex: 1 1 auto;
}

.cat__count {
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.cat__title {
  font-size: var(--t-h3);
  text-transform: uppercase;
  font-variation-settings: "wdth" var(--display-width);
}

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

.cat__text {
  font-size: var(--t-sm);
  color: var(--fume-200);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.band--light .cat__text,
.band--fog .cat__text { color: var(--text-on-light-muted); }

.rail-hint {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-5);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fume-500);
}

.band--light .rail-hint,
.band--fog .rail-hint { color: var(--text-on-light-muted); }

/* ============================================================================
   10. Sticky selection — fixed argument, changing evidence
   ========================================================================= */

@media (min-width: 64em) {
  .sticky-sel {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--space-8);
    align-items: start;
  }

  .sticky-sel__aside {
    position: sticky;
    inset-block-start: calc(var(--header-h) + var(--space-7));
    align-self: start;
  }
}

.sticky-sel__slot { position: relative; min-block-size: 15rem; }

/* One caption visible at a time; the rest are stacked underneath so the
   block never changes height mid-scroll. */
.sticky-sel__cap {
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 320ms var(--ease-entry), transform 320ms var(--ease-entry);
  pointer-events: none;
}

.sticky-sel__cap[data-active="true"] {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}

.sticky-sel__code {
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.sticky-sel__title {
  margin-block-start: var(--space-3);
  font-size: var(--t-h3);
  text-transform: uppercase;
}

.sticky-sel__text {
  margin-block-start: var(--space-3);
  color: var(--fume-200);
  max-inline-size: 38ch;
}

.sticky-sel__actions { margin-block-start: var(--space-5); }

.sticky-sel__items { display: grid; gap: var(--space-7); }

.sticky-sel__item { position: relative; }

.sticky-sel__item .plate { aspect-ratio: 16 / 10; }

.sticky-sel__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-block-start: var(--space-4);
  padding-block-start: var(--space-3);
  border-block-start: var(--hairline) solid var(--line);
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fume-500);
}

.sticky-sel__meta b {
  color: var(--fume-100);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* Below the sticky breakpoint each caption is simply printed with its item. */
@media (max-width: 63.999em) {
  .sticky-sel__aside { display: none; }

  .sticky-sel__inline {
    margin-block-end: var(--space-4);
  }
}

@media (min-width: 64em) {
  .sticky-sel__inline { display: none; }
}

/* ============================================================================
   11. Sequence — production steps (genuinely ordered, hence numbered)
   ========================================================================= */

.seq { display: grid; }

@media (min-width: 56em) {
  .seq { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.seq__step {
  position: relative;
  padding: var(--space-6) var(--space-5) var(--space-7);
  border-block-start: 2px solid var(--line-light);
  transition: border-color 420ms var(--ease-entry);
}

.band--dark .seq__step,
.band--dark-alt .seq__step { border-block-start-color: var(--line); }

.js .seq__step.is-in { border-block-start-color: var(--flame-500); }

@media (min-width: 56em) {
  .seq__step + .seq__step { border-inline-start: var(--hairline) solid var(--line-light); }
  .band--dark .seq__step + .seq__step,
  .band--dark-alt .seq__step + .seq__step { border-inline-start-color: var(--line); }
}

.seq__num {
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.14em;
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.seq__title {
  margin-block: var(--space-4) var(--space-3);
  font-size: var(--t-h4);
  text-transform: uppercase;
}

.seq__text {
  font-size: var(--t-sm);
  color: var(--text-on-light-muted);
}

.band--dark .seq__text,
.band--dark-alt .seq__text { color: var(--fume-200); }

/* ============================================================================
   12. Argument columns — each one measured
   ========================================================================= */

.args { display: grid; gap: var(--space-7); }

@media (min-width: 56em) {
  .args { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8); }
}

.arg { display: flex; flex-direction: column; gap: var(--space-4); }

.arg__title { font-size: var(--t-h4); text-transform: uppercase; }

.arg__text {
  font-size: var(--t-sm);
  color: var(--text-on-light-muted);
}

.band--dark .arg__text,
.band--dark-alt .arg__text { color: var(--fume-200); }

/* ============================================================================
   13. Product cards
   ========================================================================= */

.grid-cards {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
}

@media (min-width: 64em) {
  .grid-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-6); }
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--white);
  border: var(--hairline) solid var(--line-light);
  transition: border-color var(--dur-micro) var(--ease-micro),
              transform 320ms var(--ease-entry);
}

.band--dark .card,
.band--dark-alt .card {
  background: var(--fume-900);
  border-color: var(--line);
}

.card:hover {
  border-color: var(--flame-500);
  transform: translateY(-3px);
}

.card .plate { aspect-ratio: 4 / 3; }

.card:hover .plate > img { transform: scale(1.045); }

/* Hover brings the drawing back over the object. */
.card__draft {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background:
    linear-gradient(to right, var(--draft-light) 1px, transparent 1px) 0 0 / 22px 22px,
    linear-gradient(to bottom, var(--draft-light) 1px, transparent 1px) 0 0 / 22px 22px;
  opacity: 0;
  transition: opacity 260ms var(--ease-micro);
}

.card:hover .card__draft { opacity: 1; }

.card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  flex: 1 1 auto;
}

.card__kicker {
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

.band--dark .card__kicker,
.band--dark-alt .card__kicker { color: var(--fume-500); }

.card__title {
  font-size: var(--t-h4);
  text-transform: uppercase;
  font-variation-settings: "wdth" var(--display-width);
  transition: color var(--dur-micro) var(--ease-micro);
}

.card:hover .card__title { color: var(--flame-600); }
.band--dark .card:hover .card__title,
.band--dark-alt .card:hover .card__title { color: var(--flame-500); }

/* One click target over the card; the anchor stays the a11y handle. */
.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
}

.card__text {
  font-size: var(--t-sm);
  color: var(--text-on-light-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.band--dark .card__text,
.band--dark-alt .card__text { color: var(--fume-200); }

.card__specs {
  margin-block-start: auto;
  padding-block-start: var(--space-4);
  border-block-start: var(--hairline) solid var(--line-light);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

.band--dark .card__specs,
.band--dark-alt .card__specs {
  border-block-start-color: var(--line);
  color: var(--fume-500);
}

.card__spec { display: flex; gap: var(--space-2); }

.card__spec b {
  font-weight: 500;
  color: var(--text-on-light);
  font-variant-numeric: tabular-nums;
}

.band--dark .card__spec b,
.band--dark-alt .card__spec b { color: var(--fume-100); }

.card[hidden] { display: none; }

/* ============================================================================
   14. Marquee
   ========================================================================= */

.marquee {
  position: relative;
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
  display: flex;
  inline-size: max-content;
  animation: marquee 46s linear infinite;
}

.marquee:hover .marquee__track { animation-duration: 100s; }

@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

[dir="rtl"] .marquee__track { animation-name: marquee-rtl; }

@keyframes marquee-rtl {
  from { transform: translateX(0); }
  to   { transform: translateX(50%); }
}

.marquee__item {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: clamp(9rem, 16vw, 13rem);
  padding-inline: var(--space-5);
  block-size: 4.5rem;
}

.marquee__item img {
  max-block-size: 2.5rem;
  inline-size: auto;
  opacity: 0.55;
  filter: grayscale(1);
  transition: opacity var(--dur-micro) var(--ease-micro);
}

.marquee__item:hover img { opacity: 1; }

.marquee__name {
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* ============================================================================
   15. Closing CTA — the only full-orange surface on the site
   ========================================================================= */

.close-cta {
  position: relative;
  overflow: hidden;
  background: var(--flame-500);
  color: var(--text-on-flame);
  padding-block: clamp(3.5rem, 6vw, 6rem);
}

/* Ruled ticks along the top edge: even the loudest surface stays measured. */
.close-cta::before {
  content: "";
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 10px;
  background: repeating-linear-gradient(to right,
    rgb(18 19 22 / 0.35) 0 1px, transparent 1px 12px);
}

.close-cta__inner {
  display: grid;
  gap: var(--space-6);
  align-items: center;
}

@media (min-width: 64em) {
  .close-cta__inner { grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-8); }
}

.close-cta__title {
  font-size: var(--t-h2);
  font-variation-settings: "wdth" var(--display-width-wide);
  text-transform: uppercase;
  color: var(--fume-950);
}

.close-cta__text {
  margin-block-start: var(--space-4);
  max-inline-size: 44ch;
  color: rgb(18 19 22 / 0.78);
}

.close-cta__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); }

.close-cta .btn--primary {
  background: var(--fume-950);
  border-color: var(--fume-950);
  color: var(--white);
}

.close-cta .btn--primary:hover,
.close-cta .btn--primary:focus-visible {
  background: var(--fume-900);
  border-color: var(--fume-900);
}

.close-cta .btn--ghost {
  color: var(--fume-950);
  border-color: rgb(18 19 22 / 0.35);
}

.close-cta .btn--ghost:hover,
.close-cta .btn--ghost:focus-visible {
  color: var(--fume-950);
  border-color: var(--fume-950);
}

/*
   The full-orange band is the loudest surface on the site, so it appears
   exactly once — at the end of the home page, where the argument has been
   made. Every inner page closes on the quiet variant instead: same structure,
   dark ground, and the orange reduced to the rule and the button. Repeating
   the loud version on six pages would push the accent well past the share of
   the page it is supposed to occupy.
*/
.close-cta--quiet {
  background: var(--surface-dark);
  color: var(--text-on-dark);
  padding-block: clamp(2.75rem, 4.5vw, 4rem);
  border-block-start: 2px solid var(--flame-500);
}

.close-cta--quiet::before { content: none; }

.close-cta--quiet .close-cta__title { color: var(--white); }
.close-cta--quiet .close-cta__text { color: var(--fume-200); }

.close-cta--quiet .btn--primary {
  background: var(--flame-500);
  border-color: var(--flame-500);
  color: var(--text-on-flame);
}

.close-cta--quiet .btn--primary:hover,
.close-cta--quiet .btn--primary:focus-visible {
  background: var(--flame-300);
  border-color: var(--flame-300);
}

.close-cta--quiet .btn--ghost {
  color: var(--text-on-dark);
  border-color: var(--line-strong);
}

.close-cta--quiet .btn--ghost:hover,
.close-cta--quiet .btn--ghost:focus-visible {
  color: var(--flame-500);
  border-color: var(--flame-500);
}

/* ============================================================================
   16. Footer
   ========================================================================= */

.site-footer {
  background: var(--fume-950);
  color: var(--fume-200);
  padding-block: var(--space-9) var(--space-6);
  border-block-start: var(--hairline) solid var(--line);
}

.footer-grid { display: grid; gap: var(--space-7); }

@media (min-width: 56em) {
  .footer-grid {
    grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr));
    gap: var(--space-8);
  }
}

.footer-brand__text {
  margin-block-start: var(--space-5);
  font-size: var(--t-sm);
  color: var(--fume-500);
  max-inline-size: 34ch;
}

.footer-col__title {
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fume-500);
  margin-block-end: var(--space-4);
}

.footer-col ul { display: flex; flex-direction: column; gap: var(--space-3); }

.footer-col a,
.footer-col span {
  font-size: var(--t-sm);
  transition: color var(--dur-micro) var(--ease-micro);
}

.footer-col a:hover { color: var(--flame-500); }

.social { display: flex; gap: var(--space-3); }

.social a {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border: var(--hairline) solid var(--line);
  transition: border-color var(--dur-micro) var(--ease-micro),
              color var(--dur-micro) var(--ease-micro);
}

.social a:hover { border-color: var(--flame-500); color: var(--flame-500); }

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-block-start: var(--space-8);
  padding-block-start: var(--space-5);
  border-block-start: var(--hairline) solid var(--line);
  font: 500 var(--t-cap-sm) / 1.5 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fume-500);
}

/* Copyright and developer credit as one block. Row on a wide footer, stacked
   below it — at 360px the two sentences do not fit side by side, and wrapping
   them mid-sentence reads worse than two clean lines. */
.footer-legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-5);
}

.footer-credit {
  color: var(--fume-600);
}

/* One shade up from the label, so the name reads as the thing being pointed at
   without being loud about it. Orange is held back for the hover: a credit line
   permanently in the accent colour would compete with the CTAs, and the accent
   is the site's scarcest signal. */
/* Not uppercased with the rest of the bar. The row's text-transform is Turkish
   on a Turkish page, so "Leiyla" came out "LEİYLA" with a dotted capital while
   the same name read "LEIYLA" in English and Spanish — one company rendered
   two ways depending on which language a visitor picked. A name is written the
   way its owner writes it; left in its own casing it also reads as a proper
   noun rather than another label in the row. */
.footer-credit a {
  color: var(--fume-500);
  text-transform: none;
  letter-spacing: 0.04em;
  text-decoration: none;
  border-block-end: var(--hairline) solid transparent;
  transition: color var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

.footer-credit a:hover,
.footer-credit a:focus-visible {
  color: var(--flame-500);
  border-block-end-color: currentColor;
}

/* ============================================================================
   17. Page head (inner pages)
   ========================================================================= */

.page-head {
  position: relative;
  padding-block: calc(var(--header-h) + var(--space-8)) var(--space-8);
  background: var(--fume-950);
  color: var(--text-on-dark);
  overflow: hidden;
  isolation: isolate;
}

.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  font: 500 var(--t-cap-sm) / 1.5 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fume-500);
}

.breadcrumb a { transition: color var(--dur-micro) var(--ease-micro); }
.breadcrumb a:hover { color: var(--flame-500); }

.breadcrumb li + li::before {
  content: "/";
  margin-inline-end: var(--space-3);
  color: var(--fume-600);
}

.page-head__title {
  margin-block-start: var(--space-5);
  font-size: var(--t-h2);
  font-variation-settings: "wdth" var(--display-width-wide);
  text-transform: uppercase;
  max-inline-size: 20ch;
}

.page-head__lead {
  margin-block-start: var(--space-5);
  font-size: var(--t-lead);
  line-height: var(--leading-snug);
  color: var(--fume-200);
  max-inline-size: 52ch;
}

.page-head__dim { margin-block-start: var(--space-6); max-inline-size: 22rem; }

/* ============================================================================
   18. Product index — filter bar, search, view switch
   ========================================================================= */

.toolbar {
  display: grid;
  gap: var(--space-5);
  padding-block-end: var(--space-5);
  margin-block-end: var(--space-6);
  border-block-end: var(--hairline) solid var(--line-light);
}

@media (min-width: 64em) {
  .toolbar {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: var(--space-6);
  }
}

.chips { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); }

.chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding-block: var(--space-3);
  min-block-size: 44px;
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
  transition: color var(--dur-micro) var(--ease-micro);
}

.chip::after {
  content: "";
  position: absolute;
  inset-block-end: var(--space-2);
  inset-inline: 0;
  block-size: 2px;
  background: var(--flame-500);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 240ms var(--ease-entry);
}

.chip:hover,
.chip[aria-current="true"] { color: var(--text-on-light); }

.chip[aria-current="true"]::after { transform: scaleX(1); }

.chip__n {
  font-size: var(--t-cap-sm);
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.toolbar__tools { display: flex; align-items: center; gap: var(--space-4); }

.search { position: relative; flex: 1 1 auto; min-inline-size: 11rem; }

.search input {
  inline-size: 100%;
  padding-block: var(--space-3);
  padding-inline: 2.25rem var(--space-4);
  min-block-size: 44px;
  background: transparent;
  border: var(--hairline) solid var(--line-light-strong);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: border-color var(--dur-micro) var(--ease-micro);
}

.search input::placeholder { color: var(--text-on-light-muted); }
.search input:focus { border-color: var(--flame-500); }

.search svg {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: var(--space-3);
  transform: translateY(-50%);
  color: var(--text-on-light-muted);
  pointer-events: none;
}

.viewswitch { display: none; border: var(--hairline) solid var(--line-light-strong); }

@media (min-width: 48em) {
  .viewswitch { display: flex; }
}

.viewswitch button {
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  color: var(--text-on-light-muted);
  transition: color var(--dur-micro) var(--ease-micro),
              background-color var(--dur-micro) var(--ease-micro);
}

.viewswitch button + button { border-inline-start: var(--hairline) solid var(--line-light-strong); }

.viewswitch button[aria-pressed="true"] {
  background: var(--fume-950);
  color: var(--flame-500);
}

/* List view: the same cards, laid on their side. */
.grid-cards[data-view="list"] { grid-template-columns: minmax(0, 1fr); gap: 0; }

.grid-cards[data-view="list"] .card {
  flex-direction: row;
  border-inline: 0;
  border-block-start: 0;
}

.grid-cards[data-view="list"] .card:hover { transform: none; }

.grid-cards[data-view="list"] .plate {
  aspect-ratio: 4 / 3;
  inline-size: clamp(8rem, 24%, 15rem);
  flex: none;
}

.grid-cards[data-view="list"] .card__text { -webkit-line-clamp: 2; max-inline-size: 60ch; }

.empty { padding-block: var(--space-9); text-align: center; }

.empty__title { font-size: var(--t-h3); text-transform: uppercase; }
.empty__action { margin-block-start: var(--space-5); }

.result-count {
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
  margin-block-end: var(--space-5);
  font-variant-numeric: tabular-nums;
}

/* ============================================================================
   19. Product detail
   ========================================================================= */

.product { display: grid; gap: var(--space-7); }

@media (min-width: 64em) {
  .product {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: var(--space-8);
    align-items: start;
  }
}

.gallery__main {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--studio);
  border: var(--hairline) solid var(--line-light);
  overflow: hidden;
}

/* contain, with the padding on the box rather than the image: the frames in
   one product's set are not all the same shape — a whole machine standing up,
   a control panel lying wide — and cover would crop each of them differently
   as the visitor stepped through the strip. */
.gallery__main img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  padding: 5%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 320ms var(--ease-micro);
}

.gallery__main img[data-active="true"] { opacity: 1; }

.gallery__zoom {
  position: absolute;
  z-index: 6;
  inset-block-end: var(--space-3);
  inset-inline-end: var(--space-3);
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  background: var(--fume-950);
  color: var(--white);
  transition: background-color var(--dur-micro) var(--ease-micro),
              color var(--dur-micro) var(--ease-micro);
}

.gallery__zoom:hover { background: var(--flame-500); color: var(--text-on-flame); }

.gallery__thumbs {
  display: flex;
  gap: var(--space-3);
  margin-block-start: var(--space-3);
  overflow-x: auto;
  padding-block-end: var(--space-2);
}

.gallery__thumb {
  flex: none;
  inline-size: 5.5rem;
  aspect-ratio: 4 / 3;
  background: var(--white);
  border: var(--hairline) solid var(--line-light);
  overflow: hidden;
  opacity: 0.55;
  transition: opacity var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

.gallery__thumb img {
  inline-size: 100%;
  block-size: 100%;
  padding: 6%;
  object-fit: contain;
}

.gallery__thumb[aria-selected="true"] { opacity: 1; border-color: var(--flame-500); }

.product__short {
  font-size: var(--t-lead);
  line-height: var(--leading-snug);
  color: var(--text-on-light-muted);
}

.spec-table { inline-size: 100%; }

.spec-table tr { border-block-end: var(--hairline) solid var(--line-light); }

.spec-table th,
.spec-table td {
  padding-block: var(--space-4);
  text-align: start;
  vertical-align: baseline;
}

.spec-table th {
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
  inline-size: 45%;
}

.spec-table td {
  font-family: var(--font-mono);
  font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
  text-align: end;
}

/* Rows draw their rule in from the reading edge as the table enters. */
.js .spec-table tr { position: relative; }

.js .spec-table tr::after {
  content: "";
  position: absolute;
  inset-block-end: -1px;
  inset-inline: 0;
  block-size: 1px;
  background: var(--flame-500);
  transform: scaleX(0);
  transform-origin: left center;
}

.js .spec-table.is-in tr::after { animation: rule-draw 520ms var(--ease-entry) forwards; }

.js .spec-table.is-in tr:nth-child(2)::after { animation-delay: 60ms; }
.js .spec-table.is-in tr:nth-child(3)::after { animation-delay: 120ms; }
.js .spec-table.is-in tr:nth-child(4)::after { animation-delay: 180ms; }
.js .spec-table.is-in tr:nth-child(5)::after { animation-delay: 240ms; }
.js .spec-table.is-in tr:nth-child(6)::after { animation-delay: 300ms; }
.js .spec-table.is-in tr:nth-child(n + 7)::after { animation-delay: 360ms; }

@keyframes rule-draw {
  0%   { transform: scaleX(0); opacity: 1; }
  55%  { transform: scaleX(1); opacity: 1; }
  100% { transform: scaleX(1); opacity: 0; }
}

.product__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-block-start: var(--space-7);
}

.video-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  border: var(--hairline) solid var(--line);
  background: var(--fume-900);
}

.video-embed iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}

/* Mobile quote bar, docked. */
.quote-bar {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  block-size: var(--quote-bar-h);
  z-index: calc(var(--z-header) - 1);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--gutter);
  background: var(--fume-950);
  color: var(--text-on-dark);
  border-block-start: var(--hairline) solid var(--line);
  transform: translateY(110%);
  transition: transform 320ms var(--ease-entry);
}

.quote-bar.is-shown { transform: none; }

.quote-bar__name {
  font: 500 var(--t-cap-sm) / 1.3 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fume-200);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (min-width: 64em) {
  .quote-bar { display: none; }
}

/* ============================================================================
   20. Lightbox
   ========================================================================= */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--z-lightbox);
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgb(18 19 22 / 0.94);
  opacity: 0;
  visibility: hidden;
  transition: opacity 240ms var(--ease-micro), visibility 240ms;
}

.lightbox[data-open="true"] { opacity: 1; visibility: visible; }

/* A still gets the studio ground behind it, a video does not: the product
   frames are matted cut-outs and would otherwise be examined at full size
   against black, which is the one ground their leftover shadow shows on. */
.lightbox img,
.lightbox video {
  max-inline-size: min(100%, 72rem);
  max-block-size: 80vh;
  inline-size: auto;
  border: var(--hairline) solid var(--line);
}

.lightbox img { background: var(--studio); }

/* An iframe has no intrinsic ratio to size against, so the player is given
   16:9 and then bounded by the same 80vh ceiling as a still. */
.lightbox iframe {
  inline-size: min(100%, 72rem);
  aspect-ratio: 16 / 9;
  max-block-size: 80vh;
  border: var(--hairline) solid var(--line);
}

.lightbox__close {
  position: absolute;
  inset-block-start: var(--space-5);
  inset-inline-end: var(--space-5);
  display: grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  color: var(--white);
  border: var(--hairline) solid var(--line-strong);
  transition: border-color var(--dur-micro) var(--ease-micro),
              color var(--dur-micro) var(--ease-micro);
}

.lightbox__close:hover { border-color: var(--flame-500); color: var(--flame-500); }

.lightbox__cap {
  position: absolute;
  inset-block-end: var(--space-6);
  inset-inline: 0;
  text-align: center;
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fume-500);
}

/* ============================================================================
   21. Gallery page
   ========================================================================= */

.tiles {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
}

.tile {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--studio);
  border: var(--hairline) solid var(--line-light);
  overflow: hidden;
  inline-size: 100%;
  padding: 0;
}

/* cover, unlike the product plates: the gallery is detail frames — a control
   panel, a wheel mid-cut — and those were composed to be filled, not floated. */
.tile img {
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  transition: transform 480ms var(--ease-entry);
}

.tile:hover img { transform: scale(1.05); }

.tile__cap {
  position: absolute;
  inset-block-end: 0;
  inset-inline: 0;
  padding: var(--space-4);
  background: linear-gradient(to top, rgb(18 19 22 / 0.85), transparent);
  color: var(--white);
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: start;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur-micro) var(--ease-micro),
              transform var(--dur-micro) var(--ease-micro);
}

.tile:hover .tile__cap,
.tile:focus-visible .tile__cap { opacity: 1; transform: none; }

/* A video tile is marked, not merely clickable: the play badge is the only
   thing that distinguishes it from a photograph before the click. */
.tile__play {
  position: absolute;
  inset-block-start: var(--space-4);
  inset-inline-start: var(--space-4);
  display: grid;
  place-content: center;
  inline-size: 2.75rem;
  block-size: 2.75rem;
  border-radius: 50%;
  background: rgb(18 19 22 / 0.72);
  color: var(--white);
  backdrop-filter: blur(4px);
  transition: background-color var(--dur-micro) var(--ease-micro),
              transform var(--dur-micro) var(--ease-micro);
}

.tile__play svg { fill: currentColor; stroke: none; margin-inline-start: 2px; }

.tile:hover .tile__play,
.tile:focus-visible .tile__play {
  background: var(--flame-500);
  color: var(--fume-950);
  transform: scale(1.06);
}

/* ============================================================================
   22. Certificates — documents, shown as documents
   ========================================================================= */

.certs {
  display: grid;
  gap: var(--space-6) var(--space-5);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
}

.cert { display: flex; flex-direction: column; gap: var(--space-4); }

/* A4 upright, because that is what a certificate is. Fixing the ratio rather
   than letting each scan set its own keeps the row of documents level even
   when the office has photographed them at four different crops. */
.cert__sheet {
  position: relative;
  display: block;
  inline-size: 100%;
  aspect-ratio: 1 / 1.414;
  padding: var(--space-3);
  background: var(--white);
  border: var(--hairline) solid var(--line-light);
  box-shadow: 0 1px 0 rgb(18 19 22 / 0.06), 0 12px 28px rgb(18 19 22 / 0.07);
  transition: transform var(--dur-micro) var(--ease-micro),
              box-shadow var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

.cert__sheet img {
  inline-size: 100%;
  block-size: 100%;
  /* contain, not cover: cropping a document to fill a box cuts the seal or
     the signature off, which are the parts that make it evidence. */
  object-fit: contain;
}

.cert__sheet:hover,
.cert__sheet:focus-visible {
  transform: translateY(-3px);
  border-color: var(--flame-500);
  box-shadow: 0 1px 0 rgb(18 19 22 / 0.06), 0 18px 36px rgb(18 19 22 / 0.12);
}

.cert__title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--t-h4);
  font-variation-settings: "wdth" var(--display-width);
  line-height: var(--leading-snug);
}

.cert__sub {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-2);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--flame-600);
}

.cert__text {
  margin-block-start: var(--space-3);
  font-size: var(--t-sm);
  line-height: var(--leading-normal);
  color: var(--text-on-light-muted);
}

.cert__doc {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-3);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  text-transform: uppercase;
  color: var(--text-on-light);
  border-block-end: var(--hairline) solid var(--line-light-strong);
  padding-block-end: var(--space-1);
  transition: color var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

.cert__doc:hover { color: var(--flame-600); border-color: var(--flame-500); }

/* ============================================================================
   23. Catalogue — a shelf, not a download list
   ========================================================================= */

.catalogs {
  display: grid;
  gap: var(--space-8);
}

.catalog {
  display: grid;
  gap: var(--space-5);
  align-items: start;
}

@media (min-width: 48em) {
  .catalog {
    grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
    gap: var(--space-7);
  }
}

/* Same A4 upright as a certificate sheet, and for the same reason: these are
   documents, and a document has a shape people recognise. */
.catalog__cover {
  position: relative;
  display: block;
  inline-size: min(100%, 15rem);
  aspect-ratio: 1 / 1.414;
  background: var(--white);
  border: var(--hairline) solid var(--line-light);
  box-shadow: 0 1px 0 rgb(18 19 22 / 0.06), 0 14px 30px rgb(18 19 22 / 0.09);
  overflow: hidden;
  transition: transform var(--dur-micro) var(--ease-micro),
              box-shadow var(--dur-micro) var(--ease-micro),
              border-color var(--dur-micro) var(--ease-micro);
}

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

.catalog__cover:hover,
.catalog__cover:focus-visible {
  transform: translateY(-3px);
  border-color: var(--flame-500);
  box-shadow: 0 1px 0 rgb(18 19 22 / 0.06), 0 20px 40px rgb(18 19 22 / 0.14);
}

.catalog__blank {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-3);
  block-size: 100%;
  background: var(--fog-100);
  color: var(--fume-500);
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
}

.catalog__title {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--t-h3);
  font-variation-settings: "wdth" var(--display-width);
  line-height: var(--leading-snug);
  text-wrap: balance;
}

/* Format, weight and date, set like a parts label. */
.catalog__spec {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-block-start: var(--space-3);
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: var(--track-cap);
  color: var(--flame-600);
}

.catalog__spec > * + *::before {
  content: "/";
  margin-inline-end: var(--space-4);
  color: var(--line-light-strong);
}

.catalog__text {
  max-inline-size: var(--measure);
  margin-block-start: var(--space-4);
  line-height: var(--leading-normal);
  color: var(--text-on-light-muted);
}

.catalog__note {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  max-inline-size: var(--measure);
  margin-block-start: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: rgb(255 107 18 / 0.07);
  border-inline-start: 2px solid var(--flame-500);
  font-size: var(--t-sm);
  line-height: var(--leading-normal);
}

.catalog__note svg { flex: none; margin-block-start: 2px; color: var(--flame-600); }

.catalog__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-5);
}

.catalog-empty {
  display: grid;
  justify-items: start;
  gap: var(--space-5);
  max-inline-size: var(--measure);
}

/* ============================================================================
   24. Reference wall
   ========================================================================= */

.refwall {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 11rem), 1fr));
  border-block-start: var(--hairline) solid var(--line-light);
  border-inline-start: var(--hairline) solid var(--line-light);
}

.refwall__cell {
  display: grid;
  place-items: center;
  padding: var(--space-6) var(--space-4);
  min-block-size: 7rem;
  border-block-end: var(--hairline) solid var(--line-light);
  border-inline-end: var(--hairline) solid var(--line-light);
  transition: background-color var(--dur-micro) var(--ease-micro);
}

.refwall__cell:hover { background: var(--white); }

.refwall__cell img {
  max-block-size: 2.75rem;
  inline-size: auto;
  filter: grayscale(1);
  opacity: 0.6;
  transition: opacity var(--dur-micro) var(--ease-micro);
}

.refwall__cell:hover img { opacity: 1; }

.refwall__name {
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: center;
  color: var(--text-on-light-muted);
}

/* ============================================================================
   25. Forms / contact
   ========================================================================= */

.contact-grid { display: grid; gap: var(--space-8); }

@media (min-width: 64em) {
  .contact-grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--space-9);
    align-items: start;
  }
}

.form { display: flex; flex-direction: column; gap: var(--space-5); }

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field__label {
  font: 500 var(--t-cap-sm) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

.field__control {
  inline-size: 100%;
  padding: var(--space-4);
  min-block-size: 3rem;
  background: var(--white);
  border: var(--hairline) solid var(--line-light-strong);
  transition: border-color var(--dur-micro) var(--ease-micro);
}

textarea.field__control { min-block-size: 9rem; resize: vertical; }

.field__control:focus { border-color: var(--flame-500); }

.field__hint { font-size: var(--t-cap); color: var(--text-on-light-muted); }

.field__error {
  font: 500 var(--t-cap) / 1.4 var(--font-mono);
  letter-spacing: 0.06em;
  color: var(--flame-600);
}

/* Honeypot: never rendered to a sighted or assistive user. */
.hp {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.notice {
  padding: var(--space-5);
  border-inline-start: 3px solid var(--flame-500);
  background: var(--white);
}

.notice__title {
  font: 500 var(--t-cap) / 1 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--flame-600);
  margin-block-end: var(--space-2);
}

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

.info-row {
  display: grid;
  gap: var(--space-1);
  padding-block: var(--space-4);
  border-block-end: var(--hairline) solid var(--line-light);
}

@media (min-width: 40em) {
  .info-row {
    grid-template-columns: 8rem minmax(0, 1fr);
    gap: var(--space-4);
    align-items: baseline;
  }

  /* Pinned to the value column, because a row can carry more than one <dd> —
     a second phone number or a second address. Auto-placement would have put
     the second one back under the label, where it reads as a stray term. */
  .info-row dd {
    grid-column: 2;
  }
}

.info-row dt {
  font: 500 var(--t-cap-sm) / 1.4 var(--font-mono);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-on-light-muted);
}

.info-row dd a { border-block-end: var(--hairline) solid var(--line-light-strong); }
.info-row dd a:hover { color: var(--flame-600); border-block-end-color: var(--flame-500); }

.map-frame {
  margin-block-start: var(--space-6);
  aspect-ratio: 16 / 10;
  border: var(--hairline) solid var(--line-light);
  overflow: hidden;
}

.map-frame iframe { inline-size: 100%; block-size: 100%; border: 0; }

/* ============================================================================
   26. Error pages
   ========================================================================= */

.errpage {
  position: relative;
  min-block-size: 78svh;
  display: grid;
  align-content: center;
  background: var(--fume-950);
  color: var(--text-on-dark);
  padding-block: calc(var(--header-h) + var(--space-8)) var(--space-9);
  overflow: hidden;
  isolation: isolate;
}

.errpage__code {
  font-family: var(--font-display);
  font-weight: 800;
  font-variation-settings: "wdth" var(--display-width-wide);
  font-size: clamp(5rem, 18vw, 13rem);
  line-height: 0.85;
  color: var(--flame-500);
  font-variant-numeric: tabular-nums;
}

.errpage__title {
  margin-block-start: var(--space-5);
  font-size: var(--t-h2);
  text-transform: uppercase;
}

.errpage__text {
  margin-block-start: var(--space-4);
  color: var(--fume-200);
  max-inline-size: 46ch;
}

/* ============================================================================
   27. Custom cursor — fine pointer, wide screens only
   ========================================================================= */

.cursor {
  position: fixed;
  inset-block-start: 0;
  inset-inline-start: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  display: none;
  will-change: transform;
}

.cursor__dot {
  position: absolute;
  inline-size: 8px;
  block-size: 8px;
  margin: -4px 0 0 -4px;
  border-radius: 50%;
  background: var(--flame-500);
  transition: opacity 160ms linear;
}

.cursor__ring {
  position: absolute;
  inline-size: 44px;
  block-size: 44px;
  margin: -22px 0 0 -22px;
  border: 1px solid var(--flame-500);
  border-radius: 50%;
  display: grid;
  place-items: center;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 200ms var(--ease-micro), transform 200ms var(--ease-micro);
}

.cursor__label {
  font: 500 8px / 1 var(--font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--flame-500);
  white-space: nowrap;
}

.cursor[data-active="true"] .cursor__ring { opacity: 1; transform: scale(1); }
.cursor[data-active="true"] .cursor__dot { opacity: 0; }

@media (pointer: fine) and (min-width: 64em) {
  .js .cursor { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .cursor { display: none !important; }
}

/* ============================================================================
   28. Entrance states
   Content is visible by default; JS opts elements into the hidden start
   state, so losing JS or GSAP costs nothing.
   ========================================================================= */

.js [data-enter] {
  transition: opacity var(--dur-entry) var(--ease-entry),
              transform var(--dur-entry) var(--ease-entry),
              clip-path var(--dur-entry) var(--ease-entry);
}

.js [data-enter]:not(.is-in) { opacity: 0; }
.js [data-enter="rise"]:not(.is-in) { transform: translateY(22px); }
.js [data-enter="wipe"]:not(.is-in) { clip-path: inset(0 0 100% 0); opacity: 1; }

.js [data-enter].is-in {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 0 0);
}

@media (prefers-reduced-motion: reduce) {
  .js [data-enter]:not(.is-in) { transform: none; clip-path: none; }
  .js .dim[data-enter]:not(.is-in) .dim__rule { transform: none; }

  /* The global reset collapses every animation to 1ms, and each step of the
     opening sequence fills forwards, so the hero simply arrives complete.
     The overture line is suppressed outright — it is pure motion. */
  .js.is-opening:not(.is-returning) .opener { display: none; }
  .js.is-opening .hero__title .word > span { transform: none; }
}

/* ============================================================================
   29. WhatsApp button — docked, always reachable
   A plate of the same painted steel as everything else, carrying a mark that
   belongs to someone else. The green stays inside the logo until the pointer
   arrives; a green disc floating over the page from the first paint would be
   the loudest thing on a site that spends its colour budget on one orange.
   ========================================================================= */

.wa-fab {
  position: fixed;
  inset-block-end: var(--space-5);
  inset-inline-end: var(--space-5);
  z-index: var(--z-fab);

  display: grid;
  place-items: center;
  inline-size: 3.5rem;
  block-size: 3.5rem;
  border-radius: 50%;
  border: var(--hairline) solid var(--line-strong);
  background: var(--fume-950);
  color: var(--whatsapp);

  box-shadow: 0 6px 20px rgb(0 0 0 / 0.28);
  transition:
    background-color var(--dur-micro) var(--ease-micro),
    color var(--dur-micro) var(--ease-micro),
    border-color var(--dur-micro) var(--ease-micro),
    transform var(--dur-micro) var(--ease-micro),
    opacity var(--dur-micro) var(--ease-micro);
}

.wa-fab__mark { display: block; }

.wa-fab:hover,
.wa-fab:focus-visible {
  background: var(--whatsapp-deep);
  border-color: var(--whatsapp);
  color: var(--white);
  transform: translateY(-2px);
}

.wa-fab:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

.wa-fab:active { transform: translateY(0); }

/* The docked quote bar owns the bottom edge on a phone, so the button steps
   over it. :has() rather than a class from site.js — the bar already toggles
   its own state, and one source of truth beats two that can disagree. */
body:has(.quote-bar.is-shown) .wa-fab {
  transform: translateY(calc(-1 * var(--quote-bar-h)));
}

body:has(.quote-bar.is-shown) .wa-fab:hover,
body:has(.quote-bar.is-shown) .wa-fab:focus-visible {
  transform: translateY(calc(-1 * var(--quote-bar-h) - 2px));
}

/* The button lands on the hero's scroll hint. The hint is decoration and the
   button is a telephone number, so the hint steps aside — and only when there
   is a button to step aside for. The hint is anchored to the physical right in
   every locale while the button follows the writing direction, so this is an
   LTR collision only; in Arabic they sit at opposite corners already. */
html[dir="ltr"]:has(.wa-fab) .hero__scroll {
  right: calc(var(--gutter) + 4.5rem);
}

/* The drawer and the lightbox are their own worlds; a button hovering over
   either one is a stray from the page underneath. */
body:has(.drawer[data-open="true"]) .wa-fab,
body:has(.lightbox[data-open="true"]) .wa-fab {
  opacity: 0;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .wa-fab { transition: background-color 1ms linear, color 1ms linear; }
  .wa-fab:hover,
  .wa-fab:focus-visible { transform: none; }
  body:has(.quote-bar.is-shown) .wa-fab:hover,
  body:has(.quote-bar.is-shown) .wa-fab:focus-visible {
    transform: translateY(calc(-1 * var(--quote-bar-h)));
  }
}

/* ============================================================================
   30. Cross-document view transitions
   Supported browsers get the transition; everyone else gets a normal load.
   ========================================================================= */

@view-transition { navigation: auto; }

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root) { animation: vt-out 200ms var(--ease-micro) both; }
  ::view-transition-new(root) { animation: vt-in 300ms var(--ease-entry) both; }
}

@keyframes vt-out { to { opacity: 0; transform: translateY(-8px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(10px); } }
