/* ---------- Fonts ----------
   Self-hosted rather than linked from fonts.googleapis.com. That link was the
   single render-blocking request on the page (~1.45s of the LCP), because it
   costs a DNS+TLS handshake to googleapis, then another to gstatic, before the
   headline can paint. Served from our own origin it rides the existing
   connection. Variable font, so one file covers weights 100-900. */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geist-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: "Geist";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../assets/fonts/geist-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ---------- Tokens ---------- */
:root {
  --black: #000000;
  --graphite: #0D0D0F;
  --graphite-2: #131316;
  --graphite-3: #1B1B1F;
  --gray: #8A8983;
  --off-white: #F5F3EF;
  --wine: #6E1423;
  --wine-light: #A62A3A;
  --bronze: #B08D57;

  --border: rgba(245, 243, 239, 0.09);
  --border-strong: rgba(245, 243, 239, 0.16);

  --radius-sm: 8px;
  --radius-md: 14px;
  --radius-lg: 22px;

  --ease: cubic-bezier(.16, 1, .3, 1);
}

/* ---------- Reveal-on-scroll (portfolio, services, CTA) ----------
   Same fade + blur + lift language as .footer__anim, generalized since it's
   no longer footer-specific. Driven by the existing revealOnce() helper: the
   ancestor section gets .is-visible once, each .reveal child inside it
   un-hides on its own --d delay for a light stagger.
   Placed here, near the top of the cascade, on purpose: several .reveal
   targets (.card, .service-card, .cta__open) have their own :hover or
   .is-hiding state defined later in this file at the same specificity
   (2 classes). Declaration order breaks the tie, so this has to come first
   for those later rules to still win once an element has been revealed. */
.reveal {
  opacity: 0;
  filter: blur(4px);
  transform: translateY(16px);
  transition: opacity .7s var(--ease), filter .7s var(--ease), transform .7s var(--ease);
  transition-delay: var(--d, 0s);
}
.is-visible .reveal { opacity: 1; filter: blur(0); transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; filter: none; transform: none; transition: none; }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* Headings evened out across their lines instead of filling each line and
   dropping whatever is left onto the last one. Four of them stranded a single
   word on a line of its own at some window width, worst in Portuguese where
   the translations run longer ("Marcas e criadores com quem já / trabalhei").
   The browser does the balancing, so it holds at every width, in both
   languages, and for whatever the copy says later; browsers without support
   wrap as before.

   Listed one by one rather than as `h1, h2, h3`. Balancing re-runs line
   breaking over the whole block, and applying it to all twenty headings on
   the page (card titles, form steps, footer) cost 2.3s of Speed Index and
   4x the blocking time, measured against an otherwise identical build. Only
   these five are display-sized enough to wrap at all, and scoped to them the
   cost is back in the noise. */
.hero__headline, .section-head h2, .trust h2, .cta h2 { text-wrap: balance; }

/* Mobile Safari/Chrome paint a translucent blue rectangle over the whole hit
   box of anything tappable. On controls whose visible shape is smaller than
   their hit box (the language toggle, the nav's icon button) that rectangle
   reads as a stray selection box appearing out of nowhere. Every control here
   already has its own :active/:hover feedback, so the default is pure noise. */
a, button, summary, label, [role="button"], [role="switch"] {
  -webkit-tap-highlight-color: transparent;
}

html { scroll-behavior: smooth; }

body {
  background: var(--graphite);
  color: var(--off-white);
  font-family: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; text-decoration: none; }
img, video { display: block; max-width: 100%; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--bronze);
}

/* ---------- Layered background pattern (KSG palette) ---------- */
.bg-pattern {
  position: fixed;
  inset: 0;
  z-index: -2;
  overflow: hidden;
  pointer-events: none;
  background: var(--black);
}
.bg-pattern__base {
  position: absolute;
  inset: 0;
  background: radial-gradient(100% 100% at 0% 0%, #201417 0%, #000000 100%);
  -webkit-mask: radial-gradient(125% 100% at 0% 0%, #000 0%, rgba(0, 0, 0, 0.22) 88.29%, rgba(0, 0, 0, 0) 100%);
  mask: radial-gradient(125% 100% at 0% 0%, #000 0%, rgba(0, 0, 0, 0.22) 88.29%, rgba(0, 0, 0, 0) 100%);
}
.bg-pattern__streak {
  position: absolute;
  inset: 0;
  opacity: 0.05;
  background: linear-gradient(var(--wine-light) 0%, rgba(166, 42, 58, 0) 100%);
  transform: skewX(45deg);
}
.bg-pattern__streak--1 {
  -webkit-mask: linear-gradient(90deg, transparent 0%, #000 20%, transparent 36%, #000 55%, rgba(0, 0, 0, .13) 67%, #000 78%, transparent 97%);
  mask: linear-gradient(90deg, transparent 0%, #000 20%, transparent 36%, #000 55%, rgba(0, 0, 0, .13) 67%, #000 78%, transparent 97%);
}
.bg-pattern__streak--2 {
  -webkit-mask: linear-gradient(90deg, transparent 11%, #000 25%, rgba(0, 0, 0, .55) 41%, rgba(0, 0, 0, .13) 67%, #000 78%, transparent 97%);
  mask: linear-gradient(90deg, transparent 11%, #000 25%, rgba(0, 0, 0, .55) 41%, rgba(0, 0, 0, .13) 67%, #000 78%, transparent 97%);
}
.bg-pattern__streak--3 {
  -webkit-mask: linear-gradient(90deg, transparent 9%, #000 20%, rgba(0, 0, 0, .55) 28%, rgba(0, 0, 0, .42) 40%, #000 48%, rgba(0, 0, 0, .27) 54%, rgba(0, 0, 0, .13) 78%, #000 88%, transparent 97%);
  mask: linear-gradient(90deg, transparent 9%, #000 20%, rgba(0, 0, 0, .55) 28%, rgba(0, 0, 0, .42) 40%, #000 48%, rgba(0, 0, 0, .27) 54%, rgba(0, 0, 0, .13) 78%, #000 88%, transparent 97%);
}
.bg-pattern__streak--4 {
  -webkit-mask: linear-gradient(90deg, transparent 0%, #000 17%, rgba(0, 0, 0, .55) 26%, #000 35%, transparent 47%, rgba(0, 0, 0, .13) 69%, #000 79%, transparent 97%);
  mask: linear-gradient(90deg, transparent 0%, #000 17%, rgba(0, 0, 0, .55) 26%, #000 35%, transparent 47%, rgba(0, 0, 0, .13) 69%, #000 79%, transparent 97%);
}
.bg-pattern__streak--5 {
  -webkit-mask: linear-gradient(90deg, transparent 0%, #000 20%, rgba(0, 0, 0, .55) 27%, #000 42%, transparent 48%, rgba(0, 0, 0, .13) 67%, #000 74%, #000 82%, rgba(0, 0, 0, .47) 88%, transparent 97%);
  mask: linear-gradient(90deg, transparent 0%, #000 20%, rgba(0, 0, 0, .55) 27%, #000 42%, transparent 48%, rgba(0, 0, 0, .13) 67%, #000 74%, #000 82%, rgba(0, 0, 0, .47) 88%, transparent 97%);
}
.bg-pattern__dots {
  position: absolute;
  inset: 0;
  opacity: 0.14;
  background-image: radial-gradient(circle at 1px 1px, rgba(245, 243, 239, 0.5) 1px, transparent 0);
  background-size: 20px 20px;
}
.bg-pattern__highlight {
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 50% at 12% 8%, rgba(176, 141, 87, 0.10), transparent 70%);
}

/* grain */
.noise {
  position: fixed;
  inset: 0;
  z-index: 999;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  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='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Floating nav (collapses to a pill on scroll down) ---------- */
.floating-nav {
  position: fixed;
  top: 20px;
  left: 50%;
  translate: -50% 0;
  z-index: 100;
  display: flex;
  align-items: center;
  gap: 28px;
  height: 52px;
  padding: 0 22px;
  max-width: 560px;
  overflow: hidden;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: rgba(13, 13, 15, 0.65);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  will-change: max-width, padding;
  contain: layout style;
  transition:
    max-width .5s var(--ease),
    padding .5s var(--ease),
    background .3s ease,
    border-color .3s ease;
}
.floating-nav__mark {
  flex-shrink: 0;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.02em;
  transition: opacity .32s var(--ease);
}
.floating-nav__links {
  display: flex;
  gap: 22px;
  font-size: 0.85rem;
  color: var(--gray);
  white-space: nowrap;
  transition: opacity .32s var(--ease);
}
.floating-nav__links a { transition: color .2s var(--ease); }
.floating-nav__links a:hover { color: var(--off-white); }
.floating-nav__links a.floating-nav__cta {
  flex-shrink: 0;
  font-weight: 600;
  color: var(--off-white);
  transition: opacity .32s var(--ease), color .2s var(--ease);
}
.floating-nav__links a.floating-nav__cta:hover { color: var(--bronze); }
.floating-nav__icon {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  display: flex;
  color: var(--off-white);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s var(--ease);
}

.floating-nav.is-collapsed {
  max-width: 52px;
  padding: 0;
  justify-content: center;
  cursor: pointer;
  border-color: var(--border-strong);
}
.floating-nav.is-collapsed:hover { background: rgba(13, 13, 15, 0.85); }
.floating-nav.is-collapsed .floating-nav__mark,
.floating-nav.is-collapsed .floating-nav__links,
.floating-nav.is-collapsed .floating-nav__cta {
  opacity: 0;
  pointer-events: none;
  transition-duration: .18s;
}
.floating-nav.is-collapsed .floating-nav__icon {
  opacity: 1;
  transition-delay: .2s;
}

/* Close button. Hidden outright on desktop (where the nav collapses on scroll
   and there is nothing to dismiss), so it is never a stray tab stop there. */
.floating-nav__close {
  position: absolute;
  top: 15px;
  right: 16px;
  display: none;
  align-items: center;
  padding: 2px;
  background: none;
  border: none;
  color: var(--gray);
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s var(--ease), color .2s var(--ease);
}
.floating-nav__close:hover { color: var(--off-white); }

/* Mobile: the link row never fit across a phone. Laid out horizontally it
   overflowed the pill and clipped the last item ("Get a quote") against the
   rounded edge, so open it becomes a stacked panel instead: every link gets
   its own line, and the freed corner holds the close button. Collapsed it is
   the same 52px circle as before, and max-height (not height) is what
   animates, since the panel's real height depends on its text.

   Anchored to the right edge here rather than centred like the desktop bar.
   A panel that opens in the middle of the screen is attached to nothing and
   reads as appearing out of nowhere; pinned to the corner it visibly belongs
   to the button that opened it, and the collapse shrinks back toward that
   button instead of toward empty space. The language toggle moves to the
   opposite corner to make room (see .lang-toggle below). */
@media (max-width: 720px) {
  .floating-nav {
    /* absolute, not fixed: on a phone it belongs to the top of the page rather
       than to the screen. It is there the moment the page opens and scrolls
       out of view with everything else, instead of riding along over the
       content. Desktop keeps the fixed bar. */
    position: absolute;
    left: auto;
    right: 16px;
    translate: none;
    transform-origin: top right;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
    height: auto;
    max-height: 240px;
    /* Fixed width, not shrink-to-fit: the links are the widest thing in here
       and they change length with the language, so an auto-width panel visibly
       resized when the EN/PT toggle was flipped. */
    width: 190px;
    max-width: 190px;
    padding: 15px 20px 18px;
    border-radius: 20px;
    will-change: max-width, max-height, padding;
    transition:
      max-width .45s var(--ease),
      max-height .45s var(--ease),
      padding .45s var(--ease),
      border-radius .45s var(--ease),
      opacity .35s var(--ease),
      translate .35s var(--ease),
      background .3s ease,
      border-color .3s ease;
  }
  .floating-nav__links {
    flex-direction: column;
    gap: 12px;
    font-size: 0.95rem;
  }
  .floating-nav.is-collapsed {
    max-width: 52px;
    max-height: 52px;
    padding: 0;
    border-radius: 999px;
  }
  .floating-nav__close { display: flex; }
  .floating-nav:not(.is-collapsed) .floating-nav__close {
    opacity: 1;
    pointer-events: auto;
    transition-delay: .18s;
  }
}

/* ---------- Language toggle ----------
   Sibling of .hero__inner (not a child of it), so it positions against the
   full-width .hero box rather than the 760px-wide centered column, landing
   in the actual corner. Absolute inside .hero (position: relative), so unlike
   .floating-nav (fixed) it scrolls away with the hero instead of staying
   pinned to the viewport. Left corner at every width: the nav owns the right
   one on mobile, and keeping the two on the same sides across breakpoints
   means the control doesn't jump corners when the window is resized. */
.lang-toggle {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px;
  /* Fade/lift out as the page scrolls (opacity + translate + scale set inline
     by script.js, scroll-driven), instead of an abrupt clip once it crosses
     the hero boundary. transition smooths the two states set inline. */
  transition: opacity .35s var(--ease), transform .35s var(--ease);
  will-change: opacity, transform;
}
@media (prefers-reduced-motion: reduce) {
  .lang-toggle { transition: opacity .35s linear; }
}
.lang-toggle__label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--gray);
  transition: color .25s var(--ease);
}
.lang-toggle[aria-checked="true"] .lang-toggle__label--pt,
.lang-toggle:not([aria-checked="true"]) .lang-toggle__label--en {
  color: var(--off-white);
}
.lang-toggle__track {
  position: relative;
  width: 48px;
  height: 27px;
  border-radius: 999px;
  background: var(--graphite-3);
  border: 1px solid var(--border-strong);
  transition: background .3s var(--ease), border-color .3s var(--ease), transform .15s var(--ease);
}
.lang-toggle[aria-checked="true"] .lang-toggle__track {
  background: linear-gradient(135deg, var(--wine), var(--wine-light));
  border-color: transparent;
}
.lang-toggle__knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  background: var(--off-white);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  transition: translate .3s var(--ease);
}
.lang-toggle[aria-checked="true"] .lang-toggle__knob { translate: 21px 0; }
.lang-toggle:focus-visible .lang-toggle__track { box-shadow: 0 0 0 3px rgba(176, 141, 87, 0.35); }

/* Pressed feedback, replacing the browser's default blue tap rectangle
   (disabled above) with something that matches the rest of the site. Applied
   to the track, not to .lang-toggle itself: the scroll fade writes an inline
   transform on the button, and an inline style would win over this rule for
   any scroll position past the very top. */
.lang-toggle:active .lang-toggle__track { transform: scale(0.94); }

/* On mobile the EN/PT labels used to be display:none, which left a bare
   switch in the corner with nothing saying what it switched. The labels ARE
   the affordance here, so they stay; the control just gets tighter and picks
   up the same glass-pill treatment as .floating-nav so it reads as a
   deliberate control sitting beside the nav rather than a stray toggle. */
@media (max-width: 720px) {
  .lang-toggle {
    /* Centred against the nav's 52px pill (top 20px) rather than flush to the
       corner, so the two read as one row instead of two different heights. */
    top: 28px;
    left: 14px;
    gap: 6px;
    padding: 5px 10px;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: rgba(13, 13, 15, 0.65);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
  }
  .lang-toggle__label { font-size: 0.66rem; }
  .lang-toggle__track { width: 40px; height: 23px; }
  .lang-toggle__knob { width: 17px; height: 17px; }
  .lang-toggle[aria-checked="true"] .lang-toggle__knob { translate: 17px 0; }

}

/* ---------- Buttons ---------- */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 26px;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  /* Needed for <button class="btn">: a native button otherwise picks up the
     UA buttonface background and its own font, which turned .btn--outline
     into a white pill with invisible off-white text. No-ops on the <a> uses. */
  background: transparent;
  font-family: inherit;
  cursor: pointer;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), background .25s var(--ease), border-color .25s var(--ease);
  isolation: isolate;
  overflow: hidden;
}
.btn:active { transform: scale(0.97); }

.btn--primary {
  background: linear-gradient(135deg, var(--wine) 0%, var(--wine-light) 100%);
  color: var(--off-white);
  box-shadow: 0 8px 24px -8px rgba(166, 42, 58, 0.55);
}
.btn--primary::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 20%, rgba(255,255,255,0.35) 38%, transparent 55%);
  transform: translateX(-120%);
  z-index: -1;
}
.btn--primary:hover::before { transform: translateX(120%); transition: transform .8s var(--ease); }
.btn--primary:hover { box-shadow: 0 10px 30px -6px rgba(166, 42, 58, 0.7); transform: translateY(-1px); }

.btn--lg { padding: 16px 34px; font-size: 1rem; }

.btn--outline {
  border-color: var(--border-strong);
  color: var(--off-white);
}
.btn--outline:hover { border-color: var(--bronze); background: rgba(176, 141, 87, 0.08); }

.btn--ghost {
  border-color: var(--border-strong);
  color: var(--off-white);
  font-size: 0.8rem;
}
.btn--ghost:hover { border-color: var(--off-white); }

/* ---------- Hero ----------
   Deliberately shorter than 100svh: the next section peeks in at the bottom
   of the fold so there's something to be curious about, instead of a dead
   band of empty space under the CTAs. */
.hero {
  position: relative;
  min-height: 84svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 128px 20px 36px;
  overflow: hidden;
}
.hero__inner {
  position: relative;
  z-index: 1;
  max-width: 760px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
}
.hero__inner > * { min-width: 0; max-width: 100%; }
.hero__headline {
  font-size: clamp(2.4rem, 6.4vw, 4.6rem);
  font-weight: 500;
  line-height: 1.06;
  letter-spacing: -0.02em;
}
.hero__headline .accent { color: var(--wine-light); }
.hero__sub {
  max-width: 540px;
  color: var(--gray);
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  line-height: 1.6;
}
.hero__cta {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 10px;
}
/* ---------- Section shared ---------- */
section { padding: 110px clamp(20px, 5vw, 64px); position: relative; }
.section-head {
  max-width: 640px;
  width: 100%;
  margin: 0 auto 52px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
}
.section-head > * { min-width: 0; max-width: 100%; }
.section-head h2 {
  font-size: clamp(1.8rem, 3.4vw, 2.6rem);
  font-weight: 500;
  line-height: 1.15;
  letter-spacing: -0.015em;
}
.section-sub { color: var(--gray); font-size: 0.95rem; }

/* ---------- Portfolio grid + filters ---------- */
/* Pulled up close under the hero (which the next section peeks into) instead
   of the default section padding, to close the empty-space gap between them. */
.work { max-width: 1100px; margin: 0 auto; padding-top: 48px; }

.work__filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: -20px 0 44px;
}
.filter-btn {
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: transparent;
  color: var(--gray);
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .25s var(--ease), color .25s var(--ease), background .25s var(--ease);
}
.filter-btn:hover { border-color: var(--bronze); color: var(--off-white); }
.filter-btn.is-active {
  background: linear-gradient(135deg, var(--wine), var(--wine-light));
  border-color: transparent;
  color: var(--off-white);
}

.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
}
@media (min-width: 720px) {
  .grid { grid-template-columns: repeat(3, 1fr); gap: 22px; }
}

.card {
  position: relative;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--graphite-2);
  cursor: pointer;
  transition: transform .35s var(--ease), border-color .35s var(--ease), box-shadow .35s var(--ease), opacity .3s var(--ease);
}
.card:hover {
  transform: translateY(-6px);
  border-color: var(--border-strong);
  box-shadow: 0 20px 45px -20px rgba(166, 42, 58, 0.45);
}
.card.is-hidden { display: none; }

.card__media {
  position: relative;
  aspect-ratio: 9 / 16;
  background: var(--graphite-3);
}
.card__media img,
.card__media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card__media video { opacity: 0; transition: opacity .3s var(--ease); }
.card__media.is-playing video { opacity: 1; }
.card__media.is-playing img { opacity: 0; }

/* Hover reveal: icon + title + tag centered over a blurred scrim, same model as the
   reference gallery component, but driving the existing video-preview mechanism. */
.card__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  padding: 20px;
  background: linear-gradient(180deg, rgba(13,13,15,0.15) 0%, rgba(13,13,15,0.55) 60%, rgba(13,13,15,0.8) 100%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.card:hover .card__overlay,
.card__media.is-playing .card__overlay { opacity: 1; }

.card__overlay-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; height: 44px;
  border-radius: 50%;
  color: var(--off-white);
  background: rgba(245,243,239,0.1);
  border: 1px solid rgba(245,243,239,0.3);
  transform: scale(0.85);
  transition: transform .35s var(--ease);
}
.card:hover .card__overlay-icon { transform: scale(1); }

.card__overlay h3 {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--off-white);
}
.tag {
  font-size: 0.65rem;
  color: var(--bronze);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.9;
}

/* Touch devices have no hover: keep the caption legible without needing a tap-hold.
   No backdrop blur here (unlike the desktop hover state) since it was permanently
   softening the whole poster/preview, not just the text underneath it. */
@media (hover: none) {
  .card__overlay {
    opacity: 1;
    align-items: flex-start;
    justify-content: flex-end;
    padding: 22px 14px 12px;
    gap: 3px;
    background: linear-gradient(180deg, transparent 0%, rgba(13, 13, 15, 0.35) 45%, rgba(13, 13, 15, 0.65) 100%);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .card__overlay-icon { display: none; }
}

/* ---------- Trusted by (logo cloud, two-row infinite marquee) ---------- */
.trust { max-width: 1100px; margin: 0 auto; padding-top: 70px; padding-bottom: 70px; content-visibility: auto; contain-intrinsic-size: auto 320px; }

.trust__marquee {
  display: flex;
  flex-direction: column;
  gap: 28px;
  opacity: 0;
  transition: opacity .8s var(--ease);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.trust__marquee.is-visible { opacity: 1; }

.trust__track {
  display: flex;
  align-items: center;
  gap: 48px;
  width: max-content;
  animation: trustScrollLeft 34s linear infinite;
}
.trust__track:hover { animation-play-state: paused; }
.trust__track--reverse { animation-name: trustScrollRight; animation-duration: 28s; }

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

.trust__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  flex-shrink: 0;
  opacity: 0.55;
  transition: opacity .3s var(--ease);
}
.trust__logo:hover { opacity: 1; }
.trust__logo img {
  height: 100%;
  width: auto;
  max-width: 120px;
  object-fit: contain;
  /* Flattens mixed-color/mixed-brightness source logos into a single clean
     white mark so files with dark or saturated colors stay legible on a
     dark background without needing per-logo color correction. */
  filter: brightness(0) invert(1);
}

@media (max-width: 640px) {
  .trust__track { gap: 34px; }
  .trust__logo { height: 26px; }
}
@media (prefers-reduced-motion: reduce) {
  .trust__track { animation: none; }
}

/* ---------- Services ---------- */
.services { max-width: 1100px; margin: 0 auto; content-visibility: auto; contain-intrinsic-size: auto 480px; }
.service-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
.service-card {
  padding: 30px 26px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: linear-gradient(180deg, var(--graphite-2), var(--graphite));
  transition: transform .3s var(--ease), border-color .3s var(--ease);
}
.service-card:hover {
  transform: translateY(-4px);
  border-color: rgba(176, 141, 87, 0.4);
}
.service-card__icon {
  display: inline-block;
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--bronze);
  border: 1px solid rgba(176, 141, 87, 0.4);
  border-radius: 999px;
  padding: 4px 10px;
  margin-bottom: 18px;
}
.service-card h3 { font-size: 1.08rem; font-weight: 600; margin-bottom: 10px; }
.service-card p { color: var(--gray); font-size: 0.9rem; line-height: 1.6; }

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

/* ---------- CTA ---------- */
.cta {
  max-width: 720px;
  width: 100%;
  margin: 0 auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  content-visibility: auto;
  contain-intrinsic-size: auto 420px;
}
.cta > * { min-width: 0; max-width: 100%; }
.cta__glow {
  position: absolute;
  top: 10%;
  left: 50%;
  translate: -50% 0;
  width: 700px;
  height: 500px;
  background: radial-gradient(closest-side, rgba(166, 42, 58, 0.28), transparent 70%);
  filter: blur(6px);
  z-index: -1;
}
.cta h2 {
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.15;
}
.cta__sub { color: var(--gray); max-width: 480px; }
.cta .btn--primary { margin-top: 8px; }

/* Explicit process plan: turns the vague "answer a few questions, I reply"
   promise into stepping stones, so the path to working together reads as
   low-risk instead of open-ended. */
.cta__plan {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 460px;
  width: 100%;
  margin: 2px 0 0;
  text-align: left;
}
.cta__plan li {
  display: flex;
  align-items: flex-start;
  gap: 13px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--off-white);
}
.cta__plan-num {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-top: 1px;
  border-radius: 50%;
  border: 1px solid rgba(176, 141, 87, 0.4);
  color: var(--bronze);
  font-size: 0.72rem;
  font-weight: 700;
}

/* Risk-reversal line, set apart from the plan so it reads as a standing
   policy rather than another step in the sequence. */
.cta__guarantee {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  max-width: 460px;
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: rgba(176, 141, 87, 0.05);
  color: var(--gray);
  font-size: 0.86rem;
  line-height: 1.55;
  text-align: left;
}
.cta__guarantee strong { color: var(--off-white); font-weight: 600; }
.cta__guarantee svg { flex-shrink: 0; margin-top: 2px; color: var(--bronze); }

@media (max-width: 560px) {
  .cta__plan, .cta__guarantee { max-width: 100%; }
}
.cta__contacts {
  margin-top: 14px;
  font-size: 0.85rem;
  color: var(--gray);
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}
.cta__contacts a:hover { color: var(--off-white); }
.cta__contacts .dot { color: var(--border-strong); }

/* ---------- Lead form (3-step wizard) ----------
   Replaces the old mailto: CTA. mailto: silently dead-ends for anyone on
   webmail, which is most of the US audience this page targets. */
/* Reveal: the grid 0fr -> 1fr trick animates to the form's natural height
   without hardcoding a max-height that would clip or stutter. The inner
   element carries the fade and lift so the card arrives rather than snaps.
   Kept inert while collapsed, otherwise the whole form stays tabbable and
   readable to screen readers while invisible. */
.lead-form__reveal {
  display: grid;
  grid-template-rows: 0fr;
  width: 100%;
  transition: grid-template-rows .62s var(--ease);
}
.lead-form__reveal.is-open { grid-template-rows: 1fr; }
.lead-form__reveal-inner {
  min-height: 0;
  overflow: hidden;
  opacity: 0;
  transform: translateY(14px) scale(.985);
  transition: opacity .5s var(--ease) .08s, transform .55s var(--ease) .08s;
}
.lead-form__reveal.is-open .lead-form__reveal-inner {
  opacity: 1;
  transform: none;
}

.cta__open {
  transition: opacity .28s var(--ease), transform .28s var(--ease);
}
.cta__open.is-hiding {
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
}

.lead-form {
  width: 100%;
  max-width: 560px;
  margin: 10px auto 0;
  text-align: left;
  padding: 28px clamp(20px, 4vw, 32px) 24px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: linear-gradient(180deg, var(--graphite-2), var(--graphite));
  box-shadow: 0 30px 70px -40px rgba(0, 0, 0, 0.9);
}

/* Progress: dots for position, bar for proportion. Wine matches the primary
   button so "forward motion" reads as the same accent as the main CTA. */
.lead-form__progress { margin-bottom: 26px; }
.lead-form__dots {
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
}
.lead-form__dot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  flex: 1;
  background: none;
  border: 0;
  padding: 0;
  color: var(--gray);
  font: inherit;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  cursor: default;
}
.lead-form__dot[data-reachable="true"] { cursor: pointer; }
.lead-form__dot::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--graphite-3);
  border: 1px solid var(--border-strong);
  transition: background .3s var(--ease), box-shadow .3s var(--ease), border-color .3s var(--ease);
}
.lead-form__dot[data-state="done"]::before {
  background: var(--wine-light);
  border-color: transparent;
}
.lead-form__dot[data-state="current"]::before {
  background: var(--wine-light);
  border-color: transparent;
  box-shadow: 0 0 0 4px rgba(166, 42, 58, 0.22);
}
.lead-form__dot[data-state="current"] { color: var(--off-white); font-weight: 600; }

.lead-form__bar {
  height: 3px;
  border-radius: 999px;
  background: var(--graphite-3);
  overflow: hidden;
}
.lead-form__bar span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--wine), var(--wine-light));
  transition: width .4s var(--ease);
}

/* Only the active step is in flow; min-height keeps the card from snapping
   between wildly different heights as steps change. */
.lead-form__body { min-height: 336px; }
/* These steps are <section> elements, so the global `section` rule would hand
   them 110px of page-level padding. Reset it. */
.lead-form__step { display: none; padding: 0; }
.lead-form__step.is-active {
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: stepIn .32s var(--ease) both;
}
@keyframes stepIn {
  from { opacity: 0; transform: translateX(18px); }
  to   { opacity: 1; transform: translateX(0); }
}
.lead-form__step-title { font-size: 1.05rem; font-weight: 600; }
.lead-form__step-sub { color: var(--gray); font-size: 0.85rem; margin-top: -10px; }

.field { display: flex; flex-direction: column; gap: 7px; }
.field > label,
.fieldset > legend {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--off-white);
}
.field input,
.field textarea {
  width: 100%;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: rgba(245, 243, 239, 0.03);
  color: var(--off-white);
  font-family: inherit;
  font-size: 0.9rem;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
.field textarea { min-height: 84px; resize: vertical; }
.field__optional { color: var(--gray); font-weight: 400; }
.field input::placeholder,
.field textarea::placeholder { color: rgba(138, 137, 131, 0.7); }
.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--bronze);
  background: rgba(245, 243, 239, 0.05);
}
.field input[aria-invalid="true"] { border-color: var(--wine-light); }

.fieldset { border: 0; display: flex; flex-direction: column; gap: 9px; }
.fieldset > legend { margin-bottom: 2px; }

/* Choice rows: real radio inputs kept for keyboard and screen-reader support,
   visually replaced by the dot below. */
.choice {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  cursor: pointer;
  transition: border-color .25s var(--ease), background .25s var(--ease);
}
.choice:hover { border-color: var(--border-strong); background: rgba(245, 243, 239, 0.02); }
.choice input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.choice__dot {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  transition: border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.choice input:checked ~ .choice__dot {
  border-color: var(--bronze);
  box-shadow: inset 0 0 0 4px var(--bronze);
}
.choice:has(input:checked) {
  border-color: rgba(176, 141, 87, 0.5);
  background: rgba(176, 141, 87, 0.08);
}
.choice input:focus-visible ~ .choice__dot { box-shadow: 0 0 0 3px rgba(176, 141, 87, 0.35); }
.choice__label { font-size: 0.88rem; line-height: 1.4; }
/* The scope hint is what stops a price range from reading as "my rate" and
   makes it read as "what this size of order buys". */
.choice__hint {
  display: block;
  font-style: normal;
  font-size: 0.76rem;
  color: var(--gray);
  margin-top: 2px;
}

.lead-form__hp {
  position: absolute;
  left: -9999px;
  opacity: 0;
  pointer-events: none;
}

.lead-form__nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-top: 22px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
.lead-form__nav .btn { padding: 11px 22px; font-size: 0.85rem; }
.lead-form__back[hidden] { display: none; }
/* Keeps the forward action on the right even on step 1, where Back is hidden
   and space-between would otherwise leave this as the only child and park it
   on the left, reading as though it went backwards. */
.lead-form__submit { margin-left: auto; }
.lead-form__submit[disabled] { opacity: 0.5; cursor: not-allowed; }
.lead-form__submit[disabled]:hover { transform: none; box-shadow: 0 8px 24px -8px rgba(166, 42, 58, 0.55); }

.lead-form__error {
  margin-top: 14px;
  font-size: 0.82rem;
  color: var(--wine-light);
  line-height: 1.5;
}
.lead-form__error a { text-decoration: underline; }
.lead-form__error[hidden] { display: none; }

.spinner {
  width: 14px;
  height: 14px;
  margin-right: 8px;
  border-radius: 50%;
  border: 2px solid rgba(245, 243, 239, 0.35);
  border-top-color: var(--off-white);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* .lead-form__success sets display:flex, which would beat the UA [hidden]
   rule, so the attribute needs an explicit override to still work. */
.lead-form__success[hidden] { display: none; }
.lead-form__success {
  text-align: center;
  padding: 26px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  animation: stepIn .35s var(--ease) both;
}
.lead-form__success-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  color: var(--bronze);
  border: 1px solid rgba(176, 141, 87, 0.45);
  background: rgba(176, 141, 87, 0.1);
}
.lead-form__success h3 { font-size: 1.15rem; font-weight: 600; }
.lead-form__success p { color: var(--gray); font-size: 0.9rem; max-width: 340px; line-height: 1.6; }
/* Same override as the container above: .btn is display:inline-flex, which
   would otherwise win over the UA [hidden] rule and show this in English. */
.lead-form__wa[hidden] { display: none; }
.lead-form__wa { margin-top: 4px; }

@media (max-width: 560px) {
  .lead-form { padding: 24px 18px 20px; }
  .lead-form__body { min-height: 0; }
  .lead-form__dot { font-size: 0; gap: 0; }
  .lead-form__dot[data-state="current"] { font-size: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .lead-form__step.is-active,
  .lead-form__success { animation: none; }
  .lead-form__bar span { transition: none; }
  .spinner { animation-duration: 2s; }
  .lead-form__reveal,
  .lead-form__reveal-inner,
  .cta__open { transition: none; }
}

/* ---------- Footer ---------- */
.footer {
  position: relative;
  max-width: 1100px;
  margin: 0 auto;
  padding: 52px clamp(24px, 5vw, 64px) 36px;
  border: 1px solid var(--border);
  border-bottom: none;
  border-radius: 32px 32px 0 0;
  background: radial-gradient(35% 140px at 50% 0%, rgba(245, 243, 239, 0.06), transparent);
  overflow: hidden;
  content-visibility: auto;
  contain-intrinsic-size: auto 340px;
}
.footer__glow {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -50%;
  width: 33%;
  height: 1px;
  border-radius: 999px;
  background: rgba(245, 243, 239, 0.28);
  filter: blur(2px);
}
.footer__inner {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 40px;
}
.footer__mark { display: block; font-weight: 700; font-size: 1.1rem; letter-spacing: -0.02em; margin-bottom: 10px; }
.footer__copy { color: var(--gray); font-size: 0.8rem; max-width: 260px; line-height: 1.6; }
.footer__cols { display: flex; gap: 56px; flex-wrap: wrap; }
.footer__col h3 {
  font-size: 0.68rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--bronze);
  margin-bottom: 14px;
}
.footer__col ul { display: flex; flex-direction: column; gap: 9px; font-size: 0.86rem; color: var(--gray); list-style: none; }
.footer__col a { transition: color .2s var(--ease); }
.footer__col a:hover { color: var(--off-white); }

.footer__anim {
  opacity: 0;
  filter: blur(4px);
  transform: translateY(-8px);
  transition: opacity .8s var(--ease), filter .8s var(--ease), transform .8s var(--ease);
  transition-delay: var(--d, 0s);
}
.footer.is-visible .footer__anim {
  opacity: 1;
  filter: blur(0);
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .footer__anim { opacity: 1; filter: none; transform: none; transition: none; }
}

@media (max-width: 560px) {
  .footer { border-radius: 24px 24px 0 0; padding-top: 44px; }
  .footer__inner { gap: 32px; }
  .footer__cols { gap: 36px; }
}

/* ---------- Mobile rhythm ----------
   The 110px top+bottom section padding is tuned for desktop, where the eye
   crosses a wide column. Stacked on a phone it compounds: 110 bottom + 110 top
   left ~220px of dead space between sections, so the page read as disconnected
   blocks. Tightened here only; desktop spacing is unchanged. */
@media (max-width: 720px) {
  section { padding-top: 56px; padding-bottom: 56px; }
  .work { padding-top: 32px; }
  .trust { padding-top: 40px; padding-bottom: 40px; }
  .services { padding-top: 56px; }
  .section-head { margin-bottom: 34px; }
  .work__filters { margin: -14px 0 30px; }
}

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 5, 6, 0.86);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
.lightbox.is-open { opacity: 1; pointer-events: auto; }
.lightbox__stage {
  width: min(420px, 88vw);
  aspect-ratio: 9/16;
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,0.8);
  transform: scale(0.96);
  transition: transform .3s var(--ease);
}
.lightbox.is-open .lightbox__stage { transform: scale(1); }
.lightbox__stage video { width: 100%; height: 100%; object-fit: cover; }
.lightbox__close {
  position: absolute;
  top: 24px; right: 28px;
  width: 42px; height: 42px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: rgba(255,255,255,0.04);
  color: var(--off-white);
  font-size: 1.4rem;
  cursor: pointer;
}
.lightbox__close:hover { border-color: var(--off-white); }

.lightbox__nav {
  position: absolute;
  top: 50%;
  translate: 0 -50%;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  background: rgba(255,255,255,0.04);
  color: var(--off-white);
  font-size: 1.7rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.lightbox__nav:hover { border-color: var(--off-white); background: rgba(255,255,255,0.08); }
.lightbox__nav--prev { left: clamp(10px, 4vw, 40px); }
.lightbox__nav--next { right: clamp(10px, 4vw, 40px); }

@media (max-width: 560px) {
  .lightbox__close { top: 14px; right: 14px; width: 38px; height: 38px; font-size: 1.2rem; }
  .lightbox__nav { width: 38px; height: 38px; font-size: 1.4rem; }
}
