@import url('https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,300;0,400;0,500;1,300;1,400&family=Instrument+Serif:ital,wght@0,300;0,400;1,300;1,400&display=swap');

@font-face {
  font-family: 'PP Neue Machina';
  src: url('/fonts/pp-neue-machina/PPNeueMachina-InktrapUltrabold.woff2') format('woff2');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

/* hyperellipse SSR snippet — softens corners before JS hydrates in Safari/Firefox */
@supports not (corner-shape: squircle) {
  :root {
    --corner-scale: 0.6;
  }
}

/* Native squircle in Chrome — hyperellipse JS is skipped when supported */
@supports (corner-shape: squircle) {
  [data-corner-shape='squircle'] {
    corner-shape: squircle;
  }
}

/*
 * Squircle shadow/clip split — drop-shadow must not share a node with clip-path.
 * Host is display:grid; shadow-filter and clip share grid-area 1/1.
 */
.squircle-shadow-filter {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.squircle-shadow-plate {
  width: 100%;
  height: 100%;
  min-height: 0;
  --corner-shape: squircle;
  background: #18181b;
  overflow: hidden;
}

.squircle-clip {
  grid-area: 1 / 1;
  width: 100%;
  min-width: 0;
  --corner-shape: squircle;
  overflow: hidden;
}

/* ─────────────────────────────────────────────
   Tokens
───────────────────────────────────────────── */
:root {
  --font-serif: 'Instrument Serif', Georgia, serif;
  --font-sans: 'Instrument Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --font-machina: 'PP Neue Machina', var(--font-sans), sans-serif;

  --color-bg: #f7f6f3;
  --color-text: #18181b;
  --color-muted: #3E3E41;
  --color-home-text: color-mix(in srgb, var(--color-muted) 80%, var(--color-bg));
  --color-home-text-soft: color-mix(in srgb, var(--color-home-text) 72%, var(--color-bg));
  --color-border: #e4e4e7;
  --color-surface: #eeedea;
  --color-accent: #18181b;

  --max-w: 72rem;
  --prose-w: 32rem;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --content-inset: calc((100vw - min(var(--max-w), 100vw)) / 2 + var(--gutter));
  --content-outset: calc((100vw - min(var(--max-w), 100vw)) / 2);
  --side-rail-gap: 3.5rem;
  --side-rail-inset: 2rem;
  --side-rail-w: 26rem;
  --side-rail-max-w: min(var(--side-rail-w), calc(var(--max-w) - var(--prose-w) - var(--side-rail-gap)));

  /* Spacing scale — 4px base unit */
  --space-unit: 0.25rem;
  --space-1: var(--space-unit);
  --space-2: calc(var(--space-unit) * 2);
  --space-3: calc(var(--space-unit) * 3);
  --space-4: calc(var(--space-unit) * 4);
  --space-5: calc(var(--space-unit) * 5);
  --space-6: calc(var(--space-unit) * 6);
  --space-8: calc(var(--space-unit) * 8);
  --space-10: calc(var(--space-unit) * 10);
  --space-12: calc(var(--space-unit) * 12);

  --device-frame-padding: 10px;
  --squircle-outer: calc(24px * var(--corner-scale, 1));
  --squircle-card: calc(16px * var(--corner-scale, 1));
  --squircle-thumb-vertical: calc(36px * var(--corner-scale, 1));
  --squircle-tile: calc(24px * var(--corner-scale, 1));
  --squircle-inner: calc(var(--squircle-outer) - var(--device-frame-padding));

  /* Grain — contrast baked into noise.png; never use CSS filter on grain (Safari scroll cost).
     html::before is position:fixed (viewport grain). Hero overlays use .grain-fixed-layer. */
  --grain-opacity: 0.06;
  --grain-opacity-intro: 0.06;
  --hero-blob-grain-tint: rgb(243 212 176);
  --grain-image: url('/images/noise.png');
  --grain-size: 128px 128px;

  /* Type scale — set --type-scale to 1.2 for +20% */
  --type-scale: 1;
  --text-fluid-xs: clamp(calc(0.8125rem * var(--type-scale)), calc(1.6vw * var(--type-scale)), calc(0.9375rem * var(--type-scale)));   /* 13 → 15px */
  --text-fluid-sm: clamp(calc(0.9375rem * var(--type-scale)), calc(1.2vw * var(--type-scale)), calc(1.0625rem * var(--type-scale))); /* 15 → 17px */
  --text-fluid-base: clamp(calc(1rem * var(--type-scale)), calc(1.5vw * var(--type-scale)), calc(1.125rem * var(--type-scale)));     /* 16 → 18px */
  --text-fluid-md: clamp(calc(1rem * var(--type-scale)), calc(1.5vw * var(--type-scale)), calc(1.1875rem * var(--type-scale)));       /* 16 → 19px */
  --text-fluid-lg: clamp(calc(1.0625rem * var(--type-scale)), calc(1.5vw * var(--type-scale)), calc(1.25rem * var(--type-scale)));   /* 17 → 20px */
  --text-fluid-xl: clamp(calc(1.125rem * var(--type-scale)), calc(2.4vw * var(--type-scale)), calc(1.375rem * var(--type-scale)));    /* 18 → 22px */
  --text-fluid-2xl: clamp(calc(1.25rem * var(--type-scale)), calc(2.25vw * var(--type-scale)), calc(1.5rem * var(--type-scale)));     /* 20 → 24px */
  --text-fluid-3xl: clamp(calc(1.375rem * var(--type-scale)), calc(2.35vw * var(--type-scale)), calc(1.75rem * var(--type-scale)));  /* 22 → 28px */
  --text-fluid-3xl-wide: clamp(calc(1.25rem * var(--type-scale)), calc(4vw * var(--type-scale)), calc(2rem * var(--type-scale)));    /* 20 → 32px */
  --site-header-name-size: calc(var(--text-fluid-3xl-wide) * 0.9);
  --text-fluid-4xl: clamp(calc(1.75rem * var(--type-scale)), calc(4vw * var(--type-scale)), calc(3rem * var(--type-scale)));          /* 28 → 48px */
  --text-fluid-4xl-wide: clamp(calc(1.375rem * var(--type-scale)), calc(5.75vw * var(--type-scale)), calc(3.375rem * var(--type-scale))); /* 22 → 54px */
  --text-fluid-4xl-tight: clamp(calc(1.75rem * var(--type-scale)), calc(4vw * var(--type-scale)), calc(2.5rem * var(--type-scale))); /* 28 → 40px */
  --text-fluid-5xl: clamp(calc(2.5rem * var(--type-scale)), calc(5.5vw * var(--type-scale)), calc(4rem * var(--type-scale)));       /* 40 → 64px */
  --text-fluid-stat: clamp(calc(2.25rem * var(--type-scale)), calc(3.5vw * var(--type-scale)), calc(2.875rem * var(--type-scale)));  /* 36 → 46px */

  --site-header-h: calc(1.5rem * 2 + var(--site-header-name-size) * 0.92 + 1px);
}

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

html {
  position: relative;
  font-size: 16px;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100%;
  background-color: var(--color-bg);
}

body {
  position: relative;
  z-index: 1;
  background: transparent;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  min-height: 100dvh;
  overflow-x: hidden;
  display: flex;
  flex-direction: column;
}

body:has(.site-header) {
  padding-top: var(--site-header-h);
}

/* Grain — single viewport-fixed layer; no CSS filter (Safari repaints filtered fixed layers on scroll) */
html::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  opacity: var(--grain-opacity);
  background-image: var(--grain-image);
  background-repeat: repeat;
  background-size: var(--grain-size);
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* Intro grain — viewport-fixed layer clipped to each host via grain-fixed.ts */
.grain-fixed-host {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}

.grain-fixed-layer {
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-layer-opacity, var(--grain-opacity));
  background-image: var(--grain-image);
  background-repeat: repeat;
  background-size: var(--grain-size);
  transform: translateZ(0);
  backface-visibility: hidden;
}

html[data-perf-grain-fixed='false'] .grain-fixed-layer {
  position: absolute;
  clip-path: none !important;
}

html:not(:has(.project__intro--with-carousel)) .project__header .grain-fixed-host {
  display: block;
}

html:not(:has(.project__intro--with-carousel)) .project__header .grain-fixed-layer {
  --grain-layer-opacity: var(--grain-opacity-intro);
}

.project__intro--with-carousel .project__header .grain-fixed-layer {
  --grain-layer-opacity: var(--grain-opacity-intro);
}

.project-hero-overlay .grain-fixed-host {
  z-index: 2;
}

.project-hero-overlay .grain-fixed-layer {
  --grain-layer-opacity: var(--grain-opacity-intro);
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
ol, ul { list-style: none; }

/* ─────────────────────────────────────────────
   Site header
───────────────────────────────────────────── */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  height: var(--site-header-h);
  box-sizing: border-box;
  padding: 0;
  border-bottom: 1px solid var(--color-border);
  background-color: var(--color-bg);
  display: flex;
  align-items: center;
  transform: translateY(0);
  transition: transform 0.22s ease;
  will-change: transform;
}

.site-header--on-intro {
  border-bottom: none;
  background-color: transparent;
  isolation: isolate;
  box-shadow: none;
  transition:
    transform 0.22s ease,
    box-shadow 0.35s ease;
}

.site-header__backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background-color: var(--image-bg-colour, var(--color-bg));
  transition: opacity 0.35s ease;
}

.site-header--on-intro .site-header__backdrop {
  opacity: 0;
}

.site-header--sticky .site-header__backdrop {
  opacity: 0.9;
}

.site-header--on-intro .grain-fixed-layer {
  --grain-layer-opacity: var(--grain-opacity-intro);
  opacity: 0;
  transition: opacity 0.35s ease;
}

.site-header--sticky .grain-fixed-layer {
  opacity: var(--grain-layer-opacity);
}

.site-header--sticky {
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--image-bg-colour, #333) 18%, transparent),
    0 6px 20px color-mix(in srgb, black 10%, transparent);
}

.site-header__grain {
  z-index: 1;
}

.site-header--on-intro .site-header__inner {
  position: relative;
  z-index: 2;
}

.site-header__name--machina {
  display: inline-block;
  font-family: var(--font-machina);
  font-weight: 800;
  font-size: var(--site-header-name-size);
  line-height: 0.92;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  transform: translateY(var(--header-name-flight-y, 0));
  transform-origin: left center;
  transition: color var(--header-name-transition-ms, 650ms) cubic-bezier(0.4, 0, 0.2, 1);
}

.site-header__name--machina.site-header__name--no-transition {
  transition: none;
}

.site-header__name--on-intro {
  color: #fff !important;
}

.site-header__name--machina.site-header__name--on-transition {
  color: var(--header-name-colour, var(--color-text)) !important;
}

.site-header--on-intro .site-header__name--machina.site-header__name--on-transition {
  color: var(--header-name-colour, var(--color-text)) !important;
}

.site-header--home .site-header__name--machina {
  color: var(--color-text);
}

.site-header--home .site-header__subtitle--default {
  display: none;
}

.site-header--on-intro .site-header__name--machina {
  color: #fff;
}

.site-header__name-clip {
  display: inline-block;
  transform-origin: top left;
}

.site-header--on-intro .site-header__subtitle--default {
  display: none;
}

/* Keep project header contacts hidden until the single reveal at shader handoff.
   Scoping to project-page covers the persisted home header class during arrival. */
body.project-page .site-header .site-header__actions {
  opacity: 0;
  transition: none;
}

html[data-header-contacts='in'] body.project-page .site-header .site-header__actions {
  opacity: 1;
  transition: opacity 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

.site-header__contact-btn--on-intro {
  color: #fff;
  border-color: color-mix(in srgb, white 25%, transparent);
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background-color 0.15s ease;
}

.site-header__contact-btn--on-intro:hover,
.site-header__contact-btn--on-intro:focus-visible {
  color: #fff;
  border-color: color-mix(in srgb, white 25%, transparent);
}

.site-header__contact-btn--on-intro .site-header__contact-dot {
  background: #fff;
}

.site-header__contact-btn--on-intro .site-header__contact-icon {
  color: var(--image-bg-colour, var(--color-bg));
}

.site-header__contact-btn--on-intro:hover .site-header__contact-icon,
.site-header__contact-btn--on-intro:focus-visible .site-header__contact-icon {
  color: var(--image-bg-colour, var(--color-bg));
}

html[data-header-flight] .site-header--home .site-header__name-link.home-hero-reveal-slide {
  transform: none;
  transition: none;
}

html[data-header-flight] .site-header--home {
  border-bottom: none;
  background-color: transparent;
}

html[data-header-flight='out'] .site-header--home .site-header__actions,
html[data-header-flight='in'] .site-header--on-intro .site-header__actions {
  position: static;
  right: auto;
  bottom: auto;
}

/* Name uses FLIP only — never the tile-style home reveal slide. */
html[data-home-reveal] .index-page .site-header .home-hero-reveal-clip {
  overflow: visible;
}

html[data-home-reveal='pending'] .index-page .site-header .home-hero-reveal-slide,
html[data-home-reveal='active'] .index-page .site-header .home-hero-reveal-slide {
  transform: none;
  transition: none;
  transition-delay: 0ms;
}

html[data-transition-phase='project-out'] .site-header,
html[data-transition-phase='home-in'] .site-header,
html[data-header-flight='home'] .site-header {
  z-index: 2002;
  transition: none;
}

html[data-transition-phase='project-out'] .site-header--home,
html[data-header-flight='home'] .site-header--home {
  border-bottom: none;
  background-color: transparent;
}

html[data-transition-phase='project-out'] .site-header--home .site-header__inner,
html[data-header-flight='home'] .site-header--home .site-header__inner {
  padding: 0;
  max-width: none;
}

/* Keep centred project-bar layout until the return flight releases the pin. */
html[data-header-flight='home'] .site-header--on-intro .site-header__inner {
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* During the Y-only drop, match settled home header metrics so the name does not pop. */
html[data-header-home-drop='true'] .site-header.site-header--on-intro {
  height: auto;
  min-height: 0;
  align-items: flex-start;
}

html[data-header-home-drop='true'] .site-header.site-header--on-intro .site-header__inner {
  align-items: flex-start;
}

html[data-transition-phase='project-out'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-transition-phase='home-in'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-header-flight='home'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-page-transition='home-out'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  z-index: 2001;
}

#project-transition-shell [data-hero-blob][data-hero-blob-flight='pinned'] {
  opacity: 1;
  visibility: visible;
}

html[data-header-flight='home'] [data-header-name],
html[data-transition-phase='project-out'] [data-header-name],
html[data-transition-phase='home-in'] [data-header-name] {
  opacity: 1;
  position: relative;
  z-index: 3;
}

html[data-header-flight='home'] .variable-name[data-variable-persist='header'] {
  opacity: 1;
}

/* Home → project: blob above overlay (1000), header/name above blob (1003). */
html[data-transition-phase='home-out'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-transition-phase='project-in'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-header-flight='out'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']),
html[data-header-flight='in'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  z-index: 1002;
}

html[data-transition-phase='home-out'] .site-header,
html[data-transition-phase='project-in'] .site-header,
html[data-header-flight='out'] .site-header,
html[data-header-flight='in'] .site-header {
  z-index: 1003;
}

html[data-header-flight] .site-header__name-clip {
  position: relative;
  z-index: 1;
  isolation: isolate;
}

html[data-header-flight='out'] .site-header--home .site-header__inner,
html[data-page-transition='in'] .site-header--home .site-header__inner {
  padding: 0;
  max-width: none;
}

html[data-page-transition='in'] .site-header--on-intro .site-header__name-link:hover .site-header__name--machina {
  color: color-mix(in srgb, white 82%, transparent);
}

html[data-site-header="hidden"] .site-header {
  transform: translateY(-100%);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--gutter);
  transition: gap 0.45s cubic-bezier(0.4, 0, 0.2, 1);
}

.site-header--home .site-header__inner {
  gap: 0;
}

.site-header--no-back .site-header__inner {
  gap: 0;
}

.site-header__title {
  display: flex;
  align-items: baseline;
  gap: 0.625rem;
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  letter-spacing: normal;
  text-transform: none;
}

html[data-header-flight] .site-header__title,
html[data-page-transition='in'] .site-header__title {
  overflow: visible;
}

.site-header__name {
  flex-shrink: 0;
  color: var(--color-muted);
  transition: color var(--header-name-transition-ms, 650ms) cubic-bezier(0.4, 0, 0.2, 1);
}

.variable-name.site-header__name--project {
  animation: none !important;
  color: var(--header-name-colour, var(--color-muted)) !important;
}

.variable-name.site-header__name--project.site-header__name--no-transition {
  transition: none;
}

.site-header__name-link {
  display: inline-flex;
  align-items: baseline;
  flex-shrink: 0;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

.site-header__name-link:hover .site-header__name {
  color: var(--color-text);
}

.site-header__name-link .variable-name {
  display: inline-block;
  cursor: pointer;
}

.site-header__subtitle {
  min-width: 0;
  font-family: var(--font-sans);
  font-style: normal;
  font-weight: 400;
  font-size: 1.2rem;
  line-height: 1.375;
  letter-spacing: 0.04em;
  color: var(--color-muted);
  overflow: hidden;
  text-overflow: ellipsis;
}

.site-header--home .variable-name.site-header__name {
  color: color-mix(in srgb, var(--color-text) 92%, var(--color-bg));
}

.site-header--home .site-header__subtitle {
  color: var(--color-home-text);
}

.site-header--home .site-header__contact-btn:not(.site-header__contact-btn--project) {
  color: var(--color-home-text);
}

.site-header__back {
  flex-shrink: 0;
  display: block;
  box-sizing: border-box;
  max-width: 6rem;
  text-decoration: none;
  font-size: 0.875rem;
  line-height: 1.375;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  transform: translateX(0);
  transition:
    max-width 0.45s cubic-bezier(0.4, 0, 0.2, 1),
    opacity 0.35s ease,
    transform 0.45s cubic-bezier(0.4, 0, 0.2, 1),
    color 0.15s;
}

.site-header__back:hover { color: var(--color-text); }

.site-header__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-left: auto;
  flex-shrink: 0;
}

.site-header__contact-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.35rem 0.8rem 0.35rem 0.4rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-family: var(--font-serif);
  font-size: var(--text-fluid-xs);
  font-style: italic;
  font-weight: 400;
  line-height: 1;
  letter-spacing: 0.01em;
  text-decoration: none;
  color: var(--color-muted);
  white-space: nowrap;
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background-color 0.15s ease;
}

.site-header__contact-btn--project {
  color: var(--header-contact-colour, var(--color-muted));
  transition: color var(--header-name-transition-ms, 650ms) cubic-bezier(0.4, 0, 0.2, 1);
}

.site-header__contact-btn--project.site-header__contact-btn--no-transition {
  transition: none;
}

.site-header__contact-btn:not(.site-header__contact-btn--on-intro):hover,
.site-header__contact-btn:not(.site-header__contact-btn--on-intro):focus-visible {
  color: var(--color-text);
  border-color: color-mix(in srgb, var(--color-text) 22%, var(--color-border));
  background: color-mix(in srgb, var(--color-surface) 70%, var(--color-bg));
}

.site-header__contact-btn--project:hover,
.site-header__contact-btn--project:focus-visible {
  color: var(--header-contact-colour, var(--color-muted));
  border-color: color-mix(in srgb, var(--header-contact-colour, var(--color-muted)) 35%, var(--color-border));
  background: color-mix(in srgb, var(--header-contact-colour, var(--color-muted)) 8%, var(--color-bg));
}

.site-header__contact-mark {
  position: relative;
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  transition: background-color 0.28s ease;
}

.site-header__contact-dot,
.site-header__contact-icon {
  grid-area: 1 / 1;
}

.site-header__contact-dot {
  width: 0.5625rem;
  height: 0.5625rem;
  border-radius: 50%;
  background: currentColor;
  transition:
    opacity 0.2s ease,
    transform 0.28s cubic-bezier(0.34, 1.2, 0.64, 1);
}

.site-header__contact-icon {
  display: grid;
  place-items: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  opacity: 0;
  transform: scale(0.08);
  transform-origin: center;
  color: var(--color-bg);
  transition:
    opacity 0.2s ease 0.04s,
    transform 0.42s cubic-bezier(0.34, 1.45, 0.64, 1) 0.04s;
}

.site-header__contact-icon svg {
  display: block;
  width: 0.8125rem;
  height: 0.8125rem;
}

.site-header__contact-icon--linkedin svg {
  width: 0.5625rem;
  height: 0.5625rem;
}

.site-header__contact-btn:hover .site-header__contact-mark,
.site-header__contact-btn:focus-visible .site-header__contact-mark {
  background: currentColor;
}

.site-header__contact-btn:hover .site-header__contact-dot,
.site-header__contact-btn:focus-visible .site-header__contact-dot {
  opacity: 0;
  transform: scale(1.5);
}

.site-header__contact-btn:hover .site-header__contact-icon,
.site-header__contact-btn:focus-visible .site-header__contact-icon {
  opacity: 1;
  transform: scale(1);
}

.site-header__contact-btn:not(:hover):not(:focus-visible) .site-header__contact-icon {
  transition:
    opacity 0.16s ease,
    transform 0.2s ease;
}

.site-header__contact-label {
  position: relative;
  top: 0.04em;
}

@media (max-width: 56rem) {
  .site-header__contact-btn {
    gap: 0;
    padding: 0.35rem;
  }

  .site-header__contact-label {
    display: none;
  }

  .site-header__contact-dot {
    display: none;
  }

  .site-header__contact-icon {
    opacity: 1;
    transform: scale(1);
    color: currentColor;
  }

  .site-header__contact-btn:hover .site-header__contact-mark,
  .site-header__contact-btn:focus-visible .site-header__contact-mark {
    background: transparent;
  }

  .site-header__contact-btn:hover .site-header__contact-icon,
  .site-header__contact-btn:focus-visible .site-header__contact-icon {
    color: var(--color-text);
  }

  .site-header__contact-btn--on-intro .site-header__contact-icon,
  .site-header__contact-btn--on-intro:hover .site-header__contact-icon,
  .site-header__contact-btn--on-intro:focus-visible .site-header__contact-icon {
    color: var(--image-bg-colour, var(--color-bg));
  }

  .site-header__contact-btn--project:hover .site-header__contact-icon,
  .site-header__contact-btn--project:focus-visible .site-header__contact-icon {
    color: var(--header-contact-colour, var(--color-muted));
  }
}

.site-header--home .site-header__back--collapsed {
  max-width: 0;
  opacity: 0;
  transform: translateX(-1rem);
  pointer-events: none;
}

/* ─────────────────────────────────────────────
   Index page
───────────────────────────────────────────── */
.index {
  flex: 1;
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* ─────────────────────────────────────────────
   Index top shell
───────────────────────────────────────────── */
.index-top {
  display: block;
  position: relative;
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: calc(var(--space-10) * 2) var(--gutter) calc(var(--space-10) * 2);
}

.index-top .site-header--home {
  position: relative;
  z-index: 2;
  height: auto;
  min-height: 0;
  border-bottom: none;
  background: transparent;
  transform: none;
  margin: 0 0 var(--space-5);
}

[data-header-flight-spacer] {
  display: block;
  pointer-events: none;
}

.index-top .site-header--home .site-header__inner {
  padding: 0;
  max-width: none;
  position: relative;
  z-index: 1;
}

.index-top .site-header--home .site-header__actions,
body.index-page > .site-header--home .site-header__actions,
body.index-page .site-header--on-intro .site-header__actions,
html[data-header-flight='home'] .site-header .site-header__actions {
  display: none;
}

.index-top__actions-clip {
  position: absolute;
  right: var(--gutter);
  bottom: calc(var(--space-10) * 2);
  margin-left: 0;
  z-index: 2;
}

.index-top__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.index-top__actions .site-header__contact-btn {
  color: var(--color-home-text);
}

@media (max-width: 56rem) {
  .index-top {
    padding-top: calc(var(--space-8) * 2);
    padding-bottom: calc(var(--space-10) * 2 + 2.75rem);
  }

  .index-top__actions-clip {
    bottom: calc(var(--space-8) * 2);
  }
}

/* ─────────────────────────────────────────────
   Home hero header
───────────────────────────────────────────── */
@property --hero-blob-colour {
  syntax: '<color>';
  inherits: false;
  initial-value: #e4e4e7;
}

.home-hero-header {
  display: block;
  position: relative;
  z-index: 1;
  isolation: isolate;
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: 0;
}

body.index-page {
  padding-top: 0;
}

.home-hero-header__blob,
.project-grid-blob {
  position: absolute;
  border-radius: 50%;
  --hero-blob-colour: #e4e4e7;
  --hero-blob-opacity: 1;
  --hero-blob-core-alpha: 72%;
  --hero-blob-edge-alpha: 8%;
  /* Inline colour-mix chain — Safari won't interpolate through a derived --hero-blob-gradient-core. */
  background: radial-gradient(
    circle at 18% 18%,
    color-mix(
      in srgb,
      color-mix(
        in srgb,
        color-mix(in srgb, var(--hero-blob-colour) 62%, white) 88%,
        #e8d0b0
      ) var(--hero-blob-core-alpha),
      transparent
    ) 0%,
    color-mix(
      in srgb,
      color-mix(
        in srgb,
        color-mix(in srgb, var(--hero-blob-colour) 62%, white) 88%,
        #e8d0b0
      ) var(--hero-blob-edge-alpha),
      transparent
    ) 68%
  );
  opacity: var(--hero-blob-opacity);
  overflow: hidden;
  isolation: isolate;
  transform-origin: center center;
  transition: --hero-blob-colour 0.65s cubic-bezier(0.16, 1, 0.3, 1);
  translate: 0 var(--hero-blob-parallax-y, 0px);
  will-change: translate;
}

.home-hero-header > .home-hero-header__blob {
  top: calc(-2.5rem - 120px);
  left: calc(-4rem - 50px);
  width: min(16rem, 39vw);
  height: min(16rem, 39vw);
  pointer-events: auto;
  z-index: 0;
}

.home-hero-header__blob--no-transition,
.project-grid-blob--no-transition,
.hero-blob--no-transition {
  transition: none !important;
}

html[data-page-transition='out'] .home-hero-header__blob,
html[data-page-transition='in'] .home-hero-header__blob,
html[data-page-transition='out'] .project-grid-blob,
html[data-page-transition='in'] .project-grid-blob,
html[data-page-transition='out'] .project-header-blob,
html[data-page-transition='in'] .project-header-blob,
html[data-transition-phase='home-out'] .home-hero-header__blob,
html[data-transition-phase='project-in'] .home-hero-header__blob,
html[data-transition-phase='project-out'] .home-hero-header__blob,
html[data-transition-phase='home-out'] .project-grid-blob,
html[data-transition-phase='project-in'] .project-grid-blob,
html[data-transition-phase='project-out'] .project-grid-blob,
html[data-transition-phase='home-out'] .project-header-blob,
html[data-transition-phase='project-in'] .project-header-blob,
html[data-transition-phase='project-out'] .project-header-blob {
  transition: none;
}

@media (prefers-reduced-motion: reduce) {
  .home-hero-header__blob,
  .project-grid-blob,
  .project-header-blob {
    transition: none;
    translate: none;
    will-change: auto;
  }
}

html[data-home-reveal] .index-page .home-hero-header__blob {
  opacity: 1;
  transform: none;
}

html[data-home-reveal] .index-page .project-grid-blob {
  translate: none;
}

html[data-home-reveal] .index-page .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  opacity: 1;
  visibility: visible;
}

.home-hero-header__blob-grain {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: var(--hero-blob-grain-opacity);
  background-color: var(--hero-blob-grain-tint);
  background-image: var(--grain-image);
  --hero-blob-grain-opacity: 0.1;
  background-blend-mode: luminosity;
  mix-blend-mode: lighten;
  background-repeat: repeat;
  background-size: var(--grain-size);
  animation: hero-blob-grain-drift 14s linear infinite;
}

@keyframes hero-blob-grain-drift {
  from {
    background-position: 0 0;
  }

  to {
    background-position: var(--grain-size);
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-hero-header__blob-grain {
    animation: none;
  }
}

.home-hero-header__blob-canvas {
  position: absolute;
  inset: 0;
  display: none;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  clip-path: circle(50% at 50% 50%);
  pointer-events: none;
}

#project-transition-shell {
  pointer-events: none;
}

#project-transition-shell [data-hero-blob] {
  pointer-events: none;
}

.home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  position: fixed;
  margin: 0;
  pointer-events: none;
  z-index: 2;
  opacity: 1;
  transform: none;
  isolation: isolate;
  translate: none;
  will-change: auto;
}

body.project-page .home-hero-header__blob[data-hero-blob-scroll='true'] {
  position: absolute;
  z-index: 0;
  margin: 0;
  pointer-events: none;
  top: calc(-2.5rem - 120px);
  left: calc(-4rem - 50px);
  width: min(16rem, 39vw);
  height: min(16rem, 39vw);
}

html:not([data-header-flight]) body.project-page .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  z-index: 0;
}

html[data-page-transition]:not([data-header-flight]) .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  z-index: 1001;
}

html[data-page-transition='home-out'] .home-hero-header__blob[data-hero-blob-flight='pinned']:not([data-hero-blob-scroll='true']) {
  z-index: 2001;
}

@media (max-width: 56rem) {
  body.project-page .home-hero-header__blob[data-hero-blob-scroll='true'] {
    top: calc(-1.5rem - 120px);
    left: calc(-2.5rem - 50px);
    width: min(11rem, 42.5vw);
    height: min(11rem, 42.5vw);
  }
}

.home-hero-header__name {
  position: relative;
  z-index: 1;
  font-family: var(--font-machina);
  font-weight: 800;
  font-size: var(--text-fluid-3xl-wide);
  line-height: 0.92;
  letter-spacing: -0.025em;
  text-transform: uppercase;
  color: var(--color-text);
  margin: 0;
}

.home-hero-header__name-clip {
  position: relative;
  z-index: 1;
  margin: 0 0 var(--space-5);
}

.home-hero-header__content {
  position: relative;
  z-index: 1;
  width: calc(100% * 2 / 3);
  padding-right: var(--space-10);
}

.home-hero-header__tagline {
  font-family: var(--font-serif);
  font-style: normal;
  font-weight: 300;
  font-size: var(--text-fluid-3xl);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--color-text);
  margin: 0;
}

.home-hero-header__content > .home-hero-reveal-clip:not(:last-child) {
  margin-bottom: var(--space-5);
}

.home-hero-header__tagline strong,
.home-hero-header__tagline em {
  color: inherit;
  font-style: normal;
}

.home-hero-header__body {
  width: 100%;
  max-width: none;
  font-size: var(--text-fluid-sm);
  font-weight: 300;
  line-height: 1.65;
  color: color-mix(in srgb, var(--color-home-text) 88%, var(--color-bg));
}

.home-hero-header__body p {
  margin: 0;
}

.home-hero-header__body strong {
  font-weight: 600;
  color: var(--color-home-text);
}

.home-hero-header__actions-clip {
  position: absolute;
  right: var(--gutter);
  bottom: calc(var(--space-10) * 2);
  margin-left: 0;
}

.home-hero-header__actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

.home-hero-header__actions .site-header__contact-btn:not(.site-header__contact-btn--project) {
  color: var(--color-home-text);
}

@media (max-width: 56rem) {
  .home-hero-header {
    padding-top: calc(var(--space-8) * 2);
    padding-bottom: calc(var(--space-10) * 2 + 2.75rem);
  }

  .home-hero-header__content {
    width: 100%;
    padding-right: var(--space-6);
  }

  .home-hero-header > .home-hero-header__blob {
    top: calc(-1.5rem - 120px);
    left: calc(-2.5rem - 50px);
    width: min(11rem, 42.5vw);
    height: min(11rem, 42.5vw);
  }

  .home-hero-header__actions-clip {
    bottom: calc(var(--space-8) * 2);
  }
}

html[data-home-reveal] .index-page .home-hero-reveal-clip {
  overflow: hidden;
}

/* Hero header — sequenced reveal: name → tagline → body → tiles → blob → contact */
html[data-home-reveal='pending'][data-home-reveal-from='down'] .index-page .home-hero-reveal-slide,
html[data-home-reveal='pending'][data-home-reveal-from='down'] .index-page .project-tile__reveal,
html[data-home-reveal='pending']:not([data-home-reveal-from]) .index-page .home-hero-reveal-slide,
html[data-home-reveal='pending']:not([data-home-reveal-from]) .index-page .project-tile__reveal {
  transform: translateY(100%);
  transition: none;
}

html[data-home-reveal='pending'][data-home-reveal-from='up'] .index-page .home-hero-reveal-slide,
html[data-home-reveal='pending'][data-home-reveal-from='up'] .index-page .project-tile__reveal {
  transform: translateY(-100%);
  transition: none;
}

html[data-home-reveal='pending'][data-home-reveal-from='left'] .index-page .home-hero-reveal-slide,
html[data-home-reveal='pending'][data-home-reveal-from='left'] .index-page .project-tile__reveal {
  transform: translateX(-100%);
  transition: none;
}

html[data-home-reveal='pending'][data-home-reveal-from='right'] .index-page .home-hero-reveal-slide,
html[data-home-reveal='pending'][data-home-reveal-from='right'] .index-page .project-tile__reveal {
  transform: translateX(100%);
  transition: none;
}

html[data-home-reveal='pending'] .index-page .home-hero-reveal-grow {
  opacity: 0;
  transform: scale(0.55);
  transition: none;
}

html[data-home-reveal='active'] .index-page .home-hero-reveal-slide,
html[data-home-reveal='active'] .index-page .project-tile__reveal {
  transform: translate3d(0, 0, 0);
  transition: transform 0.75s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(
    var(--home-reveal-lead, 0ms)
    + var(--home-reveal-base, 60ms)
    + var(--reveal-index, 0) * var(--home-reveal-stagger, 90ms)
  );
}

html[data-home-reveal='active'] .index-page .home-hero-reveal-grow {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(
    var(--home-reveal-lead, 0ms)
    + var(--home-reveal-base, 60ms)
    + var(--reveal-index, 0) * var(--home-reveal-stagger, 90ms)
  );
}

@media (prefers-reduced-motion: reduce) {
  html[data-home-reveal='active'] .index-page .home-hero-reveal-slide,
  html[data-home-reveal='active'] .index-page .home-hero-reveal-grow {
    transition: none;
    transition-delay: 0ms;
  }

  html[data-home-reveal='pending'] .index-page .home-hero-reveal-slide {
    transform: none;
  }

  html[data-home-reveal='pending'] .index-page .home-hero-reveal-grow {
    opacity: 1;
    transform: scale(1);
  }
}

.home-hero-blob-pane__shell {
  position: fixed;
  left: 0.75rem;
  bottom: 0.75rem;
  z-index: 9998;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-start;
  gap: 0.45rem;
}

.home-hero-blob-pane__toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-bg) 92%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 2px 12px rgb(0 0 0 / 0.08);
  cursor: pointer;
  color: var(--color-muted);
  transition:
    color 0.15s,
    border-color 0.15s,
    background 0.15s;
}

.home-hero-blob-pane__toggle:hover,
.home-hero-blob-pane__toggle[data-open='true'] {
  color: var(--color-text);
  border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border));
}

.home-hero-blob-pane__toggle[data-open='true'] {
  background: color-mix(in srgb, var(--color-accent) 10%, var(--color-bg));
}

.home-hero-blob-pane__toggle span {
  font-size: 0.9rem;
  line-height: 1;
}

.home-hero-blob-pane {
  width: min(16rem, calc(100vw - 1.5rem));
  max-height: min(70vh, 32rem);
  overflow: auto;
}

.home-hero-blob-pane .tp-dfwv {
  position: static !important;
  width: 100% !important;
  max-height: none;
}

/* ─────────────────────────────────────────────
   Project grid (homepage)
───────────────────────────────────────────── */
.project-grid-wrap {
  position: relative;
}

.project-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-bottom: 2rem;
}

.project-grid .project-tile {
  position: relative;
  z-index: 1;
  aspect-ratio: 3 / 4;
}

.project-grid-blob-wrap {
  position: absolute;
  top: 76%;
  right: -6.75rem;
  width: min(11.25rem, 27vw);
  height: min(11.25rem, 27vw);
  z-index: 0;
  pointer-events: none;
}

.project-grid-blob-wrap > .project-grid-blob {
  inset: 0;
}

.project-grid-blob-wrap > .project-grid-blob--secondary {
  inset: auto;
  width: min(3.5rem, 8.5vw);
  height: min(3.5rem, 8.5vw);
  bottom: -2.5rem;
  left: -2.25rem;
}

@media (max-width: 56rem) {
  .project-grid {
    grid-template-columns: 1fr;
    gap: clamp(0.75rem, 3vw, 1rem);
  }

  .project-grid-blob-wrap {
    top: 80%;
    right: -4.5rem;
    width: min(8.25rem, 31.875vw);
    height: min(8.25rem, 31.875vw);
  }

  .project-grid-blob-wrap > .project-grid-blob--secondary {
    width: min(2.5rem, 9.5vw);
    height: min(2.5rem, 9.5vw);
    bottom: -0.35rem;
    left: -1.5rem;
  }
}

.project-tile {
  position: relative;
  display: block;
  aspect-ratio: 1;
  text-decoration: none;
  color: inherit;
  --tile-colour-glow-y: 10px;
  --tile-colour-glow-blur: 26px;
  --tile-colour-glow-alpha: 22%;
}

body:not(.index-page) .project-tile:hover,
html[data-home-tile-shadows='in'] .index-page .project-tile:hover {
  --tile-colour-glow-y: 18px;
  --tile-colour-glow-blur: 44px;
  --tile-colour-glow-alpha: 58%;
}

.project-tile__reveal {
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

.project-tile__stage {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateX(var(--tile-tilt-y, 0deg)) rotateY(var(--tile-tilt-x, 0deg));
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.project-tile[data-transitioning="true"] .project-tile__stage {
  transform: none;
  transition: none;
}

/* z=0 aperture frame — rides the stage tilt so the clipped edge reads as the tile's front face */
.project-tile__backdrop {
  --tile-z: 0;
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: translateZ(calc(var(--tile-z) * 1px))
    scale(calc((var(--tile-perspective) - var(--tile-z)) / var(--tile-perspective)));
  pointer-events: none;
  -webkit-filter:
    drop-shadow(0 8px 18px rgb(0 0 0 / 0.11))
    drop-shadow(0 2px 4px rgb(0 0 0 / 0.05))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
  filter:
    drop-shadow(0 8px 18px rgb(0 0 0 / 0.11))
    drop-shadow(0 2px 4px rgb(0 0 0 / 0.05))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
  transition:
    --tile-colour-glow-y 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    --tile-colour-glow-blur 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    --tile-colour-glow-alpha 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Homepage entry — tile content is always visible; shadows wait until reveal settles */
.index-page .project-tile__backdrop {
  -webkit-filter: none;
  filter: none;
  transition: filter 0.55s ease-out;
}

html[data-home-tile-shadows='in'] .index-page .project-tile__backdrop {
  -webkit-filter:
    drop-shadow(0 8px 18px rgb(0 0 0 / 0.11))
    drop-shadow(0 2px 4px rgb(0 0 0 / 0.05))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
  filter:
    drop-shadow(0 8px 18px rgb(0 0 0 / 0.11))
    drop-shadow(0 2px 4px rgb(0 0 0 / 0.05))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
  transition:
    filter 0.55s ease-out,
    --tile-colour-glow-y 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    --tile-colour-glow-blur 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    --tile-colour-glow-alpha 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.project-tile__viewport {
  --tile-perspective: 1000;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  perspective: calc(var(--tile-perspective) * 1px);
  perspective-origin: center center;
}

/* Registered so spring-back eases the parallax vars themselves, driving both
   the perspective-origin and the glass reflection in lockstep */
@property --tile-parallax-x {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 0%;
}

@property --tile-parallax-y {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 0%;
}

@property --tile-colour-glow-y {
  syntax: '<length>';
  inherits: true;
  initial-value: 10px;
}

@property --tile-colour-glow-blur {
  syntax: '<length>';
  inherits: true;
  initial-value: 26px;
}

@property --tile-colour-glow-alpha {
  syntax: '<percentage>';
  inherits: true;
  initial-value: 22%;
}

/* Clips at the (tilting) aperture, then renders its own recessed scene inside:
   overflow flattens preserve-3d, so depth comes from a local perspective whose
   origin is steered by the pointer — parallax without escaping the clip */
.project-tile__depth {
  position: absolute;
  inset: 0;
  --corner-shape: squircle;
  border-radius: var(--squircle-tile);
  overflow: hidden;
  isolation: isolate;
  perspective: calc(var(--tile-perspective) * 1px);
  perspective-origin: calc(50% + var(--tile-parallax-x, 0%)) calc(50% + var(--tile-parallax-y, 0%));
  transition:
    --tile-parallax-x 0.45s cubic-bezier(0.22, 1, 0.36, 1),
    --tile-parallax-y 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Light pass over the background stack only — sits between the grain and the
   thumbnail in paint order, so the reflection shades the recessed backdrop
   while the screenshot stays clean */
.project-tile__light {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: soft-light;
  background:
    radial-gradient(
      130% 100% at calc(50% - var(--tile-parallax-x, 0%) * 1.1) calc(25% - var(--tile-parallax-y, 0%) * 1.1),
      rgb(255 255 255 / 0.68),
      rgb(255 255 255 / 0.26) 45%,
      transparent 75%
    ),
    linear-gradient(115deg, rgb(255 255 255 / 0.42) 0%, rgb(255 255 255 / 0) 45%);
}

.project-tile[data-transitioning="true"] .project-tile__depth {
  perspective-origin: center center;
  transition: none;
}

/* Recessed position; scale compensates so the layer appears tile-sized at rest */
.project-tile__plane {
  position: absolute;
  inset: 0;
  transform: translateZ(calc(var(--tile-z) * 1px))
    scale(calc((var(--tile-perspective) - var(--tile-z)) / var(--tile-perspective)));
}

.project-tile__plane-surface {
  position: absolute;
  inset: 0;
}

/* Deep layers bleed far past the aperture so their own edges never parallax into view */
.project-tile__plane--tint .project-tile__plane-surface,
.project-tile__plane--bloom .project-tile__plane-surface,
.project-tile__plane--grain .project-tile__plane-surface {
  inset: -40%;
}

.project-tile__plane--tint {
  --tile-z: -520;
}

.project-tile__plane--bloom {
  --tile-z: -420;
}

.project-tile__plane--grain {
  --tile-z: -420;
}

.project-tile__plane--thumb {
  --tile-z: -120;
  pointer-events: none;
}

.project-tile__plane--scrim {
  --tile-z: -16;
}

.project-tile__tint {
  background: var(--image-bg-colour, #333);
}

.project-tile__bloom-canvas {
  width: 100%;
  height: 100%;
  display: block;
}

.project-tile__grain {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--grain-opacity-intro);
  background-image: var(--grain-image);
  background-repeat: repeat;
  background-size: var(--grain-size);
}

.project-tile__thumb-host {
  position: absolute;
  top: 20%;
  left: 20%;
  width: 150%;
  display: grid;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.project-tile__thumb-host--vertical {
  top: 14%;
  left: 25%;
  width: 50%;
}

.project-tile__thumb-host > .squircle-shadow-filter,
.project-tile__thumb-host > .project-tile__thumb-wrap {
  grid-area: 1 / 1;
  width: 100%;
}

.project-tile__thumb-host .squircle-shadow-filter {
  -webkit-filter:
    drop-shadow(0 8px 24px rgb(0 0 0 / 0.16))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.09));
  filter:
    drop-shadow(0 8px 24px rgb(0 0 0 / 0.16))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.09));
}

.project-tile__thumb-host .squircle-shadow-plate {
  border-radius: var(--squircle-card);
}

.project-tile__thumb-wrap {
  position: relative;
  top: auto;
  left: auto;
  width: 100%;
  pointer-events: none;
  transition: opacity 0.2s ease;
  --corner-shape: squircle;
  border-radius: var(--squircle-card);
  overflow: hidden;
}

.project-tile__thumb-wrap--plain {
  --corner-shape: initial;
  border-radius: 0;
  overflow: visible;
}

.project-tile__thumb-host--vertical .squircle-shadow-plate {
  border-radius: var(--squircle-thumb-vertical);
  background: var(--image-bg-colour, #333);
}

.project-tile__thumb-host--vertical .project-tile__thumb-wrap {
  border-radius: var(--squircle-thumb-vertical);
  background: var(--image-bg-colour, #333);
  isolation: isolate;
}

.project-tile__thumb-host--plain .project-tile__thumb {
  -webkit-filter:
    drop-shadow(0 8px 24px rgb(0 0 0 / 0.16))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.09));
  filter:
    drop-shadow(0 8px 24px rgb(0 0 0 / 0.16))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.09));
}

.project-tile__thumb {
  display: block;
  width: 100%;
  height: auto;
  /* Promote to its own layer so Safari decodes/paints inside the 3D stack sooner */
  transform: translateZ(0);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.project-tile__scrim {
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--image-bg-colour, #333) 88%, black) 0%,
    color-mix(in srgb, var(--image-bg-colour, #333) 35%, transparent) 55%,
    color-mix(in srgb, var(--image-bg-colour, #333) 15%, transparent) 100%
  );
}

.project-tile__content {
  --tile-z: 120;
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: clamp(1rem, 3vw, 1.35rem);
  transform-style: preserve-3d;
  transform: translateZ(calc(var(--tile-z) * 1px))
    scale(calc((var(--tile-perspective) - var(--tile-z)) / var(--tile-perspective)));
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.project-tile__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
}

.project-tile__tags .tag {
  font-size: 0.5625rem;
  letter-spacing: 0.06em;
  padding: 0.2em 0.45em;
  border-radius: 3px;
  background: color-mix(in srgb, var(--image-bg-colour, #333) 90%, black);
  color: var(--chip-fg, #fff);
}

.project-tile__text {
  margin-top: auto;
}

.project-tile__title {
  font-family: var(--font-serif);
  font-style: normal;
  font-size: var(--text-fluid-3xl);
  font-weight: 300;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: #fff;
  margin-bottom: 0.35rem;
}

.project-tile__subtitle {
  font-size: var(--text-fluid-xs);
  line-height: 1.35;
  color: color-mix(in srgb, white 82%, transparent);
}

/* Password-protected tiles */
.project-tile__lock {
  --tile-z: -8;
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: rgb(255 255 255 / 0.92);
  opacity: 0;
  pointer-events: none;
  transform: translateZ(calc(var(--tile-z) * 1px))
    scale(calc((var(--tile-perspective) - var(--tile-z)) / var(--tile-perspective)));
  filter: drop-shadow(0 2px 8px rgb(0 0 0 / 0.35));
  transition: opacity 0.25s ease;
}

html:not([data-portfolio-unlocked]) .project-tile[data-password-protected="true"] .project-tile__lock {
  opacity: 1;
}

html:not([data-portfolio-unlocked]) .project-tile[data-password-protected="true"] .project-tile__thumb-host,
html:not([data-portfolio-unlocked]) .project-tile[data-password-protected="true"] .project-tile__bloom-canvas {
  filter: blur(14px);
}

/* ─────────────────────────────────────────────
   Project unlock gate
───────────────────────────────────────────── */
html[data-project-locked] .project[data-password-protected] .project__header,
html[data-project-locked] .project[data-password-protected] .project__body,
html[data-project-locked] .project[data-password-protected] .project-furniture {
  filter: blur(16px);
  pointer-events: none;
  user-select: none;
}

.project-unlock {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  padding: var(--gutter);
  background: rgb(247 246 243 / 0.72);
  backdrop-filter: blur(10px);
}

.project-unlock__panel {
  width: min(24rem, 100%);
  padding: 1.75rem;
  border: 1px solid var(--color-border);
  border-radius: calc(12px * var(--corner-scale, 1));
  background: var(--color-bg);
  box-shadow: 0 18px 48px rgb(24 24 27 / 0.08);
}

.project-unlock__icon {
  color: var(--color-muted);
  margin-bottom: 0.75rem;
}

.project-unlock__title {
  font-family: var(--font-serif);
  font-style: normal;
  font-size: var(--text-fluid-2xl);
  font-weight: 300;
  margin-bottom: 0.5rem;
}

.project-unlock__text {
  font-size: var(--text-fluid-sm);
  line-height: 1.5;
  color: var(--color-muted);
  margin-bottom: 1.25rem;
}

.project-unlock__form {
  display: grid;
  gap: 0.65rem;
}

.project-unlock__label {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.project-unlock__input {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: #fff;
  font: inherit;
  color: var(--color-text);
}

.project-unlock__input:focus {
  outline: 2px solid color-mix(in srgb, var(--color-accent) 20%, transparent);
  outline-offset: 1px;
  border-color: color-mix(in srgb, var(--color-accent) 35%, var(--color-border));
}

.project-unlock__error {
  font-size: var(--text-fluid-xs);
  color: #b42318;
}

.project-unlock__submit {
  margin-top: 0.35rem;
  padding: 0.75rem 1rem;
  border: 0;
  border-radius: 8px;
  background: var(--color-accent);
  color: #fff;
  font: inherit;
  font-size: var(--text-fluid-sm);
  cursor: pointer;
}

.project-unlock__submit:hover {
  background: color-mix(in srgb, var(--color-accent) 88%, white);
}

/* ─────────────────────────────────────────────
   Page transition
───────────────────────────────────────────── */
.project-hero-overlay {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
}

.project-hero-overlay--active {
  opacity: 1;
  visibility: visible;
}

html[data-page-transition="in"][data-reveal="pending"]:not([data-shader-handoff]) .project__header-bloom {
  opacity: 0 !important;
}

html[data-shader-handoff="active"] .project-hero-overlay--active {
  opacity: 0;
  transition: opacity 0.9s ease;
}

html[data-shader-handoff="active"] .project__header-bloom {
  opacity: 1 !important;
  transition: opacity 0.9s ease;
}

html[data-page-transition="in"] {
  background-color: var(--transition-tint, var(--color-bg));
}

html[data-page-transition="in"]:not([data-header-flight]) .site-header {
  z-index: 1001;
}

html[data-page-transition="in"][data-header-flight='out'] .site-header,
html[data-page-transition="in"][data-header-flight='in'] .site-header {
  z-index: 1003;
}

html[data-page-transition="in"] .site-header--home,
html[data-page-transition="in"] .site-header--on-intro {
  background-color: transparent;
  border-bottom: none;
}

html[data-page-transition="in"]:not([data-header-back="in"]) .site-header__inner {
  gap: 0;
}

html[data-page-transition="in"]:not([data-header-back="in"]) .site-header__back {
  max-width: 0;
  opacity: 0;
  transform: translateX(-1rem);
}

html[data-page-transition="in"][data-header-back="in"] .site-header__inner {
  gap: 1.25rem;
}

html[data-page-transition="in"][data-header-back="in"] .site-header__back {
  max-width: 6rem;
  opacity: 1;
  transform: translateX(0);
}

.project-hero-overlay__snapshot {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  display: block;
  pointer-events: none;
  opacity: 0;
}

.project-hero-overlay__snapshot.project-hero-overlay__snapshot--valid {
  opacity: 1;
}

/* Flat tint is the fallback until the bloom snapshot has decoded and is visible.
   Keying off --valid (not merely the snapshot's presence) keeps the tint opaque
   through decode, avoiding a transparent gap that flashes the page behind it. */
.project-hero-overlay:has(.project-hero-overlay__snapshot--valid) .project-hero-overlay__tint {
  opacity: 0;
}

.project-hero-overlay__scrim {
  position: absolute;
  inset: 0;
  opacity: 0;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--image-bg-colour, #333) 88%, black) 0%,
    color-mix(in srgb, var(--image-bg-colour, #333) 35%, transparent) 55%,
    color-mix(in srgb, var(--image-bg-colour, #333) 15%, transparent) 100%
  );
}

.project-hero-overlay:has(.project-hero-overlay__snapshot--valid) .project-hero-overlay__scrim,
.project-hero-overlay:not(:has(.project-hero-overlay__snapshot)) .project-hero-overlay__scrim {
  opacity: 1;
}

.project-hero-overlay__tint {
  position: absolute;
  inset: 0;
  background: var(--image-bg-colour, #333);
}

.project-hero-overlay__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

.project-hero-overlay__thumb-wrap {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 100%;
  transform: translate(-50%, -50%);
  --corner-shape: squircle;
  border-radius: var(--squircle-card);
  overflow: hidden;
  pointer-events: none;
}

.project-hero-overlay__thumb {
  display: block;
  width: 100%;
  height: auto;
}

html[data-page-transition="out"] .site-header--on-intro,
html[data-header-flight='out'] .site-header--on-intro {
  background-color: transparent;
  border-bottom: none;
}

html[data-page-transition="out"] .project-tile:not([data-transitioning="true"]) {
  pointer-events: none;
}

html[data-page-transition="out"] .project-tile[data-transitioning="true"] {
  position: relative;
  z-index: 10;
}

.home-exit-overlay {
  position: fixed;
  inset: 0;
  z-index: 2000;
  background: var(--color-bg);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.home-exit-overlay--active {
  visibility: visible;
}

.home-exit-overlay--fade {
  opacity: 1;
  transition: opacity 0.45s ease;
}

html[data-home-reveal] .index-page .project-tile[data-home-reveal-clip] {
  overflow: hidden;
  isolation: isolate;
  --corner-shape: squircle;
  border-radius: var(--squircle-tile);
}

@supports (corner-shape: squircle) {
  html[data-home-reveal] .index-page .project-tile[data-home-reveal-clip] {
    corner-shape: squircle;
  }
}

html[data-home-reveal="pending"] .home-reveal-after {
  opacity: 0;
}

html[data-home-reveal="active"] .home-reveal-after {
  opacity: 1;
  transition: opacity 0.55s ease;
  transition-delay: var(--home-after-delay, 0ms);
}

html[data-reveal="pending"] .project__header-aside,
html[data-reveal="pending"] .project__body.prose > *,
html[data-reveal="pending"] .site-footer,
html[data-reveal="pending"] .project-furniture {
  opacity: 0;
}

html[data-reveal="pending"] .project__header-text .project__title,
html[data-reveal="pending"] .project__header-text .project__subtitle,
html[data-reveal="pending"] .project__header-text .project__details {
  visibility: hidden;
}

html[data-reveal] .project-header-reveal-clip {
  overflow: hidden;
  display: flow-root;
}

html[data-reveal] .project-header-reveal-slide {
  display: flow-root;
}

/* Keep spacing on the stationary clip — child margins collapse through wrappers otherwise */
html[data-reveal] .project-header-reveal-clip:has(.project__title) {
  margin-bottom: var(--space-3);
}

html[data-reveal] .project-header-reveal-clip:has(.project__subtitle) {
  margin-bottom: var(--space-8);
}

html[data-reveal] .project-header-reveal-slide > .project__title,
html[data-reveal] .project-header-reveal-slide > .project__subtitle,
html[data-reveal] .project-header-reveal-slide > .project__details {
  margin-bottom: 0;
}

html[data-reveal="pending"] .project-header-reveal-slide {
  transform: translateY(100%);
  transition: none;
}

html[data-reveal="header-active"] .project-reveal-item--header .project-header-reveal-slide,
html[data-reveal="body-active"] .project-reveal-item--header .project-header-reveal-slide {
  transform: translateY(0);
  transition: transform 0.75s cubic-bezier(0.16, 1, 0.3, 1);
  transition-delay: calc(var(--reveal-index, 0) * 90ms + 60ms);
}

/* Header carousel panel grain stays visible during transition; media reveals separately */
html[data-reveal="pending"] .carousel--header,
html[data-reveal="header-active"] .carousel--header {
  opacity: 1;
  transform: none;
}

html[data-reveal="pending"] .carousel--header .carousel__viewport,
html[data-reveal="pending"] .carousel--header .carousel__meta--inside,
html[data-reveal="header-active"] .carousel--header .carousel__viewport,
html[data-reveal="header-active"] .carousel--header .carousel__meta--inside {
  opacity: 0;
}

html[data-reveal="header-active"] .project-furniture {
  opacity: 0;
}

html[data-reveal="pending"] .project-reveal-item:not(.project-header-reveal-clip),
html[data-reveal="header-active"] .project-reveal-item--body:not(.project-header-reveal-clip) {
  opacity: 0;
  transform: translateY(8px);
}

html[data-reveal="header-active"] .project-reveal-item--header:not(.project-header-reveal-clip),
html[data-reveal="body-active"] .project-reveal-item--header:not(.project-header-reveal-clip) {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.55s ease,
    transform 0.55s ease;
  transition-delay: calc(var(--reveal-index, 0) * 55ms + 60ms);
}

html[data-reveal="body-active"] .project-reveal-item--body {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.55s ease,
    transform 0.55s ease;
  transition-delay: calc(var(--reveal-index, 0) * 55ms + 60ms);
}

html[data-reveal="header-active"] .project__header-text,
html[data-reveal="header-active"] .project-header-reveal-clip,
html[data-reveal="header-active"] .project__header-aside,
html[data-reveal="body-active"] .project__header-text,
html[data-reveal="body-active"] .project-header-reveal-clip,
html[data-reveal="body-active"] .project__header-aside,
html[data-reveal="body-active"] .carousel--header {
  position: relative;
  z-index: 1002;
}

html[data-reveal="body-active"] .project-reveal-item--body:not(.project-furniture) {
  position: relative;
  z-index: 1002;
}

html[data-reveal="pending"] .project-furniture.project-reveal-item,
html[data-reveal="header-active"] .project-furniture.project-reveal-item--body,
html[data-reveal="body-active"] .project-furniture.project-reveal-item--body {
  position: absolute;
}

@media (prefers-reduced-motion: reduce) {
  .project-tile__stage,
  .project-tile__depth {
    transition: none;
  }

  html[data-home-reveal="active"] .index-page .project-tile__reveal,
  html[data-home-reveal="active"] .home-reveal-after {
    transition: none;
    transition-delay: 0ms;
  }

  html[data-home-reveal="pending"] .index-page .project-tile__reveal {
    transform: none;
  }

  html[data-home-tile-shadows='in'] .index-page .project-tile__backdrop {
    transition: none;
  }

  .project-tile__backdrop {
    transition: none;
  }

  .site-header__back,
  .site-header__inner,
  .site-header__name,
  .site-header__contact-dot,
  .site-header__contact-icon,
  .site-header__contact-mark,
  .site-header__contact-btn {
    transition: none;
    transition-delay: 0ms;
  }

  html[data-page-transition="in"] .site-header__inner {
    gap: 1.25rem;
  }

  html[data-page-transition="in"] .site-header__back {
    max-width: 6rem;
    opacity: 1;
    transform: translateX(0);
  }

  html[data-reveal="header-active"] .project-reveal-item--header:not(.project-header-reveal-clip),
  html[data-reveal="body-active"] .project-reveal-item--header:not(.project-header-reveal-clip),
  html[data-reveal="body-active"] .project-reveal-item--body {
    transition: none;
    transition-delay: 0ms;
  }

  html[data-reveal="pending"] .project-reveal-item:not(.project-header-reveal-clip),
  html[data-reveal="header-active"] .project-reveal-item--body:not(.project-header-reveal-clip) {
    transform: none;
  }

  html[data-reveal="pending"] .project-header-reveal-slide,
  html[data-reveal="header-active"] .project-header-reveal-slide,
  html[data-reveal="body-active"] .project-header-reveal-slide {
    transform: none;
    transition: none;
    transition-delay: 0ms;
  }

  html[data-shader-handoff="active"] .project-hero-overlay--active,
  html[data-shader-handoff="active"] .project__header-bloom {
    transition: none;
  }

  .home-exit-overlay--fade {
    transition: none;
  }
}

/* ─────────────────────────────────────────────
   Tags
───────────────────────────────────────────── */
.tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6875rem;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  padding: 0.3em 0.7em;
  border-radius: 4px;
  background: #ddeaf8;
  color: #4a6f96;
  line-height: 1;
}

.has-highlight {
  --chip-bg: color-mix(in srgb, var(--image-bg-colour, #333) 90%, black);
}

.has-highlight .tag {
  background: var(--chip-bg);
  color: var(--chip-fg, #fff);
}

.project.has-highlight .project__title {
  color: #fff;
}

.project.has-highlight .prose h2 {
  background: linear-gradient(
    to top right,
    var(--image-bg-colour, var(--color-bg)),
    var(--project-highlight)
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ─────────────────────────────────────────────
   Project page
───────────────────────────────────────────── */
.project-furniture {
  position: absolute;
  pointer-events: none;
  user-select: none;
  will-change: translate;
}

.project-furniture--top {
  top: 320px;
  right: calc(var(--content-outset) - 10px);
  z-index: 1;
  animation: furniture-parallax-slow linear both;
  animation-timeline: scroll(root);
  animation-range: 0% 100%;
}

.project-furniture--bottom {
  bottom: 100px;
  left: 0;
  z-index: 2;
  animation: furniture-parallax-fast linear both;
  animation-timeline: scroll(root);
  animation-range: 0% 100%;
}

.project-furniture img {
  max-width: none;
  width: auto;
  height: auto;
  max-width: 200px;
  max-height: 200px;
}

@keyframes furniture-parallax-slow {
  from { translate: 0 0; }
  to { translate: 0 48px; }
}

@keyframes furniture-parallax-fast {
  from { translate: 0 0; }
  to { translate: 0 -48px; }
}

@media (prefers-reduced-motion: reduce) {
  .project-furniture {
    animation: none;
    will-change: auto;
  }
}

.project {
  flex: 1;
  max-width: var(--max-w);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--gutter) calc(var(--space-unit) * 24);
}

.project__header {
  padding: calc(var(--space-12) + var(--space-4)) 0 var(--space-12);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: calc(var(--space-unit) * 14);
}

.project__header-bloom {
  display: none;
}

/* ── Project intro (header + optional top carousel) ── */
.project__intro--text-only .project__header {
  display: grid;
  grid-template-columns: minmax(0, var(--prose-w)) minmax(0, 1fr);
  column-gap: var(--space-10);
  align-items: start;
}

.project__intro--text-only .project__header-aside {
  display: block;
  justify-self: end;
  width: 100%;
  max-width: var(--side-rail-max-w);
}

.project__intro--text-only .project__header-aside .features-card {
  margin: 0;
}

.project:has(.project__header-aside) .project__body > .features-card {
  display: none;
}

@media (max-width: 56rem) {
  .project__intro--text-only .project__header {
    grid-template-columns: 1fr;
  }

  .project__intro--text-only .project__header-aside {
    justify-self: stretch;
    max-width: 100%;
    margin-top: var(--space-8);
  }
}

.project-page:has(.project__intro--with-carousel) {
  padding-top: 0;
}

.project-page:has(.project__intro--with-carousel) .site-header--on-intro {
  z-index: 3;
}

.project-page:has(.project__intro--with-carousel) .project__intro--with-carousel {
  margin-top: calc(var(--site-header-h) * -1);
  padding-top: var(--site-header-h);
}

.project-page:has(.project__intro--text-only) .project__intro--text-only {
  margin-top: calc(var(--site-header-h) * -1);
  padding-top: var(--site-header-h);
}

.project-page:has(.project__intro--text-only) .project__intro--text-only .project__header {
  background: var(--image-bg-colour, var(--color-bg));
}

.project-page:has(.project__intro--text-only) .site-header--on-intro {
  z-index: 3;
}

.project-page:has(.project__intro--with-carousel) .site-header {
  z-index: 2;
}

.project:has(.project__intro--with-carousel) {
  position: relative;
  isolation: isolate;
}

.project__intro--with-carousel {
  position: relative;
  isolation: isolate;
  width: 100vw;
  max-width: 100vw;
  left: 50%;
  margin-left: -50vw;
  margin-right: -50vw;
  margin-bottom: 0;
  z-index: 1;
}

.project__intro--with-carousel .project__header {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, var(--prose-w)) minmax(0, 1fr);
  column-gap: var(--space-10);
  align-items: start;
  padding: calc(clamp(var(--space-10), 4vw, calc(var(--space-unit) * 14)) + var(--space-12) + var(--space-4)) var(--content-inset) 0;
  background: transparent;
  --header-carousel-tint: color-mix(in srgb, var(--image-bg-colour, #333) 90%, black);
  border-bottom: none;
  margin-bottom: 0;
  overflow: hidden;
  z-index: 1;
}

.project__intro--with-carousel .project__header-bloom {
  display: block;
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--image-bg-colour, var(--color-bg));
}

.project__intro--with-carousel .project__header-bloom-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.project__intro--with-carousel .project__header-text {
  grid-column: 1;
  grid-row: 1;
  position: relative;
  z-index: 2;
  min-width: 0;
  max-width: var(--prose-w);
}

.project__intro--with-carousel .project__title {
  font-size: var(--text-fluid-5xl);
  color: #fff;
}

.project__intro--with-carousel .project__subtitle {
  font-size: var(--text-fluid-2xl);
  color: color-mix(in srgb, white 82%, transparent);
}

.project__intro--with-carousel .project__header-aside .features-card {
  margin: 0;
  background: color-mix(in srgb, var(--image-bg-colour, #333) 22%, transparent);
  border: 1px solid color-mix(in srgb, white 12%, transparent);
  box-shadow: none;
}

.project__intro--with-carousel .project__header-aside {
  display: block;
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  justify-self: end;
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--side-rail-max-w);
  margin-top: 0;
}

.project__intro--with-carousel .project__details,
.project__intro--with-carousel .project__details dd {
  color: #fff;
}

.project__intro--with-carousel .project__details dt {
  color: color-mix(in srgb, white 68%, transparent);
}

.project__intro--with-carousel .project__tags .tag {
  background: var(--chip-bg, var(--header-carousel-tint));
  color: var(--chip-fg, #fff);
}

.project__intro--with-carousel .project__header-aside .features-card__label,
.project__intro--with-carousel .project__header-aside .feature__text {
  color: #fff;
}

.project__intro--with-carousel .project__header-aside .features-card__label {
  color: color-mix(in srgb, white 72%, transparent);
}

.project__intro--with-carousel .project__header-aside .feature__icon {
  background: linear-gradient(
    to top right,
    color-mix(in srgb, white 65%, transparent),
    #fff
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.project__intro--with-carousel .carousel--header {
  position: relative;
  z-index: 1;
  --grain-opacity: var(--grain-opacity-intro);
}

.project__intro--with-carousel .carousel .carousel__media--desktop-mobile {
  justify-content: flex-start;
  padding-inline-start: var(--carousel-align-inset, var(--content-inset));
  padding-inline-end: var(--content-inset);
}

.project__body .carousel--inherits-image-bg .carousel__panel {
  background: var(--image-bg-colour, #333);
}

@media (max-width: 56rem) {
  .project__intro--with-carousel .project__header {
    grid-template-columns: 1fr;
  }

  .project__intro--with-carousel .project__header-text,
  .project__intro--with-carousel .project__header-aside {
    grid-column: auto;
    grid-row: auto;
  }

  .project__intro--with-carousel .project__header-aside {
    justify-self: stretch;
    max-width: 100%;
    margin-top: var(--space-8);
  }
}

.project__header-text {
  position: relative;
  z-index: 1;
  min-width: 0;
  max-width: var(--prose-w);
}

.project-carousel-blob-wrap {
  position: relative;
  overflow: hidden;
}

.project-carousel-blob-wrap .project-header-blob {
  position: absolute;
  bottom: -1.5rem;
  right: calc(var(--content-outset) + var(--gutter) - 6.75rem);
  width: min(5rem, 11.5vw);
  height: min(5rem, 11.5vw);
  z-index: 2;
  pointer-events: none;
  translate: none;
}

@media (max-width: 56rem) {
  .project-carousel-blob-wrap .project-header-blob {
    bottom: -1rem;
    right: calc(var(--content-outset) + var(--gutter) - 4.5rem);
    width: min(3.75rem, 13.5vw);
    height: min(3.75rem, 13.5vw);
  }
}

.project__header-text > :not([data-hero-blob]) {
  position: relative;
  z-index: 1;
}

.project__meta-top {
  display: flex;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

.project__type,
.project__year {
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.project__title {
  font-family: var(--font-serif);
  font-style: normal;
  font-size: var(--text-fluid-4xl);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-bottom: var(--space-3);
}

.project__subtitle {
  font-size: var(--text-fluid-md);
  color: var(--color-muted);
  margin-bottom: var(--space-8);
  line-height: 1.5;
}

.project__details {
  display: grid;
  grid-template-columns: 6rem 1fr;
  gap: var(--space-2) var(--space-4);
  font-size: 0.875rem;
}

.project__details dt {
  color: var(--color-muted);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding-top: calc(var(--space-unit) * 0.6);
}

.project__tags {
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--space-unit) * 1.5);
}

/* ─────────────────────────────────────────────
   Prose (project body)
───────────────────────────────────────────── */
.prose {
  max-width: none;
}

.prose > p,
.prose > h2,
.prose > h3,
.prose > ul,
.prose > .feature,
.prose > .features-card,
.prose > .principles-card {
  max-width: var(--prose-w);
  transition: opacity 0.4s ease;
}

.prose > .principles-card {
  max-width: var(--side-rail-max-w);
}

.prose > .side-stack + .principles-card {
  margin-top: var(--space-8);
}

.prose .carousel {
  width: 100vw;
  max-width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  margin-top: 0;
  margin-bottom: 0;
}

.prose .carousel li::before {
  content: none;
  display: none;
}

.prose .carousel .carousel__media--desktop-mobile {
  justify-content: flex-start;
  padding-inline-start: var(--carousel-align-inset, var(--content-inset));
  padding-inline-end: var(--content-inset);
}

.prose p {
  font-size: var(--text-fluid-sm);
  line-height: 1.75;
  margin-bottom: var(--space-6);
  color: var(--color-text);
}

.prose strong {
  font-weight: 600;
  color: var(--color-text);
}

.prose h2 {
  font-family: var(--font-serif);
  font-style: normal;
  font-size: var(--text-fluid-3xl-wide);
  font-weight: 300;
  letter-spacing: -0.01em;
  margin: var(--space-12) 0 var(--space-2);
}

@media (max-width: 56rem) {
  .project__body.prose {
    display: flex;
    flex-direction: column;
  }

  .prose > .side-stack {
    order: 5;
  }

  .prose > .principles-card {
    order: 6;
  }

  .prose > .features-card {
    order: 7;
  }

  .prose > .carousel {
    order: 8;
  }

  .prose h2 {
    font-size: clamp(calc(1.875rem * var(--type-scale)), calc(6.5vw * var(--type-scale)), calc(2.5rem * var(--type-scale)));
  }
}

.prose h3 {
  font-size: var(--text-fluid-base);
  font-weight: 400;
  letter-spacing: -0.01em;
  color: var(--color-muted);
  margin: var(--space-10) 0 var(--space-3);
}

.prose ul {
  --bullet-size: 1.25rem;
  --list-line-height: 1.75;
  list-style: none;
  margin-bottom: var(--space-6);
}

.prose ul li {
  display: flex;
  align-items: flex-start;
  gap: calc(var(--space-unit) * 3.5);
  font-size: var(--text-fluid-sm);
  line-height: var(--list-line-height);
  margin-bottom: var(--space-2);
}

.prose ul li:last-child {
  margin-bottom: 0;
}

.prose ul li::before {
  content: '✻';
  flex-shrink: 0;
  font-size: var(--bullet-size);
  line-height: 1;
  margin-top: calc((var(--list-line-height) * 1em - var(--bullet-size)) / 2);
  background: linear-gradient(
    to top right,
    color-mix(in srgb, var(--color-muted) 88%, var(--color-text)),
    color-mix(in srgb, var(--color-muted) 35%, var(--color-text))
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.has-highlight .prose ul li::before {
  background: linear-gradient(
    to top right,
    color-mix(in srgb, var(--project-highlight) 42%, #3d4f5c),
    var(--project-highlight)
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}


/* ─────────────────────────────────────────────
   Features & principles cards
───────────────────────────────────────────── */
.features-card,
.principles-card {
  --corner-shape: squircle;
  background: color-mix(in srgb, var(--color-surface) 55%, var(--color-bg));
  border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
  border-radius: var(--squircle-card);
  padding: var(--space-5) var(--space-6);
  box-shadow: 0 1px 2px rgb(24 24 27 / 0.04);
}

.features-card {
  margin: var(--space-6) 0 var(--space-8);
}

.principles-card {
  float: right;
  clear: right;
  width: min(var(--side-rail-w), calc(100% - var(--prose-w) - var(--side-rail-gap)));
  max-width: var(--side-rail-max-w);
  margin: 0 0 var(--space-6) var(--side-rail-gap);
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: var(--space-10);
  row-gap: var(--space-6);
  align-content: start;
  padding: calc(var(--space-unit) * 7) var(--side-rail-inset) var(--space-8);
  background: color-mix(in srgb, white 20%, transparent);
}

.features-card__label,
.principles-card__label {
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: var(--space-4) !important;
}

.principles-card__label {
  grid-column: 1 / -1;
  margin-bottom: 0 !important;
  padding-bottom: calc(var(--space-unit) * 3.5);
  border-bottom: 1px solid color-mix(in srgb, var(--color-border) 85%, transparent);
}

.prose .principles-card__label {
  font-size: 0.6875rem;
  line-height: 1;
}

@media (max-width: 56rem) {
  .principles-card {
    float: none;
    width: 100%;
    max-width: 100%;
    margin: var(--space-8) 0;
  }

  .prose > .side-stack + .principles-card {
    margin-top: var(--space-10);
  }
}

@media (max-width: 34rem) {
  .principles-card {
    grid-template-columns: 1fr;
    row-gap: var(--space-5);
  }
}

/* ─────────────────────────────────────────────
   Solution features
───────────────────────────────────────────── */
.feature {
  --feature-text-size: var(--text-fluid-sm);
  --feature-line-height: 1.6;
  --bullet-size: 1.25rem;
  display: flex;
  align-items: flex-start;
  gap: calc(var(--space-unit) * 3.5);
  margin-bottom: calc(var(--space-unit) * 3.5);
}

.features-card .feature:last-child,
.principles-card .feature:last-child {
  margin-bottom: 0;
}

.principles-card .feature {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0;
  min-width: 0;
}

.principles-card .feature__icon {
  font-size: 0.8125rem;
  line-height: 1;
  margin-top: 0;
}

/* Stat cells lead with the big figure — the mark is only kept as a bullet for text-only cells */
.principles-card .feature:has(.feature__text em) .feature__icon {
  display: none;
}

/* Text-only cells run full-width beneath the stat grid, mark inline as a bullet */
.principles-card .feature:not(:has(.feature__text em)) {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: first baseline;
  gap: calc(var(--space-unit) * 3.5);
}

/* First takeaway after a stat cell gets a hairline separating the two zones */
.principles-card .feature:has(.feature__text em) + .feature:not(:has(.feature__text em)) {
  padding-top: var(--space-6);
  border-top: 1px solid color-mix(in srgb, var(--color-border) 85%, transparent);
}

.principles-card .feature__text,
.principles-card .feature__text p {
  font-size: 0.875rem;
  line-height: 1.5;
  margin: 0;
  color: color-mix(in srgb, var(--color-text) 78%, var(--color-muted));
}

.principles-card .feature__text em {
  display: block;
  font-family: var(--font-serif);
  font-style: normal;
  font-size: var(--text-fluid-stat);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1;
  margin-bottom: var(--space-2);
  color: var(--color-text);
  font-variant-numeric: lining-nums;
}

.has-highlight[data-secondary-colour] .principles-card .feature__text em,
.has-highlight[data-image-bg-colour] .principles-card .feature__text em {
  background: linear-gradient(
    to top right,
    var(--project-secondary, var(--image-bg-colour)),
    var(--project-highlight)
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.has-highlight[data-secondary-colour] .principles-card .feature__icon,
.has-highlight[data-image-bg-colour] .principles-card .feature__icon {
  background: linear-gradient(
    to top right,
    var(--project-secondary, var(--image-bg-colour)),
    var(--project-highlight)
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.feature__icon {
  flex-shrink: 0;
  font-size: var(--bullet-size);
  line-height: 1;
  margin-top: calc((var(--feature-line-height) * var(--feature-text-size) - var(--bullet-size)) / 2);
  background: linear-gradient(
    to top right,
    color-mix(in srgb, var(--color-muted) 88%, var(--color-text)),
    color-mix(in srgb, var(--color-muted) 35%, var(--color-text))
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.has-highlight .feature__icon {
  background: linear-gradient(
    to top right,
    color-mix(in srgb, var(--project-highlight) 42%, #3d4f5c),
    var(--project-highlight)
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.feature__text {
  font-size: var(--feature-text-size);
  line-height: var(--feature-line-height);
  color: var(--color-text);
}

/* Slideshow inside prose gets wider treatment */
.prose .slideshow {
  max-width: calc(var(--max-w) - 2 * var(--gutter));
  margin-left: calc(-1 * (calc(var(--max-w) - var(--prose-w)) / 2));
}

@media (max-width: 72rem) {
  .prose .slideshow {
    max-width: 100%;
    margin-left: 0;
  }
}

/* ─────────────────────────────────────────────
   Footer
───────────────────────────────────────────── */
.site-footer {
  padding: 1.5rem var(--gutter);
  border-top: 1px solid var(--color-border);
  display: flex;
  gap: 1.5rem;
  margin-top: auto;
}

.site-footer a {
  font-size: 0.8125rem;
  color: var(--color-muted);
  text-decoration: none;
  letter-spacing: 0.03em;
}

.site-footer a:hover { color: var(--color-text); }

.site-footer__admin { margin-left: auto; }


.site-footer--project {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: end;
  gap: clamp(1rem, 3vw, 2rem);
  padding-block: 2.5rem 3rem;
  overflow: visible;
}

.site-footer__copyright {
  grid-column: 2;
  margin: 0;
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-muted) 40%, var(--color-bg));
  pointer-events: none;
  white-space: nowrap;
}

.site-footer--project .project-tile {
  color: inherit;
  font-size: inherit;
  letter-spacing: normal;
}

.project-footer-nav {
  position: relative;
  width: min(16rem, 100%);
}

.project-footer-nav--prev {
  grid-column: 1;
  justify-self: start;
}

.project-footer-nav--next {
  grid-column: 3;
  justify-self: end;
  text-align: right;
}

.project-footer-nav__link {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  color: var(--color-muted);
  text-decoration: none;
}

.project-footer-nav--next .project-footer-nav__link {
  align-items: flex-end;
}

.project-footer-nav__link:hover,
.project-footer-nav__link:focus-visible,
.project-footer-nav:has(.project-footer-nav__tile:hover) .project-footer-nav__link {
  color: var(--color-text);
}

.project-footer-nav__label {
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: inherit;
}

.project-footer-nav__title {
  font-family: var(--font-serif);
  font-size: var(--text-fluid-sm);
  letter-spacing: 0;
  color: var(--color-text);
  line-height: 1.25;
  text-wrap: balance;
}

.project-footer-nav__tile {
  position: absolute;
  bottom: calc(100% + 0.75rem);
  left: 0;
  width: min(18rem, 72vw);
  padding-bottom: 0.75rem;
  margin-bottom: -0.75rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translateY(0.4rem) scale(0.96);
  transform-origin: bottom left;
  transition:
    opacity 0.28s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.28s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0.28s;
  z-index: 5;
}

.project-footer-nav--next .project-footer-nav__tile {
  left: auto;
  right: 0;
  transform-origin: bottom right;
}

.project-footer-nav:hover .project-footer-nav__tile,
.project-footer-nav:focus-within .project-footer-nav__tile {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transform: translateY(0) scale(1);
}

.project-footer-nav__tile .project-tile {
  width: 100%;
}

/* Slightly deeper shadow in the compact footer preview tiles */
.project-footer-nav__tile .project-tile__backdrop {
  -webkit-filter:
    drop-shadow(0 12px 28px rgb(0 0 0 / 0.14))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.06))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
  filter:
    drop-shadow(0 12px 28px rgb(0 0 0 / 0.14))
    drop-shadow(0 2px 6px rgb(0 0 0 / 0.06))
    drop-shadow(
      0 var(--tile-colour-glow-y) var(--tile-colour-glow-blur)
      color-mix(in srgb, var(--image-bg-colour, #333) var(--tile-colour-glow-alpha), transparent)
    );
}

@media (prefers-reduced-motion: reduce) {
  .project-footer-nav__tile {
    transition: opacity 0.15s ease, visibility 0.15s;
    transform: none;
  }

  .project-footer-nav:hover .project-footer-nav__tile,
  .project-footer-nav:focus-within .project-footer-nav__tile {
    transform: none;
  }
}

@media (max-width: 40rem) {
  .site-footer--project {
    gap: 1rem;
  }

  .project-footer-nav {
    width: calc(50% - 0.5rem);
  }

  .project-footer-nav__tile {
    width: min(12rem, 56vw);
  }
}

/* TEMP: Safari scroll perf — toggle via PerfTestPanel (dev) or <html data-perf-test="…">.
   Flags: parallax | grain | bloom | shadows | masks
   Grain pinning: default viewport-fixed layers; data-perf-grain-fixed="false" for scroll-attached. */
html[data-perf-grain-fixed='false']::before {
  position: absolute;
}

html[data-perf-test~='parallax'] .project-furniture,
html[data-perf-test~='parallax'] .home-hero-header__blob,
html[data-perf-test~='parallax'] .project-grid-blob,
html[data-perf-test~='parallax'] .project-header-blob {
  animation: none !important;
  translate: none !important;
  will-change: auto;
}

html[data-perf-test~='grain']::before,
html[data-perf-test~='grain'] .grain-fixed-host,
html[data-perf-test~='grain'] .project-tile__grain,
html[data-perf-test~='grain'] .home-hero-header__blob-grain {
  display: none !important;
}

html[data-perf-test~='bloom'] .project__header-bloom,
html[data-perf-test~='bloom'] .project-tile__bloom-canvas {
  display: none !important;
}

html[data-perf-test~='shadows'] .squircle-shadow-filter,
html[data-perf-test~='shadows'] .project-tile__backdrop {
  -webkit-filter: none !important;
  filter: none !important;
}

html[data-perf-test~='masks'] .squircle-clip,
html[data-perf-test~='masks'] .squircle-shadow-plate {
  -webkit-mask-image: none !important;
  mask-image: none !important;
  background: transparent !important;
}

/* Entry animation overrides — flags in data-entry-anim are disabled anims */
html[data-entry-anim~='home-tiles'][data-home-reveal] .index-page .project-tile[data-home-reveal-clip] {
  overflow: visible;
  border-radius: 0;
  corner-shape: initial;
}

html[data-entry-anim~='home-tiles'][data-home-reveal] .index-page .home-hero-reveal-clip {
  overflow: visible;
}

html[data-entry-anim~='home-tiles'][data-home-reveal] .index-page .project-tile__reveal,
html[data-entry-anim~='home-tiles'][data-home-reveal] .index-page .home-hero-reveal-slide,
html[data-entry-anim~='home-tiles'][data-home-reveal] .index-page .home-hero-header__blob {
  transform: none;
  opacity: 1;
  transition: none;
  transition-delay: 0ms;
  translate: none;
}

html[data-entry-anim~='home-after'][data-home-reveal] .home-reveal-after {
  opacity: 1;
  transition: none;
  transition-delay: 0ms;
}

html[data-entry-anim~='project'][data-reveal] .project-reveal-item,
html[data-entry-anim~='project'][data-reveal] .project-header-reveal-slide,
html[data-entry-anim~='project'][data-reveal] .project__header-aside,
html[data-entry-anim~='project'][data-reveal] .project__body.prose > *,
html[data-entry-anim~='project'][data-reveal] .site-footer,
html[data-entry-anim~='project'][data-reveal] .project-furniture,
html[data-entry-anim~='project'][data-reveal] .carousel--header .carousel__viewport,
html[data-entry-anim~='project'][data-reveal] .carousel--header .carousel__meta--inside {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
  transition-delay: 0ms !important;
}
