/* ============================================================
   Memoryflix — a streaming-style archive of personal photos
   ============================================================ */

:root{
  --red:      #e50914;
  --red-hot:  #f6121d;
  --bg:       #141414;
  --bg-2:     #181818;
  --bg-3:     #2f2f2f;
  --text:     #fff;
  --text-dim: #b3b3b3;
  --text-dim2:#808080;
  --green:    #46d369;

  --gutter:   clamp(1.25rem, 4vw, 3.75rem);
  --card-gap: 0.35rem;
  --nav-h:    68px;

  --ease: cubic-bezier(.22,.61,.36,1);
  /* longer tail than --ease: for the full-screen moves, where arriving
     somewhere should feel like settling rather than snapping */
  --slow: cubic-bezier(.22,1,.36,1);
}

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

/* Sections carry their own display value, which would otherwise beat the
   user-agent rule for [hidden]. Views are toggled by that attribute. */
[hidden]{ display:none !important; }

html{ background:var(--bg); }

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:"Helvetica Neue",Helvetica,Arial,"Hiragino Kaku Gothic ProN","Noto Sans JP",sans-serif;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

body.is-locked{ overflow:hidden; }

img{ display:block; max-width:100%; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
a{ color:inherit; text-decoration:none; }

::selection{ background:var(--red); color:#fff; }

/* Scrollbars stay out of the way */
.row__track::-webkit-scrollbar,
.modal__card::-webkit-scrollbar{ width:0; height:0; }

/* ============================================================
   Profile gate
   ============================================================ */
/* Signing in is two screens on one unbroken dark ground. The name prompt
   stays put as the backdrop while the seats arrive over it, so there is never
   a frame where the site behind shows through — that flash of the home page
   was the whole illusion falling over. */
.gate{
  position:fixed; inset:0; z-index:200;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:2.5rem; background:var(--bg);
  transition:opacity .9s var(--slow), visibility .9s;
}
.gate.is-gone{ opacity:0; visibility:hidden; pointer-events:none; }

/* Only the contents leave; the ground they stand on does not move. */
.gate > *{
  transition:opacity .45s var(--slow), transform .45s var(--slow), filter .45s var(--slow);
}
.gate.is-leaving > *{
  opacity:0; transform:translateY(-18px); filter:blur(7px); pointer-events:none;
}
.gate__title{
  margin:0; font-size:clamp(2rem,5vw,3.5rem); font-weight:400; letter-spacing:-.02em;
}
.gate__hint{ margin:-1.75rem 0 0; color:var(--text-dim2); font-size:1rem; }
.gate__form{ display:flex; gap:.75rem; align-items:stretch; flex-wrap:wrap; justify-content:center; }
.gate__input{
  background:#161616; border:1px solid #5a5a5a; border-radius:4px;
  color:#fff; font-size:1.1rem; letter-spacing:.12em; text-transform:uppercase;
  padding:.75rem 1rem; width:min(20rem,70vw); outline:0;
}
.gate__input:focus{ border-color:#fff; }
.gate__input::placeholder{ letter-spacing:normal; text-transform:none; color:#6b6b6b; }
.gate__error{ margin:-1.25rem 0 0; color:#e87c03; font-size:.95rem; }

/* The seats float on whatever is behind — the name prompt while signing in,
   the site itself when the avatar reopens them. Frosted rather than solid, so
   in both cases it reads as a layer above rather than a different page. */
.gate--picker{
  gap:2rem;
  background:rgba(9,9,11,.93);
  backdrop-filter:blur(28px) saturate(1.1);
  -webkit-backdrop-filter:blur(28px) saturate(1.1);
}

/* Each seat rises in its own moment, left to right. */
@keyframes seatIn{
  from{ opacity:0; transform:translateY(26px) scale(.94); filter:blur(9px); }
  to  { opacity:1; transform:none; filter:none; }
}
.gate--picker:not(.is-leaving) .gate__item{ animation:seatIn .85s var(--slow) both; }
.gate--picker .gate__item:nth-child(1){ animation-delay:.10s; }
.gate--picker .gate__item:nth-child(2){ animation-delay:.17s; }
.gate--picker .gate__item:nth-child(3){ animation-delay:.24s; }
.gate--picker .gate__item:nth-child(4){ animation-delay:.31s; }

@keyframes riseIn{
  from{ opacity:0; transform:translateY(16px); filter:blur(6px); }
  to  { opacity:1; transform:none; filter:none; }
}
.gate--picker:not(.is-leaving) > .gate__title{ animation:riseIn .8s var(--slow) both; }
.gate--picker:not(.is-leaving) > .gate__note{ animation:riseIn .8s var(--slow) .34s both; }
.gate--picker:not(.is-leaving) > .gate__signout{ animation:riseIn .8s var(--slow) .42s both; }

/* Arriving at the site proper: it settles into place out of a soft focus
   rather than appearing all at once. */
@keyframes arrive{
  from{ opacity:0; transform:scale(1.035); filter:blur(12px) saturate(.8); }
  to  { opacity:1; transform:none; filter:none; }
}
#app.is-arriving{ animation:arrive 1.1s var(--slow) both; }

@media (prefers-reduced-motion:reduce){
  .gate, .gate > *{ transition-duration:.15s; }
  .gate--picker .gate__item, .gate--picker > *, #app.is-arriving{ animation:none; }
}
.gate__note{
  margin:.5rem 0 0; font-size:.85rem; color:var(--text-dim2);
  max-width:34rem; text-align:center; line-height:1.6;
}
/* Quiet, and set apart from the seats — leaving is a different kind of
   action from choosing a chair. */
.gate__signout{
  margin-top:1.5rem;
  padding:.55rem 1.5rem;
  border:1px solid rgba(255,255,255,.28);
  border-radius:999px;
  font-size:.8rem; font-weight:600; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.5);
  transition:color .2s var(--ease), border-color .2s var(--ease),
             background-color .2s var(--ease);
}
.gate__signout:hover{
  color:#fff; border-color:transparent; background:rgba(229,9,20,.85);
}
.gate__list{ display:flex; gap:2rem; list-style:none; margin:0; padding:0; flex-wrap:wrap; justify-content:center; }
.gate__item{ text-align:center; cursor:pointer; }
.gate__face{
  width:clamp(88px,10vw,150px); aspect-ratio:1; border-radius:6px;
  display:grid; place-items:center;
  font-size:clamp(2rem,4vw,3.4rem); font-weight:700; color:#fff;
  border:3px solid transparent; transition:border-color .2s var(--ease), transform .2s var(--ease);
}
.gate__item:hover .gate__face{ border-color:#fff; transform:scale(1.04); }
.gate__name{ margin:.75rem 0 0; color:var(--text-dim2); font-size:1.05rem; }
.gate__item:hover .gate__name{ color:#fff; }

/* ============================================================
   Nav
   ============================================================ */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:100;
  height:var(--nav-h);
  display:flex; align-items:center; justify-content:space-between;
  padding:0 var(--gutter);
  background:linear-gradient(180deg,rgba(0,0,0,.78) 10%,rgba(0,0,0,0) 100%);
  transition:background-color .35s var(--ease);
}
.nav.is-solid{ background:var(--bg); }

.nav__left{ display:flex; align-items:center; gap:2rem; min-width:0; }
.nav__right{ display:flex; align-items:center; gap:1.15rem; }

/* ── Wordmark ───────────────────────────────────────────────────
   Heavy condensed caps on a shallow cylinder: each letter is rotated a
   little further than the last, so the row fans out and the baseline
   bows. Plus a vertical gradient and a drop shadow underneath. */
.brand{
  display:flex; align-items:baseline;
  perspective:340px;
  white-space:nowrap;
  font-family:"HelveticaNeue-CondensedBlack","Helvetica Neue",
              "Arial Narrow",Impact,sans-serif;
  font-weight:900;
  font-size:clamp(1.15rem,1.95vw,1.68rem);
  /* stretched upward, so the letters are drawn tighter than usual */
  letter-spacing:-.03em;
  line-height:1;
  text-transform:uppercase;
  filter:drop-shadow(0 3px 5px rgba(0,0,0,.55));
}
.brand__l{
  display:inline-block;
  transform-style:preserve-3d;
  /* the stretch happens about the baseline, the way a wordmark sits */
  transform-origin:center bottom;
  background:linear-gradient(180deg,#f0111c 0%,#e50914 46%,#a5060f 100%);
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  transition:transform .35s var(--ease);
}
/* the O and the tighter pairs read better a hair narrower */
.brand__l--wide{ transform:scaleX(.94); }

.nav .brand:hover .brand__l{ transform:rotateY(0) translateY(0) scaleY(1); }

.nav__links{ display:flex; gap:.15rem; align-items:center; }

/* A soft capsule follows the pointer so it's always clear what you're about
   to pick — and the current section keeps one. */
.nav__link{
  position:relative;
  padding:.42rem .82rem;
  border-radius:999px;
  font-size:.875rem; color:#e5e5e5; white-space:nowrap;
  transition:color .2s var(--ease), background-color .22s var(--ease);
}
.nav__link::before{
  content:""; position:absolute; inset:0;
  border-radius:inherit;
  background:rgba(255,255,255,.14);
  opacity:0; transform:scale(.88);
  transition:opacity .22s var(--ease), transform .22s var(--ease);
}
.nav__link:hover::before,
.nav__link:focus-visible::before{ opacity:1; transform:scale(1); }
.nav__link:hover{ color:#fff; }
.nav__link.is-active{ font-weight:600; color:#fff; }
.nav__link.is-active::before{ opacity:1; transform:scale(1); background:rgba(255,255,255,.19); }

/* the map is not another tag — it gets air, a rule, and a mark */
.nav__divider{
  width:1px; height:1.1rem; margin:0 .55rem;
  background:rgba(255,255,255,.22);
  flex:0 0 auto;
}
.nav__link--map{
  display:inline-flex; align-items:center; gap:.42rem;
  color:#fff;
}
.nav__link--map svg{
  opacity:.85;
  transition:transform .6s cubic-bezier(.3,.7,.3,1), opacity .2s var(--ease);
}
.nav__link--map:hover svg{ transform:rotate(180deg); opacity:1; }
.nav__link--map::before{ background:rgba(120,190,255,.2); }
.nav__link--map.is-active::before{ background:rgba(120,190,255,.28); }

/* the search mark gets the same capsule */
.search__btn{
  position:relative; border-radius:999px; padding:.45rem;
  transition:color .2s var(--ease);
}
.search__btn::before{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:rgba(255,255,255,.14);
  opacity:0; transform:scale(.88);
  transition:opacity .22s var(--ease), transform .22s var(--ease);
}
.search__btn:hover::before,
.search__btn:focus-visible::before{ opacity:1; transform:scale(1); }

/* Closed it's just the mark. Open, it becomes a solid capsule that grows
   leftward and sits over the nav — opaque, because a see-through field let
   the links read straight through the typing. */
.search{
  position:relative; z-index:20;
  display:flex; align-items:center;
  border:1px solid transparent; border-radius:999px;
  transition:background-color .28s var(--ease), border-color .28s var(--ease),
             box-shadow .28s var(--ease);
}
.search.is-open{
  background:#0a0a0b;
  border-color:rgba(255,255,255,.42);
  box-shadow:0 8px 30px rgba(0,0,0,.55);
}
.search__btn{ display:grid; place-items:center; padding:.35rem; }
.search__input{
  width:0; padding:0; border:0; outline:0; background:none; color:#fff;
  font-size:.9rem; transition:width .32s var(--ease), padding .32s var(--ease);
}
.search__input::placeholder{ color:rgba(255,255,255,.42); }
.search.is-open .search__input{
  width:clamp(180px,26vw,340px);
  padding:.5rem 1rem .5rem .25rem;
}

/* The capsule overlaps the section links, so they step back rather than
   showing through it. */
.nav.is-searching .nav__links{
  opacity:.25;
  pointer-events:none;
  transition:opacity .28s var(--ease);
}
.nav__links{ transition:opacity .28s var(--ease); }

/* ── Year picker ────────────────────────────────────────────────
   The year you're in sits in the bar; the rest drop out of it. No box,
   no border — the list surfaces from behind the button. */
.years{ position:relative; }

.years__now{
  position:relative;
  display:inline-flex; align-items:center; gap:.35rem;
  padding:.42rem .7rem .42rem .85rem;
  border-radius:999px;
  font-size:.875rem; font-weight:600; letter-spacing:.02em;
  color:#e5e5e5;
  transition:color .2s var(--ease);
}
.years__now::before{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:rgba(255,255,255,.14);
  opacity:0; transform:scale(.88);
  transition:opacity .22s var(--ease), transform .22s var(--ease);
}
.years__now:hover::before, .years.is-open .years__now::before{ opacity:1; transform:scale(1); }
.years__now:hover{ color:#fff; }
.years__now svg{ opacity:.65; transition:transform .28s var(--ease); }
.years.is-open .years__now svg{ transform:rotate(180deg); }

.years__menu{
  position:absolute; top:calc(100% + .5rem); right:0;
  min-width:9.5rem;
  padding:.4rem;
  border-radius:16px;
  background:rgba(16,18,24,.86);
  backdrop-filter:blur(22px) saturate(1.3);
  box-shadow:0 1px 0 rgba(255,255,255,.08) inset,
             0 22px 60px rgba(0,0,0,.6);
  transform-origin:top right;
  animation:yearsOpen .3s cubic-bezier(.22,.9,.3,1) backwards;
  z-index:120;
}
@keyframes yearsOpen{
  from{ opacity:0; transform:scale(.94) translateY(-6px); }
}

.year{
  position:relative;
  display:flex; align-items:baseline; gap:.5rem;
  width:100%; padding:.52rem .85rem;
  border-radius:11px;
  font-size:.92rem; font-weight:600; letter-spacing:.01em;
  color:rgba(255,255,255,.62);
  transition:color .18s var(--ease), background-color .18s var(--ease);
  /* each row arrives a beat after the one above */
  animation:yearRow .34s var(--ease) backwards;
  animation-delay:calc(.028s * var(--i,0));
}
@keyframes yearRow{ from{ opacity:0; transform:translateY(-5px); } }
.year:hover{ color:#fff; background:rgba(255,255,255,.1); }
.year__n{ margin-left:auto; font-size:.72rem; font-weight:500; color:rgba(255,255,255,.34); }
.year.is-now{ color:#fff; }
.year.is-now::after{
  content:""; position:absolute; left:.34rem; top:50%;
  width:3px; height:3px; margin-top:-1.5px;
  border-radius:50%; background:var(--red);
}
.year.is-empty{ color:rgba(255,255,255,.28); }
.year.is-empty:hover{ color:rgba(255,255,255,.45); }

/* Clicking it goes back to the seat picker, so it has to read as a control
   rather than a label. */
.avatar{
  position:relative;
  width:32px; height:32px; border-radius:5px;
  background:linear-gradient(135deg,#e50914,#b81d24);
  display:grid; place-items:center; font-size:.85rem; font-weight:700;
  cursor:pointer;
  transition:transform .22s var(--ease), box-shadow .22s var(--ease);
}
.avatar::after{
  content:""; position:absolute; inset:-3px;
  border-radius:8px; border:2px solid rgba(255,255,255,.85);
  opacity:0; transform:scale(.9);
  transition:opacity .22s var(--ease), transform .22s var(--ease);
}
.avatar:hover{ transform:translateY(-1px); }
.avatar:hover::after{ opacity:1; transform:scale(1); }

/* ============================================================
   Hero billboard
   ============================================================ */
.hero{
  position:relative;
  height:clamp(460px,56.25vw,860px);
  display:flex; align-items:center;
}
.hero__media{ position:absolute; inset:0; overflow:hidden; }
.hero__img{
  position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover;
  opacity:0;
  transition:opacity 1s cubic-bezier(.4,0,.2,1);
  transform:scale(1.045);
}
.hero__img.is-on{ opacity:1; }
/* the backdrop drifts almost imperceptibly while a title is up */
.hero:not(.is-held) .hero__img.is-on{
  animation:heroDrift var(--hero-hold,9s) linear forwards;
}
@keyframes heroDrift{ from{ transform:scale(1.045); } to{ transform:scale(1.11); } }

/* which title of the set you're on */
.hero__dots{
  position:absolute; right:var(--gutter); bottom:clamp(4rem,11vh,7rem);
  z-index:4; display:flex; gap:.42rem; align-items:center;
}
.hero__dot{
  width:.85rem; height:3px; border-radius:2px;
  background:rgba(255,255,255,.32);
  transition:background-color .25s var(--ease), width .25s var(--ease);
}
.hero__dot:hover{ background:rgba(255,255,255,.62); }
.hero__dot.is-now{ width:1.7rem; background:#fff; }

/* the text swaps with the picture rather than sitting through it */
.hero__body > *{ transition:opacity .45s var(--ease), transform .45s var(--ease); }
.hero.is-swapping .hero__body > *{ opacity:0; transform:translateY(10px); }

@media (max-width:820px){
  .hero__dots{ bottom:1.25rem; right:auto; left:var(--gutter); }
}
.hero__scrim{
  position:absolute; inset:0;
  background:linear-gradient(77deg,rgba(0,0,0,.85) 0%,rgba(0,0,0,.45) 42%,rgba(0,0,0,0) 72%);
}
.hero__fade{
  position:absolute; left:0; right:0; bottom:-1px; height:38%;
  background:linear-gradient(180deg,rgba(20,20,20,0) 0%,rgba(20,20,20,.65) 55%,var(--bg) 100%);
}
.hero__body{
  position:relative; z-index:2;
  padding:0 var(--gutter);
  max-width:min(46rem,62%);
  margin-top:2rem;
}
/* A label above the title, not a competitor to it. */
.hero__eyebrow{
  display:flex; align-items:center; gap:.45rem;
  margin:0 0 .55rem; font-size:.72rem; font-weight:700; letter-spacing:.3em;
  color:rgba(255,255,255,.72);
}
.hero__n{
  color:var(--red); font-weight:900; font-size:1.05rem; letter-spacing:0;
}
.hero__title{
  margin:0 0 1rem;
  font-family:"HelveticaNeue-CondensedBlack","Helvetica Neue","Arial Narrow",sans-serif;
  font-size:clamp(2.6rem,6.4vw,5.6rem);
  line-height:.94; font-weight:900;
  letter-spacing:.015em;
  text-transform:uppercase;
  text-shadow:0 3px 26px rgba(0,0,0,.75), 0 1px 2px rgba(0,0,0,.6);
}
.hero__meta{
  margin:0 0 .8rem; font-size:1rem; color:#e5e5e5;
  display:flex; align-items:center; gap:.75rem; flex-wrap:wrap;
}
.hero__synopsis{
  margin:0 0 1.5rem;
  font-size:clamp(.95rem,1.25vw,1.2rem); line-height:1.45;
  color:#fff; text-shadow:0 2px 10px rgba(0,0,0,.7);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden;
}
.hero__actions{ display:flex; gap:.75rem; flex-wrap:wrap; }

.badge-new{
  color:var(--green); font-weight:700; font-size:.95rem;
}
.badge-hd{
  border:1px solid rgba(255,255,255,.45); border-radius:3px;
  padding:0 .35rem; font-size:.7rem; letter-spacing:.05em;
}

/* Buttons */
.btn{
  display:inline-flex; align-items:center; gap:.6rem;
  padding:.7rem 1.75rem; border-radius:4px;
  font-size:clamp(.95rem,1.2vw,1.15rem); font-weight:700;
  transition:background-color .18s var(--ease), transform .12s var(--ease);
}
.btn:active{ transform:scale(.97); }
.btn--play{ background:#fff; color:#000; }
.btn--play:hover{ background:rgba(255,255,255,.78); }
.btn--info{ background:rgba(109,109,110,.7); color:#fff; }
.btn--info:hover{ background:rgba(109,109,110,.45); }

.iconbtn{
  width:42px; height:42px; border-radius:50%;
  border:2px solid rgba(255,255,255,.5);
  display:grid; place-items:center;
  transition:border-color .18s var(--ease), background-color .18s var(--ease);
}
.iconbtn:hover{ border-color:#fff; background:rgba(255,255,255,.12); }
.iconbtn.is-on{ border-color:#fff; background:#fff; color:#000; }

/* ============================================================
   Rows
   ============================================================ */
.rows{
  position:relative; z-index:3;
  margin-top:clamp(-9rem,-8vw,-4rem);
  padding-bottom:3rem;
}
/* That negative margin exists to tuck the first row under the billboard.
   With no billboard — a filtered view, or a person's album — it dragged the
   rows up behind the nav instead, so they looked empty. */
.hero[hidden] + .rows{ margin-top:calc(var(--nav-h) + 1.75rem); }

.row{ margin-bottom:clamp(1.6rem,3vw,3vw); }

.row__head{
  display:flex; align-items:baseline; gap:.75rem;
  padding:0 var(--gutter); margin:0 0 .55rem;
}
.row__title{
  margin:0; font-size:clamp(1.05rem,1.5vw,1.45rem); font-weight:700; letter-spacing:-.01em;
  color:#e5e5e5;
}
.row:hover .row__title{ color:#fff; }
.row__explore{
  font-size:.8rem; color:var(--cyan,#54b9c5); font-weight:600;
  opacity:0; transform:translateX(-6px);
  transition:opacity .2s var(--ease), transform .2s var(--ease);
}
.row:hover .row__explore{ opacity:1; transform:none; }

/* the ranked row shows its working, and offers to forget it */
.row__count{
  font-size:.74rem; letter-spacing:.06em; text-transform:uppercase;
  color:rgba(255,255,255,.34);
}
.row__reset{
  font-size:.72rem; font-weight:600; letter-spacing:.06em; text-transform:uppercase;
  color:rgba(255,255,255,.34);
  padding:.2rem .5rem; border-radius:999px;
  opacity:0; transform:translateX(-4px);
  transition:opacity .2s var(--ease), transform .2s var(--ease),
             color .2s var(--ease), background-color .2s var(--ease);
}
.row:hover .row__reset{ opacity:1; transform:none; }
.row__reset:hover{ color:#fff; background:rgba(229,9,20,.85); }

.row__viewport{ position:relative; }

/* The track scrolls horizontally, and a horizontal scroll container also
   clips vertically — so a popped card and the panel under it get cut off
   unless the padding leaves room for them. The negative margins cancel that
   padding again, so rows sit exactly where they did. */
.row__track{
  --pop-top:3rem;
  --pop-bottom:9.5rem;
  display:flex; gap:var(--card-gap);
  padding:var(--pop-top) var(--gutter) var(--pop-bottom);
  margin:calc(var(--pop-top) * -1) 0 calc(var(--pop-bottom) * -1);
  overflow-x:auto; overflow-y:hidden;
  scroll-behavior:smooth;
  scrollbar-width:none;
  scroll-padding-inline:var(--gutter);
}
/* rows sit closer together than that padding implies, so give the next one
   its space back */
.row{ position:relative; }

.row__arrow{
  position:absolute; top:0; bottom:0; z-index:12;
  width:var(--gutter); min-width:2.75rem;
  display:grid; place-items:center;
  background:rgba(20,20,20,.55);
  opacity:0; transition:opacity .2s var(--ease), background-color .2s var(--ease);
}
.row__viewport:hover .row__arrow{ opacity:1; }
.row__arrow:hover{ background:rgba(20,20,20,.8); }
.row__arrow svg{ transition:transform .18s var(--ease); }
.row__arrow:hover svg{ transform:scale(1.25); }
.row__arrow--prev{ left:0; }
.row__arrow--next{ right:0; }
.row__arrow[disabled]{ display:none; }

/* ── The cast, as a grid ────────────────────────────────────────
   Six across, running downward. A sideways row is fine for a shelf of
   albums and wrong for a list of people — you scan faces, you don't page
   through them. */
.castSection{ margin-bottom:clamp(1.6rem,3vw,3vw); }

.castGrid{
  display:grid;
  grid-template-columns:repeat(6,1fr);
  gap:1.5rem var(--card-gap);
  padding:0 var(--gutter);
  transition:max-height .5s var(--ease);
}
.castGrid .card{ width:auto; }

/* Clamped, the last visible row dissolves rather than being sliced. */
.castGrid.is-clamped{
  overflow:hidden;
  -webkit-mask-image:linear-gradient(180deg,#000 62%,rgba(0,0,0,.25) 88%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 62%,rgba(0,0,0,.25) 88%,transparent 100%);
}

.castMore{
  display:flex; justify-content:center;
  margin-top:-.5rem; padding:0 var(--gutter);
}
.castMore__btn{
  padding:.55rem 1.6rem;
  border:1px solid rgba(255,255,255,.28); border-radius:999px;
  font-size:.78rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.7);
  background:rgba(20,20,20,.6); backdrop-filter:blur(8px);
  transition:color .2s var(--ease), border-color .2s var(--ease),
             background-color .2s var(--ease), transform .2s var(--ease);
}
.castMore__btn:hover{
  color:#fff; border-color:transparent;
  background:rgba(255,255,255,.16);
  transform:translateY(-1px);
}

@media (max-width:1400px){ .castGrid{ grid-template-columns:repeat(5,1fr); } }
@media (max-width:1120px){ .castGrid{ grid-template-columns:repeat(4,1fr); } }
@media (max-width:860px){  .castGrid{ grid-template-columns:repeat(3,1fr); } }
@media (max-width:600px){  .castGrid{ grid-template-columns:repeat(2,1fr); } }

/* ── Trips ──────────────────────────────────────────────────────
   Bigger than an album card, because a trip contains several. */
.tripGrid{ grid-template-columns:repeat(3,1fr); gap:2rem var(--card-gap); }
@media (max-width:1100px){ .tripGrid{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:680px){  .tripGrid{ grid-template-columns:1fr; } }

.tripCard{ cursor:pointer; }
.tripCard__meta{
  margin:.6rem .1rem 0;
  font-size:.78rem; color:var(--text-dim2); letter-spacing:.01em;
}
.tripCard__note{ color:rgba(255,255,255,.36); font-style:italic; }
@media (hover:hover) and (pointer:fine){
  .tripCard:hover{ transform:scale(1.03); z-index:5; }
  .tripCard:hover .card__logo{ opacity:1; }
}

.tripHead{
  padding:0 var(--gutter);
  margin-bottom:clamp(1.2rem,2.4vw,2rem);
}
.tripHead__back{
  font-size:.78rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--text-dim2); padding:.4rem 0;
  transition:color .2s var(--ease);
}
.tripHead__back:hover{ color:#fff; }
.tripHead__title{
  margin:.4rem 0 .3rem;
  font-size:clamp(1.9rem,4.4vw,3.4rem); line-height:1;
  text-transform:uppercase;
  text-shadow:0 3px 20px rgba(0,0,0,.6);
}
.tripHead__title::before{ display:none; }
.tripHead__meta{ margin:0; font-size:.9rem; color:var(--text-dim); }

/* ── Card ───────────────────────────────────────────────────── */
.card{
  position:relative; flex:0 0 auto;
  width:clamp(150px,15.6vw,320px);
  border-radius:4px;
  transition:transform .3s var(--ease);
  transform-origin:center center;
  z-index:1;
}
.card__box{
  position:relative; overflow:hidden; border-radius:4px;
  background:var(--bg-2);
  aspect-ratio:16/9;
}
/* The blur-up placeholder sits *behind* the real photo. It is absolutely
   positioned, so the sharp image has to be positioned too — otherwise the
   blurred copy paints on top of it and every card looks out of focus. */
.card__lqip{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%;
  object-fit:cover; filter:blur(14px); transform:scale(1.06);
}
.card__img{
  position:relative; z-index:1;
  width:100%; height:100%; object-fit:cover;
  transition:opacity .4s var(--ease);
}
.card__img.is-loading{ opacity:0; }
/* Title treatment — set like a film title rather than a caption: heavy
   condensed caps, opened up, over a scrim so it reads on any photo. */
.card__logo{
  /* above .card__img, which is positioned so it can cover the blur-up
     placeholder — without this the title paints underneath the photo */
  position:absolute; left:0; right:0; bottom:0; z-index:2;
  padding:2.4rem .8rem .68rem;
  font-family:"HelveticaNeue-CondensedBold","HelveticaNeue-CondensedBlack",
              "Helvetica Neue","Arial Narrow",sans-serif;
  font-size:clamp(.72rem,.92vw,1.02rem);
  font-weight:800;
  letter-spacing:.11em;
  line-height:1.12;
  text-transform:uppercase;
  /* No plate behind the type — it sits straight on the photograph. Legibility
     comes from layered shadows instead: a tight one to cut the letterform out
     of whatever is behind it, and a wide soft one to darken the area around
     it without drawing an edge. */
  text-shadow:
    0 1px 2px rgba(0,0,0,.95),
    0 2px 5px rgba(0,0,0,.8),
    0 0 18px rgba(0,0,0,.7),
    0 0 40px rgba(0,0,0,.5);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  transition:opacity .2s var(--ease);
}
/* a thin rule above the title, the way a title card is set off */
.card__logo::before{
  content:""; display:block;
  width:1.6rem; height:2px; margin-bottom:.42rem;
  background:var(--red);
  box-shadow:0 1px 4px rgba(0,0,0,.6);
}

.card--top .card__logo{ padding-bottom:.8rem; letter-spacing:.09em; }

/* ── Title treatments ───────────────────────────────────────────
   A trip has a temperature, and the lettering should carry it. Each
   collection names one of these in library.json; the default is `classic`. */

/* Only the family and the spacing are shared. Size is set per place —
   a treatment must never dictate how big a billboard headline is. */
.tt-surf{
  font-family:Futura,"Avenir Next","Helvetica Neue",sans-serif;
  font-weight:500; letter-spacing:.24em;
  text-shadow:0 1px 3px rgba(0,0,0,.85), 0 4px 18px rgba(0,0,0,.5);
}
.tt-surf::before{ background:rgba(255,255,255,.85); }

.tt-road{
  font-family:"HelveticaNeue-CondensedBlack","Arial Narrow",sans-serif;
  font-weight:900; letter-spacing:.01em;
  transform:skewX(-4deg); transform-origin:left bottom;
}

.tt-city{
  font-family:Didot,"Bodoni 72",Georgia,serif;
  font-weight:700; letter-spacing:.1em;
}
.tt-city::before{ background:#fff; }

/* Skydiving — the heaviest thing on the site. Letters jammed together and
   squeezed upward, the way a stunt poster shouts. */
.tt-impact{
  font-family:Impact,Haettenschweiler,"Arial Narrow Bold",
              "HelveticaNeue-CondensedBlack",sans-serif;
  font-weight:900;
  letter-spacing:-.01em;
  transform:scaleY(1.14);
  transform-origin:left bottom;
}
.tt-impact::before{ width:2.6rem; height:4px; }

/* ── on the billboard: full film-title scale ── */
.hero__title.tt-surf{ letter-spacing:.13em; font-weight:500;
  font-size:clamp(2.2rem,5.4vw,4.6rem); }
.hero__title.tt-road{ letter-spacing:.005em;
  font-size:clamp(2.8rem,7vw,6.2rem); }
.hero__title.tt-city{ letter-spacing:.05em; font-weight:700;
  font-size:clamp(2.4rem,5.8vw,5rem); }

/* ── on a card: sized against the card, not the window ──
   Container units mean the lettering keeps the same proportion whether the
   card is 150px wide on a laptop or 320px on a big screen. */
.card__box{ container-type:inline-size; }

.card__logo{
  font-size:clamp(1rem,1.5vw,1.6rem);   /* fallback if cqw is unsupported */
  font-size:11cqw;
  line-height:1.02;
  padding:3rem .8rem .78rem;
  max-width:88%;
}
.card__logo::before{ width:14%; min-width:14px; height:2px; margin-bottom:.42em; }

/* wide tracking eats horizontal room, so this one runs a little smaller */
.card__logo.tt-surf{ font-size:7.4cqw; letter-spacing:.17em; }
.card__logo.tt-surf::before{ height:1px; }
.card__logo.tt-road{ font-size:12.5cqw; }
.card__logo.tt-road::before{ width:22%; height:3px; }
.card__logo.tt-city{ font-size:9cqw; }
.card__logo.tt-city::before{ height:1px; }

/* the ranked row shares its width with the numeral, so ease off */
.card--top .card__logo{ font-size:8.5cqw; padding-bottom:.9rem; }
.card--top .card__logo.tt-surf{ font-size:6.4cqw; }
.card--top .card__logo.tt-road{ font-size:10cqw; }
.card__count{
  position:absolute; top:.55rem; right:.55rem; z-index:2;
  background:rgba(0,0,0,.65); backdrop-filter:blur(4px);
  border-radius:3px; padding:.1rem .38rem;
  font-size:.68rem; font-weight:600; letter-spacing:.02em;
}
/* Something you sit down to watch, marked apart from something you leaf
   through. Top-left, opposite the count, the way a network stamps a show. */
.card__series{
  position:absolute; top:.55rem; left:.55rem; z-index:2;
  background:var(--red); border-radius:3px; padding:.1rem .4rem;
  font-size:.6rem; font-weight:800; letter-spacing:.09em; text-transform:uppercase;
}
.card__progress{
  position:absolute; left:.7rem; right:.7rem; bottom:.45rem; z-index:3; height:3px;
  background:rgba(255,255,255,.28); border-radius:2px; overflow:hidden;
}
.card__progress i{ display:block; height:100%; background:var(--red); }

/* hover pop-out */
.card__panel{
  position:absolute; left:0; right:0; top:100%;
  background:var(--bg-2);
  border-radius:0 0 4px 4px;
  padding:.75rem .8rem .85rem;
  opacity:0; pointer-events:none;
  transition:opacity .2s var(--ease);
  box-shadow:0 12px 26px rgba(0,0,0,.7);
}
.card__panelRow{ display:flex; align-items:center; gap:.45rem; margin-bottom:.55rem; }
.card__mini{
  width:30px; height:30px; border-radius:50%;
  border:2px solid rgba(255,255,255,.55);
  display:grid; place-items:center;
}
.card__mini--play{ background:#fff; color:#000; border-color:#fff; }
.card__mini:hover{ border-color:#fff; }
.card__facts{
  display:flex; align-items:center; gap:.45rem; flex-wrap:wrap;
  font-size:.72rem; color:#ddd; margin-bottom:.35rem;
}
.card__facts .ok{ color:var(--green); font-weight:700; }
.card__tags{
  display:flex; align-items:center; gap:.4rem; flex-wrap:wrap;
  font-size:.7rem; color:var(--text-dim);
}
.card__tags span + span::before{ content:"•"; margin-right:.4rem; color:#5a5a5a; }

/* ── Card hover ─────────────────────────────────────────────────
   Every card in every row behaves the same. The scale and the panel share
   one delay and one duration so they always arrive together — when they
   drifted apart a card could show its panel while still looking unscaled.
   `.is-hovered` mirrors the state so it can be driven from script, and
   :focus-visible gives keyboard users the same thing. */
:root{ --card-pop:1.32; --card-delay:.25s; }

@media (hover:hover) and (pointer:fine){
  /* Hovering a card also hovers its row, so this rule matched the hovered
     card too — and at (0,3,0) it outranked `.card:hover` at (0,2,0), which
     meant the card under the cursor was being shrunk instead of grown. The
     card in focus is excluded explicitly: only its neighbours draw back. */
  .row__track:hover .card:not(:hover):not(:focus-visible):not(.is-hovered),
  .row__track.is-rowhover .card:not(.is-hovered){
    transform:scale(.97);
  }

  .card:hover,
  .card:focus-visible,
  .card.is-hovered{
    transform:scale(var(--card-pop)) translateX(var(--card-shift,0));
    z-index:20;
    transition-delay:var(--card-delay);
  }
  .card:hover .card__box,
  .card:focus-visible .card__box,
  .card.is-hovered .card__box{ border-radius:4px 4px 0 0; }

  .card:hover .card__panel,
  .card:focus-visible .card__panel,
  .card.is-hovered .card__panel{
    opacity:1; pointer-events:auto;
    transition-delay:var(--card-delay);
  }
  .card:hover .card__logo,
  .card:focus-visible .card__logo,
  .card.is-hovered .card__logo{ opacity:0; }

  /* Nudge the ones at the ends inward so they don't run off the edge.
     The nudge is a variable rather than a second transform rule, because
     `.card:first-child:hover` outranks `.card--top:hover` on specificity —
     which is how the ranked row ended up with two different scales. */
  .card:first-child{ --card-shift:6%; }
  .card:last-child{ --card-shift:-6%; }
}

/* ── Top 10 row ─────────────────────────────────────────────── */
.row--top .row__track{ gap:.35rem; align-items:flex-end; }
.card--top{
  width:clamp(230px,23vw,420px);
  display:flex; align-items:flex-end;
}
.card--top .card__rank{
  flex:0 0 auto;
  width:44%;
  font-size:clamp(6rem,11.5vw,14rem);
  line-height:.78;
  font-weight:800;
  letter-spacing:-.06em;
  color:#141414;
  -webkit-text-stroke:3px #6f6f6f;
  text-align:right;
  user-select:none;
  padding-right:.04em;
}
.card--top .card__box{
  flex:1 1 auto; aspect-ratio:2/3; border-radius:4px;
}
.card--top .card__panel{ display:none; }
/* The ranked cards are already large, so they lift less — set through the
   same variable rather than a competing transform rule. */
.card--top{ --card-pop:1.1; }
@media (hover:hover) and (pointer:fine){
  .card--top:hover .card__logo,
  .card--top:focus-visible .card__logo,
  .card--top.is-hovered .card__logo{ opacity:1; }
}

/* ── Locked / coming-soon cards ─────────────────────────────── */
.card--locked .card__box{ filter:grayscale(1) brightness(.55); }
.card--locked .card__lock{
  position:absolute; inset:0; display:grid; place-items:center; gap:.4rem;
  align-content:center; text-align:center; padding:1rem;
}
.card--locked .card__lock b{ font-size:1.35rem; letter-spacing:.02em; }
.card--locked .card__lock small{ font-size:.7rem; color:var(--text-dim); letter-spacing:.12em; }
/* Coming-soon tiles barely move — there is nothing behind them yet. */
.card--locked{ --card-pop:1.06; }
@media (hover:hover) and (pointer:fine){
  .card--locked:hover .card__panel,
  .card--locked:focus-visible .card__panel,
  .card--locked.is-hovered .card__panel{ display:none; }
}

/* ============================================================
   Map — a globe of the places you've shot
   ============================================================ */
/* The whole view is the globe's world — no inner "screen", no seam
   between the page and the map. */
.map{
  position:fixed; inset:0; z-index:40;
  background:
    radial-gradient(130% 100% at 50% 4%, #1b2c46 0%, #101c30 38%, #0a1120 68%, #060911 100%);
  overflow:hidden;
}
.map__canvas{
  position:absolute; inset:0;
  display:block; width:100%; height:100%;
  cursor:grab; touch-action:none;
}
.map__canvas.is-dragging{ cursor:grabbing; }
.map__canvas.is-overPin{ cursor:pointer; }

/* keeps the edges dark so the nav and titles stay readable */
.map__vignette{
  position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(180deg,rgba(4,6,12,.82) 0%,rgba(4,6,12,0) 26%),
    radial-gradient(120% 85% at 50% 50%,rgba(4,6,12,0) 52%,rgba(4,6,12,.72) 100%);
}

.map__head{
  position:absolute; top:calc(var(--nav-h) + .5rem); left:var(--gutter);
  pointer-events:none; z-index:3;
}
.map__title{
  margin:0 0 .3rem;
  font-size:clamp(1.6rem,3.4vw,2.6rem); font-weight:800; letter-spacing:-.028em;
  text-shadow:0 3px 22px rgba(0,0,0,.75);
}
.map__sub{
  margin:0; font-size:.9rem; letter-spacing:.02em;
  color:rgba(255,255,255,.62);
}

.map__hud{
  position:absolute; left:var(--gutter); bottom:1.75rem; z-index:3;
  display:flex; flex-direction:column; gap:.6rem; align-items:flex-start;
}
.map__hint{
  margin:0; font-size:.72rem; letter-spacing:.14em; text-transform:uppercase;
  color:rgba(255,255,255,.3); pointer-events:none;
}
.map__zoomOut{
  display:inline-flex; align-items:center; gap:.45rem;
  border:1px solid rgba(255,255,255,.35); border-radius:3px;
  background:rgba(8,12,20,.6); backdrop-filter:blur(8px);
  padding:.42rem .85rem; font-size:.8rem; font-weight:600;
  transition:background-color .18s var(--ease), border-color .18s var(--ease);
}
.map__zoomOut:hover{ background:rgba(229,9,20,.85); border-color:transparent; }

.map__zoomBar{
  width:150px; height:2px; background:rgba(255,255,255,.16); border-radius:2px;
}
.map__zoomBar i{ display:block; height:100%; background:var(--red); border-radius:2px; }

/* ── Focus view ─────────────────────────────────────────────────
   Clicking a pin doesn't open a panel — it pulls focus. The globe falls
   back and desaturates, and the albums for that place come forward one
   after another. */
.focus{ position:absolute; inset:0; z-index:6; }
.focus__scrim{
  position:absolute; inset:0;
  background:
    radial-gradient(58% 78% at 30% 50%, rgba(6,10,18,.34) 0%, rgba(6,10,18,.80) 62%, rgba(4,7,12,.93) 100%);
  backdrop-filter:blur(3px) saturate(.55);
  /* animates in, but its resting state is visible — so it still works if the
     animation never runs */
  opacity:1; animation:focusScrim .55s var(--ease) backwards;
}
@keyframes focusScrim{ from{ opacity:0; } }

.focus__body{
  position:absolute; inset:0;
  display:flex; flex-direction:column; justify-content:center;
  gap:1.5rem;
  padding:calc(var(--nav-h) + 2rem) var(--gutter) 4rem;
  width:min(34rem,52%);
  pointer-events:none;
}
.focus__body > *{ pointer-events:auto; }

.focus__head{ animation:focusRise .6s var(--ease) backwards; }
.focus__eyebrow{
  margin:0 0 .35rem; font-size:.72rem; letter-spacing:.28em; text-transform:uppercase;
  color:var(--red); font-weight:700;
}
.focus__place{
  margin:0 0 .3rem;
  font-family:"HelveticaNeue-CondensedBlack","Helvetica Neue","Arial Narrow",sans-serif;
  font-size:clamp(2rem,4.4vw,3.4rem); font-weight:900;
  letter-spacing:.01em; line-height:.98; text-transform:uppercase;
  text-shadow:0 4px 30px rgba(0,0,0,.7);
}
.focus__meta{ margin:0; font-size:.92rem; color:rgba(255,255,255,.62); }

.focus__albums{
  display:flex; flex-direction:column; gap:.6rem;
  max-height:52vh; overflow-y:auto; padding-right:.4rem;
  scrollbar-width:none;
}
.focus__albums::-webkit-scrollbar{ width:0; }

/* each album arrives just behind the one above it */
.mapAlbum{
  display:flex; gap:.9rem; align-items:center;
  background:rgba(22,26,34,.72);
  border:1px solid rgba(255,255,255,.09);
  border-radius:8px; overflow:hidden;
  padding:.5rem .9rem .5rem .5rem; cursor:pointer;
  backdrop-filter:blur(10px);
  animation:focusRise .55s var(--ease) backwards;
  animation-delay:calc(.09s * var(--n,0) + .12s);
  transition:background-color .2s var(--ease), border-color .2s var(--ease),
             transform .2s var(--ease);
}
.mapAlbum:hover{
  background:rgba(38,44,56,.9);
  border-color:rgba(255,255,255,.28);
  transform:translateX(5px);
}
.mapAlbum__n{
  flex:0 0 auto; width:1.5rem; text-align:center;
  font-family:"HelveticaNeue-CondensedBlack","Helvetica Neue",sans-serif;
  font-size:1.35rem; font-weight:900; color:rgba(255,255,255,.28);
}
.mapAlbum img{
  width:104px; aspect-ratio:16/9; object-fit:cover;
  border-radius:5px; flex:0 0 auto;
}
.mapAlbum span{ min-width:0; }
.mapAlbum b{
  display:block; font-size:.95rem; font-weight:700; letter-spacing:-.005em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.mapAlbum small{ color:rgba(255,255,255,.5); font-size:.78rem; }

@keyframes focusRise{
  from{ opacity:0; transform:translateY(16px); }
  to{ opacity:1; transform:none; }
}

.focus__close{
  position:absolute; top:calc(var(--nav-h) + 1rem); right:1.5rem; z-index:2;
  width:40px; height:40px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.2);
  backdrop-filter:blur(8px);
  transition:background-color .2s var(--ease);
}
.focus__close:hover{ background:rgba(255,255,255,.24); }

@media (max-width:820px){
  .focus__body{ width:auto; justify-content:flex-end; padding-bottom:2rem; }
  .focus__albums{ max-height:42vh; }
}

@media (max-width:820px){
  .map__panel{ top:auto; bottom:1rem; right:1rem; left:1rem; width:auto; max-height:46%; }
  .map__hud{ bottom:auto; top:calc(var(--nav-h) + 5.5rem); }
}

/* ============================================================
   Browse — sort / group / filter
   ============================================================ */
.browse{ padding:calc(var(--nav-h) + 2.5rem) 0 4rem; min-height:70vh; }
.browse__bar{ padding:0 var(--gutter) 1.75rem; }
.browse__title{ margin:0 0 1.1rem; font-size:clamp(1.5rem,3vw,2.25rem); font-weight:700; letter-spacing:-.02em; }
.browse__controls{ display:flex; flex-wrap:wrap; gap:.65rem 1rem; align-items:flex-end; }

.ctl{
  display:flex; flex-direction:column; gap:.3rem;
  font-size:.72rem; letter-spacing:.08em; text-transform:uppercase; color:var(--text-dim2);
}
.ctl select{
  appearance:none;
  background:#000 url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M7 10l5 5 5-5z'/%3E%3C/svg%3E") no-repeat right .4rem center/1.15rem;
  border:1px solid #6d6d6d; border-radius:2px;
  color:#fff; font-size:.9rem; letter-spacing:normal; text-transform:none;
  padding:.5rem 2rem .5rem .75rem; min-width:9.5rem; cursor:pointer;
}
.ctl select:hover{ border-color:#fff; }
.ctl select:focus{ outline:2px solid #fff; outline-offset:1px; }
.ctl__reset{
  border:1px solid #6d6d6d; border-radius:2px; padding:.5rem 1rem;
  font-size:.9rem; color:var(--text-dim);
}
.ctl__reset:hover{ border-color:#fff; color:#fff; }
.browse__count{ margin:1rem 0 0; font-size:.85rem; color:var(--text-dim2); }

.browse__empty{ padding:3rem var(--gutter); color:var(--text-dim); }
.browse .row__track{ --pop-top:2.4rem; --pop-bottom:8rem; }

/* ============================================================
   Search results grid
   ============================================================ */
.results{ padding:calc(var(--nav-h) + 3rem) var(--gutter) 4rem; min-height:70vh; }
.results__title{ font-size:1.5rem; font-weight:500; color:var(--text-dim); margin:0 0 1.5rem; }
.results__title b{ color:#fff; font-weight:700; }
.results__grid{
  display:grid; gap:1.1rem var(--card-gap);
  grid-template-columns:repeat(auto-fill,minmax(clamp(150px,15.6vw,320px),1fr));
}
.results__grid .card{ width:auto; }
.results__head{
  display:flex; align-items:baseline; justify-content:space-between;
  border-top:1px solid #333; margin:2.5rem 0 1rem; padding-top:1.25rem;
}
.results__head h3{ margin:0; font-size:1.35rem; font-weight:600; }
.results__count{ color:var(--text-dim); font-size:.9rem; }
#resultsPhotos{ grid-template-columns:repeat(auto-fill,minmax(190px,1fr)); }
#resultsPhotos .ep__cap{ opacity:1; background:linear-gradient(180deg,transparent,rgba(0,0,0,.9)); }

/* ============================================================
   Detail modal
   ============================================================ */
.modal{
  position:fixed; inset:0; z-index:150;
  overflow-y:auto; overscroll-behavior:contain;
  padding:3.5rem 0 4rem;
}
.modal__backdrop{
  position:fixed; inset:0; background:rgba(0,0,0,.72);
  opacity:0; transition:opacity .4s var(--ease);
}
.modal.is-in .modal__backdrop{ opacity:1; }
.modal__card{
  position:relative;
  width:min(56rem,92vw); margin:0 auto;
  background:var(--bg-2); border-radius:6px; overflow:hidden;
  box-shadow:0 20px 70px rgba(0,0,0,.8);
  transform-origin:top left;
  will-change:transform, opacity;
}
/* The body fades in just behind the expanding artwork, so the card grows
   first and the text settles a beat later. */
.modal__info, .modal__episodes, .modal__heroBody, .modal__close{
  opacity:0; transition:opacity .3s var(--ease) .18s;
}
.modal.is-in .modal__info,
.modal.is-in .modal__episodes,
.modal.is-in .modal__heroBody,
.modal.is-in .modal__close{ opacity:1; }

.modal__close{
  position:absolute; top:1rem; right:1rem; z-index:5;
  width:36px; height:36px; border-radius:50%;
  background:#181818; display:grid; place-items:center;
}
.modal__close:hover{ background:#2a2a2a; }

.modal__hero{ position:relative; aspect-ratio:16/9; background:#000; }
.modal__hero img{ width:100%; height:100%; object-fit:cover; }
.modal__heroFade{
  position:absolute; inset:0;
  background:linear-gradient(180deg,rgba(24,24,24,0) 40%,rgba(24,24,24,.75) 78%,var(--bg-2) 100%);
}
.modal__heroBody{ position:absolute; left:clamp(1.25rem,3.5%,3rem); right:3rem; bottom:1.5rem; }
.modal__title{
  margin:0 0 1.1rem; font-size:clamp(1.6rem,3.4vw,2.9rem); font-weight:800; letter-spacing:-.025em;
  text-shadow:0 3px 14px rgba(0,0,0,.7);
}
.modal__actions{ display:flex; align-items:center; gap:.7rem; }

.modal__info{
  display:grid; grid-template-columns:1.6fr 1fr; gap:1.5rem 2.5rem;
  padding:1.5rem clamp(1.25rem,3.5%,3rem);
}
.modal__meta{
  display:flex; align-items:center; gap:.7rem; flex-wrap:wrap;
  margin:0 0 .9rem; font-size:.95rem; color:#ddd;
}
.modal__synopsis{ margin:0; font-size:1.05rem; line-height:1.5; }
.modal__col--side{ font-size:.85rem; line-height:1.7; }
.modal__col--side p{ margin:0 0 .35rem; }
.dim{ color:var(--text-dim2); }

.modal__episodes{ padding:0 clamp(1.25rem,3.5%,3rem) 2rem; }
.modal__episodesHead{
  display:flex; align-items:baseline; justify-content:space-between;
  border-top:1px solid #333; padding-top:1.25rem; margin-bottom:1rem;
}
.modal__episodesHead h3{ margin:0; font-size:1.35rem; font-weight:600; }
.modal__count{ color:var(--text-dim); font-size:.9rem; }

/* ── Clips ──────────────────────────────────────────────────────
   Given their own shelf above the photographs, and drawn wider, so it's
   obvious at a glance which of the two you're about to sit down to. */
.clipgrid{
  display:grid; gap:.7rem;
  grid-template-columns:repeat(auto-fill,minmax(230px,1fr));
}

/* Episodes are listed, not tiled. Half an hour each deserves a line of its
   own with a number, a length and a sentence — a grid of identical stills
   tells you nothing about which one you are picking. */
.eplist{ display:flex; flex-direction:column; }
.epr{
  display:grid; grid-template-columns:2.4rem 150px 1fr; align-items:center;
  gap:1rem; padding:.85rem .6rem; cursor:pointer;
  border-top:1px solid rgba(255,255,255,.09);
  transition:background-color .22s var(--ease);
}
.epr:last-child{ border-bottom:1px solid rgba(255,255,255,.09); }
.epr:hover{ background:rgba(255,255,255,.06); }
.epr__n{
  text-align:center; font-size:1.35rem; font-weight:500;
  color:rgba(255,255,255,.55);
}
.epr__still{
  position:relative; display:block; aspect-ratio:16/9;
  border-radius:4px; overflow:hidden; background:#000;
}
.epr__still img{ width:100%; height:100%; object-fit:cover; transition:opacity .25s; }
.epr:hover .epr__still img{ opacity:.6; }
.epr__play{
  position:absolute; inset:0; display:grid; place-items:center;
  opacity:0; transition:opacity .25s var(--ease); pointer-events:none;
}
.epr:hover .epr__play{ opacity:1; }
.epr__body{ display:block; min-width:0; }
.epr__head{
  display:flex; align-items:baseline; gap:.75rem; margin-bottom:.28rem;
}
.epr__head b{ font-size:.95rem; font-weight:600; }
.epr__len{ margin-left:auto; font-size:.82rem; color:rgba(255,255,255,.6); }
.epr__syn{
  display:block; font-size:.82rem; line-height:1.45;
  color:rgba(255,255,255,.62);
}
@media (max-width:820px){
  .epr{ grid-template-columns:1.7rem 108px 1fr; gap:.65rem; padding:.7rem .2rem; }
  .epr__n{ font-size:1rem; }
  .epr__head b{ font-size:.86rem; }
  .epr__syn{ font-size:.76rem; }
}
.clip{
  position:relative; aspect-ratio:16/9; border-radius:5px; overflow:hidden;
  background:#000; cursor:pointer;
}
.clip img{ width:100%; height:100%; object-fit:cover; transition:transform .4s var(--ease), opacity .3s; }
.clip:hover img{ transform:scale(1.05); opacity:.85; }
.clip__play{
  position:absolute; inset:0; display:grid; place-items:center;
  pointer-events:none;
}
.clip__play span{
  width:46px; height:46px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(10,12,18,.55); backdrop-filter:blur(6px);
  border:1.5px solid rgba(255,255,255,.75);
  transition:transform .25s var(--ease), background-color .25s var(--ease);
}
.clip:hover .clip__play span{ transform:scale(1.12); background:rgba(229,9,20,.9); border-color:transparent; }
.clip__len{
  position:absolute; right:.45rem; bottom:.45rem;
  background:rgba(0,0,0,.72); border-radius:3px;
  padding:.1rem .35rem; font-size:.7rem; font-weight:700; letter-spacing:.02em;
}
.clip__cap{
  position:absolute; left:0; right:0; bottom:0;
  padding:1.4rem .55rem .45rem;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.85));
  font-size:.74rem; opacity:0; transition:opacity .2s var(--ease);
}
.clip:hover .clip__cap{ opacity:1; }

.btn--clips{ background:rgba(255,255,255,.92); }
.btn--clips:hover{ background:#fff; }

/* ── The cinema frame ───────────────────────────────────────────
   A phone films 16:9; a film is wider than that. The clip is cropped to a
   scope ratio and pushed out to the full width, so it sits in black bars
   like something projected rather than something uploaded. */
.cinema{
  position:absolute; inset:0; z-index:2;
  display:grid; place-items:center;
  background:#000;
}
.cinema__video{
  width:100%;
  aspect-ratio:2.39 / 1;
  max-height:100%;
  object-fit:cover;              /* the crop that makes the bars */
  display:block;
  background:#000;
}
/* A clip already shot tall would be gutted by that crop, so it keeps its
   own shape and the bars move to the sides instead. */
.cinema.is-tall .cinema__video{
  width:auto; height:100%; aspect-ratio:auto; object-fit:contain;
}

/* ── The transport ──────────────────────────────────────────────
   The browser's own controls looked like a browser. This is the site's. */
.vbar{
  position:absolute; left:0; right:0; bottom:0; z-index:6;
  padding:3.5rem clamp(1rem,3vw,2.6rem) clamp(1rem,2.4vh,1.8rem);
  background:linear-gradient(0deg,rgba(0,0,0,.86) 20%,rgba(0,0,0,.45) 60%,transparent 100%);
  opacity:1; transition:opacity .35s var(--ease);
}
.player.is-idle .vbar{ opacity:0; pointer-events:none; }

.vbar__scrub{
  position:relative; height:3px; border-radius:3px;
  background:rgba(255,255,255,.28);
  cursor:pointer; margin-bottom:.9rem;
  transition:height .18s var(--ease);
}
.vbar__scrub:hover{ height:6px; }
.vbar__buffered{
  position:absolute; inset:0 auto 0 0; width:0;
  background:rgba(255,255,255,.4); border-radius:inherit;
}
.vbar__played{
  position:absolute; inset:0 auto 0 0; width:0;
  background:var(--red); border-radius:inherit;
}
.vbar__knob{
  position:absolute; right:0; top:50%;
  width:13px; height:13px; margin:-6.5px -6.5px 0 0;
  border-radius:50%; background:var(--red);
  transform:scale(0); transition:transform .18s var(--ease);
}
.vbar__scrub:hover .vbar__knob{ transform:scale(1); }

.vbar__row{ display:flex; align-items:center; gap:.35rem; }
.vbar__btn{
  width:40px; height:40px; border-radius:50%;
  display:grid; place-items:center; color:#fff;
  transition:background-color .18s var(--ease), transform .18s var(--ease);
}
.vbar__btn:hover{ background:rgba(255,255,255,.16); transform:scale(1.06); }
.vbar__btn--full{ margin-left:auto; }
.vbar__btn.is-muted{ color:rgba(255,255,255,.4); }
.vbar__time{
  margin:0 .3rem 0 .5rem; font-size:.82rem; font-weight:600;
  color:rgba(255,255,255,.8); font-variant-numeric:tabular-nums;
}
.vbar__label{
  margin:0 0 0 1rem; font-size:.85rem; font-weight:600;
  color:rgba(255,255,255,.55);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}

/* ── Up next ────────────────────────────────────────────────────
   Slides in near the end, with the ring counting down. Clicking goes now;
   ignoring it lets the clip finish first. */
/* Up next — a still from the coming clip with the type sitting on it, the
   way a card in a row looks. It waits to be pressed; nothing rolls on by
   itself. */
.upnext{
  position:absolute; right:clamp(1rem,3vw,2.6rem); bottom:clamp(5.5rem,12vh,7.5rem);
  z-index:7;
  display:flex; align-items:stretch; gap:0;
  padding:0; overflow:hidden;
  width:min(19rem,60vw);
  border:0; border-radius:6px;
  background:rgba(14,14,16,.82); backdrop-filter:blur(20px) saturate(1.2);
  box-shadow:0 1px 0 rgba(255,255,255,.1) inset, 0 22px 60px rgba(0,0,0,.7);
  text-align:left;
  animation:upnextIn .5s cubic-bezier(.22,.9,.3,1) backwards;
  transition:transform .28s var(--ease), box-shadow .28s var(--ease);
}
@keyframes upnextIn{ from{ opacity:0; transform:translateX(34px) scale(.96); } }
.upnext:hover{ transform:translateY(-3px); box-shadow:0 1px 0 rgba(255,255,255,.16) inset, 0 28px 70px rgba(0,0,0,.78); }

.upnext__thumb{ position:relative; width:44%; flex:0 0 auto; overflow:hidden; }
.upnext__thumb::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(90deg,rgba(14,14,16,0) 40%,rgba(14,14,16,.9) 100%);
}
.upnext__thumb img{
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .5s var(--ease);
}
.upnext:hover .upnext__thumb img{ transform:scale(1.06); }

.upnext__body{
  display:flex; flex-direction:column; justify-content:center; gap:.2rem;
  padding:.85rem .5rem .85rem .2rem; min-width:0; flex:1 1 auto;
}
.upnext__label{
  font-size:.62rem; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(255,255,255,.5); font-weight:700;
  font-variant-numeric:tabular-nums;
}
.upnext.is-ready .upnext__label{ color:var(--red); }
.upnext__title{
  font-size:.92rem; font-weight:700; letter-spacing:-.01em;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.upnext__go{
  flex:0 0 auto; width:52px;
  display:grid; place-items:center;
  color:#fff;
  border-left:1px solid rgba(255,255,255,.1);
  transition:background-color .25s var(--ease), color .25s var(--ease);
}
.upnext:hover .upnext__go{ background:var(--red); }
/* once the clip has finished, the button asks for attention */
.upnext.is-ready .upnext__go{
  background:rgba(229,9,20,.9);
  animation:upnextPulse 2s ease-in-out infinite;
}
@keyframes upnextPulse{ 50%{ background:rgba(229,9,20,.55); } }

/* ── The opener ─────────────────────────────────────────────────
   Shapes and a synthesised tone rather than a film — a few kilobytes,
   sharp on any screen, and it begins the moment it's called. */
/* The length is set by the sting in music/ — the picture holds until the
   sound has finished rather than cutting out under it. */
.intro{
  position:absolute; inset:0; z-index:9;
  background:#000;
  display:grid; place-items:center;
  animation:introOut .55s var(--ease) 3.55s forwards;
}
@keyframes introOut{ to{ opacity:0; visibility:hidden; } }

.intro__stage{ position:relative; display:grid; place-items:center; }

.intro__mark{
  position:relative; z-index:2;
  font-family:"HelveticaNeue-CondensedBlack","Helvetica Neue","Arial Narrow",sans-serif;
  font-size:clamp(7rem,26vw,20rem); font-weight:900; line-height:1;
  letter-spacing:-.04em;
  color:var(--red);
  transform:scaleY(1.22) scale(.82);
  opacity:0;
  animation:introMark 3.6s cubic-bezier(.16,.9,.24,1) forwards;
  text-shadow:0 0 60px rgba(229,9,20,.5);
}
@keyframes introMark{
  0%   { opacity:0; transform:scaleY(1.22) scale(.82); filter:blur(14px); }
  13%  { opacity:1; transform:scaleY(1.22) scale(1); filter:blur(0); }
  70%  { opacity:1; transform:scaleY(1.22) scale(1.03); }
  100% { opacity:1; transform:scaleY(1.22) scale(1.07); }
}

/* a band of light crossing the letter on the beat */
.intro__sweep{
  position:absolute; inset:-20% -60%; z-index:3;
  background:linear-gradient(105deg,transparent 42%,rgba(255,255,255,.85) 50%,transparent 58%);
  transform:translateX(-60%);
  opacity:0;
  animation:introSweep .85s cubic-bezier(.3,.6,.2,1) .5s forwards;
  mix-blend-mode:overlay;
  pointer-events:none;
}
@keyframes introSweep{
  0%{ opacity:0; transform:translateX(-60%); }
  30%{ opacity:1; }
  100%{ opacity:0; transform:translateX(60%); }
}

.intro__shards{ position:absolute; inset:0; z-index:1; pointer-events:none; }
.shard{
  position:absolute; left:50%; top:50%;
  width:var(--w,3px); height:var(--h,26px);
  background:var(--c,#e50914);
  border-radius:2px;
  opacity:0;
  transform:translate(-50%,-50%);
  animation:shardOut var(--d,1.3s) cubic-bezier(.12,.7,.2,1) var(--delay,.5s) forwards;
}
@keyframes shardOut{
  0%{ opacity:0; transform:translate(-50%,-50%) rotate(var(--r,0deg)) translateY(0) scaleY(.4); }
  18%{ opacity:1; }
  100%{ opacity:0;
        transform:translate(-50%,-50%) rotate(var(--r,0deg)) translateY(var(--dist,40vh)) scaleY(1.6); }
}

@media (prefers-reduced-motion:reduce){
  .intro__mark, .intro__sweep, .shard{ animation-duration:.01ms !important; }
  .intro{ animation-delay:.3s; }
}

@media (max-width:820px){
  .vbar{ padding:2.6rem 1rem 1rem; }
  .vbar__label{ display:none; }

  /* On a phone the card ran off the right edge and sat on top of the
     transport. It spans the width instead and stands clear above it. */
  .upnext{
    left:1rem; right:1rem; width:auto;
    bottom:8.25rem;
  }
  .upnext__thumb{ width:38%; }
  .upnext__body{ padding:.7rem .5rem .7rem .2rem; }
  .upnext__title{ font-size:.86rem; }
  .upnext__go{ width:46px; }
}
/* Watching footage, the slideshow controls have nothing to act on — the
   clip brings its own transport bar. */
.player.is-clips .player__stage{ background:#000; }
.player.is-clips #playerSlideshow,
.player.is-clips #playerFit,
.player.is-clips #playerMute{ display:none; }
/* the site's own transport replaces the stills scrubber */
.player.is-clips .player__bottom{ display:none; }

/* The way out has to stay put. With the chrome fading on idle there was no
   arrow to reach for, which left the Escape key as the only exit. */
.player.is-clips.is-idle .player__chrome{ opacity:1; }
.player.is-clips.is-idle .player__nav{ opacity:0; pointer-events:none; }
.player.is-clips .player__chrome{ transition:opacity .35s var(--ease); }
.player.is-clips .player__nav{ transition:opacity .35s var(--ease); }
.player.is-clips .player__back{
  background:rgba(10,12,18,.5); backdrop-filter:blur(8px);
  border-radius:50%; width:44px; height:44px;
  display:grid; place-items:center;
  transition:background-color .2s var(--ease), transform .2s var(--ease);
}
.player.is-clips .player__back:hover{ background:rgba(255,255,255,.2); transform:scale(1.06); }
.player.is-clips .player__top{
  background:linear-gradient(180deg,rgba(0,0,0,.72),transparent);
}

.epgrid{
  display:grid; gap:.6rem;
  grid-template-columns:repeat(auto-fill,minmax(150px,1fr));
}
.ep{
  position:relative; aspect-ratio:3/2; border-radius:4px; overflow:hidden;
  background:#000; cursor:pointer;
}
.ep img{ width:100%; height:100%; object-fit:cover; transition:transform .35s var(--ease), opacity .3s; }
.ep:hover img{ transform:scale(1.06); }
.ep__num{
  position:absolute; top:.35rem; left:.45rem;
  font-size:.7rem; font-weight:700; color:#fff;
  text-shadow:0 1px 4px rgba(0,0,0,.9);
}
.ep__cap{
  position:absolute; left:0; right:0; bottom:0;
  padding:1.5rem .5rem .4rem;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.85));
  font-size:.72rem; opacity:0; transition:opacity .2s var(--ease);
}
.ep:hover .ep__cap{ opacity:1; }

/* ============================================================
   Player / lightbox
   ============================================================ */
/* Going in and coming out of the viewer is a change of room, so it's given
   a moment rather than a cut. */
.player{
  position:fixed; inset:0; z-index:180; background:#000;
  opacity:0;
  transition:opacity .38s var(--ease);
}
.player.is-in{ opacity:1; }
.player.is-leaving{ opacity:0; transition-duration:.3s; }
.player__stage{ position:absolute; inset:0; overflow:hidden; }

.player__layer{
  position:absolute; inset:0;
  opacity:0;
  transition:opacity var(--fade,900ms) cubic-bezier(.4,0,.2,1);
}
.player__layer.is-on{ opacity:1; }

/* the same photo, blown up and blurred, filling whatever the sharp one
   doesn't — turns dead black bars into something that belongs to the shot */
.player__bg{
  position:absolute; inset:-6%;
  background-position:center; background-size:cover;
  filter:blur(46px) saturate(1.5) brightness(.55);
  transform:scale(1.1);
  opacity:0;
  transition:opacity 500ms ease;
}

.player__frames{
  position:absolute; inset:0;
  display:flex; align-items:center; justify-content:center;
  gap:0;
}
.player__frames img{
  display:block; min-width:0; min-height:0;
  max-width:100%; max-height:100%;
  width:100%; height:100%;
  object-fit:contain;
  transition:transform calc(var(--dwell,5s) + var(--fade,900ms)) linear;
}
/* a slow drift while each frame is held — alive, but not readable as motion */
.player.is-playing .player__layer.is-on img{ transform:scale(1.045); }

/* ── fit modes ──────────────────────────────────────────────── */

/* FILL — crop to the screen. Cinematic for landscape, brutal on portraits. */
.player.fit-fill .player__frames img{ object-fit:cover; }

/* BLUR — sharp photo untouched, blurred copy behind it (default) */
.player.fit-blur .player__bg{ opacity:1; }
.player.fit-blur .player__frames img{ object-fit:contain; }
/* landscape still fills the screen; only portraits keep their shape */
.player.fit-blur .player__frames img[data-shape="wide"]{ object-fit:cover; }

/* PAIR — two portraits share the screen, landscape runs full width */
.player.fit-pair .player__bg{ opacity:1; }
.player.fit-pair .player__frames{ gap:2px; padding:0; }
.player.fit-pair .player__frames img{ object-fit:contain; }
.player.fit-pair .player__frames img[data-shape="wide"]{ object-fit:cover; }
.player.fit-pair .player__frames.is-pair img{ width:50%; object-fit:cover; }

/* ── FRAME — the print on a gallery wall ──────────────────────────
   The default. A warm paper ground, a white mat and a soft shadow, so a
   portrait sits on the wall rather than stranded between black bars. */
.player.fit-frame{ background:#dedbd4; }
.player.fit-frame .player__stage{
  background:
    radial-gradient(120% 100% at 50% 22%, #f2f0ea 0%, #e4e1d9 58%, #d3cfc5 100%);
}
.player.fit-frame .player__bg{ opacity:0; }

/* Enough wall around the print to read as hung, not so much that the photo
   shrinks — the top and bottom clear the chrome, the sides stay tight. */
.player.fit-frame .player__frames{
  padding:clamp(1.4rem,4.5vh,3rem) clamp(.9rem,2.2vw,2.2rem) clamp(2rem,6.5vh,3.6rem);
  gap:clamp(.9rem,2vw,2.2rem);
}
.player.fit-frame .player__frames img{
  object-fit:contain;
  width:auto; height:auto;
  max-width:100%; max-height:100%;
  background:#fff;
  padding:clamp(.5rem,1.1vh,1.1rem);
  box-shadow:0 2px 4px rgba(60,50,40,.16),
             0 18px 48px rgba(60,50,40,.30);
}
/* two prints hung together */
.player.fit-frame .player__frames.is-pair img{ max-width:calc(50% - 1.3rem); }

/* the chrome has to flip to dark-on-light or it fights the paper */
.player.fit-frame .player__top{
  background:linear-gradient(180deg,rgba(244,242,236,.96) 0%,rgba(244,242,236,0) 100%);
  color:#1c1a17;
}
.player.fit-frame .player__bottom{
  background:linear-gradient(0deg,rgba(244,242,236,.96) 0%,rgba(244,242,236,0) 100%);
  color:#1c1a17;
}
.player.fit-frame .player__caption{ color:#6a6459; }
.player.fit-frame .player__caption .who{ color:#1c1a17; }
.player.fit-frame .player__caption .tags{ color:#8c8579; }
.player.fit-frame .player__index{ color:#6a6459; }
.player.fit-frame .player__slideshow,
.player.fit-frame .player__fit,
.player.fit-frame .player__mute{ border-color:rgba(28,26,23,.35); }
.player.fit-frame .player__slideshow:hover,
.player.fit-frame .player__fit:hover,
.player.fit-frame .player__mute:hover{ background:rgba(28,26,23,.1); }
.player.fit-frame .player__slideshow.is-on{ background:#1c1a17; color:#f4f2ec; border-color:#1c1a17; }
.player.fit-frame .player__nav{ background:rgba(255,255,255,.72); color:#1c1a17; }
.player.fit-frame .player__nav:hover{ background:#fff; }
.player.fit-frame .player__scrub i{ background:rgba(28,26,23,.2); }
.player.fit-frame .player__scrub i.is-seen{ background:rgba(28,26,23,.42); }
.player.fit-frame .player__scrub i.is-now{ background:var(--red); }

.player__fit{
  border:1px solid rgba(255,255,255,.5); border-radius:4px;
  padding:.4rem .85rem; font-size:.82rem; font-weight:600;
  flex:0 0 auto; white-space:nowrap;
}
.player__fit:hover{ background:rgba(255,255,255,.15); }

/* ── Saving a photo ─────────────────────────────────────────────
   Everything is already on the machine, so this is just a download — but
   it should feel like lifting a print out of the box, not clicking a link. */
.player__save{
  display:inline-flex; align-items:center; gap:.45rem;
  border:1px solid rgba(255,255,255,.5); border-radius:4px;
  padding:.4rem .85rem; font-size:.82rem; font-weight:600;
  flex:0 0 auto; white-space:nowrap;
  transition:background-color .18s var(--ease), border-color .18s var(--ease);
}
.player__save:hover{ background:#fff; color:#000; border-color:#fff; }
.player__save svg{ transition:transform .25s var(--ease); }
.player__save:hover svg{ transform:translateY(2px); }
.player.fit-frame .player__save{ border-color:rgba(28,26,23,.35); }
.player.fit-frame .player__save:hover{ background:#1c1a17; color:#f4f2ec; border-color:#1c1a17; }

/* the button that appears over a photo in the grid */
.ep__save{
  position:absolute; top:.4rem; right:.4rem; z-index:2;
  width:30px; height:30px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(10,12,18,.62); color:#fff;
  border:1px solid rgba(255,255,255,.28);
  backdrop-filter:blur(8px);
  opacity:0; transform:translateY(-4px) scale(.9);
  transition:opacity .2s var(--ease), transform .2s var(--ease),
             background-color .2s var(--ease);
}
.ep:hover .ep__save{ opacity:1; transform:none; }
.ep__save:hover{ background:#fff; color:#000; border-color:#fff; }
.ep__save.is-done{ background:var(--green); color:#08240f; border-color:transparent; opacity:1; }

.toast{
  position:fixed; left:50%; bottom:2.5rem; transform:translateX(-50%) translateY(14px);
  z-index:400;
  display:flex; align-items:center; gap:.6rem;
  background:rgba(20,22,28,.94); backdrop-filter:blur(14px);
  border:1px solid rgba(255,255,255,.14); border-radius:999px;
  padding:.7rem 1.35rem;
  font-size:.9rem; font-weight:600;
  box-shadow:0 14px 44px rgba(0,0,0,.6);
  opacity:0; transition:opacity .28s var(--ease), transform .28s var(--ease);
  pointer-events:none;
}
.toast svg{ color:var(--green); }
.toast.is-up{ opacity:1; transform:translateX(-50%) translateY(0); }

.player__mute{
  width:40px; height:40px; border-radius:50%;
  border:1px solid rgba(255,255,255,.5);
  display:grid; place-items:center; flex:0 0 auto;
}
.player__mute:hover{ background:rgba(255,255,255,.15); }
.player__mute.is-muted{ opacity:.45; }
.player__credit{ color:var(--text-dim2); }
.player__credit:not(:empty)::before{ content:" · "; }

.player__chrome{
  position:absolute; inset:0;
  z-index:5;              /* above the clip, or the way out sits behind it */
  opacity:1; transition:opacity .4s var(--ease);
}
/* the chrome covers the whole viewer, so only its controls take the pointer */
.player__chrome{ pointer-events:none; }
.player__top, .player__bottom, .player__nav, .cast, .notes{ pointer-events:auto; }
.player.is-idle .player__chrome{ opacity:0; }
.player.is-idle{ cursor:none; }

.player__top{
  position:absolute; top:0; left:0; right:0;
  display:flex; align-items:center; gap:1.25rem;
  padding:1.25rem clamp(1rem,3vw,2.5rem);
  background:linear-gradient(180deg,rgba(0,0,0,.8),transparent);
}
.player__titles{ flex:1 1 auto; min-width:0; }
.player__collection{ margin:0; font-size:1.05rem; font-weight:700; }
.player__caption{ margin:.15rem 0 0; font-size:.85rem; color:var(--text-dim); }
.player__caption .who{ color:#fff; font-weight:600; }
.player__caption .tags{ color:var(--text-dim2); }
/* ── Tools ──────────────────────────────────────────────────────
   No boxes, no rings. Just the mark and its name, sitting on the image —
   they come forward when you reach for them and stay out of the way when
   you don't. */
.tools{ display:flex; align-items:center; gap:.15rem; flex:0 0 auto; }

.tool{
  display:inline-flex; align-items:center; gap:.42rem;
  padding:.5rem .7rem;
  font-size:.78rem; font-weight:600; letter-spacing:.02em;
  color:rgba(255,255,255,.72);
  border:0; background:none; border-radius:10px;
  transition:color .2s var(--ease), background-color .2s var(--ease),
             transform .2s var(--ease);
}
.tool svg{ opacity:.9; transition:transform .25s var(--ease); }
.tool:hover{
  color:#fff;
  background:rgba(255,255,255,.1);
  transform:translateY(-1px);
}
.tool:active{ transform:translateY(0); }
.tool--icon{ padding:.5rem; }
.tool.is-on{ color:#fff; }
.tool.is-on svg{ opacity:1; }
.tool.is-muted{ color:rgba(255,255,255,.34); }
#playerSave:hover svg{ transform:translateY(2px); }

/* on the gallery wall the tools invert */
.player.fit-frame .tool{ color:rgba(28,26,23,.62); }
.player.fit-frame .tool:hover{ color:#1c1a17; background:rgba(28,26,23,.09); }
.player.fit-frame .tool.is-on{ color:#1c1a17; }

/* ── Comments ───────────────────────────────────────────────────
   A column down the right of the frame. Kept narrow so the photograph is
   still the thing you're looking at, and translucent so it belongs to the
   image rather than covering it. */
.notes{
  position:absolute; top:0; right:0; bottom:0; z-index:6;
  width:min(23rem,34vw);
  display:flex; flex-direction:column;
  background:linear-gradient(270deg,rgba(10,12,18,.94) 68%,rgba(10,12,18,0) 100%);
  backdrop-filter:blur(16px);
  padding:calc(var(--nav-h) + .5rem) 1.15rem 1.1rem 1.6rem;
  animation:notesIn .32s var(--ease) backwards;
}
@keyframes notesIn{ from{ opacity:0; transform:translateX(22px); } }

.notes__head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:.9rem; }
.notes__title{
  margin:0; font-size:.68rem; letter-spacing:.24em; text-transform:uppercase;
  color:rgba(255,255,255,.45);
}
.notes__close{
  width:26px; height:26px; border-radius:50%; display:grid; place-items:center;
  color:rgba(255,255,255,.5);
}
.notes__close:hover{ background:rgba(255,255,255,.12); color:#fff; }

.notes__list{
  flex:1 1 auto; overflow-y:auto; scrollbar-width:none;
  display:flex; flex-direction:column; gap:.7rem;
  padding-right:.2rem;
}
.notes__list::-webkit-scrollbar{ width:0; }

.note{ display:flex; gap:.6rem; align-items:flex-start; }
.note__face{
  width:26px; height:26px; border-radius:50%; flex:0 0 auto;
  display:grid; place-items:center;
  font-size:.72rem; font-weight:700; color:#fff;
}
.note__body{ min-width:0; }
.note__who{ font-size:.78rem; font-weight:700; }
.note__when{ font-size:.68rem; color:rgba(255,255,255,.35); margin-left:.4rem; font-weight:500; }
.note__text{ margin:.1rem 0 0; font-size:.85rem; line-height:1.45; color:rgba(255,255,255,.86); overflow-wrap:anywhere; }
.note__bin{
  margin-left:auto; align-self:center; flex:0 0 auto;
  color:rgba(255,255,255,.25); font-size:.9rem; padding:.2rem .3rem;
  opacity:0; transition:opacity .18s var(--ease), color .18s var(--ease);
}
.note:hover .note__bin{ opacity:1; }
.note__bin:hover{ color:var(--red); }

.notes__empty{ margin:0; font-size:.85rem; color:rgba(255,255,255,.35); line-height:1.6; }

.notes__form{ display:flex; gap:.5rem; align-items:center; margin-top:.9rem; }
.notes__input{
  flex:1 1 auto; min-width:0;
  background:rgba(255,255,255,.09);
  border:1px solid rgba(255,255,255,.14); border-radius:999px;
  padding:.6rem .95rem; color:#fff; font-size:.85rem; outline:0;
  transition:border-color .2s var(--ease), background-color .2s var(--ease);
}
.notes__input:focus{ border-color:rgba(255,255,255,.45); background:rgba(255,255,255,.14); }
.notes__input::placeholder{ color:rgba(255,255,255,.32); }
.notes__send{
  width:36px; height:36px; border-radius:50%; flex:0 0 auto;
  display:grid; place-items:center;
  background:var(--red); color:#fff;
  transition:transform .18s var(--ease), opacity .18s var(--ease);
}
.notes__send:hover{ transform:scale(1.08); }
.notes__send:disabled{ opacity:.3; transform:none; }
.notes__who{
  margin:.55rem 0 0; font-size:.68rem; color:rgba(255,255,255,.3);
  letter-spacing:.04em;
}

.player.fit-frame .notes{
  background:linear-gradient(270deg,rgba(248,247,243,.96) 68%,rgba(248,247,243,0) 100%);
  color:#1c1a17;
}
.player.fit-frame .notes__title,
.player.fit-frame .notes__when,
.player.fit-frame .notes__who,
.player.fit-frame .notes__empty{ color:rgba(28,26,23,.45); }
.player.fit-frame .note__text{ color:rgba(28,26,23,.82); }
.player.fit-frame .notes__input{
  background:rgba(28,26,23,.06); border-color:rgba(28,26,23,.18); color:#1c1a17;
}
.player.fit-frame .notes__input::placeholder{ color:rgba(28,26,23,.38); }

@media (max-width:820px){
  .notes{ width:auto; left:0; top:auto; height:58%;
    background:linear-gradient(0deg,rgba(10,12,18,.96) 76%,rgba(10,12,18,0) 100%);
    padding:1.2rem 1.1rem 1.1rem; }
}

/* ── Who's in the photo ─────────────────────────────────────── */
.cast{
  position:absolute; top:calc(100% + .4rem); right:clamp(1rem,3vw,2.5rem);
  z-index:5;
  min-width:12rem; max-width:18rem;
  background:rgba(18,20,26,.9); backdrop-filter:blur(18px) saturate(1.2);
  border:1px solid rgba(255,255,255,.12); border-radius:12px;
  padding:.85rem .9rem;
  box-shadow:0 18px 48px rgba(0,0,0,.55);
  animation:castIn .28s var(--ease) backwards;
}
@keyframes castIn{ from{ opacity:0; transform:translateY(-8px); } }
.cast__head{
  margin:0 0 .6rem; font-size:.66rem; letter-spacing:.22em; text-transform:uppercase;
  color:rgba(255,255,255,.45);
}
.cast__list{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.3rem; }
.cast__item{
  display:flex; align-items:center; gap:.6rem;
  padding:.35rem .45rem; border-radius:8px; cursor:pointer;
  transition:background-color .18s var(--ease);
}
.cast__item:hover{ background:rgba(255,255,255,.1); }
.cast__face{
  width:30px; height:30px; border-radius:50%;
  display:grid; place-items:center; flex:0 0 auto;
  font-size:.82rem; font-weight:700; color:#fff;
}
.cast__name{ font-size:.9rem; font-weight:600; }
.cast__n{ margin-left:auto; font-size:.72rem; color:rgba(255,255,255,.4); }
.cast__none{ font-size:.85rem; color:rgba(255,255,255,.45); margin:0; }

.player.fit-frame .cast{
  background:rgba(250,249,245,.94); border-color:rgba(28,26,23,.14); color:#1c1a17;
}
.player.fit-frame .cast__head{ color:rgba(28,26,23,.45); }
.player.fit-frame .cast__item:hover{ background:rgba(28,26,23,.08); }
.player.fit-frame .cast__n{ color:rgba(28,26,23,.45); }
.player.fit-frame .cast__none{ color:rgba(28,26,23,.5); }

.player__nav{
  position:absolute; top:50%; transform:translateY(-50%);
  width:64px; height:64px; border-radius:50%;
  display:grid; place-items:center;
  background:rgba(20,20,20,.5);
}
.player__nav:hover{ background:rgba(20,20,20,.85); }
.player__nav--prev{ left:clamp(.75rem,2vw,2rem); }
.player__nav--next{ right:clamp(.75rem,2vw,2rem); }

.player__bottom{
  position:absolute; bottom:0; left:0; right:0;
  padding:2.5rem clamp(1rem,3vw,2.5rem) 1.5rem;
  background:linear-gradient(0deg,rgba(0,0,0,.8),transparent);
}
.player__scrub{
  display:flex; gap:2px; height:4px; margin-bottom:.6rem;
  border-radius:2px; overflow:hidden;
}
.player__scrub i{ flex:1 1 0; background:rgba(255,255,255,.28); border-radius:1px; cursor:pointer; }
.player__scrub i.is-seen{ background:rgba(255,255,255,.55); }
.player__scrub i.is-now{ background:var(--red); }
.player__index{ margin:0; font-size:.8rem; color:var(--text-dim); }

/* ============================================================
   Footer
   ============================================================ */
.footer{
  padding:3rem var(--gutter) 4rem;
  color:var(--text-dim2); font-size:.82rem; line-height:1.6;
  border-top:1px solid #222;
}
.footer__brand{ color:var(--red); font-weight:800; letter-spacing:.06em; margin:0 0 .5rem; }

/* ============================================================
   Responsive
   ============================================================ */
/* ── Phones ──────────────────────────────────────────────────────
   The layout above is left exactly as it is on a laptop. This is a
   separate arrangement for a hand: the billboard stands tall like a
   poster, the sections become a strip you thumb along, and one card takes
   most of the width with the next one peeking so it reads as a row rather
   than a grid that happens to be cut off. */
@media (max-width:820px){
  :root{ --gutter:1rem; --nav-h:56px; }

  .modal__info{ grid-template-columns:1fr; }

  /* the bar */
  .nav{ padding:0 var(--gutter); gap:.5rem; }
  .nav__left{ gap:.6rem; flex:1 1 auto; min-width:0; }
  .nav__right{ gap:.45rem; flex:0 0 auto; }
  .brand{ font-size:1.02rem; }
  .years__now{ padding:.3rem .45rem; font-size:.76rem; }
  .avatar{ width:28px; height:28px; font-size:.78rem; }

  /* Hiding these left Travel, People and the map unreachable on a phone.
     They become a scrolling strip under the bar instead. */
  .nav__links{
    display:flex;
    position:fixed; left:0; right:0; top:var(--nav-h);
    padding:.4rem var(--gutter) .5rem;
    gap:.28rem;
    overflow-x:auto; scrollbar-width:none;
    background:linear-gradient(180deg,rgba(0,0,0,.8),rgba(0,0,0,0));
    -webkit-overflow-scrolling:touch;
  }
  .nav__links::-webkit-scrollbar{ display:none; }
  .nav__link{ flex:0 0 auto; font-size:.8rem; padding:.32rem .68rem; }
  .nav__divider{ height:.9rem; margin:0 .28rem; }
  .nav.is-searching .nav__links{ opacity:0; }

  /* the billboard */
  .hero{ height:78svh; min-height:29rem; align-items:flex-end; }
  .hero__scrim{
    background:linear-gradient(0deg,rgba(0,0,0,.93) 5%,rgba(0,0,0,.34) 45%,
                                    rgba(0,0,0,.08) 68%,rgba(0,0,0,.62) 100%);
  }
  .hero__fade{ height:20%; }
  .hero__body{ max-width:100%; margin-top:0; padding-bottom:1.1rem; text-align:center; }
  .hero__eyebrow{ justify-content:center; font-size:.58rem; letter-spacing:.26em; }
  .hero__title{ font-size:clamp(1.55rem,7.2vw,2.3rem) !important; margin-bottom:.65rem; }
  .hero__title.tt-road{ transform:none; }
  .hero__meta{ justify-content:center; gap:.45rem; font-size:.8rem; margin-bottom:.85rem; }
  .hero__meta .badge-hd{ display:none; }
  .hero__synopsis{ display:none; }        /* a phone wants the facts, not the paragraph */
  .hero__actions{ justify-content:center; gap:.55rem; }
  .hero__actions .btn{ flex:1 1 0; justify-content:center; padding:.68rem .8rem; font-size:.92rem; }

  /* Sat under the bar, these collided with the section strip. On a phone
     they sit along the bottom edge of the billboard, under the buttons,
     where a pager belongs. */
  .hero__dots{
    left:0; right:0; top:auto; bottom:.55rem;
    justify-content:center;
  }
  .hero__body{ padding-bottom:2.1rem; }

  /* rows — no pulling up into the billboard, or the first row's heading
     ends up behind the buttons */
  .rows{ margin-top:.9rem; }
  .hero[hidden] + .rows{ margin-top:calc(var(--nav-h) + 3.2rem); }
  .row{ margin-bottom:1.35rem; }
  .row__head{ margin-bottom:.42rem; }
  .row__title{ font-size:1rem; }
  .row__explore, .row__arrow{ display:none; }
  .row__track{
    --pop-top:.5rem; --pop-bottom:.5rem;   /* touch: nothing pops out */
    gap:.5rem; scroll-snap-type:x proximity;
  }
  .card{ width:64vw; scroll-snap-align:start; }
  .card--top{ width:50vw; }
  .card__logo{ padding:1.7rem .6rem .55rem; }
  .card__panel{ display:none; }

  .castGrid{ grid-template-columns:repeat(2,1fr); gap:1rem .5rem; }
  .tripGrid{ grid-template-columns:1fr; }
  .epgrid{ grid-template-columns:repeat(2,1fr); }

  /* viewer */
  .player__top{ padding:.85rem .75rem; gap:.5rem; flex-wrap:wrap; }
  .player__collection{ font-size:.88rem; }
  .player__caption{ font-size:.74rem; }
  .tools{ width:100%; order:3; justify-content:space-between; gap:0; }
  .tool{ padding:.45rem .28rem; }
  .tool span{ display:none; }            /* the marks are enough on a phone */
  .player__nav{ width:44px; height:44px; }
  .player__bottom{ padding:1.9rem .75rem 1rem; }

  .modal{ padding:0; }
  .modal__card{ width:100%; border-radius:0; }
}

@media (max-width:400px){
  .card{ width:72vw; }
  .hero{ height:74svh; }
}

@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.01ms !important; transition-duration:.01ms !important; }
  .row__track{ scroll-behavior:auto; }
}

/* ── Subtitles ───────────────────────────────────────────────────
   Set in the same face as the titles over the footage, and kept clear of
   the transport so a line is never hidden by the scrubber. */
::cue{
  font-family:'Avenir Next','Hiragino Sans','Helvetica Neue',sans-serif;
  font-size:1.05rem; line-height:1.45;
  color:#fff; background:rgba(8,10,14,.66);
}
.player.is-clips #playerVideo::cue{ font-size:1.1rem; }
#vCC.is-on{ color:var(--red); }
#vCC.is-on::after{
  content:''; position:absolute; left:50%; bottom:.28rem; translate:-50% 0;
  width:16px; height:2px; border-radius:1px; background:var(--red);
}
#vCC{ position:relative; }

/* ── The shows a person turns up in ──────────────────────────────
   A series has no photograph to tag, so it cannot appear in the grid below.
   Listed instead, in the same shape as an episode row so the two shelves
   read as one system. */
.showlist{ display:flex; flex-direction:column; }
.showrow{
  display:grid; grid-template-columns:132px 1fr 1.6rem; align-items:center;
  gap:1rem; padding:.8rem .6rem; cursor:pointer;
  border-top:1px solid rgba(255,255,255,.09);
  transition:background-color .22s var(--ease);
}
.showrow:last-child{ border-bottom:1px solid rgba(255,255,255,.09); }
.showrow:hover{ background:rgba(255,255,255,.06); }
.showrow__art{
  position:relative; display:block; aspect-ratio:16/9;
  border-radius:4px; overflow:hidden; background:#000;
}
.showrow__art img{ width:100%; height:100%; object-fit:cover; transition:opacity .25s; }
.showrow:hover .showrow__art img{ opacity:.75; }
.showrow__body{ display:block; min-width:0; }
.showrow__body b{ display:block; font-size:.95rem; font-weight:600; }
.showrow__body small{
  display:block; margin-top:.22rem; font-size:.82rem; color:rgba(255,255,255,.62);
}
.showrow__go{
  display:grid; place-items:center; color:rgba(255,255,255,.45);
  transition:color .2s var(--ease), transform .2s var(--ease);
}
.showrow:hover .showrow__go{ color:#fff; transform:translateX(3px); }
@media (max-width:820px){
  .showrow{ grid-template-columns:96px 1fr 1.2rem; gap:.7rem; padding:.7rem .2rem; }
  .showrow__body b{ font-size:.86rem; }
}
