/* ═══════════════════════════════════════════════════════════
   imkashif.com — one-page profile
   Dark, brand red, Bionix Fat display + SF Pro body.
   Palette sampled from the portrait: #1B0202 / #5B0103 / #97010B
   ═══════════════════════════════════════════════════════════ */

/* ── FONTS ───────────────────────────────────────────────── */
@font-face {
  font-family: "Bionix Fat";
  src: url("../fonts/bionix-fat.woff2") format("woff2"),
       url("../fonts/bionix-fat.ttf") format("truetype");
  font-weight: 400 1000;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Surfaces — near-black with a red bias so the page and the portrait agree */
  --bg:        #0A0708;
  --bg-rgb:    10, 7, 8;   /* for gradient stops — color-mix in gradients proved unreliable */
  --bg-2:      #120C0D;
  --bg-3:      #1A1112;
  --maroon:    #1B0202;
  --crimson:   #5B0103;

  /* Brand */
  --red:       #DD3516;
  --red-hi:    #FF4A2B;
  --red-deep:  #97010B;

  /* Text — warm-toned to sit with the red */
  --tx:        #F7F3F2;
  --tx-2:      #B3A9A7;   /* 8.1:1 on --bg */
  --tx-3:      #8A807E;   /* 4.9:1 on --bg */

  --line:      rgba(255, 255, 255, .10);
  --line-2:    rgba(255, 255, 255, .20);

  /* Type */
  --f-display: "Bionix Fat", "Arial Black", sans-serif;
  --f-body:    -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
               "Inter", "Helvetica Neue", Arial, sans-serif;

  --fs-huge:   clamp(3.5rem, 1rem + 15vw, 16rem);
  --fs-big:    clamp(2.5rem, 1rem + 7vw, 7rem);
  --fs-big-sm: clamp(2rem, 1rem + 5vw, 5rem);
  --fs-h3:     clamp(1.25rem, 1.05rem + .8vw, 1.75rem);
  --fs-lead:   clamp(1.0625rem, 1rem + .5vw, 1.375rem);
  --fs-body:   1.0625rem;
  --fs-sm:     .9375rem;
  --fs-xs:     .8125rem;

  /* Rhythm */
  --sec-y:     clamp(5rem, 16vh, 11rem);
  --pad-x:     clamp(1.5rem, 6vw, 6rem);
  --gap:       clamp(1.5rem, 4vw, 2.5rem);
  --maxw:      1920px;   /* full-wide grid */
  /* Content is inset by --pad-x, and by more once the viewport exceeds the
     grid — so backgrounds stay full-bleed while content caps at 1920. */
  --gutter-x:  max(var(--pad-x), calc((100% - var(--maxw)) / 2));

  /* Motion — symmetric in-out, matched to the reference's feel */
  --ease:      cubic-bezier(.7, 0, .3, 1);
  --ease-out:  cubic-bezier(.16, 1, .3, 1);
  --t-fast:    .3s;
  --t:         .5s;
  --t-slow:    .9s;

  --hdr-h:     76px;
  color-scheme: dark;
}

/* ── RESET ───────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--tx);
  font-family: var(--f-body);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; padding: 0; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
h1, h2, h3 { font-weight: 400; }
:focus-visible { outline: 2px solid var(--red-hi); outline-offset: 4px; border-radius: 2px; }
::selection { background: var(--red); color: #fff; }

.skip {
  position: absolute; top: -100px; left: var(--gutter-x); z-index: 300;
  background: var(--red); color: #fff; padding: .8rem 1.4rem; border-radius: 100px;
  transition: top var(--t-fast) var(--ease);
}
.skip:focus { top: 1rem; }

/* Shared logo mark — inline <svg><use> from the sprite in index.html.
   Previously a CSS mask, which broke: XAMPP serves .svg with a MIME type
   Chrome won't decode, so the mask resolved empty and hid the element. */
.mark {
  display: block; width: 60px; height: 26px;
  fill: currentColor;   /* inline <use> inherits colour — no mask, no MIME dependency */
}
.mark--sm { width: 46px; height: 20px; }

/* ── LOADER ──────────────────────────────────────────────── */
.loader {
  position: fixed; inset: 0; z-index: 999;
  background: #000;
  will-change: background-color;
}
/* viewBox is written by JS to match the viewport, so the liquid is a
   true full-screen fill and the logo is knocked out of it. */
.loader__stage {
  position: absolute; inset: 0;
  width: 100%; height: 100%; display: block;
}
.loader__outline path {
  stroke: rgba(255, 255, 255, .55);
  stroke-width: 1.25;
  vector-effect: non-scaling-stroke;
}
.loader__wave { will-change: transform; }
.loader__wave--back  { fill: var(--red-deep); opacity: .55; }
.loader__wave--front { fill: var(--red); }
.loader__liquid { will-change: transform; }

/* No loader unless this is a fresh session (class set before first paint) */
html:not(.js) .loader,
html:not(.is-loading) .loader { display: none; }
/* hero photo waits behind the loader, then fades up through it */
html.is-loading .hero__media img { opacity: 0; }

/* ── HEADER ──────────────────────────────────────────────── */
.hdr {
  position: fixed; inset: 0 0 auto; z-index: 100; height: var(--hdr-h);
  display: flex; align-items: center; gap: var(--gap);
  padding-inline: var(--gutter-x);
  transition: background var(--t) var(--ease), backdrop-filter var(--t), border-color var(--t);
  border-bottom: 1px solid transparent;
}
.hdr.is-stuck {
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border-bottom-color: var(--line);
}
.hdr__logo { color: var(--tx); transition: color var(--t-fast) var(--ease); }
.hdr__logo:hover { color: var(--red); }
.hdr__nav { display: flex; gap: clamp(1rem, 2.5vw, 2.25rem); margin-inline: auto; }
.hdr__nav a { font-size: var(--fs-sm); color: var(--tx-2); overflow: hidden; display: block; }
.hdr__nav a span { display: block; transition: transform var(--t) var(--ease), color var(--t) var(--ease); }
.hdr__nav a:hover span { transform: translateY(-100%); color: var(--red-hi); }
.hdr__nav a span::after {
  content: attr(data-x); position: absolute;
}

/* ── BUTTON ──────────────────────────────────────────────── */
.btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  padding: .9rem 1.6rem; border-radius: 100px; overflow: hidden; isolation: isolate;
  background: var(--red); color: #fff; font-size: var(--fs-sm); font-weight: 500;
  white-space: nowrap;
  transition: transform var(--t) var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--tx);
  transform: translateY(101%); border-radius: 50% 50% 0 0;
  transition: transform var(--t) var(--ease), border-radius var(--t) var(--ease);
}
.btn:hover { color: var(--maroon); }
.btn:hover::before { transform: translateY(0); border-radius: 0; }
.btn--sm { padding: .7rem 1.25rem; font-size: var(--fs-xs); }
.btn--lg {
  padding: 1.15rem 2.25rem; font-size: var(--fs-lead);
  font-family: var(--f-display); letter-spacing: .01em;
}
.btn--block { display: flex; width: 100%; }

.burger { display: none; }

/* ── HERO ────────────────────────────────────────────────── */
.hero {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: var(--hdr-h) var(--gutter-x) clamp(1.5rem, 4vh, 3rem);
  overflow: hidden;
  isolation: isolate; /* keeps the media layer inside the hero's stacking context */
}
/* z-index 0 (not -1) — negative would drop it behind the body background */
.hero__media { position: absolute; inset: 0; z-index: 0; }
/* 38% keeps the face above the headline instead of behind it */
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%; }
.hero__scrim {
  position: absolute; inset: 0;
  /* Light touch only: enough to land the copy and melt into the page,
     not enough to flatten the photograph. */
  background:
    linear-gradient(to top,
      rgba(var(--bg-rgb), 1) 0%,
      rgba(var(--bg-rgb), .55) 14%,
      rgba(var(--bg-rgb), 0) 45%),
    linear-gradient(to right,
      rgba(var(--bg-rgb), .55) 0%,
      rgba(var(--bg-rgb), 0) 42%);
}
.hero__body {
  position: relative; z-index: 1;
  width: 100%; max-width: min(60rem, 100%); text-align: left;
  margin-bottom: clamp(2rem, 6vh, 4rem);
}
.hero__title {
  font-family: var(--f-display);
  font-size: clamp(2.5rem, .5rem + 8vw, 8rem);
  line-height: .94; letter-spacing: -.02em;
}
.hero__title span { display: block; overflow: hidden; }
/* the full stop, as a brand-red square */
.hero__title em {
  display: inline-block; vertical-align: baseline;
  width: .16em; height: .16em; margin-left: .07em;
  background: var(--red);
}
.hero__meta {
  margin-top: clamp(1.75rem, 4vw, 3rem);
  display: grid; gap: .55rem;
  font-size: var(--fs-sm); color: var(--tx-3);
}
.hero__claim {
  font-size: var(--fs-lead); color: var(--tx);
  max-width: 44ch;
}
.hero__meta b { font-weight: 400; color: var(--tx); }
.hero__meta s { text-decoration: none; color: var(--red); margin-inline: .35rem; }
.hero__meta a {
  color: var(--tx); border-bottom: 1px solid var(--line-2); padding-bottom: 1px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.hero__meta a:hover { color: var(--red-hi); border-color: var(--red-hi); }
.hero__meta a i {
  font-style: normal; display: inline-block; margin-left: .25em;
  transition: transform var(--t-fast) var(--ease);
}
.hero__meta a:hover i { transform: translate(2px, -2px); }
.hero__foot {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap);
  padding-top: 1.5rem; border-top: 1px solid var(--line);
}
.avail { display: inline-flex; align-items: center; gap: .6rem; font-size: var(--fs-xs); color: var(--tx-2); }
.avail i { width: 7px; height: 7px; border-radius: 50%; background: var(--red-hi); animation: pulse 2.4s var(--ease) infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--red-hi) 60%, transparent); } 70%, 100% { box-shadow: 0 0 0 9px transparent; } }
.scrollcue { width: 1px; height: 46px; background: var(--line-2); overflow: hidden; }
.scrollcue i { display: block; width: 100%; height: 100%; background: var(--red); animation: cue 2.4s var(--ease) infinite; }
@keyframes cue { 0% { transform: translateY(-100%); } 60%, 100% { transform: translateY(100%); } }

/* ── SECTIONS ────────────────────────────────────────────── */
.sec { padding: var(--sec-y) var(--gutter-x); }
.lbl {
  display: flex; align-items: center; gap: .8rem;
  font-size: var(--fs-xs); letter-spacing: .16em; text-transform: uppercase;
  color: var(--tx-3); padding-bottom: 1.5rem; margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
  border-bottom: 1px solid var(--line);
}
/* --red is 4.39:1 on --bg, which fails AA at small sizes. Small red text uses
   --red-hi (5.98:1); --red stays for large display text and fills. */
.lbl i { font-style: normal; color: var(--red-hi); }

.big {
  font-family: var(--f-display); font-size: var(--fs-big);
  line-height: .95; letter-spacing: -.015em; text-transform: uppercase;
}
.big--sm { font-size: var(--fs-big-sm); }
.big span { display: block; overflow: hidden; }
.big em { font-style: normal; color: var(--red); }
.huge {
  font-family: var(--f-display); font-size: var(--fs-huge);
  line-height: .86; letter-spacing: -.02em; text-transform: uppercase;
}

/* ── WORK ROWS (scoped under .rows — `.row` alone collides with Bootstrap) ───────────────────────────────────────────── */
.rows { border-top: 1px solid var(--line); }
.rows .row { border-bottom: 1px solid var(--line); }
.rows .row a {
  position: relative; display: grid; align-items: center; gap: var(--gap);
  grid-template-columns: 4rem minmax(0, 1fr) 11rem 5rem 3rem;
  padding: clamp(1.4rem, 3.5vw, 2.4rem) clamp(.5rem, 2vw, 1.5rem);
  overflow: hidden; isolation: isolate;
  transition: padding-inline var(--t) var(--ease);
}
.rows .row a::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--red);
  transform: translateY(101%); transition: transform var(--t) var(--ease);
}
.rows .row a:hover::before { transform: translateY(0); }
.rows .row a:hover { padding-inline: clamp(1.25rem, 3vw, 2.5rem); color: #fff; }
.rows .row__n { font-family: var(--f-display); font-size: var(--fs-sm); color: var(--red-hi); transition: color var(--t) var(--ease); }
.rows .row a:hover .row__n { color: #fff; }
.rows .row__body { display: block; min-width: 0; }
.rows .row__t { display: block; font-family: var(--f-display); font-size: clamp(1.25rem, 2.6vw, 2.35rem); line-height: 1.05; text-transform: uppercase; }
.rows .row__d {
  display: block; margin-top: .5rem; max-width: 62ch;
  font-size: var(--fs-sm); color: var(--tx-3);
  transition: color var(--t) var(--ease);
}
.rows .row a:hover .row__d { color: color-mix(in srgb, #fff 80%, transparent); }
.rows .row__m, .rows .row__y { font-size: var(--fs-sm); color: var(--tx-2); transition: color var(--t) var(--ease); }
.rows .row a:hover .row__m, .rows .row a:hover .row__y { color: color-mix(in srgb, #fff 82%, transparent); }
.rows .row__a { justify-self: end; font-size: 1.4rem; transition: transform var(--t) var(--ease); }
.rows .row a:hover .row__a { transform: translateX(6px); }
.note { margin-top: 2rem; font-size: var(--fs-sm); color: var(--tx-3); }
.note a {
  color: var(--tx-2); border-bottom: 1px solid var(--line-2); padding-bottom: 1px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.note a:hover { color: var(--red-hi); border-color: var(--red-hi); }

/* ── CONTACT ─────────────────────────────────────────────── */
.contact { position: relative; text-align: center; overflow: hidden; }
.contact::before {
  content: ""; position: absolute; left: 50%; bottom: -40%; translate: -50% 0;
  width: min(1100px, 130%); aspect-ratio: 1;
  background: radial-gradient(circle, color-mix(in srgb, var(--red-deep) 42%, transparent), transparent 62%);
  filter: blur(20px); pointer-events: none; z-index: -1;
}
.contact .lbl { justify-content: center; }
.contact__sub { margin: clamp(1.5rem, 3vw, 2.5rem) auto 2.5rem; max-width: 48ch; font-size: var(--fs-lead); color: var(--tx-2); }
.social { display: flex; flex-wrap: wrap; justify-content: center; gap: clamp(1rem, 3vw, 2.5rem); margin-top: clamp(3rem, 7vw, 5rem); }
.social a {
  display: inline-flex; align-items: center; min-height: 44px; /* WCAG 2.2 target size */
  font-size: var(--fs-sm); color: var(--tx-2);
  border-bottom: 1px solid var(--line-2);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.social a:hover { color: var(--red-hi); border-color: var(--red-hi); }
.social--left { justify-content: flex-start; margin-top: clamp(2.5rem, 5vw, 4rem); }

/* ── FOOTER ──────────────────────────────────────────────── */
.ftr {
  padding-inline: var(--gutter-x); border-top: 1px solid var(--line);
}

/* ── DRAWER ──────────────────────────────────────────────── */
.drawer {
  position: fixed; inset: var(--hdr-h) 0 0; z-index: 95;
  display: flex; flex-direction: column; justify-content: center; gap: 1rem;
  padding: var(--gutter-x); background: var(--bg);
}
.drawer[hidden] { display: none !important; }
.drawer a {
  font-family: var(--f-display); font-size: clamp(2rem, 11vw, 3.5rem);
  text-transform: uppercase; line-height: 1.05;
}
.drawer a:hover { color: var(--red); }

/* ── REVEAL BASE ─────────────────────────────────────────── */
/* `> span` is load-bearing: main.js injects an inner <span> per line, and an
   unscoped descendant selector kept those at opacity 0 forever, so every
   line-revealed heading stayed invisible. */
.js [data-rise], .js [data-rise-lines] > span { opacity: 0; }

/* ── RESPONSIVE ──────────────────────────────────────────── */
@media (max-width: 1024px) {
  .rows .row a { grid-template-columns: 3rem minmax(0, 1fr) 8rem 4rem 2rem; }
  .hero__title { white-space: normal; }
}

@media (max-width: 760px) {
  :root { --hdr-h: 64px; }
  .hdr__nav, .hdr .btn { display: none; }
  .hdr__logo { margin-right: auto; }
  .burger {
    display: grid; gap: 5px; place-content: center;
    width: 44px; height: 44px; border: 1px solid var(--line); border-radius: 100px;
  }
  .burger i { display: block; width: 16px; height: 1.5px; background: currentColor; transition: transform var(--t) var(--ease); }
  .burger[aria-expanded="true"] i:first-child { transform: translateY(3.25px) rotate(45deg); }
  .burger[aria-expanded="true"] i:last-child { transform: translateY(-3.25px) rotate(-45deg); }

  .hero__media img { object-position: 50% 22%; }
  .hero__body { max-width: none; }
  .stats { grid-template-columns: 1fr; gap: 2rem; }
  .rows .row a { grid-template-columns: 2.5rem minmax(0, 1fr) 2rem; row-gap: .4rem; }
  .rows .row__m { grid-column: 2; font-size: var(--fs-xs); }
  .rows .row__y { display: none; }
  .social { gap: 1.25rem; }
  .ftr__base { justify-content: flex-start; }
}

/* ── REDUCED MOTION ──────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .js [data-rise], .js [data-rise-lines] span {
    opacity: 1 !important; transform: none !important;
  }
  .loader { display: none; }
}


/* ── FOOTER ──────────────────────────────────────────────── */
.ftr { display: block; padding-block: clamp(2rem, 5vw, 3rem); }
.ftr__base {
  display: flex; justify-content: space-between; gap: var(--gap); flex-wrap: wrap;
  font-size: var(--fs-xs); color: var(--tx-3);
}
.ftr__base a:hover { color: var(--red-hi); }

@media (max-width: 1024px) {
  .steps { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
  .steps { grid-template-columns: 1fr; }
  .rows .row__d { display: none; }
}


/* ── 03 EXPERIENCE (skills) ──────────────────────────────── */
.skillset {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap); margin-top: clamp(3rem, 7vw, 5rem);
}
.skillgroup h3 {
  font-family: var(--f-display); font-size: var(--fs-h3); text-transform: uppercase;
  letter-spacing: -.01em; padding-bottom: 1rem; margin-bottom: .5rem;
  border-bottom: 1px solid var(--line-2);
}
.skillgroup li {
  padding-block: .75rem; border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm); color: var(--tx-2);
}
/* Monochrome marks, not the brands' own colours — eight full-colour logos
   would drop green, blue and purple into a strictly red-and-black page and
   read as a sponsor wall. Inheriting currentColor keeps the same grey→red
   hover the text pills had.
   Icons are inlined as <symbol>s rather than loaded as .svg files: Apache
   serves .svg with a MIME type Chrome won't decode, so an external file
   loads but paints nothing (the same bug that hid the logo). */
.tools {
  display: flex; flex-wrap: wrap; gap: .6rem; align-items: center;
  margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
}
.tools li {
  display: grid; place-items: center;
  width: 68px; min-height: 44px;          /* 44px keeps the touch target legal */
  color: var(--tx-3);
  border: 1px solid var(--line); border-radius: 100px;
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease),
              background var(--t) var(--ease);
}
.tools li:hover {
  color: var(--red-hi);
  border-color: color-mix(in srgb, var(--red) 50%, transparent);
  background: rgba(var(--bg-rgb), .6);
}
.tools__i {
  display: block; width: 22px; height: 22px;
  fill: currentColor;
}

/* visually hidden — the accessible name for each logo, since the text is gone */
.vh {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ── 04 HISTORY (timeline) ───────────────────────────────── */
.tl { margin-top: clamp(3rem, 7vw, 5rem); border-top: 1px solid var(--line); }
.tl__item {
  display: grid; grid-template-columns: 14rem minmax(0, 1fr);
  gap: var(--gap); align-items: start;
  padding-block: clamp(1.5rem, 3vw, 2.25rem);
  border-bottom: 1px solid var(--line);
  transition: background var(--t) var(--ease);
}
.tl__item:hover { background: var(--bg-2); }
.tl__yr {
  font-family: var(--f-display); font-size: var(--fs-sm);
  color: var(--red-hi); white-space: nowrap; padding-top: .2rem;
}
.tl__body h3 {
  font-family: var(--f-display); font-size: clamp(1.15rem, 2vw, 1.65rem);
  text-transform: uppercase; letter-spacing: -.01em;
}
.tl__co { margin-top: .3rem; font-size: var(--fs-sm); color: var(--tx); }
.tl__body p:last-child { margin-top: .5rem; font-size: var(--fs-sm); color: var(--tx-3); max-width: 62ch; }

/* ── 06 SHOWREEL ─────────────────────────────────────────── */
.reel__frame { margin-top: clamp(3rem, 7vw, 5rem); }
.reel__media {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border: 1px solid var(--line); border-radius: 16px;
  background:
    radial-gradient(80% 120% at 50% 0%, color-mix(in srgb, var(--red-deep) 40%, transparent), transparent 65%),
    linear-gradient(160deg, var(--bg-3), var(--bg));
  display: grid; place-items: center;
}
.reel__play {
  display: grid; place-items: center; width: clamp(64px, 7vw, 92px); aspect-ratio: 1;
  border-radius: 50%; background: var(--red); color: #fff;
  box-shadow: 0 20px 60px -18px color-mix(in srgb, var(--red) 70%, transparent);
  transition: transform var(--t) var(--ease-out), background var(--t) var(--ease);
}
.reel__play:hover { transform: scale(1.08); background: var(--red-hi); }
.reel__meta {
  position: absolute; left: clamp(1rem, 2.5vw, 2rem); bottom: clamp(1rem, 2.5vw, 2rem);
  font-family: var(--f-display); font-size: var(--fs-xs); text-transform: uppercase;
  letter-spacing: .06em; color: var(--tx-2);
}
.reel__meta i { color: var(--red-hi); font-style: normal; }
.reel__ph {
  position: absolute; right: clamp(1rem, 2.5vw, 2rem); bottom: clamp(1rem, 2.5vw, 2rem);
  font-size: var(--fs-xs); color: var(--tx-3);
}

/* ── 07 WHAT THEY SAID ───────────────────────────────────── */
.quotes {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap); margin-top: clamp(3rem, 7vw, 5rem);
}
.quote {
  display: flex; flex-direction: column; justify-content: space-between; gap: 2rem;
  padding: clamp(1.5rem, 2.5vw, 2.25rem);
  border: 1px solid var(--line); border-radius: 16px;
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  transition: border-color var(--t) var(--ease), transform var(--t) var(--ease);
}
.quote:hover { border-color: color-mix(in srgb, var(--red) 50%, transparent); transform: translateY(-5px); }
.quote blockquote {
  font-size: var(--fs-lead); color: var(--tx); line-height: 1.45; text-wrap: pretty;
}
.quote blockquote::before { content: "“"; color: var(--red-hi); margin-right: .1em; }
.quote blockquote::after  { content: "”"; color: var(--red-hi); }
.quote figcaption { border-top: 1px solid var(--line); padding-top: 1rem; }
.quote figcaption b { display: block; font-weight: 500; font-size: var(--fs-sm); }
.quote figcaption span { display: block; margin-top: .15rem; font-size: var(--fs-xs); color: var(--tx-3); }

/* ── 08 MY MOTTO ─────────────────────────────────────────── */
/* no overflow:hidden here — the section got shorter than the glow was tuned
   for, and clipping it mid-circle left a hard, visible crop edge. The
   gradient already fades to fully transparent on its own (62% radius), so
   letting it render past the box is invisible where it matters and removes
   the artifact. */
/* clipped again: at this size (2250px) and offset (-205%), an unclipped
   glow doesn't just soft-fade past the section — it bleeds for thousands of
   pixels down the page, painting over Get In Touch and the footer and
   reading as a giant dead red void instead of content. */
.motto { position: relative; overflow: hidden; padding-bottom: clamp(2.5rem, 5vw, 4rem); }
.motto__glow {
  position: absolute; left: 50%; bottom: -205%;
  width: min(2250px, 140%); aspect-ratio: 1; pointer-events: none; z-index: -1;
  background: radial-gradient(circle, color-mix(in srgb, var(--red-deep) 45%, transparent), transparent 62%);
  filter: blur(20px);
  will-change: transform;
  transform: translateX(-50%);
  transition: transform .45s var(--ease-out);
}
/* --fs-huge suits one or two words; a two-line sentence needs its own scale */
.motto__line {
  font-size: clamp(2.1rem, .4rem + 6.5vw, 6.75rem);
  line-height: .96;
  max-width: 22ch;
}
.motto__line em { font-style: normal; color: var(--red); }
/* second line reads as an outline — filled headline, hollow payoff */
.motto__line span.motto__line--outline {
  color: transparent; -webkit-text-stroke: 1.5px var(--tx); text-stroke: 1.5px var(--tx);
}
.motto__line span.motto__line--outline em { -webkit-text-stroke: 0; text-stroke: 0; }

.motto__cta { margin-top: clamp(2.5rem, 5vw, 4rem); display: grid; justify-items: start; gap: 1rem; }
.motto__email {
  display: inline-flex; align-items: center; gap: .75rem;
  font-family: var(--f-display); font-size: clamp(1.75rem, 1rem + 3vw, 3rem);
  color: var(--tx); padding-bottom: .85rem; border-bottom: 2px solid var(--red);
  transition: color var(--t) var(--ease), gap var(--t) var(--ease), border-color var(--t) var(--ease);
}
.motto__email i {
  font-style: normal; font-size: .55em; display: inline-block;
  transition: transform var(--t) var(--ease);
}
.motto__email:hover { color: var(--red-hi); gap: 1.15rem; border-color: var(--red-hi); }
.motto__email:hover i { transform: translate(3px, -3px); }
.motto__cta p { max-width: 44ch; font-size: var(--fs-sm); color: var(--tx-3); }

.motto__meta {
  margin-top: clamp(3.5rem, 7vw, 6rem); padding-top: clamp(1.75rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap);
}
.motto__metaCol p { font-size: var(--fs-sm); color: var(--tx-2); }
.motto__metaCol p + p { margin-top: .4rem; color: var(--tx-3); }
.motto__metaCol .avail { color: var(--tx-2); }
.motto__social { display: grid; gap: .6rem; justify-items: start; }
.motto__social a {
  font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--tx-2);
  transition: color var(--t-fast) var(--ease);
}
.motto__social a:hover { color: var(--red-hi); }

@media (max-width: 760px) {
  .motto__meta { grid-template-columns: 1fr; gap: 1.75rem; }
}

@media (max-width: 1024px) {
  .skillset, .quotes { grid-template-columns: 1fr 1fr; }
  .tl__item { grid-template-columns: 9rem minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .skillset, .quotes { grid-template-columns: 1fr; }
  .tl__item { grid-template-columns: 1fr; gap: .5rem; }
  .reel__ph { display: none; }
}


/* ═══════════════ 01 ABOUT / INTRO ═══════════════
   Editorial statement register. Deliberately NOT Bionix: a fat display face
   is unreadable across a 40-word sentence at 100px. SF Pro at 600 is what
   gives the reference its editorial feel. */
.intro {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: 92svh;
  display: flex; flex-direction: column; justify-content: center;
}






.lbl--intro { border-bottom: 0; padding-bottom: 0; margin-bottom: clamp(2.5rem, 6vw, 4.5rem); }
.lbl--intro i { color: var(--red); margin-right: .5rem; }
.lbl--center { justify-content: center; border-bottom: 0; }

.intro__head {
  font-family: var(--f-body);
  font-size: clamp(2.1rem, 1rem + 4.6vw, 7.5rem);   /* 34px → 120px */
  font-weight: 600;
  line-height: 1.03;
  letter-spacing: -.035em;
  max-width: 78%;                                    /* typography is the hero */
  text-wrap: pretty;
}
.intro__head em { font-style: normal; color: var(--red); }
.intro__word { display: inline-block; will-change: transform, opacity; }

.intro__foot {
  display: grid; grid-template-columns: 1fr minmax(0, 34rem);
  gap: var(--gap); align-items: end;
  margin-top: clamp(3rem, 8vw, 6rem);
}
/* The markup carries Bootstrap column classes so it drops straight into the
   WP theme, but Bootstrap isn't loaded here — these rules give the wrapper
   real behaviour in the meantime. */
.intro__foot > [class*="col-"] { grid-column: 2; min-width: 0; }
.intro__sub {
  font-size: var(--fs-sm); color: var(--tx-2); max-width: 46ch;
  will-change: transform, opacity;
}

.btn-ghost {
  width: fit-content; margin-top: 1.75rem;
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  padding: 1.05rem 2.25rem; border-radius: 100px;
  border: 1px solid var(--line-2);
  background: rgba(255, 255, 255, .02);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  font-size: var(--fs-sm); color: var(--tx);
  will-change: transform, opacity;
  transition: transform var(--t) var(--ease-out),
              border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease),
              background var(--t) var(--ease);
}
.btn-ghost:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--red) 70%, transparent);
  background: color-mix(in srgb, var(--red) 12%, transparent);
  box-shadow: 0 18px 50px -18px color-mix(in srgb, var(--red) 75%, transparent);
}

@media (max-width: 1024px) {
  .intro__head { max-width: 100%; font-size: clamp(2rem, 1rem + 4.4vw, 4rem); }
  .intro__foot { grid-template-columns: 1fr; }
  .intro__foot > [class*="col-"] { grid-column: 1; }
}
@media (max-width: 760px) {
  .intro { min-height: auto; }
  .intro__head { font-size: clamp(2.05rem, 1.1rem + 5.4vw, 3.5rem); letter-spacing: -.03em; }
}
@media (prefers-reduced-motion: reduce) {
  
  .intro__word, .intro__sub, .btn-ghost { opacity: 1 !important; transform: none !important; }
}

/* ═══════════════ GLASS PANEL (About) ═══════════════
   Layer order, back to front:
     -3  .glass__layer   hero image, warped by #glassWarp
     -2  .glass__tint    dark overlay for legibility
     -1  .intro__bg      blobs + grain
      0  content
   The filter lives on .glass__media only, so the text above it is never
   rasterised through an SVG filter — that would destroy both text
   rendering and performance. */
.glass { position: relative; isolation: isolate; overflow: hidden; }

.glass__layer {
  position: absolute; inset: 0; z-index: -3;
  overflow: hidden; pointer-events: none;
}
.glass__media {
  position: absolute; inset: -10%;          /* bleed, so displaced edges never gap */
  will-change: filter, transform;
  transform: translateZ(0);                  /* own layer */
  opacity: 0;                                /* faded in by ScrollTrigger */
}
.glass__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%;
}
.js .glass__media { filter: url(#glassWarp); }

.glass__tint {
  position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgba(var(--bg-rgb), .88) 0%,
      rgba(var(--bg-rgb), .58) 30%,
      rgba(var(--bg-rgb), .62) 70%,
      rgba(var(--bg-rgb), .92) 100%),
    linear-gradient(to right, rgba(var(--bg-rgb), .42), rgba(var(--bg-rgb), .12) 55%);
}


.intro__inner { padding: 0; max-width: none; }
.intro__inner .rows .row { margin: 0; }
.intro__inner [class^="col-"] { padding: 0; }

/* Mobile: SVG filters over a full-viewport surface are far too expensive.
   Drop the filter, keep a static frosted read. */
@media (max-width: 760px) {
  .js .glass__media { filter: none; opacity: .28 !important; }
  .glass__tint { background: linear-gradient(to bottom, rgba(var(--bg-rgb), .93), rgba(var(--bg-rgb), .97)); }
}
@media (prefers-reduced-motion: reduce) {
  .js .glass__media { filter: none; opacity: .22 !important; }
}





/* ═══════════════ SCROLL-OVER FLUTED GLASS (Hero → About) ═══════════════
   Replaces the SVG feDisplacementMap backdrop, which was the source of the
   scroll lag: an SVG filter on a full-viewport backdrop must re-sample and
   re-run turbulence every single frame, on the CPU.

   This version is compositor-only:
     · ONE backdrop-filter: blur/saturate/brightness — GPU, rasterised once
     · vertical ribs drawn as plain gradients — no filter, no blend mode
     · during scroll we animate ONLY opacity and translateX, never the blur
   Reeded (fluted) glass is also the more accurate reference: real vertical
   crystal glass refracts in discrete ribs, it does not smear.

   Stacking inside About:
     0 .glass__pane    frosted backdrop of the real sticky hero
     1 .glass__flutes  rib shading + highlights
     2 .glass__tint    readability
     3 .glass__edge    lit top edge
     4 content
*/
.stage { position: relative; }

.stage .hero {
  position: sticky; top: 0;
  height: 100svh; min-height: 100svh;
  z-index: 0;
}

.intro.glass {
  position: relative; z-index: 2;
  background: transparent;      /* opaque = nothing to refract */
  overflow: hidden;
}

.glass__pane {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  backdrop-filter: blur(14px) saturate(150%) brightness(.86);
  -webkit-backdrop-filter: blur(14px) saturate(150%) brightness(.86);
}

/* Ribs. Two periods, offset, so it reads as hand-made glass rather than a
   printed pattern. Plain rgba — no mix-blend-mode, which forces recompositing. */
.glass__flutes {
  position: absolute; inset: 0 -4%; z-index: 1; pointer-events: none;
  will-change: transform, opacity;
  background: repeating-linear-gradient(90deg,
    rgba(255, 255, 255, .085) 0px,
    rgba(255, 255, 255, .020) 2px,
    rgba(0, 0, 0, .150)      13px,
    rgba(0, 0, 0, .060)      24px,
    rgba(255, 255, 255, .050) 32px,
    rgba(255, 255, 255, .085) 34px);
}
.glass__flutes--fine {
  opacity: .5;
  background: repeating-linear-gradient(90deg,
    rgba(255, 255, 255, .05) 0px,
    rgba(255, 255, 255, .00) 1px,
    rgba(0, 0, 0, .07)       6px,
    rgba(255, 255, 255, .05) 11px);
}

.glass__tint {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(var(--bg-rgb), .26) 0%,
    rgba(var(--bg-rgb), .52) 22%,
    rgba(var(--bg-rgb), .70) 55%,
    rgba(var(--bg-rgb), .97) 92%,
    rgb(var(--bg-rgb)) 100%);
}
.glass__edge {
  position: absolute; inset: 0 0 auto; height: 1px; z-index: 3; pointer-events: none;
  background: linear-gradient(to right,
    transparent, rgba(255,255,255,.30) 22%, rgba(255,255,255,.10) 55%, transparent);
}
.intro.glass .intro__inner { position: relative; z-index: 4; }

/* Tablet: lighter blur. Mobile: no sticky overlap, minimal glass. */
@media (max-width: 1024px) {
  .glass__pane { backdrop-filter: blur(9px) saturate(125%) brightness(.85);
                 -webkit-backdrop-filter: blur(9px) saturate(125%) brightness(.85); }
  .glass__flutes--fine { display: none; }
}
@media (max-width: 760px) {
  .stage .hero { position: relative; }
  .glass__pane { backdrop-filter: blur(6px) brightness(.8);
                 -webkit-backdrop-filter: blur(6px) brightness(.8); }
  .glass__flutes { opacity: .45; }
  .glass__tint { background: linear-gradient(to bottom,
    rgba(var(--bg-rgb), .84), rgb(var(--bg-rgb)) 62%); }
}
@media (prefers-reduced-motion: reduce) {
  .stage .hero { position: relative; }
  .glass__flutes { opacity: .4 !important; transform: none !important; }
}





/* ═══════════════ 02 WHAT I DO ═══════════════
   Sticky heading holds for one viewport, then each card wrapper pins while
   the card inside scales up from 0.65 and lifts into place. A summary grid
   is pulled up over the last card at the end.
   Card tints are dark analogues of the reference's three pastels. */
.wid { position: relative; width: 100%; padding: 0 0 clamp(6rem, 12vh, 9.5rem); background: var(--bg); }

/* ── sticky heading ── */
.wid__heading {
  position: sticky; top: 0; z-index: 1;
  height: 100svh;
  /* top-anchored, not centred — centring made the headline's vertical extent
     depend on its own height, which is what put it under the cards */
  display: flex; flex-direction: column; justify-content: flex-start;
  padding: calc(var(--hdr-h) + 4svh) var(--gutter-x) 0;
}
.wid__meta {
  display: flex; align-items: center; gap: 1.25rem;
  margin-bottom: clamp(1.75rem, 4vh, 2.8rem);
  font-family: var(--f-body);
  font-size: var(--fs-xs); font-weight: 500;
  letter-spacing: .16em; text-transform: uppercase;
}
.wid__metaNum { display: flex; align-items: center; gap: 1.25rem; color: var(--red-hi); }
.wid__metaNum::after { content: ""; width: 75px; height: 1px; background: var(--line-2); }
.wid__metaName { color: var(--tx-3); }
.wid__statement {
  max-width: 1500px;
  font-family: var(--f-display);
  font-size: clamp(2.9rem, .6rem + 7.4vw, 8.5rem);
  font-weight: 400; line-height: .86; letter-spacing: -.03em;
  text-transform: uppercase;
}
.wid__statement span { display: block; overflow: hidden; }
.wid__statement span > span { display: block; will-change: transform, opacity; }
.wid__statement em { font-style: normal; color: var(--red); }

/* ── large sticky cards ── */
/* The 100svh tail does two jobs: it gives the LAST card a sticky range (three
   equal sticky children exactly filling their parent leaves the last with
   none), and it buys a full viewport of hold after all three have stacked,
   before the grid arrives and the morph begins. Without it the grid's
   -100svh margin lands it exactly as card 03 pins, so the morph ran while
   the cards were still stacking. */
/* 200svh tail, not 100: the last 100svh is the hold before the grid arrives,
   the first 100svh keeps every wrapper inside its sticky range for the whole
   length of the morph. With only 100svh the wrappers hit their containment
   limit part-way through and rode up over the sticky headline. */
.wid__cards { position: relative; z-index: 5; }
/* 100svh of hold after the third card pins, then 100svh for the morph itself */
/* 100svh of hold after the third card pins, then 200svh for the morph —
   double the old travel, which is what makes the landing feel unhurried. */
.wid__tail { height: 300svh; pointer-events: none; }
/* Cards sit in the lower band so they never cross the headline. flex-end
   rather than center: the heading owns the top of the sticky viewport, the
   card owns what's left underneath it. */
.wid__wrap {
  position: sticky; top: 0;
  height: 100svh;
  display: flex; align-items: flex-end; justify-content: center;
  padding: 0 var(--gutter-x) clamp(2.5rem, 7vh, 5rem);
}
.wid__card {
  position: relative;
  width: min(72vw, 1080px); height: min(48svh, 520px);
  padding: clamp(1.5rem, 3vw, 3.25rem);
  display: flex; align-items: stretch; gap: clamp(1.25rem, 3vw, 3rem);
  border-radius: 10px;
  overflow: hidden;
  transform-origin: center center;
  will-change: transform, opacity;
}

/* ── one glass treatment, shared by the large card and its grid twin ──
   Page black at partial alpha over a backdrop blur, so the headline behind
   goes soft instead of being hidden. All three are the same colour now; the
   number is the only thing that distinguishes them. */
.wid__card, .wid__mini {
  background: rgba(var(--bg-rgb), .55);
  backdrop-filter: blur(26px) saturate(135%);
  -webkit-backdrop-filter: blur(26px) saturate(135%);
  border: 1px solid var(--line);
  box-shadow: 0 24px 70px rgba(0, 0, 0, .45);
}
/* Safari and Firefox parse backdrop-filter but won't always paint it behind a
   transformed element — fall back to a near-opaque black so text stays legible. */
@supports not (backdrop-filter: blur(1px)) {
  .wid__card, .wid__mini { background: rgba(var(--bg-rgb), .94); }
}

/* ── card content ── */
/* Text column and object column. The object slot is a square sized off the
   card's inner height, so the large card and its grid twin hold the object at
   the same proportion — which is what lets the morph read as one shrink. */
.wid__body {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; justify-content: space-between;
}
.wid__viz {
  /* Sized as a PERCENTAGE OF CARD WIDTH, not height. Height-based sizing made
     the slot 23% of the large card's width but 39% of the twin's, so the
     object grew as the card shrank. A width percentage scales with the FLIP. */
  flex: 0 0 32%; align-self: center;
  aspect-ratio: 1; max-height: 100%;
  /* Nothing is painted here. The shared WebGL canvas reads this element's
     rect each frame and renders the object into it, so the box only needs to
     reserve the space and stay measurable. */
}
.wid__top { display: flex; justify-content: space-between; gap: var(--gap); }
.wid__num {
  font-family: var(--f-display);
  font-size: clamp(1.9rem, 3.4vw, 3.8rem); line-height: 1;
  color: var(--red);
}
.wid__cat {
  max-width: 210px; text-align: right;
  font-size: var(--fs-xs); line-height: 1.5;
  letter-spacing: .12em; text-transform: uppercase; color: var(--tx-3);
}
.wid__title {
  max-width: 900px; margin-bottom: clamp(1rem, 2vw, 1.75rem);
  font-family: var(--f-display);
  font-size: clamp(2rem, .8rem + 2.9vw, 4.2rem);
  font-weight: 400; line-height: .88; letter-spacing: -.03em;
  text-transform: uppercase;
}
.wid__desc {
  max-width: 52ch; margin-bottom: 0;
  font-size: var(--fs-body); line-height: 1.55; color: var(--tx-2);
}

/* ── 3D object layer ──
   ONE canvas for all three objects. It sits ABOVE .wid__cards (z 5) on
   purpose: below it, the cards' own backdrop-filter would blur the object
   inside its own card. Transparent everywhere except the slot rectangles. */
.viz-canvas {
  position: fixed; inset: 0; z-index: 6;
  width: 100%; height: 100%;
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s var(--ease);
}
@media (max-width: 767px) { .viz-canvas { display: none; } }

/* ── summary grid, pulled up over the last card ── */
/* Bottom-aligned inside a full viewport box, matching .wid__wrap — so the
   grid lands in the same empty band the large cards occupy, clear of the
   headline, and the morph is a pure shrink with no vertical jump. */
.wid__grid {
  position: relative; z-index: 2;      /* under .wid__cards (5) */
  width: 100%;
  /* -300svh, not -200: the row must be pinned BEFORE the first card starts
     its cross-fade, not halfway through. At -200 the morph began while the
     row was still rising, so a card faded out against a target that was
     still moving — that is the ghost duplicate. */
  margin-top: -300svh;
  height: 300svh;
  pointer-events: none;
}
.wid__gridSticky {
  position: sticky; top: 0;
  height: 100svh;
  display: flex; align-items: flex-end;
  padding: 0 var(--gutter-x) clamp(7rem, 20vh, 13rem);
}
.wid__gridInner {
  width: 100%;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gap); align-items: stretch;
}
/* Same markup as the large card, just smaller — so the shrink reads as one
   object, not a swap. Each starts hidden and cross-fades in exactly as its
   large card lands on it (03, then 02, then 01). */
/* aspect ratio is synced from the large card by JS (--wid-ar) so the shrunk
   card covers the mini exactly — a mismatch shows as a jump at the cross-fade */
.wid__mini {
  aspect-ratio: 1 / var(--wid-ar, 0.435);
  padding: clamp(.85rem, 1.15vw, 1.2rem);
  will-change: opacity;
  display: flex; align-items: stretch; gap: clamp(.6rem, 1.2vw, 1.1rem);
  border-radius: 10px; overflow: hidden;
  opacity: 0;
}
/* the mini re-scales the card's own type rather than using different copy */
html:not(.js) .wid__mini { opacity: 1; }
.wid__mini .wid__num   { font-size: clamp(1.05rem, 1.35vw, 1.6rem); }
.wid__mini .wid__cat   { max-width: 120px; font-size: 9px; letter-spacing: .09em; }
.wid__mini .wid__title { font-size: clamp(1.05rem, 1.35vw, 1.6rem); margin-bottom: .5rem; }
.wid__mini .wid__desc  {
  font-size: 13px; line-height: 1.45; margin-bottom: 0;
}
/* ── mobile ── */
@media (max-width: 767px) {
  .wid { padding-bottom: var(--sec-y); }
  .wid__heading { position: relative; height: auto; padding: var(--sec-y) var(--gutter-x) 3rem; }
  .wid__statement { font-size: 15vw; line-height: .9; }
  .wid__wrap {
    position: relative; height: auto;
    padding: 0 var(--gutter-x) var(--gap);
  }
  .wid__card {
    width: 100%; height: auto; min-height: 620px;
    padding: 1.75rem 1.35rem;
    transform: none !important; opacity: 1 !important;
  }
  .wid__cat { display: none; }
      .wid__grid { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .wid__heading, .wid__wrap { position: relative; height: auto; }
  .wid__card { transform: none !important; opacity: 1 !important; }
  .wid__grid { margin-top: 0; }
  .wid__statement span > span { transform: none !important; opacity: 1 !important; }
}

/* ── PORTFOLIO ROWS: industry + services instead of a year ── */
.work .rows .row a { grid-template-columns: 4rem minmax(0, 1fr) 11rem 9rem 3rem; }
@media (max-width: 1024px) {
  .work .rows .row a { grid-template-columns: 3rem minmax(0, 1fr) 9rem 7rem 2rem; }
}

/* Cursor-follow cover preview — desktop pointer only. On touch there's no
   cursor to follow, so the whole thing stays off rather than getting stuck
   on-screen after a tap. */
.rowPreview {
  position: fixed; top: 0; left: 0; z-index: 250; pointer-events: none;
  width: min(320px, 26vw); aspect-ratio: 4 / 3; overflow: hidden; border-radius: 10px;
  opacity: 0; transform: translate(-50%, -50%) scale(.94);
  transition: opacity .25s var(--ease), transform .4s var(--ease);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
}
.rowPreview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rowPreview.is-active { opacity: 1; transform: translate(-50%, -50%) scale(1); }
@media (hover: none), (pointer: coarse) {
  .rowPreview { display: none; }
}

/* ── CASE STUDY PAGES ────────────────────────────────────── */
.cs-hero {
  padding-top: clamp(7rem, 16vh, 10rem); padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
}
.cs-back {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--fs-xs); color: var(--tx-3);
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
  transition: color var(--t-fast) var(--ease);
}
.cs-back:hover { color: var(--red-hi); }
.cs-hero__title {
  font-family: var(--f-display); text-transform: uppercase;
  font-size: var(--fs-big-sm); line-height: .96; letter-spacing: -.015em;
}
.cs-hero__title span { display: block; }
.cs-hero__title span + span { margin-top: .1em; }
.cs-hero__rule {
  display: inline-block; width: clamp(1.75rem, 5vw, 4rem); height: 3px;
  background: currentColor; vertical-align: middle; margin-right: .5em;
  transform: translateY(-.15em);
}
.cs-hero__meta {
  display: flex; flex-wrap: wrap; gap: .6rem;
  margin-top: clamp(1.5rem, 3vw, 2rem);
}
.cs-tag {
  border: 1px solid var(--line-2); border-radius: 100px;
  padding: .45rem 1rem; font-size: var(--fs-xs); color: var(--tx-2);
}
.cs-tag--industry { color: var(--red-hi); border-color: color-mix(in srgb, var(--red-hi) 45%, var(--line-2)); }
.cs-hero__desc {
  margin-top: clamp(1.5rem, 3vw, 2rem); max-width: 56ch;
  font-size: var(--fs-lead); color: var(--tx-2);
}

/* full-width cover, right under the hero */
.cs-cover { padding-top: 0; padding-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.cs-cover__img { width: 100%; display: block; border-radius: 10px; background: var(--bg-2); }

/* text on the left at a comfortable reading measure, a small supporting
   image on the right — so the space beside the prose isn't just empty */
.cs-narrative {
  padding-top: 0; padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
  display: grid; grid-template-columns: minmax(0, 68ch) 1fr;
  gap: clamp(2.5rem, 5vw, 4rem); align-items: start;
}
.cs-narrative__body { min-width: 0; }
.cs-narrative__aside { position: sticky; top: calc(var(--hdr-h) + 2rem); }
.cs-narrative__aside img {
  width: 100%; border-radius: 10px; display: block; background: var(--bg-2);
}
/* no side image to show (too few images to avoid repeating one) — run the
   text the full width of the section instead of leaving an empty column */
.cs-narrative--full { grid-template-columns: 1fr; }
.cs-narrative__lead { max-width: 68ch; font-size: var(--fs-lead); color: var(--tx-2); line-height: 1.7; }
.cs-narrative__title {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  font-family: var(--f-display); text-transform: uppercase;
  font-size: clamp(1.5rem, 1rem + 2vw, 2.25rem);
}
.cs-narrative p:not(.cs-narrative__lead) {
  max-width: 68ch; margin-top: 1.25rem; color: var(--tx-2); line-height: 1.7;
}
.cs-narrative__roles { margin-top: clamp(2.5rem, 5vw, 3.5rem); }

.cs-cta { padding-block: clamp(3rem, 6vw, 5rem); border-top: 1px solid var(--line); }

.cs-body {
  margin-top: clamp(3.5rem, 7vw, 5.5rem);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2.5rem, 5vw, 4rem) var(--gap);
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
  border-top: 1px solid var(--line);
}
.cs-block p { max-width: 52ch; color: var(--tx-2); line-height: 1.7; }
.cs-kicker {
  font-size: var(--fs-xs); letter-spacing: .14em; text-transform: uppercase;
  color: var(--tx-3); margin-bottom: .85rem;
}
.cs-kicker i { font-style: normal; color: var(--red-hi); margin-right: .5rem; }
.cs-role { display: grid; gap: .65rem; }
.cs-role li {
  position: relative; padding-left: 1.3rem;
  font-size: var(--fs-sm); color: var(--tx-2); line-height: 1.5;
}
.cs-role li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--red-hi);
}
.cs-role--pillar { margin-top: 1.5rem; max-width: 60ch; }
@media (max-width: 760px) {
  .cs-body { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .cs-narrative { grid-template-columns: 1fr; }
  .cs-narrative__aside { position: static; order: -1; }
}

.cs-gallery {
  padding-top: 0;
  display: flex; flex-direction: column; gap: clamp(3rem, 6vw, 5rem);
}
.cs-gallery .lbl { margin-bottom: clamp(2rem, 4vw, 3rem); }
.cs-figure img {
  width: 100%; border-radius: 6px; background: var(--bg-2);
}
.cs-figure figcaption {
  margin-top: 1rem; max-width: 60ch;
  font-size: var(--fs-sm); color: var(--tx-3);
}

.cs-next {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--gap); border-top: 1px solid var(--line);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.cs-next__link { min-width: 0; }
.cs-next__lbl {
  display: block; font-size: var(--fs-xs); letter-spacing: .12em; text-transform: uppercase;
  color: var(--tx-3); margin-bottom: .5rem;
}
.cs-next__title {
  font-family: var(--f-display); text-transform: uppercase;
  font-size: clamp(1.5rem, 3.5vw, 2.5rem); color: var(--tx);
  transition: color var(--t-fast) var(--ease);
}
.cs-next__link:hover .cs-next__title { color: var(--red-hi); }

@media (max-width: 760px) {
  .cs-next { flex-direction: column; align-items: flex-start; }
}

/* ── PORTFOLIO PAGE (staggered grid) ────────────────────────── */
.pf-grid {
  padding-top: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--gap); row-gap: clamp(3.5rem, 7vw, 6rem);
}
.pf-item { display: block; }
.pf-item:nth-child(even) { margin-top: clamp(4rem, 9vw, 7rem); }
.pf-item__media {
  position: relative; border-radius: 10px; overflow: hidden;
  background: var(--bg-2);
}
/* varied cover sizes, so the grid reads as a scattered wall of work rather
   than a uniform tile set */
.pf-item__media--wide     { aspect-ratio: 16 / 9; }
.pf-item__media--standard { aspect-ratio: 4 / 3; }
.pf-item__media--square   { aspect-ratio: 1 / 1; }
.pf-item__media--tall     { aspect-ratio: 3 / 4; }
.pf-item__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .6s var(--ease-out);
}
.pf-item:hover .pf-item__media img { transform: scale(1.05); }
.pf-item__meta { margin-top: 1.25rem; display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; }
.pf-item__title {
  font-family: var(--f-display); text-transform: uppercase;
  font-size: clamp(1.25rem, 1rem + 1.5vw, 1.75rem); color: var(--tx);
  transition: color var(--t-fast) var(--ease);
}
.pf-item:hover .pf-item__title { color: var(--red-hi); }
.pf-item__tag { font-size: var(--fs-xs); color: var(--tx-3); text-align: right; white-space: nowrap; }

@media (max-width: 760px) {
  .pf-grid { grid-template-columns: 1fr; row-gap: 2.5rem; }
  .pf-item:nth-child(even) { margin-top: 0; }
}

.pf-cta {
  position: relative; overflow: hidden; text-align: center;
  padding-top: clamp(5rem, 12vw, 8rem); padding-bottom: clamp(2.5rem, 5vw, 4rem);
}
.pf-cta__glow {
  position: absolute; left: 50%; bottom: -40%; translate: -50% 0;
  width: min(1100px, 140%); aspect-ratio: 1; pointer-events: none; z-index: -1;
  background: radial-gradient(circle, color-mix(in srgb, var(--red-deep) 45%, transparent), transparent 62%);
  filter: blur(20px);
}
.pf-cta__title {
  font-family: var(--f-display); text-transform: uppercase;
  font-size: clamp(2.25rem, 1rem + 6vw, 5rem); line-height: .98; letter-spacing: -.01em;
  max-width: 18ch; margin-inline: auto;
}
.pf-cta__title em { font-style: normal; color: var(--red); }
.pf-cta .motto__cta { justify-items: center; margin-top: clamp(2rem, 4vw, 3rem); }

/* ── CONTACT FORM ────────────────────────────────────────── */
.cf { max-width: 44rem; margin-top: clamp(2.5rem, 5vw, 4rem); display: grid; gap: 1.5rem; }
.cf__row { display: grid; gap: .5rem; }
.cf__row label {
  font-size: var(--fs-xs); letter-spacing: .1em; text-transform: uppercase; color: var(--tx-3);
}
.cf input, .cf textarea {
  width: 100%; background: rgba(255, 255, 255, .03); border: 1px solid var(--line-2); border-radius: 8px;
  padding: .85rem 1rem; color: var(--tx); font: inherit; font-size: var(--fs-body);
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.cf select {
  width: 100%; background: rgba(255, 255, 255, .03); border: 1px solid var(--line-2); border-radius: 8px;
  padding: .85rem 1rem; color: var(--tx); font: inherit; font-size: var(--fs-body);
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23B3A9A7' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 1rem center;
}
.cf select option { background: var(--bg-2); color: var(--tx); }
.cf input:focus, .cf textarea:focus, .cf select:focus { border-color: var(--red-hi); background: rgba(255, 255, 255, .05); outline: none; }
.cf textarea { resize: vertical; min-height: 120px; }
.cf__note { font-size: var(--fs-xs); color: var(--tx-3); }
.cf .btn, .cf .btn-ghost { width: fit-content; }

/* ── STEP FORM (Get In Touch) ────────────────────────────── */
.cf__steps {
  display: flex; flex-wrap: wrap; gap: clamp(1rem, 3vw, 2rem);
  margin-bottom: clamp(1.75rem, 3vw, 2.5rem);
}
.cf__stepDot {
  display: flex; align-items: center; gap: .5rem;
  font-size: var(--fs-xs); letter-spacing: .06em; text-transform: uppercase; color: var(--tx-3);
  transition: color var(--t-fast) var(--ease);
}
.cf__stepDot span {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; border-radius: 50%; border: 1px solid var(--line-2);
  font-family: var(--f-display); font-size: .7rem; color: var(--tx-3);
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.cf__stepDot.is-active { color: var(--tx); }
.cf__stepDot.is-active span { color: var(--red-hi); border-color: var(--red-hi); }
.cf__stepDot.is-done span { color: var(--bg); background: var(--red-hi); border-color: var(--red-hi); }

.cf__step { display: none; }
.cf__step.is-active { display: grid; gap: 1.5rem; }
.cf__step--book.is-active { margin-top: clamp(1.75rem, 3vw, 2.5rem); }
.cf__bookIntro { font-size: var(--fs-lead); color: var(--tx); max-width: 44ch; }
.cf__actions { display: flex; align-items: center; justify-content: space-between; gap: 1rem; }

.calendly-inline-widget { max-width: 100%; border-radius: 10px; overflow: hidden; }
/* Calendly's own snippet hardcodes min-width:320px inline. On the very
   narrowest phones (page padding eats into the 320px viewport) that forces
   the page wider than the screen — override it once there isn't 320px of
   content width to spare. */
@media (max-width: 368px) {
  .calendly-inline-widget { min-width: 0 !important; height: 620px !important; }
}

/* ── GET IN TOUCH (site-wide, every page) ───────────────────── */
.gt { border-top: 1px solid var(--line); padding-block: clamp(3rem, 6vw, 4.5rem); }
.gt__grid {
  display: grid; grid-template-columns: 1fr 1.1fr;
  gap: clamp(2.5rem, 6vw, 5rem); align-items: start;
}
.gt__label {
  font-size: var(--fs-xs); letter-spacing: .16em; text-transform: uppercase;
  color: var(--tx-3); margin-bottom: 1rem;
}
.gt__title {
  font-family: var(--f-display); text-transform: uppercase;
  font-size: clamp(2rem, 1rem + 4vw, 3.25rem); line-height: 1; letter-spacing: -.01em;
  max-width: 14ch;
}
.gt__links {
  margin-top: clamp(1.5rem, 3vw, 2rem); display: grid; gap: .5rem;
  font-size: var(--fs-body); color: var(--tx-2);
}
.gt__links a {
  color: var(--tx); border-bottom: 1px solid var(--line-2); padding-bottom: 1px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.gt__links a:hover { color: var(--red-hi); border-color: var(--red-hi); }
.gt__desc {
  margin-top: clamp(1.5rem, 3vw, 2rem); max-width: 46ch;
  color: var(--tx-3); font-size: var(--fs-sm); line-height: 1.7;
}
.gt .cf { max-width: none; margin-top: 0; }

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

@media (max-width: 640px) {
  .cf__steps { gap: 1rem; }
  .cf__stepDot { font-size: 0; gap: 0; } /* keep the numbered circle, drop the label text to save width */
  .cf__stepDot span { font-size: .7rem; }
  .cf__actions { flex-wrap: wrap; }
  .cf__actions .btn, .cf__actions .btn-ghost { flex: 1 1 auto; }
}
