/* ============================================
   Tayler Prince-Fraser — Portfolio site
   Monochrome iteration
   ============================================ */

:root {
  --bg: #f7f7f5;
  --bg-dark: #161616;
  --ink: #161616;
  --ink-soft: #6b6b6b;
  --ink-faint: rgba(22,22,22,0.45);
  --cream: #f7f7f5;
  --cream-soft: rgba(247,247,245,0.7);
  --line: rgba(22, 22, 22, 0.12);
  --line-strong: rgba(22, 22, 22, 0.3);
  --line-dark: rgba(247,247,245,0.15);
  --max: 1100px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }

/* Respect OS-level reduced motion preference. We trim heavy animations and
   long transitions but deliberately leave the hero stack and preview area
   alone - their crossfades are core to how the work reads, and snapping them
   to instant cuts is worse for everyone than letting them play softly. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *:not(.hero-frame):not(.preview):not(.work-tile-image):not(.work-tile),
  *:not(.hero-frame):not(.preview):not(.work-tile-image):not(.work-tile)::before,
  *:not(.hero-frame):not(.preview):not(.work-tile-image):not(.work-tile)::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

/* On touch devices, give text-only nav and footer links real tap targets
   (WCAG / Apple HIG recommend 44x44px). Desktop visuals stay unchanged. */
@media (hover: none) and (pointer: coarse) {
  .nav-bar .nav-links a {
    padding: 12px 4px;
    margin: -12px -4px;
  }
  .project-page .project-footer a {
    padding: 14px 8px;
    margin: -14px -8px;
    display: inline-block;
  }
  .work-grid-end .archive-hint {
    padding: 12px 8px;
    margin: -12px -8px;
    display: inline-block;
  }
  .view-toggle-btn { min-height: 40px; }
  .site-footer a { padding: 10px 0; margin: -10px 0; }
}
body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Switzer', sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
a { color: inherit; text-decoration: none; }

/* ============================================
   Site footer — single quiet line
   ============================================ */
.site-footer {
  border-top: 0.5px solid var(--line);
  padding: 32px 48px 40px;
  background: var(--bg);
}
.site-footer-inner {
  max-width: var(--max);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 0 12px;
  align-items: baseline;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}
.site-footer-mark { color: var(--ink); }
.site-footer-sep { color: var(--ink-faint); }
.site-footer a {
  color: var(--ink-soft);
  transition: color 0.2s ease;
  padding: 4px 0;
}
.site-footer a:hover { color: var(--ink); }
.site-footer-year { margin-left: auto; }
@media (max-width: 600px) {
  .site-footer { padding: 24px 20px 32px; }
  .site-footer-inner { font-size: 9px; gap: 0 8px; }
  .site-footer-year { margin-left: 0; }
}

/* ============================================
   Custom cursor (desktop only, fine pointer)
   ============================================ */
@media (hover: hover) and (pointer: fine) {
  body.has-custom-cursor,
  body.has-custom-cursor a,
  body.has-custom-cursor button,
  body.has-custom-cursor .work-tile,
  body.has-custom-cursor .project-row,
  body.has-custom-cursor .selects-tile,
  body.has-custom-cursor .view-toggle-btn,
  body.has-custom-cursor .show-all-toggle,
  body.has-custom-cursor [role="button"] {
    cursor: none;
  }
  /* Keep native text caret in text inputs (when contact form etc. is added) */
  body.has-custom-cursor input,
  body.has-custom-cursor textarea {
    cursor: text;
  }
}

.custom-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--cream);
  pointer-events: none;
  z-index: 9999;
  mix-blend-mode: difference;
  opacity: 0;
  transition: width 0.22s cubic-bezier(0.2, 0, 0.1, 1),
              height 0.22s cubic-bezier(0.2, 0, 0.1, 1),
              opacity 0.18s ease;
  will-change: transform;
}
.custom-cursor.is-active {
  opacity: 1;
}
.custom-cursor.is-hovering {
  width: 26px;
  height: 26px;
}
img { display: block; max-width: 100%; }

/* ============================================
   Persistent nav
   ============================================ */

.nav-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 48px;
  pointer-events: none;
  mix-blend-mode: difference;
  transition: background-color 0.3s ease, mix-blend-mode 0s linear 0.3s, border-color 0.3s ease;
  border-bottom: 0.5px solid transparent;
}
/* Past the hero section: switch to solid cream bar with dark text. The
   mix-blend-mode is dropped so the nav reads cleanly over body content. */
.nav-bar.is-solid {
  background: var(--bg);
  mix-blend-mode: normal;
  border-bottom-color: transparent;
  transition: background-color 0.3s ease, mix-blend-mode 0s linear;
}
.nav-bar.is-solid .mark,
.nav-bar.is-solid .nav-links a { color: var(--ink); }
.nav-bar .mark {
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--cream);
  pointer-events: auto;
}
.nav-bar .nav-links {
  display: flex;
  gap: 24px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--cream);
  pointer-events: auto;
}
.nav-bar .nav-links a:hover { font-style: italic; }

/* ============================================
   Hero — neutral drift
   ============================================ */

/* Loading overlay - cream-on-cream cover that fades when first hero is ready */
/* Loading overlay doubles as the page-transition surface. On first paint it
   sits opaque until the hero/page is ready, then fades out. On link click
   the soft-nav handler re-adds opacity so the overlay fades back in before
   navigation, hiding the LCP race on the next page. Quicker transition than
   the original 0.6s so the lock feels deliberate, not slow. */
.loading-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 9999;
  pointer-events: none;
  opacity: 1;
  transition: opacity 0.3s ease;
}
.loading-overlay.is-ready {
  opacity: 0;
}

/* Scroll snap: a soft pull between the hero and the work grid so you don't
   get stuck halfway between them. Proximity snap only fires when you're
   close to a snap point - once you're scrolling through the grid, the snap
   stops mattering and About is reachable normally. scroll-padding-top
   accounts for the fixed nav so #work doesn't slide under it. */
html, body {
  scroll-snap-type: y proximity;
}
html {
  scroll-padding-top: 64px;
}
.hero-stack {
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}
#work {
  scroll-snap-align: start;
  scroll-snap-stop: normal;
}
@media (max-width: 768px) {
  html { scroll-padding-top: 48px; }
}

/* Back-to-top floating button (project pages, appears on long scroll) */
.back-to-top {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 90;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--bg-dark);
  color: var(--cream);
  border: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transform: translateY(8px);
  pointer-events: none;
  transition: opacity 0.3s ease, transform 0.3s ease;
}
.back-to-top.is-visible {
  opacity: 0.85;
  transform: translateY(0);
  pointer-events: auto;
}
.back-to-top:hover { opacity: 1; }
@media (max-width: 600px) {
  .back-to-top { bottom: 16px; right: 16px; width: 44px; height: 44px; font-size: 15px; }
}

/* View Transitions API - smooth crossfade between pages where supported */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 240ms;
  animation-timing-function: cubic-bezier(0.2, 0, 0.1, 1);
}

.hero-stack {
  position: relative;
  height: 100vh;
  min-height: 600px;
  overflow: hidden;
  background: var(--bg-dark);
}
/* Mobile: hero takes a shorter slice. Most images in the rotation are
   landscape and look better at a more cinematic crop on a portrait viewport. */
@media (max-width: 600px) {
  .hero-stack {
    height: 70vh;
    min-height: 480px;
  }
}
.hero-stack-stop {
  /* placeholder to keep block from being recognised */
  display: none;
}

.hero-stack .hero-frame {
  position: absolute;
  inset: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  background-color: var(--bg-dark);
  opacity: 0;
  z-index: 10;
}
.hero-stack .hero-frame.is-visible { opacity: 1; }
.hero-stack .hero-frame.is-fading-in { opacity: 1; }

/* Legacy frame rule - kept for graceful fallback if JS doesn't run */
.hero-stack .frame {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
}

.hero-stack .flash-layer .frame {
  animation: fast-cycle 2s linear forwards;
}
.hero-stack .flash-layer .frame:nth-child(1) { animation-delay: 0s;    background: linear-gradient(135deg, #2a2a2a 0%, #0d0d0d 100%); }
.hero-stack .flash-layer .frame:nth-child(2) { animation-delay: 0.25s; background: linear-gradient(135deg, #1f1f1f 0%, #0a0a0a 100%); }
.hero-stack .flash-layer .frame:nth-child(3) { animation-delay: 0.5s;  background: linear-gradient(135deg, #383838 0%, #131313 100%); }
.hero-stack .flash-layer .frame:nth-child(4) { animation-delay: 0.75s; background: linear-gradient(135deg, #2c2c2c 0%, #0a0a0a 100%); }
.hero-stack .flash-layer .frame:nth-child(5) { animation-delay: 1s;    background: linear-gradient(135deg, #242424 0%, #0e0e0e 100%); }

.hero-stack .drift-layer .frame {
  animation: slow-drift 24s infinite ease-in-out 2.6s;
}
.hero-stack .drift-layer .frame:nth-child(1) { animation-delay: 2.6s;  background: radial-gradient(ellipse at 30% 50%, rgba(180,180,180,0.18), transparent 65%), linear-gradient(135deg, #1f1f1f 0%, #0d0d0d 100%); }
.hero-stack .drift-layer .frame:nth-child(2) { animation-delay: 8.6s;  background: radial-gradient(ellipse at 65% 40%, rgba(160,160,160,0.18), transparent 60%), linear-gradient(135deg, #1a1a1a 0%, #0a0a0a 100%); }
.hero-stack .drift-layer .frame:nth-child(3) { animation-delay: 14.6s; background: radial-gradient(ellipse at 40% 60%, rgba(200,200,200,0.15), transparent 65%), linear-gradient(135deg, #2a2a2a 0%, #0d0d0d 100%); }
.hero-stack .drift-layer .frame:nth-child(4) { animation-delay: 20.6s; background: radial-gradient(ellipse at 55% 55%, rgba(170,170,170,0.16), transparent 60%), linear-gradient(135deg, #1f1f1f 0%, #0a0a0a 100%); }

@keyframes fast-cycle { 0%,12% { opacity: 1; } 18%,100% { opacity: 0; } }
@keyframes flash-curtain { 0%,80% { opacity: 1; } 100% { opacity: 0; } }
@keyframes slow-drift { 0%,25% { opacity: 1; } 33%,100% { opacity: 0; } }
@keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }

.hero-stack .frame-number {
  position: absolute;
  bottom: 32px; right: 32px;
  z-index: 50;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.15em;
  color: rgba(247,247,245,0.55);
  writing-mode: vertical-rl;
  opacity: 0;
  animation: fade-in 0.8s ease forwards 2.8s;
}
.hero-stack .scroll-cue {
  position: absolute;
  bottom: 36px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 50;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(247, 247, 245, 0.88);
  opacity: 0;
  animation: fade-in 0.8s ease forwards 2.4s, scroll-bob 1.6s ease-in-out 3.4s infinite;
  text-shadow: 0 0 18px rgba(0, 0, 0, 0.35);
  pointer-events: none;
}
@keyframes scroll-bob {
  0%, 100% { transform: translateX(-50%) translateY(0); }
  50%      { transform: translateX(-50%) translateY(5px); }
}

/* ============================================
   Info strip (black band)
   ============================================ */

.info-strip {
  background: var(--bg-dark);
  color: var(--cream);
  padding: 48px;
}
.info-strip .strip-inner {
  max-width: var(--max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px;
}
.info-strip .col .label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(247,247,245,0.5);
  margin-bottom: 12px;
  text-transform: uppercase;
}
.info-strip .col .value {
  font-size: 15px;
  color: var(--cream);
  line-height: 1.5;
  font-weight: 300;
}

/* ============================================
   Section shells
   ============================================ */

.section {
  background: var(--bg);
  padding: 100px 48px 120px;
  border-top: 0.5px solid var(--line);
}
.section:first-of-type { border-top: none; }
.section-inner { max-width: var(--max); margin: 0 auto; }

.section-header {
  border-bottom: 0.5px solid var(--line);
  padding-bottom: 16px;
  margin-bottom: 48px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
}
.section-header h3 {
  grid-column: 2;
  font-family: 'Switzer', sans-serif;
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.section-header .right-link {
  grid-column: 3;
  text-align: right;
  font-size: 12px;
  color: var(--ink);
  font-family: 'IBM Plex Mono', monospace;
  letter-spacing: 0.05em;
  cursor: pointer;
}
.section-header .right-link:hover { font-style: italic; }

/* Index header (left-aligned title, filter on right) */
.index-header {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  padding-bottom: 16px;
  border-bottom: 0.5px solid var(--line);
  margin-bottom: 48px;
}
.index-header h3 {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.index-header .filter {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-soft);
  letter-spacing: 0.1em;
}
.index-header .filter span { margin-left: 16px; cursor: pointer; }
.index-header .filter span.active { color: var(--ink); font-style: italic; }

/* View toggle (Index / Grid). Treated as a clear segmented control: small
   label on the left, then two buttons that visibly look like options the
   user can pick between. The active button wears the dark pill, inactive
   sits in a subtle outlined cell so it's obvious it can be clicked. */
.view-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
}
.view-toggle-label {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 10px;
  color: var(--ink-faint);
  padding-right: 4px;
}
/* Segmented control buttons: inactive sits in an outlined pill, active in
   a filled dark pill. The outline on inactive makes it visually clear it's
   a button you can click, not just text. */
.view-toggle-btn {
  background: transparent;
  border: 0.5px solid var(--line-strong);
  padding: 8px 14px;
  font: inherit;
  letter-spacing: inherit;
  color: var(--ink-soft);
  cursor: pointer;
  border-radius: 4px;
  transition: color 0.2s ease, background 0.2s ease, border-color 0.2s ease;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
}
.view-toggle-btn:hover {
  color: var(--ink);
  border-color: var(--ink);
}
.view-toggle-btn.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--cream);
}
.view-toggle-btn.is-active:hover { color: var(--cream); }

/* View containers - only the active one is visible */
.work-view { display: none; }
.work-view.is-active { display: block; }

/* ============================================
   Selected Work — grid view (CSS-columns masonry, native crops)
   ============================================ */

/* CSS columns masonry. Each tile takes its image's natural aspect ratio so
   nothing gets cropped - the curation is in WHICH images appear (1-3 per
   project, flagged in the data), not in their visual hierarchy. */
.work-view-grid {
  column-count: 3;
  column-gap: 16px;
  margin-bottom: 80px;
}
.work-grid-end {
  border-top: 0.5px solid var(--line);
  margin: 40px 0 0;
  padding: 40px 0 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.work-grid-end .archive-hint { color: var(--ink-faint); }
@media (max-width: 980px) {
  .work-view-grid { column-count: 2; }
}
@media (max-width: 600px) {
  .work-view-grid { column-count: 1; }
}

/* ---- Tablet pass (769-1024px / iPad-class viewports) ----
   The default desktop layout assumes ~1100px+ for breathing room. Without an
   intermediate query the index list gets crushed (~316px) next to a 600px
   preview pane, and section padding feels generous for the available width.
   This block tightens the preview pane, trims section padding, and gives the
   list room to breathe. */
@media (min-width: 769px) and (max-width: 1024px) {
  .section { padding: 80px 32px 96px; }
  .index-grid {
    grid-template-columns: 1fr 420px;
    gap: 40px;
  }
  .about-grid {
    grid-template-columns: 280px 1fr;
    gap: 56px;
  }
  .nav-bar { padding: 18px 32px; }
}

.work-tile {
  position: relative;
  cursor: pointer;
  display: block;
  width: 100%;
  margin: 0 0 16px 0;
  break-inside: avoid;
  background: transparent;
  overflow: hidden;
  /* aspect-ratio set inline per tile from image's natural ratio - prevents
     layout shift as images load, no cropping. */
  /* Default state - tiles fade in as they enter the viewport */
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.work-tile.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.work-tile picture {
  display: block;
  width: 100%;
}
.work-tile-image,
video.work-tile-image {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 0.6s cubic-bezier(0.2, 0, 0.1, 1);
}
.work-tile:hover .work-tile-image { transform: scale(1.04); }
/* Videos within grid tiles: clean object-fit (cover for safety), no controls */
video.work-tile-image {
  object-fit: cover;
  background: #161616;
}

.work-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 20px 22px;
  background: linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.05) 50%, rgba(0,0,0,0) 70%);
  color: var(--cream);
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.work-tile:hover .work-tile-overlay { opacity: 1; }
.work-tile-num {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(247,247,245,0.65);
  margin-bottom: 6px;
}
.work-tile-title {
  font-family: 'Switzer', sans-serif;
  font-weight: 400;
  font-size: 18px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-bottom: 4px;
}
.work-tile-reveal {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 12px;
  line-height: 1.4;
  color: rgba(247,247,245,0.8);
  max-width: 360px;
}

/* ============================================
   Selected Work — index view (list with hover preview)
   ============================================ */

.index-grid {
  display: grid;
  grid-template-columns: 1fr 600px;
  gap: 64px;
  align-items: start;
}

.project-list { text-align: left; }
.project-row {
  display: grid;
  grid-template-columns: 36px 1fr 80px;
  gap: 18px;
  align-items: baseline;
  padding: 11px 0;
  border-bottom: 0.5px solid var(--line);
  cursor: pointer;
  color: var(--ink-faint);
  transition: color 0.3s ease, padding-left 0.3s ease;
}
.project-row:first-child { border-top: 0.5px solid var(--line); }
.project-row .num {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.05em;
  color: var(--ink-faint);
  transition: color 0.3s ease;
}
.project-row .title-block { grid-column: 2; }
.project-row .title {
  font-size: 14px;
  font-weight: 300;
  letter-spacing: -0.01em;
  line-height: 1.3;
  transition: font-style 0.3s ease;
}
.project-row .reveal {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 10px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin-top: 3px;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  word-wrap: break-word;
  overflow-wrap: break-word;
  transition: max-height 0.4s cubic-bezier(0.2, 0, 0.1, 1), opacity 0.3s ease 0.1s;
}
.project-row .discipline {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
  text-align: right;
  text-transform: uppercase;
  transition: color 0.3s ease;
}
.project-row:hover, .project-row.is-active {
  color: var(--ink);
  padding-left: 8px;
}
.project-row:hover .num, .project-row.is-active .num,
.project-row:hover .discipline, .project-row.is-active .discipline { color: var(--ink); }
.project-row:hover .title, .project-row.is-active .title { font-style: italic; }
.project-row:hover .reveal, .project-row.is-active .reveal {
  max-height: 160px;
  opacity: 1;
}

/* show-all toggle (mobile only) */
.show-all-toggle {
  display: none;
  margin-top: 24px;
  width: 100%;
  background: transparent;
  border: 0.5px solid var(--line-strong);
  padding: 14px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink);
  cursor: pointer;
  text-align: center;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.show-all-toggle:hover {
  border-color: var(--ink);
  background: rgba(22,22,22,0.04);
}

.right-column {
  position: sticky;
  top: 100px;
  height: calc(100vh - 180px);
  max-height: 820px;
  min-height: 560px;
  display: flex;
  align-items: center;
}
.image-preview-area {
  width: 100%;
  aspect-ratio: 4/5;
  max-height: 100%;
  overflow: hidden;
  /* 4px charcoal frame around the preview - museum print mount style */
  border: 4px solid var(--bg-dark);
  background: var(--bg-dark);
  position: relative;
}
.image-preview-area .preview {
  position: absolute;
  inset: 0;
  display: block;
  background-size: cover;
  background-position: center;
  opacity: 0;
  pointer-events: none;
  cursor: pointer;
  transition: opacity 0.8s cubic-bezier(0.2, 0, 0.1, 1);
}
.image-preview-area .preview.active {
  opacity: 1;
  pointer-events: auto;
}
.image-preview-area .preview-meta {
  position: absolute;
  bottom: 14px; left: 14px; right: 14px;
  display: flex;
  justify-content: space-between;
  color: rgba(247,247,245,0.85);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  z-index: 10;
  opacity: 0;
  transition: opacity 0.4s ease 0.2s;
  pointer-events: none;
}
.image-preview-area.has-active .preview-meta { opacity: 1; }

/* ============================================
   Selects — image grid with lightbox carousel
   ============================================ */

.selects-section {
  background: var(--bg);
}

.selects-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 12px;
  grid-auto-rows: 200px;
  grid-auto-flow: dense;
}

/* Varied tile sizes for masonry feel — cycles through patterns */
.selects-tile {
  position: relative;
  cursor: pointer;
  overflow: hidden;
  background: #ededeb;
  border: 0.5px solid var(--line);
  grid-column: span 4;
  grid-row: span 2;
  transition: opacity 0.3s ease;
}
.selects-tile:nth-child(7n+1) { grid-column: span 6; grid-row: span 3; }
.selects-tile:nth-child(7n+2) { grid-column: span 3; grid-row: span 2; }
.selects-tile:nth-child(7n+3) { grid-column: span 3; grid-row: span 2; }
.selects-tile:nth-child(7n+4) { grid-column: span 4; grid-row: span 2; }
.selects-tile:nth-child(7n+5) { grid-column: span 4; grid-row: span 3; }
.selects-tile:nth-child(7n+6) { grid-column: span 4; grid-row: span 2; }
.selects-tile:nth-child(7n+7) { grid-column: span 6; grid-row: span 2; }

.selects-image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transition: transform 0.6s cubic-bezier(0.2, 0, 0.1, 1);
}

.selects-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 16px;
  background: linear-gradient(to top, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0) 50%);
  color: var(--cream);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.selects-tile:hover .selects-overlay { opacity: 1; }
.selects-tile:hover .selects-image { transform: scale(1.02); }
.selects-overlay .selects-title {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 18px;
  letter-spacing: -0.005em;
  margin-bottom: 4px;
}
.selects-overlay .selects-count {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(247,247,245,0.7);
}

/* Lightbox */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(15, 15, 15, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.lightbox[aria-hidden="false"] {
  opacity: 1;
  pointer-events: auto;
}
.lightbox-image {
  width: calc(100vw - 200px);
  height: calc(100vh - 140px);
  max-width: 1400px;
  max-height: 900px;
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}
.lightbox-close,
.lightbox-prev,
.lightbox-next {
  position: absolute;
  background: transparent;
  border: 0;
  color: rgba(247, 247, 245, 0.7);
  cursor: pointer;
  transition: color 0.2s ease;
  font-family: 'Switzer', sans-serif;
  z-index: 10;
}
.lightbox-close:hover,
.lightbox-prev:hover,
.lightbox-next:hover { color: var(--cream); }
.lightbox-close {
  top: 24px;
  right: 32px;
  font-size: 32px;
  line-height: 1;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox-prev,
.lightbox-next {
  top: 50%;
  transform: translateY(-50%);
  font-size: 56px;
  line-height: 1;
  width: 60px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lightbox-prev { left: 24px; }
.lightbox-next { right: 24px; }
.lightbox-meta {
  position: absolute;
  bottom: 32px;
  left: 32px;
  right: 32px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: rgba(247, 247, 245, 0.7);
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
}
.lightbox-meta .lightbox-title {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 16px;
  letter-spacing: -0.005em;
  color: rgba(247, 247, 245, 0.85);
  text-transform: none;
}
.lightbox-meta .lightbox-link {
  color: rgba(247, 247, 245, 0.7);
  border-bottom: 0.5px solid rgba(247, 247, 245, 0.3);
  padding-bottom: 2px;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.lightbox-meta .lightbox-link:hover {
  color: var(--cream);
  border-color: var(--cream);
}

/* ============================================
   About
   ============================================ */

.about-grid {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 80px;
  align-items: start;
}
.about-portrait {
  aspect-ratio: 1/1;
  background-color: #161616;
  /* Fallback for browsers that don't understand image-set() with type() */
  background-image: url('/about/portrait.jpg');
  background-image: image-set(
    url('/about/portrait.webp') type('image/webp'),
    url('/about/portrait.jpg') type('image/jpeg')
  );
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.about-text { padding-top: 8px; }
.about-text .opener {
  font-family: 'IBM Plex Mono', monospace;
  font-style: normal;
  font-weight: 400;
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink);
  margin-bottom: 32px;
  max-width: 540px;
}
.about-text .body {
  font-size: 14px;
  font-weight: 300;
  line-height: 1.75;
  color: var(--ink);
  max-width: 540px;
  margin-bottom: 32px;
}
.about-text .body p { margin-bottom: 14px; }

.about-text .credits {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: 16px 32px;
  border-top: 0.5px solid var(--line);
  padding-top: 24px;
  max-width: 540px;
  margin-bottom: 40px;
}
.about-text .credits dt {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-soft);
  text-transform: uppercase;
  padding-top: 4px;
}
.about-text .credits dd {
  font-size: 13px;
  font-weight: 300;
  line-height: 1.6;
  color: var(--ink);
}

.original-shift-callout {
  border: 0.5px solid var(--line);
  padding: 20px 24px;
  max-width: 540px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  cursor: pointer;
  transition: border-color 0.3s ease;
}
.original-shift-callout:hover { border-color: var(--ink); }
.original-shift-callout .label {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: var(--ink-soft);
  text-transform: uppercase;
  margin-bottom: 6px;
}
.original-shift-callout .name {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 20px;
  letter-spacing: -0.005em;
  color: var(--ink);
  margin-bottom: 2px;
}
.original-shift-callout .desc {
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.4;
  font-weight: 300;
}
.original-shift-callout .arrow {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 14px;
  color: var(--ink);
}

/* ============================================
   Notes from the Studio (diary)
   ============================================ */

.diary-section {
  background: var(--bg);
  padding: 100px 48px 140px;
  border-top: 0.5px solid var(--line);
}
.diary-empty {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 16px;
  color: var(--ink-soft);
  text-align: center;
  padding: 40px 0;
  letter-spacing: -0.005em;
}
.diary-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 32px;
}
.diary-entry {
  cursor: pointer;
}
.diary-entry .image-wrap {
  position: relative;
  aspect-ratio: 4/5;
  margin-bottom: 16px;
  overflow: hidden;
  background: #ededeb;
  border: 0.5px solid var(--line);
}
.diary-entry .image {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.diary-entry .date {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-soft);
  letter-spacing: 0.05em;
  text-align: center;
}

/* Full diary archive */
.diary-archive {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 64px 48px;
  max-width: 880px;
  margin: 0 auto;
}
.diary-archive .diary-entry .image-wrap {
  aspect-ratio: 3/4;
}

/* ============================================
   Project page
   ============================================ */

.project-page {
  background: var(--bg);
  padding: 120px 48px 140px;
}
.project-page-inner {
  max-width: var(--max);
  margin: 0 auto;
}
.project-page .meta-row {
  display: grid;
  grid-template-columns: 80px 1fr 1fr 1fr;
  gap: 24px;
  padding-bottom: 16px;
  border-bottom: 0.5px solid var(--line);
  margin-bottom: 56px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-soft);
  letter-spacing: 0.05em;
}
.project-page .meta-row .num { color: var(--ink); }

/* 3-tier title block */
.project-title-block {
  margin-bottom: 24px;
  max-width: 800px;
}
.project-page .project-brand {
  font-family: 'IBM Plex Mono', monospace;
  font-weight: 400;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: 8px;
}
.project-page .project-work {
  font-family: 'Switzer', sans-serif;
  font-style: normal;
  font-weight: 400;
  font-size: 40px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin-bottom: 8px;
}
.project-page .project-work em { font-style: italic; }
.project-page .project-subtitle {
  font-family: 'Switzer', sans-serif;
  font-weight: 400;
  font-size: 18px;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--ink);
}

.project-page .project-deck {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 400;
  font-size: 15px;
  letter-spacing: -0.005em;
  color: var(--ink-soft);
  max-width: 580px;
  margin-bottom: 72px;
  line-height: 1.55;
}

/* ========================================================
   Project page images - book layout
   ========================================================
   Per-image placement system. Hero is always full-width.
   Subsequent images get one of:
     .full     - 100% container width
     .left     - ~62% width, flush left, white space to right
     .right    - ~62% width, flush right, white space to left
     .pair > figure - two images side-by-side, half each
   Layout class is computed per image in project.js based on
   its aspect ratio and position. Generous gaps between
   images give the work room to breathe (monograph feel).
   ======================================================== */
.project-page .project-images {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 96px;
  max-width: 1200px;
  margin: 0 auto 96px;
  padding: 0 6vw;
}
.project-page .project-images > figure {
  margin: 0;
  background: transparent;
  line-height: 0;
  text-align: center;
}
.project-page .project-images > figure img,
.project-page .project-images .pair figure img {
  display: block;
  width: 100%;
  height: auto;
  /* Width-driven sizing: each image fills the figure's column width and the
     browser derives the height from the natural aspect ratio. This keeps
     images responsive to the layout (and to browser zoom) rather than being
     pinned to a fraction of the physical viewport via vh units. */
}
.project-page .project-images > figure.full {
  width: 100%;
}
.project-page .project-images > figure.left {
  width: 62%;
  align-self: flex-start;
}
.project-page .project-images > figure.right {
  width: 62%;
  align-self: flex-end;
}
.project-page .project-images .pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  width: 100%;
  align-items: stretch;
}
/* Paired figures get a shared aspect-ratio set inline by project.js (the
   average of the two images' aspects). Both images cover that shared box
   with object-fit: cover, so the figures sit at identical heights and the
   smaller mismatch crops a few percent off one edge rather than stretching. */
.project-page .project-images .pair figure {
  margin: 0;
  background: transparent;
  line-height: 0;
  text-align: center;
  overflow: hidden;
}
.project-page .project-images .pair figure picture {
  display: block;
  width: 100%;
  height: 100%;
}
.project-page .project-images .pair figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.project-page .project-images .placeholder-block {
  width: 100%;
  aspect-ratio: 16/9;
  background: var(--bg-dark);
}

/* ========================================================
   Project videos (Vimeo embeds)
   ======================================================== */
.project-page .project-videos {
  max-width: 1200px;
  margin: 0 auto 96px;
  padding: 0 6vw;
  display: flex;
  flex-direction: column;
  gap: 96px;
}
.project-page .video-block {
  display: flex;
  flex-direction: column;
  gap: 24px;
}
.project-page .video-frame {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
  background: var(--bg-dark);
}
.project-page .video-frame iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.project-page .video-body {
  font-family: 'Switzer', sans-serif;
  font-style: italic;
  font-weight: 300;
  font-size: 17px;
  line-height: 1.55;
  max-width: 640px;
  margin-top: 12px;
  color: var(--ink);
}
.project-page .video-credits,
.project-page .project-credits {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  line-height: 1.8;
  color: var(--ink-soft);
  max-width: 640px;
  margin: 32px 0 0;
  letter-spacing: 0.01em;
}
.project-page .project-credits {
  margin: 0 0 96px;
}
/* When a project has both credits and body, give them clear separation */
.project-page .project-credits + .project-body,
.project-page .video-credits + .project-body { margin-top: 48px; }
.project-page .video-credits pre,
.project-page .project-credits pre {
  font: inherit;
  white-space: pre-wrap;
  margin: 0;
}

@media (max-width: 800px) {
  .project-page .project-videos {
    gap: 48px;
    padding: 0 16px;
    margin-bottom: 48px;
  }
  .project-page .video-credits,
  .project-page .project-credits {
    padding: 0 16px;
  }
  .project-page .project-credits {
    margin-bottom: 48px;
  }
}
@media (max-width: 800px) {
  .project-page .project-images {
    gap: 48px;
    padding: 0 16px;
    margin-bottom: 48px;
  }
  .project-page .project-images > figure.left,
  .project-page .project-images > figure.right {
    width: 100%;
    align-self: stretch;
  }
  .project-page .project-images .pair {
    flex-direction: column;
    gap: 48px;
    height: auto;
  }
  .project-page .project-images .pair figure {
    height: auto;
    flex: 0 0 auto;
  }
  .project-page .project-images .pair figure img {
    width: 100%;
    height: auto;
    max-height: 90vh;
  }
}

.project-page .project-body {
  max-width: 640px;
  margin: 64px 0 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.75;
  color: var(--ink);
}
.project-page .project-body p { margin: 0 0 1.2em 0; }
.project-page .project-body p:last-child { margin-bottom: 0; }
/* Empty body block - don't reserve space */
.project-page .project-body:empty { display: none; }
.project-page .project-footer {
  margin-top: 100px;
  padding-top: 24px;
  border-top: 0.5px solid var(--line);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 24px;
  align-items: center;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-soft);
  letter-spacing: 0.05em;
}
.project-page .project-footer .footer-prev { text-align: left; }
.project-page .project-footer .footer-all { text-align: center; }
.project-page .project-footer .footer-next { text-align: right; }
.project-page .project-footer a:hover { font-style: italic; color: var(--ink); }

/* ============================================
   Diary archive page header
   ============================================ */

.archive-header {
  background: var(--bg);
  padding: 120px 48px 60px;
  text-align: center;
  border-bottom: 0.5px solid var(--line);
}
.archive-header h1 {
  font-family: 'Switzer', sans-serif;
  font-weight: 300;
  font-size: 40px;
  letter-spacing: -0.025em;
  margin-bottom: 12px;
}
.archive-header h1 em { font-style: italic; }
.archive-header p {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  color: var(--ink-soft);
  letter-spacing: 0.1em;
}

/* ============================================
   Mobile
   ============================================ */

@media (max-width: 768px) {
  .nav-bar { padding: 16px 20px; }
  .nav-bar .nav-links { gap: 12px; font-size: 10px; }
  .hero-stack { min-height: 520px; }
  .info-strip { padding: 32px 20px; }
  .info-strip .strip-inner { grid-template-columns: 1fr 1fr; gap: 24px; }
  .section { padding: 56px 20px 64px; }
  /* On mobile: stack preview on top, list below.
     The preview area is sticky to the top of the viewport so it stays
     visible while you scroll the list. Tapping a row updates the sticky
     preview without forcing you back to the top of the page. */
  .index-grid {
    grid-template-columns: 1fr;
    gap: 24px;
    display: flex;
    flex-direction: column;
  }
  .index-grid .right-column {
    order: 0;
    /* Reset all the desktop sticky/sizing rules so the inner preview can be the sticky element */
    position: static;
    top: auto;
    height: auto;
    min-height: 0;
    max-height: none;
    display: block;
  }
  .index-grid .project-list { order: 1; }
  .index-grid .show-all-toggle { order: 2; }
  .image-preview-area {
    position: sticky;
    top: 64px;
    z-index: 40;
    aspect-ratio: 4/3;
    width: 100%;
    max-height: none;
    background: var(--bg);
  }

  /* Touch devices don't have hover, so the overlay sits visible by default.
     The grid layout itself is now handled by the global rules + responsive
     breakpoints, so no overrides needed here. */
  .work-tile-overlay {
    opacity: 1;
    background: linear-gradient(to top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0) 55%);
  }
  .work-tile-title { font-size: 14px; }
  .work-tile-reveal { font-size: 10px; max-width: none; }
  .view-toggle { font-size: 10px; }

  /* (right-column / image-preview-area mobile rules consolidated above) */
  .project-row { grid-template-columns: 36px 1fr 70px; gap: 12px; padding: 12px 0; }
  .project-row .title { font-size: 16px; }
  .show-all-toggle { display: block; }
  .project-row.is-hidden-mobile { display: none; }
  .project-list.is-expanded .project-row.is-hidden-mobile { display: grid; }
  .recent-pairs { grid-template-columns: 1fr; gap: 48px; }
  .selects-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: 140px;
    gap: 8px;
  }
  .selects-tile,
  .selects-tile:nth-child(7n+1),
  .selects-tile:nth-child(7n+2),
  .selects-tile:nth-child(7n+3),
  .selects-tile:nth-child(7n+4),
  .selects-tile:nth-child(7n+5),
  .selects-tile:nth-child(7n+6),
  .selects-tile:nth-child(7n+7) {
    grid-column: span 1;
    grid-row: span 2;
  }
  .selects-tile:nth-child(5n+1) { grid-column: span 2; grid-row: span 2; }
  .selects-overlay {
    opacity: 1;
    background: linear-gradient(to top, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 60%);
  }
  .selects-overlay .selects-title { font-size: 14px; }
  .selects-overlay .selects-count { font-size: 9px; }
  .lightbox-image {
    width: calc(100vw - 24px);
    height: calc(100vh - 120px);
  }
  .lightbox-close { top: 12px; right: 16px; font-size: 28px; }
  .lightbox-prev, .lightbox-next {
    width: 40px; height: 60px; font-size: 40px;
  }
  .lightbox-prev { left: 4px; }
  .lightbox-next { right: 4px; }
  .lightbox-meta {
    bottom: 16px; left: 16px; right: 16px;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    font-size: 10px;
  }
  .lightbox-meta .lightbox-title { font-size: 14px; }
  .about-grid { grid-template-columns: 1fr; gap: 32px; }
  .about-portrait { max-width: 320px; }
  .about-text .opener { font-size: 11px; }
  .about-text .credits { grid-template-columns: 1fr; gap: 4px 0; }
  .about-text .credits dt { padding-top: 12px; }
  .about-text .credits dd { padding-bottom: 8px; }
  .diary-section { padding: 56px 20px 80px; }
  .diary-strip { grid-template-columns: 1fr; gap: 48px; }
  .diary-archive { grid-template-columns: 1fr; gap: 48px; }
  .project-page { padding: 80px 20px 64px; }
  .project-page .meta-row {
    grid-template-columns: 56px 1fr;
    gap: 6px 12px;
    padding-bottom: 14px;
    margin-bottom: 32px;
    row-gap: 6px;
    font-size: 10px;
  }
  /* On mobile, lay meta as two rows (num+client, location+discipline) */
  .project-page .meta-row > div:nth-child(1) { grid-row: 1; grid-column: 1; }
  .project-page .meta-row > div:nth-child(2) { grid-row: 1; grid-column: 2; }
  .project-page .meta-row > div:nth-child(3) { grid-row: 2; grid-column: 1 / span 2; }
  .project-page .meta-row > div:nth-child(4) { grid-row: 3; grid-column: 1 / span 2; }
  .project-title-block { margin-bottom: 14px; }
  .project-page .project-brand { font-size: 11px; letter-spacing: 0.16em; margin-bottom: 4px; }
  .project-page .project-work { font-size: 32px; line-height: 1.05; }
  .project-page .project-subtitle { font-size: 14px; margin-top: 6px; }
  .project-page .project-deck { font-size: 14px; line-height: 1.5; margin-bottom: 32px; max-width: 100%; }
  .project-page h1 { font-size: 32px; }
  .project-page .images { grid-template-columns: 1fr; }
  .project-page .images .full { grid-column: span 1; }
  .project-page .project-body { font-size: 13px; max-width: 100%; padding: 0 4px; }
  .archive-header { padding: 80px 20px 40px; }
  .archive-header h1 { font-size: 30px; }
}
