mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
fix(theme): replace no-op --mat-sys-* tokens with --app-* design tokens
The Material theme setup in apps/web/src/m3-theme.scss uses the older M3 API (mat.define-theme + mat.all-component-themes), which emits component tokens but never emits the --mat-sys-* system tokens. As a result ~540 var(--mat-sys-*) references across the app were silent no-ops: the declarations were invalid at computed-value time and fell back to inherited/initial values, so many backgrounds, borders and dividers never rendered and several text/icon colors sat at the wrong contrast. Rather than migrate to mat.theme() (which would flip every no-op at once with M3 azure-palette values foreign to the hand-tuned design), remap the high-visibility usages to the existing --app-* design tokens defined for both themes in m3-theme.scss, verified screenshot-driven in light and dark via Electron CDP. Changes: - Add --app-error-color and --app-accent-color tokens (light + dark). - Fix high-visibility surfaces: settings area, workspace shell header, playlist switcher, downloads, channel-details dialog, account-info, group/category management dialogs, sources context/filters panels, nav-list, and the .dark-theme app background. - Point the Tailwind color palette at --app-* tokens instead of --mat-sys-*. - Strip ~150 dead var(--app-x, var(--mat-sys-y)) fallbacks repo-wide (the fallback can never be taken). - UI polish surfaced by the remap: suppress Material's circular icon-button state layer in the header (keep the rounded-rectangle hover), remove the orphan divider before the download button, remove the redundant right-edge accent bar on active rail items (the filled chip is enough), and raise the header/switcher control icons from the muted tier to --app-body-color so they no longer read as disabled. Guard against regressions: - tools/styles/check-mat-sys-usage.mjs fails on any new var(--mat-sys-*) reference; legacy usages are grandfathered in a shrink-only baseline (tools/styles/mat-sys-baseline.mjs). Wired into the CI Lint job and exposed as `pnpm run lint:styles`. Docs: - docs/architecture/theme-design-tokens.md documents why the tokens are no-ops, the --app-* mapping table, and the screenshot-driven migration protocol. CLAUDE.md updated with the token policy and the new lint check. Scrollbar-related --mat-sys-* usages are intentionally left untouched here; they belong to the separate branch claude/iptvnator-dark-scrollbar-2600aa. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f856226dc3
commit
eac1dfa09e
45 files changed
+801
-488
No files matched your search
@@ -0,0 +1,87 @@
|
||||
# Theme design tokens: `--app-*` is canonical, `--mat-sys-*` is a no-op
|
||||
|
||||
## TL;DR
|
||||
|
||||
- The only CSS design tokens that exist at runtime are the `--app-*` custom
|
||||
properties defined (for light and dark) in `apps/web/src/m3-theme.scss`.
|
||||
- `var(--mat-sys-*)` references **do not work anywhere in this app**. The
|
||||
theme uses Angular Material's older M3 API (`mat.define-theme` +
|
||||
`mat.all-component-themes` / `mat.all-component-colors`), which emits
|
||||
_component_ tokens with literal values but never emits the `--mat-sys-*`
|
||||
_system_ tokens. Verified empirically via CDP on 2026-07-12: no stylesheet
|
||||
rule defines any `--mat-sys-*` variable.
|
||||
- CI fails when new `var(--mat-sys-*)` references are added
|
||||
(`tools/styles/check-mat-sys-usage.mjs`); legacy usages are grandfathered
|
||||
in `tools/styles/mat-sys-baseline.mjs`, which must only shrink.
|
||||
|
||||
## What a `--mat-sys-*` reference actually does today
|
||||
|
||||
Because the token is never defined, any declaration containing
|
||||
`var(--mat-sys-x)` without a fallback becomes _invalid at computed-value
|
||||
time_, which behaves like `unset`:
|
||||
|
||||
| Declaration shape | Actual rendering |
|
||||
| ------------------------------------------------------------------ | -------------------------------------------------------------- |
|
||||
| `color: var(--mat-sys-on-surface-variant)` | inherited text color |
|
||||
| `background: var(--mat-sys-surface-container)` | transparent |
|
||||
| `background: color-mix(..., var(--mat-sys-x) 12%, ...)` | transparent |
|
||||
| `border: 1px solid var(--mat-sys-outline-variant)` | **no border at all** |
|
||||
| `border-color: var(--mat-sys-primary)` (width/style set elsewhere) | `currentColor` border |
|
||||
| `--local-var: ... var(--mat-sys-x) ...` | `--local-var` becomes invalid too, cascading to every consumer |
|
||||
| `var(--app-x, var(--mat-sys-y))` | `--app-x` (fallback is dead but harmless) |
|
||||
|
||||
This means the app's accepted visual design was produced _with_ these
|
||||
no-ops. Making the tokens suddenly resolve (e.g. by migrating the theme to
|
||||
`mat.theme()`, available since Material v19) would flip hundreds of sites at
|
||||
once: surfaces, borders, and dividers that are currently invisible would
|
||||
appear app-wide with M3 azure-palette values that were never part of the
|
||||
hand-tuned design. That is why the fix strategy is **(b) replace usages
|
||||
incrementally with `--app-*` tokens**, not (a) emit the system tokens.
|
||||
|
||||
Every migration step must be screenshot-verified in both themes (see
|
||||
"Migration protocol" below) because replacing a no-op is a deliberate visual
|
||||
change: the borders/backgrounds the original author intended will start
|
||||
rendering.
|
||||
|
||||
## Token mapping for migration
|
||||
|
||||
When migrating a file, map by _role in context_, not mechanically:
|
||||
|
||||
| `--mat-sys-*` token | Replacement |
|
||||
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `on-surface` (text) | `--app-heading-color` (emphasis/hover text), `--app-body-color` (regular copy) |
|
||||
| `on-surface` (inside `color-mix` overlays) | `--app-on-surface` |
|
||||
| `on-surface-variant` | `--app-muted-color` (icons, captions, placeholders, meta), `--app-body-color` (secondary copy) |
|
||||
| `outline-variant`, `outline` | `--app-separator` (hairlines/dividers), `--app-widget-header-border` (faintest) |
|
||||
| `surface` | `--app-content-bg` (page-level), `--app-widget-bg` (component surface) |
|
||||
| `surface-container`, `-low` | `--app-widget-bg`; for chips/pills on a widget surface prefer `color-mix(in srgb, var(--app-on-surface) 6%, transparent)` |
|
||||
| `surface-container-high`, `-highest` | `--app-widget-header-bg` (raised surface), `--app-card-hover-bg` (hover state) |
|
||||
| `primary` | `--app-selection-color` |
|
||||
| `on-primary` | `--app-selection-on-color` |
|
||||
| `primary-container` | `--app-selection-surface` (`-strong` for emphasis) |
|
||||
| `error`, `error-container` | `--app-error-color`; surfaces via `color-mix(in srgb, var(--app-error-color) N%, transparent)` |
|
||||
| `tertiary`, `tertiary-container` | `--app-accent-color` (cyan accent: radio badge, external-playback and success states); surfaces via `color-mix` |
|
||||
|
||||
Dead-fallback usages `var(--app-x, var(--mat-sys-y))` are always safe to
|
||||
simplify to `var(--app-x)` — the fallback can never be taken (and if
|
||||
`--app-x` were undefined, the fallback would be invalid anyway, so behavior
|
||||
is identical in every case).
|
||||
|
||||
## Migration protocol
|
||||
|
||||
1. Replace the file's `var(--mat-sys-*)` references using the table above.
|
||||
2. Run the app (`pnpm nx serve electron-backend`, CDP on 9222) and
|
||||
screenshot the affected views in **both** light and dark themes; compare
|
||||
against pre-change screenshots. Newly appearing borders/backgrounds must
|
||||
look intentional and consistent with the `--app-*` design language.
|
||||
3. Regenerate the baseline: `node tools/styles/generate-mat-sys-baseline.mjs`
|
||||
and commit the shrunken `tools/styles/mat-sys-baseline.mjs`.
|
||||
4. `pnpm run lint:styles` must pass.
|
||||
|
||||
## Guard
|
||||
|
||||
- `pnpm run lint:styles` → `tools/styles/check-mat-sys-usage.mjs` scans
|
||||
`apps/` and `libs/` (`.scss`, `.css`, `.ts`, `.html`, `.js`) and fails if
|
||||
any file has more `var(--mat-sys-` references than its baseline entry.
|
||||
- CI runs it in the Lint job (`.github/workflows/ci.yml`).
|
||||
- Never add new entries or raise counts in the baseline.
|
||||
Reference in new issue
Block a user