/* ============================================================
   LEMIR — Built for the drop.
   Void black. Bone. Sodium for the quiet. Magenta only where it acts.
   ============================================================ */

:root{
  --void:#050505;
  --bone:#EDEAE4;
  --sodium:#C8763A;
  --laser:#FF2D75;
  --bone-dim:rgba(237,234,228,.42);
  --bone-faint:rgba(237,234,228,.14);
  --hair:rgba(237,234,228,.13);

  --serif:"Cormorant Garamond",Georgia,serif;
  --grot:"Inter",system-ui,-apple-system,"Segoe UI",sans-serif;

  --gut:clamp(20px,5vw,84px);
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}

html{background:var(--void)}

/* ---- Lenis requires the viewport to stay the scroll container ---- */
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-stopped{overflow:hidden}
.lenis.lenis-smooth iframe{pointer-events:none}

body{
  margin:0;
  background:var(--void);
  color:var(--bone);
  font-family:var(--grot);
  font-weight:300;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  /* MUST be `clip`, not `hidden`: `overflow-x:hidden` makes the browser
     compute `overflow-y:auto`, which turns <body> into the scroll container.
     Lenis then writes scroll to the window and the wheel does nothing.
     `clip` suppresses horizontal overflow without creating a scroller. */
  overflow-x:clip;
}

/* scroll is locked until every frame is decoded */
body.is-locked{overflow:hidden;height:100vh}

img,video,canvas{display:block;max-width:100%}

::selection{background:var(--laser);color:var(--void)}

/* ---------- shared type ---------- */
.overline{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  font-weight:400;
  letter-spacing:.42em;
  text-transform:uppercase;
  color:var(--bone-dim);
  margin:0;
}

.accent-link{
  color:var(--laser);
  text-decoration:none;
  border-bottom:1px solid transparent;
  transition:border-color .5s var(--ease),opacity .5s var(--ease);
}
.accent-link:hover{border-bottom-color:var(--laser)}
.accent-link:focus-visible{outline:1px solid var(--laser);outline-offset:6px}

/* ============================================================
   LOADER
   ============================================================ */
.loader{
  position:fixed;inset:0;z-index:120;
  background:var(--void);
  display:flex;align-items:center;justify-content:center;
  transition:opacity 1.1s var(--ease),visibility 1.1s;
}
.loader.is-done{opacity:0;visibility:hidden;pointer-events:none}

.loader__inner{width:min(420px,72vw);text-align:center}

.loader__label{
  font-family:var(--grot);
  font-size:10px;letter-spacing:.62em;text-transform:uppercase;
  color:var(--bone-dim);margin:0 0 28px;padding-left:.62em;
}

/* the level meter: one hairline that fills */
.loader__meter{
  position:relative;height:1px;width:100%;
  background:var(--bone-faint);overflow:hidden;
}
.loader__fill{
  position:absolute;inset:0 auto 0 0;width:0%;
  background:var(--sodium);
  transition:width .25s linear;
}
.loader__pct{
  font-family:var(--grot);
  font-size:10px;letter-spacing:.3em;
  color:var(--bone-dim);
  margin:18px 0 0;
  font-variant-numeric:tabular-nums;
}

/* ============================================================
   SCRUB CHAPTERS
   ============================================================ */
.chapter{position:relative;width:100%}

.chapter__sticky{
  position:sticky;top:0;
  height:100vh;height:100svh;
  width:100%;overflow:hidden;
  background:var(--void);
}

.chapter__canvas{
  position:absolute;inset:0;
  width:100%;height:100%;
  opacity:0;
  transition:opacity .9s var(--ease);
}
.chapter__canvas.is-ready{opacity:1}

/* mobile / reduced-motion fallback */
.chapter__video{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  display:none;
}

.chapter__vignette{
  position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 min(30vw,320px) min(6vw,70px) rgba(5,5,5,.92);
}

/* ---------- hero type ---------- */
.hero__type{
  position:absolute;inset:0;
  display:flex;flex-direction:column;
  align-items:center;justify-content:center;
  text-align:center;pointer-events:none;
  padding:0 var(--gut);
}

.hero__word{
  font-family:var(--serif);
  font-weight:300;
  /* sized for the 8-character "DJ LEMIR" at max tracking without wrapping */
  font-size:clamp(30px,10vw,176px);
  line-height:.9;
  margin:0;
  color:var(--bone);
  white-space:nowrap;
  letter-spacing:.02em;   /* animated out by JS */
  opacity:0;              /* animated in by JS */
  will-change:letter-spacing,opacity;
}

/* the genre/location line sits over the lit part of the film, so it needs
   real weight and contrast — this was illegible at caption size */
.hero__sub{
  display:flex;
  align-items:center;
  justify-content:center;
  flex-wrap:wrap;
  gap:.2em;
  font-family:var(--grot);
  font-size:clamp(11px,1.05vw,15px);
  font-weight:400;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--bone);
  margin:clamp(24px,3.2vw,46px) 0 0;
  text-shadow:0 1px 26px rgba(5,5,5,.95),0 0 8px rgba(5,5,5,.8);
  opacity:0;
  transform:translateY(10px);
  transition:opacity 1.6s var(--ease) .3s,transform 1.6s var(--ease) .3s;
}
.hero__sub.is-in{opacity:1;transform:none}
.hero__sub-sep{color:var(--sodium);margin:0 .55em;font-weight:300}

.scroll-cue{
  position:absolute;left:50%;bottom:clamp(22px,4vh,46px);
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:12px;
  opacity:0;transition:opacity 1s var(--ease);
}
.scroll-cue.is-in{opacity:1}
.scroll-cue__label{
  font-size:9px;letter-spacing:.44em;color:var(--bone-dim);padding-left:.44em;
}
.scroll-cue__line{
  width:1px;height:clamp(28px,5vh,54px);
  background:linear-gradient(to bottom,var(--bone-faint),transparent);
}

/* ============================================================
   INTRO — pressure.mp4 plays through once, then cross-fades
   out to reveal the hero title over the scrub canvas
   ============================================================ */
.intro{
  position:fixed;inset:0;z-index:110;
  background:var(--void);
  opacity:1;
  transition:opacity 1.1s var(--ease);
}
.intro.is-done{opacity:0;pointer-events:none}

.intro__video{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
}

.intro__skip{
  position:absolute;
  right:var(--gut);bottom:clamp(22px,4vh,44px);
  appearance:none;background:transparent;
  border:0;border-bottom:1px solid var(--bone-faint);
  color:var(--bone-dim);
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  font-weight:400;
  letter-spacing:.36em;
  padding:0 0 6px;
  cursor:pointer;
  text-shadow:0 1px 20px rgba(5,5,5,.9);
  transition:color .45s var(--ease),border-color .45s var(--ease);
}
.intro__skip:hover{color:var(--bone);border-bottom-color:var(--bone)}
.intro__skip:focus-visible{outline:1px solid var(--laser);outline-offset:6px}

/* ============================================================
   NAV — fixed, minimal, never competes with the film
   ============================================================ */
.nav{
  position:fixed;top:0;right:0;z-index:90;
  display:flex;align-items:center;
  gap:clamp(16px,2.4vw,38px);
  padding:clamp(18px,2.4vw,36px) var(--gut);
  opacity:0;
  transition:opacity 1.2s var(--ease);
  pointer-events:none;
}
.nav.is-in{opacity:1;pointer-events:auto}

.nav__link{
  font-family:var(--grot);
  font-size:clamp(9px,.74vw,11px);
  font-weight:400;
  letter-spacing:.32em;
  text-transform:uppercase;
  color:var(--bone);
  text-decoration:none;
  white-space:nowrap;
  padding-bottom:5px;
  border-bottom:1px solid transparent;
  text-shadow:0 1px 20px rgba(5,5,5,.9);
  transition:border-color .45s var(--ease),color .45s var(--ease);
}
.nav__link:hover{border-bottom-color:currentColor}
.nav__link:focus-visible{outline:1px solid var(--laser);outline-offset:6px}
.nav__link--accent{color:var(--laser)}

/* ============================================================
   MACRO caption
   ============================================================ */
.macro__caption{
  position:absolute;left:var(--gut);bottom:clamp(26px,5vh,58px);
  margin:0;opacity:0;
  transition:opacity 1.1s var(--ease);
  pointer-events:none;
}
.macro__caption.is-in{opacity:1}

/* ============================================================
   PANELS — mixes / dates / booking
   ============================================================ */
.panel{
  position:relative;
  padding:clamp(110px,17vh,220px) var(--gut);
  background:var(--void);
}

.panel__head{margin-bottom:clamp(52px,7vw,110px)}
.panel__head .overline{padding-left:.42em;margin-bottom:clamp(16px,2vw,28px)}

.panel__title{
  font-family:var(--serif);
  font-weight:300;
  font-size:clamp(38px,7.6vw,124px);
  line-height:1.02;
  letter-spacing:-.01em;
  margin:0;
  color:var(--bone);
}
.panel__title em{font-style:italic;color:var(--bone-dim)}

/* ---------- mixes index ---------- */
.index{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}
.index__row{border-bottom:1px solid var(--hair)}

.index__link{
  display:grid;
  grid-template-columns:auto minmax(0,1.05fr) minmax(0,1.35fr) auto;
  align-items:baseline;
  gap:clamp(16px,3vw,52px);
  padding:clamp(24px,3.4vw,46px) 0;
  text-decoration:none;color:inherit;
  transition:opacity .55s var(--ease);
}
.index__row:hover .index__link{opacity:1}
.index:hover .index__link{opacity:.4}
.index__link:focus-visible{outline:1px solid var(--laser);outline-offset:4px}

.index__glyph{
  color:var(--bone-faint);
  display:flex;align-items:center;
  transform:translateY(-.12em);
  transition:color .5s var(--ease),transform .5s var(--ease);
}
.index__link:hover .index__glyph,
.index__link:focus-visible .index__glyph{
  color:var(--laser);transform:translate(4px,-.12em);
}

.index__title{
  font-family:var(--serif);
  font-size:clamp(24px,3.6vw,58px);
  font-weight:300;line-height:1;
  letter-spacing:.005em;
}

.index__desc{
  font-family:var(--grot);
  font-size:clamp(11px,1vw,14px);
  font-weight:300;line-height:1.6;
  color:var(--bone-dim);
}

.index__year{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.3em;
  color:var(--bone-dim);
  font-variant-numeric:tabular-nums;
  justify-self:end;
}

/* ---------- dates ---------- */
.dates{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}

.dates__row{
  display:grid;
  grid-template-columns:minmax(0,.85fr) minmax(0,1.5fr) minmax(0,.5fr);
  align-items:center;
  gap:clamp(14px,3vw,48px);
  padding:clamp(22px,3.2vw,42px) 0;
  border-bottom:1px solid var(--hair);
}

.dates__row.is-unavailable{opacity:.4}

/* Shown in place of the list when there are no dates, or the database is
   unreachable. Deliberately quiet: a missing schedule is not an error page. */
.dates__note{
  font-family:var(--serif);
  font-size:clamp(18px,2vw,24px);
  font-weight:300;
  color:var(--bone-faint);
  margin:0;
}

.dates__date{
  font-family:var(--grot);
  font-size:clamp(10px,.85vw,12px);
  letter-spacing:.28em;
  color:var(--bone-dim);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}
.dates__day{
  font-family:var(--serif);
  font-size:clamp(22px,2.9vw,44px);
  letter-spacing:0;
  color:var(--bone);
  margin-right:.4em;
}

.dates__venue{
  display:flex;flex-direction:column;gap:6px;
  text-align:center;
}
.dates__place{
  font-family:var(--serif);
  font-size:clamp(17px,2.1vw,34px);
  font-weight:300;line-height:1.1;
  color:var(--bone);
}
.dates__city{
  font-family:var(--grot);
  font-size:clamp(9px,.7vw,10.5px);
  letter-spacing:.34em;text-transform:uppercase;
  color:var(--bone-dim);
}

.dates__action{justify-self:end;text-align:right}
.dates__action a{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.34em;
  color:var(--laser);
  text-decoration:none;
  border-bottom:1px solid transparent;
  padding-bottom:3px;
  transition:border-color .5s var(--ease);
  white-space:nowrap;
}
.dates__action a:hover{border-bottom-color:var(--laser)}
.dates__action a:focus-visible{outline:1px solid var(--laser);outline-offset:5px}

.dates__struck{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.34em;
  color:var(--bone-dim);
  text-decoration:line-through;
  text-decoration-thickness:1px;
  white-space:nowrap;
}

/* ---------- booking ---------- */
.panel--booking{padding-bottom:clamp(60px,9vh,110px)}

.booking__title{
  font-family:var(--serif);
  font-weight:300;
  /* Two steps down from clamp(46px,11.5vw,200px). All three values drop by
     the same ratio so it shrinks consistently, rather than only on the
     widest screens. */
  font-size:clamp(36px,9vw,156px);
  line-height:.96;
  letter-spacing:-.015em;
  margin:0 0 clamp(20px,3vw,42px);
  color:var(--bone);
}
.booking__title em{font-style:italic}

.booking__mail{
  font-family:var(--grot);
  font-size:clamp(12px,1.25vw,17px);
  letter-spacing:.16em;
  /* Was up to 130px. The heading, this line and the whole form have to share
     one screen once BOOKING scrolls here, and this gap was the loosest thing
     in the block -- it read as a hole rather than as breathing room. */
  margin:0 0 clamp(40px,5vw,72px);
}

/* form — hairlines only, no boxes */
/* Was up to 130px, which left the submit button stranded a long way above the
   social row. The 40px below the button is the status line's reserved space,
   held open so the layout does not jump when a message appears. */
.form{max-width:1000px;margin:0 0 clamp(28px,3vw,48px)}
.form__grid{
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(26px,3.6vw,56px);
}
.field{display:flex;flex-direction:column}
.field--wide{grid-column:1/-1}

.field label{
  font-family:var(--grot);
  font-size:9.5px;letter-spacing:.4em;text-transform:uppercase;
  color:var(--bone-dim);margin-bottom:14px;padding-left:.4em;
}

.field input,.field textarea,.field select{
  appearance:none;
  background:transparent;
  border:0;border-bottom:1px solid var(--hair);
  border-radius:0;
  color:var(--bone);
  font-family:var(--serif);
  font-size:clamp(16px,1.6vw,24px);
  font-weight:300;
  padding:0 0 12px;
  resize:none;
  transition:border-color .5s var(--ease);
}
.field input:focus,.field textarea:focus,.field select:focus{
  outline:none;border-bottom-color:var(--sodium);
}
.field input::placeholder,.field textarea::placeholder{color:var(--bone-faint)}

/* date input on a dark canvas */
.field input[type="date"]{color-scheme:dark}

/* ---- event dropdown ----
   appearance:none strips the native arrow, so one is drawn back in as an
   inline SVG. color-scheme keeps the popup list dark, and the explicit
   option colours cover Windows, which ignores color-scheme for options. */
.field select{
  color-scheme:dark;
  cursor:pointer;
  padding-right:28px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23EDEAE4' stroke-width='1.2' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right .15em center;
  background-size:12px 8px;
}
.field select option{background:#0b0b0b;color:var(--bone)}
/* the disabled placeholder should read as a prompt, not as a chosen value */
.field select:invalid{color:var(--bone-faint)}

.field.has-error input,.field.has-error textarea,.field.has-error select{
  border-bottom-color:var(--laser);
}

/* Spam trap: off-canvas rather than display:none, which some bots skip. */
.form__trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.field__err{
  font-family:var(--grot);
  font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;
  color:var(--laser);
  margin-top:10px;min-height:12px;
  opacity:0;transition:opacity .35s var(--ease);
}
.field.has-error .field__err{opacity:1}

.form__submit{
  appearance:none;
  margin-top:clamp(32px,3.8vw,52px);
  background:transparent;
  border:0;border-bottom:1px solid var(--bone-faint);
  color:var(--bone);
  font-family:var(--grot);
  font-size:clamp(10px,.8vw,12px);
  letter-spacing:.42em;
  padding:0 0 12px;
  cursor:pointer;
  transition:color .5s var(--ease),border-color .5s var(--ease),letter-spacing .5s var(--ease);
}
.form__submit:hover{color:var(--laser);border-bottom-color:var(--laser);letter-spacing:.5em}
.form__submit:focus-visible{outline:1px solid var(--laser);outline-offset:8px}

.form__status{
  font-family:var(--grot);
  font-size:10.5px;letter-spacing:.26em;text-transform:uppercase;
  color:var(--sodium);
  margin:26px 0 0;min-height:14px;
  opacity:0;transition:opacity .5s var(--ease);
}
.form__status.is-in{opacity:1}

.social{
  display:flex;flex-wrap:wrap;
  gap:clamp(24px,4vw,60px);
  padding-top:clamp(26px,3vw,40px);
  border-top:1px solid var(--hair);
}
.social a{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.4em;
}

/* Phone number, between the social row and the colophon.
   Deliberately larger and brighter than both: the links either side are
   9-11px in laser and bone-faint, so this is the one contact detail meant
   to be read at a glance. --bone is the palette's white; pure #fff would
   sit outside it. */
.social-phone{
  margin:clamp(26px,3.2vw,44px) 0 0;
}
.social-phone a{
  font-family:var(--grot);
  font-size:clamp(15px,1.5vw,21px);
  font-weight:300;
  letter-spacing:.18em;
  color:var(--bone);
  text-decoration:none;
  white-space:nowrap;
  border-bottom:1px solid transparent;
  transition:border-color .5s var(--ease),color .5s var(--ease);
}
.social-phone a:hover{border-bottom-color:var(--bone)}
.social-phone a:focus-visible{outline:1px solid var(--laser);outline-offset:6px}

.colophon{
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:14px;
  margin-top:clamp(70px,10vw,130px);
}
.colophon p{
  font-family:var(--grot);
  font-size:9.5px;letter-spacing:.26em;text-transform:uppercase;
  color:var(--bone-faint);
  margin:0;
}

/* ============================================================
   MOBILE / REDUCED MOTION — swap scrub for looping video
   ============================================================ */
body.is-fallback .chapter__canvas{display:none}
body.is-fallback .chapter__video{display:block}
body.is-fallback .chapter{height:auto !important}
body.is-fallback .chapter__sticky{position:relative}

@media (max-width:900px){
  .index__link{
    grid-template-columns:auto minmax(0,1fr) auto;
    row-gap:12px;
  }
  .index__desc{grid-column:2/-1}
  .dates__row{
    grid-template-columns:minmax(0,1fr) auto;
    row-gap:14px;
  }
  .dates__venue{text-align:left;grid-column:1/2}
  .dates__action{grid-column:2/3}
  .form__grid{grid-template-columns:minmax(0,1fr)}
}

@media (max-width:520px){
  .colophon{flex-direction:column}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
  .macro__caption,.hero__sub,.scroll-cue,.nav{opacity:1 !important;transform:none !important}
}

/* ============================================================
   GALLERY — /gallery.php
   A quiet room after the film. No canvas, no scrub, no lock:
   an ordinary scrolling page that borrows the same palette.
   ============================================================ */

/* ---- current page marker in the nav ---- */
.nav__link--current{border-bottom-color:var(--bone-faint)}

/* ---- wordmark: the way back to the film ---- */
.wordmark{
  position:fixed;top:0;left:0;z-index:90;
  padding:clamp(18px,2.4vw,36px) var(--gut);
  font-family:var(--grot);
  font-size:clamp(9px,.74vw,11px);
  font-weight:400;
  letter-spacing:.34em;
  text-transform:uppercase;
  color:var(--bone);
  text-decoration:none;
  white-space:nowrap;
  text-shadow:0 1px 20px rgba(5,5,5,.9);
  border-bottom:1px solid transparent;
  transition:color .45s var(--ease);
}
.wordmark:hover{color:var(--bone-dim)}
.wordmark:focus-visible{outline:1px solid var(--laser);outline-offset:6px}

/* ============================================================
   TRACKS — /tracks.php
   Same hairline list as the mixes index, but each row owns a
   transport control rather than a link.
   ============================================================ */
.tracks{list-style:none;margin:0;padding:0;border-top:1px solid var(--hair)}

.track{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto auto;
  align-items:center;
  gap:clamp(14px,2.4vw,34px);
  padding:clamp(18px,2.2vw,26px) 0;
  border-bottom:1px solid var(--hair);
}

.track__play{
  appearance:none;
  display:flex;align-items:center;justify-content:center;
  width:clamp(34px,3.4vw,44px);height:clamp(34px,3.4vw,44px);
  padding:0;
  background:transparent;
  border:1px solid var(--bone-faint);
  border-radius:50%;
  color:var(--bone);
  cursor:pointer;
  transition:border-color .4s var(--ease),color .4s var(--ease),background .4s var(--ease);
}
.track__play:hover{border-color:var(--bone);}
.track__play:focus-visible{outline:1px solid var(--laser);outline-offset:4px}
.track.is-playing .track__play{
  border-color:var(--laser);
  color:var(--laser);
}

/* The play triangle is optically light on its left edge inside a circle. */
.track__icon--play{margin-left:2px}
.track__icon--pause{display:none}
.track.is-playing .track__icon--play{display:none}
.track.is-playing .track__icon--pause{display:block}

.track__title{
  font-family:var(--serif);
  font-size:clamp(19px,2.3vw,34px);
  font-weight:300;
  color:var(--bone);
  min-width:0;
  overflow-wrap:anywhere;
}
.track.is-playing .track__title{color:var(--bone)}

.track__time{
  font-family:var(--grot);
  font-size:clamp(9px,.74vw,11px);
  letter-spacing:.24em;
  color:var(--bone-dim);
  font-variant-numeric:tabular-nums;
  white-space:nowrap;
}

.track__get{
  font-family:var(--grot);
  font-size:clamp(9px,.74vw,11px);
  letter-spacing:.32em;
  text-transform:uppercase;
  color:var(--laser);
  text-decoration:none;
  white-space:nowrap;
  border-bottom:1px solid transparent;
  transition:border-color .5s var(--ease);
}
.track__get:hover{border-bottom-color:var(--laser)}
.track__get:focus-visible{outline:1px solid var(--laser);outline-offset:6px}

@media (max-width:640px){
  /* Title on its own line; the transport and download stay on the first,
     which keeps the two tap targets far apart on a phone. */
  .track{grid-template-columns:auto 1fr auto;row-gap:10px}
  .track__title{grid-column:1/-1;grid-row:2}
}

/* ---- page shell ---- */
.gallery-page{
  padding:clamp(88px,11vh,150px) var(--gut) clamp(60px,9vh,110px);
  max-width:1680px;
  margin:0 auto;
}
.gallery__head{margin-bottom:clamp(44px,6vw,92px)}

/* ---- grid: two up, broken by full-width features ---- */
.gallery{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(14px,2.2vw,34px);
}
.gallery__item--wide{grid-column:1/-1}

/* A full-bleed 16:9 image is ~850px tall on a desktop and pushes its own
   subject under the fold — these three renders all carry their subject low,
   so the feature row is cropped to a cinematic band instead. Only above the
   one-column breakpoint: on mobile the item is already narrow and short. */
@media (min-width:901px){
  .gallery__item--wide .shot__btn img{
    aspect-ratio:21/9;
    object-position:center 58%;
  }
}

.shot{margin:0}

/* The reveal is opt-in: gallery.js adds `js-reveal` to the grid. With JS off
   the class never lands, so every shot stays visible instead of being stuck
   at opacity 0 waiting for an observer that will never fire. */
.gallery.js-reveal .shot{
  opacity:0;
  transform:translateY(18px);
  transition:opacity 1s var(--ease),transform 1s var(--ease);
}
.gallery.js-reveal .shot.is-in{opacity:1;transform:none}

.shot__btn{
  display:block;width:100%;
  padding:0;margin:0;
  border:1px solid var(--hair);
  background:#0a0a0a;
  cursor:zoom-in;
  overflow:hidden;
  position:relative;
  line-height:0;
}
.shot__btn img{
  width:100%;height:auto;
  aspect-ratio:16/9;
  object-fit:cover;
  filter:brightness(.88) saturate(.94);
  transform:scale(1.001);   /* pre-promote: kills the first-hover jitter */
  transition:transform 1.1s var(--ease),filter .7s var(--ease);
}
.shot__btn:hover img{transform:scale(1.035);filter:brightness(1) saturate(1)}
.shot__btn:focus-visible{outline:1px solid var(--laser);outline-offset:4px}

.shot__cap{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:16px;
  margin-top:clamp(10px,1.1vw,16px);
}
.shot__title{
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  font-weight:400;
  letter-spacing:.32em;
  text-transform:uppercase;
  color:var(--bone-dim);
  transition:color .5s var(--ease);
}
.shot:hover .shot__title{color:var(--bone)}
.shot__meta{
  font-family:var(--serif);
  font-size:clamp(12px,1vw,15px);
  font-style:italic;
  color:var(--bone-faint);
  white-space:nowrap;
}

/* ---- foot ---- */
.gallery__foot{
  margin-top:clamp(56px,8vw,120px);
  padding-top:clamp(28px,3.4vw,52px);
  border-top:1px solid var(--hair);
}
.gallery__foot-line{
  font-family:var(--serif);
  font-size:clamp(17px,2vw,26px);
  font-weight:300;
  color:var(--bone-dim);
  margin:clamp(12px,1.5vw,20px) 0 0;
}
.gallery__back{
  margin:clamp(26px,3vw,44px) 0 0;
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.32em;
  text-transform:uppercase;
}

/* ============================================================
   LIGHTBOX
   ============================================================ */
.lightbox{
  position:fixed;inset:0;z-index:200;
  display:flex;align-items:center;justify-content:center;
  background:rgba(5,5,5,.97);
  opacity:0;
  transition:opacity .5s var(--ease);
}
/* `hidden` must beat `display:flex` — without this the dialog stays laid out */
.lightbox[hidden]{display:none}
.lightbox.is-open{opacity:1}

body.is-lightbox-open{overflow:hidden}

.lightbox__stage{
  margin:0;
  display:flex;flex-direction:column;align-items:center;
  gap:clamp(14px,2vw,26px);
  max-width:94vw;
}
.lightbox__img{
  max-width:94vw;
  max-height:78vh;
  width:auto;height:auto;
  object-fit:contain;
  border:1px solid var(--hair);
}
.lightbox__cap{
  display:flex;align-items:baseline;gap:clamp(14px,2vw,28px);
  font-family:var(--grot);
  font-size:clamp(9px,.72vw,11px);
  letter-spacing:.32em;
  text-transform:uppercase;
}
.lightbox__title{color:var(--bone)}
.lightbox__count{color:var(--bone-dim);font-variant-numeric:tabular-nums}

.lightbox__close,
.lightbox__nav{
  position:absolute;
  background:none;border:1px solid transparent;
  color:var(--bone-dim);
  cursor:pointer;
  font-family:var(--grot);
  line-height:1;
  transition:color .4s var(--ease),border-color .4s var(--ease);
}
.lightbox__close:hover,
.lightbox__nav:hover{color:var(--laser)}
.lightbox__close:focus-visible,
.lightbox__nav:focus-visible{outline:1px solid var(--laser);outline-offset:4px}

.lightbox__close{
  top:clamp(14px,2.4vw,32px);right:clamp(14px,2.4vw,32px);
  font-size:34px;
  width:48px;height:48px;
}
.lightbox__nav{
  top:50%;transform:translateY(-50%);
  font-size:46px;
  width:56px;height:72px;
}
.lightbox__nav--prev{left:clamp(6px,1.6vw,26px)}
.lightbox__nav--next{right:clamp(6px,1.6vw,26px)}

/* ============================================================
   GALLERY — RESPONSIVE
   ============================================================ */
@media (max-width:900px){
  .gallery{grid-template-columns:minmax(0,1fr)}
  .gallery__item--wide{grid-column:auto}
  .nav{justify-content:flex-end}
}

/* ---- nav on a phone ----
   Five items have to share one line. Wrapping used to absorb the overflow,
   but it dropped CONTACT ME onto a row of its own, which reads as a fault
   rather than a layout. Nothing wraps now; the type and gaps tighten instead.
   left:0 lets the row use the full width — index.php is the only page with
   this nav, and it has no wordmark to collide with. */
@media (max-width:767px){
  .nav{
    left:0;
    flex-wrap:nowrap;
    justify-content:flex-end;
    gap:10px;
    padding-left:10px;
    padding-right:10px;
  }
  .nav__link{
    /* 9px is the desktop clamp's own floor, so the labels stay as legible as
       they get anywhere. Only the tracking gives ground. */
    font-size:9px;
    letter-spacing:.14em;
    padding-bottom:4px;
  }

  /* Same problem, same answer, in the footer: a fourth link tipped the row
     over and left ANGHAMI stranded on a line by itself. The tracking is the
     only thing that gives — the labels stay at their desktop size. */
  .social{gap:16px}
  .social a{letter-spacing:.2em}
}

/* Below ~360px the same five labels need one more notch. */
@media (max-width:360px){
  .nav{gap:8px}
  .nav__link{font-size:8px;letter-spacing:.08em}
  .social{gap:9px}
  .social a{letter-spacing:.1em}
}

@media (max-width:640px){
  .wordmark{letter-spacing:.24em;font-size:9px}
  .shot__meta{display:none}          /* the title carries it on small screens */
  .lightbox__nav{font-size:34px;width:42px;height:60px}
  .lightbox__img{max-height:66vh}
}

@media (prefers-reduced-motion:reduce){
  /* belt and braces: if the observer is skipped, nothing stays invisible */
  .gallery.js-reveal .shot{opacity:1 !important;transform:none !important}
  .shot__btn:hover img{transform:none}
}
