/* ============================================================
   Onkar Gore — cinematic portfolio
   Near-black canvas · Archivo + Geist Mono · zero chroma
   ------------------------------------------------------------
   No accent hue anywhere: the footage is the only coloured thing
   on the page. Because hue can't signal state, every hover runs on
   value instead — muted at rest, bone on hover. Anything that sits
   at full bone already uses a rule or underline for its hover, not
   a colour change.
   ============================================================ */

:root {
  --bg:        #0a0a0b;
  --bg-lift:   #131315;
  /* One light value for the whole site. The wordmark and the body copy
     used to be two different whites — cool #f2f2f3 against warm bone —
     which read as a mistake wherever they stacked. */
  --bone:      #ede7db;      /* film white — warmer than UI white */
  --fg:        var(--bone);
  --muted:     #8c8c92;
  --muted-2:   #5a5a60;
  --line:      rgba(242, 242, 243, 0.13);
  --accent:    var(--bone);  /* the "accent" is just light */
  --accent-rgb: 237, 231, 219;

  --display: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono:  'Geist Mono', ui-monospace, 'SFMono-Regular', monospace;

  --pad: clamp(1.15rem, 4vw, 4rem);
  /* Soft corners are for media surfaces only — the hero panel, the work
     tiles, the lightbox stage. Type and controls stay hard-cornered, so
     the curve reads as "this is a screen showing footage" rather than as
     a stray rounded box. */
  --radius: clamp(0.5rem, 0.75vw, 0.85rem);
  --radius-lg: clamp(0.7rem, 1vw, 1.1rem);
  --ease: cubic-bezier(0.65, 0.05, 0.1, 1);
}

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

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--display);
  font-weight: 400;
  line-height: 1.4;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--accent); color: #0a0a0b; }

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

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

/* Off-screen until focused. Used by the skip link and by the play buttons
   that sit over each tile — both need to be reachable by keyboard and
   assistive tech without appearing in the composition. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 9999;
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase;
  background: var(--bg-lift); color: var(--accent);
  padding: 0.85rem 1.2rem; border: 1px solid var(--line);
}
.skip:focus { left: var(--pad); top: 0.75rem; }

/* ---------- Grain texture ---------- */
.grain {
  position: fixed; inset: -150%;
  z-index: 9000; pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain 6s steps(6) infinite;
}
@keyframes grain {
  0%,100% { transform: translate(0,0); }
  20% { transform: translate(-8%, 5%); }
  40% { transform: translate(6%, -8%); }
  60% { transform: translate(-4%, 6%); }
  80% { transform: translate(9%, -3%); }
}
/* the grain layer is the most expensive paint on the page — drop it on phones */
@media (max-width: 700px) { .grain { display: none; } }

/* ---------- Nav ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 1000;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: clamp(0.85rem, 2.4vw, 1.75rem) var(--pad);
  transition: background .5s var(--ease), backdrop-filter .5s var(--ease),
              border-color .5s var(--ease), padding .5s var(--ease);
  border-bottom: 1px solid transparent;
}
/* Over the hero the nav has no plate of its own, and the footage behind
   it changes shot to shot — a soft top scrim keeps the links readable
   whatever the frame is doing. Retired once the solid bar takes over. */
.nav::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 220%;
  background: linear-gradient(to bottom, rgba(10, 10, 11, 0.7), rgba(10, 10, 11, 0));
  pointer-events: none; z-index: -1;
  transition: opacity .5s var(--ease);
}
.nav.is-past-hero::before { opacity: 0; }
.nav.is-past-hero {
  background: rgba(10, 10, 11, 0.72);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom-color: var(--line);
  padding-top: clamp(0.7rem, 1.6vw, 1rem);
  padding-bottom: clamp(0.7rem, 1.6vw, 1rem);
}
/* Centred on the viewport, not between the mark and the links — absolute
   positioning keeps it dead centre no matter how wide those two get. */
.nav__logo {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  line-height: 0;
  opacity: 0.92;
  transition: opacity .3s var(--ease);
}
.nav__logo:hover, .nav__logo:focus-visible { opacity: 1; }
.nav__logo img {
  display: block; width: auto;
  height: clamp(1.15rem, 2.2vw, 1.6rem);
}
/* below this the centred mark collides with the links — the wordmark on
   the left is already carrying identity at that width */
@media (max-width: 380px) { .nav__logo { display: none; } }

.nav__mark { display: flex; flex-direction: column; line-height: 1; }
.nav__mark span {
  font-weight: 700; font-size: clamp(1.05rem, 2.4vw, 1.25rem); letter-spacing: -0.025em;
}
.nav__mark em {
  font-family: var(--mono); font-style: normal;
  font-size: clamp(0.62rem, 1.5vw, 0.68rem);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--muted); margin-top: 0.45rem;
}
.nav__links { display: flex; gap: clamp(1.1rem, 2.6vw, 2.6rem); }
.nav__links a {
  font-family: var(--mono);
  font-size: clamp(0.74rem, 1.6vw, 0.84rem);
  letter-spacing: 0.12em; text-transform: uppercase;
  /* vertical padding is the tap target, not decoration — keeps the row
     at a comfortable touch height without moving the type */
  position: relative; padding: 0.6rem 0 0.5rem;
  color: rgba(var(--accent-rgb), 0.8);
  transition: color .3s var(--ease);
}
.nav__links a::after {
  content: ''; position: absolute; left: 0; bottom: 0.32rem;
  width: 100%; height: 1px; background: var(--accent);
  transform: scaleX(0); transform-origin: right; transition: transform .4s var(--ease);
}
.nav__links a:hover,
.nav__links a:focus-visible { color: var(--accent); }
.nav__links a:hover::after { transform: scaleX(1); transform-origin: left; }

/* On a phone the desktop link size can't share the row with the mark —
   CONTACT runs off the edge. Tighten the links and drop the tagline;
   the hero wordmark is already carrying identity at that width. */
@media (max-width: 560px) {
  .nav__mark em { display: none; }
  .nav__links { gap: 0.9rem; }
  .nav__links a {
    font-size: 0.68rem; letter-spacing: 0.08em;
    padding: 0.8rem 0 0.7rem;   /* ~39px tap target */
  }
  .nav__links a::after { bottom: 0.52rem; }
}

/* ---------- Hero ----------
   Two columns on a flat background: copy left, the reel as a framed panel
   right. Nothing overlaps, so this hero has no scrim — every previous
   version needed one because type sat on moving footage. */
.hero {
  position: relative;
  min-height: 100svh;
  display: grid;
  /* The copy column is sized to the copy, not to a share of the viewport.
     As `1fr` it grew with the screen while .hero__inner stayed capped at
     34rem, so on a wide monitor ~300px of empty column opened up between
     the text and the panel and read as a hole. */
  grid-template-columns: minmax(0, 34rem) minmax(0, 1fr);
  gap: clamp(2.5rem, 5vw, 5.5rem);
  align-items: center;
  /* the global `section` rule pads every section; this one needs its own
     top value to clear the fixed nav */
  padding: clamp(6.5rem, 15vh, 9.5rem) var(--pad) clamp(4.5rem, 11vh, 6.5rem);
  /* past this the panel just inflates and the two halves drift apart */
  max-width: 108rem; margin-inline: auto;
  background: var(--bg);
}
/* fills its column, which is already the right measure */
.hero__inner { max-width: none; }

/* ---------- Hero panel ----------
   16:9, matching the source exactly, so object-fit has nothing to crop.
   The radius is the one soft edge on the site: everything else — tiles,
   buttons, the lightbox — is hard-cornered, and the curve is what makes
   this read as a screen showing a piece of work rather than a hole cut
   in the page. */
.hero__panel {
  position: relative; margin: 0;
  aspect-ratio: 16 / 9;
  /* never taller than the space it has, so a short viewport shrinks the
     panel instead of pushing the copy off the top */
  max-height: 72svh;
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--line);
  /* lifts the panel off the page — without it a black rectangle on a
     near-black background reads as a gap rather than an object */
  box-shadow: 0 1.75rem 4.5rem rgba(0, 0, 0, 0.6);
}
.hero__panel.reveal { --d: 0.16s; }
.hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* graded in the encode, not here — a CSS filter on a full-frame video is
     a per-frame GPU pass for something ffmpeg can bake in once */
}

/* Stacked: copy first so the claim still leads, then the panel. */
@media (max-width: 900px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
    gap: clamp(2rem, 6vw, 3rem);
    padding-top: clamp(6rem, 17vh, 8.5rem);
  }
  .hero__inner { max-width: none; }
  .hero__panel { max-height: none; }
}

/* ---------- Hero headline ----------
   Was a full-bleed SVG wordmark. It is the offer now, set in the same
   Archivo 800 but at a size that leaves room for the sub-line, both
   CTAs and the proof row above the fold. Measure is capped so the
   three lines break where they mean to rather than wherever the
   viewport happens to end. */
.hero__title {
  font-weight: 800; font-stretch: 110%;
  font-size: clamp(2.15rem, 3.7vw, 3.7rem);
  line-height: 0.98; letter-spacing: -0.035em;
  color: var(--bone);
  /* the copy column caps the measure, so no ch limit of its own */
  /* the raw wrap stranded "media." alone on line three; balance spreads
     the three lines evenly instead, and re-balances at every width
     rather than needing a hand-placed <br> that breaks on phones */
  text-wrap: balance;
}

/* Sub-line under the headline. Mono and quiet on purpose — the headline
   makes the claim, this names the craft and the sectors it applies to. */
.hero__line {
  margin-top: clamp(0.85rem, 1.8vw, 1.4rem);
  font-family: var(--mono);
  font-size: clamp(0.68rem, 1.15vw, 0.85rem);
  font-weight: 300;
  letter-spacing: 0.14em; text-transform: uppercase;
  line-height: 1.55;
  color: rgba(var(--accent-rgb), 0.72);
  max-width: 46ch;
}
/* staggered behind the headline so the two don't land together */
.hero__line.reveal { --d: 0.18s; }

/* ---------- Scroll cue ----------
   Centred at the foot of the section, under the seam between the two
   columns. */
.hero__scroll {
  position: absolute; left: 50%; bottom: clamp(1.25rem, 3.5vh, 2.25rem);
  width: 2.75rem; height: 2.75rem;

  display: grid; place-items: center;
  color: var(--bone); opacity: 0.7;
  transition: opacity .3s var(--ease);
  animation: hero-bob 1.9s var(--ease) infinite;
}
.hero__scroll:hover,
.hero__scroll:focus-visible { opacity: 1; }
.hero__scroll svg {
  width: 1.4rem; height: 1.4rem;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  filter: drop-shadow(0 1px 6px rgba(10, 10, 11, 0.7));
}
/* the translate has to be restated in the keyframes — it is doing the
   horizontal centring as well as the bob */
@keyframes hero-bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 8px); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__scroll { animation: none; transform: translate(-50%, 0); }
}

/* ---------- Section scaffolding ---------- */
section { padding: clamp(3.5rem, 12vh, 10rem) var(--pad); }
.section-head__label {
  display: flex; align-items: center; gap: 0.7rem;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.2em; text-transform: uppercase;
  /* quiet eyebrow — the bone tick beside it carries the emphasis */
  color: var(--muted); margin-bottom: 1.3rem;
}
.section-head__label::before {
  content: ''; width: 18px; height: 1px; background: var(--accent); flex: none;
}
/* ---------- Creators ----------
   Sits in the gap between the hero and the first category, so it uses
   the work section's top padding rather than adding its own. */
/* Tight to the hero above and the first category below — this is a
   credibility strip, not a section of its own. */
.clients { padding-top: clamp(2rem, 5vh, 3.5rem); padding-bottom: 0; }
.clients .cat__label { text-align: center; }
/* space-between, not equal columns: the entries are different widths, so
   equal columns left visibly uneven gaps between them. */
.clients__list {
  list-style: none;
  display: flex; flex-wrap: wrap;
  justify-content: space-between;
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
@media (max-width: 900px) {
  .clients__list { flex-direction: column; justify-content: flex-start; }
}

.client__link {
  display: flex; align-items: center; gap: clamp(0.85rem, 1.6vw, 1.15rem);
  padding: 0.5rem 0;
}
.client__pfp {
  width: clamp(5.25rem, 8vw, 7rem);
  height: clamp(5.25rem, 8vw, 7rem);
  flex: none;
  border-radius: 50%; object-fit: cover;
  transition: transform .4s var(--ease);
}
.client__link:hover .client__pfp { transform: scale(1.06); }
.client__text { display: flex; flex-direction: column; gap: 0.2rem; min-width: 0; }
.client__name {
  display: inline-flex; align-items: center; gap: 0.3em;
  font-weight: 700; font-size: clamp(1.1rem, 1.8vw, 1.45rem); letter-spacing: -0.025em;
  color: var(--muted); transition: color .3s var(--ease);
}
.client__link:hover .client__name { color: var(--accent); }
/* Instagram verified badge — all three accounts carry it */
.client__badge { width: 0.82em; height: 0.82em; flex: none; }
.client__badge-bg { fill: #0095f6; }
.client__badge-tick {
  fill: none; stroke: #fff; stroke-width: 2.4;
  stroke-linecap: round; stroke-linejoin: round;
}
.client__handle,
.client__meta {
  font-family: var(--mono); font-size: clamp(0.68rem, 1.05vw, 0.78rem); letter-spacing: 0.06em;
  color: var(--muted-2);
  /* long handles must not blow out the column */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.client__meta b { font-weight: 500; color: var(--muted); }

/* follows the creators strip directly, so it supplies only a small gap */
.work {
  padding-top: clamp(1.75rem, 4.5vh, 3rem);
  padding-bottom: clamp(1.25rem, 3vh, 2.25rem);
}

/* ---------- Work categories ----------
   No section title: the work is grouped, and each group's own label
   does the naming. Small mono caps sitting just above the images —
   the label is a caption for the grid, not a headline over it. */
.cat + .cat { margin-top: clamp(2.75rem, 8vh, 6rem); }
.cat__label {
  font-family: var(--mono); font-weight: 400;
  font-size: clamp(0.64rem, 1.4vw, 0.72rem);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: clamp(0.75rem, 1.5vw, 1.15rem);
}

/* ---------- Work grid ----------
   Two up, big. Masonry made sense for ten mixed tiles; with a curated
   pair per category it left ragged holes, so the grid is explicit now. */
.grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(0.6rem, 1.4vw, 1.1rem);
}
@media (max-width: 620px) { .grid { grid-template-columns: minmax(0, 1fr); } }

/* Three across, full bleed like the landscape grids. Don't cap the media
   height here: with aspect-ratio set, a max-height makes the browser
   shrink the tile's width to keep the ratio, which leaves gaps between
   the columns instead of filling the row. */
.grid--portrait { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 620px) { .grid--portrait { grid-template-columns: minmax(0, 1fr); } }

.tile { cursor: pointer; }
.tile__media {
  position: relative; overflow: hidden;
  background: var(--bg-lift);
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
}
.tile--tall .tile__media { aspect-ratio: 9 / 16; }
/* a full-bleed 9:16 tile eats an entire phone screen */
@media (max-width: 620px) {
  .tile--tall .tile__media { aspect-ratio: 4 / 5; }
}
.tile__media img,
.tile__media video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.1s var(--ease), opacity .6s var(--ease);
}
.tile__media video { opacity: 0; }
.tile.is-playing .tile__media video { opacity: 1; }
.tile.is-playing .tile__media img { opacity: 0; }
.tile:hover .tile__media img,
.tile:hover .tile__media video { transform: scale(1.045); }

.tile__media::after {
  content: ''; position: absolute; inset: 0;
  border: 1px solid var(--line); pointer-events: none;
  /* matches the parent, or the hairline cuts the corners square */
  border-radius: inherit;
  transition: border-color .4s var(--ease);
}
/* View count sits on the footage itself — boxed so it reads over any
   frame, and above the ::after hairline so the border can't cross it. */
/* .tile__views removed: view badges were replaced by client credits. */

.tile__open {
  position: absolute; inset: 0; z-index: 1;
  background: none; border: 0; padding: 0;
  cursor: pointer;
  /* the label is for screen readers only — push the glyphs out of frame */
  text-indent: -9999px; overflow: hidden; white-space: nowrap;
  color: transparent;
}
.tile__open:focus-visible { outline-offset: -4px; }

.tile:hover .tile__media::after,
.tile:focus-within .tile__media::after { border-color: var(--accent); }

/* Stacked, not spread. With space-between the credit was pushed to the far
   right of its own column, landing beside the NEXT tile's title and reading
   as if it belonged to it. */
.tile figcaption {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0.3rem;
  padding: 0.95rem 0.1rem 0;
}
/* Client credit above the piece name — studio grammar. This replaced the
   view-count badge that used to sit over the media: a number under the work
   invites comparison between pieces and dates the moment the portfolio
   changes, where a client name only ever gains weight. */
.tile__client {
  font-family: var(--mono); font-size: 0.62rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--muted-2);
  transition: color .3s var(--ease);
}
.tile:hover .tile__client,
.tile:focus-within .tile__client { color: var(--muted); }

.tile__title {
  font-size: clamp(1.15rem, 1.9vw, 1.6rem); font-weight: 700; letter-spacing: -0.03em;
  color: var(--muted);
  transition: color .3s var(--ease);
}
/* value, not hue: the title lifts to full bone as the tile wakes up */
.tile:hover .tile__title,
.tile:focus-within .tile__title { color: var(--accent); }
.tile__meta {
  font-family: var(--mono); font-size: clamp(0.66rem, 0.9vw, 0.76rem);
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted-2);
}
/* ---------- Services ----------
   No cards. A card grid would put four boxes on a page whose whole
   language is full-bleed footage and hairlines — the scopes are separated
   by the same 1px rule the tiles use, and nothing else. */
.services {
  padding-top: clamp(3rem, 9vh, 6.5rem);
  padding-bottom: clamp(2rem, 6vh, 4rem);
}
.services__title {
  font-weight: 800; font-stretch: 110%;
  font-size: clamp(1.9rem, 5.5vw, 4rem);
  line-height: 0.95; letter-spacing: -0.035em;
  color: var(--bone);
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
  max-width: 18ch;
}
.services__grid {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.75rem, 3vw, 2.75rem);
}
@media (max-width: 980px) { .services__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .services__grid { grid-template-columns: minmax(0, 1fr); } }

.service {
  border-top: 1px solid var(--line);
  padding-top: clamp(1rem, 1.8vw, 1.4rem);
  transition: border-color .5s var(--ease);
}
.service:hover { border-top-color: var(--accent); }
.service__no {
  display: block;
  font-family: var(--mono); font-size: 0.66rem;
  letter-spacing: 0.2em;
  color: var(--muted-2);
}
.service__name {
  margin-top: 0.7rem;
  font-size: clamp(1.15rem, 1.7vw, 1.45rem); font-weight: 700; letter-spacing: -0.025em;
  color: var(--bone);
}
.service__desc {
  margin-top: 0.7rem;
  font-size: clamp(0.92rem, 1.05vw, 1rem); line-height: 1.5;
  color: rgba(var(--accent-rgb), 0.66);
}
.service__list {
  list-style: none;
  margin-top: clamp(1rem, 1.8vw, 1.4rem);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.service__list li {
  font-family: var(--mono); font-size: 0.7rem;
  letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--muted);
  /* the tick is a rule, not a bullet glyph — same hairline vocabulary */
  display: flex; align-items: center; gap: 0.6rem;
}
.service__list li::before {
  content: ''; width: 12px; height: 1px; flex: none;
  background: var(--muted-2);
}

/* ---------- Why Us ----------
   No panel: centred type straight on the near-black ground, so the
   section reads as a pause between the work grid and the contact. */
/* padding lives on .why, so the section adds none of its own */
.about { border-top: none; padding: 0; }
.contact .section-head__label { display: inline-flex; }

.why {
  padding: clamp(1.75rem, 4vw, 3rem) var(--pad);
  text-align: center;
}
.why__title {
  font-weight: 800; font-stretch: 125%;
  font-size: clamp(2.6rem, 9vw, 7rem);
  line-height: 0.9; letter-spacing: -0.04em; text-transform: uppercase;
  color: var(--bone);
}
.why__eyebrow {
  font-family: var(--mono);
  font-size: clamp(0.66rem, 1.2vw, 0.78rem);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted);
  margin-top: clamp(0.9rem, 2.2vw, 1.5rem);
}
.why__body {
  margin: clamp(0.9rem, 2vw, 1.5rem) auto 0;
  /* wide measure so the lines run long rather than stacking narrow */
  max-width: 92ch;
  display: flex; flex-direction: column; gap: 0.75em;
}
.why__body p {
  font-size: clamp(1rem, 1.5vw, 1.35rem);
  line-height: 1.45; letter-spacing: -0.01em;
  color: rgba(var(--accent-rgb), 0.78);
}

/* ---------- Process ----------
   Four steps under the studio statement. Left-aligned against the centred
   block above it on purpose: the statement is a title card, this is the
   spec sheet. */
.process {
  list-style: none;
  margin: clamp(2.25rem, 6vh, 4rem) 0 0;
  padding: 0 var(--pad) clamp(1rem, 3vh, 2rem);
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
}
@media (max-width: 900px) { .process { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 520px) { .process { grid-template-columns: minmax(0, 1fr); } }

.process__step {
  border-top: 1px solid var(--line);
  padding-top: clamp(0.9rem, 1.6vw, 1.25rem);
}
.process__no {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.2em;
  color: var(--muted-2);
}
.process__name {
  margin-top: 0.55rem;
  font-size: clamp(1.05rem, 1.5vw, 1.25rem); font-weight: 700; letter-spacing: -0.025em;
  color: var(--bone);
}
.process__step p {
  margin-top: 0.5rem;
  font-size: clamp(0.88rem, 1vw, 0.97rem); line-height: 1.5;
  color: rgba(var(--accent-rgb), 0.6);
}

/* ---------- Contact ---------- */
.contact {
  padding-top: clamp(2rem, 5vh, 3.5rem);
  padding-bottom: clamp(2rem, 5vh, 3.5rem);
  text-align: center;
  display: flex; flex-direction: column; align-items: center;
}
.contact__lead {
  margin-top: 0.4rem;
  font-size: clamp(1.05rem, 2vw, 1.6rem);
  font-weight: 700; letter-spacing: -0.025em;
  color: rgba(var(--accent-rgb), 0.72);
}
.contact__meta {
  margin: 0 0 clamp(1.4rem, 3vh, 2rem);
  font-family: var(--mono); font-size: 0.67rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted-2);
}
.contact__email {
  display: inline-block; margin: clamp(1rem, 2.5vh, 1.6rem) 0 clamp(1rem, 2.5vh, 1.5rem);
  font-weight: 800; letter-spacing: -0.04em;
  /* long address — vw-driven so it never overflows a narrow screen */
  font-size: clamp(1.35rem, 7vw, 5.5rem); line-height: 1.05;
  max-width: 100%; word-break: break-word;
  position: relative;
  transition: color .3s var(--ease);
}
.contact__email::after {
  content: ''; position: absolute; left: 0; bottom: -0.06em; width: 100%; height: 2px;
  background: var(--accent); transform: scaleX(0); transform-origin: right;
  transition: transform .5s var(--ease);
}
/* already at full bone, so the sweeping rule is the whole hover */
.contact__email:hover::after { transform: scaleX(1); transform-origin: left; }
.contact__socials { display: flex; flex-wrap: wrap; justify-content: center; gap: 1.4rem; }
.contact__socials a {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--muted); transition: color .3s;
}
.contact__socials a:hover { color: var(--accent); }

/* ---------- Footer ---------- */
.footer {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.6rem 1rem;
  padding: 2rem var(--pad);
  padding-bottom: calc(2rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.63rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.footer__mark { color: var(--bone); font-weight: 500; }
.footer__nav { display: flex; flex-wrap: wrap; gap: 1.2rem; }
.footer__nav a { transition: color .3s var(--ease); }
.footer__nav a:hover, .footer__nav a:focus-visible { color: var(--accent); }
/* four items across a phone wraps into a ragged stack — centre the row
   under the mark instead of letting space-between strand one item */
@media (max-width: 700px) {
  .footer { justify-content: center; text-align: center; }
  .footer__nav { width: 100%; justify-content: center; }
}

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 9800;
  background: rgba(6,6,7,0.94);
  backdrop-filter: blur(6px);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(1rem, 4vw, 3rem);
  padding-top: clamp(3.5rem, 8vw, 4rem);
  opacity: 0; visibility: hidden; transition: opacity .45s var(--ease), visibility .45s;
}
.lightbox.is-open { opacity: 1; visibility: visible; }
.lightbox__stage {
  width: min(1100px, 100%);
  transform: translateY(18px) scale(0.98); transition: transform .5s var(--ease);
}
.lightbox.is-open .lightbox__stage { transform: none; }
.lightbox__stage video {
  width: 100%; max-height: 74vh; background: #000;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.lightbox__caption {
  display: flex; justify-content: space-between; align-items: baseline; gap: 0.5rem 1rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}
.lightbox__title { font-size: clamp(1.05rem, 3vw, 1.3rem); font-weight: 600; letter-spacing: -0.015em; }
.lightbox__meta {
  font-family: var(--mono); font-size: 0.63rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted);
}
.lightbox__close {
  position: absolute; top: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 4vw, 3rem);
  background: none; border: none; color: var(--muted); cursor: pointer;
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.14em; text-transform: uppercase;
  padding: 0.6rem 0.2rem; /* comfortable tap target */
  transition: color .3s var(--ease);
}
.lightbox__close:hover { color: var(--accent); }

/* ---------- Reveal animation ---------- */
.reveal { opacity: 0; transform: translateY(26px); }
.reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity 1s var(--ease), transform 1s var(--ease);
  transition-delay: var(--d, 0s);
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .grain { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  * { transition-duration: 0.001ms !important; }
}

/* ============================================================
   v4 — conversion layer
   ------------------------------------------------------------
   Everything above is the v1 system and is untouched. This block
   adds only what the short page needs: hero CTAs and an inline
   proof line, the two-lane offer split, and the scroll rule.

   The page is four sections long by design — proof, work, offer,
   ask. Anything that did not move a visitor toward the ask (a
   process list, a studio history) was cut rather than styled.

   The rule the whole page follows: value, never hue. A solid
   button is bone-on-black; a quiet one is a hairline. There is
   still no accent colour anywhere except the footage.
   ============================================================ */

/* ---------- Scroll progress ----------
   A two-pixel rule at the top. Driven by main.js, which degrades to
   simply not drawing rather than to a broken bar. */
.progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px;
  z-index: 1001; pointer-events: none;
  background: rgba(var(--accent-rgb), 0.08);
}
.progress span {
  display: block; height: 100%;
  background: var(--accent);
  transform: scaleX(0); transform-origin: 0 50%;
  /* no transition: this tracks the scrollbar, and easing it would
     make the bar lag the page it is reporting on */
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  /* generous vertical padding keeps these above the 44px tap target
     even at the smallest clamp */
  padding: 0.95rem 1.6rem;
  border: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.68rem;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fg);
  transition: border-color .4s var(--ease), background .4s var(--ease),
              color .4s var(--ease);
}
.btn:hover, .btn:focus-visible { border-color: var(--accent); background: rgba(var(--accent-rgb), 0.07); }
.btn--solid { background: var(--accent); border-color: var(--accent); color: var(--bg); }
.btn--solid:hover, .btn--solid:focus-visible { background: transparent; color: var(--accent); }

/* ---------- Nav CTA ----------
   The one link in the bar that is an action rather than a destination,
   so it gets a frame and drops the underline the others use. */
.nav__cta {
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--line);
  transition: border-color .4s var(--ease), color .4s var(--ease);
}
.nav__cta::after { display: none; }
.nav__cta:hover { border-color: var(--accent); }
/* on a phone the bar keeps only the action — the two section anchors
   survive in the footer, and the hero repeats both of them anyway */
@media (max-width: 600px) {
  .nav__links a:not(.nav__cta) { display: none; }
}

/* ---------- Hero CTAs ---------- */
.hero__ctas {
  display: flex; flex-wrap: wrap; gap: 0.7rem;
  margin-top: clamp(1.1rem, 2.6vw, 1.7rem);
}
.hero__ctas.reveal { --d: 0.3s; }

/* v1's line was three clauses long and wanted a 46ch measure to break
   sensibly. This one is a single sentence, and that measure snapped
   "with media" onto a line of its own — give it room to sit flat. */
.hero__line { max-width: 48ch; }
@media (max-width: 480px) {
  /* side by side they wrap to two ragged rows — stack and fill instead */
  .hero__ctas { flex-direction: column; align-items: stretch; width: 100%; }
}

/* ---------- Hero proof line ----------
   The numbers sit in the hero rather than in a section below it, so a
   visitor gets the claim and the evidence for it in one screen. Inline
   and mono: this is a credit line, not a dashboard. */
.hero__proof {
  list-style: none;
  /* stacked, not inline: this used to run the width of the viewport, and
     three entries do not fit across a ~34rem copy column */
  display: flex; flex-direction: column;
  gap: 0.35rem;
  margin-top: clamp(1.1rem, 2.6vw, 1.7rem);
  font-family: var(--mono);
  font-size: clamp(0.63rem, 1vw, 0.72rem);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: rgba(var(--accent-rgb), 0.6);
}
.hero__proof.reveal { --d: 0.42s; }
.hero__proof b { font-weight: 600; color: var(--bone); }


/* ---------- Shared section header ---------- */
.section-head { margin-bottom: clamp(1.75rem, 4vw, 3rem); }
.section-head__title {
  font-weight: 800; font-stretch: 110%;
  font-size: clamp(1.9rem, 5.5vw, 4rem);
  line-height: 0.95; letter-spacing: -0.035em;
  color: var(--bone);
  max-width: 18ch;
}

/* ---------- What I do ----------
   Two lanes, side by side, three items each. A brand reads its own
   column and never scrolls through an offer written for someone else. */
.split {
  padding-top: clamp(3rem, 9vh, 6.5rem);
  padding-bottom: clamp(3rem, 9vh, 6.5rem);
  border-top: 1px solid var(--line);
  background: var(--bg-lift);
}
.lanes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
}
@media (max-width: 780px) { .lanes { grid-template-columns: minmax(0, 1fr); gap: clamp(2.25rem, 6vw, 3rem); } }
.lane {
  display: flex; flex-direction: column; align-items: flex-start;
  border-top: 1px solid var(--line);
  padding-top: clamp(1rem, 1.8vw, 1.4rem);
  transition: border-color .5s var(--ease);
}
.lane:hover { border-top-color: var(--accent); }
.lane__title {
  font-family: var(--mono); font-weight: 400;
  font-size: clamp(0.64rem, 1.4vw, 0.72rem);
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--muted);
}
.lane__list {
  list-style: none;
  margin-top: clamp(1rem, 2vw, 1.5rem);
  display: flex; flex-direction: column;
  gap: clamp(0.9rem, 1.8vw, 1.3rem);
}
.lane__list li {
  font-size: clamp(0.95rem, 1.25vw, 1.08rem);
  line-height: 1.5; letter-spacing: -0.008em;
  color: rgba(var(--accent-rgb), 0.62);
  padding-left: 1.15rem; position: relative;
}
.lane__list li::before {
  content: ''; position: absolute; left: 0; top: 0.72em;
  width: 10px; height: 1px; background: var(--muted-2);
}
/* the offer name carries the weight; the clause after the dash explains it */
.lane__list b {
  display: block; font-weight: 600;
  color: var(--bone); letter-spacing: -0.02em;
}
/* Pushed to the lane's foot so both buttons sit on one line however
   uneven the two lists run. The minimum gap lives on the list's margin,
   not the button's: as `.lane__list + .btn` it had the same specificity
   as the rule above and, coming later, silently beat `auto` — which is
   why the two buttons were landing at different heights. */
.lane .btn { margin-top: auto; }
.lane__list { margin-bottom: clamp(1.6rem, 3.5vw, 2.4rem); }

/* Price floors. Deliberately quiet and deliberately on the brand lane
   only: a floor's job here is to filter enquiries and anchor the first
   conversation, not to sell. The creator lane carries none — that side is
   buying relief from work and is price-sensitive, and putting the two
   scales on one screen invites the cheaper one to anchor the dearer. */
.lane__price {
  display: block;
  margin-top: 0.55rem;
  font-family: var(--mono); font-size: 0.63rem;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--bone);
}

.split__note {
  margin-top: clamp(2rem, 5vw, 3.25rem);
  padding-top: clamp(1.1rem, 2.2vw, 1.6rem);
  border-top: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.63rem;
  letter-spacing: 0.13em; text-transform: uppercase;
  line-height: 1.7; color: var(--muted);
  max-width: 70ch;
}

/* ---------- Contact ----------
   The studio note is two sentences directly above the ask rather than a
   section of its own — the last thing read before the address. */
.contact__note {
  margin-top: clamp(1rem, 2.5vw, 1.6rem);
  max-width: 62ch;
  font-size: clamp(0.95rem, 1.25vw, 1.1rem);
  line-height: 1.55; letter-spacing: -0.008em;
  color: rgba(var(--accent-rgb), 0.62);
}
/* v1's lead sat directly under the eyebrow and so carried a small top
   margin. The note is between them now and needs the room. */
.contact__note + .contact__lead { margin-top: clamp(1.5rem, 3.5vw, 2.25rem); }

/* ---------- Roster overflow fix ----------
   Inherited from v1, visible below ~430px. v1's media query flips the row
   to flex-direction: column but leaves flex-wrap: wrap set. A wrapping
   COLUMN container is multi-line: its items size to their own max-content
   and never stretch to the container, so the nowrap handle underneath
   pushed each row past the viewport. Single-line is what was meant, and
   with it the items stretch and the existing ellipsis engages. */
@media (max-width: 900px) {
  .clients__list { flex-wrap: nowrap; }
}
.client, .client__link { min-width: 0; }
.client__text > * { min-width: 0; max-width: 100%; }

@media (prefers-reduced-motion: reduce) {
  .progress span { transition: none; }
}
