aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/mediacenter.md68
1 files changed, 63 insertions, 5 deletions
diff --git a/docs/mediacenter.md b/docs/mediacenter.md
index 7a712d9..b4526aa 100644
--- a/docs/mediacenter.md
+++ b/docs/mediacenter.md
@@ -592,15 +592,16 @@ season_meta_resp { tmdb_id, season, confidence, name, overview, air_date,
poster_thumb_hash }
```
-`video-app.js`'s `VideoDetailModal` shows a season tab bar
-(`Season 1` / `Season 2` / … / `Specials`) whenever a show has more than one
+`video-app.js`'s `VideoDetailModal` shows a season picker
+(`Specials` / `Season 1` / `Season 2` / …) whenever a show has more than one
season, defaulting to whichever season the representative episode belongs
-to. Selecting a tab both filters the episode list to that season and swaps
-in that season's own `overview`/`air_date` — falling back to the show-level
+to. Selecting a season both filters the episode list to it and swaps in that
+season's own `overview`/`air_date` — falling back to the show-level
`overview` when a season's own comes back empty (TMDB has no season-level
text for every show), the same per-field fallback shape §5.4's English
fallback already established, just one level further down when there is
-nothing at all to show otherwise.
+nothing at all to show otherwise. It was a row of tabs until §10.4; it is a
+menu now, for the reasons given there.
**An operator needs a way to correct a wrong match** when TMDB's own
top-ranked result is simply wrong — no amount of local re-ranking fixes
@@ -798,6 +799,63 @@ keyword is what carried the index, `sequel_variants` no longer emits the bare ba
still offered. Verified live against a numbered franchise's episodes plus the earlier
numbered-sequel / two-part-film / franchise-subtitle regressions.
+### 10.4 The detail modal jumped from one season to the next (2026-09-02)
+
+Three faults, one complaint: opening a different season of the same show moved
+everything under the synopsis, which is where the season control and the
+episode list are, so the thing just clicked was no longer under the pointer.
+
+- **The synopsis is however many lines TMDB wrote.** A twelve-line season
+ summary and a two-line one put the season control ten lines apart, and
+ resized the modal with it. It is now **exactly three lines** with a "read
+ more" link — clamped from above and, for a multi-season show only (the one
+ case where a season can change underneath it), pinned from below to the same
+ number. A constant, not a range: a two-line band still reads as a jump, and
+ the point is that the picker is at the same pixel from one season to the
+ next. Five lines was built first and is why the number is three — at five, a
+ short synopsis sat over three blank lines. `-webkit-line-clamp` cannot do
+ the clamp half of this: it only ever puts its ellipsis at the end of the
+ last line and leaves no room for anything after it. The link is floated
+ into the third line box instead, which is why
+ `OverviewText` writes the button *before* the text (a float only pushes the
+ line boxes that follow it) and the CSS reserves the two lines above with a
+ zero-width float. That spacer is scoped to `.has-more`: `overflow: hidden`
+ makes the paragraph a block formatting context, so it *contains* the float
+ and would otherwise stand two lines tall for a one-line movie synopsis.
+ Whether three lines is all of it depends on the modal's width, so it is
+ measured in the browser, not counted, and re-measured on a resize.
+- **The cast line was however long the cast was.** Clamped to two lines,
+ ellipsised at the end of the second. Nothing to expand to here, so this one
+ is a plain `-webkit-line-clamp`.
+- **The season tab bar scrolled sideways.** A show with a dozen seasons hid
+ most of them behind a horizontal scrollbar — unusable on a phone, and ugly
+ everywhere. `SeasonMenu` replaces `SeasonTabs`: one trigger reading
+ `Season 5 · 1997` and a menu of every season with its episode count, one row
+ high whatever the season count. The selected season's air year moved onto
+ that trigger, where it names what it belongs to; the *show's* year moved
+ into the facts line next to the director. Per-season air dates are still
+ fetched lazily for the selected season only (§5.7), so the menu lists
+ episode counts — which are local — rather than a year per row.
+
+A series also had no director: `media_meta_resp.director` was filled from the
+credits crew's `job == "Director"`, a movie shape. TMDB's aggregate
+`tv_credits` crew is routinely empty and never carries that job, so every show
+answered `null` and the modal dropped the line. It now comes from `created_by`
+on the show details, which is what TMDB's own page shows. Cached show metadata
+keeps its `null` until `TMDB_META_TTL_SECS` expires or an operator re-matches.
+
+Measured, not read out of the stylesheet (`test_video_detail_measured.py`,
+via the `layout_probe.py` harness): the season picker's offset inside its own
+modal body is the same pixel for a one-line and a twelve-line synopsis, at
+every width from 320 px up; the clamped synopsis is three line-heights either
+way and the cast at most two; the read-more link lands on the third line; an
+unreserved short synopsis has no floor under it; and the open menu fits inside
+the modal at 320 px. Each measured block sits in a whole-pixel-height
+container — stacked in flow they start at fractional offsets, and two
+identical layouts an eighth of a pixel apart round to tops one pixel apart,
+which reads as a defect in the thing being measured and is not one.
+`test_tmdb_show_director.py` covers the credit.
+
## 11. Acceptance before shipping
1. Re-run the §3 validation (real TMDB calls, same corpus, same script