/* ---------- Fonts ---------- */
@font-face {
  font-family: 'Troika';
  src: url('assets/Fonts/troika/troika.otf') format('opentype');
  font-weight: 400 900;
  font-display: swap;
}

/* ---------- Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
body, h1, h2, h3, p, figure { margin: 0; }
img, iframe { max-width: 100%; display: block; }
button { font: inherit; }
a { color: inherit; }

/* ---------- Design tokens ---------- */
:root {
  --bg: #17171a;
  --bg-elevated: #1f1f23;
  --bg-card: #26262b;
  --fg: #f1f1ee;
  --muted: #9a9aa2;
  --accent: #a78bfa;
  --accent-fg: #17171a;
  --accent-soft: rgba(167, 139, 250, 0.5);
  --border: rgba(255, 255, 255, 0.1);
  --border-strong: rgba(255, 255, 255, 0.18);

  --font-display: 'Troika', 'Archivo', system-ui, sans-serif;
  --font-body: 'Space Grotesk', system-ui, sans-serif;

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;
  --space-5: 3rem;
  --space-6: 4rem;
  --space-7: 6rem;
  --space-8: 8rem;
  --space-divider: 3.25rem; /* ~60% shorter than --space-8 — the standard gap between major sections */

  --container: 1360px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --dur: 250ms;
}

body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--accent);
  color: var(--accent-fg);
  padding: 0.75rem 1.25rem;
  z-index: 999;
  font-weight: 600;
}
.skip-link:focus {
  left: 1rem;
  top: 1rem;
}

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

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.9rem 1.6rem;
  border-radius: 0;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
  min-height: 44px;
}
.btn-primary {
  background: var(--accent);
  color: var(--accent-fg);
  transform: rotate(-1.5deg);
}
.btn-primary:hover { background: #bda6fb; transform: translateY(-2px) rotate(-1.5deg); }
.btn-ghost {
  background: transparent;
  color: var(--fg);
  border-color: var(--border-strong);
  border-radius: 0;
  transform: rotate(1.2deg);
}
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); transform: translateY(-2px) rotate(1.2deg); }

/* ---------- Header ---------- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 0.65025rem 0;
  transition: padding var(--dur) var(--ease);
}
/* The dark bar is its own oversized, slightly rotated layer behind the nav
   content — same technique as the tilted project bars — so the rotation
   never opens a gap at the header's edges and never skews the clickable
   nav links/logo themselves. */
.site-header-bg {
  position: absolute;
  top: -26px;
  right: -6px;
  bottom: 22px;
  left: -6px;
  z-index: 0;
  background: rgba(10,10,10,0.8);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  transform: rotate(-0.6deg);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .site-header-bg { transform: none; }
}
.header-inner {
  position: relative;
  z-index: 1;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.logo {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 2rem;
  text-decoration: none;
  color: var(--fg);
  letter-spacing: -0.02em;
  transform: translateY(-8px);
}
.logo span { color: var(--accent); }
.main-nav {
  display: flex;
  gap: var(--space-5);
  transform: translateY(-15px);
}
.main-nav a {
  text-decoration: none;
  color: var(--muted);
  font-weight: 500;
  font-size: 0.95rem;
  transition: color var(--dur) var(--ease);
}
.main-nav a:hover { color: var(--fg); }
.header-actions { display: flex; align-items: center; gap: var(--space-3); }
/* Smaller box than the standard .btn-primary — same font-size, just tighter
   padding and no enforced min-height, so it reads as a compact header CTA. */
.header-actions .btn {
  padding: 0.5rem 1.1rem;
  min-height: 0;
}

.menu-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  background: transparent;
  border: none;
  cursor: pointer;
}
.menu-toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--fg);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  margin: 0 auto;
}
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

.mobile-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  z-index: 99;
  display: flex;
  flex-direction: column;
  padding: 6rem var(--space-4) var(--space-4);
  gap: var(--space-3);
  transform: translateY(-100%);
  opacity: 0;
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
  pointer-events: none;
}
.mobile-nav.open {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}
.mobile-nav a {
  font-family: var(--font-display);
  font-size: 1.75rem;
  font-weight: 800;
  text-decoration: none;
  color: var(--fg);
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}
.hero-media {
  position: absolute;
  inset: -16% -10%;
  z-index: -1;
  background: var(--bg);
  transform: perspective(3600px) rotateX(4deg) rotateY(-7deg);
  transform-origin: center;
}
@media (prefers-reduced-motion: reduce) {
  .hero-media { transform: none; }
}
.hero-video-wrap {
  position: absolute;
  top: 50%; left: 50%;
  width: 100%; height: 100%;
  transform: translate(-50%, -50%);
  overflow: hidden;
}
.hero-video-wrap iframe {
  position: absolute;
  top: 50%; left: 50%;
  width: 100vw; height: 56.25vw;
  min-height: 100vh; min-width: 177.78vh;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.hero-overlay {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(0deg, rgba(10,10,10,0.97) 0%, rgba(10,10,10,0.9) 50%, rgba(10,10,10,0.6) 75%, rgba(10,10,10,0.35) 100%),
    linear-gradient(90deg, rgba(10,10,10,0.5) 0%, rgba(10,10,10,0.1) 30%, rgba(10,10,10,0.1) 70%, rgba(10,10,10,0.5) 100%);
}
.hero-noise {
  position: absolute;
  inset: 0;
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  mix-blend-mode: overlay;
}
.hero-corner-gradient {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at bottom left, rgba(0,0,0,0.96) 0%, rgba(0,0,0,0) 65%);
  pointer-events: none;
}

.hero-content {
  position: relative;
  z-index: 1;
  max-width: var(--container);
  margin: 0 auto;
  width: 100%;
  padding: 0 var(--space-4) var(--space-7);
}
.hero-heading {
  margin-top: -5px;
  transform: perspective(1000px) rotateY(20deg);
  transform-origin: left center;
}
@media (prefers-reduced-motion: reduce) {
  .hero-heading { transform: none; }
}
.eyebrow {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: 0;
}
.hero-title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(3.2rem, 11vw, 9rem);
  line-height: 0.88;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}
.hero-title-line { display: block; }
#heroTitleMain { transform: translateX(3px); }
.hero-title-accent { color: var(--accent); }
.hero-title-sub {
  font-size: clamp(1.2rem, 4.1vw, 3.45rem);
  font-weight: 700;
  text-transform: none;
  letter-spacing: -0.01em;
  margin-top: -0.22em;
}
.hero-tagline {
  margin-top: 6px;
  max-width: 600px;
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  line-height: 1.15;
  color: var(--fg);
}
.hero-tagline-inner {
  display: block;
  transform: perspective(1000px) rotateY(-20deg);
  transform-origin: left center;
}
@media (prefers-reduced-motion: reduce) {
  .hero-tagline-inner { transform: none; }
}
.hero-tagline-muted { color: var(--muted); }
.hero-actions {
  margin-top: var(--space-5);
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  transform: translateX(5px);
}

/* ---------- Fixed bug mascot ---------- */
/* Pinned to the viewport corner like the header, rather than living inside
   the hero — stays put and clickable at any scroll position. */
.bug-mascot-wrap {
  position: fixed;
  right: var(--space-4);
  bottom: var(--space-3);
  /* Below .lightbox (200) and .password-gate (300) so the mascot — and its
     splat when squished — sits behind any open project window instead of
     floating on top of it. */
  z-index: 150;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.squish-counter {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.2;
  opacity: 0;
  transform: translateX(8px);
  transition: opacity 1000ms var(--ease), transform 1000ms var(--ease);
  pointer-events: none;
}
.squish-counter.visible { opacity: 1; transform: translateX(0); }
.squish-counter-label {
  font-family: var(--font-body);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.62rem;
  font-weight: 600;
  color: var(--muted);
}
.squish-counter-value {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.4rem;
  color: var(--accent);
}
.squish-counter-value.pop {
  animation: squish-count-pop 500ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@keyframes squish-count-pop {
  0% { transform: scale(1) rotate(0deg); opacity: 1; }
  40% { transform: scale(0.25) rotate(-12deg); opacity: 0; }
  55% { transform: scale(0.25) rotate(10deg); opacity: 0; }
  75% { transform: scale(1.25) rotate(-4deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .squish-counter-value.pop { animation: none; }
}
.bug-mascot {
  position: relative;
  width: 192px;
  height: 108px;
  padding: 0;
  border: none;
  background: none;
  color: var(--accent);
  cursor: pointer;
  filter: drop-shadow(0 6px 14px rgba(0,0,0,0.5));
  transform-origin: 50% 85%;
}
.bug-mascot svg, .bug-mascot img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
.bug-mascot img { object-fit: contain; transition: filter 250ms var(--ease); }
/* Splat is scaled up to 3x+ its box on squish (see splat-pop below) — without
   this it visually spills over neighboring content and, because pointer
   events follow the post-transform paint area, silently blocks clicks on
   whatever it overlaps (e.g. a project bar scrolled underneath it). */
.bug-mascot .bug-icon-splat { display: none; pointer-events: none; }
.bug-mascot.squished .bug-icon-walk { display: none; }
.bug-mascot.squished .bug-icon-splat { display: block; }
/* Applied via JS a frame after .squished (see script.js) — starting a CSS
   animation in the same style pass that also flips display:none to block
   doesn't reliably play in every browser, so the two are split apart. */
.bug-icon-splat.splat-anim {
  animation: splat-pop 380ms var(--ease) forwards;
}
.bug-mascot:hover,
.bug-mascot:focus-visible {
  color: var(--fg);
}
.bug-mascot:hover .bug-icon-walk,
.bug-mascot:focus-visible .bug-icon-walk {
  filter: brightness(0) invert(1);
}
.bug-mascot.squished {
  cursor: default;
  animation: bug-squish 380ms var(--ease) forwards;
}
.bug-mascot.squished:hover,
.bug-mascot.squished:focus-visible {
  color: var(--accent);
}
@keyframes bug-squish {
  0% { transform: translateY(0) rotate(-4deg); }
  45% { transform: translateY(10px) rotate(0deg); }
  75% { transform: translateY(6px) rotate(0deg); }
  100% { transform: translateY(8px) rotate(0deg); }
}
@keyframes splat-pop {
  0% { transform: scale(0.3); opacity: 0; }
  60% { transform: scale(3.3); opacity: 1; }
  100% { transform: scale(3); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .bug-mascot.squished { animation: none; transform: translateY(8px); }
  .bug-mascot.squished .bug-icon-splat { animation: none; transform: scale(3); opacity: 1; }
}
@media (max-width: 768px) {
  .bug-mascot { width: 156px; height: 88px; }
  /* On mobile, hide the mascot outright while a project window is open
     rather than just letting it sit behind it — less clutter on a small
     screen, not just out of the way. */
  body:has(.lightbox.open) .bug-mascot-wrap { display: none; }
}

/* ---------- Credibility strip ---------- */
.credibility {
  position: relative;
  z-index: 5;
  overflow: hidden;
  /* Pulled up to sit closer to the hero's buttons — deliberately overlapping
     the tail end of the hero video, which is fine since z-index puts this
     bar in front of it. Vertical padding here is clearance for the tilted
     card's corners (see .credibility-card), not visual spacing — without it
     the rotation's raised/lowered corners get clipped by this overflow. */
  margin-top: clamp(-100px, calc(-6vw - 10px), -66px);
  padding: clamp(20px, 2.2vw, 32px) 0;
}
/* Shared section-boundary divider — a soft purple line replacing plain gray
   borders, used consistently everywhere sections meet. Credibility's own
   top/bottom lines live on .credibility-card instead (see below), since that
   whole bar — borders included — tilts together as one rigid unit. */
.work::before,
.contact::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  width: 100vw;
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(167,139,250,0.45) 50%, transparent);
  pointer-events: none;
}
/* The "industry" bar (stat + scrolling logos) is treated as a single rigid
   card — top border, content, and bottom border all tilt together — rather
   than tilting the text independently of its edges. Slightly oversized and
   held inside .credibility's overflow:hidden so the rotation never reveals
   a gap at the viewport edges. */
.credibility-card {
  position: relative;
  width: 104vw;
  margin-left: -2vw;
  background: var(--bg-elevated);
  transform: rotate(-1deg);
}
.credibility-card::before,
.credibility-card::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(167,139,250,0.45) 50%, transparent);
  pointer-events: none;
}
.credibility-card::before { top: 0; }
.credibility-card::after { bottom: 0; }
@media (prefers-reduced-motion: reduce) {
  .credibility-card { transform: none; }
}
.credibility-inner {
  position: relative;
  z-index: 1;
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--space-4);
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.credibility-stat {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  padding-right: var(--space-5);
  border-right: 1px solid var(--border);
}
.stat-number {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 2rem;
  color: var(--accent);
  line-height: 1;
}
.stat-label {
  font-size: 0.8rem;
  color: var(--muted);
  margin-top: 0.25rem;
  white-space: nowrap;
}
/* The scrolling company-names bar is its own tilted 3D card — separate from
   the flat "15+" stat beside it — so the rotation is unmistakable rather
   than hidden inside a flat, textureless background. */
.marquee {
  overflow: hidden;
  flex: 1;
  mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, black 8%, black 92%, transparent);
}
.marquee-track {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: max-content;
  white-space: nowrap;
  animation: marquee 32s linear infinite;
  font-size: 1.05rem;
  font-weight: 500;
  color: var(--muted);
}
.marquee-track .dot { color: var(--accent); font-size: 0.7rem; }
/* Brand marks rendered via CSS mask so every logo — regardless of its own
   fill colors — reads as a single consistent monochrome mark on the bar. */
.brand-logo {
  display: inline-block;
  width: 108px;
  height: 32px;
  flex-shrink: 0;
  background-color: var(--muted);
  -webkit-mask-image: var(--logo-src);
  mask-image: var(--logo-src);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
  opacity: 0.75;
  transition: opacity 250ms var(--ease), background-color 250ms var(--ease);
}
.brand-logo:hover { opacity: 1; background-color: var(--fg); }
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  .marquee { overflow-x: auto; }
}

/* ---------- Section shared ---------- */
/* .section-head lives inside .work, which already provides the container
   width/padding — giving section-head its own copy of that padding used to
   double the top gap before "Selected Work" ever appeared. */
.work {
  position: relative;
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--space-divider) var(--space-4) 0;
}
.section-kicker {
  position: relative;
  z-index: 1;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: var(--space-2);
}
.section-title {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.2rem, 5.5vw, 4rem);
  line-height: 0.92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

/* ---------- Work strips ---------- */
/* Each bar is oversized on both sides so both its left and right edges bleed
   past the viewport and are cropped by .work-strips — you never see where a
   bar starts or ends. The actual text/button content lives in a separate
   .strip-content layer sized and inset to the visible viewport, so it stays
   put and aligned with the section heading above even though the background
   box behind it bleeds off both edges. */
.work-strips {
  --bar-bleed: 18vw;
  position: relative;
  z-index: 1;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
  margin-top: var(--space-6);
  margin-bottom: 0;
  /* Extra top clearance so the first bar's 3D tilt (rotateX/rotateY on
     .project-strip) doesn't get clipped by this container's overflow:hidden —
     later bars overlap into that same space, but they have something behind
     them there; the first bar doesn't, so its clipped edge is visible. */
  padding: clamp(72px, 7vw, 110px) 0 clamp(24px, 3vw, 44px);
}
/* Shown only when JavaScript is disabled (script.js never runs to inject the
   real project strips) — a plain, readable list so crawlers and no-JS
   visitors still get project titles, studios, and roles immediately. */
.work-fallback-list {
  list-style: none;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-family: var(--font-body);
  font-size: 1.1rem;
  color: var(--fg);
}
.work-fallback-list strong {
  font-family: var(--font-display);
  color: var(--accent);
}
.project-strip {
  position: relative;
  margin-left: calc(-1 * var(--bar-bleed));
  margin-top: clamp(-60px, -4vw, -32px);
  cursor: pointer;
  text-align: left;
  color: var(--fg);
  background-color: var(--bg);
  background-image:
    var(--strip-overlay, linear-gradient(0deg, transparent, transparent)),
    linear-gradient(160deg, rgba(10,6,18,0.72), rgba(10,6,18,0.32) 55%, rgba(10,6,18,0.64)),
    var(--project-thumb, none),
    var(--project-tint, linear-gradient(135deg, #1a1a1a, var(--bg)));
  background-size: cover, cover, cover, cover;
  background-position: center, center, var(--project-thumb-position, center), center;
  background-repeat: no-repeat;
  border: 1px solid rgba(167,139,250,0.35);
  box-shadow: 0 28px 55px -18px rgba(0,0,0,0.75), 0 10px 22px -10px rgba(0,0,0,0.5);
  transform: translateY(var(--float, 0px)) var(--tilt, perspective(2200px) rotateX(5deg) rotateY(-18deg));
  filter: saturate(1);
  transition: transform 350ms var(--ease), box-shadow 350ms var(--ease), color 350ms var(--ease), background-image 350ms var(--ease), filter 350ms var(--ease), border-color 350ms var(--ease);
}
.project-strip:first-child { margin-top: 0; }
.project-strip::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--sheen, linear-gradient(100deg, rgba(255,255,255,0.1), transparent 40%));
  mix-blend-mode: overlay;
  pointer-events: none;
}
.strip-content {
  position: absolute;
  top: 0;
  left: calc(var(--bar-bleed) + var(--space-4));
  height: 100%;
  width: calc(100vw - var(--space-4));
  z-index: 1;
  display: flex;
  align-items: center;
  padding: 0 clamp(1.5rem, 5vw, 4rem);
}
/* Irregular rectangles: each variant carries its own height as well as its
   own tilt, so the stack reads as uneven panels rather than a uniform grid.
   Widths are all comfortably wider than 100vw so the right edge never shows. */
.project-strip.tilt-1 { --tilt: perspective(2200px) rotateX(5deg) rotateY(-18deg); --sheen: linear-gradient(100deg, rgba(255,255,255,0.14), transparent 42%); --float: -4px; height: clamp(215px, 23vw, 290px); width: 130vw; }
.project-strip.tilt-2 { --tilt: perspective(2200px) rotateX(-4deg) rotateY(20deg); --sheen: linear-gradient(260deg, rgba(255,255,255,0.14), transparent 42%); --float: 5px; height: clamp(185px, 19vw, 240px); width: 134vw; }
.project-strip.tilt-3 { --tilt: perspective(2200px) rotateX(6deg) rotateY(15deg); --sheen: linear-gradient(80deg, rgba(255,255,255,0.1), transparent 46%); --float: -3px; height: clamp(225px, 24vw, 300px); width: 128vw; }
.project-strip.tilt-4 { --tilt: perspective(2200px) rotateX(-5deg) rotateY(-21deg); --sheen: linear-gradient(280deg, rgba(255,255,255,0.1), transparent 46%); --float: 4px; width: 132vw; height: clamp(195px, 20vw, 250px); }
.strip-title {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.25rem, 3.76vw, 2.82rem);
  letter-spacing: -0.02em;
  line-height: 1;
  text-transform: uppercase;
  flex: 1;
  transition: transform 400ms var(--ease);
}
.strip-title-line {
  display: block;
}
.strip-title-line + .strip-title-line {
  margin-top: 0.08em;
}
.strip-lock-icon {
  display: inline-block;
  height: 1.62em;
  width: auto;
  margin-left: 0.35em;
  vertical-align: middle;
  filter: drop-shadow(0 2px 6px rgba(0,0,0,0.6));
}
.strip-details {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  margin: 0 clamp(1rem, 3vw, 3rem);
  flex-shrink: 0;
  opacity: 0;
  transform: translateX(12px);
  transition: opacity 300ms var(--ease), transform 300ms var(--ease);
}
.project-strip:hover .strip-details,
.project-strip:focus-visible .strip-details {
  opacity: 1;
  transform: translateX(0);
}
/* Hierarchy, biggest to smallest: company -> project type -> my role -> contributions */
.strip-company {
  font-family: var(--font-display);
  font-size: clamp(1.43rem, 2.41vw, 1.96rem);
  font-weight: 800;
  letter-spacing: -0.01em;
  color: currentColor;
  white-space: nowrap;
}
.strip-type {
  font-size: 1.28rem;
  font-weight: 600;
  color: currentColor;
  opacity: 0.75;
  white-space: nowrap;
  margin-top: 0.15rem;
}
.strip-role {
  font-size: 1.13rem;
  font-weight: 600;
  color: currentColor;
  opacity: 0.6;
  white-space: nowrap;
  margin-top: 0.41rem;
}
.strip-skills {
  font-size: 1.03rem;
  font-weight: 400;
  color: currentColor;
  opacity: 0.48;
  white-space: normal;
  line-height: 1.01;
  max-width: clamp(160px, 20vw, 280px);
  margin-top: 0.15rem;
}
.project-strip:hover,
.project-strip:focus-visible {
  color: var(--accent-fg);
  z-index: 2;
  background-image:
    linear-gradient(160deg, rgba(167,139,250,0.88), rgba(167,139,250,0.55) 55%, rgba(167,139,250,0.82)),
    var(--project-thumb, none),
    var(--project-tint, linear-gradient(135deg, #1a1a1a, var(--bg)));
  background-position: center, var(--project-thumb-position, center), center;
  transform: translateY(calc(var(--float, 0px) - 10px)) var(--tilt, perspective(2200px) rotateX(5deg) rotateY(-18deg)) scale(1.04);
  border-color: rgba(167,139,250,0.7);
  box-shadow: 0 34px 60px -16px rgba(167,139,250,0.32), 0 14px 28px -10px rgba(0,0,0,0.65);
  filter: saturate(1.1);
}
.project-strip:hover .strip-title,
.project-strip:focus-visible .strip-title {
  transform: translateX(clamp(8px, 1.5vw, 20px));
}
@media (prefers-reduced-motion: reduce) {
  .project-strip { transform: none !important; }
}
@media (max-width: 768px) {
  .strip-details { display: none; }
  .project-strip { margin-top: -40px; }
}

/* ---------- About ---------- */
.about {
  position: relative;
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--space-divider) var(--space-4) var(--space-4);
}
.about-inner { position: relative; z-index: 1; max-width: 900px; }
.about-lead {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 3.2vw, 2.4rem);
  line-height: 1.05;
  letter-spacing: -0.01em;
  margin-top: var(--space-2);
}
.about-body {
  margin-top: var(--space-4);
  font-size: 1.1rem;
  line-height: 1.2;
  color: var(--muted);
  max-width: 720px;
}
/* ---------- Contact ---------- */
.contact {
  position: relative;
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--space-divider) var(--space-4) var(--space-8);
}
.contact-heading { position: relative; z-index: 1; text-align: right; }
.contact-inner { position: relative; z-index: 1; max-width: 720px; }
.contact-email {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  margin-top: var(--space-4);
  text-decoration: none;
  word-break: break-word;
  transform: perspective(900px) rotateY(-14deg);
  transform-origin: right center;
  transition: transform 350ms var(--ease);
}
.contact-email:hover,
.contact-email:focus-visible {
  transform: perspective(900px) rotateY(0deg);
}
@media (prefers-reduced-motion: reduce) {
  .contact-email { transform: none; transition: none; }
}
.contact-email-name {
  position: relative;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.8rem, 5.5vw, 3rem);
  color: var(--accent);
  letter-spacing: -0.01em;
  line-height: 1;
  transition: color 250ms var(--ease);
}
.contact-email:hover .contact-email-name,
.contact-email:focus-visible .contact-email-name {
  color: var(--fg);
}
.contact-email-domain {
  font-family: var(--font-display);
  font-weight: 700;
  /* Scaled down so this line renders the same width as just "patpat" (the
     second half of clarkepatpat) — since both lines are right-aligned,
     matching that width is what makes "@gmail.com" line up under "patpat"
     rather than the full name above it. */
  font-size: clamp(0.744rem, 2.273vw, 1.53rem);
  line-height: 1;
  color: var(--muted);
  letter-spacing: 0.02em;
  transition: color 250ms var(--ease);
}
.contact-email-at {
  display: inline-block;
  font-size: 2em;
  line-height: 1;
  vertical-align: middle;
}
.contact-email:hover .contact-email-domain,
.contact-email:focus-visible .contact-email-domain {
  color: var(--accent);
}

.contact-form {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--border);
}
.contact-form-hint {
  color: var(--muted);
  font-size: 0.9rem;
  margin-bottom: var(--space-3);
}
.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-3);
}
.field { margin-bottom: var(--space-3); display: flex; flex-direction: column; gap: 0.4rem; }
.field label { font-size: 0.85rem; color: var(--muted); }
.field input, .field textarea {
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 0.8rem 1rem;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 1rem;
  resize: vertical;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
/* Each field gets its own slight, hand-placed tilt — like loose cut paper
   scraps rather than a perfectly aligned grid — and straightens up when
   focused. */
#cf-name { transform: rotate(-1.4deg); }
#cf-email { transform: rotate(1.1deg); }
#cf-message { transform: rotate(-0.8deg); }
.field input:focus, .field textarea:focus {
  border-color: var(--accent);
  outline: none;
  transform: rotate(0deg);
}
.field input:invalid[data-touched="true"],
.field textarea:invalid[data-touched="true"] {
  border-color: #ff6b6b;
}

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--border);
}
.footer-inner {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  color: var(--muted);
  font-size: 0.9rem;
  flex-wrap: wrap;
}
.footer-inner a { text-decoration: none; color: var(--muted); transition: color var(--dur) var(--ease); }
.footer-inner a:hover { color: var(--accent); }
.footer-top { margin-left: auto; }

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.lightbox.open { display: flex; }
.lightbox-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(5,5,5,0.9);
  backdrop-filter: blur(6px);
}
/* Non-clipping wrapper around the whole project window — lets the close
   button overhang the thin-lined box's corner while .lightbox-content keeps
   overflow:auto for scrolling long content (a child positioned outside a
   scrollable box gets clipped, so the button has to live outside it). */
.lightbox-frame-outer {
  position: relative;
  /* Explicit calc, not shrink-to-fit: .lightbox is a flex container, so a
     child's inline-block/fit-content sizing gets "blockified" and stretches
     to fill the row instead of hugging .lightbox-content's actual
     footprint. Matches .lightbox-content's own width formula + its
     margin-left below, in viewport units so neither depends on the other's
     computed size (percentages here would be circular). */
  width: calc(min(760px, 66vw) + 10px);
  max-width: 96vw;
}
.lightbox-content {
  position: relative;
  width: min(760px, 66vw);
  /* .lightbox-frame sits at top:-20px/left:-20px (see below). "Overhang" is
     how far the video sticks out PAST this box's own edge, not how deep it
     cuts into the box — so a small 30px overhang means this box's corner
     sits close to the video's corner (margin = frame offset + 30px), and
     most of the video's area ends up sitting over this box's interior.
     The description column gets its own extra top clearance below to drop
     out from under it, since the video only covers part of that column's
     width, not the sidebar's. */
  margin-top: 10px;
  margin-left: 10px;
  max-height: 90vh;
  overflow-y: auto;
  overflow-x: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(220px, 0.9fr);
  align-items: start;
  gap: var(--space-5);
  padding: clamp(1.25rem, 3vw, 2.25rem);
  border: 1px solid rgba(167,139,250,0.35);
  background: var(--bg-elevated);
  scrollbar-width: none;
  -ms-overflow-style: none;
  transform: perspective(1800px) rotateY(18deg);
  transform-origin: center;
}
.lightbox-content::-webkit-scrollbar { display: none; }
/* Solo pieces (e.g. the demo reel) have no related clips — drop the sidebar
   column entirely and let the description breathe at a larger size instead
   of splitting a layout meant for two columns. Wider than the base box to
   comfortably sit under the enlarged .lightbox-frame (see below). */
.lightbox-content--solo {
  width: min(880px, 70vw);
  grid-template-columns: 1fr;
}
.lightbox-content--solo .lightbox-sidebar { display: none; }
/* Matches .lightbox-content--solo's width + the shared 10px margin-left, so
   this non-clipping wrapper is sized to actually fit the wider solo box
   (see the comment on the base .lightbox-frame-outer rule above). */
.lightbox-frame-outer--solo {
  width: calc(min(880px, 70vw) + 10px);
}
.lightbox-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  /* This box's own edge sits just 30px past the video's edge (see the
     overhang math above .lightbox-content), so almost the entire video
     overlaps this column — the description needs substantial extra
     clearance here to drop below the video's bottom edge. The sidebar
     column doesn't need this to clear the video (it doesn't reach that
     column), but gets a comparable push below so both columns start in
     roughly the same place instead of the sidebar floating up top alone. */
  margin-top: 280px;
}
/* The solo demo-reel frame is much taller than the standard 520px-wide one
   (see .lightbox-frame-outer--solo below), so the description needs
   proportionally more clearance to drop below its bottom edge. */
.lightbox-content--solo .lightbox-main {
  margin-top: 420px;
}
/* Positioned to overhang the top-left corner of .lightbox-content (see
   above) — this is why it lives outside that box in the DOM, as a sibling
   inside .lightbox-frame-outer instead of a child of .lightbox-main. */
.lightbox-frame {
  position: absolute;
  top: -20px;
  left: -20px;
  width: min(520px, 60vw);
  z-index: 2;
}
/* Solo pieces (the demo reel) have no sidebar competing for width, so the
   video can run much larger — same -20px top/left hangover as every other
   project window, just a bigger frame hanging off it. */
.lightbox-frame-outer--solo .lightbox-frame {
  width: min(820px, 64vw);
}
.lightbox-panel {
  position: relative;
  width: 100%;
  aspect-ratio: var(--lightbox-aspect, 16 / 9);
  background: var(--bg);
  border-radius: 0;
  overflow: hidden;
  border: 1px solid var(--border-strong);
  transform: perspective(2200px) rotateX(3deg) rotateY(-5deg);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,0.7);
}
@media (prefers-reduced-motion: reduce) {
  .lightbox-panel { transform: none; }
  .lightbox-content { transform: none; }
}
.lightbox-video, .lightbox-video iframe, .lightbox-video video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  background: var(--bg);
}
.lightbox-video video { object-fit: contain; }
.lightbox-title {
  position: absolute;
  top: 0;
  left: clamp(0.25rem, 3vw, 2rem);
  transform: translateY(-56%) perspective(1400px) rotateX(-5deg) rotateY(7deg);
  transform-origin: left bottom;
  z-index: 2;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: clamp(1.6rem, 4.5vw, 3.2rem);
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--fg);
  text-shadow: 0 4px 24px rgba(0,0,0,0.9), 0 1px 3px rgba(0,0,0,0.9);
  pointer-events: none;
}
.lightbox-desc {
  color: var(--fg);
  font-size: 1rem;
  line-height: 1.2;
  max-width: 680px;
  transform: perspective(1600px) rotateX(-2.5deg) rotateY(4deg);
  transform-origin: left center;
}
.lightbox-desc strong { color: var(--accent); }
.lightbox-details {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-2);
  padding-top: var(--space-4);
  padding-bottom: var(--space-2);
  border-top: 1px solid var(--border);
  transform: perspective(1600px) rotateX(-2.5deg) rotateY(4deg);
  transform-origin: left center;
}
@media (prefers-reduced-motion: reduce) {
  .lightbox-title { transform: translateY(-56%); }
  .lightbox-desc,
  .lightbox-details { transform: none; }
}
.lightbox-detail-label {
  display: block;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 0.2rem;
}
.lightbox-detail-value {
  display: block;
  font-size: 0.95rem;
  color: var(--fg);
  line-height: 1.25;
}
.close-x {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.15rem;
  line-height: 1;
}
.lightbox-close {
  position: absolute;
  /* Straddles .lightbox-content's top-right corner — offset by roughly half
     the button's own size so it visibly overlaps the corner rather than
     mostly hanging outside it. Nudged 20px left and 20px down twice from
     that original straddle position. */
  top: 10px;
  right: 20px;
  width: 48px; height: 48px;
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 10px 22px -8px rgba(0,0,0,0.6);
  z-index: 210;
  transform: rotate(10deg);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.lightbox-close:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }

/* ---------- Password gate ---------- */
/* Guards individual locked project bars (see `locked: true` in script.js).
   Same fixed-overlay pattern as the lightbox, sized down to a single
   compact card since it's just a short prompt, not a video player. */
.password-gate {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
}
.password-gate.open { display: flex; }
.password-gate-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(5,5,5,0.9);
  backdrop-filter: blur(6px);
}
.password-gate-content {
  position: relative;
  width: min(440px, 100%);
  background: var(--bg-elevated);
  border: 1px solid rgba(167,139,250,0.35);
  padding: clamp(1rem, 2.2vw, 1.25rem) clamp(1.5rem, 4vw, 2.25rem) clamp(0.7rem, 1.6vw, 0.9rem);
  transform: rotate(-0.8deg);
  box-shadow: 0 40px 70px -20px rgba(0,0,0,0.7);
  text-align: center;
}
@keyframes password-gate-pop {
  0% { transform: rotate(-0.8deg) scale(0.94); opacity: 0; }
  70% { transform: rotate(-0.8deg) scale(1.015); opacity: 1; }
  100% { transform: rotate(-0.8deg) scale(1); opacity: 1; }
}
.password-gate.open .password-gate-content {
  animation: password-gate-pop 260ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .password-gate.open .password-gate-content { animation: none; }
}
@keyframes password-gate-shake {
  0%, 100% { transform: rotate(-0.8deg) translateX(0); }
  20% { transform: rotate(-0.8deg) translateX(-10px); }
  40% { transform: rotate(-0.8deg) translateX(8px); }
  60% { transform: rotate(-0.8deg) translateX(-6px); }
  80% { transform: rotate(-0.8deg) translateX(4px); }
}
.password-gate.shake .password-gate-content {
  animation: password-gate-shake 420ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .password-gate-content { transform: none; }
  .password-gate.shake .password-gate-content { animation: none; }
}
.password-gate-close {
  position: absolute;
  top: -18px;
  right: -18px;
  z-index: 2;
  width: 48px; height: 48px;
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 10px 22px -8px rgba(0,0,0,0.6);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.password-gate-close:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.password-gate-message {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(0.85rem, 1.5vw, 0.95rem);
  line-height: 1.3;
  color: var(--muted);
  text-align: left;
}
.password-gate-shout {
  position: relative;
  z-index: 1;
  top: -1.8rem;
  left: -1.8rem;
  display: block;
  text-align: left;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(3rem, 7.2vw, 3.9rem);
  line-height: 0.82;
  color: var(--accent);
  margin-bottom: -1.1rem;
  text-shadow: 0 4px 18px rgba(0,0,0,0.8);
}
.password-gate-form {
  margin-top: 0.7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
.password-gate-form input {
  width: 100%;
}
.password-gate-form input {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 0;
  padding: 0.8rem 1rem;
  color: var(--fg);
  font-family: var(--font-body);
  font-size: 1rem;
  transition: border-color var(--dur) var(--ease);
}
.password-gate-form input:focus {
  border-color: var(--accent);
  outline: none;
}
.password-gate-error {
  font-size: 0.85rem;
  color: #ff6b6b;
  margin: 0;
}
.password-gate-form .btn {
  position: relative;
  z-index: 1;
  margin-top: var(--space-2);
  margin-bottom: -2.5rem;
  box-shadow: 0 14px 26px -10px rgba(0,0,0,0.6);
}
/* The lock/unlock artwork is already a complete purple icon on a transparent
   background — a purple button background behind it would make the icon
   disappear, so this strips the standard .btn-primary chrome down to just
   the icon itself. */
.password-unlock-btn {
  position: relative;
  width: 84px;
  height: 84px;
  padding: 0;
  background: transparent;
  border: none;
  box-shadow: none;
}
.password-unlock-btn:hover { background: transparent; transform: translateY(-2px); }
.unlock-icon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 10px 16px rgba(0,0,0,0.5));
}
.unlock-icon-unlocked { display: none; }
.password-unlock-btn.unlocked .unlock-icon-locked { display: none; }
.password-unlock-btn.unlocked .unlock-icon-unlocked { display: block; }
@keyframes unlock-icon-pop {
  0% { transform: scale(0.6) rotate(-10deg); opacity: 0; }
  60% { transform: scale(1.3) rotate(5deg); opacity: 1; }
  100% { transform: scale(1) rotate(0deg); opacity: 1; }
}
.password-unlock-btn.unlocked .unlock-icon-unlocked {
  animation: unlock-icon-pop 420ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .password-unlock-btn.unlocked .unlock-icon-unlocked { animation: none; }
}

/* Placeholder sidebar content — swap for real related clips/credits later */
.lightbox-sidebar {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  /* Flush with .lightbox-main's description top — matches its margin-top
     exactly, with no extra padding-top of its own (that would push this
     column's heading below the description's own top edge instead of
     level with it). */
  margin-top: 280px;
  min-width: 0;
}
.lightbox-sidebar-section {
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--border);
}
.lightbox-sidebar-section:last-child { border-bottom: none; padding-bottom: 0; }
.lightbox-related {
  position: relative;
  margin-top: var(--space-3);
}
/* Only applied when there are 5+ clips (see script.js) — with 4 or fewer,
   the list just sits at its natural height with no cap, fade, border, or
   scrollbar at all. */
.lightbox-related--scrollable {
  /* Bounded height with its own scroll — this wrapper (not just the list)
     is the scroll container so the sliding highlight (a sibling of the
     list, both children of this element) scrolls in lockstep with the
     buttons instead of staying put while they move underneath it. Shorter
     than before so this column doesn't force the whole box taller than
     the description/role/contributions column, leaving dead space under
     it — a visible scrollbar (below) does the "more to scroll" signaling
     instead of a tall list. */
  max-height: 230px;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 1.75rem;
  /* Thin lines marking the scroll boundary — a visual cue that items are
     passing behind an edge. No fade here: a cut-off item is clipped clean,
     not softened into transparency. */
  border-top: 1px solid rgba(167,139,250,0.5);
  border-bottom: 1px solid rgba(167,139,250,0.5);
  /* Visible, rectangular purple scrollbar instead of a hidden one — a
     clearer cue that this list scrolls independently from the rest of the
     window. Extra-wide to be easy to grab, and square-edged (no
     border-radius) to match the site's sharp-cornered "paper cutout"
     style rather than the OS's default pill-shaped thumb. */
  scrollbar-width: auto;
  scrollbar-color: rgba(167,139,250,0.7) transparent;
}
.lightbox-related--scrollable::-webkit-scrollbar { width: 24px; }
.lightbox-related--scrollable::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 0;
}
.lightbox-related--scrollable::-webkit-scrollbar-thumb {
  background: rgba(167,139,250,0.7);
  border-radius: 0;
  border: none;
  box-shadow: none;
}
.lightbox-related--scrollable::-webkit-scrollbar-thumb:hover { background: rgba(167,139,250,0.9); }
/* Sliding purple indicator behind whichever related item is currently
   playing — repositioned via JS (see positionRelatedHighlight in script.js)
   whenever the main video changes, so it glides to the new selection
   instead of jumping. */
.lightbox-related-highlight {
  position: absolute;
  top: 0;
  left: -0.35rem;
  right: -0.35rem;
  height: 0;
  border-radius: 0;
  background: rgba(167,139,250,0.22);
  border: 1px solid rgba(167,139,250,0.5);
  opacity: 0;
  pointer-events: none;
  z-index: 0;
  transition: transform 350ms var(--ease), height 350ms var(--ease), opacity 200ms var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .lightbox-related-highlight { transition: opacity 200ms var(--ease); }
}
.lightbox-related-list {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.lightbox-related-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  background: none;
  border: none;
  padding: 0.35rem;
  margin: -0.35rem;
  border-radius: 8px;
  text-align: left;
  cursor: pointer;
  transition: background 200ms var(--ease);
}
.lightbox-related-item:hover:not(:disabled) { background: rgba(255,255,255,0.06); }
.lightbox-related-item:disabled { cursor: default; opacity: 0.55; }
.lightbox-related-item.is-playing .lightbox-related-title { color: var(--accent); }
.lightbox-related-thumb {
  width: 64px;
  height: 40px;
  border-radius: 6px;
  flex-shrink: 0;
}
.lightbox-related-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.lightbox-related-title {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lightbox-related-meta {
  font-size: 0.72rem;
  color: var(--muted);
}
@media (max-width: 800px) {
  /* .lightbox itself has no scroll and vertically centers its child — when
     the stacked video+box (taller than most phone screens once the video
     is back in normal flow above the box) overflows, centering pushes the
     video off the TOP of the viewport with no way to scroll up to it. Let
     the whole overlay scroll instead, starting from the top so the video
     is visible immediately. */
  .lightbox {
    align-items: flex-start;
    overflow-y: auto;
    padding-top: var(--space-4);
    padding-bottom: var(--space-4);
  }
  .lightbox-content { grid-template-columns: 1fr; }
  /* The video-overhangs-the-corner treatment relies on fixed pixel offsets
     that only make sense once there's enough spare width beside the box —
     on narrow screens it just pushes the box off-screen, so fall back to a
     simple stacked layout instead: video in normal flow above a flat,
     untilted box, nothing needing extra clearance from an overhang that no
     longer exists. */
  .lightbox-frame-outer { width: min(94vw, 600px); max-width: 94vw; }
  .lightbox-frame {
    position: static;
    width: 100%;
    margin-bottom: var(--space-3);
  }
  .lightbox-content {
    width: 100%;
    margin-top: 0;
    margin-left: 0;
    transform: none;
  }
  .lightbox-main { margin-top: 0; }
  .lightbox-sidebar { margin-top: 0; padding-top: var(--space-4); }
  .lightbox-close { top: -14px; right: -14px; }
}

/* ---------- Scroll reveal ---------- */
/* A whisper of perspective on entrance — elements tilt up into place rather
   than just fading, carrying the site's depth language through every scroll. */
.reveal {
  opacity: 0;
  transform: perspective(800px) rotateX(7deg) translateY(24px);
  transform-origin: center bottom;
  transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}
.reveal.in-view {
  opacity: 1;
  transform: perspective(800px) rotateX(0deg) translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Responsive ---------- */
@media (max-width: 1024px) {
  .credibility-inner { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .credibility-stat { border-right: none; padding-right: 0; flex-direction: row; align-items: baseline; gap: 0.6rem; }
  /* In column direction, align-items:flex-start stops the marquee being
     stretched to the container width, so it shrinks-to-fit its un-wrapped
     scrolling track instead — ballooning far past the viewport and causing
     horizontal scroll. Force it back to full width explicitly. */
  .marquee { width: 100%; min-width: 0; }
}

@media (max-width: 768px) {
  .main-nav { display: none; }
  .header-actions .btn { display: none; }
  .menu-toggle { display: flex; }
  .hero-content { padding-bottom: var(--space-5); }
  .form-row { grid-template-columns: 1fr; }
  .work, .about, .contact { padding-left: var(--space-3); padding-right: var(--space-3); }
  .header-inner { padding: 0 var(--space-3); }
}

@media (max-width: 375px) {
  .hero-title { font-size: clamp(2.6rem, 15vw, 4rem); }
  .btn { padding: 0.8rem 1.3rem; font-size: 0.9rem; }
}

@media (min-width: 1440px) {
  :root { --container: 1440px; }
}
