docs(design): composition and the reader — a chapter and a Conformance step (E30 S6)
The rules covered each piece; nothing asked whether a screen works as a whole, and the person page passed every rule with half its panel empty. New chapter: the space is used, one focal point, worst real data, where am I, a click answers at once (no outside service on open), zoom and text size first-class (the owner reads zoomed in). Conformance step 5 writes one composition line per screenshot and checks 200% zoom and the largest text size. Anti-patterns and a decision-log row to match. HU: the download worker setting reads "Párhuzamos letöltések" (a leftover from the S5 sweep).
This commit is contained in:
@@ -38,6 +38,11 @@ runs this check before it is called done (E28 S3g):
|
||||
which the measure cannot trace to a component) and the playlist table's own rows.
|
||||
4. **Seen.** A screenshot of every changed state, thin edges at 1:1; the tablet widths (1024 × 768, a
|
||||
narrow split screen) when the layout can reflow. Phones are the E29 epic's, not this check's.
|
||||
5. **Judged as a whole** (E30 S6). For each screenshot, one written line on its composition: where the empty
|
||||
space is, what hugs one side, what the eye lands on first. Then the screen at 200% browser zoom and at
|
||||
the largest text size. Both are held to [Composition and the reader](#composition-and-the-reader--decided-e30-s6).
|
||||
A rule that holds is not the same as a screen that works: the person page passed every rule above with
|
||||
half its panel empty.
|
||||
|
||||
## The design lab
|
||||
|
||||
@@ -435,6 +440,36 @@ pick a density step; it never changes the anatomy or loses an action. [Nielsen #
|
||||
- **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]
|
||||
|
||||
## Composition and the reader — _Decided_ (E30 S6)
|
||||
|
||||
The rules above say how each piece looks; these say whether the screen works as a whole, for the one
|
||||
reader it is built for. Found when the person page passed every rule with its biography in the left half
|
||||
of a full-width panel and nothing on the right.
|
||||
|
||||
- **The space is used.** A narrow element in a wide container (prose at `measure`, a form, a short list)
|
||||
comes with a decision about the rest of the width: a second column with related content (the person
|
||||
page: facts and bio left, "Known for" right), a container sized to its content, or a layout that stacks.
|
||||
A band of nothing wider than about a third of a panel, beside content that stops short, is a finding.
|
||||
[Material layout, Gestalt proximity]
|
||||
- **One focal point, then an order.** A screen has one thing the eye lands on first (the page heading, the
|
||||
hero, the player), then the sections, then the metadata. A heading level keeps one look across screens;
|
||||
a second focal point competing with the first is a finding. [Nielsen #8, HIG hierarchy]
|
||||
- **Worst real data, not the demo row.** A screen is judged with the longest title, the Hungarian label,
|
||||
zero items, the largest list, a missing picture and a missing field. None of them clips, overlaps or
|
||||
leaves a hole where a value was. [Nielsen #9, WCAG 1.4.10]
|
||||
- **Where am I.** The browser tab names the place and the object in it ("Nicolas Cage · Plex · Siftlode"),
|
||||
the rail marks the place, and Back returns to the same view at the same scroll position with focus
|
||||
where it was. [Nielsen #1, WCAG 2.4.2]
|
||||
- **A click answers at once.** A control shows its pressed or changed state within ~100ms (an optimistic
|
||||
update, a spinner in the control); what a screen opens with is the app's own data — an outside service
|
||||
(TMDB, YouTube) is fetched ahead of time by a job, not on the click, so a page never waits on it.
|
||||
Late content keeps its place (B8). [Nielsen #1, RAIL]
|
||||
- **Zoom and text size are first-class.** The owner reads with the browser zoomed and a large text size.
|
||||
Every screen holds at 200% browser zoom on a desktop window and at the largest Settings text size at
|
||||
1024 wide: nothing clipped or overlapping, no sideways page scroll, every control reachable and at
|
||||
least its rung, text wrapping rather than cut. Measured, not assumed, on every UI change. [WCAG 1.4.4,
|
||||
1.4.10, 1.4.12]
|
||||
|
||||
## Interaction rules — _Decided_
|
||||
|
||||
- **Keyboard:** everything works by keyboard, in visual order, with no traps. A shortcut is a row in
|
||||
@@ -561,6 +596,9 @@ pick a density step; it never changes the anatomy or loses an action. [Nielsen #
|
||||
- A click handler on text that swallows the user's text selection.
|
||||
- A colour literal, a px font size, a px-frozen box.
|
||||
- An empty state shown for an error.
|
||||
- Half a panel left empty beside content that stops short.
|
||||
- A page that waits on an outside service when the user opens it.
|
||||
- A screen checked only at 100% zoom and the default text size.
|
||||
|
||||
## Decision log
|
||||
|
||||
@@ -635,6 +673,7 @@ pick a density step; it never changes the anatomy or loses an action. [Nielsen #
|
||||
| 2026-09-27 | C4 as built | `initialFocus` required on every `Modal`; the commit row in `ModalFooter`, portalled under the body from any depth; the fades driven by the body's scroll timeline; `interactive-widget=resizes-content` | An optional prop defaulting to the ✕; a `footer` prop (the issue composer's buttons live three components down); always-on fades | A default is how 21 dialogs came to open on the ✕; lifting the composer's state to reach a prop is the larger change; a resting fade dimmed the first line |
|
||||
| 2026-09-27 | C3 + C5 as built | A tap toggles the bar through `pointerType` from `pointerdown`; a double-tap takes back its first tap's toggle; the card's pair is the video card's `MediaResumeButtons` (Continue / Restart), a sibling over the picture; the YT description is an ⓘ click popover | A delayed single tap (wait out the double-tap window); new "Resume / From the start" words for Plex; the pair inside the picture's button | A delayed tap feels dead; one media card says one pair of words; a button inside a button is invalid and the hover row already sits beside the picture |
|
||||
| 2026-09-27 | C2 as built | The side panel's drawer is `ui/Modal` `drawer-start`; drawer = a coarse pointer or below 768; the pin offered in its header ≥ 1024 | A drawer of its own inside `SidePanel` | Esc, Back, the scrim, the trap and the scroll lock are the dialog's; a second implementation is how two shells drift |
|
||||
| 2026-09-30 | Composition and the reader (E30 S6) | A chapter and a Conformance step: the space is used, one focal point, worst real data, where am I, a click answers at once, zoom and text size first-class; the person page as two columns (facts and bio left, "Known for" right) | Rules for pieces only; the bio in a full-width panel; a narrower panel | The person page passed every piece rule with half its panel empty; the owner reads zoomed in, so zoom is a requirement, not a nicety |
|
||||
| 2026-09-30 | Hungarian words (E30 S5) | The D3 list: Feed, Shorts, Admin, Token, Port stay; stream, Prio, Job, Audit, Demo, Auto, Info, Frontend/Backend, Backfill, transcode get the Hungarian word; one name per thing (kérelem, behúzás, one "Test connection") | Keep every loanword; translate Feed/Shorts too | The owner chose the list (D3); the final sweep found the same feature under two names in three places |
|
||||
| 2026-09-29 | Numbers and order in the UI language (E30 S3) | Every number through `lib/format.ts` in the UI language (decimal mark, grouping, compact, units); A→Z by the shown name in the UI language's alphabet, client and server alike; the language comes off `useTranslation`, never the singleton | `toFixed`, hand-built "1.2K", `localeCompare` in the browser's locale, byte-order server sorts | A Hungarian reader saw "8.3", "1.2K", "Életrajzi" after "Z"; the singleton read also left values in the old language after a switch (React Compiler) |
|
||||
| 2026-09-27 | Narrow rows by container | The download row, the playlist table and the Channels tag row stack by a container query; a fact line never wraps | Breakpoints on the window | The iPad zoomed in, split screen and a column beside a rail are narrow while the window is not; the zoomed download row broke "18.9 / MB" apart |
|
||||
|
||||
@@ -149,8 +149,8 @@
|
||||
"hint": "„Plex” = Csatorna/Évad ÉÉÉÉ/… fastruktúra .nfo + poszter fájlokkal (Plexben indexelhető); „Egy mappa” = minden egyetlen mappában."
|
||||
},
|
||||
"download_worker_concurrency": {
|
||||
"label": "Worker párhuzamosság",
|
||||
"hint": "Hány letöltést dolgoz fel a worker párhuzamosan."
|
||||
"label": "Párhuzamos letöltések",
|
||||
"hint": "Hány letöltést dolgoz fel egyszerre a letöltő folyamat."
|
||||
},
|
||||
"sponsorblock_default": {
|
||||
"label": "SponsorBlock alapból",
|
||||
|
||||
Reference in New Issue
Block a user