/* Self-hosted fonts (latin subsets, woff2 from Fontsource - the same files
   Google Fonts serves). Keeping them on our own origin removes a blocking
   third-party stylesheet and a second connection from the critical path.
   font-display: swap so text paints immediately in the fallback face. */
@font-face {
  font-family: "Prata";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/prata-latin-400-normal.woff2") format("woff2");
}

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

@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/lato-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Lato";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/lato-latin-400-italic.woff2") format("woff2");
}

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

html,
body {
  height: 100%;
  overflow: hidden; /* no native scroll - page transitions are transform-based */
  background: #ebebeb;
  color: #000;
  font-family: "Lato", -apple-system, BlinkMacSystemFont, sans-serif;
  scrollbar-width: none;
}

/* Lock the layout viewport on iOS: with the body fixed to the screen, Safari
   can never expand or pan the page because of wide content (the carousel rows
   are many screens wide). There is no native scroll, so this costs nothing. */
body {
  position: fixed;
  inset: 0;
  width: 100%;
}

body::-webkit-scrollbar {
  display: none;
}

/* Loading curtain */
.curtain {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.curtain-logo {
  height: clamp(1.4rem, 3vw, 2rem);
  opacity: 0.6;
}

/* Nav */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: clamp(1rem, 2.5vw, 1.5rem);
  pointer-events: auto;
  opacity: 0;
}

.nav-logo {
  height: clamp(1.2rem, 2.5vw, 1.6rem);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(0.5rem, 1.5vw, 1rem);
}

.nav-links a {
  color: #fff;
  text-decoration: none;
  font-size: clamp(0.8rem, 1.5vw, 0.9rem);
  letter-spacing: 0.02em;
}

.nav-links a:hover {
  opacity: 0.7;
}

.nav-home {
  display: flex;
  align-items: center;
  text-decoration: none;
  cursor: pointer;
}

.nav-divider {
  opacity: 0.4;
  font-size: 0.9rem;
}

/* Page 1 hero content */
.hero-content {
  position: fixed;
  z-index: 15;
  bottom: 20vh;
  left: 0;
  right: 0;
  text-align: center;
  padding: 0 1.5rem;
  pointer-events: none;
  opacity: 0;
}

.hero-headline {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.8rem, 6vw, 3.2rem);
  font-weight: 700;
  color: #fff;
  line-height: 1.15;
  margin: 0;
}

.hero-subheadline {
  font-family: "Lato", -apple-system, sans-serif;
  font-size: clamp(0.85rem, 2vw, 1.05rem);
  font-weight: 400;
  color: rgba(255, 255, 255, 0.75);
  margin-top: 0.8rem;
  letter-spacing: 0.03em;
}

.hero-cta-row {
  display: flex;
  justify-content: center;
  gap: 1rem;
  margin-top: clamp(1.2rem, 3vw, 2rem);
}

.hero-cta {
  display: inline-block;
  min-width: 12rem;
  text-align: center;
  padding: 0.7rem 2rem;
  font-family: "Lato", -apple-system, sans-serif;
  font-size: clamp(0.8rem, 1.5vw, 0.9rem);
  font-weight: 400;
  letter-spacing: 0.08em;
  color: #fff;
  text-decoration: none;
  border: 1px solid rgba(255, 255, 255, 0.5);
  border-radius: 100px;
  pointer-events: auto;
  transition: background 0.3s, border-color 0.3s;
}

.hero-cta:hover {
  background: rgba(255, 255, 255, 0.12);
  border-color: rgba(255, 255, 255, 0.8);
}

.hero-lottie {
  width: clamp(60px, 8vw, 100px);
  margin: 0 auto 1rem;
}

/* Contact modal */
.contact-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
}

.contact-modal {
  position: fixed;
  z-index: 51;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(90vw, 480px);
  background: #1a1a1a;
  color: #fff;
  border-radius: 12px;
  padding: clamp(2rem, 4vw, 3rem);
}

.contact-close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  transition: color 0.2s;
}

.contact-close:hover {
  color: #fff;
}

/* The admin login modal reuses .contact-backdrop, .contact-modal, .contact-close
   and .contact-heading below - it is the only thing left that does. The contact
   details themselves live on the about page now, not in a modal. */
.contact-heading {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.4rem, 3vw, 1.8rem);
  font-weight: 400;
  margin-bottom: 2rem;
}

/* Reel modal */
.reel-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, 0.85);
}

/* The reel runs full-bleed: the stage is as wide as the layout viewport and
   only steps down when the file's own ratio would make it taller than the
   screen. That sizing is done in JS (sizeReel) from the viewport probe, for
   the same reason everything else is: innerHeight is not the fixed-element
   viewport on iOS. */
.reel-modal {
  position: fixed;
  z-index: 51;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* The author rule above beats the UA stylesheet's [hidden] { display: none },
   so the closed modal has to be told to stay away explicitly */
.reel-modal[hidden] {
  display: none;
}

.reel-close {
  position: absolute;
  z-index: 2;
  top: clamp(0.8rem, 3vh, 1.6rem);
  right: clamp(0.8rem, 3vw, 1.6rem);
  background: none;
  border: none;
  color: rgba(255, 255, 255, 0.6);
  cursor: pointer;
  transition: color 0.2s;
}

.reel-close:hover {
  color: #fff;
}

.reel-stage {
  position: relative;
  background: #000;
  max-width: 100%;
}

.reel-video {
  width: 100%;
  height: 100%;
  display: block;
}

/* Loading screen - the logo and the reel's name sit over the player until the
   video actually starts, then fade out. Never accepts clicks: the controls
   underneath belong to the visitor the moment they are usable. */
.reel-loading {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vh, 1.6rem);
  background: #000;
  pointer-events: none;
}

.reel-loading-logo {
  width: clamp(120px, 22vw, 260px);
  height: auto;
  display: block;
}

/* Same treatment as the "About Ghost VFX" kicker on the about page */
.reel-loading-label {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.4);
  text-align: center;
  padding: 0 1rem;
}

/* Back control, top left of pages 1 and 2. Above the about layer (z 12) but
   below the modals (z 50), and invisible on the front page - opacity is
   animated by goToPage(), which also owns the pointer events, since a
   transparent link would otherwise still take clicks over the hero video.
   The text shadow keeps it legible over an arbitrary video frame. */
.nav-back {
  position: fixed;
  z-index: 20;
  top: clamp(1rem, 2.5vw, 1.5rem);
  left: clamp(1rem, 2.5vw, 1.5rem);
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: clamp(0.6rem, 1.3vw, 0.7rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.55);
  text-decoration: none;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transition: color 0.2s;
}

.nav-back:hover {
  color: #fff;
}

/* Scroll indicator */
.scroll-indicator {
  position: fixed;
  z-index: 15;
  bottom: clamp(1.5rem, 4vh, 2.5rem);
  left: 50%;
  transform: translateX(-50%);
  width: clamp(36px, 8vw, 48px);
  height: clamp(36px, 8vw, 48px);
  pointer-events: auto;
  cursor: pointer;
  opacity: 0;
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50% { transform: translateX(-50%) translateY(6px); }
}

/* Hero */
.hero-image {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #000; /* any subpixel gap shows black, never the page background */
  pointer-events: none;
}

.hero-image::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  /* --hero-gradient-strength is the editor's dial (CMS: Forside > Mørk
     overgang, 0-1, default 0.7); --gradient-opacity is main.js fading the
     whole thing out during the page 0 -> 1 transition. Two variables so the
     transition never fights the setting. */
  background: linear-gradient(transparent 0%, rgba(0, 0, 0, var(--hero-gradient-strength, 0.7)) 70%);
  opacity: var(--gradient-opacity, 1);
  z-index: 1;
  pointer-events: none;
}

/* main.js sets the element's width/height to the cover size it computed from
   the file's own aspect, so the picture is never distorted by `fill`. */
.hero-video {
  position: absolute;
  display: block;
  object-fit: fill;
}

/* Overlay inside hero - SHOWS title + arrows */
/* Sits over the shrunken hero video on page 1: the logo, and a discreet
   contact link beside it. pointer-events are handed to it by goToPage() and
   only on page 1 - the overlay is transparent everywhere else, and an
   invisible link is still a clickable one. */
.hero-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: flex-end;
  gap: clamp(0.9rem, 2.5vw, 1.6rem);
  padding: clamp(1rem, 2.5vw, 1.5rem);
  opacity: 0;
  pointer-events: none;
}

.overlay-contact {
  font-size: clamp(0.6rem, 1.3vw, 0.7rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.45);
  text-decoration: none;
  line-height: 1;
  padding-bottom: 0.1rem; /* sit on the logo's baseline, not below it */
  transition: color 0.2s;
}

.overlay-contact:hover {
  color: #fff;
}

.hero-title {
  margin: 0;
  line-height: 0;
}

.hero-title-logo {
  height: clamp(1.1rem, 3vw, 1.9rem);
  width: auto;
  display: block;
}

/* Projects page */
/* Pure wrapper - the grid inside is position:fixed, no layout role left */
.page--projects {
  height: 0;
  margin: 0;
  padding: 0;
}

/* Projects grid - fixed like the hero video but BELOW it (z 9 vs 10), so the
   fullscreen video conceals the cards on page 1 and reveals them as it shrinks */
.projects-grid {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 10px;
  z-index: 9;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow: hidden; /* the rows are many screens wide - without clipping, iOS
                       lets the user pan the whole page horizontally */
  pointer-events: none; /* enabled by JS on page 2 only */
}

.projects-row {
  display: flex;
  gap: 10px;
}

.projects-row img {
  display: block;
  object-fit: cover;
  aspect-ratio: 2 / 1;
  flex: 0 0 auto;
  border: 1px solid #fff;
  background: #101010; /* dark placeholder while the image loads */
  transition: transform 0.4s ease, box-shadow 0.4s ease;
  cursor: pointer;
}

/* Hover lifts the thumbnail with a shadow. The siblings are deliberately NOT
   dimmed - that used to fight the continuous hover-scroll, since every frame
   moved a new thumbnail under the cursor and re-triggered the fade. */
.projects-row img:hover {
  z-index: 2;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.4);
}

/* A project the CMS flags as incomplete (data-locked, set in data.js) still
   shows in the carousel but has nothing to open, so it gets neither the
   pointer nor the hover lift that promise a detail view. */
.projects-row img[data-locked] {
  cursor: default;
}

.projects-row img[data-locked]:hover {
  z-index: auto;
  box-shadow: none;
}

/* Large row */
.projects-row--large img {
  height: clamp(100px, 27.78vh, 300px);
  width: auto;
}

/* Small row, offset left */
.projects-row--small {
  margin-left: -8vw;
}

.projects-row--small img {
  height: clamp(70px, 18.52vh, 200px);
  width: auto;
}

/* Page 3 - About / Contact: fixed layer that slides in over page 2 */
.page--about {
  position: fixed;
  inset: 0;
  z-index: 12;
  transform: translateY(100%); /* offscreen until JS animates it in */
  background: #0a0a0a;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: clamp(1.5rem, 5vw, 4rem);
}

.about-inner {
  max-width: 720px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.about-kicker {
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: rgba(255, 255, 255, 0.4);
  margin-bottom: 1.2rem;
}

.about-heading {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.8rem, 5vw, 3rem);
  font-weight: 400;
  line-height: 1.2;
  margin-bottom: clamp(1.2rem, 3vw, 2rem);
}

.about-text {
  font-size: clamp(0.9rem, 2vw, 1.05rem);
  line-height: 1.8;
  color: rgba(255, 255, 255, 0.75);
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

/* Four items now (general, careers, studio, phone), so the gap is tighter than
   it was with three - they still have to sit on one line inside .about-inner */
.about-contact {
  display: flex;
  gap: clamp(1.4rem, 4vw, 3rem);
  justify-content: center;
  flex-wrap: wrap;
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

.about-contact-item {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.about-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: rgba(255, 255, 255, 0.4);
}

.about-value {
  font-size: clamp(0.85rem, 1.8vw, 0.95rem);
  color: #fff;
  text-decoration: none;
  line-height: 1.5;
}

a.about-value:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Sister companies, bottom of the about page. The files are already white on
   transparency, so they only need dimming - held back at rest so they read as
   a footer, not as a second headline. */
.about-partners {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(2rem, 6vw, 4.5rem);
  flex-wrap: wrap;
  margin-bottom: clamp(1.5rem, 4vw, 2.5rem);
}

.about-partners a {
  display: block;
  line-height: 0;
  opacity: 0.5;
  transition: opacity 0.3s;
}

.about-partners a:hover {
  opacity: 1;
}

.about-partners img {
  height: clamp(34px, 5vw, 48px);
  width: auto;
  display: block;
}

/* A tall, narrow mark reads bigger than a wide one at the same height */
.partner-formosa {
  height: clamp(30px, 4.4vw, 42px);
}

.about-footer {
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: rgba(255, 255, 255, 0.3);
}

.admin-link {
  color: rgba(255, 255, 255, 0.18);
  text-decoration: none;
  margin-left: 0.8rem;
  transition: color 0.2s;
}

.admin-link:hover {
  color: rgba(255, 255, 255, 0.6);
}

/* Admin modal (inherits contact-modal look) */
.admin-modal .admin-label {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.4);
  margin: 1rem 0 0.35rem;
}

.admin-modal input {
  width: 100%;
  background: #111;
  border: 1px solid #333;
  color: #fff;
  padding: 0.6rem 0.8rem;
  border-radius: 6px;
  font: inherit;
}

.admin-modal input:focus {
  outline: none;
  border-color: #666;
}

.admin-modal .hero-cta {
  min-width: 0;
  margin-top: 1.5rem;
  background: none;
  font: inherit;
  cursor: pointer;
}

.admin-error {
  color: #d68f8f;
  font-size: 0.85rem;
  margin-top: 1rem;
}

.admin-user {
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.9rem;
  margin-bottom: 0.5rem;
}

.admin-menu-actions {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Detail modal */
.detail-backdrop {
  position: fixed;
  inset: 0;
  z-index: 29;
  background: rgba(0, 0, 0, 0.8);
}

.detail-backdrop[hidden] {
  display: none;
}

.detail {
  position: fixed;
  z-index: 30;
  border-radius: 5px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.detail[hidden] {
  display: none;
}

/* Mobile bottom sheet variant (class toggled per open in main.js, matching the
   768px breakpoint below). Kept outside the media query so a rotation while the
   sheet is open doesn't swap the corner radius mid-flight. 90% width, flush
   with the bottom edge - hence rounded top corners only. */
.detail--sheet {
  border-radius: 14px 14px 0 0;
}

/* The sheet runs to the bottom of the layout viewport, which on iOS sits behind
   Safari's toolbar - pad the last content out of harm's way. */
.detail--sheet .detail-body {
  padding-bottom: calc(clamp(1.5rem, 4vw, 3rem) + env(safe-area-inset-bottom, 0px) + 3rem);
}

.detail-close {
  position: absolute;
  top: clamp(0.6rem, 1.5vw, 1rem);
  right: clamp(0.6rem, 1.5vw, 1.2rem);
  background: rgba(0, 0, 0, 0.35);
  border: none;
  color: #fff;
  cursor: pointer;
  opacity: 0.85;
  transition: opacity 0.2s;
  z-index: 31;
  line-height: 1;
  width: clamp(2rem, 5vw, 2.4rem);
  height: clamp(2rem, 5vw, 2.4rem);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.detail-close:hover {
  opacity: 1;
}

/* Scrollable inner content */
.detail-scroll {
  width: 100%;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* Allow vertical panning inside the modal, and never chain the overscroll
     out to the page behind it */
  touch-action: pan-y;
  overscroll-behavior: contain;
}

.detail-scroll::-webkit-scrollbar {
  display: none;
}

/* Hero image - bleeds to edges, no padding */
.detail-hero-wrap {
  position: relative;
  width: 100%;
}

.detail-hero {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.detail-hero-caption {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: clamp(1.5rem, 5vw, 4rem) clamp(1.2rem, 5vw, 3.5rem) clamp(1.2rem, 3vw, 2.5rem);
  background: linear-gradient(transparent 0%, rgba(0, 0, 0, 0.75) 100%);
}

.detail-hero-scope {
  font-family: "Lato", -apple-system, sans-serif;
  font-size: clamp(0.65rem, 1.3vw, 0.75rem);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.6);
  margin-bottom: clamp(0.4rem, 1vw, 0.8rem);
}

.detail-title {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.8rem, 6vw, 3.2rem);
  font-weight: 400;
  color: #fff;
  line-height: 1.1;
  margin: 0;
}

.detail-subtitle {
  font-family: "Lato", -apple-system, sans-serif;
  font-size: clamp(0.8rem, 2vw, 1rem);
  font-weight: 400;
  color: rgba(255, 255, 255, 0.7);
  margin-top: 0.3rem;
  letter-spacing: 0.02em;
}

.detail-hero-tagline {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(0.85rem, 1.8vw, 1.05rem);
  font-style: italic;
  color: rgba(255, 255, 255, 0.55);
  margin-top: clamp(0.6rem, 1.5vw, 1rem);
  line-height: 1.5;
  max-width: 500px;
}

/* Body content */
.detail-body {
  /* Held in a variable so full-bleed children can cancel it exactly */
  --detail-pad-x: clamp(1.2rem, 5vw, 3.5rem);
  padding: clamp(1.5rem, 4vw, 2.5rem) var(--detail-pad-x) clamp(1.5rem, 4vw, 3rem);
  font-family: "Lato", -apple-system, sans-serif;
  background: #fff;
}

/* Trailer runs edge to edge; only its heading keeps the text indent */
.detail-trailer {
  margin-left: calc(-1 * var(--detail-pad-x));
  margin-right: calc(-1 * var(--detail-pad-x));
}

.detail-trailer .detail-section-title {
  padding-left: var(--detail-pad-x);
  padding-right: var(--detail-pad-x);
}

/* Meta row - client, year, scope */
.detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2rem);
  padding-bottom: clamp(1.2rem, 3vw, 2rem);
  border-bottom: 1px solid #e0e0e0;
  margin-bottom: clamp(1.2rem, 3vw, 2rem);
}

.detail-meta-item {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.detail-meta-item--wide {
  flex: 1;
  min-width: 200px;
}

.detail-label {
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: #999;
}

.detail-value {
  font-size: clamp(0.85rem, 1.8vw, 0.95rem);
  color: #1a1a1a;
  line-height: 1.5;
}

/* Introduction */
.detail-intro {
  font-size: clamp(1rem, 2.2vw, 1.15rem);
  line-height: 1.8;
  color: #222;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

/* Section blocks (challenge, process) */
.detail-section {
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.detail-section-title {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.3rem, 3vw, 1.8rem);
  font-weight: 700;
  color: #111;
  margin-bottom: 1rem;
  line-height: 1.2;
}

.detail-section-text {
  font-size: clamp(0.9rem, 2vw, 1.05rem);
  line-height: 1.8;
  color: #333;
}

/* Image galleries - full-bleed, break out of body padding */
/* Both galleries hold a pair of stills, side by side, edge to edge. The process
   row used to declare three columns while only ever receiving two images, which
   left the third empty and stopped the row short of the modal edge. */
.detail-gallery {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: 4px;
  margin: clamp(2rem, 4vw, 3rem) calc(-1 * var(--detail-pad-x));
}

/* A lone still spans the full width rather than sitting half-orphaned */
.detail-gallery img:only-child {
  grid-column: 1 / -1;
}

/* No forced ratio: film stills are usually 2.35:1, and cropping them to 16/10
   was what kept the letterbox bars in frame. A pair from the same production
   shares a ratio, so they line up on their own. */
.detail-gallery img {
  width: 100%;
  height: auto;
  display: block;
}

.detail-gallery figcaption {
  font-size: 0.75rem;
  color: #888;
  padding: 0.5rem clamp(1.2rem, 5vw, 3.5rem);
  letter-spacing: 0.02em;
  grid-column: 1 / -1;
}

/* Pull quote */
.detail-quote {
  position: relative;
  margin: clamp(2rem, 4vw, 3rem) 0;
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1.5rem, 3vw, 3rem);
  background: #f7f7f7;
  border-radius: 8px;
  border: none;
}

.detail-quote::before {
  content: "\201C";
  font-family: "Prata", Georgia, serif;
  font-size: clamp(2.5rem, 6vw, 4rem);
  color: #ccc;
  position: absolute;
  top: 0.2rem;
  left: 1rem;
  line-height: 1;
}

.detail-quote-text {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(0.95rem, 2.2vw, 1.2rem);
  font-style: italic;
  font-weight: 500;
  line-height: 1.65;
  color: #1a1a1a;
  margin: 0;
  padding-left: 1.5rem;
}

.detail-quote-cite {
  display: block;
  margin-top: 1rem;
  padding-left: 1.5rem;
  font-family: "Lato", -apple-system, sans-serif;
  font-size: 0.8rem;
  font-style: normal;
  color: #888;
  letter-spacing: 0.02em;
}

/* Video breakdown */
.detail-reel {
  margin: clamp(2rem, 4vw, 3rem) calc(-1 * var(--detail-pad-x));
}

/* The frame is the size the video should *appear* at; the player inside keeps
   its own ratio. When the two match, nothing is cropped. When the file has
   letterbox bars baked in, --frame-ratio is the picture ratio and the player
   overflows top and bottom, taking Vimeo's control bar with it (fitReel).
   Both custom properties are set from JS; these are the safe defaults. */
.detail-reel-frame {
  --player-ratio: 1.7778;
  --frame-ratio: 1.7778;
  position: relative;
  width: 100%;
  aspect-ratio: var(--frame-ratio);
  overflow: hidden;
  background: #000;
}

.detail-reel-frame iframe {
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  aspect-ratio: var(--player-ratio);
  border: 0;
  display: block;
}

/* Click-to-play facade. Our own still and play button stand in for the
   embedded player until the viewer asks for it - YouTube no longer lets any
   parameter hide its logo, title or "Watch on YouTube" overlay. */
.video-facade {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  background: #000;
  cursor: pointer;
  overflow: hidden;
}

.video-facade img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.5s ease, opacity 0.3s ease;
  opacity: 0.75;
}

.video-facade:hover img,
.video-facade:focus-visible img {
  transform: scale(1.03);
  opacity: 0.9;
}

.video-facade-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.video-facade-play svg {
  width: clamp(48px, 9%, 68px);
  height: auto;
  filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.45));
}

.video-facade-play-bg {
  fill: rgba(0, 0, 0, 0.55);
  transition: fill 0.25s ease;
}

.video-facade:hover .video-facade-play-bg,
.video-facade:focus-visible .video-facade-play-bg {
  fill: rgba(0, 0, 0, 0.8);
}

.video-facade:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -2px;
}

.detail-reel-placeholder {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #0a0a0a;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  cursor: pointer;
  transition: background 0.3s;
}

.detail-reel-placeholder:hover {
  background: #1a1a1a;
}

.detail-reel-label {
  font-family: "Lato", -apple-system, sans-serif;
  font-size: 0.8rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.4);
}

/* Team credits */
.detail-credits {
  margin: clamp(2rem, 4vw, 3rem) 0;
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid #e0e0e0;
}

.detail-credits-heading {
  font-family: "Prata", Georgia, serif;
  font-size: clamp(1.3rem, 3vw, 1.8rem);
  font-weight: 700;
  color: #111;
  margin-bottom: 0.6rem;
}

.detail-credits-intro {
  font-size: clamp(0.9rem, 2vw, 1rem);
  line-height: 1.7;
  color: #555;
  margin-bottom: clamp(1.5rem, 3vw, 2rem);
}

.detail-credits-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: clamp(0.8rem, 2vw, 1.2rem);
}

.detail-credit {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.detail-credit-role {
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #999;
}

.detail-credit-name {
  font-size: 0.95rem;
  color: #1a1a1a;
  font-weight: 500;
}

/* Closing statement */
.detail-closing {
  font-size: clamp(0.9rem, 2vw, 1.05rem);
  line-height: 1.8;
  color: #333;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-bottom: clamp(2rem, 4vw, 3rem);
}

/* ------------------------------------------------
   Mobile breakpoint
   ------------------------------------------------ */
@media (max-width: 768px) {
  /* Hero content - lower on screen for mobile */
  .hero-content {
    bottom: 15vh;
    padding: 0 1.2rem;
  }

  /* Nav - hide text links, keep logo */
  .nav-links a:not(.nav-home),
  .nav-divider {
    display: none;
  }

  /* Small row - remove offset on mobile */
  .projects-row--small {
    margin-left: 0;
  }

  /* Thumbnails sized by viewport width so neighbours peek in (invites swiping).
     heroEnd() measures the grid, so the video shrink follows automatically. */
  .projects-row--large img {
    height: 32vw;
  }

  .projects-row--small img {
    height: 22vw;
  }

  /* About page - stack contact info vertically */
  .about-contact {
    flex-direction: column;
    gap: 1.4rem;
  }

  /* Meta - stack vertically */
  .detail-meta {
    flex-direction: column;
    gap: 1rem;
  }

  .detail-meta-item--wide {
    min-width: 0;
  }

  /* Galleries - single column on mobile */
  .detail-gallery {
    grid-template-columns: 1fr;
  }

  /* Credits - two columns on mobile */
  .detail-credits-grid {
    grid-template-columns: 1fr 1fr;
  }
}
