:root {
  --bg: #000;
  --fg: #fff;
  --muted: #aeaca8;
  --pad: 16px;
  --display: "Inter", "Inter Display", system-ui, sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  background: var(--bg);
  color: var(--fg);
  font-family: var(--display);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
::selection { background: var(--fg); color: var(--bg); }

/* Small labels — same typeface as the headings, just smaller (Title Case, as written) */
.mono {
  font-family: var(--display);
  font-variation-settings: "opsz" 32;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.01em;
}

/* Section headings — "Explore Projects", "The Room", "West 42 Studios"
   all share one size, weight and finish */
.title, .studio-title, .room-title {
  font-size: clamp(38px, 4.6vw, 60px);
  font-weight: 700;
  letter-spacing: -0.045em;
  line-height: 1.06;
  font-variation-settings: "opsz" 32;
  background: linear-gradient(180deg, #fff 35%, #a1a1a6 130%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  /* Extra room so letter edges/descenders aren't clipped by the gradient fill
     (negative margins cancel it out, so the layout doesn't shift) */
  padding: .12em .1em;
  margin: -.12em -.1em;
}

/* ---------- Header ---------- */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 50;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 28px;
  height: 52px;
  padding: 0 var(--pad);
  color: #fff;
  border-bottom: 1px solid rgba(255,255,255,.12);
  /* Own compositing layer: the browser can slide the glass over the page smoothly
     without repainting the rest of the page on every scroll frame */
  transform: translateZ(0);
  isolation: isolate;
}
/* Logo: a small distant star. A bright pin-point core, a soft blue-white halo,
   and faint cross-shaped light spikes, twinkling very slowly. */
.logo {
  position: fixed; top: 6px; left: var(--pad); z-index: 51;
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
}
/* Desktop: the star sits in the centre of the header (the links start on the
   left edge of the centred project grid) */
@media (min-width: 810px) {
  .logo { left: calc(50% - 20px); }
}
.star {
  position: relative;
  width: 4px; height: 4px; border-radius: 50%;
  background: #fff;
  box-shadow:
    0 0 3px 1px #fff,
    0 0 9px 3px rgba(200, 222, 255, .55),
    0 0 20px 7px rgba(140, 180, 255, .22);
  animation: star-twinkle 5s ease-in-out infinite;
}
.star::before, .star::after {                     /* the light spikes */
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 30px; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.75) 50%, transparent);
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.star::after { transform: translate(-50%, -50%) rotate(90deg); width: 22px; }
@keyframes star-twinkle {
  0%, 100% { opacity: 1;   transform: scale(1); }
  45%      { opacity: .72; transform: scale(.86); }
  55%      { opacity: .8;  transform: scale(.9); }
}
.logo:hover .star { animation-duration: 1.6s; }   /* quickens a little on hover */
@media (prefers-reduced-motion: reduce) { .star { animation: none; } }

/* Desktop links start on the left edge of the centred project grid (the star sits in the centre) */
.nav {
  display: flex; gap: 32px;
  position: absolute; top: 50%;
  left: max(var(--pad), calc(50% - 464px));
  transform: translateY(-50%);
}
/* Hover dims the text colour (not opacity) so the glass header behind it isn't re-rendered */
.nav a { font-size: 14px; font-weight: 700; color: #fff; transition: color .2s; }
.nav a:hover { color: rgba(255,255,255,.6); }

/* Hamburger: mobile only (shown in the media query below) */
/* Apple-style: two short, thin lines in a generous 40px tap area.
   Lines are 17px wide, 1.2px thick, 5px apart — each moves (5 + 1.2) / 2 = 3.1px
   to meet in the middle as it rotates into the ✕. */
.menu-btn {
  display: none;
  width: 40px; height: 40px;
  margin-right: -11.5px;                 /* keeps the lines' right edge aligned with the page margin */
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.menu-btn span {
  display: block; width: 17px; height: 1.2px; border-radius: 1px;
  background: #fff;
  transition: transform .45s cubic-bezier(.77,0,.18,1);
}
.menu-btn[aria-expanded="true"] span:first-child { transform: translateY(3.1px) rotate(45deg); }
.menu-btn[aria-expanded="true"] span:last-child  { transform: translateY(-3.1px) rotate(-45deg); }

/* Mobile menu: a glass panel directly under the header. The glass grows straight
   down from the header's bottom edge (a vertical scale anchored at that edge) and
   the links fade in on top; closing reverses it. Only `transform` and `opacity`
   animate, which the phone's graphics chip handles on its own, so it stays smooth.
   Nothing ever passes behind the header, so no glass layers stack. */
.menu {
  display: none;
  position: fixed; top: 51px; left: 0; right: 0; z-index: 49;   /* right under the header's glass */
  visibility: hidden; pointer-events: none;
  transition: visibility 0s linear .5s;
}
.menu.is-open { visibility: visible; transition: visibility 0s; }
.menu-panel {
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; gap: 2px;
  padding: 10px var(--pad) 26px;
  pointer-events: auto;
}
/* The glass: exactly the header's. Like the header's, it reaches 64px past its top
   edge and is clipped back, so both blur across the seam the same way. It scales
   from the panel's top edge (64px into this layer): the rounded corners and the
   hairline round out as it opens and flatten as it closes. */
.menu-panel::before {
  content: ""; position: absolute; inset: -64px 0 0 0; z-index: -1;
  background: rgba(22,22,24,.42);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid rgba(255,255,255,.14);
  border-radius: 0 0 24px 24px;
  clip-path: inset(64px 0 0 0);
  transform-origin: 50% 64px;
  transform: scaleY(0);
  transition: transform .5s cubic-bezier(.32,.72,0,1);
  will-change: transform;
  pointer-events: none;
}
.menu.is-open .menu-panel::before { transform: none; transition-duration: .55s; }

/* Header glass: frosted and slightly tinted (Apple's recipe). The layer reaches
   64px below the header but is clipped to the header's height, so the blur along
   its bottom edge picks up the page below, just like the drawer's top edge does:
   header and drawer meet without a visible seam. */
.site-header::before {
  content: "";
  position: absolute; inset: 0 0 -64px 0;
  z-index: -1;
  background: rgba(22,22,24,.42);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
  clip-path: inset(0 0 64px 0);
  pointer-events: none;
}
/* While the drawer is open the header's hairline is hidden, so header and drawer
   read as one sheet; it returns once the drawer has fully slid away (.5s). */
.site-header { transition: border-color 0s linear .5s; }
body.menu-open .site-header { border-bottom-color: transparent; transition: none; }

.menu-link {
  font-size: 32px; font-weight: 500;
  letter-spacing: -0.04em; line-height: 1.25;
  font-variation-settings: "opsz" 32;
  color: #fff;
  width: fit-content;
  opacity: 0; transform: translateY(-8px);
  transition: opacity .3s ease, transform .45s cubic-bezier(.32,.72,0,1);
}
.menu.is-open .menu-link { opacity: 1; transform: none; }
.menu.is-open .menu-link:nth-child(1) { transition-delay: .12s; }
.menu.is-open .menu-link:nth-child(2) { transition-delay: .18s; }
.menu.is-open .menu-link:nth-child(3) { transition-delay: .24s; }
.menu-link:active { opacity: .6; }

/* Invisible layer below the menu: tap it to close (no dimming) */
.menu-scrim {
  position: fixed; inset: 0; z-index: 48;
  background: transparent;
  visibility: hidden;
}
body.menu-open .menu-scrim { visibility: visible; }

/* ---------- Home (simple Apple-style landing) ---------- */
.hero {
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; align-items: center;
  padding: clamp(110px, 16vh, 170px) var(--pad) 64px;
  text-align: center;
}
.hero-name {
  font-size: clamp(48px, 7vw, 96px);
  font-weight: 700; letter-spacing: -0.05em; line-height: 1.02;
  font-variation-settings: "opsz" 32;
  background: linear-gradient(180deg, #fff 35%, #a1a1a6 130%);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  padding: .1em .1em; margin: -.1em -.1em;      /* room so letter edges aren't clipped */
}
.hero-role {
  margin-top: 14px;
  font-size: clamp(19px, 2vw, 26px); font-weight: 500;
  letter-spacing: -0.02em; color: #86868b;
}
.hero-actions {
  display: flex; align-items: center; justify-content: center; gap: 22px;
  margin-top: 34px;
}
.btn-primary {
  display: inline-flex; align-items: center;
  height: 44px; padding: 0 24px;
  border-radius: 999px;
  background: #f5f5f7; color: #000;
  font-size: 16px; font-weight: 600; letter-spacing: -0.01em;
  transition: background .25s, transform .2s cubic-bezier(.32,.72,0,1);
}
.btn-primary:hover { background: #fff; }
.btn-primary:active { transform: scale(.97); }
.btn-link {
  font-size: 16px; font-weight: 500; color: #2997ff;     /* Apple's link blue */
  transition: opacity .2s;
}
.btn-link:hover { opacity: .75; text-decoration: underline; text-underline-offset: 3px; }
.btn-link span { margin-left: 2px; }

/* One still frame from the latest work — plays only when clicked */
.hero-card {
  position: relative;
  width: min(1080px, 100%);
  margin: clamp(48px, 7vh, 80px) 0 0;
  aspect-ratio: 2206 / 946;
  border-radius: 24px;
  overflow: hidden;
  background: #0b0b0c;
  cursor: pointer;
  box-shadow: 0 0 0 .5px rgba(255,255,255,.1), 0 30px 80px rgba(0,0,0,.6);
}
.hero-card video { width: 100%; height: 100%; display: block; object-fit: cover; pointer-events: none; }
.hero-card::after {                                   /* gentle shade for the caption */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,.55), transparent 40%);
}
.hero-play {
  position: absolute; left: 50%; top: 50%; z-index: 2;
  width: 64px; height: 64px; border-radius: 50%;
  translate: -50% -50%;
  display: grid; place-items: center;
  background: rgba(30,30,32,.45);
  border: .5px solid rgba(255,255,255,.25);
  -webkit-backdrop-filter: blur(16px) saturate(170%);
  backdrop-filter: blur(16px) saturate(170%);
  transition: transform .35s cubic-bezier(.32,.72,0,1), background .3s;
}
.hero-play svg { width: 20px; height: 20px; fill: #fff; margin-left: 3px; }
.hero-card:hover .hero-play { transform: scale(1.08); background: rgba(60,60,64,.55); }
.hero-caption {
  position: absolute; left: 22px; bottom: 18px; z-index: 2;
  font-size: 14px; color: #fff; text-align: left;
}
.hero-caption span { color: rgba(255,255,255,.7); margin-left: 6px; }

/* Entrance: name, role, buttons and image fade up in sequence, then stay still */
.hero-name, .hero-role, .hero-actions, .hero-card { animation: hero-in 1.2s cubic-bezier(.16,.84,.3,1) both; }
.hero-role    { animation-delay: .12s; }
.hero-actions { animation-delay: .24s; }
.hero-card    { animation-delay: .38s; }
@keyframes hero-in { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .hero-name, .hero-role, .hero-actions, .hero-card { animation: none; }
}
/* ---------- Work heading ---------- */
/* "Projects" centred, with the categories as a segmented control beneath it */
.work-head {
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  padding: 140px var(--pad) 72px;
  text-align: center;
}
.work-head .title { order: 1; }

.filters {
  position: relative;
  display: inline-flex; align-items: center; gap: 2px;
  max-width: 100%;
  padding: 4px;
  border-radius: 999px;
  background: rgba(255,255,255,.06);
  border: .5px solid rgba(255,255,255,.12);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.06);
  overflow-x: auto; scrollbar-width: none;      /* scrolls sideways on very narrow screens */
}
.filters::-webkit-scrollbar { display: none; }
.filter {
  position: relative; z-index: 1;
  padding: 9px 18px;
  border-radius: 999px;
  white-space: nowrap;
  color: var(--muted);
  transition: color .3s ease;
}
.filter:hover, .filter.is-active { color: var(--fg); }
/* Highlight that glides to the selected category */
.filter-indicator {
  position: absolute; top: 4px; bottom: 4px; left: 0; width: 0;
  border-radius: 999px;
  background: rgba(255,255,255,.14);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 3px rgba(0,0,0,.3);
  transition: transform .5s cubic-bezier(.32,.72,0,1), width .5s cubic-bezier(.32,.72,0,1);
  pointer-events: none;
}

.title { white-space: nowrap; }      /* size/weight shared with the other section headings */
/* Long search terms trim with "…" */
#titleText {
  display: inline-block; vertical-align: bottom;
  max-width: min(80vw, 720px);
  overflow: hidden; text-overflow: ellipsis;
  /* room inside the trim box for the "j" descender and round letter edges */
  padding: .08em .08em .14em; margin: -.08em -.08em -.14em;
  background: inherit; -webkit-background-clip: text; background-clip: text;
}

/* ---------- Grid view ---------- */
/* Social-profile style: a compact, centred grid of justified rows with tight
   gaps and no empty spaces. On desktop every video keeps its own shape; on phones
   tiles share one shape per kind, like a feed. JS positions each tile
   (see layoutGrid in script.js). */
.projects.grid {
  --tile-gap: 4px;
  position: relative;
  max-width: 960px;
  margin: 0 auto;
  padding: 0 var(--pad);
}
.project { cursor: pointer; position: absolute; top: 0; left: 0; }
.project.is-hidden, .project.is-collapsed { display: none; }

/* Sort-by switch: fade out → swap → ease height → cascade in */
.projects { transition: height .6s cubic-bezier(.32,.72,0,1); }
.projects.is-switching, .projects.is-settling { overflow: hidden; }
.projects.is-switching .project {
  opacity: 0 !important; transform: translateY(14px) !important;
  transition: opacity .3s ease, transform .3s ease !important;
}
.projects.is-settling .project {
  transition: opacity .6s ease, transform .7s cubic-bezier(.2,.7,.2,1);
}

/* "Show more" — frosted pill, same family as the search bar */
.show-more-wrap { display: flex; justify-content: center; padding: 48px var(--pad) 8px; }
.show-more {
  display: inline-flex; align-items: center; gap: 10px;
  height: 44px; padding: 0 22px;
  border-radius: 999px;
  font-size: 15px; font-weight: 500; letter-spacing: -0.01em;
  font-variation-settings: "opsz" 32;
  color: #fff;
  background: rgba(255,255,255,.08);
  border: .5px solid rgba(255,255,255,.16);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.10), 0 1px 2px rgba(0,0,0,.25);
  -webkit-backdrop-filter: blur(20px) saturate(170%);
  backdrop-filter: blur(20px) saturate(170%);
  transition: background .3s cubic-bezier(.32,.72,0,1), border-color .3s, transform .2s cubic-bezier(.32,.72,0,1);
}
.show-more[hidden] { display: none; }
.show-more:hover { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.28); }
.show-more:active { transform: scale(.97); }
.show-more-count { color: #a1a1a6; font-variant-numeric: tabular-nums; }
.media { position: relative; overflow: hidden; background: #0d0d0d; border-radius: 4px; }
.wide .media { aspect-ratio: 16 / 9; }
.tall .media { aspect-ratio: 9 / 16; }
.media video { width: 100%; height: 100%; display: block; object-fit: cover; }
/* Soft dim on idle tiles that lifts on hover. Done with an overlay rather than
   scaling/filtering the video itself, which made playback jitter. */
.media::after {
  content: ""; position: absolute; inset: 0;
  background: #000; opacity: .12;
  transition: opacity .5s cubic-bezier(.2,.7,.2,1);
  pointer-events: none;
}
.project:hover .media::after { opacity: 0; }

/* Title + category over the bottom of the tile, Apple TV-style: a small grey
   category line above a larger semibold title, on a tall, soft shade.
   Text scales with each tile's width (container units), so big tiles get big type. */
.project { container-type: inline-size; }
.meta {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  display: flex; flex-direction: column; gap: 3px;
  padding: clamp(40px, 14cqw, 90px) clamp(12px, 3.2cqw, 24px) clamp(12px, 3cqw, 22px);
  border-radius: 0 0 4px 4px;
  background: linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.38) 45%, rgba(0,0,0,0) 100%);
  pointer-events: none;
  font-family: var(--display);
  text-shadow: 0 1px 12px rgba(0,0,0,.35);
}
.meta .name {
  font-size: clamp(15px, 1.7cqw + 11px, 26px);
  font-weight: 600; letter-spacing: -0.022em; line-height: 1.15;
  font-variation-settings: "opsz" 32;
  color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.meta .client {
  order: -1;                                     /* category sits above the title */
  font-size: clamp(11px, .5cqw + 10px, 14px);
  font-weight: 600; letter-spacing: .01em;
  color: rgba(255,255,255,.68);
}
/* Small tiles (three-across on phones): the title alone, still crisp and readable */
@media (max-width: 809px) {
  @container (max-width: 200px) {
    .meta { padding: 36px 8px 8px; }
    .meta .name {
      font-size: 13px; letter-spacing: -0.015em; line-height: 1.2;
      white-space: normal;                         /* long titles wrap to two lines instead of "…" */
      display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
    }
    .meta .client { display: none; }
  }
}

/* ---------- West 42 Studios (scroll-scrubbed intro) ---------- */
.studio { margin-top: 160px; background: #000; }
.studio-scroll { position: relative; height: 340vh; }        /* scroll distance that drives the sequence */
.studio-sticky {
  position: sticky; top: 0;
  height: 100vh; height: 100svh;
  overflow: hidden;
  background: #000;
}
.studio-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  transform-origin: center;
  will-change: transform, opacity;
  opacity: 0;                          /* JS fades it in as the section arrives */
}
/* Soft edge fade so the footage melts into the black page above and below */
.studio-sticky::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to bottom, #000, transparent 18%, transparent 82%, #000),
    radial-gradient(120% 90% at 50% 50%, transparent 55%, rgba(0,0,0,.55));
}
.studio-caption {
  position: absolute; inset: 0; z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 0 var(--pad);
  opacity: 0; pointer-events: none;
  will-change: opacity, transform;
}
.studio-sub { color: #86868b; margin-top: 18px; font-size: 15px; letter-spacing: 0; }
/* Apple-style text link: blue, with a chevron that nudges right on hover.
   Only clickable once the title has faded in (JS enables it). */
.studio-link {
  margin-top: 26px;
  font-size: 17px; font-weight: 500; letter-spacing: -0.01em;
  color: #2997ff;
  pointer-events: none;
  transition: color .2s;
}
.studio-link span { display: inline-block; margin-left: 2px; transition: transform .3s cubic-bezier(.32,.72,0,1); }
.studio-link:hover { color: #47a6ff; text-decoration: underline; text-underline-offset: 3px; }
.studio-link:hover span { transform: translateX(3px); }
.studio-caption.is-shown .studio-link { pointer-events: auto; }

/* Portrait screens: show more of the frame so the W42 mark isn't cropped */
@media (orientation: portrait) {
  .studio-video {
    inset: auto; top: 50%; left: 50%;
    width: 190vw; height: auto; aspect-ratio: 16 / 9;
    translate: -50% -50%;
    /* Feather the top/bottom edges so the frame melts into the black page */
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 28%, #000 72%, transparent);
    mask-image: linear-gradient(to bottom, transparent, #000 28%, #000 72%, transparent);
  }
  .studio-scroll { height: 280vh; }
}
/* ---------- The Room (a still image of the space) ---------- */
/* Theatrical intro: the heading rises in on black, then the room's lights come up
   (a soft flicker, then full brightness). */
.room-section { margin-top: 160px; text-align: center; scroll-margin-top: 84px; }   /* menu jumps stop below the header bar */
.room-head { padding: 0 var(--pad); }
.room-sub { margin-top: 14px; font-size: clamp(17px, 1.6vw, 21px); font-weight: 500; letter-spacing: -0.015em; color: #86868b; }
.room-stage {
  position: relative;
  max-width: 1600px; margin: 28px auto 0;
  aspect-ratio: 16 / 9;
  user-select: none; -webkit-user-select: none;
}
.room-img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  pointer-events: none;                           /* the room itself isn't interactive */
  -webkit-user-drag: none;
  /* edges melt into the black page */
  -webkit-mask-image: radial-gradient(75% 80% at 50% 50%, #000 62%, transparent 100%);
  mask-image: radial-gradient(75% 80% at 50% 50%, #000 62%, transparent 100%);
}

.room-head { opacity: 0; transform: translateY(26px); transition: opacity 1s ease, transform 1.2s cubic-bezier(.16,.84,.3,1); }
.room-img { filter: brightness(0); transform: scale(1.06); }
.room-section.is-presented .room-head { opacity: 1; transform: none; }
.room-section.is-presented .room-img { animation: room-lights 2.8s cubic-bezier(.3,.1,.2,1) .5s both; }
@keyframes room-lights {
  0%   { filter: brightness(0) saturate(.6); transform: scale(1.06); }
  22%  { filter: brightness(.38) saturate(.7); }
  28%  { filter: brightness(.16) saturate(.7); }   /* a little flicker as the lights catch */
  36%  { filter: brightness(.5) saturate(.8); }
  100% { filter: brightness(1) saturate(1); transform: scale(1); }
}

/* Phones: a squarer render of the same room */
@media (max-width: 700px) {
  .room-stage { aspect-ratio: 1400 / 1150; margin-top: 18px; }
}
@media (prefers-reduced-motion: reduce) {
  .room-head { opacity: 1; transform: none; transition: none; }
  .room-img, .room-section.is-presented .room-img { filter: none; transform: none; animation: none; }
}

/* ---------- Footer ---------- */
.site-footer { padding: 160px var(--pad) 56px; }
/* Slow fade-up used across the site as content scrolls into view */
.js .reveal {
  opacity: 0; transform: translateY(40px);
  transition: opacity 1.4s cubic-bezier(.16,.84,.3,1), transform 1.4s cubic-bezier(.16,.84,.3,1);
}
.js .reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
}

/* Footer links — three equal columns, centred on the page */
.cols {
  border-top: 1px solid #1d1d1f;   /* thin divider above the footer links */
  padding-top: 56px;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px;
  max-width: 900px; margin: 0 auto;
  text-align: center;
}
.cols > div { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.cols a { width: fit-content; transition: opacity .2s; }
.cols a:hover { opacity: .6; }
.label { color: #a9a9a9; margin-bottom: 14px; }
.bottom {
  display: flex; justify-content: center;
  margin-top: 96px;
  color: #6e6e73;
}

/* ---------- Lightbox ---------- */
.lightbox {
  position: fixed; inset: 0; z-index: 60;
  background: #000;                     /* fully dark room — only the video's glow lights it */
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
  padding: 64px var(--pad) 32px;
  opacity: 0; pointer-events: none; transition: opacity .3s;
}
.lightbox.is-open { opacity: 1; pointer-events: auto; }
/* Dark-room viewing: a blurred live copy of the video spills soft coloured light
   around the frame, like a screen glowing in a dark room */
.lb-stage { position: relative; display: flex; max-width: 100%; }
.lb-glow {
  position: absolute; left: -12%; top: -12%; width: 124%; height: 124%;
  z-index: 0; pointer-events: none;
  filter: blur(90px) saturate(1.2);
  opacity: 0; transition: opacity 1.2s ease;
}
.lightbox.is-open .lb-glow { opacity: .28; }    /* very subtle light spill */
.lightbox video {
  position: relative; z-index: 1;
  max-width: 100%; max-height: calc(100vh - 180px);
  border-radius: 10px;
  background: #000;
  cursor: pointer;
}

/* Minimal controls row beneath the video */
.lb-controls {
  display: flex; align-items: center; gap: 14px;
  width: min(720px, 100%);
  margin-top: 4px;
}
.lb-btn {
  flex: none;
  width: 30px; height: 30px; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff;
  transition: background .2s, opacity .2s;
}
.lb-btn:hover { background: rgba(255,255,255,.1); }
.lb-btn svg { width: 14px; height: 14px; fill: currentColor; }
.lb-btn .i-play, .lb-btn .i-muted { display: none; }
.lightbox.is-paused .lb-btn .i-play { display: block; }
.lightbox.is-paused .lb-btn .i-pause { display: none; }
.lightbox.is-muted .lb-btn .i-muted { display: block; }
.lightbox.is-muted .lb-btn .i-sound { display: none; }

.lb-progress {
  position: relative; flex: 1;
  height: 18px;                          /* generous hit area around a thin line */
  cursor: pointer;
}
.lb-progress::before, .lb-progress-fill {
  content: ""; position: absolute; left: 0; top: 50%;
  height: 2px; border-radius: 2px; transform: translateY(-50%);
}
.lb-progress::before { right: 0; background: rgba(255,255,255,.18); }
.lb-progress-fill { width: 0; background: #fff; }
.lb-progress:hover::before, .lb-progress:hover .lb-progress-fill { height: 4px; }
.lb-time { flex: none; color: #a1a1a6; font-variant-numeric: tabular-nums; }
.close { position: absolute; top: 18px; right: var(--pad); }
.close:hover { opacity: .6; }

/* ---------- Projects toolbar ---------- */
/* Small "N Results for “…”" line under the toolbar while searching */
.results-note {
  order: 3;
  margin-top: -8px;
  font-size: 13px; color: #86868b;
  animation: note-in .35s ease both;
}
.results-note[hidden] { display: none; }
@keyframes note-in { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* Categories (and the search inside the same pill), centred under the heading */
.toolbar {
  order: 2;
  display: flex; align-items: center; justify-content: center; flex-wrap: wrap;
  gap: 12px;
  max-width: 100%;
}
/* Search lives inside the category pill: a magnifier icon after the last category.
   Opening it crossfades the same pill into a full-width search field. */
.filters-divider {
  flex: none; width: 1px; height: 18px; margin: 0 4px;
  background: rgba(255,255,255,.14);
}
.search-open {
  position: relative; z-index: 1; flex: none;
  width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--muted);
  transition: color .3s ease, background .3s ease;
}
.search-open:hover { color: var(--fg); background: rgba(255,255,255,.08); }
.search-open svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }

/* The search field: sits exactly over the pill's buttons, hidden until opened */
.search {
  position: absolute; inset: 4px; z-index: 2;
  display: flex; align-items: center; gap: 7px;
  padding: 0 6px 0 14px;
  cursor: text;
  opacity: 0; visibility: hidden;
  transform: scale(.98);
  transition: opacity .3s ease, transform .4s cubic-bezier(.32,.72,0,1), visibility 0s linear .3s;
}
.search svg.icon {
  width: 13px; height: 13px; flex: none;
  fill: none; stroke: rgba(255,255,255,.55); stroke-width: 1.7; stroke-linecap: round;
  transition: stroke .3s ease;
}
.search:focus-within svg.icon { stroke: rgba(255,255,255,.85); }
.search input {
  flex: 1; min-width: 0;
  height: 100%; align-self: stretch; padding: 0; cursor: text;
  background: none; border: 0; outline: 0;
  color: #fff; font: inherit; letter-spacing: inherit;
  caret-color: #fff;
}
.search input::placeholder { color: rgba(255,255,255,.45); }
.search input::-webkit-search-cancel-button { -webkit-appearance: none; }
/* ✕ clears the search and turns the pill back into the categories */
.search-clear {
  width: 16px; height: 16px; flex: none;
  display: grid; place-items: center;
  border-radius: 50%;
  background: rgba(255,255,255,.32);
  transition: background .2s;
}
.search-clear svg { width: 7px; height: 7px; stroke: #1c1c1e; stroke-width: 2; stroke-linecap: round; }
.search-clear:hover { background: rgba(255,255,255,.5); }
.no-results { padding: 40px var(--pad) 80px; color: var(--muted); text-align: center; }

/* Open state */
.filters > .filter, .filters > .filters-divider, .filters > .search-open {
  transition: opacity .25s ease, transform .4s cubic-bezier(.32,.72,0,1), color .3s ease;
}
.filters.is-searching > .filter,
.filters.is-searching > .filters-divider,
.filters.is-searching > .search-open { opacity: 0; transform: scale(.96); pointer-events: none; }
/* The highlight is positioned with transform, so it only fades */
.filters.is-searching > .filter-indicator { opacity: 0; }
.filter-indicator { transition: transform .5s cubic-bezier(.32,.72,0,1), width .5s cubic-bezier(.32,.72,0,1), opacity .25s ease; }
.filters.is-searching > .search {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .3s ease .05s, transform .4s cubic-bezier(.32,.72,0,1), visibility 0s;
}
.filters.is-searching { background: rgba(255,255,255,.1); border-color: rgba(255,255,255,.22); }
.filters { transition: background .3s ease, border-color .3s ease; }

/* ---------- Phones ---------- */
@media (max-width: 809px) {
  .site-header { gap: 16px; }
  .hero { justify-content: center; padding-top: 84px; padding-bottom: 48px; }
  .hero-card { border-radius: 16px; }
  .hero-play { width: 52px; height: 52px; }
  .hero-caption { left: 14px; bottom: 12px; font-size: 13px; }

  .nav { display: none; }
  /* Phones: categories + search icon in one pill; 16px text stops iPhones zooming in */
  .search input { font-size: 16px; }
  .filters-divider { margin: 0 2px; }
  .search-open { width: 32px; height: 32px; }
  .menu-btn { display: flex; }
  .menu { display: block; }

  .work-head { gap: 20px; padding: 96px var(--pad) 40px; }
  #titleText { max-width: calc(100vw - 40px); }
  .filter { padding: 8px 9px; }

  /* Phones: still three across, edge to edge with hairline gaps, like the apps */
  .projects.grid { --tile-gap: 2px; padding: 0; }
  .media, .meta { border-radius: 0; }

  .cols { grid-template-columns: 1fr; gap: 40px; }
  .bottom { margin-top: 64px; }
}
