/* ============================================================
   Matheus Vagmaker — Portfolio
   Editorial · minimal · premium — #1A49E5 on warm neutrals
   ============================================================ */

:root {
  --blue: #1A49E5;
  --blue-deep: #0F2FA0;
  --blue-soft: #5E80F2;
  --ink: #16161A;
  --ink-60: rgba(22, 22, 26, 0.62);
  --bg: #F7F6F3;
  --bg-raised: #FFFFFF;
  --line: rgba(22, 22, 26, 0.12);

  --glass-bg: rgba(255, 255, 255, 0.55);
  --glass-line: rgba(255, 255, 255, 0.7);
  --glass-blur: 14px;

  --font-sans: "Archivo", system-ui, sans-serif;
  --font-serif: "Instrument Serif", Georgia, serif;

  /* Fluted glass background — all derived from the palette above, so the
     shader stays in sync with the brand instead of carrying its own colors.
     Defaults describe a light surface; .footer overrides them for dark. */
  --fluted-swirl-a: var(--bg);
  --fluted-swirl-b: #ECEFF7;      /* --bg, nudged cool toward --blue-soft */
  --fluted-base: var(--bg);
  --fluted-up: #8FA9F6;           /* --blue, lightened */
  --fluted-down: var(--blue);
  --fluted-left: var(--blue-soft);
  --fluted-right: var(--blue-deep);
  --fluted-highlight: var(--bg-raised);

  --container: 1280px;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --radius: 16px;
  --radius-lg: 20px;

  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

html {
  scroll-padding-top: 96px;
}
/* Deliberately NOT `scroll-behavior: smooth`. Every in-page jump already goes
   through GSAP's ScrollToPlugin (see smoothScrollTo in js/main.js), so the CSS
   property added nothing — but it broke ScrollTrigger: refresh() jumps the page
   to 0 to measure, and with smooth scrolling the browser animates instead of
   jumping, so everything gets measured off by the current scroll position.
   Pins then fire hundreds of pixels early. */

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--ink);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img, svg { display: block; max-width: 100%; }
a { color: inherit; }
ul { padding: 0; list-style: none; }
button { font: inherit; cursor: pointer; }

.serif {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

/* ---------- A11y ---------- */
:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: fixed;
  top: 12px; left: 12px;
  z-index: 100;
  padding: 0.7rem 1.2rem;
  background: var(--ink);
  color: #fff;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform 0.25s var(--ease-out);
}
.skip-link:focus { transform: translateY(0); }

/* ---------- Grain ---------- */
.grain {
  position: fixed;
  inset: -50%;
  z-index: 60;
  pointer-events: none;
  opacity: 0.045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Fluted glass background ---------- */
/* Decorative shader canvas. Fills its positioned parent, sits behind the
   parent's content, and never intercepts a click. Until (or unless) WebGPU
   renders, the canvas is transparent and the section's own background shows
   through unchanged. */
fluted-glass-background {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: block;
  pointer-events: none;
  overflow: hidden;
  /* Fades in only once a frame exists, so nothing flickers on load. */
  opacity: 0;
  transition: opacity 0.6s var(--ease-out);
}
fluted-glass-background[data-gpu-ready] {
  opacity: var(--fluted-opacity, 1);
}
fluted-glass-background canvas {
  width: 100%;
  height: 100%;
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  fluted-glass-background { transition: none; }
}

/* ---------- Layout ---------- */
.container {
  width: min(var(--container), 100% - var(--gutter) * 2);
  margin-inline: auto;
}

/* ---------- Glass utility ---------- */
.glass {
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.4);
  border: 1px solid var(--glass-line);
  box-shadow: 0 8px 32px rgba(22, 22, 26, 0.08);
}

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.95rem 1.7rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background-color 0.3s var(--ease-out),
              color 0.3s var(--ease-out),
              border-color 0.3s var(--ease-out),
              box-shadow 0.3s var(--ease-out);
  will-change: transform;
}
.btn-arrow {
  display: inline-block;
  transition: transform 0.3s var(--ease-out);
}
.btn:hover .btn-arrow { transform: translate(3px, -3px); }
.btn-primary:hover .btn-arrow { transform: translateY(3px); }
.btn-top:hover .btn-arrow { transform: translateY(-4px); }

.btn-primary {
  background: var(--blue);
  color: #fff;
  box-shadow: 0 10px 30px rgba(26, 73, 229, 0.28);
}
.btn-primary:hover {
  background: var(--blue-deep);
  box-shadow: 0 14px 36px rgba(26, 73, 229, 0.34);
}

.btn-ghost {
  background: rgba(255, 255, 255, 0.4);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-color: var(--line);
  color: var(--ink);
}
.btn-ghost:hover {
  border-color: var(--ink);
  background: rgba(255, 255, 255, 0.75);
}

/* ---------- Header / nav ---------- */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 50;
  padding: 1rem var(--gutter);
  transition: transform 0.4s var(--ease-out);
}

.nav {
  width: min(var(--container), 100%);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.6rem 0.6rem 0.6rem 1.4rem;
  border-radius: 999px;
  background: rgba(247, 246, 243, 0.72);
  -webkit-backdrop-filter: blur(16px) saturate(1.5);
  backdrop-filter: blur(16px) saturate(1.5);
  border: 1px solid rgba(22, 22, 26, 0.08);
  box-shadow: 0 6px 24px rgba(22, 22, 26, 0.06);
}

.nav-logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.nav-logo img {
  height: 26px;
  width: auto;
  display: block;
}

/* wrapper for links + CTA (a dropdown panel on mobile) */
.nav-menu {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* Hamburger toggle (mobile only) */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--ink);
  cursor: pointer;
}
.nav-toggle-bar {
  display: block;
  width: 18px;
  height: 2px;
  margin: 0 auto;
  background: #fff;
  border-radius: 2px;
  transition: transform 0.3s var(--ease-out), opacity 0.3s var(--ease-out);
}
.nav[data-open="true"] .nav-toggle-bar:nth-child(1) {
  transform: translateY(3.5px) rotate(45deg);
}
.nav[data-open="true"] .nav-toggle-bar:nth-child(2) {
  transform: translateY(-3.5px) rotate(-45deg);
}

.nav-links {
  display: flex;
  gap: 0.25rem;
}
.nav-links a {
  position: relative;
  display: inline-block;
  padding: 0.5rem 0.9rem;
  font-weight: 500;
  font-size: 0.95rem;
  text-decoration: none;
  color: var(--ink-60);
  border-radius: 999px;
  transition: color 0.25s var(--ease-out), background-color 0.25s var(--ease-out);
}
.nav-links a:hover {
  color: var(--ink);
  background: rgba(22, 22, 26, 0.05);
}

.nav-links a.btn-nav {
  padding: 0.65rem 1.25rem;
  background: var(--ink);
  color: #fff;
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
}
.nav-links a.btn-nav:hover { background: var(--blue); color: #fff; }

/* ============ HERO ============ */
.hero {
  position: relative;
  min-height: 46svh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 10rem 0 0.5rem;
  overflow: hidden;
}
.hero::before {
  /* soft blue wash behind the centered title */
  content: "";
  position: absolute;
  top: 46%; left: 50%;
  transform: translate(-50%, -50%);
  width: 72vw; height: 72vw;
  max-width: 900px; max-height: 900px;
  background: radial-gradient(closest-side, rgba(26, 73, 229, 0.10), transparent 70%);
  pointer-events: none;
}

.gravity-stars {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  opacity: 0.82;
  -webkit-mask-image: linear-gradient(to bottom, transparent 2%, #000 20%, #000 88%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 2%, #000 20%, #000 88%, transparent 100%);
}

.hero-inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 1100px;
}

.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-60);
  margin-bottom: 1.75rem;
}
.eyebrow-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 0 4px rgba(26, 73, 229, 0.15);
}

.hero-title {
  font-size: clamp(2.1rem, 5.4vw, 4.2rem);
  line-height: 1.12;
  font-weight: 720;
  letter-spacing: -0.03em;
  max-width: 22ch;
  margin: 0 auto 1.5rem;
}
.hero-title em {
  font-family: var(--font-serif);
  font-weight: 400;
  font-style: italic;
  color: var(--blue);
}
.hero-title-keep { white-space: nowrap; }

.hero-title-role,
.hero-title-message {
  display: block;
}

.hero-title-role {
  white-space: nowrap;
}

/* Portrait tucked inline into the headline, arch-shaped */
.hero-portrait {
  position: relative;
  display: inline-block;
  vertical-align: -0.2em;
  width: 0.82em;
  height: 1.12em;
  margin: 0 0.16em;
  border-radius: 0.98em 0.98em 0.26em 0.26em;
  overflow: visible;
  cursor: pointer;
}
.hero-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 32%;
  display: block;
  border-radius: inherit;
  background: var(--blue);
  box-shadow: 0 12px 28px rgba(26, 73, 229, 0.28);
  transition: transform 0.6s cubic-bezier(0.34, 1.1, 0.4, 1),
              box-shadow 0.6s var(--ease-out);
  will-change: transform;
}
.hero-portrait:hover img,
.hero-portrait:focus-visible img {
  transform: translateY(-5px) scale(1.05);
  box-shadow: 0 22px 44px rgba(26, 73, 229, 0.38);
}

/* Hover tooltip on the photo */
.hero-tooltip {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  transform: translate(-50%, 6px);
  white-space: nowrap;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 600;
  font-stretch: 100%;
  letter-spacing: 0;
  text-transform: none;
  color: #fff;
  background: var(--ink);
  padding: 0.5rem 0.9rem;
  border-radius: 999px;
  box-shadow: 0 12px 28px rgba(22, 22, 26, 0.22);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.28s var(--ease-out), transform 0.28s var(--ease-out);
}
.hero-tooltip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--ink);
}
.hero-portrait:hover .hero-tooltip,
.hero-portrait:focus-visible .hero-tooltip {
  opacity: 1;
  visibility: visible;
  transform: translate(-50%, 0);
}

.hero-copy {
  max-width: 50ch;
  color: var(--ink-60);
  margin: 0 auto;
}

.hero-company-link {
  color: var(--blue);
  font-weight: 650;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

.hero-company-link:hover {
  color: var(--blue-deep);
}

.hero-brands {
  position: relative;
  /* .hero-brands already sits inside .container, so 100% == the content grid width */
  width: 100%;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  overflow: hidden;
}

/* Edge fade: gradient into the page + a soft blur, strongest at the very edge */
.hero-brands::before,
.hero-brands::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 2;
  width: clamp(48px, 9%, 130px);
  pointer-events: none;
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}
.hero-brands::before {
  left: 0;
  background: linear-gradient(to right, var(--bg), transparent);
  -webkit-mask-image: linear-gradient(to right, #000 35%, transparent);
  mask-image: linear-gradient(to right, #000 35%, transparent);
}
.hero-brands::after {
  right: 0;
  background: linear-gradient(to left, var(--bg), transparent);
  -webkit-mask-image: linear-gradient(to left, #000 35%, transparent);
  mask-image: linear-gradient(to left, #000 35%, transparent);
}

/* Track = two identical lists scrolling left; -50% loops seamlessly */
.hero-brands-track {
  display: flex;
  width: max-content;
  animation: brands-marquee 50s linear infinite;
}
.hero-brands:hover .hero-brands-track {
  animation-play-state: paused;
}

@keyframes brands-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-brands-track { animation: none; }
}

.hero-brands-list {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
}

.hero-brands-list li {
  display: inline-flex;
  flex: 0 0 auto;
  justify-content: center;
  /* symmetric side padding = half the gap, so the two lists join seamlessly */
  padding-inline: clamp(1rem, 2.5vw, 2.25rem);
}

.hero-brands-list img {
  width: clamp(72px, 6vw, 100px);
  height: clamp(72px, 6vw, 100px);
  object-fit: contain;
  filter: brightness(0);
  opacity: 0.45;
}

/* ============ SECTIONS (shared) ============ */
.section-title {
  font-size: clamp(2.4rem, 6vw, 4.5rem);
  font-weight: 750;
  font-stretch: 116%;
  letter-spacing: -0.03em;
  line-height: 1.02;
  text-transform: uppercase;
}
.section-title .serif {
  text-transform: none;
  color: var(--blue);
}

.section-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 1rem 3rem;
  margin-bottom: clamp(3rem, 7vw, 5.5rem);
}
.section-sub {
  max-width: 30ch;
  color: var(--ink-60);
  padding-bottom: 0.5rem;
}

/* ============ WORK ============ */
.work {
  padding: clamp(5rem, 11vw, 9rem) 0;
}

.work-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(3rem, 6vw, 5rem) clamp(1.5rem, 3vw, 3rem);
  align-items: start;
}

.work-card.card-lg { grid-column: span 7; }
.work-card.card-sm { grid-column: span 5; }
.work-card.card-offset { margin-top: clamp(3rem, 8vw, 7rem); }

.card-link {
  display: block;
  text-decoration: none;
}

.card-media {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--ink);
  aspect-ratio: 4 / 3;
  box-shadow: 0 10px 30px rgba(22, 22, 26, 0.06);
  transition: transform 0.55s var(--ease-out),
              box-shadow 0.55s var(--ease-out);
  will-change: transform;
}
.card-sm .card-media { aspect-ratio: 3 / 3.8; }
.card-link:hover .card-media,
.card-link:focus-visible .card-media {
  transform: translateY(-8px);
  box-shadow: 0 28px 56px rgba(22, 22, 26, 0.16);
}

.card-art {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: center;
  transition: transform 0.7s var(--ease-out);
  will-change: transform;
}
.card-link:hover .card-art,
.card-link:focus-visible .card-art {
  transform: scale(1.06);
}

.card-view {
  position: absolute;
  left: 50%;
  bottom: 1.4rem;
  transform: translate(-50%, 16px);
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 1.3rem;
  border-radius: 999px;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}
.card-link:hover .card-view,
.card-link:focus-visible .card-view {
  opacity: 1;
  transform: translate(-50%, 0);
}

.card-meta { padding: 1.4rem 0.4rem 0; }

.card-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.card-title {
  font-size: clamp(1.35rem, 2.2vw, 1.7rem);
  line-height: 1.32;
  font-weight: 700;
  font-stretch: 110%;
  letter-spacing: -0.02em;
  transition: color 0.3s var(--ease-out);
}
.card-link:hover .card-title { color: var(--blue); }
.card-year {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.05rem;
  color: var(--ink-60);
}
.card-desc {
  margin-top: 0.4rem;
  max-width: 42ch;
  color: var(--ink-60);
  font-size: 0.98rem;
}

.card-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0;
  margin-top: 1rem;
}
.tag {
  display: inline-flex;
  align-items: center;
  padding: 0;
  border: 0;
  border-radius: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-60);
  box-shadow: none;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.tag + .tag::before {
  content: "•";
  margin-inline: 0.65rem;
  color: var(--ink-40);
}

/* ============ ABOUT ============ */
.about {
  padding: clamp(5rem, 11vw, 9rem) 0;
  background: var(--bg-raised);
  border-block: 1px solid var(--line);
}

.about-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: clamp(2.5rem, 6vw, 6rem);
  align-items: center;
}

.about-media { position: relative; }

.portrait {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 5;
  box-shadow: 0 30px 70px rgba(26, 73, 229, 0.22);
}
.portrait svg,
.portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

.about-lead {
  font-size: clamp(1.1rem, 1.8vw, 1.3rem);
  font-weight: 500;
  line-height: 1.55;
  margin: 1.5rem 0 1.25rem;
}
.about-copy {
  color: var(--ink-60);
  max-width: 56ch;
  margin-bottom: 2.25rem;
}

/* ---------- Cat peek (hover Joaquim / Lobo) ---------- */
/* The name gets a quiet affordance so it reads as "there's something here"
   without pretending to be a link. JS adds .is-live only once the photo has
   actually loaded, so a missing file leaves plain text behind. */
.cat-name {
  color: var(--ink);
  font-weight: 600;
}
.cat-name.is-live {
  cursor: default;
  text-decoration: underline dotted;
  text-decoration-color: var(--blue);
  text-underline-offset: 4px;
  transition: color 0.25s var(--ease-out);
}
.cat-name.is-live:hover { color: var(--blue); }

/* One shared follower, reused by both names. Fixed because it tracks the
   cursor rather than any section. */
.cat-peek {
  position: fixed;
  top: 0; left: 0;
  z-index: 70;              /* above .grain (60) */
  width: clamp(140px, 14vw, 200px);
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--radius);
  border: 3px solid var(--bg-raised);
  box-shadow: 0 18px 44px rgba(22, 22, 26, 0.22);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  will-change: transform;
  transition: opacity 0.28s var(--ease-out), visibility 0.28s;
}
.cat-peek.is-visible {
  opacity: 1;
  visibility: visible;
}
@media (prefers-reduced-motion: reduce) {
  .cat-peek { transition: none; }
}

.about-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
}
.about-socials {
  display: flex;
  gap: 0.6rem;
}
.about-socials a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 999px;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--line);
  transition: color 0.3s var(--ease-out),
              background-color 0.3s var(--ease-out),
              border-color 0.3s var(--ease-out),
              transform 0.3s var(--ease-out);
}
.about-socials a:hover,
.about-socials a:focus-visible {
  color: #fff;
  background: var(--blue);
  border-color: var(--blue);
  transform: translateY(-3px);
}
/* ============ APPROACH ============ */
.approach {
  padding: clamp(5rem, 11vw, 9rem) 0;
}

.approach-grid {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
}

.approach-lead {
  margin-top: 1.5rem;
  max-width: 68ch;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem);
  color: var(--ink-60);
  line-height: 1.6;
}

.approach-cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.4rem);
}

.approach-card {
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
  border-radius: var(--radius);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  box-shadow: 0 10px 30px rgba(22, 22, 26, 0.05);
  transition: transform 0.45s var(--ease-out),
              box-shadow 0.45s var(--ease-out),
              border-color 0.45s var(--ease-out);
}
.approach-card:hover {
  transform: translateY(-6px);
  border-color: rgba(26, 73, 229, 0.28);
  box-shadow: 0 24px 48px rgba(26, 73, 229, 0.14);
}

.approach-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  border-radius: 14px;
  color: var(--blue);
  background: rgba(26, 73, 229, 0.09);
}
.approach-icon svg { width: 22px; height: 22px; }

.approach-card-title {
  margin-top: 1.1rem;
  font-size: clamp(1.15rem, 1.8vw, 1.35rem);
  font-weight: 700;
  font-stretch: 110%;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.approach-card-desc {
  margin-top: 0.5rem;
  color: var(--ink-60);
  font-size: 0.95rem;
  line-height: 1.5;
}

.about-socials svg {
  width: 20px;
  height: 20px;
}

/* ============ FOOTER ============ */
.footer {
  background: var(--ink);
  color: #F7F6F3;
  padding: clamp(5rem, 11vw, 8.5rem) 0 2.5rem;
  position: relative;
  overflow: hidden;
  /* Keeps the shader canvas layered inside the footer and nowhere else. */
  isolation: isolate;

  /* Dark-surface mapping for the fluted glass background. The footer is the
     one dark section in the site, so it retints the tokens rather than
     inheriting the light-surface defaults from :root. Held well under 1 so
     the CTA, links and copyright keep their contrast. */
  --fluted-swirl-a: var(--ink);
  --fluted-swirl-b: #1E1F2B;      /* --ink, lifted and cooled */
  --fluted-base: var(--ink);
  --fluted-up: #6D8CF4;           /* --blue-soft, lightened */
  --fluted-down: var(--blue);
  --fluted-left: var(--blue-soft);
  --fluted-right: var(--blue-deep);
  --fluted-highlight: var(--bg);
  --fluted-opacity: 0.5;
}
/* The existing blue bloom stays on top of the shader, so the footer still
   reads as it always has and the glass is texture underneath it. */
.footer::before {
  content: "";
  position: absolute;
  z-index: 1;
  bottom: -40%; left: 50%;
  transform: translateX(-50%);
  width: 80vw; height: 60vw;
  max-width: 1100px; max-height: 800px;
  background: radial-gradient(closest-side, rgba(26, 73, 229, 0.35), transparent 70%);
  pointer-events: none;
  transform-origin: 50% 65%;
  will-change: transform, opacity;
  animation: footer-breathe 7s cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

.footer > .container {
  position: relative;
  z-index: 1;
}

@keyframes footer-breathe {
  0%, 100% {
    transform: translateX(-50%) scale(0.94);
    opacity: 0.72;
  }
  50% {
    transform: translateX(-50%) scale(1.08);
    opacity: 1;
  }
}

.footer-cta {
  position: relative;
  text-align: center;
  margin-bottom: clamp(4rem, 9vw, 7rem);
}
.footer-title {
  font-size: clamp(2.4rem, 7vw, 5.5rem);
  font-weight: 750;
  font-stretch: 116%;
  letter-spacing: -0.03em;
  line-height: 1.05;
  text-transform: uppercase;
  margin-bottom: 2.5rem;
}
.footer-title .line { display: block; }
.footer-title .serif {
  text-transform: none;
  color: var(--blue-soft);
}

.footer-email {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: clamp(1.1rem, 2.6vw, 1.6rem);
  font-weight: 600;
  text-decoration: none;
  padding: 1rem 2rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(255, 255, 255, 0.16);
  transition: background-color 0.3s var(--ease-out), border-color 0.3s var(--ease-out);
  will-change: transform;
}
.footer-email:hover {
  background: var(--blue);
  border-color: var(--blue);
}
.footer-email .btn-arrow { transition: transform 0.3s var(--ease-out); }
.footer-email:hover .btn-arrow { transform: translate(4px, -4px); }

.footer-links {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  margin-top: 1.75rem;
}
.footer-links a {
  font-size: 0.95rem;
  font-weight: 500;
  text-decoration: none;
  color: rgba(247, 246, 243, 0.7);
  transition: color 0.25s var(--ease-out);
}
.footer-links a:hover { color: #fff; }
.footer-links-sep { color: rgba(247, 246, 243, 0.35); }

.btn-arrow {
  display: inline-block;
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
  overflow: visible;
}

.footer-bar {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.25rem;
  padding-top: 2rem;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.footer-copy {
  font-size: 0.88rem;
  color: rgba(247, 246, 243, 0.55);
}
.btn-top {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.16);
  color: #F7F6F3;
  font-size: 0.88rem;
  padding: 0.7rem 1.3rem;
}
.btn-top:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.4);
}

/* ============ CASE STUDY PAGE ============ */
.case-hero {
  padding: 9.5rem 0 clamp(2rem, 5vw, 3.5rem);
}

.case-back {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink-60);
  margin-bottom: 2.5rem;
  transition: color 0.25s var(--ease-out), transform 0.25s var(--ease-out);
}
.case-back:hover { color: var(--blue); }
.case-back-arrow {
  width: 1.15rem;
  height: 1.15rem;
  flex: 0 0 auto;
  transition: transform 0.35s var(--ease-out);
}
.case-back:hover .case-back-arrow,
.case-back:focus-visible .case-back-arrow { transform: translateX(-3px); }

.case-title {
  /* headline-style title: sized to sit on 2 or 3 lines */
  font-size: clamp(2.1rem, 4.6vw, 3.9rem);
  font-weight: 750;
  font-stretch: 116%;
  letter-spacing: -0.03em;
  line-height: 1.06;
  text-transform: uppercase;
  max-width: 22ch;
  margin-bottom: 1.5rem;
}
.case-title .serif {
  text-transform: none;
  color: var(--blue);
}
.case-title .case-title-last-line {
  display: block;
}
@media (min-width: 520px) {
  .case-title .case-title-last-line { white-space: nowrap; }
}

.case-subtitle {
  font-size: clamp(1.05rem, 1.8vw, 1.35rem);
  color: var(--ink-60);
  max-width: 52ch;
}

.case-meta {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.5rem;
  margin: clamp(2.25rem, 5vw, 3.25rem) 0;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}
.case-meta span {
  display: block;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 0.4rem;
}
.case-meta strong {
  font-weight: 600;
  font-size: 0.98rem;
}

.case-cover {
  margin: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 16 / 9;
  background: var(--ink);
  box-shadow: 0 24px 60px rgba(22, 22, 26, 0.12);
}
.case-cover img,
.case-cover svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- summary "at a glance" panel --- */
.case-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 2.75rem);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.case-summary-item .case-label { padding-top: 0; margin-bottom: 0.6rem; }
.case-summary-item p { color: var(--ink-60); }
.case-summary-item ul {
  margin: 0;
  padding-left: 1.1rem;
  list-style: disc;
  color: var(--ink-60);
}
.case-summary-item li { margin-bottom: 0.4rem; }
.case-summary-item li::marker { color: var(--blue); }

/* --- layout: sticky table-of-contents + content --- */
.case-layout {
  display: grid;
  grid-template-columns: 190px minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
.case-toc {
  position: sticky;
  top: 110px;
  align-self: start;
}
.case-toc-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-60);
  margin-bottom: 1rem;
}
.case-toc ul { list-style: none; margin: 0; padding: 0; }
.case-toc a {
  display: block;
  padding: 0.5rem 0 0.5rem 1rem;
  border-left: 2px solid transparent;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink-60);
  text-decoration: none;
  transition: color 0.25s var(--ease-out), border-color 0.25s var(--ease-out);
}
.case-toc a:hover { color: var(--ink); }
.case-toc a.is-active {
  color: var(--blue);
  border-left-color: var(--blue);
  font-weight: 600;
}
.case-content { min-width: 0; }

/* --- wildcard sections --- */
.case-section {
  padding: clamp(2rem, 5vw, 3.75rem) 0;
}

.case-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2.2fr);
  gap: 1.25rem 4rem;
  align-items: start;
}
.case-label {
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue);
  padding-top: 0.45em;
}
.case-heading {
  font-size: clamp(1.55rem, 3vw, 2.3rem);
  font-weight: 720;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-bottom: 1.1rem;
}
.case-subheading {
  font-size: clamp(1.15rem, 2vw, 1.45rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.25;
  margin: 2rem 0 0.75rem;
}
.case-body p {
  color: var(--ink-60);
  max-width: 62ch;
}
.case-body p + p { margin-top: 1rem; }
.case-body code {
  font-size: 0.9em;
  background: rgba(22, 22, 26, 0.06);
  padding: 0.1em 0.4em;
  border-radius: 6px;
}

.case-figure { margin: 0; }
.case-img {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--bg-raised);
}
.case-img.wide { aspect-ratio: 2 / 1; }
.case-img.tall { aspect-ratio: 5 / 6; }
/* keeps the image at its own aspect ratio, uncropped (brand boards, diagrams) */
.case-img.natural { aspect-ratio: auto; background: var(--bg-raised); }
.case-img.natural img,
.case-img.natural svg { height: auto; object-fit: contain; }
/* Empty state: a visible slot to drop an <img> into. Once real content is
   added, this rule simply no longer matches (:empty), no cleanup needed. */
.case-img.natural:empty {
  min-height: clamp(220px, 32vw, 380px);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
}
.case-img img,
.case-img svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.case-figure figcaption {
  margin-top: 0.8rem;
  font-size: 0.85rem;
  color: var(--ink-60);
}

.pain-points-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: clamp(0.8rem, 1.5vw, 1.25rem);
  margin-top: clamp(2rem, 4vw, 3rem);
}

.pain-point-card {
  display: grid;
  place-items: center;
  min-height: clamp(180px, 18vw, 250px);
  padding: clamp(1.25rem, 2vw, 2rem);
  border-radius: clamp(16px, 1.5vw, 22px);
  background: #e8eaf1;
  color: var(--blue-deep);
  text-align: center;
}

.pain-point-card q {
  font-size: clamp(0.95rem, 1.25vw, 1.2rem);
  line-height: 1.35;
  letter-spacing: -0.02em;
}

.redesign-gallery {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  width: 100%;
  margin-top: clamp(2rem, 4vw, 3rem);
}

.case-grid-2 {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1.25rem, 3vw, 2.5rem);
}
.case-grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 1.75rem);
}

/* App-screen showcase: the screenshot fills the frame edge-to-edge */
.case-shot {
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--bg-raised);
}
.case-shot.tall { aspect-ratio: 3 / 4; }
.case-shot img,
.case-shot svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Process methodology tags */
.case-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1.75rem;
}
.case-tag {
  padding: 0.42rem 0.9rem;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--blue);
  background: rgba(26, 73, 229, 0.08);
}

/* Simple lists inside case copy.
   The global reset sets `list-style: none` on every <ul>, so bullets have to
   be switched back on explicitly here. */
.case-body ul {
  margin-top: 1rem;
  padding-left: 1.15rem;
  list-style: disc;
  color: var(--ink-60);
}
.case-body li { margin-bottom: 0.5rem; }

/* .case-tags is a <ul> too — override the bullet-list padding/spacing
   above so the pills sit flush left with the heading and paragraphs. */
.case-body .case-tags {
  padding-left: 0;
  list-style: none;
}
.case-body .case-tag { margin-bottom: 0; }
.case-body li::marker { color: var(--blue); }

.case-quote {
  margin: 0 auto;
  max-width: 780px;
  text-align: center;
  padding: clamp(1rem, 3vw, 2rem) 0;
}
.case-quote p {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: clamp(1.5rem, 3.4vw, 2.4rem);
  line-height: 1.3;
  color: var(--ink);
}
.case-quote cite {
  display: block;
  margin-top: 1.25rem;
  font-style: normal;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink-60);
}

.case-split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.case-split.reverse .case-figure { order: 2; }

/* --- persona card --- */
.persona-card {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.6fr);
  gap: clamp(1.75rem, 4vw, 3rem);
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
}
.persona-avatar {
  width: 88px;
  height: 88px;
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: rgba(26, 73, 229, 0.1);
  color: var(--blue);
  font-weight: 800;
  font-size: 1.7rem;
}
.persona-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.persona-name {
  margin-top: 1.1rem;
  font-size: 1.45rem;
  font-weight: 750;
  letter-spacing: -0.01em;
}
.persona-tags {
  margin-top: 0.5rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--blue);
}
.persona-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem 1.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.persona-facts span {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: 0.3rem;
}
.persona-facts strong {
  font-weight: 600;
  font-size: 0.95rem;
}
.persona-frustrations {
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
.persona-frustrations .case-label { padding-top: 0; margin-bottom: 0.6rem; }
.persona-frustrations ul {
  margin: 0;
  padding-left: 1.15rem;
  list-style: disc;
  color: var(--ink-60);
}
.persona-frustrations li { margin-bottom: 0.5rem; }
.persona-frustrations li::marker { color: var(--blue); }

/* image slot for the logo construction / brand board */
.brand-figure {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
}
/* a second brand image right after the first shouldn't repeat the divider */
.brand-figure + .brand-figure {
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
  padding-top: 0;
  border-top: none;
}

/* --- horizontal scroll carousel ---
   Baseline (no JS / no GSAP): a plain horizontal scroller with snap, usable
   by swipe, trackpad and keyboard. When main.js pins the section, it sets
   data-pinned and the container hands control over to the scroll-driven
   tween instead. */
.case-hscroll {
  /* One slide, sized off the viewport height since the pinned stage owns the
     whole screen. 105svh of width is 66svh of height at 16/10 — the frame
     fills two thirds of the screen. The 84vw cap keeps a margin of the
     neighbouring slides in view on any shape of screen; that peek is what
     reads as "this moves sideways" before it has moved. */
  --hscroll-slide: min(84vw, clamp(340px, 105svh, 1200px));

  position: relative;
  /* own the full viewport while pinned, so the carousel is the only thing
     on screen for the length of its travel */
  min-height: 100svh;
  display: grid;
  align-content: center;
  /* keeps ::before behind the carousel but in front of the sections the
     pinned box floats over */
  isolation: isolate;
}
/* Pinned, this section floats above its neighbours — so it carries the page
   background with it instead of letting them show through. It sits in the
   content column, so it is pulled back to the screen's left edge and given
   the screen's width — both measured by main.js (see --hscroll-bleed below).
   Sized exactly, never overshot: a fill that spilled past the viewport would
   widen the page and hand mobile a horizontal scrollbar. */
.case-hscroll::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--hscroll-bleed, 0px));
  width: var(--hscroll-stage, 100%);
  background: var(--bg);
}

.hscroll-viewport {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  /* the track slides past both ends, so soften the edges */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 2.5%, #000 97.5%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 2.5%, #000 97.5%, transparent);
}
/* The section lives in the content column, which the sticky TOC pushes off
   centre. main.js measures how far the column sits from the screen edge and
   publishes it as --hscroll-bleed, letting the stage span the real viewport
   so slides centre on the screen rather than on the column. Without JS the
   attribute is absent and the scroller just stays column-width. */
.case-hscroll[data-bleed] .hscroll-viewport {
  width: var(--hscroll-stage, 100%);
  margin-left: calc(-1 * var(--hscroll-bleed, 0px));
}
.hscroll-viewport[data-pinned="true"] {
  overflow: hidden;
  scroll-snap-type: none;
}

.hscroll-track {
  display: flex;
  gap: clamp(1rem, 2vw, 1.75rem);
  width: max-content;
  margin: 0;
  list-style: none;
  will-change: transform;
  /* Half a slot of lead-in and lead-out (100% here is the viewport box), so
     the run opens with slide one centered and closes with slide five
     centered instead of both sitting flush against an edge. */
  padding-inline: max(0px, calc((100% - var(--hscroll-slide)) / 2));
}

.hscroll-slide {
  flex: 0 0 auto;
  width: var(--hscroll-slide);
  scroll-snap-align: center;
}

/* 16/10 frame — the screens are 1440x900, so they fill it without cropping. */
.hscroll-media {
  aspect-ratio: 16 / 10;
  border-radius: var(--radius-lg);
  background: var(--bg-raised);
  border: 1px solid var(--line);
  overflow: hidden;
}
.hscroll-media img,
.hscroll-media svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* --- more projects carousel --- */
.case-carousel-section {
  padding: clamp(3.5rem, 8vw, 6rem) 0;
  border-top: 1px solid var(--line);
}
.case-carousel-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}
.case-carousel-head h2 {
  font-size: clamp(1.6rem, 3.5vw, 2.6rem);
  font-weight: 750;
  font-stretch: 112%;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}
.case-carousel {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.5vw, 1.75rem);
  /* small vertical breathing room so card hover-shadows aren't clipped */
  padding-block: 0.5rem 1.5rem;
}
.carousel-card {
  text-decoration: none;
  color: inherit;
}
.carousel-media {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--ink);
  box-shadow: 0 10px 30px rgba(22, 22, 26, 0.06);
  transition: transform 0.5s var(--ease-out), box-shadow 0.5s var(--ease-out);
}
.carousel-card:hover .carousel-media,
.carousel-card:focus-visible .carousel-media {
  transform: translateY(-6px);
  box-shadow: 0 24px 48px rgba(22, 22, 26, 0.14);
}
.carousel-media img,
.carousel-media svg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
}
.carousel-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 1rem;
}
.carousel-meta h3 {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  transition: color 0.3s var(--ease-out);
}
.carousel-card:hover .carousel-meta h3 { color: var(--blue); }
.carousel-cat {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink-60);
  white-space: nowrap;
}

/* ============ RESPONSIVE ============ */
@media (max-width: 1024px) {
  .pain-points-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .work-card.card-lg,
  .work-card.card-sm { grid-column: span 6; }
  .work-card.card-offset { margin-top: clamp(2rem, 6vw, 4rem); }
  .card-sm .card-media { aspect-ratio: 4 / 4.4; }

  .about-grid { grid-template-columns: 1fr; }
  .about-media { max-width: 480px; margin-inline: auto; }

  .approach-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .footer-bar {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
  }

  /* case: fold the sticky TOC away, content goes full width */
  .case-layout { grid-template-columns: 1fr; gap: 0; }
  .case-toc { display: none; }
}

@media (max-width: 720px) {
  .pain-points-grid { grid-template-columns: 1fr; }
  .approach-cards { grid-template-columns: 1fr; }
  .pain-point-card { min-height: 160px; }
  .hero-title {
    font-size: clamp(1.75rem, 8vw, 2.25rem);
    max-width: 100%;
  }
  .nav { position: relative; padding-left: 1.1rem; }
  .nav-toggle { display: flex; }

  /* links + CTA become a dropdown panel anchored to the right */
  .nav-menu {
    position: absolute;
    top: calc(100% + 0.7rem);
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
    min-width: 220px;
    padding: 0.9rem;
    border-radius: 24px;
    background: rgba(247, 246, 243, 0.94);
    -webkit-backdrop-filter: blur(18px) saturate(1.5);
    backdrop-filter: blur(18px) saturate(1.5);
    border: 1px solid rgba(22, 22, 26, 0.08);
    box-shadow: 0 16px 44px rgba(22, 22, 26, 0.14);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px) scale(0.98);
    transform-origin: top right;
    transition: opacity 0.28s var(--ease-out),
                transform 0.28s var(--ease-out),
                visibility 0.28s var(--ease-out);
    pointer-events: none;
  }
  .nav[data-open="true"] .nav-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
    pointer-events: auto;
  }
  .nav-links {
    flex-direction: column;
    gap: 0.15rem;
  }
  .nav-links a {
    display: block;
    padding: 0.7rem 0.9rem;
    font-size: 1rem;
  }
  .nav-menu .btn-nav {
    justify-content: center;
    margin-top: 0.3rem;
  }

  .hero { padding-top: 7rem; }

  .section-head { grid-template-columns: 1fr; align-items: start; }

  .work-grid { grid-template-columns: 1fr; gap: 3.5rem; }
  .work-card.card-lg,
  .work-card.card-sm { grid-column: 1 / -1; }
  .work-card.card-offset { margin-top: 0; }
  .card-sm .card-media { aspect-ratio: 4 / 4.6; }

  .footer-bar { align-items: center; }

  /* case study page */
  .case-hero { padding-top: 7.5rem; }
  .case-grid { grid-template-columns: 1fr; gap: 0.75rem; }
  .case-label { padding-top: 0; }
  .case-meta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .case-summary { grid-template-columns: 1fr; }
  .case-grid-2 { grid-template-columns: 1fr; }
  .case-grid-3 { grid-template-columns: 1fr; }
  .case-split { grid-template-columns: 1fr; }
  .case-split.reverse .case-figure { order: 0; }
  .case-img.wide { aspect-ratio: 16 / 10; }

  .case-carousel { grid-template-columns: 1fr; }

  .persona-card { grid-template-columns: 1fr; }
  .persona-facts { grid-template-columns: 1fr; }
}

/* Short viewports (14" laptops, windowed browsers): the first fold ends right
   on top of the work grid, so the cards give no hint that anything follows.
   Tighten the vertical rhythm just enough for the first card to peek above the
   fold. Height-gated, so tall displays keep the original spacing. The hero's
   top padding is mostly clearance for the fixed header, so most of the space
   comes from the gap between the brand marquee and the grid. */
@media (min-width: 721px) and (max-height: 900px) {
  /* flat, not fluid: this still has to clear the 97px fixed header */
  .hero { padding-top: 8.5rem; }
  .work { padding-top: clamp(3rem, 7.5vh, 4.5rem); }
}

/* ============ REDUCED MOTION ============
   Intentionally NOT disabling motion here: animations were enabled by
   request even when the OS prefers reduced motion. Killing transition
   durations globally (as the usual reset does) made every hover snap
   instantly, so that override is deliberately omitted. */

/* ============ 404 · PAGE NOT FOUND ============
   The numerals are an inline SVG: the same 404 drawn twice, each copy
   clipped to a horizontal slice, jittering out of register on a loop.
   The keyframes ship inside the SVG; it's inlined rather than loaded
   through <img> precisely so the rules below can reach in and hold the
   glitch until the pointer arrives. */
.nf-hero {
  padding: clamp(9rem, 18vh, 13rem) 0 clamp(4rem, 10vw, 8rem);
}

/* The lockup below is decorative type; this carries the accessible name. */
.nf-title {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.nf-art {
  display: grid;
  justify-items: center;
}

.nf-glyph {
  width: 100%;
  max-width: 1100px;
  height: auto;
  user-select: none;
  will-change: transform;
}

/* The glitch idles in register and only comes apart under the pointer.
   These beat the SVG's own `animation:` shorthand on specificity (id +
   class vs. id), so they win regardless of which stylesheet parses last. */
.nf-glyph #Frame_25,
.nf-glyph #Frame_26 { animation-play-state: paused; }
.nf-art:hover .nf-glyph #Frame_25,
.nf-art:hover .nf-glyph #Frame_26 { animation-play-state: running; }
/* Touch has no pointer to hover with, so there it just runs. */
@media (hover: none) {
  .nf-glyph #Frame_25,
  .nf-glyph #Frame_26 { animation-play-state: running; }
}

.nf-caption {
  margin-top: clamp(0.75rem, 2vw, 2rem);
  font-size: clamp(1.9rem, 3.8vw, 3.4rem);
  /* Instrument Serif italic hangs its p/g descenders below a line-height:1
     box, and the wipe below clips to that box — hence the leading here and
     the vertical bleed in the inset. */
  line-height: 1.25;
  color: var(--blue);
  white-space: nowrap;
  /* the entrance wipes this in from the left */
  clip-path: inset(-25% 0 -25% 0);
  will-change: transform;
}

.nf-projects {
  border-top: 1px solid var(--line);
}

@media (max-width: 720px) {
  .nf-hero { padding-top: 8rem; }
}
