/* ============================================
   TOKENS
   Palette and type scale live in theme.css, shared
   with the Studio admin tool. Near-black "darkroom"
   ground — the photographs still supply most of the
   color, but UI chrome (nav, filters, controls)
   borrows the warm accent for a consistent feel.
   ============================================ */
@import url("theme.css");

:root {
  /* Override Bootstrap's theme variables so its components
     (navbar, collapse, buttons) inherit this palette. */
  --bs-body-bg: var(--void);
  --bs-body-color: var(--paper);
  --bs-border-color: var(--hairline);
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  background: var(--void);
  color: var(--paper);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
}

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

/* ============================================
   NAVBAR
   ============================================ */
.navbar {
  background: rgba(13, 13, 12, 0.86);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--hairline);
  padding-top: 16px;
  padding-bottom: 16px;
}

.wordmark {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: 1.25rem;
  color: var(--paper) !important;
}

.nav-link {
  color: var(--paper) !important;
  font-size: 0.85rem;
  opacity: 0.85;
  transition: opacity 0.2s, color 0.2s;
}
.nav-link:hover { opacity: 1; color: var(--accent) !important; }

.navbar-toggler {
  border-color: var(--hairline);
  box-shadow: none !important;
  border-radius: 3px;
  transition: border-color 0.2s;
}
.navbar-toggler:hover { border-color: var(--accent); }
.navbar-toggler-icon {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(243,241,234,0.85)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* ============================================
   INTRO
   ============================================ */
.hero {
  padding-top: clamp(40px, 7vw, 84px);
  padding-bottom: clamp(24px, 4vw, 44px);
  max-width: none; /* the column widths now control this */
}

/* Lets the intro column actually shrink to its col-md-4 share instead
   of a flex item's default min-width:auto forcing it wide enough to
   fit the H1 on one line — needed so the oversized H1 below wraps
   within the column instead of blowing the grid out. */
.hero-intro {
  min-width: 0;
}

.intro-eyebrow {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 0 0 16px;
}

/* Editorial-scale headline — dramatic size contrast against the rest
   of the type on the page. overflow-wrap/hyphens keep a long word
   (e.g. "documentary") from overflowing the narrow intro column. */
.hero h1 {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(3rem, 7vw, 7rem);
  line-height: 1.02;
  margin: 0;
  color: var(--paper);
  overflow-wrap: break-word;
  hyphens: auto;
}

/* Hero's lead image sits in a fixed wide frame regardless of the
   photo's own orientation — left at its native size class, a portrait
   photo filling this wide col-md-8 slot would blow out to an enormous
   height. contain (not the shared .frame rule's cover) shows the whole
   photo letterboxed rather than cropping a tall photo down hard to
   fit, same technique the old carousel used. */
#heroFeatured .frame {
  aspect-ratio: 3 / 2;
  height: auto;
}
#heroFeatured .frame img {
  object-fit: contain;
  /* Zooms in slightly on top of contain's letterboxing, trimming the
     bars down rather than removing them outright — .frame's
     overflow:hidden crops the scaled-up overflow. */
  transform: scale(1.15);
}

.hero-body {
  font-size: 0.95rem;
  line-height: 1.7;
  color: #c9c6bc;
  margin: 24px 0 0;
  max-width: 42ch;
}

/* ============================================
   FEATURED
   ============================================ */
/* Shares the same italic serif treatment as .contact-heading below —
   see that rule for the shared declaration (also covers the "About"
   heading in its section-divider, and "Gallery" on gallery.html). */

/* ============================================
   SECTION DIVIDERS
   Large, low-opacity outline numerals extend the film-frame numbering
   convention on individual photos to the page's own structure, paired
   with a hairline marking where each major section starts.
   ============================================ */
.section-divider {
  display: flex;
  align-items: baseline;
  gap: 18px;
  border-top: 1px solid var(--hairline);
  padding-top: 22px;
  margin-bottom: 28px;
}

.section-number {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.2rem, 5vw, 3.8rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--stone);
  opacity: 0.5;
}

/* Fades/slides up into place the first time it scrolls into view
   (.revealed is added by the [data-reveal] observer in script.js). */
.gallery-cta {
  padding: 24px 0;
  opacity: 0;
  transform: translateY(36px);
  /* Slower and a longer drift than --ease (which front-loads most of
     its motion in the first third of the duration, reading as a quick
     flick) — a reveal wants to read as a gradual drift, not a snap. */
  transition: opacity 1.1s ease-out, transform 1.1s ease-out;
}
.gallery-cta.revealed {
  opacity: 1;
  transform: translateY(0);
}

.gallery-cta-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  font-size: clamp(1.3rem, 3vw, 2.4rem);
  color: var(--paper);
  border-bottom: 1px solid var(--hairline);
  padding-bottom: 6px;
  transition: color 0.2s, border-color 0.2s;
}
.gallery-cta-link:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.gallery-cta-arrow {
  flex-shrink: 0;
  transition: transform 0.25s var(--ease);
}
.gallery-cta-link:hover .gallery-cta-arrow {
  transform: translateX(6px);
}

/* ============================================
   PROJECT FOLDERS
   ============================================ */
#foldersList {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.folder-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--stone);
  background: transparent;
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 7px 15px;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.folder-tab:hover { color: var(--paper); border-color: var(--stone); }

.folder-tab-icon {
  flex-shrink: 0;
  opacity: 0.85;
}
.folder-tab.active {
  color: var(--void);
  background: var(--accent);
  border-color: var(--accent);
}

/* Mobile filter menu — a Studio-style dropdown that replaces the
   inline pill row below the md breakpoint (see the d-md-block /
   d-md-none split in index.html). */
.folder-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--paper);
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: 3px;
  padding: 10px 14px;
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.folder-toggle:hover,
.folder-toggle[aria-expanded="true"] {
  border-color: var(--accent);
  color: var(--accent);
}
.folder-toggle-icon {
  display: inline-block;
  transition: transform 0.2s var(--ease);
}
.folder-toggle[aria-expanded="true"] .folder-toggle-icon { transform: rotate(180deg); }

@media (max-width: 767.98px) {
  #foldersCollapse {
    margin-top: 8px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: 4px;
    padding: 4px 14px;
  }
  #foldersList { flex-direction: column; gap: 0; }
  .folder-tab {
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    border-radius: 0;
    border-bottom: 1px solid var(--hairline);
    padding: 12px 2px;
  }
  .folder-tab:last-child { border-bottom: none; }
  .folder-tab:hover { color: var(--paper); }
  .folder-tab.active { background: transparent; color: var(--accent); }
}

/* ============================================
   GENRE THEMING (gallery.html only)
   Picking a category sets <html data-genre="..."> (see buildFolders()
   in script.js), which retints the whole page to that genre's mood by
   overriding theme.css's tokens — theme.css itself, and the Studio
   admin tool (which never sets data-genre), are untouched. One
   hue/saturation/lightness-offset triple drives every token so each
   genre still reads as part of the same dark "darkroom" family;
   Architecture is the deliberate exception, dropping to near-zero
   saturation instead of picking a hue. "All" clears the attribute,
   falling back to the default palette. */
html[data-genre] {
  --genre-s: 18%;
  --genre-l: 0%;
  --void: hsl(var(--genre-h) var(--genre-s) calc(5% + var(--genre-l)));
  --surface: hsl(var(--genre-h) var(--genre-s) calc(9% + var(--genre-l)));
  --surface-raised: hsl(var(--genre-h) var(--genre-s) calc(12% + var(--genre-l)));
  --hairline: hsl(var(--genre-h) var(--genre-s) calc(17% + var(--genre-l)));
  --stone: hsl(var(--genre-h) calc(var(--genre-s) * 0.6) calc(58% + var(--genre-l)));
  --accent: hsl(var(--genre-h) 48% 62%);
  --accent-soft: hsl(var(--genre-h) 48% 62% / 0.12);
}
html[data-genre="nature"]       { --genre-h: 140; } /* muted forest green */
html[data-genre="water"],
html[data-genre="underwater"]   { --genre-h: 205; } /* deep, quiet blue */
html[data-genre="astro"]        { --genre-h: 265; } /* dusty violet */
html[data-genre="landscape"],
html[data-genre="travel"]       { --genre-h: 30;  } /* warm umber/brown */
html[data-genre="architecture"] { --genre-h: 30;  --genre-s: 5%; } /* plain desaturated grey — no hue reads as intentional here */
html[data-genre="street"]       { --genre-h: 15;  } /* muted rust/terracotta */
html[data-genre="portrait"]     { --genre-h: 350; } /* dusty rose */
html[data-genre="wildlife"]     { --genre-h: 80;  } /* olive/khaki, distinct from Nature's green */
html[data-genre="abstract"]     { --genre-h: 190; } /* muted teal */
html[data-genre="aerial"]       { --genre-h: 200; --genre-l: 2%; } /* pale slate-blue — lighter than Water/Underwater so they don't collide */

/* ============================================
   PHOTO GRID
   Shared by the full gallery (gallery.html, #galleryRow) and the
   featured section on the home page (index.html, #featuredGrid).
   ============================================ */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: dense;
  gap: 4px; /* matches the old g-1 gutter */
}
@media (min-width: 768px) {
  .photo-grid { grid-template-columns: repeat(4, 1fr); }
}
.photo-grid > .is-wide { grid-column: span 2; }

/* Without this, a differently-shaped tile (e.g. narrow-pair) can force
   its column's 1fr track wider than the others — its aspect-ratio
   width is computed from a row height that another tile in a
   different row set, and that inflated width gets counted as the
   column's minimum content size otherwise. That misalignment then
   compounds down the grid and can blow a tile's height up by
   thousands of pixels, bleeding into whatever comes after the grid. */
.photo-grid > div {
  min-width: 0;
  min-height: 0;
}

.frame {
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--hairline);
  cursor: pointer;
  aspect-ratio: 4 / 5;
  height: 100%; /* fills its grid cell rather than the aspect-ratio alone deciding height */
}

.frame.size-wide { aspect-ratio: 3 / 2; }
.frame.size-tall { aspect-ratio: 3 / 4; }
.frame.size-narrow-pair { aspect-ratio: 5 / 4; }

.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.frame img.loaded { opacity: 1; }

@media (hover: hover) {
  .frame:hover img { transform: scale(1.035); }
}

.frame-number {
  position: absolute;
  top: 10px; left: 10px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: #fff;
  background: rgba(13, 13, 12, 0.6);
  padding: 3px 7px;
}

.frame-caption {
  position: absolute;
  left: 10px; right: 10px; bottom: 10px;
  color: #fff;
  font-size: 0.78rem;
  line-height: 1.3;
  /* No dark gradient behind the caption anymore — a text-shadow keeps
     it readable over bright photos without permanently darkening the
     bottom of every tile. */
  text-shadow: 0 1px 3px rgba(0,0,0,0.85), 0 1px 10px rgba(0,0,0,0.6);
}

.frame-caption .loc {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: rgba(255,255,255,0.7);
  margin-top: 2px;
}

/* ============================================
   ABOUT / CONTACT
   ============================================ */
/* Keeps the sticky navbar from covering the top of the section when a
   link (in-page, or gallery.html's "About"/"Contact" jumping back here
   via index.html#about) scrolls it into view. */
#about,
#contact {
  scroll-margin-top: 90px;
}

/* Bootstrap tops out at py-5 — About wants more room to breathe than
   the rest of the page now that it's text-only again. */
.py-6 {
  padding-top: clamp(64px, 9vw, 128px);
  padding-bottom: clamp(64px, 9vw, 128px);
}

/* Shared by every section's heading: Featured (.featured-eyebrow, also
   reused as-is for "Gallery" on gallery.html), About's h2, and this
   one. Keeps every "0N — Section" pair reading as the same family. */
.featured-eyebrow,
#about .section-divider h2,
.contact-heading {
  font-family: var(--font-display);
  font-weight: 300;
  font-style: italic;
  font-size: 1.6rem;
  color: var(--stone);
  margin-bottom: 20px;
}

.contact-social {
  display: flex;
  justify-content: center;
  gap: 24px;
  font-size: 1.05rem;
  color: var(--stone);
}
.contact-social a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: color 0.2s;
}
.contact-social a:hover { color: var(--accent); }
.instagram-icon { flex-shrink: 0; }

.site-footer {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--stone);
  border-top: 1px solid var(--hairline);
}

/* ============================================
   LIGHTBOX with pinch / double-tap zoom
   ============================================ */
.lightbox {
  position: fixed;
  inset: 0;
  background: rgba(8, 8, 7, 0.98);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1050;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--ease);
}
.lightbox.open { opacity: 1; visibility: visible; }

.lightbox-viewport {
  width: 92vw;
  height: 76vh;
  overflow: hidden;
  touch-action: none;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-in;
}
.lightbox-viewport.zoomed { cursor: grab; }
.lightbox-viewport.zoomed:active { cursor: grabbing; }

.lightbox-viewport img {
  max-width: 92vw;
  max-height: 76vh;
  width: auto;
  height: auto;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform;
  transform-origin: center center;
}

.lightbox-footer {
  position: absolute;
  left: 0; right: 0; bottom: 20px;
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
  padding: 0 16px;
  color: rgba(255,255,255,0.85);
  font-size: 0.82rem;
  text-align: center;
}

.lightbox-frame {
  font-family: var(--font-mono);
  color: rgba(255,255,255,0.5);
  font-size: 0.72rem;
}

.lightbox-zoom-hint {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: rgba(255,255,255,0.4);
  width: 100%;
}

.lightbox-close,
.lightbox-nav {
  position: absolute;
  background: transparent;
  border: none;
  color: #fff;
  cursor: pointer;
  z-index: 2;
  transition: color 0.2s, opacity 0.2s;
}
.lightbox-close:hover,
.lightbox-nav:hover { color: var(--accent); }

.lightbox-close {
  top: 20px; right: 20px;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.lightbox-nav {
  top: 50%;
  transform: translateY(-50%);
  font-size: 1.6rem;
  padding: 10px;
  opacity: 0.6;
}
.lightbox-nav:hover { opacity: 1; }
.lightbox-prev { left: 16px; }
.lightbox-next { right: 16px; }

@media (max-width: 768px) {
  .lightbox-nav { display: none; } /* swipe instead, see script.js */
}
