- Persist source/view/sort toggles via URL query params (?s=…&v=…&o=…).
Short keys keep shared URLs readable; defaults are stripped to keep
the bare URL clean. history.replaceState (no history pollution).
Init seeds toggles from URL with clamp-to-default validation.
- View class is applied BEFORE first render so renderGrid sees the
correct show-all state on direct deep-link loads.
- Add #source-note pill next to the source tag; shows
"91 ngôn ngữ — palette riêng so với GitHub" when GitLab selected,
hidden otherwise. Plus title attr on the source-toggle group with
the full GitHub-vs-GitLab disparity.
- In TIOBE view, hide cards with zero TIOBE-ranked langs (currently
KIM has 0 of 19) — all-langs view still shows every Ngũ Hành card
so the wheel stays intact.
- source-tag firstChild text-node overwrite preserves the source-note
span sibling.
Closes phase-02 of plan 260428-1003-implement-all-remaining (items
2, 3, 4).
- Drop italic on .hero .subtitle; use letter-spacing instead (Be Vietnam
Pro italic renders rough on Linux).
- Migrate anchor underlines from border-bottom dotted to native
text-decoration-style: dotted (figcaption + credit).
- Bump .card h3 to 1.2rem with thin gold rule under each Ngũ Hành
label; reduce letter-spacing 1.2px → 0.4px so Vietnamese diacritics
don't drift.
- Tighten .credit ul indent (move 1.25rem from margin to padding).
- Strengthen chip border 0.18 → 0.22 so pale chips (Rust-class) read
against the cream page bg.
- Add role="list" to .chips and role="listitem" to chip spans for
screen-reader semantics; aria-label per element bucket.
- Document 5-card-row decision (auto-fit retained) and chip contrast
policy (best-effort WCAG luminance) as inline CSS comments.
Closes phase-01 of plan 260428-1003-implement-all-remaining (items
5-10, 13, 14, 15).
4-phase plan covering 15 remaining items from todo.md + 2043 review:
- Phase 01: CSS/HTML polish (items 5-10, 13, 14, 15)
- Phase 02: URL persistence, GitLab tooltip, hide empty KIM (items 2-4)
- Phase 03: Top-5 non-TIOBE peek, lunar SVG body texture (items 11-12)
- Phase 04: OG social card image generation (item 1, may block on tooling)
Defaults baked for the 5 open product questions; flag now if any need
changing. KISS: vanilla HTML/CSS/ES modules, no build step, single-file
edits only (plus assets/og-card.png).
Re-verification confirmed both .original-image > summary (style.css:100)
and #debug-panel > summary (style.css:196) already declare list-style:
none. Firefox respects this; the webkit pseudo only handles Safari.
Cross-browser coverage was always there. Also softened the disclaimer
item — current text is already 3 sentences; only the trailing
parenthetical is a quibble.
- Slim ui-ux-260427-2043 from 293 to 88 lines: drop §2 fix code blocks
and §5 mobile section (all shipped); trim §3/§4 to only items still
pending in code; keep §1 verdict, §6 nice-to-haves, §7 open questions,
file refs.
- Drop "ARIA radio pattern is in place — recheck with NVDA" from
todo.md §3; implementation done in render-elements.js:66-111, manual
screen-reader recheck is a release-time activity, not a leftover.
Delete plans/reports/uiux-260427-0927-audit-improvements.md — all 12
fixes shipped, every open question decided in later commits, and
ui-ux-260427-2043-fengshui-page-review.md is now the live UX baseline.
Update todo.md "Reference reports" list to match.
- delete plans/260427-0854-color-element-mapping/ — feature shipped, classic
panel later removed; plan no longer reflects the codebase.
- plans/todo.md captures: OG image regen, open questions from the latest
UI/UX review, polish leftovers, and which reports are still load-bearing.
Apply remaining UI/UX-review items:
- new "Sắp xếp" segmented control: Mặc định / A–Z / Cầu vồng (hue).
Re-sorts cached buckets without re-fetching.
- DRY the three toggles into one `mountSegmentedControl` helper using
ARIA `role="radiogroup"` / `role="radio"` with `aria-checked` (was
tab/tablist + aria-selected — wrong pattern, no associated tabpanels).
- element-tinted card backgrounds via color-mix(... 6%, card-bg);
count line picks up the element color too — Ngũ Hành identity
reads at a glance instead of relying on a 4 px stripe.
- chip text-shadow stroke applied only to colored chips to rescue
borderline contrast (Swift #F05138 etc.).
- mobile (<= 480 px): modern-controls stack as labeled rows,
segmented buttons hit the 44 px touch-target floor.
- show-all view caps each card's chip cloud at 60 vh w/ thin
scrollbar — HOẢ no longer pushes the page to 5700 px tall on phones.
- hero ribbon stripes 28×4 → 64×6, gap 6 → 8 — reads as a ribbon now,
not a dashed underline; clamps narrower on small phones.
- TIOBE chip emphasis: stronger inset highlight + outer hairline so
the rank-pinned chips read against any background.
- drop dead 320 px breakpoint (clamp() floor already covers it).
UI/UX review found three blockers (report at plans/reports/):
- main.js queried #panel-modern (deleted with classic page); view-toggle
silently failed to mount and legend/error sink no-op'd. Re-anchor refs
to `main .elements`.
- forced 5-col grid at 880px gave each card ~126px of inner room; long
chip names like "Mathematical Programming System" were silently
ellipsis-truncated. Switch to auto-fit minmax(220px, 1fr) and let
chips soft-wrap.
- pickTextColor luminance>0.5 threshold drove white text onto mid-tones
(Rust #dea584 → 2.14:1, Go 2.64, Swift 3.54...). Pick whichever of
black/white has higher WCAG ratio; Rust now 8.34:1.
Polish:
- move "Nguồn: GitHub Linguist" out of <h2> into its own <p class="mode-tag"> for cleaner heading semantics.
- modern-controls align-items: end → stretch (fixes label/toggle misalignment when wrapped).
- bump .card-count to 0.85rem/600 for clearer hierarchy.
- wrap original 2018 image in <details class="original-image"> spoiler again
- view-toggle becomes a 2-state segmented control (TIOBE Top 20 / Tất cả ngôn ngữ)
matching the source-toggle pattern, with arrow-key roving tabindex
- label both controls ("Nguồn màu" / "Hiển thị") for discoverability
KIM was effectively empty (3 GH / 0 GL) because the old rule required
S<5 AND L≥70 — only near-white grays. Generalize KIM to any color with
L≥70, regardless of hue. Stretches Ngũ Hành orthodoxy slightly (KIM was
canonically white-only) but stays within the spirit: highly-reflective
pastels read as 'metallic shine'.
New distribution:
GitHub: KIM 3 → 65 (10%)
GitLab: KIM 0 → 6 (7%)
Sample-language drift: only Kotlin #A97BFF (L=74 light purple) moves
HOẢ → KIM. Updated fixture and plan acceptance criteria to match.
See plans/reports/brainstorm-260427-1046-kim-rebalance.md
Replace the auto-fit minmax(160px,1fr) that was collapsing to 4 cols on
the 880px container with repeat(5, minmax(0,1fr)) so all five elements
always sit in a single row. Long chips wrap inside the card thanks to
minmax(0,1fr). Mobile collapse breakpoint moved 420px → 720px so the
single-card-per-row layout kicks in for tablets and phones.
GitLab maintains its own Linguist fork with materially different colors
(JavaScript orange instead of yellow, Go olive instead of cyan, ...).
Added a segmented GitHub | GitLab toggle next to the view toggle in the
modern panel. Switching reloads the data and re-classifies on the fly.
- data/gitlab-colors.json: 91 entries, 2.9KB, converted from gitlab-org/linguist YAML
- js/main.js: refactored render path into loadAndRender(sourceKey)
- js/render-elements.js: new mountSourceToggle helper (tablist + arrow keys)
- index.html: source-toggle slot, source-tag in h2, updated disclaimer
- style.css: pill-segmented .source-toggle styling
Default view shows only TIOBE-ranked languages (19 chips total) for a cleaner
first impression. A single button at the top of the modern panel toggles to
the full 664-language list. Card counts now read 'X TIOBE · Y khác'. Chips
of TIOBE-ranked languages get a slightly heavier border to stand out.
- js/tiobe-top.js: TIOBE Top 20 (April 2026) keyed by GH Linguist names
- js/main.js: tag entries with rank, sort TIOBE-first then alphabetical
- js/render-elements.js: chip distinction + view-toggle mount
- index.html: view-toggle slot + updated disclaimer
- style.css: .chip-tiobe / .chip-other / .view-toggle-btn rules
Classic mode reproduces the 2018 toidicodedao image and its 5 hardcoded
element cards verbatim. Modern mode renders a data-driven grid built from
GitHub Linguist colors classified into Ngũ Hành elements via a deterministic
HSL rule set. Toggle persists via URL hash; both panels coexist in DOM with
a CSS opacity fade. Includes a collapsed debug panel listing skipped (no
color) and borderline (near hue boundary) entries.
- data/github-colors.json: vendored from ozh/github-colors (722 entries)
- js/classify-element.js: pure HSL classifier (664 lang sample, 22/22 fixtures pass)
- js/mode-toggle.js: tablist with hash persistence + arrow-key nav
- js/render-elements.js: chip rendering with YIQ contrast + debug panel
- js/main.js: fetch + classify + render entry point
- style.css: segmented toggle, panel fade, chip pill, debug-panel, mobile
Static site presenting the 'Lựa chọn ngôn ngữ lập trình theo phong thuỷ'
image from toidicodedao.com with Ngũ Hành element cards and source credit.
Includes GitHub Pages deploy workflow.