/* ==========================================================================
   nolanmillermedia.com — "Blackout"

   One rule, held everywhere: THE SITE HAS NO COLOR. THE WORK DOES.
   The page is black and white. Every pixel of hue comes from the photographs.
   There is deliberately no accent hue anywhere in this file.

   Second rule: work rests UNLIT and comes up on hover/focus. Browsing the
   site is bringing up light on things.
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------- */

:root {
  --black:      #000;
  --raise:      #0a0a0a;   /* raised surface, barely off-black */
  --line:       #1c1c1c;   /* hairline rules */
  --line-lit:   #383838;   /* hairline on hover */

  --white:      #fff;
  --grey-1:     #b4b4b4;   /* body copy */
  --grey-2:     #7a7a7a;   /* secondary meta */
  --grey-3:     #4e4e4e;   /* tertiary, index numerals */

  --display: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* A fader move: slow to start, decisive at the end. Used for every cue. */
  --cue: cubic-bezier(0.16, 1, 0.3, 1);

  --pad: clamp(1.25rem, 5vw, 5rem);   /* horizontal page gutter */
  --gap: clamp(5rem, 12vh, 11rem);    /* vertical section rhythm */
  --max: 1600px;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--black);
  color: var(--white);
  font-family: var(--display);
  font-weight: 500;
  line-height: 1.5;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { display: block; max-width: 100%; height: auto; }

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

h1, h2, h3, p, figure, ul { margin: 0; padding: 0; }
ul { list-style: none; }

::selection { background: var(--white); color: var(--black); }

:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 3px;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--white); color: var(--black);
  padding: .75rem 1.25rem; z-index: 200;
  font-family: var(--mono); font-size: .75rem;
}
.skip:focus { left: 1rem; top: 1rem; }

.shell { max-width: var(--max); margin-inline: auto; }


/* --- Type ----------------------------------------------------------------- */

/* Display: enormous, uppercase, set tight. A title card, not a headline. */
.display {
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.025em;
  line-height: 0.86;
  margin: 0;
  text-wrap: balance;
  /* Safety net: "CINEMATOGRAPHY" is a single 14-character word that cannot
     wrap, so without this it silently clips instead of overflowing visibly.
     The clamps below are sized so this should never actually fire. */
  overflow-wrap: break-word;
}

.d-hero { font-size: clamp(3.4rem, 13vw, 12.5rem); font-weight: 900; letter-spacing: -0.035em; }

/* Sized against the longest title on the site, "CINEMATOGRAPHY", which sets
   ~8.9x its font-size in width. At 10vw inside 5vw gutters that leaves only a
   1% margin and clips the final letter around 1400-1470px, so this is
   deliberately backed off to keep real headroom at every width. */
.d-page { font-size: clamp(1.6rem, 8.2vw, 7.6rem);  font-weight: 900; letter-spacing: -0.035em; }

/* Archivo 900 uppercase runs ~10.1x its font-size for "CINEMATOGRAPHY". The
   lower bounds here are set from that measurement so the longest word still
   fits its container at 360px, the narrowest viewport worth supporting. */
.d-lg   { font-size: clamp(1.75rem, 5.2vw, 4.4rem); }
.d-md   { font-size: clamp(1.5rem, 3vw, 2.5rem); }

/* Mono: labels, credits, nav, anything that reads like a cue sheet. */
.mono {
  font-family: var(--mono);
  font-weight: 400;
  font-size: clamp(.62rem, 1.05vw, .74rem);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--grey-2);
}
.mono--lit { color: var(--white); }

/* Section eyebrow: mono label preceded by a short rule. */
.eyebrow {
  display: flex;
  align-items: center;
  gap: .9rem;
  margin-bottom: clamp(1.5rem, 4vw, 2.75rem);
}
.eyebrow::before {
  content: '';
  width: clamp(1.75rem, 5vw, 3.5rem);
  height: 1px;
  background: var(--line-lit);
  flex: none;
}

.lede {
  font-size: clamp(1.05rem, 1.9vw, 1.45rem);
  font-weight: 500;
  line-height: 1.5;
  color: var(--grey-1);
  max-width: 46ch;
  text-wrap: pretty;
}
.lede strong { color: var(--white); font-weight: 600; }


/* --- Nav ------------------------------------------------------------------ */

.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.35rem var(--pad);
  border-bottom: 1px solid transparent;
  transition: background .5s var(--cue), border-color .5s var(--cue), padding .5s var(--cue);
}
.nav.is-stuck {
  background: rgba(0, 0, 0, .82);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--line);
  padding-block: 1rem;
}

.nav-mark {
  font-family: var(--mono);
  font-size: .74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--white);
  white-space: nowrap;
}

.nav-links { display: flex; align-items: center; gap: clamp(1.1rem, 3vw, 2.6rem); }
.nav-links a {
  font-family: var(--mono);
  font-size: .7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--grey-2);
  transition: color .3s var(--cue);
  position: relative;
  padding-block: .3rem;
}
.nav-links a:hover,
.nav-links a:focus-visible { color: var(--white); }
.nav-links a[aria-current='page'] { color: var(--white); }
.nav-links a[aria-current='page']::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 1px;
  background: var(--white);
}

.nav-toggle { display: none; }


/* --- Hero ----------------------------------------------------------------- */

.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 8rem var(--pad) clamp(2rem, 5vh, 3.5rem);
  overflow: hidden;
  isolation: isolate;
}

.hero-plate {
  position: absolute;
  inset: 0;
  z-index: -2;
}
.hero-plate img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Knocked back so the type stays the loudest thing — but only just. This
     material is already very low-key, so heavy dimming crushes it to solid
     black and the photograph disappears entirely. */
  filter: brightness(.72) contrast(1.05) saturate(1.02);
}
/* Vignette + floor gradient so type always has something to sit on. */
.hero::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(0,0,0,.92) 0%, rgba(0,0,0,.3) 42%, rgba(0,0,0,0) 68%, rgba(0,0,0,.35) 100%),
    radial-gradient(125% 90% at 50% 45%, transparent 42%, rgba(0,0,0,.55) 100%);
  pointer-events: none;
}

.hero-inner { position: relative; width: 100%; }

.hero-title { margin-bottom: clamp(1.25rem, 3vh, 2rem); }
.hero-title .ln { display: block; }

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .6rem clamp(1rem, 3vw, 2.25rem);
  padding-top: clamp(1.1rem, 3vh, 1.75rem);
  border-top: 1px solid var(--line);
}
.hero-meta .sep { color: var(--grey-3); }

.hero-cue {
  position: absolute;
  right: var(--pad);
  bottom: clamp(2rem, 5vh, 3.5rem);
  display: flex;
  align-items: center;
  gap: .75rem;
}
.hero-cue .bar {
  width: 1px; height: 46px;
  background: linear-gradient(to bottom, var(--white), transparent);
  transform-origin: top;
  animation: cue-slide 2.4s var(--cue) infinite;
}
@keyframes cue-slide {
  0%   { transform: scaleY(0); opacity: 0; }
  35%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}


/* --- Statement ------------------------------------------------------------ */

.statement {
  padding: var(--gap) var(--pad);
  border-bottom: 1px solid var(--line);
}
.statement .display { max-width: 22ch; }
.statement .display em {
  font-style: normal;
  color: var(--grey-3);
}


/* --- The split: two discipline panels ------------------------------------- */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  border-bottom: 1px solid var(--line);
}
.split > * + * { border-left: 1px solid var(--line); }

/* The single "next discipline" panel at the foot of a subpage is full-width,
   so it must be much shorter than the two half-width panels on the index —
   at the tall height it reads as an empty black box with a caption. */
.split--single .panel { min-height: clamp(17rem, 40vh, 24rem); }
.split--single .panel-index { margin-bottom: 1.25rem; }

.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: clamp(30rem, 78vh, 46rem);
  padding: clamp(2rem, 4vw, 3.5rem);
  overflow: hidden;
  isolation: isolate;
}
.panel-plate { position: absolute; inset: 0; z-index: -2; }
.panel-plate img { width: 100%; height: 100%; object-fit: cover; }
.panel::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(to top, rgba(0,0,0,.9) 4%, rgba(0,0,0,.28) 58%, rgba(0,0,0,.45) 100%);
  pointer-events: none;
}

.panel-index { margin-bottom: auto; }

/* Panels are half-width on desktop, so the shared .d-lg size overflows here —
   "CINEMATOGRAPHY" needs ~10.1x its font-size and only gets ~607px of column.
   Sized to fit the column rather than the page. */
.panel-title {
  margin: clamp(.75rem, 2vw, 1.1rem) 0 .75rem;
  font-size: clamp(1.6rem, 3.6vw, 3.2rem);
}
.split--single .panel-title { font-size: clamp(1.6rem, 4.4vw, 4rem); }
.panel-sub { color: var(--grey-1); font-size: clamp(.85rem, 1.4vw, 1rem); max-width: 32ch; font-weight: 500; }

.panel-go {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  margin-top: clamp(1.25rem, 3vw, 1.9rem);
  padding-top: 1.1rem;
  border-top: 1px solid var(--line-lit);
  width: 100%;
}
.panel-go .arw { transition: transform .55s var(--cue); }
.panel:hover .panel-go .arw,
.panel:focus-visible .panel-go .arw { transform: translateX(.4rem); }


/* --- Work: full-width cinematic frames ------------------------------------ */

.works { padding: var(--gap) 0; }

.work + .work { margin-top: clamp(3.5rem, 9vw, 7rem); }

.work-link { display: block; }

.work-plate {
  position: relative;
  overflow: hidden;
  background: var(--raise);
}
.work-plate img { width: 100%; }

/* The play/watch cue, revealed on hover. */
.work-cue {
  position: absolute;
  inset: auto auto clamp(1rem, 2vw, 1.75rem) clamp(1rem, 2vw, 1.75rem);
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  padding: .55rem .9rem;
  background: rgba(0,0,0,.55);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,.28);
  opacity: 0;
  transform: translateY(.5rem);
  transition: opacity .5s var(--cue), transform .5s var(--cue);
}
.work-link:hover .work-cue,
.work-link:focus-visible .work-cue { opacity: 1; transform: none; }

.work-credit {
  display: grid;
  grid-template-columns: 4rem 1fr auto;
  align-items: baseline;
  gap: clamp(.75rem, 2vw, 2rem);
  padding: clamp(1rem, 2.2vw, 1.6rem) var(--pad) 0;
  border-top: 1px solid var(--line);
  margin-top: clamp(1rem, 2.2vw, 1.6rem);
  transition: border-color .5s var(--cue);
}
.work-link:hover .work-credit,
.work-link:focus-visible .work-credit { border-top-color: var(--line-lit); }

.work-no { color: var(--grey-3); }
.work-title { transition: opacity .4s var(--cue); }
.work-genre { margin-top: .5rem; }
.work-role { text-align: right; white-space: nowrap; }

.works .work { padding-inline: var(--pad); }
.works .work-credit { padding-inline: 0; }


/* --- Credits list (lighting) ---------------------------------------------- */

.credits { border-top: 1px solid var(--line); }

.credit {
  display: grid;
  grid-template-columns: 4rem 1.1fr 1fr;
  gap: clamp(1rem, 3vw, 3rem);
  padding: clamp(2rem, 4vw, 3.25rem) var(--pad);
  border-bottom: 1px solid var(--line);
  transition: background .5s var(--cue);
}
.credit:hover { background: var(--raise); }

.credit-no { color: var(--grey-3); }
.credit-venue { margin-bottom: .6rem; }
.credit-role { margin-bottom: 1.1rem; }
.credit-body { color: var(--grey-1); font-size: clamp(.9rem, 1.4vw, 1.02rem); max-width: 44ch; }

.credit-specs { display: flex; flex-direction: column; gap: .5rem; align-items: flex-start; }
.spec {
  display: flex; gap: .75rem;
  font-family: var(--mono);
  font-size: .68rem;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.spec dt { color: var(--grey-3); min-width: 5.5rem; }
.spec dd { color: var(--grey-1); margin: 0; }


/* --- Gallery -------------------------------------------------------------- */

.gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
.shot { position: relative; overflow: hidden; background: var(--black); }
.shot img { width: 100%; height: 100%; object-fit: cover; }

/* The two 4:5 portraits get portrait frames instead of being cropped to 16:9,
   which is what the old carousel did — it showed a narrow band of a tall photo.
   Pairs are matched by aspect so each grid row resolves to one clean height. */
.shot--tall { aspect-ratio: 4 / 5; }
.shot--wide { aspect-ratio: 4 / 3; }

.shot-cap {
  position: absolute;
  inset: auto 0 0 0;
  padding: 2.5rem 1rem .9rem;
  background: linear-gradient(to top, rgba(0,0,0,.85), transparent);
  opacity: 0;
  transition: opacity .5s var(--cue);
}
.shot:hover .shot-cap { opacity: 1; }


/* --- Toolkit -------------------------------------------------------------- */

.toolkit {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  padding: var(--gap) var(--pad);
  border-top: 1px solid var(--line);
}
.tool-head { padding-bottom: 1rem; margin-bottom: 1.25rem; border-bottom: 1px solid var(--line); }
.tool-list li {
  font-family: var(--mono);
  font-size: .78rem;
  letter-spacing: .06em;
  color: var(--grey-1);
  padding: .5rem 0;
}


/* --- About ---------------------------------------------------------------- */

.about {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  gap: clamp(2rem, 6vw, 6rem);
  padding: var(--gap) var(--pad);
  border-bottom: 1px solid var(--line);
}
.about-body { display: flex; flex-direction: column; gap: 1.25rem; }
.about-body p {
  color: var(--grey-1);
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  line-height: 1.65;
  max-width: 52ch;
  text-wrap: pretty;
}
.about-body p:first-child { color: var(--white); font-size: clamp(1.1rem, 2vw, 1.5rem); line-height: 1.45; }


/* --- Contact -------------------------------------------------------------- */

.contact { padding: var(--gap) var(--pad); }

.contact-mail {
  display: inline-block;
  margin: clamp(1.5rem, 4vw, 2.5rem) 0 clamp(2rem, 5vw, 3rem);
  font-size: clamp(1.1rem, 3.6vw, 2.6rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  border-bottom: 1px solid var(--line-lit);
  padding-bottom: .35rem;
  transition: border-color .4s var(--cue), opacity .4s var(--cue);
  overflow-wrap: anywhere;
}
.contact-mail:hover { border-bottom-color: var(--white); }

.profiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid var(--line);
}
.profile {
  display: flex;
  flex-direction: column;
  gap: .55rem;
  padding: clamp(1.25rem, 3vw, 2rem) 0;
  border-bottom: 1px solid transparent;
  transition: border-color .45s var(--cue);
}
.profile + .profile { border-left: 1px solid var(--line); padding-left: clamp(1rem, 3vw, 2rem); }
.profile:hover { border-bottom-color: var(--white); }
.profile-handle { color: var(--grey-1); font-family: var(--mono); font-size: .78rem; letter-spacing: .08em; }


/* --- Footer --------------------------------------------------------------- */

.footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding: clamp(2rem, 5vw, 3rem) var(--pad);
  border-top: 1px solid var(--line);
}
.footer-links { display: flex; flex-wrap: wrap; gap: 1rem 1.75rem; }
.footer-links a { transition: color .3s var(--cue); }
.footer-links a:hover { color: var(--white); }


/* ==========================================================================
   UNLIT → LIT
   Work rests dimmed and desaturated, and comes up to full colour on
   hover/focus. Gated behind (hover: hover) so touch devices — which can
   never trigger it — get the lit state from the start.
   ========================================================================== */

.plate img {
  transition: filter 1.1s var(--cue), transform 1.4s var(--cue);
  will-change: filter, transform;
}

@media (hover: hover) and (pointer: fine) {
  /* Tuned against this specific material: these are night exteriors, haze and
     low-key interiors, so the unlit state has to stay readable rather than
     going to mud. Desaturation carries most of the "unlit" read; brightness
     only assists. */
  .plate img { filter: grayscale(.62) brightness(.74) contrast(1.06); }

  .panel:hover .plate img,
  .panel:focus-visible .plate img,
  .work-link:hover .plate img,
  .work-link:focus-visible .plate img,
  .shot:hover img,
  .shot:focus-within img {
    filter: none;
    transform: scale(1.035);
  }

  /* A bump: neighbouring work dims slightly further while one is lit. */
  .works:hover .work-link:not(:hover) .work-title { opacity: .45; }
}


/* ==========================================================================
   CUES (motion)

   Everything here degrades safely. Reveals only arm themselves once the
   `js` class is on <html>, so with JS disabled every element is simply
   visible — the previous site went fully blank without JS.
   ========================================================================== */

/* Blackout → up. Pure CSS, so it can never leave the page stuck black. */
.blackout { display: none; }

.js .blackout {
  display: block;
  position: fixed;
  inset: 0;
  z-index: 300;
  background: var(--black);
  pointer-events: none;
  animation: house-lights 1.5s var(--cue) forwards;
}
@keyframes house-lights {
  0%   { opacity: 1; }
  100% { opacity: 0; visibility: hidden; }
}

.js .hero-plate img { animation: plate-up 2.4s var(--cue) forwards; }
@keyframes plate-up {
  from { transform: scale(1.07); }
  to   { transform: none; }
}

.js .hero-inner > * { animation: fade-up 1.15s var(--cue) backwards; }
.js .hero-title { animation-delay: .35s; }
.js .hero-meta  { animation-delay: .55s; }
.js .hero-cue   { animation: fade-up 1.15s var(--cue) .8s backwards; }

@keyframes fade-up {
  from { opacity: 0; transform: translateY(1.5rem); }
  to   { opacity: 1; transform: none; }
}

/* Scroll reveal — a fader move. */
.js .reveal {
  opacity: 0;
  transform: translateY(2rem);
  transition: opacity 1s var(--cue), transform 1s var(--cue);
}
.js .reveal.is-lit { opacity: 1; transform: none; }
.js .reveal-1 { transition-delay: .1s; }
.js .reveal-2 { transition-delay: .2s; }
.js .reveal-3 { transition-delay: .3s; }


/* --- Reduced motion: kill every cue, keep every state --------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .js .blackout { display: none; }
  .js .reveal { opacity: 1; transform: none; }
  .hero-cue .bar { animation: none; }
  .plate img { filter: none !important; transform: none !important; }
}


/* ==========================================================================
   BREAKPOINTS
   Real width breakpoints. The old site keyed its entire mobile layout on
   (pointer: coarse), so an iPad Pro in landscape got the phone layout and a
   1024px tablet got the full desktop one.
   ========================================================================== */

@media (max-width: 1100px) {
  .toolkit  { grid-template-columns: repeat(2, 1fr); }
  .credit   { grid-template-columns: 3rem 1fr; }
  .credit-specs { grid-column: 2; padding-top: .5rem; }
  .about    { grid-template-columns: 1fr; }
}

@media (max-width: 860px) {
  .split { grid-template-columns: 1fr; }
  .split > * + * { border-left: 0; border-top: 1px solid var(--line); }
  .panel { min-height: clamp(24rem, 62vh, 34rem); }

  .work-credit { grid-template-columns: 2.5rem 1fr; }
  .work-role { grid-column: 2; text-align: left; margin-top: .5rem; white-space: normal; }

  .profiles { grid-template-columns: 1fr; }
  .profile + .profile { border-left: 0; padding-left: 0; border-top: 1px solid var(--line); }
}

@media (max-width: 620px) {
  /* Keep all three destinations on phones — tightened rather than hidden.
     Dropping the two disciplines here would strand a phone user on a subpage
     with no way back to the other one except the footer. Measured to fit
     inside 390px alongside the wordmark. */
  .nav { padding-inline: 1rem; }
  .nav-mark  { font-size: .6rem; letter-spacing: .12em; }
  .nav-links { gap: .7rem; }
  .nav-links a { font-size: .55rem; letter-spacing: .06em; }

  .hero { justify-content: flex-end; padding-top: 6rem; }
  .hero-cue { display: none; }

  .toolkit  { grid-template-columns: 1fr; }
  .gallery  { grid-template-columns: 1fr; }

  .credit { grid-template-columns: 1fr; }
  .credit-no { margin-bottom: .75rem; }
  .credit-specs { grid-column: 1; }

  .footer { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 400px) {
  .work-credit { grid-template-columns: 1fr; }
  .work-no { margin-bottom: .4rem; }
}

/* Print: black-on-white, images off. */
@media print {
  body { background: #fff; color: #000; }
  .nav, .blackout, .hero-cue, .work-cue { display: none !important; }
  .plate, .hero-plate, .panel-plate { display: none !important; }
}
