:root {
  --bg: #011111;
  --bg-hi: #102018;
  --paper: #eef0ea;
  --paper-hi: #f8f9f5;
  --ink: #0d1b15;
  --fg: #f0f4ee;
  --accent: #d6f93b;
  --teal: #135240;
  --muted: rgba(240, 244, 238, 0.55);
  --line: rgba(240, 244, 238, 0.14);
  --line-strong: rgba(240, 244, 238, 0.3);
  --radius: 40px;
  --header-h: 84px;
  --pad: clamp(20px, 4vw, 60px);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);
  --display: 'Archivo', sans-serif;
}

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

html { scroll-behavior: auto; overflow-x: hidden; max-width: 100%; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: 'Poppins', -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  /* no overflow-x here — html already clips horizontal overflow for the
     whole document. Setting it on body too was redundant, and per the CSS
     overflow computation rules it silently forced body's overflow-y to
     "auto", turning body into an unintended second scroll container
     alongside html — which breaks position:sticky for every descendant. */
  color-scheme: dark;
}

img { display: block; max-width: 100%; }
main img { border-radius: var(--radius); }
a { color: inherit; text-decoration: none; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 0.98;
}

em {
  font-style: normal;
  font-family: inherit;
  color: var(--accent);
  letter-spacing: inherit;
}

::selection { background: var(--accent); color: var(--ink); }

/* ---------- preloader ---------- */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--bg);
  color: var(--fg);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  clip-path: circle(150% at 50% 50%);
  transition: clip-path .85s var(--ease-io);
}
.preloader.is-done { clip-path: circle(0% at 50% 50%); }

.preloader-name {
  position: absolute;
  top: clamp(20px, 4vh, 40px);
  left: var(--pad);
  font-family: var(--display);
  font-size: clamp(18px, 2.2vw, 24px);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
}

.preloader-center {
  position: relative;
  width: clamp(280px, 32vw, 440px);
  transition: transform .3s var(--ease);
  will-change: transform;
}
.preloader-logo-ghost {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.13;
  filter: grayscale(1);
}
.preloader-logo-fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: auto;
  clip-path: inset(100% 0 0 0);
  transition: clip-path .2s linear;
}

.preloader-status {
  position: absolute;
  bottom: clamp(28px, 6vh, 56px);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: rgba(240, 244, 238, 0.65);
  opacity: 0;
  transform: translateY(8px);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.preloader-status.is-visible { opacity: 1; transform: translateY(0); }

/* ---------- chrome: progress, cursor, grain ---------- */

.progress-bar {
  position: fixed;
  top: 0; left: 0;
  height: 4px;
  width: 100%;
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(0);
  z-index: 1000;
}

.grain {
  position: fixed;
  inset: -70px;
  z-index: 998;
  pointer-events: none;
  opacity: 0.035;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  animation: grain-shift 9s steps(8) infinite;
}
/* steps() instead of a smooth tween — noise that eases would read as a
   glow pulsing, not grain; whole-pixel jumps are what keep it looking gritty */
@keyframes grain-shift {
  0%   { transform: translate(0, 0); }
  10%  { transform: translate(-2%, -4%); }
  20%  { transform: translate(3%, 2%); }
  30%  { transform: translate(-3%, 3%); }
  40%  { transform: translate(4%, -2%); }
  50%  { transform: translate(-2%, 4%); }
  60%  { transform: translate(2%, -3%); }
  70%  { transform: translate(-4%, 1%); }
  80%  { transform: translate(3%, -4%); }
  90%  { transform: translate(-1%, 2%); }
  100% { transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
}

/* ---------- custom cursor ---------- */
/* markup injected once by main.js, fine-pointer + motion-ok only; on touch
   or reduced-motion the OS cursor is left completely alone (html keeps its
   default cursor, nothing here ever applies) */

.cursor-dot, .cursor-ring {
  position: fixed;
  top: 0; left: 0;
  z-index: 2100;
  pointer-events: none;
  border-radius: 50%;
  transform: translate3d(-50%, -50%, 0);
  will-change: transform;
}
.cursor-dot {
  width: 6px; height: 6px;
  background: var(--accent);
  opacity: 0;
  transition: opacity .3s var(--ease), width .3s var(--ease), height .3s var(--ease), background .3s var(--ease);
}
.cursor-ring {
  width: 34px; height: 34px;
  border: 1px solid rgba(240, 244, 238, 0.5);
  opacity: 0;
  transition: opacity .3s var(--ease), width .3s var(--ease), height .3s var(--ease), border-color .3s var(--ease), background .3s var(--ease);
}
html.has-custom-cursor, html.has-custom-cursor a, html.has-custom-cursor button { cursor: none; }
body.cursor-active .cursor-dot, body.cursor-active .cursor-ring { opacity: 1; }
body.cursor-hover .cursor-dot {
  width: 10px; height: 10px;
}
body.cursor-hover .cursor-ring {
  width: 56px; height: 56px;
  border-color: var(--accent);
  background: rgba(214, 249, 59, 0.08);
}
@media (pointer: coarse), (prefers-reduced-motion: reduce) {
  .cursor-dot, .cursor-ring { display: none; }
}

/* ---------- mask reveal: images/text wipe into view instead of fading ---------- */
/* same clip-path technique as the preloader logo fill, applied on scroll */

[data-mask] {
  clip-path: inset(100% 0 0 0);
  transition: clip-path .7s var(--ease);
}
[data-mask].in-view { clip-path: inset(0 0 0 0); }
@media (prefers-reduced-motion: reduce) {
  [data-mask] { clip-path: inset(0 0 0 0); transition: none; }
}

/* ---------- scale media entrance ---------- */

[data-reveal-media] {
  opacity: 0;
  transform: scale(1.06);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
[data-reveal-media].in-view {
  opacity: 1;
  transform: scale(1);
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal-media] { opacity: 1; transform: none; transition: none; }
}

/* ---------- flip label ---------- */

.flip {
  position: relative;
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
}
.flip .fi {
  display: block;
  position: relative;
  transition: transform .45s var(--ease);
}
.flip .fi::after {
  content: attr(data-text);
  position: absolute;
  left: 0; top: 100%;
  width: 100%;
  text-align: center;
}
a:hover .flip .fi { transform: translateY(-100%); }

/* ---------- service preview ---------- */

.service-preview {
  position: fixed;
  top: 0; left: 0;
  width: 280px;
  height: 350px;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  z-index: 490;
  opacity: 0;
  transform: translate(-50%, -55%) scale(0.9) rotate(-3deg);
  transition: opacity .35s var(--ease), transform .35s var(--ease);
}
.service-preview.is-active {
  opacity: 1;
  transform: translate(-50%, -55%) scale(1) rotate(0deg);
}
.service-preview img { width: 100%; height: 100%; object-fit: cover; }
@media (pointer: coarse) { .service-preview { display: none; } }

/* ---------- header ---------- */

.site-header {
  position: fixed;
  top: 4px; left: 0; right: 0;
  z-index: 500;
  height: var(--header-h);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 var(--pad);
  transition: background .4s var(--ease), box-shadow .4s var(--ease), transform .5s var(--ease), backdrop-filter .4s var(--ease);
}
.site-header .logo { justify-self: start; }
.site-header .nav { justify-self: center; }
.site-header .nav-toggle { justify-self: end; }
.site-header {
  background: transparent;
  box-shadow: none;
}
.site-header.is-scrolled {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}
/* slides fully out of view while scrolling down, and back in — still
   transparent, same as always — the instant scroll direction reverses */
.site-header.is-hidden { transform: translateY(-130%); }

.logo { display: inline-flex; align-items: center; filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.55)); }
.logo img { height: 62px; width: auto; display: block; }

.nav { display: flex; align-items: center; gap: clamp(16px, 2.6vw, 36px); }
.nav-link {
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  position: relative;
  padding: 4px 0;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 0 12px rgba(0, 0, 0, 0.25);
}
.nav-link::after {
  content: '';
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 3px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .35s var(--ease);
}
.nav-link:hover::after { transform: scaleX(1); transform-origin: left; }

/* ---------- services dropdown ---------- */

.nav-item--dropdown { position: relative; display: inline-flex; align-items: center; }
.nav-item--dropdown .nav-link { display: inline-flex; align-items: center; gap: 6px; }
.nav-caret { width: 10px; height: 10px; transition: transform .35s var(--ease); }
.nav-item--dropdown:hover .nav-caret,
.nav-item--dropdown:focus-within .nav-caret { transform: rotate(180deg); }

.nav-dropdown {
  position: absolute;
  top: calc(100% + 18px);
  left: 50%;
  translate: -50% 0;
  min-width: 236px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px;
  border-radius: 20px;
  background: rgba(6, 18, 15, 0.97);
  border: 1px solid rgba(240, 244, 238, 0.14);
  box-shadow: 0 24px 48px -16px rgba(0, 0, 0, 0.55);
  opacity: 0;
  pointer-events: none;
  transform: translateY(-8px) scale(0.98);
  transform-origin: top center;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.nav-item--dropdown:hover .nav-dropdown,
.nav-item--dropdown:focus-within .nav-dropdown {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}
.nav-dropdown a {
  padding: 11px 14px;
  border-radius: 13px;
  font-size: 13px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--fg);
  transition: background .25s var(--ease), color .25s var(--ease), translate .25s var(--ease);
}
.nav-dropdown a:hover { background: var(--accent); color: var(--ink); translate: 3px 0; }

/* ---------- nav social icons ---------- */

.nav-social { display: flex; align-items: center; gap: 10px; margin-left: 4px; }
.nav-social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  color: #fff;
  font-family: var(--display);
  font-weight: 800;
  font-size: 11px;
  letter-spacing: -0.02em;
  text-shadow: none;
  transition: background .3s var(--ease), border-color .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.nav-social-link svg { width: 15px; height: 15px; }
.nav-social-link:hover { background: var(--accent); border-color: var(--accent); color: var(--ink); transform: translateY(-2px); }

@media (max-width: 680px) {
  .nav-item--dropdown { flex-direction: column; }
  .nav-dropdown {
    position: static;
    translate: 0;
    opacity: 1;
    pointer-events: auto;
    transform: none;
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 4px 0 0;
    align-items: center;
    margin-top: 6px;
  }
  .nav-dropdown a { font-size: 16px; padding: 6px 14px; }
  .nav-caret { display: none; }
  .nav-social { margin: 10px 0 0; }
}

.nav-toggle {
  display: none;
  position: relative;
  z-index: 501;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55));
}
.nav-toggle span {
  display: block;
  width: 26px;
  height: 2.5px;
  background: #fff;
  border-radius: 2px;
  transition: transform .3s var(--ease), opacity .3s var(--ease), background .3s var(--ease);
}
body.nav-open .nav-toggle span:nth-child(1) { transform: translateY(8.5px) rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-8.5px) rotate(-45deg); }

@media (max-width: 680px) {
  .nav-toggle { display: flex; }
  .nav {
    position: fixed;
    inset: 0;
    z-index: 480;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 30px;
    background: var(--bg);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-12px);
    transition: opacity .35s var(--ease), transform .35s var(--ease);
  }
  body.nav-open .nav {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }
  .nav .nav-link {
    font-size: 24px;
    color: var(--fg);
    mix-blend-mode: normal;
  }
}

/* ---------- reveals ---------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(28px) scale(0.98);
  transition: opacity .65s var(--ease), transform .65s var(--ease);
}
[data-reveal].in-view { opacity: 1; transform: none; }
/* directional variants: text that sits on the right side of its row
   travels in from the right, not up from below, and vice versa — same
   [data-reveal]/.in-view toggle, just a different starting transform.
   The settled (.in-view) state stays the single rule above regardless of
   direction, since "arrived" always just means transform: none. */
[data-reveal="right"] { transform: translateX(56px) scale(0.98); }
[data-reveal="left"] { transform: translateX(-56px) scale(0.98); }

[data-split] .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
  max-width: 100%;
}
[data-split] .wi {
  display: inline-block;
  transform: translateY(120%) rotate(3deg);
  transform-origin: left bottom;
  transition: transform .6s var(--ease);
  overflow-wrap: anywhere;
  word-break: break-word;
}
[data-split].in-view .wi { transform: translateY(0) rotate(0); }

/* ---------- hero ---------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  align-items: center;
  gap: clamp(24px, 4vw, 60px);
  padding: calc(var(--header-h) + 30px) var(--pad) 60px;
  overflow: hidden;
  background: radial-gradient(ellipse 80% 60% at 50% 20%, #14261d 0%, rgba(11, 21, 17, 0) 70%);
}
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; padding-top: calc(var(--header-h) + 24px); text-align: center; }
  .hero-cta-group { margin: 0 auto; }
}

@keyframes blob-float {
  0%, 100% { transform: translate(0, 0) scale(1); }
  33% { transform: translate(-4%, 6%) scale(1.08); }
  66% { transform: translate(3%, -4%) scale(0.94); }
}

.hero-copy { position: relative; z-index: 2; }

.hero-title {
  font-size: clamp(34px, 4.6vw, 66px);
  font-weight: 900;
  position: relative;
  z-index: 1;
}
.hero-title .line { display: block; overflow: hidden; }
.hero-title .line-inner {
  display: block;
  transform: translateY(112%);
  transition: transform .8s var(--ease);
}
body.is-loaded .hero-title .line-inner { transform: translateY(0); }
.hero-title .line:nth-child(2) .line-inner { transition-delay: .1s; }
.hero-title .line:nth-child(3) .line-inner { transition-delay: .2s; }
.hero-title em {
  position: relative;
  padding: 0 0.06em;
  color: var(--accent);
}

.hero-foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 34px;
  margin-top: 40px;
  position: relative;
  z-index: 2;
}
.hero-sub {
  max-width: 440px;
  font-size: 17px;
  color: var(--muted);
  font-weight: 500;
}

/* ---------- hero: dual CTA buttons ---------- */

.hero-cta-group {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: 100%;
  max-width: 400px;
}
.hero-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 19px 30px;
  border-radius: 999px;
  background: var(--accent);
  color: var(--ink);
  font-family: var(--display);
  font-weight: 800;
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: 5px 7px 0 rgba(0, 0, 0, 0.45);
  transition: background .3s var(--ease), box-shadow .3s var(--ease), translate .3s var(--ease);
}
.hero-btn:hover { background: var(--paper-hi); box-shadow: 5px 7px 0 rgba(214, 249, 59, 0.5); translate: 0 -2px; }

/* ---------- hero: floating 3D card carousel ----------
   4 photo cards genuinely orbit a shared center — .hero-orbit-ring spins
   continuously (hero-ring-spin), and since each .hero-card sits at a fixed
   angle within that ring (rotate(--slot-angle) translateY(-radius)), the
   whole group revolves together: the card that starts "up" swings through
   "right", then "down", then "left" and back to "up", each one taking over
   the position the next one just left, tracing one continuous circle.
   Every card's content would otherwise spin in place along with the ring
   (it's rigidly rotated to reach its angle) — .hero-card-counter cancels
   exactly that (ring rotation + the card's own slot angle) via the same
   keyframes run out of phase per card (negative animation-delay, timed to
   each one's starting angle), so the photos themselves stay upright the
   whole time they're travelling the circle. */

.hero-visual {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 480px;
  margin-left: auto;
  justify-self: end;
}
.hero-orbit {
  position: relative;
  width: 100%;
  aspect-ratio: 6 / 7;
  perspective: 1600px;
}
.hero-orbit-ring {
  position: absolute;
  inset: 0;
  animation: hero-ring-spin 28s linear infinite;
}
@keyframes hero-ring-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.hero-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 38%;
  aspect-ratio: 3 / 4;
  --orbit-radius: 148px;
  translate: -50% -50%;
  transform: rotate(var(--slot-angle)) translateY(calc(-1 * var(--orbit-radius)));
}
.hero-card--up    { --slot-angle: 0deg; }
.hero-card--right { --slot-angle: 90deg; }
.hero-card--down  { --slot-angle: 180deg; }
.hero-card--left  { --slot-angle: 270deg; }

/* receives the existing mouse/scroll depth-parallax loop's `translate`
   writes (js/main.js) on a property separate from `transform`, so it
   layers on top of the orbit + counter-spin below without fighting either
   for control of the same property */
.hero-card-parallax { width: 100%; height: 100%; }

.hero-card-counter {
  width: 100%;
  height: 100%;
  animation: hero-card-counter-spin 28s linear infinite;
}
/* delay = -(slot-angle / 360) * 28s — starts each card's counter-rotation
   already offset by exactly its own slot angle, which is what it needs to
   cancel (on top of the ring's live rotation) to stay upright from t=0 */
.hero-card--up    .hero-card-counter { animation-delay: 0s; }
.hero-card--right .hero-card-counter { animation-delay: -7s; }
.hero-card--down  .hero-card-counter { animation-delay: -14s; }
.hero-card--left  .hero-card-counter { animation-delay: -21s; }
@keyframes hero-card-counter-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(-360deg); }
}

.hero-card-face {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 22px;
  overflow: hidden;
  transform-style: preserve-3d;
  transform: rotateX(4deg) rotateY(-4deg);
  box-shadow: 0 30px 50px -18px rgba(0, 0, 0, 0.55);
}
.hero-card-face img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(0.92) saturate(1.05);
}
.hero-card-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(3, 9, 7, 0.85) 0%, rgba(3, 9, 7, 0.12) 48%, transparent 68%);
  pointer-events: none;
}
.hero-card-label {
  position: absolute;
  left: 16px; right: 16px; bottom: 14px;
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  line-height: 1.05;
  font-size: clamp(13px, 1.5vw, 17px);
  color: #fff;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.35);
}
.hero-card-label em { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  .hero-orbit-ring { animation: none; }
  .hero-card-counter { animation: none; }
  .hero-card { transform: translateY(calc(-1 * var(--orbit-radius))); }
}

@media (max-width: 900px) {
  .hero-visual { max-width: 380px; margin: 54px auto 0; justify-self: center; }
  .hero-orbit {
    aspect-ratio: auto;
    perspective: none;
  }
  .hero-orbit-ring {
    position: static;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
    animation: none;
  }
  .hero-card { position: static; width: auto; translate: 0; transform: none; }
  .hero-card-counter { animation: none; }
  .hero-card-face { transform: none; box-shadow: 0 18px 38px -16px rgba(0, 0, 0, 0.55); }
}

/* ---------- self-drawing doodles ---------- */

.draw--arrow {
  position: absolute;
  right: clamp(30px, 10vw, 180px);
  bottom: -10px;
  width: clamp(90px, 10vw, 150px);
}
.draw--arrow path,
.scribble path {
  stroke: var(--accent);
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  transition: stroke-dashoffset .9s var(--ease-io) .3s;
}
.draw--arrow.in-view path { stroke-dashoffset: 0; }

.scribble-wrap {
  position: relative;
  display: inline-block;
}
.scribble {
  position: absolute;
  left: -8%;
  top: -12%;
  width: 116%;
  height: 124%;
  overflow: visible;
  pointer-events: none;
}
.statement.in-view .scribble path { stroke-dashoffset: 0; }

.smiley {
  position: absolute;
  right: clamp(20px, 9vw, 170px);
  top: 42%;
  width: 88px;
  rotate: 8deg;
  transition: rotate .4s var(--ease), scale .4s var(--ease);
}
.smiley:hover { rotate: -6deg; scale: 1.12; }
.smiley svg { display: block; }
.smiley circle, .smiley path, .smiley line { stroke: var(--accent); }
.smiley-eye--l {
  animation: wink 5.2s ease-in-out infinite;
  transform-box: fill-box;
  transform-origin: center;
}
@keyframes wink {
  0%, 86%, 100% { transform: scaleY(1); }
  92% { transform: scaleY(0.12); }
}

/* ---------- marquee ---------- */

.marquee {
  border-top: 2.5px solid var(--line);
  border-bottom: 2.5px solid var(--line);
  padding: 18px 0;
  overflow: hidden;
  white-space: nowrap;
}
.marquee--accent {
  background: var(--accent);
  color: var(--ink);
  border-color: var(--accent);
  padding: 7px 0;
}
.marquee--accent .marquee-track {
  font-size: clamp(11px, 1.5vw, 17px);
  gap: 16px;
}
.marquee-track {
  display: inline-flex;
  align-items: center;
  gap: 26px;
  animation: marquee 26s linear infinite;
  font-family: var(--display);
  font-size: clamp(26px, 4.4vw, 46px);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  will-change: transform;
}
.marquee--reverse .marquee-track { animation-direction: reverse; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee .star { font-size: 0.7em; }
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}

/* ---------- sections ---------- */

.section-head { position: relative; padding: 130px var(--pad) 60px; }
.section-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  background: var(--accent);
  color: var(--ink);
  padding: 7px 14px;
  border-radius: 999px;
  margin-bottom: 22px;
  transition: background .3s var(--ease), rotate .3s var(--ease);
}
.section-tag:hover { background: var(--paper-hi); rotate: -2deg; }
.section-tag--center { display: block; width: fit-content; margin: 0 auto 0; }
.section-head h2 { font-size: clamp(36px, 6.5vw, 80px); }
.section-head em { color: var(--accent); }

/* ---------- light "slide" sections ---------- */
/* flat color-block cut against the dark sections above/below — a dark-to-
   light gradient here reads as a smoky grey haze band at the seam, so this
   is a hard cut instead */

.about, .team, .process {
  background: var(--paper);
  color: var(--ink);
  --muted: rgba(13, 27, 21, 0.58);
  --line: rgba(13, 27, 21, 0.14);
}
.about em, .team em, .process em { color: var(--teal); }
.about .section-tag, .team .section-tag, .process .section-tag {
  background: var(--ink);
  color: var(--paper-hi);
}
.about .section-tag:hover, .team .section-tag:hover, .process .section-tag:hover {
  background: var(--teal);
}

/* ---------- featured case study ---------- */

.feature {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: clamp(30px, 5vw, 70px);
  align-items: center;
  margin: 0 var(--pad) 90px;
}
.feature-media {
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 26px 52px -20px rgba(0, 0, 0, 0.5);
}
.feature-media img {
  width: 100%;
  aspect-ratio: 16 / 11;
  object-fit: cover;
  scale: 1.1;
}
.feature-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  margin-bottom: 14px;
}
.feature-info h3 { font-size: clamp(28px, 3.6vw, 48px); margin-bottom: 14px; }
.feature-desc { color: var(--muted); font-size: 16px; font-weight: 500; max-width: 480px; margin-bottom: 32px; }
.feature-stats {
  display: flex;
  gap: clamp(20px, 3vw, 40px);
  flex-wrap: wrap;
  margin-bottom: 30px;
}
.feature-stats div { display: flex; flex-direction: column; gap: 2px; font-size: 13px; color: var(--muted); font-weight: 600; }
.feature-stats span { font-family: var(--display); font-size: 22px; font-weight: 800; text-transform: uppercase; color: var(--accent); }
.feature-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 15px;
  transition: gap .3s var(--ease), color .3s var(--ease);
}
.feature-link svg { width: 16px; height: 16px; }
.feature:hover .feature-link { gap: 14px; color: var(--accent); }
@media (max-width: 900px) { .feature { grid-template-columns: 1fr; } }

/* ---------- work hero: floating glass showcase ---------- */

.work-hero {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 55% at 50% 34%, #10261f 0%, #0b1c19 48%, #071412 100%);
  padding: calc(var(--header-h) + 50px) var(--pad) 90px;
}

.work-hero-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.work-hero-particles { position: absolute; inset: 0; }
.wh-particle {
  position: absolute;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: rgba(214, 249, 59, 0.55);
  opacity: 0;
  animation: wh-drift var(--pdur, 16s) linear infinite, wh-fade var(--pdur, 16s) ease-in-out infinite;
  animation-delay: var(--pdelay, 0s);
}
@keyframes wh-drift { from { transform: translate(0, 0); } to { transform: translate(var(--pdx, 30px), var(--pdy, -140px)); } }
@keyframes wh-fade { 0%, 100% { opacity: 0; } 15%, 75% { opacity: var(--pmax, .5); } }

.work-hero-head { position: relative; z-index: 2; max-width: 640px; }
.work-hero-head h2 {
  font-size: clamp(30px, 4.6vw, 58px);
  line-height: 1.08;
  margin-top: 18px;
}
.work-hero-sub {
  margin-top: 16px;
  max-width: 46ch;
  font-size: 16px;
  color: var(--muted);
}

.work-hero-scroll {
  position: absolute;
  bottom: 28px; left: 50%;
  translate: -50% 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.work-hero-scroll-mouse {
  position: relative;
  width: 18px; height: 28px;
  border: 1.5px solid var(--line-strong);
  border-radius: 10px;
}
.work-hero-scroll-mouse::before {
  content: '';
  position: absolute;
  top: 5px; left: 50%;
  width: 3px; height: 6px;
  margin-left: -1.5px;
  border-radius: 2px;
  background: var(--accent);
  animation: wh-scroll-dot 1.8s var(--ease) infinite;
}
@keyframes wh-scroll-dot { 0% { transform: translateY(0); opacity: 1; } 70% { transform: translateY(9px); opacity: 0; } 100% { opacity: 0; } }

@media (max-width: 900px) {
  .work-hero { min-height: auto; padding-bottom: 60px; }
  .work-hero-scroll { display: none; }
}

/* ---------- work reel: cinematic stacking case-study scroller ----------
   each .reel-panel is a tall scroll runway; its .reel-panel-inner is
   position:sticky, so it pins full-screen while the runway scrolls past.
   the exit animation (work-cinematic.js) is scrubbed to the second half of
   that runway — which is exactly the range the browser's own sticky math
   uses to let the next panel's sticky child slide up and cover this one, so
   the shrink/dim tracks the natural cover motion frame for frame
   instead of running on its own clock. */

.work-reel {
  position: relative;
  background: var(--bg);
}

/* full-bleed accent flash pulsed at each panel handoff — a colored light-leak
   that sells the cut between case studies (work-cinematic.js drives opacity
   + background-color per panel's --reel-accent) */
.reel-wash {
  position: fixed;
  inset: 0;
  z-index: 350;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
}
@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  .reel-wash { display: none; }
}

.reel-hud {
  position: fixed;
  z-index: 400;
  top: 50%;
  right: clamp(18px, 3vw, 40px);
  translate: 0 -50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s var(--ease);
}
.reel-hud.is-visible { opacity: 1; pointer-events: auto; }

.reel-progress {
  width: 2px;
  height: 120px;
  border-radius: 2px;
  background: rgba(240, 244, 238, 0.16);
  overflow: hidden;
}
.reel-progress-fill {
  display: block;
  width: 100%;
  height: 20%;
  border-radius: 2px;
  background: var(--accent);
  transition: height .5s var(--ease);
}

.reel-nav {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.reel-nav-item {
  position: relative;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: transparent;
  color: var(--muted);
  font-family: var(--display);
  font-size: 10px;
  font-weight: 700;
  cursor: pointer;
  transition: border-color .3s var(--ease), background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease);
}
.reel-nav-item:hover, .reel-nav-item:focus-visible { border-color: var(--accent); color: var(--fg); outline: none; }
.reel-nav-item.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
  transform: scale(1.15);
}
.reel-nav-name {
  position: absolute;
  right: 100%;
  top: 50%;
  translate: -10px -50%;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity .3s var(--ease), translate .3s var(--ease);
}
.reel-nav-item:hover .reel-nav-name, .reel-nav-item:focus-visible .reel-nav-name {
  opacity: 1;
  translate: -16px -50%;
}

.reel-counter {
  font-family: var(--display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.reel-counter i { display: inline-block; width: 12px; height: 1px; background: var(--line-strong); font-style: normal; }
.reel-counter span:first-child { color: var(--fg); }

.reel-panel {
  position: relative;
  height: 200vh;
  --reel-accent: rgba(214, 249, 59, 0.35);
}
.reel-panel--malina    { --reel-accent: rgba(214, 249, 59, 0.4); }
.reel-panel--maitrisez { --reel-accent: rgba(255, 107, 149, 0.4); }
.reel-panel--aeronest  { --reel-accent: rgba(111, 214, 232, 0.4); }
.reel-panel--rouad     { --reel-accent: rgba(155, 140, 247, 0.4); }
.reel-panel--sokuto    { --reel-accent: rgba(255, 157, 92, 0.4); }

.reel-panel-inner {
  position: sticky;
  top: 0;
  display: block;
  height: 100vh;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 55% at 50% 34%, #10261f 0%, #0b1c19 48%, #071412 100%);
}

.reel-media { position: absolute; inset: 0; }
.reel-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1);
  filter: brightness(0.82) saturate(1.05);
  transition: transform 7s linear, filter .6s var(--ease);
}
.reel-panel.is-active .reel-media img { transform: scale(1.08); }
.reel-panel-inner:hover .reel-media img,
.reel-panel-inner:focus-visible .reel-media img { filter: brightness(0.9) saturate(1.2); }

.reel-tint {
  position: absolute;
  inset: 0;
  background: var(--reel-accent);
  mix-blend-mode: overlay;
  opacity: 0.5;
}
.reel-media-scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(3, 9, 7, 0.97) 0%, rgba(3, 9, 7, 0.86) 30%, rgba(3, 9, 7, 0.5) 54%, rgba(3, 9, 7, 0.15) 74%, transparent 92%),
    linear-gradient(to bottom, rgba(3, 9, 7, 0.55) 0%, transparent 22%);
}

.reel-dim {
  position: absolute;
  inset: 0;
  background: #010504;
  opacity: 0;
  pointer-events: none;
}

.reel-num {
  position: absolute;
  top: 6%;
  right: var(--pad);
  z-index: 1;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(70px, 11vw, 170px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(255, 255, 255, 0.35);
  pointer-events: none;
}

.reel-info {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: clamp(56px, 9vh, 110px);
  z-index: 1;
  max-width: 720px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.reel-cat {
  display: inline-flex;
  align-self: flex-start;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(20, 26, 22, 0.55);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
}
.reel-title {
  font-size: clamp(40px, 7.6vw, 108px);
  line-height: 0.94;
  color: #fff;
}
.reel-desc {
  max-width: 46ch;
  font-size: clamp(15px, 1.3vw, 19px);
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.75);
}
.reel-cta {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
  padding: 15px 28px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: #fff;
  font-family: var(--display);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: background .35s var(--ease), border-color .35s var(--ease), color .35s var(--ease);
}
.reel-cta-icon { width: 15px; height: 15px; transition: transform .4s var(--ease); }
.reel-panel-inner:is(:hover, :focus-visible) .reel-cta {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
}
.reel-panel-inner:is(:hover, :focus-visible) .reel-cta-icon { transform: translate(3px, -3px); }

.reel-outro {
  position: relative;
  z-index: 1;
  padding: clamp(90px, 14vh, 160px) var(--pad);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: var(--bg);
}
.reel-outro .section-tag { margin: 0 auto; }
.reel-outro h3 { margin-top: 20px; font-size: clamp(32px, 6vw, 68px); }
.reel-outro p { margin-top: 16px; max-width: 46ch; color: var(--muted); font-size: 16px; }
.reel-outro-btn { width: auto; margin-top: 34px; padding: 19px 42px; }

@media (max-width: 900px) {
  /* the sticky/absolute stacking system is desktop-only; below this width
     each panel becomes an ordinary in-flow card (image, then copy) so
     nothing needs an ancestor with a definite height to size against */
  .reel-hud { display: none; }
  .reel-panel { height: auto; }
  .reel-panel-inner {
    position: relative;
    display: block;
    height: auto;
    margin-bottom: 28px;
  }
  .reel-media { position: relative; height: 64vh; min-height: 380px; overflow: hidden; }
  .reel-num { font-size: clamp(48px, 18vw, 90px); top: 14px; right: 16px; }
  .reel-info { position: relative; padding: 26px 20px 38px; }
  .reel-cta { justify-content: center; width: 100%; }
}

@media (prefers-reduced-motion: reduce) and (min-width: 901px) {
  /* keep the full-bleed desktop composition, just not pinned/scrubbed —
     .reel-panel-inner must stay a positioned element (relative, not
     static) since .reel-media/.reel-num/.reel-info are absolutely
     positioned against it */
  .reel-panel { height: auto; }
  .reel-panel-inner { position: relative; height: 100vh; }
  .reel-media img { transition: none; }
  .reel-panel.is-active .reel-media img { transform: none; }
}

/* ---------- manifesto ---------- */

.manifesto {
  padding: 150px var(--pad);
  text-align: center;
  background: radial-gradient(ellipse 70% 90% at 50% 50%, #12241b 0%, var(--bg) 75%);
  color: var(--fg);
}
.manifesto-kicker {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 40px;
}
.statement {
  max-width: 1000px;
  margin: 0 auto;
  font-family: var(--display);
  font-size: clamp(30px, 4.8vw, 66px);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.02em;
}
.statement em { color: var(--accent); }
.statement .wi { transition-property: transform, color; transition-duration: .9s, .3s; }
.statement .w:hover .wi { color: var(--accent); }

/* ---------- about ---------- */

.about {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(40px, 7vw, 110px);
  padding: 150px var(--pad);
  align-items: center;
}
.polaroid {
  position: relative;
  transition: scale .5s var(--ease),
              opacity .7s var(--ease), transform .7s var(--ease);
}
.polaroid:hover { scale: 1.02; }
.polaroid-media {
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 26px 52px -20px rgba(13, 27, 21, 0.38);
}
.polaroid img {
  aspect-ratio: 6 / 7;
  object-fit: cover;
  filter: grayscale(0.3);
  scale: 1.12;
  transition: opacity .3s var(--ease);
}
#polaroid-img {
  aspect-ratio: 4 / 5;
  object-position: 34% 38%;
  filter: grayscale(0.1) contrast(1.05);
  scale: 1.2;
}
.polaroid-caption {
  display: block;
  margin-top: 16px;
  font-family: 'Poppins', sans-serif;
  font-style: italic;
  font-weight: 500;
  font-size: 15px;
  color: var(--muted);
}
.about-copy h2 { font-size: clamp(28px, 4vw, 50px); margin-bottom: 24px; }
.about-copy > p { font-size: 17px; color: var(--muted); font-weight: 500; max-width: 600px; margin-bottom: 48px; }
.about-copy > p strong { color: var(--ink); font-weight: 800; }

@media (max-width: 900px) {
  .about { grid-template-columns: 1fr; padding: 100px var(--pad); }
  .polaroid { max-width: 420px; margin: 0 auto; }
}

.stats {
  display: grid;
  grid-template-columns: repeat(4, auto);
  gap: 28px;
  position: relative;
  padding-top: 30px;
}
.stats::before {
  content: '';
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 2.5px;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .8s var(--ease-io) .15s;
}
.stats.in-view::before { transform: scaleX(1); }
.stat { display: flex; flex-direction: column; gap: 4px; }
.stat-num {
  font-family: var(--display);
  font-size: clamp(30px, 3.4vw, 46px);
  font-weight: 800;
  color: var(--teal);
}
.stat-label { font-size: 13px; color: var(--muted); font-weight: 600; }
@media (max-width: 640px) {
  .stats { grid-template-columns: repeat(2, auto); gap: 24px 32px; }
}

/* ---------- team ---------- */

.team {
  padding: 0 var(--pad) 150px;
  text-align: center;
  background: var(--paper);
}
.team-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 34px);
  max-width: 980px;
  margin: 40px auto 0;
}
.team-member { text-align: left; }
.team-photo {
  overflow: hidden;
  border-radius: var(--radius);
  margin-bottom: 16px;
  box-shadow: 0 18px 36px -16px rgba(13, 27, 21, 0.3);
  transition: box-shadow .35s var(--ease), translate .35s var(--ease);
}
.team-member:hover .team-photo { box-shadow: 0 26px 48px -18px rgba(13, 27, 21, 0.4); translate: 0 -4px; }
.team-photo img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
  filter: grayscale(0.5);
  transition: filter .4s var(--ease);
}
.team-member:hover .team-photo img { filter: grayscale(0); }
.team-member h4 { font-family: var(--display); font-size: 17px; font-weight: 800; text-transform: uppercase; margin-bottom: 2px; }
.team-member p { font-size: 13px; color: var(--muted); font-weight: 600; }
@media (max-width: 900px) { .team-grid { grid-template-columns: repeat(2, 1fr); } }

/* ---------- process ---------- */

.process {
  padding-bottom: 150px;
  background: var(--paper);
}
.process-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(20px, 3vw, 40px);
  padding: 0 var(--pad);
  position: relative;
}
.process-list::before {
  content: '';
  position: absolute;
  top: 14px;
  left: var(--pad);
  right: var(--pad);
  height: 2px;
  background: var(--line);
  z-index: -1;
}
.process-step { position: relative; }
.process-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--paper);
  border: 2.5px solid var(--ink);
  font-size: 12px;
  font-weight: 800;
  margin-bottom: 22px;
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.process-step:hover .process-num { background: var(--accent); border-color: var(--ink); color: var(--ink); }
.process-step h3 { font-size: clamp(18px, 2.2vw, 24px); margin-bottom: 10px; }
.process-step p { color: var(--muted); font-size: 14px; font-weight: 500; }
@media (max-width: 900px) {
  .process-list { grid-template-columns: repeat(2, 1fr); row-gap: 40px; }
  .process-list::before { display: none; }
}

/* ---------- services ---------- */

.services { padding-bottom: 150px; }
.service-list {
  border-top: 2.5px solid var(--line-strong);
  margin: 0 var(--pad);
}
.service {
  display: grid;
  grid-template-columns: 1fr auto 40px;
  align-items: center;
  gap: 24px;
  padding: 30px 10px;
  border-bottom: 2.5px solid var(--line-strong);
  position: relative;
  overflow: hidden;
  scroll-margin-top: calc(var(--header-h) + 40px);
  transition: color .35s var(--ease), padding-left .35s var(--ease),
              opacity 1s var(--ease), transform 1s var(--ease);
}
.service::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: translateY(101%);
  transition: transform .45s var(--ease-io);
  z-index: -1;
}
.service:hover::before { transform: translateY(0); }
.service:hover { padding-left: 26px; color: var(--ink); }
.service h3 { font-size: clamp(22px, 3.4vw, 44px); }
.service p { color: var(--muted); font-size: 15px; font-weight: 500; max-width: 340px; text-align: right; transition: color .35s var(--ease); }
.service:hover p { color: rgba(13, 27, 21, 0.7); }
.service-arrow {
  font-size: 26px;
  transition: transform .35s var(--ease), color .35s var(--ease);
}
.service:hover .service-arrow { transform: rotate(45deg) scale(1.25); color: var(--ink); }

@media (max-width: 640px) {
  .service {
    grid-template-columns: 1fr 32px;
    column-gap: 16px;
    padding: 24px 10px;
  }
  .service h3 { grid-column: 1; grid-row: 1; }
  .service-arrow { grid-column: 2; grid-row: 1; }
  .service p {
    grid-column: 1 / -1;
    grid-row: 2;
    text-align: left;
    max-width: none;
    margin-top: 6px;
  }
}

/* ---------- reviews ---------- */

.reviews { padding: 60px var(--pad) 150px; }
.reviews-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3.5vw, 46px);
  align-items: start;
  max-width: 1420px;
  margin: 60px auto 0;
}
.review {
  text-align: center;
  opacity: 0.9;
  transition: opacity .3s var(--ease);
}
.review:hover { opacity: 1; }
.quote-mark {
  fill: var(--accent);
  opacity: 0;
  width: 30px; height: 22px;
  margin: 0 auto 16px;
  transition: opacity .35s var(--ease);
}
.review:hover .quote-mark { opacity: 0.85; }
.review-text {
  margin-bottom: 22px;
  font-family: 'Poppins', sans-serif;
  font-size: clamp(13px, 1.05vw, 15px);
  font-weight: 500;
  line-height: 1.65;
  color: var(--muted);
  transition: font-size .35s var(--ease), color .35s var(--ease);
}
.review:hover .review-text {
  font-family: var(--display);
  font-size: clamp(17px, 1.65vw, 22px);
  font-weight: 700;
  line-height: 1.4;
  letter-spacing: -0.005em;
  color: var(--fg);
}
.review-attr { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.review-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--line-strong);
  color: var(--fg);
  font-family: var(--display);
  font-weight: 800;
  font-size: 12px;
  transition: width .35s var(--ease), height .35s var(--ease), background .35s var(--ease), color .35s var(--ease), font-size .35s var(--ease);
}
.review:hover .review-avatar {
  width: 40px; height: 40px;
  font-size: 15px;
  background: var(--accent);
  color: var(--ink);
}
.review-attr h4 {
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-size: 11px;
  color: var(--muted);
  transition: font-size .35s var(--ease), color .35s var(--ease);
}
.review:hover .review-attr h4 { font-size: 14px; color: var(--fg); }
.review-attr p { font-size: 11px; color: var(--muted); font-weight: 600; margin-top: 2px; }

@media (max-width: 900px) {
  .reviews-row { grid-template-columns: 1fr; gap: 54px; max-width: 480px; }
}

/* ---------- cta ---------- */

.cta {
  position: relative;
  padding: 160px var(--pad) 170px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: radial-gradient(ellipse 70% 70% at 50% 40%, #12241b 0%, rgba(11, 21, 17, 0) 75%);
}
.cta h2 { font-size: clamp(34px, 11vw, 160px); margin: 24px 0 44px; }
.cta em { color: transparent; -webkit-text-stroke: 2.5px var(--accent); }
.cta-email {
  display: inline-block;
  font-family: var(--display);
  font-size: clamp(20px, 3vw, 34px);
  font-weight: 800;
  text-transform: uppercase;
  background: var(--accent);
  color: var(--ink);
  padding: 18px 34px;
  border-radius: 999px;
  box-shadow: 5px 7px 0 rgba(0, 0, 0, 0.45);
  transition: background .3s var(--ease), color .3s var(--ease), transform .3s var(--ease), box-shadow .3s var(--ease);
}
.cta-email:hover { background: var(--paper-hi); box-shadow: 5px 7px 0 rgba(214, 249, 59, 0.5); }
.cta-sub { margin-top: 22px; color: var(--muted); font-size: 14px; font-weight: 600; max-width: 480px; }

.contact-actions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  flex-wrap: wrap;
  margin-top: 46px;
}
.cta-whatsapp {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-family: var(--display);
  font-size: clamp(20px, 3vw, 34px);
  font-weight: 800;
  text-transform: uppercase;
  color: var(--fg);
  border: 2.5px solid var(--fg);
  padding: 15px 32px;
  border-radius: 999px;
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease), transform .3s var(--ease);
}
.cta-whatsapp svg { width: 0.9em; height: 0.9em; fill: currentColor; }
.cta-whatsapp:hover { background: var(--fg); border-color: var(--fg); color: var(--ink); }

/* ---------- footer ---------- */

.site-footer {
  background: #070f0b;
  color: var(--fg);
  padding-top: 30px;
}
.footer-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 26px var(--pad) 34px;
  border-top: 1px solid rgba(240, 244, 238, 0.16);
  font-size: 13px;
  font-weight: 600;
}
#local-time { color: var(--accent); }
.footer-links { display: flex; gap: 26px; }
.footer-links a {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  transition: color .3s var(--ease);
}
.footer-links a:hover { color: var(--accent); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
  .hero-title .line-inner { transform: none; }
  [data-split] .wi { transform: none; }
  .feature-media img, .work-card-media img { scale: 1; }
  .preloader { display: none; }
}

/* ---------- deck slides (brand PDF pages 2 & 3) ---------- */

.deck3-copy {
  position: absolute;
  left: 3.2%;
  top: 19%;
  width: 46%;
  font-size: clamp(14px, 1.5vw, 21px);
  font-weight: 500;
  line-height: 1.5;
}
.deck3-copy p + p { margin-top: 1.4em; }
.deck3-copy strong { color: #cf0; font-weight: 700; }
.deck3-center {
  position: absolute;
  left: 50%;
  top: 55%;
  transform: translateX(-50%);
  text-align: center;
  width: max-content;
  max-width: 94%;
}
.deck3-labels {
  display: flex;
  justify-content: space-between;
  gap: 40px;
  color: #cf0;
  font-size: clamp(12px, 1.3vw, 19px);
  font-weight: 500;
}
.deck3-center h2 {
  font-size: clamp(44px, 6.9vw, 100px);
  line-height: 0.94;
  margin: 0.1em 0;
}
.deck3-pencil {
  position: absolute;
  top: 68.5%;
  width: 14.2%;
  border-radius: 0 !important;
}
.deck3-pencil--l { left: 5.5%; }
.deck3-pencil--r { right: 5.5%; transform: scaleX(-1); }

/* ---------- subpages ---------- */

.page-head {
  position: relative;
  padding: calc(var(--header-h) + 90px) var(--pad) 40px;
}
.page-head h1 { font-size: clamp(48px, 8vw, 116px); }
.page-head em { color: var(--accent); }
.page-head-sub {
  margin-top: 18px;
  max-width: 540px;
  color: var(--muted);
  font-weight: 500;
}

/* ---------- project pages ---------- */

.project-cover { padding: 20px var(--pad) 0; }
.project-cover img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: 0; }
.project-body { padding: 70px var(--pad) 20px; }
.project-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  padding-bottom: 40px;
  margin-bottom: 60px;
  border-bottom: 2.5px solid var(--line-strong);
  background: var(--bg);
}
/* the stat strip holds at the very top of the viewport while the copy
   below scrolls past — .project-body (its containing block) is always
   taller than the strip itself, so it releases cleanly once the copy runs
   out. `top: 0` (not offset below the header) is deliberate: the header
   hides on scroll-down and reappears transparent on scroll-up, so any
   fixed offset here would leave a gap that isn't covered by either
   element's background whenever the header isn't there to fill it — the
   copy scrolling behind both would peek through as a stray sliver of
   text. Sticking flush at 0 means the strip's own solid background always
   covers that space regardless of the header's current state; the
   (transparent) header simply floats over it on top, same as it does
   over every other section on the site. */
@media (min-width: 901px) {
  .project-meta { position: sticky; top: 0; z-index: 3; }
}
.project-meta div {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 17px;
}
.project-meta span {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  font-family: 'Poppins', sans-serif;
}
.project-copy { max-width: 760px; }
.project-copy p { color: var(--muted); font-size: 17px; font-weight: 500; }
.project-copy p + p { margin-top: 1.4em; }
.project-images {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(18px, 2.5vw, 30px);
  margin-top: 60px;
}
.project-images img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }

/* ---------- project story: alternating photo/text chapters ----------
   the "how we built it" narrative — each .story-row pairs one photo with
   one chapter of copy, alternating which side the photo sits on
   (.story-row--flip swaps the DOM order rather than fighting it with
   CSS `order`, so reading order in markup always matches reading order
   on screen). Photo and text animate independently and at their own
   pace: the photo through the same scroll-scrubbed [data-reveal-media]
   zoom used everywhere else on the site, the text through the standard
   [data-split]/[data-reveal] line reveal — both riding the site's
   existing Lenis+GSAP/ScrollTrigger scroll rig (this is that same rig's
   job — the one Locomotive Scroll would otherwise do — so a second
   smooth-scroll library was not added alongside it). */
.story {
  padding: 40px var(--pad) 20px;
  display: flex;
  flex-direction: column;
  gap: clamp(70px, 11vw, 140px);
}
.story-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(36px, 5.5vw, 100px);
  align-items: center;
}
.story-media {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  border-radius: var(--radius);
  background: var(--paper-hi);
  box-shadow: 0 30px 60px -24px rgba(13, 27, 21, 0.35);
}
.story-media img, .story-media video { width: 100%; height: 100%; object-fit: cover; }
.story-kicker {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 16px;
}
.story-text h3 {
  font-size: clamp(26px, 3.4vw, 42px);
  margin-bottom: 18px;
}
.story-text p { color: var(--muted); font-size: 17px; font-weight: 500; max-width: 46ch; }

/* more chapter layouts beyond the plain 50/50 split, so the story
   reads like an edited sequence of spreads rather than one template
   repeated with the sides mirrored — each used exactly once. */

/* --stacked: full-width photo, caption centered underneath — a quiet
   "breather" beat between the side-by-side chapters */
.story-row--stacked { display: block; }
.story-row--stacked .story-media { aspect-ratio: 21 / 9; margin-bottom: 40px; }
.story-row--stacked .story-text { max-width: 640px; margin: 0 auto; text-align: center; }
.story-row--stacked .story-text p { margin: 0 auto; }

/* --offset: the photo runs larger and the copy sits lower, so the pair
   reads as one asymmetric composition instead of two equal halves */
.story-row--offset { grid-template-columns: 1.35fr 1fr; }
.story-row--offset .story-text { padding-top: clamp(20px, 6vw, 90px); align-self: start; }
.story-row--offset .story-media { aspect-ratio: 3 / 4; }

/* --offset-flip: the mirror of --offset — copy runs smaller on the left,
   the photo runs larger on the right; DOM order matches (text markup
   comes first), keeping the --flip convention that reading order always
   matches the visual order instead of fighting it with CSS order */
.story-row--offset-flip { grid-template-columns: 1fr 1.35fr; }
.story-row--offset-flip .story-text { padding-top: clamp(20px, 6vw, 90px); align-self: start; }
.story-row--offset-flip .story-media { aspect-ratio: 3 / 4; }

/* --overlay: the photo goes full-bleed and the copy floats over it in
   its own paper-toned card — the boldest beat, reserved for one chapter */
.story-row--overlay { display: block; position: relative; }
.story-row--overlay .story-media { aspect-ratio: 16 / 9; }
.story-row--overlay .story-text {
  position: absolute;
  left: clamp(20px, 5vw, 56px);
  bottom: clamp(20px, 5vw, 56px);
  max-width: 420px;
  background: var(--paper-hi);
  padding: clamp(22px, 3vw, 34px);
  border-radius: var(--radius);
  box-shadow: 0 26px 54px -20px rgba(13, 27, 21, 0.45);
}
.story-row--overlay .story-kicker { margin-bottom: 10px; }

/* --flank: two photos bracket a centered column of copy — the one
   three-way beat, for the one chapter with a genuine pair to show */
.story-row--flank {
  grid-template-columns: 1fr 1.25fr 1fr;
  gap: clamp(24px, 4vw, 56px);
}
.story-row--flank .story-media { aspect-ratio: 3 / 4; }
.story-row--flank .story-text { text-align: center; }
.story-row--flank .story-text p { margin: 0 auto; }

/* --scene: hosts the Three.js hang-tag scene. Floats directly on the
   page's own background like the old CSS 3D object did — no card behind
   it, unlike the plain .story-media rows this overrides (background,
   shadow, radius all off; the tags' own lighting/shadow-plane inside the
   scene does the "lifted off the page" work instead). */
.story-media--scene {
  overflow: visible;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  box-shadow: none;
  border-radius: 0;
}
.tag-scene {
  width: 100%;
  height: 100%;
}
.tag-scene canvas { display: block; width: 100%; height: 100%; }

/* --reveal-follow: a media element that only starts its own entrance
   (fade + scale, same feel as [data-reveal-media]) once the copy sitting
   next to it has finished animating in — driven from js/main.js, which
   watches the row's [data-reveal] text for its transitions to end before
   adding .in-view here, rather than firing off this element's own scroll
   position like [data-reveal-media] does. */
[data-reveal-follow] {
  opacity: 0;
  transform: scale(1.06);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
[data-reveal-follow].in-view {
  opacity: 1;
  transform: scale(1);
}
@media (prefers-reduced-motion: reduce) {
  [data-reveal-follow] { opacity: 1; transform: none; transition: none; }
}

@media (max-width: 860px) {
  .story-row, .story-row--flip, .story-row--offset, .story-row--offset-flip, .story-row--flank { grid-template-columns: 1fr; gap: 28px; }
  .story-row--flip .story-media { order: 0; }
  .story-row--flip .story-text { order: 1; }
  .story-media { aspect-ratio: 4 / 3; }
  .story-row--offset .story-text, .story-row--offset-flip .story-text { padding-top: 0; }
  .story-row--stacked .story-media { aspect-ratio: 4 / 3; margin-bottom: 24px; }
  .story-row--stacked .story-text { text-align: left; }
  /* the floating card only works with room to float in — on narrow
     screens it becomes a plain block stacked under the photo instead */
  .story-row--overlay .story-media { aspect-ratio: 4 / 3; }
  .story-row--overlay .story-text {
    position: static;
    max-width: none;
    margin-top: 24px;
    box-shadow: none;
    padding: 0;
    background: none;
  }
  /* rows stack into a single column here, so "comes from the right/left"
     stops meaning anything — back to the plain rise-up reveal */
  [data-reveal="right"], [data-reveal="left"] { transform: translateY(28px) scale(0.98); }
}

@media (max-width: 700px) {
  .project-meta { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
}
@media (max-width: 460px) {
  .project-meta { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .project-images { grid-template-columns: 1fr; }
}
.next-project {
  display: inline-flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 90px;
  font-family: var(--display);
  font-size: clamp(28px, 4vw, 56px);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  transition: color .3s var(--ease);
}
.next-project small {
  font-size: 13px;
  letter-spacing: 0.12em;
  color: var(--accent);
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
}
.next-project:hover { color: var(--accent); }

/* ---------- home: featured projects — pinned cinematic crossfade ---------- */

.home-featured { padding: 20px 0 60px; }
.home-featured .section-head { padding: 0 var(--pad) 40px; max-width: 760px; }
.home-featured-sub { color: var(--muted); font-size: 17px; font-weight: 500; max-width: 640px; margin-top: 20px; margin-bottom: 60px; }

/* .hf-pinwrap is one tall scroll runway (its height is set in JS, from the
   same perSlide/count the progress tracker below uses); .hf-pin is plain
   CSS position:sticky — NOT a JS/ScrollTrigger pin — so it holds
   center-screen for that whole runway without ever pausing or hijacking
   scroll input. Deck-of-cards stack: every slide sits in the same spot at
   all times — moving to the next one lifts the current slide off the top
   (is-exited, slides fully out of frame, staying opaque throughout so it
   reads as physically leaving) which reveals the next slide fading into
   view underneath, instead of crossfading between them. Queued slides
   stay at opacity 0 (not just dimmed) since they share the exact same
   layout box as the active one — anything above zero bleeds its title/
   caption text into the active slide's. */
.hf-pinwrap { position: relative; }
.hf-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 0 var(--pad);
}
.hf-stage {
  position: relative;
  width: min(1300px, 94vw);
  height: min(76vh, 720px);
  /* .hf-pin clips at the viewport edge, but that leaves the empty space
     it centers .hf-stage within (above/below the card itself) unclipped —
     an exiting slide's title, translating up out of the stage, would
     still be visible drifting through that space instead of disappearing
     at the card's own top edge. Clipping here instead means it gets cut
     off exactly there, so no exiting slide's text is ever visible above
     the incoming one. */
  overflow: hidden;
}
.hf-slide {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  pointer-events: none;
  z-index: 1;
}
.hf-slide.is-active { pointer-events: auto; z-index: 3; }
.hf-slide.is-exited { pointer-events: none; z-index: 4; }
/* only the photo travels — the caption (.hf-arrow/.hf-info) fades in
   place instead of riding along with it. They share one flex box, so
   sliding the whole slide would carry the outgoing title up through the
   middle of the frame as it left, visibly crossing over the incoming
   card underneath. Fading it in place keeps every exit confined to the
   photo itself, so no exiting slide's text is ever visible over the next
   one, at the top or anywhere else. */
.hf-media {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 30px 70px -20px rgba(0, 0, 0, 0.55);
  opacity: 0;
  transform: translateY(0);
  transition: transform 1.05s var(--ease-io), opacity .5s var(--ease);
}
.hf-slide.is-active .hf-media { opacity: 1; transform: translateY(0); }
.hf-slide.is-exited .hf-media { opacity: 1; transform: translateY(-112%); }
.hf-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.4s var(--ease);
}
.hf-slide.is-active .hf-media img { transform: scale(1.04); }
.hf-arrow {
  position: absolute;
  top: 20px; left: 20px;
  z-index: 2;
  width: 50px; height: 50px;
  border-radius: 50%;
  background: var(--paper-hi);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: background .3s var(--ease), transform .4s var(--ease), opacity .3s var(--ease);
}
.hf-slide.is-active .hf-arrow { opacity: 1; }
.hf-arrow svg { width: 19px; height: 19px; transition: transform .4s var(--ease); }
.hf-slide:hover .hf-arrow { background: var(--accent); transform: scale(1.08); }
.hf-slide:hover .hf-arrow svg { transform: rotate(45deg); }
.hf-info {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 20px;
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.hf-slide.is-active .hf-info { opacity: 1; }
.hf-info h3 {
  font-family: var(--display);
  font-size: clamp(18px, 2.2vw, 28px);
  font-weight: 800;
  text-transform: uppercase;
  color: var(--accent);
  transition: color .3s var(--ease);
}
.hf-slide:hover .hf-info h3 { color: var(--fg); }
.hf-info p { font-size: 13px; color: var(--muted); font-weight: 600; letter-spacing: 0.02em; }

.hf-dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: 26px;
}
.hf-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line-strong); transition: background .3s var(--ease), transform .3s var(--ease); }
.hf-dot.is-active { background: var(--accent); transform: scale(1.35); }

.see-more {
  display: block;
  width: max-content;
  margin: 60px auto 0;
  font-size: clamp(18px, 2vw, 26px) !important;
}

@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  .hf-pinwrap { height: auto !important; }
  .hf-pin {
    position: static;
    height: auto;
    padding: 0 var(--pad);
  }
  .hf-stage { position: static; width: 100%; height: auto; display: flex; flex-direction: column; gap: 60px; }
  .hf-slide {
    position: static;
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .hf-media { aspect-ratio: 4 / 3; flex: none; }
  .hf-dots { display: none; }
}

/* ---------- web dev: fanned card spread ----------
   a hand of cards held fanned out, each one's rest position set by
   --fanx/--fany/--fanr/--fanz (inline per card, in the HTML) — not a
   scroll-driven carousel, just a still spread like a fanned photo stack.
   Hovering one card sets a new --fanx/--fany/--fanr/--fanz on every card
   in JS (computed from each one's own base values, stored once on load):
   the hovered card lifts, straightens and scales up in front of the
   others; its neighbors get pushed further outward and rotated a touch
   more, the way a real stack of cards gives way under a finger pressing
   into it. Restoring on mouseleave just writes the original base values
   back — the CSS transition on transform does the rest, so nothing here
   needs its own animation loop. */
.wd-fan {
  position: relative;
  height: min(620px, 68vh);
  max-width: 1100px;
  margin: 56px auto 0;
}
.wd-card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(340px, 32vw);
  aspect-ratio: 3 / 4;
  z-index: var(--fanz, 1);
  transform:
    translate(-50%, -50%)
    translate(var(--fanx, 0%), var(--fany, 0%))
    rotate(var(--fanr, 0deg))
    scale(var(--fanscale, 1));
  transition: transform .6s var(--ease-io);
}
.wd-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: var(--radius);
  box-shadow: 0 30px 60px -16px rgba(0, 0, 0, 0.6);
  background: #12141a;
}
.wd-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform .6s var(--ease);
}
.wd-card:hover .wd-media img { transform: scale(1.06); }
.wd-info {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 14px;
  padding: 20px;
  border-radius: 0 0 var(--radius) var(--radius);
  background: linear-gradient(to top, rgba(1, 17, 17, 0.85), transparent 70%);
  opacity: 0;
  transition: opacity .35s var(--ease);
}
.wd-card:hover .wd-info { opacity: 1; }
.wd-info h3 {
  font-family: var(--display);
  font-size: clamp(15px, 1.5vw, 19px);
  font-weight: 800;
  text-transform: uppercase;
  color: #fff;
}
.wd-info p { display: none; }
.wd-info-arrow {
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.wd-info-arrow svg { width: 15px; height: 15px; }

@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  .wd-fan { position: static; height: auto; max-width: none; display: flex; flex-direction: column; gap: 36px; }
  .wd-card { position: static; transform: none !important; width: 100%; aspect-ratio: 3 / 4; }
  .wd-info { opacity: 1; }
}

/* ---------- studio principles + impact stats ---------- */

.principles {
  background: var(--ink);
  color: var(--fg);
  padding: 90px var(--pad);
}
.principles-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  margin-bottom: 44px;
}
.principles-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(20px, 3vw, 40px);
}
.principle h3 { font-size: clamp(17px, 1.6vw, 23px); margin-bottom: 10px; }
.principle p { font-size: 14px; font-weight: 500; color: rgba(240, 244, 238, 0.6); }

@media (max-width: 900px) {
  .principles-grid { grid-template-columns: repeat(2, 1fr); row-gap: 36px; }
}
@media (max-width: 480px) {
  .principles-grid { grid-template-columns: 1fr; }
}

.stat--plus .stat-num::after { content: '+'; }
.stat--pct .stat-num::after { content: '%'; }
.stat-num-static {
  font-family: var(--display);
  font-size: clamp(26px, 3vw, 40px);
  font-weight: 800;
  text-transform: uppercase;
  color: var(--teal);
}

/* ---------- pricing ---------- */

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 40px);
  padding: 30px var(--pad) 60px;
  align-items: stretch;
}
.price-card {
  position: relative;
  background: var(--bg-hi);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  padding: 40px 32px 36px;
  display: flex;
  flex-direction: column;
  transition: transform .4s var(--ease), border-color .4s var(--ease);
}
.price-card:hover { transform: translateY(-8px); border-color: var(--accent); }
.price-card--featured {
  background: var(--accent);
  color: var(--ink);
  transform: scale(1.045);
  z-index: 2;
  box-shadow: 0 30px 70px -24px rgba(0, 0, 0, 0.6);
}
.price-card--featured:hover { transform: scale(1.045) translateY(-8px); }
.price-card-badge {
  position: absolute;
  top: -16px; right: 28px;
  background: var(--ink);
  color: var(--accent);
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 8px 16px;
  border-radius: 999px;
  rotate: 4deg;
}
.price-card-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  margin-bottom: 14px;
}
.price-card--featured .price-card-tag { color: var(--ink); opacity: 0.7; }
.price-card h3 { font-size: clamp(22px, 2.2vw, 28px); margin-bottom: 18px; }
.price-card-amount {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-family: var(--display);
  margin-bottom: 10px;
}
.price-card-amount .from { font-size: 12px; font-weight: 700; text-transform: uppercase; color: var(--muted); }
.price-card--featured .price-card-amount .from { color: var(--ink); opacity: 0.65; }
.price-card-amount .num { font-size: clamp(38px, 4vw, 52px); font-weight: 900; }
.price-card-amount .unit { font-size: 14px; font-weight: 700; color: var(--muted); }
.price-card--featured .price-card-amount .unit { color: var(--ink); opacity: 0.65; }
.price-card-desc { font-size: 14px; color: var(--muted); font-weight: 500; margin-bottom: 26px; }
.price-card--featured .price-card-desc { color: var(--ink); opacity: 0.8; }
.price-card-list {
  list-style: none;
  border-top: 2px dashed var(--line);
  padding-top: 22px;
  margin-bottom: 30px;
  display: flex;
  flex-direction: column;
  gap: 13px;
  flex: 1;
}
.price-card--featured .price-card-list { border-top-color: rgba(13, 27, 21, 0.25); }
.price-card-list li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 14px;
  font-weight: 500;
}
.price-card-list svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 2px; color: var(--accent); }
.price-card--featured .price-card-list svg { color: var(--ink); }
.price-card-cta {
  display: block;
  text-align: center;
  font-family: var(--display);
  font-weight: 800;
  text-transform: uppercase;
  font-size: 14px;
  letter-spacing: 0.02em;
  padding: 15px;
  border-radius: 999px;
  border: 2.5px solid var(--fg);
  color: var(--fg);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.price-card-cta:hover { background: var(--fg); color: var(--ink); }
.price-card--featured .price-card-cta { border-color: var(--ink); color: var(--ink); }
.price-card--featured .price-card-cta:hover { background: var(--ink); color: var(--accent); border-color: var(--ink); }

.pricing-note {
  text-align: center;
  max-width: 600px;
  margin: 0 auto;
  padding: 0 var(--pad) 150px;
  color: var(--muted);
  font-size: 14px;
  font-weight: 500;
}
.pricing-note strong { color: var(--fg); }

@media (max-width: 900px) {
  .pricing-grid { grid-template-columns: 1fr; }
  .price-card--featured { transform: none; }
  .price-card--featured:hover { transform: translateY(-8px); }
}

/* ---------- special offers ---------- */

.offers {
  padding: 130px var(--pad) 150px;
  background: radial-gradient(circle at 50% 30%, #1a2929 0%, #142323 18%, #061616 60%, #011111 100%);
  color: #f2f2f2;
}
.offers-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(24px, 3vw, 46px);
  margin-top: 60px;
  max-width: 1100px;
  margin-left: auto;
  margin-right: auto;
}
.offer-card {
  position: relative;
  background: rgba(240, 244, 238, 0.04);
  border: 2px solid rgba(240, 244, 238, 0.14);
  border-radius: var(--radius);
  padding: 44px 38px;
  overflow: hidden;
  transition: border-color .35s var(--ease), transform .35s var(--ease);
}
.offer-card:hover { border-color: var(--accent); transform: translateY(-6px); }
.offer-card-blob {
  position: absolute;
  right: -60px; top: -60px;
  width: 200px; height: 200px;
  background: var(--accent);
  opacity: 0.06;
  border-radius: 50%;
}
.offer-card-pct {
  position: relative;
  font-family: var(--display);
  font-size: clamp(50px, 6vw, 80px);
  font-weight: 900;
  color: var(--accent);
  line-height: 1;
  margin-bottom: 18px;
}
.offer-card h3 { position: relative; font-size: clamp(20px, 2vw, 26px); margin-bottom: 12px; }
.offer-card p {
  position: relative;
  color: rgba(240, 244, 238, 0.65);
  font-size: 14.5px;
  font-weight: 500;
  margin-bottom: 26px;
  max-width: 380px;
}
.offer-card-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--accent);
  transition: gap .3s var(--ease);
}
.offer-card-link svg { width: 14px; height: 14px; }
.offer-card:hover .offer-card-link { gap: 14px; }

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

/* ---------- project gallery (case study extras) ---------- */

.gallery-head {
  padding: 90px var(--pad) 30px;
  max-width: 700px;
}
.gallery-kicker {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--accent);
  margin-bottom: 16px;
}
.gallery-head h2 { font-size: clamp(30px, 4.5vw, 54px); margin-bottom: 14px; }
.gallery-head p { color: var(--muted); font-size: 15px; font-weight: 500; }

/* ---------- gallery: "the proof" — big 3D photos, panned by scroll ----------
   no background scene at all now — just the page's own paper colour —
   and no fixed {top, left} scatter either: the photos sit in one row
   (.photo3d-track, reusing the same [data-hscroll] pinned-scroll-pan
   rig the web-dev case studies use — see js/main.js) that pans left as
   the page scrolls down, so photos arrive from the right one at a time
   instead of all being visible loose in a scene at once. Alternating
   .photo3d--top/--bottom (align-self: flex-start/flex-end inside the
   flex row) staggers them high-low-high-low as they cross the screen,
   the "one top left, one bottom right" rhythm — and each one is a real
   tilted object (perspective + rotateY on its own preserve-3d layer),
   not a flat image, matching how every other "3D" photo on this page
   is built. */
.photo3d-pinwrap { position: relative; }
.photo3d-track { align-items: center; }
.photo3d {
  flex: 0 0 auto;
  width: min(440px, 40vw);
  aspect-ratio: 4 / 5;
  perspective: 1600px;
}
.photo3d--top { align-self: flex-start; margin-top: 7vh; }
.photo3d--bottom { align-self: flex-end; margin-bottom: 7vh; }
.photo3d-inner {
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateY(-11deg) rotateX(3deg);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 44px 84px -20px rgba(13, 27, 21, 0.5);
}
.photo3d--bottom .photo3d-inner { transform: rotateY(11deg) rotateX(-3deg); }
.photo3d-inner img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 900px) {
  .photo3d { width: min(320px, 62vw); }
}

.gallery-float {
  margin: 10px auto 20px;
  padding: 20px var(--pad) 10px;
  max-width: 900px;
  display: flex;
  justify-content: center;
}
.gallery-float img {
  width: 100%;
  max-width: 620px;
  height: auto;
  display: block;
  filter: drop-shadow(0 46px 40px rgba(0, 0, 0, 0.45)) drop-shadow(0 12px 16px rgba(0, 0, 0, 0.35));
  transition: transform .6s var(--ease);
}
.gallery-float:hover img { transform: translateY(-10px); }
.gallery-float-caption { text-align: center; }

/* ---------- simple gallery: tinted static grid ----------
   the closing gallery on the other project pages — deliberately a
   different layout from Malina's floating nebula scene: a plain, static,
   rounded-panel grid tinted in the project's own colour (--sg-tint, set
   inline per page) with a gentle hover lift, no drift, no preview panel. */
.simple-gallery {
  background: var(--sg-tint, var(--paper-hi));
  margin: 0 var(--pad) 26px;
  border-radius: var(--radius);
  padding: clamp(28px, 4vw, 56px);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(18px, 2.4vw, 30px);
}
.simple-gallery-item {
  border-radius: calc(var(--radius) / 2);
  overflow: hidden;
  box-shadow: 0 20px 40px -20px rgba(13, 27, 21, 0.35);
  transition: transform .4s var(--ease), box-shadow .4s var(--ease);
}
.simple-gallery-item:hover {
  transform: translateY(-8px);
  box-shadow: 0 30px 54px -18px rgba(13, 27, 21, 0.45);
}
.simple-gallery-item img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  display: block;
  scale: 1.02;
  transition: scale .6s var(--ease);
}
.simple-gallery-item:hover img { scale: 1.08; }
.simple-gallery-caption {
  margin: 10px 2px 0;
  font-size: 11.5px;
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.gallery-next { padding: 0 var(--pad) 150px; }

/* ---------- web dev case studies: a different template entirely ----------
   the brand-identity case studies (malina.html and friends) all run on
   .story/.gallery-head/.simple-gallery over body.project-light's white
   theme. These stay on the site's own dark theme instead and use a
   completely different set of sections — a full-viewport title hero, a
   pinned horizontal feature scroller, a stat band — so a web-dev project
   doesn't just look like a brand case study with different photos. */

.wdcase-hero {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 140px var(--pad) 60px;
}
.wdcase-hero-tag {
  display: inline-block;
  width: max-content;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 22px;
}
.wdcase-hero-title {
  font-size: clamp(56px, 11vw, 160px);
  line-height: 0.92;
  margin-bottom: 26px;
}
.wdcase-hero-sub {
  max-width: 640px;
  font-size: clamp(16px, 1.6vw, 20px);
  color: var(--muted);
  font-weight: 500;
  margin-bottom: 56px;
}
.wdcase-hero-frame {
  width: 100%;
  aspect-ratio: 16 / 9.5;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 50px 100px -30px rgba(0, 0, 0, 0.7);
  margin-bottom: 48px;
}
.wdcase-hero-frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wdcase-hero-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  border-top: 1.5px solid var(--line);
  padding-top: 26px;
}
.wdcase-hero-meta div { display: flex; flex-direction: column; gap: 6px; }
.wdcase-hero-meta span { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); font-weight: 700; }
.wdcase-hero-meta strong, .wdcase-hero-meta div > *:last-child:not(span) { font-weight: 700; }

.wdcase-intro {
  padding: 110px var(--pad) 60px;
  max-width: 900px;
}
.wdcase-intro p {
  font-family: var(--display);
  font-size: clamp(24px, 3.4vw, 42px);
  font-weight: 700;
  line-height: 1.3;
}
.wdcase-intro em { color: var(--accent); font-style: normal; }

/* ---------- reusable pinned horizontal scroller ----------
   same "plain CSS position:sticky, JS just reads scroll progress"
   approach as .hf-pin/.wd-pin above — here the progress drives a
   continuous translateX scrub of .hscroll-track instead of a stepped
   card-index change, so the row pans smoothly left as the page scrolls
   down, rather than snapping between fixed states. */
.hscroll-pinwrap { position: relative; }
.hscroll-pin {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.hscroll-track {
  display: flex;
  gap: clamp(24px, 4vw, 64px);
  padding-left: var(--pad);
  will-change: transform;
}
.hscroll-panel {
  flex: 0 0 auto;
  width: min(640px, 76vw);
}
.hscroll-num {
  display: block;
  font-family: var(--display);
  font-size: clamp(40px, 5vw, 64px);
  font-weight: 800;
  color: var(--accent);
  margin-bottom: 18px;
}
.hscroll-panel-media {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 30px 60px -20px rgba(0, 0, 0, 0.6);
  margin-bottom: 24px;
}
.hscroll-panel-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hscroll-panel h3 { font-size: clamp(20px, 2.2vw, 28px); margin-bottom: 10px; }
.hscroll-panel p { color: var(--muted); font-size: 15px; font-weight: 500; max-width: 46ch; }

.wdcase-stats {
  padding: 110px var(--pad);
  display: grid;
  grid-template-columns: repeat(4, auto);
  gap: 40px;
  border-top: 1.5px solid var(--line);
}
.wdcase-stats .stat-num { color: var(--accent); }

.wdcase-close {
  padding: 60px var(--pad) 150px;
}

@media (max-width: 900px) {
  .wdcase-hero-meta { grid-template-columns: repeat(2, 1fr); row-gap: 22px; }
  .wdcase-stats { grid-template-columns: repeat(2, auto); }
  .hscroll-panel { width: 84vw; }
}
@media (max-width: 900px), (prefers-reduced-motion: reduce) {
  .hscroll-pinwrap { height: auto !important; }
  .hscroll-pin { position: static; height: auto; padding: 40px 0; }
  .hscroll-track { flex-direction: column; padding-left: var(--pad); padding-right: var(--pad); transform: none !important; }
}

/* ---------- project case-study pages: white theme ---------- */
/* scoped to body.project-light so the work index and every other page keep
   the dark theme untouched — reuses the site's own paper/ink/teal pairing
   (the same one .about/.team/.process already use for their light bands)
   instead of inventing a new palette. */

body.project-light {
  --bg: var(--paper);
  --fg: var(--ink);
  --muted: rgba(13, 27, 21, 0.58);
  --line: rgba(13, 27, 21, 0.12);
  --line-strong: rgba(13, 27, 21, 0.25);
  color-scheme: light;
}

body.project-light em { color: var(--teal); }

/* malina only: the body copy's usual grey (--muted) reads as the site's
   own dark green instead, on this page alone */
body.project-light--malina { --muted: var(--teal); }

/* header sits transparent over the page on every route; give it the inverse
   treatment (dark ink instead of white) so it stays legible over paper */
body.project-light .nav-link { color: var(--ink); text-shadow: 0 1px 2px rgba(255, 255, 255, 0.6); }
body.project-light .nav-social-link { border-color: rgba(13, 27, 21, 0.3); color: var(--ink); }
body.project-light .nav-toggle span { background: var(--ink); }
body.project-light .cursor-ring { border-color: rgba(13, 27, 21, 0.35); }

body.project-light .section-tag:hover { background: var(--ink); color: var(--paper-hi); }

/* the services flyout stays a dark glass panel at any width the mouse can
   trigger it from — restore its light-on-dark text there only */
@media (min-width: 681px) {
  body.project-light .nav-dropdown a { color: rgba(240, 244, 238, 0.92); }
}

