/* ==========================================================================
   PORTFOLIO — Sheikh Safwan
   Black-and-white editorial poster on graph paper, one red accent.
   ========================================================================== */

/* ---------- Fonts ---------- */
@font-face {
  font-family: "Heading Now";
  src: url("fonts/heading-now-15-medium.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Anton";
  src: url("fonts/anton.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Oswald";
  src: url("fonts/oswald-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Oswald";
  src: url("fonts/oswald-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Proxima Nova XW";
  src: url("fonts/proxima-nova-xbold.woff2") format("woff2");
  font-weight: 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Carnivalee Freakshow";
  src: url("fonts/carnivalee-freakshow.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  --paper: #EDEBE4;
  --grid: #D6D3C8;
  --offwhite: #F6F5F0;
  --ink: #0C0C0C;
  --soft: #3A3A36;
  --red: #DC3419;
  --tape: #D9CE8E;
  --black: #0A0A0A;

  --grid-size: 34px;
  --gutter: 24px;
  --max: 1680px;
  --tear: 22px;                      /* depth of the torn edge */

  --f-display: "Anton", Impact, "Arial Narrow Bold", sans-serif;
  --f-wordmark: "Heading Now", "Anton", "Arial Narrow", Impact, sans-serif;
  --f-heading: "Proxima Nova XW", "Arial Black", "Helvetica Neue", Arial, sans-serif;
  --f-body: "Oswald", "Arial Narrow", "Roboto Condensed", Arial, sans-serif;
  --f-marquee: "Carnivalee Freakshow", "Playfair Display", Georgia, serif;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
html, body { overflow-x: hidden; }
body {
  margin: 0;
  background: var(--black);
  color: var(--ink);
  font-family: var(--f-body);
  font-weight: 500;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, p, ul, figure { margin: 0; }
ul { padding: 0; list-style: none; }
img, video { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; }

/* ---------- Graph paper ---------- */
.paper {
  position: relative;
  background-color: var(--paper);
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  background-position: center top;
}

/* ---------- Torn paper edges (two ragged layers: white fibre + paper) ---------- */
.torn { position: relative; z-index: 2; }
.tear { position: absolute; left: 0; right: 0; height: 34px; pointer-events: none; z-index: 3; }
.tear::before, .tear::after { content: ""; position: absolute; left: 0; right: 0; top: 0; bottom: 0; }
.tear::before { background: #FBFAF7; }            /* white paper fibres showing at the rip */
.tear::after {                                     /* the paper itself, grid included */
  background-color: var(--paper);
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  background-position: center top;
}
.tear--top { top: -30px; }
.tear--top::before { top: -5px;  clip-path: polygon(0.0% 12.0px, 0.99% 19.0px, 1.9% 2.0px, 3.07% 4.9px, 4.49% 1.6px, 5.29% 4.5px, 6.27% 10.9px, 7.12% 26.2px, 9.02% 4.5px, 10.27% 10.4px, 11.73% 3.7px, 14.06% 29.8px, 15.7% 14.5px, 16.65% 3.1px, 18.07% 7.9px, 20.36% 4.8px, 21.2% 28.5px, 22.95% 4.4px, 24.73% 0.8px, 26.48% 29.4px, 28.83% 20.9px, 30.11% 11.0px, 31.21% 23.2px, 32.96% 23.4px, 34.36% 6.7px, 36.62% 29.5px, 38.95% 24.2px, 41.23% 22.2px, 42.43% 15.5px, 43.87% 0.9px, 44.72% 8.4px, 45.99% 20.8px, 48.51% 13.4px, 51.0% 29.6px, 53.52% 10.9px, 54.72% 6.8px, 55.87% 6.1px, 57.79% 27.0px, 60.11% 14.4px, 62.08% 24.0px, 63.03% 19.8px, 65.47% 23.5px, 67.62% 14.3px, 68.74% 23.7px, 70.14% 24.0px, 72.69% 11.9px, 74.21% 28.4px, 76.32% 5.1px, 77.35% 4.5px, 79.77% 24.2px, 80.84% 24.8px, 83.4% 19.7px, 84.83% 16.5px, 85.87% 0.4px, 88.42% 19.5px, 90.16% 28.0px, 91.75% 26.2px, 94.03% 6.3px, 95.29% 8.8px, 96.52% 17.6px, 97.79% 12.6px, 98.82% 27.3px, 100% 13.7px, 100% 100%, 0 100%); }
.tear--top::after  { clip-path: polygon(0.0% 8.4px, 1.07% 16.9px, 2.0% 13.9px, 3.46% 1.5px, 5.17% 1.0px, 6.75% 1.8px, 7.72% 11.0px, 10.01% 3.2px, 11.21% 16.3px, 13.71% 15.0px, 15.23% 25.4px, 16.11% 22.3px, 17.43% 3.8px, 18.44% 8.0px, 20.71% 4.7px, 22.56% 16.6px, 24.03% 14.2px, 24.94% 1.5px, 26.11% 17.7px, 27.68% 8.2px, 29.54% 11.8px, 30.88% 20.7px, 32.94% 6.3px, 34.77% 13.7px, 37.15% 19.0px, 38.46% 25.5px, 39.48% 10.9px, 41.64% 4.0px, 43.32% 1.0px, 45.32% 19.9px, 47.15% 22.8px, 48.52% 18.1px, 50.39% 15.1px, 52.01% 21.8px, 54.51% 12.3px, 56.5% 1.6px, 58.57% 16.8px, 61.16% 21.4px, 62.47% 10.0px, 64.47% 0.6px, 66.1% 4.4px, 67.11% 1.5px, 69.3% 3.4px, 70.54% 10.2px, 72.91% 2.1px, 74.52% 14.3px, 76.91% 21.3px, 79.26% 7.2px, 80.81% 9.3px, 83.2% 24.9px, 84.27% 4.6px, 85.49% 6.1px, 87.16% 15.3px, 88.44% 0.1px, 89.99% 9.6px, 91.81% 24.8px, 93.85% 13.4px, 95.77% 17.6px, 96.66% 23.4px, 98.87% 22.7px, 100% 10.2px, 100% 100%, 0 100%); }
.tear--bottom { bottom: -30px; }
.tear--bottom::before { bottom: -5px; clip-path: polygon(0 0, 100% 0, 100% calc(100% - 7.6px), 98.19% calc(100% - 2.0px), 96.21% calc(100% - 16.1px), 94.5% calc(100% - 22.4px), 92.26% calc(100% - 0.1px), 90.58% calc(100% - 20.4px), 88.66% calc(100% - 18.8px), 86.85% calc(100% - 25.1px), 85.86% calc(100% - 10.8px), 84.82% calc(100% - 0.9px), 83.61% calc(100% - 20.8px), 81.58% calc(100% - 26.8px), 79.73% calc(100% - 24.8px), 77.48% calc(100% - 25.0px), 75.77% calc(100% - 15.7px), 74.72% calc(100% - 24.4px), 72.6% calc(100% - 18.8px), 70.19% calc(100% - 25.1px), 69.32% calc(100% - 19.3px), 67.21% calc(100% - 4.5px), 64.64% calc(100% - 9.8px), 63.14% calc(100% - 26.4px), 61.05% calc(100% - 19.7px), 58.9% calc(100% - 15.9px), 57.04% calc(100% - 7.0px), 55.7% calc(100% - 0.7px), 54.82% calc(100% - 12.0px), 53.86% calc(100% - 7.9px), 53.05% calc(100% - 15.1px), 51.89% calc(100% - 15.1px), 50.24% calc(100% - 11.4px), 49.43% calc(100% - 10.7px), 48.08% calc(100% - 29.0px), 46.84% calc(100% - 16.4px), 44.29% calc(100% - 28.9px), 43.01% calc(100% - 13.4px), 41.93% calc(100% - 13.8px), 40.6% calc(100% - 7.3px), 39.29% calc(100% - 20.1px), 36.93% calc(100% - 25.2px), 35.97% calc(100% - 4.9px), 34.71% calc(100% - 22.2px), 33.79% calc(100% - 3.9px), 32.89% calc(100% - 10.4px), 31.36% calc(100% - 19.1px), 29.29% calc(100% - 25.0px), 27.87% calc(100% - 29.5px), 25.83% calc(100% - 15.2px), 24.33% calc(100% - 25.0px), 22.64% calc(100% - 13.0px), 20.36% calc(100% - 3.2px), 17.88% calc(100% - 14.2px), 16.74% calc(100% - 16.5px), 14.62% calc(100% - 0.5px), 13.37% calc(100% - 0.5px), 11.94% calc(100% - 5.3px), 10.24% calc(100% - 8.7px), 8.08% calc(100% - 9.2px), 6.71% calc(100% - 6.1px), 5.82% calc(100% - 4.8px), 4.83% calc(100% - 7.2px), 3.08% calc(100% - 3.9px), 1.8% calc(100% - 27.8px), 0.0% calc(100% - 10.2px)); }
.tear--bottom::after  { clip-path: polygon(0 0, 100% 0, 100% calc(100% - 11.8px), 98.76% calc(100% - 1.7px), 96.42% calc(100% - 2.2px), 94.17% calc(100% - 16.5px), 91.69% calc(100% - 1.9px), 90.12% calc(100% - 17.9px), 89.22% calc(100% - 2.3px), 87.16% calc(100% - 14.8px), 84.7% calc(100% - 3.9px), 83.44% calc(100% - 21.3px), 80.99% calc(100% - 11.0px), 79.96% calc(100% - 7.0px), 77.76% calc(100% - 1.0px), 76.48% calc(100% - 2.7px), 73.93% calc(100% - 20.5px), 71.36% calc(100% - 1.7px), 69.64% calc(100% - 16.2px), 68.24% calc(100% - 0.5px), 66.65% calc(100% - 14.4px), 65.81% calc(100% - 18.8px), 64.44% calc(100% - 5.1px), 63.03% calc(100% - 13.4px), 61.45% calc(100% - 4.2px), 59.15% calc(100% - 25.7px), 57.48% calc(100% - 10.4px), 54.96% calc(100% - 5.7px), 52.42% calc(100% - 23.0px), 51.36% calc(100% - 17.2px), 49.27% calc(100% - 4.0px), 46.86% calc(100% - 20.4px), 44.85% calc(100% - 1.9px), 43.62% calc(100% - 1.9px), 42.03% calc(100% - 3.2px), 40.98% calc(100% - 21.8px), 38.48% calc(100% - 14.5px), 37.21% calc(100% - 24.5px), 34.84% calc(100% - 18.2px), 32.34% calc(100% - 12.4px), 30.58% calc(100% - 11.8px), 28.53% calc(100% - 13.3px), 26.82% calc(100% - 15.9px), 25.23% calc(100% - 23.7px), 23.06% calc(100% - 14.6px), 21.34% calc(100% - 20.1px), 20.05% calc(100% - 6.5px), 18.24% calc(100% - 2.8px), 16.03% calc(100% - 14.4px), 14.29% calc(100% - 8.5px), 12.49% calc(100% - 18.9px), 10.84% calc(100% - 4.5px), 8.6% calc(100% - 0.1px), 7.47% calc(100% - 11.4px), 6.64% calc(100% - 13.6px), 4.88% calc(100% - 13.0px), 2.43% calc(100% - 10.9px), 0.0% calc(100% - 15.2px)); }
/* keep the section's own grid aligned with the tear's grid */
.tear--top::after { background-position: center 30px; }

/* ---------- Tears rip open left-to-right as the section arrives ----------
   A mask handles the reveal so the ragged clip-path above is untouched.
   Default is 100%, so without JS (or @property support) the tear just shows. */
@property --rip { syntax: "<percentage>"; inherits: true; initial-value: 100%; }
.tear {
  --rip: 100%;
  -webkit-mask-image: linear-gradient(90deg, #000 0 var(--rip), transparent var(--rip));
          mask-image: linear-gradient(90deg, #000 0 var(--rip), transparent var(--rip));
}
.torn.rip-armed .tear { --rip: 0%; }
.torn.rip-armed.rip-go .tear {
  --rip: 100%;
  transition: --rip 820ms cubic-bezier(.22,.78,.3,1);
}
.torn.rip-armed.rip-go .tear--bottom { transition-delay: 130ms; }

/* ---------- Type helpers ---------- */
.kicker {
  font-family: var(--f-body);
  font-weight: 600;
  font-size: clamp(11px, 0.9vw, 15px);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
}
.heading {
  font-family: var(--f-heading);
  font-weight: 800;
  text-transform: uppercase;
  line-height: 0.95;
  letter-spacing: 0.01em;
  color: var(--ink);
}
.heading--huge { font-size: clamp(56px, 6.2vw, 108px); letter-spacing: -0.01em; }
.heading--md   { font-size: clamp(26px, 2.1vw, 36px); }
.heading--row  { font-size: clamp(22px, 2vw, 34px); white-space: nowrap; }
.label-red {
  color: var(--red);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  margin: 18px 0 10px;
}
.body {
  color: var(--soft);
  font-size: clamp(15px, 1.15vw, 19px);
  line-height: 1.55;
  letter-spacing: 0.005em;
}
.intro {
  font-size: clamp(18px, 1.5vw, 24px);
  font-weight: 600;
  color: var(--ink);
}

/* Slot marker: visible only until the real content/asset is dropped in */
.slot { outline: 1px dashed rgba(220, 52, 25, 0.75); outline-offset: 3px; }

/* ==========================================================================
   BLOCK 1 — HERO
   ========================================================================== */
.hero { padding: 4px var(--gutter) 24px; }
.hero__inner { max-width: var(--max); margin: 0 auto; position: relative; }
/* The top kicker + 2026 sit just above the tops of the letters. They're taken
   out of flow entirely so they add no headspace above the wordmark; main.js
   sets --hero-drop from the fitted wordmark size so the offset tracks the type
   at every width. (A margin here would collapse out of .hero and expose the
   black body behind it — hence absolute, not margin.) */
.hero__toprow {
  position: absolute; top: var(--hero-drop, 0px); left: 0; right: 0;
  display: flex; justify-content: space-between; align-items: baseline;
}
.hero__bottomrow { display: flex; margin-top: 2px; }
/* kickers fade up on load, in step with the wordmark letters */
.hero__toprow .kicker,
.hero__bottomrow .kicker { animation: kicker-in 620ms cubic-bezier(.2,.9,.25,1) both; }
.hero__toprow .kicker:nth-child(1) { animation-delay: 60ms; }
.hero__toprow .kicker:nth-child(2) { animation-delay: 560ms; }
.hero__bottomrow .kicker { animation-delay: 620ms; }
@keyframes kicker-in {
  0%   { opacity: 0; transform: translateY(-10px); filter: blur(4px); }
  100% { opacity: 1; transform: none; filter: blur(0); }
}
/* kickers glitch in step with the wordmark (main.js toggles .is-glitch on .hero) */
.hero.is-glitch .kicker { animation: kicker-glitch 420ms steps(3, end) both; }
.hero.is-glitch .hero__toprow .kicker:nth-child(2) { animation-delay: 80ms; }
.hero.is-glitch .hero__bottomrow .kicker { animation-delay: 140ms; }
@keyframes kicker-glitch {
  0%   { transform: none; filter: none; }
  25%  { transform: translateX(calc(var(--g, 1) * -6px)) scaleY(1.18); filter: blur(2.5px); }
  55%  { transform: translateX(calc(var(--g, 1) * 4px))  scaleY(0.92); filter: blur(1px); }
  100% { transform: none; filter: none; }
}

.wordmark {
  margin: 0;
  font-family: var(--f-wordmark);
  font-weight: 500;
  line-height: 0.84;
  color: var(--ink);
}
.wordmark__row {
  display: inline-flex;
  width: max-content;
  align-items: flex-end;
  justify-content: flex-start;
  white-space: nowrap;
  letter-spacing: -0.03em;
  font-size: 200px;             /* overwritten by main.js to fit the width */
  padding-top: 0;                /* no headroom — the face is the tallest item, so it sets the row height */
}
/* letter drop-in on load + periodic glitch (see main.js) */
.wm-l { display: block; }
.wordmark.is-ready .wm-l:not(.wordmark__face) {
  animation: wm-in 620ms cubic-bezier(.2,.9,.25,1) both;
  animation-delay: calc(var(--i) * 55ms);
}
@keyframes wm-in {
  0%   { transform: translateY(-38%) scaleY(1.25); opacity: 0; filter: blur(6px); }
  60%  { transform: translateY(6%)   scaleY(0.96); opacity: 1; filter: blur(0); }
  100% { transform: none; }
}
.wordmark.is-glitch .wm-l:not(.wordmark__face) {
  animation: wm-glitch 420ms steps(3, end) both;
  animation-delay: calc(var(--i) * 18ms);
}
@keyframes wm-glitch {
  0%   { transform: none; filter: none; }
  25%  { transform: translateY(calc(var(--g, 1) * -9%)) scaleY(1.12); filter: blur(4px); }
  55%  { transform: translateY(calc(var(--g, 1) * 6%))  scaleY(0.94); filter: blur(2px); }
  100% { transform: none; filter: none; }
}
.wordmark { overflow: visible; }   /* hair rises past the cap line, like the reference */
.wordmark__row.is-capped { width: 100%; justify-content: space-between; }
.wordmark__row > span { display: block; }

/* The second O is the face */
.wordmark__face {
  position: relative;
  width: 0.74em;                 /* ≈ the cap height, like the reference */
  height: 1.0em;                 /* taller than the caps (~0.72em) — hair rises above the letter tops */
  margin: 0 -0.04em 0.01em;      /* tuck into neighbours; chin just above baseline */
  flex: 0 0 auto;
  align-self: flex-end;
}
.face-video {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center bottom;
  mix-blend-mode: multiply;      /* white background disappears; linework stays */
}
/* slot outline until the video has frames */
.wordmark__face:not(.loaded)::after {
  content: attr(data-slot);
  position: absolute; inset: 0;
  display: grid; place-items: center;
  border: 1px dashed rgba(220, 52, 25, 0.75);
  font: 700 11px/1 var(--f-body);
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--red);
}

.hero__icons {
  display: flex; justify-content: center; align-items: center; gap: 26px;
  margin-top: 26px;
}
.icon { width: 34px; height: 34px; display: block; position: relative; color: var(--ink); }
/* 1 — mine: 12-point spiky burst, slowly spinning */
.icon--mine {
  background: var(--ink);
  clip-path: polygon(50% 0%, 58% 30%, 79% 10%, 70% 38%, 100% 32%, 76% 50%, 100% 68%, 70% 62%, 79% 90%, 58% 70%, 50% 100%, 42% 70%, 21% 90%, 30% 62%, 0% 68%, 24% 50%, 0% 32%, 30% 38%, 21% 10%, 42% 30%);
  animation: icon-spin 9s linear infinite;
}
/* 2 — star that becomes a play button, then a square, and back */
.icon--morph > span { position: absolute; inset: 0; background: var(--ink); }
.icon__star   { clip-path: polygon(50% 0%, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0% 50%, 38% 38%); animation: morph-a 6s ease-in-out infinite; }
/* supplied play-button artwork rather than a CSS triangle.
   Selector matches `.icon--morph > span` specificity so the image actually wins. */
.icon--morph > .icon__play {
  background: url("assets/images/icon-play.png") center / contain no-repeat;
  border-radius: 0;
  animation: morph-b 6s ease-in-out infinite;
}
.icon--morph > .icon__play::after { content: none; }
.icon__square { border-radius: 12%; transform: rotate(45deg) scale(0.72); animation: morph-c 6s ease-in-out infinite; }
@keyframes morph-a { 0%,30% { opacity: 1; transform: rotate(0deg) scale(1); } 40%,72% { opacity: 0; transform: rotate(90deg) scale(0.4); } 82%,100% { opacity: 1; transform: rotate(180deg) scale(1); } }
@keyframes morph-b { 0%,30% { opacity: 0; transform: scale(0.4); } 40%,60% { opacity: 1; transform: scale(1); } 70%,100% { opacity: 0; transform: scale(0.4); } }
@keyframes morph-c { 0%,62% { opacity: 0; } 70%,78% { opacity: 1; } 86%,100% { opacity: 0; } }
/* 3 — club: bobs and flips */
.icon--club { font: 40px/34px system-ui, "Segoe UI Symbol", sans-serif; text-align: center; animation: club-flip 6s ease-in-out infinite; }
@keyframes icon-spin { to { transform: rotate(360deg); } }
@keyframes club-flip { 0%,40% { transform: rotateY(0) translateY(0); } 50% { transform: rotateY(180deg) translateY(-4px); } 60%,100% { transform: rotateY(360deg) translateY(0); } }

/* ==========================================================================
   MARQUEE BANDS
   ========================================================================== */
.band {
  position: relative;
  background: var(--black);
  color: var(--offwhite);
  overflow: hidden;
  isolation: isolate;
}
/* faint grid overlay */
.band::before {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255,255,255,0.07) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.07) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
}
/* soft dark-red glow fading in from both edges */
.band::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(90deg, rgba(120, 16, 4, 0.75) 0%, rgba(120, 16, 4, 0) 22%),
    linear-gradient(270deg, rgba(120, 16, 4, 0.75) 0%, rgba(120, 16, 4, 0) 22%);
}
.band__track {
  position: relative; z-index: 1;
  display: flex; align-items: center;
  width: max-content;
  font-family: var(--f-marquee);
  font-weight: 400;
  text-transform: uppercase;
  white-space: nowrap;
  animation: marquee 22s linear infinite;
  will-change: transform;
}
.band__item, .band__sep { display: inline-block; padding: 0 0.55em; }
.band__sep { font-family: system-ui, sans-serif; letter-spacing: 0.15em; }

/* extra bottom room so the torn paper edge below never clips the lettering */
.band--thin { padding: 14px 0 36px; }
.band--thin .band__track { font-size: clamp(24px, 2.8vw, 40px); letter-spacing: 0.04em; }
.band--thin .band__sep { font-size: 0.72em; }

.band-wrap { position: relative; z-index: 1; overflow-x: clip; }                       /* bust lives here so it can rise above the band; stays under the torn paper below */
.band--tall {
  /* top room for the bust, with enough bottom room that the lettering reads
     vertically centred in the black rather than sitting low in it */
  padding: clamp(130px, 17vw, 258px) 0 clamp(104px, 11.5vw, 178px);
}
.band__track--big { font-size: clamp(36px, 6.4vw, 94px); animation-duration: 40s; }
.band__track--big .band__sep { font-size: 0.6em; }
/* Curved-drum illusion: items scale up towards the edges and shrink through the
   centre. main.js sets --s per item from its distance to the viewport centre. */
.band__track--big .band__item,
.band__track--big .band__sep {
  transform: scale(var(--s, 1));
  transform-origin: center center;
  will-change: transform;
}

@keyframes marquee { from { transform: translate3d(0,0,0); } to { transform: translate3d(-50%,0,0); } }

/* Bust portrait breaking out of the top of the tall band */
.bust {
  position: absolute; z-index: 3;
  left: 50%; bottom: 0; transform: translateX(-50%);
  height: clamp(300px, 34vw, 560px);
  width: auto; max-width: 90vw;
  object-fit: contain; object-position: center bottom;
  pointer-events: none;
}
.bust:not(.loaded) { opacity: 0; }
.bust-glow {
  position: absolute; z-index: 2; pointer-events: none;
  left: 50%; bottom: 40px; transform: translate(-50%, 10%);
  width: clamp(360px, 40vw, 680px); height: clamp(360px, 40vw, 680px);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(220,52,25,0.55) 0%, rgba(220,52,25,0.28) 38%, rgba(220,52,25,0) 68%);
  animation: glow-pulse 5s ease-in-out infinite;
}
@keyframes glow-pulse { 0%,100% { transform: translate(-50%, 10%) scale(1); opacity: .9; } 50% { transform: translate(-50%, 10%) scale(1.08); opacity: 1; } }
.band-wrap:not(.has-bust)::after {
  content: "Bust portrait"; position: absolute; z-index: 3;
  left: 50%; bottom: 40px; transform: translateX(-50%);
  width: clamp(200px, 22vw, 380px); height: clamp(260px, 30vw, 500px);
  display: grid; place-items: center;
  border: 1px dashed rgba(220, 52, 25, 0.75);
  font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--red);
}

/* ==========================================================================
   BLOCK 2 — ABOUT
   ========================================================================== */
.about { padding-top: 64px; padding-bottom: 80px; margin-top: 0; }
.about__inner {
  max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: 0.72fr 1.5fr 1fr;
  grid-template-areas:
    "rot mid right"
    "rot formats right";
  column-gap: clamp(28px, 4vw, 72px);
  row-gap: 0;
  align-items: start;
}
.about__left    { grid-area: rot; }
.about__mid     { grid-area: mid; }
.about__formats { grid-area: formats; }
.about__right   { grid-area: right; }
.about__formats .heading--md { margin-top: 36px; margin-bottom: 16px; }
.about__mid > * + * { margin-top: 16px; }
.about__mid .heading--huge { margin-bottom: 22px; }
.about__mid .heading--md { margin-top: 36px; }

/* Transform-selection box (Premiere/Photoshop style), 9:16 */
.transform-box {
  position: relative;
  aspect-ratio: 9 / 16;
  width: 100%;
  border: 1px solid var(--red);
  background: transparent;
}
.rotate-video {
  width: 100%; height: 100%;
  object-fit: cover;
  mix-blend-mode: multiply;      /* white drops out; grid reads through */
}
.handle {
  position: absolute; width: 8px; height: 8px;
  background: var(--offwhite); border: 1px solid var(--red);
  transform: translate(-50%, -50%);
}
.h-tl { top: 0;    left: 0; }    .h-tc { top: 0;    left: 50%; }  .h-tr { top: 0;    left: 100%; }
.h-ml { top: 50%;  left: 0; }                                     .h-mr { top: 50%;  left: 100%; }
.h-bl { top: 100%; left: 0; }    .h-bc { top: 100%; left: 50%; }  .h-br { top: 100%; left: 100%; }
.transform-box:not(.loaded)::after {
  content: "360° loop"; position: absolute; inset: 0;
  display: grid; place-items: center;
  font: 700 11px/1 var(--f-body); letter-spacing: 0.2em; text-transform: uppercase; color: var(--red);
}

.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  border: 2px solid var(--ink);
  padding: 8px 14px 7px;
  font-weight: 600;
  font-size: 14px; letter-spacing: 0.14em; text-transform: uppercase;
  line-height: 1;
}

.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
/* software tiles: real app icon on a white card, name underneath */
.tile {
  aspect-ratio: 1 / 1;
  background: #fff;
  border: 2px solid var(--ink);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 10px; text-align: center;
  font-weight: 600;
  font-size: clamp(9px, 0.72vw, 11px); letter-spacing: 0.08em; text-transform: uppercase; line-height: 1.15;
  color: var(--ink);
}
.tile img {
  width: 56%; max-width: 64px; aspect-ratio: 1 / 1;
  object-fit: contain; display: block;
}
.about__right .heading--md { margin-top: 30px; }
.about__right .heading--md:first-child { margin-top: 0; }
.exp-years { margin: 14px 0 10px; font-weight: 600; font-size: 17px; letter-spacing: 0.12em; text-transform: uppercase; }

/* ==========================================================================
   BLOCK 3 — CLIENTS
   ========================================================================== */
.clients { padding-top: 64px; padding-bottom: 80px; }
.clients__inner {
  max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: clamp(20px, 3vw, 56px);
  align-items: center;          /* CLIENTS sits centred against the card grid */
}
.clients__title {
  font-family: var(--f-heading); font-weight: 800; text-transform: uppercase;
  font-size: clamp(64px, 8.5vw, 150px);
  line-height: 0.9;
  color: var(--red);
  -webkit-text-stroke: 5px var(--offwhite);
  paint-order: stroke fill;
  display: flex; align-items: center; justify-content: center;
}
.clients__title span {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  display: block;
}
.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(28px, 3.4vw, 56px);
  max-width: 980px;
  padding: 18px 12px 14px 0;
}
.card {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--offwhite);
  box-shadow: 6px 8px 0 var(--red);
}
.card img { width: 100%; height: 100%; object-fit: contain; }
.card img:not(.loaded) { display: none; }
.card:has(img:not(.loaded))::after {
  content: ""; position: absolute; inset: 0;
  border: 1px dashed rgba(220, 52, 25, 0.75); margin: 10px;
}
/* hover: the tile inverts — card goes black, logo knocks out light.
   invert(1) handles both the transparent PNGs and the ones composited
   over white, so every logo reads the same way on hover. */
.card {
  transition: background 220ms ease, transform 220ms cubic-bezier(.2,.9,.25,1),
              box-shadow 220ms ease;
}
.card img { transition: filter 220ms ease; }
.card:hover {
  background: var(--black);
  transform: translate(-2px, -3px);
  box-shadow: 9px 12px 0 var(--red);
}
.card:hover img { filter: invert(1); }

/* masking tape */
.card::before {
  content: ""; position: absolute; z-index: 2;
  top: -12px; left: 50%;
  width: 84px; height: 26px;
  background: var(--tape); opacity: 0.86;
  transform: translateX(-50%) rotate(-4deg);
  box-shadow: 0 1px 2px rgba(0,0,0,0.18);
}

/* ==========================================================================
   BLOCK 4 — THE WORK
   ========================================================================== */
.work { padding-top: 56px; padding-bottom: 88px; }
.work__inner { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); }
.row + .row { margin-top: 56px; }
.row__head { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; }
.row__num { color: var(--red); font-weight: 600; font-size: 14px; letter-spacing: 0.2em; }
.row__rule { flex: 1; height: 2px; background: var(--ink); }

.clips {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(14px, 1.6vw, 28px);
}
.clip figure {
  position: relative;
  transition: transform 160ms ease-out;
}
.clip:hover figure, .clip.is-playing figure { transform: translateY(-5px); }
.clip__poster, .clip__video {
  width: 100%; aspect-ratio: 9 / 16;
  object-fit: cover; background: var(--ink);
}
.clip__video { position: absolute; top: 0; left: 0; height: auto; opacity: 0; pointer-events: none; }
.clip.is-playing .clip__video { opacity: 1; }
.clip.is-playing .clip__poster { visibility: hidden; }
.clip__poster:not(.loaded) { background: #1a1a1a; }
.clip figure:has(.clip__poster:not(.loaded))::before {
  content: attr(data-slot);          /* main.js copies the poster's data-slot onto the figure */
  position: absolute; top: 0; left: 0; width: 100%; aspect-ratio: 9 / 16;
  display: grid; place-items: center; z-index: 1;
  border: 1px dashed rgba(220, 52, 25, 0.75);
  font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--red);
}

.clip__mute {
  position: absolute; z-index: 3; right: 8px; bottom: 8px;
  width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: rgba(10,10,10,0.72) no-repeat center / 16px 16px;
  cursor: pointer;
  /* speaker muted */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F6F5F0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polygon points='11 5 6 9 2 9 2 15 6 15 11 19 11 5' fill='%23F6F5F0'/><line x1='23' y1='9' x2='17' y2='15'/><line x1='17' y1='9' x2='23' y2='15'/></svg>");
}
.clip__mute[aria-pressed="true"] {
  /* speaker on */
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F6F5F0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polygon points='11 5 6 9 2 9 2 15 6 15 11 19 11 5' fill='%23F6F5F0'/><path d='M15.5 8.5a5 5 0 0 1 0 7'/><path d='M19 5a9 9 0 0 1 0 14'/></svg>");
}
.clip.has-caption .clip__mute { bottom: calc(8px + 30px); }
.clip__caption {
  margin-top: 10px; text-align: center;
  font-weight: 600; font-size: 13px; letter-spacing: 0.24em; text-transform: uppercase;
}

/* ==========================================================================
   BLOCK 5 — FOOTER
   ========================================================================== */
.footer {
  position: relative; z-index: 1;
  background: var(--black); color: var(--offwhite);
  padding: 120px var(--gutter) 40px;
}
.footer__inner { max-width: var(--max); margin: 0 auto; }
.cta {
  font-family: var(--f-display); font-weight: 400;
  font-size: clamp(60px, 10.4vw, 200px);
  line-height: 0.92; letter-spacing: 0.01em;
  text-transform: uppercase;
}
.cta__line { display: block; white-space: nowrap; }
.cta__red { color: var(--red); }
.footer__rule { border: 0; border-top: 1px solid rgba(246,245,240,0.25); margin: 56px 0 40px; }
.footer__cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.footer__col .label-red { margin-top: 0; }
.footer__link {
  font-weight: 600;
  font-size: clamp(16px, 1.3vw, 22px); letter-spacing: 0.04em;
  text-decoration: none; display: inline-block;
}
.footer__link:hover { color: var(--red); }

/* Book a call — a button, not a link. Slow pulse so it reads as the primary action. */
.book-btn {
  display: inline-flex; align-items: center; gap: 12px;
  background: var(--red); color: var(--offwhite);
  font-family: var(--f-body); font-weight: 600;
  font-size: clamp(15px, 1.15vw, 19px);
  letter-spacing: 0.14em; text-transform: uppercase;
  padding: 16px 28px; border: 0; text-decoration: none;
  box-shadow: 5px 6px 0 rgba(246,245,240,0.92);
  animation: book-pulse 2.6s ease-in-out infinite;
  transition: transform 140ms ease, box-shadow 140ms ease;
}
.book-btn::after { content: "→"; font-size: 1.15em; line-height: 1; }
.book-btn:hover {
  transform: translate(2px, 3px);
  box-shadow: 2px 2px 0 rgba(246,245,240,0.92);
  animation-play-state: paused;
}
.book-btn:focus-visible { outline: 3px solid var(--offwhite); outline-offset: 4px; }
@keyframes book-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.045); }
}
.footer__fine {
  margin-top: 72px; font-weight: 600; font-size: 12px; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(246,245,240,0.4);
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 900px) {
  :root { --gutter: 20px; }
  /* Phones: copy first, then the rotation loop and the format list side by
     side so the loop's dead column gets used, then skills. */
  .about__inner {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
    grid-template-areas:
      "mid mid"
      "rot formats"
      "right right";
    column-gap: 18px;
    row-gap: 36px;
  }
  .about__formats .heading--md { margin-top: 0; }
  /* One format per line, filling the column beside the loop */
  .about__formats .chips { flex-direction: column; flex-wrap: nowrap; gap: 8px; }
  .about__formats .chip { text-align: center; }
  .clients__inner { grid-template-columns: auto 1fr; }
  .cards { grid-template-columns: repeat(2, 1fr); gap: 36px 28px; padding-right: 8px; }
  .clips { grid-template-columns: repeat(2, 1fr); }
  .footer__cols { grid-template-columns: 1fr; gap: 26px; }
  .hero__icons { margin-top: 30px; }
  .band--tall { padding-top: clamp(150px, 34vw, 260px); }
  .bust { height: clamp(220px, 46vw, 340px); }
}
@media (max-width: 520px) {
  :root { --gutter: 16px; }
  .clients__inner { grid-template-columns: 1fr; gap: 12px; }
  .clients__title { font-size: clamp(56px, 16vw, 84px); -webkit-text-stroke-width: 3px; }
  .clients__title span { writing-mode: horizontal-tb; transform: none; }
  .cards { gap: 30px 20px; }
  .card::before { width: 60px; height: 20px; top: -9px; }
  .card { box-shadow: 4px 6px 0 var(--red); }
  .kicker { letter-spacing: 0.18em; }
  .icon { width: 22px; height: 22px; }
}

/* ---------- Reduced motion ---------- */
/* ---------- Film grain + flicker ---------- */
.grain {
  position: fixed; inset: -150%;
  z-index: 60; pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: grain-shift 700ms steps(1, end) infinite, grain-flicker 4.2s ease-in-out infinite;
  will-change: transform, opacity;
}
@keyframes grain-shift {
  0%   { transform: translate3d(0, 0, 0); }
  20%  { transform: translate3d(-8%, 4%, 0); }
  40%  { transform: translate3d(5%, -7%, 0); }
  60%  { transform: translate3d(-4%, -3%, 0); }
  80%  { transform: translate3d(7%, 6%, 0); }
  100% { transform: translate3d(0, 0, 0); }
}
@keyframes grain-flicker {
  0%, 100% { opacity: 0.040; }
  37%      { opacity: 0.062; }
  63%      { opacity: 0.032; }
}

/* ---------- Cursor trail ---------- */
.trail {
  position: fixed; top: 0; left: 0;
  width: 100vw; height: 100vh;
  z-index: 70; pointer-events: none;
}

/* ---------- Clip scrub ---------- */
.clip figure { cursor: pointer; }
.clip.is-scrubbing figure { cursor: ew-resize; }
.clip.is-scrubbing .clip__mute { opacity: 0; pointer-events: none; }
.clip.is-scrubbing figure::after {
  content: ""; position: absolute; inset: 0; z-index: 3;
  border: 2px solid var(--red); pointer-events: none;
}
.clip__scrub {
  position: absolute; z-index: 4;
  left: 8px; right: 8px; bottom: 8px;
  height: 4px;
  background: rgba(246, 245, 240, 0.28);
  opacity: 0; transition: opacity 140ms ease;
  pointer-events: none;
}
.clip.is-scrubbing .clip__scrub { opacity: 1; }
.clip__scrub > i {
  display: block; height: 100%; width: 0;
  background: var(--red);
}
.clip__time {
  position: absolute; z-index: 4;
  left: 8px; top: 8px;
  padding: 3px 6px;
  background: var(--red); color: #fff;
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.06em; font-variant-numeric: tabular-nums;
  opacity: 0; transition: opacity 140ms ease;
  pointer-events: none;
}
.clip.is-scrubbing .clip__time { opacity: 1; }
.clip.has-caption.is-scrubbing .clip__scrub { bottom: 8px; }

/* ==========================================================================
   MOBILE PASS
   Phones get no hover, a narrow column and a battery, so three things change:
   the reading order, the tap affordances, and the decorative load.
   ========================================================================== */

/* --- Touch devices: no hover, so the grid needs a visible play affordance --- */
@media (hover: none) {
  /* :hover sticks after a tap on touch — kill the lift so tapped clips don't
     stay raised. The .is-playing lift below is the real feedback. */
  .clip:hover figure { transform: none; }
  .clip.is-playing figure { transform: translateY(-5px); }

  /* Play badge over every idle clip. Without it a phone visitor sees twelve
     still images and no reason to think they're videos. */
  .clip figure::after {
    content: ""; position: absolute; z-index: 2;
    left: 50%; top: 50%; width: 46px; height: 46px;
    margin: -23px 0 0 -23px;
    border-radius: 50%;
    background: rgba(10, 10, 10, 0.55)
      url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8 5.5v13l11-6.5z' fill='%23F6F5F0'/></svg>")
      no-repeat center / 20px 20px;
    pointer-events: none;
    transition: opacity 160ms ease;
  }
  .clip.is-playing figure::after { opacity: 0; }

  /* Thumb-sized mute target (32px is below the 44px minimum) */
  .clip__mute { width: 44px; height: 44px; background-size: 20px 20px; }
  .clip.has-caption .clip__mute { bottom: calc(8px + 30px); }

  /* No grey flash on tap */
  .clip, .clip__mute, .book-btn, .footer__link { -webkit-tap-highlight-color: transparent; }

  /* The grain is a fixed layer four times the viewport being repainted on a
     loop — cheap on a laptop, not on a phone mid-scroll. Keep the texture,
     drop the animation. */
  .grain { animation: none; opacity: 0.05; }
}

@media (max-width: 900px) {
  /* Stacked, the rotation loop came first and pushed the writing a whole
     screen down. On a phone the copy leads and the loop follows it. */
}

@media (max-width: 520px) {
  /* The CTA lines are nowrap, so the 60px floor overflowed the screen and the
     end of "WINNING AD" was clipped off the right edge. Let it scale with the
     viewport instead, down to a 40px floor. */
  .cta { font-size: clamp(40px, 13.4vw, 60px); }
  .footer { padding-top: 84px; }
  .footer__rule { margin: 40px 0 32px; }

  /* Captions sit under a ~160px column at this width */
  .clip__caption { font-size: 12px; letter-spacing: 0.16em; }
  .clips { gap: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .trail { display: none; }
  .grain { animation: none; opacity: 0.03; }
  html { scroll-behavior: auto; }
  .band__track { animation-play-state: paused; }
  .icon, .icon--morph > span, .bust-glow, .book-btn { animation: none !important; }
  .icon__play, .icon__square { display: none; }
  .wordmark .wm-l { animation: none !important; }
  .kicker { animation: none !important; }
  .band__track--big .band__item, .band__track--big .band__sep { transform: none !important; }
  .face-video { transform: none !important; }
  .tear { --rip: 100% !important; transition: none !important; }
  .clip figure { transition: none; }
}
