/* Shared deep-page hero component.
 *
 * Owns the hero block that /show/:id, /show/:id?season=N, /detail/:id and
 * /movie/:id all open with: poster column, heading column, synopsis. The page
 * bodies below the hero stay page-owned (season tabs / episode tree on show,
 * version-comparison card on detail) and are not touched here.
 *
 * Loaded after shared/deep-page-shell.css and before the page's own
 * show.css / detail.css. The page sheets must not redeclare the properties
 * this file owns: poster column width, hero gaps, heading/copy width caps,
 * synopsis measure, H1 type role, poster image geometry.
 *
 * ---------------------------------------------------------------------------
 * BREAKPOINTS
 *
 * This component uses NO width media query. Every size below is a single
 * continuous clamp() spanning 320-2560px, so there is nothing left to keep in
 * sync between the two pages. @media is reserved for real structural changes,
 * and the hero has none left: detail.css used to switch at 760px from a
 * stacked ("poster title" / "copy copy") map to the side-by-side ("media
 * info") one, which pushed the synopsis and cast rows under the poster on
 * phones; the side-by-side map is now the base map at every width on both
 * pages. Before this the hero's SIZING was also spread across four different
 * query boundaries (640 min, 640 max, 759 max, 760 min) that disagreed with
 * each other; those are gone, not moved.
 *
 * ---------------------------------------------------------------------------
 * POSTER WIDTH
 *
 * --hero-poster-width replaces five disconnected curves:
 *
 *   show    <=640px   --size-mobile-poster   78px -> 86px
 *   show    >=641px   flat 160px
 *   detail  <=640px   --size-mobile-poster   78px -> 86px
 *   detail  641-759   flat 176px
 *   detail  >=760px   clamp(168px, 18vw, 198px)
 *
 * which produced an 86px -> 160px cliff across a single pixel on show, a
 * 176px -> 168px -> 198px shrink-then-grow on detail, and a poster that then
 * never grew again on show no matter how wide the screen got. Measured, the
 * poster oscillated between 25.7% and 11.4% of the content shell.
 *
 * The replacement is linear through two anchors -- 84px at 320px and 214px at
 * 1440px -- clamped at both ends:
 *
 *   320px    84px      (clamp floor; was 78px)
 *   390px    92px      (was 80px)
 *   640px   121px      (was 86px)
 *   641px   121px      (was 160px show / 176px detail -- the cliff)
 *   760px   135px      (was 160px show / 168px detail -- the shrink)
 *   1024px  166px      (was 160px / 184px)
 *   1280px  195px      (was 160px / 198px)
 *   1440px  214px      (was 160px / 198px)
 *   >=1458  216px      (clamp ceiling; the content shell stops growing at
 *                       1400px + gutters, so the poster stops with it)
 *
 * ---------------------------------------------------------------------------
 * WIDTH
 *
 * The heading and the synopsis fill the content column. They carry NO width
 * cap, so they track the viewport exactly like .show-info-card /
 * .detail-* cards below them, which have none either and simply fill the
 * site shell -- min(1400px, 100vw - gutters).
 *
 * Two earlier attempts here were both wrong and both got rejected:
 *
 *   1. copy capped at --size-scale-px-980 (980px) while the heading had no
 *      cap at all. The two right edges disagreed by up to 236px.
 *   2. both capped at --hero-measure (72ch = 524px). The edges agreed, but
 *      the whole hero became a narrow fixed-width island sitting above a
 *      full-width info card -- a fixed px/ch cap does not scale with the
 *      viewport at all, which is exactly what this project's hard rule
 *      forbids: every block adapts to screen width, 320-2560px.
 *
 * So there is no cap. Line length on very wide screens is a real tradeoff
 * and it loses to the fluid-width rule on purpose: the page reads as one
 * column that grows together, not as blocks that stop at different points.
 */

:root {
  --hero-poster-width: clamp(5.25rem, 2.92875rem + 11.607vw, 13.5rem);
  --hero-col-gap: clamp(.5rem, 2.5vw, 2rem);
  --hero-row-gap: clamp(.375rem, .125rem + 1.25vw, 1.125rem);
}

/* Hero grid: poster column + content column. The row/area map stays with the
 * page, because show and detail place different things in the second column. */
.page-hero {
  grid-template-columns: var(--hero-poster-width) minmax(0, 1fr);
  column-gap: var(--hero-col-gap);
  row-gap: var(--hero-row-gap);
}

.page-hero-poster {
  min-width: 0;
}

/* Poster image. The detail page already reserved the 2:3 box before the image
 * loaded; the show page did not, so its hero reflowed on every poster load.
 * Both now reserve it from the same declaration. */
.page-hero-poster-img {
  display: block;
  width: 100%;
  aspect-ratio: 2/3;
  object-fit: cover;
}

/* No-poster placeholder, same box as the image it stands in for. Its
 * `display` stays owned by the flex utility the markup carries. */
.page-hero-poster-fallback {
  width: 100%;
  aspect-ratio: 2/3;
}

/* Heading and copy blocks both fill the content column, so they share one
 * right edge with each other and with the cards below the hero. */
.page-hero-heading,
.page-hero-copy {
  min-width: 0;
}

/* Hero H1 role. Both pages resolve to the content-title role at every width.
 * The detail template used to reach --type-content-title below 641px and above
 * 759px but the raw --type-scale-rem-1-5 type-scale step in between, because
 * that band was the only place its `sm:text-2xl` utility class had no
 * page-level override on top of it. Phase 1's pin that reproduced that band is
 * gone with it. */
.page-hero-title {
  font-size: var(--type-content-title);
  line-height: var(--leading-title);
  font-weight: var(--weight-content-title);
}

.page-hero-synopsis-body {
  min-width: 0;
}

/* Synopsis row. Label, rule, row padding and the expand control are the same on
 * both pages, so they live here rather than being written twice. The collapsed
 * height is not a CSS clamp: -webkit-line-clamp can cut the text at three lines
 * but cannot keep the control on the third line -- as a sibling it took a fourth
 * row of its own, and inside the clamped box it was cut away with the text it
 * belongs to. assets-src/shared/overview-fit.js measures the fit instead and
 * hands the paragraph a string that already leaves room for the control, so the
 * control is simply the last inline thing in it. */
.page-hero-synopsis {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  column-gap: var(--space-detail-group);
  padding: var(--space-detail-row-block) 0;
  border-top: 1px solid var(--visual-detail-divider);
}

.page-hero-synopsis-label {
  color: var(--text-muted);
  font-size: var(--type-field-label);
  line-height: var(--leading-field-label);
  font-weight: var(--weight-field-label);
  white-space: nowrap;
}

.page-hero-synopsis-copy {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--type-field-value);
  line-height: var(--leading-detail-prose);
  font-weight: var(--weight-field-value);
}

.detail-overview-toggle {
  position: relative;
  margin-left: var(--space-detail-intra);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  font-size: var(--type-meta);
  line-height: var(--leading-detail-prose);
  font-weight: 750;
  cursor: pointer;
}

.detail-overview-toggle:hover {
  color: var(--text-primary);
}

/* UI-011: invisible vertical hit-area expansion toward 44px; horizontal stays
 * untouched since the control's own text width already exceeds 44px. */
.detail-overview-toggle::after {
  content: "";
  position: absolute;
  top: calc(-1 * max(0px, (44px - 1.4em) / 2));
  bottom: calc(-1 * max(0px, (44px - 1.4em) / 2));
  left: 0;
  right: 0;
}
