/* ==========================================================================
   Previously — TMDB quick-view modal · v20261002b (2026-10-02)
   --------------------------------------------------------------------------
   MOBILE-FIRST. Clicking a movie/TV card on /browse/ opens this quick-view
   BEFORE the full title page: backdrop, rating, full synopsis, cast with
   photos, director/creators, genres, trailer, "View full page" CTA.

   James 2026-10-02: "Have it fit in view. Build this for laptop and mobile
   from the ground up so they both fit. Respectively."

   - Base (mobile, 375px): full-screen sheet, single column, everything in
     normal document flow. Text wraps. Cast rail scrolls independently.
     Trailer fits 16:9 within the viewport width. No horizontal overflow.
   - Desktop (min-width 701px): centered 920px cinematic dialog, backdrop
     hero + two-column body (poster left, details right).
   - Real TMDB artwork only. Reduced-motion respected.
   ========================================================================== */

/* ---------- overlay ---------- */
.pv-qv{ position: fixed; inset: 0; z-index: 300; display: flex; align-items: stretch; justify-content: center; padding: 0; }.pv-qv[hidden]{ display: none; }.pv-qv__scrim{ position: absolute; inset: 0; background: rgba(var(--desert-card-rgb), 0.8); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); opacity: 0; transition: opacity 0.25s ease; cursor: pointer; }.pv-qv.open .pv-qv__scrim{ opacity: 1; }/* ---------- dialog: mobile base (full-screen sheet) ---------- */
.pv-qv__dialog{ position: relative; width: 100%; height: 100%; max-height: none; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; background: var(--desert-bg); border: 0; border-radius: 0; box-shadow: none; transform: translateY(24px); opacity: 0; transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.25, 1), opacity 0.22s ease; }.pv-qv.open .pv-qv__dialog{ transform: none; opacity: 1; }.pv-qv__dialog:focus{ outline: none; }/* ---------- close ---------- */
.pv-qv__close{ position: absolute; top: 12px; right: 12px; z-index: 5; width: 40px; height: 40px; border-radius: 50%; border: 1px solid rgba(var(--desert-ink-rgb), 0.25); background: rgba(var(--desert-ink-rgb), 0.65); color: var(--desert-card); font-size: 22px; line-height: 1; cursor: pointer; -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); transition: background 0.2s, transform 0.2s; }.pv-qv__close:hover{ background: rgba(var(--brand-red-rgb), 0.85); transform: scale(1.06); }/* ---------- hero ---------- */
.pv-qv__hero{ position: relative; min-height: 220px; display: flex; align-items: flex-end; background: var(--desert-pressed); overflow: hidden; }.pv-qv__bg{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }.pv-qv__shade{ position: absolute; inset: 0; background: linear-gradient(180deg, rgba(var(--scrim-black-rgb),0) 30%, rgba(var(--scrim-black-rgb),.72) 100%); }.pv-qv__head{ position: relative; z-index: 2; padding: 20px 20px 18px; width: 100%; min-width: 0; }.pv-qv__kicker{ color: var(--pv-red, var(--brand-red)); font-size: 12px; letter-spacing: 0.24em; text-transform: uppercase; font-weight: 700; margin: 0 0 10px; }.pv-qv__title{ margin: 0 0 10px; font-size: clamp(26px, 7.4vw, 34px); letter-spacing: -0.02em; line-height: 1.08; color: var(--desert-card); text-shadow: 0 1px 8px rgba(var(--scrim-black-rgb),.5); overflow-wrap: break-word; word-wrap: break-word; }.pv-qv__meta{ display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin: 0 0 12px; color: rgba(var(--desert-card-rgb),.78); font-size: 14px; }.pv-qv__rate{ display: inline-flex; align-items: center; gap: 5px; background: rgba(var(--brand-red-rgb), 0.16); border: 1px solid rgba(var(--brand-red-rgb), 0.55); color: var(--desert-card); font-weight: 700; font-size: 13px; padding: 4px 12px; border-radius: 4px; white-space: nowrap; }.pv-qv__genres{ display: flex; flex-wrap: wrap; gap: 6px 18px; margin: 0; }.pv-qv__genre{ font-size: 12.5px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600; color: var(--desert-card); padding: 3px 1px; white-space: nowrap; text-shadow: 0 1px 6px rgba(var(--scrim-black-rgb),.55); }a.pv-qv__genre{ text-decoration: underline; text-underline-offset: 4px; text-decoration-color: rgba(var(--desert-card-rgb),.6); cursor: pointer; transition: color 0.2s, text-decoration-color 0.2s; }a.pv-qv__genre:hover, a.pv-qv__genre:focus-visible{ color: var(--desert-card); text-decoration-color: var(--pv-red, var(--brand-red)); }a.pv-qv__genre:focus-visible{ outline: 2px solid var(--pv-red, var(--brand-red)); outline-offset: 2px; }.pv-qv__genre.is-plain{ cursor: default; }/* ---------- body: single column, everything wraps ---------- */
.pv-qv__body{ display: block; padding: 22px 20px 34px; }.pv-qv__poster{ width: 120px; border-radius: 12px; overflow: hidden; background: var(--desert-pressed); box-shadow: 0 16px 44px rgba(var(--desert-shadow-rgb), 0.5); margin: 0 0 18px; }.pv-qv__poster img{ display: block; width: 100%; height: auto; }.pv-qv__noposter{ display: flex; align-items: center; justify-content: center; aspect-ratio: 2/3; font-size: 64px; font-weight: 800; color: rgba(var(--desert-ink-rgb), .35); }/* synopsis: wraps, never overflows */
.pv-qv__ov{ margin: 0 0 22px; font-size: 15.5px; line-height: 1.65; color: var(--desert-ink); overflow-wrap: break-word; word-wrap: break-word; }.pv-qv__ov:empty{ display: none; }.pv-qv__seclabel{ font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--pv-ivory-dim, var(--desert-ink-dim)); margin: 0 0 12px; font-weight: 700; }/* ---------- cast rail: scrolls BY ITSELF, popup stays put ---------- */
.pv-qv__cast{ display: flex; gap: 14px; overflow-x: auto; overflow-y: hidden; padding: 2px 2px 14px; margin: 0 -20px 20px; padding-left: 20px; padding-right: 20px; scrollbar-width: thin; -webkit-overflow-scrolling: touch; scroll-snap-type: x proximity; }.pv-qv__cast::-webkit-scrollbar{ height: 6px; }.pv-qv__cast::-webkit-scrollbar-thumb{ background: rgba(var(--desert-ink-rgb), 0.2); border-radius: 3px; }.pv-qv__person{ flex: 0 0 76px; scroll-snap-align: start; text-align: center; }a.pv-qv__person{ text-decoration: none; cursor: pointer; border-radius: 10px; transition: background 0.2s; display: block; padding: 4px 2px; margin: -4px -2px; }a.pv-qv__person:hover, a.pv-qv__person:focus-visible{ background: rgba(var(--desert-ink-rgb), 0.06); }a.pv-qv__person:hover .pv-qv__pname, a.pv-qv__person:focus-visible .pv-qv__pname{ color: var(--pv-red, var(--brand-red)); }a.pv-qv__person:focus-visible{ outline: 2px solid var(--pv-red, var(--brand-red)); outline-offset: 2px; }a.pv-qv__person .pv-qv__face{ border-color: rgba(var(--brand-red-rgb), 0.45); }.pv-qv__face{ width: 64px; height: 64px; border-radius: 50%; object-fit: cover; background: var(--desert-pressed); display: block; margin: 0 auto 8px; border: 2px solid rgba(var(--desert-ink-rgb), 0.14); }.pv-qv__face--init{ display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 800; color: var(--desert-ink-dim); }.pv-qv__pname{ display: block; font-size: 12px; font-weight: 600; color: var(--pv-ivory, var(--desert-ink)); line-height: 1.3; overflow-wrap: break-word; word-wrap: break-word; }.pv-qv__prole{ display: block; font-size: 11px; color: var(--pv-ivory-dim, var(--desert-ink-dim)); line-height: 1.3; margin-top: 2px; overflow-wrap: break-word; word-wrap: break-word; }.pv-qv__credit{ margin: 0 0 22px; font-size: 14px; color: var(--pv-ivory-dim, var(--desert-ink-dim)); overflow-wrap: break-word; word-wrap: break-word; }.pv-qv__credit strong{ color: var(--pv-ivory, var(--desert-ink)); font-weight: 600; }/* ---------- trailer: the artwork IS the trigger — seamless in-place play ----------
   No pill button. Tapping the 16:9 artwork crossfades + scales gently into the
   playing video inside the same frame. The video feels like it was always there. */
.pv-qv__trailer{ position: relative; margin: 0 0 24px; max-width: 100%; aspect-ratio: 16/9; border-radius: 12px; overflow: hidden; background: var(--desert-bg); }.pv-qv__trailerart{ position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; background: var(--desert-bg); cursor: pointer; transition: opacity .3s ease, transform .3s ease; }.pv-qv__trailerart:hover .pv-qv__playring, .pv-qv__trailerart:focus-visible .pv-qv__playring{ transform: translate(-50%, -50%) scale(1.1); }.pv-qv__trailerart:focus-visible{ outline: 2px solid var(--pv-red, var(--brand-red)); outline-offset: 3px; }.pv-qv__trailerart.is-playing{ opacity: 0; transform: scale(1.06); pointer-events: none; }.pv-qv__trailerimg{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }.pv-qv__trailershade{ position: absolute; inset: 0; background: linear-gradient(0deg, rgba(var(--desert-shadow-rgb), .5), transparent 55%); pointer-events: none; }.pv-qv__playring{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 76px; height: 76px; transition: transform .25s ease; pointer-events: none; }.pv-qv__playring svg{ width: 100%; height: 100%; display: block; }.pv-qv__playring circle{ fill: rgba(var(--desert-ink-rgb), .55); stroke: rgba(var(--desert-ink-rgb), .9); stroke-width: 2; backdrop-filter: blur(4px); }.pv-qv__playring path{ fill: var(--desert-card); }.pv-qv__trailerlabel{ position: absolute; left: 0; right: 0; bottom: 14px; text-align: center; font-size: 11px; letter-spacing: .28em; text-transform: uppercase; color: rgba(var(--desert-card-rgb),.85); pointer-events: none; }.pv-qv__frame{ position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity .3s ease .06s; background: var(--desert-bg); }.pv-qv__frame.is-live{ opacity: 1; }.pv-qv__frame iframe{ position: absolute; inset: 0; width: 100%; height: 100%; max-width: 100%; border: 0; }/* ---------- actions ---------- */
.pv-qv__actions{ display: flex; align-items: center; gap: 16px; flex-wrap: wrap; border-top: 1px solid rgba(var(--desert-ink-rgb), 0.1); padding-top: 22px; margin-top: 4px; }.pv-qv__cta{ display: inline-block; background: var(--pv-red, var(--brand-red)); color: var(--desert-bg); font-weight: 700; font-size: 15px; padding: 13px 30px; border-radius: 6px; text-decoration: none; transition: transform 0.2s, box-shadow 0.2s; max-width: 100%; }.pv-qv__cta:hover{ transform: translateY(-2px); box-shadow: 0 12px 30px rgba(var(--brand-red-rgb), 0.35); }.pv-qv__kind{ font-size: 12px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--pv-ivory-dim, var(--desert-ink-dim)); }/* ---------- error ---------- */
.pv-qv__err{ padding: 60px 24px; text-align: center; color: var(--pv-ivory-dim, var(--desert-ink-dim)); }.pv-qv__err p{ margin: 0 0 18px; font-size: 15px; }.pv-qv__err button{ background: none; border: 1px solid var(--pv-red, var(--brand-red)); color: var(--pv-red, var(--brand-red)); border-radius: 6px; padding: 10px 26px; font-weight: 700; font-size: 14px; cursor: pointer; }/* ---------- skeleton ---------- */
.pv-qv__sk{ border-radius: 10px; background: linear-gradient(100deg, var(--desert-pressed) 40%, var(--desert-pressed) 50%, var(--desert-pressed) 60%); background-size: 200% 100%; animation: pvqvshimmer 1.3s infinite; }@keyframes pvqvshimmer{to{ background-position: -200% 0; } }.pv-qv__skwrap{ padding: 22px 20px 30px; display: grid; gap: 14px; }.pv-qv__sk--title{ height: 40px; width: 70%; }.pv-qv__sk--meta{ height: 18px; width: 45%; }.pv-qv__sk--line{ height: 15px; }.pv-qv__sk--line.w90{ width: 90%; }.pv-qv__sk--line.w75{ width: 75%; }.pv-qv__sk--cast{ height: 96px; }/* ==========================================================================
   DESKTOP (min-width 701px): cinematic dialog, two-column body
   ========================================================================== */
@media (min-width: 701px){
  .pv-qv { align-items: center; padding: 44px; }
  .pv-qv__dialog { width: min(920px, 100%); height: auto; max-height: calc(100vh - 88px); border: 1px solid rgba(var(--desert-ink-rgb), 0.14); border-radius: 20px; box-shadow: 0 40px 120px rgba(var(--desert-shadow-rgb), 0.65); transform: translateY(16px) scale(0.985); }
  .pv-qv__hero { min-height: 360px; border-radius: 20px 20px 0 0; }
  .pv-qv__head { padding: 28px 36px 26px; }
  .pv-qv__title { font-size: clamp(30px, 3.6vw, 46px); }
  .pv-qv__body { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 30px; padding: 30px 36px 36px; }
  .pv-qv__body > * { min-width: 0; } /* grid overflow fix: children can shrink */
  .pv-qv__poster { width: 200px; margin: 0; align-self: start; }
  .pv-qv__close { top: 14px; right: 14px; }
  .pv-qv__cast { gap: 16px; margin: 0 0 20px; padding-left: 2px; padding-right: 2px; }
  .pv-qv__person { flex-basis: 84px; }
  .pv-qv__face { width: 72px; height: 72px; }
  .pv-qv__skwrap { padding: 30px 36px 40px; }
  .pv-qv__sk--title { height: 44px; }
  .pv-qv__err { padding: 60px 36px; }
}/* ---------- reduced motion ---------- */
@media (prefers-reduced-motion: reduce){
  .pv-qv__scrim, .pv-qv__dialog, .pv-qv__close, .pv-qv__cta, .pv-qv__trailerart, .pv-qv__frame { transition: none; }
  .pv-qv__sk { animation: none; }
  .pv-qv__cast { scroll-snap-type: none; }
}/* ==========================================================================
   FIT FIX · 2026-10-13 (appended) — pv-qv must land on ONE screen with ZERO
   internal scrolling at phone (390x844, 360x660) and laptop (1280x720,
   1440x900). James 2026-10-13 08:12: the pv-qv DESIGN and its content set
   are preserved exactly — this section changes FIT only:
   - the dialog never scrolls internally (overflow hidden, flex column);
   - the ART yields first: hero band drops its forced min-height down to
     the head's natural height on shorter viewports; the trailer facade is
     height-capped via --qv-th (width follows at 16:9, centered, aspect
     always preserved — never cropped, never stretched); the poster steps
     down on short screens;
   - spacing rhythm compresses in height tiers;
   - LAST resort, only at the shortest tiers: the overview line-clamps
     (full text lives on the full page, one tap on the CTA away).
   ========================================================================== */
.pv-qv{ --qv-th: 190px; }
.pv-qv__dialog{ overflow: hidden; display: flex; flex-direction: column; }
#pvQvContent{ display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
.pv-qv__hero{ flex: none; }
.pv-qv__body{ flex: 1 1 auto; min-height: 0; }
.pv-qv__trailer{ width: min(100%, calc(var(--qv-th) * 16 / 9)); margin-left: auto; margin-right: auto; }

/* ---- phones (max-width 700px), all heights: compact two-up top block ----
   Poster floats beside the overview (same poster-left / text-right language
   as the desktop design) instead of stacking a full-width row above it.
   The actions row stays on ONE line like desktop (CTA + kind note). */
@media (max-width: 700px){
  .pv-qv__poster{ float: left; width: 104px; margin: 0 14px 8px 0; }
  .pv-qv__seclabel{ clear: left; }
  .pv-qv__actions{ flex-wrap: nowrap; gap: 12px; }
  .pv-qv__cta{ flex: none; padding: 12px 20px; font-size: 14.5px; }
  .pv-qv__kind{ flex: 1 1 auto; min-width: 0; font-size: 11px; }
}

/* ---- tier 1: viewport height <= 1100px ---------------------------------- */
@media (max-height: 1100px){
  .pv-qv{ --qv-th: 150px; }
  .pv-qv__ov{ margin-bottom: 16px; }
  .pv-qv__cast{ margin-bottom: 14px; }
  .pv-qv__credit{ margin-bottom: 16px; }
  .pv-qv__trailer{ margin-bottom: 18px; }
  .pv-qv__actions{ padding-top: 16px; }
}
@media (min-width: 701px) and (max-height: 1100px){
  .pv-qv{ padding: 28px; }
  .pv-qv__dialog{ max-height: calc(100dvh - 56px); }
  .pv-qv__hero{ min-height: 0; }
  .pv-qv__body{ padding: 24px 36px 28px; }
}
@media (max-width: 700px) and (max-height: 1100px){
  .pv-qv__body{ padding: 18px 20px 20px; }
  .pv-qv__hero{ min-height: 0; }
  .pv-qv__face{ width: 56px; height: 56px; }
  .pv-qv__person{ flex-basis: 84px; }
  .pv-qv__ov{ display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
  .pv-qv__prole{ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
}

/* ---- tier 2: viewport height <= 760px ----------------------------------- */
@media (max-height: 760px){
  .pv-qv{ --qv-th: 118px; }
  .pv-qv__ov{ margin-bottom: 12px; }
  .pv-qv__seclabel{ margin-bottom: 8px; }
  .pv-qv__cast{ margin-bottom: 10px; padding-bottom: 8px; }
  .pv-qv__credit{ margin-bottom: 12px; }
  .pv-qv__trailer{ margin-bottom: 14px; }
  .pv-qv__actions{ padding-top: 12px; }
  .pv-qv__ov{ display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
}
@media (min-width: 701px) and (max-height: 760px){
  .pv-qv{ padding: 20px; --qv-th: 112px; }
  .pv-qv__dialog{ max-height: calc(100dvh - 40px); }
  .pv-qv__head{ padding: 20px 36px 16px; }
  .pv-qv__body{ padding: 20px 36px 18px; }
  .pv-qv__poster{ width: 168px; }
  .pv-qv__face{ width: 60px; height: 60px; }
  .pv-qv__person{ flex-basis: 92px; }
  .pv-qv__prole{ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
}
@media (max-width: 700px) and (max-height: 760px){
  .pv-qv__body{ padding: 14px 20px 20px; }
  .pv-qv__head{ padding: 14px 20px 12px; }
  .pv-qv__poster{ width: 92px; }
  .pv-qv__face{ width: 52px; height: 52px; }
  .pv-qv__prole{ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
}

/* ---- tier 3: viewport height <= 700px (shortest phones, 720p laptops) --- */
@media (max-height: 700px){
  .pv-qv{ --qv-th: 104px; }
  .pv-qv__ov{ -webkit-line-clamp: 2; }
  .pv-qv__face{ width: 52px; height: 52px; }
}
@media (max-width: 700px) and (max-height: 700px){
  .pv-qv{ --qv-th: 96px; }
  .pv-qv__face{ width: 48px; height: 48px; }
  .pv-qv__body{ padding-bottom: 16px; }
  .pv-qv__head{ padding-bottom: 10px; }
  .pv-qv__pname{ display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
  /* At this tier the overview is clamped to 2 lines, far shorter than the
     floated poster — letting the cast rail start beside the poster's tail
     (it is a horizontal rail) instead of clearing below it. */
  .pv-qv__seclabel{ clear: none; }
}

/* ==========================================================================
   ACTION ROW · 2026-10-13 (appended) — Favorite / Watched / Want to Watch
   in pv-qv. tmdb-quickview.js renders a .td-hero anchor carrying the
   title's data-like-* identity; pv-marks.js builds the labeled marks row
   inside it and pv-account.js lands the Favorite heart on it, which
   pv-marks adopts into the row — the same engines, state and styling as
   the full title pages and the story popup. NO new behavior lives here.

   James's ruling (2026-10-13 09:04): show the row ONLY where it fits
   cleanly. Gates sit just inside the smallest measured-fit viewport of
   each layout regime (phones 375x667, desktop 1440x900); any unmeasured
   size stays hidden, because the one-screen / zero-internal-scroll
   guarantee OUTRANKS the row. Hidden is display:none — no gap, layout
   identical to the shipped fit fix.

   Production calibration (rendered on the public page, live data —
   the earlier fixture proof ran ~35px optimistic): at shown sizes the
   ART yields first, exactly like the fit fix's height tiers — the
   trailer cap steps down a band and block margins compress; the row
   itself keeps the pv-marks look, with host spacing trims of the same
   kind the story popup already uses (.mpop-card .pv-marks-row). The
   "Coming <date>" note is suppressed in pv-qv (the button still flips
   to Remind Me; the date lives on the full page) so an unreleased
   title can never wrap the row past its measured width.
   ========================================================================== */
.pv-qv__marks{ display: none; position: relative; margin: 0; padding: 0; background: none; border: 0; min-height: 0; }
/* The heart is an overlay until pv-marks adopts it into the row; never
   let the not-yet-adopted overlay flash over the dialog. */
.pv-qv__marks > .pv-heart{ visibility: hidden; }
/* Heart in the row: the title-page row treatment (mirrors #td-root in
   pv-marks.css and .mpop-card in mini-popup.css), scoped to pv-qv.
   border-box pins the heart to exactly the measured 40px. */
.pv-qv .pv-marks-row .pv-heart--row{ position: static; box-sizing: border-box; width: 40px; height: 40px; flex: none; border: 1.5px solid var(--desert-ink, #2b2118); border-radius: 999px; background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
.pv-qv .pv-marks-row .pv-heart--row svg{ width: 19px; height: 19px; fill: none; stroke: var(--desert-ink, #2b2118); }
.pv-qv .pv-marks-row .pv-heart--row[aria-pressed="true"]{ border-color: #e0245e; }
.pv-qv .pv-marks-row .pv-heart--row[aria-pressed="true"] svg{ fill: #e0245e; stroke: #e0245e; }
.pv-qv .pv-marks-row .pv-heart--row:focus-visible{ outline: 2px solid var(--brand-red, #c0391b); outline-offset: 2px; }
/* Row spacing in this host (story-popup precedent) + note suppression. */
.pv-qv .pv-marks-row{ gap: 6px; margin: 8px 0 2px; }
.pv-qv .pv-marks-row .pv-mark-note{ display: none; }
/* Phones: smallest measured fit is 375x667; 360x660 wraps/overflows.
   Shown here, the trailer cap steps down per height band and the
   overview gives up one clamp line (761-1100 band) so trailer-less
   titles fit too. */
@media (max-width: 700px) and (min-width: 373px) and (min-height: 665px){
  .pv-qv__marks{ display: block; }
  .pv-qv__trailer{ margin-bottom: 10px; }
  .pv-qv__credit{ margin-bottom: 10px; }
  .pv-qv__ov{ margin-bottom: 12px; }
}
@media (max-width: 700px) and (min-width: 373px) and (min-height: 665px) and (max-height: 700px){
  .pv-qv{ --qv-th: 84px; }
}
@media (max-width: 700px) and (min-width: 373px) and (min-height: 701px) and (max-height: 760px){
  .pv-qv{ --qv-th: 100px; }
}
@media (max-width: 700px) and (min-width: 373px) and (min-height: 761px) and (max-height: 1100px){
  .pv-qv{ --qv-th: 116px; }
  .pv-qv__ov{ -webkit-line-clamp: 4; }
}
/* Desktop: dialog width is capped at 920px, so height is the binding
   constraint — smallest measured fit is 1440x900; 1280x720 overflows. */
@media (min-width: 701px) and (min-height: 890px){
  .pv-qv__marks{ display: block; }
  .pv-qv__trailer{ margin-bottom: 12px; }
  .pv-qv__credit{ margin-bottom: 10px; }
  .pv-qv__ov{ margin-bottom: 12px; }
}

/* ==========================================================================
   720P RECALIBRATION · 2026-10-13 (appended) — production data runs
   ~5px (TV) / ~19px (movie) taller than the fixtures the fit tiers were
   proven against: at 1280x720 the base dialog's right column (overview,
   cast rail, credit, trailer, actions) pushed the CTA 5-19px past the
   dialog's bottom edge. This block recalibrates ONLY the short-wide
   desktop class (701-760px tall, wider than a phone) — every other
   viewport keeps the exact shipped behavior, and the marks row stays
   gated off here. Doctrine order preserved: the ART yields first
   (trailer facade cap 112 -> 88px, cast faces 60 -> 54px), spacing
   compresses second, the overview clamp is NOT touched.
   ========================================================================== */
@media (min-width: 701px) and (min-height: 701px) and (max-height: 760px){
  .pv-qv{ --qv-th: 88px; }
  .pv-qv__head{ padding-bottom: 14px; }
  .pv-qv__meta{ margin-bottom: 10px; }
  .pv-qv__body{ padding: 18px 36px 16px; }
  .pv-qv__ov{ margin-bottom: 10px; }
  .pv-qv__seclabel{ margin-bottom: 6px; }
  .pv-qv__cast{ margin-bottom: 8px; padding-bottom: 6px; }
  .pv-qv__face{ width: 54px; height: 54px; }
  .pv-qv__credit{ margin-bottom: 10px; }
  .pv-qv__trailer{ margin-bottom: 12px; }
  .pv-qv__actions{ margin-top: 2px; padding-top: 10px; }
}

/* ==========================================================================
   SCROLL SAFETY NET · 2026-10-14 (appended) — James 13:09 PT, from Browse
   on his phone: the Animals quick view ran off the bottom of the screen
   and could NOT be scrolled at all — "View full page" half-buried, the
   template "off". Root cause: the 2026-10-13 fit system replaced the
   dialog's internal scroll with overflow:hidden plus a flex column whose
   body item may shrink (min-height:0) while its block children overflow
   visibly and are clipped at the dialog's edge. The stack stays in budget
   ONLY via the height-tier calibration (art caps, clamps, spacing)
   measured against fixtures — real data at real font metrics on a real
   phone runs taller, the actions row is amputated at the bottom edge,
   and with scrolling designed out there is no way to reach it.
   This net keeps the fit design FIRST (art yields, tiers and clamps all
   stand — titles that fit still land on one screen, pixel-identical)
   and restores the sheet's own scroll as the guarantee underneath:
   - #pvQvContent is the scroller: hero + body scroll together, the way
     a phone sheet behaves. The dialog keeps overflow:hidden, so the x
     (a dialog-level element) stays pinned and tappable at all times.
   - .pv-qv__body takes its natural height (flex:none) inside the
     scroller instead of shrinking while its children overflow.
   - The overlay and dialog size to the DYNAMIC viewport (100dvh) and
     the dialog carries the bottom safe-area inset, so the last row can
     always clear phone browser chrome and gesture bars.
   - No scroll bleed: the JS body lock stays, and overscroll-behavior
     contains the sheet's scroll at both ends.
   ========================================================================== */
.pv-qv{ height: 100vh; height: 100dvh; }
.pv-qv__dialog{ box-sizing: border-box; padding-bottom: env(safe-area-inset-bottom, 0px); }
#pvQvContent{ overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
#pvQvContent::-webkit-scrollbar{ width: 6px; }
#pvQvContent::-webkit-scrollbar-thumb{ background: rgba(var(--desert-ink-rgb), 0.2); border-radius: 3px; }
.pv-qv__body{ flex: none; }
@media (min-width: 701px){
  .pv-qv__dialog{ max-height: calc(100vh - 88px); max-height: calc(100dvh - 88px); }
}
@media (min-width: 701px) and (max-height: 1100px){
  .pv-qv__dialog{ max-height: calc(100vh - 56px); max-height: calc(100dvh - 56px); }
}
@media (min-width: 701px) and (max-height: 760px){
  .pv-qv__dialog{ max-height: calc(100vh - 40px); max-height: calc(100dvh - 40px); }
}
/* Marks row (Watched / Want to Watch): the 2026-10-13 gate showed the
   row only at viewport sizes measured to fit it on ONE screen, because
   an overflowing row was unreachable in a no-scroll sheet. With the
   scroll net above, an overflowing row is simply scrolled to — the
   reachability problem the gate existed for is gone — so the row shows
   at every size, like the full title pages. (James 2026-10-14: the
   primary actions are always reachable.) */
.pv-qv__marks{ display: block; }
