/* ============ Tokens ============ */
:root {
  --bg-dark: #1a1a1a;
  --bg-panel: #2e2e2e;
  --bg-hero: #3a3a3a;
  --bg-light: #f8f8f8;
  --accent: #def876;
  --accent-text: #aecb39;
  --border-light: #e9e9e9;
  --border-feature: #e4e4e4;
  --border-dark: #2e2e2e;
  --border-footer: #1d1d1d;
  --white-80: rgba(255, 255, 255, 0.8);
  --white-60: rgba(255, 255, 255, 0.6);
  /* "40" tokens are lifted to 0.55/0.62 alpha: at 0.4 the muted text (form labels, kickers,
     tags) composites to ~3.8:1 on dark / ~2.9:1 on light — below the WCAG AA 4.5:1 minimum.
     These values clear AA while keeping the muted look. */
  --white-40: rgba(255, 255, 255, 0.55);
  --black-60: rgba(0, 0, 0, 0.6);
  --black-40: rgba(0, 0, 0, 0.62);
  /* 40px gutters up to 1440; beyond that the gutters grow so content caps at ~1360px
     (the design width) and stays centered instead of stretching across huge screens.
     --sbw (set by JS) subtracts the scrollbar width so content stays perfectly centered. */
  --sbw: 0px;
  --pad-x: max(40px, calc((100vw - var(--sbw) - 1360px) / 2));
  --font: "Geist", -apple-system, sans-serif;
}

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

html { scroll-behavior: smooth; }

body {
  font-family: var(--font);
  background: var(--bg-dark);
  color: #fff;
  -webkit-font-smoothing: antialiased;
}

img { display: block; }
[hidden] { display: none !important; }
ul { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; background: none; border: none; cursor: pointer; color: inherit; }

/* Type scale (V+V Desktop styles) */
.section-title {
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
}

.section-dark { background: var(--bg-dark); color: #fff; }
.section-light { background: var(--bg-light); color: #000; }

/* Center column guides (3 hairlines over middle band) */
.grid-lines {
  position: absolute;
  inset: 0 0 0 auto;
  left: calc(37.5% + 12px);
  width: 47.36%;
  pointer-events: none;
  background-image: url("../assets/grid-lines.svg");
  background-size: 100% 100%;
  z-index: 0;
}

/* ============ Buttons ============ */
.btn {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  height: 60px;
  padding: 4px 4px 4px 16px;
  border-radius: 5px;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.32px;
  white-space: nowrap;
  transition: color 0.25s ease 0.1s, border-color 0.3s ease;
}
/* Green arrow square stretches right-to-left inside the button (Figma Button/Hover: 326x52 fill inset 4px, dark shell stays) */
.btn::before {
  content: "";
  position: absolute;
  top: 4px;
  bottom: 4px;
  right: 4px;
  left: calc(100% - 56px);
  border-radius: 2px;
  background: var(--accent);
  transition: left 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn > * { position: relative; z-index: 1; }
.btn:hover { color: #000; font-weight: 600; }
.btn:hover::before { left: 4px; }
.btn--dark { background: var(--bg-panel); color: #fff; }
.btn--white { background: #fff; color: #000; }
.btn--bordered:hover { border-color: var(--accent); }
.btn--bordered { border: 1px solid var(--border-light); width: 334px; max-width: 100%; }
.btn__icon { width: 52px; height: 52px; flex-shrink: 0; }
.btn__icon img { width: 100%; height: 100%; transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1); }
.btn:hover .btn__icon img { transform: translateX(5px); }

/* ============ Header ============ */
.header {
  position: fixed; /* stays available: hides on scroll down, returns on scroll up */
  top: 22px;
  left: 0;
  right: 0;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 0 var(--pad-x);
  z-index: 50; /* over page content, under the mobile menu overlay (100) */
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
/* scrolling down — tuck it away; scrolling up brings it back */
.header.is-hidden { transform: translateY(-130%); }
/* the intro rise-in animation is fill:forwards, which would outrank the transform above;
   JS drops the animation once it has played so the hide/show transform can take over */
.header.is-ready { animation: none; opacity: 1; }

/* Soft top scrim behind the bar so the white nav/logo stay legible over the bright animated
   scene — a gradient that fades to nothing (not a solid pill). Hidden over light sections where
   the bar already inverts to black. It's a header child so it hides together with the bar. */
.header::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 130px;
  z-index: -1; /* behind the nav/logo, above page content */
  pointer-events: none;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0.15) 55%, transparent);
  opacity: 1;
  transition: opacity 0.3s ease;
}
.header--on-light::before { opacity: 0; } /* no dark scrim over light sections */

/* No backdrop — instead the bar inverts over light sections (JS toggles .header--on-light):
   white logo/nav/button on dark, black on the light #work / #pricing sections. */
.menu a,
.menu-toggle span,
.logo img,
.header__cta { transition: color 0.3s ease, background-color 0.3s ease, filter 0.3s ease; }
.header--on-light .menu a { color: #000; }
.header--on-light .logo img { filter: invert(1) brightness(0.85); } /* white wordmark → near-black */
.header--on-light .menu-toggle span { background: #000; }
/* the CTA stays its usual grey (--bg-panel) on light sections too — it reads fine and matches
   every other button on the site */
.logo { width: 93px; height: 32px; flex-shrink: 0; }
.logo img { width: 100%; height: 100%; }
.menu {
  display: flex;
  gap: 24px;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.32px;
}
.menu a { position: relative; opacity: 1; transition: opacity 0.15s ease; }
/* Hairline slides in from the left on hover, retreats to the right on leave */
.menu a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.menu a:hover::after { transform: scaleX(1); transform-origin: left; }
.header__cta { width: 334px; flex-shrink: 0; }
.menu-toggle { display: none; }

/* ============ Hero ============ */
.hero {
  position: relative;
  height: 100vh;
  height: 100dvh; /* exactly one screen; dvh tracks the visible viewport (mobile browser chrome) */
  /* --vh is set by the large-screen scaler: under zoom, 100dvh would overflow by the zoom factor */
  height: var(--vh, 100dvh);
  min-height: 600px; /* floor so content never crushes into the header on very short windows */
  /* Dark base (matches the scene's near-black tone) instead of the old bg.webp still — the animated
     scene fades in over this, so there's no jarring swap from an unrelated static image. */
  background: #0e100c;
  overflow: hidden;
}
/* Reduced-motion / no-WebGL users don't get the animated scene, so give them the static texture. */
@media (prefers-reduced-motion: reduce) {
  .hero { background: var(--bg-hero) url("../assets/bg.webp") center / cover no-repeat; }
}
/* Animated Unicorn Studio scene, layered over the static bg.webp poster. Fades in once ready;
   pointer-events:none so header/hero clicks + page scroll pass straight through to the page. */
.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
}
.hero__bg.is-ready { opacity: 1; }
.hero .grid-lines { display: none; } /* no guide hairlines over the animated hero — kept on other sections */
/* readability scrim: darkens the lower half (where the title/subtitle sit) so white text stays
   legible no matter how bright the animated scene gets. Above the scene, below the content. */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.62), rgba(0, 0, 0, 0.22) 40%, transparent 66%);
}
.hero__bg canvas { display: block; width: 100% !important; height: 100% !important; }
.hero__title {
  position: absolute;
  left: var(--pad-x);
  top: auto;
  bottom: 110px; /* anchored to the bottom-left so it holds its place at any viewport height */
  font-size: 80px;
  font-weight: 400;
  line-height: 0.85;
  letter-spacing: -4.8px;
  color: var(--white-80);
  z-index: 1;
}
.hero__subtitle {
  position: absolute;
  left: var(--pad-x);
  top: auto;
  bottom: 24px;
  width: 338px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--white-60);
  z-index: 1;
}
.hero__card {
  position: absolute;
  right: var(--pad-x); /* flush to the right content edge, same as the header CTA (was a fragile left calc that drifted off 1440) */
  top: auto;
  bottom: 24px;
  width: 358px;
  height: 300px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  padding: 12px;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  z-index: 1;
}
.hero__card-icon {
  width: 45px;
  height: 45px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hero__card-icon img { width: 32px; height: 32px; transform: rotate(-45deg); }
.hero__card p {
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.32px;
  color: var(--white-80);
}
.hero__card .btn { width: 100%; }

/* ============ Statement / side panel ============ */
.statement {
  position: relative;
  padding: 120px var(--pad-x) 180px;
}
.statement__inner {
  position: relative;
  display: flex;
  gap: 176px;
  align-items: flex-start;
  z-index: 1;
}

.side-panel {
  width: 337px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.side-panel__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.side-panel__counter {
  font-size: 16px;
  font-weight: 400;
  letter-spacing: -0.48px;
  line-height: 1;
  text-transform: uppercase;
  color: var(--white-40);
}
.side-panel__arrows { display: flex; gap: 4px; }
.arrow { position: relative; width: 40px; height: 24px; padding: 0; transition: opacity 0.15s ease; }
/* Invisible halo extends the 40×24 visual to a ≥44px hit area (a11y tap-target minimum) */
.arrow::after { content: ""; position: absolute; inset: -10px -4px; }
.arrow:hover { opacity: 0.8; }
.arrow img { width: 100%; height: 100%; }
.arrow--prev img { transform: rotate(180deg); }
.side-panel__rule {
  position: relative;
  height: 2px;
  width: 100%;
  background: #3b3b3b;
  overflow: hidden;
}
.side-panel__rule::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--progress, 66.34%);
  background: #787878;
  transition: width 0.4s ease;
}

.stat { display: flex; flex-direction: column; gap: 8px; }
.stat__value {
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
}
.stat__label {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--white-60);
}

.statement__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.statement__text {
  position: relative;
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
  color: #323232; /* plain gray base (design's unlit text) — no background-clip, so no edge halo */
}
/* Gradient overlay layer, revealed word-by-word on scroll (white → lime → olive → #323232) */
.statement__fill {
  position: absolute;
  inset: 0;
  pointer-events: none;
  /* stays lime all the way down, so every revealed word (incl. the last line) reads as lit */
  background: linear-gradient(180deg, #f4ffd0 0%, #def876 24%, #cbe75f 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.statement__fill .word { opacity: 0; transition: opacity 0.5s ease; }
.statement__fill .word.is-on { opacity: 1; }

.person { display: flex; align-items: center; gap: 16px; }
.person__avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-panel);
  flex-shrink: 0;
}
.person__avatar img { width: 100%; height: 100%; object-fit: cover; }
.person__meta {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--white-60);
}
.person__meta br { content: ""; display: block; margin-top: 4px; }
.person__meta--sm { font-size: 16px; letter-spacing: -0.32px; }

/* ============ Selected Work ============ */
.work { padding: 120px 0 180px; display: flex; flex-direction: column; gap: 60px; }
.work .section-title { padding: 0 var(--pad-x); }
.work__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px 4px;
  padding: 0 var(--pad-x);
}
.work-card { display: flex; flex-direction: column; gap: 16px; min-width: 0; /* let the 1fr grid track shrink so the nowrap desc can't force page-wide overflow */ }
.work-card__media {
  position: relative;
  height: 596px;
  border-radius: 8px;
  overflow: hidden;
  display: block;
}
.work-card__media img {
  position: relative;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.5s ease, filter 0.5s ease;
}
/* second cover shown on hover — a reduced panel floating over the blurred base image.
   Selector is scoped to .work-card__media so it outranks `.work-card__media img`
   (otherwise that rule's transition/height/z-index would win). */
.work-card__media img.work-card__media-hover {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(0.96);
  /* keep the hover cover's native proportions — no cropping. It scales down to fit
     within the card (whichever of max-width/max-height binds first). */
  width: auto;
  height: auto;
  max-width: 82%;
  max-height: 76%;
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.45);
  z-index: 2; /* above the dark ::after overlay (z-index 1) */
  opacity: 0;
  transition: opacity 0.45s ease, transform 0.45s ease;
  pointer-events: none;
}
/* hover: blur + darken the image */
.work-card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(0, 0, 0, 0.3);
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
.work-card__caption {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 0 24px;
}
.work-card__head {
  display: flex;
  align-items: center;
  gap: 16px;
  overflow: hidden; /* never let the hover caption spill past the card edge */
}
.work-card__name {
  flex-shrink: 0; /* keep the highlighted name intact; the description shrinks instead */
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.72px;
  color: #000;
  transition: background 0.25s ease;
}
/* bullet + description are a hover-only extra — fully removed (not just transparent) so
   they don't reserve width and overflow on touch screens */
.work-card__dot {
  display: none;
  width: 8px;
  height: 8px;
  flex-shrink: 0;
  background: #000;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.work-card__desc {
  display: none;
  min-width: 0; /* allow it to shrink below its text width so the ellipsis kicks in */
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.72px;
  color: #000;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.25s ease;
}

/* Hover state lives on desktop only (real pointer) — never triggers on a tap, so nothing
   blurs/expands or overflows on mobile. */
@media (hover: hover) {
  .work-card__dot,
  .work-card__desc { display: block; }
  /* only blur/darken when there's a hover cover to reveal — cards without one (e.g. NVIDIA
     until its hover asset lands) keep a clean static image instead of an empty dark panel */
  .work-card:has(.work-card__media-hover):hover .work-card__media img:not(.work-card__media-hover) { transform: scale(1.08); filter: blur(8px); }
  .work-card:has(.work-card__media-hover):hover .work-card__media::after { opacity: 1; }
  .work-card:hover .work-card__media img.work-card__media-hover { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  .work-card:hover .work-card__name { background: var(--accent); }
  .work-card:hover .work-card__dot,
  .work-card:hover .work-card__desc { opacity: 1; }
}
.work-card__tags {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--black-40);
}

/* ============ Services ============ */
.services {
  position: relative;
}
.services__sticky {
  position: relative;
  overflow: hidden;
  padding: 160px var(--pad-x);
}
.services__inner { width: 100%; }
.services__inner {
  position: relative;
  display: flex;
  gap: 176px;
  align-items: flex-start;
  z-index: 1;
}
.testimonial { display: flex; flex-direction: column; gap: 16px; }
.testimonial-slide {
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: slide-fade 0.35s ease;
}
@keyframes slide-fade {
  from { opacity: 0; transform: translateX(8px); }
  to { opacity: 1; transform: none; }
}
.testimonial__label {
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.32px;
  color: var(--white-40);
}
.testimonial__quote {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
}
.services__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 80px;
}
.services__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  font-size: 80px;
  font-weight: 400;
  line-height: 0.85;
  letter-spacing: -4.8px;
  color: var(--bg-panel);
}
.services__list li { transition: color 0.2s ease; cursor: default; }
.services__list li.is-active,
.services__list li:hover { color: #fff; }
.services__media {
  position: absolute;
  right: var(--pad-x);
  top: 50%;
  transform: translateY(-50%);
  width: 507px;
  height: 408px;
  border-radius: 8px;
  overflow: hidden;
  mix-blend-mode: difference;
  z-index: 2;
  pointer-events: none;
}
.services__media img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 860px;
  height: 600px;
  object-fit: cover;
  border-radius: 16px;
  opacity: 0;
  transition: opacity 0.45s ease;
}
.services__media img.is-visible { opacity: 1; }

/* ============ Process ============ */
.process {
  position: relative;
  padding: 60px var(--pad-x) 180px;
  display: flex;
  flex-direction: column;
  gap: 60px;
}
.process .section-title { position: relative; z-index: 1; }
.process__list { position: relative; display: flex; flex-direction: column; z-index: 1; }
.process-step {
  position: relative;
  display: flex;
  align-items: flex-start;
}
.process-step:first-child::before,
.process-step::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--border-dark);
}
.process-step:first-child::before { top: 0; }
.process-step::after { bottom: 0; }
.process-step__label {
  width: 167px;
  flex-shrink: 0;
  padding: 32px 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.32px;
  color: var(--white-40);
}
.process-step__info {
  width: 507px;
  padding: 32px 0;
  margin-left: 4px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.process-step__heading {
  display: flex;
  align-items: flex-start;
  gap: 8px;
}
.process-step__heading h3 {
  font-size: 32px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.96px;
}
.process-step__duration {
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.32px;
  color: var(--accent-text);
}
.process-step__desc {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--white-60);
}
.process-step__media {
  position: relative;
  margin-left: auto;
  width: 507px;
  height: 350px;
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
  isolation: isolate; /* contain the halftone blend so it can't mix with the page behind */
}
.process-step__media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Videos reproduce the exact Figma framing (node 414:915): each clip is scaled and offset
   inside the 507×350 card. Percentages of the card box, so the crop holds on mobile too
   (the mobile card keeps the same 1.449 aspect). height:auto preserves the clip's ratio. */
.process-step__media video {
  position: absolute;
  display: block;
  height: auto;
}
.process-step:nth-child(1) .process-step__media video { width: 184.68%; left: -51.08%; bottom: -29.71%; }
.process-step:nth-child(2) .process-step__media video { width: 144.16%; left: -1.18%; top: -1.43%; transform: scaleX(-1); }
.process-step:nth-child(3) .process-step__media video { width: 117.16%; left: -16.77%; top: -27.71%; }
.process-step:nth-child(4) .process-step__media video { width: 143.39%; left: 0; top: -37.14%; }
/* The green duotone grade (Figma "overlay color") is now BAKED INTO the video files.
   It used to be a color-burn overlay here, but color-burn divides by the source colour, so in
   dark frame areas tiny per-channel differences exploded into coloured blotches — invisible on
   sRGB desktop, glaring on iPhone (Display-P3 blending over a hardware video layer).
   Baked with the identical maths (ffmpeg burn @ 0.48 in RGB), so the look is unchanged. */
/* signature halftone pattern kept on top of the video (Figma FW_Cross overlay) */
.process-step__pattern {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: url("../assets/cross-bitmap-small.jpg") center / cover no-repeat;
  mix-blend-mode: soft-light;
  opacity: 0.85;
}

/* ============ Pricing ============ */
.pricing {
  background: #fff;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  column-gap: 0; /* columns sit at the edges via space-between (fits the capped 1360 width) */
  row-gap: 60px; /* if they wrap on mid-size screens, this spaces the stacked columns */
  padding: 120px var(--pad-x) 180px;
}
.pricing__intro {
  position: sticky;
  top: 120px;
  display: flex;
  flex-direction: column;
  gap: 32px;
  width: 507px;
  flex-shrink: 0; /* wrap (stack) on mid-size screens instead of squishing */
}
.pricing__connect {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.72px;
  color: var(--accent-text);
}
.pricing__connect img { width: 24px; height: 20px; }
.pricing__content {
  width: 847px;
  max-width: 100%;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 60px;
}
.pricing__cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
}
.price-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 500px;
  padding: 24px;
  border-radius: 4px;
  border: 1px solid var(--border-light);
  background: var(--bg-light);
  overflow: hidden;
  position: relative;
}
.price-card--accent { background: var(--accent); }
.price-card--accent::before {
  content: "";
  position: absolute;
  inset: -48px; /* headroom so the drift animation never exposes a bare edge */
  background: url("../assets/cross-bitmap-small.jpg") center / cover no-repeat;
  opacity: 0.2;
  mix-blend-mode: hard-light;
  pointer-events: none;
}
.price-card--accent > * { position: relative; }
.price-card--custom {
  grid-column: 2;
  height: auto;
  gap: 32px;
  justify-content: flex-start;
}
.price-card__top { display: flex; flex-direction: column; gap: 32px; }
.price-card__heading { display: flex; flex-direction: column; gap: 16px; }
.price-card__kicker {
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  color: var(--black-40);
}
.price-card__price {
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
  color: #000;
}
.price-card__features li {
  padding: 10px 0;
  border-bottom: 1px solid var(--border-feature);
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: #000;
}
.price-card--accent .price-card__features li { border-bottom-color: var(--accent-text); }

/* ============ FAQ ============ */
.faq { display: flex; flex-direction: column; gap: 4px; }
.faq__item {
  border: 0.667px solid var(--border-light);
  border-radius: 8px;
}
.faq__item.is-open { background: var(--bg-light); }
.faq__item summary {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 32px;
  padding: 24.667px;
  cursor: pointer;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__question {
  font-size: 24px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.72px;
  color: #000;
}
/* Toggle icon: keeps the custom plus/× SVGs, morphing between them with a rotate + crossfade */
.faq__icon {
  position: relative;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
}
.faq__icon img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
/* Cross sits underneath as a solid base; only the plus on top fades — the square never
   goes semi-transparent mid-transition, so there's no flicker/jump. */
.faq__icon-cross { opacity: 1; }
.faq__icon-plus {
  opacity: 1;
  z-index: 1;
  transition: opacity 0.5s ease-in-out;
}
.faq__item.is-open .faq__icon-plus { opacity: 0; }
/* Grid-rows accordion: 0fr → 1fr collapses cleanly (padding lives on the inner element,
   so there's no border-box padding "floor" and no jump). */
.faq__answer {
  display: grid;
  grid-template-rows: 0fr;
  font-size: 0;
  line-height: 0;
  transition: grid-template-rows 0.4s ease-in-out, opacity 0.3s ease;
  opacity: 0;
}
.faq__item.is-open .faq__answer {
  grid-template-rows: 1fr;
  opacity: 1;
}
.faq__answer-clip {
  overflow: hidden;
  min-height: 0;
} /* pure clipper — no padding, so the track collapses to exactly 0 */
.faq__answer-inner {
  padding: 8px 24.667px 24.667px;
  max-width: 718px;
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--black-60);
}

/* ============ CTA ============ */
.cta {
  position: relative;
  padding: 180px 10px 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 48px;
  background: #000 url("../assets/cta-bg.webp") center / cover no-repeat;
  overflow: hidden;
}
.cta::after {
  content: "";
  position: absolute;
  inset: 0;
  background: url("../assets/cross-bitmap-small.jpg") center / cover no-repeat;
  mix-blend-mode: soft-light;
  pointer-events: none;
}
.cta > * { position: relative; z-index: 1; }
.cta__title {
  max-width: 1018px;
  text-align: center;
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
}
.cta__btn-label { font-weight: 600; }

/* ============ Footer ============ */
.footer {
  background: var(--bg-dark);
  padding-top: 100px;
  display: flex;
  flex-direction: column;
  gap: 148px;
}
.footer__top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 0 var(--pad-x);
}
.footer__kicker {
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  color: var(--white-40);
}
.footer__nav-col {
  width: 513px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.footer__nav { display: flex; flex-direction: column; gap: 4px; }
.footer__nav a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 60px;
  padding: 0 4px 0 0;
  border-bottom: 1px solid var(--border-footer);
  border-radius: 3px;
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
  transition: background 0.15s ease, padding 0.15s ease;
}
.footer__nav-icon {
  width: 52px;
  height: 52px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.footer__nav-icon img { width: 100%; height: 100%; }
.footer__nav a:hover {
  background: var(--bg-panel);
  padding-left: 12px;
}
.footer__nav a:hover .footer__nav-icon { opacity: 1; }

.footer__details {
  width: 507px;
  display: flex;
  flex-direction: column;
  gap: 32px;
}
.footer__links-row { display: flex; gap: 4px; }
.footer__links-col {
  width: 166px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.footer__links { display: flex; flex-direction: column; }
.footer__links a {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  /* vertical padding (in place of list gap) grows the ~24px hit height toward the 44px
     tap-target minimum without changing the visual rhythm */
  padding: 8px 0;
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
}
.footer__links a:hover { color: var(--accent); }
.footer__links img { width: 24px; height: 24px; }
.footer__contact { display: flex; flex-direction: column; gap: 16px; }
.footer__email {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
}
.footer__email a:hover { color: var(--accent); }
.footer__location {
  font-size: 18px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.36px;
  color: var(--white-40);
  margin-top: -8px;
}

.footer__band {
  height: 280px;
  background: var(--bg-dark); /* animated Unicorn scene sits on top; no static image here anymore */
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.footer__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
}
.footer__bg.is-ready { opacity: 1; }
.footer__bg canvas { display: block; width: 100% !important; height: 100% !important; }
/* keep the clock/copyright readable over the scene */
.footer__band::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent 70%);
}
.footer__band-row {
  width: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  padding: 0 var(--pad-x) 40px;
  font-size: 16px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.32px;
}
.footer__clock { display: flex; flex-direction: column; gap: 8px; }

/* ============ Mobile menu (Figma: Menu Mob) ============ */
body.menu-open { overflow: hidden; }

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  /* No justify-content:space-between here: combined with overflow-y:auto it clips overflowing
     content ABOVE the scroll origin on short viewports (landscape phones), stranding the close
     button off-screen. margin-top:auto on __bottom gives the same layout without the trap. */
  padding: 24px 16px 36px;
  background: #0e100c; /* dark base, same as the hero — the animated scene fades in over it */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s;
  overflow-y: auto;
}
.mobile-menu.is-open { opacity: 1; visibility: visible; }
/* Animated Unicorn Studio scene — same one as the hero. Initialised on first open (see main.js)
   and fades in once ready. pointer-events:none so taps pass through to the menu content above. */
.mobile-menu__bg {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
}
.mobile-menu__bg.is-ready { opacity: 1; }
.mobile-menu__bg canvas { display: block; width: 100% !important; height: 100% !important; }
/* readability scrim over the animation, under the content */
.mobile-menu::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.55));
  pointer-events: none;
}
.mobile-menu > *:not(.mobile-menu__bg) { position: relative; z-index: 2; }

.mobile-menu__main { display: flex; flex-direction: column; gap: 80px; }
.mobile-menu__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 60px;
}
.mobile-menu__close { width: 52px; height: 52px; padding: 0; flex-shrink: 0; }
.mobile-menu__close img { width: 100%; height: 100%; }

.mobile-menu__nav { display: flex; flex-direction: column; gap: 16px; }
.mobile-menu__kicker {
  font-size: 16px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -0.48px;
  text-transform: uppercase;
  color: var(--white-40);
}
.mobile-menu__links { display: flex; flex-direction: column; gap: 4px; }
.mobile-menu__links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 60px;
  padding-right: 4px;
  border-bottom: 1px solid var(--border-footer);
  border-radius: 3px;
  font-size: 56px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -3.36px;
  color: #fff;
  transition: background 0.15s ease, padding 0.15s ease;
}
.mobile-menu__arrow { width: 52px; height: 52px; flex-shrink: 0; opacity: 0; transition: opacity 0.15s ease; }
.mobile-menu__arrow img { width: 100%; height: 100%; }
.mobile-menu__links a:hover,
.mobile-menu__links a:active {
  background: var(--bg-panel);
  padding-left: 12px;
}
.mobile-menu__links a:hover .mobile-menu__arrow,
.mobile-menu__links a:active .mobile-menu__arrow { opacity: 1; }

.mobile-menu__bottom { display: flex; flex-direction: column; gap: 16px; margin-top: auto; padding-top: 40px; }
.mobile-menu__socials { display: flex; gap: 4px; }
.mobile-menu__socials a {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 19px 8px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  transition: background 0.15s ease;
}
.mobile-menu__socials a:hover { background: rgba(255, 255, 255, 0.1); }
.mobile-menu__socials img { width: 32px; height: 32px; }

/* ============ Tablet / small laptop (901–1300px) ============ */
/* The layout is designed for a 1360px canvas; between the mobile breakpoint and ~1300px the
   fixed-width absolute pieces start colliding. Shrink/cap them so nothing overlaps. */
@media (min-width: 901px) and (max-width: 1300px) {
  /* Hero: smaller title, lifted fully above the glass card so the last line can't run under it */
  .hero__title { font-size: 64px; letter-spacing: -3.84px; bottom: 348px; }

  /* Services: cap the floating media so it can't reach the testimonial column on the left */
  .services__media { width: min(507px, 40vw); height: auto; aspect-ratio: 507 / 408; }

  /* The 176px column gap starves the content column at this width */
  .statement__inner, .services__inner { gap: 80px; }
}

/* ============ Mobile ============ */
@media (max-width: 900px) {
  :root { --pad-x: 16px; }

  .grid-lines { left: 40.5%; width: 40.3%; }

  /* Header */
  .menu, .header__cta { display: none; }
  .header { top: 24px; }
  .menu-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 6px;
    width: 52px;
    height: 52px;
    margin-left: auto;
    border-radius: 2px;
    background: var(--accent);
  }
  .menu-toggle span {
    display: block;
    width: 22px;
    height: 2px;
    background: #fff; /* white over dark sections; .header--on-light flips it to black */
  }

  /* Hero */
  .hero__title {
    top: auto;
    bottom: 393px; /* bottom-anchored (from the 800px mobile reference) */
    font-size: 56px;
    letter-spacing: -3.36px;
  }
  .hero__subtitle { top: auto; bottom: 274px; width: 338px; }
  .hero__card {
    left: var(--pad-x);
    right: var(--pad-x);
    top: auto;
    bottom: 24px;
    width: auto;
    height: 225px;
  }

  /* Statement */
  .statement { padding: 80px var(--pad-x) 120px; }
  .statement__inner { flex-direction: column-reverse; gap: 120px; }
  .side-panel { width: 100%; }
  .statement__text { font-size: 32px; letter-spacing: -1.92px; }
  .statement__body { gap: 32px; }

  /* Work */
  .work { padding: 80px 0 120px; gap: 40px; }
  .work .section-title { font-size: 40px; letter-spacing: -2.4px; }
  .work__grid { grid-template-columns: 1fr; gap: 24px; }
  .work-card__media { height: 358px; }
  .work-card__caption { padding: 0; }

  /* Services — pinned scrollytelling on mobile too (section pins, cycles 4 services +
     images on scroll like desktop); the testimonial stays below within the pinned view.
     Top-aligned (not centered) with design-proportional gaps (title↔list : list↔testimonial
     ≈ 1:2, like Figma's 80/160) — as generous as fits the pinned viewport. */
  .services__sticky {
    padding: 80px var(--pad-x);
  }
  .services__inner { flex-direction: column-reverse; gap: 64px; } /* list ↔ testimonial */
  .section-title { font-size: 40px; letter-spacing: -2.4px; }
  .services__body { gap: 40px; } /* title ↔ list */
  /* Figma mobile (511:296): 56px list; the active service (white) cuts through the image
     via mix-blend-difference, inactive items #2e2e2e. Active item driven by JS (.is-active). */
  .services__list {
    position: relative;
    /* Scale with the viewport so "Website design" fits a 360/375px screen instead of being
       clipped by the sticky wrapper's overflow:hidden (nowrap keeps each name on one line). */
    font-size: min(56px, 13.4vw);
    letter-spacing: -0.06em;
    gap: 16px;
    white-space: nowrap;
  }
  /* Mobile: no photo behind the service list for now — just the names. Without the
     difference-blended image the #2e2e2e text would be invisible on the dark background,
     so inactive items get a readable muted white (the active one stays solid #fff). */
  .services__media { display: none; }
  .services__list { color: var(--white-40); }

  /* Process */
  .process { padding: 80px var(--pad-x) 120px; gap: 40px; }
  .process-step { flex-wrap: wrap; padding-bottom: 18px; }
  .process-step__label { width: 100%; padding: 32px 0 0; }
  .process-step__info { width: 100%; margin-left: 0; padding: 32px 0 16px; }
  .process-step__media { width: 100%; height: 247px; margin-left: 0; }

  /* Pricing */
  .pricing { flex-direction: column; padding: 80px var(--pad-x) 120px; gap: 80px; }
  .pricing__intro { position: static; width: 100%; }
  .pricing__content { width: 100%; }
  .pricing__cards { grid-template-columns: 1fr; }
  .price-card--custom { grid-column: 1; }
  .faq__question { font-size: 20px; letter-spacing: -0.6px; }

  /* CTA */
  .cta { padding: 120px 16px 160px; }
  .cta__title { font-size: 36px; letter-spacing: -2.16px; }

  /* Footer */
  .footer { gap: 100px; }
  .footer__top { flex-direction: column; gap: 80px; }
  .footer__nav-col, .footer__details { width: 100%; }
  .footer__nav a { font-size: 40px; letter-spacing: -2.4px; }
  .footer__band { height: 220px; }
  .footer__band-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 24px;
    padding-bottom: 32px;
  }
}

/* ============ Animations ============ */

/* Generic scroll-reveal (classes added by JS; no-JS keeps content visible) */
.anim-item {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.anim-item.in-view {
  opacity: 1;
  transform: none;
}

/* Hero load cascade */
@keyframes rise-in {
  from { opacity: 0; transform: translateY(44px); }
  to { opacity: 1; transform: none; }
}
.hero__line { display: block; }
.hero .hero__line {
  opacity: 0;
  animation: rise-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
.hero .hero__line:nth-child(1) { animation-delay: 0.1s; }
.hero .hero__line:nth-child(2) { animation-delay: 0.22s; }
.hero .hero__line:nth-child(3) { animation-delay: 0.34s; }
.hero .hero__subtitle {
  opacity: 0;
  animation: rise-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) 0.5s forwards;
}
.hero .hero__card {
  opacity: 0;
  animation: rise-in 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) 0.62s forwards;
}
.header {
  opacity: 0;
  animation: rise-in 0.6s ease 0.15s forwards;
}

/* Pixel cross slow spin in hero card */
@keyframes spin-slow {
  from { transform: rotate(-45deg); }
  to { transform: rotate(315deg); }
}
.hero__card-icon img { animation: spin-slow 24s linear infinite; }

/* Manifest: word-by-word gradient reveal (spans injected by JS) */

/* Process steps: divider draw + photo settle */
.process-step.anim-lines:first-child::before,
.process-step.anim-lines::after {
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.9s ease 0.1s;
}
.process-step.anim-lines.in-view:first-child::before,
.process-step.anim-lines.in-view::after { transform: scaleX(1); }
/* settle-in zoom applies to images only — videos carry their own Figma framing transforms */
.process-step__media.anim-item img {
  transform: scale(1.06);
  transition: transform 1.2s ease 0.15s;
}
.process-step__media.anim-item.in-view img { transform: scale(1); }

/* FAQ: smooth accordion (icon morph lives with the .faq__icon rules above) */

/* Accent price card: texture drift */
@keyframes tex-drift {
  from { background-position: 50% 50%; }
  to { background-position: calc(50% - 40px) calc(50% - 28px); }
}
.price-card--accent::before { animation: tex-drift 16s ease-in-out infinite alternate; }

/* CTA: word blur reveal (spans injected by JS) + texture drift */
.cta__title .word {
  display: inline-block;
  opacity: 0;
  filter: blur(10px);
  transform: translateY(12px);
  transition: opacity 0.6s ease, filter 0.6s ease, transform 0.6s ease;
}
.cta__title.in-view .word {
  opacity: 1;
  filter: none;
  transform: none;
}
@keyframes cta-drift {
  from { background-position: 50% 50%; }
  to { background-position: 53% 52%; }
}
.cta::after { animation: cta-drift 22s ease-in-out infinite alternate; }

/* Footer band: breathing green glow */
.footer__band { position: relative; }
.footer__band::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2; /* lime glow above the scene + scrim */
  background: radial-gradient(60% 90% at 50% 100%, rgba(174, 203, 57, 0.5), transparent 70%);
  mix-blend-mode: screen;
  pointer-events: none;
  animation: glow-pulse 9s ease-in-out infinite;
}
@keyframes glow-pulse {
  0%, 100% { opacity: 0.1; }
  50% { opacity: 0.4; }
}
.footer__band-row { position: relative; z-index: 3; } /* clock/copyright above scene, scrim and glow */

/* Crosshair cursor: full-viewport hairlines meeting at the pointer + x/y readout.
   difference blend keeps the lines visible on both dark and light sections. */
.cursor-cross {
  position: fixed;
  inset: 0;
  z-index: 300;
  pointer-events: none;
  mix-blend-mode: difference;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.cursor-cross.is-visible { opacity: 1; }
.cursor-cross__x {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: rgba(255, 255, 255, 0.22);
}
.cursor-cross__y {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 1px;
  background: rgba(255, 255, 255, 0.22);
}
.cursor-cross__x,
.cursor-cross__y { transition: background 0.25s ease; }
/* Over interactive elements the hairlines pick up the accent */
.cursor-cross.is-link .cursor-cross__x,
.cursor-cross.is-link .cursor-cross__y { background: rgba(222, 248, 118, 0.5); }
/* First-visit loader: crosshair hairlines draw in, meet with an accent flash, curtain lifts */
.loader {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: #0e100c;
  pointer-events: none;
  transition: opacity 0.8s ease;
}
.loader__x {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: rgba(255, 255, 255, 0.35);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.loader__y {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: rgba(255, 255, 255, 0.35);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) 0.08s;
}
.loader.is-drawn .loader__x { transform: scaleX(1); }
.loader.is-drawn .loader__y { transform: scaleY(1); }
/* Reveal: the dark and its hairlines simply dissolve while the hero entrance plays beneath */
.loader.is-done { opacity: 0; }
/* The hero entrance waits under the loader and is released as the dissolve starts */
.is-loading .hero .hero__line,
.is-loading .hero .hero__subtitle,
.is-loading .hero .hero__card,
.is-loading .header { animation-play-state: paused; }

/* Page transition fade */
.page-fade {
  position: fixed;
  inset: 0;
  z-index: 400;
  background: var(--bg-dark);
  opacity: 1;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.page-fade.is-out { opacity: 0; }

/* Respect reduced motion */
@media (prefers-reduced-motion: reduce) {
  .hero .hero__line,
  .hero .hero__subtitle,
  .hero .hero__card,
  .header { opacity: 1; animation: none; }
  .hero__card-icon img,
  .price-card--accent::before,
  .cta::after,
  .footer__band::before { animation: none; }
  .anim-item { opacity: 1; transform: none; transition: none; }
  .cursor-cross { display: none; }
  .page-fade { display: none; }
}

/* Touch devices: scroll-driven hover for work cards — JS adds .is-hovered when a card
   crosses the middle of the viewport, mirroring the desktop hover state. */
@media (hover: none) {
  /* keep these in flow so opacity can animate (they're display:none on touch otherwise);
     ellipsis clipping already prevents overflow */
  .work-card__dot,
  .work-card__desc { display: block; }

  .work-card:has(.work-card__media-hover).is-hovered .work-card__media img:not(.work-card__media-hover) { transform: scale(1.08); filter: blur(8px); }
  .work-card:has(.work-card__media-hover).is-hovered .work-card__media::after { opacity: 1; }
  .work-card.is-hovered .work-card__media img.work-card__media-hover { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  .work-card.is-hovered .work-card__name { background: var(--accent); }
  .work-card.is-hovered .work-card__dot,
  .work-card.is-hovered .work-card__desc { opacity: 1; }
}
