/* Theoria — Home only. The theatre with the lights down.
   Per the contract in theoria.css, this file only ADDS components; it never
   restyles a shared one. No token redefinition, no nav/footer overrides.

   Motion budget (the cinema redesign): the page is meant to feel alive, so
   motion is spent in four places, each tied to the films themselves —
     1. the "Explore" reel: backdrops cross-fade and slowly push in, the
        title rises word by word, and the room light takes the film's colour;
     2. the poster wall drifts, two rows in opposite directions, and stops
        under the pointer;
     3. posters tilt toward the pointer (cinema.js);
     4. the decade chart draws itself once, when it scrolls into view.
   Everything holds still under prefers-reduced-motion. This replaces the
   earlier "one moment only" contact sheet, by request: the stillness read as
   unfinished rather than calm. */

.page-home {
  /* The full-bleed bands below are 100vw wide, which on a desktop with a
     classic scrollbar is a few pixels wider than the page. */
  overflow-x: clip;
}

.page-home main.container {
  padding-top: 0;
}

/* Breaks a band out of main's centred column to the full viewport width.
   Viewport lengths on this page go through --vw / --vh rather than vw / vh:
   on a TV the page is zoomed (see "TV" at the end of this file), and a zoom
   multiplies a vw too, so a 100vw band would come out 1.6 screens wide.
   They are set, in pre-zoom px, only while a TV zoom is in force; everywhere
   else they fall back to plain vw / vh. */
.reel,
.wall,
.rail {
  width: calc(100 * var(--vw, 1vw));
  margin-inline: calc(50% - 50 * var(--vw, 1vw));
}

/* --- 1. The reel -------------------------------------------------------------- */

.reel {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: min(calc(92 * var(--vh, 1vh)), 900px);
  padding-top: 120px;
}

.reel__stage {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--paper);
}

.reel__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.12);
  transition: opacity 1.4s var(--ease);
}

.reel__image.is-on {
  opacity: 1;
  animation: reel-push 9s linear forwards;
}

@keyframes reel-push {
  from { transform: scale(1.12); }
  to { transform: scale(1.02) translate3d(-1.5%, -1%, 0); }
}

/* Darken toward the copy: up from the bottom, in from the left. */
.reel__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, var(--paper) 2%, color-mix(in srgb, var(--paper) 72%, transparent) 30%,
                    color-mix(in srgb, var(--paper) 10%, transparent) 62%, color-mix(in srgb, var(--paper) 50%, transparent)),
    linear-gradient(to right, color-mix(in srgb, var(--paper) 85%, transparent), transparent 60%);
}

/* The letterbox: the frame opens from 2.39:1 to full height on load. */
.reel::before,
.reel::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  z-index: 3;
  height: 14%;
  background: #000;
  animation: reel-letterbox 1.6s var(--ease-out) 0.25s forwards;
  pointer-events: none;
}

.reel::before { top: 0; transform-origin: top; }
.reel::after { bottom: 0; transform-origin: bottom; }

@keyframes reel-letterbox {
  to { transform: scaleY(0); }
}

.reel__copy {
  position: relative;
  padding-bottom: var(--space-7);
}

.reel__slide[hidden] { display: none; }

.reel__title {
  margin-top: var(--space-5);
  max-width: 14ch;
  font-family: var(--font-display);
  font-weight: 850;
  font-stretch: 118%;
  font-size: clamp(2.6rem, calc(8.4 * var(--vw, 1vw)), 7.4rem);
  line-height: 0.88;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* cinema.js wraps each word so it can rise out of its own mask. */
.reel__title .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.06em;
}

.reel__title .w > span {
  display: inline-block;
  animation: reel-rise 1s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 70ms + 120ms);
}

@keyframes reel-rise {
  from { transform: translateY(105%) rotate(4deg); filter: blur(6px); }
  to { transform: none; filter: none; }
}

.reel__tagline {
  margin-top: var(--space-5);
  max-width: 46ch;
  font-size: clamp(1.05rem, calc(1.6 * var(--vw, 1vw)), 1.3rem);
  color: var(--ink-muted);
  animation: reel-fade 0.9s var(--ease-out) 0.45s both;
}

@keyframes reel-fade {
  from { transform: translateY(14px); opacity: 0.2; }
  to { transform: none; opacity: 1; }
}

.reel__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3) var(--space-6);
  margin-top: var(--space-6);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.reel__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-7);
}

/* Reel tabs: the queue, with a progress bar under the film that's showing.
   Meaningless without the script that advances them, so has-js only. */
.reel__tabs {
  display: none;
}

html.has-js .reel__tabs {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: var(--space-4);
  padding-block: var(--space-5) var(--space-8);
  border-top: var(--hairline);
}

.reel__tab {
  display: grid;
  gap: var(--space-3);
  min-width: 0;
  padding: 0;
  text-align: left;
  background: none;
  border: 0;
  color: var(--ink-faint);
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}

.reel__tab:hover,
.reel__tab.is-on {
  background: none;
  color: var(--ink);
}

.reel__bar {
  display: block;
  height: 2px;
  border-radius: 2px;
  overflow: hidden;
  background: var(--rule-strong);
}

.reel__bar i {
  display: block;
  width: 100%;
  height: 100%;
  background: var(--ink);
  transform: scaleX(0);
  transform-origin: left;
}

.reel__tab.is-done .reel__bar i {
  transform: scaleX(1);
  background: var(--ink-faint);
}

.reel__tab.is-on .reel__bar i {
  animation: reel-progress var(--reel-dur, 8s) linear forwards;
}

@keyframes reel-progress {
  to { transform: scaleX(1); }
}

.reel__tab-title {
  font-size: var(--text-xs);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.reel__tab-year {
  font-size: var(--text-3xs);
}

/* --- Figures ------------------------------------------------------------------- */

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  border-block: var(--hairline);
}

/* dt comes first in the markup (the label names the value) but the number
   reads first on screen, so the cell stacks in reverse. */
.figure {
  display: flex;
  flex-direction: column-reverse;
  justify-content: flex-end;
  padding: var(--space-7) var(--space-6);
  border-left: var(--hairline);
}

.figure:first-child {
  border-left: 0;
  padding-left: 0;
}

.figure dd {
  margin: 0;
  font-size: clamp(1.6rem, calc(2.8 * var(--vw, 1vw)), 2.4rem);
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.figure dt {
  margin-top: var(--space-4);
  font-size: var(--text-xs);
  color: var(--ink-faint);
}

/* --- Section heads ------------------------------------------------------------- */

.home-section {
  margin-top: clamp(4rem, calc(10 * var(--vw, 1vw)), 8rem);
}

.home-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6) var(--space-9);
  margin-bottom: var(--space-8);
}

.home-title {
  margin-top: var(--space-5);
  font-family: var(--font-display);
  font-weight: 800;
  font-stretch: 108%;
  font-size: clamp(2rem, calc(4.6 * var(--vw, 1vw)), 3.6rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.home-title em {
  font-style: normal;
  color: var(--ink-faint);
}

.home-note {
  max-width: 42ch;
  color: var(--ink-muted);
}

.home-note a {
  display: inline-block;
  margin-top: var(--space-3);
  color: var(--lime-text);
}

/* --- 2. The poster wall ------------------------------------------------------- */

.wall {
  display: grid;
  gap: 14px;
  padding-block: var(--space-3);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
}

.wall__track {
  display: flex;
  gap: 14px;
  width: max-content;
  animation: wall-slide 70s linear infinite;
}

.wall__track.is-reverse {
  animation-direction: reverse;
  animation-duration: 84s;
}

.wall:hover .wall__track,
.wall:focus-within .wall__track {
  animation-play-state: paused;
}

/* Exactly one copy of the row: the track holds two, so -50% (less half a
   gap) lands the second copy where the first began. */
@keyframes wall-slide {
  to { transform: translateX(calc(-50% - 7px)); }
}

.wall__tile,
.rank__poster {
  position: relative;
  display: block;
  flex: none;
  aspect-ratio: 2 / 3;
  border-radius: 10px;
  overflow: hidden;
  background: var(--sheet-2);
  transition: transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-out);
}

.wall__tile {
  width: clamp(120px, calc(13 * var(--vw, 1vw)), 170px);
}

.wall__tile img,
.rank__poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The highlight cinema.js moves under the pointer (--gx/--gy). */
.wall__tile::after,
.rank__poster::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(circle at var(--gx, 50%) var(--gy, 0%), rgb(255 255 255 / 0.35), transparent 55%);
  mix-blend-mode: soft-light;
  transition: opacity var(--dur-slow) var(--ease);
}

.wall__tile:hover,
.wall__tile:focus-visible,
.rank__card:hover .rank__poster,
.rank__card:focus-visible .rank__poster {
  z-index: 2;
  box-shadow: 0 30px 60px -20px rgb(0 0 0 / 0.8), 0 0 0 1px var(--rule-strong);
}

.wall__tile:hover::after,
.rank__card:hover .rank__poster::after {
  opacity: 1;
}

/* --- Highest rated rail -------------------------------------------------------- */

.rail-controls {
  display: flex;
  gap: var(--space-3);
}

.rail {
  display: flex;
  gap: var(--space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
  margin-block: 0;
  padding: var(--space-3) max(var(--space-6), calc(50 * var(--vw, 1vw) - var(--measure) / 2 + var(--space-6))) var(--space-7);
  cursor: grab;
}

.rail::-webkit-scrollbar { display: none; }

.rail.is-dragging {
  cursor: grabbing;
  scroll-snap-type: none;
}

.rank {
  display: flex;
  align-items: flex-end;
  flex: none;
  scroll-snap-align: start;
}

.rank__num {
  margin-right: -0.14em;
  font-family: var(--font-display);
  font-weight: 900;
  font-stretch: 62%;
  font-size: clamp(7rem, calc(13 * var(--vw, 1vw)), 11rem);
  line-height: 0.78;
  letter-spacing: -0.06em;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--rule-strong);
  user-select: none;
  transition: -webkit-text-stroke-color var(--dur-slow) var(--ease);
}

.rank:hover .rank__num {
  -webkit-text-stroke-color: var(--lime);
}

.rank__card {
  display: block;
  color: var(--ink);
}

.rank__card:hover { text-decoration: none; }

.rank__poster {
  width: clamp(140px, calc(15 * var(--vw, 1vw)), 190px);
}

.rank__meta {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  width: clamp(140px, calc(15 * var(--vw, 1vw)), 190px);
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.rank__title {
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- 4. Decades chart ---------------------------------------------------------- */

/* overflow-x: clip, because once the chart is drawn the table is shrunk to a
   1px screen-reader box, and a table never lays out narrower than its
   content: on a 360px phone it pokes ~20px past the viewport, which mobile
   browsers answer by widening the whole page. Clip, not hidden, so the
   tooltip above a bar still escapes vertically. */
.decades {
  position: relative;
  overflow-x: clip;
  padding: clamp(18px, calc(3 * var(--vw, 1vw)), 36px);
  border: var(--hairline);
  border-radius: 20px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--ink) 3%, transparent), transparent);
}

.decades__legend {
  display: none;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-6);
  margin-bottom: var(--space-5);
  font-size: var(--text-xs);
  color: var(--ink-muted);
}

.decades__legend i {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin-right: var(--space-3);
  border-radius: 3px;
  vertical-align: -1px;
}

.decades__legend .is-bar { background: color-mix(in srgb, var(--ink) 25%, transparent); }
.decades__legend .is-line { height: 2px; border-radius: 0; vertical-align: 3px; background: var(--ink); }

.decades__chart {
  display: none;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Once cinema.js has drawn the chart, the table steps back to screen-reader
   only and the legend and chart take its place. */
.decades.is-drawn .decades__legend { display: flex; }
.decades.is-drawn .decades__chart { display: block; }
.decades.is-drawn .decades__table {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.decades__table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.decades__table caption {
  text-align: left;
  padding-bottom: var(--space-4);
  color: var(--ink-muted);
}

.decades__table th,
.decades__table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: var(--hairline);
}

.decades__chart .bar {
  fill: color-mix(in srgb, var(--ink) 10%, transparent);
  transform-box: fill-box;
  transform-origin: bottom;
  transition: fill var(--dur) var(--ease);
}

.decades__chart .bar:hover,
.decades__chart .bar.is-active { fill: color-mix(in srgb, var(--ink) 22%, transparent); }

/* A full-height column behind each bar, so a finger can tap a decade
   without landing on a 30px-wide bar. */
.decades__chart .hit { fill: transparent; }
.decades__chart .bar.is-best { fill: var(--lime); }

.decades__chart.is-animating .bar {
  animation: decade-grow 1.1s var(--ease-out) both;
  animation-delay: calc(var(--i) * 80ms);
}

@keyframes decade-grow {
  from { transform: scaleY(0); }
}

.decades__chart .line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 2;
}

.decades__chart.is-animating .line {
  stroke-dasharray: 1600;
  animation: decade-draw 1.8s var(--ease) 0.5s both;
}

@keyframes decade-draw {
  from { stroke-dashoffset: 1600; }
  to { stroke-dashoffset: 0; }
}

.decades__chart .pt {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2;
}

.decades__chart .grid { stroke: var(--rule); }

.decades__chart text {
  fill: var(--ink-faint);
  font: 500 12px var(--font-mono);
}

/* The rating figures ride the line, which crosses the bars; a halo in the
   page colour keeps "7.34" legible where it lands on the lime one. */
.decades__chart .val {
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 4px;
  stroke-linejoin: round;
}

.decades__tip {
  position: absolute;
  padding: var(--space-3) var(--space-4);
  border-radius: 10px;
  border: 1px solid var(--rule-strong);
  background: var(--sheet-2);
  font-size: var(--text-xs);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -110%);
  transition: opacity var(--dur) var(--ease);
}

/* --- Small screens ---------------------------------------------------------------- */

/* Horizontal swipes on the reel are cinema.js's to read (next / previous
   film); vertical ones still scroll the page. */
html.has-js .reel {
  touch-action: pan-y;
}

@media (max-width: 900px) {
  /* Every film in the queue stays on screen: a tab scrolled out of view is a
     film the reader never learns is there. Titles ellipsise instead. */
  html.has-js .reel__tabs {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
  }

  .figures {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .figure,
  .figure:first-child {
    border-left: 0;
    padding-left: 0;
    border-top: var(--hairline);
  }

  .figure:nth-child(-n + 2) {
    border-top: 0;
  }
}

/* Phones. Rethought for a thumb and a narrow column rather than shrunk:
   the reel's queue becomes a row of progress segments, the two poster grids
   become swipeable shelves like the top-ten rail (twelve posters stacked two
   abreast were ~2,200px of scrolling each), and every full-bleed strip lines
   its first poster up with the page's text edge. */
@media (max-width: 600px) {
  .reel {
    min-height: min(84svh, 720px);
    padding-top: 104px;
  }

  /* Scales with the screen instead of sitting on a 2.6rem floor that a
     long word ("REDEMPTION") or a Cyrillic title can't fit at 320px, and
     sets a touch less wide so ten capitals fit a 320px column whole. A word
     that still won't fit breaks rather than being clipped by its mask. */
  .reel__title {
    font-size: clamp(1.75rem, 10.5vw, 3.4rem);
    font-stretch: 108%;
    max-width: none;
    hyphens: auto;
    overflow-wrap: break-word;
  }

  .reel__tagline {
    margin-top: var(--space-4);
    font-size: var(--text-base);
  }

  .reel__meta {
    gap: var(--space-2) var(--space-5);
    margin-top: var(--space-5);
    font-size: var(--text-xs);
  }

  .reel__actions {
    gap: var(--space-3);
    margin-top: var(--space-6);
  }

  /* Two thumb-sized buttons sharing the row, not two islands on the left. */
  .reel__actions .cta {
    flex: 1 1 auto;
    justify-content: center;
  }

  .reel__copy {
    padding-bottom: var(--space-6);
  }

  /* The queue as story segments: one bar per film, the showing one filling.
     Titles drop out of view but stay in the button for screen readers; the
     slide above already names the film. The padding makes each segment a
     44px tap target although only its 3px bar is drawn. */
  html.has-js .reel__tabs {
    gap: var(--space-2);
    padding-block: 0 var(--space-5);
    border-top: 0;
  }

  .reel__tab {
    gap: 0;
    padding-block: 20px 21px;
  }

  .reel__bar {
    height: 3px;
  }

  .reel__tab-title,
  .reel__tab-year {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  .figure {
    padding-block: var(--space-6);
  }

  .home-head {
    gap: var(--space-4);
    margin-bottom: var(--space-6);
  }

  .home-note {
    font-size: var(--text-sm);
  }

  /* --- Strips: the top-ten rail and the two shelves -------------------- */

  .rail,
  .poster-grid.home-shelf {
    padding-inline: var(--space-5);
    scroll-padding-inline: var(--space-5);
    overscroll-behavior-x: contain;
  }

  .rank__num {
    font-size: clamp(4.75rem, 24vw, 6.5rem);
  }

  .rank__poster,
  .rank__meta {
    width: clamp(118px, 34vw, 150px);
  }

  .rank__meta {
    margin-top: var(--space-3);
    font-size: var(--text-xs);
  }

  /* The grid becomes a shelf: same cards, laid in a row that scrolls
     sideways, with the next poster peeking in at the edge as the cue. */
  .poster-grid.home-shelf {
    display: flex;
    gap: var(--space-4);
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    padding-bottom: var(--space-3);
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }

  .poster-grid.home-shelf::-webkit-scrollbar { display: none; }

  .poster-grid.home-shelf > * {
    flex: 0 0 clamp(128px, 38vw, 176px);
    min-width: 0;
    scroll-snap-align: start;
  }

  .poster-grid.home-shelf > .empty {
    flex: 1 1 auto;
  }

  /* --- Decades chart --------------------------------------------------- */

  .decades {
    padding: var(--space-5) var(--space-4);
    border-radius: 14px;
  }

  .decades__legend {
    gap: var(--space-2) var(--space-5);
  }
}

/* Phone in landscape: the reel can't take 84% of a 390px-tall screen and
   still show its copy, so it sizes to the copy and lets the backdrop fill
   in behind. */
@media (max-height: 500px) and (orientation: landscape) {
  .reel {
    min-height: 0;
    padding-top: 96px;
  }

  .reel__title {
    font-size: clamp(2rem, 6vw, 3.2rem);
  }
}

/* Touch screens. Nothing here can be hovered, so the hint that says to
   hover goes, and the rail's arrow buttons give way to the swipe the rail
   already answers to (keyboard and mouse users keep them). */
@media (hover: none) and (pointer: coarse) {
  .home-note--pointer,
  .rail-controls {
    display: none;
  }
}

/* --- TV ---------------------------------------------------------------------------
   The ten-foot page. base.html marks a TV browser (or any screen 3000px+
   wide, which only a 4K panel reports) with html.is-tv and works out a zoom
   that makes the screen read as a 1280px-wide page: 1.5x on a 1080p TV,
   3x on a 4K one that reports its full 3840px. Body text lands at 24
   physical px on a 1080p panel, readable from a sofa, and 1280 is wide
   enough for the desktop header to keep its search field. A TV whose browser
   already reports a halved 960px viewport is drawn at 2x by the device and
   keeps a zoom of 1.

   Media queries still see the real screen width, which is why they are not
   used here: everything below is keyed on the class. The shell every page
   shares (the zoom, the safe margins, the header, the heavier focus ring) is
   in theoria.css, "TV shell"; this file keeps what only the home page has.
   Beyond the scale, the page changes in three ways a remote needs:
     - every edge keeps a safe margin, since many TVs still crop the outer
       few percent of the picture;
     - the two poster grids become single rows, the shape a remote's
       left/right moves along;
     - focus is the cursor, so it has to read from across the room: the
       poster under focus lifts and takes a lime frame. */

/* The reel is exactly one screen: the first thing a TV shows is a film. */
html.is-tv .reel {
  min-height: calc(100 * var(--vh, 1vh));
  padding-top: 104px;
}

/* Capped by the screen's height as well as its width, so a three-line
   title still leaves the queue on the first screen. */
html.is-tv .reel__title {
  max-width: 16ch;
  font-size: min(7.4rem, calc(8.4 * var(--vw, 1vw)), calc(13 * var(--vh, 1vh)));
}

html.is-tv .reel__copy {
  padding-bottom: var(--space-6);
}

html.is-tv .reel__tabs {
  padding-bottom: var(--space-7);
}

html.is-tv .reel__tab-title {
  font-size: var(--text-sm);
}

html.is-tv .reel__tab-year {
  font-size: var(--text-2xs);
}

/* There is no pointer to hover with on most TVs. */
html.is-tv .home-note--pointer {
  display: none;
}

/* --- Rows ---------------------------------------------------------------- */

html.is-tv .rail,
html.is-tv .poster-grid.home-shelf {
  padding-inline: var(--tv-gutter);
  scroll-padding-inline: var(--tv-gutter);
}

html.is-tv .poster-grid.home-shelf {
  display: flex;
  gap: var(--space-6);
  width: calc(100 * var(--vw, 1vw));
  margin-inline: calc(50% - 50 * var(--vw, 1vw));
  /* Room above and below for a focused poster to lift without being cut
     off by the row's own scroll box. */
  padding-block: var(--space-5) var(--space-6);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

html.is-tv .poster-grid.home-shelf::-webkit-scrollbar { display: none; }

html.is-tv .poster-grid.home-shelf > * {
  flex: 0 0 172px;
  min-width: 0;
  scroll-snap-align: start;
}

html.is-tv .poster-grid.home-shelf > .empty {
  flex: 1 1 auto;
}

/* --- Focus ----------------------------------------------------------------
   The poster carries the focus, not an outline around the whole card: it
   scales up and takes the lime frame, the way hover lifts it on a desktop.
   Everything else focusable gets a heavier version of the site's ring. */

html.is-tv .wall__tile:focus-visible,
html.is-tv .rank__card:focus-visible,
html.is-tv .home-shelf .poster-card a:focus-visible {
  outline: none;
}

html.is-tv .wall__tile:focus-visible,
html.is-tv .rank__card:focus-visible .rank__poster,
html.is-tv .home-shelf .poster-card a:focus-visible .poster {
  transform: scale(1.07);
  border-color: var(--lime-mark);
  box-shadow: 0 0 0 3px var(--lime-mark), 0 28px 56px -20px rgb(0 0 0 / 0.85);
}

/* Rows lift a poster from its bottom edge, so it grows up into the free
   space instead of down over its own title. */
html.is-tv .rank__poster,
html.is-tv .home-shelf .poster-card .poster {
  transform-origin: 50% 100%;
}

html.is-tv .home-shelf .poster-card .poster {
  transition: transform var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-out);
}

html.is-tv .rank:focus-within .rank__num {
  -webkit-text-stroke-color: var(--lime);
}

html.is-tv .rank__card:focus-visible .rank__title,
html.is-tv .home-shelf .poster-card a:focus-visible .card-title {
  color: var(--lime-text);
}

@media (prefers-reduced-motion: reduce) {
  .wall {
    overflow-x: auto;
  }

  .wall__track {
    animation: none;
  }

  .reel::before,
  .reel::after {
    display: none;
  }
}
