/* ---------------------------------------------------------
   Rhys Warren — portfolio site  ·  V2

   A second layout, built to the new reference:
   - Pure white gallery ground (no warm paper, no page grain).
   - "RHYS WARREN" wordmark centred along the top.
   - Section nav stacked in the top-right corner, each item
     trailed by a small italic count, e.g. MOTION (12).
   - Home is one locked canvas of freely-scattered image
     tiles (percentage-positioned against the reference's own
     aspect ratio, so the composition holds at any window
     shape and the page never scrolls).
   - Each tile carries a hairline index tag and a fine screen
     mesh over the media; hover draws a blue keyline.
   - Serif blurb pinned bottom-left.

   FONT NOTES:
   - Display (wordmark + section nav): Paul Grotesk, self-hosted
     from PaulGrotesk-{Thin,Regular,Bold}-Trail.otf in fonts/.
     NOTE: this is the trial cut — it carries A-Z, a-z, 0-9 and
     ( ) but NOT square brackets, so anything using [ ] must
     stay on the fallback face.
   - Workhorse sans (inner-page UI + the [01]-[05] number tags):
     Neue Haas Grotesk Display Pro, self-hosted — same as V1's
     number tags, kept here so the brackets render.
   - Serif (blurb): meant to be Adobe "Minion Pro" — still
     EB Garamond (Google Fonts) as a close free stand-in.
   --------------------------------------------------------- */

@font-face {
  font-family: "Neue Haas Grotesk Display Pro";
  src: url("../fonts/NeueHaasDisplayRoman.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Haas Grotesk Display Pro";
  src: url("../fonts/NeueHaasDisplayMedium.ttf") format("truetype");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Neue Haas Grotesk Display Pro";
  src: url("../fonts/NeueHaasDisplayBold.ttf") format("truetype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Paul Grotesk";
  src: url("../fonts/PaulGrotesk-Thin-Trail.otf") format("opentype");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Paul Grotesk";
  src: url("../fonts/PaulGrotesk-Regular-Trail.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Paul Grotesk";
  src: url("../fonts/PaulGrotesk-Bold-Trail.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Barely-warm paper white — the grain layer below does the rest of the
     work of making it read as paper rather than a flat screen white. */
  --color-bg: #f4f2ec;
  --color-text: #141414;
  --color-muted: rgba(20, 20, 20, 0.5);
  --color-line: rgba(20, 20, 20, 0.14);
  --color-tile: #e6e2d8;

  /* Blue keyline on tile hover / active nav — matches the reference. */
  --blue: #2a4fee;

  --font-display: "Paul Grotesk", "Neue Haas Grotesk Display Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-sans: "Neue Haas Grotesk Display Pro", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-serif: "EB Garamond", Georgia, "Times New Roman", serif;

  /* Locked to the reference composition's own aspect ratio, so every
     tile's percentage position reproduces it regardless of the
     window's shape. */
  --canvas-w: 1920;
  --canvas-h: 1320;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

html {
  background: var(--color-bg);
}

body {
  background: var(--color-bg);
  min-height: 100vh;
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  position: relative;
}

/* Paper grain — same technique as V1 / the subtext site: a fractal-noise
   layer multiplied over everything (chrome included, so it reads as one
   continuous sheet rather than a flat panel over texture). Fixed and
   full-screen; the pages use viewport-fit=cover so this also covers the
   iOS status-bar and home-indicator strips, which otherwise show a flat
   untextured band top and bottom. pointer-events:none keeps it out of
   the way of clicks. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0.08;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch' result='noise'/%3E%3CfeColorMatrix in='noise' type='matrix' values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 1.4 -0.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  z-index: 100;
}

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

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

/* ---------- page chrome: wordmark + section nav ---------- */
/* Both are position:absolute against <body> — pinned to the SAME spot at
   the top of every page (so the placement never shifts between the home
   canvas and the inner pages), but part of the document, so they scroll
   up and out of view with the page rather than following the scroll. */

.wordmark {
  position: absolute;
  top: 40px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 40;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(18px, 1.5vw, 24px);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color 0.15s ease;
}

.wordmark:hover {
  color: var(--blue);
}

/* Top-right, dropped a little below the wordmark. Same offsets on every
   page. On mobile this collapses into the burger menu (see the media
   query at the foot of the file). */
.site-nav {
  position: absolute;
  top: 64px;
  right: 40px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

/* Burger toggle — hidden on desktop, shown on mobile. */
.nav-toggle {
  display: none;
}

.site-nav a {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 14px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: color 0.15s ease;
}

.site-nav a:hover {
  color: var(--blue);
}

.site-nav a[aria-current="page"] {
  color: var(--blue);
}

/* Trailing section number, e.g. MOTION [01] — Neue Haas, light, same
   treatment as the tile tags and V1's nav numbers (Paul Grotesk's trial
   cut has no square brackets, so these stay on the fallback face). */
.site-nav .n {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 0.7em;
  letter-spacing: 0.02em;
  margin-left: 0.4em;
  opacity: 0.55;
}

/* ---------- home canvas ---------- */

.home-stage {
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.home-canvas {
  position: relative;
  width: min(100%, calc(100vh * var(--canvas-w) / var(--canvas-h)));
  aspect-ratio: var(--canvas-w) / var(--canvas-h);
}

.tile {
  position: absolute;
  top: var(--y);
  left: var(--x);
  width: var(--w);
}

.tile__link {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--color-tile);
}

.tile__media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s ease;
}

.tile__link:hover .tile__media {
  transform: scale(1.03);
}

/* Hairline index tag, e.g. [01] — pinned to a tile corner. Sized to
   match the [0x] counts in the top-right nav. */
.tile__tag {
  position: absolute;
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 10px;
  letter-spacing: 0.03em;
  color: var(--color-text);
}

.tile__tag--tl { top: -18px; left: 0; }
.tile__tag--bl { bottom: -18px; left: 0; }
.tile__tag--br { bottom: -18px; right: 0; }
.tile__tag--tr { top: -18px; right: 0; }

/* Home nav-click transition (see main.js): tiles fade before navigating. */
.tile--leaving {
  transition: opacity 0.4s ease;
  opacity: 0;
}

/* ---------- home blurb ---------- */

.blurb {
  position: fixed;
  left: 40px;
  bottom: 36px;
  z-index: 40;
  max-width: 42ch;
  font-family: var(--font-display);
  font-size: 13px;
  line-height: 1.55;
  color: var(--color-text);
}

.blurb p {
  margin: 0;
}

.blurb a {
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.blurb a:hover {
  color: var(--blue);
}

/* ---------- inner pages ---------- */

/* Top padding clears the 5-item nav (lower edge ~210px down) so the
   gallery / heading never starts underneath CONTACT on first view. */
.page {
  max-width: 1500px;
  margin: 0 auto;
  padding: 224px 40px 96px;
}

/* Motion: a touch narrower than the other pages, tighter gaps between
   frames, and pulled up closer to the nav than the other inner pages. */
.page.gallery--motion {
  max-width: 1200px;
  padding-top: 200px;
}

.page__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 28px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-line);
}

/* Short holding message (Stills, while it's still being built). */
.page__note {
  max-width: 44ch;
}

.page__note p {
  font-family: var(--font-serif);
  font-size: 18px;
  line-height: 1.6;
  margin: 0 0 14px;
}

.page__note p:last-child {
  margin-bottom: 0;
}

/* Subcategory filter row (Motion) — spread edge to edge along the rule,
   not bunched at the left. */
.category-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 16px 28px;
  margin: 0 0 32px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-line);
}

.category-tabs a {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  transition: color 0.15s ease;
}

.category-tabs a:hover,
.category-tabs a.is-active {
  color: var(--color-text);
}

/* ---------- gallery grid (stills / travels) ---------- */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 28px 24px;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.gallery-grid.is-visible {
  opacity: 1;
}

.project-card {
  display: block;
}

.project-card__thumb {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  background: var(--color-tile);
  margin-bottom: 10px;
  transition: opacity 0.15s ease;
}

.project-card:hover .project-card__thumb {
  opacity: 0.82;
}

.project-card__thumb-wrap {
  position: relative;
  overflow: hidden;
  margin-bottom: 10px;
  aspect-ratio: 4 / 5;
  background: #000;
}

.project-card__thumb-wrap .project-card__thumb {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
}

.project-card:hover .project-card__thumb-wrap .project-card__thumb {
  opacity: 0.82;
}

.project-card__thumb-wrap iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Hover preview — a silent looping stream of the main clip, dropped in
   over the still by main.js on mouseenter and pulled on mouseleave.
   pointer-events:none so the card still takes the click. */
.project-card__preview {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  z-index: 1;
  pointer-events: none;
  /* Blow the player up a touch and let the 16:9 frame clip it — a 4:3
     source otherwise shows Vimeo's pill/letterbox bars at the edges. */
  transform: scale(1.32);
  transform-origin: center;
  animation: preview-in 0.35s ease both;
}

@keyframes preview-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Cards with no still yet: paper-toned frame, title always visible. */
.project-card--noposter .project-card__thumb-wrap {
  background: var(--color-tile);
}

.project-card--noposter .project-card__play::before {
  border-color: transparent transparent transparent rgba(20, 20, 20, 0.5);
}

.project-card__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}

.project-card:hover .project-card__play {
  opacity: 1;
}

.project-card__play::before {
  content: "";
  width: 0;
  height: 0;
  margin-left: 3px;
  border-style: solid;
  border-width: 9px 0 9px 15px;
  border-color: transparent transparent transparent #fff;
}

.project-card__reel-badge {
  position: absolute;
  bottom: 8px;
  right: 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  padding: 3px 7px;
  pointer-events: none;
}

.project-card__info {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
}

/* Credit line under a single-clip card's title (revealed on play/hover). */
.project-card__credit {
  flex-basis: 100%;
  margin-top: 3px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 10px;
  line-height: 1.55;
  letter-spacing: 0.03em;
  color: var(--color-muted);
}

.project-card__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.project-card__meta {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ---------- Motion: three independent columns ---------- */
/* Cards are dealt round-robin across three .gallery-col flex stacks, so
   the rows read left-to-right in Milanote board order while each column
   flows on its own — hovering a card expands its caption in place and
   pushes only that column down. Gaps are equal in both directions. */
.gallery--motion .gallery-grid {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}

.gallery-col {
  display: flex;
  flex-direction: column;
  gap: 14px;
  flex: 1;
  min-width: 0;
}

.gallery--motion .project-card {
  position: relative;
}

/* Every Motion thumbnail is a uniform 16:9 in the grid. On play, main.js
   sets an inline aspect-ratio on the wrap (from the card's data-ar) and
   the box eases open into the clip's own shape. */
.gallery--motion .project-card__thumb,
.gallery--motion .project-card__thumb-wrap {
  aspect-ratio: 16 / 9;
  transition: aspect-ratio 0.35s ease;
}

/* Caption collapsed until hover; on hover it opens in flow and grows the
   card, nudging the rest of that column down. */
.gallery--motion .project-card__info {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transform: translateY(-4px);
  transition: max-height 0.28s ease, opacity 0.2s ease, transform 0.2s ease;
}

.gallery--motion .project-card:hover .project-card__info,
.gallery--motion .project-card--noposter .project-card__info {
  max-height: 16em;
  opacity: 1;
  transform: translateY(0);
}

/* ---------- Motion project detail ---------- */

/* Centred, narrow column — the videos are deliberately never full-bleed. */
.project-detail {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}

.project-detail__header {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 20px;
  margin: 0 0 32px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-line);
}

.project-detail__back {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  transition: color 0.15s ease;
}

.project-detail__back:hover {
  color: var(--blue);
}

.project-detail__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.project-detail__meta {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0 auto;
}

/* The main clip never fills the screen: capped at 50vw wide (landscape)
   or ~52vh tall (portrait) — main.js sets width/height per clip against
   the aspect-ratio it also sets, and this box shrink-wraps to it. */
.project-detail__stage {
  text-align: center;
  margin-bottom: 44px;
}

.project-detail__main {
  display: inline-block;
  vertical-align: top;
  position: relative;
  overflow: hidden;
  background: #000;
  max-width: 50vw;
  max-height: 74vh;
}

.project-detail__main iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Credit line — below the main video (or wall), above the reels. Rhys'
   own roles first, then "Role: Name" collaborators, middle-dot separated. */
.project-detail__credits {
  max-width: 620px;
  margin: 0 auto 44px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  line-height: 1.7;
  letter-spacing: 0.03em;
  color: var(--color-muted);
  text-align: center;
}

.project-detail__reels-heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-line);
}

/* Cuts sit side by side, three to a row at most; fewer than three just
   centre. Each box's aspect-ratio is set inline per clip (4:3, 9:16, …).
   A "wall" project (all 9:16, no hero) uses the same grid, a touch
   wider. */
.project-detail__reels {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
}

.project-detail__reels--wall {
  gap: 16px;
}

.project-detail__reel {
  position: relative;
  flex: 0 1 auto;
  width: calc((100% - 24px) / 3);
  max-width: 260px;
  overflow: hidden;
  background: #000;
}

.project-detail__reels--wall .project-detail__reel {
  width: calc((100% - 32px) / 3);
  max-width: 280px;
}

.project-detail__reel iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ---------- About ---------- */

.about {
  display: grid;
  grid-template-columns: minmax(0, 300px) minmax(0, 58ch);
  gap: 48px;
  align-items: start;
}

.about__photo {
  width: 100%;
  height: auto;
  display: block;
}

.about p {
  font-family: var(--font-serif);
  font-size: 17px;
  line-height: 1.7;
  margin: 0 0 20px;
}

.about p:last-of-type {
  margin-bottom: 0;
}

@media (max-width: 720px) {
  .about {
    grid-template-columns: 1fr;
    gap: 24px;
  }
  .about__photo {
    max-width: 100%;
  }
}

.about__contact {
  margin-top: 40px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.about__contact a {
  display: block;
  margin-top: 8px;
  font-family: var(--font-sans);
  color: var(--color-muted);
}

.about__contact a:hover {
  color: var(--blue);
}

/* ---------- Travels ---------- */

.travel-section {
  margin-bottom: 64px;
}

.travel-section:last-child {
  margin-bottom: 0;
}

.travel-section__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 22px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--color-line);
}

.travel-feature {
  max-width: 720px;
  margin: 0 0 22px;
  background: #000;
  aspect-ratio: 16 / 9;
}

.travel-feature video,
.travel-feature iframe {
  width: 100%;
  height: 100%;
  display: block;
  border: 0;
  object-fit: cover;
}

.travel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}

.travel-tile {
  position: relative;
  overflow: hidden;
  background: var(--color-tile);
  aspect-ratio: 4 / 3;
}

.travel-tile video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.travel-tile__label {
  position: absolute;
  left: 9px;
  bottom: 8px;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
  pointer-events: none;
}

/* ---------- Contact ---------- */

.contact__lede {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 15px;
  line-height: 1.7;
  max-width: 46ch;
  margin: 0 0 44px;
}

.contact__choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  max-width: 760px;
  margin-bottom: 56px;
}

.contact-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 26px 24px 22px;
  border: 1px solid var(--color-line);
  transition: border-color 0.15s ease, background 0.15s ease;
}

.contact-card:hover {
  border-color: var(--blue);
  background: rgba(42, 79, 238, 0.04);
}

.contact-card__num {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 10px;
  color: var(--color-muted);
}

.contact-card__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 16px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.contact-card__desc {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-muted);
  flex: 1;
}

.contact-card__go {
  margin-top: 6px;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--blue);
}

.contact__direct {
  font-family: var(--font-display);
  font-size: 13px;
}

.contact__direct-label {
  display: block;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 8px;
}

.contact__direct a {
  display: block;
  margin-top: 6px;
  color: var(--color-text);
}

.contact__direct a:hover {
  color: var(--blue);
}

/* --- contact forms --- */

.contact-form {
  max-width: 40rem;
}

/* Third-party (Pixieset) form embed — the vendor styles its own insides;
   we just give it the column width and some air above. */
.pixieset-embed {
  margin-top: 8px;
  min-height: 320px;
}

.pixieset-embed iframe {
  width: 100% !important;
  border: 0;
  display: block;
}

.contact-form__lede {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 15px;
  line-height: 1.7;
  color: var(--color-muted);
  max-width: 44ch;
  margin: 0 0 16px;
}

.contact-form__alt {
  display: inline-block;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue);
  border-bottom: 1px solid rgba(42, 79, 238, 0.4);
  margin-bottom: 40px;
  transition: border-color 0.15s ease;
}

.contact-form__alt:hover {
  border-color: var(--blue);
}

.form {
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.field label {
  display: block;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin-bottom: 8px;
}

.field .hint {
  display: block;
  font-family: var(--font-serif);
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-muted);
  margin: 4px 0 10px;
}

.form input[type="text"],
.form input[type="email"],
.form input[type="tel"],
.form select,
.form textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--color-line);
  padding: 8px 2px;
  font-family: var(--font-sans);
  font-size: 16px;
  color: var(--color-text);
  outline: none;
  border-radius: 0;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.15s ease;
}

.form textarea {
  resize: vertical;
  min-height: 6rem;
  line-height: 1.5;
}

.form input:focus,
.form select:focus,
.form textarea:focus {
  border-color: var(--blue);
}

.form ::placeholder {
  color: rgba(20, 20, 20, 0.32);
}

.form select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%23141414' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 2px center;
  padding-right: 20px;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px 28px;
}

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

.checkbox-group {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 12px;
}

.checkbox-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-sans);
  font-size: 14px;
  cursor: pointer;
  border: 1px solid var(--color-line);
  padding: 8px 14px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.checkbox-option:has(input:checked) {
  border-color: var(--blue);
  background: rgba(42, 79, 238, 0.06);
}

.checkbox-option input {
  width: 14px;
  height: 14px;
  accent-color: var(--blue);
  margin: 0;
}

.file-field {
  border: 1px dashed var(--color-line);
  padding: 16px;
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--color-muted);
}

.file-field input[type="file"] {
  display: block;
  margin-top: 8px;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--color-text);
}

button.submit {
  align-self: flex-start;
  margin-top: 8px;
  background: var(--color-text);
  color: var(--color-bg);
  border: 0;
  padding: 14px 34px;
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s ease;
}

button.submit:hover {
  background: var(--blue);
}

button.submit:disabled {
  opacity: 0.5;
  cursor: default;
}

.form-status {
  font-family: var(--font-serif);
  font-size: 15px;
  margin-top: -8px;
}

.form-status.success {
  color: var(--blue);
}

.form-status.error {
  color: #a3271b;
}

form.is-hidden {
  display: none;
}

.success-panel {
  display: none;
  max-width: 30rem;
}

.success-panel.is-visible {
  display: block;
}

.success-panel__heading {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 18px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin: 0 0 12px;
}

.success-panel__text {
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.7;
  color: var(--color-muted);
  margin: 0 0 32px;
}

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.step {
  padding: 22px 0;
}

.step + .step {
  border-top: 1px solid var(--color-line);
}

.step__num {
  font-family: var(--font-sans);
  font-weight: 300;
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--blue);
}

.step__title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 6px 0;
}

.step__desc {
  font-family: var(--font-serif);
  font-size: 15px;
  line-height: 1.6;
  color: var(--color-muted);
  margin: 0;
}

@media (max-width: 720px) {
  .contact__choices {
    grid-template-columns: 1fr;
  }
}

/* ---------- mobile ---------- */

@media (max-width: 820px) {
  /* --- chrome: wordmark centred, burger top-right, the section nav
     becomes a full-screen overlay menu. Same on every page. --- */
  .wordmark {
    top: calc(20px + env(safe-area-inset-top));
    font-size: 15px;
    letter-spacing: 0.2em;
    z-index: 60;
  }

  .nav-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    position: absolute;
    top: calc(20px + env(safe-area-inset-top));
    right: calc(16px + env(safe-area-inset-right));
    width: 28px;
    height: 22px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
    z-index: 60;
  }

  .nav-toggle span {
    display: block;
    width: 100%;
    height: 1.5px;
    background: var(--color-text);
    transition: transform 0.25s ease, opacity 0.2s ease;
  }

  .nav-open .nav-toggle span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
  .nav-open .nav-toggle span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

  .site-nav {
    position: fixed;
    inset: 0;
    background: var(--color-bg);
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 22px;
    z-index: 55;
    opacity: 0;
    visibility: hidden;
    transform: none;
    transition: opacity 0.25s ease, visibility 0.25s;
  }

  .nav-open .site-nav {
    opacity: 1;
    visibility: visible;
  }

  .site-nav a {
    font-size: 17px;
    letter-spacing: 0.18em;
  }

  .site-nav a[aria-current="page"] {
    color: var(--blue);
  }

  .site-nav .n {
    display: none;
  }

  /* --- home keeps the persistent centred nav (no burger): the section
     list sits in the middle of the scatter, legible over the tiles via a
     soft paper halo. Every other page uses the burger overlay above. --- */
  .home .nav-toggle {
    display: none;
  }

  .home .site-nav {
    position: absolute;
    inset: auto;
    /* Anchored to the middle of the scatter's clear central channel
       (canvas starts at the stage's padding-top; +300px is the channel
       centre). The tiles are placed to leave this column frame-free, so
       the nav sits in the middle without touching any frame. */
    top: calc(88px + env(safe-area-inset-top) + 300px);
    left: 50%;
    right: auto;
    transform: translate(-50%, -50%);
    background: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 16px;
    opacity: 1;
    visibility: visible;
    z-index: 45;
  }

  .home .site-nav a {
    font-size: 13px;
    letter-spacing: 0.14em;
  }

  /* --- home: the scatter sits in a fixed-height canvas with a consistent
     gutter (tiles are held within 5%–95% and never bleed off the edge);
     the page scrolls, and the blurb follows in normal flow below the
     frames rather than sitting over them. --- */
  .home-stage {
    height: auto;
    display: block;
    overflow: visible;
    padding-top: calc(88px + env(safe-area-inset-top));
  }

  .home-canvas {
    position: relative;
    width: 100%;
    height: 660px;
    margin: 0;
    aspect-ratio: auto;
    display: block;
    padding: 0;
  }

  .tile {
    display: none;
  }

  .tile--m {
    display: block;
    position: absolute;
    top: var(--my);
    left: var(--mx);
    width: var(--mw);
  }

  .tile__link:hover .tile__media {
    transform: none;
  }

  .tile__tag {
    display: none;
  }

  .blurb {
    position: static;
    margin: 0;
    padding: 28px 20px calc(52px + env(safe-area-inset-bottom));
    max-width: none;
    font-size: 12px;
    line-height: 1.6;
  }

  /* --- inner pages --- */
  .page {
    padding:
      calc(78px + env(safe-area-inset-top))
      calc(16px + env(safe-area-inset-right))
      calc(64px + env(safe-area-inset-bottom))
      calc(16px + env(safe-area-inset-left));
  }

  .page.gallery--motion {
    padding-top: calc(78px + env(safe-area-inset-top));
  }

  .page__heading {
    font-size: 12px;
    margin-bottom: 20px;
  }

  .page__note p {
    font-size: 16px;
  }

  /* --- Motion grid: the three columns collapse to one wrapping row; the
     inline `order` on each card re-flows them into board order, two-up,
     with equal gaps. --- */
  .gallery--motion .gallery-grid {
    flex-wrap: wrap;
    gap: 10px;
  }

  .gallery-col {
    display: contents;
  }

  .gallery--motion .project-card {
    width: calc((100% - 10px) / 2);
  }

  /* Pure grid gallery on mobile: no titles/subtitles under the thumbs.
     The caption only drops in once a single-clip card is playing inline
     (main.js adds .is-playing), so the grid stays clean until you tap. */
  .gallery--motion .project-card__info {
    display: none;
  }

  .gallery--motion .project-card.is-playing .project-card__info {
    display: flex;
    max-height: none;
    overflow: visible;
    opacity: 1;
    transform: none;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 3px 6px;
    margin-top: 7px;
  }

  .gallery--motion .project-card.is-playing .project-card__title {
    flex: 0 0 auto;
  }

  .project-card__title { font-size: 10px; }
  .project-card__meta { font-size: 10px; letter-spacing: 0.02em; }
  .project-card__credit { font-size: 9px; letter-spacing: 0.02em; }
  .project-card__reel-badge { font-size: 9px; padding: 2px 5px; }

  /* Category tabs spread across the border. */
  .category-tabs {
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 24px;
  }

  .category-tabs a {
    font-size: 10px;
    letter-spacing: 0.05em;
  }

  /* --- Motion project detail --- */
  .project-detail__header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .project-detail__meta {
    margin: 0;
  }

  .project-detail__stage {
    margin-bottom: 32px;
  }

  .project-detail__main {
    max-width: 100%;
    max-height: 82vh;
  }

  /* Reels two-up on mobile — the width must net out against the 12px
     flex gap or the second one wraps to its own row. */
  .project-detail__reels,
  .project-detail__reels--wall {
    gap: 12px;
  }

  .project-detail__reel,
  .project-detail__reels--wall .project-detail__reel {
    width: calc((100% - 12px) / 2);
    max-width: none;
  }

  /* --- About --- */
  .about__photo {
    max-width: 100%;
  }

  /* --- Travels --- */
  .travel-section {
    margin-bottom: 44px;
  }

  .travel-grid {
    grid-template-columns: 1fr;
    gap: 14px;
  }

  /* --- Contact --- */
  .contact__lede {
    font-size: 14px;
    margin-bottom: 32px;
  }

  .contact__choices {
    grid-template-columns: 1fr;
    gap: 16px;
    margin-bottom: 40px;
  }

  .contact-form__lede {
    font-size: 14px;
  }

  .contact-form__alt {
    margin-bottom: 32px;
  }
}
