/* Marketingz — art direction, with reasons.

   The page is a journey, not five panels. It opens at night: one person alone
   in the dark, which is what running a business without a system actually
   feels like. It warms through the middle as the work gets done. It ends in
   first light. The colour does the narrating, so the copy never has to say
   any of this out loud.

   Because of that, almost every colour here is a variable that site.js
   interpolates from scroll position across three stops:
     NIGHT  cold, near-black, a cyan cast   — alone
     EMBER  warm, low amber                 — we are working
     DAWN   soft rose, the ground lifts     — it is running

   The shift has to stay under the threshold of notice from one screen to the
   next. Read as a gradient it should be obvious; read screen by screen it
   should be invisible. That restraint is the whole trick.

   Type: three serifs, one job each. Playfair Display carries statements,
   Cinzel (Roman inscriptional capitals) carries every label, EB Garamond
   carries reading copy. No sans anywhere — one would drag this back to a
   product page. */

:root {
  /* Interpolated live by site.js. These are the NIGHT values. */
  --bg: #05070a;
  --text: #e8e6e2;
  --muted: #7d8288;
  --faint: #3b4148;
  --rule: #1b2128;
  --accent: #4fbfb8;

  --display: "Playfair Display", Georgia, serif;
  --caps: "Cinzel", Georgia, serif;
  --body: "EB Garamond", Georgia, serif;

  --pad: clamp(22px, 5vw, 78px);
  --rail: clamp(0px, 9vw, 148px);
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.85;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  transition: background 0.6s linear;
}

a { color: inherit; text-decoration: none; }
img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ---------- atmosphere ----------
   A soft tinted veil over everything. It is what makes the three stages read
   as one continuous air rather than as three different websites. */
/* The liquid layer: a live WebGL field flowing behind the whole page, tinted
   by the current stage and churned by scroll velocity. Sits under everything;
   if WebGL fails it simply never appears and the flat ground remains. */
/* Layered stage media. Each stage frame holds three things stacked: the still
   photograph (fallback), the same photograph rendered through the water shader,
   and a fog layer drifting independently above it. The independence is the
   point — one displaced photo ripples in place, two layers travelling at
   different speeds is what reads as weather. */
/* Reveal canvas sits over the still <img> (which stays as the no-WebGL
   fallback) and is hidden once the GL canvas is up. */
[data-liquid] .reveal-gl { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
[data-liquid].is-reveal > img { opacity: 0; }

/* Hero fog layer: drifting cloud between the photograph and the headline. */
.hero-fog { position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: screen; }
.hero-fog-gl { display: block; width: 100%; height: 100%; }

.atmos {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: soft-light;
  opacity: 0.9;
  background:
    radial-gradient(120% 90% at 50% 110%, var(--accent), transparent 62%);
  transition: background 0.6s linear;
}

/* ---------- entrance ---------- */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: #05070a;
  display: flex;
  align-items: flex-end;
  padding: var(--pad);
}
.pre-count {
  font-family: var(--display);
  font-size: clamp(2.4rem, 7vw, 5rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: #4a5057;
}

/* ---------- nav ---------- */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: var(--pad);
  mix-blend-mode: difference;
}
.brand { display: flex; flex-direction: column; gap: 0.45rem; }
.brand-mark { font-family: var(--display); font-size: 1.85rem; line-height: 1; }
.brand-name {
  font-family: var(--caps);
  font-size: 0.54rem;
  letter-spacing: 0.42em;
  opacity: 0.65;
}
.nav-right { display: flex; gap: 2.25rem; }
.nav-right a {
  font-family: var(--caps);
  font-size: 0.58rem;
  letter-spacing: 0.3em;
  opacity: 0.75;
  transition: opacity 0.4s ease;
}
.nav-right a:hover { opacity: 1; }

/* ---------- rail ----------
   A quiet index of where you are in the journey. It reports position; it does
   not compete for attention, which is why it is set at the size of a caption. */
.rail {
  position: fixed;
  left: var(--pad);
  top: 50%;
  transform: translateY(-50%);
  z-index: 55;
  pointer-events: none;
}
.rail ol { list-style: none; display: flex; flex-direction: column; gap: 1.1rem; }
.rail li {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  font-family: var(--caps);
  font-size: 0.5rem;
  letter-spacing: 0.28em;
  color: var(--faint);
  transition: color 0.6s ease;
}
/* Scaled, not widened: animating width here would relayout the row on every
   rail change. transform-origin keeps it growing rightward as before. */
.rail li i {
  width: 30px; height: 1px;
  background: currentColor;
  display: block;
  transform: scaleX(0.47);
  transform-origin: left center;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1), background 0.6s ease;
}
.rail li.on { color: var(--text); }
.rail li.on i { transform: scaleX(1); background: var(--accent); }

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

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  padding: var(--pad) var(--pad) clamp(3rem, 10vh, 7rem);
  overflow: hidden;
  z-index: 2;
}
.hero-img { position: absolute; inset: 0; z-index: 0; }
.hero-img img,
.hero-img video { width: 100%; height: 100%; object-fit: cover; filter: brightness(0.42) contrast(1.1) saturate(0.72); transform: scale(1.06); }
.hero-img::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg) 1%, rgba(5, 7, 10, 0.35) 50%, rgba(5, 7, 10, 0.55) 100%);
}
.hero-type { position: relative; z-index: 2; max-width: min(92%, 46rem); }
.kicker {
  font-family: var(--caps);
  font-size: 0.58rem;
  letter-spacing: 0.4em;
  color: var(--muted);
  margin-bottom: 2.25rem;
}
h1 {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(2rem, 5.2vw, 4.3rem);
  line-height: 1.18;
}
.hero-sub {
  margin-top: 1.75rem;
  max-width: 34ch;
  color: #b9bcc0;
  font-size: clamp(1rem, 1.2vw, 1.14rem);
}

/* ---------- movements ---------- */

.movement,
.closing {
  position: relative;
  z-index: 2;
  padding: clamp(8rem, 24vh, 18rem) var(--pad) clamp(8rem, 24vh, 18rem)
           calc(var(--pad) + var(--rail));
  max-width: 1560px;
}

/* Sticky label: it rides with you through the whole movement and releases at
   the end, rather than sitting parked at the top. */
.movement-label {
  position: sticky;
  top: clamp(7rem, 24vh, 12rem);
  float: left;
  margin-left: calc((var(--rail) + clamp(0.6rem, 1.6vw, 1.4rem)) * -1);
  writing-mode: vertical-rl;
  font-family: var(--caps);
  font-size: 0.52rem;
  letter-spacing: 0.42em;
  color: var(--faint);
  height: 0;
  transition: color 0.6s ease;
}

.lead {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.55rem, 4vw, 3.3rem);
  line-height: 1.3;
  max-width: 30ch;
  margin-bottom: clamp(2.25rem, 6vh, 4.5rem);
}
.body {
  font-size: clamp(1rem, 1.15vw, 1.12rem);
  line-height: 1.95;
  color: #b4b7bb;
  max-width: 48ch;
}

/* ---------- tenets ---------- */

.tenets { list-style: none; margin-top: clamp(3rem, 9vh, 7rem); }
.tenets li {
  display: flex;
  gap: clamp(1.25rem, 4.5vw, 4rem);
  padding: clamp(2.25rem, 6vh, 4rem) 0;
  border-top: 1px solid var(--rule);
}
.tenets li:last-child { border-bottom: 1px solid var(--rule); }
.tenet-n, .work-n {
  font-family: var(--caps);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  color: var(--accent);
  flex-shrink: 0;
  min-width: 2.25rem;
  padding-top: 0.75rem;
  transition: color 0.6s ease;
}
.tenets h2, .works h2 {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(1.3rem, 2.5vw, 2rem);
  line-height: 1.25;
  margin-bottom: 0.9rem;
}

/* ---------- plates (b-roll) ----------
   Offset, overlapping, floating in the dark. A neat grid here would read as a
   portfolio template; the asymmetry is what makes them feel placed. */

.plates {
  position: relative;
  z-index: 2;
  padding: clamp(2rem, 8vh, 6rem) var(--pad);
  display: flex;
  justify-content: center;
  gap: clamp(1rem, 4vw, 4rem);
  align-items: flex-start;
}
.plate { overflow: hidden; }
.plate img { filter: brightness(0.62) contrast(1.05) saturate(0.7); }
.plate-a { width: min(30vw, 390px); aspect-ratio: 4 / 5; }
.plate-b { width: min(22vw, 290px); aspect-ratio: 3 / 4; margin-top: clamp(4rem, 15vh, 12rem); }
.plates-warm .plate img { filter: brightness(0.72) contrast(1.02) saturate(0.85); }

/* The middle stage. It gets the same billing as the hero and the closing —
   full bleed, full viewport — because the walk is three beats and the middle
   one collapsing into a small inline strip is what made it read as missing. */
.stage {
  position: relative;
  z-index: 2;
  height: 100svh;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  padding: var(--pad);
}
.stage-img { position: absolute; inset: 0; }
.stage-img img { filter: brightness(0.66) contrast(1.02) saturate(0.9); }
.stage-img::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, var(--bg) 1%, rgba(0, 0, 0, 0.15) 45%, rgba(0, 0, 0, 0.4) 100%);
}
.stage-caption {
  position: relative;
  z-index: 2;
  font-family: var(--display);
  font-style: italic;
  font-size: clamp(1.15rem, 2.4vw, 2rem);
  color: var(--text);
  max-width: 24ch;
}

/* ---------- works: stacked sticky panels ----------
   Each holds at the top while the next climbs over it, so the five arrive as a
   deck being dealt. The opaque background is load-bearing. */

.works { list-style: none; margin-top: clamp(1rem, 4vh, 3rem); }
/* Each panel fills the slot beneath the sticky offset and centres its content.
   Short panels were the bug: at 336px in a 639px slot the next card rose over
   the previous one mid-sentence, which read as the text being cropped rather
   than as a card being replaced. Filling the slot means a panel is always
   completely readable while it is the one on top. */
.works.stack li {
  position: sticky;
  top: clamp(6rem, 20vh, 10rem);
  min-height: calc(100svh - clamp(6rem, 20vh, 10rem));
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 4.5vw, 4rem);
  padding: clamp(2rem, 5vh, 3rem) 0 clamp(2rem, 5vh, 3rem);
  background: var(--bg);
  border-top: 1px solid var(--rule);
  transition: background 0.6s linear;
}
.works.stack li:nth-child(1) { z-index: 1; }
.works.stack li:nth-child(2) { z-index: 2; }
.works.stack li:nth-child(3) { z-index: 3; }
.works.stack li:nth-child(4) { z-index: 4; }
.works.stack li:nth-child(5) { z-index: 5; }
.works.stack li:nth-child(6) { z-index: 6; }

/* The rule wipes in from the left as each panel arrives. */
.works.stack li::before {
  content: "";
  position: absolute;
  top: -1px; left: 0; right: 0;
  height: 1px;
  background: var(--accent);
  clip-path: inset(0 100% 0 0);
}
.works.stack li.wiped::before {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.work-for {
  font-family: var(--caps);
  font-size: 0.52rem;
  letter-spacing: 0.24em;
  color: var(--faint);
  margin-top: 1.6rem;
}

/* ---------- method ---------- */

.method { list-style: none; margin-top: clamp(1rem, 4vh, 3rem); }
.method li {
  display: flex;
  gap: clamp(1.25rem, 4.5vw, 4rem);
  align-items: baseline;
  padding: clamp(1.75rem, 5vh, 3rem) 0;
  border-top: 1px solid var(--rule);
}
.method li:last-child { border-bottom: 1px solid var(--rule); }
.method span {
  font-family: var(--caps);
  font-size: 0.62rem;
  letter-spacing: 0.26em;
  color: var(--accent);
  min-width: 7rem;
  flex-shrink: 0;
  transition: color 0.6s ease;
}

/* ---------- closing ---------- */

.closing { position: relative; overflow: hidden; }
.closing-img { position: absolute; inset: 0; z-index: 0; }
.closing-img img { filter: brightness(0.5) contrast(1.02) saturate(0.9); transform: scale(1.05); }
.closing-img::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to right, var(--bg) 6%, rgba(5, 7, 10, 0.55) 55%, rgba(5, 7, 10, 0.2) 100%);
}
.closing-type { position: relative; z-index: 2; }
.mail {
  display: inline-block;
  font-family: var(--display);
  font-size: clamp(1rem, 2vw, 1.55rem);
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.5rem;
  margin-bottom: 2.5rem;
  transition: border-color 0.5s ease;
}
.mail:hover { border-color: var(--accent); }

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

.footer {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 2.25rem var(--pad) calc(var(--pad) + 0.5rem);
  border-top: 1px solid var(--rule);
  font-family: var(--caps);
  font-size: 0.52rem;
  letter-spacing: 0.32em;
  color: var(--faint);
}

/* ---------- motion states ---------- */

.ln { display: block; overflow: hidden; }
.ln-i { display: block; }
.js-anim .ln-i {
  transform: translateY(112%);
  transition: transform 1.15s cubic-bezier(0.16, 1, 0.3, 1);
}
.js-anim .ln-i.in { transform: translateY(0); }

.js-anim .rise { opacity: 0; transform: translateY(26px); }
.js-anim .hero-type > * { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js-anim .rise, .js-anim .hero-type > * { opacity: 1; transform: none; }
  .js-anim .ln-i { transform: none; }
  .hero-img img, .hero-img video, .closing-img img { transform: none; }
  .atmos { display: none; }
}

@media (max-width: 900px) {
  :root { --rail: 0px; }
  .rail { display: none; }
  .nav-right { gap: 1.1rem; }
  .nav-right a { font-size: 0.5rem; letter-spacing: 0.2em; }
  .movement-label { display: none; }
  .plates { flex-direction: column; align-items: center; }
  .plate-a { width: min(74vw, 380px); }
  .plate-b { width: min(52vw, 260px); margin-top: -2.5rem; align-self: flex-end; }
  .tenets li, .works.stack li, .method li { flex-direction: column; gap: 0.6rem; }
  .method span { min-width: 0; }
}
