# Changelog

All notable changes to the **OOS Digital Library design system** are logged here.

**Conventions** (binding — see `notes/decisions.md` → "Versioning + CHANGELOG"):

- Version string: standard semver `MAJOR.MINOR.PATCH` **plus the date of last change** as `yyyy-mm-dd` — e.g. `1.0.0 (2026-06-12)`.
- The top entry `[Unreleased]` collects **in-flight** changes as they land (newest bullet first).
- A version is **tagged when a deployment archive is created**: rename `[Unreleased]` to the new number + date, start a fresh empty `[Unreleased]` above it, and update the version string shown in `index.html` (hub footer) — the changelog top entry is the source of truth.
- English, compressed bullets, lead with the surface touched.

## [Unreleased]

## [1.9.1] — 2026-07-20

- **Release 1.9.1 — presentation-only patch; offline bundles deliberately NOT rebuilt** (`version.js` 1.9.1 · release archive `backups/bundles/oos-digital-library-1.9.1.zip`): everything since 1.9.0 lives in `presentation/` + docs/notes — none of it is inside the three `downloads/` bundles, so they stay byte-identical to the 1.9.0 build and keep their `1.9.0 · sestaveno 2026-07-19` stamp (accurate for their content; the next minor refresh re-stamps them). Archive per DEPLOY.md step 3 (zip-only convention, card markers neutralised, staging deleted after verify).

- **Presentation — deck copy pass, 36 direct edits mapped to source** (`presentation/deck.html`, user direct edits): title slide „verze 1.9.x“ + presenter name filled in; section kickers unified to „NN / 06“; slide 08 cells swapped + „Research preview ➜ Beta — funkce, vzhled i limity…“; slide 11 stat 9→10 vydání + „Včetně vlastních nástrojů:“; slide 12 provenance sentence italicised; slide 17 chrome scénář (jazyk demo dropped); slide 20 subtitle „Stejné komponenty, jiná témata“; slide 24 SoT card „Verzování 1.0.0 → 1.9.0“; slide 26 research-preview limits line; slide 27 NEW fourth follow-up card + footer placeholder → live link `https://aura-oos.mazy.cc/`; stray deck-stage `left:0px` artifact removed. Slide 11 speaker notes still say „devět vydání“ (flagged, awaiting user).

- **Docs — Claude Design „Edit“ mode gating root-caused** (`notes/pitfalls.md` NEW H2 „Claude Design Edit-mode gating (Animated-video flag)“): the missing Edit toolbar option on the deck traced to app-side file-type gating, not to in-page scripts (transitions / copy-to-clipboard cleared); direct-edit batches mapped by the agent are the countermeasure.

- **Presentation — waiting/filler loop animation** (NEW `presentation/waiting-loop.html` + `presentation/waiting-loop-scenes.jsx` · `preview/test-babel-parse.html` PAGES, user request): 31 s seamlessly looping 1280×720 Czech animation for screen-shared pauses ("za chvíli pokračujeme" corner badge on every scene) — 8 scenes on the invitation's visual language: intro, document chips + card, six-apps grid, Claude Design stats count-up (navy), dark mode + 3 languages, iteration/care stats, Studio Kit checklist, navy loop outro. Loop playback (`OM_PLAYBACK mode:loop`); in-page playback bar hideable for live use via H key, "Playback bar" tweak, or `?bar=0` (CSS gate `.wl-nobar [data-omelette-chrome]`).

- **Presentation — waiting loop round 2 + app naming canon** (`presentation/waiting-loop.html` + `-scenes.jsx` · NEW `presentation/aura-logo.js` · `presentation/deck.html` · `presentation/run-of-show.html`, user request): Tweaks gain persistent Speed (0.25–1.5×, rederives scene durs) and "Hold after settle" (0–6 s settled delay per scene; content remaps via `wlP()`, waiting dots keep stepping through the hold); AURA logotype top-right on every scene exactly as the deck (verbatim SVG via `aura-logo.js`, blue on light / white on dark). App naming canon: dash-case shortcut rows "index · playground · dev-reference · prototype · data-preview · theme-lab" (Aplikace + Smycka scenes), app cards Czech names (Rozcestník, Komponenty, Referenční příručka, Prototyp knihovny, Náhled dat, Theme Lab) + gray mono code; deck slide 15/16 titles + labels and prose renamed to match, run-of-show prose app refs switched to dash-case codes. Round 3 fixes: speed/hold now actually apply (the engine captures the scenes prop as initial state only — `key={scenes}` remounts the stage on change); AURA recolor animates on every scene boundary incl. the loop seam (prev→own variant tween over the first ~12% ≈ the deck’s 460ms, live mix override during Temata’s dark flip); Pece footer shortened + inset (right:340) clear of the corner badge.

## [1.9.0] — 2026-07-19

- **Release 1.9.0 — offline bundles refreshed** (`downloads/` ×3 rebuilt from the committed `_standalone-src-*` source copies with the build stamp baked): first refresh since 1.8.0 (Jul 11) — ships the Theme Lab (+ its 9 feedback rounds), the W1–W4 token-flexibility role hooks + opt-in variants, guide key-press showcase / learning mode / keyboard tours (kit 0.8.0→0.9.0), panel section drag-reorder + the drop-target root-cause fix (kit 0.10.x), per-app SVG favicons, the preview demo-control canon, `Num.reveal` and the presentation package. Pre-bundle source checks (`tools/verify-bundle-sources.md`) run before the rebuild; release archive `backups/bundles/oos-digital-library-1.9.0.zip` (zip-only convention, card markers neutralised). DEPLOY.md exclusion list gains `scratch/` + `skills/`.

- **Docs — collaboration-profile skill** (NEW `skills/collaboration-profile/SKILL.md`, user request): persona + working-conventions profile distilled from `backups/chats/` (102 conversations / 295 user messages) and the notes files — values ranking, review axes with real catches from project history, feedback voice, decision map (delegated vs. kept), info-structure preferences, Claude Design gotchas + countermeasures (chat trimming → per-turn backups · @dsCard sanitization in archives · root-only Pages dropdown → launcher stubs · CLAUDE.md injection truncation → size budgets), portable optional practices (zip-only bundles, checkpoints, per-app favicons, tours), a new-project bootstrap checklist, a simulated-review protocol, and an embedded digest-regeneration script. Intended as input for agents simulating the user's review or jump-starting new projects. Registered in the CLAUDE.md root-docs map + `notes/decisions.md`.

- **Docs / project memory — context-management consolidation sweep** (`CLAUDE.md` · NEW `notes/context-plan.md` + `notes/verification.md` · `notes/pitfalls.md` · `notes/decisions.md`, user request): `CLAUDE.md` (injected every turn) rewritten 72.5KB→15.9KB — its 53KB content-mirroring "Notes index" (which the platform TRUNCATED mid-file, silently dropping the whole decisions index from every turn) replaced by a names-only domain map, stale tool names fixed, verification know-how consolidated into the new canonical `notes/verification.md`; grouped indexes added at the top of both notes files; duplicate "Library cover card" H2 merged; standing size budgets + a staged compaction backlog documented in `notes/context-plan.md`. Structural only — no pitfall/decision content deleted. **Phase 2 (same day, user request): the 19 oversized notes sections compressed IN PLACE** — pitfalls.md 325→239KB, decisions.md 555→465KB (−177KB; rule-first bullets, repeats merged, every distinct rule/identifier kept; H2 counts + file indexes unchanged; per-section figures in `notes/context-plan.md`).
- **Preview chrome — demo-controls consistency pass + full playground coverage** *(Backfilled at the 1.9.0 tag — the Jul 18–19 turns never logged)* (`preview/_help.css` · 38 `comp-*.html` audited · `preview/comp-page-transition.html` · `comp-filter-pills.html` · `comp-guide.html` · `comp-status.html` · `comp-request-card.html` · `preview/playground.html` · `preview/_devguide.js` GROUPS · NEW `docs/components/iconography.md` + `.cs.md` · `docs/getting-started.md` + `.cs.md` map rows · `preview/_standalone-src-dev-reference.html` metas · audit in `scratch/preview-controls-audit.md`, user request): one demo-chrome vocabulary per job, now binding (`notes/decisions.md` → "Preview demo controls" + CLAUDE.md pre-flight) — `_help.css` owns the shared `.play` pill (+ forced-state selectors), `.ex-head`/`.ex-actions` and the `.insp-preset` trio (8 local `.play` + 6 `.insp-preset` copies deleted; missing links added); page-transition Replay + wipe triggers converted off bare `.btn` (the unstyled-button bug) onto `.play` pills + the shared `_select.css` combo; status / request-card / filter-group / quick-tile drivers made list-visible via `data-playground`; filter-pills Restore/Add restyled as pills; icon/label canon applied (Replay `bi-play-fill` · reseed `bi-shuffle` · English verb-first chrome, breadcrumbs "Sbalit"→"Collapse"). Playground coverage completed: NEW sections App favicons (17, Brand), Iconography (22, Basics) and Region navigation (55) — 01–56 with Tools, 55 iframe sections; iconography got the full docs ceremony (GROUPS entry, md + cs twin, getting-started map rows, 2 dev-reference metas — no config/run assets).
- **Animated number — `Num.reveal` hero count-in (vague upper limits / animated suffix) + deck 11–12 rebuilt on it** (`preview/_num.js` · `preview/comp-num.html` · `docs/components/num.md`/`.cs.md` · `presentation/deck.html` · notes, user request): NEW API `Num.reveal(el, opts?)` promotes the deck stat-figure recipe into the DS — rolls the committed text up from a same-length zero baseline (digits→0, non-digits kept: no width-glide, nothing clips) and hides non-digit GHOST columns so a vague-limit suffix ("150+") sits blank until the incoming char rolls in at its staggered turn (defaults `dir:1`; blank-suffix applies to per-digit motions — pair with `roll-inc`). comp-num gains a "Reveal · vague limit" tile (follows the shared demo count with a "+" suffix while non-zero — plain "0" at zero — so ±/=0/=rand/Replay animate it too), an "Inspector-driven" tile (no pinned motion — `nxApply` stamps the Inspector's Motion onto it, so it follows Motion/effect/timing like the in-context row), a Reveal action that plays the count-in on every figure, and the demo action row (Narrow/Broaden/±/=0/Replay/Reveal) is now `data-playground`-marked so it shows in the main playground view, not just the preview modal. Deck root cause fixed en route: `--num-dy: auto` is SCALE-CONTAMINATED under deck-stage's transform scaling (getBoundingClientRect returns visual px → travel collapsed and the roll read as a cross-fade in the preview pane while fullscreen 1:1 looked right) — slides 11–12 now set `--num-dy: 1.05em` and otherwise run the stock deliberate rendition (the 800/100 quick-tile timing + relaxed clips are retired; pre-change file in `backups/files/`). NEW pitfalls H2 **"Deck / slide animations"** (scale contamination, entrance overlap, restart-safe re-entry, degrade paths, live-clock verification).
- **Presentation — click-to-copy file references** (NEW `presentation/copy-code.js` · `presentation/deck.html` · `presentation/run-of-show.html`, user request): every monospace file/path reference now copies its own text to the clipboard on click, so the presenter's clipboard-watching browser extension can jump to the matching tab. ONE shared vanilla file drives both pages, auto-initialising from `data-copy-*` attrs on its `<script>` tag. **deck.html** — the 11 blue mono chips (selected by having BOTH `font-family:var(--font-mono,monospace)` AND `border:1px solid #c7ddf3`, so the slide-09 flow boxes / slide-10 card that share only the border are excluded); `data-copy-stop="true"` calls `stopPropagation()`+`preventDefault()` so the click never reaches `deck-stage`'s tap-to-advance `click` listener on the host — the slide never moves, forward or back, on touch or desktop (probe-verified: host listener never sees the event, active-slide index unchanged). **run-of-show.html** — all 14 inline `.ros code` references. Feedback: a dark anchored toast above the chip (✓/! icon + localized „Zkopírováno“/"Copied" + the copied value in mono), a brief success ring, a `title` hint, and a hover box-shadow (`@media(hover:hover)`); language auto-follows each page's `<html lang>` (cs deck / en run-of-show); reduced-motion aware; runtime-injected style marked `data-omelette-injected`. Clipboard uses the async Clipboard API with a hidden-textarea `execCommand` fallback for insecure/`file://` contexts (the in-app preview iframe blocks both → shows the failure toast there; works in a real tab).
- **Root launcher stubs for the presentation** (NEW `deck.html`, `run-of-show.html` → forward to `presentation/deck.html` / `presentation/run-of-show.html`): the presentation pages live nested so they never appeared in Claude Design's root-only "Pages" / "All files" menu; two root stubs (same launcher pattern as `prototype.html`/`playground.html` — `location.replace` + meta-refresh + fallback link, preserving `search`/`hash`) surface them there. Each carries the target's favicon so the instant redirect shows no globe flash — deck reuses `favicon-deck.svg`; NEW `assets/favicons/favicon-runofshow.svg` (checklist glyph, steel-blue `#3d5a73`) added for the run-of-show and wired into the real `presentation/run-of-show.html` too — it was the only presentation page without a favicon.
- **Presentation package — 28-slide Czech deck + run-of-show + invitation animation** *(Backfilled at the 1.9.0 tag — the Jul 14–15 turns never logged)* (NEW `presentation/deck.html` · `presentation/run-of-show.html` · `presentation/Pozvanka-animace.html` + `pozvanka-scenes.jsx` (since renamed `invitation-animation.html` / `invitation-animation-scenes.jsx`) · NEW `tools/chat-stats.md`, user request): colleague-facing talk package in the DS look (Czechia Sans, gov blue, doc-type chips, Lev) — 1920×1080 Czech deck with per-slide speaker notes and a consistent ŽIVÁ UKÁZKA layout for the 7 demo slides (intro/program → východiska → teaser → Claude Design → DS zblízka → prototyp → Theme Lab + Studio Kit → pod kapotou → živé finále → follow-upy); printable A4 run-of-show (pre-flight checklist, minute-by-minute blocks with cut-if-late notes, rehearsed live-build prompt + fallback, risk matrix, 3 follow-up tracks); ~16.6 s looping 1280×720 invitation animation on SceneStage (5 scenes, host-editable timings, babel-harness registered). Deck polish rounds: borders lifted to DS tokens (#e1e8f0→#b9c1c6 ×44 · #c7ddf3→#9fcaff ×15); slides 11–12 stat figures animated with the DS quick-tile Num recipe — root cause of clipped digits / popping "+" was `_num.js`'s width-glide clip, fixed by rolling from a same-length `roll-inc` baseline; stats re-based on full project history incl. the pre-backup era mined from upload timestamps, deduped at the first backup (150+ conversations / 500+ feedback rounds, floors; slide-12 histogram from the 97 documented chats; methodology + rerun script in `tools/chat-stats.md`, trimming root-cause note in `notes/pitfalls.md`).
- **Brand — per-app SVG favicons** *(Backfilled at the 1.9.0 tag — the Jul 14 turn never logged)* (NEW `assets/favicons/` family · 7 app pages + 4 root launcher stubs wired · NEW `preview/brand-favicons.html` @dsCard · `notes/decisions.md` "Per-app SVG favicons", user request): one favicon family — rounded tile + white glyph, distinct hue/mark per app so deployed tabs read at a glance: hub = Lev on JVS Modrá `#00469B` (the README favicon spec) · library = book spines `#2362a2` · reader = folded-corner doc `#2c6e63` · playground = 2×2 module grid `#5d4a83` · dev reference = `</>` `#4a575c` · Theme Lab = split light/dark circle `#b06b00` · deck = play triangle on dark navy `#0c1838`; SVG-only (`<link rel="icon" type="image/svg+xml">`), stubs carry their target's icon so the instant redirect never flashes the default globe; `comp-*`/`colors-*`/`type-*` cards deliberately bare (internal DS-tab demos, not apps); faux tab-strip showcase card (later playground section 17).
- **Deployment — zip-only release archives** *(Backfilled at the 1.9.0 tag — the Jul 14 turn never logged)* (`DEPLOY.md` · NEW `tools/make-bundle-zip.md` · `backups/bundles/` · CLAUDE.md, user-decided): `backups/bundles/` now holds only `.zip` archives — named `oos-digital-library-<ver>.zip`, every entry under ONE identically-named top-level folder (never bare-root entries or baked-in project paths, which `present_fs_item_for_download` on a folder produces); the three legacy unpacked snapshots (1.2.0/1.5.0/1.8.0) repacked and their source trees deleted (60.5 MB on disk → 35.9 MB zipped); hand-rolled CompressionStream ZIP builder + verifier committed (incl. the non-ASCII-filename remap the `downloads/` exports need); code searches exclude `backups/` except when mining chats or diffing snapshots.
- **Panels — drop-target saga CLOSED (user-confirmed) + thorough documentation**: drag-diagnostics overlay reverted to opt-in (`localStorage twk-debug=1` or "twkdebug" in the URL) and kept permanently; NEW deep-dive doc `notes/drag-reorder-debug.md` (engine anatomy, r1–r4 bug history, overlay field guide, verification limits); binding rules added to `notes/decisions.md` ("Panel drag-reorder"); post-fix engine checkpoint in `backups/checkpoints/2026-07-14_drag-reorder-r4/` (SoT + twin + cos tweaks.jsx).
- **Panels — drop-target skew ROOT CAUSE fixed: indirect TweakSections** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated twin, kit 0.10.3 + `ui_kits/cos-library/tweaks.jsx`; diagnosed from the user's `?twkdebug` screenshots — `sess` listed 5 ids while `dom` listed 7): a `TweakSection` rendered through a wrapper component child (cos-library's `<LocaleWipeControl />` / `<SearchDelayControl />`) never joins the panel's reorder ids yet still carried `data-twk-sec` via context — so it sat in the slot grid and `stackBounds` while missing from `sess.order`, and every drop below it landed rows off (the true cause behind the whole "drop-target off" series). Kit: sections join the drag machinery only when MANAGED by the panel (`ctx.reorder.managed`); unmanaged ones render fixed with no handle. Consumer: "Locale wipe" + "Search" restructured as direct `<TweakSection>` children (bodies extracted), so all 7 Tweaks sections reorder again — they re-enter the saved order at the end, so re-drag them once. Inspector's `<AnimationControl />`/`<MenuMotionControl />` stay indirect → now safely fixed-position.
- **Panels — reorder drag diagnostics** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated twin): `?twkdebug` (or `localStorage twk-debug=1`) draws the slot grid, the chip's intended (green) vs painted (blue dotted) centre, and a live engine readout (revision marker, cur→idx, clamp window, panel shift, sess-vs-DOM order with a lagging-commit flag) during section drags, logging every reslot to the console; the COMMIT frame lingers 8 s post-drop — so screenshots of a misbehaving drag carry the full engine state (and reveal stale-cache engines via the revision marker).
- **Panels — reorder drop slot no longer walks away from the chip on a quick drag** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated twin, kit 0.10.2, user-caught with screenshots): the insertion index was counted off LIVE sibling rects — the current slot *assignment* — so when a fast drag landed several pointermoves before React committed the previous splice, each move re-spliced against the stale assignment and the drop slot walked several rows from the chip, persisted while the pointer rested, and committed wrong on drop. `reslot` now targets the slot GRID (sorted untransformed section midpoints — invariant under occupant permutation, so a lagging commit can't skew it) and picks the slot nearest the chip's intended centre; `teardown(commit)` re-resolves once before persisting. Boundary between slots is commit-invariant → no oscillation, gap sits exactly under the chip.
- **Panels — reorder drop target now reaches the first/last slot** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated twin, kit 0.10.1, user-caught): the `stackBounds` chip clamp that fixed the drag-down self-feeding overflow also capped the chip's visual centre ~half a section short of the top and bottom rows, so `reslot` (which targeted that clamped centre) could not reach the first or last insertion slot and read biased at the extremes — exactly the "self-feed fixed but drop-target still off" report. `reslot` now targets the chip's UNCLAMPED intended centre (`sess.aimCy = lastY − grab + chipHeight/2`, set in `place()`): equal to the visual centre wherever the chip moves freely (no "one slot above" regression) but not clamped by `stackBounds`, so every slot is reachable while the visible chip still never extends the scroll area. Verified by arithmetic on measured section geometry (the drag interaction can't be driven in the offscreen preview iframe — see notes/pitfalls).
- **Panels — reorder drop-target + drag-down overflow fixes** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated twin, user-caught): the dragged chip is now clamped inside the slot stack — previously a chip translated past the last slot extended the body's scrollable overflow and edge-scrolling into that self-made space kept adding empty room inside the panel; and drops are targeted by the chip's visual centre against untransformed slot midpoints instead of the raw pointer (the grab-offset clamp let the pointer ride the chip's top edge, so drops landed one slot above what the eye expected). Probe-verified: chip bottom pins exactly at the stack bottom on a far drag with `scrollHeight == clientHeight` throughout, and the far drag commits first→last correctly.
- **Panels — drag-reorder panel-follow** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated `preview/tweaks-panel.jsx` twin, user request): when the sections fold at drag start in a FLOATING panel, the whole panel temporarily moves so the dragged section lands under the cursor with its neighbours right next to it — the engine's new `panelShift` seam lets the host absorb the fold displacement up to the viewport clamp (the chip translates the remainder when there's no room). The shift applies only on fold-driven ResizeObserver ticks, never per pointer move (a 1:1 follow dragged the panel around instead of reordering — caught by user); pointer motion drives the chip through its neighbours as usual, and on drop/cancel the panel glides back to its pre-drag position (composite-add settle, reduced-motion aware). Docked panels (Theme Lab) are untouched. Probe-verified: panel stays put through pointer moves while the chip translates and the reorder commits + persists.

- **Panels — adaptive vertical anchor + non-selectable section headers** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated `preview/tweaks-panel.jsx` twin · `studio-kit/studio-kit.js` · `theme-lab/panel.jsx`, user feedback): the floating Tweaks/Inspector panel no longer blindly anchors to its bottom edge when sections fold — it anchors to whichever viewport edge it RESTS nearer (`data-anchor` top/bottom, re-decided on drop and on every panel/viewport resize), so collapsing near the top keeps the header put and expanding grows downward; when the growing edge runs out of room the clamp continues the expansion the other way until the panel takes the full available height (body scrolls). A full-height panel shrinks per its LAST anchor; with none, the configurable default applies (`StudioKit.configure({ panels: { anchorDefault } })`, fallback **top** — the DS's choice, and what the twin gets with no kit core). Also per convention: section headers/labels (kit `.twk-sect`/`.twk-sect-btn` + Theme Lab `.tlp-sec-hd`) are no longer text-selectable.

- **Panels — section drag-reorder + Theme Lab header backport into the kit shell** (`studio-kit/panels/studio-panels.jsx` SoT → regenerated `preview/tweaks-panel.jsx` twin · `studio-kit/studio-kit.js` 0.10.0 · `theme-lab/panel.jsx`, user request): sections in every collapsible panel now REORDER by dragging their header — on drag start all sections temporarily FOLD (pure CSS off `.twk-reordering`; the open/closed mix is untouched and restores on drop), the dragged section floats as a chip with FLIP-gliding siblings + edge auto-scroll, Escape cancels, the move cursor flags the affordance, and the custom order persists per panel (`twk-order:<ns>`, merge-commit keeps ids hidden in the current view — Theme Lab basic mode — in their slots). Engine = NEW `useTwkSectionReorder` (13th panels export); `TweaksPanel` re-sequences its `TweakSection` children by persisted order automatically (on with `collapsibleSections`, `reorderableSections={false}` opts out; duplicate labels disable; new optional `TweakSection id` prop), mouse/pen arm after 5px slop (click still toggles), touch after a 350ms hold (panel keeps scrolling — `touch-action:pan-y` + armed non-passive touchmove blocker). BACKPORTED Theme Lab header treatment to the kit's collapsible sections: label · separator · chevron header, hover/focus contrast lift + sibling recede, and an adaptive collapse/expand-all button in the panel header (section census via context `registerOpen` + `allCmd` broadcast; inline-SVG icons; `panel.sections.*` strings). The Theme Lab panel now consumes the SAME engine (TlOrdered ordered render, chevron/pin excluded via `data-twk-noreorder`, drag in both basic + expert modes, disabled while searching) — every `collapsibleSections` consumer (comp-* Inspectors, playground combined Tweaks, cos-library Tweaks, collection inspector, kit demos) inherits via the regenerated twin. Fixed en route: drag-commit could persist a stale order when pointerup landed in the same frame as the last move (session-local working order is now authoritative). Pitfalls: `[data-noncommentable]` roots (kit panel) are excluded from html-to-image captures — probe the DOM, don't trust the pixels.

- **Theme Lab — responsive fixes round 9b** (`theme-lab.html` + `theme-lab/showcase.js`, user feedback): content never sits under the settings panel now — the docked two-column layout holds down to **761px** (the frame's container-query layouts absorb the narrow column), and below that the panel leaves the fixed layer and becomes an **in-flow block** between demo and docs (the kit's floating bottom-right form covered most of a narrow viewport; `transform:none` guards against a stale drag offset). E-shop cards: the price pair STACKS (struck original under the current price) and each card is its own inline-size container (`tlscard`) — the add-to-cart CTA steps down with card width: full label → „Koupit“/„Add“ ≤250px → icon-only ≤190px (aria-label stays on the button); all three auto-fill grids floor their track at `min(Npx, 100%)` so a sub-minimum frame shrinks the track instead of overflowing.
- **Theme Lab round 9 — per-domain showcase layouts · preset sweep onto the round-8 knobs · frame-width responsivity** (`theme-lab/showcase.js` + `theme-lab/presets.js` + `theme-lab/bgfx.js` + `theme-lab.html`, user feedback): the Showcase scene's five domains no longer share one card grid — shop keeps the product grid (auto-fill columns, struck sale price), delivery = wide venue cards with rating/delivery-time flags OVERLAID on 21/9 media, tv = an evening schedule RAIL (mono start/end times, connected dots, finished show dimmed, „Živě“ chip + progress bar on the running one — the only row with a CTA), office = dated notice-board rows (day/month leaf, mono ref. numbers, category tag, quiet ghost CTA), kids = a bookshelf of portrait covers tinted by the `--doc-*` token pairs (Hravé's playful remap recolors the shelf) with age flags and a full-width borrow CTA. Two marker classes are engine contracts: `.tls-panel` joined presets.js `BW_NONE_SCOPES.panel` + `CHIP_SCOPE` + the glass surfaces rule + bgfx `PANEL_SCOPE` (so „no borders“, chip treatments, glass and panel tints now reach showcase surfaces), `.tls-line` joined `BW_NONE_SCOPES.line`. Layouts respond to the DEMO FRAME's width — `.tl-app` is an inline-size container (`@container tlapp`; the docked panel's 336px viewport gutter made viewport queries lie): grids are auto-fill, tv/board rows restack their right-hand cells under the body ≤700px, domain-seg labels collapse to icons ≤860px (buttons gained aria-label + data-tip). Preset sweep: Úřad + Archiv Brno → paper desk · Sklo → mist · Vzdušné → aurora desk+bar + Spectral display face (reach h2) + light weights · Wolt → wash desk + heavy weights · Hravé → aurora dialogs · AURA → panel/dialog washes · Material → tonal panel tint · LIS → grid desk + compact element size · ČT → bold focus · Alza → block tabs · Ostrava → Lora display (h2) + tinted bar · Brno → warm neutrals · NATO Partner → stone neutrals; Space Grotesk / Nunito GF queries widened (300..700 / +500) so the new weight sets don't faux-render; `ICON_MAP` += bi-tv / bi-basket / bi-cake2 for the new items (5–6 per domain).
- **Theme Lab panel — hover-recede suppressed while searching** (`theme-lab/panel.jsx`, user feedback): with an active query the match/non-match opacity split owns the hierarchy — the search effect stamps `.tlp-searching` on `.twk-body` and the hover-recede `:has()` rule is gated `:not(.tlp-searching)`, so matching sections/controls stay full-strength when hovering another section; only `.tlp-sec--dim`/`.tlp-row-dim` recede. The hover contrast lift (bold name + darker separator/chevron) still applies during search.
- **Theme Lab panel — search round 3 + focus-shape fixes** (`theme-lab/panel.jsx`, user feedback): "hide non-matching" now truly removes match-less sections INCLUDING their header — `.tlp-sec--nohit{display:none}` sat BEFORE `.tlp-sec{display:flex}` in the same sheet at equal specificity, so flex won (fix = doubled class `.tlp-sec.tlp-sec--nohit`); the in-field overlays (magnifier, match counter, ×, kbd hint) now ride `z-index:3` ABOVE the focused input — the kit's panel focus rule lifts a focused control to `position:relative;z-index:2`, which painted the field's near-opaque fill over them and made the × UNCLICKABLE; only the „Ctrl K" hint still dims deliberately while typing (`:focus-within` opacity .45). Focus shapes: the kit focus rule also hard-sets `border-radius:7px` — a CIRCLE on the 13px Expert checkbox, a squared-off rect on preset pills — pinned back to their own radii (`.twk-panel .tlp-expert input:focus-visible{border-radius:4px}` / `.tlp-pill:focus-visible{border-radius:999px}`, the kit's own .twk-slider pattern). Pitfalls bullet added (kit focus rule = radius override + z-lift, same-sheet order trap).

- **Theme Lab panel — search round 2: match navigation · eye toggle · Ctrl+K · per-section counts · icon fix** (`theme-lab/panel.jsx`, user feedback): typing scrolls the FIRST match into view (manual `body.scrollTo`, reduced-motion aware — never scrollIntoView); an in-field counter shows total matches („n“) or position („i/n“) once navigating; ▲/▼ buttons + Enter / Shift+Enter / ↑↓ in the field cycle matches — the active match gets an outline ring, is scrolled into the body's view and its first control takes focus (`preventScroll`); an EYE toggle (persisted `theme-lab-search-hide`, default hide) switches non-matching content between HIDDEN (rows + sections removed) and DIMMED (kept at low opacity, collapse states respected); Ctrl/Cmd+K focuses the search (expert only; „Ctrl K“ kbd hint sits in the empty field); matched sections show an inverted count pill next to their name (injected beside the label's text node — matching reads only the first text node so pill digits can't false-match numeric queries); the search-icon-invisible-on-focus bug fixed (the focused field's near-opaque background painted OVER the absolutely-positioned glyph — z-index lift + focus-within contrast bump).
- **Theme Lab panel — adaptive collapse-all button · global pin · expert search** (`theme-lab/panel.jsx`, user feedback): the two bulk chevron buttons merged into ONE adaptive header button — expands everything when at least one section is collapsed, collapses everything otherwise (icon + tooltip flip with the pending action). NEW global pin pill in the Presets row (beside the dice): three states — nothing pinned (outline pin) / some pinned (filled pin + „{n} z {m}“ tooltip) / all pinned (dark pill); click pins ALL groups unless everything is pinned, then unpins all (master-checkbox cycle). NEW expert-mode SEARCH — sticky field atop the panel body filters settings by section name and/or control label (diacritics-insensitive via `Chips.fold`): non-matching sections hide, matching sections force-open while the query is active (DOM `data-open` written by an after-render effect so React re-renders can't re-close them), non-matching rows inside matched sections dim to 32%; ✕ or Esc clears and restores the persisted collapse states; leaving expert mode clears the query.
- **Theme Lab panel — Expert checkbox glyph + section emphasis + collapse/expand-all** (`theme-lab/panel.jsx`, user feedback): the Expert checkbox's checked state now draws a real ✓ (CSS rotated-L, white on the dark fill) instead of the ambiguous inner square, with a lighter unchecked border + hover affordance; the active section header (hover anywhere in the section or focus inside) now also goes **bold 700** at near-full ink while every OTHER section — header and controls — recedes to 68% opacity (`.twk-body:has(.tlp-sec:is(:hover,:focus-within))` dim); two icon-only header buttons left of the Expert toggle (expert mode only) collapse / expand ALL sections at once (`bi-chevron-contract`/`-expand`, persisted through the same `theme-lab-sections` key).
- **Theme Lab — basic/expert mode + collapsible panel sections** (`theme-lab/panel.jsx`): NEW „Expert“ checkbox in the panel header (LS `theme-lab-expert`, default OFF) — basic mode shows only the headline knobs (presets · themes · mode/transition · palette+neutrals · page background · main/mono font + scale · radius set · spacing · shadows+glass master · motion master · button style · icon set · brand · export) and hides User presets entirely plus every „same-as / default / auto“ configuration control (role radii, border group, variants, focus, table, glass roles, bar/panel/overlay backgrounds, display-font trio, weights, size, reveal/pagefx, Material icon style/weight). In expert mode every all-caps section is COLLAPSIBLE — new `TlSection` mirrors the kit's TweakSection mechanics verbatim (grid-rows 0fr↔1fr collapse, overflow-visible-after-open, `inert` on the collapsed body) with a richer header: label · separator line · chevron (left of the pin, rotates −90°) · randomize pin (stays visible + toggleable while collapsed); collapse states persist per section (LS `theme-lab-sections`); hovering the header OR the section's controls, or focusing inside, lifts the header contrast (label/separator/chevron). Basic mode keeps plain non-collapsible headers.
- **Theme Lab round 8 (ideas round) — Backgrounds axis · adaptive Showcase scene · display-font axis · user presets with sharing** (`theme-lab.html` · `theme-lab/presets.js` + `panel.jsx` + `scenes.js` · NEW `theme-lab/bgfx.js` + `showcase.js` + `user-presets.js` + `theme-lab/bg/*.png`): (1) NEW **Backgrounds** group — page desk (wash / aurora / dots / grid / hatch / generated paper+mist grayscale-alpha textures / custom image URL under a `color-mix` page-token veil), app bar (tint / brand gradient / aurora through the `--tl-bar-*` hooks — overrides preset bars), panels & cards (tint = background-color + `--fg-bg`; wash = background-image so glass surfaces survive), dialogs & toasts (wash / aurora — background-image only, never the shorthand); token-riding `color-mix()` forms serve both themes with ONE rule; the glass effect emits its aurora desk only as a fallback when `bgPage` is off; all randomizable + pinnable (new `bg` PIN group; pools never roll the image option); Hravé preset gains dots. (2) NEW adaptive **Showcase scene** (4th tab) — one scene, five domains (e-shop „alzium“ · rozvoz „Voltín“ · ČT program · úřední deska · dětská Knihovnička), auto-switched by preset (`PRESET_DOMAIN`: alza/wolt/ct/urad/hrave) with a manual in-scene segmented override (LS `theme-lab-domain`); hero + category pills + 4 item cards as `tls-*` scenery riding DS tokens + shared pieces (.seg/.btn/.vchip/toast CTAs per domain), fully cs/en (re-render on `themelab:lang`), striped-placeholder media with icon glyphs; ~25 new `ICON_MAP` entries so icon-set swaps cover the new glyphs; `scenes.js` SCENES += showcase with a lazy `TLShowcase.onShow()` hook. (3) NEW **display-font axis** — `fontDisplay` decouples `--font-display` from the main face (11 curated serif/slab/display faces + custom Google Font; single-weight faces excluded — h1 runs bold and would faux-bold) with a REACH knob: H1+wordmark (pure token) / + section `h2, .h2` / + `.tld-head__sub, .text-eyebrow` — generic unlayered rules, export-safe, emitted only when a display face is set. (4) NEW **user presets** (`ThemeLab.user`) — save/restore named looks as JSON DIFFS from DEFAULTS (LS `theme-lab-user-presets`; mode/transition/preset never saved), apply = defaults-reset + diff (same contract as preset pills); sharing ×3: `?u=<base64url {n,d}>` link (decoded in state INIT so the shared look paints first + boot toast), copy/paste JSON import (accepts `{name,d}` / `{diff}` / raw diff, unknown keys dropped), `.json` download + file import; panel section with match-highlighted pills + ✕ delete, share actions operate on the current look.
- **Theme Lab — presets reworked onto the full W1–W4 knob surface; 2 new fonts** (`theme-lab/presets.js`): each preset now exercises the role/variant/focus/glass knobs its source look implies — ČT: Archivo (TV Sans stand-in) + lined tables + stronger borders · AURA: outlined filter panels, rail dropdown highlight, fade ticks · LIS: block header tabs, strong borders, no focus gap · Alza: 4px button/control radii, blue links beside the green primary, fade ticks · Wolt: Nunito (Omnes stand-in), pill buttons/chips/header-tabs, borderless shadow-only panels, bare filters + pagination, pop ticks, rounded dropdown highlights, branded blue bar · Material: pill buttons, drawn ticks, comfortable density, M3 surface-tint bar, segmented switch back to fill (M3 segmented buttons) · Úřad: contrast borders, outline filter panels, block tabs · Hravé: Baloo 2, pill tabs, rounded highlights, tinted bar · Vzdušné: airy spacing, hairline borders, bare pagination, tonal links, soft focus glow · Sklo: bare pagination, pill tabs, wipe ticks · Archiv Brno theme: Roboto Slab. `MAIN_FONTS` gains `archivo` + `baloo` (Google Fonts, latin-ext); `barCSS` gains wolt/material/hrave branded bars; Alza palette gains a dedicated link blue.
- **Theme Lab round 7b (user feedback) — frost the dialog surface only** (`theme-lab/presets.js`): round 7 put the glass gaussian on the scrim, which frosted the WHOLE page behind the dialog; the veil now keeps its plain dim — glass instead sets `backdrop-filter: none` on `.modal-scrim` (un-filtering the parent so the child's blur can sample the page at all — the default 1.5px scrim blur was the backdrop root killing it) and puts `saturate(140%) blur(24px)` + an explicit translucent surface on `.modal` itself (dark twin included), keeping the overlays role self-sufficient without the surfaces role. Pitfalls bullet rewritten to the correct recipe.

- **Theme Lab round 7 (user feedback) — glass actually visible; dialogs get a real frosted backdrop; modal footer separator now opt-in** (`theme-lab/presets.js` · `preview/_modal.css` · `docs/components/modal.md` + `.cs.md`): (1) glass read as "nothing changed" because the demo frame `.tl-app` paints an opaque `--color-bg-page` OVER the body's glass gradients — the effectsCSS scaffolding now sets `.tl-app { background: transparent }` while any glass role is active so the gradient shows through the translucent surfaces. (2) The dialog's own `backdrop-filter` was DEAD — its parent `.modal-scrim` is already backdrop-filtered (the default 1.5px dim-blur), and a child never re-samples through a filtered ancestor — so glass dialogs showed plain transparency; the overlay bucket now puts the BIG gaussian on the SCRIM (`saturate(140%) blur(24px)`, whole page frosts behind the dialog) and drops the dead modal rule (toasts keep their own blur — no filtered ancestor). (3) **Shared default change:** `.modal__foot` no longer draws a separator line above the actions — the border moved to a new opt-in `.modal__foot--bordered` (mirrors `.modal__head--bordered`); Theme Lab's bwLine "none" scope + modal md/cs docs updated.

- **W4 — glass matrix per role, drawn-tick animation, header-tab knob (lab-only), md-twin docs for all W3/W4 variants** (`theme-lab/presets.js` + `panel.jsx` · `preview/_checkbox-radio.css` · `preview/comp-checkbox-radio.html` · `docs/components/{segmented,pagination,select,checkbox-radio,filter-group,links}.md` + `.cs.md`): `effectsCSS` split into ROLE BUCKETS — surfaces (surface/field tokens + panel backdrop + zebra tints) / overlays (popup near-opaque recipe + modal/toast blur) / controls (the heavy block) — master mapping glass = surfaces+overlays, heavy = all three, with per-role Auto/On/Off selects overriding it (the same master→role pattern as radius/border widths); shared scaffolding (page gradients + stacking-context z-index rescue) emits when ANY role is on; default stays fully off (no new stacking contexts — glass remains a lab feature, no DS partial gains backdrop-filter). `data-v-check="draw"` / `.checkbox--anim-draw`: the tick INKS IN along its stroke — a fill-coloured cover with a soft diagonal edge swept by a registered `--chk-draw` percentage driving the gradient stops (rest = 115% so the soft edge sits fully past the box); radio dot inks in with a smooth no-overshoot grow; comp example row + panel option + POOLS added. Header tabs = LAB-ONLY knob per the settled decision (appnav is scene chrome; a DS tabs compound stays demand-gated): `tabsCSS` restyles `.tl-appnav` active/hover as pills or blocks via `color-mix(in srgb, currentColor …)` fills that adapt to branded bars and both themes. fx PIN group gains the glass roles, variants gains tabStyle. Docs: Variants rows/sections for every W3/W4 variant across all six component md files + Czech twins (pagination + filter-group gained their Variants section).

- **W3 — opt-in component variants (class modifiers + body theme hooks) with Theme Lab knobs, presets and comp-page examples** (`preview/_segmented.css` · `_pagination.css` · `_select.css` · `_checkbox-radio.css` · `_filter-group.css` · `colors_and_type.css` · `theme-lab/presets.js` + `panel.jsx` · `preview/comp-{segmented,pagination,select,checkbox-radio,filter-group,links}.html`): every variant exists as `.comp--<variant>` AND `body[data-v-<comp>="<variant>"]`, written once via `:is()` after the base rules — base selectors untouched, defaults byte-identical. (1) `.seg--underline` — tabs vocabulary: transparent set on a hairline rule, active = primary text + 2px bar (`::after`), the transient thumb restyled into the GLIDING BAR (same controller/metrics; `border-radius: 0 !important` beats the inline computed-corner write); disabled-active = gray bar. (2) `.pag--bare` — buttons rest borderless/transparent; hover/pressed/focus restore the frame via the base rules' higher specificity; active page + sliding thumb keep the solid fill (incl. a bare `.is-sliding` reset). (3) Dropdown highlight contract — `.combo-item` tints read `--combo-hl-bg`, rails `--combo-rail-w/-c` (hover rail default 0px = invisible; keyboard rail `max(rail, 2px)` keeps its disambiguator); variants `.combo-list--rail` (3px rail on hover+selected) and `--rounded` (forces `--combo-inset: 6px` + `--combo-item-r` ≈ concentric). (4) Checkbox/radio tick animations `fade|pop|wipe` — pure CSS keyframes on `:checked` (no DOM change; reduced-motion collapses them): tick `background-size` pop with overshoot, two-layer cover wipe (fill-coloured gradient shrinking rightward), fill fade; radio dot via registered `@property --rd-dot/--rd-ink` (grow / slide-in / ink fade); reaches `.filter-item` checkboxes under the body hook; glyph geometry parameterized as `--chk-tick` (14px / filter rows 12px). (5) `.filter-group--tree` — hairline tree connectors as per-row `::before` stub + `::after` rail segments (rail always ends at the last row's stub; find/more/empty rows stay flush; pseudos inside the scroll clip). (6) Link underline tokens — the global `a`/`a:hover` rules (and comp-links' `.prose a`) read `--link-uln-style/-w/-offset/-color` + `-h` hover twins with today's values as fallbacks. Theme Lab: new "Varianty komponent" group (view-switch / pagination / dropdown highlight / check animation / link underline selects, cs+en), fgStyle gains "Strom", `applyVariants()` stamps the `data-v-*` attrs in paint(), `linkCSS()` emits the underline tokens, POOLS + a new `variants` PIN group join Randomize, and the CSS export appends a comment listing the body attrs a consumer must add (CSS can't set attributes). Preset flavors: ČT + Material → underline tabs, LIS → bare pagination, Hravé → pop ticks + thick links, Vzdušné → rounded dropdown highlights. Follow-up debt: docs/components md twins for the new variants.

- **Theme Lab round 6 (user feedback) — radius role hooks reach interaction geometry; filter-panel "no fill" truly unfilled; metabox rows obey line "none"; AURA DS preset removed; board gains segmented + radio examples** (`preview/_segmented.css` + `_segmented.js` · `preview/_checkbox-radio.css` · `preview/_select.css` · `preview/_filter-group.css` · `theme-lab/presets.js` · `theme-lab.html`): W1 gap closed — interaction geometry now derives from the role hooks like container corners do: segmented end buttons ride `max(0px, var(--radius-control, 4px) - 1px)` (was `3px` literal; hover/active fills AND the box-shadow focus ring follow border-radius for free) and the WAA gliding thumb READS the destination button's computed corners instead of baking `'3px'` (`_segmented.js metrics()`); checkbox/radio hover-shell rides `var(--radius-control, 8px)`; combo dropdown items get DERIVED inset + rounding (`--combo-inset: clamp(0px, (var(--radius-overlay, 6px) - 6px) * 0.6, 8px)` on `.combo-list`, item radius `max(0px, R - 6px)` — default resolves byte-identical to the old full-bleed rows, rounded themes get concentric inset highlights); filter-find input → `var(--radius-chip, 3px)`. Theme Lab: `fgStyle` outline/bare now also clear `backdrop-filter` (under glass the blur+saturate frost read as leftover fill; fgCSS emits after effectsCSS → same-specificity source-order win); `bwLine` "none" now reaches metabox row separators — `BW_NONE_SCOPES.line` gains `.metabox--lines/--zebra .metabox__row` args to TIE the unlayered (0,3,0) row-treatment pins (injected sheet sits last in `<body>` → wins); AURA DS preset removed (user request — `aura` covers the family); component board scene gains a live segmented switch (auto-wired by `initSegmented`) + a two-option radio group, cs/en labels.
- **Token flexibility W1+W2 — radius/border/focus ROLE HOOKS across the DS + Theme Lab role knobs** (17 `preview/_*.css` partials · `colors_and_type.css` docs comment · `preview/_tweaks-css.js` · `theme-lab/presets.js` · `theme-lab/panel.jsx` · `theme-lab.html`): W1 — components now read radii/border-widths through optional role hooks with their old literals as fallbacks (`border-radius: var(--radius-control, 4px)`; nested shapes derive via `max(0px, var(--radius-control, 4px) - 1px)`), so the visual is a BYTE-IDENTICAL no-op until a theme sets a hook on `<body>`. Roles: `--radius-btn / -control / -panel / -overlay / -chip` + `--bw-panel / -control / -line`; carriers: pagination (incl. compact + thumb + focus-ring radius), segmented (+thumb), fields/search (lg/hero = control+2), selects + combo list, filter-group (+`--fg-bg`/`--fg-bd` surface hooks, find input, items, checkboxes), checkbox/radio, buttons, fav, doc-card/lib-card (+`.pill`), table wrap + td/th lines (th = line+1), metabox (box, h3, rows incl. stripe-variant + `_tweaks-css.js` emissions), related (+rel-pill/rel-tag), cta-panel (+notice, note separator), modal (radius + head/foot lines), menu (trigger/panel/separator), toast, list-toolbar wrap, filter-pills. W2 — Theme Lab: radius SETS now also emit role values (sharp/soft/round/pill re-shape pagination, inputs, segmented, filter panels and chips too — pill = fully circular pag buttons + round checkboxes) + five per-role radius selects override the set; border thickness gains Hairline 0.5px and maps master→roles with three per-role selects (Panels/Controls/Lines; "none" = transparent border-color, zero layout shift); BORDER_SCOPE width hack replaced by tokens; NEW Focus-ring group (thickness 2/3/4 × gap 0/2/4 × glow soft/strong, composed with the active palette's halo for both themes, emitted after paletteCSS so it wins); NEW filter-panel surface select (fill+border / border only / fill only / neither via the `--fg-*` hooks); presets updated (Úřad bold+tight ring, Hravé soft glow, Sklo strong glow + flat filters, Vzdušné flat filters, LIS bare filters); POOLS/PIN_GROUPS extended (new `focus` pin group; per-role keys reset to auto on Randomize unless pinned); crossfade rule now transitions `border-width`; docs paragraph documents the role-hook contract. Babel harness ALL PASS (68); computed-style no-op verified at defaults in BOTH themes.

- **Theme Lab round 5b — combo wheel/keyboard + EN gaps** (`studio-kit/panels/studio-panels.jsx` · `theme-lab.html` · `theme-lab/scenes.js`): kit `TweakSelect` — (1) wheel over the OPEN trigger now STEPS THE COMMITTED VALUE in place (list stays open; moving just the highlight gave no way to change anything); (2) the open list no longer closes on scroll — the capture-phase close listener also caught the LIST's OWN scrolls, so arrow keys moving the highlight to an off-screen option (keyboard-follow `scrollTop` write) dismissed the dropdown; scroll/resize now RE-PLACE the list from the trigger's live rect instead of closing; (3) wheel inside the open list: overflowing list scrolls via a manual clamped `scrollTop` (preventDefault — no scroll-chaining into the panel at the ends), fully-visible list forwards the wheel to the panel body found via the TRIGGER's ancestors (the list is portaled to `<body>`, so native chaining would scroll the page, not the panel) while staying open + anchored. EN: detail classification chip NEOZN.→UNCL. (`data-tl` spans), board name-field placeholder "Jméno a příjmení"→"Full name" (`#tl-name` relabel).
- **Theme Lab round 5 follow-up** (`theme-lab.html` · `theme-lab/presets.js` · `theme-lab/panel.jsx`): header-tab BLINK at the end of preset crossfades FIXED — the broad `html.tl-anim .tl-app * { transition: color … !important }` made `color: inherit` followers (nav tabs, lockup word) re-ease the app bar's already-animating color every frame (exponential chase) and SNAP when `tl-anim` dropped at 700 ms; inherit-followers now exclude `color` from their transition set (inheritance tracks the bar's fade for free) + the class removal moved 700→950 ms so late-starting transitions aren't cut mid-flight. Neutrals gain FOUR sets — Ocelové/Slate (blue-gray) · Kamenné/Stone (greige) · Šalvějové/Sage (green-tinted) · Fialkové/Mauve (purple-tinted), full light+dark ramps + surface/fg/border picks, auto-joined to Randomize via `Object.keys(NEUTRALS)`.
- **Theme Lab round 5 (user feedback)** (`theme-lab.html` · `theme-lab/scenes.js` · `studio-kit/panels/studio-panels.jsx`): KIT `TweakSelect` wheel is now ENGAGED-ONLY — open list → wheel over the trigger moves the highlight, focused closed trigger → steps the committed value, plain hover-scroll passes through (an always-on cycle made the panel unscrollable wherever combos sat in the wheel's path; `preview/tweaks-panel.jsx` mirror still OWED, now incl. this gating). Two-column layout while the panel is docked (≥1021px): `body { padding-right: 336px }` reserves the gutter for the fixed panel so header/demo/docs/footer center in the left content column and nothing sits under the panel; dialogs re-center on the content column via `.modal-layer .modal-scrim` padding (scrim still covers the whole viewport). Hub-link underline moved off the flex anchor onto the label spans (system rule: never under the ← glyph). EN demo locale COMPLETED — table headers, validity/availability chip labels (+tips), card CTAs/meta labels and pagination labels localize via a `FP_COMPOUNDS` merge-relabel (the locale-data.js consumer seam in miniature; re-render guarded by a lastLang check so the panel-mount event doesn't replay entrances); sort combo relabelled in JS + keys switched to `data-sort` (the `_select.js` `data-value`→trigger-label trap, re-hit — board Útvar combo dropped `data-value` too, its committed label showed "osk"); detail extent / edition / relation tags+descriptors ride `data-tl` spans (tooltip-safe — `data-tip-clip` reads `innerText`, which excludes hidden spans); static chip `data-tip`s flip via a cs↔en `TIP_PAIRS` swap map.
- **Theme Lab round 4 + Studio Kit panel-control a11y** (`theme-lab/*` · `studio-kit/panels/studio-panels.jsx` · `theme-lab.html`): icon swap FIXED — bootstrap-icons declares `font-family/font-weight !important` on every `::before`, so the Material/FA overrides now carry `!important` too (raw "check_circle" words / FA tofu bug); FA codepoint corrections (hashtag `\f292`, external-link `\f35d`) + globe/bookmark/collection mappings; emoji glyphs centred + sized (0.88em, flex-centred). Toasts re-anchored to the DEMO BLOCK's bottom-right (scenes.js pre-creates `.toast-layer` inside `.tl-app` — `_toast.js` adopts an existing layer; page CSS flips it to `position:absolute`), so they never hide under the fixed panel. Six new palettes (Oranž `#E8590C` · Zlatá `#A87900` · Cyan `#0C8599` · Fialová `#7048E8` · Les `#2F9E44` · Půlnoc `#364FC7`). KIT: `TweakRadio` segments now keyboard-operable (per-button click handlers — Enter/Space were dead; arrows/Home/End step the value on the radiogroup) and `TweakSelect` gains closed-state ←/→/Home/End value stepping (DS combo model; ↓/↑/Enter/Space still open per ARIA) + wheel-cycling on the closed trigger via a NATIVE non-passive listener (React root wheel listeners are passive — `onWheel` can't preventDefault); the open list keeps native wheel scrolling. `preview/tweaks-panel.jsx` mirror of these control fixes is still OWED.
- **Theme Lab round 3 (user feedback)** (`theme-lab.html` · `theme-lab/*` · `preview/_modal.js`): NEW presets Alza (`#71BC44` gen ramp) · Wolt (`#009DE0`) · Material (M3 `#6750A4` handpicked ramp, Material Symbols, rounded, fade transitions) · "Sklo"→"Vzdušné" + a heavier new "Sklo" (`effects:'heavy'` — translucent + blurred buttons/fields/chips/segs). NEW axes: icon set (Bootstrap/Material Symbols/Font Awesome/emoji via `::before` content overrides — survives renderer re-renders; unmapped glyphs keep Bootstrap) + Material variant (outlined/filled/rounded/sharp) + weight; separate main/mono font selects (16+9 curated Google-Fonts options incl. Roboto Slab, Inter, Montserrat, Merriweather, Slabo 27px, Geist, Fira Code, Victor Mono, Inconsolata, Ubuntu Mono…) + custom Google-Font name inputs; font-weight sets; element-size scale (`.tl-app` zoom); 5-step spacing; border thickness/color group; content-reveal vector (Collection setEffect) + scene-transition variant (PageTransition VARIANTS) selects — all randomizable with group pins (PIN_GROUPS). Fixes: glass popups now near-opaque + own blur (child backdrop-filter can't re-sample through a filtered ancestor — the unreadable Sklo sort dropdown), chip/table tweaks now reach Detail + Komponenty scenes (`CHIP_SCOPE` + `.tld-head`/`.tlb-cell`), ČT preset button style id fixed (`'ČT DS'`). Shared: **`_modal.js` gains opt-in `draggable: true`** (header drag via the independent CSS `translate` property + pointer events — open/close transforms untouched); Theme Lab dialogs use it. LS key bumped to `theme-lab-state2` (fonts axis split).
- **Shared fix — `styles.css` gains the missing `preview/_num.css` @import** — animated utility counts (`Num.set`) were silently static in every consumer that links only styles.css (the prototype/templates/theme-lab); comp pages linked the partial individually so the playground masked it.
- **Theme Lab round 2 (user feedback)** (`theme-lab.html` · `theme-lab/*` · `notes/pitfalls.md` new H2): panel rebuilt on the real Studio-Kit chrome (`StudioKit.Panels.styleCss` + TweakRadio/Select/Toggle/Text/Button; fixed body-level `[data-fp-chrome]` host — modal-inert exempt, never reflows with demo tokens); new tweak groups table density · row striping · chip treatment (FP_TWEAKS_CSS builders through the shared palette remap, wired into presets); card view gains Collection reveal/refresh motion; `[hidden]` vs `display:grid` fix for the card grid; glass stacking fix (toolbar dropdown above table); board select rebuilt on the canonical combo markup; scene chrome fully bilingual (`[data-tl]` spans + JS-owned strings in `TL_TXT`).
- **Theme Lab — token-flexibility showcase page** (`theme-lab.html` NEW · `theme-lab/presets.js` + `scenes.js` + `panel.jsx` NEW · `index.html` hub door · `preview/test-babel-parse.html` PAGES): a live mini-app (catalogue / detail / component-board scenes built from the shared compounds) beside a docked Studio-Kit panel that re-skins the whole system through tokens only — mode, palette (OKLCH ramp generator + handpicked ČT `#041E42` / AURA `#003DA5` / LIS navy ramps), neutrals, font pairs (on-demand Google-font stand-ins), type scale, radius, spacing, shadows (incl. palette-tinted glow), glass effect (translucent surfaces + backdrop blur), motion tokens, button style (reuses `FP_TWEAKS_CSS` presets with literals remapped to the active ramp) and a text-only brand lockup. Presets DSGCZ · ČT · AURA · AURA DS · AURA LIS · Úřad · Hravé · Sklo + three tenant "themes"; Randomize with per-group pins; changes apply via `PageTransition.wipe` / transient crossfade / instant (user-selectable); state persists (`theme-lab-*` LS) + shareable `?preset=`; live "copy theme CSS" export + bilingual (cs/en) how-to docs. Overrides ride `@layer tweaks` on `body:not([data-theme=dark])` / `body[data-theme=dark]` (never `:root` — token-freeze pitfall).
- **Feature guide — keycap history dim + LEARNING MODE (kit 0.9.0)** (`studio-kit/guide/studio-guide.{js,css}` → regenerated `preview/_guide.js`/`_guide.css` · `tools/ds-wraps/_guide.css.overlay.css` · `preview/_guide-demos.js` · `preview/comp-guide.html` · `docs/components/guide.md` + `.cs.md`): the showcase queue now dims everything but the newest cap (`is-past`, smaller + faded — default ON, `{dimPast:false}` opt-out; evictions fade from current opacity; the demo-stage HUD ports it) — and `['key', …, {learn:true}]` acts become real EXERCISES: starting a learnable tour offers a Watch/Try-it chooser (choice persisted as `learnPref`; touch-only devices + `?gdaudit` always watch; `Guide.start(id,{learn})` pre-chooses), the whole sequence renders at once (armed cap pulses, upcoming caps dim) and the engine WAITS for the real press — held modifiers depress their cap part, wrong keys shake the armed cap, Esc still exits unless Esc IS the expected key — a match pins a green ✓ (the effect stays the synthetic dispatch on `to`; the real event is stopped so app handlers never double-fire), a „Show me" button appears after ~5 s (`showMeAfter`; gray ✓, not earned), and user-earned steps auto-advance per `cfg.learnAdvance`/`Guide.setLearnAdvance` (`'hybrid'` default: mid-tour only — the last learn step and the tour end wait). Chrome strings added in cs/en/ja; new `--studio-ok` token (green, DS overlay → `--gov-color-success-500`); audit hooks `helpers.tourLearnable`/`learnState()`/`learnFulfil()`. comp-guide: learn/history state specimens in the caps row, the keyboard tour's three key acts flagged `learn:true` (its launcher now opens the chooser), Tweaks „Dim past caps", Inspector „Learn advance" (Auto/Hybrid/Wait). Studio Kit → 0.9.0.

- **Playground global-FAB launcher rows for the component keyboard tours (kit 0.8.2) + modal-visibility retargets** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · `preview/tours-playground.js` · `preview/playground.html` · `preview/comp-pagination.html` · `preview/comp-menu.html` · `preview/_guide-audit.js`): user feedback — the ⌨ modal button alone wasn't discoverable enough AND two tours broke inside the modal because they targeted `[data-fp-configurable]` Inspector wells (display:none until the Inspector reveal → 0×0 spotlight). Engine: tours may now carry `launch: fn` — the feature-panel row renders normally but activating it closes the panel, marks the row seen and DELEGATES instead of running steps (`Guide.start(id)` routes the same way); the audit skips launcher rows with an info. Playground: five „Klávesnice: …“ rows in the global "?" FAB (tours-playground.js `kbLauncher` factory) call the new `window.FP_KB.open(file)` hook — opens that component's preview modal, waits for its dormant guide, starts the `keyboard` tour inside the frame (bails if the user closes the modal or navigates mid-wait). Retargets: comp-pagination now demos on the always-visible standard nav (`#kb-pag` / `#kb-pag-cell`, onEnd restores page 1 via Home), comp-menu on the always-visible row menu (`#kb-menu`, step targets follow the OPEN panel, Esc-step undo reopens). Studio Kit → 0.8.2; babel harness ALL PASS (65); probed end-to-end (FAB row → modal → inner tour step 0 with visible targets).
- **Per-component „Keyboard navigation“ tours + playground ⌨ surfacing (kit 0.8.1)** (NEW `preview/_kb-tour.js` · `preview/comp-{region-nav,pagination,filter-pills,menu,switch}.html` · `studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · `preview/playground.html` · `preview/test-tour-audit.html` PAGES): flagship interactive components now carry a manual „Keyboard navigation“ tour registered via the declarative `KbTour.init({app, ready, steps, onEnd})` helper — F6/Shift+F6 region cycling, pagination PgUp/PgDn/Home/End + arrow focus, filter-pill arrows/⌫/Enter, menu ↓-open/↑↓/Esc, switch Enter/←→ — each press showcased with the engine's big keycaps, focus made visible via `KbTour.ringActive` (`.is-focus` mirror; synthetic presses never produce `:focus-visible`), state restored in onEnd. Engine: `?fp` now registers the guide DORMANT (FAB hidden, no auto/nudge/suggest/pulse, `Guide.start` still works; `?guide=0` stays the hard kill) — so the playground's source-preview modal shows a ⌨ titlebar button (soft-dep, Inspector-button pattern: appears only when the frame's dormant guide reports a `keyboard` tour) that starts the tour INSIDE the frame; the guide's window-capture Esc ends a running tour without closing the modal, and closing the modal stops the tour. Studio Kit → 0.8.1; babel harness ALL PASS (65); comp pages added to the tour audit.
- **All four app guides retrofitted with the key-press showcase + a new prototype „Keyboard navigation“ tour** (`ui_kits/cos-library/tours.js` · `tours2.js` · `tours-data-preview.js` · `preview/tours-playground.js` · `preview/tours-dev-reference.js`): steps that describe shortcuts now DEMO them with queued keycaps — prototype: views-pager PgDn×2/PgUp, reader Esc-closes-TOC + →→ paging, theme restored via the `\` shortcut it describes, cluster force-state H→P→D live cycle (onEnd re-sends D), filters gain static ↑↓/Esc key rows; NEW `keyboard` tour (F6 region cycling with the spotlight leading each press + announcer pill, pager keys, everywhere-shortcuts summary); data preview: metadata ↓↓↑ set-browsing, pager PgDn/PgUp ×2-stacking (net-zero), `\` hint on the dark step; playground: Space pause, digit speed keys 6/8 (captured + restored — speed persists), E error / A show-all on+off, Ctrl+K opens the drawer + ↓↓ nav-cursor moves, T toggles Tweaks, `?`-open→spot-card→Esc-close cheat-sheet finale; dev reference: Ctrl+Enter re-runs the live fence (palette steps stay static — `<dialog>` top-layer sits above the veil). Hardening: `tours-data-preview.js` `relLink` scopes to the live `:not(.is-ghost)` content copy and a new `settleModal()` finishes in-flight WAA swaps before the related-doc seek — in a hidden document the swap clock is frozen and the incoming copy would stay off-fold forever (audit fail at both widths, now green). Tour audit: all surfaces pass (dev-ref reveal infos only).

- **Feature guide spec page — keyboard-tour choreography: spotlight moves BEFORE the caps; padded highlight wrappers** (`preview/comp-guide.html` · rule in `notes/decisions.md`): the „Keyboard navigation“ steps showed keypresses while the highlight still sat on the previous step's area (showStep runs acts first, spotlights the target after) — every step now leads with `['spot', …]` before its `['key', …]` acts. Keyboard-control highlights ring padded wrappers instead of bare controls (pager + search each wrapped in a 12/14px `.kb-cell`, used as step target AND caps anchor; pills already ring `#kb-zone`) so the forced focus ring / pressed flash has clearance inside the highlight. Babel harness ALL PASS (62).
- **Feature guide spec page — key-press showcase feedback round: roomier replay spotlight, reactive controls, Space, pager + Ctrl+K examples, „Keyboard navigation“ live tour** (`preview/comp-guide.html` only — engine untouched): the filter-keys replay now spotlights a padded `#kb-zone` wrapper instead of hugging the bare 19px pills row (the engine pad clamp keys off box height); controls visibly REACT to simulated presses — an explicit `.is-focus` ring mirror follows the arrows (programmatic focus never matches `:focus-visible`, and unfocused/hidden documents don't fire focus events at all — activeElement moves silently), toggled pills dip (`.is-pressed`), pager buttons flash their forced-state pressed mirror, and Ctrl+K lights the search field's native ring. Space is supported (handler, replay label „Přepnout mezerníkem“, specimen row → 10 caps). New second stage row: pagination (PgUp/PgDn work from anywhere in the stage) + a Ctrl+K-focused search field, with a „Replay shortcuts“ button (Ctrl+K · PgDn ×2 ×n-stacking · PgUp) and an Inspector twin. NEW manual live tour „Keyboard navigation / Ovládání klávesnicí“ (3 steps: pills arrows + Enter/Space · paging keys · compound shortcut) with per-step undo + onEnd state rollback; „Keyboard tour“ launcher in the Live row. Babel harness ALL PASS (62).
- **Feature guide — key-press showcase (kit 0.8.0): `['key']` tour acts + a queued keycap HUD; comp-guide demos** (`studio-kit/guide/studio-guide.{js,css}` → regenerated `preview/_guide.js`/`_guide.css` · `preview/_guide-demos.js` · `preview/_guide-audit.js` · `preview/comp-guide.html`): tours can now SHOWCASE keyboard input — `['key', 'ArrowRight']` / `['key', ['ArrowRight','ArrowRight','Enter'], {to, at, label}]` queue big engine-styled keycaps over the veil near the spotlight (newest lands at the anchor, older caps FLIP aside, beyond the queue max the oldest evicts, ~2.4s ttl fade, ×n badge for immediate same-key repeats — all pace + governor scaled) while the key's effect is dispatched as a synthetic keydown+keyup on `to`/activeElement (`send:false` = visual-only; quick/reduced-motion replays dispatch silently; caps clear as the step card arrives / on Back / at end). Defaults overridable via `Guide.init({keyHud:{max,ttl,gap,hold}})` and per act. `Guide.helpers` gains `keyParts`/`keyCapHTML`/`keyEventInit`; the tour audit understands the new op (combo parse + `to`/`at` checks + drive-mode dispatch). comp-guide.html gains §5 „Key-press showcase“: engine-rendered keycap specimens, a keyboard-driven availability-pills stage (stage-local HUD port in `_guide-demos.js`; real ←/→/Enter/Backspace presses inside the stage mirror caps too), Inspector queue-size + key-lifetime knobs, and a new live showcase-tour step driving the real engine op. Deliberately NOT wired into any production tour (user request). Studio Kit → 0.8.0.
- **Feature guide — circle hover-flash concentricity (kit 0.7.11) + spec-page dark-target & tour-ref polish** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · `preview/_guide-demos.js` · `preview/comp-guide.html` · docs tables): the engine's `unionRect` flattened `visualRect`'s badge-aware rect and DROPPED the `own`/`reach` fields, so a hovered 🎯 reference on a badge-wearing FAB flashed a circle centred on the lopsided fab∪badge union (the 0.7.7 spotlight fix never reached the flash path; user screenshot) — the sole-element case now carries `own`/`reach` through and the flash ring is dead-centred. Hand cursor proportions: finger a touch shorter, thumb a touch longer (hotspot hy 1.6 → 2.5). comp-guide: the dark spotlight target is now a small gov.cz button ON a larger dark panel, so the light-mode white inset hairline actually reads against dark (the ring previously sat on the light stage around the dark block); live-tour 🎯 refs into the highlights stage now mirror onto the STAGE veil (delegated hover → `flash(el,{veilOnly:true})` + ring dim — the engine's hole2 can only lift its own veil, and inside its spotlight it correctly does nothing, leaving the stage's local veil dimming the referenced element). Studio Kit → 0.7.11; babel harness ALL PASS (62).
- **Feature guide spec page — feedback round: real spotlight anatomy, geometry + choreography fixes; hand cursor redrawn (kit 0.7.10)** (`preview/comp-guide.html` · `preview/_guide-demos.js` · `studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · `docs/components/guide.md` + `.cs.md`): the anatomy "Spotlight + cursor" illustration is now a REAL GuideDemos mini stage (feathered veil, full ring outline stack, engine arrow cursor) instead of a hand-drawn mock; demo-stage highlights are pixel-exact (absolute chrome anchors to the padding box — geometry now subtracts `clientLeft/Top`, killing the 1px stage-border offset) and self-healing (page port of the engine driftWatch: verdict chips fill before first measure + a 350ms re-hug poll — `space-around` reflow left rings ~2px stale); hover references also UN-VEIL their element via the engine's secondary-hole behaviour (`gd-hole2` added to demo veils); new 4th spotlight target on a dark gov.cz-style bar showcases the light-mode white inset hairline; gallery crosshairs are tick-symmetric (border-box + 17px shadow offsets) and the hourglass turns over its hotspot at any rendered size (`transform-origin: 50%` — the kit's 12px origin only fits the live 24px box); specimen FABs match the live "?" size (18px, the `#__cos-guide`-scoped rule re-declared page-wide). Live tour: steps now `['scroll'] + ['spot']` BEFORE `['call']`-replaying a demo (the highlight/page used to lag the demo), and the shapes step's rect/pill/circle are 🎯 hover-flash references. Kit: the pointer (hand) cursor is ONE united silhouette path — outline hugs the combined shape, index finger flush with the palm's left edge, thumb more pronounced; hotspot 9.4→7.6 (docs tables updated). Studio Kit → 0.7.10; babel harness ALL PASS (62).
- **Feature guide spec page — rebuilt as a live showcase; kit exposes its spec surface** (`preview/comp-guide.html` · NEW `preview/_guide-demos.js` · `studio-kit/guide/studio-guide.js` 0.7.9 → regenerated `preview/_guide.js` · `docs/components/guide.md` + `.cs.md` · `preview/test-babel-parse.html` PAGES · playground section sub): the guide card now demos the real thing instead of static pictures — a cursor gallery drawn from the engine's OWN SVG shape map (all four kinds enlarged with hotspot crosshairs, hourglass turn-over, a live click-feedback tile), a simulated-interactions stage (arc glide, `data-state` hover/press mirror, halo ripple, per-character typing, wait beat), a highlights stage (feathered veil + ring gliding between a rounded-rect button, a pill chip and a badge-wearing FAB with the engine's live shape verdicts; hover references flash marching-ants while the area ring dims), a FAB row (badge pill, notification aura replay, Notify bump), and the REAL engine registered on the page (manual `showcase-tour` whose steps replay the demos; FAB + panel live, standalone only). `Guide.helpers` now exposes `cursors` / `classifyShape` / `shapeGeom` / `paceFactors` (Studio Kit → 0.7.9) so spec pages + docs render from the engine instead of keeping drifting copies. Tweaks panel restyles the chrome (veil darkness, ring border/glow, halo size, ants period, aura spread/pulses — kit-class override CSS hits demos AND the live overlay); the Inspector drives demo motion (pace, spotlight glide, arc bow, typing cadence, spot padding, shape override, replays, WidthLimiter). Developer reference gains four sections (cursor shapes/hotspots, highlight geometry rules, pace/timing table, `Guide.helpers` table) and TWO live run-fences — a minimal `Guide.init` that boots the real engine inside the docs sandbox, and a helpers-driven cursor/shape-verdict demo. Fixed: the anatomy FAB's unseen-count pill rendered at the page's top-right corner (specimen override forced `position:static`, ejecting the absolutely-positioned badge from its containing block → now `relative`); dark mode previously left specimens on the kit's light literals (the `--studio-*` overlay is `#__cos-guide`-scoped → re-pointed on `.card`). All helper copy tagged (`.help` / `.is-helper`) for both hide-helper-text toggles; babel-parse harness ALL PASS (62).

## [1.8.0] — 2026-07-11

- **Release 1.8.0 — offline bundles refreshed** (`downloads/` ×3 rebuilt from the committed `_standalone-src-*` source copies with the build stamp baked): first refresh since 1.7.0 (Jul 8) — ships the whole post-1.7.0 wave below (the Studio Kit sub-kit + the kit→live single-sourcing, the panel-shell combobox/tooltip/collapsible upgrades + Randomize/pins in both Combined panels, deep-link open params for locale + theme, and the feature-guide hardening arc kit 0.7.1 → 0.7.8: icons, theme-invariant cursor + shape tuning, drift watch, box-model pin, tour-audit tooling + showability contract, auto-reveal opener sub-steps + Back rollback, concentric circle spotlights, mid-action re-hug). ⚠️ Deployments must now include `studio-kit/` — `preview/_tooltip.css` @imports the kit tooltip CSS. Noto Sans JP stays inlined so the offline `ja` locale renders correctly. Release snapshot archived + card-neutralized at `backups/bundles/oos-digital-library-1.8.0/` per DEPLOY.md step 3.

- **Feature guide — mid-action spotlight tracks a moving box** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js`): the ring drawn during a hover/click/tap/type act was a one-shot measurement and the step-level driftWatch is busy-gated while actions run — so the playground „Navigace a hledání" typing step rang a stale box the moment focusing the nav filter grew the field, only correcting when the step card appeared (user report). The action path now runs its own act-scoped re-hug poll (seeded baseline, 90ms, >2px, showability-guarded) until the act ends, mid-action corrections snap on a quick .12s ease instead of the .38s step glide (which chased the moved box for the whole typing window), and the type act re-spots deterministically 60/240ms after `fire()` focuses the field — also covers entrance-transition races and filter-driven reflow. Tour audit: ALL PASS. Studio Kit → 0.7.8.

- **Feature guide — skew-free circle spotlights + reveal click lands before the drawer covers it** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js`): circle spotlights (guide FAB, cluster buttons) are now CONCENTRIC with the element itself — `visualRect` reports the element's own box + the farthest badge protrusion (`own`/`reach`) and `shapeGeom` grows the ring's radius to keep the unseen-count badge inside, instead of re-centring on the lopsided fab∪badge union (dev-ref welcome step 5 rang tight bottom-left / loose top-right — user report; screenshot-measured margins 3/13/10.5/5.5px → now dead-centred with the badge inside). Auto-reveal opener sub-steps fire the actual open a pace-scaled 200ms press-beat AFTER the cursor press starts, so the click ripple is seen ON the hamburger before the off-canvas drawer slides over it („Navigace a hledání" step 2 — the drawer showed before the simulated click; user report). Tour audit: ALL PASS (7 page-widths · 47 tour runs · 187 steps). Studio Kit → 0.7.7.

- **Feature guide — auto-reveal opener sub-steps + Back-navigation state rollback** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · `preview/tours-dev-reference.js` · `preview/_guide-audit.js`): a step/action target hidden inside a registered off-canvas container (`Guide.init({ reveals })` — dev-reference registers `#dg-drawer` × `.dg-fab`) now plays an INLINE sub-step first — spotlight ring + simulated-cursor click on the opener — so narrow-screen users see HOW the side menu opens instead of it flipping open by magic; the open is journaled and closed again on Back / tour end. The engine keeps a per-step change journal: Back runs the departing step's `undo` (now also on run-less steps), then pops the journal in reverse — returning from the dev-ref „Boční nabídka" step no longer leaves the drawer covering the search field (user report). Tour content: the drawer step drops its silent `openDrawer` call; the EN/CS language step reveals via the registry before tapping and restores the language on Back; the dark-mode step restores the theme on Back. Audit `_guide-audit.js` (v2) drives registered reveals exactly like the engine (hidden-in-drawer targets report info, not fail), sanity-checks `reveals` selectors, and gives routed tours' first step cold-render headroom. Quick replays (resume fast-forward / reduced motion / undo) reveal silently instead of burning their timeout and clicking through a closed drawer; `isShowable` also rejects targets whose fixed panel is itself off-viewport (an off-canvas close keeps `visibility:visible` for its 240ms transition-delay beat). Real-engine drive proof: `scratch/reveal-rollback-drive.html`. Studio Kit → 0.7.6.

- **Feature guide — tour audit tooling + engine visibility/reachability contract; every reported tour defect fixed** (`studio-kit/guide/studio-guide.js` → regenerated `preview/_guide.js` · NEW `preview/_guide-audit.js` + `preview/test-tour-audit.html` · `preview/tours-playground.js` · `preview/tours-dev-reference.js` · `ui_kits/cos-library/tours-data-preview.js` · `docs/components/guide.md` + `.cs.md`): the engine now refuses to spotlight targets that exist but aren't SHOWABLE (off-canvas drawers keep a full-size rect while `visibility:hidden` — the dev-reference "thin bar along the left border" highlight), scrolls overflow:auto ANCESTORS before the window pass (drawer-fold targets like the dev-ref language toggle are reached), shields its own Next/Back clicks from app outside-click closers (the playground section menu no longer closes between the open step and the type-to-filter step), maps `display:contents`/hidden-input targets to their visible box, and exposes `?gdaudit` + `Guide.inspect()`/`Guide.helpers` for tooling (Studio Kit → 0.7.5). Content fixes: dev-ref drawer detection is visibility-based + the `live` tour routes by hash (stale hidden `#dg-comp` no longer skips navigation); playground nav-search step ensures the menu is open; data-preview's master-detail step drills into a real related doc first (`seekRelatedDoc` + function target — the Back button is width-collapsed until then) and the „shoda" step types a hidden-field-only query picked from the live dataset. NEW audit harness drives every tour on all four surfaces at widths straddling each responsive breakpoint (`[tour-audit] ALL PASS` verdict; prototype static — driving writes user stores); authoring recipe + gotcha checklist added to the guide's developer reference.

- **Feature guide — spotlight box-model pin** (`studio-kit/guide/studio-guide.css` · regenerated `preview/_guide.css`): the guide chrome's box model silently depended on the HOST page's CSS reset — under the playground/dev-reference shells (no global `border-box` reset) the ring rendered content-box, so its 2px border grew the box down-right of the anchored corner: 4px bigger + 2px off-centre highlights on exactly those surfaces (the prototype/data-preview, whose `ui-kit.css` resets globally, were fine). Kit CSS now pins `box-sizing: border-box` on all `.gd-*` chrome. Verified rendered clearances 4/4/4/4 around the 26px pause button. Studio Kit → 0.7.4.

- **Feature guide — hover-ref flash regression fix + spotlight reflow watch** (`studio-kit/guide/studio-guide.js` · regenerated `preview/_guide.js`): the shape-tuning round's `visualRect` dropped `right`/`bottom` from its rect, which `unionRect` consumes → NaN union → every `[data-gd-ref]` hover highlight silently dead across all surfaces; rect restored. New `driftWatch`: while a tour step is displayed, a 300ms poll re-hugs the ring + tip when the target moves with NO scroll/resize event (playground's lazy section iframes growing, dev-ref docs rendering, font swaps, the scrollbar appearing) — the residual "highlight off-centre / wrong size" on Playground and Dev Reference. Studio Kit → 0.7.3.

- **Feature guide — theme-invariant simulated cursor + spotlight auto-shape tuning** (`studio-kit/guide/studio-guide.{js,css}` · `preview/tours-playground.js` · regenerated twins via `tools/sync-studio-kit-to-live.md`): the simulated-cursor SVGs no longer negate in dark mode — dark ink + white outline (the OS-cursor scheme) reads on any background, so both themes share one cursor (halo .7→1px). Spotlight/flash geometry now maps native inputs to their visible box (`spotBox`: input → `.field` → custom-control `<label>`; the playground „Error variant" chip highlights the chip, not its hidden 13px checkbox), unions small protruding badges (`visualRect` — the guide FAB's unseen-count pill now sits inside the ring instead of cramming its edge), clamps padding on small targets (`padFor`, ≤16% of the short side) with a slimmer ring glow under 40px (`.gd-ring--slim`), and grows a rounded-rect's radius by only part of the pad (`elRad + min(pad,4)` — full concentric growth drew radius-8 toolbar buttons as near-circles). Playground tours dropped stale `shape:'circle'` overrides (`#fp-pause`, `#fp-help`). Studio Kit → 0.7.2.

- **Prototype — deep-link OPEN params for locale + theme** (`ui_kits/cos-library/open-params.js` NEW · `index.html`/`_standalone-src.html` registration · README + `notes/decisions.md`): a shareable link can now open the app in a chosen interface language and colour theme — `?locale=cs|en|ja` (alias `?lang=`) and `?theme=light|dark|auto` (alias `?dark`; `auto|system` follows the OS `prefers-color-scheme` at open time). Loaded FIRST so it seeds the `cos-locale` + `cos-preview-theme` localStorage stores before any reader runs (`i18n.js`, the flash-free boot theme applier in `_inspector.js`, `app.jsx`) → no flash of the wrong state. Precedence mirrors `data-source.js` (URL → localStorage → default); a valid param writes through to its store so every surface agrees (header switch/combo, Tweaks mirrors, Inspector cluster, `<html lang>`); in-app controls still change live and a reload with the param still present re-asserts it. `window.COS_OPEN` reports what was seeded. Offline bundles stale until the next DEPLOY refresh.
- **Prototype + playground — both Combined Tweaks panels gain comp-buttons' Randomize + per-axis pins** (`ui_kits/cos-library/tweaks.jsx` · `preview/playground-tweaks.jsx` · shared pools in `preview/_tweaks-css.js`): a dice pill in Buttons → Presets randomizes every UNPINNED button axis (3D border / Fill / Shadow / Motion / Secondary); a pin toggle beside each of the 5 selects protects that axis from Randomize, persisted per surface (`cos-prototype-pins` / `cos-playground-pins`). The axis pools live once in `FP_TWEAKS_CSS.BTN_AXES`, so a new border/gradient/shadow/motion matrix entry joins both dice automatically; functional controls (Data / Locale / Search / Locale-wipe / Requests) stay outside Randomize by design (randomizing a dataset or locale would trigger a disruptive reload). comp-buttons' own per-component panel untouched. *(Backfilled at the 1.8.0 tag — landed 2026-07-10.)*
- **Studio Kit → live DS de-duplication — 5 of 7 modules single-sourced from the kit** (`preview/_tooltip.css` now a thin `@import` re-export of `studio-kit/tooltip/studio-tooltip.css` · NEW generator `tools/sync-studio-kit-to-live.md` + `tools/ds-wraps/` · regenerated `preview/_tooltip.js` / `_playback.js` / `_force-state.js` / `_guide.js` / `_guide.css` / `tweaks-panel.jsx`): the kit is the single EDIT source; each live twin is GENERATED — a complete, offline-safe file carrying a "GENERATED — do not edit here" banner (never a runtime shim, so the single-file bundles keep working) — via per-file transforms: `banner` (byte-identical body: tooltip JS, panels JSX), `rebrand` (DS-config head + kit engine body VERBATIM + `window.FP_*` alias tail: playback, force-state), `css-append` (kit CSS verbatim + a DS overlay re-pointing the `--studio-*` tokens to gov.cz tokens: guide). The kit guide's identity became config (`rootId:'__cos-guide'`, `chromeAttr:'data-fp-chrome'`, `storePrefix:'cos-guide'`) so every cross-module exclusion (Modal/Sheet inert, force-state, playback) and users' stored onboarding state survive unchanged. DELIBERATELY NOT collapsed (assessed + documented): cluster/inspector (`_inspector.js` is a SUPERSET also owning configurable-content + the inspector protocol; the cluster identity `#__fp-cluster`/`.fpc-*`/aria-labels is a cross-module AND live-tours contract; its CSS is inline-injected for offline safety) and the playground/dev-reference SHELLS (bespoke DS artifacts vs the kit's generic manifest frames) — those stay dogfooded twins. *(Backfilled at the 1.8.0 tag — landed 2026-07-09/10.)*
- **Feature guide — icons restored to bootstrap-icons on every live surface** (`studio-kit/guide/studio-guide.{js,css}` · `tools/ds-wraps/_guide.head.js` + `_guide.css.overlay.css` · regenerated `preview/_guide.js`/`_guide.css` via `tools/sync-studio-kit-to-live.md`): after the Studio-Kit de-duplication the guide drew from the kit's minimal inline-SVG sprite, which under the DS root left tour icons like the playground's compass / hourglass EMPTY and rendered un-sized glyphs GIANT (the „Spustit vše znovu" undo arrow). The kit guide's `gico()` is now overridable via `config.guide.icon`; the live DS supplies a bootstrap-icons renderer (already a DS-wide dependency) to restore the pre-dedup look + full icon set. The bare Studio Kit keeps its self-contained SVG sprite (now root-agnostic). Studio Kit → 0.7.1.
- **Studio Kit — the DS-agnostic chrome engines extracted into a portable sub-kit** (NEW `studio-kit/` — `studio-kit.js` public API `window.StudioKit` (`version`/`config`/`configure()`/`applyTokens()`/`t()`/`ensureTooltip()`) · `tokens/studio-tokens.css` `--studio-*` fallback layer · seven modules: `panels/`+`tooltip/` (0.1.0) · `cluster/` (0.2.0) · `force-state/` (0.3.0) · `playback/` (0.4.0) · `guide/` (0.5.0) · `playground/` (0.6.0) · `dev-reference/` (0.7.0) · `studio.config.js` this-DS config + `studio.config.example.js` "Acme" adopter · own README/CHANGELOG · plan `scratch/studio-kit-plan.md`): everything that makes this project a WORKBENCH (tweaks/inspector panel shell + controls, styled tooltip, floating cluster, force-state, playback governor, guide/tour engine, playground + dev-reference frames) now also exists as a self-contained, de-branded, config-driven kit (`#sk-*` namespaces, `--studio-*` tokens, `StudioKit.t()` strings, inline-SVG icons) that another design system adopts by copying the folder and writing a config — dogfooded by interactive demo cards in the new "Studio Kit" DS-tab group (kit demo with a live Default·OOS·Acme config switcher, controls reference, cluster, force-state, playback, guide, playground, dev-reference). P0 seam in the live DS: `_tooltip.css` reads `--studio-tip-*` first with DS-token fallbacks (zero visual change). *(Backfilled at the 1.8.0 tag — landed 2026-07-09.)*
- **Panels — LOCAL Tweaks-panel controls converted to styled tooltips** (`preview/comp-buttons.html` · `comp-menu.html`): the shell conversion covered the shared controls only — each file's OWN panel controls still showed native `title=` OS tips. comp-buttons' preset pills (DSGCZ/1–6/ČTi/ČT DS) + Randomize dice + pin toggles and comp-menu's Inspector corner-placement presets (↖↗↙↘) now use `data-tip` (+ `aria-label` where glyph-only); zero native `title=` remains on real panel controls (only `<TweaksPanel title>` props / `<iframe title>` names). *(Backfilled at the 1.8.0 tag — landed 2026-07-09.)*
- **Panels — shared shell upgrade: styled combobox dropdowns, styled tooltips, collapsible-section affordance** (`preview/tweaks-panel.jsx` — propagates to the Tweaks panel, both Combined panels and every Inspector): `TweakSelect` is no longer a native `<select>` — a custom combobox with a glass trigger + rotating chevron and a dropdown PORTALED to `<body>` (escapes the panel's `overflow:hidden`+transform clipping), viewport-flip, selected-row checkmark, hover/active highlight and the full keyboard model (↑↓/Home/End/Enter/Esc/Tab + type-ahead). The remaining native `title=` on shell controls (colour chips, preset pills, number-scrubber label, close ✕) moved to the shared `.tip` system via `data-tip` (kept `aria-label`s; the panel self-ensures `_tooltip.js`). Section headers got a hover/press pill affordance; `collapsibleSections` enabled on the two live Inspectors missing it (prototype `CosInspector` + data-preview). *(Backfilled at the 1.8.0 tag — landed 2026-07-08.)*
- **Feature guide — rolled out to the other three surfaces** (`ui_kits/cos-library/tours-data-preview.js` NEW · `preview/tours-playground.js` NEW · `preview/tours-dev-reference.js` NEW · `_guide.css`/`_guide.js` includes added to `ui_kits/cos-library/data-preview.html`, `preview/playground.html`, `preview/dev-reference.html`): each surface now has an auto-welcome + context-aware feature tours (cs/en), reusing the prototype's shared engine. Dataset preview — row anatomy, search + „shoda" match hints, owner/workgroup facets, the metadata dialog, pagination/PinDock/theme/normalization. Playground — the section drawer + Ctrl K, the motion governor, the Combined Tweaks broadcast, error/show-all/width/keyboard-shortcuts. Developer reference — command palette + rail + map, the component contract + EN/CS language toggle, the LIVE run-fence editor, and the reading path + dark mode.
- **Feature guide documented as a component** (`preview/comp-guide.html` NEW · `docs/components/guide.md` + `guide.cs.md` NEW · `preview/_devguide.js` GROUPS · `docs/getting-started.md` + `.cs.md` component map · `preview/playground.html` section): the guide now appears in the playground, in the developer-reference rail / command palette / map (`#ref/guide`), and in the component map — grouped under „Menus & overlays".

## [1.7.0] — 2026-07-08

- **Release 1.7.0 — offline bundles refreshed** (`downloads/` ×3 rebuilt from the committed `_standalone-src-*` source copies with the build stamp baked): first refresh since 1.6.0 (Jul 5) — ships the whole post-1.6.0 wave below (feature-guide / „What's new“ tour wizard incl. the wave-2 feedback round, native scrollbar + pager back-to-top, reader floating pin/dock pager + controlled-distribution grant strip, `data-label` live channel, cover-view complete-rows pagination + reading anchor, status-timeline connector geometry, dense list-toolbar + My-Library toolbar compound, quick-tile grid ladder, header-tab drag disable). Noto Sans JP stays inlined so the offline `ja` locale renders correctly. Release snapshot archived + card-neutralized at `backups/bundles/oos-digital-library-1.7.0/` per DEPLOY.md step 3.

- **Feature guide — wave-2 feedback round** (`preview/_guide.js`/`_guide.css` · `ui_kits/cos-library/tours.js` + NEW `tours2.js`):
  - **Six new prototype tours**: About the app (data, DSGCZ + JVS), live locale switch (CS→EN→JA→back with the wipe), dark-theme toggle, floating tool-cluster overview, and Inspector/Tweaks panel tours **suggested the moment the user opens those panels** (new `Guide.suggest(id)` + a cluster-button watcher; never nudged by route). Reader tour split: public reader vs „Granted document“ (grant strip + watermark + terms, enabled by an approved controlled request).
  - **Engine**: PARTIAL-progress state (exit mid-tour → play-glyph checkbox + „i/n“ in the panel, resume from the recorded step), tour-pace segmented switch (fast/normal/calm — scales cursor, typing, waits and the hole/ring transition), draggable step card, ←/→/Esc keycap hint + per-step `keys` shortcut hints (pagination PgUp/PgDn, reader ←/→), Next-button icon, interactive `data-gd-ref` element references in step text (hover flash / click trigger — search tour wired), page-scroll lock during runs, transition softening (ring dim + veil lighten) with the hole pre-animating toward the predicted post-scroll rect, body word-wrap.
  - **Dark fixes**: literal-blue primary buttons (token remap made hover a pale slab), border-mix separators (the bright `--color-border-subtle` fallback lines in the panel).

- **Feature guide / „What's new“ wizard — engine + prototype tours** (`preview/_guide.css`/`_guide.js` NEW · `ui_kits/cos-library/tours.js` NEW · `index.html`/`_standalone-src.html` registration · plan `scratch/guide-plan.md`):
  - **Shared engine `window.Guide`** — context-aware onboarding layer: „?“ FAB bottom-left with unseen-count badge, per-context nudge card (session-snoozable), feature panel (grouped list, seen checkboxes, replay, reset, guide-locale switch), spotlight veil (SVG-mask hole with feathered edge) + target ring, step card with 1/N counter and ←/→/Esc keys, simulated cursor (WAA glide, press ripple, per-char typing via native setter — drives React AND vanilla fields). Governor-scaled timing (no-op WAA clock + toast whenDone backstop); reduced-motion = instant actions, no cursor; suppressed under `?fp`/`?guide=0`; `data-fp-chrome` root stays operable above open modals.
  - **Guide locale is INDEPENDENT of the app locale** (cs/en/ja chrome + per-step tour strings; prototype initial = app locale, elsewhere cs) — documented exception to the `t()`/strings.js rule.
  - **Prototype content: 10 tours** — welcome (auto-starts first visit), search (typed query + highlighting), filters (availability, pills, collapsed owner/wg + find), views & pagination (incl. floating pager), availability levels, simulated sign-in (drives the real modal), access request (full form → confirm → timeline), my requests, my library, document reader (TOC/zoom/paging/watermark note). Tours revert reversible state on end.
  - Rollout to data preview / playground / dev reference + the compound ceremony (comp page, md twins, playground section) deliberately deferred until the engine settles — catalogs per app in `scratch/guide-plan.md`. Offline bundles stale until next DEPLOY refresh.

- **Prototype — native window scrollbar restored on product pages + pager back-to-top** (`preview/_inspector.js` · `_pindock.js` · `_dark.css` · `ui_kits/cos-library` `index.html`/`data-preview.html`/`_standalone-src-*.html`/`catalog.js`/`ui-kit.css`/`strings.js`):
  - **Back-to-top follow-up (label fit + locale fix)** — `_pagination.js`: new `data-label-overflow="shrink"` (content-aware: degrades the label form in place — range → page → mini — until the control fits one line, restores richer forms when space returns; catalogue pager uses it) + the responsive driver now observes the NAV as well as its host (a flex sibling like the back-to-top control changes the nav's share without touching the host — the stale `pag--stacked` bug) with the width guard keyed on both. `_pindock.js`: `pindock--can-top` now stamps on `opts.canTopEl` (catalogue passes the controller-owned panel — React commits wiped the stamp from `#pager` on locale switch, hiding the button on en/ja) + `ctl.syncTop()` re-stamp hook called from `mountPager`. `_pagination.config.js` + `pagination.md`/`.cs.md` document the new overflow value.
  - **Scrollbar** — `_inspector.js`'s standalone base CSS hid the window scrollbar on EVERY page it decorates; product-style pages now opt out via `data-fp-keep-scrollbar` on `<html>` (prototype + dataset preview + both standalone sources). Component/demo surfaces keep hiding it. `_dark.css` adds `html[data-theme="dark"]{color-scheme:dark}` so the now-visible scrollbar (and native controls) follows the theme.
  - **Back-to-top** — shared contract in `_pindock.js`: the controller stamps `pindock--can-top` on the bar while the page top is out of view; new `ctl.goTop(topInset)` is TWO-STAGE — `scrollToStart` (the page-change landing) while the first row is cut off above, else smooth-scroll to the absolute top (reduced-motion instant; aborts stale settle-watchers). Catalogue opts in: `mountPager` renders a `.pager-top` arrow button after the nav inside `.pager-bar__panel` (mirrors the `.pag` button face; collapses width+margin+border when idle; coarse-pointer 44px overlay; localized `a11y.pager.top` cs/en/ja). Reader/data-preview can opt in the same way later.

- **Shared + prototype — pagination `data-label` is a live channel; reader locale-switch staleness fixed** (`preview/_pagination.js` · `ui_kits/cos-library/reader.js` · new `scratch/pagination-label-live-probe.html`): the reader pager's label („Strana 1 z 12") stayed in the mount locale across header locale switches — the responsive driver cached the raw-template `data-label` into `nav.__labelForm` and `labelForm()` preferred the stale cache over the freshly set attribute, so the reader's `relabel()` re-render was a no-op until remount. Compound fix: a FIXED (non-`auto`) `data-label` is re-read live on every render; the cache now only carries the responsive auto-cascade pick (preset-name consumers — catalogue/data-preview `range` — were already live via `labelPresets`). Swept the other `coslocale:change` consumers for the same „baked once, cache wins" class: one more found and fixed — the reader bar's doc-type chip `data-tip` (baked `TYPE_TOOLTIP`) is now rebuilt on locale change; catalog (full pager+view rebuild), library (full render), React surfaces (locale-keyed re-render) and locale-data.js maps are clean. Probe covers raw-template re-set · preset re-localize · auto cascade re-render · post-relabel `goTo`. Offline bundles stale until the next DEPLOY refresh.

- **Prototype — document reader: floating pin/dock pager + controlled-distribution grant indication** (`ui_kits/cos-library/reader.js` · `pages2.jsx` · `ui-kit.css` · `strings.js` (reader.grant ×3 locales) · `scratch/reader-probe.html`): the reader pager now rides the shared PinDock exactly like the catalogue list — pinned at the viewport bottom while the sheet continues below the fold, docking into its in-flow slot at the end, frozen across page-turn reflows (freeze → render → the scroll-to-sheet-top settles it), inactive in fullscreen (the fs column keeps it in flow). Controlled documents opened via an approved request now say so: ReaderPage resolves the granting request (`readerGrant`, also reused by `readerAccess`) and the reader shows (a) a grant strip under the toolbar — availability chip + "not publicly available — access granted under approved request {id} ({date})" + a link to that request in My Requests — and (b) a diagonal repeated watermark on every page (doc-language "ŘÍZENÁ DISTRIBUCE"/"CONTROLLED DISTRIBUTION" + request code + organisation; em-sized so it scales with the text-size stepper, fg-mix ink so both themes work, unselectable/pointer-inert, painted under the content). The strip is dismissible per reader visit — close button (ghost, localized aria/tip), WAA full-vertical-box collapse honouring reduced motion, in-memory flag only, so it returns on the next reader entry. Strip responsive pass (same day, user screenshots): link + × grouped into one right-aligned `.rd-grant__actions` unit (per-line auto margin — the × can no longer orphan-wrap bottom-left) + a ≤640px ladder where the chip takes the first line, the text a full-width line, and the actions the last line right. Reader probe grown 36 → 50 assertions (pin/dock lifecycle, fs handoff, strip, watermark, public-doc absence, dismiss + reappear-on-remount).

- **Catalogue — cover view paginates in complete rows + reading-anchor position model** (`ui_kits/cos-library/catalog.js`; pre-change checkpoint at `backups/checkpoints/2026-07-05_pre-complete-rows/catalog.js`): the cover wall's page size now snaps to the nearest multiple of the CURRENT column count (target 25 → 24 @ 2/3/4/6 cols · 25 @ 5 — the fixed 25 stranded a lone orphan tile on almost every width, 25 ≡ 1 mod 2/3/4), so every cover page ends on a full row and a partial row only ever means the true last page; table + card list stay at 25. Position model: NEW `state.anchor` (item index) is the source of truth — the page number is derived (`floor(anchor/per)+1`) whenever page geometry changes (view switch; cover column-count resize via window resize + a ResizeObserver on the covers section, debounced + silent repaint with no motion), so table⇄covers flips round-trip exactly and the top document stays on screen. The anchor moves only on real navigation (pager click / hash apply; criteria change → 0); geometry-derived page changes write the hash as REPLACE (one action ≠ a back-stack entry); `persist.anchor` survives detail→Back while it still maps to the hash page. Pager `data-page-size`/label stay truthful per view („Zobrazeno 1–24 z 2 597“). Offline bundles stale until the next DEPLOY refresh.

- **Shared — status timeline: connector geometry fixed for unequal step content + post-play resize** (`preview/_status.css` · `_status.js` · new `scratch/status-geometry-probe.html`): stepper tracks are now `minmax(0, 1fr)` — bare `1fr`'s auto (min-content) floor let the active step's callout widen its track, and BOTH the connector's %-based span (`left:50% → right:calc(-50% + 22px)`) and the JS draw mask (`--conn-lead` = measured centre distance) assume EQUAL tracks, so the done→active segment stopped ~8px short of the active dot at rest and desynced from the sliding dot during the entrance (user report: in-review card in the dataset preview's žádosti view). v2 (same day, user report — segments truncated mid-air after resizing the page): the finished draw animations hold `--conn-lead` in PIXELS (fill:both), and in the live tab they were PHANTOMS — absent from `getAnimations()` while still applying — so the first resize resync cancelled nothing. Teardown now goes through STORED refs (`tl.__stConnAnims`); CONSUMER timelines drop the holds at entrance completion (`go()`, render-identical — the cliff sits +CONN_OVL past the element end) so rest geometry is pure CSS and resize/collapse-proof, while PLAYGROUND (`data-playground`) timelines keep holds for the scrubber, cleaned by `Status.resync(tl)` + a per-timeline ResizeObserver. Probe covers consumer auto-clean · consumer resize with no resync · playground hold+stale+resync · 2-step collapse · replay-at-collapsed-then-widen — all gap=0.00. Offline bundles stale until the next DEPLOY refresh.

- **Shared — dense list-toolbar demotes earlier + combobox dropdowns viewport-flip horizontally** (`preview/_list-toolbar.css` · `_select.js` · `comp-list-toolbar.html` · `docs/components/list-toolbar.md`/`.cs.md` · `select.md`/`.cs.md` · `ui_kits/cos-library/pages2.jsx` + `ui-kit.css` comments): dense ladder re-tuned — ≤1020 ALL segs (incl. availability `.seg--swap`) → icon-only + sort label → icon + no seps; ≤780 chips short **and** icon-only sort trigger (was ≤560) with its dropdown re-anchored to the trigger's LEFT (right-anchored it hung toward/off the container edge). Fixes the search field overlapping the sort controls at mid widths (wide EN labels beat the old 980/760/560 steps). `_select.js placeMenu` now also flips the horizontal anchor globally when an open `.combo-list` would clip a viewport side edge (inline `left`/`right`, layout-metric measured, stretch form skipped) — mirroring the `_menu.js` `data-h` flip.

- **Shared + prototype — My Library toolbar promoted into the list-toolbar compound as its DENSE variant; single-row responsiveness** (`preview/_list-toolbar.css` · `_search.js` · `comp-list-toolbar.html` · `docs/components/list-toolbar.md` + `search.md` (+ `.cs` twins) · `ui_kits/cos-library/pages2.jsx` / `library.js` / `ui-kit.css` / `strings.js` / `region-nav.js`): the library toolbar no longer wraps ad hoc — `.tbar-wrap--dense` holds ONE row from desktop down to ~490px container via an earlier-firing ladder (≤980 view-seg icons + sort icon + no seps · ≤780 chips short · ≤760 availability swap-seg icons · ~660 search → mini · ≤560 icon-only sort trigger), then a deliberate two-row floor: the search un-minis onto a full-width row of its own — NEW `_search.js` **`data-mini-floor`** (mini only while the watched width exceeds it; kept EQUAL to the ≤490 step, no hysteresis on that edge). New shared slots: `.toolbar__chips`/`.chip-toggle` (promoted from `.lib-types`/`.lib-tf`), `.seg--swap` + `.seg__ico` label⇄icon segmented (avail icons follow AVAIL_META: asterisk / unlock-fill / shield-lock), `.tb-select__icon` icon-only sort form. The left cluster carries the flex squeeze (shrink 5 vs 0.05) so the sort value never ellipsizes mid-ladder (probed 320–1100 with shortest + longest sort values, valClip 0 everywhere); the catalogue's ≤880 filter-sheet retune is now scoped to `.results` so its 200px search cap can't break the library's full-width search row; region-nav entry/typeto expands a collapsed mini search via its toggle instead of focusing the hidden input. comp-list-toolbar.html gains the dense demo with its own width slider. Offline bundles stale until the next DEPLOY refresh.

- **Catalogue + dataset preview — paginate/quick-tile landing accounts for the pill rows; PinDock `scrollToStart` hardened** (`ui_kits/cos-library/catalog.js` · `data-preview.html` + `_standalone-src-` twin · `preview/_pindock.js`): hosts widen the `scrollToStart` inset by `pillRowsExtra()` — the query-pill + filter-pill rows' exact contribution, probed by forcing the rows to baseline (`height:0` **and `min-height:0`** — the curtain GROW reservation pins an inline min-height that beats height alone) and diffing the results block's top **in layout space (offsetTop chain) with `overflow-anchor` suppressed** — CSS scroll anchoring synchronously re-adjusts scrollY around a rect-based probe and zeroed it whenever the user was scrolled past the pills (the "corrects on the second click" bug). The shared controller also computes landings from the offset chain (immune to the in-flight curtain transform) and verifies the landing once the scroll settles (≤3 corrections, aborting on any user input). Landings verified live: pagination and quick-tile both land the toolbar ~20px below the viewport top, matching the unfiltered layout across pills / query pill / both / none.

- **Shared + prototype — header nav tabs: native link-drag disabled** (`ui_kits/cos-library/ui-kit.css` + `components.jsx` · `preview/brand-header.html`): same two-part fix as the quick tiles — `-webkit-user-drag: none` on `.nav a` (WebKit/Blink) + `draggable="false"` on the prototype's tab anchors (Firefox), so a press with slight mouse movement registers as a click instead of starting an anchor drag.

## [1.6.0] — 2026-07-05

- **Release 1.6.0 — offline bundles refreshed (R1)** (`downloads/` ×3 rebuilt from the committed `_standalone-src-*` source copies with the build stamp baked): first refresh since 1.5.0 (Jun 15) — ships everything below plus the whole post-1.5.0 wave (locale switch cs·en·ja incl. **Noto Sans JP inlined — offline `ja` fixed**, `locale-data.js`, document reader, search depth + organisational facets + typing perf, `_sheet`/`_page-transition`/`_list-toolbar` compounds, clamp guard, dataset title repair, quick-tile ladder). Release snapshot archived + card-neutralized at `backups/bundles/oos-digital-library-1.6.0/` per DEPLOY.md step 3.
- **Design system — R3: starting-point templates for consuming projects** (NEW `templates/app-shell/` · `templates/catalogue-page/` · `templates/document-detail/`): the compiler previously registered ZERO templates — consuming projects got 59 reference cards but no scaffold to copy. Three `.dc.html` starting points composed from the shared vocabulary, each with a `ds-base.js` loader (ONE `base` line to repoint in a consumer; loads `styles.css` + exactly the controllers the template consumes — `_ds_bundle.js` deliberately NOT loaded: this DS exposes no namespace components and the compiled bundle evaluates the prototype's locale layer, which would rewrite `FP_COMPOUNDS` strings with raw i18n keys outside the prototype) + a small page-layout stylesheet. **App shell** = gov.cz bar + header lockup + nav (shared `_nav-ink` glide, theme switch → `body[data-theme]`, language combo) + footer, container-query ladders mirrored from the brand cards, dark strips pinned to the literal `#0c1838` in both themes. **Catalogue page** = filter-group sidebar with live facet recounts + `_list-toolbar` (animated count · search · sort combo · table⇄cards seg) + `Table.render`/`DocCard.render` through the shared renderers with Collection reveal/refresh/paginate + Pagination; `density`/`stripe` exposed as template props. **Document detail** = breadcrumbs + document header chips + metabox + related rows + public CTA panel.
- **Docs — R2: the locale-rollout renderer hooks are now documented in the md twins** (`docs/components/doc-card.md`/`cover-card.md`/`lib-card.md`/`chips.md`/`related.md`/`table.md` + all `.cs.md` twins): new **Localization hooks** sections covering `FP_COMPOUNDS.docmeta` (`title(d)`/`subtitle(d)`), the per-renderer `strings` params (doc-card meta labels + CTAs + ★ · cover eyebrows/overlay `av`/`state` labels/`coverAria`/CTAs/badge · lib-card CTAs/badge), `chips.editionFormat`/`classDisplay`, `related.relLabel`, and the `FP_COMPOUNDS.table` manifest relabel incl. `strings.titleLang` — each with the merge-never-replace rule and the "compounds never read a locale API; the consumer sets these" contract. doc-card's `opts` line now also documents `highlight`. Closes the md-twin debt flagged in `notes/decisions.md`.
- **Design system — R4: iconography reference card** (NEW `preview/comp-iconography.html`, Basics group — 59 cards): the icon language finally has a card — the blessed Bootstrap Icons 1.11.3 subset grouped by role (document types / availability / validity & status / actions / navigation / feedback, each glyph with its semantic role) plus the usage rules distilled from the pitfalls: icons are text (size/colour via `font-size`/`currentColor`), centre the PARENT never nudge the glyph, the system-wide `.bi` strut reset stays untouched, recolour scoping (the nested-nchip trap), underline never under a glyph, icon-only controls carry `data-tip` + `aria-label`, and never hand-drawn SVG icons.

- **Shared + prototype + dataset preview — search-typing performance with the organisational facets** (`preview/_filter-group.js` · `ui_kits/cos-library/catalog.js` · `data-preview.html` + `_standalone-src-data-preview.html` · `docs/components/filter-group.md`+`.cs.md` · `comp-filter-group.html`): typing feedback had regressed since the owner/working-group facets — every keystroke re-folded the corpus haystack (NFD normalize) once for filtering plus once per facet group, and re-wrote ~150+ animated facet counters even inside collapsed groups. Now (1) the folded haystack is cached per doc (`hayFold`; raw fields ⇒ stable) and the folded query memoized; (2) live facet recounts join the rows+pager in the DEFERRED typing redraw (`cos-search-delay`, Tweaks → Search) instead of running per keystroke — any cancel path flushes a pending recount so counts never go stale; (3) COLLAPSED groups (owner + wg default) skip the count pass + DOM writes entirely and recount lazily on expand via the compound's new bubbling `filtergroup:toggle` CustomEvent (detail.open). Result count, pills and sheet CTA stay per-keystroke live. Offline bundles stale until the next DEPLOY refresh.
- **Shared — doc-card + cover: the displayed workgroup now match-highlights** (`preview/_doc-card.js` · `_cover.js`): with owner/working group searchable, the card's „Skupina: …“ meta item and the catalogue cover's foot workgroup now run through the existing `opts.highlight` → `Chips.mark` path like title/code (user report: „marops“ matched those surfaces but didn't light up there). Lib-cover foot and aria-labels stay plain (established rule). v2 (same day, user report): a partial match put a SPACE inside the word on cover feet („MAR OPS“) — `.cv__foot-l` is flex + `gap: 6px` and the injected `<mark>` split the bare text run into separate flex items; the workgroup now renders inside a single `.cv__foot-wg` span (inline flow — the mark can't split it; geometry verified identical to the pre-change text node). Offline bundles stale until the next DEPLOY refresh.

- **Prototype — catalogue gains the organisational search + facets (owner / working group), ported from the dataset preview** (`ui_kits/cos-library/catalog.js` · `data-source.js` · `strings.js` · `index.html` + `_standalone-src.html`): search now reaches owner + working group (raw AND canonical `wgNorm`) via the single `hayOf()` haystack, and the sidebar gains two count-sorted, collapsed-by-default facets — **Garant / vlastník** (top-7) and **Pracovní skupina** (top-10 + inline find + scroll cap) — wired into filtering, live facet counts, active pills (compact owner labels) and the < 880px filter bottom-sheet. Working-group values are the canonical `normalizeWorkgroup` form: `data-source.js` stamps `d.wgNorm` on BOTH datasets at load (`tools/normalize.js` now loads in the app; metadata surfaces keep the raw register value). A query hit invisible in the result (owner / working group / other-locale title) appends the shared `.match-hint` values-only explainer — in table rows (under the title, as in data-preview) AND on doc cards (`decorateCardHints`; a card's subtitle + raw workgroup meta count as shown); covers stay hint-free (raw workgroup already sits on the tile foot). Fully localized (cs·en·ja: `catalog.filter.owner/.wg/.more/.less/.wgFind/.findEmpty` + pill keys + `a11y.filter.findClear`): the compound bakes its generated scalable chrome at enhance time, so `relabelScalableChrome` re-writes the data attrs AND the generated nodes (state-aware show-all/less button, find placeholder + clear ×, empty text) on `coslocale:change` and once at mount for non-cs locales. Offline bundles stale until the next DEPLOY refresh.

- **Shared + dataset preview — scalable filter groups (collapsible · top-N „Zobrazit vše“ · inline find · scroll cap) + search/facets over owner & working group** (`preview/_filter-group.js`/`.css` · `_chips.css` · `comp-filter-group.html` · `docs/components/filter-group.md`+`.cs.md` · `ui_kits/cos-library/data-preview.html` + `_standalone-src-data-preview.html`): the shared filter-group compound gains opt-in data attrs for many-values facets — `data-collapsible`/`data-collapsed` (chevron title toggle, grid 0fr⇄1fr body collapse, collapsed body `inert`, inner overflow flips visible post-settle so focus rings aren't clipped), `data-top="N"` (truncation + generated „Zobrazit vše (n)“ toggle; checked rows always visible), `data-filterable` (inline diacritic-folded substring find; live query suspends top-N), `data-scroll` (`--fg-scroll-max` list cap) — all chrome generated by the controller; keyboard nav is now visibility-aware (skips hidden rows; find box: Esc clears, ↓ enters the list). The dataset preview consumes it with two new count-sorted facets — **Garant / vlastník** (15 values, top-7, collapsed) and **Pracovní skupina** (~174 values, top-10 + find + scroll, collapsed) — wired into filtering, live facet counts and active pills (compact owner labels), and search now reaches both fields via a single `hayOf()` haystack; a hit invisible in the table row (owner / workgroup / EN title) appends a „shoda — …“ explainer under the title (new shared `.match-hint` in `_chips.css`, value highlighted via `Chips.mark`). v2 (same day, user feedback): a COLLAPSED group stays a ←/→ stop (the jump lands on its title toggle; ↓ drops into an open list); `data-scroll`'s scrollport engages only while the full set shows (show-all / live query / no `data-top`) — the truncated top-N list never scrolls or clips rings (6px ring padding, extra right-side reserve where the scrollbar eats it); long option labels truncate properly (`.fi-txt` min-width:0) and tip their full text via `data-tip-clip`; the match hint no longer widens the Název column (`width:0; min-width:100%` table trick). Plus **owner data normalized** — new `normalizeOwner` in `tools/normalize.js` drops the redundant „VTÚ/“ parent prefix (`VTÚ/VTÚVM Slavičín` → `VTÚVM Slavičín`; applied to the 255 shipped `library-data.js` records; title round-trip untouched). v3 (same day): show-all rows re-aligned with the find box — scrollport padding made symmetric (5px) with `scrollbar-gutter: stable` replacing the asymmetric right "scrollbar reserve" that pushed rows into the panel edge; match-hint copy compressed to the marked VALUES only (no „shoda —“ prefix / field labels, ·-separated). Catalogue (prototype) extension deferred by user decision. Offline bundles stale until the next DEPLOY refresh.

- **Shared + prototype — quick tiles: explicit 4→2→1 grid ladder + native link-drag disabled** (`preview/_quick-tile.css`/`.js` · `comp-quick-tile.html` · `ui_kits/cos-library/ui-kit.css` · `data-preview.html` + `_standalone-src-data-preview.html`): the tile grids drop `repeat(auto-fit, minmax(…))` — which could settle on 3 columns and orphan the 4th tile next to a huge empty cell — for explicit `repeat(4/2/1, minmax(0,1fr))` breakpoints (app 980/600, comp page 860/520), so only 4×1, 2×2 and 1×4 arrangements occur. And since the tile is a full-surface `<a>`, the slightest press-move used to start a native anchor drag (ghost image + cancelled click): the shared component now sets `-webkit-user-drag: none` (CSS, WebKit/Blink) and `QuickTile.init` stamps `draggable="false"` on every tile (Firefox; re-stamped on rebuilds). Offline bundles stale until the next DEPLOY refresh.

- **Shared — dark-mode clamp ellipsis kept the light color** (`preview/_clamp.js`): switching theme repaints text but Chromium styles the `-webkit-line-clamp` "…" fragment at LAYOUT time, so covers' `.cv__title-mini` and the `.cv__title` above the CTA kept the pre-flip ellipsis color on both flips. `_clamp.js` now watches `data-theme` on html/body and re-runs the full clamp guard on every `[data-clamp-guard]` element (innerHTML restore + rewrap — a style-only forced relayout was NOT enough, the stale fragment survived it), regenerating the ellipsis in the current color; a ~450ms second pass covers transition-faded colors. New `Clamp.repaint()` export. Offline bundles stale until the next DEPLOY refresh.

- **Prototype — JA locale: doc-type chips no longer thinner** (`ui_kits/cos-library/ui-kit.css`): the ja typography block force-set `line-height: 1` on ALL chip classes, but `.dc-chip`/`.cchip` carry Latin/mono text only (ČOS, STANAG, UNCL.) with a base line-height of 1.4 — under ja the doc-type chips lost ~4px of height (visible in the filter sidebar + result rows). The ja `line-height: 1` now applies only to CJK-capable chips (`.vchip`/`.achip`/`.chip`, whose base is already 1); `white-space: nowrap` stays on the full chip set. Offline bundles stale until the next DEPLOY refresh.

- **Shared + prototype — locale switch gets a diagonal page wipe (`PageTransition.wipe`)** (`preview/_page-transition.js`/`.css`/`.config.js` · `comp-page-transition.html` · `docs/components/page-transition.md`+`.cs.md` · `ui_kits/cos-library/i18n.js`/`components.jsx`/`tweaks.jsx`): new second lifecycle on the page-transition compound — `wipe(apply, { anchor, shape, feather, duration, easing })` wraps a whole-page DOM update in a **View Transition** and reveals the new state with a sweep radiating from the anchor toward the farthest viewport corner (`:root.pt-vt-wipe` disables the default crossfade; tokens on `:root` — the instance IS the page). v2 (same day, user feedback): slower default (640 ms → 1000 ms, ease → `cubic-bezier(0.4,0,0.2,1)`) and the hard clip-path edge replaced by **feathered mask gradients** reading a registered `@property --pt-wipe-p` length animated via WAA on `::view-transition-new(root)` (governor-scaled) — two shapes: `diagonal` (soft linear front, gradient angle/anchor projection computed in JS as inline `--pt-wipe-x/-y/-angle` vars + `data-pt-wipe` attr) and `circle` (expanding circle from the anchor). v3 (user pick): defaults settled at **circle · 2000 ms · 200 px feather** (`--pt-wipe-shape`/`-dur`/`-feather` + tweaks defaults + md twins), and the prototype's route-change entrance moved to the **deliberate** timing preset (`pt--deliberate` on the app.jsx body wrapper; reader page-turn slips keep their own tuned timing). The prototype routes its interface-language switch through it: `CosLocale.set` defers the lang stamp + `coslocale:change` dispatch into the wipe anchored at the header locale combo (`[data-locale-anchor]` on the trigger; the Tweaks·Data mirror wipes too since the seam is set()); store state stays synchronous; NEW **Tweaks → Locale wipe** section (shape / duration / feather, persisted `cos-wipe-tweaks`, applied as inline `:root` vars). Safety: React re-renders get two macrotask hops before the new capture (late repaints still show — the new snapshot is live); a stall guard `skipTransition()`s when the animation clock stops (frozen offscreen iframes, paused governor) and the update callback still runs, so the swap always lands; reduced motion / no VT API ⇒ instant. comp page gains "Diagonal wipe" + "Circular wipe" demo buttons (cs ⇄ en copy swap); md twins document the API/tokens/event. Offline bundles stale until the next DEPLOY refresh.

- **Shared — clear (×) animation: placeholder slides in + global default now `roll-down`** (`preview/_form-field.js` · `comp-inputs.html` · `_inputs.config.js` · `docs/components/inputs.md`+`.cs.md`): clearing a field now plays a slide-through — the old value ghosts OUT while the emptied input (i.e. its placeholder) animates IN from the opposite side (WAA on the input element itself since native `::placeholder` can't be animated; 280 ms expo-out, 50 ms stagger held by `fill:'backwards'`, restart-safe via `field.__phIn`; reduced-motion/`none` stay instant, governor-scaled). Global default technique changed `fade` → `roll-down` (value slides down + fades out, placeholder slides in from the top + fades in) — `clearTech()` fallback, the comp-inputs Inspector default + demo cells (all demos gained placeholders so the in-motion shows), the inputs-builder knob default and both md twins updated; explicit `data-clear-anim` values keep working unchanged.

- **Shared — cover-title clipping: clamp guard + highlight slack** (NEW `preview/_clamp.js` · `_cover.css` · `_cover.js` · `comp-cover-card.html` · `comp-lib-cover.html` · `ui_kits/cos-library/index.html` + `_standalone-src.html` · cover/lib-cover md twins + getting-started rows): `-webkit-line-clamp` only clips geometrically, so the first hidden line's tall diacritics and `mark.hl` top bleed painted ABOVE its line box — visible slivers under the last visible title line — and the highlight's em bleed was cut at the box's top/left/right edges. Cover titles (`.cv__title-mini`/`.cv__title`) now (a) carry em slack padding inside the overflow clip (+ compensating negative margins) so the highlight ring/fill paints at line starts/ends and on the first line, and (b) are `data-clamp-guard`-marked for the new shared clamp guard (`window.Clamp`): it wraps everything from the first clamped-away character in a `visibility:hidden` `.clamp-cut` span (layout/ellipsis untouched — nothing from hidden lines paints) and stamps `.is-clamp-guarded`, which gates the titles' bottom slack (descenders + mark bottom bleed now show; no-JS pages keep the old tight clip). v2 (same day): the hide is a converging LOOP — the UA clamp ellipsis is layout-real (ejects trailing words to the hidden line), so a one-shot split near the boundary could re-wrap a word's VISIBLE half onto the hidden line (hyphenated "použi|telnosti" sliver); the guard now snaps the boundary to a word start, keeps a leading hidden `<br>` in the span (forces the break — hidden text can't occupy the clamp line's tail) and re-measures/extends until no visible char sits below the clip edge (cap 6 passes; on cap the bottom slack stays closed). Self-wiring: scans on load + `fonts.ready`/`loadingdone`, MutationObserver guards re-rendered results, shared ResizeObserver re-guards on real size changes (cqw cover typography), restore path freezes `hl-sweep` replays. Standard `line-clamp` (which would do this natively) is unsupported in this engine — documented in pitfalls.

- **Shared — match-highlight hairline ring in BOTH themes + left→right sweep-in (prototype)** (`preview/_chips.css` · `_dark.css` · `_field.css`): `mark.hl` now carries the hairline inset ring in LIGHT mode too (`rgba(35,98,162,.34)` — the bare primary-100 tint was hard to see on tinted surfaces, e.g. invalid-document cover faces; the static `.suggest__item mark` demo matches). The fill was restructured from `background` to a gradient `background-image` driven by `--hl-bg`/`--hl-ring` custom props (the dark rescue in `_dark.css` now re-values the props — a `background:` shorthand there would kill the sweep), and the box got an em-relative bleed (asymmetric, user-tuned: `padding: 0.18em 0.12em 0.07em` — most on top for caps/carons, least on the bottom; negative side margins, radius `0.28em` — overlap of surrounding content is accepted and inline vertical padding doesn't move lines), enabling the new `hl-sweep` keyframes: the highlight wipes left→right (380 ms expo-out, `background-size` 0→100 %) while fading in from fully transparent (registered `@property --hl-a` driving a `color-mix()` alpha — unregistered props flip discretely) with the ring fading in over the tail; plays once per DOM insertion, i.e. re-fires on every results redraw. Follow-up fix: `background-color: transparent` on `mark.hl` — narrowing the shorthand to `background-image` had resurfaced the UA's default yellow `<mark>` background (peeked ahead of the sweep; showed through the translucent dark tint permanently). Reduced motion collapses it via the global policy; the playground speed governor scales it. **PROTOTYPE** — to drop, delete the `animation` line + the `@keyframes hl-sweep` + `@property --hl-a` blocks in `_chips.css`.

- **Prototype + shared — reader improvements wave (tooltips on truncation, reader toolbar/zoom/fullscreen, NATO documents, focus, Číst CTA)** (shared `preview/_tooltip.js` · `_pagination.js` · `_cover.js` · `_related.js` · `preview/comp-tooltip.html` · `docs/components/tooltip.md`+`.cs.md`/`pagination.md`+`.cs.md` · `ui_kits/cos-library/reader.js`/`ui-kit.css`/`strings.js`/`catalog.js`/`library.js`/`pages.jsx`/`pages2.jsx`/`app.jsx` · NEW `nso.png`/`nso-dark.png` · probe `scratch/reader-probe.html` now 36 assertions incl. a NATO/EN phase):
  - **`data-tip-clip` (shared tooltip)** — truncation tips: an element so marked tips its FULL text only while actually clipped (ellipsis or line-clamp); stamped on cover titles (`.cv__title`/`.cv__title-mini`), related `.rel-desc` and the reader toolbar title. Untruncated elements never tip; documented in md twins + a comp-tooltip live section.
  - **Reader toolbar** — title cluster now LEFT-aligned next to the nav buttons (stops shifting with the section-readout length); the current-section readout ROLLS up/down on page change (WAA ghost+incoming, restart-safe, reduced-motion plain swap). The % value is a button opening a **text-size slider popover** (80–140, live-applies, Esc/outside closes); new **fullscreen** mode (`.reader--fs` viewport overlay above header/footer, stage scrolls, sheet stretches full-width, Esc exits, body scroll-locked). New `reader.zoomPanel`/`fsOn`/`fsOff` strings × cs·en·ja.
  - **Document language + NATO identity** — the simulated document renders in the DOCUMENT's language (`doc.lang` EN → English section skeleton, "Contents"/"Imprint"/"Title page", imprint labels, page furniture, `lang="en"` sheet); NATO docs (type ≠ ČOS) drop Praha + the Lev/OOS identity — ed line = edition · year, org line = `doc.owner` ("NSO — NATO Standardization Office"), emblem = the NSO logotype (background-keyed flat-color transparent PNGs, `nso-dark.png` swapped in via theme, no CSS filter). The title-page main/sub title pair follows the UI locale via `CosDoc` (same swap as everywhere else) — `relabel()` silently repaints the current page on `coslocale:change`.
  - **Pagination.goTo no longer steals focus** (default hint now `null` — programmatic changes keep focus where it was; pass an explicit hint to restore into the pager). ←/→ paging from the reader content keeps focus ON the content.
  - **„Číst“ CTAs open the reader directly** — catalog cards/covers (`data-act="read"` → new `opts.onRead`) and My-library cards route to `#/cteni/<id>` instead of the detail; detail/download/request unchanged. Offline bundles stale until the next DEPLOY refresh.

- **Prototype — document reader stub (ROADMAP #4 closed)** (NEW `ui_kits/cos-library/reader.js` · `pages2.jsx` ReaderPage/readerAccess + detail „Číst dokument“ wiring · `app.jsx` `#/cteni/<id>` route + skip links + screen label · `ui-kit.css` reader section · `strings.js` `reader.*`/`a11y.*`/`toast.reader*` × cs·en·ja · `tweaks.jsx` chip scope · `index.html`/`_standalone-src.html` registration · self-check `scratch/reader-probe.html`): the find → open → **read** journey gets its final screen. Reader toolbar (contents Menu with per-section jump + `aria-current` · prev/next · doc-type chip + code + locale-aware title + current section · A−/A+ text-size stepper 80–140 % persisted in `cos-reader-zoom` · ★ favourite island re-synced on `cosfav:change`); simulated paged document — front matter (title page with the Lev emblem / impressum / contents) from the REAL metadata, body pages as deterministic seeded placeholder bars (paragraphs / lists / striped figure / table skeletons); shared **Pagination** compound as pager with a consumer `data-label` template („Strana {current} z {total}“ — the promised label-model validation, second consumer outside the catalogue); reading position per doc (`cos-reader-pos`), ←/→ keyboard paging, PageTransition slip page-turns (governor/reduced-motion safe), F6 regions. Access-aware: controlled-without-approved-request, signed-out login docs and metadata-only records bounce to the detail with an explaining toast (hash REPLACE — Back never loops). Document body stays Czech corpus; only chrome localizes. Offline bundles stale until the next DEPLOY refresh.

- **Dataset + pipeline — title-casing repair & normalizer hardening** (`ui_kits/cos-library/library-data.js` · `tools/normalize.js` / `normalize.test.html` / `README.md`): 202 wrongly-cased title fields fixed — 10 ČOS Czech (lowercase „čos“ / „aqap-110/-2110/-2310“ / „(dss)“ / „vme“ / „cl-20“ / „dnan“ / „dadne“ / „fox-7“ / roman ordinals „ii.–vi.“) + 192 NATO English („Stanag 4222“→STANAG, „Nato-led“→NATO-led, „(Gps)“→(GPS), „Vhf/uhf“→VHF/UHF, „Non-epm“→Non-EPM, „Have Quick“→HAVE QUICK, „(at)“→(AT) …) — plus the glued-sentence description of cos-051610 („manažery.Má“). `normalize.js` hardened so a re-parse reproduces the corrected data: acronyms now FORCED uppercase (repairs already-cased text too), ~90 corpus-curated initialisms added to `ACRONYMS_EN`, hyphen/slash compounds cased per segment (single-letter segments uppercase: BDNPA/F) with a `NO_SEGMENT_EN` word-acronym guard („Multi-link“ never becomes „Multi-LINK“), parenthesized-small-word abbreviation rule, `PHRASES_EN` post-pass, CZ keep-set extensions (ČOS, CL, DNAN, DADNE, DSS, FOX, VME) holding through digit tails + slash segments, dot-suffixed roman-ordinal rule (bare „v“/„i“ prepositions untouched), and new `fixJoinedSentences()` for descriptions. `normalize.test.html` gains 18 pinned regression cases — ALL PASS (2,615 checks). Offline bundles in `downloads/` stale until the next DEPLOY refresh.

- **data-preview search parity + shared SearchDefer helper (#11 follow-up)** (shared `preview/_search.js` · `ui_kits/cos-library/catalog.js`/`data-preview.html`/`_standalone-src-data-preview.html` · `docs/components/search.md`+`.cs.md`): the deferred-results-redraw machinery was EXTRACTED from catalog.js into `window.SearchDefer` (`_search.js`): `delay()` reads `cos-search-delay` (default 350 / 0 = immediate), `create(el|fn)` owns the timer + `.res-stale`/`aria-busy` marking; catalog.js now consumes it (behaviour unchanged). data-preview gained the same UX: diacritic-folded matching (`Chips.fold` on both haystack sites — „vyskyt" now matches + highlights „výskyt") and the typing-deferred rows+pager redraw (typing-aware `scheduleApply`, `refreshResults` tail, pagination-change cancel, table dim in the page style; tuned by the SAME Tweaks → Search slider key). Rows now open by `data-id` resolved against the current list (positional `data-idx` could open the wrong document during the stale window).

- **Debt closed — ROADMAP #11 + #12** (NEW shared `preview/_list-toolbar.css` · `preview/comp-list-toolbar.html` · `ui_kits/cos-library/ui-kit.css`/`index.html`/`data-preview.html`/`_standalone-src-data-preview.html` · `styles.css` · `docs/getting-started.md`+`.cs.md` · `docs/components/list-toolbar.md`+`.cs.md`):
  - **#12 List toolbar → shared compound** — the results/library toolbar chrome is now the canonical `_list-toolbar.css`: `.tbar-wrap` container-query host (named `tbar`), `.toolbar` left/right slot clusters, count (wide ⇄ pill), `.toolbar__q` search slot, sort label + combo-truncation deltas, separator, seg/tb-select vertical-rhythm deltas, and the base ≤760/≤560/≤430 demotion ladder — ONE ladder definition. No `_list-toolbar.js` (behaviour stays delegated to `_select.js`/`_segmented.js`/`_search.js`/`_num.js`). comp-list-toolbar.html rebased onto the partial (diverged mirror deleted; `.seg__label` unified to the prototype's `.seg__lbl`; `tb-q` → the shared `.toolbar__q`; toolbar sort dropdowns are now right-anchored everywhere). ui-kit.css keeps only consumer retunes (≤880 filter-sheet ladder + `.lib-tbar`); `styles.css` + prototype `index.html` import the partial; component-map rows + md twins updated.
  - **#11 data-preview re-based on the shared renderers** — the last hand-typed consumer is gone: rows via `Table.renderRows` + a `decorateRows` pass (data-idx/tabindex/role/aria-label), chips/edition pills via `window.Chips` (reads the dataset's `*_META`/`*_TOOLTIP` maps — output identical), library-view code cell via `Chips.codeCell`, related aggregation via `Related.collectRefs(d, findByRef)` + rows via `Related.rowsHTML` (modal click switched `data-relidx` → `data-relid` resolved through `docById`; unresolved refs now non-navigable, skipped by the focus trap). Bonus: catalogue rows get match highlighting free (`{ highlight: state.q }`). Nav-stack / pin-dock / curtain contracts untouched (renderRows stays a DOM-only tbody swap). `_standalone-src-data-preview.html` mirrored — **the offline bundles in `downloads/` are stale until the next DEPLOY refresh.**

- **Search follow-ups — dark-mode highlight, diacritic folding, deferred results redraw** (shared `preview/_chips.js`/`_chips.css`/`_dark.css` · `ui_kits/cos-library/catalog.js`/`library.js`/`ui-kit.css`/`tweaks.jsx`):
  - **Dark highlight rescue** — `mark.hl` (+ the static `.suggest__item mark`) was riding the remapped primary-100 token (0.20 alpha — too faint on dark rows/cards); `_dark.css` now gives it a stronger `rgba(82,142,210,0.42)` tint + hairline inset ring.
  - **Diacritic folding** — new shared `Chips.fold(s)` (NFD + strip combining marks + lowercase); the catalogue `passQ`, the library matcher and `Chips.mark` all fold both sides, so „vyskyt" matches AND highlights „Výskyt" (mark folds per-char with an index map back to the original accented text). Renderer fallbacks unchanged.
  - **Deferred results redraw while typing** — `catalog.js applyFilters(initial, typing)`: live edits in #q/#q2 (activeElement-gated; the filter `change` path passes an Event and stays instant) update the count, facet counts, pills, sheet CTA and hash on every keystroke, but rows + pager redraw only after a quiet period — `localStorage['cos-search-delay']`, new **Tweaks → Search „Results delay" slider** (0–1500 ms, default 350, **0 = redraw immediately** = original behaviour). Empty result sets and leaving the empty panel always render immediately; while deferred `.res-slide` carries `.res-stale` + `aria-busy` (rows dim to 0.55); pending deferrals are cancelled by pagination / view switch / dispose.

- **Search depth — match highlighting + recent queries (ROADMAP #3 closed) · sheet scrollbars hidden** (shared `preview/_chips.js`/`_chips.css`/`_table.js`/`_doc-card.js`/`_cover.js`/`_search.js`/`_field.css`/`_sheet.css` · `ui_kits/cos-library/catalog.js`/`pages.jsx`/`strings.js` · `preview/comp-search.html` · `docs/components/search.md`+`.cs.md`/`table.md`+`.cs.md`):
  - **Match highlighting** — new shared `Chips.mark(text, q)` (escape + wrap case-insensitive full-phrase matches in `<mark class="hl">`; mirrors the catalogue's lowercase-indexOf matching) and an `opts.highlight` on the structure renderers: `Table.render/renderRows` (title + code cells), `DocCard.render` (title, subtitle, code number), `Cover.render` (cover code, mini title, meta title; lib variant + aria-labels stay plain). Styled once in `_chips.css` (`mark.hl`, primary-100 token — flips translucent in dark, `box-decoration-break: clone`). `catalog.js renderView` passes the live `state.q` in all three views.
  - **Recent queries** — shared opt-in layer in `_search.js`: `data-recent="<localStorage key>"` on a `.search` host builds a floating `.suggest--pop` panel (new floating form of the `.suggest` vocabulary in `_field.css`, combo-list open/close motion) listing the last N (default 5) committed queries — committed = Enter or leaving a non-empty field, picked entries re-promote. ARIA combobox model (focus stays in the input, `aria-activedescendant`); ↓/↑/Enter/Esc (stopPropagation — dialog-safe)/Delete + per-item × (visible on hover/highlight, always under coarse pointer). Opens only while the focused input is empty — mirrored/programmatic `input` dispatches never pop it; suppressed in the `.search--mini` state (fixed-overlay anchor). Labels via `data-recent-label`/`data-recent-remove`, re-read per open (locale-agnostic; prototype passes `t()` strings — new keys `catalog.search.recent` + `a11y.search.recentRemove` × cs·en·ja). Prototype hero search uses key `cos-recent-searches`; comp-search.html gained a live seeded demo (+ card subtitle/viewport), md twins document `data-recent*`, `.suggest--pop` and the `highlight` option.
  - **Bottom sheet** — `.sheet__body` no longer shows scrollbars (`scrollbar-width:none` + WebKit rule; `overflow-x:hidden` so transient horizontal overflow from filter motion never flashes a bar) — touch-first surface, scroll behaviour unchanged.

- **Prototype — catalogue toolbar retuned for the filter-sheet trigger + sheet CTA count animated** (`ui-kit.css`, `catalog.js`, `strings.js`, `i18n.js`, `preview/comp-list-toolbar.html`): the ≤880 „Filtry (n)" trigger (ROADMAP #6) added ~100px the demotion ladder never budgeted — the sort combo truncated early and could paint under the view switch. New media-nested container ladder (≤880: icon-mode at once · ≤720 no „Nalezeno" · ≤600 count→pill, no sort label · ≤470 icon-only trigger · ≤400 pill drops), search yields first, `tb-select` overflow guard. Vertical rhythm: `.toolbar .seg` re-centered (the comp-list-toolbar delta had never been mirrored — it sat 2.5px high) and seg/combo heights raised to match the 31px field/btn--sm (comp mirrored). Sheet confirm now reads „Zobrazit N **dokumentů**" (cs·en·ja), with the count in its own span rolling via the shared Animated-number compound and locale-formatted (`tn()` now formats `{n}` via `Intl.NumberFormat` by default; explicit `vars.n` overrides).

- **Prototype — JA locale: monospace runs restored** (`ui_kits/cos-library/ui-kit.css`): the Japanese-typography block used a bare `:lang(ja)` selector — which matches EVERY element (language inherits), not just `<html>` — so its `font-family: var(--font-ja)` tie-beat the earlier-loaded mono rules (`.quick-tile__count`/`__type`, `.dc-chip`, `code`…): stat figures and ČOS/STANAG type chips rendered Czechia Sans under ja. Re-scoped to `:root:lang(ja)` and re-pointed the TOKENS there (`--font-sans`/`--font-display` → `--font-ja`), so every `var(--font-*)` consumer (incl. `font:` shorthand rules) resolves the ja stack on its own while `var(--font-mono)` consumers stay monospaced; the explicit `:is()` re-assert list remains as belt-and-suspenders for literal Latin faces. Verified live in both locales (mono = Roboto Mono under ja; en unchanged).

- **Prototype + design system — locale follow-up: display metadata, cards/covers/table, sign-in providers, EN-preferred titles, JA font cascade, pill-row contract** (`ui_kits/cos-library/locale-data.js` — NEW · `strings.js` · `components.jsx`/`pages.jsx`/`pages2.jsx`/`app.jsx`/`catalog.js`/`library.js` · `ui-kit.css` · `index.html`/`_standalone-src.html` · shared `preview/_chips.js`/`_table.js`/`_table.config.js`/`_doc-card.js`/`_cover.js`/`_lib-card.js`/`_related.js`/`_filter-pills.css`/`_filter-pills.js`): closes the “baked Czech in data files” deferred gap and six user-reported follow-ups.
  - **`locale-data.js` (NEW)** — consumer-owned locale layer registered before the app controllers: on load + every `coslocale:change` it re-labels `AVAIL_META`/`VALIDITY_META`/`REQUEST_STATUS_META` + `TYPE_TOOLTIP`/`CLASS_TOOLTIP`, the `FP_COMPOUNDS.table` manifest (column headers, chip labels, type tips, title `lang` attr) and injects localized `strings` into the shared doc-card / lib-card / cover renderers, plus `FP_COMPOUNDS.docmeta` (locale-aware `title`/`subtitle`), `FP_COMPOUNDS.chips` (`editionFormat` — „1. vyd.“ → “Ed. 1” / 「第1版」, „(návrh)“ → “(draft)”/「（案）」; `classDisplay` — NEOZN. → UNCL. in en/ja) and `FP_COMPOUNDS.related.relLabel` (Souvisí/Zavádí/Přejímá… display-localized, canonical values kept for class mapping). Exposes `window.CosDoc = { title, subtitle, edition }`.
  - **Shared renderers grew optional consumer hooks (Czech defaults — zero change for DS pages)** — `_doc-card.js` (meta labels Jazyk/Aktualizace/Rozsah/Skupina/Vazba + Číst/Požádat CTAs + fav tips), `_cover.js` (eyebrows, availability/state overlay labels, CTAs, „Nové“ badge, cover aria), `_lib-card.js`, `_table.js` (`strings.titleLang`), `_chips.js` (edition/classification display hooks; abbreviation split now requires a dot/space so CJK editions stay one run).
  - **Locale-preferred titles** — cs → `titleCZ || title` with the EN title as subtitle (unchanged); **en/ja → `titleEN || title`** with the original title as the subtitle — applied on the detail header, doc/cover/lib cards, table rows + aria, related rows, request cards (stored `docTitle` snapshot overridden at render via `docId`), library sort and the request-form summary.
  - **Sign-in providers localize** (`auth.provider.*` × cs·en·ja) following the reference gov.cz portal's own EN translations (“Citizen Identity”, “Data box”, “Mobile Key of eGovernment”, “Bank identity”) — labels + notes in the modal, redirect interstitial and account-menu meta; `auth.js` keeps Czech canonical store values.
  - **JA typography** — `--font-ja` is now a **Latin-first cascade** (`Czechia Sans` → `Noto Sans JP` → system JP): digits, codes and Latin chips render identically to cs/en, only CJK glyphs fall through to Noto (standard JP-web pattern). `--font-mono` gets a ja-scoped re-pin with extra widely-available Latin monos — the generic `monospace` resolves through per-language browser prefs under `lang="ja"`. Chips also `white-space: nowrap` under `:lang(ja)` (有効 stacked per-char before).
  - **Filter-pill row contract made locale-agnostic** — spacing (`margin-right`), the `--afp-*` motion tokens and `initFilterPills` wiring were keyed on `aria-label="Aktivní filtry"`, so localizing the aria-label silently dropped pill spacing + motion in en/ja. New marker `data-fp-pills="active|suggested"` (Czech aria-labels still match as legacy fallback); the prototype's `#afp` carries it.
  - **Locale switch now repaints results in place** — `catalog.js relabel()` rebuilds the table shell (headers) + re-renders the active view silently (no Collection motion); avail/validity filter-chip labels rebuild from the re-labelled maps (buildFilters bakes raw text — no `.chip-label` span). Gates: `test-babel-parse.html` ALL PASS (51); comp pages (filter-pills, doc-card, cover-card) verified unchanged. **⚠️ offline bundles stale until the next DEPLOY refresh** (locale-data.js registration + Noto inline both pending there).

- **Prototype — locale switch: Čeština · English · 日本語 (ROADMAP #5-extended, cs · en · ja)** (`ui_kits/cos-library/i18n.js` + `strings.js` — both NEW · `components.jsx`/`app.jsx`/`pages.jsx`/`pages2.jsx`/`catalog.js`/`library.js`/`requests.js`/`controls.jsx`/`tweaks.jsx` · shared `preview/_sheet.js`/`_toast.js`/`_breadcrumbs.js`/`_request-card.js` · `ui-kit.css` · `index.html`/`_standalone-src.html`): the header locale combo (and a mirrored Tweaks·Data control) now switches all interface chrome between three locales — persisted (`cos-locale`, default `cs`) and evented (`coslocale:change`, the `CosFav` store pattern). Document CONTENT (titles, codes, metadata), doc codes, proper nouns, routes and localStorage keys stay Czech/unchanged.
  - **Infrastructure (T1)** — `window.CosLocale` (`.get()`/`.set(l)`, stamps `document.documentElement.lang`), `t(key, vars)` (dotted lookup, `{var}` interpolation, fallback chain `active → cs → key`, warn-once per missing key), `tn(key, n, vars)` (`Intl.PluralRules` — cs one/few/many/other, en one/other, ja other) and `fdate(d)` (`Intl.DateTimeFormat`). `*_html`-suffixed keys are the only innerHTML sink. `strings.js` = `window.COS_STRINGS = { cs, en, ja }` on the T0 key scheme (~357 cs leaf keys across `nav`/`chrome`/`a11y`/`auth`/`toast`/`help`/`catalog`/`detail`/`request`/`requests`/`library`/`compound`). Scripts load before the React app in both `index.html` and the standalone src.
  - **React + vanilla re-render seam (T2 · T3)** — every literal in `components.jsx`/`app.jsx`/`pages*.jsx` and the vanilla controllers (`catalog.js`/`library.js`/`requests.js`) routes through `t()`/`tn()`/`fdate`. App holds a plain `locale` state (**NO keyed remount** — never trips the page-transition / auth-xfade gates); locale joins every memo/innerHTML signature (`detailMetaboxHTML`, `RequestsPage.filteredSig`). Vanilla controllers **relabel silently on `coslocale:change`** — in place or via the non-Collection repaint path, **never through `Collection.reveal`** (no entrance-motion replay); the requests vertical is membership-gated so a switch repaints without replaying the stagger. Islands: `AccountMenu` rebuilds + disposes its prior Menu; `LocaleCombo`/`ThemeSwitch` relabel attrs in place (locale-invariant content).
  - **Shared-compound label params (T3 — backport rule; Czech defaults, zero behaviour change for other consumers)** — `_sheet.js` `gripLabel`, `_toast.js` `closeLabel`, `_breadcrumbs.js` `data-crumb-label` (`{path}` token), `_request-card.js` `labels` object; `_modal.js` `closeLabel` + `_pagination` `strings`/`labelPresets` (pre-existing) now consumed. Compounds stay locale-agnostic — the CONSUMER passes localized labels; comp-page examples + md/.cs.md twins updated for each.
  - **EN + JA translations (T4 · T5, glossary-bound — `scratch/locale-tasks/out/glossary.md`)** — full `en` (UK-neutral gov-service register, sentence case; drops the six cs-only `.few`/`.many` plural sub-forms `tn()` never selects for English) and full `ja` (terse 体言止め labels / polite です・ます messages, 「」 quotes, 、。 punctuation; Latin doc codes + proper nouns verbatim). Every `{var}` placeholder + `*_html` markup verified byte-identical to cs. **10 defence/gov-register ja terms flagged `// TODO native review`** (ships without user review per the 2026-07-02 decision — revisable later).
  - **Japanese typography (T5)** — **Noto Sans JP (400/500/700)** loaded in `index.html` + `_standalone-src.html`, applied under **`:lang(ja)` scope ONLY** (`--font-ja` stack ahead of the system JP fallback); Czechia Sans + every base token untouched for cs/en. Scoped `:lang(ja)` block in `ui-kit.css` re-asserts the font on Latin-family elements (**mono runs / doc codes excluded**), `line-break: strict; word-break: normal`, relaxed heading leading, chips `line-height:1`, buttons + segmented `white-space:nowrap`. **⚠️ The three `downloads/` offline bundles must inline the Noto Sans JP `@font-face` at the next refresh — see DEPLOY.md; they are stale for the `ja` locale until then.**
  - **Tweaks·Data control (T6)** — the combined Tweaks panel's Data section gains a 3-option **Locale** control (`Čeština · English · 日本語`) mirroring the header combo; both drive `CosLocale.set` (store is the single SoT, its event drives both), so they can never diverge.
  - **QA sweep (T7)** — 3 locales × 2 themes × 3 breakpoints × 6 routes: chrome flips with zero console errors and **no entrance-motion replay** (verified at 1× AND 0.1× governor); plurals correct at n=0/1/2/5 in every locale; `documentElement.lang` tracks each switch (**ja resolves Noto Sans JP, cs/en Czechia Sans** by computed-style probe); missing-key fallback shows cs + warns once; reload persistence + fresh-profile default cs + Tweaks-control ↔ combo sync; 5×+ round-trips leak no listeners / no combo duplication; responsive 360/768/1280 in all three locales, both themes. **Fixed inline:** the request form stored *resolved* field-error strings, so a mid-error locale switch left them in the old language — `computeErrors()` now stores the message **key**, resolved at render, so shown errors re-localize on the parent's `coslocale:change` re-render. Gates: `test-babel-parse.html` **ALL PASS (51)**, `test-run-fences.html` **ALL PASS (33)**, `check_design_system` no new items.
  - **Known deferred gap (structural, follow-up item):** baked Czech in data files still renders in en/ja — (a) the compact availability/validity/request-status chips from `window.AVAIL_META`/`VALIDITY_META`/`REQUEST_STATUS_META` (`data.js`/`library-data.js`) on doc-cards, table, library covers and the request-card `.rstat` pill; (b) the sign-in modal provider notes from `PROVIDERS.note` (`auth.js`) — provider *labels* (Identita občana / Datová schránka) are Czech e-gov proper nouns, correctly untranslated. Fix = new `*_META`/`auth.provider.note.*` keys × cs·en·ja + shared-compound label params + comp-page/md twins.

- **Design system + prototype — ROADMAP #6: Bottom-sheet compound; the catalogue filter column gets its small-screen answer** (`preview/_sheet.css` · `_sheet.js` · `_sheet.config.js` · `comp-sheet.html` · `docs/components/sheet.md`/`.cs.md` — all NEW · `styles.css` · playground §50 · `_devguide.js` GROUPS · getting-started map (+`.cs`) · `test-run-fences` · `_standalone-src-dev-reference.html` metas · prototype `index.html`/`_standalone-src.html`/`pages.jsx`/`ui-kit.css`/`catalog.js`):
  - **New `_sheet` compound on the full contract** — `window.Sheet` (`open`/`close`/`init`/`render` — the Modal's API shape): bottom-docked `role="dialog"` panel with **drag handle + head as Pointer-Events drag surfaces** (`touch-action:none`; mid-drag the pointer owns the height via `.is-dragging`), **snap points half/full** (`data-snap` + `--sh-half`/`--sh-full`, release glides to the nearer point; keyboard on the grip: Enter toggles, ↑/↓ pick), **drag-to-dismiss** below 0.55×half, Esc + scrim dismiss, focus trap + `inert` background (dev-chrome exempt, same set as Modal), safe-area footer padding, sticky confirm row outside the scrolling body. Motion = CSS transitions on `--sh-*` tokens (governor-scaled; presets gentle/snappy/deliberate/instant in `FP_COMPOUNDS.sheet`), restart-safe run token, reduced-motion = instant with a **visible resting state** (no-JS/print safe), `.sheet-scrim--inline` showcase variant, declarative `[data-sheet-open]`/`[data-sheet-close]`, events `sheet:open`/`sheet:snap`/`sheet:close`. **Scroll lock is shared with Modal** — the sheet releases the `<html>` overflow lock only when no other modal/sheet scrim remains open. Snippet builder = documented skip (open()-driven behaviour, like page-transition/collection). **58 DS cards.**
  - **Catalogue integration (the ROADMAP scope)** — ≤880px the filter column now leaves the layout entirely (was: a space-hungry wrap-row above results) and a **„Filtry (n)“ trigger** (funnel + active-count badge; label drops ≤430 via the tbar container query) opens the **same `#filters` element MOVED into the sheet** (never cloned — one source of state, wiring travels with the subtree) with a **live-updating sticky confirm „Zobrazit N výsledků“** re-painted on every apply. Closing re-homes the column; growing the viewport past 880 auto-closes; `dispose()` closes + unhooks the media listener.

- **Prototype + design system — ROADMAP #3 (empty-state slice): the zero-results panel repeats the active criteria as removable pills** (`ui_kits/cos-library/catalog.js` · `preview/_empty-state.css` · `comp-empty-state.html` · `_empty-state.config.js` · `docs/components/empty-state.md`/`.cs.md`): the catalogue's 0-results empty state now lists every active criterion — each filter as the shared `.filter-pill.is-active` token plus a „Hledání“ pill for the search phrase — in a new shared **`.empty__pills`** row (centered wrap; start-aligned in `--inline`); one click on a pill's × removes just that criterion (unchecks the source checkbox / clears the query, `stashH0` first so the pill-row curtain measures cleanly) and the results re-render, alongside the existing „Odstranit aktivní filtry“ clear-all CTA. Lead-in copy rule: „Zkuste odebrat některé z aktivních kritérií:“. Showcased on the comp page's bare/catalogue demo (one-click removal, WAA collapse, reduced-motion-safe), added as an **Active criteria** knob to the snippet builder (block/bare forms), documented in the md twins (usage fence now also loads `_filter-pills.css`). #3's remaining scope (match highlighting, recent queries) stays open.

- **Prototype — fixed the catalogue pager pinning at the foot of the page instead of the viewport bottom** (`ui_kits/cos-library/ui-kit.css` → `.auth-xfade`): a regression from the #8 page-transition work. The auth-crossfade wrapper `.auth-xfade.pt` (which wraps the whole routed body, incl. the `#pager-float` PinDock host) ran `animation: authXfade … both`. A `both`-filled animation whose `to` frame sets a transform leaves the element with a **resolved identity matrix** (`matrix(1,0,0,1,0,0)`, not `none`) at rest — a non-`none` transform that *permanently* makes the wrapper the containing block for its `position:fixed` descendants. So the "viewport-fixed" pinned pager resolved against the tall wrapper and floated ~1700px down at the page foot instead of pinning to the viewport bottom (`data-preview.html` has no such wrapper, so it was unaffected). Fix: `fill` changed `both` → **`backwards`** (matching `_page-transition`'s resting-visible contract) — the 380ms entrance still plays, but reverts to the resting style (`opacity:1`, `transform:none`) the instant it finishes; the resting style already equals the `to` frame, so there is no flash.

- **Design system — backup snapshots no longer pollute the entry-page card menu** (`backups/bundles/1.3.0–1.5.0/**` · `DEPLOY.md` step 3 · `notes/decisions.md` → "DS tab cards" · new `tools/neutralize-archived-cards.md`): the DS compiler scans the whole project and ignores `.assetsignore` (deploy-only), so the three kept release snapshots under `backups/bundles/` were each re-registering every page as a duplicate `@dsCard` — inflating the "Pages" / DS menu to **225 cards** (every component appeared 3–4×). Neutralised the line-2 `@dsCard`/`@template` markers across all **168** snapshot pages (token rewritten to a readable `ARCHIVED-SNAPSHOT (was a dsCard)` comment — the snapshot stays intact, only its card registration drops; 1.2.0 predates the convention and had none). Live menu back to **57 cards**. The deployment-archive procedure now neutralises markers as a required step (DEPLOY.md step 3), with a reusable per-version script so future bundles stay clean automatically.

- **Prototype — closed the partial ROADMAP items #10, #7, #8** (`ui_kits/cos-library/app.jsx` · `ui-kit.css` · `index.html` · `_standalone-src.html` + new shared `preview/_page-transition.*`):
  - **#10 Toast — favourite feedback wired** (`app.jsx`). An app-level `cosfav:change` listener now toasts every favourite toggle: **adding** is a plain `success` confirmation that doubles as the *added-to-library* message (`Přidáno do oblíbených · <code> · Moje knihovna` — a favourited public doc joins Moje knihovna), **removing** is an `info` toast carrying a **„Zpět" undo** action that re-adds it. The undo's re-add re-fires `cosfav:change`, so a one-shot `window.__cosFavUndo` flag suppresses the recursive confirmation toast. The single listener covers every call site (library grid + detail panel) — no per-site wiring. The *locale-switched* toast stays deferred until #5 (EN locale). Toast graduating to a compound + submit/status/auth toasts already shipped in 1.5.0, so #10 is now complete.
  - **#8 Cross-page transitions — new shared `_page-transition` compound** (`preview/_page-transition.css` · `_page-transition.js` · `_page-transition.config.js` · `comp-page-transition.html` · `docs/components/page-transition.md`/`.cs.md` — all NEW). `window.PageTransition.enter(el, opts)` replays the system entrance (subtle rise + fade) on a page's content wrapper: WAA-driven (governor-scaled), restart-safe (cancels an in-flight enter), reduced-motion-aware (no-op → resting state visible), with orthogonal **direction** variants (rise / fall / slip-left|right / fade / scale / none) ⊥ **timing** presets (`.pt--snappy|gentle|deliberate|instant` on `--pt-*` tokens). The prototype consumes it in `app.jsx` on hash-route change, **deliberately gated** so it never fights the router seam: skip the first paint, skip an unchanged route key (`?q=` replace), skip on Back / scroll-restore (`window.__cosNavWasPush` false — the return nav already flashes the item and a wrapper transform would offset a floating PinDock pager), and skip the frame the `.auth-xfade` crossfade owns (sign-in / sign-out). Registered in `styles.css`, the playground (Menu §49 → new Page-transition §50, Tools → §51), the `_devguide.js` GROUPS registry (Navigation & filtering), the getting-started component map (+ `.cs` twin), the run-fence harness IDS list, and loaded by the prototype `index.html` + `_standalone-src.html`. The `.config.js` is a deliberate snippet-builder skip (motion behaviour, like collection / region-nav). **57 DS cards.**
  - **#7 Responsive pass — detail / requests / library at 360–768.** Audit found the shared partials already collapse cleanly (metabox → 1-col @640, related → container-query ladder to 340, status timeline → 2-step/mini, library grids fluid) and no horizontal overflow at 390/768. Two real gaps fixed in `ui-kit.css`: (1) the **My Requests filter** `.seg` (inline-flex, never wraps) overflowed on phones — `#req-seg` now spans the row and splits evenly ≤560 (counts drop ≤380), scoped so the shared segmented component is untouched; (2) the **detail CTA panel** stayed `position: sticky` on mobile because `.detail .cta-panel` (sticky) and the `@940 .cta-panel` (static) tied on specificity and source order won — the pin is now a `@media (min-width: 941px)` rule, so the panel sits inline beneath the content on the single-column layout.

## [1.5.0] — 2026-06-15

- **Shared fix — mini search panel overlay vertical position** (`preview/_search.js`): the toolbar's collapsed search (`data-expand="panel"`, `position:fixed`) opened its floating input far below the mini button. A fixed element's containing block is the viewport only if no ancestor establishes one — but `.results`/`.tbar-wrap` (`container: inline-size`) and an auth-crossfade `transform` ancestor both do, so the overlay was offset by the ancestor's top. `positionMiniField` now **probes** the real containing-block origin (pin at `0,0`, read `getBoundingClientRect`, offset from there) instead of assuming viewport coords — correct under any combination of transformed / container-type / contained ancestors, in every engine.

- **Prototype + design system — Request-form follow-ups & checkbox error variant** (`ui_kits/cos-library/pages2.jsx` · `ui-kit.css` · `preview/playground.html` · `preview/comp-checkbox-radio.html` · `preview/_checkbox-radio.config.js` · `docs/components/checkbox-radio.md`/`.cs.md`):
  - **Form-level error notice moved inline-left.** The `.notice.notice--inline.notice--error` now sits at the LEFT of the actions row (same line as the buttons, `margin-right:auto`) instead of stacked above, and **fades out** when the errors clear (kept mounted one beat via `noticeMounted`/`noticeLeaving` state + `reqErrOut`, then unmounted; reduced-motion-safe).
  - **Playground "Error variant" (E) now reflects on checkboxes.** `applyErrorTo` previously only toggled `.field--error`; it now also forces `.checkbox--error` on non-disabled checkboxes (radios excluded on purpose — a single choice can't be "required & empty"), and restores cleanly without clobbering static `--error` demos.
  - **Checkbox error variant documented + showcased.** New "Error — checkbox" column in `comp-checkbox-radio.html` (resting + error·hover + error·focus, with a paired message), an **error/validity knob** in the snippet builder (`_checkbox-radio.config.js`), and the variants table + notes in `checkbox-radio.md`/`.cs.md`. The red error affordance **persists** through hover/pressed (red border + `error-50` tint) and focus (red `--shadow-focus-error` ring + red tint), mirroring `.field--error` — the invalid state stays visible while interacting; red border only while unchecked.

- **Prototype — Request form: shared components, validation states & confirmation modals** (`ui_kits/cos-library/pages2.jsx` · `ui-kit.css` · `index.html` · `preview/_doc-card.css` · `comp-doc-card.html` · `docs/components/doc-card.md`/`.cs.md` · `preview/_checkbox-radio.css` · `_modal.css`):
  - **Migrated off the prototype's own form controls onto the SHARED ones.** Text inputs + the textarea are now the shared `.field` well (`_form-field.css`) and the consent control the shared `.checkbox` (`_checkbox-radio.css`, newly loaded by the prototype) — so they pick up the focus-ring bloom, dark mode and, crucially, the **forced states** (Inspector D/H/P/F/X) the old `.input`/`.checkbox` ignored. The retired `.input`/`.input--error`/`.checkbox`/`.radio` rules dropped from `ui-kit.css`.
  - **Validation + error states.** Each required field validates (non-empty; reason ≥ 20 chars; consent checked) on blur and on submit. Invalid fields show `.field--error` (red border + red leading icon) / `.checkbox--error` (new shared variant) with a red `.field__err` message + icon beneath; a failed send reveals every error at once, **shakes** the invalid fields (the shared `FieldKit.shake` — restart-safe, reduced-motion-aware, governor-scaled) and focuses the first. The form-level message is the SHARED inline notice (`.notice.notice--inline.notice--error`) above the actions. The submit button is no longer silently disabled — clicking it always gives feedback. The reason field's min-length is shown as a live counter pinned to the right of the help row (new shared `.field__foot` + `.field__count` in `_form-field.css`: muted → `--gov-color-success-700` + a check glyph once met) so the help text never reflows as digits change.
  - **Shared promotions:** `FieldKit.shake(el)` (in `_form-field.js`) and the `.field__foot`/`.field__count` counter (in `_form-field.css`) are now reusable; a **Validation** interactive demo (error state + counter + shake + inline notice) was added to `comp-inputs.html` (+ `inputs.md`/`.cs.md`).
  - **Confirmation modals on both actions** (shared Modal compound). **Send** validates first, then opens a confirm dialog summarising the document (the `.dc--plain` identity) + requester; only its confirm submits → existing "Žádost odeslána" toast + navigation. **Cancel** confirms a discard ("Zahodit a odejít", danger) when the form is dirty (leaves straight away when pristine).
  - **Form top rebuilt on the document card.** The summary block is now the SHARED doc-card identity without its shell — a new **`.dc--plain`** variant (added to `_doc-card.css` + documented on `comp-doc-card.html`/`doc-card.md`): availability chip floats and the title flows around / under it, chips collapse at narrow widths (the same responsive behaviour the catalogue card gained), with an optional muted `.dc-owner` line (now part of the shared doc-card identity). Replaces the bespoke `.req-doc` flex block.
  - **Page transition.** The form fades + rises in on mount (heading leads, card follows); resting state visible, collapsed by the system reduced-motion policy.
  - **Shared fix:** `.modal__foot` now `flex-wrap`s and its buttons are `white-space: nowrap`, so two-action footers never wrap a button label mid-word (they stack only when truly cramped).

- **Prototype — Requests vertical & history restore** (`ui_kits/cos-library/app.jsx` · `pages2.jsx` · `catalog.js` · `library-data.js` · `preview/_request-card.js` · `_cta-panel.css` · `_cta-panel.config.js` · `comp-cta-panel.html` · `docs/components/cta-panel.md`/`.cs.md`):
  - **My Requests — surgical single-card refresh.** On a status update (auto-advance or the Tweaks Data controls) only the ONE request whose status/date/note changed is re-rendered + its timeline replayed; sibling cards (and their running timelines) are left untouched. `listHTML` is now memoised on the membership SIGNATURE (set+order of ids), so a pure status change returns the cached string → React leaves the DOM alone and a fingerprint-diff effect calls the new `RequestCard.refresh(root, req)` (single-card replace + `initOne` wire/replay) on just the changed card. A structural change (filter switch / add / remove) still does the full replay.
  - **Documents with multiple requests.** The detail CTA now picks the EFFECTIVE request by precedence (granted ▸ active ▸ declined) instead of first-match. A new **declined** CTA state (`.cta-panel__status--rejected`, red) surfaces when the latest outcome is a rejection with nothing newer in flight: it states the decision + date + reason and that a new request can be submitted immediately („Požádat znovu“ + „Zobrazit žádost“). Added as a 7th scenario to the CTA-panel comp page + snippet builder + variant docs. Seed gains a 2nd (older) rejected request for STANAG 1455 to exercise the multi-request case.
  - **CTA → filtered My Requests.** Following the request link from any detail CTA lands on My Requests **pre-filtered to that request's state group** (in progress / accepted / declined) before scrolling its card into view.
  - **Back restores scroll position** (`app.jsx` owns it centrally now). The outgoing page's scroll is captured under its full hash BEFORE the forward scroll-to-top (which previously clobbered the catalogue's own unmount-time capture — the reason Back used to land at the page top); a rAF-retry restore replays it once the returned route is laid out. Works for every route; `catalog.js`'s private restore removed.
  - **Back also flashes the item you navigated off from.** Returning to a list re-blooms the focus ring on the exact card / cover / table row the user opened, then fades it out — same attention treatment as the My Requests `.req-flash`. `openDoc` records the id per source hash; the app re-asserts a `.cos-flash` class via a MutationObserver across the controllers' re-renders, then releases it to fade. The flash now reuses each view's OWN focus ring verbatim (so the two always match): outset `--shadow-focus` on the `.dc` card and the cover's `.cv__img` (single ring on the cover part only — no more whole-card double ring), and an inset, offset + rounded mirror on table rows. The doc card also gained a real `:focus-visible` ring (its base `box-shadow` had been hiding the global one), and the table-row focus ring was restyled to the offset + rounded inset look.

- **`RELEASES.cs.md` Czech twin + hub inline preview** (`RELEASES.cs.md` NEW · `index.html` · `DEPLOY.md` · `notes/decisions.md`):
  - **`RELEASES.cs.md`** — machine-translation twin of `RELEASES.md` (same `.cs.md` convention as `README.cs.md`; EN authoritative, component/proper names untranslated).
  - **Hub (`index.html`)** — new "Náhled — RELEASES.cs.md" preview section rendered inline ABOVE the existing README.cs.md preview; the single-purpose README fetch refactored into a reusable `loadPreview(id, file)` (missing twin → its section is hidden, mirroring the README fallback). The `RELEASES.md` doc-row description now points at the `RELEASES.cs.md` preview below (mirrors the README row).
  - **`DEPLOY.md`** — release procedure (step 1) now requires updating the `RELEASES.cs.md` twin in the SAME turn as `RELEASES.md`; `RELEASES.cs.md` added to the runtime-required files list.

## [1.4.0] — 2026-06-15

- **Distilled release notes (`RELEASES.md`) + hub & download polish** (`RELEASES.md` NEW · `index.html` · `DEPLOY.md` · `notes/decisions.md`):
  - **`RELEASES.md`** — a plain-language highlights companion to this technical changelog: per version, items are regrouped into a few themed blocks with a 1–2 sentence summary each, with no implementation detail and no `[Unreleased]` section (tagged releases only, newest first). Intended to ship inside the deployment bundle for readers who want the gist without the technical log.
  - **Hub (`index.html`)** — new `RELEASES.md` doc row (`bi-list-stars`, "Přehled vydání") in the Dokumentace section, placed BEFORE the `CHANGELOG.md` row; the `CHANGELOG.md` row's description reworded to mark it as the detailed/technical log (components, files, mechanics). The three "Ke stažení" offline cards now carry an explicit `download="<filename>"` so they reliably save to disk instead of opening in the browser.
  - **`DEPLOY.md`** — the release procedure (step 1) now requires distilling the just-tagged `[Unreleased]` changes into a new top section of `RELEASES.md` per its house style; `RELEASES.md` added to the runtime-required files list. Convention recorded in `notes/decisions.md` → "Versioning + CHANGELOG".

## [1.3.0] — 2026-06-15

- **Menu compound — new shared menu-button + dropdown panel; the account menu is its first consumer** (`preview/_menu.css` · `_menu.js` · `_menu.config.js` NEW · `comp-menu.html` NEW · `menu.md`/`.cs.md` NEW · `_force-state.js` · `_modal.js` · `styles.css` · playground §49 · prototype `components.jsx` · `ui-kit.css` · `app.jsx` · `tweaks.jsx` · `index.html` + `_standalone-src.html`):
  - **New `_menu` compound** — the ACTION sibling of the combobox (`_select`): a trigger carrying arbitrary content on its face (avatar + identity, a "⋯ more" glyph, a labelled button) opening a floating `role="menu"` panel of actions + an optional custom `.menu-panel__head`. ARIA menu-button pattern (DOM focus moves onto items; `↑↓ Home End` + type-ahead + `Esc`; outside-click/`Esc` dismiss; viewport-flip). `Menu.render(spec)` is the structure SoT; `Menu.init`/`el.__menu`; `menu:open`/`close`/`select` events. **Animated open/close** with four motion variants (`data-menu-motion` = slide / zoom / both / fade) on `--mnu-*` tokens + presets — Inspector-tunable + governor-scaled. Self-contained CSS architecture; reduced-motion safe.
  - **Account menu rebuilt on it** (`components.jsx` AccountMenu, now a vanilla island like LocaleCombo) — the chevron now SPRINGS (rotate + scale + stroke, was a hard snap with no transition), the dropdown animates open AND close, and menu items get the system focus-ring **bloom**. The redundant `.acct-trigger`/`.acct-menu*`/`.acct-item*` CSS retired from `ui-kit.css` (only the avatar + identity FACE remains). An Inspector "Menu" control (`tweaks.jsx`) picks the open-motion variant app-wide.
  - **Forced states reach the menu** — `.menu-trigger` / `.menu-item` added to `_force-state.js`'s state-stamp + focus-target lists, so the focus playground / Inspector State button can force their hover / pressed / focus / disabled (previously the account button ignored forced states entirely).
  - **Modal no longer blocks the floating cluster** (`_modal.js`) — the open-modal inert pass now EXEMPTS the standalone chrome (`#__fp-cluster`, `.twk-panel`, `.tip`, `[data-fp-chrome]`, `[data-fp-no-force]`), so the top-right theme / state / Inspector buttons stay operable behind a dialog (they were going dead because the cluster is a body child).
  - **Sign-in / sign-out page crossfade** (`app.jsx` + `ui-kit.css`) — the page body remounts on auth flip (keyed wrapper) and replays a subtle fade + rise, so logging in/out reads as an animated refresh; the header + footer stay put. Reduced-motion safe (resting state visible, entrance gated behind no-preference).
  - **Audit:** the account menu is the only true menu-button in the prototype — the sort + language controls are value-SELECTORS and correctly stay on `_select` (a combobox commits a value; a menu fires actions). No other conversions.
  - **Refinements (Jun 15)** — default is now **slide + fade · deliberate timing** (`:root` + config). Placement resolves on open to `data-v` (down/up) + `data-h` (start/end): **horizontal flip** (swap anchor side when it would clip left/right) joins the vertical above/below flip; transform-origin + slide/zoom direction follow the resolved corner; placement is **preserved through the close animation** (a menu opened above closes upward). **← / →** close + move focus to the previous / next control (Shift+Tab / Tab) and auto-open it if it is a menu button — never activating an item. **Mouse-open Down / Tab** focus the first item (Tab on a focused item still closes + moves on). **Esc** stops propagation + marks the open wrapper `[data-fp-overlay-open]` so it closes only the dropdown inside a host dialog (Playground Preview modal), not the modal. Open panels float at `z-index: 8000` (above page content, below the chrome cluster) so a dropdown never sits under later static content. Menu-item shortcuts render **OS-aware keycaps** (`shortcut: ['Cmd', ',']` / `data-keys` → ⌘/Ctrl via FP_OS, with `+` separators). The showcase well + docs run-fence reserve min size so the motion reads cleanly.
  - **Keycaps + Inspector (Jun 15)** — menu keycaps now use the **shared system keycap look** (the tooltip recipe: `currentColor`-mix fill + 2px bottom border); the chord **`+` separator is global** — bigger (12px) + tight (zero padding, negative margin) across tooltips (`.tip__plus`), the playground cheat sheet / prose (`.fp-keys__plus` / `.fp-kplus`) and menu items (`.menu-item__kplus`). The comp-page Inspector's button is now **Replay (toggle)** (plays open OR close by current state; open deferred past the outside-click `closeAll`), plus a **Position** control that parks the demo trigger in the four corners of the well to exercise the placement flips.
  - Gates: babel-parse PAGES gains comp-menu.html; registered in styles.css, the playground (Tools §49→§50), and the component map (getting-started.md/.cs.md). 56 DS cards.
  - **Reference menu fix (Jun 15)** — added **`menu`** *and* **`modal`** to the `preview/_devguide.js` `GROUPS` registry (the membership/grouping SoT that drives the Developer reference's side-menu rail, Ctrl+K palette and grouped component map — NOT the md table). Both were missing there, so neither showed in the reference menu despite being in the md table + playground. Menu → "Menus & overlays" (new registry group), Modal → "Status & feedback", mirroring `@dsCard`/`data-fp-group`. Added an "Adding a new component" surfaces checklist to CLAUDE.md and a meta-block-regeneration substep to DEPLOY.md so this can't recur.

- **Field polish — animated clear, more fade demos, a configurable inputs builder, and an overlay opacity fix** (`preview/_form-field.js` · `_form-field.css` · `_field.css` · `_inputs.config.js` NEW · `_select.config.js` · `_inspector-controls.jsx` · `comp-inputs.html` · `inputs.md`/`.cs.md` · test harnesses):
  - **Animated clear** — the clear (×) button now ghosts the current text OUT (fade / slide-left / slide-right / roll-up / roll-down, per `data-clear-anim` on the `.field`, or `<body>` for a page default) before emptying, and the × reveals with the reverse motion when content first appears. WAA (governor-scaled), reduced-motion = instant, restart-safe + backstopped; `FieldKit.clear()` stays instant. `.field` gained `position: relative` (ghost anchor). Exposed `FieldKit.clearTech / animateClearOut / animateClearReveal`.
  - **Floating-overlay opacity fix** — the expanded mini/auto **search** overlay went see-through on hover in dark mode (the hover tint `--gov-color-primary-50` is `rgba …/0.12`), so page content behind it (the toolbar count) bled through. The overlay now keeps an opaque `--field-bg` base and composites the hover/error tint as a `background-image`, so it always reads as a solid surface. (Repro: List-toolbar comp page, expanded search + hover.)
  - **comp-inputs** — Edge-fade section gained a long-placeholder demo and a caret-at-end demo (pre-scrolled → the left edge fades after the icon); a new "Clear button — animated" section demos every technique; and a React **Inspector panel** (`hostProtocol={false}`, opened from the floating cluster's Inspector button / key `I`) with the Clear-animation select driving `body[data-clear-anim]`, plus the width limiter + playback.
  - **Width-limit floors lowered to 50px** — both the universal `WidthLimiter` (`_inspector-controls.jsx` default `min`) AND the run-fence / Preview-modal width slider (`_devdocs.js`, was 280px) now go down to 50px.
  - **Configurable inputs builder** (`_inputs.config.js`) — the `inputs.md` Usage is now a `builder="inputs"` run fence: icon / clear button / clear-animation / content / state knobs (17 variations). The **select** builder gained a `.tb-select--fit` (Width: fixed-ellipsis vs fit-to-value) toggle on the inline form.
  - Gates: babel-parse ALL PASS (48), run-fences ALL PASS (31), builder-configs ALL PASS (26 incl. inputs). comp-inputs added to the babel-parse PAGES list; `_inputs.config.js` added to the builder-config harness.

- **Generic field re-base — edge fade + optional clear are now `.field` capabilities; search builds on them** (`preview/_form-field.css` · `_form-field.js` NEW · `_field.css` · `_search.js` · `_select.css` · `_select.js` · `comp-inputs.html` · `comp-search.html` · `comp-list-toolbar.html` · `comp-modal.html` · `_modal.js` · prototype `index.html` + `data-preview.html` + standalone srcs · `inputs.md`/`.cs.md` · `search.md`/`.cs.md` · `select.md`/`.cs.md` · `getting-started.md`):
  - **FieldKit** (`preview/_form-field.js`, NEW — `window.FieldKit` + `initFields`) owns the behaviours the search field used to: the **edge fade** (`.fade-l`/`.fade-r`/`.fade-soft`, animated `@property` mask), the **clear (×) button** (opt-in two ways — author `<button class="clear">` OR set `data-clearable` on the `.field` and it's injected; `data-clear-label` for the label), the **responsive placeholder** (`data-ph`) and the **`data-empty` sync** — for **every** `.field` with an `<input>`, not just search. Edge fade is ON BY DEFAULT for single-line inputs; the clear coexists with a leading icon.
  - **`_form-field.css`** gains the generic clear button + the fade mask (both unlayered, moved out of `_field.css`), plus a `--field-gap` variable so the empty-clear collapse cancels the real gap (6px base; search sets 8px).
  - **`_field.css` / `_search.js` re-based** — the search field is now a thin layer over the generic `.field`: `_field.css` keeps only the search layout + mini/auto/suggest (the clear + fade blocks now point at `_form-field.css`); `_search.js` consumes FieldKit and adds only the mini/auto compounds + the mini `data-filled`/tooltip signalling. **Load order: `_form-field.css`/`.js` BEFORE `_field.css`/`_search.js`** (added to every search consumer + the modal compound, which now wires dialog-body fields via `initFields`).
  - **Combobox value fade** (`_select.css` + `_select.js`) — a too-long selected label now fades at the right edge (`.is-fade` on `.value`, re-checked on init/commit/resize) instead of an ellipsis, matching the input/search fade. `.tb-select--fit` (width-to-content) never clips, so it never fades.
  - **comp-inputs** showcases the new fade + both clear opt-ins; `data-preview` + prototype search inline controllers slimmed to delegate the `.field` chrome to FieldKit. Gates: babel-parse ALL PASS (45), run-fences ALL PASS (30).

- **Animation governor — toast motion now honours the speed pills** (`preview/playground.html` · `_playback.js` · `_toast.js`):
  - **Governors recurse into nested same-origin iframes** — the playground toolbar governor and standalone `_playback.js` only scaled their own document's `getAnimations()`, so animations inside the run-fence sandboxes / devdocs embeds (nested iframes) ran at 1× regardless of the speed pills (the usage-fence reveal never scaled). Both now collect recursively via `collectAnims(doc,out)` (+ `resetRates` recurses); cross-origin frames skipped.
  - **Toast exit is governor-scaled** (`_toast.js`) — the WAA exit was sequenced/removed by unscaled `setTimeout` backstops that ripped the element out mid-animation at slow speed (close/dismiss "snapped"). New `whenDone(a,cb)` drives sequencing off `onfinish` (fires at the scaled time) with a poll backstop that force-completes only when the animation is finished or its clock has stalled (offscreen frozen clock) — never because it's slow/paused.
- **Modal/Toast polish — styled fields + runner-sandbox overlay sizing** (`preview/_form-field.css` NEW · `comp-modal.html` · `comp-toast.html` · `comp-inputs.html` · `comp-textarea.html` · `_devdocs.js` · `modal.md`/`.cs.md` · `toast.md`/`.cs.md` · `inputs.md`/`.cs.md` · `textarea.md`/`.cs.md` · `search.md`/`.cs.md` · `getting-started.md`/`.cs.md` · `styles.css`):
  - **Shared `_form-field.css`** — the generic `.field` well (plain text inputs **and** textarea, via `:has(textarea)` for the multiline metrics) is now a single shared component, extracted from comp-inputs / comp-textarea (which now link it) and imported into `styles.css`. Reverses the old per-surface-copy decision: the **Modal compound** hosts these fields in its dialog bodies, so comp-modal.html loads it — the modal's inputs/textarea were previously unstyled (loaded only the SEARCH `_field.css`).
  - **comp-toast.html** — now links `_buttons.css`; the toast trigger buttons (Success/With undo/Error/Warning/Queue burst) were rendering unstyled. The `toast.md` live Usage fence gained `_buttons.css` too (the "Toast" button was unstyled in the runner); `modal.md`'s fence gained `_form-field.css`.
  - **Runner sandbox — fixed-overlay sizing** (`_devdocs.js` `MEASURE_JS`) — a `position:fixed` full-bleed overlay (the Modal scrim, the Toast layer) spans the iframe viewport, so measuring its own box fed the iframe height straight back → the live modal grew partial-then-forever and the toast had no room. Such overlays are now measured via `natOv()` = the NATURAL content height (dialog head+body+foot scrollHeights, or stacked toasts) + the layer's bottom inset + breathing room — decoupled from the iframe height, so the stage grows once to fit and settles (verified stable across measure ticks; settles back to base on close/dismiss). A MutationObserver also reports synchronously the instant an overlay node is inserted/removed (microtask, before the entrance paints), so the stage is sized **before** the toast/dialog is shown — no jump as the bottom-anchored toast would otherwise shift while the iframe grows. Tooltip/menu popups are unchanged.
- **Prototype — mock auth + live request lifecycle (ROADMAP wave 1, items 1+2)** + two new shared compounds. End-to-end the find → request → track → approved loop now works on real session + request state:
  - **Modal compound** (`preview/_modal.css` · `_modal.js` · `_modal.config.js` · `comp-modal.html` · `modal.md`/`.cs.md` · playground §37) — the system's first dialog compound on the full contract: `Modal.open(opts)` (scrim, focus trap, Esc/scrim dismiss, scroll-lock + `inert` rest-of-page, restored focus, stacking), `--mo-*` motion tokens (gentle/snappy/deliberate/instant presets), `Modal.render` structure SoT, sizes sm–xl, inline (`.modal-scrim--inline`) variant for showcases. Reduced-motion / no-JS show the dialog (resting state = visible). Registered in styles.css + the playground (sections 37→48 renumbered +1, modal slots in as 37).
  - **Toast manager** (`preview/_toast.js` + `_toast.css` additions + `toast.md`/`.cs.md` upgraded to deep) — promotes the toast from a styled surface to a real compound: `window.Toast` (`push`/`success`/`error`/`warning`/`info`/`dismiss`/`clear`/`render`), single fixed `.toast-layer`, queue (max 3 + promotion), ~4.6 s auto-dismiss **paused on hover + while focus is inside**, inline `.act` action button (undo), `aria-live`, WAA enter/exit (governor-scaled; reduced-motion = instant). `toast:show`/`toast:dismiss` events.
  - **Auth** (`ui_kits/cos-library/auth.js` · `window.CosAuth`) — localStorage session store (`cos-session`, `cossession:change`), CosFav pattern. Prototype now **starts SIGNED OUT**; an original brand-consistent sign-in modal (NOT a copy of the státní gateway) on the shared Modal: 4-provider picker (Identita občana · datová schránka · mobilní klíč eGovernment · bankovní identita) → "redirecting…" interstitial → signed-in return. Header gains an **account menu** (initials avatar + Moje knihovna / Moje žádosti / Odhlásit); signed-out shows a "Přihlásit se" CTA. Request form, My Requests + My Library are gated (sign-in modal / signed-out empty states).
  - **Live request lifecycle** (`ui_kits/cos-library/requests.js` · `window.CosReq`) — submitting the request form creates a REAL entry (`cos-requests`, `cosreq:change`); requests page shows live entries (newest) then the dataset seed. Status **auto-advances** submitted → in-review → approved on a timer (toggle in Tweaks → Data) **plus** a manual Advance / Approve / Reject control on the latest request. An approved request unlocks the document — it appears in **Moje knihovna** as `granted` (live entries merged in `library.js`); in-flight requests show as `pending`. Toasts confirm submit + every status change.
  - **Touches** — `app.jsx` (session + merged requests + gate + status-change toasts; dropped the inline React `<Toast>`/`toast` state), `components.jsx` (AccountMenu + `openSignIn` vanilla flow; removed the dead React `Toast` that would have clobbered `window.Toast`), `pages2.jsx` (form prefilled from session + passes form data; signed-out empty states), `tweaks.jsx` (Data-section lifecycle controls), `ui-kit.css` (`.acct*` + `.signin-*` chrome), prototype `index.html` (loads auth.js/requests.js + the modal/toast scripts + `_modal.css`).

- **Search — small-space variants + responsive collapse compound** (`_field.css` · `_search.js` · `_search.config.js` · `comp-search.html` · `search.md`/`.cs.md`). A family of tight-space behaviours on the shared search:
  - **`.search--sm` reclaim + responsive placeholder** — an empty field now collapses the clear-button slot to `width:0` and cancels the flex gap (was a wasted reserved slot), re-expanding on the first keystroke; `data-ph="long|medium|short"` lets JS measure and pick the longest placeholder that fits, re-fitting on resize/font-load (e.g. "Hledat v katalogu" → "Hledat", since CSS can't swap placeholder text).
  - **Edge fade** — clipped value OR placeholder text fades at the cut edge via a transitioned `@property` mask (`.fade-l`/`.fade-r`, wider `.fade-soft` 44px for the placeholder case where no clear button reserves room); grows/shrinks in and out instead of snapping; purely cosmetic (doesn't touch caret/hit-testing); auto-managed, no markup.
  - **`.search--mini`** — a square, field-bordered icon button that expands into a field overlay **out of flow** (toolbar never reflows); click to expand (focus+select), collapses on blur, Esc closes; non-empty + collapsed signals state with an accent icon + corner `×` clear badge; `--mini--left` expands leftward; `data-expand="panel"` pins the expanded field to a stable left edge, viewport-clamped so it never slides off and a long query just scrolls within the field; registered in `_force-state.js` (toggle + badge get `[data-state]`/`.is-focus`/`:disabled` mirrors so the Inspector State control drives them); styled `_tooltip.js` tips on the empty toggle / filled toggle / both clear affordances (overridable via `data-tip-empty|-filled|-clear`); disabled mini dims, shows no tooltip, and doesn't react to hover.
  - **`.search--auto`** — a JS-driven responsive compound that morphs one element from a hero field (icon **+ label** submit button) → icon-only button → no button → the interactive mini icon, stepping on a watched container's content-box width.
  - **Prototype + spec adoption** — the catalogue toolbar search collapses to the mini icon only when low on space (≤540, watching `.tbar-wrap`), two-way synced with the hero search; responsive `data-ph` placeholders added to the catalogue toolbar, My Library and the dataset-preview searches; `comp-list-toolbar.html` mirrors it (width slider demos the collapse). Toolbar cascade hardened so the sort combo can no longer overlap the field (right cluster `0 1 auto` + `min-width:0`, long sort value ellipsizes; view-switch → icon-only and separator dropped ≤760). Quick-tile click now scrolls to the top of the table via PinDock when out of view.
  - **Tooling** — `.rz` resizable demo wells promoted to a shared `_help.css` helper (`max-width:100%`, min 50px, corner grip), reusable on any spec page; builder gained `mini` + `auto` (Responsive) knobs (builder-config gate green, 12 variations).
  - ⚠️ The three `downloads/` offline bundles are now **stale** (mini + the data-preview placeholders + toolbar cascade) — refresh them next time we bundle.
- **Deployment — UTF-8 charset fix (server-side)** — the live Worker was serving HTML without `charset=utf-8` on the `Content-Type` header; an HTTP charset overrides the in-document `<meta charset>`, so valid UTF-8 bytes were read as Windows-1250/1252 (mojibake `Č→ÄŒ`, `ů→Å¯`, `—→â€"`, and the Roboto Mono arrow glyphs). The source files were never wrong. Added `wrangler.toml` (Cloudflare Workers Static Assets — no custom serving code, so `text/html; charset=utf-8` is emitted automatically) + `.assetsignore`, a "⚠️ Charset" section in `DEPLOY.md`, and a `notes/decisions.md` entry. Redeploy with `npx wrangler deploy`; do NOT re-encode source files.

## [1.2.0] — 2026-06-13

- **Developer reference — metabox builder gains the table's structural knobs + run-bar animation triggers** — the metabox **Edit & run** fence now offers the **same controls as the catalogue table**: **Density** (compact / comfort / roomy) and **Row styling** (zebra / lines / bare) alongside the Collection-motion effect knobs. These ride new `.metabox--compact/--comfort/--roomy` + `.metabox--zebra/--lines/--bare` pin classes added to `_metabox.css` (unlayered, mirroring `FP_TWEAKS_CSS.METABOX_DENSITY` + the table stripe tiers, so a local pin == the matching global Tweaks tier). The metabox builder's `target` widened to the whole fence body so a class-only edit re-emits the host markup.
- **Developer reference — Appear / Refresh trigger buttons in the run bar** — any builder whose config declares `builder.animations` (currently table + metabox) now renders **Appear** and **Refresh** buttons right after **Run** — the run-fence analogue of the Inspector's “Replay” — firing `Collection.reveal` / `Collection.refresh` on the demo host inside the live preview (no full re-run). The shared `FP_COL_MOTION` slice now exports `anims(host)`; the runner (`_devdocs.js`) mounts the group via `api.mountAnims`. The redundant **Demo phase** knob was dropped (the two buttons replace it); the generated snippet keeps both `setEffect` calls + a comment pointing at the buttons.
- **Playground — section menu keyboard upgrades** — the grouped section menu (the `Ctrl + Shift + P` command palette) now also opens with **`Ctrl + K`** (matching the Developer-reference palette), and **`PgUp` / `PgDn` jump between groups** inside the open menu (Typography → Colors → …) instead of scrolling the page behind the popover. Cheat sheet + trigger/pill tooltips updated.

- **Hub Dokumentace cards — meaning-based icons + reference title** — `index.html`'s `Dokumentace` rows gained left icon chips (primary-50/primary-600, matching the `Ke stažení` download chips) whose glyph expresses *what the file is*, not its filetype: reference `journal-code`, README `info-circle`, CHANGELOG `clock-history`, DEPLOY `cloud-upload`, SKILL `magic`, CLAUDE `robot`, architecture `diagram-3`, decisions `journal-check`, pitfalls `exclamation-triangle`. The `dev-reference.html` row's title is restored to the human label **"Referenční příručka"** (it opens an app, not a Markdown file) while the rest keep their filename as the title. Rows are now `display:flex` (icon + `.docrow__tx` text column).
- **Hub card availability guard** — `index.html` now HEAD-checks every linked card before showing it: the three intro doors, all `Dokumentace` rows, the `Ke stažení` offline downloads and the `Nástroje pro vývojáře` test harnesses. A card whose target returns 404/410 removes itself; a section whose cards all vanish is hidden along with its heading + hint (the prose `O projektu` is untouched); the README preview section hides if `README.cs.md` is absent. This keeps the deployment hub honest in **bundle zips** that deliberately omit top-level Markdown / dev-only files (Cloudflare Pages). Surviving cards cascade in with a staggered fade (`.js-guard` set pre-paint = no flash; the revealed resting state is a STATIC `opacity:1`, so a throttled tab / reduced-motion still ends visible; a 6 s failsafe pins visibility). Network/other errors keep the card — only a definitive "not found" prunes it.
- **Version stamp on every surface + `version.js` SoT** — new root `version.js` is the single source of truth for the displayed version string. Live files read `Unreleased · <date>` (we always serve the latest sources); it fills the hub footer (`[data-oos-version]`) and drops a small bottom-left badge on the playground, developer reference, prototype and dataset preview. The three `downloads/` offline bundles now bake a **build timestamp** into the inlined copy (`builtAt`) so they read `… · sestaveno <ts>` — rebuilt from their `_standalone-src-*.html` sources. `DEPLOY.md` procedure reworked: **bump `version.js` (`number`+`date`) FIRST**, then refresh the bundles with `builtAt` temporarily set (restore to `null` after).
- **Hub dark mode** — `index.html` now supports dark mode via the SAME floating top-right cluster (`preview/_inspector.js`, shared `cos-preview-theme`) used across every standalone surface; `_dark.css` linked, code-block slab pinned dark in both themes, the Markdown-viewer modal marked `data-fp-chrome` so no stray State button appears.

## [1.1.0] — 2026-06-13

- **Developer reference / live runner v3** — usage fences with inline render calls (table, chips, doc-card, …) now actually render: the sandbox defers inline `<script>`s to DOMContentLoaded so they run AFTER the `run=` controller assets (was: `Table.render` threw on an undefined global → empty preview). Tooltips/dropdown menus opened inside an example grow the preview stage instead of being clipped (`__ddNeed` helper — measures visible positioned boxes only; v3.1 fixed a feedback ratchet that grew the stage on any interaction, and a light-mode canvas seam below short content; v3.2: popup growth snaps instead of animating + resets the rescue scroll, so the content stays pinned to the top edge instead of panning out of view). The width-limit slider draws a dashed guide line at the limit position. The live-source editor is drag-resizable (the configurator strip dictates the minimum; Reset restores auto-sizing). Body-level Developer-reference strips (comp-table & co.) align to the card insets (`body > .devdocs`). dev-reference.html navigation shows a top loader bar (>120ms hops only; gradient grow → sprint → accelerate-out exit with left fade). New gate: `preview/test-run-fences.html` executes all 29 run fences and asserts they paint without errors.
- **Select / combobox — viewport-aware dropdown placement** — an open list that would clip at the viewport bottom now flips above the trigger (`data-up`) when it fits there, else the controller nudges the nearest scrollable ancestor to reveal it (deferred ~100ms so hosts that grow their iframe — playground autosize, docs-runner stage — get first chance; scroll clamps back on close). One mechanism for every consumer of `_select.js`: comp pages, list toolbar, prototype, the playground Preview modal. **Root-cause fix alongside it:** `_card.css` body is no longer a clipping scroll container (`html{overflow:auto}` + `body{overflow:visible}`) — a content-sized body with `overflow:auto` was cutting popups at its own box (≈88px) regardless of iframe height (the Preview-modal clipping). **Playground grid frames now share the same generic popup-growth contract** — the hardcoded `.combo-list[data-open]` selector + attribute MutationObserver replaced by the runner-style positioned-box scan (interaction-driven, instant growth, content pinned to top, settles on close; works for any popup incl. tooltips). Documented in `select.md` + `.cs.md`.
- **Developer reference — snippet builders on (almost) every component** — 24 components/compounds now carry a `builder="<id>"` configurator on their Usage fence (was: pagination only). 19 new pure-data `_<id>.config.js` docs manifests (buttons, chips, notices, toast, empty-state, cta-panel, checkbox-radio, switch, segmented, breadcrumbs, search, select, tooltip, filter-group, doc-card, cover-card, lib-card, lib-cover, request-card) + `builder` blocks added to the status / table / num / quick-tile compound configs. `_devdocs.js`: builder knobs may come from `builder.knobs` (overrides Inspector `knobs`), and spec pages lazy-inject a missing `_<id>.config.js` (same as the guide's ensureConfigs). New gate: `preview/test-builder-configs.html` validates every builder (knob shape, generate across all variations, target re-match, target-vs-md-fence). Standalone dev-reference source gained the 19 config metas. Deliberate skips: filter-pills, related, metabox, region-nav, links/inputs/textarea/list-toolbar, collection.
- **Status docs fix** — `Status.render` `opts.detail` middle value documented as `labels` (was wrongly `compact`) in `status.md` + `.cs.md`.
- **Versioning introduced** — this changelog, the version string convention, and the hub footer version stamp.
- **Czech README** — `README.cs.md` (machine translation, EN stays authoritative); the hub's inline preview now renders the Czech version.
- **Developer reference — Czech by default from the hub** — `preview/dev-reference.html` accepts `?lang=cs|en` (per-load override of the stored language choice); the hub's new "Dokumentace" link uses it.
- **Developer reference — offline single-file export** — `downloads/Digitální knihovna ČOS - reference (offline).html` (new `_standalone-src-dev-reference.html` source copy; `DevDocs.extRes` resource hook resolves runtime-fetched markdown/runner assets inside bundles; sibling-page links demoted to text offline).
- **Translation rules** — `.cs.md` files are machine-translated twins of the English originals (EN authoritative, CS auto-updated with every EN edit, component names never translated); `docs/getting-started.cs.md` component-map names corrected to English.

## [1.0.0] — 2026-06-12

Baseline version — first state covered by versioning. Comprises the full design system to date:

- Tokens + base styles (`colors_and_type.css`, dark theme, reduced-motion policy), Czechia Sans, Bootstrap Icons.
- ~35 shared components/compounds (`preview/_*.css` / `_*.js`) with config manifests, motion contracts and the playground (47 sections + Tools).
- Developer reference (`preview/dev-reference.html`) rendered from `docs/getting-started.md` + `docs/components/*.md` (with `.cs.md` Czech set).
- Interactive prototype (`ui_kits/cos-library/index.html`) and dataset preview (`data-preview.html`, 2 597 documents).
- Offline single-file exports of the prototype and dataset preview in `downloads/`.
- Deployment hub (`index.html`) + `DEPLOY.md`.
