/* GABRIEL LAMBERT — Stills · Film · Flight
   Basel editorial system: warm gallery paper, black type, one red dot language. */

:root {
  --black: #0b0b0b;
  --ink: #141414;
  --paper: #f3f0e8;              /* warm gallery paper */
  --paper-deep: #edeae1;
  --red: #d71920;                /* the logo red — the only interaction accent */
  --sep: #77736c;                /* neutral separator dots (never red) */
  --nav-grey: #9a9790;           /* inactive category/series labels */
  --nav-grey-hover: #4a4742;     /* inactive label on hover — darker, still not black */
  --hair: rgba(20, 20, 20, .18);
  --sans: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --serif: "EB Garamond", Georgia, "Times New Roman", serif;
  --margin-w: clamp(150px, 12vw, 200px);   /* space reserved for the fixed brand column on inner pages */
  --logo-w: clamp(84px, 7.4vw, 122px);     /* one logo size everywhere */
  --brand-inset: clamp(24px, 2.2vw, 38px); /* logo + vertical name left edge (off the viewport edge) */
  --brand-top: clamp(20px, 2.8vh, 34px);   /* logo top offset, every page */
  --name-gap: clamp(24px, 4vh, 48px);      /* logo → vertical name, every page */
  --home-portrait-w: clamp(300px, 34vw, 480px);          /* homepage portrait, full-bleed from x=0 */
  --home-stage-pad: clamp(28px, 3.5vw, 56px);            /* homepage content column inset */
  --nav-x: calc(var(--home-portrait-w) + var(--home-stage-pad));  /* left edge of STILLS·FILM·FLIGHT, every page */
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible { outline: 1px solid var(--red); outline-offset: 4px; }

/* the red dot — the single interaction element */
.dot-el { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--red); }

/* ============ shell ============ */
:root {
  --header-h: clamp(78px, 9.5vh, 96px);
  --header-h-open: calc(var(--header-h) + clamp(38px, 5vh, 50px));
  /* album pages add a third header row (the series selector) below the cats row */
  --header-h-album: calc(var(--header-h-open) + clamp(54px, 6.8vh, 70px));
}
.site { display: block; min-height: 100vh; }

/* ============ shared brand column — fixed top-left, identical on every page ============ */
/* logo and vertical name are LEFT-ALIGNED at --brand-inset from the edge (like the
   mockup). On the homepage they overlay the photo's light top-left; elsewhere cream. */
.brand-col {
  position: fixed; top: 0; left: 0; z-index: 25;
  width: auto; height: 100vh;
  background: transparent; pointer-events: none;
}
.brand-col .logo-tile { pointer-events: auto; }
.lp-identity {
  display: flex; flex-direction: column; align-items: flex-start;
  padding: var(--brand-top) 0 0 var(--brand-inset);
}
.logo-tile { display: block; width: var(--logo-w); }
.logo-tile img { width: 100%; height: auto; }
.logo-words {
  display: block; width: var(--logo-w); margin-top: 8px;
  text-align: justify; text-align-last: justify; text-justify: inter-word;
  font-size: 6.5px; font-weight: 500; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink); white-space: nowrap; opacity: .82;
}
.vertical-name {
  margin: var(--name-gap) 0 0;
  writing-mode: vertical-rl; transform: rotate(180deg);   /* reads bottom → top */
  font-size: 13.5px; font-weight: 500; letter-spacing: .4em; text-transform: uppercase;
  color: var(--ink);
}

/* Gabriel's portrait — figure on the right, light studio backdrop on the left
   (under the logo + name). Naturally printed, no overlay/vignette. */
.lp-portrait { margin: 0; overflow: hidden; background: var(--paper); }
.lp-portrait img {
  /* height drives the fit (cover), so the full photo top-to-bottom always
     stays in frame — only width is ever cropped, via object-position; no
     extra transform:scale on top (that used to eat into the top/bottom
     too). A LOW object-position-x pins the image's own LEFT edge to the
     frame's left edge — i.e. it shows the source photo's own left side,
     which is where its plain white backdrop is, right under the logo
     and name. (Raising this value pins the image's right edge instead,
     sliding the picture left and showing more of its right side —
     the opposite of what we want here.) */
  width: 100%; height: 100%; object-fit: cover; object-position: 45% 6%;
  /* natural tone kept (not forced grayscale) — its warm backdrop already
     matches --paper almost exactly, so the panel edge disappears */
  filter: saturate(0.9) brightness(1.02) contrast(1.02);
}

/* ============ global top header ============ */
/* STILLS·FILM·FLIGHT begins at --nav-x (the homepage hero's left edge) on EVERY
   page; INDEX·ABOUT·CONTACT sits at the far right; the category row wraps below,
   aligned under STILLS. */
.site-header {
  position: sticky; top: 0; z-index: 20;
  background: var(--paper);
  display: flex; flex-wrap: wrap; align-items: center; align-content: center;
  column-gap: clamp(20px, 3vw, 44px); row-gap: 0;
  padding: clamp(6px, 1.5vh, 14px) clamp(18px, 2.6vw, 40px) 0 var(--nav-x);
  min-height: var(--header-h);
}
body.album-page .site-header { position: fixed; left: 0; right: 0; }
.nav-primary { display: flex; align-items: center; }
.nav-utility { margin-left: auto; display: flex; align-items: baseline; gap: clamp(8px, 1.3vw, 20px); }
.nav-cats {
  flex-basis: 100%; order: 3;
  display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-start;
  gap: clamp(12px, 2.2vw, 30px);
  max-height: 0; opacity: 0; overflow: hidden; padding-bottom: 0;
  transition: max-height .5s cubic-bezier(.22,.61,.36,1), opacity .4s ease, padding-bottom .5s cubic-bezier(.22,.61,.36,1);
}
.site-header.cats-open .nav-cats,
body.album-page .nav-cats {
  max-height: 60px; opacity: 1; padding-bottom: clamp(10px, 1.6vh, 18px);
}

/* ============ numbered navigation system ============ */
/* three levels: ● STILLS·FILM·FLIGHT / 01 STREET 02 PORTRAIT… / BAKU·NEW YORK…
   Level 1: one red dot, always immediately before the active word.
   Level 2: active number red, active word black, inactive words grey.
   Level 3: active word black, inactive words grey. No dots below level 1. */
.support-link, .main-link, .cat-link, .series-link, .sp-nav {
  display: inline-flex; align-items: center; position: relative;
  min-height: 44px;
  font-weight: 500; text-transform: uppercase; color: inherit; cursor: pointer;
}
.support-link::after {
  content: ""; flex: none; border-radius: 50%; background: var(--red);
  opacity: 0; transform: scale(.35);
  transition: opacity .3s ease, transform .3s ease;
}
.support-link:hover::after, .support-link.is-active::after {
  opacity: 1; transform: scale(1);
}

/* LEVEL 1 — PRIMARY. The one red dot sits after the active word, same
   gesture as the utility nav's own dot (.support-link::after): hidden
   until hover (a "you can click this" affordance), permanently on for
   whichever page is truly active. A real flex item (like
   .support-link's), not absolutely positioned, so it reserves constant
   space and never shifts the WORD itself — only what comes after it —
   which keeps "STILLS" pixel-aligned to the homepage photo wall's left
   edge regardless of hover/active state. */
.main-link {
  padding: 8px 6px;
  font-size: clamp(15px, 1.4vw, 20px); font-weight: 500; letter-spacing: .13em;
  color: var(--ink);
}
.main-link::after {
  content: ""; flex: none;
  width: 10px; height: 10px; border-radius: 50%; background: var(--red);
  opacity: 0; transform: scale(.35);
  margin-left: 10px;
  transition: opacity .3s ease, transform .3s ease;
}
.main-link:hover::after, .main-link.is-active::after {
  opacity: 1; transform: scale(1);
}
.nav-vsep {
  display: inline-block; flex: none; align-self: center;
  width: 1px; height: 14px;              /* matches the primary row's cap-height */
  background: var(--red);
  margin: 0 clamp(10px, 1.6vw, 18px);
}

/* UTILITY — smaller, quieter, same baseline */
.support-link {
  padding: 10px 5px;
  font-size: clamp(10px, .82vw, 11.5px); letter-spacing: .2em;
  color: var(--ink); opacity: .75;
}
.support-link:hover, .support-link.is-active { opacity: 1; }
.support-link::after { width: 5px; height: 5px; margin-left: .6em; }
.nav-usep {
  display: inline-block; flex: none; align-self: center;
  width: 1px; height: 9px;               /* matches the utility row's smaller cap-height */
  background: var(--red);
}

/* LEVEL 2 — CATEGORY row. Number + word; only the active pair breaks from
   grey (number → red, word → black). No separators — the numbering already
   orders the row. */
.cat-link {
  padding: 10px 8px; gap: 7px;
  font-size: clamp(9px, .82vw, 10.5px); letter-spacing: .2em;
}
.cat-num  { color: var(--nav-grey); font-weight: 600; transition: color .25s ease; }
.cat-word { color: var(--nav-grey); transition: color .25s ease; }
.cat-link.is-active .cat-num  { color: var(--red); }
.cat-link.is-active .cat-word { color: var(--ink); font-weight: 600; }
.cat-link:not(.is-active):hover .cat-word { color: var(--nav-grey-hover); }

/* ============ page content wrapper ============ */
.page {
  /* left edge lines up with --nav-x — the same x where STILLS·FILM·FLIGHT
     starts in the header, and where the homepage photo wall's left edge
     sits — so every content page's copy/photos share that one reference
     line instead of the narrower brand-column margin */
  padding: clamp(18px, 4vh, 44px) clamp(20px, 3.4vw, 52px) 64px var(--nav-x);
  min-height: calc(100vh - var(--header-h));
}

/* ============ generic content pages ============ */
/* ============ generic content pages ============ */
.content { padding: 0 0 56px; }
.page-head { margin-bottom: clamp(26px, 3vw, 48px); }
.crumb { font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase; opacity: .55; margin-bottom: 14px; }
.crumb a:hover { opacity: 1; }
.page-title { font-family: var(--serif); font-weight: 400; font-size: clamp(30px, 3.4vw, 52px); line-height: 1.05; }
.page-blurb { max-width: 52ch; margin-top: 14px; font-size: 13px; line-height: 1.75; opacity: .8; }
.sub-title { font-size: 10.5px; font-weight: 600; letter-spacing: .3em; text-transform: uppercase; margin: clamp(30px, 4vw, 56px) 0 18px; }

/* ============ homepage — portrait full-bleed from x=0 (like the mockup) ============ */
/* the header just floats transparent over the top; its --nav-x padding already
   puts STILLS·FILM·FLIGHT at the hero photo's left edge */
.site-home .site-header {
  position: absolute; top: 0; left: 0; right: 0;
  background: transparent; pointer-events: none;
}
.site-home .site-header nav { pointer-events: auto; }
.page-home {
  display: grid;
  grid-template-columns: var(--home-portrait-w) 1fr;
  padding: 0; min-height: 100vh;
}
.page-home .lp-portrait {
  grid-column: 1; align-self: stretch;
  height: 100vh; min-height: 100vh; margin: 0;
}
.page-home .home-stage {
  grid-column: 2; align-self: stretch; height: 100vh;
  display: flex; flex-direction: column;
  /* right padding matches the header's own right padding exactly, so the
     last photo's right edge lines up with CONTACT's; left padding is
     --home-stage-pad, which by definition (--nav-x = --home-portrait-w +
     --home-stage-pad) already lands the first photo's left edge on
     --nav-x — the same x where STILLS starts */
  padding: clamp(110px, calc(10.6vh + 16px), 128px) clamp(18px, 2.6vw, 40px) clamp(30px, 5vh, 64px) var(--home-stage-pad);
}
.ph { position: relative; }
.ph img { display: block; width: 100%; height: auto; }

/* New York on top, full width of the stage and the biggest frame — the
   establishing shot. The other two sit underneath, side by side and
   balanced against each other. Straight on the cream background — no
   mat, no shadow, no caption. Both rows are sized by flex-grow (never a
   fixed/clamped height), so together they always fill exactly the space
   between the header padding and the stage's own bottom padding —
   flush with the bottom of Gabriel's portrait, whatever the viewport
   height, with no leftover band of beige underneath. */
.home-wall {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  gap: clamp(28px, 4.6vh, 56px);
}
.frame { display: block; height: 100%; }
.frame .ph { overflow: hidden; height: 100%; }
.frame .ph img { display: block; width: 100%; height: 100%; object-fit: cover; }
.wall-top { flex: 1.83 1 0; min-height: 0; }
.wall-bottom {
  flex: 1 1 0; min-height: 0;
  display: flex; align-items: stretch; justify-content: flex-start;
  gap: clamp(16px, 2.2vw, 32px);
}
.wall-bottom .frame { flex: 1 1 0; min-width: 0; }

/* the three hero photos fade in on arrival — New York first, then the
   supporting pair a beat after. Gabriel's portrait is unaffected. */
@keyframes home-wall-in { from { opacity: 0; } to { opacity: 1; } }
.home-wall .frame {
  opacity: 0;
  animation: home-wall-in 2.2s ease-out forwards;
}
.wall-top .frame { animation-delay: .2s; }
.wall-bottom .frame:nth-child(1) { animation-delay: .9s; }
.wall-bottom .frame:nth-child(2) { animation-delay: 1.15s; }

/* project pages */
.proj-loc-line { font-size: 10px; font-weight: 500; letter-spacing: .3em; text-transform: uppercase; margin-top: 12px; opacity: .6; }
.gallery { display: grid; gap: clamp(34px, 5vw, 84px); max-width: 980px; }
.gallery .ph:nth-child(odd) { max-width: 86%; justify-self: start; }
.gallery .ph:nth-child(even) { max-width: 78%; justify-self: end; }
.gallery .ph:hover { cursor: zoom-in; }
.gallery-2 { grid-template-columns: 1fr 1fr; max-width: none; }
.proj-pn { margin-top: clamp(40px, 5vw, 70px); font-size: 10px; letter-spacing: .3em; text-transform: uppercase; }
.proj-pn a { opacity: .7; }
.proj-pn a:hover { opacity: 1; }

/* index lists */
.idx-list { max-width: 860px; }
.idx-row {
  display: grid; grid-template-columns: 1fr 110px 170px 90px; gap: 16px; align-items: baseline;
  padding: 15px 0;
  transition: padding-left .4s cubic-bezier(.22,.61,.36,1);
}
.idx-row:hover { padding-left: 14px; }
.idx-title { font-family: var(--serif); font-size: 17px; }
.idx-cat, .idx-loc, .idx-year { font-size: 9px; font-weight: 500; letter-spacing: .24em; text-transform: uppercase; opacity: .55; }
.still-cat-row {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 16px 0; border-bottom: 1px solid var(--hair);
  font-size: 11.5px; font-weight: 600; letter-spacing: .34em; text-transform: uppercase;
  transition: padding-left .4s cubic-bezier(.22,.61,.36,1);
}
.still-cat-row:first-child { border-top: 1px solid var(--hair); }
.still-cat-row:hover { padding-left: 14px; }

/* film / flight */
.film-frame { aspect-ratio: 16 / 9; max-width: 980px; background: var(--black); color: var(--paper);
  display: flex; align-items: center; justify-content: center; }
.film-frame span { font-size: 9px; letter-spacing: .34em; text-transform: uppercase; opacity: .5; }
.film-frame.ultra-wide { aspect-ratio: 21 / 9; max-width: none; }
.placeholder-inline { max-width: 56ch; margin-top: 16px; font-size: 12.5px; line-height: 1.7; opacity: .55; font-style: italic; }
.placeholder-frame { border: 1px solid var(--hair); max-width: 760px; aspect-ratio: 16 / 6;
  display: flex; align-items: center; justify-content: center; text-align: center; margin-bottom: 26px; }
.placeholder-frame.wide { max-width: none; aspect-ratio: 21 / 6; }
.placeholder-note { font-size: 10px; letter-spacing: .3em; text-transform: uppercase; opacity: .55; line-height: 2.1; }

/* about / contact */
.about-grid { display: grid; grid-template-columns: minmax(220px, 340px) 1fr; gap: clamp(26px, 4vw, 64px); align-items: start; }
.about-portrait img { filter: grayscale(1); }
.serif-lede { font-family: var(--sans); font-weight: 500; font-size: clamp(17px, 1.4vw, 21px); line-height: 1.55; max-width: 30em; }
.about-body { margin-top: 20px; max-width: 52ch; font-size: 14px; line-height: 1.75; opacity: .82; }
.about-meta { margin-top: 26px; font-size: 10px; letter-spacing: .3em; text-transform: uppercase; opacity: .6; line-height: 2.2; }
.contact-list { max-width: 720px; }
.contact-row { display: grid; grid-template-columns: 140px 1fr; gap: 18px; align-items: baseline;
  padding: 15px 0; border-bottom: 1px solid var(--hair); }
.contact-row:first-child { border-top: 1px solid var(--hair); }
.contact-label { font-size: 9.5px; font-weight: 600; letter-spacing: .3em; text-transform: uppercase; opacity: .55; }
.contact-value { font-family: var(--serif); font-size: 17px; }
.contact-value a:hover { color: var(--red); }

/* ============================================================
   PHOTOGRAPHIC ALBUM — series spreads, three compositions, horizontal paging
   ============================================================ */
@media (min-width: 901px) {
  body.album-page { overflow: hidden; height: 100vh; }
}
.catwrap { position: relative; }

/* stage sits below the fixed 2-row header, fills the rest of the viewport */
.album-stage {
  position: fixed; left: 0; right: 0; bottom: 0; top: var(--header-h-album);
  overflow: hidden; background: var(--paper);
}
/* single-series categories (Portrait, …) hide the series row entirely —
   don't leave its reserved space empty above the photograph */
body.album-page:has(.series-nav[hidden]) .album-stage { top: var(--header-h-open); }
.album-track { display: flex; height: 100%;
  transition: transform .7s cubic-bezier(.22,.61,.36,1), opacity .3s ease; }
.album-stage.fading .album-track { opacity: 0; }

.spread {
  flex: 0 0 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(14px, 3vh, 34px) clamp(72px, 9vw, 150px)
           clamp(74px, 10vh, 116px) var(--margin-w);
  /* room the imagery may occupy (bottom HUD + caption already deducted) */
  --album-h: calc(100vh - var(--header-h-album) - clamp(140px, 19vh, 210px));
  --stage-w: calc(100vw - var(--margin-w) - clamp(72px, 9vw, 150px));
}
/* figure = imagery + its OWN caption, right under that photo — no shared
   spread-level category/series summary, so every picture says what it is */
.spread-inner {
  display: flex; flex-direction: column; align-items: flex-start;
  max-width: 100%; max-height: 100%; min-height: 0;
}
.spread-imgs {
  display: flex; align-items: flex-start; justify-content: center;
  gap: clamp(16px, 2.2vw, 40px); min-height: 0; max-width: 100%;
}
.spread .ph {
  margin: 0; min-height: 0; min-width: 0; cursor: zoom-in;
  display: flex; flex-direction: column; gap: 6px;
}
.spread .ph-frame { overflow: hidden; min-height: 0; }
.spread .ph picture { display: block; width: 100%; height: 100%; }
.spread .ph img {
  display: block; width: 100%; height: 100%;
  object-fit: contain; object-position: center;
  transition: opacity .4s ease;
}
.spread .ph:hover img { opacity: .93; }
.ph-cap {
  display: flex; flex-direction: column; gap: 2px;
  max-width: 100%; font-weight: 500; text-transform: uppercase;
}
.ph-cap-title {
  font-size: 9px; letter-spacing: .2em; color: var(--ink); opacity: .82;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ph-cap-meta {
  font-size: 8.5px; letter-spacing: .18em; opacity: .55;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* A — one dominant photograph. Box ratio matches the photo (no letterboxing). */
.spread--a .ph { width: min(calc(var(--stage-w) * .82), calc(var(--album-h) * var(--ar))); }
.spread--a .ph-frame { aspect-ratio: var(--ar); }
/* B — two complementary photographs, sized by their own aspect ratios */
.spread--b .ph { width: min(calc(var(--stage-w) * .46), calc(var(--album-h) * var(--ar))); }
.spread--b .ph-frame { aspect-ratio: var(--ar); }
/* C — hero (fills exactly) + two stacked supporting frames, roughly equal height */
.spread--c .spread-imgs {
  --c-side: clamp(210px, 28vw, 360px);
  --c-gap: clamp(18px, 2.4vw, 44px);
  --c-h: max(200px, min(var(--album-h),
    calc((var(--stage-w) - var(--c-gap) - var(--c-side)) / var(--ar))));
  align-items: flex-start;
  gap: var(--c-gap);
}
.spread--c .sp-main { width: calc(var(--c-h) * var(--ar)); }
.spread--c .sp-main .ph-frame { width: 100%; height: var(--c-h); }
.spread--c .sp-side {
  display: flex; flex-direction: column; gap: clamp(10px, 1.4vw, 20px);
  width: var(--c-side); min-height: 0;
}
.spread--c .sp-side .ph-frame {
  width: 100%; height: calc((var(--c-h) - clamp(10px, 1.4vw, 20px) - 2 * 24px) / 2);
}
.spread--c .sp-side .ph img { object-fit: cover; }   /* supporting frames may crop lightly */

/* LEVEL 3 — SERIES row, third header row on album pages. Indented to start
   under STREET (the word), not under 01 (the number) — this row is series
   *within* the category above, and the indent says so. Active word black,
   others grey; no dot, no number, no underline, no box. */
.series-nav {
  flex-basis: 100%; order: 4;
  display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-start;
  margin-top: clamp(10px, 1.6vh, 16px);
  padding-bottom: clamp(8px, 1.4vh, 16px);
  padding-left: clamp(24px, 2.4vw, 32px);   /* ≈ width of "01 " in the row above */
}
/* categories with only one series (Portrait, single-shoot Landscape series, …)
   must not keep showing a leftover series list from whatever category was
   open before a client-side swap — [hidden] has to actually win here */
.series-nav[hidden] { display: none; }
.series-link {
  padding: 8px 6px;
  font-size: clamp(8px, .74vw, 9.5px); letter-spacing: .22em;
  color: var(--nav-grey);
  transition: color .25s ease;
}
.series-link.is-active { color: var(--ink); font-weight: 600; }
.series-link:not(.is-active):hover { color: var(--nav-grey-hover); }
.series-vsep {
  display: inline-block; flex: none; align-self: center;
  width: 1px; height: 7px;                 /* matches the series row's smaller cap-height */
  background: var(--sep);
  margin: 0 8px;
}

/* ============ album HUD — paging only ============ */
.hud-cap { display: none; }   /* desktop uses the per-spread <figcaption> */
.stage-ui {
  position: fixed; z-index: 9;
  right: clamp(16px, 2.4vw, 40px); bottom: clamp(18px, 3vh, 36px);
  display: flex; align-items: center; gap: clamp(6px, 1.2vw, 16px);
}
.sp-nav {
  position: relative; background: none; border: 0; cursor: pointer; color: var(--ink);
  font: inherit; padding: 15px 18px;
  font-size: 9px; font-weight: 500; letter-spacing: .28em; text-transform: uppercase;
  opacity: .7; transition: opacity .3s ease;
  display: inline-flex; align-items: center;
}
.sp-nav:hover:not([disabled]) { opacity: 1; }
.sp-nav[disabled] { opacity: .16; cursor: default; }
.sp-nav::after {
  content: ""; flex: none; width: 5px; height: 5px; border-radius: 50%;
  background: var(--red); margin-left: .7em;
  opacity: 0; transform: scale(.35); transition: opacity .3s ease, transform .3s ease;
}
.sp-nav:hover:not([disabled])::after { opacity: 1; transform: scale(1); }
.sp-progress { font-size: 9px; letter-spacing: .3em; opacity: .6; min-width: 52px; text-align: center; }

/* ============ lightbox ============ */
.lightbox {
  position: fixed; inset: 0; z-index: 60;
  background: var(--black); color: var(--paper);
  display: none; align-items: center; justify-content: center;
}
.lightbox.open { display: flex; }
.lightbox img { max-width: 92vw; max-height: 86vh; width: auto; height: auto; }
.lightbox figcaption {
  position: absolute; left: clamp(18px, 3vw, 44px); bottom: clamp(16px, 2.6vw, 34px);
  font-size: 9.5px; letter-spacing: .28em; text-transform: uppercase; opacity: .8;
}
.lightbox .lb-cap2 { display: block; margin-top: 6px; opacity: .6; letter-spacing: .22em; font-size: 8.5px; }
.lightbox .print-link {
  position: absolute; right: clamp(18px, 3vw, 44px); bottom: clamp(16px, 2.6vw, 34px);
  color: inherit; font-size: 9px; letter-spacing: .28em; text-transform: uppercase;
}
.lightbox .print-link:hover { color: var(--red); }
.lightbox.light { background: var(--paper); color: var(--ink); }
.lb-count {
  position: absolute; top: clamp(16px, 2.4vw, 30px); right: clamp(18px, 3vw, 44px);
  font-size: 9.5px; letter-spacing: .3em; opacity: .55;
}
.lb-close {
  position: absolute; top: clamp(12px, 2vw, 24px); left: clamp(14px, 2.2vw, 34px);
  background: none; border: 0; color: inherit; cursor: pointer;
  font-size: 9.5px; letter-spacing: .3em; text-transform: uppercase; opacity: .6; padding: 10px;
}
.lb-close:hover { opacity: 1; }
.lb-arrow {
  position: absolute; top: 50%; transform: translateY(-50%);
  background: none; border: 0; cursor: pointer; color: inherit;
  font-size: 26px; font-weight: 200; opacity: .45; padding: 24px 18px; line-height: 1;
  transition: opacity .3s ease;
}
.lb-arrow:hover, .lb-arrow:focus-visible { opacity: 1; }
.lb-prev { left: 6px; } .lb-next { right: 6px; }
.lightbox.idle .lb-arrow, .lightbox.idle .lb-close, .lightbox.idle .lb-count,
.lightbox.idle .print-link { opacity: 0; }

/* ============ responsive ============ */
@media (max-width: 900px) {
  :root { --m-brand-h: calc(58px + env(safe-area-inset-top, 0px)); }
  body { padding-top: var(--m-brand-h); }

  /* compact horizontal identity, fixed at the very top — the full logo
     square (circle + red dot) stays intact, only the bar itself compacts */
  .brand-col {
    position: fixed; top: 0; left: 0; z-index: 30;
    width: 100%; height: var(--m-brand-h);
    background: var(--paper); pointer-events: auto;
  }
  .brand-col .lp-identity {
    flex-direction: row; align-items: center; gap: 10px;
    padding: env(safe-area-inset-top, 0px) max(18px, env(safe-area-inset-right, 0px)) 0 max(18px, env(safe-area-inset-left, 0px));
    height: 100%;
  }
  .brand-col .logo-tile { width: 40px; flex: none; }
  .brand-col .logo-words { display: none; }
  .brand-col .vertical-name {
    writing-mode: horizontal-tb; transform: none; margin: 0;
    font-size: 11px; letter-spacing: .3em;
  }

  /* header: STILLS·FILM·FLIGHT and INDEX·ABOUT·CONTACT share row 1 (utility
     shrunk down and pulled up close, like desktop) so there's no separate
     row that can appear/disappear and jolt the layout on album pages —
     cats and series still get their own full-width rows below */
  .site-header {
    position: sticky; top: var(--m-brand-h); z-index: 20;
    display: flex; flex-wrap: wrap; align-items: center;
    column-gap: 6px; row-gap: 4px;
    padding: 6px 14px 5px; min-height: 0;
  }
  body.album-page .site-header { position: fixed; top: var(--m-brand-h); }
  .nav-primary { padding-left: 0; }
  .nav-utility { margin-left: auto; gap: 5px; }
  .nav-vsep { height: 11px; margin: 0 5px; }
  .main-link::after { width: 8px; height: 8px; margin-left: 6px; }
  .nav-cats {
    flex-basis: 100%; order: 3; align-self: stretch;
    flex-wrap: nowrap; justify-content: flex-start;
    max-height: none; opacity: 1; overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
    scrollbar-width: none; gap: 8px; padding-left: 0;
    padding-bottom: 0;   /* the desktop reveal-open padding-bottom doesn't apply here — row is always visible */
  }
  .nav-cats::-webkit-scrollbar { display: none; }
  .cat-link { padding: 7px 4px; gap: 5px; scroll-snap-align: start; }
  /* on an album page the utility row isn't needed while browsing photos —
     it now lives inline on row 1, so hiding it only frees its own width,
     never a whole row, so nothing else shifts or "collapses" */
  body.album-page .nav-utility { display: none; }
  .series-nav {
    flex-basis: 100%; order: 4; align-self: stretch;
    flex-wrap: nowrap; justify-content: flex-start;
    overflow-x: auto; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity;
    scrollbar-width: none;
    margin-top: 10px; padding-left: 20px;
  }
  .series-nav::-webkit-scrollbar { display: none; }
  .series-link { flex: 0 0 auto; padding: 10px 6px; font-size: 8.5px; scroll-snap-align: start; }
  .series-vsep { height: 6px; margin: 0 6px; }
  .main-link { font-size: clamp(12px, 3.2vw, 15px); padding: 8px 2px; letter-spacing: .06em; }
  /* utility shrinks noticeably to make room alongside the primary words */
  .support-link { padding: 8px 2px; font-size: 7.5px; letter-spacing: .05em; }
  .support-link, .main-link, .cat-link, .series-link, .sp-nav { min-height: 48px; }

  .lp-portrait { margin: 0; }
  .lp-portrait img { height: auto; max-height: 62vh; transform: none; object-position: 38% 8%; }
  .idx-row { grid-template-columns: 1fr 80px; }
  .idx-loc { display: none; }
  .about-grid { grid-template-columns: 1fr; }

  /* content pages: no reserved brand column on mobile */
  .page {
    padding: 14px 16px 48px; min-height: 0;
  }
  /* homepage on mobile: same stacked header as every other page, portrait below */
  .site-home .site-header {
    position: sticky; top: var(--m-brand-h); background: var(--paper);
    padding: 2px 14px 5px;
  }
  .site-home .nav-primary, .site-home .nav-utility, .site-home .nav-cats { padding-left: 0; }
  .page-home { display: block; min-height: 0; grid-template-columns: none; }
  .page-home .lp-portrait { height: auto; min-height: 0; margin-bottom: 14px; }
  /* desktop's home-stage is a 100vh flex column so the wall can stretch
     flush to the portrait's bottom edge — mobile stacks everything in
     normal flow instead, so undo both */
  .page-home .home-stage { display: block; height: auto; padding: 4px 16px 8px; }
  .home-stage { padding: 4px 16px 8px; }
  /* smaller viewport, tighter but still deliberate gaps; aspect-ratio
     sizing instead of the desktop's fixed --wall-top-h/--wall-bottom-h —
     a fixed height at this width would over-crop the bottom pair. Also
     reset the desktop's flex-grow:_ 1 0 (flex-basis:0) on the two rows —
     home-wall has no definite height here (home-stage is auto/block on
     mobile), and a flex-basis:0 child in an auto-height flex column
     collapses to zero height with nothing to grow into, which silently
     overlapped every photo on top of the next */
  .home-wall { gap: 20px; }
  .wall-top { flex: none; }
  .wall-top .ph { height: auto; aspect-ratio: 3 / 2; }
  .wall-bottom { flex: none; gap: 12px; }
  .wall-bottom .frame { flex: 1 1 0; min-width: 0; }
  .wall-bottom .ph { height: auto; aspect-ratio: 2 / 3; }

  /* ---- album on mobile: one photograph per page, horizontal swipe ---- */
  body.album-page { overflow: hidden; height: 100vh; }
  .album-stage {
    position: fixed; left: 0; right: 0;
    top: calc(var(--m-brand-h) + 198px);
    bottom: calc(110px + env(safe-area-inset-bottom, 0px));
  }
  /* single-series categories hide the series row — reclaim its space too */
  body.album-page:has(.series-nav[hidden]) .album-stage {
    top: calc(var(--m-brand-h) + 124px);
  }
  .album-track { height: 100%; display: flex; }
  body.album-page .spread,
  body.album-page .spread-inner,
  body.album-page .spread-imgs,
  body.album-page .spread--c .sp-side,
  body.album-page .ph-frame { display: contents; }
  .spread-cap, .ph-cap { display: none; }   /* mobile already shows a per-photo caption in .hud-cap */
  .album-track .ph {
    flex: 0 0 100%; width: 100%; height: 100%;
    display: flex; align-items: center; justify-content: center;
    margin: 0; padding: 6px 16px; overflow: hidden;
  }
  .album-track .ph picture {
    display: flex; align-items: center; justify-content: center;
    width: 100%; height: 100%;
  }
  .album-track .ph img {
    width: auto; height: auto; max-width: 100%; max-height: 100%; object-fit: contain;
  }

  /* bottom HUD — kept off the screen edges and clear of the Home indicator */
  .album-hud {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 9;
    display: flex; flex-direction: column; gap: 8px;
    padding: 10px max(20px, env(safe-area-inset-right, 0px)) max(20px, env(safe-area-inset-bottom, 0px)) max(20px, env(safe-area-inset-left, 0px));
    background: var(--paper);
  }
  .hud-cap {
    display: flex; flex-direction: column; gap: 2px;
    font-size: 8.5px; font-weight: 500; letter-spacing: .24em; text-transform: uppercase;
  }
  .hud-cap span:first-child { font-weight: 600; letter-spacing: .28em; }
  .hud-cap span:last-child { opacity: .55; }
  .stage-ui {
    position: static; right: auto; bottom: auto;
    justify-content: space-between; gap: 8px;
  }
  .sp-nav { padding: 15px 12px; }
}

/* phone in landscape — very little viewport height to work with, so the
   header compacts hard: identity shrinks, utility hides everywhere (not just
   albums), and every row's vertical padding tightens. Touch targets ease
   below 48px here deliberately — the alternative is a photo with no visible
   height at all, which serves no one. */
@media (max-width: 900px) and (max-height: 500px) {
  :root { --m-brand-h: calc(38px + env(safe-area-inset-top, 0px)); }
  .brand-col .logo-tile { width: 26px; }
  .brand-col .vertical-name { font-size: 9.5px; }
  .nav-utility { display: none; }
  .main-link { min-height: 34px; padding: 3px 4px; }
  .nav-vsep { height: 10px; }
  .cat-link { min-height: 34px; padding: 3px 4px; }
  .series-nav { margin-top: 4px; }
  .series-link { min-height: 0; padding: 4px 4px; }
  .album-stage {
    top: calc(var(--m-brand-h) + 128px) !important;
    bottom: calc(48px + env(safe-area-inset-bottom, 0px)) !important;
  }
  body.album-page:has(.series-nav[hidden]) .album-stage {
    top: calc(var(--m-brand-h) + 78px) !important;
  }
  .album-hud { padding: 4px max(16px, env(safe-area-inset-right, 0px)) max(10px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px)); gap: 2px; }
  .hud-cap { display: none; }   /* caption gives way to the photo when height is this tight */
  .sp-nav { padding: 8px 10px; min-height: 34px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
  html { scroll-behavior: auto; }
  .home-wall .frame { opacity: 1; }
}

@media print {
  .brand-col, .site-header, .lb-arrow, .lb-close, .stage-ui, .series-nav { display: none !important; }
  .page { padding: 0; }
}
