﻿/* =====================================================================
   Self-hosted type (assets/fonts) — no third-party font origins.
   One variable Archivo file covers 400–900; "Archivo Expanded" is the
   true wdth-125 cut of Archivo, registered under the family name the
   hero line already asks for. (The old Google Fonts request for
   "Archivo Expanded" returned 400 — that family never existed there —
   so the hero line silently fell back to regular Archivo.)
   url() resolves against this stylesheet, so the paths work from both
   / and /admin/.
   ===================================================================== */
@font-face {
  font-family: "Anton";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("assets/fonts/anton-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url("assets/fonts/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Archivo Expanded";
  font-style: normal;
  font-weight: 800;
  font-stretch: 125%;
  font-display: swap;
  src: url("assets/fonts/archivo-expanded-800-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@property --theme-luma {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --theme-bg-channel {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

@property --theme-fg-channel {
  syntax: "<number>";
  inherits: true;
  initial-value: 255;
}

@property --theme-inverse-channel {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

:root {
  --black: #000;
  --white: #fff;
  --ink: #090909;
  --theme-bg-channel: 0;
  --theme-fg-channel: 255;
  --theme-inverse-channel: 0;
  --theme-bg-rgb: var(--theme-bg-channel), var(--theme-bg-channel), var(--theme-bg-channel);
  --theme-fg-rgb: var(--theme-fg-channel), var(--theme-fg-channel), var(--theme-fg-channel);
  --theme-inverse-rgb: var(--theme-inverse-channel), var(--theme-inverse-channel), var(--theme-inverse-channel);
  --theme-luma: 0;
  --theme-grid-opacity: 0.18;
  --theme-ambient-opacity: 0.18;
  --theme-field-opacity: 0.56;
  --theme-canvas-opacity: 0.46;
  --theme-grain-opacity: 0.045;
  --soft: rgba(var(--theme-fg-rgb), 0.88);
  --muted: rgba(var(--theme-fg-rgb), 0.66);
  --line: rgba(var(--theme-fg-rgb), 0.18);
  --dark-line: rgba(var(--theme-fg-rgb), 0.14);
  --accent: rgb(var(--theme-fg-rgb));
  --pad: clamp(18px, 3vw, 44px);
  /* Notched phones (landscape especially): never tuck content under the
     safe area. Second declaration wins where env() is supported. */
  --pad: max(clamp(18px, 3vw, 44px), env(safe-area-inset-left), env(safe-area-inset-right));
  --max: 1240px;
  --scroll: 0;
  --display: "Anton", "Arial Narrow", Impact, sans-serif;
  --body: "Archivo", "Helvetica Neue", Arial, sans-serif;
  /* Motion tokens — every new animation should pick from these so the
     whole site shares one timing voice. --ease aliases --ease-out for
     the many existing rules that reference it. */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-snap: cubic-bezier(0.3, 1.25, 0.35, 1);
  --ease: var(--ease-out);
  --motion-fast: 220ms;
  --motion-med: 460ms;
  --motion-slow: 700ms;
  --duration-fast: var(--motion-fast);
  --duration-medium: var(--motion-med);
  --duration-slow: var(--motion-slow);
  --stagger-small: 70ms;
  --stagger-medium: 120ms;
  --section-p: 0;
  --hero-p: 0;
  --theme-p: 0;
  --reveal-y: clamp(18px, 2.4vw, 28px);
  --reveal-scale: 0.985;
  --parallax-depth: clamp(24px, 4svh, 48px);
  color-scheme: dark;
  transition:
    --theme-luma 180ms linear,
    --theme-bg-channel 180ms linear,
    --theme-fg-channel 240ms var(--ease),
    --theme-inverse-channel 240ms var(--ease);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  overflow-x: clip;
  -webkit-tap-highlight-color: transparent;
}

/* Selection inverts with the theme — no stock blue on a monochrome site. */
::selection {
  background: rgb(var(--theme-fg-rgb));
  color: rgb(var(--theme-bg-rgb));
  text-shadow: none;
}

body {
  min-width: 0;
  margin: 0;
  overflow-x: clip;
  overflow-y: visible;
  background: rgb(var(--theme-bg-rgb));
  color: rgb(var(--theme-fg-rgb));
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  transition: background-color 80ms linear, color 180ms ease;
}

@media (min-width: 761px) {
  html {
    overflow-y: scroll;
    scrollbar-gutter: stable;
    scrollbar-color: rgba(var(--theme-fg-rgb), 0.4) rgb(var(--theme-bg-rgb));
    scrollbar-width: thin;
  }

  html::-webkit-scrollbar {
    width: 8px;
  }

  html::-webkit-scrollbar-track {
    background: rgb(var(--theme-bg-rgb));
  }

  html::-webkit-scrollbar-thumb {
    border: 2px solid rgb(var(--theme-bg-rgb));
    border-radius: 999px;
    background: rgba(var(--theme-fg-rgb), 0.4);
  }
}

body.is-light {
  color-scheme: light;
}

body::before,
body::after {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  content: "";
  transition: opacity 220ms ease, filter 220ms ease;
}

body::before {
  background:
    linear-gradient(rgba(var(--theme-fg-rgb), 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--theme-fg-rgb), 0.04) 1px, transparent 1px);
  background-size: clamp(62px, 8vw, 118px) clamp(62px, 8vw, 118px);
  opacity: var(--theme-grid-opacity);
  transform: translate3d(0, calc(var(--scroll) * -55px), 0);
}

body::after {
  background:
    radial-gradient(circle at 100% 40%, rgba(var(--theme-fg-rgb), 0.14), transparent 30%),
    linear-gradient(90deg, rgba(var(--theme-inverse-rgb), 0.14), transparent 22%, transparent 76%, rgba(var(--theme-fg-rgb), 0.08)),
    linear-gradient(180deg, transparent 0 58%, rgba(var(--theme-inverse-rgb), 0.22));
  opacity: var(--theme-ambient-opacity);
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
}

/* Visually hidden but available to assistive tech. Used for the clean,
   readable heading text behind the per-character split animation. */
.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.nerve-canvas {
  position: fixed;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  opacity: var(--theme-canvas-opacity);
  pointer-events: none;
  transition: opacity 220ms ease;
}

/* The baked depth layers + source glow live here as compositor-promoted
   elements that app.js slides with `transform` (no per-frame canvas repaint —
   the big mobile win). #nerveCanvas above stays the live pulse overlay. */
.nerve-field {
  position: fixed;
  inset: 0;
  z-index: 2;
  overflow: hidden;
  opacity: var(--theme-canvas-opacity);
  pointer-events: none;
  transition: opacity 220ms ease;
}

.nerve-field .nerve-layer,
.nerve-field .nerve-source {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
  transform: translateZ(0);
  backface-visibility: hidden;
}

.background-field {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(circle at 100% 40%, rgba(var(--theme-fg-rgb), 0.16), transparent 33%),
    linear-gradient(90deg, rgba(var(--theme-inverse-rgb), 0.52), rgba(var(--theme-inverse-rgb), 0.2) 48%, rgba(var(--theme-inverse-rgb), 0.06));
  opacity: var(--theme-field-opacity);
  transition: filter 220ms ease, opacity 220ms ease;
}

/* Oversized by the grain-shift travel so the transform-based jitter never
   exposes an edge. Translating the layer is compositor-only; the old
   background-position keyframes repainted the full screen on every step. */
.grain {
  position: fixed;
  inset: -48px;
  z-index: 3;
  pointer-events: none;
  opacity: var(--theme-grain-opacity);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}

@keyframes grainShift {
  0% { transform: translate3d(0, 0, 0); }
  20% { transform: translate3d(-37px, 29px, 0); }
  40% { transform: translate3d(31px, -41px, 0); }
  60% { transform: translate3d(-23px, 19px, 0); }
  80% { transform: translate3d(43px, 31px, 0); }
  100% { transform: translate3d(0, 0, 0); }
}

/* =====================================================================
   Boot loader. Deliberately hardcoded black/white — the page always
   boots dark at the top, outside the theme system. app.js dismisses it
   (.is-done + body.is-ready) once the hero image and fonts land; the
   failsafe animation hides it after 6s even if JS never finishes, and
   a <noscript> style removes it entirely without JS. pointer-events is
   none throughout so it can never trap the reader.
   ===================================================================== */
.loader {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  background: #191919;
  color: #fff;
  pointer-events: none;
  transition: transform 680ms var(--ease-out) 140ms, visibility 0s 880ms;
  animation: loaderFailsafe 1ms linear 6s forwards;
}

.loader.is-done {
  visibility: hidden;
  transform: translateY(-101%);
}

@keyframes loaderFailsafe {
  to {
    visibility: hidden;
    opacity: 0;
  }
}

.loader-inner {
  display: grid;
  gap: 16px;
  justify-items: center;
  transition: opacity 220ms ease;
}

.loader.is-done .loader-inner {
  opacity: 0;
}

.loader-mark {
  opacity: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loader-logo {
  display: block;
  width: min(58vw, 300px);
  height: auto;
}

body.fonts-ready .loader-mark {
  opacity: 1;
  animation: loaderMarkIn 700ms var(--ease-out) backwards;
}

@keyframes loaderMarkIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}

.loader-line {
  width: min(220px, 44vw);
  height: 2px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.16);
}

.loader-line i {
  display: block;
  width: 44%;
  height: 100%;
  background: #fff;
  transform: translateX(-110%);
  animation: loaderSweep 1.1s ease-in-out 200ms infinite;
}

@keyframes loaderSweep {
  to { transform: translateX(260%); }
}

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

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: calc(100% - (var(--pad) * 2));
  min-height: 74px;
  margin: 0 auto;
  padding-top: 14px;
}

.brand,
.instagram-link,
.whatsapp-button {
  border: 1px solid var(--line);
  background: rgba(var(--theme-bg-rgb), 0.78);
  color: rgb(var(--theme-fg-rgb));
  text-shadow: 0 1px 8px rgba(var(--theme-inverse-rgb), 0.32);
  backdrop-filter: blur(12px);
}

body.is-light .brand,
body.is-light .instagram-link,
body.is-light .whatsapp-button {
  border-color: var(--line);
  background: rgba(var(--theme-bg-rgb), 0.72);
  text-shadow: none;
}

.brand {
  display: inline-flex;
  align-items: center;
  min-height: 46px;
  padding: 0 15px;
  font-family: var(--body);
  font-size: clamp(0.68rem, 2vw, 0.8rem);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  transition: transform 220ms var(--ease), border-color 220ms ease, background 220ms ease;
}

.brand:hover,
.brand:focus-visible {
  transform: translateY(-2px);
  border-color: currentColor;
}

.brand-mark {
  position: relative;
  white-space: nowrap;
}

.brand-mark::after {
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 100%;
  height: 1px;
  content: "";
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 360ms var(--ease);
}

.brand:hover .brand-mark::after,
.brand:focus-visible .brand-mark::after {
  transform: scaleX(1);
}

.header-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.instagram-link {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 46px;
  height: 46px;
  overflow: hidden;
  color: rgb(var(--theme-fg-rgb));
  transition: opacity 180ms ease, transform 220ms var(--ease), border-color 220ms ease, background 220ms ease;
}

.instagram-link::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  content: "";
  background: linear-gradient(120deg, transparent, rgba(var(--theme-fg-rgb), 0.24), transparent);
  transform: translateX(-110%);
  transition: transform 520ms ease;
}

.instagram-link svg {
  width: 32px;
  height: 32px;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.9;
}

.instagram-lens {
  opacity: 0.96;
}

.instagram-dot {
  fill: #fa7e1e;
  stroke: none;
  opacity: 0.95;
}

.instagram-link:hover,
.instagram-link:focus-visible {
  transform: translateY(-2px);
  border-color: currentColor;
  opacity: 0.92;
}

.instagram-link:hover::before,
.instagram-link:focus-visible::before {
  transform: translateX(110%);
}

.whatsapp-button {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 0 18px;
  overflow: hidden;
  font-family: var(--body);
  font-size: 0.74rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  transition: transform 220ms var(--ease), border-color 220ms ease, background 220ms ease;
}

.whatsapp-button::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  content: "";
  background: linear-gradient(120deg, transparent, rgba(var(--theme-fg-rgb), 0.24), transparent);
  transform: translateX(-110%);
  transition: transform 520ms ease;
}

.whatsapp-button:hover,
.whatsapp-button:focus-visible {
  transform: translateY(-2px);
  border-color: currentColor;
}

.whatsapp-button:hover::before,
.whatsapp-button:focus-visible::before {
  transform: translateX(110%);
}

.whatsapp-button span:not(.whatsapp-dot) {
  display: inline-block;
  transform: translateY(1px);
}

.whatsapp-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #25d366;
  box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.42);
  animation: dotPulse 2.4s var(--ease) infinite;
}

body.is-light .whatsapp-dot {
  animation: dotPulseLight 2.4s var(--ease) infinite;
}

@keyframes dotPulse {
  0% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.45); }
  70% { box-shadow: 0 0 0 9px rgba(37, 211, 102, 0); }
  100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0); }
}

@keyframes dotPulseLight {
  0% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.38); }
  70% { box-shadow: 0 0 0 9px rgba(37, 211, 102, 0); }
  100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0); }
}

.section-frame {
  width: min(calc(100% - (var(--pad) * 2)), var(--max));
  margin: 0 auto;
}

.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  align-items: end;
  gap: clamp(18px, 2.2vw, 34px);
  width: 100%;
  max-width: none;
  min-height: 100vh;
  min-height: 100svh;
  padding: clamp(124px, 16vh, 164px) var(--pad) clamp(58px, 8vh, 96px);
  overflow: hidden;
}

.hero::before {
  position: absolute;
  inset: 0;
  z-index: 1;
  content: "";
  pointer-events: none;
  background:
    linear-gradient(90deg, #000 0 27%, rgba(0, 0, 0, 0.95) 38%, rgba(0, 0, 0, 0.56) 59%, rgba(0, 0, 0, 0.12) 100%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.22), transparent 42%, rgba(0, 0, 0, 0.58));
}

.hero-visual {
  position: absolute;
  inset: 0 0 0 38%;
  z-index: 0;
  margin: 0;
  overflow: hidden;
  border-left: 1px solid rgba(255, 255, 255, 0.24);
  background: #17120f;
}

.hero-visual::after {
  position: absolute;
  inset: 0;
  content: "";
  pointer-events: none;
  background: linear-gradient(120deg, rgba(0, 0, 0, 0.1), transparent 46%, rgba(255, 191, 138, 0.06));
  mix-blend-mode: soft-light;
}

.hero-visual img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 48% 50%;
  filter: saturate(1.02) contrast(1.08) brightness(1.05);
  transform: scaleX(-1) scale(1.015);
}

/* Scroll cue — a hairline that repeatedly draws downward at the hero's
   base. Desktop + fx only; it dissolves as soon as scrolling starts. */
.hero-cue {
  position: absolute;
  bottom: clamp(22px, 4vh, 42px);
  left: 50%;
  z-index: 2;
  display: none;
  width: 1px;
  height: 54px;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.2);
  transform: translateX(-50%);
}

body.fx .hero-cue {
  display: block;
  opacity: calc(1 - var(--hero-p, 0) * 3.4);
}

.hero-cue i {
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.85);
  transform: translateY(-101%);
  animation: cueSweep 2.6s var(--ease) 1.6s infinite;
}

@keyframes cueSweep {
  0% { transform: translateY(-101%); }
  52% { transform: translateY(0); }
  100% { transform: translateY(101%); }
}

@media (max-width: 960px) {
  body.fx .hero-cue {
    display: none;
  }
}

@media (min-width: 961px) {
  .hero {
    --hero-fade-depth: clamp(190px, 30svh, 320px);
    overflow: visible;
  }

  .hero::before,
  .hero-visual {
    height: calc(100% + var(--hero-fade-depth));
    -webkit-mask-image: linear-gradient(to bottom, #000 0 58%, rgba(0, 0, 0, 0.96) 62%, transparent 85%);
    mask-image: linear-gradient(to bottom, #000 0 58%, rgba(0, 0, 0, 0.96) 62%, transparent 85%);
  }

  .hero::before {
    inset: 0 0 auto;
  }

  .hero-visual {
    inset: 0 0 auto 38%;
  }

  .manifesto {
    position: relative;
    z-index: 1;
  }
}

.hero-copy {
  position: relative;
  z-index: 2;
  grid-column: 1 / 9;
  max-width: 930px;
}

.hero .eyebrow,
.hero .hero-line,
.hero .hero-actions p {
  color: rgba(255, 255, 255, 0.82);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.72);
}

.eyebrow,
.section-label {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  color: var(--muted);
  font-family: var(--body);
  font-size: 0.74rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  text-shadow: 0 1px 5px rgba(0, 0, 0, 0.7);
}

.eyebrow::before,
.section-label::before {
  width: 22px;
  height: 1px;
  content: "";
  background: currentColor;
  opacity: 0.7;
}

body.is-light .eyebrow,
body.is-light .section-label {
  color: rgba(var(--theme-fg-rgb), 0.56);
  text-shadow: none;
}

.section-label.dark {
  color: rgba(var(--theme-fg-rgb), 0.56);
  text-shadow: none;
}

h1,
h2,
h3,
p {
  text-wrap: balance;
}

.eyebrow,
.section-label,
h1,
h2,
h3,
p {
  transition: color 240ms ease, text-shadow 240ms ease;
}

h1,
h2,
h3 {
  text-shadow: 0 1px 7px rgba(0, 0, 0, 0.72);
}

body.is-light h1,
body.is-light h2,
body.is-light h3,
.contact h2 {
  text-shadow: none;
}

p {
  text-shadow: 0 1px 5px rgba(0, 0, 0, 0.58);
}

body.is-light p,
.contact p {
  text-shadow: none;
}

.button,
.contact-panel {
  text-shadow: none;
}

.message-card,
.message-card * {
  text-shadow: 0 1px 5px rgba(0, 0, 0, 0.72);
}

.hero h1 {
  position: relative;
  margin: 0;
  color: #fff;
  font-family: var(--display);
  font-size: clamp(5rem, 13vw, 12.8rem);
  font-weight: 400;
  line-height: 0.82;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.42);
}

.hero h1 span {
  display: block;
  transform-origin: left center;
}

.hero h1 .char {
  display: inline-block;
}

/* Entrances key off body.is-ready (added when the boot loader dismisses)
   so the choreography plays as the loader wipes away, not hidden behind
   it. Before is-ready the title sits static under the opaque loader. */
body.is-ready .hero h1[data-animate] .char {
  transform: translateY(108%) rotate(6deg);
  opacity: 0;
  animation: charRise 0.9s var(--ease) forwards;
}

@keyframes charRise {
  to {
    transform: translateY(0) rotate(0);
    opacity: 1;
  }
}

/* Save-Data fallback: the two words rise as units instead of per character. */
body.is-ready .hero h1[data-animate="words"] [data-split] {
  animation: wordRise 0.8s var(--ease-out) backwards;
}

@keyframes wordRise {
  from {
    transform: translateY(0.45em);
    opacity: 0;
  }
}

/* Hero entrance choreography — visual settles, title rises (above), then
   eyebrow → tagline → CTA → cue. Transform/opacity only, fx-scoped so
   reduced-motion and no-JS render the hero fully static. */
@keyframes heroEnter {
  from {
    transform: translateY(18px);
    opacity: 0;
  }
}

body.fx.is-ready .hero .eyebrow {
  animation: heroEnter var(--duration-medium) ease-out 0.1s backwards;
}

body.fx.is-ready .hero-line {
  animation: heroEnter var(--duration-slow) var(--ease-out) 0.66s backwards;
}

body.fx.is-ready .hero-actions {
  animation: heroEnter var(--duration-slow) var(--ease-out) 0.86s backwards;
}

body.fx.is-ready .hero-visual {
  animation: heroVisualIn var(--motion-slow) var(--ease-out) backwards;
}

@keyframes heroVisualIn {
  from { opacity: 0; }
}

.hero h1 {
  transition: text-shadow 420ms ease, color 420ms ease;
}

.hero h1:hover {
  text-shadow: 0 0 18px rgba(255, 255, 255, 0.22), 0 1px 7px rgba(0, 0, 0, 0.72);
}

.hero-line {
  max-width: 760px;
  margin: clamp(24px, 4vw, 44px) 0 0;
  color: var(--soft);
  font-family: "Archivo Expanded", var(--body);
  font-size: clamp(1.3rem, 3.6vw, 3.1rem);
  font-stretch: 125%;
  font-weight: 800;
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.hero-actions {
  position: relative;
  z-index: 2;
  grid-column: 8 / 12;
  display: grid;
  gap: 18px;
  margin-bottom: 10px;
  padding: clamp(14px, 2vw, 22px);
  border: 1px solid rgba(255, 255, 255, 0.24);
  background: rgba(0, 0, 0, 0.58);
  backdrop-filter: blur(12px);
}

.hero-actions p {
  max-width: 330px;
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}

.button {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 76px;
  padding: 0 20px;
  overflow: hidden;
  border: 1px solid currentColor;
  background: rgb(var(--theme-fg-rgb));
  color: rgb(var(--theme-inverse-rgb));
  font-family: var(--body);
  font-weight: 900;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  transition: transform 240ms var(--ease), box-shadow 240ms var(--ease);
}

.button > span {
  font-size: 0.78rem;
  letter-spacing: 0.14em;
}

.button::after {
  position: absolute;
  right: 18px;
  top: 50%;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgb(var(--theme-inverse-rgb));
  color: rgb(var(--theme-fg-rgb));
  content: "\2192";
  font-weight: 400;
  transform: translateY(-50%);
  transition: transform 280ms var(--ease);
}

.button:hover::after,
.button:focus-visible::after {
  transform: translateY(-50%) translateX(4px);
}

.button strong {
  white-space: nowrap;
}

.button:hover,
.button:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 14px 40px rgba(var(--theme-fg-rgb), 0.16);
}

.manifesto {
  padding: clamp(82px, 12vw, 150px) 0;
}

.manifesto h2,
.services h2,
.contact h2 {
  max-width: 900px;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(3rem, 8vw, 8rem);
  font-weight: 400;
  line-height: 0.92;
  text-transform: uppercase;
  letter-spacing: 0.004em;
}

.manifesto p,
.contact-copy p {
  max-width: 720px;
  margin: 26px 0 0;
  color: var(--soft);
  font-size: clamp(1.04rem, 1.8vw, 1.28rem);
  line-height: 1.5;
}

.section-head {
  display: grid;
  gap: 14px;
  margin-bottom: clamp(30px, 5vw, 58px);
}

[data-pulse-item] {
  isolation: isolate;
}

[data-pulse-item]:not(.site-header) {
  position: relative;
}

.contact {
  width: 100%;
  padding: clamp(86px, 11vw, 150px) var(--pad) clamp(98px, 12vw, 162px);
  background: transparent;
  color: rgb(var(--theme-fg-rgb));
}

.contact-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 0.42fr);
  gap: clamp(30px, 5.4vw, 76px);
  align-items: stretch;
  width: min(100%, var(--max));
  margin: 0 auto;
  padding: clamp(30px, 4.6vw, 58px);
  border-top: 1px solid rgba(var(--theme-fg-rgb), 0.22);
  border-bottom: 1px solid rgba(var(--theme-fg-rgb), 0.22);
  background:
    linear-gradient(90deg, rgba(var(--theme-fg-rgb), 0.07), transparent 54%),
    linear-gradient(180deg, rgba(var(--theme-fg-rgb), 0.05), transparent 42%);
  color: rgb(var(--theme-fg-rgb));
  /* Readability wash behind the contact copy + card — strong enough that
     the network lines read as atmosphere behind the panel, not across it. */
  box-shadow: inset 0 0 0 100vmax rgba(var(--theme-bg-rgb), 0.62);
}

.contact-copy {
  display: grid;
  align-content: center;
}

.contact-copy p {
  color: rgba(var(--theme-fg-rgb), 0.7);
}

.contact h2 span {
  display: block;
}

.contact .section-label.dark {
  color: rgba(var(--theme-fg-rgb), 0.58);
}

.message-card {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  min-height: 292px;
  gap: clamp(18px, 3vw, 32px);
  padding: clamp(22px, 3vw, 36px);
  overflow: hidden;
  border: 1px solid rgba(var(--theme-fg-rgb), 0.26);
  background:
    linear-gradient(135deg, rgba(var(--theme-fg-rgb), 0.14), rgba(var(--theme-fg-rgb), 0.045)),
    rgba(var(--theme-bg-rgb), 0.72);
  color: rgb(var(--theme-fg-rgb));
  text-shadow: none;
  box-shadow: inset 0 0 0 1px rgba(var(--theme-fg-rgb), 0.05);
  transition: transform 240ms ease, box-shadow 240ms ease, border-color 240ms ease, background 240ms ease;
}

.message-card * {
  position: relative;
  z-index: 1;
  text-shadow: none;
}

.message-card::before {
  position: absolute;
  inset: 0;
  z-index: 0;
  content: "";
  background:
    linear-gradient(125deg, transparent 0 38%, rgba(var(--theme-fg-rgb), 0.18) 46%, transparent 54%),
    linear-gradient(rgba(var(--theme-fg-rgb), 0.08) 1px, transparent 1px);
  background-size: 180% 100%, 100% 18px;
  opacity: 0.34;
  transform: translateX(-34%);
  transition: transform 520ms ease, opacity 520ms ease;
}

.message-arrow {
  position: absolute;
  right: clamp(18px, 2.4vw, 28px);
  top: clamp(18px, 2.4vw, 28px);
  width: clamp(42px, 4vw, 56px);
  height: clamp(42px, 4vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgb(var(--theme-fg-rgb));
  border-radius: 50%;
  background: rgb(var(--theme-fg-rgb));
  color: rgb(var(--theme-inverse-rgb));
  transition: transform 280ms var(--ease), background 280ms ease, color 280ms ease;
}

.message-arrow svg {
  width: 52%;
  height: 52%;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.message-card:hover .message-arrow,
.message-card:focus-visible .message-arrow {
  transform: translateX(4px);
}

.message-card:hover,
.message-card:focus-visible {
  transform: translateY(-4px);
  border-color: rgba(var(--theme-fg-rgb), 0.58);
  background:
    linear-gradient(135deg, rgba(var(--theme-fg-rgb), 0.2), rgba(var(--theme-fg-rgb), 0.07)),
    rgba(var(--theme-bg-rgb), 0.78);
  box-shadow: 0 24px 70px rgba(var(--theme-inverse-rgb), 0.2);
}

.message-card:hover::before,
.message-card:focus-visible::before {
  opacity: 0.72;
  transform: translateX(0);
}

/* Poster composition: label pinned top-left (clearing the arrow), the
   number anchored to the card's base — no floating middle. */
.message-label {
  position: relative;
  align-self: start;
  max-width: 11ch;
  padding-right: clamp(52px, 5vw, 68px);
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2.45rem, 4.4vw, 4.05rem);
  line-height: 0.92;
  letter-spacing: 0.01em;
  text-transform: uppercase;
}

.message-card strong {
  position: relative;
  display: block;
  width: 100%;
  max-width: 100%;
  padding-right: 0;
  color: rgb(var(--theme-fg-rgb));
  font-size: clamp(1.35rem, 1.8vw, 1.75rem);
  font-weight: 900;
  line-height: 1.1;
  white-space: nowrap;
  word-break: normal;
}

/* Numerals in CTAs and counters sit on a fixed grid — phone numbers and
   the services index never wobble as digits change. */
.button strong,
.message-card strong,
.services-count,
.service-num {
  font-variant-numeric: tabular-nums;
}

.site-footer {
  position: relative;
  z-index: 4;
  display: flex;
  justify-content: space-between;
  width: min(calc(100% - (var(--pad) * 2)), var(--max));
  margin: 0 auto;
  padding: 24px 0 28px;
  padding-bottom: max(28px, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-family: var(--body);
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  opacity: 1;
  visibility: visible;
}

.footer-brand {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}

.footer-brand small {
  color: currentColor;
  font-size: 0.62em;
  font-weight: 700;
  letter-spacing: 0.08em;
  opacity: 0.38;
}

.footer-meta {
  display: inline-flex;
  align-items: baseline;
  gap: 16px;
}

.footer-meta a {
  position: relative;
  color: inherit;
  opacity: 0.72;
  transition: opacity 180ms ease;
}

.footer-meta a::after {
  position: absolute;
  right: 0;
  bottom: -3px;
  left: 0;
  height: 1px;
  content: "";
  background: linear-gradient(90deg, #833ab4, #fd1d1d, #fcb045);
  opacity: 0.5;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 240ms var(--ease);
}

.footer-meta a:hover,
.footer-meta a:focus-visible {
  opacity: 1;
}

.footer-meta a:hover::after,
.footer-meta a:focus-visible::after {
  transform: scaleX(1);
}

[data-reveal] {
  opacity: 0;
  transform: translateY(var(--reveal-y));
  transition:
    opacity var(--motion-slow) ease var(--reveal-delay, 0ms),
    transform var(--motion-slow) var(--ease-out) var(--reveal-delay, 0ms);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

.hero [data-reveal] {
  opacity: 1;
  transform: none;
}

a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@media (max-width: 960px) {
  .hero,
  .contact-panel {
    grid-template-columns: 1fr;
  }

  .hero {
    align-content: end;
    gap: 18px;
    padding-top: 56svh;
  }

  .hero::before {
    background:
      linear-gradient(180deg, rgba(0, 0, 0, 0.06) 0 34%, rgba(0, 0, 0, 0.7) 60%, #000 78%),
      linear-gradient(90deg, rgba(0, 0, 0, 0.42), transparent 72%);
  }

  .hero-visual {
    inset: 0 0 auto;
    height: 68svh;
    border-left: 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.22);
  }

  .hero-visual img {
    object-position: 50% 48%;
  }

  .hero-copy,
  .hero-actions {
    grid-column: 1;
  }

  .hero-actions {
    justify-self: end;
    width: min(100%, 360px);
    max-width: none;
    margin-right: clamp(16px, 5vw, 56px);
  }
}

@media (max-width: 760px) {
  .brand,
  .instagram-link,
  .whatsapp-button {
    backdrop-filter: none;
  }

  .background-field {
    background:
      radial-gradient(circle at 96% 34%, rgba(var(--theme-fg-rgb), 0.18), transparent 38%),
      linear-gradient(90deg, rgba(var(--theme-inverse-rgb), 0.46), rgba(var(--theme-inverse-rgb), 0.18) 50%, rgba(var(--theme-inverse-rgb), 0.06));
    opacity: var(--theme-field-opacity);
  }

  .hero {
    align-content: end;
    gap: 16px;
    min-height: 100vh;
    min-height: 100svh;
    padding-top: clamp(380px, 59svh, 540px);
    padding-bottom: 34px;
    overflow: visible;
  }

  .hero::before {
    height: 105vh;
    height: 105svh;
    background:
      linear-gradient(180deg, rgba(0, 0, 0, 0.02) 0 38%, rgba(0, 0, 0, 0.38) 58%, rgba(0, 0, 0, 0.86) 78%, #000 100%),
      linear-gradient(90deg, rgba(0, 0, 0, 0.3), transparent 82%);
  }

  .hero-visual {
    height: 105vh;
    height: 105svh;
    border-bottom: 0;
    -webkit-mask-image: linear-gradient(to bottom, #000 0 52%, rgba(0, 0, 0, 0.98) 60%, rgba(0, 0, 0, 0.72) 74%, rgba(0, 0, 0, 0.26) 90%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 0 52%, rgba(0, 0, 0, 0.98) 60%, rgba(0, 0, 0, 0.72) 74%, rgba(0, 0, 0, 0.26) 90%, transparent 100%);
  }

  .hero-visual img {
    object-position: 22% 54%;
    transform: scaleX(-1) scale(1.08);
  }

  .hero-copy {
    align-self: end;
  }

  .hero .eyebrow {
    margin-bottom: 12px;
  }

  .hero-line {
    margin-top: 18px;
  }

  .hero-actions {
    gap: 10px;
    padding: 12px;
  }

  .hero-actions p {
    font-size: 0.88rem;
    line-height: 1.4;
  }

  .button {
    min-height: 64px;
  }

  .manifesto,
  .services {
    padding-top: 76px;
    padding-bottom: 76px;
  }

  .manifesto h2,
  .services h2,
  .contact h2 {
    font-size: clamp(2.7rem, 13vw, 4.2rem);
    line-height: 0.94;
  }

  .section-head {
    gap: 10px;
    margin-bottom: 28px;
  }

  .service-meta {
    margin-top: 8px;
    line-height: 1.45;
  }

  .contact {
    padding-top: 76px;
    padding-bottom: 88px;
  }

  .contact-panel {
    gap: 26px;
  }

}

@media (pointer: coarse) {
  .brand,
  .instagram-link,
  .whatsapp-button {
    backdrop-filter: none;
  }

  /* Touch press feedback — the tap equivalent of the desktop hover lifts.
     Transform/opacity only; the elements' existing transitions ease it. */
  .button:active {
    transform: translateY(1px) scale(0.98);
  }

  .message-card:active {
    transform: scale(0.99);
    border-color: rgba(var(--theme-fg-rgb), 0.5);
  }

  .whatsapp-button:active {
    transform: scale(0.96);
  }

  .brand:active,
  .instagram-link:active {
    transform: scale(0.95);
  }

  .site-nav a:active {
    color: rgb(var(--theme-fg-rgb));
  }

  .background-field {
    background:
      radial-gradient(circle at 96% 34%, rgba(var(--theme-fg-rgb), 0.18), transparent 38%),
      linear-gradient(90deg, rgba(var(--theme-inverse-rgb), 0.46), rgba(var(--theme-inverse-rgb), 0.18) 50%, rgba(var(--theme-inverse-rgb), 0.06));
    opacity: var(--theme-field-opacity);
  }

}

@media (max-width: 620px) {
  :root {
    --pad: 18px;
    --pad: max(18px, env(safe-area-inset-left), env(safe-area-inset-right));
  }

  .site-header {
    right: var(--pad);
    left: var(--pad);
    width: auto;
    min-height: 66px;
    padding-top: 10px;
  }

  .brand,
  .instagram-link,
  .whatsapp-button {
    min-height: 44px;
  }

  .brand {
    padding: 0 10px;
    font-size: 0.64rem;
    letter-spacing: 0.12em;
  }

  .whatsapp-button {
    gap: 8px;
    padding: 0 12px;
    font-size: 0.68rem;
  }

  .header-actions {
    gap: 7px;
  }

  .instagram-link {
    width: 44px;
    height: 44px;
  }

  .instagram-link svg {
    width: 28px;
    height: 28px;
  }

  .hero {
    min-height: 100vh;
    min-height: 100svh;
    padding-top: clamp(380px, 59svh, 540px);
    padding-bottom: 34px;
  }

  .hero-actions {
    justify-self: stretch;
    width: 100%;
    max-width: 440px;
    margin-right: 0;
  }

  .hero-visual {
    height: 105vh;
    height: 105svh;
  }

  .hero-visual img {
    object-position: 22% 54%;
    transform: scaleX(-1) scale(1.08);
  }

  .brand,
  .instagram-link,
  .whatsapp-button {
    backdrop-filter: none;
  }

  body::before {
    background-size: 58px 58px;
    opacity: 0.17;
  }

  body::after {
    background:
      radial-gradient(circle at 96% 34%, rgba(var(--theme-fg-rgb), 0.16), transparent 35%),
      linear-gradient(90deg, rgba(var(--theme-inverse-rgb), 0.16), transparent 24%, transparent 70%, rgba(var(--theme-fg-rgb), 0.1)),
      linear-gradient(180deg, transparent 0 52%, rgba(var(--theme-inverse-rgb), 0.28));
    opacity: var(--theme-ambient-opacity);
  }

  .hero h1 {
    font-size: clamp(4rem, 20vw, 6.6rem);
  }

  .button {
    min-height: 64px;
    padding-right: 64px;
  }

  .manifesto h2,
  .services h2,
  .contact h2 {
    font-size: clamp(2.7rem, 13vw, 4.2rem);
  }

  .contact-panel {
    padding: 20px;
  }

  .message-card {
    min-height: 230px;
  }

  .message-label {
    max-width: 10ch;
  }
}

@media (max-width: 420px) {
  .message-card strong {
    font-size: 1.18rem;
  }

  .site-footer {
    align-items: flex-end;
  }
}

@media (max-width: 360px) {
  :root {
    --pad: 16px;
    --pad: max(16px, env(safe-area-inset-left), env(safe-area-inset-right));
  }

  .site-header {
    right: var(--pad);
    left: var(--pad);
  }

  .brand {
    padding-right: 8px;
    padding-left: 8px;
    font-size: 0.6rem;
    letter-spacing: 0.1em;
  }

  .whatsapp-button {
    padding-right: 10px;
    padding-left: 10px;
  }

  .header-actions {
    gap: 6px;
  }
}

@media (max-width: 760px) and (max-height: 680px) {
  .hero {
    gap: 12px;
    padding-top: clamp(320px, 60svh, 390px);
    padding-bottom: 28px;
  }

  .hero-visual {
    height: 110vh;
    height: 110svh;
  }

  .hero h1 {
    font-size: clamp(3.8rem, 19vw, 5.5rem);
  }

  .hero-line {
    margin-top: 14px;
    font-size: 1.08rem;
  }

  .hero-actions {
    padding: 10px;
  }

  .hero-actions p {
    font-size: 0.82rem;
  }

  .button {
    min-height: 60px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
    transition-duration: 1ms !important;
  }

  .hero h1 .char {
    transform: none;
    opacity: 1;
  }

}

/* =====================================================================
   Scroll-driven motion system â€” fx layer.
   Everything below is inert unless app.js adds body.fx (skipped when
   prefers-reduced-motion is set), so the page stays fully readable
   without it.
   ===================================================================== */

main {
  position: relative;
  z-index: 4;
}

/* Scroll-velocity headline skew and the hero latency-echo distortion were
   removed: they fought the content for attention and hurt readability. The
   hero keeps its character entrance and the split-portal drift only. */

body.fx .hero h1 [data-split] {
  transform: translateX(calc(var(--hero-p, 0) * var(--dir, 0) * 16.1vw));
}

body.fx .hero [data-reveal] {
  transition: none;
}

body.fx .hero-copy,
body.fx .hero-actions {
  opacity: calc(1 - var(--hero-p, 0) * 0.9);
  transform: translate3d(0, calc(var(--hero-p, 0) * var(--parallax-depth) * -1), 0);
}

body.fx .hero-visual {
  transform: translate3d(0, calc(var(--hero-p, 0) * var(--parallax-depth) * -0.5), 0);
}

@media (max-width: 960px) {
  body.fx .hero h1 {
    transform: translate3d(0, calc(var(--hero-p, 0) * var(--parallax-depth) * -0.52), 0);
  }
}

/* --- Servo cooldown settle --- */
body.fx .hero-line {
  transform: translateY(calc(var(--servo, 0) * 1.1px));
}

body.fx .site-footer {
  transform: translateY(calc(var(--servo, 0) * 1.7px));
}

/* --- Manifesto phrase direction --- */
.manifesto-phrases .phrase {
  display: block;
}

/* Every viewport consumes the same cached scroll progress. Compact devices
   get a shorter distance from app.js, but the timing and sequence stay equal. */
body.fx .manifesto-phrases .phrase {
  opacity: var(--po, 0);
  transform: translate3d(var(--px, 0px), 0, 0);
}

/* --- Polarizer band reveal + phase-locked copy --- */
body.fx [data-polarize] .pword {
  display: inline-block;
  transition: opacity 280ms ease, transform 380ms var(--ease);
}

body.fx [data-polarize] .pword.is-pending {
  opacity: 0.34;
  transform: translateX(4px);
}

body.fx [data-polarize] .pword.is-live {
  opacity: 1;
  transform: none;
}

body.fx [data-polarize] .pword.is-locked {
  opacity: 0.94;
  transform: none;
}


/* --- Grid parallax (desktop; pinned static on touch/compact below) --- */
body.fx::before {
  transform: translate3d(0, calc(var(--scroll) * -55px), 0);
}

/* --- WhatsApp card construction --- */
.card-trace {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.card-trace rect {
  fill: none;
  stroke: rgba(var(--theme-fg-rgb), 0.85);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}

.message-card.is-built .card-trace rect {
  animation: capCharge 1150ms var(--ease) forwards;
}

body.fx .message-card .message-label,
body.fx .message-card strong {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 600ms ease, transform 600ms var(--ease);
}

body.fx .message-card.is-built .message-label {
  opacity: 1;
  transform: none;
  transition-delay: 420ms;
}

body.fx .message-card.is-built strong {
  opacity: 1;
  transform: none;
  transition-delay: 600ms;
}

body.fx .message-card .message-arrow {
  opacity: 0;
  transition: opacity 500ms ease, transform 280ms var(--ease), background 280ms ease, color 280ms ease;
}

body.fx .message-card.is-built .message-arrow {
  opacity: 1;
  transition: opacity 500ms ease 780ms, transform 280ms var(--ease), background 280ms ease, color 280ms ease;
}

/* phone number transmission */
.tx-char {
  display: inline-block;
}

.tx-digit {
  min-width: 0.62ch;
  text-align: center;
}

body.fx .tx-digit:not(.is-locked) {
  opacity: 0.45;
}

body.fx .tx-digit.is-locked {
  opacity: 1;
}

.whatsapp-button.is-ack .whatsapp-dot {
  animation: ackPulse 700ms ease-out 3;
}

@keyframes ackPulse {
  0% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.8); }
  100% { box-shadow: 0 0 0 14px rgba(37, 211, 102, 0); }
}

/* --- Footer energy collapse --- */
.site-footer {
  position: relative;
}

body.fx .site-footer::before {
  position: absolute;
  top: -18px;
  left: 0;
  right: 0;
  height: 1px;
  content: "";
  background: rgba(var(--theme-fg-rgb), 0.4);
  transform: scaleX(calc(1 - var(--endp, 0)));
}

/* =====================================================================
   Round 2: services and extra life
   ===================================================================== */

.hero {
  position: relative;
}

/* --- Services --- */
.services {
  padding: clamp(74px, 11vw, 140px) 0;
}

.services .section-head p {
  max-width: 560px;
  margin: 0;
  color: var(--soft);
  font-size: clamp(1rem, 1.6vw, 1.18rem);
  line-height: 1.5;
}

/* Contact copy resets after the panel leaves, so returning to the section
   replays the reveal alongside the phone transmission. */
body.fx .contact h2 span {
  opacity: 0;
  transform: translate3d(0, 0.62em, 0);
  transform-origin: left bottom;
  transition:
    opacity 420ms ease,
    transform var(--motion-slow) var(--ease-out);
}

body.fx .contact-panel.is-contact-live h2 span:nth-child(1) {
  opacity: 1;
  transform: none;
  transition-delay: 100ms;
}

body.fx .contact-panel.is-contact-live h2 span:nth-child(2) {
  opacity: 1;
  transform: none;
  transition-delay: 240ms;
}

body.fx .contact-copy > p {
  opacity: 0;
  transform: translate3d(0, var(--reveal-y), 0);
  transition:
    opacity 500ms ease,
    transform var(--motion-slow) var(--ease-out);
}

body.fx .contact-panel.is-contact-live .contact-copy > p {
  opacity: 1;
  transform: none;
  transition-delay: 430ms;
}

/* --- Section label line draws in on reveal --- */
.section-label::before {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 600ms var(--ease) 150ms;
}

.section-label.is-visible::before,
.is-visible .section-label::before {
  transform: scaleX(1);
}

body:not(.fx) .section-label::before {
  transform: scaleX(1);
}

/* The infinite CTA glint was removed â€” the button's hover lift + arrow
   nudge already signal interactivity, and a perpetual sweep is exactly the
   kind of idle motion this pass is quieting. */
/* --- Living grain --- */
body.fx .grain {
  animation: grainShift 9s steps(8) infinite;
}

/* =====================================================================
   Round 3: a11y skip link, hero depth, magnetic CTA
   ===================================================================== */

/* --- Skip link: hidden until keyboard-focused --- */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 200;
  padding: 10px 16px;
  border: 1px solid var(--line);
  background: rgb(var(--theme-bg-rgb));
  color: rgb(var(--theme-fg-rgb));
  font-family: var(--body);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transform: translateY(-180%);
  transition: transform 220ms var(--ease);
}

.skip-link:focus-visible {
  transform: translateY(0);
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* --- Hero framing + depth (desktop).
   Lift the photo so her face sits high in the frame, with just enough
   zoom that the image still fills the figure to its base â€” otherwise the
   lift exposes the figure background below the photo and the figure's
   bottom mask fades empty space instead of the image (a hard edge).
   The slow Ken Burns drifts around that framing (fx only) and pauses when
   the hero leaves the viewport. --- */
@media (min-width: 961px) {
  .hero-visual img {
    transform: scaleX(-1) translateY(-157px) scale(1.3);
  }

  body.fx .hero-visual img {
    animation: heroKenBurns 28s ease-in-out infinite alternate;
    will-change: transform;
  }
}

@media (max-width: 960px) {
  body.fx .hero-visual img {
    animation: heroKenBurnsMobile 28s ease-in-out infinite alternate;
    will-change: transform;
  }

  body.fx .grain {
    animation: none;
  }
}

@keyframes heroKenBurns {
  from { transform: scaleX(-1) translateY(-157px) scale(1.3); }
  to { transform: scaleX(-1) translateY(-164px) scale(1.33); }
}

@keyframes heroKenBurnsMobile {
  from { transform: scaleX(-1) translate3d(0, 0, 0) scale(1.08); }
  to { transform: scaleX(-1) translate3d(0, -0.8%, 0) scale(1.11); }
}

body:not(.is-hero-visible) .hero-visual img {
  animation-play-state: paused;
}

/* The magnetic CTA pull was removed: hover already communicates
   interactivity, and one interaction motion per element keeps the hierarchy
   clean (and drops a getBoundingClientRect on every pointer move). */

/* =====================================================================
   Round 4: mobile performance.
   The grain layer is a full-screen mix-blend-mode composite â€” invisible
   at phone opacity/size but costly on every repaint, so it goes. The
   theme flip on touch devices is discrete (app.js snaps it with
   hysteresis instead of scrubbing the crossover), so the registered
   channels get one slightly longer ease to make the inversion land as a
   deliberate cut rather than a stutter.
   ===================================================================== */
@media (max-width: 960px), (pointer: coarse) {
  .grain {
    display: none;
  }

  /* The grid + ambient gradients are full-screen fixed layers. Scrubbing
     their transform with --scroll repaints the whole viewport every frame —
     one of the biggest mobile costs. Pin them static; the network field
     (CSS --scroll transform on promoted layers) carries the motion instead. */
  body::before,
  body.fx::before {
    transform: none;
  }

  :root {
    transition:
      --theme-luma 360ms ease,
      --theme-bg-channel 360ms ease,
      --theme-fg-channel 360ms ease,
      --theme-inverse-channel 360ms ease;
  }
}

/* =====================================================================
   Round 5: header nav.
   ===================================================================== */

/* Anchored sections clear the fixed header when jumped to from the nav. */
#services,
#contact {
  scroll-margin-top: 96px;
}

/* --- Compact primary navigation --- */
.site-nav {
  position: absolute;
  left: 50%;
  display: inline-flex;
  align-items: center;
  gap: clamp(14px, 2vw, 28px);
  padding: 0 12px;
  font-family: var(--body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  transform: translateX(-50%);
}

.site-nav a {
  position: relative;
  color: rgba(var(--theme-fg-rgb), 0.72);
  text-shadow: 0 1px 6px rgba(var(--theme-inverse-rgb), 0.4);
  transition: color 200ms ease;
}

body.is-light .site-nav a {
  text-shadow: none;
}

.site-nav a::after {
  position: absolute;
  left: 0;
  bottom: -4px;
  width: 100%;
  height: 1px;
  content: "";
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 260ms var(--ease);
}

.site-nav a:hover,
.site-nav a:focus-visible {
  color: rgb(var(--theme-fg-rgb));
}

.site-nav a:hover::after,
.site-nav a:focus-visible::after {
  transform: scaleX(1);
}

@media (max-width: 859px) {
  .site-nav {
    display: none;
  }
}

/* =====================================================================
   Services word machine.
   The desktop list scrubs through a fixed signal band. Compact layouts
   keep the same oversized vocabulary as a natural observer-driven list.
   ===================================================================== */
.services {
  padding: clamp(86px, 11vw, 148px) 0;
}

.services-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "label count"
    "title count";
  gap: 4px clamp(24px, 4vw, 58px);
  align-items: end;
}

.services-intro .section-label {
  grid-area: label;
  align-self: end;
  margin-bottom: 8px;
}

.services-intro h2 {
  grid-area: title;
  margin: 0;
  font-family: var(--display);
  font-size: clamp(3.4rem, 6.4vw, 6.8rem);
  font-weight: 400;
  line-height: 0.86;
  letter-spacing: 0.005em;
  text-transform: uppercase;
}

.services-count {
  grid-area: count;
  display: inline-flex;
  align-items: baseline;
  align-self: end;
  gap: 8px;
  margin: 0 0 4px;
  color: rgb(var(--theme-fg-rgb));
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.services-count em {
  color: var(--muted);
  font-style: normal;
}

.services-count span {
  display: inline-block;
  min-width: 2ch;
  font-family: var(--display);
  font-size: 1.15rem;
  letter-spacing: 0.08em;
}

.services-machine {
  --service-p: 0;
  --service-index: 0;
  --service-row: clamp(118px, 18vh, 160px);
  /* Shared column template so the band's clipped clone aligns exactly
     with the base reel at every breakpoint. */
  --svc-cols: clamp(104px, 12vw, 176px) minmax(0, 1fr);
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: var(--svc-cols);
  height: calc(var(--service-row) * 3);
  overflow: hidden;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.services-band {
  position: absolute;
  top: var(--service-row);
  left: 0;
  right: 0;
  z-index: 1;
  display: grid;
  grid-template-columns: var(--svc-cols);
  height: var(--service-row);
  overflow: hidden;
  background: rgb(var(--theme-fg-rgb));
  pointer-events: none;
}

.services-band::before {
  content: none;
}

/* The clipped inverse reel inside the band. It consumes the same
   --service-p as the base list, offset by the band's one-row origin, so
   both copies are always pixel-locked — a word crossing the band edge
   flips tone exactly at the boundary. */
.services-band-viewport {
  position: relative;
  grid-column: 2;
  height: 100%;
  overflow: hidden;
}

/* body.fx prefix: must outrank the base `body.fx .services-list`
   transform in both viewport media blocks, or the clone rides one full
   row behind the reel. */
body.fx .services-band .services-list {
  transform: translate3d(0, calc(var(--service-row) * var(--service-p, 0) * -1), 0);
  will-change: transform;
  backface-visibility: hidden;
}

.services-band .service-item h3,
.services-band .service-num,
.services-band .service-copy {
  color: rgb(var(--theme-bg-rgb));
}

.services-band .service-meta {
  color: rgba(var(--theme-bg-rgb), 0.62);
}

.services-command {
  position: relative;
  z-index: 2;
  grid-column: 1;
  display: grid;
  align-content: center;
  height: var(--service-row);
  margin-top: var(--service-row);
  padding-left: clamp(14px, 2vw, 28px);
  color: rgb(var(--theme-bg-rgb));
  font-family: var(--body);
  font-size: clamp(0.82rem, 1.25vw, 1.08rem);
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.services-command span:last-child {
  margin-top: 6px;
  font-family: var(--display);
  font-size: clamp(2.6rem, 4.6vw, 4.4rem);
  font-weight: 400;
  letter-spacing: 0.02em;
}

.services-viewport {
  position: relative;
  z-index: 0;
  grid-column: 2;
  height: calc(var(--service-row) * 3);
  overflow: hidden;
}

.services-list {
  padding: 0;
  margin: 0;
  list-style: none;
}

.service-item {
  height: var(--service-row);
}

.service-item article {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(250px, 0.7fr);
  align-items: center;
  gap: clamp(22px, 4vw, 64px);
  height: 100%;
  padding: 0 clamp(34px, 5vw, 74px) 0 clamp(12px, 2vw, 28px);
}

.service-word {
  display: flex;
  align-items: baseline;
  min-width: 0;
}

.service-num {
  flex: 0 0 auto;
  width: clamp(34px, 4vw, 58px);
  margin: 0;
  color: rgba(var(--theme-fg-rgb), 0.28);
  -webkit-text-stroke: 0;
  font-family: var(--body);
  font-size: clamp(0.62rem, 0.9vw, 0.76rem);
  font-weight: 800;
  letter-spacing: 0.14em;
  transition: color 260ms ease;
}

.service-item h3 {
  margin: 0;
  color: rgba(var(--theme-fg-rgb), 0.3);
  font-family: var(--display);
  font-size: clamp(4.2rem, 7.2vw, 7.8rem);
  font-weight: 400;
  line-height: 0.74;
  letter-spacing: -0.015em;
  text-transform: uppercase;
  white-space: nowrap;
  text-shadow: none;
  transition: color 260ms ease, transform 420ms var(--ease-out);
}

.service-copy {
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 240ms ease, transform 420ms var(--ease-out);
}

.service-copy strong {
  display: block;
  margin-bottom: 8px;
  font-size: clamp(0.76rem, 1.04vw, 0.92rem);
  font-weight: 900;
  letter-spacing: 0.12em;
  line-height: 1.25;
  text-transform: uppercase;
}

.service-copy p {
  margin: 0 0 10px;
  font-size: clamp(0.8rem, 1.05vw, 0.98rem);
  line-height: 1.4;
  text-shadow: none;
}

.service-meta {
  display: block;
  margin: 0;
  font-size: clamp(0.58rem, 0.76vw, 0.68rem);
  font-weight: 800;
  letter-spacing: 0.12em;
  line-height: 1.35;
  text-transform: uppercase;
}

/* The base reel keeps one quiet tone even when active — the inverted,
   readable state lives only in the band clone. The base copy column
   never reveals under fx (even black-on-black text would silhouette
   against the network lines); non-fx layouts force it visible below. */
.service-item.is-active h3 {
  transform: translateX(clamp(4px, 0.7vw, 12px));
}

.services-band .service-item.is-active .service-copy {
  opacity: 1;
  transform: none;
}

@media (min-width: 961px) {
  body.fx .services {
    padding: 0;
  }

  body.fx .services-pin {
    height: 452vh;
  }

  body.fx .services.is-pinned .services-stage {
    position: sticky;
    top: 0;
    display: grid;
    grid-template-rows: auto auto;
    align-content: center;
    gap: clamp(18px, 3vh, 34px);
    min-height: 100vh;
    padding: clamp(72px, 9vh, 92px) 0 clamp(20px, 4vh, 38px);
  }

  body.fx .services-list {
    transform: translate3d(0, calc(var(--service-row) * (1 - var(--service-p))), 0);
    will-change: transform;
  }

  body:not(.fx) .services-intro {
    margin-bottom: 54px;
  }

  body:not(.fx) .services-machine,
  body:not(.fx) .services-viewport {
    display: block;
    height: auto;
    overflow: visible;
  }

  body:not(.fx) .services-band,
  body:not(.fx) .services-command {
    display: none;
  }

  body:not(.fx) .service-item {
    height: auto;
    min-height: 320px;
    border-top: 1px solid var(--line);
  }

  body:not(.fx) .service-item:last-child {
    border-bottom: 1px solid var(--line);
  }

  body:not(.fx) .service-item article {
    min-height: inherit;
  }

  body:not(.fx) .service-item h3,
  body:not(.fx) .service-item.is-active h3 {
    color: rgb(var(--theme-fg-rgb));
    transform: none;
  }

  body:not(.fx) .service-item .service-num,
  body:not(.fx) .service-item.is-active .service-num {
    color: var(--muted);
  }

  body:not(.fx) .service-copy,
  body:not(.fx) .service-item.is-active .service-copy {
    color: rgb(var(--theme-fg-rgb));
    opacity: 1;
    transform: none;
  }

  body:not(.fx) .service-meta,
  body:not(.fx) .service-item.is-active .service-meta {
    color: var(--muted);
  }
}

@media (max-width: 960px) {
  html {
    scroll-behavior: auto;
  }

  .services {
    padding: 88px 0 42px;
  }

  .services-intro {
    display: block;
    margin-bottom: 46px;
  }

  .services-intro .section-label {
    margin-bottom: 18px;
  }

  .services-intro h2 {
    margin-bottom: 0;
    font-size: clamp(3.2rem, 11vw, 5.6rem);
  }

  body:not(.fx) .services-count,
  body:not(.fx) .services-band,
  body:not(.fx) .services-command {
    display: none;
  }

  body:not(.fx) .services-machine,
  body:not(.fx) .services-viewport {
    display: block;
    height: auto;
    overflow: visible;
    border: 0;
  }

  body:not(.fx) .services-list {
    transform: none !important;
  }

  body:not(.fx) .service-item {
    height: auto;
    min-height: 48svh;
    border-top: 1px solid var(--line);
  }

  body:not(.fx) .service-item:last-child {
    border-bottom: 1px solid var(--line);
  }

  body:not(.fx) .service-item article {
    display: grid;
    grid-template-columns: 1fr;
    align-content: center;
    gap: 24px;
    min-height: inherit;
    padding: 46px 0;
  }

  body:not(.fx) .service-item h3,
  body:not(.fx) .service-item.is-active h3 {
    color: rgb(var(--theme-fg-rgb));
    font-size: clamp(4.2rem, 13vw, 7rem);
    white-space: normal;
    transform: none;
  }

  body:not(.fx) .service-num,
  body:not(.fx) .service-item.is-active .service-num {
    width: clamp(34px, 7vw, 54px);
    color: var(--muted);
  }

  body:not(.fx) .service-copy,
  body:not(.fx) .service-item.is-active .service-copy {
    max-width: 580px;
    color: rgb(var(--theme-fg-rgb));
    opacity: 1;
    transform: none;
  }

  body:not(.fx) .service-copy p {
    color: var(--soft);
    font-size: clamp(0.94rem, 2.4vw, 1.08rem);
  }

  body:not(.fx) .service-meta {
    color: var(--muted);
  }

  body.fx .services {
    padding: 0;
  }

  body.fx .services-pin {
    height: 320vh;
    height: 320svh;
  }

  body.fx .services.is-pinned .services-stage {
    position: sticky;
    top: 0;
    display: grid;
    grid-template-rows: auto auto;
    align-content: center;
    gap: clamp(14px, 2.2svh, 22px);
    min-height: 100vh;
    min-height: 100svh;
    padding: clamp(62px, 8svh, 78px) 0 clamp(14px, 2.5svh, 24px);
  }

  body.fx .services-intro {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "label count"
      "title count";
    gap: 3px 14px;
    align-items: end;
    margin: 0;
  }

  body.fx .services-intro .section-label {
    margin-bottom: 5px;
  }

  body.fx .services-intro h2 {
    font-size: clamp(2.7rem, 10.5vw, 5rem);
  }

  body.fx .services-count {
    display: inline-flex;
    margin-bottom: 2px;
  }

  body.fx .services-machine {
    --service-row: clamp(118px, calc((100svh - 300px) / 3), 156px);
    --svc-cols: clamp(50px, 14vw, 74px) minmax(0, 1fr);
    display: grid;
    grid-template-columns: var(--svc-cols);
    height: calc(var(--service-row) * 3);
    overflow: hidden;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    contain: layout paint;
  }

  body.fx .services-band,
  body.fx .services-command {
    display: grid;
  }

  body.fx .services-band {
    top: var(--service-row);
  }

  body.fx .services-command {
    height: var(--service-row);
    margin-top: var(--service-row);
    padding-left: 9px;
    font-size: 0.72rem;
    letter-spacing: 0.12em;
  }

  body.fx .services-command span:last-child {
    margin-top: 5px;
    font-size: clamp(1.8rem, 6vw, 2.8rem);
  }

  body.fx .services-viewport {
    position: relative;
    display: block;
    height: calc(var(--service-row) * 3);
    overflow: hidden;
  }

  body.fx .services-list {
    transform: translate3d(0, calc(var(--service-row) * (1 - var(--service-p))), 0);
    will-change: transform;
    backface-visibility: hidden;
  }

  body.fx .service-item {
    display: block;
    position: relative;
    contain: layout;
    height: var(--service-row);
    min-height: 0;
    border: 0;
    opacity: 1;
    pointer-events: auto;
    transform: none;
    backface-visibility: hidden;
  }

  body.fx .service-item article {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-content: center;
    height: 100%;
    min-height: 0;
    padding: 10px clamp(12px, 3vw, 22px);
    opacity: 1;
  }

  body.fx .service-num {
    display: none;
  }

  body.fx .service-item h3 {
    font-size: clamp(2.45rem, 12.6vw, 4.8rem);
    line-height: 0.76;
    white-space: nowrap;
    transform: none;
  }

  body.fx .service-copy {
    display: none;
  }

  .service-copy,
  .service-num {
    display: none;
  }

  body.fx .service-item.is-active h3 {
    transform: translateX(clamp(4px, 1.5vw, 10px));
  }
}

@media (max-width: 560px) {
  body:not(.fx) .services {
    padding-top: 74px;
  }

  body:not(.fx) .services-intro {
    margin-bottom: 28px;
  }

  body:not(.fx) .service-item {
    min-height: 54svh;
  }

  body:not(.fx) .service-item article {
    padding: 40px 0;
  }

  body:not(.fx) .service-item h3,
  body:not(.fx) .service-item.is-active h3 {
    font-size: clamp(2.9rem, 14.5vw, 5.6rem);
    line-height: 0.8;
  }

  body:not(.fx) .service-copy strong {
    font-size: 0.72rem;
  }

  body.fx .services.is-pinned .services-stage {
    gap: clamp(12px, 2svh, 18px);
    padding-top: clamp(58px, 7.5svh, 70px);
  }

  body.fx .services-intro h2 {
    font-size: clamp(2.5rem, 12vw, 3.8rem);
    line-height: 0.84;
  }

  body.fx .services-count {
    gap: 5px;
    font-size: 0.54rem;
    letter-spacing: 0.12em;
  }

  body.fx .services-count span {
    font-size: 0.92rem;
  }

  body.fx .services-machine {
    --service-row: clamp(116px, calc((100svh - 280px) / 3), 148px);
    --svc-cols: 50px minmax(0, 1fr);
    grid-template-columns: var(--svc-cols);
    border-color: rgba(var(--theme-fg-rgb), 0.28);
  }

  body.fx .services-command {
    display: grid;
    grid-column: 1;
    width: 50px;
    padding-left: 8px;
    font-size: 0.68rem;
    letter-spacing: 0.1em;
  }

  body.fx .services-command span:last-child {
    margin-top: 5px;
    font-size: 2rem;
  }

  body.fx .services-band {
    box-shadow: none;
  }

  body.fx .services-viewport {
    grid-column: 2;
  }

  body.fx .service-item article {
    padding: 12px clamp(5px, 1.5vw, 10px);
  }

  body.fx .service-item h3 {
    line-height: 0.76;
  }
}

@media (max-width: 560px) and (max-height: 680px) {
  body.fx .services.is-pinned .services-stage {
    gap: 8px;
    padding-top: 54px;
    padding-bottom: 10px;
  }

  body.fx .services-intro h2 {
    font-size: clamp(2rem, 9.5vw, 2.8rem);
  }

  body.fx .services-machine {
    --service-row: clamp(104px, calc((100svh - 220px) / 3), 124px);
  }

  body.fx .service-item article {
    padding-top: 9px;
    padding-bottom: 9px;
  }

  body.fx .service-item h3 {
    font-size: clamp(2.4rem, 12.4vw, 3.1rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .services-list,
  .service-item,
  .service-item h3,
  .service-copy {
    transition: none !important;
    transform: none !important;
  }
}

/* =====================================================================
   404 — a static page (no JS): shares the token system and type, needs
   nothing revealed or animated to be complete.
   ===================================================================== */
.notfound {
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 6px;
  min-height: 100vh;
  min-height: 100svh;
  padding: 120px var(--pad) 90px;
  text-align: center;
}

.notfound h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(7rem, 26vw, 17rem);
  font-weight: 400;
  line-height: 0.85;
  text-transform: uppercase;
}

.notfound p {
  margin: 0;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.notfound .button {
  min-width: min(280px, 76vw);
  margin-top: 34px;
  padding-right: 72px;
  text-align: left;
}
