fix(custom-v2): wire markdown + text-code viewers to real v2 design tokens#202
Merged
Conversation
The TipTap markdown viewer was using a `--si-bg` / `--si-danger` token that doesn't exist in v2's design system, so the var() fallbacks (`#fff`, `#c0392b`) painted a white sheet across the editor while text inherited the navy-palette near-white --si-fg — i.e. white text on white. v2's tokens (set at .v2-root) are a navy ramp: --si-bg0…bg6 for surfaces, --si-fg/--si-fg-muted/etc for text, --si-rose for warm-red status. Point the viewer at those: - :host and .md-view__body background → --si-bg0 (matches the file-detail stage so the editor blends with surrounding chrome instead of stamping a sheet). - .md-view__state--error color → --si-rose (v2's red). - Dropped the dead .md-view__editor--dark selector and the corresponding [class.md-view__editor--dark] template binding — v2's palette is always dark by design, so the WYSIWYG body always uses --si-fg directly. - Removed the spurious var() fallbacks on .ProseMirror color and :host color; the tokens always exist under .v2-root. Browser-verified via chrome-devtools: navy bg, readable near-white text, all markdown elements (headings, lists, blockquote, fenced code, inline code, accent-colored link) render correctly.
Same broken --si-bg / --si-danger references as the markdown viewer's prior bug, just less visible because CodeMirror paints its own background. The surrounding chrome (status bar above the editor, error states) was still latently broken. - :host + .text-view__body bg → --si-bg0 (matches .detail__stage) - .text-view__state--error color → --si-rose - Drop the spurious var() fallbacks on :host bg/color now that the tokens are guaranteed under .v2-root. Browser-verified: text-test.txt opens with the navy canvas matching the rest of v2 chrome.
zjean
added a commit
that referenced
this pull request
May 19, 2026
#203) ## Summary Two changes to `.claude/skills/` based on lessons from this session's PR #200 / #201 / #202 cycle: 1. **Refines `sync-in-fork-maintenance`** to capture friction that hit today and would hit again. 2. **Adds `v2-dev-loop-verify`** — a new browser-verification skill specifically for catching v2-specific bugs (like the PR #202 white-on-white token miss) that pass build + lint cleanly. Both skills are tooling-only and ship under `.claude/skills/` — no application code is changed. ## `sync-in-fork-maintenance` refinements - **`gh CLI gotchas`** — generalize the `rtk proxy` JSON rule to *any* `gh ... --json` call you depend on a field of, not just `gh api`. Hit today: `gh pr view 199 --json mergeable,mergeStateStatus,...` silently hid the `CONFLICTING` state until re-run through `rtk proxy`. - **`gh CLI gotchas`** — extend the rtk-rejects-`--allow-empty` note to also cover `--no-edit`. The merge-commit step in task 2 now uses `rtk proxy git commit --no-edit` so rtk doesn't strip the flag. - **Task 2 \"Verify before committing\"** — drop `git add -A`. Conflict-resolved files are already staged via per-file `git add` during resolution; cleanly-auto-merged files are staged by `git merge` itself. `git add -A` would also sweep in unrelated `.claude/scheduled_tasks.lock` + `.claude/settings.local.json` working-tree state. Stage regenerated files (e.g. `package-lock.json` after `npm install`) by name and commit. - **New \"Aftermath — once the sync PR is merged\" subsection** — fast-forward local `main`, delete the local sync branch. Notes the SHA-divergence quirk where GitHub's \"Create a merge commit\" produces a new merge commit on the server side, so the local merge-commit SHA won't match origin's after pull (today: local `ad0979a7` ≠ origin's `07a8bce1` — same tree, different SHA). - **Task 3 classification table** — adds a 4th bucket for \"New component / styles in classic UI\" pointing into the new style-translation section. - **New \"Style token translation (when porting classic UI into custom-v2)\" section** — codifies the PR #202 white-on-white root cause as a generalizable port-with-care guideline. Lists `.v2-root`'s actual token inventory (the `--si-bg0`–`--si-bg6` navy ramp, `--si-fg`/`--si-fg-muted`/etc., `--si-rose`, accent variants). Provides a rewrite table for the common bad patterns (`var(--si-bg, #fff)` → `var(--si-bg0)`, `var(--si-danger, #c0392b)` → `var(--si-rose)`, classic light-mode fallbacks → drop). Codifies the \"drop fallbacks; drop dead light/dark plumbing; verify via chrome-devtools\" procedure. - **evals.json** — tightens eval #2 (conflict-resolution) to assert `rtk proxy git commit --no-edit` and absence of `git add -A`. Adds eval #4 (`port-classic-styles-to-v2-tokens`) exercising the design-token translation end-to-end against the PR #201/#202 scenario. ## New `v2-dev-loop-verify` skill 8-step browser-verification recipe via the `chrome-devtools` MCP against the local dev server. Triggers proactively after any visual or behavioural change under `custom-v2/`. Covers, in order: 1. **Dodge the loopback hijack** — `127.0.0.1:8080` / `localhost:8080` are hijacked by VS Code's helper process; use the active LAN IP (`/sbin/ifconfig en0` for the active interface). 2. **Log in** via the UI form with `sync-in` / `password` (per CLAUDE.md memory). 3. **Create fixtures** via the CSRF-authenticated API. The file-creation flow is non-obvious: `POST upload` alone returns `405 Resource already exists` because the URL treats `files/personal` as a parent dir. Right flow is `POST make → UNLOCK → PATCH upload → UNLOCK` (the last UNLOCK release matters — without it the v2 viewer opens in read-only because of the lock the upload left). 4. **Navigate + snapshot** to confirm the right viewer mounted (`.ProseMirror` for TipTap, `.cm-editor` for CodeMirror, etc.). 5. **Computed-styles audit** for v2 design-token bugs — walk from the leaf (`.ProseMirror`) up to `.v2-root` capturing `color` + `background-color` at each layer. Smoking gun for the PR #202 bug class: `color: oklch(0.9x ...)` (near-white) over an `rgb(255,255,255)` ancestor — a `var()` fallback fired because the token doesn't exist. 6. **Drive signal-backed editors** via `window.ng.getComponent(host)` — `component.editor.chain().insertContent()` for TipTap, `component.content.set()` for CodeMirror-via-ngModel. Synthetic `InputEvent('beforeinput', ...)` and `document.execCommand` **don't** trigger TipTap's `onUpdate`, so dirty-flag never flips. 7. **Save round-trip** — click Save, `wait_for ['Opgeslagen', 'Saved']`, then `GET /api/app/spaces/operation/<path>` and confirm the new content is in the response body. 8. **Cleanup** — release locks, optionally `DELETE` test fixtures. Path gotcha worth flagging: `chrome-devtools` enforces workspace roots on screenshot saves; `/tmp/foo.png` is denied. `$TMPDIR` (resolves to `/var/folders/zc/.../T/` on macOS) and the repo path both work. evals.json — 3 test cases: `verify-after-styling-change` (proactive), `debug-v2-styling-bug` (regression test for the PR #202 class), `verify-edit-save-round-trip` (exercises the Angular debug-API trick). ## Merge strategy Squash and merge per CLAUDE.md (chore PR).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
In the just-merged v2 TipTap markdown viewer (#201), the editor area renders white text on a white background — completely unreadable.
The classic
text-code-viewhad the same latent bug, just less visible because CodeMirror paints its own background over the editor body. The chrome around the editor (status bar, error states) was still rendering against a misplaced white sheet.Root cause
Both viewers used
var(--si-bg, #fff)andvar(--si-danger, #c0392b), but v2's design system has no such tokens. The tokens that do exist (defined at.v2-rootfrom PR #195 — the Stack navy palette) are--si-bg0…--si-bg6for surfaces,--si-fg/--si-fg-muted/ etc. for text, and--si-rosefor warm-red status.So
var(--si-bg, #fff)falls back to#fff(white sheet), whilevar(--si-fg, #111)correctly resolves to v2's near-white. White text on white sheet.Verified the variable inventory at
.v2-rootvia chrome-devtools —--si-bgis genuinely absent;--si-bg0–--si-bg6are the navy ramp.Fix
Two components touched, identical pattern:
markdown-view.component.ts:hostand.md-view__bodybackground →--si-bg0(the same canvas the surrounding.detail__stageuses)..md-view__state--errorcolor →--si-rose..md-view__editor--darkselector and its[class.md-view__editor--dark]template binding — v2's palette is always-dark by design.var()fallbacks on.ProseMirrorcolor and:hostcolor.text-code-view.component.ts:hostand.text-view__bodybackground →--si-bg0..text-view__state--errorcolor →--si-rose.var()fallbacks on:hostbg/color.Verification
npm --prefix frontend run buildclean.npm --prefix frontend run lintclean.192.168.1.133:8080:/v2/file?path=/files/personal/tiptap-test.md— navy--si-bg0background, readable near-white text, all markdown elements render with proper contrast./v2/file?path=/files/personal/text-test.txt— CodeMirror gutter/content unchanged; surrounding chrome (status bar, body) now navy and consistent with the rest of v2.Merge strategy
Squash and merge per
CLAUDE.md(fix PR).