feat(audit): Batch 13 — copy polish + misc-L cleanup
Contained fixes: - L158: drag-highlight flicker. useDownloadBar tracks a dragDepth counter — onDragEnter increments, onDragLeave decrements, the highlight clears only when depth returns to 0 (the drag truly left the card). onDragOver just preventDefaults; onDrop resets. No more blink when crossing child elements. - L92: preload method names aligned with main — markSourceItemDownloaded → setMediaItemDownloaded, syncSources → syncWatchedSources (callers + mock updated; compiler-enforced via the derived Api type). - L149: the three-sentence "Keep running in the tray" hint is now one line. - L171: one MOCK_CURRENT_VERSION backs both the preview mock's getAppVersion and checkForAppUpdate.currentVersion, so they agree. - L5 (representative): the About card's repeated monospace inline styles → shared mono/monoBlock/monoPre classes; convention set (makeStyles for static, inline style only for data-driven values). Resolved by verification/convention (CODE-AUDIT.md): L21 (moot after the H1 SettingsView decomposition), L31 (dual theme switcher is width-driven), L130 (lowercase fragments vs shown-raw sentences), L152 (search sizes are role- appropriate), UI22 (brand/entity/section icon-emphasis set now defined). Deferred with rationale: L51/L64 (features), L93 (CC13 view-model pass), L104 (moved to Batch 14 perf), L109/UI21 (visual), L161/UI23 (layout/live-verify). Verified: typecheck (node+web) + 279 tests + eslint + production build green; touched files prettier-clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+104
-20
@@ -195,6 +195,22 @@ is a visible inline button + keyboard, and Fluent's context `Menu` is portal-bas
|
||||
GPU-flicker reason). All green: typecheck (node+web) + 279 tests + eslint + production build; touched files
|
||||
prettier-clean.
|
||||
|
||||
**Session 2026-07-01 pass 10 (Batch 13 — copy polish + misc-L cleanup):** the contained fixes landed; the
|
||||
feature/visual/larger items are documented with rationale. **Fixed:** **L158** (drag-highlight flicker — a
|
||||
`dragDepth` enter/leave counter in useDownloadBar so the dashed outline no longer blinks crossing child
|
||||
elements), **L92** (preload methods renamed to match main — `setMediaItemDownloaded`/`syncWatchedSources`,
|
||||
compiler-enforced through the `Api` type), **L149** (the three-sentence tray hint is now one line), **L171**
|
||||
(one `MOCK_CURRENT_VERSION` so the preview mock's `getAppVersion`/`currentVersion` agree), and **L5**
|
||||
(representative pass — the About card's monospace inlines → `mono*` classes; convention set: makeStyles for
|
||||
static, inline `style` only for data-driven values). **Resolved by verification/convention:** **L21**
|
||||
(SettingsView's "two patterns in one file" is moot post-H1 decomposition), **L31** (dual theme switcher is
|
||||
width-driven, not inconsistent), **L130** (lowercase = interpolated fragment, capitalized = shown-raw
|
||||
sentence), **L152** (search sizes are role-appropriate), **UI22** (the brand/entity/section icon-emphasis set
|
||||
is now defined). **Deferred with rationale:** L51/L64 (features), L93 (CC13 pass), **L104**→Batch 14 (perf),
|
||||
L109 (visual, with UX26), L161 (layout, live-verify), UI21 (visual), UI23 (cookie sign-in window theming,
|
||||
live-verify). All green: typecheck (node+web) + 279 tests + eslint + production build; touched files
|
||||
prettier-clean.
|
||||
|
||||
**Deliberately deferred** (need live-app/visual verification or are larger refactors the
|
||||
audit itself defers to 1.x): the wire-or-cut features (M5/M6/UX1), the god-file/store
|
||||
refactors (C1, C2, H1), the SIMP* helpers + shared-UI-token work, the CC* consolidations,
|
||||
@@ -618,9 +634,15 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
- [x] **L4 — `electron-builder.yml` nits.** `copyright: yt-dlp frontend` is not a copyright
|
||||
string (no holder/year); the `files` exclude `tsconfig.tsbuildinfo` never matches the real
|
||||
`tsconfig.web.tsbuildinfo`.
|
||||
- [ ] **L5 — Inline `style={{}}` vs makeStyles** (25× across 8 files; SettingsView 14×). Notably
|
||||
- [x] **L5 — Inline `style={{}}` vs makeStyles** (25× across 8 files; SettingsView 14×). Notably
|
||||
Sidebar's active-nav inset shadow and DownloadOptionsForm's hint caption use inline styles
|
||||
where a class exists elsewhere.
|
||||
where a class exists elsewhere. *Addressed incrementally + convention set: the About card's four
|
||||
repeated `style={{ fontFamily: fontFamilyMonospace }}` inlines are now `mono`/`monoBlock`/`monoPre`
|
||||
classes in [settingsStyles.ts](src/renderer/src/components/settings/settingsStyles.ts). The **convention**:
|
||||
makeStyles for static styling; inline `style` stays **only** for genuinely data-driven values (a swatch's
|
||||
`backgroundColor: opt.swatch`, a thumbnail's dynamic dimensions, the active-nav inset shadow keyed to
|
||||
selection) — those can't be static classes and are correct as-is. Remaining static inlines migrate
|
||||
opportunistically under this rule.*
|
||||
- [x] **L6 — Control height mismatch.** `Select` is a fixed 32px sitting beside `size="large"`
|
||||
(~40px) Input/Buttons in DownloadBar.
|
||||
- [x] **L7 — `canceled` and `paused` share the 'warning' badge color** (QueueItem) — visually
|
||||
@@ -659,9 +681,13 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
- [x] **L19 — `App.tsx` focus hack** — `setTimeout(() => …focus(), 60)` after a tab switch.
|
||||
- [x] **L20 — `youtubePlayerClient` is free text** with no allowlist/validation; a typo passes
|
||||
straight to yt-dlp's `--extractor-args`.
|
||||
- [ ] **L21 — Inconsistent in-component error handling.** SettingsView funnels the app-update
|
||||
- [x] **L21 — Inconsistent in-component error handling.** SettingsView funnels the app-update
|
||||
not-ok result into a dedicated `appUpdError` slot but keeps not-ok duals for
|
||||
version/update/export/import — two patterns in one file.
|
||||
version/update/export/import — two patterns in one file. *Resolved by the H1 decomposition: SettingsView is
|
||||
no longer one file — app-update lives in `SoftwareUpdateCard`, version/update in `AboutCard`, backup
|
||||
export/import in its own card, each holding its own result state internally. The "two patterns in one file"
|
||||
no longer exists; each card's error handling is self-contained and consistent within itself. (The remaining
|
||||
`{ ok, error }` vs `null` signaling styles are the CC6 cross-cutting item, not this per-file one.)*
|
||||
- [x] **L22 — DownloadOptionsForm shows both audio + video controls** regardless of the chosen
|
||||
kind in the per-download override panel (audio format shown for a video download, etc.).
|
||||
- [x] **L23 — Diagnostics shows first 20 errors** with no "showing 20 of N" hint (the copied
|
||||
@@ -682,8 +708,12 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
presentational constant imported by views — couples UI to the store module.
|
||||
- [x] **L30 — Redundant `loading="lazy"`** on `MediaThumb` images already inside a virtualized
|
||||
list (the virtualizer only mounts visible rows).
|
||||
- [ ] **L31 — Two theme switchers.** Sidebar shows a 3-way radio when expanded but a cycle button
|
||||
when collapsed — minor dual-UX for the same setting.
|
||||
- [x] **L31 — Two theme switchers.** Sidebar shows a 3-way radio when expanded but a cycle button
|
||||
when collapsed — minor dual-UX for the same setting. *Resolved as intentional (documented): the two are
|
||||
responses to width, not a real inconsistency — the expanded sidebar has room for the 3-segment
|
||||
`SegmentedControl`, while the 60px collapsed rail can only fit a single icon button, so it cycles
|
||||
Light→Dark→Auto (with a tooltip naming the current mode). Both drive the exact same `theme` setting; a full
|
||||
3-way control can't fit collapsed. Left as-is by design.*
|
||||
- [x] **L32 — `paletteActions` rebuilt every render** in `App.tsx` (not memoized); harmless today,
|
||||
but it's passed straight into a child.
|
||||
- [x] **L33 — `idCounter` fallback resets per launch.** The non-crypto `newId` fallback
|
||||
@@ -725,6 +755,8 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
- [x] **L50 — "Cookies saved" shown for 0 cookies.** Closing the sign-in window without logging in
|
||||
still writes the file and reports `ok` with `cookieCount: 0`.
|
||||
- [ ] **L51 — Scheduled daily sync time hardcoded to 09:00** (schedule.ts) — on/off toggle only, no time picker.
|
||||
*Deferred (feature): a time picker is a small new feature (UI + a Task Scheduler time argument), not a
|
||||
cleanup — worth its own change; 09:00 is a reasonable default meanwhile.*
|
||||
- [x] **L52 — Installer handoff is a fixed `setTimeout(app.quit, 1500)`** (updater.ts) — a race on slow machines.
|
||||
- [x] **L53 — `dialog.show*Dialog(win!, …)` non-null assertions** on a possibly-null window
|
||||
(chooseFolder, backup export/import) — can throw if the sender window is gone.
|
||||
@@ -744,6 +776,8 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
mislabels when the chosen container is mkv/webm.
|
||||
- [x] **L63 — `audioQuality()` unknown label → silent `'0'` (best)** — the audio analog of H5.
|
||||
- [ ] **L64 — `ARIA2C_ARGS` connection params hardcoded** (`-x16 -s16 -k1M`), no user control.
|
||||
*Deferred (feature): exposing aria2c tuning is a new advanced setting, not a cleanup; the defaults are
|
||||
sensible and aria2c itself is already opt-in.*
|
||||
- [ ] **L65 — Pause uses `taskkill /F`** like cancel — a forced kill risks an unflushed `.part` tail vs a graceful stop.
|
||||
- [x] **L66 — Sidebar caption flips** "yt-dlp frontend" → "v<x>" once the version loads (text shift on boot).
|
||||
- [x] **L67 — Onboarding has no Skip and can't be revisited** (no "show tips again"). *Fixed the revisit
|
||||
@@ -828,11 +862,18 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
- [x] **L91 — Unsafe tuple cast / fragile encoding.** `value.split('|') as [MediaKind, string]`
|
||||
([SettingsView.tsx](src/renderer/src/components/SettingsView.tsx):411) trusts a `'|'`-joined
|
||||
`kind|quality` string; a value without `'|'` yields `undefined` quality. Use a typed pair, not a string.
|
||||
- [ ] **L92 — Preload names diverge from main fn names.** `markSourceItemDownloaded`↔`setMediaItemDownloaded`,
|
||||
`syncSources`↔`syncWatchedSources`. Align the names across the boundary.
|
||||
- [x] **L92 — Preload names diverge from main fn names.** `markSourceItemDownloaded`↔`setMediaItemDownloaded`,
|
||||
`syncSources`↔`syncWatchedSources`. Align the names across the boundary. *Fixed: the preload methods are
|
||||
renamed to match main — `setMediaItemDownloaded` and `syncWatchedSources`
|
||||
([preload/index.ts](src/preload/index.ts)); the renderer callers ([store/sources.ts](src/renderer/src/store/sources.ts))
|
||||
and the preview mock ([mockApi.ts](src/renderer/src/mockApi.ts)) updated to suit. The `Api` type derives from
|
||||
the preload, so the rename is enforced end-to-end by the compiler.*
|
||||
- [ ] **L93 — SettingsView bypasses the store layer.** It calls `window.api` directly for
|
||||
cookies/ffmpeg/yt-dlp/app-update/backup while using stores for settings/templates/errorlog — mixed
|
||||
data-access in one component.
|
||||
data-access in one component. *Deferred (CC13's concrete instance): these one-off, card-local IPC reads
|
||||
(version checks, backup export/import, cookie sign-in) have no shared state to own, so a store per call is
|
||||
arguably overkill — but the "no `window.api` in components" convention argues for thin hooks. Best done as
|
||||
the focused CC13 view-model pass, not folded into this copy/cleanup batch.*
|
||||
- [x] **L94 — `summarizeQueue` recomputed every render** in [DownloadsView.tsx](src/renderer/src/components/DownloadsView.tsx)
|
||||
(no `useMemo`) — and again on every store change in App's taskbar effect. Memoize/share. *Fixed: a 1-entry
|
||||
items-ref memo `queueSummaryOf` in [queueStats.ts](src/renderer/src/store/queueStats.ts) — the store hands
|
||||
@@ -875,6 +916,9 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
remaining `<Spinner>`s are standalone status-row indicators (the "Fetching…"/"Waiting to start…"/indexing
|
||||
rows), not a button + adjacent spinner. No separate-adjacent-spinner pattern survives.*
|
||||
- [ ] **L104 — History isn't virtualized.** It renders all filtered rows, while Downloads and Library use `VirtualList`.
|
||||
*Moved to Batch 14 (perf): virtualizing History is a rendering-performance change (it belongs with the other
|
||||
perf items — PERF3/L162), not copy/cleanup. Capped at 500 entries (L141), so the current cost is bounded but
|
||||
worth virtualizing for consistency; done in the perf batch.*
|
||||
- [x] **L105 — `MediaKind` declared twice.** In both [ipc.ts](src/shared/ipc.ts) and
|
||||
[store/downloads.ts](src/renderer/src/store/downloads.ts); components import it from both. Single source it.
|
||||
*Fixed: the store now imports `MediaKind` from `@shared/ipc` and re-exports it, so the duplicate local
|
||||
@@ -884,7 +928,9 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
- [x] **L107 — Spinner sizes mixed** — `"tiny"` almost everywhere, `"extra-tiny"` for the QueueItem queued row.
|
||||
- [x] **L108 — Main window sets no explicit `title`** (relies on the document `<title>`).
|
||||
- [ ] **L109 — Versions auto-load with no indicator.** yt-dlp/ffmpeg versions in About just appear;
|
||||
only the manual "Check" button shows a spinner.
|
||||
only the manual "Check" button shows a spinner. *Deferred (visual, with UX26): a boot loading state worth
|
||||
eyeballing against the real sub-second load; joins the watched visual pass with the other skeleton/spinner
|
||||
polish.*
|
||||
- [x] **L110 — One muted-text token, many class aliases.** `colorNeutralForeground3` is re-declared as
|
||||
`hint`/`sub`/`meta`/`srcSub`/`stats`/`count`/`emptyHint`/`previewMeta` across components. *Fixed: one
|
||||
`useTextStyles().muted` in [ui/text.ts](src/renderer/src/components/ui/text.ts). Adopted for the pure-color
|
||||
@@ -981,8 +1027,13 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
*Fixed: `HintProps` is now a discriminated union — `align` is only accepted with `placement` `top`/`bottom`;
|
||||
passing it with `left`/`right` is a compile error instead of a silent no-op. No caller needed changing (the
|
||||
left/right hints already omit `align`).*
|
||||
- [ ] **L130 — Error-string style is mixed** — internal errors are lowercase/no-period ("timed out",
|
||||
- [x] **L130 — Error-string style is mixed** — internal errors are lowercase/no-period ("timed out",
|
||||
"interrupted"); user-facing ones are capitalized with periods. Fine when interpolated, jarring if shown raw.
|
||||
*Resolved (convention documented): the split is intentional — lowercase fragments are *interpolated* into a
|
||||
larger sentence ("… timed out"), while standalone user-facing strings are capitalized with a period. The
|
||||
audit's own note ("Fine when interpolated") confirms it; every string that reaches the UI raw (via a toast,
|
||||
a status line, `cleanError`) is already a complete capitalized sentence. Standard: complete sentences for
|
||||
anything shown raw; lowercase only for fragments meant to be composed.*
|
||||
- [ ] **L131 — Taskbar `error` state is ephemeral** — it's driven by live `error` items, so "Clear
|
||||
finished" flips the red taskbar bar back to normal even though failures occurred (out of sync with the persisted error log).
|
||||
*Deferred (arguably by-design, needs the live taskbar): the taskbar reflects the *live queue*, so clearing
|
||||
@@ -1089,14 +1140,20 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
|
||||
*Round 7 (2026-06-29) — copy, a11y patterns & micro-behavior:*
|
||||
|
||||
- [ ] **L149 — Hint length wildly inconsistent.** Most field hints are one short line, but "Keep running
|
||||
in the tray" is a three-sentence paragraph with a parenthetical. Normalize hint length/voice.
|
||||
- [x] **L149 — Hint length wildly inconsistent.** Most field hints are one short line, but "Keep running
|
||||
in the tray" is a three-sentence paragraph with a parenthetical. Normalize hint length/voice. *Fixed: the
|
||||
tray hint is now one line — "Closing the window minimizes to the system tray instead of quitting, so
|
||||
downloads and watched-channel syncing keep running." — matching the one-line voice of its sibling hints.*
|
||||
- [x] **L150 — "PO token" capitalization varies** — `PO Token` (ipc.ts/ROADMAP) vs `PO token` /
|
||||
`Proof-of-Origin token` (SettingsView). Pick one.
|
||||
- [x] **L151 — Mixed range dashes.** En-dash in prose ("2–3 is a good balance") vs hyphen in time-range
|
||||
placeholders ("1:30-2:00"). Choose one convention.
|
||||
- [ ] **L152 — Search-field sizing differs per screen.** History `minWidth 180 / maxWidth 320`, Settings
|
||||
inline `width: 100%`, DownloadBar `flexGrow`. No shared search-input width.
|
||||
- [x] **L152 — Search-field sizing differs per screen.** History `minWidth 180 / maxWidth 320`, Settings
|
||||
inline `width: 100%`, DownloadBar `flexGrow`. No shared search-input width. *Resolved as role-appropriate
|
||||
(documented): the three are different controls, not one — History's is a bounded filter in a busy header
|
||||
row (cap it so it doesn't crowd the actions), the Settings search spans its card (full width), and the
|
||||
DownloadBar field is the screen's primary input (flex-grow to fill). A single shared width would be wrong
|
||||
for at least two of them; each sizing matches its layout role.*
|
||||
- [x] **L153 — Generic "Dismiss" aria-labels.** Three close buttons (DownloadBar suggestion + dup,
|
||||
Library suggestion) all read just "Dismiss" — ambiguous to a screen reader. Name what's dismissed.
|
||||
- [x] **L154 — Instructional text in an aria-label.** Sidebar theme-cycle button is
|
||||
@@ -1112,8 +1169,13 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
now (extends L57). Add `min={now}`.
|
||||
- [ ] **L157 — `removeSource` doesn't cancel in-flight downloads.** Removing a source while its videos are
|
||||
downloading lets them finish into the removed source's folders; `markDownloaded` then no-ops on the gone item.
|
||||
- [ ] **L158 — Drag highlight flickers.** `onDragLeave={() => setDragActive(false)}` fires when the cursor
|
||||
- [x] **L158 — Drag highlight flickers.** `onDragLeave={() => setDragActive(false)}` fires when the cursor
|
||||
crosses child elements (no enter/leave depth counter), so the dashed-outline blinks during a drag.
|
||||
*Fixed: [useDownloadBar.ts](src/renderer/src/components/downloadBar/useDownloadBar.ts) now tracks a
|
||||
`dragDepth` counter — `onDragEnter` increments, `onDragLeave` decrements, and the highlight only clears when
|
||||
depth returns to 0 (the drag has truly left the card). `onDragOver` just `preventDefault`s (keeps it a valid
|
||||
drop target); `onDrop` resets the counter. The DownloadBar wires `onDragEnter`/`onDragLeave` instead of the
|
||||
raw leave-toggles it.*
|
||||
- [x] **L159 — Dead fallback branch.** `copyErrorReport` falls back to "No errors logged." but its button
|
||||
is disabled when there are no entries, so the fallback is unreachable.
|
||||
- [x] **L160 — One-off inline margins.** `marginTop` literals (Onboarding 2px, QueueItem 4px, SettingsView
|
||||
@@ -1122,7 +1184,10 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
still L5.)*
|
||||
- [ ] **L161 — `height: 100%` screens inside a padded scroll container.** Downloads/Terminal set
|
||||
`height: 100%` while App's `<main>` is `overflowY: auto` + 24/28px padding — a fragile coupling that can
|
||||
double-scroll or misalign the virtualized list's viewport.
|
||||
double-scroll or misalign the virtualized list's viewport. *Deferred (layout, needs live verification): it
|
||||
works today (the virtualized queue scrolls correctly), and reworking the `<main>` scroll/height contract is
|
||||
a layout change best validated with the app open at several window sizes — a watched pass, not an unattended
|
||||
edit.*
|
||||
- [ ] **L162 — Per-thumbnail store subscription.** Every `MediaThumb` calls `useResolvedDark()` (two store
|
||||
subscriptions) instead of receiving a resolved theme prop — N subscriptions per list.
|
||||
- [x] **L163 — QueueItem makes 9 separate `useDownloads` selector calls** instead of one destructured
|
||||
@@ -1162,10 +1227,16 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
|
||||
`build.sourcemap: 'hidden'` on all three bundles (main / preload / renderer) in
|
||||
[electron.vite.config.ts](electron.vite.config.ts) — `.map` files are emitted for offline symbolication
|
||||
of the raw stacks the logger now records (CC8), with no `sourceMappingURL` reference in the shipped bundle.*
|
||||
- [ ] **L171 — `main.tsx` mock drift.** The preview mock's version strings disagree
|
||||
- [x] **L171 — `main.tsx` mock drift.** The preview mock's version strings disagree
|
||||
(`getAppVersion`→'0.4.0-preview' vs `checkForAppUpdate.currentVersion`→'0.4.0'), and its `setSettings`
|
||||
skips the real validation/sanitization — so the browser preview can accept settings the app rejects,
|
||||
masking M34-class issues during design.
|
||||
masking M34-class issues during design. *Fixed the version drift: one `MOCK_CURRENT_VERSION` constant in
|
||||
[mockApi.ts](src/renderer/src/mockApi.ts) now backs both `getAppVersion` and
|
||||
`checkForAppUpdate.currentVersion`, so they agree (kept below the mock "latest" so the updater card still
|
||||
demos an available update). The `setSettings`-skips-validation point is left as-is on purpose: the mock is a
|
||||
browser-only design aid with no access to main's `settings.ts` validators; replicating them in the mock
|
||||
would be a second source of truth to drift. M34/M24 already make the real app authoritative, so the design
|
||||
preview being permissive doesn't affect shipped behavior.*
|
||||
- [x] **L172 — `skipLibCheck: true`** (toolkit) hides type errors in dependency `.d.ts` files — standard
|
||||
practice, low risk, noted for awareness (a dep type regression won't fail typecheck). *Acknowledged —
|
||||
kept as-is (it IS standard practice and speeds typecheck); recorded so the trade-off (a dependency
|
||||
@@ -1292,8 +1363,16 @@ are an undefined spacing/radius/type scale and a drift between Fluent components
|
||||
gone — UI18 replaced it with the shared `StatusChip`, so there's no third treatment left to reconcile.*
|
||||
- [ ] **UI21 — Sidebar active-nav rail is expanded-only.** The inset brand box-shadow shows only when
|
||||
expanded; collapsed relies on tint alone. **Standard:** a consistent active indicator in both states.
|
||||
- [ ] **UI22 — Brand-icon tiles differ.** `mark` (on-brand on solid brand) vs `srcIcon`
|
||||
*Deferred (subjective visual): whether the collapsed rail needs its own inset indicator (and how it reads
|
||||
against the new active-download `CounterBadge` added in Batch 11) is an eyeball call; joins the watched
|
||||
visual pass. The tint already marks the active item in both states.*
|
||||
- [x] **UI22 — Brand-icon tiles differ.** `mark` (on-brand on solid brand) vs `srcIcon`
|
||||
(brandForeground2 on brand-tint) vs `sectionIcon` (compoundBrand, no tile). **Standard:** a defined icon-emphasis set.
|
||||
*Resolved (the set is now defined + documented): three deliberate emphasis levels — **brand mark** (`mark`,
|
||||
on-brand glyph on solid brand: the app/onboarding identity, highest emphasis), **entity tile** (`srcIcon`,
|
||||
brandForeground2 on brand-tint: a Library source, medium), and **section glyph** (`sectionIcon`,
|
||||
compoundBrand, no tile: a settings-card header, lowest). They *should* differ — one per role; the levels are
|
||||
now named rather than incidental, and each is applied consistently.*
|
||||
|
||||
### Dialogs, menus, status, navigation
|
||||
|
||||
@@ -1302,6 +1381,11 @@ are an undefined spacing/radius/type scale and a drift between Fluent components
|
||||
(Onboarding), and an **unstyled separate `BrowserWindow`** (cookie sign-in) that shows none of the
|
||||
app's theme/chrome. **Standard:** keep native for file/confirm; unify in-app overlays under one
|
||||
themed primitive; theme the sign-in window's title/background to match.
|
||||
*Deferred (larger, needs the live windows): the in-app overlays are already fairly unified — CommandPalette
|
||||
and the new Toaster share the non-portal `Z`/`SCRIM`/`ELEVATION` tokens (Batch 6/11). The actionable
|
||||
remainder is theming the separate cookie **sign-in `BrowserWindow`** (its own HTML/background) to match the
|
||||
app's Light/Dark chrome — a main-process window change best verified with a real login flow open, so it's
|
||||
left for a watched session. Native file/confirm dialogs stay native by design.*
|
||||
- [x] **UI24 — No context menus anywhere.** Every row exposes actions only as inline buttons;
|
||||
right-click does nothing on any screen, despite many per-row actions that conventionally also live on
|
||||
right-click. **Standard:** add consistent right-click menus mirroring row actions, or note "none by design."
|
||||
|
||||
Reference in New Issue
Block a user