/* MEDIA's shell, Home, title page, My Space and search, in the TV app's style.
   Tokens live in tokens.css; the player, settings and sign-in have their own sheets. */

* {
  box-sizing: border-box;
  letter-spacing: 0;
}
body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--text);
  transition: background-color var(--motion-backdrop);
}
button,
input,
select {
  font: inherit;
}
button {
  cursor: pointer;
  color: inherit;
  border: 0;
  transition:
    background var(--motion-control),
    color var(--motion-control),
    opacity var(--motion-control),
    scale var(--motion-control) var(--ease),
    box-shadow var(--motion-control);
}
button:disabled {
  opacity: 0.45;
  cursor: default;
}
a {
  color: inherit;
  text-decoration: none;
}
/* One focus ring everywhere: a thin accent line, a little away from what it rings. */
:is(button, a, input, select, textarea):focus-visible {
  outline: var(--focus-ring);
  outline-offset: 3px;
}
[hidden] {
  display: none !important;
}
h1,
h2,
h3,
p {
  margin: 0;
}
svg {
  width: 21px;
  height: 21px;
  stroke-width: 1.6;
  flex-shrink: 0;
}
select,
input {
  background: var(--raised);
  border: 1px solid var(--hairline);
  border-radius: var(--r-button);
  color: var(--text);
  padding: 10px 12px;
  min-width: 0;
}
select {
  max-width: 220px;
}
.muted {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.7;
}

/* ---- Buttons ---- */
.actions {
  display: flex;
  gap: var(--gap-buttons);
  align-items: center;
  flex-wrap: wrap;
}
.button {
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 24px;
  border-radius: var(--r-button);
  font-size: var(--fs-button);
  font-weight: 700;
  border: 1px solid transparent;
  background: none;
  color: var(--text);
  transition: scale var(--motion-control) var(--ease), background var(--motion-control) var(--ease), opacity var(--motion-control) var(--ease);
}
.button svg {
  width: 20px;
  height: 20px;
}
/* Buttons, quiet as the player's: the main one is the accent's light inside a thin ring, the others
   are words; a soft fill comes up under the pointer or focus. Their corners follow Appearance. */
.primary {
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  color: var(--accent-light);
}
.primary:is(:hover, :focus-visible):not(:disabled) {
  background: var(--accent-wash);
}
.button:focus-visible {
  scale: 1.03;
}
.secondary:is(:hover, :focus-visible):not(:disabled) {
  background: var(--glass);
}
/* A press dims a moment; nothing squashes. */
.button:active:not(:disabled),
.icon-button:active:not(:disabled) {
  opacity: .72;
}
.icon-button {
  width: 44px;
  height: 44px;
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  padding: 0;
  border-radius: var(--r-tile);
  background: var(--tile);
  border: 1px solid var(--hairline);
  color: var(--text);
}
.icon-button:hover {
  background: var(--glass-hover);
}
/* The top bar's Downloads icon: a thin accent ring fills as the running downloads go (downloads.js). */
.downloads-toggle {
  position: relative;
}
.download-ring {
  position: absolute;
  inset: 3px;
  rotate: -90deg;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-card) var(--ease);
}
.download-ring circle {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--f, 0));
  transition: stroke-dashoffset var(--motion-stage) var(--ease);
}
.downloads-toggle.downloading .download-ring {
  opacity: 1;
}
#search-input:focus-visible {
  outline: none;
  border-color: var(--accent);
}
.icon-button.active {
  color: var(--accent);
}
.icon-button.primary {
  background: none;
  border-color: color-mix(in srgb, var(--accent) 65%, transparent);
  color: var(--accent-light);
}
.icon-button[data-action="liked"] svg {
  transition: fill var(--motion-control), stroke var(--motion-control);
  fill: transparent;
}
.icon-button[data-action="liked"].active svg {
  fill: var(--accent);
}
.icon-button[data-action="watchlist"].active {
  color: var(--accent-hover);
}

/* ---- Top bar: the wordmark, two tab groups with one gold underline each, and tiles ---- */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 44px);
  padding: 0 var(--inset);
  isolation: isolate;
  background: linear-gradient(
    color-mix(in srgb, var(--bg) 70%, transparent),
    color-mix(in srgb, var(--bg) 25%, transparent) 65%,
    transparent
  );
  transition: height var(--motion-stage) var(--ease);
}
/* The bar always stays. Once the page has scrolled it settles: a little lower, on a calmer, more
   solid ground, so the rows passing beneath never compete with it. */
.topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    color-mix(in srgb, var(--bg) 96%, transparent),
    color-mix(in srgb, var(--bg) 84%, transparent) 70%,
    transparent
  );
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--motion-stage) var(--ease);
}
@media (min-width: 601px) {
  body.scrolled {
    --bar-h: 72px;
  }
}
body.scrolled .topbar::before {
  opacity: 1;
}
.brand {
  display: inline-flex;
  align-items: center;
  font-size: 26px;
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
}
/* The gold capsule from the TV's launcher mark. */
.brand::before {
  content: "";
  width: 5px;
  height: 25px;
  margin-right: 11px;
  border-radius: 99px;
  background: linear-gradient(180deg, var(--accent-light), var(--accent));
}
.brand span {
  color: var(--accent);
}
.browse-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 49px;
}
.world-tabs,
.view-tabs {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 22px;
}
/* The hairline between the two groups. */
.view-tabs::before {
  content: "";
  position: absolute;
  left: -25px;
  top: 50%;
  width: 1px;
  height: 28px;
  translate: 0 -50%;
  background: var(--hairline);
}
.nav-link {
  position: relative;
  background: none;
  color: var(--nav);
  padding: 14px 0;
  font-size: var(--fs-nav);
  white-space: nowrap;
}
.nav-link:hover,
.nav-link.selected {
  color: var(--text);
}
.nav-link.selected {
  font-weight: 800;
}
.nav-link:focus-visible {
  outline: none;
  color: var(--text);
}
/* One bar per group (effects.js moveIndicator): gold, brighter while the group has focus. */
.active-indicator {
  position: absolute;
  left: 0;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  pointer-events: none;
  transform-origin: left center;
  transition: background-color var(--motion-control);
}
:focus-within > .active-indicator {
  background: var(--accent-hover);
}
.header-actions {
  margin-left: auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.topbar .icon-button svg {
  width: 22px;
  height: 22px;
}
/* Round and unfilled, as in the player (player.css): a soft glass circle only when pointed at. */
:is(.topbar, .rail-controls, #info-header, .settings, .collection) .icon-button {
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  background: none;
  transition: background var(--motion-control) var(--ease), color var(--motion-control) var(--ease);
}
:is(.topbar, .rail-controls, #info-header, .settings, .collection) .icon-button:is(:hover, :focus-visible) {
  background: var(--glass);
  color: var(--accent-light);
  box-shadow: none;
}
/* One focus ring for round buttons here and in the player. */
:is(.topbar, .rail-controls, #info-header, .settings, .collection) .icon-button:focus-visible,
.player-panel :is(button, input):focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 3px;
}
/* The profile's colour in a circle, held by a thin ring that lights up when pointed at. */
.avatar {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 16px;
  font-weight: 700;
  background: #474749;
  color: #f3f3f3;
  outline: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  outline-offset: 2px;
  transition: outline-color var(--motion-control), box-shadow var(--motion-control);
}
.avatar:is(:hover, :focus-visible) {
  outline-color: var(--accent);
  box-shadow: 0 0 16px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* Search: the tile opens into a field; results replace the rows. */
.search {
  display: flex;
  align-items: center;
  margin: 0;
}
#search-input {
  width: 0;
  height: 40px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 20px;
  background: var(--tile);
  color: var(--text);
  font-size: 16px;
  opacity: 0;
  pointer-events: none;
  transition:
    width var(--motion-view) var(--ease),
    padding var(--motion-view) var(--ease),
    opacity var(--motion-control),
    border-color var(--motion-control);
}
.search.open #search-input {
  /* Only the room the nav and buttons leave, so the avatar never leaves the window. */
  width: clamp(160px, 100vw - 800px, 420px);
  padding: 0 18px;
  margin-right: 8px;
  border-color: var(--hairline);
  opacity: 1;
  pointer-events: auto;
}
#search-input::placeholder {
  color: var(--muted);
}
#search-input::-webkit-search-cancel-button {
  appearance: none;
}
.search.open #search-button {
  color: var(--accent);
}

/* Phone bottom bar (shown at 600 px and below). */
.mobile-navigation {
  display: none;
}

/* ---- Stage: the shared backdrop behind Home (moods, hero slides, the hovered card) ---- */
#stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  background: var(--bg);
  transition: background-color var(--motion-backdrop);
}
#stage > * {
  position: absolute;
  inset: 0;
}
.mood,
.stage-card {
  opacity: 0;
}
.mood,
.stage-hero,
.stage-card {
  transition: opacity var(--motion-backdrop) var(--ease);
}
.mood-cinema {
  background:
    radial-gradient(70% 60% at 72% 18%, var(--mood-glow-cinema, color-mix(in srgb, var(--accent) 14%, transparent)), transparent 72%);
}
.mood-animation {
  background:
    radial-gradient(70% 60% at 72% 16%, color-mix(in srgb, #8b7bd8 30%, transparent), transparent 72%),
    radial-gradient(45% 45% at 12% 88%, color-mix(in srgb, #5fb3c9 14%, transparent), transparent 72%);
}
body[data-world="cinema"] .mood-cinema,
body[data-world="animation"] .mood-animation {
  opacity: 1;
}
#stage.card-shown .stage-hero {
  opacity: 0;
}
#stage.card-shown .stage-card {
  opacity: 1;
}
.stage-card img,
.hero-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  opacity: 0;
  transition: opacity var(--motion-backdrop) var(--ease);
}
.stage-card img.is-current {
  opacity: 1;
}
.stage-card img.art-contain {
  object-fit: contain;
  object-position: 80% center;
}
.scrim-x {
  background: linear-gradient(
    to right,
    color-mix(in srgb, var(--bg) 92%, transparent) 0%,
    color-mix(in srgb, var(--bg) 62%, transparent) 38%,
    transparent 78%
  );
}
.scrim-y {
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--bg) 45%, transparent) 0,
    transparent 16%,
    transparent 50%,
    color-mix(in srgb, var(--bg) 78%, transparent) 82%,
    var(--bg) 100%
  );
}
/* Hero slides: one per featured title (its artwork). A newer slide sits above the one it replaces
   and crossfades in (hero.js). */
.hero-slide,
.card-trailer {
  position: absolute;
  inset: 0;
  overflow: hidden;
}
.hero-art {
  object-position: center 30%;
  translate: 0 var(--hero-offset, 0px);
}
.hero-art.art-loaded {
  opacity: 1;
}
.card-trailer {
  pointer-events: none;
  container-type: size;
}
.card-trailer :is(video, iframe) {
  position: absolute;
  top: 50%;
  left: 50%;
  border: 0;
  opacity: 0;
  translate: -50% -50%;
  transition: opacity var(--motion-reveal) var(--ease);
}
.card-trailer video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* YouTube letterboxes inside its frame; oversize the frame to cover and crop its edges. */
.card-trailer iframe {
  width: max(100cqw, 177.78cqh);
  height: max(56.25cqw, 100cqh);
  scale: 1.12;
}
.card-trailer .trailer-ready {
  opacity: 1;
}

/* ---- Home ---- */
#browse {
  position: relative;
  z-index: 1;
}
/* Laptops: Home scrolls inside #browse, so rows passing under the info header can be masked. */
body.stage-scroll #browse {
  height: 100svh;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
}
/* The veil over rows above the info header fades in and out (--rows-veil is registered in
   tokens.css so it can be animated) instead of cutting them off in one frame. */
body.stage-scroll #browse {
  mask-image: linear-gradient(
    to bottom,
    rgb(0 0 0 / calc(1 - var(--rows-veil))) 0,
    rgb(0 0 0 / calc(1 - var(--rows-veil))) calc(var(--info-h) + 4px),
    #000 calc(var(--info-h) + 16px)
  );
  transition: --rows-veil var(--motion-stage) var(--ease);
}
body.stage-scroll.rows-engaged #browse {
  --rows-veil: 1;
}
/* Compact, as on the TV: the first row shows in full under it. */
.hero {
  position: relative;
  height: 62svh;
  min-height: 420px;
  display: flex;
  align-items: flex-end;
}
.hero-content {
  position: relative;
  display: grid;
  justify-items: start;
  gap: 10px;
  width: min(100%, calc(var(--inset) + 35px + 600px));
  padding: 0 var(--inset) clamp(84px, 14svh, 150px) calc(var(--inset) + 35px);
  transition: opacity var(--motion-stage) var(--ease);
}
.eyebrow {
  font-size: var(--fs-eyebrow);
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.hero h1 {
  max-width: 100%;
  font-size: 30px;
  line-height: 1.2;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.metadata {
  display: flex;
  gap: 4px 14px;
  align-items: center;
  flex-wrap: wrap;
  color: var(--meta);
  font-size: var(--fs-meta);
}
.metadata .rating {
  color: var(--rating);
  font-weight: 700;
}
.hero h1.has-logo > span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.hero-logo {
  display: block;
  max-width: min(320px, 70vw);
  max-height: 56px;
  object-fit: contain;
  object-position: left center;
  filter: drop-shadow(0 2px 10px rgb(0 0 0 / .6));
}
.hero-description {
  font-size: 14px;
  color: var(--desc);
  max-width: min(520px, 100%);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Play and More info as words, like the title page: no fill, no pill. */
:is(.hero, #info-header) .spoken-actions {
  justify-content: flex-start;
  margin-top: 2px;
}
/* While a card holds the stage, the featured title steps back and the header speaks for it. */
body.rows-engaged .hero-content {
  opacity: 0;
}
body.rows-engaged .stage-hero {
  opacity: 0;
}
/* A full page covers Home: Home stops painting but keeps its scroll positions. */
body.page-covered :is(#browse, #stage, .topbar, #info-header, .mobile-navigation) {
  visibility: hidden;
}
/* A small dash per featured title, gold for the one shown. */
.hero-dots {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}
.hero-dots button {
  width: 14px;
  height: 12px;
  padding: 0;
  cursor: pointer;
  background: linear-gradient(rgb(255 255 255 / .2), rgb(255 255 255 / .2)) center / 100% 2px no-repeat;
}
.hero-dots button[aria-current="true"] {
  background-image: linear-gradient(var(--accent), var(--accent));
}
/* The gold thread: from the hero's eyebrow down into the first row's ring (effects.js sets its
   height). It fades once you are browsing the rows. */
.hero-content::before {
  content: "";
  position: absolute;
  left: calc(var(--inset) + 5.5px);
  top: 3px;
  width: 2px;
  height: var(--thread-h, 0px);
  border-radius: 2px;
  background: linear-gradient(var(--accent), var(--accent) 80%, color-mix(in srgb, var(--accent) 70%, transparent));
  transform-origin: top;
  transition: opacity var(--motion-card);
  pointer-events: none;
}
.hero-content.thread-drawn::before {
  animation: thread-draw 600ms var(--ease) both;
}
@keyframes thread-draw {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}
body.rows-engaged .hero-content::before,
#browse.searching .hero-content::before {
  opacity: 0;
}

.rails {
  position: relative;
  margin-top: calc(-1 * clamp(36px, 7svh, 84px));
  padding-bottom: 120px;
}
.rail {
  margin-bottom: var(--row-bottom);
  scroll-margin-top: calc(var(--header-h) - 8px);
}
.rail-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 var(--inset);
  margin-bottom: 2px;
}
.rail-heading > div {
  min-width: 0;
}
.rail h2,
.space-part .rail-heading h3 {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 18px;
  font-size: var(--fs-rail);
  font-weight: 700;
}
/* The ring each row hangs from: part of the gold line. */
.rail h2::before,
.space-part .rail-heading h3::before {
  content: "";
  width: 13px;
  height: 13px;
  margin-right: 4px;
  border: 2px solid var(--accent);
  border-radius: 50%;
  flex: none;
}
.rail-subtitle {
  font-size: 14px;
  font-weight: 400;
  color: var(--muted);
}
.rail-controls {
  display: flex;
  gap: 8px;
  transition: opacity var(--motion-control), translate var(--motion-control);
}
.rail-controls button:disabled {
  opacity: 0.2;
}
@media (hover: hover) and (pointer: fine) {
  .rail-controls {
    opacity: 0;
    translate: 4px 0;
  }
  :is(.rail, .space-part):is(:hover, :focus-within) .rail-controls {
    opacity: 1;
    translate: 0 0;
  }
}
@media (hover: none), (pointer: coarse) {
  .rail-controls {
    display: none;
  }
}
.rail-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: var(--poster-w);
  gap: var(--gap-card);
  overflow-x: auto;
  overflow-y: clip;
  padding: 14px var(--inset) 18px;
  /* Snap points include the side padding, so an endless row's jump lands exactly on one. */
  scroll-padding-inline: var(--inset);
  scrollbar-width: none;
  scroll-behavior: smooth;
  /* With a mouse or trackpad a row stops exactly where it is flicked: a snap would pull it
     back to the nearest card after the motion ends, which reads as a jerk. Arrow buttons and
     keys already land on a card. Touch screens snap (below). */
  scroll-snap-type: none;
  overscroll-behavior-x: contain;
}
@media (pointer: coarse) {
  .rail-track {
    scroll-snap-type: x proximity;
  }
}
.rail-track::-webkit-scrollbar {
  display: none;
}
.rail[data-shape="landscape"] .rail-track,
.rail[data-kind="continue"] .rail-track {
  grid-auto-columns: var(--landscape-w);
}
.rail[data-shape="landscape"] .skeleton-art,
.rail[data-kind="continue"] .skeleton-art {
  aspect-ratio: 16 / 9;
}

/* ---- Cards: artwork, the gold ring when it is where you are, and one personal line ---- */
.media-card {
  position: relative;
  min-width: 0;
  scroll-snap-align: start;
}
.art-button {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 2 / 3;
  padding: 0;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--r-card);
  background: var(--raised);
  transition:
    translate var(--motion-card) var(--ease),
    box-shadow var(--motion-card) var(--ease);
}
.landscape-card .art-button {
  aspect-ratio: 16 / 9;
}
.art-button::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--hairline-soft);
  pointer-events: none;
  transition: box-shadow var(--motion-control);
}
.art-button:focus-visible {
  outline: none;
}
/* One selection state, the same for mouse, keyboard and remote: the card you are on lifts a
   little and wears the gold ring. Hovering only hints at it. Nothing grows, so neighbours and the
   row never shift. */
.media-card.is-active .art-button,
.art-button:focus-visible {
  translate: 0 -4px;
  box-shadow: 0 10px 24px -8px var(--accent-glow);
}
.media-card.is-active .art-button::after,
.art-button:focus-visible::after {
  box-shadow: inset 0 0 0 2px var(--accent-hover);
}
@media (hover: hover) and (pointer: fine) {
  .media-card:not(.is-active):hover .art-button::after {
    box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent-hover) 45%, transparent);
  }
}
.art-button img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity var(--motion-view);
}
.art-button img.art-loaded {
  opacity: 1;
}
.art-button img.art-contain {
  object-fit: contain;
  background: var(--surface);
}
.art-button img.art-cover {
  object-fit: cover;
}
.art-button img.art-failed {
  visibility: hidden;
}
.art-fallback {
  position: absolute;
  inset: 0;
  z-index: -1;
  display: grid;
  place-items: center;
  padding: 16px;
  text-align: center;
  font-size: 16px;
  font-weight: 650;
  overflow-wrap: anywhere;
  color: var(--muted);
  background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 22%, #221b12), #1a1612 55%, #121112);
}
.progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1;
  height: 4px;
  background: var(--accent-track);
}
.progress span {
  display: block;
  height: 100%;
  min-width: 2%;
  background: var(--accent);
}
.card-caption {
  display: flex;
  align-items: center;
  gap: 5px;
  min-height: 24px;
  padding-top: var(--gap-caption);
}
.card-caption h3 {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-card);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-meta,
.card-reason {
  margin-top: 3px;
  font-size: var(--fs-caption);
  line-height: 1.4;
  min-height: 1.4em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-meta {
  color: var(--muted);
}
.card-meta[data-kind="progress"],
.card-meta[data-kind="new"],
.card-meta[data-kind="next"] {
  color: var(--accent-light);
}
.card-meta[data-kind="saved"] {
  color: var(--meta);
}
/* Why a title is here: the server's reason replaces the plain line. */
.card-reason {
  color: var(--meta);
}
.media-card:has(.card-reason) .card-meta {
  display: none;
}
.media-card.watched .art-button img {
  filter: brightness(0.62) saturate(0.85);
}
.watched-badge {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 1;
  padding: 3px 7px;
  border-radius: 4px;
  background: color-mix(in srgb, var(--bg) 80%, transparent);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
}

/* Skeletons keep the card's boxes, so titles replace them without the row moving. */
.skeleton-card {
  position: relative;
  min-width: 0;
}
.skeleton-art,
.skeleton-text {
  position: relative;
  overflow: hidden;
  background: rgb(255 255 255 / .07);
}
:is(.skeleton-art, .skeleton-text)::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(255 255 255 / .07), transparent);
  translate: -100% 0;
  animation: sheen 1400ms linear infinite;
}
@keyframes sheen {
  to { translate: 100% 0; }
}
.rail:not(.in-viewport) :is(.skeleton-art, .skeleton-text)::after,
.page-hidden :is(.skeleton-art, .skeleton-text)::after {
  animation-play-state: paused;
}
.skeleton-text {
  display: inline-block;
  vertical-align: middle;
  height: 0.8em;
  width: 70%;
  border-radius: 3px;
}
.card-caption .skeleton-text {
  flex: 1;
  width: auto;
  margin-right: 25%;
}
.skeleton-text.short {
  width: 40%;
}
.skeleton-text.heading {
  width: 180px;
  height: 0.9em;
}
.skeleton-button {
  flex: none;
  width: 26px;
  height: 26px;
}

/* ---- Info header: the title you are on, with its buttons, while you browse the rows ----
   A fixed shape right under the top bar: title, one info line, the reason, two lines of
   description, the buttons. Each line keeps its place whether it is empty or not, so moving
   from one title to the next only changes words, never positions. */
#info-header {
  position: fixed;
  z-index: 15;
  left: 0;
  top: 0;
  width: calc(var(--inset) + 35px + 600px);
  max-width: 100%;
  /* A fixed height, empty or not, so the rows always line up with the same edge. */
  height: var(--info-h);
  overflow: hidden;
  padding: calc(var(--bar-h) + 20px) var(--inset) 0 calc(var(--inset) + 35px);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity var(--motion-header-out) var(--ease),
    visibility 0s linear var(--motion-header-out);
}
#info-header.shown {
  opacity: 1;
  visibility: visible;
  transition:
    opacity var(--motion-header-in) var(--ease),
    visibility 0s;
}
#info-header .info-body {
  display: grid;
  justify-items: start;
  gap: 6px;
}
#info-header h2 {
  max-width: 100%;
  font-size: var(--fs-info);
  line-height: 1.15;
  min-height: 1.15em;
  font-weight: 800;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#info-header .metadata {
  min-height: 1.5em;
  flex-wrap: nowrap;
  overflow: hidden;
  white-space: nowrap;
  font-size: 14px;
}
#info-header .info-reason {
  max-width: 100%;
  min-height: 1.45em;
  line-height: 1.45;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--accent-light);
  font-size: 14px;
  font-weight: 600;
}
#info-header .info-description {
  max-width: 560px;
  min-height: calc(2 * 1.47em);
  font-size: 15px;
  line-height: 1.47;
  color: var(--desc);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
#info-header .actions {
  margin-top: 8px;
  flex-wrap: nowrap;
}
/* The header's first appearance fades in; a change of title crossfades (effects.js crossfade). */
#info-header .info-body.entering {
  animation: fade-in 220ms var(--ease) both;
}

/* ---- Quick menu: right-click, Shift+F10 or a long press on a card ---- */
#quick-menu {
  position: fixed;
  z-index: 70;
  width: 260px;
  padding: 8px;
  border-radius: 12px;
  border: 1px solid var(--hairline-soft);
  background: rgb(20 20 22 / .96);
  box-shadow: 0 18px 60px rgb(0 0 0 / .6);
}
#quick-menu h3 {
  padding: 8px 10px 10px;
  font-size: 15px;
  font-weight: 800;
  overflow-wrap: anywhere;
}
#quick-menu .actions {
  display: grid;
  gap: 2px;
}
#quick-menu .actions button {
  width: 100%;
  height: auto;
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
}
#quick-menu .actions button::after {
  content: attr(title);
}
#quick-menu .actions button:hover,
#quick-menu .actions button:focus-visible {
  outline: none;
  background: var(--accent-wash);
}
#quick-menu .actions svg {
  width: 18px;
  height: 18px;
}

/* ---- Browse all, interest picker, row loader ---- */
.browse-all-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: calc(100% - 2 * var(--inset));
  min-height: 62px;
  margin: 12px var(--inset) 0;
  padding: 18px 0;
  border-top: 1px solid var(--hairline);
  background: transparent;
  color: var(--desc);
  font-size: 17px;
  font-weight: 700;
  text-align: left;
}
.browse-all-toggle svg {
  width: 20px;
  height: 20px;
  transition: transform var(--motion-control);
}
.browse-all-toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
.browse-all-toggle:hover {
  color: var(--text);
}
.browse-all-toggle:focus-visible {
  outline: none;
  color: var(--text);
  border-top-color: var(--accent-hover);
}
.browse-all-heading {
  margin: 18px var(--inset) 22px;
  padding-top: 26px;
  border-top: 1px solid var(--hairline-soft);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.catalog-rows .browse-all-heading {
  display: none;
}
.catalog-rows .rail {
  content-visibility: auto;
  contain-intrinsic-size: auto 380px;
}
.personal-row-sentinel {
  height: 2px;
  width: 100%;
  pointer-events: none;
}
.personal-row-loading {
  display: flex;
  gap: 12px;
  align-items: center;
  min-height: 48px;
  margin: -8px var(--inset) 28px;
  color: var(--muted);
}
.personal-row-loading .skeleton-text {
  width: 110px;
  height: 8px;
}
.personal-row-loading .skeleton-text.short {
  width: 52px;
}
.interest-picker {
  margin: 0 var(--inset) 38px;
  padding: 20px 0;
  border-block: 1px solid var(--hairline-soft);
}
.picker-heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px 24px;
  margin-bottom: 20px;
}
.picker-heading .eyebrow {
  margin-bottom: 8px;
}
.picker-heading h2 {
  font-size: 24px;
  font-weight: 800;
}
.picker-hint {
  margin-top: 6px;
  font-size: 14px;
  color: var(--muted);
}
.picker-actions {
  display: flex;
  gap: 10px;
}
.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 16px 12px;
}
.picker-choice {
  position: relative;
  display: grid;
  gap: 8px;
  padding: 0;
  background: none;
  text-align: left;
}
.picker-choice img {
  width: 100%;
  aspect-ratio: 2 / 3;
  object-fit: cover;
  border-radius: var(--r-card);
  background: var(--raised);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: outline-color var(--motion-control), opacity var(--motion-control);
}
.picker-name {
  font-size: 13px;
  color: var(--desc);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.picker-check {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
  opacity: 0;
  scale: 0.8;
  transition: opacity var(--motion-control), scale var(--motion-control);
}
.picker-check svg {
  width: 15px;
  height: 15px;
}
.picker-choice[aria-pressed="true"] img {
  outline-color: var(--accent);
}
.picker-choice[aria-pressed="true"] .picker-check {
  opacity: 1;
  scale: 1;
}
.picker-choice:hover img {
  opacity: 0.85;
}

/* ---- Empty states (with a constellation where something is waiting) ---- */
.empty-state {
  padding: 28px var(--inset);
  color: var(--muted);
  font-size: 17px;
  line-height: 1.5;
}
.empty-state h3 {
  color: var(--text);
  font-size: 26px;
  font-weight: 700;
  margin-bottom: 8px;
}
.empty-state.with-sky {
  display: grid;
  justify-items: center;
  text-align: center;
  padding-block: 24px 48px;
}
.empty-state .constellation {
  width: min(420px, 90%);
  height: 180px;
  margin-bottom: 8px;
}
.personal-retry .empty-state {
  padding-block: 28px;
}
.search-results .empty-state .button,
.personal-retry .empty-state .button,
.space-error .button {
  margin-top: 18px;
}
.constellation {
  display: block;
  color: var(--accent);
}
.constellation svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
.constellation .star {
  fill: var(--accent-light);
  animation: twinkle 6s ease-in-out infinite;
  animation-delay: var(--delay, 0ms);
}
.constellation .halo {
  fill: var(--accent);
  opacity: 0.18;
}
.constellation .link {
  stroke: var(--accent);
  stroke-width: 1;
  opacity: 0.3;
}
.constellation .link.faint {
  opacity: 0.12;
}
.constellation .anchor {
  fill: none;
  stroke: var(--accent);
  stroke-opacity: 0.55;
  stroke-width: 1.5;
}
.constellation.is-offscreen .star,
.page-hidden .constellation .star {
  animation-play-state: paused;
}
@keyframes twinkle {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* ---- Panels: shade, full-screen pages and dialogs ---- */
.shade {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: #000a;
}
.overlay {
  position: fixed;
  z-index: 50;
  background: var(--surface);
}
.panel-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-bottom: 24px;
}
.panel-heading h2 {
  font-size: var(--fs-page);
  font-weight: 800;
}
.panel-heading .eyebrow {
  margin-bottom: 8px;
}
/* Underline tabs (My Space filters and destinations): the same gold bar as the top bar. */
.segments {
  position: relative;
  isolation: isolate;
  display: flex;
  gap: 24px;
  margin-bottom: 26px;
}
.segments button {
  position: relative;
  background: none;
  padding: 10px 0;
  color: var(--nav);
  font-size: 16px;
}
.segments button:hover,
.segments button.selected {
  color: var(--text);
}
.segments button.selected {
  font-weight: 800;
}
.segments button:focus-visible {
  outline: none;
  color: var(--text);
}

/* My Space as "Tonight" (space/space.js): one suggestion for the time you have on its own art, the
   lineup under it, an honest look at old saves and what you finished; Liked and Downloads as tiles.
   Its rows are Home's (ring headings, chevrons, cards), and it arrives from a skeleton of its shape. */
.collection {
  inset: 0;
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--hairline) transparent;
  padding: calc(var(--bar-h) * .55) var(--inset) 60px;
  background: var(--bg);
}
.space-bar {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}
.space-bar h2 {
  margin-right: auto;
  font-size: var(--fs-page);
  font-weight: 800;
}
.space-time {
  margin: 0;
}
.space-time button[aria-checked="true"] {
  color: var(--text);
  font-weight: 800;
}
.space-time button:focus-visible {
  color: var(--accent-light);
}
.tonight {
  position: relative;
  isolation: isolate;
  display: grid;
  align-items: end;
  min-height: min(56svh, 540px);
  padding: 40px clamp(20px, 4vw, 56px);
  border-radius: var(--r-tile);
  overflow: hidden;
}
/* The art and its scrim belong to the words, so a new title's art crossfades with them. */
.tonight-words {
  max-width: 560px;
}
.tonight-copy {
  display: grid;
  justify-items: start;
  gap: 10px;
}
.tonight-words::before,
.tonight-words::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -2;
  background: var(--tonight-art) center 25% / cover;
}
.tonight-words::after {
  z-index: -1;
  background:
    linear-gradient(90deg, var(--bg) 0, color-mix(in srgb, var(--bg) 72%, transparent) 42%, transparent 78%),
    linear-gradient(0deg, color-mix(in srgb, var(--bg) 80%, transparent), transparent 55%);
}
/* Nothing on the stage: a soft gold light instead of art. */
.tonight-words.empty::before {
  background: radial-gradient(ellipse at 75% 20%, var(--accent-soft), transparent 60%), var(--surface);
}
.tonight-name {
  font-size: var(--fs-title);
  font-weight: 800;
  line-height: 1.05;
}
.tonight-logo {
  max-width: 340px;
  max-height: 96px;
  object-fit: contain;
  object-position: left;
}
.tonight-line {
  color: var(--meta);
  font-size: var(--fs-meta);
}
.tonight .spoken-actions {
  justify-content: flex-start;
}
/* Decide for me breathes out before the new title comes in, and lands with a gold ring on Play. */
.tonight .tonight-words {
  transition: opacity var(--motion-reveal) var(--ease);
}
.tonight.deciding .tonight-words {
  opacity: .55;
}
.play.landed .play-ring {
  animation: ring-pulse 1100ms var(--ease) 300ms 2;
}
@keyframes ring-pulse {
  from { box-shadow: 0 0 0 0 var(--accent-glow); }
  to { box-shadow: 0 0 0 14px transparent; }
}
/* Not tonight: the words slide aside while the art crossfades (effects.js crossfade). */
::view-transition-old(tonight-copy) {
  animation: slide-out var(--motion-cross-out) var(--ease) both;
}
::view-transition-new(tonight-copy) {
  animation: slide-in var(--motion-cross-in) var(--ease) 60ms both;
}
::view-transition-new(tonight-skip) {
  animation: fade-in var(--motion-cross-in) var(--ease) both;
}
@keyframes slide-out { to { opacity: 0; translate: -32px 0; } }
@keyframes slide-in { from { opacity: 0; translate: 32px 0; } }
/* The skeleton keeps the stage's shape and the lineup's row. */
.space-loading .tonight-copy {
  width: min(420px, 70vw);
}
.space-loading .tonight-copy .skeleton-text {
  width: 60%;
}
.space-loading .tonight-copy .bone-title {
  width: 100%;
  height: 2.4em;
}
.space-loading .tonight-copy .bone-actions {
  width: 50%;
  height: 1.6em;
}
.space-part .skeleton-art {
  aspect-ratio: 16 / 9;
  border-radius: var(--r-card);
}
/* A season as dots: gold watched, a ring for the next one. */
.journey {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
}
.journey-dots {
  display: flex;
  gap: 5px;
}
.journey-dots span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgb(255 255 255 / .18);
}
.journey-dots .done {
  background: var(--accent);
}
.journey-dots .next {
  background: none;
  box-shadow: inset 0 0 0 1.5px var(--accent-light);
}
.journey.compact {
  margin-top: 7px;
}
.journey.compact .journey-dots {
  gap: 3px;
}
.journey.compact .journey-dots span {
  width: 5px;
  height: 5px;
}
.journey-left,
.still-card span,
.space-links small {
  color: var(--muted);
  font-size: var(--fs-caption);
}
/* The rows: Home's ring heading with a count, chevrons, and a track that lets cards lift. */
.space-part {
  margin-top: 40px;
}
.space-part .rail-heading {
  padding: 0;
}
.space-part .rail-track {
  grid-auto-columns: var(--landscape-w);
  padding: 14px 4px 12px;
  margin-inline: -4px;
  scroll-padding-inline: 4px;
}
.lineup-card.longer {
  opacity: .55;
  transition: opacity var(--motion-card);
}
.lineup-card.longer:is(:hover, :focus-within) {
  opacity: .9;
}
.lineup-card .art-button::before {
  content: "";
  position: absolute;
  inset: 45% 0 0;
  z-index: 1;
  background: linear-gradient(transparent, rgb(0 0 0 / .6));
  pointer-events: none;
}
.lineup-number {
  position: absolute;
  left: 12px;
  bottom: 4px;
  z-index: 1;
  font-size: clamp(30px, 1.4vw + 20px, 46px);
  font-weight: 800;
  line-height: 1;
  text-shadow: 0 2px 12px rgb(0 0 0 / .7);
}
.finished.rail-track {
  grid-auto-columns: clamp(92px, 7vw, 124px);
}
.finished-card,
.still-art,
.download-art {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  aspect-ratio: 2 / 3;
  padding: 0;
  border-radius: var(--r-card);
  background: var(--raised);
}
:is(.finished-card, .still-art, .download-art) img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:is(.still-art, .download-art) .art-fallback {
  padding: 3px;
  font-size: 8px;
}
.finished-card .art-fallback {
  padding: 10px;
  font-size: 13px;
}
.finished-card {
  transition: translate var(--motion-card) var(--ease), box-shadow var(--motion-card) var(--ease);
}
.finished-card:focus-visible {
  outline: none;
  translate: 0 -4px;
  box-shadow: 0 0 0 2px var(--accent-hover), 0 10px 24px -8px var(--accent-glow);
}
.finished-card i {
  position: absolute;
  top: 6px;
  right: 6px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--on-accent);
}
.finished-card svg {
  width: 13px;
}
.finished-card.arrive i {
  animation: badge-in 420ms var(--ease) calc(var(--i) * 70ms + 250ms) both;
}
@keyframes badge-in {
  from { opacity: 0; scale: .3; }
  60% { scale: 1.15; }
}
/* Still want to watch?: a small poster and two words; Let go turns into a 6 s Undo bar. */
.still-card,
.still-undo {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 112px;
  margin-top: 10px;
  padding: 14px 0;
  border-block: 1px solid var(--hairline-soft);
}
.still-art {
  flex: none;
  width: 56px;
  border-radius: 6px;
}
.still-card p,
.still-undo p {
  flex: 1;
  display: grid;
  gap: 4px;
}
.still-card .spoken-actions {
  margin: 0;
}
.still-undo.fresh {
  animation: slide-in var(--motion-card) var(--ease) both;
}
.undo-count {
  min-width: 3ch;
  color: var(--muted);
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
}
.undo-line {
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--accent);
  transform-origin: left;
  animation: drain 6s linear both;
}
@keyframes drain { to { scale: 0 1; } }
body[data-motion="low"] .undo-line {
  display: none;
}
/* Liked and Downloads: two quiet tiles with an icon and a count. */
.space-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 280px));
  gap: 12px;
  margin-top: 44px;
}
.space-links button {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: var(--r-tile);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hairline-soft);
  text-align: left;
  transition: background-color var(--motion-control), box-shadow var(--motion-control);
}
.space-links button:is(:hover, :focus-visible) {
  outline: none;
  background: var(--raised);
  box-shadow: inset 0 0 0 2px var(--accent-hover);
}
.tile-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-light);
}
.tile-icon svg {
  width: 18px;
}
.space-links strong {
  display: block;
  font-size: var(--fs-card);
  font-weight: 600;
}
.space-body > .space-part:first-child {
  margin-top: 4px;
}
.collection-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--poster-w), 1fr));
  gap: 28px var(--gap-card);
}
.collection-grid:has(.resume-card),
.collection-grid:has(.landscape-card) {
  grid-template-columns: repeat(auto-fill, minmax(var(--landscape-w), 1fr));
}
.collection-grid .empty-state {
  grid-column: 1 / -1;
  padding: 24px 0;
}
.remove-item {
  font-size: 13px;
  color: var(--muted);
  padding: 6px 0;
  background: none;
}
.remove-item:hover {
  color: var(--text);
}
.library-surface {
  display: none !important;
}

/* ---- Title page: full screen, its own artwork, the info block, episodes ---- */
.details {
  inset: 0;
  overflow: auto;
  overscroll-behavior: contain;
  background: var(--bg);
}
/* The TV's "horizon" title page: the picture edge to edge at the top (68% high for a film, 46% for a
   series) fading into black, and one centred 720px column at the bottom. */
.title-horizon {
  position: relative;
  min-height: 100%;
  display: grid;
  align-content: end;
  padding: 0 var(--inset) 26px;
  background: var(--base-bg);
}
.horizon-picture {
  position: absolute;
  inset: 0 0 auto;
  height: 68svh;
  overflow: hidden;
  pointer-events: none;
}
.series .horizon-picture {
  height: 46svh;
}
.horizon-picture img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 25%;
  opacity: 0;
  transition: opacity 280ms;
}
.horizon-picture img.art-loaded,
.previewing.has-still .horizon-picture .episode-still {
  opacity: 1;
}
.previewing.has-still .horizon-picture img:not(.episode-still) {
  opacity: 0;
}
.horizon-picture::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(circle at 0 0, rgb(0 0 0 / .3), transparent 30%),
    radial-gradient(circle at 100% 0, rgb(0 0 0 / .3), transparent 30%),
    linear-gradient(rgb(0 0 0 / .22), transparent 16% 38%, rgb(0 0 0 / .62) 66%, rgb(0 0 0 / .94) 86%, var(--base-bg));
}
.title-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 30px var(--inset);
}
.title-bar .brand {
  font-size: 20px;
}
.title-bar .brand::before {
  width: 4px;
  height: 20px;
}
.detail-body {
  position: relative;
  width: min(720px, 100%);
  margin: calc(46svh - 40px) auto 0;
  display: grid;
  justify-items: center;
  gap: 8px;
  text-align: center;
}
.title-horizon:not(.series) .detail-body {
  margin-top: calc(68svh - 200px);
}
.horizon-line {
  width: 64px;
  height: 1px;
  margin-bottom: 6px;
  background: color-mix(in srgb, var(--accent) 60%, transparent);
}
.horizon-words {
  grid-area: 2 / 1;
  display: grid;
  justify-items: center;
  gap: 8px;
  transition: opacity 250ms;
}
.previewing .horizon-words:not(.episode-words),
.title-horizon:not(.previewing) .episode-words {
  opacity: 0;
  visibility: hidden;
}
.horizon-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--accent);
}
.horizon-name {
  font-size: 32px;
  font-weight: 500;
  line-height: 1.15;
  color: #f6f0df;
  text-wrap: balance;
  overflow-wrap: anywhere;
}
.series .horizon-name {
  font-size: 28px;
}
.episode-words .horizon-name {
  font-size: 26px;
}
.horizon-name img {
  display: block;
  max-width: 360px;
  max-height: 64px;
  object-fit: contain;
  filter: drop-shadow(0 2px 12px rgb(0 0 0 / .7));
}
.series .horizon-name img {
  max-height: 52px;
}
.horizon-meta {
  font-size: 13px;
  color: #bdbcc2;
}
.horizon-reason {
  font-size: 13px;
  color: var(--accent-light);
}
.horizon-description {
  max-width: 620px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--desc);
  text-wrap: balance;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.series .horizon-description {
  -webkit-line-clamp: 2;
}
.horizon-resume {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--accent-light);
}
.horizon-resume span {
  width: 120px;
  height: 2px;
  background: linear-gradient(90deg, var(--accent) calc(var(--f) * 100%), rgb(255 255 255 / .2) 0);
}
/* The actions as spoken words, gold dots between them: gold-light and underlined when pointed at. */
.spoken-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 18px;
  margin-top: 10px;
}
.spoken-action + .spoken-action::before {
  content: "";
  width: 4px;
  height: 4px;
  margin-right: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 55%, transparent);
}
.spoken-action {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 0;
  background: none;
  font-size: 16px;
  font-weight: 500;
  color: rgb(247 247 248 / .82);
}
.spoken-action > span:last-child {
  text-decoration: underline 1px transparent;
  text-underline-offset: 6px;
  transition: color 180ms, text-decoration-color 180ms;
}
.spoken-action[aria-pressed="true"] {
  color: var(--accent);
}
.spoken-action:is(:hover, :focus-visible) {
  outline: none;
  color: var(--accent-light);
}
.spoken-action:is(:hover, :focus-visible) > span:last-child {
  text-decoration-color: var(--accent);
}
.play-ring {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 50%;
}
.play-ring svg {
  width: 13px;
  height: 13px;
}
.play:is(:hover, :focus-visible) .play-ring {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 15%, transparent);
}
/* A series: its seasons, then the scrubber with a notch per episode. */
#episodes {
  width: 100%;
  margin-top: 16px;
}
.season-tabs {
  position: relative;
  isolation: isolate;
  display: flex;
  justify-content: center;
  gap: 24px;
  overflow-x: auto;
  scrollbar-width: none;
}
.season-tabs button {
  position: relative;
  flex: none;
  padding: 8px 0;
  background: none;
  color: var(--nav);
  font-size: 15px;
}
.season-tabs button[aria-selected="true"],
.season-tabs button:focus-visible {
  outline: none;
  color: var(--text);
}
.season-scrubber {
  margin-top: 14px;
}
.scrubber-words {
  display: flex;
  justify-content: center;
  gap: 10px;
  min-height: 18px;
  font-size: 12px;
  color: var(--desc);
}
.previewing .scrubber-words {
  opacity: 0;
}
.scrubber-words b {
  color: var(--accent);
  font-weight: 500;
}
.scrubber-words small {
  color: var(--muted);
}
.notches {
  display: flex;
  gap: 4px;
  margin-top: 8px;
}
.notch {
  flex: 1;
  display: grid;
  gap: 6px;
  padding: 6px 0;
  background: none;
  color: var(--muted);
  font-size: 11px;
}
.notch-line {
  position: relative;
  height: 2px;
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 85%, transparent) calc(var(--f) * 100%), rgb(255 255 255 / .18) 0);
  transition: height 180ms;
}
.notch.current .notch-line {
  background: linear-gradient(90deg, var(--accent-light) calc(var(--f) * 100%), rgb(255 255 255 / .45) 0);
}
.notch.current .notch-line::after {
  content: "";
  position: absolute;
  left: calc(var(--f) * 100%);
  top: 50%;
  width: 6px;
  height: 6px;
  margin: -3px;
  border-radius: 50%;
  background: var(--accent-light);
}
.notch:is(:hover, :focus-visible) {
  outline: none;
  color: var(--accent-light);
}
.notch:is(:hover, :focus-visible) .notch-line {
  height: 3px;
}
.notch:focus-visible .notch-line::after {
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 25%, transparent);
}
/* Arriving: the picture, then the horizon line, the words rising 8px, then the actions. */
.arriving .horizon-picture {
  animation: fade-in 280ms var(--ease) both;
}
.arriving .horizon-line {
  animation: grow 400ms var(--ease) 120ms both;
}
.arriving .horizon-words {
  animation: rise 280ms var(--ease) 200ms both;
}
.arriving :is(.spoken-actions, #episodes) {
  animation: rise 280ms var(--ease) 260ms both;
}
@keyframes fade-in { from { opacity: 0; } }
@keyframes grow { from { width: 0; } }
@keyframes rise { from { opacity: 0; translate: 0 8px; } }
body[data-motion="low"] .arriving * {
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  .arriving * { animation: none; }
}

/* ---- Search results ---- */
#browse.searching #hero {
  display: none;
}
#browse.searching .rails {
  margin-top: 0;
  padding-top: calc(var(--bar-h) + 40px);
  min-height: 100svh;
}
.search-heading {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 0;
  padding: 0 var(--inset);
  margin-bottom: 26px;
}
.search-heading h2 {
  font-size: var(--fs-page);
  font-weight: 800;
  overflow-wrap: anywhere;
}
.search-heading h2::before {
  display: none;
}
.search-note {
  margin: -14px 0 24px;
  padding: 0 var(--inset);
  color: var(--muted);
  font-size: 14px;
}
.search-rows {
  transition: opacity var(--motion-control);
}
.search-results.loading .search-rows {
  opacity: 0.45;
}
/* Searching: the player loading screen's sky, headline and quiet line (shared in player.css). */
.search-waiting {
  display: grid;
  justify-items: center;
  padding: 0 var(--inset) 64px;
  text-align: center;
  text-shadow: 0 1px 14px #000c;
}
.search-sky {
  position: relative;
  width: min(520px, 88%);
  aspect-ratio: 9 / 4;
}
/* The mark sits where the player's poster would (constellation.js: x ±1/3, y ±.5 of its sky). */
.constellation .search-mark {
  position: absolute;
  left: 50%;
  top: 59.4%;
  width: 18.5%;
  translate: -50% -50%;
  fill: var(--accent);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.constellation .search-mark .m {
  fill: none;
  stroke: var(--accent-light);
  stroke-width: 7;
}
/* Solid lines that fade in (a dash on a non-scaling stroke draws as dots at this size). */
.search-waiting .search-sky.constellation .link {
  stroke-dasharray: none;
  animation-name: link-in;
}
@keyframes link-in {
  from { opacity: 0; }
}
/* The backdrop steps back while searching, so the sky and the results read on it. */
body:has(#browse.searching) .stage-hero {
  opacity: 0.25;
}
.search-waiting .loading-detail {
  color: var(--desc);
}
/* Refining: the old rows stay, dimmed, and a thin gold line runs along the foot of the field. */
.search.busy #search-input {
  background: linear-gradient(90deg, #0000, var(--accent), #0000) no-repeat -40% 100% / 40% 2px, var(--tile);
  animation: field-sweep 1.2s linear infinite;
}
@keyframes field-sweep {
  to { background-position: 140% 100%, 0 0; }
}

/* ---- Toast and offline banner ---- */
.toast {
  position: fixed;
  bottom: 40px;
  left: 50%;
  translate: -50% 0;
  z-index: 100;
  max-width: calc(100% - 32px);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 24px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: color-mix(in srgb, var(--raised) 94%, transparent);
  font-size: 15px;
  font-weight: 600;
  box-shadow: 0 12px 34px #0008;
}
.toast::before,
.offline-banner::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
}
.offline-banner {
  position: fixed;
  top: 12px;
  left: 50%;
  translate: -50% 0;
  z-index: 120;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 32px);
  padding: 9px 16px;
  border: 1px solid var(--accent-soft);
  border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 95%, transparent);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  box-shadow: 0 8px 24px #0000008c;
}
.transition-ghost {
  position: fixed;
  overflow: hidden;
  pointer-events: none;
}
/* The calm crossfade (effects.js crossfade, the TV's Immersive.kt): the old words fade out while the
   new ones fade in a moment later, drifting up into place. Only named parts take part. */
:root {
  view-transition-name: none;
}
::view-transition {
  pointer-events: none;
}
::view-transition-old(*) {
  animation: fade-out var(--motion-cross-out) var(--ease) both;
}
::view-transition-new(*) {
  animation: rise var(--motion-cross-in) var(--ease) 60ms both;
}
@keyframes fade-out { to { opacity: 0; } }

/* ---- Tablets ---- */
@media (max-width: 1000px) {
  .topbar {
    gap: 20px;
  }
  .browse-nav {
    gap: 33px;
  }
  .view-tabs::before {
    left: -17px;
  }
  :is(.world-tabs, .view-tabs) {
    gap: 14px;
  }
  .header-actions {
    gap: 8px;
  }
}
/* While searching on a laptop-sized window the field needs the room: MEDIA Extras steps aside. */
@media (max-width: 1180px) {
  .topbar.search-open #extras-button {
    display: none;
  }
}
@media (max-width: 900px), (hover: none), (pointer: coarse) {
  /* No fixed layers on touch screens: the stage scrolls away with the hero (as effects.js decides). */
  #stage {
    position: absolute;
    bottom: auto;
    height: max(520px, 90svh);
  }
  #info-header {
    display: none;
  }
}

/* ---- Phones ---- */
@media (max-width: 600px) {
  .topbar {
    height: auto;
    padding: 10px var(--inset) 6px;
    flex-wrap: wrap;
    gap: 2px 12px;
    background: linear-gradient(color-mix(in srgb, var(--bg) 94%, transparent), color-mix(in srgb, var(--bg) 70%, transparent) 70%, transparent);
  }
  .brand {
    font-size: 22px;
  }
  .brand::before {
    width: 4px;
    height: 21px;
    margin-right: 9px;
  }
  .browse-nav {
    order: 3;
    width: 100%;
    gap: 33px;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .view-tabs::before {
    left: -17px;
    height: 20px;
  }
  :is(.world-tabs, .view-tabs) {
    gap: 18px;
    flex: none;
  }
  .nav-link {
    padding: 10px 0;
    font-size: 15px;
  }
  .header-actions {
    gap: 6px;
  }
  #my-space-button,
  #extras-button,
  #settings-button {
    display: none;
  }
  .avatar {
    width: 36px;
    height: 36px;
    font-size: 15px;
  }
  .topbar.search-open .search {
    position: absolute;
    left: var(--inset);
    right: var(--inset);
    top: 10px;
    z-index: 2;
    background: var(--bg);
  }
  .topbar.search-open #search-input {
    flex: 1;
    width: 100%;
  }
  .mobile-navigation {
    position: fixed;
    z-index: 30;
    inset: auto 0 0;
    display: flex;
    justify-content: space-around;
    gap: 0;
    height: calc(64px + env(safe-area-inset-bottom));
    padding: 0 8px env(safe-area-inset-bottom);
    background: color-mix(in srgb, var(--bg) 96%, transparent);
    border-top: 1px solid var(--hairline);
  }
  .mobile-navigation button {
    position: relative;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: 3px;
    width: 84px;
    padding: 4px;
    background: none;
    color: var(--nav);
    font-size: 11px;
  }
  .mobile-navigation button.current {
    color: var(--text);
  }
  .mobile-navigation button.current svg {
    color: var(--accent);
  }
  .mobile-navigation button.current::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 24px;
    height: 2px;
    translate: -50% 0;
    border-radius: 2px;
    background: var(--accent);
  }
  .mobile-navigation svg {
    width: 22px;
    height: 22px;
  }
  .hero {
    height: 72svh;
    min-height: 460px;
  }
  #stage {
    height: max(460px, 72svh);
  }
  .hero-content {
    width: 100%;
    padding: 0 var(--inset) 64px;
    gap: 8px;
  }
  .hero-content::before {
    display: none;
  }
  .hero .eyebrow {
    font-size: 11px;
  }
  .hero-description {
    font-size: 14px;
  }
  .hero .spoken-action {
    min-height: 44px;
  }
  .scrim-x {
    background: linear-gradient(to right, color-mix(in srgb, var(--bg) 70%, transparent), transparent 90%);
  }
  .rails {
    margin-top: -28px;
    padding-bottom: 110px;
  }
  .rail-heading {
    margin-bottom: 0;
  }
  .rail-controls {
    display: none;
  }
  .rail h2 {
    gap: 2px 12px;
  }
  .rail h2::before {
    width: 11px;
    height: 11px;
    margin-right: 0;
  }
  .rail-subtitle {
    width: 100%;
    padding-left: 23px;
  }
  .rail-track {
    padding-block: 10px 14px;
  }
  .rail {
    scroll-margin-top: 110px;
    scroll-margin-bottom: 96px;
  }
  .card-caption {
    flex-wrap: wrap;
  }
  .card-caption h3 {
    flex-basis: 100%;
  }
  .collection {
    padding: 18px var(--inset) 110px;
  }
  .space-bar {
    flex-wrap: wrap;
  }
  .space-time {
    order: 3;
    width: 100%;
  }
  .tonight {
    min-height: 62svh;
    padding: 20px;
  }
  .space-links {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .still-card {
    flex-wrap: wrap;
  }
  .collection-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px 12px;
  }
  .collection-grid:has(.resume-card),
  .collection-grid:has(.landscape-card) {
    grid-template-columns: minmax(0, 1fr);
  }
  .detail-body {
    margin-top: 30svh;
  }
  .horizon-name img {
    max-width: 70vw;
  }
  #browse.searching .rails {
    padding-top: 128px;
  }
  .search-heading .rail-subtitle {
    display: inline;
  }
  .toast {
    bottom: calc(80px + env(safe-area-inset-bottom));
  }
}
@media (max-width: 600px) and (pointer: coarse) {
  .rail-track {
    scroll-snap-type: x mandatory;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
  }
  .media-card .art-button,
  .art-button:focus-visible,
  .hero-art {
    scale: 1 !important;
    translate: none !important;
  }
}
body[data-motion="low"] .media-card .art-button {
  scale: 1 !important;
}
/* Low motion (Settings › Appearance): what loops for decoration (stars, sheens, breathing marks)
   stands still, and one-off entrances finish at once. */
body[data-motion="low"] *,
body[data-motion="low"] *::before,
body[data-motion="low"] *::after {
  animation-duration: 1ms !important;
  animation-iteration-count: 1 !important;
}
/* Someone waits in Beta requests (the owner's admin profile, desktop app). */
:is(#settings-button,#my-space-button)[data-attention]{position:relative}
:is(#settings-button,#my-space-button)[data-attention]::after{content:"";position:absolute;top:9px;right:9px;width:7px;height:7px;border-radius:50%;background:var(--accent)}
/* MEDIA Extras (extras.js): the bundle bar with its three slots and price, then the extras as cards. */
.extras-lead {
  max-width: 720px;
  margin: 0 0 24px;
  color: var(--desc);
  font-size: 17px;
}
.extras-bundle {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 18px 32px;
  align-items: center;
  margin-bottom: 36px;
  padding: 22px 0;
  border-block: 1px solid var(--hairline);
}
.extras-slots {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.extras-slot {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 16px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  color: var(--accent-light);
  font-weight: 600;
}
.extras-slot svg {
  width: 16px;
  height: 16px;
}
.extras-slot.empty {
  border-style: dashed;
  border-color: var(--hairline);
  color: var(--muted);
  font-weight: 500;
}
.extras-slot.extra small {
  color: var(--muted);
}
.extras-sum {
  text-align: right;
}
.extras-price {
  font-size: 18px;
}
.extras-price strong {
  font-size: 26px;
}
.extras-note,
.extras-status {
  color: var(--muted);
  font-size: 13px;
}
.extras-actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.extras-group {
  margin: 28px 0 14px;
  color: var(--muted);
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.extras-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
  gap: 16px;
}
.extras-card {
  display: grid;
  align-content: start;
  gap: 8px;
  min-height: 190px;
  padding: 20px;
  border: 1px solid var(--hairline);
  border-radius: var(--r-tile);
  background: var(--tile);
  color: var(--text);
  text-align: left;
  transition: scale var(--motion-card) var(--ease), border-color var(--motion-card), background var(--motion-card);
}
.extras-card:hover:not(:disabled),
.extras-card:focus-visible {
  scale: 1.04;
  background: var(--glass-hover);
}
.extras-card.chosen {
  border-color: var(--accent);
}
.extras-card small {
  color: var(--desc);
  font-size: 13px;
}
.extras-icon {
  display: inline-grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent-light);
}
.extras-icon svg {
  width: 20px;
  height: 20px;
}
.extras-state {
  margin-top: auto;
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}
.extras-card.chosen .extras-state {
  color: var(--accent-light);
}
.extras-card.soon {
  opacity: .55;
}
@media (max-width: 760px) {
  .extras-bundle { grid-template-columns: 1fr; }
  .extras-sum { text-align: left; }
}
