docs(design): the media card chapter and its log rows (E28 S3h)

This commit is contained in:
2026-09-27 00:54:28 +02:00
parent a453b77f04
commit 4c63d6660d
+63
View File
@@ -336,6 +336,58 @@ Wherever there is text, the user can select it and copy it, and no click action
- On touch the long-press belongs to the context menu, so the object's menu offers **Copy title** and - On touch the long-press belongs to the context menu, so the object's menu offers **Copy title** and
**Copy link**. **Copy link**.
## Media card — _Decided_ (S3h)
A film, a show, an episode, a video or a pinned channel is ONE card wherever it appears: the Plex grid,
the feed, Home's shelves and hero, the Plex rails, the media-info page's collection strip. A place may
pick a density step; it never changes the anatomy or loses an action. [Nielsen #4]
- **Anatomy (the owner's pick C).** One frame: the picture, the title, the meta line pinned to the
frame's bottom edge, so a one-line title leaves no hole above the meta. What is ON the picture: the
length (a film's runtime, a show's season count, a video's duration) as a dark badge in the corner,
the watched mark, the progress bar along the bottom. Built as `ui/MediaCard` + the classes in
`ui/mediaCardStyles` (`MEDIA_PICTURE`, `MEDIA_IMG`, `MEDIA_BADGE`, `MEDIA_HOVER_LAYER`, `MEDIA_BAR`,
`mediaTitleClass`, `mediaPictureBox`).
- **Play only where the click plays.** The hover layer dims the picture and shows `MediaPlayGlyph`, the
one round media Play (the button family's `media` variant), only on a card whose click starts
playback; a show without a next episode opens instead and shows none. The hover row (watched, save or
add, "…") docks at the picture's bottom-right; the length badge steps aside while it shows.
- **Density.** A grid card: a two-line title and the full meta (Plex: year · ★ score; a video: the
channel, then views · age). On a shelf (any horizontal strip) the title is one line, cut with an
ellipsis, over ONE meta line (Plex: year · ★; a video: the channel; a tile: its count), so every card on
the strip is the same height. A Home shelf slot is 232px: at 200 the Play and the hover row
overlapped by 2px, at 232 they stand 6px apart; a landscape shelf picture takes the smaller Play.
- **A mixed shelf is landscape.** Beside videos a Plex title shows its wide art, not its poster; a
rail's slot is a grid cell, so each card fills the height the strip stretches to. A carousel turns
the cards' content-visibility off (`mediaRail.contract.test.ts`): an off-screen card's reserved height
had become the strip's.
- **The preview (the owner's pick C).** Resting the mouse on a Plex card for ~0.9 s opens a panel beside
it: the whole title, year · length · ★, and the synopsis in short lines (`ui/MediaPreview` +
`useMediaPreview`). Mouse only (a keyboard walk or a tap never opens it; "…" → Media info has the same),
passive (it never takes a click), and any press on the card closes it. Long text never goes in a
native `title` tooltip.
- **Home's hero is a card** (the owner's pick A): the same hover row and Play on its picture, the same
whole menu on right-click, long-press and a touch "…" in its button row. In a wide window it stands
three quarters wide and centred, with even padding; its text is one centred stack — kicker, title,
subtitle (dropped when it is only the year), one fact line, a summary only when there is one.
- **Home's shelf tiles act like their object.** A pinned channel or playlist: Play when it has a next
video, ↗ to open it, "…" with an Open row. A show carries its next episode: the Play, the watched
toggle and add act on that episode ("Next: S6·E16" is its meta line), and an ⓘ opens the show. A
channel's Home menu is play, open and the shelf's own rows; its tags, priority, hide and unsubscribe
stay on the Channels page.
- **The compact list row (the owner's pick B).** The title leads; a faint "…" is always at the row's end;
on hover or focus the quick toggles float in beside it over the date, which steps aside (the Gmail
row). On touch only the "…".
- **The media-info page (layout B).** Under the hero a main column — the collection strips (the same
card), then the crew, then the cast — beside a 20rem sidebar of facts (details, keywords). Every
section is the reader's to hide; a column with nothing in it is not drawn and the other takes the
width. A show's page uses the same meta row: a value that filters is a chip, a plain fact is flat
text, spaced by the gap, no "·".
- **Browse tiles** (genres, playlists, collections) answer the pointer as a card does: the edge takes
the accent, the shadow lifts and the art zooms.
- **Reading measure.** Prose (a synopsis, a biography, a channel's description) is capped at ~65
characters a line (the `measure` utility) wherever its container can be wider. [WCAG 1.4.8]
## Interaction rules — _Decided_ ## Interaction rules — _Decided_
- **Keyboard:** everything works by keyboard, in visual order, with no traps. A shortcut is a row in - **Keyboard:** everything works by keyboard, in visual order, with no traps. A shortcut is a row in
@@ -473,5 +525,16 @@ Wherever there is text, the user can select it and copy it, and no click action
| 2026-09-26 | Fade at rest | The sticky header's fade appears with the first 1rem of scroll (a scroll-driven animation; no fade where unsupported) | A fade that is always drawn | At rest it dimmed the first row and hid its ring's top edge; nothing is under the header yet | | 2026-09-26 | Fade at rest | The sticky header's fade appears with the first 1rem of scroll (a scroll-driven animation; no fade where unsupported) | A fade that is always drawn | At rest it dimmed the first row and hid its ring's top edge; nothing is under the header yet |
| 2026-09-26 | Narrow playlist table | "#" and Channel hide by the table's own width (under 42rem), not the window's | Hiding below the `sm` window width | Beside the playlist rail a desktop window left the table 432 px and the title 0 px | | 2026-09-26 | Narrow playlist table | "#" and Channel hide by the table's own width (under 42rem), not the window's | Hiding below the `sm` window width | Beside the playlist rail a desktop window left the table 432 px and the title 0 px |
| 2026-09-26 | Background menu built | Five list pages (feed, Plex grid, channels, playlist, notifications); the toolbar's sort / view / filters and the band's actions; no destructive row | Every page with a toolbar; the "…" menus copied whole, delete included | The tab-only pages have nothing a menu would add; a blank-area right-click must not be one click from delete | | 2026-09-26 | Background menu built | Five list pages (feed, Plex grid, channels, playlist, notifications); the toolbar's sort / view / filters and the band's actions; no destructive row | Every page with a toolbar; the "…" menus copied whole, delete included | The tab-only pages have nothing a menu would add; a blank-area right-click must not be one click from delete |
| 2026-09-26 | Media card anatomy (C) | One frame; the meta line pinned to its bottom; the length a badge on the picture; the Plex card on the same primitive as the video card | A: the year as an overline over the title; B: the year inline after it; a fixed two-line title slot | A one-line title left a hole the eye reads as a missing line; C puts nothing under a variable-height title |
| 2026-09-26 | One Play | `MediaPlayGlyph` (the media button variant) and only where the click plays | The Plex card's hand-painted accent circle; a playable dot on every card | One Play for every card; a dot that only a colour and a tooltip explain says nothing |
| 2026-09-26 | Filtering values on the info page | A value that filters (year, certificate, studio, director) is an edged chip; a fact is flat text | Everything flat, the clickable ones only hover-tinted | The S3d rule: edged = pressable, so the reader sees which values do something |
| 2026-09-26 | Shelf density | On any strip: one title line over one meta line | The grid's two lines and full meta on a strip | The tallest card set the strip's height and left holes in the cards with less to say |
| 2026-09-26 | Compact list row (B) | The title leads; a faint "…" at the end; the toggles float over the date on hover | A leading 128px action column | That column sat empty at rest, a hole at the start of every row |
| 2026-09-26 | Media-info layout (B) | A main column (collections first, crew, cast) beside a facts sidebar; an empty column is not drawn | Every section full width, stacked | The collection is the most used; the keywords' column left a void beside a short details box |
| 2026-09-26 | Mixed Home shelf (A) | Plex titles as wide art beside videos | Posters, with the videos not stretched | Stretching a video card to a poster's height left an ~80px gap |
| 2026-09-27 | Home hero | A card (hover row + Play on the picture, the whole menu, a touch "…"; owner: A); three quarters wide and centred on a wide window; one fact line; the summary at the measure | The hero's pin row alone; full width; an 18rem picture column | The one answer stands in focus, and it offers what the same card offers anywhere |
| 2026-09-27 | Home shelf tiles | A channel / playlist tile: Play, ↗ open, "…" with Open; a show acts on its next episode, ⓘ opens it; the shelf slot 232px | The tile's pin row alone; 200px | A tile without its object's actions read as broken; at 200 the Play touched the hover row |
| 2026-09-27 | Synopsis preview (C) | A ~0.9 s mouse rest opens a passive panel beside the card | The synopsis as the picture's `title` tooltip; an ⓘ to hover; none | One long tooltip line fired anywhere on the art and clashed with the cut title's own tooltip |
| 2026-09-27 | Reading measure | Prose capped at ~65 characters a line (`measure`) | The container's full width | At 110–130 characters a line the eye loses the next line's start |
| 2026-09-24 | Chip family | One `Chip` (filter / token / tag / suggest / ghost) + `DismissibleChip`; nothing under 24; the lint rule "no raw `<button>` outside ui/" | Five chip geometries in five files | The applied-filter row, the tag cells, the year picker and the saved-view editor each drew their own chip; a one-letter tag was 21px wide | | 2026-09-24 | Chip family | One `Chip` (filter / token / tag / suggest / ghost) + `DismissibleChip`; nothing under 24; the lint rule "no raw `<button>` outside ui/" | Five chip geometries in five files | The applied-filter row, the tag cells, the year picker and the saved-view editor each drew their own chip; a one-letter tag was 21px wide |
| 2026-09-24 | Button families | `Button` / `IconButton` / `Pressable` / chips / `DragHandle`; `lg` 40 for a hero CTA; pills and a 48 Play on media (from C5) | Every button hand-painted | 268 hand-rolled buttons in 79 files drifted into as many looks; the ladder only holds if every button stands on it | | 2026-09-24 | Button families | `Button` / `IconButton` / `Pressable` / chips / `DragHandle`; `lg` 40 for a hero CTA; pills and a 48 Play on media (from C5) | Every button hand-painted | 268 hand-rolled buttons in 79 files drifted into as many looks; the ladder only holds if every button stands on it |