@font-face {
  font-family: "Rinter";
  src: url("fonts/Rinter/Web-TT/Rinter.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@property --light-1-x {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 18%;
}

@property --light-1-y {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 24%;
}

@property --light-2-x {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 74%;
}

@property --light-2-y {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 48%;
}

@property --light-3-x {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 42%;
}

@property --light-3-y {
  syntax: "<percentage>";
  inherits: false;
  initial-value: 82%;
}

:root {
  --color-black: #000000;
  --color-white: #ffffff;
  --color-grey: #8c8f91;
  --color-bg: #f1f1f0;
  --color-surface: #ffffff;
  --color-text: #0b0b0b;
  --color-text-secondary: #7a7c7d;
  --color-line: #c9caca;
  --color-accent: #ff5000;
  --color-nav-dark: rgba(0, 0, 0, 0.75);
  --color-nav-light: rgba(255, 255, 255, 0.75);
  --color-nav-panel: rgba(255, 255, 255, 0.96);
  --color-nav-submenu: rgba(38, 38, 38, 0.96);
  --nav-blur: 25px;
  --font-display: "Rinter", Arial, Helvetica, sans-serif;
  --font-body: "Google Sans Flex", Arial, Helvetica, sans-serif;
  --font-mono: "Google Sans Code", "SFMono-Regular", Consolas, monospace;
  --rinter-optical-offset: 0.03em;
  --type-body: clamp(0.75rem, 0.7rem + 0.16vw, 0.875rem);
  --type-label: var(--type-body);
  --type-mono: var(--type-body);
  --type-project: clamp(1.5rem, 2.5vw, 3.5rem);
  --type-statement: clamp(3.4rem, 8.4vw, 10.5rem);
  --type-project-title: clamp(4rem, 11.5vw, 13rem);
  --type-project-heading: clamp(2.5rem, 5vw, 6rem);
  --type-editorial-copy: clamp(1.35rem, 2.2vw, 2.6rem);
  --type-paragraph: clamp(1rem, 0.96rem + 0.15vw, 1.125rem);
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --media-radius: 5px;
  --page-gutter: clamp(1.25rem, 3.1vw, 4rem);
  --section-space: clamp(7rem, 15vw, 15rem);
  --preview-width: min(37.5vw, 44rem);
  --preview-height: min(51vh, 38rem);
  --preview-aspect: 1.3333;
  --preview-cursor-offset: 1.25rem;
  --preview-viewport-margin: 1rem;
  --preview-enter-duration: 360ms;
  --preview-leave-duration: 280ms;
  --preview-enter-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --preview-leave-ease: cubic-bezier(0.4, 0, 1, 1);
  --row-enter-duration: 500ms;
  --row-leave-duration: 360ms;
  --row-enter-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --row-leave-ease: cubic-bezier(0.55, 0.085, 0.68, 0.53);
  --row-title-shift: 0.625rem;
  --row-active-title-color: var(--color-accent);
  --main-nav-panel-height: clamp(4.5rem, 5.5vw, 5.25rem);
  --nav-float-gap: max(clamp(0.75rem, 1vw, 1rem), env(safe-area-inset-top));
  --nav-panel-padding: clamp(1.25rem, 1.8vw, 2rem);
  --nav-panel-radius: 5px;
  --nav-submenu-radius: 5px;
  --nav-panel-shadow:
    0 1.5rem 4.5rem color-mix(in srgb, var(--color-black) 10%, transparent),
    0 0.25rem 0.9rem color-mix(in srgb, var(--color-black) 4%, transparent);
  --main-nav-height: calc(var(--main-nav-panel-height) + var(--nav-float-gap));
  --project-subnav-height: 3.5rem;
  --z-main-nav: 1000;
  --z-site-loader: 2000;
  --z-project-gate: 950;
  --z-project-preview: 900;
  --z-project-subnav: 800;
  --z-content: 1;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--type-body);
  line-height: 1.15;
  -webkit-font-smoothing: antialiased;
}

html.has-entry-loader,
html.has-entry-loader body {
  overflow: hidden;
}

.site-loader {
  position: fixed;
  inset: 0;
  z-index: var(--z-site-loader);
  display: none;
  padding: var(--page-gutter);
  background: var(--color-bg);
  color: var(--color-text);
  opacity: 1;
  transition: opacity 260ms cubic-bezier(0.4, 0, 1, 1);
}

html.has-entry-loader .site-loader {
  display: block;
}

.site-loader.is-leaving {
  opacity: 0;
  pointer-events: none;
}

.site-loader__inner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  column-gap: clamp(1.25rem, 3vw, 4rem);
  width: 100%;
  height: 100%;
}

.site-loader__title {
  align-self: center;
  margin: 0;
  padding-block: 0.12em;
  font-family: var(--font-display);
  font-size: clamp(1rem, 1.4vw, 2rem);
  font-weight: 400;
  letter-spacing: -0.065em;
  line-height: 0.9;
  white-space: nowrap;
}

.site-loader__status {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 2rem);
  min-height: 2rem;
}

.site-loader__track {
  height: 1px;
  overflow: hidden;
  background: var(--color-line);
}

.site-loader__track > span {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--color-accent);
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}

.site-loader__value {
  min-width: 4ch;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font-family: var(--font-mono);
  font-size: var(--type-mono);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  text-align: right;
}

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

/* Pairs with media-guard.js: the script cancels the drag event, this stops the browser from
   treating the image as draggable content in the first place, and removes the selection
   highlight that makes a picture feel like something to pick up. Text stays selectable —
   only media is covered. */
img,
video {
  -webkit-user-drag: none;
  user-select: none;
  -webkit-user-select: none;
}

.site-header,
.site-footer,
.intro,
.work {
  padding-inline: var(--page-gutter);
}

.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-main-nav);
  isolation: isolate;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  column-gap: clamp(1rem, 2.5vw, 3rem);
  height: var(--main-nav-height);
  padding-top: var(--nav-float-gap);
  padding-right: var(--page-gutter);
  padding-left: var(--page-gutter);
  background: transparent;
  color: var(--color-text);
  text-transform: uppercase;
  letter-spacing: -0.015em;
  transition:
    color 600ms cubic-bezier(0.16, 1, 0.3, 1),
    padding-right 600ms cubic-bezier(0.16, 1, 0.3, 1),
    padding-left 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.site-header::before {
  position: absolute;
  top: var(--nav-float-gap);
  right: var(--page-gutter);
  bottom: 0;
  left: var(--page-gutter);
  z-index: -1;
  background: transparent;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: blur(0);
  backdrop-filter: blur(0);
  content: "";
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, -0.3rem, 0);
  transition:
    background-color 600ms cubic-bezier(0.16, 1, 0.3, 1),
    border-radius 600ms cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 600ms cubic-bezier(0.16, 1, 0.3, 1),
    opacity 420ms ease-out,
    transform 600ms cubic-bezier(0.16, 1, 0.3, 1),
    -webkit-backdrop-filter 600ms cubic-bezier(0.16, 1, 0.3, 1),
    backdrop-filter 600ms cubic-bezier(0.16, 1, 0.3, 1);
}

.site-header.is-sticky {
  padding-right: calc(var(--page-gutter) + var(--nav-panel-padding));
  padding-left: calc(var(--page-gutter) + var(--nav-panel-padding));
  color: var(--color-text);
}

.site-header.is-sticky::before {
  background: var(--color-nav-panel);
  border-radius: var(--nav-panel-radius);
  box-shadow: var(--nav-panel-shadow);
  -webkit-backdrop-filter: blur(var(--nav-blur));
  backdrop-filter: blur(var(--nav-blur));
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.site-header.has-docked-subnav::before {
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}

.identity {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.5vw, 1.5rem);
  min-width: 0;
  width: fit-content;
  white-space: nowrap;
}

.identity__name {
  display: flex;
  align-items: center;
  font-family: var(--font-display);
  font-size: clamp(0.95rem, 1vw, 1.15rem);
  font-weight: 400;
  letter-spacing: -0.025em;
  line-height: 1;
}

.identity__logo {
  display: block;
  width: auto;
  max-width: min(18rem, 35vw);
  height: 1em;
  object-fit: contain;
  object-position: left center;
}

.identity__role {
  font-family: var(--font-mono);
  font-size: clamp(0.58rem, 0.55rem + 0.1vw, 0.68rem);
  letter-spacing: 0;
  line-height: 1.1;
  color: var(--color-text-secondary);
  transition: color 280ms cubic-bezier(0.16, 1, 0.3, 1);
}

.site-header.is-sticky .identity__role {
  color: var(--color-text-secondary);
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(1.1rem, 2.5vw, 3.4rem);
  font-family: var(--font-body);
}

.site-nav a,
.site-footer a {
  position: relative;
}

.site-nav a::after,
.site-footer a::after {
  position: absolute;
  right: 0;
  bottom: -0.2em;
  left: 0;
  height: 1px;
  background: var(--color-accent);
  content: "";
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 180ms ease;
}

.site-nav a:hover::after,
.site-nav a:focus-visible::after,
.site-footer a:hover::after,
.site-footer a:focus-visible::after {
  transform: scaleX(1);
  transform-origin: left;
}

.intro {
  display: flex;
  align-items: flex-end;
  min-height: calc(100svh - var(--main-nav-height) - var(--project-subnav-height));
  min-height: calc(100dvh - var(--main-nav-height) - var(--project-subnav-height));
  padding-top: 9rem;
  padding-bottom: clamp(3rem, 6vw, 7rem);
}

.intro h1 {
  position: relative;
  width: fit-content;
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--type-statement);
  font-weight: 400;
  letter-spacing: -0.068em;
  line-height: 0.84;
  perspective: 800px;
}

.hero-copy,
.hero-light {
  display: block;
  white-space: nowrap;
}

.hero-split-line {
  display: block;
  transform-style: preserve-3d;
}

.hero-light {
  --light-1-x: 18%;
  --light-1-y: 24%;
  --light-2-x: 74%;
  --light-2-y: 48%;
  --light-3-x: 42%;
  --light-3-y: 82%;

  position: absolute;
  inset: 0;
  background:
    radial-gradient(
      ellipse 58% 50% at var(--light-1-x) var(--light-1-y),
      var(--color-accent) 0%,
      color-mix(in srgb, var(--color-accent) 68%, transparent) 25%,
      color-mix(in srgb, var(--color-accent) 24%, transparent) 54%,
      transparent 78%
    ),
    radial-gradient(
      ellipse 64% 54% at var(--light-2-x) var(--light-2-y),
      color-mix(in srgb, var(--color-accent) 88%, transparent) 0%,
      color-mix(in srgb, var(--color-accent) 56%, transparent) 28%,
      color-mix(in srgb, var(--color-accent) 22%, transparent) 56%,
      transparent 80%
    ),
    radial-gradient(
      ellipse 76% 62% at var(--light-3-x) var(--light-3-y),
      color-mix(in srgb, var(--color-accent) 55%, transparent) 0%,
      color-mix(in srgb, var(--color-accent) 28%, transparent) 32%,
      color-mix(in srgb, var(--color-accent) 10%, transparent) 60%,
      transparent 84%
    );
  color: transparent;
  opacity: 0;
  pointer-events: none;
  -webkit-background-clip: text;
  background-clip: text;
  animation:
    hero-light-one 24s ease-in-out -7s infinite alternate,
    hero-light-two 31s ease-in-out -15s infinite alternate,
    hero-light-three 35s ease-in-out -23s infinite alternate;
}

@keyframes hero-light-one {
  0% { --light-1-x: 12%; --light-1-y: 18%; }
  38% { --light-1-x: 46%; --light-1-y: 34%; }
  72% { --light-1-x: 24%; --light-1-y: 76%; }
  100% { --light-1-x: 62%; --light-1-y: 58%; }
}

@keyframes hero-light-two {
  0% { --light-2-x: 82%; --light-2-y: 26%; }
  44% { --light-2-x: 58%; --light-2-y: 72%; }
  76% { --light-2-x: 88%; --light-2-y: 84%; }
  100% { --light-2-x: 36%; --light-2-y: 42%; }
}

@keyframes hero-light-three {
  0% { --light-3-x: 34%; --light-3-y: 88%; }
  32% { --light-3-x: 68%; --light-3-y: 62%; }
  70% { --light-3-x: 48%; --light-3-y: 18%; }
  100% { --light-3-x: 16%; --light-3-y: 54%; }
}

.work {
  padding-top: 0;
  padding-bottom: clamp(8rem, 14vw, 13rem);
}

.work-heading {
  position: sticky;
  top: calc(var(--main-nav-height) - 1px);
  z-index: var(--z-project-subnav);
  isolation: isolate;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: clamp(2rem, 5vw, 6rem);
  min-height: var(--project-subnav-height);
  margin-inline: 0;
  margin-bottom: clamp(2.25rem, 5vw, 5rem);
  padding: 1rem 0;
  background: transparent;
  text-transform: uppercase;
  transition:
    color 420ms cubic-bezier(0.16, 1, 0.3, 1),
    padding-right 480ms cubic-bezier(0.16, 1, 0.3, 1),
    padding-left 480ms cubic-bezier(0.16, 1, 0.3, 1);
}

.work-heading::before {
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: var(--nav-submenu-radius);
  background: var(--color-nav-submenu);
  box-shadow: 0 1rem 2.5rem color-mix(in srgb, var(--color-black) 9%, transparent);
  -webkit-backdrop-filter: blur(var(--nav-blur));
  backdrop-filter: blur(var(--nav-blur));
  content: "";
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, -0.5rem, 0);
  transition:
    opacity 320ms ease-out,
    transform 480ms cubic-bezier(0.16, 1, 0.3, 1);
}

.work-heading.is-sticky {
  padding-right: var(--nav-panel-padding);
  padding-left: var(--nav-panel-padding);
  color: var(--color-white);
}

.work-heading.is-sticky::before {
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.work-heading.is-sticky .work-filters button {
  color: color-mix(in srgb, var(--color-white) 62%, transparent);
}

.work-heading.is-sticky .work-filters button:hover:not([aria-pressed="true"]),
.work-heading.is-sticky .work-filters button:focus-visible:not([aria-pressed="true"]),
.work-heading.is-sticky .work-filters button[aria-pressed="true"] {
  color: var(--color-white);
}

.work-heading__title {
  display: flex;
  align-items: center;
  gap: 0.45em;
  white-space: nowrap;
}

.work-heading h2,
.work-heading__count {
  margin: 0;
  font-size: inherit;
  font-weight: 400;
}

.work-heading__count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.work-filters {
  position: relative;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  min-width: 0;
  margin-block: -1rem;
  padding-block: 1rem;
}

.work-filters button {
  --filter-reveal-delay: 0ms;

  flex: 0 0 auto;
  max-width: 12rem;
  margin: 0;
  margin-left: clamp(0.8rem, 1.35vw, 1.6rem);
  padding: 0;
  overflow: hidden;
  border: 0;
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  opacity: 1;
  transform: translateX(0);
  white-space: nowrap;
  text-transform: inherit;
  cursor: pointer;
  transition:
    max-width 480ms cubic-bezier(0.16, 1, 0.3, 1) var(--filter-reveal-delay),
    margin-left 480ms cubic-bezier(0.16, 1, 0.3, 1) var(--filter-reveal-delay),
    opacity 220ms ease-out var(--filter-reveal-delay),
    transform 480ms cubic-bezier(0.16, 1, 0.3, 1) var(--filter-reveal-delay),
    color 160ms ease-out;
}

.work-filters button:first-child {
  margin-left: 0;
}

.work-filters button:nth-child(2) { --filter-reveal-delay: 0ms; }
.work-filters button:nth-child(5) { --filter-reveal-delay: 35ms; }
.work-filters button:nth-child(6) { --filter-reveal-delay: 70ms; }
.work-filters button:nth-child(7) { --filter-reveal-delay: 105ms; }
.work-filters button:nth-child(8) { --filter-reveal-delay: 140ms; }
.work-filters button:nth-child(9) { --filter-reveal-delay: 175ms; }

.work-filters:not(.is-expanded) button {
  --filter-reveal-delay: 0ms;
}

.work-filters button.is-concealed {
  max-width: 0;
  margin-left: 0;
  opacity: 0;
  transform: translateX(0.75rem);
  pointer-events: none;
}

.work-filters button:hover:not([aria-pressed="true"]),
.work-filters button:focus-visible:not([aria-pressed="true"]) {
  color: var(--color-text);
  opacity: 0.68;
}

.work-filters button[aria-pressed="true"] {
  color: var(--color-text);
  opacity: 1;
}

.work-filters button:focus-visible {
  outline: 1px solid var(--color-accent);
  outline-offset: 0.2rem;
}

.project-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.8fr) minmax(8rem, 0.62fr) minmax(3rem, 0.16fr);
  column-gap: 2rem;
}

.project-grid--header {
  padding-bottom: 0.75rem;
  color: var(--color-text-secondary);
  text-transform: uppercase;
}

.project-list {
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-line);
  list-style: none;
}

.project-item {
  border-bottom: 1px solid var(--color-line);
}

.project-item--last-visible {
  border-bottom: 0;
}

.project-row {
  position: relative;
  z-index: var(--z-content);
  align-items: center;
  min-height: clamp(4.5rem, 6.25vw, 7.5rem);
  padding-block: clamp(1rem, 1.3vw, 1.5rem);
}

.project-name {
  overflow: visible;
  font-family: var(--font-display);
  font-size: var(--type-project);
  letter-spacing: -0.052em;
  line-height: 1.05;
  white-space: nowrap;
  transform: translate3d(0, var(--rinter-optical-offset), 0);
  transition:
    color var(--row-leave-duration) var(--row-leave-ease),
    transform var(--row-leave-duration) var(--row-leave-ease);
}

.project-lock {
  width: 0.38em;
  height: 0.44em;
  margin-left: 0.14em;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-linecap: square;
  stroke-linejoin: miter;
  stroke-width: 1.2;
  vertical-align: 0.55em;
}

.project-client,
.project-year {
  text-transform: uppercase;
}

.project-year {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  text-align: left;
}

.project-preview {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-project-preview);
  width: min(
    var(--preview-width),
    calc(var(--preview-height) * var(--preview-aspect)),
    calc(100vw - (var(--preview-viewport-margin) * 2))
  );
  height: auto;
  max-height: var(--preview-height);
  aspect-ratio: var(--preview-aspect);
  margin: 0;
  overflow: hidden;
  border-radius: var(--media-radius);
  contain: layout paint;
  pointer-events: none;
  opacity: 0;
  transform: translate3d(-200vw, -200vh, 0);
  transition: opacity var(--preview-leave-duration) var(--preview-leave-ease);
  will-change: transform, opacity;
}

.project-preview.is-visible {
  opacity: 1;
  transition-duration: var(--preview-enter-duration);
  transition-timing-function: var(--preview-enter-ease);
}

.project-preview img,
.project-preview video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  transform-origin: center;
  will-change: transform;
}

.project-preview [hidden] {
  display: none;
}

/* 404 --------------------------------------------------------------------- */

/* Sized off the same statement scale as the homepage hero, so the error page reads as part of
   the site rather than a system page that happens to share its colours. */
/* The page is pinned to the viewport rather than given a guessed min-height, so the footer
   lands on the bottom edge whatever the header and footer actually measure. */
.notfound-page {
  display: flex;
  flex-direction: column;
  min-height: 100svh;
}

.notfound-page main {
  display: flex;
  flex: 1;
}

.notfound {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-xl) var(--page-gutter);
}

.notfound__label {
  margin: 0 0 var(--space-xl);
  color: var(--color-text-secondary);
  font-family: var(--font-mono);
  font-size: var(--type-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.notfound__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--type-statement);
  font-weight: 400;
  letter-spacing: -0.068em;
  line-height: 0.84;
}

.notfound__copy {
  max-width: 34ch;
  margin: var(--space-xl) 0 0;
  color: var(--color-text-secondary);
  font-size: var(--type-paragraph);
  line-height: 1.4;
}

.notfound__link {
  margin-top: var(--space-xl);
  padding-bottom: 0.15em;
  border-bottom: 1px solid var(--color-line);
  color: var(--color-text);
  font-size: var(--type-paragraph);
  text-decoration: none;
  transition: border-color 200ms ease, color 200ms ease;
}

.notfound__link:hover,
.notfound__link:focus-visible {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

@media (prefers-reduced-motion: reduce) {
  .notfound__link { transition: none; }
}

.site-footer {
  display: flex;
  justify-content: space-between;
  padding-top: 1.25rem;
  padding-bottom: 1.5rem;
  border-top: 1px solid var(--color-line);
  text-transform: uppercase;
}

.site-footer p {
  margin: 0;
}

.site-footer__links {
  display: flex;
  gap: clamp(1rem, 2vw, 2rem);
  margin-left: auto;
  margin-right: clamp(1rem, 3vw, 4rem);
}

.site-footer__links:has(a:not([hidden])) {
  display: flex;
}

.site-footer__links:not(:has(a:not([hidden]))) {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .project-row:hover,
  .project-row:focus-visible {
    outline: none;
  }

  .project-row:hover .project-name,
  .project-row:focus-visible .project-name {
    color: var(--row-active-title-color);
    transform: translate3d(var(--row-title-shift), var(--rinter-optical-offset), 0);
    transition-duration: var(--row-enter-duration), var(--row-enter-duration);
    transition-timing-function: var(--row-enter-ease), var(--row-enter-ease);
  }
}

@media (max-width: 900px) {
  :root {
    --project-subnav-height: 4.67rem;
  }

  .work-heading {
    grid-template-columns: 1fr;
    align-items: center;
    gap: 0.85rem;
  }

  .work-filters {
    flex-wrap: wrap;
    justify-content: flex-end;
    row-gap: 0.55rem;
  }
}

@media (max-width: 760px) {
  :root {
    --type-statement: clamp(3.75rem, 17.5vw, 6.75rem);
    --type-project: clamp(1.5rem, 7.5vw, 2.5rem);
    --section-space: 7.5rem;
    --project-subnav-height: 4.5rem;
    --nav-float-gap: max(0.5rem, env(safe-area-inset-top));
    --nav-panel-padding: 1rem;
  }

  .site-header {
    column-gap: 0.65rem;
  }

  .identity {
    gap: 0.5rem;
  }

  .identity__name {
    font-size: clamp(0.72rem, 2.2vw, 0.95rem);
  }

  .identity__role {
    font-size: clamp(0.44rem, 1.35vw, 0.58rem);
  }

  .site-nav {
    justify-content: flex-end;
    gap: 0.75rem;
  }

  .intro {
    padding-inline: min(var(--page-gutter), 3.5vw);
    padding-top: calc(var(--main-nav-height) + 2rem);
    padding-bottom: 2rem;
  }

  .intro h1 {
    line-height: 0.88;
  }

  .work-heading {
    gap: 0.75rem;
  }

  .work-filters {
    justify-content: flex-end;
  }

  .project-grid {
    grid-template-columns: minmax(0, 1fr) 3rem;
    column-gap: 1.5rem;
  }

  .project-grid--header span:nth-child(2) {
    display: none;
  }

  .project-grid--header span:last-child {
    grid-column: 2;
    text-align: left;
  }

  .project-row {
    min-height: 6rem;
  }

  .project-name {
    grid-column: 1 / -1;
    margin-bottom: 1rem;
  }

  .project-client {
    grid-column: 1;
  }

  .project-year {
    grid-column: 2;
  }

  .project-preview {
    display: none;
  }

  .site-footer {
    align-items: flex-end;
    gap: 3rem;
  }

  .site-footer p {
    max-width: 18rem;
  }
}

/* Sticky scroll-driven preview panel — the touch counterpart to the desktop
   cursor-follow preview. This query must stay identical to stickyPanelLayout in
   script.js, which decides whether the panel these rules style is built at all. */
@media (hover: none), (pointer: coarse), (max-width: 760px) {
  /* The whole selected-work bar goes: heading, counter and filters alike. Beyond costing
     vertical space, it is sticky at a z-index far above the preview panel with a
     background that stays transparent until it sticks, so its label painted straight over
     the cover image on the way past. Desktop keeps the bar in full. */
  .work-heading {
    display: none;
  }

  /* Replaces the spacing the hidden bar used to contribute below itself. */
  .work {
    padding-top: 2rem;
  }

  .project-featured {
    position: relative;
    height: var(--project-sequence-height, 100dvh);
  }

  .project-featured__stage {
    position: sticky;
    top: 0;
    height: 100svh;
    height: 100dvh;
    overflow: hidden;
  }

  .project-panel {
    position: absolute;
    top: 50%;
    left: 0;
    z-index: 3;
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    max-height: 55vh;
    margin: 0;
    overflow: hidden;
    border-radius: var(--media-radius);
    background: var(--color-line);
    transform: translateY(-50%);
    pointer-events: auto;
    touch-action: manipulation;
  }

  .project-panel:focus-visible {
    outline: 1px solid var(--color-accent);
    outline-offset: 0.25rem;
  }

  .project-panel__layer {
    position: absolute;
    inset: 0;
    z-index: 0;
    opacity: 0;
    transition: opacity 320ms cubic-bezier(0.16, 1, 0.3, 1);
  }

  .project-panel__layer.is-visible {
    opacity: 1;
  }

  /* The incoming layer sits above the outgoing one so it fades in over an opaque cover
     rather than both being half-transparent at once. */
  .project-panel__layer.is-front {
    z-index: 1;
  }

  .project-panel__media {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform-origin: center;
    will-change: transform;
  }

  /* A plain dark wash rather than a blend mode: it lifts white type off a bright cover
     without the title and the image mixing into each other. */
  .project-panel__scrim {
    position: absolute;
    inset: 0;
    z-index: 2;
    background: linear-gradient(
      to bottom,
      rgb(0 0 0 / 12%) 0%,
      rgb(0 0 0 / 30%) 55%,
      rgb(0 0 0 / 42%) 100%
    );
  }

  .project-panel__title {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: grid;
    place-items: center;
    padding-inline: var(--page-gutter);
    color: var(--color-white);
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 9vw, 3rem);
    letter-spacing: -0.045em;
    line-height: 1.05;
    text-align: center;
    text-shadow: 0 1px 28px rgb(0 0 0 / 45%);
  }

  .project-list--featured {
    position: absolute;
    inset: 0;
    border-top: none;
    pointer-events: none;
  }

  .project-list--featured .project-item {
    position: absolute;
    top: 50%;
    left: 0;
    z-index: 1;
    width: 100%;
    border-bottom: none;
    opacity: 1;
    transform: translate3d(0, calc(-50% + var(--project-track-y, 0px)), 0);
    pointer-events: none;
    will-change: transform;
  }

  .project-list--featured .project-client,
  .project-list--featured .project-year {
    display: none;
  }

  .project-list--featured .project-row {
    grid-template-columns: minmax(0, 1fr);
    min-height: 2.75rem;
    text-align: center;
    pointer-events: none;
  }

  .project-list--featured .project-name {
    grid-column: 1;
    margin-bottom: 0;
    /* Titles are nowrap and .project-name is overflow: visible for the optical offset, so
       a long one paints past its box and out beyond the panel's edge, where it is no
       longer covered. Clip it back to the row. */
    overflow: hidden;
    text-overflow: ellipsis;
    transition: color 200ms ease-out, opacity 200ms ease-out;
  }

  .project-list--featured .project-item--past .project-name {
    color: var(--color-grey);
  }

  .project-list--featured .project-item--upcoming .project-name {
    color: var(--color-text);
  }

  .project-list--featured .project-item--active {
    opacity: 0;
  }

  .project-table > .project-grid--header {
    display: none;
  }

  /* Two lines: the availability line spans full width on its own row (flex-basis: 100%
     forces the wrap), then links and "back to top" share the second row — space-between
     on .site-footer, inherited from the base rule, is what pushes those two apart once
     they're alone on that line. */
  .site-footer {
    flex-wrap: wrap;
    row-gap: 1rem;
  }

  .site-footer p {
    flex: 1 0 100%;
    max-width: none;
  }

  .site-footer__links {
    margin-left: 0;
  }

  /* Header down to name + two links — "Art Director / Creative Director" has nowhere to
     go on a narrow header and was crowding the nav. */
  .identity__role {
    display: none;
  }

  /* Hero copy overflow had two contributing causes, not one: .hero-copy/.hero-light were
     forced white-space: nowrap (so a manually <br>-broken line had no way to reflow if it
     was still too wide for the viewport), and .intro h1 sized itself with
     width: fit-content (correct on desktop, where it hugs whatever the longest line
     needs) instead of filling the available column — the two together let the widest
     line grow flush to the very edge with no gutter to spare. Both are overridden here:
     the line breaks are still the deliberate manual <br> ones, but any line that doesn't
     fit now wraps instead of running out of room. */
  .intro h1 {
    width: 100%;
  }

  .hero-copy,
  .hero-light {
    white-space: normal;
  }

  /* Hero as a pinned background layer: it fills the screen at scroll position zero and
     stays exactly there — position: fixed rather than sticky, because sticky's "stuck"
     window is bounded by its own contribution to the document's height, and a fixed
     element that reserves no flow space needs .work's margin-top below to still have a
     hero-height's worth of scroll before the list starts sliding over it. dvh/svh rather
     than vh so the mobile browser chrome collapsing on scroll doesn't resize the layer
     out from under itself. */
  .intro {
    position: fixed;
    inset: 0 0 auto;
    z-index: 0;
    box-sizing: border-box;
    width: 100%;
    height: 100svh;
    height: 100dvh;
    min-height: 100svh;
    min-height: 100dvh;
    padding-top: calc(var(--main-nav-height) + 2rem);
    /* Overrides the narrower hero-only gutter set further up (min(--page-gutter, 3.5vw)),
       which predates the headline wrapping and left it starting ~7px further left than
       everything else. Now that the hero sits directly behind the preview panel while the
       list rides over it, the two have to share one left edge. */
    padding-inline: var(--page-gutter);
  }

  /* Keep a solid fallback when the line animation is unavailable. The script adds
     .has-mobile-hero-fade only after the scrubbed GSAP timeline exists; in that state the
     moving work section becomes transparent so its rectangular edge cannot mask/crop the
     headline. The footer remains opaque because it sits outside the animation sequence. */
  .work,
  .site-footer {
    position: relative;
    z-index: 1;
    background: var(--color-bg);
  }

  html.has-mobile-hero-fade .work {
    background: transparent;
  }

  /* Once the scrub reaches its end, keep the fixed hero composited away as a safety
     latch. Safari can defer scroll/resize paints while a finger remains on screen; the
     parent-level opacity prevents any stale line frame from flashing under the project
     track. updateHeroFade removes this class immediately when scrolling back upward. */
  html.is-mobile-hero-dismissed .intro {
    opacity: 0;
  }

  /* The return position is restored after project data and the sticky preview have been
     built. Hide only the fixed hero during that short setup window so its entrance state
     can never flash over the returning project. */
  html.is-restoring-home .intro {
    opacity: 0;
  }

  .work {
    margin-top: calc(100svh - var(--main-nav-height));
    margin-top: calc(100dvh - var(--main-nav-height));
    padding-bottom: 0;
  }
}

/* Motion-sensitive users get the hero back in normal document flow: it scrolls away with
   the page instead of being pinned under a sliding mask. */
@media (prefers-reduced-motion: reduce) {
  @media (hover: none), (pointer: coarse), (max-width: 760px) {
    .intro {
      position: static;
      width: auto;
      height: auto;
      min-height: calc(100svh - var(--main-nav-height));
      min-height: calc(100dvh - var(--main-nav-height));
      padding-top: calc(var(--main-nav-height) + 2rem);
    }

    .work {
      margin-top: 0;
    }
  }
}

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

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }

  .hero-light {
    display: none;
    animation: none;
  }

  .site-loader {
    transition: none;
  }
}
