/* =========================================================
   MOTION BY VINNY — design tokens
   Techy sans display (Space Grotesk) + clean body (Inter)
   + a mono utility face (JetBrains Mono) for labels/eyebrows.
   Palette: a "brand guidelines" system in the vein of the
   Danelec reference — a near-black, warm-neutral base (not a
   saturated maroon — that read as too brown), a vivid orange-
   red accent that fades to warm gray in large gradients (never
   in small UI, which stays solid), and a cream neutral. Real
   frosted-glass panels — backdrop-blur that actually distorts
   what's behind it — plus grain texture, carried over from the
   last pass since only the color direction is in question here.
   Light is the default theme; dark is an explicit opt-in via
   the toggle (see [data-theme="dark"] below and js/script.js).
   Colors not settled yet — treat as a trial, not final.
   ========================================================= */

:root {
  --bg: #D9E4F1;
  --bg-2: #FFFFFF;
  --ink: #10233F;
  --ink-soft: #3E5573;
  --ink-faint: #7A8DA6;

  --violet: #C9531F;
  --violet-2: #F7A47F;
  --cyan: #A9BDD6;
  --coral: #3E5573;

  /* "Mars Navy" is now the primary accent — used everywhere
     --brand-fill is (buttons, nav-active, badges, the ambient
     glow's main blob, pricing dollar amounts, etc.). Orange
     (--violet) steps back to a secondary highlight: category tags
     and the pricing discount callout, the two spots that benefit
     from a warm accent standing apart from all the navy around it.
     --navy is per-theme (not one fixed hex) because the same value
     can't work as both a dark-on-light text/icon color and a
     light-on-dark one — light theme anchors on the deep navy,
     dark theme lightens it a few steps so it still reads clearly
     against a near-black card. */
  --navy: #1B3C69;
  --navy-2: #5E88B8;
  --navy-fill: linear-gradient(135deg, var(--navy) 0%, var(--navy-2) 100%);
  --brand-fill: var(--navy-fill);
  --on-brand: #F4F8FD;

  --line: rgba(16, 35, 63, 0.14);

  --glass-bg: rgba(255, 255, 255, 0.34);
  --glass-bg-strong: rgba(255, 255, 255, 0.62);
  --glass-border: rgba(255, 255, 255, 0.7);
  --glass-shadow: 0 12px 48px rgba(40, 70, 120, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  --glass-blur: blur(30px) saturate(170%);
  --btn-glow: rgba(27, 60, 105, 0.3);

  /* Small generic chrome tokens (hover pills, inputs, hairlines) —
     kept separate from the --glass-* set above because these need
     different (much subtler) values in dark mode than the glass
     panels do. */
  --surface-hover: rgba(255, 255, 255, 0.55);
  --surface-input: rgba(255, 255, 255, 0.7);
  --input-border: rgba(16, 35, 63, 0.14);
  --pill-bg: rgba(255, 255, 255, 0.45);
  --marquee-bg: rgba(255, 255, 255, 0.28);
  --hairline: rgba(16, 35, 63, 0.1);
  --hero-overlay-bg: rgba(255, 255, 255, 0.3);

  --radius-lg: 22px;
  --radius-md: 14px;
  --radius-sm: 9px;

  --nav-h: 84px;
  --container: 1180px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* =========================================================
   Dark theme — an explicit opt-in via the .theme-toggle
   button (see js/script.js), not something the OS setting
   turns on automatically. The default experience is light.
   ========================================================= */
:root[data-theme="dark"] {
  --bg: #0A1524;
  --bg-2: #16263B;
  --ink: #EAF1FA;
  --ink-soft: #B4C5DA;
  --ink-faint: #7D92AC;

  --violet: #FF8A5C;
  --violet-2: #FFB08C;
  --cyan: #8FB2DA;
  --coral: #7D92AC;

  /* Lightened a few steps from the light theme's --navy so it still
     reads clearly against a near-black card. */
  --navy: #8FB5E0;
  --navy-2: #D2E3F5;
  --navy-fill: linear-gradient(135deg, var(--navy) 0%, var(--navy-2) 100%);
  --brand-fill: var(--navy-fill);
  /* Dark text here, not light — this fill runs light-to-lighter in
     dark mode, the opposite of the light theme's dark-to-medium
     fill, so it needs the opposite foreground too. */
  --on-brand: #0E2038;

  --line: rgba(255, 255, 255, 0.14);

  --glass-bg: rgba(255, 255, 255, 0.07);
  --glass-bg-strong: rgba(22, 38, 59, 0.7);
  --glass-border: rgba(255, 255, 255, 0.16);
  --glass-shadow: 0 12px 48px rgba(0, 0, 0, 0.4), inset 0 1px 0 rgba(255, 255, 255, 0.14);
  --glass-blur: blur(30px) saturate(150%);
  --btn-glow: rgba(143, 181, 224, 0.34);

  --surface-hover: rgba(255, 255, 255, 0.1);
  --surface-input: rgba(255, 255, 255, 0.08);
  --input-border: rgba(255, 255, 255, 0.18);
  --pill-bg: rgba(255, 255, 255, 0.1);
  --marquee-bg: rgba(255, 255, 255, 0.07);
  --hairline: rgba(255, 255, 255, 0.12);
  --hero-overlay-bg: rgba(8, 16, 30, 0.5);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 16px); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  transition: background .25s var(--ease), color .25s var(--ease);
}

h1, h2, h3, h4 {
  font-family: 'Space Grotesk', 'Inter', sans-serif;
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.02em;
  margin: 0 0 0.5em;
  color: var(--ink);
}

p { margin: 0 0 1em; color: var(--ink-soft); }

a { color: inherit; text-decoration: none; }

img, video { max-width: 100%; display: block; }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 28px;
}

.eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
}
.eyebrow::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--brand-fill);
  box-shadow: 0 0 0 4px rgba(18,50,85, 0.15);
}

/* =========================================================
   Ambient background — blurred, drifting glow blobs behind
   everything, so the glass panels above have real color and light
   to bend as they blur it. Brought back on purpose for this pass:
   the point of real backdrop-blur glass is that it's blurring
   *something* — a flat single-color background makes a frosted
   panel pointless.
   ========================================================= */

.mesh {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}
.mesh span {
  position: absolute;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.2;
  will-change: transform;
  transform: translateZ(0);
}
.mesh .b1 {
  width: 620px; height: 620px;
  top: -200px; left: -160px;
  background: radial-gradient(circle at 35% 35%, var(--navy), transparent 70%);
  animation: drift1 26s ease-in-out infinite;
}
.mesh .b2 {
  width: 560px; height: 560px;
  top: 5%; right: -200px;
  background: radial-gradient(circle at 60% 40%, var(--cyan), transparent 70%);
  opacity: 0.16;
  animation: drift2 32s ease-in-out infinite;
}
.mesh .b3 {
  width: 520px; height: 520px;
  bottom: -220px; left: 25%;
  background: radial-gradient(circle at 50% 50%, var(--navy-2), transparent 70%);
  opacity: 0.13;
  animation: drift3 30s ease-in-out infinite;
}
@keyframes drift1 {
  0%, 100% { transform: translate(0,0) scale(1); }
  50% { transform: translate(60px, 40px) scale(1.08); }
}
@keyframes drift2 {
  0%, 100% { transform: translate(0,0) scale(1); }
  50% { transform: translate(-50px, 60px) scale(0.94); }
}
@keyframes drift3 {
  0%, 100% { transform: translate(0,0) scale(1); }
  50% { transform: translate(40px, -50px) scale(1.1); }
}
@media (prefers-reduced-motion: reduce) {
  .mesh span { animation: none !important; }
}

/* Film grain — a tiled SVG noise texture over the glow, matching
   the grainy-photo texture in the reference: mix-blend-mode:overlay
   reads as texture on both the base and the glow blobs instead of
   a flat gray haze. */
.grain {
  position: fixed;
  inset: -60px;
  z-index: -1;
  pointer-events: none;
  opacity: 0.5;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  animation: grain-drift 9s steps(8) infinite;
}
@keyframes grain-drift {
  0%   { transform: translate(0, 0); }
  12%  { transform: translate(-3%, 2%); }
  25%  { transform: translate(2%, -4%); }
  37%  { transform: translate(-4%, -2%); }
  50%  { transform: translate(3%, 3%); }
  62%  { transform: translate(-2%, 4%); }
  75%  { transform: translate(4%, -1%); }
  87%  { transform: translate(-1%, -3%); }
  100% { transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .grain { animation: none; }
}

/* =========================================================
   Glass primitive — real frosted glass: a translucent fill over
   backdrop-blur so whatever sits behind a panel (the ambient glow,
   a photo, another panel) actually distorts through it, the way
   real glass would, instead of a flat opaque card pretending to
   be glass.
   ========================================================= */

.glass {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--glass-shadow);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

/* =========================================================
   Nav
   ========================================================= */

.nav {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  /* Equal padding above and below the glass pill — rather than a
     fixed-height flex-centered band plus a separate margin before
     the hero section — is what actually keeps the nav centered
     between the top of the page and the top of the section below
     it, at any pill height. */
  padding: 24px 0;
}
.nav-inner {
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 20px;
}
.nav-glass {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  border-radius: var(--radius-lg);
}
.brand {
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--navy);
}
.nav-links {
  display: flex;
  align-items: center;
  gap: 6px;
}
.nav-links a {
  position: relative;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-soft);
  padding: 9px 16px;
  border-radius: 999px;
  /* Transparent by default, colored only on .active — a same-width
     border on every link (rather than adding one only when active)
     keeps every pill the same height, so the active state doesn't
     grow taller than its neighbors and throw off the bar's vertical
     centering. */
  border: 2px solid transparent;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.nav-links a:hover {
  color: var(--ink);
  background: var(--surface-hover);
}
.nav-links a.active {
  color: var(--on-brand);
  font-weight: 600;
  background: var(--brand-fill);
  border-color: transparent;
  box-shadow: 0 4px 16px var(--btn-glow);
}
.nav-links a.active:hover { background: var(--brand-fill); }
.nav-cta {
  font-weight: 700;
  color: var(--navy) !important;
}
.nav-cta:hover { background: rgba(18,50,85,0.1); }
.nav-cta.active { color: var(--on-brand) !important; }

.nav-right {
  display: flex;
  align-items: center;
  gap: 8px;
}
.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  flex-shrink: 0;
  border-radius: 999px;
  border: none;
  background: var(--surface-hover);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease);
}
.theme-toggle:hover { color: var(--ink); }
.theme-toggle svg { width: 18px; height: 18px; }
.theme-toggle .icon-moon { display: none; }
.theme-toggle.is-dark .icon-sun { display: none; }
.theme-toggle.is-dark .icon-moon { display: block; }

.nav-toggle {
  display: none;
  width: 40px; height: 40px;
  border-radius: 999px;
  border: none;
  background: var(--surface-hover);
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.nav-toggle svg { width: 18px; height: 18px; }

/* =========================================================
   Buttons
   ========================================================= */

/* A soft glow instead of a hard offset shadow — meant to read as
   light coming through the gradient/glass, not a cast shadow. Lifts
   slightly and brightens on hover rather than pressing flat. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: 'Inter', sans-serif;
  font-size: 15px;
  font-weight: 600;
  padding: 14px 26px;
  border-radius: 999px;
  cursor: pointer;
  border: 1px solid var(--glass-border);
  box-shadow: 0 8px 26px var(--btn-glow);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease), background .2s var(--ease);
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 12px 34px var(--btn-glow); }
.btn:active { transform: translateY(0); box-shadow: 0 6px 18px var(--btn-glow); }
.btn-primary {
  color: var(--on-brand);
  background: var(--brand-fill);
  border-color: transparent;
}
.btn-ghost {
  color: var(--ink);
  background: var(--glass-bg-strong);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

/* =========================================================
   Hero (simple, page-header version — About / Contact)
   ========================================================= */

.hero {
  padding: 64px 0 40px;
}
.hero h1 {
  font-size: clamp(38px, 5vw, 60px);
  margin-bottom: 20px;
}
/* Unscoped (not just .hero h1 .grad) so it also reaches the
   homepage's "alive" in .hero-overlay h1, which uses a different
   parent wrapper than the About/Contact .hero pattern. The one
   display-serif italic moment on the site — a single word breaking
   out of the grotesk/mono system for a bit of flourish. */
.grad {
  font-family: 'Newsreader', 'Space Grotesk', serif;
  font-style: italic;
  font-weight: 500;
  background: var(--brand-fill);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.hero p.lead {
  font-size: 18px;
  max-width: 480px;
  margin-bottom: 30px;
}

/* About page: intro text on the left, portrait filling the empty
   space on the right. Sized off the viewport (clamped) so it never
   dwarfs the text or shrinks to a thumbnail; drop-shadow (not
   box-shadow) so it follows the image's own round alpha edge. */
.about-hero {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 56px;
}
.about-portrait {
  width: clamp(240px, 27vw, 340px);
  height: auto;
  border-radius: 50%;
  justify-self: end;
  filter: drop-shadow(0 18px 36px rgba(0, 0, 0, 0.3));
}
@media (max-width: 720px) {
  .about-hero { grid-template-columns: 1fr; gap: 28px; }
  .about-portrait { order: -1; width: 200px; justify-self: start; }
}
.hero-actions {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}
.hero-note {
  margin-top: 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}

/* =========================================================
   Hero reel (Home) — full-bleed autoplay video with a glass
   panel over it that "melts" away as you scroll, revealing
   the video, then the work grid right underneath.
   ========================================================= */

.hero-reel {
  position: relative;
  height: 58vh;
  min-height: 420px;
  overflow: hidden;
}
.hero-bg-video,
.hero-bg-placeholder {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* No video dropped in yet — a quiet grid on a flat indigo tint
   stands in for the reel instead of an obvious "empty slot". */
.hero-bg-placeholder {
  background-color: rgba(18,50,85,0.10);
  background-image:
    repeating-linear-gradient(0deg, var(--hairline) 0 1px, transparent 1px 48px),
    repeating-linear-gradient(90deg, var(--hairline) 0 1px, transparent 1px 48px);
}
.hero-reel.has-video .hero-bg-placeholder { display: none; }
.hero-reel:not(.has-video) .hero-bg-video { display: none; }

.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 24px;
  background: var(--hero-overlay-bg);
  border-bottom: 1px solid var(--glass-border);
  will-change: opacity;
}
.hero-overlay h1 {
  font-size: clamp(34px, 5.2vw, 58px);
  max-width: 780px;
  margin-bottom: 16px;
}
.hero-overlay p {
  max-width: 480px;
  font-size: 17px;
  margin-bottom: 26px;
}
.scroll-cue {
  position: absolute;
  bottom: 26px;
  left: 50%;
  transform: translateX(-50%);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.scroll-cue::after {
  content: "";
  width: 1px;
  height: 26px;
  background: var(--navy);
  animation: scrollcue 1.8s ease-in-out infinite;
}
@keyframes scrollcue {
  0% { transform: scaleY(0.3); opacity: 0.3; }
  50% { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(0.3); opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .scroll-cue::after { animation: none; }
}

/* Reel frame — the placeholder-to-final-video slot */
.reel-frame {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg);
  overflow: hidden;
  padding: 10px;
}
.reel-frame video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-lg) - 10px);
  display: none;
}
.reel-frame.has-video video { display: block; }
.reel-frame.has-video .reel-placeholder { display: none; }
/* A static thumbnail (e.g. a Vimeo-hosted still) for a card whose
   only footage lives on Vimeo, rather than a local looping file. */
.reel-frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: calc(var(--radius-lg) - 10px);
  display: block;
}
/* For a card whose only footage lives on Vimeo (no local export to
   loop): Vimeo's own "background" player mode autoplays muted and
   loops silently, same as the local <video> cards do. pointer-events
   is off so a click still reaches the card's role="button" handler
   instead of landing on the embedded player. */
.reel-frame iframe {
  position: absolute;
  inset: 10px;
  width: calc(100% - 20px);
  height: calc(100% - 20px);
  border: 0;
  border-radius: calc(var(--radius-lg) - 10px);
  pointer-events: none;
}
.work-card .reel-frame iframe { inset: 0; width: 100%; height: 100%; border-radius: var(--radius-md); }
.reel-placeholder {
  position: absolute;
  inset: 10px;
  border-radius: calc(var(--radius-lg) - 10px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  background-color: rgba(232,69,27,0.18);
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.5) 0 2px, transparent 2px 14px);
  text-align: center;
}
.reel-placeholder-icon {
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--brand-fill);
  color: var(--on-brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  box-shadow: 0 8px 24px rgba(232,69,27,0.35);
}
.reel-placeholder-text {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
  padding: 0 20px;
}

/* =========================================================
   Sections
   ========================================================= */

.section { padding: 90px 0; }
.section-head {
  max-width: 640px;
  margin-bottom: 52px;
}
.section-head h2 { font-size: clamp(28px, 3.4vw, 40px); }
.section-head p { font-size: 16.5px; }

/* Process — a 4-up timeline: icon, day range, title, description */
.steps-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 20px;
}
.step-card { padding: 26px 24px; }
.step-icon {
  width: 48px; height: 48px;
  border-radius: var(--radius-sm);
  background: var(--brand-fill);
  box-shadow: 0 8px 22px var(--btn-glow);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-brand);
  margin-bottom: 18px;
}
.step-icon svg { width: 22px; height: 22px; }
.step-day {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  letter-spacing: 0.06em;
  color: var(--navy);
  margin-bottom: 6px;
}
.step-card h3 { font-size: 19px; margin-bottom: 8px; }
.step-card p { font-size: 14.5px; margin-bottom: 0; }

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

/* Marquee — a small looping strip of motion, cheap on performance
   since it only animates transform (GPU-composited, no layout/paint
   cost), unlike blur or backdrop-filter. */
.marquee {
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  overflow: hidden;
  padding: 16px 0;
  background: var(--marquee-bg);
}
.marquee-track {
  display: flex;
  width: max-content;
  animation: marquee 24s linear infinite;
  will-change: transform;
}
/* Two identical sets, each carrying its own trailing 48px spacer.
   That spacer is what makes the loop mathematically seamless: a
   flex `gap` only sits *between* items, so 10 items duplicated in
   one row only get 9 gaps — one short of the 10 needed to tile
   perfectly — which is what caused the visible snap on every loop.
   Giving each set its own trailing spacer restores that missing
   gap, and script.js measures the exact pixel distance between the
   two sets so the animation shifts by that precise amount instead
   of an assumed (and therefore slightly wrong) 50%. */
.marquee-set {
  display: flex;
  align-items: center;
  gap: 48px;
  padding-right: 48px;
  flex-shrink: 0;
}
.marquee-item {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 12px;
  white-space: nowrap;
}
.marquee-item::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--brand-fill);
  flex-shrink: 0;
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(var(--marquee-shift, -50%)); }
}
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
}

/* Work grid — flex + centered wrap so a 5-item set stays symmetrical
   (a 3-2 grid would otherwise strand the last row to one side). */
.work-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 22px;
}
.work-grid .work-card {
  flex: 0 1 calc((100% - 22px * 2) / 3);
}
@media (max-width: 1020px) {
  .work-grid .work-card { flex-basis: calc((100% - 22px) / 2); }
}
@media (max-width: 640px) {
  .work-grid .work-card { flex-basis: 100%; }
}
.work-card {
  padding: 12px;
  overflow: hidden;
  cursor: pointer;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.work-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.12);
}
.work-card:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 3px;
}
.work-card .reel-frame { aspect-ratio: 16/10; padding: 0; border-radius: var(--radius-md); }
.work-card .reel-frame video,
.work-card .reel-frame img,
.work-card .reel-frame .reel-placeholder { border-radius: var(--radius-md); }
.work-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 8px 6px;
}
.work-meta h4 { font-size: 16.5px; margin-bottom: 2px; }
.work-meta .tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--violet);
  background: rgba(232,69,27,0.1);
  padding: 5px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

/* =========================================================
   Case study dialogs — native <dialog>, one per card. Gives us a
   built-in backdrop, Escape-to-close and focus handling for free;
   js/script.js only wires up opening/closing it and the Vimeo embed.
   This panel is intentionally a fixed dark "cinema mode" card (like
   a lightbox) rather than following the site's light/dark toggle —
   a light video stage on top, a dark write-up below, regardless of
   which theme the rest of the page is in.
   ========================================================= */
.work-dialog {
  border: none;
  padding: 0;
  background: transparent;
  max-width: 720px;
  width: calc(100% - 40px);
  border-radius: 24px;
  color: var(--ink);
}
.work-dialog::backdrop {
  background: rgba(8, 8, 12, 0.6);
  backdrop-filter: blur(6px);
}
.work-dialog[open] .work-dialog-inner {
  animation: work-dialog-in .25s var(--ease);
}
@keyframes work-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
.work-dialog-inner {
  position: relative;
  background: #17171F;
  border-radius: 24px;
  overflow-x: hidden;
  overflow-y: auto;
  max-height: 85vh;
}

/* Video stage — light, fixed, textured with a faint grid so an empty
   (no Vimeo id yet) state doesn't read as a broken box. */
.case-dialog-media {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #F2F1ED;
  background-image:
    repeating-linear-gradient(0deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 28px),
    repeating-linear-gradient(90deg, rgba(0,0,0,0.05) 0 1px, transparent 1px 28px);
}
.case-dialog-video { position: absolute; inset: 0; }
.case-dialog-iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: none; }
.case-dialog-video.has-video .case-dialog-iframe { display: block; }
.case-dialog-video.has-video .case-dialog-video-placeholder { display: none; }
.case-dialog-video-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  color: rgba(0,0,0,0.4);
}

.case-dialog-body { padding: 30px 32px 26px; }
.case-dialog-meta { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; }
/* Fully defined here rather than relying on .work-meta .tag — that
   rule doesn't reach this element (different parent), so without
   this the pill fell back to the page's default near-black text
   color, which is nearly invisible on this panel's fixed dark
   background. Colors are hardcoded (not a var) so this panel's
   accent stays fixed even if the token values are retuned later —
   it's always dark regardless of the site's light/dark toggle. */
.case-dialog-meta .tag {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: #FF4B1F;
  background: rgba(255, 75, 31, 0.16);
  padding: 5px 10px;
  border-radius: 999px;
  white-space: nowrap;
}
.case-dialog-format { font-size: 13px; color: #8a8a94; }
.case-dialog-body h3 { color: #fff; font-size: 26px; margin: 0 0 14px; }
.case-dialog-desc { color: #b0b0ba; font-size: 15.5px; line-height: 1.6; margin: 0 0 26px; }
.case-dialog-label { display: block; color: #fff; font-weight: 600; font-size: 14px; margin-bottom: 12px; }
.case-dialog-deliverables { margin-bottom: 28px; }
.case-dialog-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.case-pill {
  font-size: 13px;
  color: #c8c8ce;
  background: rgba(255,255,255,0.06);
  border: 1px solid rgba(255,255,255,0.12);
  padding: 7px 14px;
  border-radius: 999px;
}
.case-dialog-quote {
  background: rgba(232,69,27,0.1);
  border-left: 3px solid var(--violet);
  border-radius: 0 12px 12px 0;
  padding: 20px 24px;
  margin-bottom: 28px;
}
.case-dialog-quote-text { font-style: italic; color: #fff; font-size: 15.5px; line-height: 1.55; margin: 0 0 14px; }
.case-dialog-quote-footer { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.case-dialog-quote-attr { color: #9a9aa2; font-size: 13.5px; }
.case-dialog-quote-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #fff;
  color: #111;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: 999px;
  transition: transform .2s var(--ease);
}
.case-dialog-quote-link:hover { transform: translateY(-1px); }
.case-dialog-quote-link svg { width: 13px; height: 13px; }
.case-dialog-footer {
  border-top: 1px solid rgba(255,255,255,0.08);
  padding-top: 18px;
  display: flex;
  justify-content: flex-end;
}
.case-dialog-close {
  background: none;
  border: none;
  color: #9a9aa2;
  font-size: 14px;
  cursor: pointer;
  padding: 4px;
  transition: color .2s var(--ease);
}
.case-dialog-close:hover { color: #fff; }

.filters {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 36px;
}
.filter-btn {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  letter-spacing: 0.04em;
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--glass-border);
  background: var(--glass-bg);
  cursor: pointer;
  color: var(--ink-soft);
  transition: all .2s var(--ease);
}
.filter-btn:hover { color: var(--ink); }
.filter-btn.active {
  background: var(--brand-fill);
  color: var(--on-brand);
  border-color: transparent;
}

/* About */
.about-grid {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: 56px;
  align-items: start;
}
.about-photo {
  aspect-ratio: 4/5;
  padding: 10px;
}
.about-photo-inner {
  width: 100%; height: 100%;
  border-radius: calc(var(--radius-lg) - 10px);
  background-color: rgba(232,69,27,0.22);
  background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.5) 0 2px, transparent 2px 14px);
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px;
  color: var(--ink-soft);
  padding: 20px;
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 22px 0 8px;
}
.chip {
  font-size: 13.5px;
  font-weight: 500;
  padding: 8px 15px;
  border-radius: 999px;
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
}

/* Stat / fact row */
.fact-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  margin-top: 36px;
}
.fact-card { padding: 22px 20px; }
.fact-card .num {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 26px;
  font-weight: 700;
  background: var(--brand-fill);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  display: block;
  margin-bottom: 4px;
}
.fact-card .label {
  font-size: 13.5px;
  color: var(--ink-soft);
}

/* CTA band */
.cta-band {
  padding: 60px 48px;
  text-align: center;
  position: relative;
  overflow: hidden;
}
.cta-band h2 { font-size: clamp(26px, 3.4vw, 36px); }
.cta-band p { max-width: 480px; margin: 0 auto 28px; }
.cta-actions { display: flex; justify-content: center; gap: 14px; flex-wrap: wrap; }

/* Contact — a single focal point (the email address) rather than a
   form: click it to copy, or use the mailto fallback below it. */
.contact-wrap {
  max-width: 560px;
  margin: 0 auto;
  padding: 52px 44px;
  text-align: center;
}
.email-copy-label {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 18px;
}
.email-copy {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  max-width: 100%;
  font-family: 'JetBrains Mono', monospace;
  font-size: clamp(15px, 2.6vw, 21px);
  font-weight: 500;
  color: var(--ink);
  background: var(--glass-bg-strong);
  border: 1px solid var(--glass-border);
  border-radius: 999px;
  padding: 16px 16px 16px 26px;
  cursor: pointer;
  transition: transform .2s var(--ease), border-color .2s var(--ease), box-shadow .2s var(--ease);
}
.email-copy:hover {
  transform: translateY(-2px);
  border-color: var(--navy);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
.email-copy.is-copied { border-color: var(--navy); }
.email-copy-text { overflow-wrap: anywhere; }
.email-copy-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px; height: 34px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--brand-fill);
  color: var(--on-brand);
}
.email-copy-icon svg { width: 16px; height: 16px; }
.email-copy-icon .icon-check { display: none; }
.email-copy.is-copied .icon-copy { display: none; }
.email-copy.is-copied .icon-check { display: block; }
.contact-fallback {
  text-align: center;
  margin-top: 20px;
  font-size: 14.5px;
}
.contact-fallback a { color: var(--navy); font-weight: 600; }

/* Footer */
.footer {
  padding: 46px 0 40px;
  border-top: 1px solid var(--hairline);
  margin-top: 40px;
}
.footer-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
}
/* True center: with the old flex + space-between, the links only
   sat "between" the brand and the copyright text, so unequal widths
   on either side (brand vs. copyright) pushed them off the visual
   center of the footer. The grid's middle column centers them
   against the full footer width instead, regardless of what the
   other two columns measure. */
.footer-links { display: flex; gap: 22px; align-items: center; justify-content: center; }
.footer-links a {
  font-size: 14px;
  color: var(--ink-soft);
  transition: color .2s var(--ease);
}
.footer-links a:hover { color: var(--navy); }
.footer-copy {
  justify-self: end;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ink-faint);
}

/* =========================================================
   Pricing
   ========================================================= */
/* Pricing type switcher — SaaS videos (priced by length) vs live
   stream packages (priced by what's included). Panels are toggled
   with the hidden attribute in js/script.js. */
.pricing-tabs {
  display: flex;
  width: max-content;
  max-width: 100%;
  margin: 0 auto 40px;
  padding: 5px;
  gap: 4px;
  border-radius: 999px;
  background: var(--pill-bg);
  border: 1px solid var(--glass-border);
}
.pricing-tab {
  font-family: 'Inter', sans-serif;
  font-size: 14.5px;
  font-weight: 600;
  padding: 10px 22px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
  transition: color .2s var(--ease), background .2s var(--ease);
}
.pricing-tab:hover { color: var(--ink); }
.pricing-tab.is-active {
  background: var(--brand-fill);
  color: var(--on-brand);
  box-shadow: 0 4px 16px var(--btn-glow);
}
.pricing-tab:focus-visible { outline: 2px solid var(--navy); outline-offset: 2px; }
.pricing-panel[hidden] { display: none; }

.pricing-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  align-items: stretch;
}
@media (max-width: 900px) {
  .pricing-grid { grid-template-columns: 1fr; }
}
.price-card {
  position: relative;
  padding: 32px 28px 28px;
  display: flex;
  flex-direction: column;
}
.price-card--featured {
  border-color: var(--navy);
  box-shadow: 0 0 0 1px var(--navy), var(--glass-shadow);
}
.price-badge {
  position: absolute;
  top: -14px;
  left: 50%;
  transform: translateX(-50%);
  font-family: 'Inter', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--on-brand);
  background: var(--brand-fill);
  padding: 6px 16px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(232,69,27,0.32);
}
.price-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 20px;
}
.price-card-head h3 { font-size: 20px; margin: 0; }
.price-duration-pill {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ink-soft);
  background: var(--surface-hover);
  padding: 5px 12px;
  border-radius: 999px;
  white-space: nowrap;
}
:root[data-theme="dark"] .price-duration-pill { color: #E4D8CD; }
.price-slider { margin-bottom: 24px; }
.price-slider-track {
  position: relative;
  height: 4px;
  border-radius: 999px;
  background: var(--hairline);
  margin-bottom: 8px;
}
.price-slider-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  border-radius: 999px;
  background: var(--brand-fill);
}
.price-slider-dot {
  position: absolute;
  top: 50%;
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--navy);
  box-shadow: 0 0 0 4px rgba(18,50,85,0.18);
  transform: translate(-50%, -50%);
}
.price-slider-labels {
  display: flex;
  justify-content: space-between;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--ink-faint);
}
.price-amount {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 6px;
}
.price-amount-value {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 42px;
  font-weight: 700;
  background: var(--navy-fill);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.price-amount-old {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 22px;
  font-weight: 600;
  color: var(--ink-faint);
  text-decoration: line-through;
}
.price-promo {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--violet);
  margin: 0 0 10px;
}
.price-desc { font-size: 14.5px; margin-bottom: 20px; }
.price-features {
  list-style: none;
  margin: 0 0 26px;
  padding: 18px 0 0;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 13px;
  flex: 1;
}
.price-features li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14.5px;
  color: var(--ink);
}
.price-features li svg { width: 16px; height: 16px; color: var(--navy); flex-shrink: 0; }
.price-features li.is-excluded { color: var(--ink-faint); text-decoration: line-through; }
.price-features li.is-excluded svg { color: var(--ink-faint); }
.price-cta { justify-content: center; width: 100%; margin-bottom: 10px; }
.price-example {
  display: block;
  text-align: center;
  font-size: 13.5px;
  color: var(--ink-soft);
  transition: color .2s var(--ease);
}
.price-example:hover { color: var(--navy); }

/* =========================================================
   Responsive
   ========================================================= */

@media (max-width: 860px) {
  .about-grid { grid-template-columns: 1fr; }
  .fact-row { grid-template-columns: 1fr 1fr; }
  .fact-row .fact-card:last-child { grid-column: span 2; }

  .nav-links { display: none; }
  .nav-toggle { display: flex; }
  .nav.open .nav-links {
    display: flex;
    flex-direction: column;
    gap: 4px;
    position: absolute;
    top: calc(100% + 10px);
    left: 0; right: 0;
    padding: 16px;
    border-radius: var(--radius-md);
    /* Solid (not the usual translucent glass) — this is a functional
       menu sitting over page copy, not a decorative panel, and the
       glass tokens don't leave enough contrast for the link text once
       there's a headline blurring through underneath. */
    background: var(--bg-2);
    box-shadow: var(--glass-shadow);
    border: 1px solid var(--glass-border);
  }
  .nav.open .nav-links a { padding: 10px 16px; border-radius: var(--radius-sm); }
  .nav.open .nav-links a { width: 100%; text-align: center; }

  .footer-inner { display: flex; flex-direction: column; align-items: flex-start; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}


/* =========================================================
   DREAMY PASS — soft-focus photographic backdrop, glassy
   panels, serif display type. (Previous version backed up at
   ../motion-by-vinny-backup-pre-dreamy — delete this block and
   swap the tokens back to revert.)
   Light theme shows the "Stream Visuals" sky, dark theme the
   "SaaS Motion" dusk; both are blurred hard enough that the
   text baked into the source images can't be read.
   ========================================================= */
.mesh span { display: none; }
.mesh::before {
  content: "";
  position: absolute;
  inset: -90px;
  background: url("../assets/images/bg-stream-sky.webp") center / cover no-repeat;
  filter: blur(44px) saturate(1.15);
  transform: translateZ(0);
}
.mesh::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.18) 0%, rgba(214, 226, 241, 0.32) 45%, rgba(214, 226, 241, 0.72) 100%);
}
:root[data-theme="dark"] .mesh::before { background-image: url("../assets/images/bg-saas-dusk.webp"); filter: blur(44px) saturate(1.1) brightness(0.9); }
:root[data-theme="dark"] .mesh::after { background: linear-gradient(180deg, rgba(6, 14, 28, 0.35), rgba(6, 14, 28, 0.15) 55%, rgba(6, 14, 28, 0.4)); }
.grain { opacity: 0.22; }

h1, h2 {
  font-family: 'Newsreader', 'Times New Roman', serif;
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 1.04;
}
.eyebrow { letter-spacing: 0.2em; font-size: 11.5px; }
.lead, .section-head p { font-weight: 400; }
.btn, .nav-links a { letter-spacing: 0.01em; }
