Skip to content

Raise contrast in both themes, stop idle repaints, show code as typed, and fix print - #15

Merged
renrenmimi merged 2 commits into
masterfrom
fix/visual-css
Oct 10, 2026
Merged

renrenmimi merged 2 commits into
masterfrom
fix/visual-css

Conversation

@renrenmimi

Copy link
Copy Markdown
Owner

Branches from #9 (commit 2148ad8), so it can be merged before or after it, and independently of #10–#14. In app/globals.css it only touches the rules outside the ranges the other PRs own: the shell, the fonts, .reveal, quiz, task list and lab rules are left alone.

Summary

Fixes from the 2026-10-09 audit (04-TSer-代码与体验.md):

  • A5 Ten callouts and the /narrowing guards grid ran past the viewport on phones, and one callout did on a 1440 px desktop. html, body { overflow-x: clip } then cut the text off.
  • A7 In the light theme, visualisations drawn on the always-dark code background used the light theme's darkened colours. The /narrowing funnel type was 1.09:1, and type chips were 1.5–2.5:1.
  • A8
    • Tertiary text was 2.5–4.0:1 and code comments were 2.9:1.
    • Line numbers were 1.8:1.
    • The dark theme's primary buttons had white text on a bright gradient, about 2:1.
  • A15 JetBrains Mono drew =>, !==, <= and -> as ligatures.
  • A20
    • Code windows: file names were cut off on phones, and highlighted lines lost their band after scrolling sideways.
    • Scrolling stages: gave no hint that they scroll.
    • Titles: long hero titles overflowed at 360 px.
  • A21 The hero gradient's background-position animation re-styled every idle page about 60 times a second.
  • A22 (print) Printing left unrevealed sections blank and printed light text on white.
  • A26 (hero nav) The hero section links were an unnamed <nav>.
  • A28 (useStepper) useStepper called setPlaying inside a setStep updater.

Changes

  • app/globals.css, tokens:
    • --text-3 is #858fa7 in the dark theme and #5a6479 in the light theme.
    • --tk-com is #808a9f, and --code-ln is 54%.
    • The light theme's --ok, --warn, --risk and --info are darkened. These are the values from AlgoAlgo Match chapter 05's preset text to the compiler, align its examples, and tidy chapter 04 #19.
    • --on-fill sets the text colour on primary buttons.
    • --tk-*-ink variants are added for syntax colours on light panels.
    • --code-acc and --code-ink are accents for the dark code background.
  • app/globals.css, rules:
    • A [data-theme="light"] :is(.codewin, .ut-machine, …) rule restores the dark theme's text, panel, border, status and accent tokens inside the 26 always-dark panels.
    • font-variant-ligatures: no-contextual is set on body and on form controls.
    • .callout uses auto minmax(0, 1fr), and inline code in callouts may wrap.
    • Code windows:
      • The body is a single minmax(max-content, 1fr) grid column, so a highlighted line's band reaches the end of the line.
      • On phones the file name takes its own row.
      • Scrollable stages fade at the hidden side through a scroll-driven animation; browsers without support are unchanged.
    • Long hero titles are 34px at 380px or narrower.
    • The hero gradient plays once.
    • A print block hides the shell, reveals every section, switches to light tokens and keeps dark panels printed exactly.
  • Chapter CSS and app/home.css:
    • Chips and types on light panels use the -ink colours.
    • Small spots on tinted backgrounds get stronger text (/classes).
    • .nr-gx uses minmax(0, 1fr), and the zh typeof list may break anywhere.
    • The home, generics and type-magic hero glows and pulses run three times and stop.
  • lib/code.tsx: the file name has a title, and the spacer is a class.
  • lib/kit.tsx:
    • The hero nav has aria-label "On this page" / 本页目录.
    • The key-points title reads 本章要点.
  • lib/stepper.tsx: autoplay is one timeout per frame and stops in an effect at the last frame.
  • Test: test/visual-css.test.ts covers token contrast in both themes, endless non-compositable animations, ligatures, the callout grid and print.

Verification

  • npx tsc --noEmit --incremental false: clean.
  • npm test: 7 files, 47 tests pass.
  • npm run build: succeeds.
  • Headless Chrome against a local next start. Colours are resolved by painting on a canvas, so oklch and color-mix are measured correctly.
    • Low-contrast scan: every text element on the 12 pages is checked against 4.5:1, or 3:1 for large text. In the light theme, 1536 elements in 205 groups fell below; now none do. In the dark theme, 1431 elements in 159 groups fell below; now none do. The only remaining hits are false positives: an untick checkbox whose ✓ is intentionally transparent, and buttons on a gradient that the scanner cannot see.
    • Primary button: measured against both gradient ends, the dark theme is 8.67–9.39:1 and the light theme is 5.13–6.81:1.
    • Clipping: elements past the viewport on all 12 pages at 360, 390 and 1440 px, in English and Chinese, total 0. Before the fix it was 10 at 390.
    • Code windows (/types, 390): 0 of 11 file names are truncated, highlighted lines span the full scroll width, and at mid-scroll the fades are 28 px on both sides. Ligatures are no-contextual.
    • Idle (desktop): 23 s after load, every page does 3–12 style recalculations in 3 s. Before the fix every page did 180, one per frame.
    • Print emulation: /narrowing shows 11 of 11 sections, the sidebar is hidden, body text is rgb(77, 88, 113), and code windows use print-color-adjust: exact.
    • Stepper: autoplay on /types reaches 7 / 7 and switches to "↻ Replay".

🤖 Generated with Claude Code

renrenmimi and others added 2 commits October 9, 2026 16:07
JSX trims each line of a text block and joins the lines with one space.
The Chinese copy is wrapped across source lines throughout the course, so
it rendered with spaces between Chinese characters and around full-width
punctuation: 1,572 of them in 36 files.

- 1,548 line breaks are joined by a script that walks the TypeScript
  syntax tree and touches only JSX text and JSX attribute strings, never
  code samples, template literals or comments. Breaks next to Latin
  letters, digits, expressions, "——" or operators keep their space.
- 24 more spaces go: 20 after full-width punctuation, 3 between Chinese
  text and a tag whose text is Chinese, and one {" "} between a
  full-width mark and Chinese text.
- test/zh-copy-spacing.test.ts, the check DataData and AlgoAlgo use,
  scans every TSX file and fails on any new stray space; CLAUDE.md states
  the rule.

Apart from the one {" "}, the diff changes nothing but whitespace. The
text every edited file renders differs from master only by deleted
spaces, each next to Chinese text, so the English copy is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, fix print

- Tokens: tertiary text, code comments and line numbers meet WCAG AA in both themes; the
  light theme's status colours are darkened (the same values as AlgoAlgo); primary buttons
  use --on-fill, so the dark theme's bright gradient gets dark text instead of 2:1 white.
- Visualisations drawn on the always-dark code background keep the dark theme's text,
  border, status and accent colours in the light theme, where the darker values had dropped
  to 1.1–2.5:1. Syntax colours used on light panels have -ink variants for the light theme.
- Callouts use auto minmax(0, 1fr), so a code window or a long inline error inside them
  scrolls in place instead of pushing the callout off a phone screen; the same for the
  narrowing guards grid, and the Chinese typeof list may wrap anywhere.
- Turn off JetBrains Mono's contextual ligatures, so => and !== look as typed.
- Code windows: highlighted lines reach the end of the line after scrolling, file names show
  in full on phones (and as a tooltip), and scrollable stages fade at the side that hides
  more content.
- The hero gradient and the chapter hero glows play a few times and stop instead of
  repainting idle pages every frame; useStepper stops at the last frame in an effect, not in
  a state updater.
- Printing hides the shell, shows every section and prints in light colours with the code
  windows kept dark; the hero section links have a navigation label; long hero titles fit
  360px screens.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 10, 2026 02:40
@vercel

vercel Bot commented Oct 10, 2026

Copy link
Copy Markdown

Deployment failed for project tser with the following error:

Resource is limited - try again in 24 hours (more than 100, code: "api-deployments-free-per-day").

Learn More: https://vercel.com/renrenmimis-projects?upgradeToPro=build-rate-limit

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-10T02:42:52.673733Z ab1cd6e PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab1cd6e3a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/globals.css
Comment on lines +2350 to +2352
--text: #171c28;
--text-2: #4d5871;
--text-3: #5a6479;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore light text tokens inside dark panels when printing

When the currently selected theme is dark (the default), this print rule replaces --text, --text-2, --text-3, status colors, and --acc-ink with light-page values globally, while the later print list merely preserves dark panel backgrounds and does not restore their foreground tokens. Consequently elements such as .nr-fn-type render #171c28 text on --code-bg: #0a0d16, and panels such as .ut-machine have similarly unreadable labels in print/PDF output. The light-theme restoration selector does not apply because the root still has data-theme="dark"; apply the dark-panel token overrides within the print block as well.

Useful? React with 👍 / 👎.

@renrenmimi
renrenmimi merged commit 79decd2 into master Oct 10, 2026
1 of 2 checks passed
@renrenmimi
renrenmimi deleted the fix/visual-css branch October 10, 2026 06:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants