/* Self-hosted (not a CDN) so it can't silently fail to load. The
   Keynote's work captions are Roboto Condensed; its nav is Keynote
   text in Helvetica Neue Light, which ships with macOS. */
@font-face {
  font-family: 'Roboto Condensed';
  src: url(../assets/fonts/roboto-condensed-latin.woff2) format('woff2');
  font-weight: 100 900;
  font-display: block;
}
@font-face {
  font-family: 'Roboto';
  src: url(../assets/fonts/roboto-latin.woff2) format('woff2');
  font-weight: 100 900;
  font-display: block;
}

:root {
  --black: #0a0a0a;
  --gray: #8a8a8a;
  --gray-light: #c7c7c7;
  --line: #cfcfcf;
  --font: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-caption: 'Roboto Condensed', 'Arial Narrow', sans-serif;
  --font-nav: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #ffffff;
  color: var(--black);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}

img { display: block; max-width: none; }
a { color: inherit; text-decoration: none; }

/* ---------- Slide scaling system ---------- */
/* Every slide (Intro, Work, Contact) is authored on a fixed 1920x1080
   canvas — matching the original Keynote deck exactly — and scaled
   uniformly, by whichever of width/height is tighter, so it always
   fits the viewport at its exact 16:9 proportions, letterboxed and
   centered like an actual presentation. The ratio never changes, only
   the overall size. */

/* Slides crossfade instead of cutting instantly — every slide stays
   laid out (flex-centered, fixed full-screen) all the time, and only
   its opacity + pointer-events toggle, so switching slides dissolves
   smoothly instead of jumping. */
.slide {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  inset: 0;
  background: #ffffff;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.45s ease;
}
.slide.active {
  opacity: 1;
  pointer-events: auto;
}

.slide-wrap {
  position: relative;
  overflow: hidden;
  flex: none;
}

.canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 1920px;
  height: 1080px;
  transform-origin: top left;
  background: #ffffff;
}

/* ---------- Slide 1 : Intro ---------- */
/* Same pairing as every work caption on the site (bold condensed caps
   title over a Roboto credit line), just scaled up under the logo, with
   one quiet fade-in — no extra decoration. */
.intro-canvas { position: relative; }
.intro-stack {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  animation: intro-fade 0.4s ease forwards;
}
.intro-logo { height: 56px; width: auto; margin-bottom: 28px; }
.intro-name,
.intro-role { margin: 0; line-height: 1; white-space: nowrap; }
.intro-name {
  font-family: var(--font-caption);
  font-size: 26px;
  font-weight: 700;
  color: #333333;
  text-transform: uppercase;
}
.intro-role {
  margin-top: 16px;
  font-family: 'Roboto', sans-serif;
  font-size: 22px;
  font-weight: 400;
  color: #111111;
}
@keyframes intro-fade { to { opacity: 1; } }

/* ---------- Shared: top logo ---------- */
/* logo.svg is a vector trace of the Keynote's logo PNG, cropped to the
   mark itself — so it stays sharp at any scale and its height is the
   height of the visible mark. */
.top-logo {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  height: 44px;
  cursor: pointer;
}
.top-logo img { height: 100%; width: auto; }

/* Detail pages (Keynote's "GNX" slide) put the logo bottom-left
   instead of top-center. */
.detail-canvas .top-logo {
  top: auto;
  bottom: 8px;
  left: 24px;
  transform: none;
}

/* ---------- Slide 2 : Work ---------- */
/* Same fixed 1920x1080 canvas as every other slide, scaled as one
   uniform unit — the locked 16:9 frame never changes proportions.
   Logo and nav sit at fixed coordinates in that frame exactly like
   Intro/Contact/Detail; only the grid itself sits in a clipped
   viewport window (fixed height, no visible border) so it can scroll
   for the extra works without ever spilling past its own edges or
   disturbing the frame around it. */
/* Two works at a time, in fixed slots (top:220 / top:610, height:300 —
   images crop via object-fit:cover so every pair lines up identically
   regardless of each work's native aspect ratio). Side arrows step
   through the 6 pages; nothing scrolls. */
.work-page {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.work-page.active { opacity: 1; }
/* Only the visible section's current page takes clicks — otherwise a hidden
   section's last-viewed page (still .active) sits invisibly on top and
   swallows clicks meant for the section on screen. */
.slide.active .work-page.active { pointer-events: auto; }

.nav-arrow.work-prev, .nav-arrow.work-next { top: 545px; }
.nav-arrow.work-prev { left: 250px; }
.nav-arrow.work-next { left: 1630px; }

.work-row-link { display: block; }

/* Multi-image works use a justified row: each cell's flex-grow is set
   inline to its own image's native aspect ratio (width/height), so
   the row fills the full 1064px width with every photo at its real
   ratio — no cropping, no letterbox bars. Single-image works just
   center one image at its native ratio, height-capped to match. */
.row-multi {
  position: absolute;
  left: 428px;
  width: 1064px;
  height: 300px;
  display: flex;
  gap: 8px;
}
.row-multi .cell {
  flex-basis: 0;
  min-width: 0;
  overflow: hidden;
}
.row-multi .cell img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.row-single {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  height: 300px;
}
.row-single img {
  display: block;
  height: 300px;
  width: auto;
}

.caption-title,
.caption-credit {
  position: absolute;
  left: 428px;
  width: 1064px;
  margin: 0;
  text-align: center;
}
/* Sizes calibrated by rendering the Keynote's own strings and matching
   their ink width to the slide ("KENDRICK LAMAR GNX" = 146px,
   "Dave Free | PG LANG" = 138px at 1920 wide). */
.caption-title {
  font-family: var(--font-caption);
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  color: #333333;
  text-transform: uppercase;
}
.caption-credit {
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1;
  color: #111111;
}

.work-bottom-nav {
  position: absolute;
  top: 1042px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  justify-content: center;
  gap: 56px;
  white-space: nowrap;
  font-family: var(--font-nav);
  font-size: 17px;
  font-weight: 300;
  line-height: 1;
  color: #5e5e5e;
}
.work-bottom-nav a:hover { color: var(--black); }
.work-bottom-nav span { color: #5e5e5e; cursor: default; }
.work-bottom-nav a.active {
  position: relative;
  font-weight: 700;
  color: var(--black);
}
.work-bottom-nav a.active::before {
  content: '';
  position: absolute;
  top: -7px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: currentColor;
}

/* ---------- Slide 4+ : Project detail ---------- */
/* Matches the Keynote "GNX" example slide exactly: title/credits
   stacked and centered, then the media below — laid out as a normal
   top-down flex column (not hand-placed absolute coordinates) so the
   gap before the image always lands right after however many credit
   lines a given work actually has. */
.detail-canvas {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Header is pinned at its original top spot; the media alone is centered
   on the canvas, so every video sits dead-center regardless of how many
   credit lines a work has. */
.detail-header {
  position: absolute;
  top: 58px;
  left: 0;
  width: 100%;
  text-align: center;
}
.detail-header p {
  margin: 0 0 17px;
  line-height: 1;
}
.detail-header p:last-child { margin-bottom: 0; }
.detail-title {
  font-family: var(--font-caption);
  font-size: 18px;
  font-weight: 700;
  color: #333333;
  text-transform: uppercase;
  margin-bottom: 15px !important;
}
.detail-director,
.detail-production,
.detail-dp {
  font-family: 'Roboto', sans-serif;
  font-size: 15px;
  font-weight: 400;
  color: #111111;
}
.detail-director .name,
.detail-production .name,
.detail-dp .name {
  font-weight: 700;
}

.detail-image-link {
  max-width: 990px;
  max-height: 700px;
  line-height: 0;
}
.detail-image-link img {
  display: block;
  max-width: 990px;
  max-height: 700px;
  width: auto;
  height: auto;
}

.detail-divider { display: none; }

/* Detail-page video(s). One work can have more than one cut — .detail-video-group
   holds them all and, when there's more than one, shows its own local
   prev/next arrows (separate from the old page-to-page nav-arrow) to flip
   between cuts without leaving the page. */
.detail-video-group {
  position: relative;
  max-width: 990px;
  max-height: 700px;
}
.detail-video-item {
  display: none;
  max-width: 990px;
  max-height: 700px;
  width: auto;
  height: auto;
  margin: 0 auto;
}
.detail-video-item.active { display: block; }
.video-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-size: 34px;
  line-height: 1;
  color: var(--black);
  cursor: pointer;
  z-index: 2;
  user-select: none;
}
.video-nav:hover { color: var(--gray); }
.video-prev { left: -50px; }
.video-next { right: -50px; }

/* Photo-type works show a 2x2 contact-sheet grid instead of one image —
   fixed-size cells (like the Keynote reference) with object-fit:contain
   so each still keeps its own ratio with no cropping, just letterboxed
   inside its cell. */
.detail-photo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 358px);
  gap: 24px;
  width: 990px;
}
.detail-photo-grid .cell { overflow: hidden; }
.detail-photo-grid .cell img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.nav-arrow {
  position: absolute;
  top: 582px;
  transform: translateY(-50%);
  font-size: 34px;
  line-height: 1;
  color: var(--black);
  cursor: pointer;
  z-index: 3;
  padding: 20px;
  margin: -20px;
}
.nav-arrow:hover { color: var(--gray); }
.nav-arrow--left { left: 350px; }
.nav-arrow--right { left: 1570px; }

/* ---------- Slide 3 : Contact ---------- */
.section-label {
  position: absolute;
  left: 431px;
  width: 1063px;
  display: flex;
  align-items: center;
  gap: 16px;
}
.section-label span {
  font-family: var(--font-caption);
  font-size: 16px;
  font-weight: 700;
  color: #1f1f1f;
  white-space: nowrap;
}
.section-label i {
  flex: 1;
  height: 1px;
  background: var(--line);
  font-style: normal;
}
.europe-label { top: 214px; }
.about-label { top: 565px; }

.europe-content {
  position: absolute;
  top: 322px;
  left: 427px;
}
.rep-logo { display: block; height: 90px; width: auto; }

.about-col {
  position: absolute;
  top: 655px;
  width: 340px;
}
.about-col p {
  margin: 0 0 19px;
  font-family: 'Roboto', sans-serif;
  font-size: 16px;
  font-weight: 500;
  color: #000000;
}
.about-col p:last-child { margin-bottom: 0; }
.about-col a { text-decoration: underline; text-underline-offset: 2px; }
.about-col a:hover { color: var(--gray); }
.about-col1 { left: 797px; }
.about-col2 { left: 1164px; }

.copyright {
  position: absolute;
  left: 383px;
  top: 868px;
  margin: 0;
  font-family: var(--font-nav);
  font-size: 11px;
  color: #494949;
}

/* Rep (Rough Laboratory) text — same two-column grid as ABOUT, styled after
   the reference: bold condensed caps title, Roboto body, underlined links. */
.rep-col {
  position: absolute;
  top: 280px;
  width: 340px;
}
.rep-col1 { left: 797px; }
.rep-col2 { left: 1164px; }
.rep-col p {
  margin: 0 0 12px;
  font-family: 'Roboto', sans-serif;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.7;
  color: #000000;
  word-break: keep-all;
}
.rep-col p:last-child { margin-bottom: 0; }
.rep-col .rep-title {
  margin-bottom: 14px;
  font-family: var(--font-caption);
  font-size: 16px;
  font-weight: 700;
  line-height: 1;
  color: #333333;
  text-transform: uppercase;
}
.rep-col a { text-decoration: underline; text-underline-offset: 2px; }
.rep-col a:hover { color: var(--gray); }
.rep-col .rep-title .plus { font-weight: 400; }

/* ================= Phones only =================
   The desktop site is a fixed 16:9 slide scaled to fit, which on a
   portrait phone shrinks to a thin strip. Below 768px each slide becomes
   a normal top-to-bottom scrolling page instead. Many desktop positions
   are inline styles (generated per work), hence the !important. */
@media (max-width: 767px) {
  .slide { display: block; overflow-y: auto; -webkit-overflow-scrolling: touch; }
  .slide-wrap { width: auto !important; height: auto !important; overflow: visible; }
  .canvas { position: relative; width: auto !important; height: auto !important; transform: none !important; }

  /* Listing pages (Commercial / MV / Photo): logo, sticky menu, then every work stacked */
  .work-canvas { display: flex; flex-direction: column; padding: 0 16px 48px; }
  .work-canvas .top-logo,
  .detail-canvas .top-logo,
  .contact-canvas .top-logo {
    position: static; transform: none; align-self: center; height: 30px; margin: 22px 0 10px;
  }
  .work-bottom-nav {
    position: sticky; top: 0; left: auto; transform: none; order: 1; z-index: 5;
    background: #ffffff; padding: 12px 0 14px; margin-bottom: 12px;
    gap: 18px; font-size: 14px; flex-wrap: wrap;
  }
  .nav-arrow.work-prev, .nav-arrow.work-next { display: none; }
  .work-page { order: 2; opacity: 1; }
  .slide.active .work-page { pointer-events: auto; }
  .work-row-link { margin-bottom: 40px; }
  .row-multi {
    position: static !important; top: auto !important; left: auto !important;
    width: auto !important; height: auto !important; gap: 4px;
  }
  .row-multi .cell img { height: auto; }
  .caption-title, .caption-credit {
    position: static !important; top: auto !important; left: auto !important; width: auto !important;
  }
  .caption-title { margin-top: 12px; font-size: 15px; }
  .caption-credit { margin-top: 8px; font-size: 13px; }
  /* Each work's images stacked top-to-bottom at full width */
  .row-multi { flex-direction: column; gap: 6px; }
  .row-multi .cell { flex: none !important; }

  /* Detail pages: logo (back), credits, then the media full width */
  .detail-canvas { justify-content: flex-start; padding: 0 16px 72px; }
  .detail-header { position: static; order: 1; margin-bottom: 24px; }
  .detail-video-group { order: 2; width: 100%; max-width: none; max-height: none; margin-bottom: 48px; }
  .detail-video-item {
    width: 100% !important; height: auto !important; max-width: none; max-height: 75vh; object-fit: contain;
  }
  .video-nav { top: auto; bottom: -44px; transform: none; }
  .video-prev { left: calc(50% - 56px); }
  .video-next { right: calc(50% - 56px); }

  /* Contact: everything in one column */
  .contact-canvas { padding: 0 20px 48px; }
  .contact-canvas .top-logo { display: block; width: fit-content; margin: 22px auto 28px; }
  .section-label { position: static; width: auto; margin: 0 0 18px; }
  .about-label { margin-top: 12px; }
  .europe-content { position: static; margin-bottom: 22px; }
  .rep-logo { height: 56px; }
  .rep-col, .about-col { position: static; width: auto; margin-bottom: 24px; }
  .copyright { position: static; margin-top: 32px; }

  /* Intro: fill the phone screen, same centered stack */
  .intro-canvas { height: 100svh !important; }
  .intro-logo { height: 40px; margin-bottom: 20px; }
  .intro-name { font-size: 20px; }
  .intro-role { font-size: 16px; margin-top: 10px; }
}
