All notable deploys of TropicoHead to tropico.stefan.xxx.
Format: Keep a Changelog.
Deploy command: ~/stefanxxx/ops/deploy-static-site.sh tropico.stefan.xxx ~/tropico root@<vps>.
[Unreleased]
[phase-127] โ 2026-06-04 โ TESTING + ARCHITECTURE current snapshot
Changed
- TESTING.md current counts refreshed to 181 Vitest files, 2,375 Vitest tests, and 53 Playwright checks.
- TESTING.md documents the current Playwright harness:
serviceWorkers: block,tests/e2e/search-helper.js, andTropicoheadSearchReady. - ARCHITECTURE.md now describes all six generated game pages, the live production URL, deploy command, and current key-file line counts.
- README Phase Map extended through Phase 127.
Added
tests/integration/phase-127-testing-architecture-docs.test.jsโ 5 specs.
Verified
- 2,375 vitest passing. Zero regressions.
[phase-126] โ 2026-06-04 โ README current-count polish
Changed
- README cabinet feature count now says 41-badge Hall of Fame.
- README engagement-loop count now says 41 achievement badges.
- README Sitemap.xml count now says 144 URLs.
- README stats snapshot bumped to Phase 126.
Added
tests/integration/phase-126-readme-current-counts.test.jsโ 3 specs.
Verified
- 2,370 vitest passing. Zero regressions.
[phase-125] โ 2026-06-04 โ Codex SDLC + VisualHUD handoff + README sync
Added
- Repo-local Codex SDLC handoff pointers in README:
.codex/,.codex-sdlc/,.agents/skills/sdlc/,START-SDLC.md,SDLC-LOOP.md,PROVE-IT.md. - Repo-local VisualHUD handoff pointer in README, including active
tmnttheme and upstream feedback issue https://github.com/BaseInfinity/visualhud/issues/5. tests/integration/phase-125-readme-handoff-sync.test.jsโ 5 specs.
Changed
- README stats snapshot bumped to Phase 125.
- README Phase Map extended through Phase 125.
Verified
- 2,367 vitest passing. Zero regressions.
[phase-124] โ 2026-06-04 โ Footer also links /sitemap.html
Added
- build.js footer-tour-link extended with a second link:
๐๏ธ Site mapโ /sitemap.html, separated from the existing tour link byยท. - index.html hand-edited to match.
tests/integration/phase-124-footer-sitemap-link.test.jsโ 8 specs.
Verified
- 2,361 vitest passing. Zero regressions.
[phase-123] โ 2026-06-04 โ README final stats refresh (phases 119-122)
Changed
- README Phase Map extended with phases 119-123.
- Stats snapshot bumped to Phase 122: 41 badges (3 legendary), 2,352+ tests across 147+ test files, 65+ client modules, 30 meta pages.
Verified
- 2,354 vitest passing. Zero regressions.
[phase-122] โ 2026-06-04 โ Next-badge hint on /me.html
Added
next-badge-hint.js(1.2KB) โTropicoheadNextBadgeHint.attach/pickNext.pickNextreturns first locked common-tier badge, falls back to first locked non-common, null when all unlocked. Renders.tropicohead-next-badge-hint"Next badge: NAME โ DESCRIPTION" callout on /me.html. No-op when achievements absent. Idempotent..tropicohead-next-badge-hintmuted left-bordered callout, visually secondary to welcome-back.- Wired: me.html + sw.js precache.
tests/integration/phase-122-next-badge-hint.test.jsโ 12 specs.
Verified
- 2,352 vitest passing. Zero real regressions.
[phase-121] โ 2026-06-04 โ Bookmark-count chip on /me.html
Added
bookmark-count-chip.js(788 bytes) โTropicoheadBookmarkCountChip.attachrendersโญ N bookmarkschip on /me.html. Pluralized. No-op when bookmarks module absent. Idempotent..tropicohead-bookmark-count-chipCSS joins the existing pill family.- Wired: me.html + sw.js precache.
tests/integration/phase-121-bookmark-chip.test.jsโ 9 specs.
Verified
- 2,340 vitest passing. Zero real regressions.
[phase-120] โ 2026-06-04 โ Heading anchor links (ยถ)
Added
heading-anchor.js(758 bytes) โwindow.TropicoheadHeadingAnchor.attach. Walks everyh3[id]+h4[id]and appends a small ยถ anchor link pointing at its own id. Headings without id are skipped. aria-label per anchor..tropicohead-heading-anchorCSS: opacity 0 by default; fades in onh3:hover/h4:hover. Hover-only reveal preserves heading visual rhythm.- Wired across all 6 game pages (build.js + index.html). sw.js precaches
/heading-anchor.js. tests/integration/phase-120-heading-anchors.test.jsโ 10 specs.
Verified
- 2,324 vitest passing (+9 skipped). Zero regressions.
[phase-119] โ 2026-06-04 โ README stats refresh (phases 113-118)
Changed
- README Phase Map table extended with phases 113-119 entries.
- Hero line badge count 39 โ 41. Stats section bumped to Phase 118 snapshot: 41 badges (3 legendary surfaced at
/honor.html), 2,323+ tests across 145+ test files, 62+ client modules, 30 meta pages.
Verified
- 2,322 vitest passing. Zero real regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-118] โ 2026-06-04 โ 41st badge "Honored" + mobile menu /honor link
Added
honoredbadge (common tier, ๐) โ unlocks when you open/honor.htmlfor the first time.achievements.jsaddstrigger('visit-honor', {})case that unlocks on first stamp.honor.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.- ๐ Hall of Honor โ /honor.html added as 25th entry in
mobile-menu.jsLINKS. tests/integration/phase-118-honored.test.jsโ 7 specs covering catalog count, badge lookup, trigger unlocks, progress total, honor.html loads achievements.js + trigger script, mobile-menu.js has honor.html.
Changed
- Achievement catalog: 40 โ 41 badges. Bumped sibling regression assertions across 27 existing test files.
Verified
- 2,313 vitest passing (+9 skipped). Zero real regressions.
[phase-117] โ 2026-06-04 โ /honor.html Hall of Honor for legendary badges
Added
honor.htmlโ Lighthouse-95-clean dedicated showcase page for the 3 legendary-tier badges (Konami Caudillo, Forever Caudillo, Tropican Patriot). Gold gradient cards with legendary-pill tier markers. Unlock condition in an italic accent-bordered callout per card.- CollectionPage JSON-LD, standard meta head, footer tour link.
- Wired: sitemap.xml extends with
/honor.htmlat priority 0.5; sw.js precaches/honor.html; sitemap.html (human map) links honor.html under Personal. tests/integration/phase-117-honor.test.jsโ 11 specs covering existence, Hall of Honor / Legendary mention, all 3 badge names, unlock conditions, /cabinet cross-link, single h1 + meta, full meta-head suite, JSON-LD, sitemap + sw + human-map wiring.
Verified
- 2,306 vitest passing (+9 skipped). Zero real regressions (two known concurrency flakes in full-run, both pass in isolation).
[phase-116] โ 2026-06-04 โ Welcome-back greeting on /me.html
Added
welcome-back.js(1.7KB) โwindow.TropicoheadWelcomeBack.attach/render. Combines real data fromTropicoheadTimeSpent.read+TropicoheadAchievements.progress+TropicoheadStreak.read. Renders.tropicohead-welcome-backaside between header and main on /me.html. Adapts copy: empty โ "Click around and start unlocking badges", full โ "Welcome back. N minutes here. M/40 badges. ๐ฅ K-day streak." Idempotent..tropicohead-welcome-backaccent-bordered callout (left stripe + accent-light bg + accent-dark text). Inherits per-game palette + 5 themes.- Wired: me.html loads
welcome-back.jsafter streak.js; sw.js precaches/welcome-back.js. tests/integration/phase-116-welcome-back.test.jsโ 9 specs covering existence + 2KB budget, 2-method surface, render with full stats includes all 4 numbers, empty state still renders, idempotent attach, me.html wiring, sw precache, style.css rule.
Verified
- 2,305 vitest passing. Zero regressions.
[phase-115] โ 2026-06-04 โ Footer "Take the tour" link on every game page
Added
- Footer link "๐งญ New here? Take the 5-step tour โ" appended to every game-page footer via the build.js template. All 5 generated game pages (t2-t6) pick it up automatically. index.html hand-edited to match.
tests/integration/phase-115-footer-tour-link.test.jsโ 8 specs covering build.js template has footer-tour-link + tour.html, each of the 6 game pages has tour.html + footer-tour-link class.
Verified
- 2,294 vitest passing. Zero real regressions (two flakes on phase-20 CACHE_VERSION + phase-108 status badge in full-run, both pass in isolation โ known concurrency race).
[phase-114] โ 2026-06-04 โ 40th badge "Tropican Patriot" (32 unlocked) ๐ 40-BADGE MILESTONE
Added
tropican-patriotbadge (legendary tier, ๐๏ธ) โ self-referential meta achievement that unlocks when 32 of the 39 other badges are unlocked. Even Penultimo salutes you now.achievements.js checkCuratorMilestoneextended โ same hook runs after everytrigger(), now excludes bothcuratorandtropican-patriotfrom the count so neither badge counts toward unlocking the other. Count โฅ 25 unlocks curator (epic), count โฅ 32 unlocks tropican-patriot (legendary). Both idempotent.tests/integration/phase-114-tropican-patriot.test.jsโ 4 specs covering catalog count, badge lookup + legendary tier, locked-at-zero, progress total.
Changed
- Achievement catalog: 39 โ 40 badges. Bumped sibling regression assertions across 26 existing test files.
Verified
- 2,279 vitest passing (+9 skipped). Zero regressions. 40-badge milestone.
[phase-113] โ 2026-06-04 โ README Phase Map refresh (phases 89-112)
Changed
- README Phase Map table extended from phase 88 to phase 113 โ every overnight + morning ship named.
- Hero line badge count 31 โ 39. Stats section bumped to Phase 112 snapshot: 39 badges, 2,283+ tests across 140+ test files, 60+ client JS modules, 28 meta pages.
- Phase 55 README-refresh test loosened to accept current phase numbers (regex extended to cover 100-199).
Verified
- 2,283 vitest passing. Zero real regressions (phase-20 flake on full-run, passes in isolation โ known race pattern).
[phase-112] โ 2026-06-04 โ Mobile menu adds /tour.html
Added
- ๐งญ Take the tour โ /tour.html added as 24th entry in
mobile-menu.jsLINKS array. tests/integration/phase-112-mobile-tour-link.test.jsโ 2 specs covering tour.html href present and emoji label.
Verified
- 2,283 vitest passing. Zero regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-111] โ 2026-06-04 โ 39th badge "Curious" (visit /tour.html)
Added
curiousbadge (common tier, ๐งญ) โ unlocks when you open/tour.htmlfor the first time. Now you know the layout of the palace.achievements.jsaddstrigger('visit-tour', {})case that unlocks on first stamp.tour.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-111-curious.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, tour.html loads achievements.js, tour.html trigger script.
Changed
- Achievement catalog: 38 โ 39 badges. Bumped sibling regression assertions across 25 existing test files.
Verified
- 2,273 vitest passing (+9 skipped). Zero regressions.
[phase-110] โ 2026-06-04 โ /tour.html 5-step guided intro
Added
tour.htmlโ Lighthouse-95-clean static page with 5 numbered tour steps:- Search across all 6 games
- Find a strategy walkthrough
- Browse the Tropicodex
- Unlock badges in your Cabinet (with share URL mention)
- Personalize themes + shortcuts (with focus-mode tip)
- HowTo JSON-LD with 5 named HowToStep entries โ eligible for search-engine "how to" snippets. Cross-linked accent-bordered step cards with numbered pills.
- Standard meta head + cross-links to /strategy, /compare, /tropicodex, /almanac, /cabinet, /shortcuts, /sitemap, /faq.
- Wired: sitemap.xml extends with
/tour.htmlat priority 0.7 (high โ newcomer-targeted); sw.js precaches/tour.html; sitemap.html (human map) links tour.html between /q and /faq under Discovery. tests/integration/phase-110-tour.test.jsโ 10 specs covering existence, โฅ5 step sections, all 5 themes mentioned, all 5 destination links, single h1 + meta, full meta-head suite, JSON-LD, sitemap + sw + human-map wiring.
Verified
- 2,266 vitest passing (+9 skipped). Zero real regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-109] โ 2026-06-04 โ status.html surfaces badge count cell
Changed
status-page.js render(data)appends a 6th cell{ value: data.badges, label: 'Badges', extra: 'common โ legendary' }whendata.badgesis a number. Graceful โ cell hidden when badges field absent (no breaking change for olderstatus.json).- Phase 54 status-page budget bumped from 4KB โ 5KB. Real size now 4.2KB.
Added
tests/integration/phase-109-status-badges-cell.test.jsโ 2 specs covering render with badges=38 shows "Badges" + 38, render without badges hides the cell.
Verified
- 2,265 vitest passing. Zero real regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-108] โ 2026-06-04 โ status.json now includes badge count
Changed
build.js buildStatusJson()now readsachievements.js, counts CATALOG entries via regex/\{\s*id:\s*'[a-z-]+'/g, and writes the count asstatus.badgesinstatus.json. Current value: 38.
Verified
- Phase 107 footer-info "๐
N badges" segment now reads real data โ was previously dependent on a
status.badgesfield that didn't exist. - 2,254 vitest passing (+9 skipped). Zero real regressions (phase-20 flake on full-run, passes in isolation โ known race pattern).
[phase-107] โ 2026-06-04 โ Footer-info adds badge count from status.json
Changed
footer-info.js(Phase 43) extended โattach()now also fetches/status.jsonin parallel with build-manifest + feed.rss.render(data)adds a fourth segment "๐ N badges" sourced fromdata.status.badges. Graceful fallback when status.json fetch fails or doesn't include badges.- Module size 2.4KB (was 2.1KB), well under the loosened 3KB budget.
Added
tests/integration/phase-107-footer-badge-count.test.jsโ 3 specs covering render withstatus.badges=38includes "38 badges", render without status doesn't include "badges", file under 3KB.
Verified
- 2,260 vitest passing. Zero regressions. Phase 43 footer-info specs continue to pass.
[phase-106] โ 2026-06-04 โ 38th badge "Bookworm" (50 distinct sections)
Added
bookwormbadge (epic tier, ๐) โ unlocks at 50 distinct visited guide sections. The library calls you family.achievements.js visit-sectioncase extended: count โฅ 25 โ avid-reader (rare), count โฅ 50 โ bookworm (epic).- Same section repeated does NOT double-count (per
visitSections[sectionId] = 1dedupe from Phase 62). tests/integration/phase-106-bookworm.test.jsโ 6 specs covering catalog count, badge lookup + epic tier, 49 sections no-unlock, 50 unlocks both bookworm + avid-reader, repeat-same-section no double-count, progress total.
Changed
- Achievement catalog: 37 โ 38 badges. Bumped sibling regression assertions across 24 existing test files.
Verified
- 2,257 vitest passing. Zero regressions.
[phase-105] โ 2026-06-04 โ 37th badge "Postmaster" + mobile menu /contact link
Added
postmasterbadge (common tier, ๐จ) โ unlocks when you open/contact.htmlfor the first time. The Ministry of Correspondence is open.achievements.jsaddstrigger('visit-contact', {})case that unlocks on first stamp.contact.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.- ๐จ Contact + feedback โ /contact.html added as 23rd entry in
mobile-menu.jsLINKS. tests/integration/phase-105-postmaster.test.jsโ 7 specs covering catalog count, badge lookup, trigger unlocks, progress total, contact.html loads achievements.js + trigger script, mobile-menu.js has contact.html.
Changed
- Achievement catalog: 36 โ 37 badges. Bumped sibling regression assertions across 23 existing test files.
- Phase 21 per-asset budget for
achievements.jsbumped from 14KB โ 16KB (real size 14.2KB after 11 new badges in this overnight block).
Verified
- 2,242 vitest passing (+9 skipped). Zero regressions.
[phase-104] โ 2026-06-04 โ /contact.html contact + feedback page
Added
contact.htmlโ Lighthouse-95-clean page with 5 contact cards: ๐ bugs/features (GitHub Issues), โ๏ธ content edits (Community Edit Loop + PR), ๐ข phase ship notifications (RSS+Atom+changelog cross-link), ๐ OpenSearch description, ๐ฆ data pulls (cross-link to /data). Intro nudges visitors to read /faq first.- ContactPage JSON-LD schema. Standard meta head + cross-links to /faq, /credits, /data, /changelog.
- Wired: sitemap.xml extends with
/contact.htmlat priority 0.5; sw.js precaches/contact.html; sitemap.html (human map) links contact.html under Meta. tests/integration/phase-104-contact.test.jsโ 13 specs covering page existence, GitHub mention, feedback/bug/contribute mentions, all cross-links, single h1 + meta, full meta-head suite, ContactPage JSON-LD, sitemap + sw + human-map wiring.
Verified
- 2,243 vitest passing. Zero regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-103] โ 2026-06-04 โ Mobile menu surfaces /data.html + budget bump
Added
- ๐ฆ Data artifacts โ /data.html entry added to
mobile-menu.jsLINKS array (22nd menu entry). tests/integration/phase-103-mobile-data-link.test.jsโ 3 specs covering data.html href present, emoji label, mobile-menu.js under 4.5KB.
Changed
- Phase 64 mobile-menu size-budget assertion bumped from 3KB โ 4KB. Real size is 3.1KB after 8 new entries since Phase 64.
Verified
- 2,231 vitest passing. Zero regressions. Phase 64's 38 existing specs continue to pass.
[phase-102] โ 2026-06-04 โ 36th badge "Data Diver" (visit /data.html)
Added
data-diverbadge (common tier, ๐ฆ) โ unlocks when you open/data.htmlfor the first time. The republic respects researchers.achievements.jsaddstrigger('visit-data', {})case that unlocks on first stamp.data.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-102-data-diver.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, data.html loads achievements.js, data.html trigger script.
Changed
- Achievement catalog: 35 โ 36 badges. Bumped sibling regression assertions across 22 existing test files.
Verified
- 2,228 vitest passing. Zero regressions.
[phase-101] โ 2026-06-04 โ /data.html public data artifacts page
Added
data.htmlโ Lighthouse-95-clean static page documenting every public JSON artifact powering TropicoHead. 12-row table covering combined-index, glossary, buildings, edicts, audit, status, strategy-index, build-manifest, feed.rss, feed.atom, sitemap.xml, opensearch.xml. Each row clickable + code-styled filename.- Usage notes: CORS open, no auth, refresh cadence via build manifest SHA-256, privacy stance, license.
- Standard meta head + cross-links to /credits, /faq.
- Wired: sitemap.xml extends with
/data.htmlat priority 0.5; sw.js precaches/data.html; sitemap.html (human map) links data.html under Meta. tests/integration/phase-101-data-page.test.jsโ 15 specs covering page existence, all 7 artifact links, usage + privacy mentions, single h1 + meta + canonical + theme-color, pre-paint + PWA + opensearch, sitemap + sw + human-map wiring.
Verified
- 2,213 vitest passing (+9 skipped). Zero regressions.
[phase-100] โ 2026-06-04 โ Milestone banner on /index.html ๐ 100-PHASE MILESTONE
Added
milestone-banner.js(1.4KB) โwindow.TropicoheadMilestoneBanner.attach/dismiss. Injects an<aside aria-live="polite">above<header>on /index.html: "๐ Phase 100 milestone shipped โ 35 badges, 100+ phases, 2,000+ tests. Long live the republic." Dismiss button persists vialocalStorage['tropicohead.milestoneBanner.phase-100.dismissed']='1'so the banner never re-appears once dismissed..tropicohead-milestone-bannerlinear-gradient (accent-light โ accent) strip with white text + ghost-button ร dismiss. Inherits per-game palette + all 5 theme variants.- Wired: index.html loads
milestone-banner.jsafter section-up-next.js (Tropico 1 page only โ this is a milestone celebration, not site-wide chrome); sw.js precaches/milestone-banner.js. tests/integration/phase-100-milestone-banner.test.jsโ 12 specs covering existence + 1.5KB budget, 2-method surface, attach injects with Phase 100 mention, dismiss button + aria-label, dismiss removes, attach after dismiss = no re-inject (localStorage persistence), idempotent fresh attach, aria-live attribute, index.html wiring, sw precache, style.css rule.
Verified
- 2,207 vitest passing. Zero regressions.
Milestone
- 100 phases shipped on TropicoHead overall. 35 badges. 2,200+ vitest tests across 140+ test files. Long live the republic.
[phase-99] โ 2026-06-04 โ 35th badge "Forever Caudillo" (30-day streak)
Added
forever-caudillobadge (legendary tier, ๐) โ unlocks at 30 consecutive-day visits. The republic remembers.achievements.js streak-updatecase extended to a 3-tier ladder: โฅ3 days โ iron-will (rare), โฅ7 days โ loyalist (epic), โฅ30 days โ forever-caudillo (legendary). All three unlock on the same call when count first crosses 30.tests/integration/phase-99-forever-caudillo.test.jsโ 5 specs covering catalog count, badge lookup + legendary tier, count 29 no-unlock, count 30 unlocks all 3 streak badges, progress total.
Changed
- Achievement catalog: 34 โ 35 badges. Bumped sibling regression assertions across 21 existing test files.
Verified
- 2,195 vitest passing. Zero regressions.
[phase-98] โ 2026-06-04 โ 34th badge "Loyalist" (7-day streak)
Added
loyalistbadge (epic tier, ๐ต๏ธ) โ unlocks at 7 consecutive-day visits. Long live El Presidente.achievements.js streak-updatecase extended: count โฅ 3 keeps unlocking iron-will, count โฅ 7 now also unlocks loyalist.tests/integration/phase-98-loyalist.test.jsโ 5 specs covering catalog count, badge lookup + epic tier, count 6 no-unlock, count 7 unlocks both loyalist + iron-will, progress total.
Changed
- Achievement catalog: 33 โ 34 badges. Bumped sibling regression assertions across 20 existing test files.
Verified
- 2,190 vitest passing. Zero regressions.
[phase-97] โ 2026-06-04 โ Mobile menu refresh
Added
- 7 new entries to
mobile-menu.jsLINKS array surfacing pages that landed since Phase 64 (mobile menu birth): ๐ timeline (Phase 67), ๐บ๏ธ atlas (78), โ FAQ (87), ๐ changelog (90), โจ๏ธ shortcuts (70), ๐๏ธ site map (80), ๐ perf (65). tests/integration/phase-97-mobile-menu-refresh.test.jsโ 9 specs covering each of the 7 new entries, all 14 prior entries preserved, and mobile-menu.js stays under 4KB.
Verified
- 2,185 vitest passing. Zero regressions.
[phase-96] โ 2026-06-04 โ Section "Previous" link in up-next callout
Changed
section-up-next.jsextended โ callout now reads "โ Previous:ยท Up next: โ" for middle sections. First section keeps next-only. Last section gets "โ Previous: ยท Back to top โ". ยทseparator between Prev and Next inside the same callout.- Module stays at 1.4KB โ well under 2KB budget. No new file, just a logic-only extension.
Added
tests/integration/phase-96-section-prev.test.jsโ 5 specs covering middle section has both Prev + Next + correct titles, first section next-only, last section Prev + back-to-top + correct titles, prev link points to prior section id, idempotent on double-attach.
Verified
- 2,176 vitest passing. Zero regressions. Phase 95's 11 specs continue to pass (no behavior regression for next-only / back-to-top cases).
[phase-95] โ 2026-06-04 โ Section "Up next" link footer
Added
section-up-next.js(1.1KB) โwindow.TropicoheadSectionUpNext.attach. At the end of everysection[id], inserts a.tropicohead-up-nextcallout: "Up next: Next title โ". Last section gets "Back to top โ" instead. Picks title via.section-titlespan (existing build artifact) or falls back to h2/h3 text. Idempotent. Graceful no-op for single-section pages..tropicohead-up-nextaccent-bordered callout (left stripe + accent-light bg + accent-dark link). Inherits per-game palette + 5 themes.- Wired across all 6 game pages: build.js template (t2-t6) + index.html hand-edit. sw.js precaches
/section-up-next.js. tests/integration/phase-95-section-up-next.test.jsโ 11 specs covering existence + 2KB budget, attach surface, N-section injection, firstโsecond-link with id + title, last โ back-to-top, idempotent, single-section graceful, build.js + sw + style.css wiring.
Verified
- 2,162 vitest passing (+9 skipped). Zero regressions.
[phase-94] โ 2026-06-04 โ 33rd badge "Saver" (5 bookmarks)
Added
saverbadge (rare tier, โญ) โ unlocks at 5 bookmarked sections. Building a personal library, one decree at a time.achievements.jsaddstrigger('bookmark-add', { count })case that unlocks when count โฅ 5.bookmarks.js add(entry)firesTropicoheadAchievements.trigger('bookmark-add', { count: arr.length })after write. try/catch wrapped. No remove-side trigger โ unlocked badges stay unlocked when count drops.tests/integration/phase-94-saver.test.jsโ 6 specs covering catalog count, badge lookup + rare tier, count 1-4 no unlock, count โฅ 5 unlocks, progress total, bookmarks.js trigger wiring.
Changed
- Achievement catalog: 32 โ 33 badges. Bumped sibling regression assertions across 19 existing test files.
Verified
- 2,160 vitest passing. Zero regressions (one flake in full-run, passes on retry โ known race pattern).
[phase-93] โ 2026-06-04 โ 32nd badge "Iron Will" (3-day streak)
Added
iron-willbadge (rare tier, ๐ฅ) โ unlocks at 3 consecutive-day visits. Dictators are made of consistency. Builds on Phase 92 streak tracker.achievements.jsaddstrigger('streak-update', { count })case that unlocks when count โฅ 3.streak.jsadds compactfire(n)helper called on every state write toTropicoheadAchievements.trigger('streak-update', { count: n }). try/catch wrapped โ never breaks streak tracker if achievements module fails to load.- Phase 92 streak.js per-asset budget bumped from 2KB โ 2.5KB (real size 2.1KB after trigger wiring).
tests/integration/phase-93-iron-will.test.jsโ 6 specs covering catalog count, badge lookup + rare tier, count 1-2 no unlock, count โฅ 3 unlocks, progress total, streak.js trigger wiring.
Changed
- Achievement catalog: 31 โ 32 badges. Bumped sibling regression assertions across 18 existing test files.
Verified
- 2,154 vitest passing. Zero regressions.
[phase-92] โ 2026-06-04 โ Reading-streak tracker
Added
streak.js(1.9KB) โwindow.TropicoheadStreak.record/read/reset/attach.record(dateIso?)defaults to today; same-day is a no-op; +1 day extends; gap > 1 day resets to 1. Auto-records on page load.attach()renders.tropicohead-streak-chip"๐ฅ N-day streak" only when streak > 0..tropicohead-streak-chipdistinct warm-tone chip styling (#ffe8d4bg,#6b2e00text,#d4842eborder) โ visually stands out from the accent-light activity/time chips while sharing pill geometry.- Wired: me.html loads
streak.jsafter time-spent-chip.js; sw.js precaches/streak.js. tests/integration/phase-92-streak.test.jsโ 14 specs covering existence + 2KB budget, 4-method surface, read default 0, record once = 1, consecutive records extend, same-day no-op, gap resets to 1, reset clears state, attach renders chip when streak > 0, idempotent, me.html wiring, sw precache, style.css rule.
Verified
- 2,148 vitest passing. Zero regressions. Local-only โ never sent to a server.
[phase-91] โ 2026-06-04 โ Time-spent display chip on /me.html
Added
time-spent-chip.js(760 bytes) โwindow.TropicoheadTimeSpentChip.attach. Rendersโฑ <format(read())>chip next to the activity-rank pill in /me.html header. ReusesTropicoheadTimeSpent.format+readfrom Phase 85. Graceful no-op when TropicoheadTimeSpent module is absent. aria-label for SR..tropicohead-time-spent-chipshares the activity-rank pill style (accent-light bg, accent-dark text, accent border). Right-margin between sibling chips for visual spacing.- Wired: me.html loads
time-spent-chip.jsafter time-spent.js; sw.js precaches/time-spent-chip.js. tests/integration/phase-91-time-spent-chip.test.jsโ 9 specs covering existence + 1KB budget, attach surface, attach injects chip with formatted time, idempotent, no-op when module absent, me.html wiring, sw precache, style.css rule.
Verified
- 2,134 vitest passing. Zero regressions.
[phase-90] โ 2026-06-04 โ changelog.html generated page ๐ 90-phase milestone
Added
build.js buildChangelogPage()โ readsCHANGELOG.md, strips the top# Changelogh1, runs throughmarked.parse, wraps in the standard meta head + game-nav + theme-toggle + header + footer template, writeschangelog.html.- Inline
<style>tones h2/h3/li/code for compact readable changelog rendering with per-game accent palette. - CollectionPage-friendly meta + canonical + og:* + theme-color + pre-paint theme + apple/iOS PWA + RSS/Atom/OpenSearch wiring.
tests/integration/phase-90-changelog-html.test.jsโ 11 specs covering page existence, [Unreleased] + recent phases rendered, single h1, full meta-head suite, theme-toggle/style.css loaded, sitemap + sw + human-map wiring.
Changed
- sitemap.xml extends with
/changelog.htmlat priority 0.5. - sw.js precaches
/changelog.html. - sitemap.html (human map) links changelog.html under Meta.
Fixed
- Broken
<a href="changelog.html">from /faq.html (Phase 87) โ page now exists.
Verified
- 2,125 vitest passing. Zero regressions. 90 phases shipped on TropicoHead overall.
[phase-89] โ 2026-06-04 โ Back-to-top floating button
Added
back-to-top.js(1.4KB) โwindow.TropicoheadBackToTop.attach/show/hide. Fixed bottom-right round 44ร44 โ button, accent-colored, drop shadow. Visibility toggled at scroll Y โฅ 800px via rAF-throttled passive scroll listener. NativescrollTo({behavior:'smooth'})on click. aria-label for SR..tropicohead-back-to-top+.tropicohead-back-to-top-hiddenCSS rules. Hidden in@media printand under.tropicohead-focus-mode. z-index 997 (sits below mobile FAB at 998).- Wired across all 6 game pages: build.js template (t2-t6) + index.html hand-edit. sw.js precaches
/back-to-top.js. tests/integration/phase-89-back-to-top.test.jsโ 13 specs covering existence + 1.5KB budget, 3-method surface, attach injects button with aria-label, starts hidden, show/hide class toggles, idempotent attach, build.js wiring, sw precache, CSS rule + print-hide + focus-mode-hide.
Verified
- 2,114 vitest passing. Zero regressions.
[phase-88] โ 2026-06-04 โ README.md refresh (Phase 87 state snapshot)
Changed
- README stats section bumped from Phase 55 โ Phase 87 snapshot: 31 badges (was 21), 2,100+ vitest tests (was 1,760), 55+ client JS modules (was 45+), 24 meta pages noted. Hero line updated to "31-badge engagement loop".
- Phase Map extended with phases 56-88 โ every overnight + morning ship is now named.
- Phase 55 README-refresh test loosened: phase regex 40 โ 40-99, test count regex permits 2xxx/3xxx, badge count regex permits 21-99.
Verified
- 2,101 vitest passing. Zero regressions.
[phase-87] โ 2026-06-04 โ /faq.html deeper site FAQ
Added
faq.htmlโ Lighthouse-95-clean static page with 12 Q&A sections: what is TropicoHead, data sources, privacy, "local-only" meaning, badges, contributing, accessibility, mobile, offline, update cadence, search, contact.- FAQPage JSON-LD schema with first 4 Q&As as schema entries (search-engine FAQ snippets).
- Standard meta head + cross-links to /q (quick questions), /credits, /shortcuts, /perf, /cabinet, /status, /easter-eggs.
- Wired: sitemap.xml extends with
/faq.htmlat priority 0.6; sw.js precaches/faq.html; sitemap.html (human map) links faq.html under Discovery. tests/integration/phase-87-faq.test.jsโ 13 specs covering existence, โฅ8 Q&A blocks, privacy/contributing/sources/a11y mentions, FAQPage JSON-LD, single h1 + meta, full meta-head suite, /q.html cross-link, sitemap + sw + human-map wiring.
Verified
- 2,100 vitest passing. Zero regressions (one flake on buildings-json-build in full-run, passes in isolation โ known race pattern).
[phase-86] โ 2026-06-04 โ 31st badge "Devoted Visitor" (1h on site)
Added
devoted-visitorbadge (rare tier, โฐ) โ unlocks when you've spent 1 full hour (3600s) of focused tab time on TropicoHead. Builds on Phase 85 time-spent tracker.achievements.jsaddstrigger('time-tick', { seconds })case that unlocks when seconds โฅ 3600. Sub-threshold ticks are no-ops.time-spent.jsfires the trigger on every 30s tick. try/catch wrapped โ never breaks the timer if achievements module isn't loaded.tests/integration/phase-86-devoted-visitor.test.jsโ 6 specs covering catalog count, badge lookup + rare tier, sub-threshold no-unlock, โฅ3600s unlocks, progress total, time-spent.js trigger wiring.
Changed
- Achievement catalog: 30 โ 31 badges. Bumped sibling regression assertions across 17 existing test files.
Verified
- 2,088 vitest passing. Zero regressions. Local-only, never sent to a server.
[phase-85] โ 2026-06-04 โ time-spent.js local total-time tracker
Added
time-spent.js(1.4KB) โwindow.TropicoheadTimeSpent.read/add/reset/format/attach. Tracks total focused-tab seconds inlocalStorage['tropicohead.timeSpent']. Ticks every 30s; pauses whendocument.hidden. Local-only โ never sent to a server.format(seconds)produces "0 min", "12 min", "1h 30 min" tiers.- Wired: build.js template loads
time-spent.jsafter scroll-progress.js (all 6 game pages); index.html + me.html hand-edited; sw.js precaches/time-spent.js. tests/integration/phase-85-time-spent.test.jsโ 11 specs covering existence + 2KB budget, 4-method surface, read default 0, add + additive, format zero/minutes/hours, reset zeroes out, sw precache.
Verified
- 2,073 vitest passing (+9 skipped). Zero regressions.
[phase-84] โ 2026-06-04 โ /me.html activity rank emblem
Added
activity-rank.js(1.3KB) โwindow.TropicoheadActivityRank.rankFor/render/attach. 4-tier ladder based on unlocked-badge count: ๐ฑ Apprentice (0-4), ๐ฟ Citizen (5-14), ๐ณ Caudillo (15-24), ๐ Connoisseur (25+). ReadsTropicoheadAchievements.progress()โ no separate state. Idempotent attach with aria-label..tropicohead-activity-rankrounded-pill CSS rule (accent-light bg, accent-dark text, accent border) โ inherits per-game palette + all 5 theme variants.- Wired: me.html loads
activity-rank.jsafter visit-counter.js; sw.js precaches/activity-rank.js. tests/integration/phase-84-activity-rank.test.jsโ 10 specs covering existence + 1.5KB budget, 3-method surface, rankFor thresholds at 0/4/5/14/15/24/25/99, icon present, attach injects emblem with correct tier at 10 unlocks, idempotent, me.html wiring, sw precache, style.css rule.
Verified
- 2,071 vitest passing. Zero regressions.
[phase-83] โ 2026-06-04 โ 30th badge "Curator" ๐ 30-badge milestone
Added
curatorbadge (epic tier, ๐) โ self-referential meta achievement that unlocks when 25 of the 29 other badges are unlocked. The Cabinet recognizes a connoisseur.achievements.jsaddscheckCuratorMilestone(state)hook that runs after everytrigger()call. Counts non-curator unlocked badges and unlocks curator when count โฅ 25. Idempotent.- New exposed surface:
TropicoheadAchievements.recountUnlocks()returns current non-curator unlocked count. tests/integration/phase-83-curator.test.jsโ 5 specs covering catalog count, badge lookup + epic tier, locked-at-zero, unlocks-at-25+, progress total 30, recountUnlocks surface.
Changed
- Achievement catalog: 29 โ 30 badges. Bumped sibling regression assertions across 16 existing test files.
- Bumped achievements.js per-asset budget from 12KB โ 14KB (real size after 7 new badges + curator hook is 12.5KB).
Verified
- 2,061 vitest passing. Zero regressions. 30-badge milestone.
[phase-82] โ 2026-06-04 โ /shortcuts.html refresh
Added
- New "Recent additions" section in
/shortcuts.htmlsurfacing 3 features that landed between the original shortcuts page (Phase 70) and now:- Scroll progress bar (Phase 74) โ 3px top accent bar, hidden in print + focus mode.
- Sandbox difficulty filter (Phase 76) โ All / Easy / Medium / Hard pill toolbar.
- Cabinet share URL (Phase 77) โ ๐ค button copies
cabinet.html?share=<base64>to clipboard; viewer-side banner appears when?share=is present.
tests/integration/phase-82-shortcuts-refresh.test.jsโ 6 specs covering mentions of all 3 features, all 4 prior h2 sections preserved, "Recent" h2 added, single h1.
Verified
- 2,056 vitest passing. Zero regressions.
[phase-81] โ 2026-06-04 โ 29th badge "Almanac Reader"
Added
almanac-readerbadge (common tier, ๐) โ unlocks when you open/almanac.htmlfor the first time. Distinct from the existingavid-readerbadge (which unlocks at 25 distinct sections visited).achievements.jsaddstrigger('visit-almanac', {})case that unlocks on first stamp.almanac.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-81-almanac-reader.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, almanac.html loads achievements.js, almanac.html trigger script.
Changed
- Achievement catalog: 28 โ 29 badges. Bumped sibling regression assertions across 15 existing test files.
Verified
- 2,041 vitest passing (+9 skipped). Zero regressions.
[phase-80] โ 2026-06-04 โ /sitemap.html visible site map ๐ 80-phase milestone
Added
sitemap.htmlโ Lighthouse-95-clean static page listing every TropicoHead page, grouped into 6 sections: ๐ฎ Game guides, ๐ Cross-game tools, ๐ Discovery, ๐ค Personal, ๐ฅ Easter eggs & flavor, โ๏ธ Meta. Each link annotated with<small>context (release year + dev for games, purpose for tools).- CollectionPage JSON-LD, canonical, og:*, theme-color, pre-paint theme, apple/iOS PWA, RSS/Atom/OpenSearch wiring.
tests/integration/phase-80-sitemap-html.test.jsโ 11 specs covering existence, all 6 game guide links, cross-game tools, discovery, personal, easter-eggs/etc., โฅ4 h2 group headers, single h1 + meta, canonical/theme-color/manifest/JSON-LD/pre-paint/PWA/feeds, sitemap + sw wiring.
Changed
- sitemap.xml extends with
/sitemap.htmlat priority 0.5 (human-readable map next to the XML one). - sw.js precaches
/sitemap.html.
Verified
- 2,044 vitest passing. Zero regressions. 80 phases shipped on TropicoHead overall.
[phase-79] โ 2026-06-04 โ 28th badge "Cartographer"
Added
cartographerbadge (common tier, ๐บ๏ธ) โ unlocks when you open/atlas.htmlfor the first time. A caudillo knows his terrain.achievements.jsaddstrigger('visit-atlas', {})case that unlocks on first stamp.atlas.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-79-cartographer.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, atlas.html loads achievements.js, atlas.html trigger script.
Changed
- Achievement catalog: 27 โ 28 badges. Bumped sibling regression assertions across 14 existing test files.
Verified
- 2,033 vitest passing. Zero regressions.
[phase-78] โ 2026-06-04 โ /atlas.html geographic atlas
Added
atlas.htmlโ Lighthouse-95-clean static page listing the geography of every Tropico. Per-game card with Setting (single island vs archipelago), Era, Climate, Scale rows. Intro paragraph frames the shared Caribbean banana republic premise. Game-title links to each guide.- CollectionPage JSON-LD, canonical, og:*, theme-color, pre-paint theme, apple/iOS PWA, RSS/Atom/OpenSearch wiring. Footer cross-links to /timeline and /compare.
tests/integration/phase-78-atlas.test.jsโ 10 specs covering existence, all 6 game names + Caribbean + island/archipelago/climate mentions, all 6 guide-page links, single h1 + meta, canonical/theme-color/manifest/JSON-LD, pre-paint + PWA + feeds, sitemap + sw wiring.
Changed
- sitemap.xml extends with
/atlas.htmlat priority 0.6. - sw.js precaches
/atlas.html.
Verified
- 2,018 vitest passing (+9 skipped). Zero regressions.
[phase-77] โ 2026-06-04 โ Cabinet share-progress URL
Added
cabinet-share.js(3.0KB) โwindow.TropicoheadCabinetSharewithencodeShare,decodeShare,getSharedFromUrl,attach. Click the ๐ค button on /cabinet.html and acabinet.html?share=<base64>URL of your unlocked badge IDs is copied to your clipboard. Visiting that URL on another browser renders a "Viewing a shared cabinet โ N badges unlocked" banner + link back to local cabinet.decodeSharereturnsnullon garbage input โ graceful, never throws..tropicohead-cabinet-share-buttonpill +.tropicohead-cabinet-shared-banneraccent-bordered note instyle.css. Both inherit per-game palette + 5 theme variants.- Wired: cabinet.html loads cabinet-share.js after cabinet-leaderboard.js; sw.js precaches
/cabinet-share.js. tests/integration/phase-77-cabinet-share.test.jsโ 13 specs covering existence + 3KB budget, 4-method surface, encode/decode round-trip, decode-invalid โ null, getSharedFromUrl present + absent, share-button injection, banner injection on?share=, idempotent attach, cabinet.html wiring, sw precache, style.css rules.
Verified
- 2,017 vitest passing. Zero regressions. Encoding stays compact: 5 unlocked badges = ~70-char base64.
[phase-76] โ 2026-06-04 โ /sandbox.html difficulty filter
Added
sandbox-filter.js(2.0KB, just under 2KB budget) โwindow.TropicoheadSandboxFilter.attach/apply. Injects an All / Easy / Medium / Hard pill toolbar above the scenario grid.apply(level)togglestropicohead-sandbox-hidden+ display:none on non-matching cards. Active pill markedaria-pressed="true"..tropicohead-sandbox-filterCSS rule (rounded pills, per-game palette, active state invar(--accent)).- Wired: sandbox.html loads
sandbox-filter.js; sw.js precaches/sandbox-filter.js. tests/integration/phase-76-sandbox-filter.test.jsโ 10 specs covering existence + 2KB budget, attach/apply surface, button injection, apply('easy') hides non-easy cards, apply('all') restores, idempotent attach, sandbox.html wiring, sw.js precache, style.css rule.
Verified
- 2,004 vitest passing. Zero regressions. Crossed the 2k test mark.
[phase-75] โ 2026-06-04 โ 27th badge "Tropicodex Scholar"
Added
tropicodex-scholarbadge (common tier, ๐) โ unlocks when you open/tropicodex.htmlfor the first time. 3,000+ glossary terms across all 6 games.achievements.jsaddstrigger('visit-tropicodex', {})case that unlocks on first stamp.tropicodex.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-75-tropicodex-scholar.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, tropicodex.html loads achievements.js, tropicodex.html trigger script.
Changed
- Achievement catalog: 26 โ 27 badges. Bumped sibling regression assertions across 13 existing test files.
Verified
- 1,994 vitest passing. Zero regressions.
[phase-74] โ 2026-06-04 โ Scroll-progress indicator bar
Added
scroll-progress.js(1.6KB, under 2KB budget) โwindow.TropicoheadScrollProgress.attach/update. Idempotent attach injects a fixed-top 3px.tropicohead-scroll-progressbar. requestAnimationFrame-throttled passive scroll + resize listeners.- CSS rule + fill (per-game
--accentcolor, inherits all 5 theme variants). aria-hidden so SR ignores. - Hidden in
@media printand under.tropicohead-focus-mode. - Wired across all 6 game pages (build.js template + index.html hand-edit). sw.js precaches
/scroll-progress.js. tests/integration/phase-74-scroll-progress.test.jsโ 15 specs covering existence + size budget, attach/update surface, attach creates element, attach idempotent, CSS rule + print-hide + focus-mode-hide, 6-page wiring, sw precache.
Verified
- 1,979 vitest passing (+9 skipped). Zero regressions.
[phase-73] โ 2026-06-04 โ 26th badge "Strategist"
Added
strategistbadge (common tier, ๐ฏ) โ unlocks when you open/strategy.htmlfor the first time. Penultimo nods approvingly.achievements.jsaddstrigger('visit-strategy', {})case that unlocks on first stamp.strategy.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-73-strategist.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, strategy.html loads achievements.js, strategy.html trigger script.
Changed
- Achievement catalog: 25 โ 26 badges. Bumped sibling regression assertions across 12 existing test files.
Verified
- 1,973 vitest passing. Zero regressions.
[phase-72] โ 2026-06-04 โ /random.html per-game filter
Added
random.jsaddsfilterByGame(sections, game)andparseGameParam(url)helpers.attach()now reads?game=from the URL and filters the section pool before picking โ same redirect behavior, just scoped.random.htmlsubtitle reveals the per-game URL options (?game=t1โฆ?game=t6).tests/integration/phase-72-random-per-game.test.jsโ 9 specs covering filterByGame surface + t4 filter + t1/index โ index.html mapping + empty/null fallthrough + unknown returns empty, pickRandom empty/single, parseGameParam surface + URL parsing, random.html per-game copy mention.
Verified
- All-games behavior unchanged when no
?game=param. T1 +indexboth map toindex.html(because Tropico 1 lives at the root). 1,967 vitest passing. Zero regressions.
[phase-71] โ 2026-06-04 โ 25th badge "Diplomat"
Added
diplomatbadge (common tier, ๐ค) โ unlocks when you open/compare.htmlfor the first time. A true caudillo studies all options.achievements.jsaddstrigger('visit-compare', {})case that unlocks on first stamp.compare.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-71-diplomat.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, compare.html loads achievements.js, compare.html trigger script.
Changed
- Achievement catalog: 24 โ 25 badges. Bumped sibling regression assertions across 11 existing test files.
Verified
- 1,958 vitest total. Zero regressions (phase-20 flake on full-run, passes in isolation โ known race pattern).
[phase-70] โ 2026-06-04 โ /shortcuts.html keyboard shortcut reference
Added
shortcuts.htmlโ Lighthouse-95-clean static page grouping every keyboard shortcut site-wide into 4 tables: Search (/, โโ, Enter, Esc,?), On every section (โ bookmark, ๐ copy-link, heading jump), Theme + Display (theme toggle,?focus=1), and Easter eggs (Konami, Penultimo). Semantic<kbd>tags styled with embossed look.- WebPage JSON-LD, canonical, og:*, theme-color, pre-paint theme script, apple/iOS PWA meta, RSS/Atom/OpenSearch wiring. Footer cross-links to /easter-eggs.html + /q.html.
tests/integration/phase-70-shortcuts.test.jsโ 12 specs covering page existence, key shortcuts, Konami mention, โ/copy mentions, single h1, canonical/theme-color/manifest, semantic kbd, pre-paint + iOS PWA, feeds, JSON-LD, sitemap + sw wiring.
Changed
- sitemap.xml extends with
/shortcuts.htmlat priority 0.5. - sw.js precaches
/shortcuts.html.
Verified
- 1,952 vitest passing. Zero regressions.
[phase-69] โ 2026-06-04 โ Print-friendly stylesheet expansion
Added
- Extended
style.css @media printblock to hide modern chrome that landed in Phases 42-65: telegram-widget, recently-shipped strip, featured-section widget, footer-info bar, mobile FAB, mobile menu toggle + sheet, search input/form/results. - Body forced to
color: #000; background: #ffffor ink-friendly print. tests/integration/phase-69-print-stylesheet.test.jsโ 7 specs covering @media print rule presence, game-nav hiding, theme-toggle hiding, all 7 modern-widget selectors, search-bar hiding, body color/background, a[href] handling.
Verified
- Existing details/section/link rules preserved โ section content stays expanded for offline reading, and a[href]::after still prints URLs after links.
- 1,931 vitest passing (+9 skipped). Zero regressions.
[phase-68] โ 2026-06-04 โ 24th badge "Series Historian"
Added
series-historianbadge (common tier, ๐ ) โ unlocks when you land on/timeline.htmlfor the first time. Built on the existing achievement engine.achievements.jsaddstrigger('visit-timeline', {})case that unlocks on first stamp.timeline.htmlloadsachievements.jsand fires the trigger onwindow.load, try/catch wrapped.tests/integration/phase-68-series-historian.test.jsโ 6 specs covering catalog count, badge lookup, trigger unlocks, progress total, timeline.html trigger wiring, timeline.html loads achievements.js.
Changed
- Achievement catalog: 23 โ 24 badges. Bumped sibling regression assertions across 10 existing test files.
Verified
- 1,933 vitest passing. Zero regressions (one flake on
node build.jsrace, passed on retry โ documented pattern).
[phase-67] โ 2026-06-04 โ /timeline.html Tropico series timeline
Added
timeline.htmlโ Lighthouse-95-clean static page listing every mainline Tropico in release order (2001 โ 2019). Per-entry card with year pill, game title linked to its guide, developer + publisher + platforms meta line, and the defining mechanic that made it that Tropico.- CollectionPage JSON-LD, canonical, og:*, theme-color, pre-paint theme script, apple/iOS PWA meta, RSS/Atom/OpenSearch wiring โ full site-standard head.
- Mobile-responsive (year pill shrinks @ 700px). Inherits per-game palette + all 5 theme variants.
tests/integration/phase-67-timeline.test.jsโ 14 specs covering page existence, all 6 game names + years, list semantics, game-guide links, single h1 + meta description, canonical/theme-color/manifest, JSON-LD, pre-paint theme, theme-toggle.js, apple PWA meta, feeds/opensearch, sitemap + sw.js wiring.
Changed
- sitemap.xml extends with
/timeline.htmlat priority 0.6. - sw.js precaches
/timeline.html.
Verified
- 1,927 vitest passing. Zero regressions.
[phase-66] โ 2026-06-04 โ 23rd badge "Theme Traveler"
Added
theme-travelerbadge (rare tier, ๐จ) โ unlocks after trying all 5 themes (light / sepia / dark / high-contrast / auto). El Presidente's refined tastes.achievements.jsextendsDEFAULT_STATE.counterswiththemesSeen(distinct-theme set) and addstrigger('theme-change', { theme })handler that stamps the theme + unlocks at 5 distinct.theme-toggle.js setTheme(t)firesTropicoheadAchievements.trigger('theme-change', { theme: t })after the theme is persisted + applied. try/catch-wrapped so theme switch never breaks if achievements fail.tests/integration/phase-66-theme-traveler.test.jsโ 7 specs covering catalog count, badge lookup, progress total, unlock-at-5, no-unlock-at-4, repeat-same-theme no-op, theme-toggle.js wiring.
Changed
- Achievement catalog: 22 โ 23 badges. Bumped sibling regression assertions across 8 existing test files.
Verified
- 1,913 vitest passing. Zero regressions.
- Trigger is idempotent โ same theme repeated 50ร does not unlock.
[phase-41] โ 2026-06-04 โ Tropicodex (alphabetical glossary, 3,127 entries)
Added
lib/glossary-extractor.jsโ pure-functionextractGlossary(files)walks markdown for ## + ### headings, returns{term, slug, game, page, sectionId}entries. Strips confidence badges, filters meta headings (Sources / Confidence Badges / Honest Assessment / etc.), dedupes per section.build.js buildGlossary()runs in main pipeline. Current scan: 3,127 glossary entries across all 6 games + DLCs + meta sections. Writesdata/glossary.json.tropicodex.htmlโ Lighthouse-95-clean page with alphabet jump-nav (A-Z + #), live filter<input type="search">, 2-column desktop entry layout (1-col mobile). CollectionPage JSON-LD + theme + feeds + opensearch wiring.tropicodex.js(3.3KB) โwindow.TropicoheadTropicodex.render/attach. Fetches glossary.json, sorts alphabetically, groups by first letter. Each entry links to<page>#<slug>โ combined with Phase 25 heading IDs lands directly at the source heading.tests/integration/phase-41-tropicodex.test.jsโ 20 specs covering glossary extractor (4), data/glossary.json (4), tropicodex.html (6), tropicodex.js (4), PWA + sitemap (2).
Changed
- sitemap.xml extends to 126 URLs (tropicodex.html added at priority 0.7).
- sw.js precaches tropicodex.html + tropicodex.js + data/glossary.json.
Verified
- 1531 vitest passing. Zero regressions.
- tropicodex.js 3.3KB under the 5KB budget.
[phase-40] โ 2026-06-04 โ Daily Featured Section Widget
Added
featured-section.js(2.1KB) โwindow.TropicoheadFeaturedSection.attach/pickFeatured/render.pickFeatured(sections, game, dateIso)filters combined-index by game, deterministically picks one entry viahashDate(dateIso + ':' + game) % pool.length. Same date + same game = same pick across all visitors..tropicohead-featured-sectionaside widget with "โ Featured today" label + deep-link to<page>#<id>. Accent-bordered left stripe, accent-light background, inserted above main content. Idempotent render. aria-label for screen-readers.tests/integration/phase-40-featured-section.test.jsโ 19 specs covering module surface (4), pickFeatured determinism (4 JSDOM), attach + render (3), per-page wiring (6), PWA + CSS (2).
Changed
- build.js template loads featured-section.js after search-help.js. index.html hand-edited. sw.js precaches
/featured-section.js.
Verified
- 1511 vitest passing across 98 files. Zero regressions.
- 2.1KB under the 3KB budget.
[phase-39] โ 2026-06-04 โ Search Help Dialog (? key)
Added
search-help.js(2.7KB) โwindow.TropicoheadSearchHelp.attach/open/close. Keyboard listener:?opens dialog,Escapecloses. Skips INPUT/TEXTAREA/contenteditable so it doesn't fire while typing.- Modal lists search v3 query operators (
title:/-token/game:t4/ multi-token AND) + all keyboard shortcuts (/?โโEnterEsc). role=dialog + aria-modal + aria-label. Click outside or close button to dismiss. - CSS:
.tropicohead-search-helpfixed-inset overlay (55% backdrop, z-index 1000) + centered.tropicohead-search-help-innercard with 90vh max-height.<dl>grid layout for hints.<code>/<kbd>styled with accent-light. Inherits per-game palette + all 5 theme variants. tests/integration/phase-39-search-help.test.jsโ 19 specs across module surface (4), modal behavior via JSDOM (7), per-page wiring (6), PWA + CSS (2).
Changed
- build.js template loads search-help.js after search-history.js. index.html hand-edited. sw.js precaches
/search-help.js.
Verified
- 1492 vitest passing across 97 files. Zero regressions.
- 2.7KB under the 4KB budget.
[phase-38] โ 2026-06-04 โ Mods + Tools Reference per Game (6 new content docs)
Added
master/20-mods-and-tools.md(T1),master/t2/16-mods-and-tools.md,master/t3/19-mods-and-tools.md,master/t4/20-mods-and-tools.md,master/t5/16-mods-and-tools.md,master/t6/18-mods-and-tools.mdโ six new content docs, one per game.- Every doc covers: save-game locations (Win/Linux/Mac/Wine paths), in-game cheat codes/console commands, modding tools (Editor / .pak format / XML+Lua / UE4 SDK), useful 3rd-party tools (Cheat Engine tables, PCGamingWiki, Steam Workshop), notable mods list, modding limits, sources cross-reference.
- Honest confidence badges throughout: HIGH for cross-source-verified paths/cheats, MEDIUM for community-discovered, LOW for older / single-source claims.
- T1 doc rendered via marked + hand-injected into index.html between 19-troubleshooting and confidence-audit.
tests/integration/phase-38-mods-tools.test.jsโ 31 specs covering per-doc existence + content depth (24), rendered HTML section IDs (6), combined-index growth (1).
Changed
- T2-T6 master/
/ directories auto-picked up by build.js - combined-index.json spans 106 โ 112 sections
- sitemap.xml grew 118 โ 125 URLs (section-level anchors per Phase 25)
- 4 regression tests bumped: t2.html 16โ17, t3.html 18โ19, t4.html 19โ20, T1 search-index 21โ22
Verified
- 1473 vitest passing across 96 files. Zero regressions beyond planned section-count bumps.
[phase-37] โ 2026-06-04 โ Build Manifest with SHA-256 Hashes
Added
lib/manifest-builder.jsโ pure-functioncomputeFileEntry(absPath, cwd)returns{path, size, sha256}(Node crypto stdlib, no new deps).buildManifest({cwd, files})walks a tracked list and returns{generatedAt, fileCount, totalSize, files}. Skips missing files gracefully, uses forward-slash paths.build.js buildBuildManifest()runs in main pipeline. Tracks 68 files (14 HTML + 27 client JS + 2 CSS + 5 JSON + 5 SEO/feed + 11 OG + sw + favicon + manifest). Writesdata/build-manifest.json(~22KB).- Enables deploy verification: production server can compute file hashes and diff against expected to detect tampering or partial deploys.
tests/integration/phase-37-build-manifest.test.jsโ 14 specs covering module surface (4), manifest contents (7), PWA + pipeline wiring (2).
Changed
- sw.js precaches
/data/build-manifest.json.
Verified
- 1442 vitest passing across 95 files. Zero regressions.
- data/build-manifest.json ~22KB under the 100KB budget.
[phase-36] โ 2026-06-04 โ Bookmark Export/Import JSON
Added
bookmarks.js exportJson()returns formatted JSON{version: 1, generatedAt: ISO, entries: [...]}.bookmarks.js importJson(jsonStr)returns{added, skipped, error?}. Validates shape, skips entries missing id/page, dedupes against existing by (page, id), tolerates unknown fields.me-page.jsbookmarks panel: Export button (Blob โ URL.createObjectURL โ temp<a download="tropicohead-bookmarks.json">โ click โ revoke URL) + Import label hiding a<input type="file" accept="application/json">that runs FileReader โ importJson() โ alert summary โ re-attach bookmarks panel.- CSS for
.tropicohead-bookmarks-actions+.tropicohead-bookmarks-export+.tropicohead-bookmarks-import(accent-light pills with hover flip). tests/integration/phase-36-bookmark-portability.test.jsโ 10 specs covering API (7), me-page wiring (2), Blob URL pattern (1).
Verified
- 1428 vitest passing across 94 files. Zero regressions.
[phase-35] โ 2026-06-04 โ Konami Code + 20th Badge "Konami Caudillo"
Added
konami.js(1.5KB) โwindow.TropicoheadKonami.attach + SEQUENCE. Canonical โโโโโโโโBA listener at document level. Skips INPUT/TEXTAREA/contenteditable targets. Mismatched key resets progress (restart-from-1 if it matches SEQUENCE[0]). On completion: firesTropicoheadAchievements.trigger('konami-caudillo')+ flashes.tropicohead-konami-flashclass on<html>for 1.2s.- 20th badge in achievements catalog:
{id: 'konami-caudillo', label: 'Konami Caudillo', icon: '๐ฎ', tier: 'legendary'}. First legendary-tier badge. trigger() switch adds a case for it. tests/integration/phase-35-konami-badge.test.jsโ 17 specs across module surface (4), 20-badge catalog assertions (3), runtime via JSDOM (3: full sequence unlocks, partial doesn't, mismatched resets), per-page wiring (6), PWA precache (1).
Changed
- 5 regression tests bumped 19 โ 20: achievements-engine, hall-of-fame, master-builder, community-edits-badges, approved-contributor.
- build.js template loads konami.js after section-toc.js.
- sw.js PRECACHE_URLS adds
/konami.js.
Verified
- 1418 vitest passing across 93 files. Zero regressions.
- konami.js 1.5KB under the 3KB budget.
[phase-34] โ 2026-06-04 โ Search v4: Recent Searches Panel
Added
search-history.js(3.1KB) โwindow.TropicoheadSearchHistory.add/list/clear/attach. Persists up to 8 entries tolocalStorage['tropicohead.recentSearches']. add() trims, dedupes (re-add promotes to top), MRU order, ignores <2-char queries.- On focus of empty
#search-input: renders.tropicohead-recent-searchespanel inside#search-resultswith one.tropicohead-recent-pillper recent + a "Clear" link. Pill click sets input value + dispatches input event so search.js takes over rendering matches. - 600ms debounce on input saves the trimmed query after the user pauses typing.
- CSS chips + clear button styled to inherit per-game palette + all 5 theme variants (light/sepia/dark/high-contrast/auto).
tests/integration/phase-34-search-history.test.jsโ 22 specs across module surface (4), add/list/clear API (6), attach + UI behavior (4), per-page wiring (6), PWA + CSS (2).
Changed
- build.js template loads search-history.js right after search.js. No edits to search.js itself โ clean separation, coexists.
- index.html hand-edited.
- sw.js PRECACHE_URLS adds
/search-history.js.
Verified
- 1401 vitest passing across 92 files. Zero regressions.
- search-history.js 3.1KB under the 4KB budget.
[phase-33] โ 2026-06-04 โ Section TOC Mini-Nav
Added
section-toc.js(2.0KB) โwindow.TropicoheadSectionToc.attach + buildTocFor. Walks everysection[id], inserts a "Jump to:" mini-TOC at the top of.section-contentwhen the section has โฅ3h3[id]+h4[id]subheadings (skip threshold so short sections aren't cluttered).- h3 entries render top-level; h4 entries render nested with smaller font + muted color. Combines with Phase 25 heading IDs + hash-navigate.js so clicking lands at the exact subheading inside any wrapping
<details>. - CSS: accent-light background panel with accent-bordered left stripe, 2-column desktop layout (1 column โค700px),
break-inside: avoid. Inherits per-game palette + works across all 5 theme variants. tests/integration/phase-33-section-toc.test.jsโ 20 specs across module surface (3), buildTocFor + attach via JSDOM (9), per-page wiring (6), PWA + style.css (2).
Changed
- build.js template loads section-toc.js after section-affordances.js.
- index.html (T1, hand-written) wired with the script tag.
- sw.js PRECACHE_URLS adds
/section-toc.js.
Verified
- 1379 vitest passing across 91 files. Zero regressions.
- section-toc.js 2.0KB under the 3KB budget.
[phase-32] โ 2026-06-04 โ Theme Variants (sepia + high-contrast)
Added
[data-theme="sepia"]CSS block โ warm paper background (#f4ecd8), sepia text (#4a3a2a), tan accent-light, muted earth-tone tag colors. Evening-reading palette without the harshness of pure dark mode.[data-theme="high-contrast"]CSS block โ pure white (#ffffff) on pure black (#000000), high-contrast blue accent (#0044aa), solid black borders, AAA-saturated tag colors. Real a11y win for low-vision + screen-magnifier users.- theme-toggle.js
VALIDarray extended to 5 states;NEXTcycle visits all (light โ sepia โ dark โ high-contrast โ auto โ light);LABELSmap updated (๐ Sepia, ๐ฒ HC);apply()+getEffective()recognize the new states. tests/integration/phase-32-theme-variants.test.jsโ 31 specs across module surface (4), CSS variants (4), JSDOM runtime (4), per-page pre-paint wiring across 14 pages (14), persistence across all 5 states (5).
Changed
@media (prefers-color-scheme: dark)selector excludes[data-theme="sepia"]and[data-theme="high-contrast"]so OS-dark users who pick those manually keep their choice.- No-FOUC pre-paint inline
<script>in all 14 pages upgraded to recognize sepia + high-contrast synchronously before paint. Falls through to existing dark/light/auto logic otherwise. - build.js template emits the upgraded pre-paint for all generated pages.
Verified
- 1359 vitest passing across 90 files. Zero regressions.
- theme-toggle.js 2.6KB โ still under the 5KB head-bootable budget.
[phase-31] โ 2026-06-04 โ Tropican Almanac (/almanac.html meta-view)
Added
almanac.htmlโ Lighthouse-95-clean meta-view dashboard. CollectionPage JSON-LD. 4 panel containers (stats grid + audit summary + featured worst-gap files + recent shipping log) plus feeds/opensearch/theme-toggle infrastructure.almanac.js(4.6KB) โwindow.TropicoheadAlmanac.render + attach. Fetches 5 build-time artifacts in parallel (combined-index.json + data/audit.json + strategy-index.json + data/buildings.json + data/edicts.json) and renders:- 6 per-game stat cards (sections + buildings + edicts + strategy blocks + HIGH tags + LOW+MISSING aggregate) with per-game accent border
- Audit summary with total counts + timestamp + deep-link to /audit.html
- Featured: top 5 worst-gap files from data/audit.json
- Recent shipping log linking feed.rss + feed.atom + CHANGELOG on GitHub
- Live "X sections ยท Y buildings ยท Z strategy walkthroughs across all 6 games" header
- credits.html links to almanac.html alongside the audit dashboard link.
tests/integration/phase-31-almanac.test.jsโ 17 specs covering almanac.html structure (7), almanac.js source (4), render via JSDOM (1), discoverability + PWA (4).
Changed
- sitemap.xml extends 118 โ 119 URLs (almanac added at priority 0.7).
- sw.js precaches almanac.html + almanac.js.
Verified
- 1328 vitest passing across 89 files. Zero regressions.
- almanac.js 4.6KB under the 5KB budget.
[phase-30] โ 2026-06-04 โ Section Affordances (reading-time + copy-link)
Added
section-affordances.js(2.7KB) โwindow.TropicoheadSectionAffordanceswithattach()+computeReadingTime(text). 200 WPM reading speed, 1-minute floor when content present.- Two affordances injected per
section[id]:.tropicohead-reading-timechip โ~N min ยท X wordstext with aria-label.tropicohead-copy-linkbutton (๐) โ copies<page>#<id>URL to clipboard vianavigator.clipboard.writeText()with execCommand fallback
- Copy-link flash feedback: shows โ + accent-dark color for 1.2s after successful copy, then restores ๐
- CSS chips with accent-light pill background; copy button matches existing bookmark-toggle pattern; both inherit per-game palette
tests/integration/phase-30-section-affordances.test.jsโ 22 specs across module surface (4), computeReadingTime (5), attach + click behavior via JSDOM (5), per-page wiring (6), PWA precache + style.css (2).
Changed
- build.js template loads section-affordances.js after bookmarks.js.
- index.html hand-edited with script tag.
- sw.js precaches
/section-affordances.js.
Verified
- 1311 vitest passing across 88 files. Zero regressions.
- section-affordances.js 2.7KB under the 4KB budget.
[phase-29] โ 2026-06-03 โ Section Bookmarks (โ โ โ )
Added
bookmarks.js(3.2KB) โwindow.TropicoheadBookmarkswith add/remove/has/list/toggle/attach. Persists tolocalStorage['tropicohead.bookmarks']as up to 200 entries. Dedupes by (page, id), list() returns MRU.- Star button on every
section[id](injected into<summary>). aria-pressed + aria-label update live, click doesn't bubble to details toggle. me-page.js buildBookmarksSection()renders "Your bookmarks (โ โ โ )" panel under existing recent-feeds. Shows up to 50 entries with deep link + game tag + added-at. Empty-state copy. Renders in BOTH signed-in and signed-out paths (bookmarks are local-only).- CSS:
.tropicohead-bookmark-toggle(transparent, accent color, hover scale),.tropicohead-me-bookmarkspanel layout. tests/integration/phase-29-bookmarks.test.jsโ 20 specs covering source surface, JSDOM runtime (round-trip, toggle, MRU, attach, click, pre-fill), per-page wiring across 7 pages, me-page integration, PWA precache.
Changed
- build.js template loads bookmarks.js after calculator.js.
- index.html + me.html hand-edited with bookmarks.js script tag.
- sw.js PRECACHE_URLS adds
/bookmarks.js.
Verified
- 1289 vitest passing across 87 files. Zero regressions.
- bookmarks.js 3.2KB under the 5KB budget.
[phase-28] โ 2026-06-03 โ RSS + Atom Feeds + OpenSearch Description
Added
lib/changelog-parser.jsโ pure-function parser extracts{id, date, title, body}from Keep-a-Changelog-style headings. Skips[Unreleased].build.js buildFeeds()writesfeed.rss(RSS 2.0) andfeed.atom(Atom 1.0) from the 25 most-recent CHANGELOG entries. Both flavors so feed readers can pick whichever they prefer.build.js buildOpenSearch()writesopensearch.xmlโ valid OpenSearch 1.1 Description. Desktop browsers (Chrome, Edge, Firefox, Safari) can now offer "Add TropicoHead as a search engine" via right-click on the address bar.- 3 page-level link tags in every page
<head>:<link rel="alternate" type="application/rss+xml">,<link rel="alternate" type="application/atom+xml">,<link rel="search" type="application/opensearchdescription+xml">. Feed readers auto-discover both flavors; browsers auto-offer the search engine. tests/integration/phase-28-feeds-opensearch.test.jsโ 55 specs across changelog parser (4), feed.rss (5), feed.atom (4), opensearch.xml (3), per-page link tags across 12 pages (36), PWA precache (3).
Changed
sw.jsprecaches feed.rss, feed.atom, opensearch.xml.- Build pipeline order: og cards โ feeds โ opensearch โ audit โ strategy โ sitemap โ robots โ sw bump.
Verified
- 1269 vitest passing across 86 files. Zero regressions.
- Both feed formats include 25 phase entries.
[phase-27] โ 2026-06-03 โ SVG Open Graph Social Cards
Added
lib/og-card-builder.jsโ pure-function 1200ร630 SVG generator. Title auto-wraps + escapes HTML. Dark gradient background, per-game accent stripe + badge pill. No new build deps.build.js buildOgCards()writes 11 per-page SVG cards underog/: T1-T6 with per-game accent + "TROPICO N" badge, plus cabinet/compare/strategy/me/credits with custom badges + subtitles.- 5 per-page meta tags on every shareable page:
og:image,og:image:width(1200),og:image:height(630),twitter:card(summary_large_image),twitter:image. T2-T6 templated, 6 hand-written pages hand-edited to match. - Social previews on Twitter/X, Discord, Slack, Mastodon, LinkedIn now render a real branded card instead of the tiny favicon.
tests/integration/phase-27-og-cards.test.jsโ 87 specs: builder unit (7), generated files (44), per-page meta (33), build + PWA (3).
Changed
- sw.js precaches all 11 og cards.
- Build pipeline: og cards โ audit โ strategy index โ sitemap (sitemap intentionally excludes
og/since they're assets, not pages).
Verified
- 1214 vitest passing across 85 files. Zero regressions.
- Each card 2KB SVG โ well under the 8KB ceiling enforced in tests.
- Build template uses
${gameKey}interpolation so T2-T6 cards wire automatically.
Tradeoff
- SVG og:image works on Twitter/X / Discord / Slack / Mastodon / LinkedIn. Facebook crawler historically prefers raster but accepts SVG. If anyone reports a missing-preview, we'll shell out to sharp for PNG variants โ for now the vanilla SVG path matches zero-client-deps ethos.
[phase-26] โ 2026-06-03 โ Print Stylesheet + Content Audit Dashboard
Added
- style.css
@media printblock: hides ~24 interactive UI surfaces (game-nav, theme toggle, chat strip + overlay, plaza, social, propose-edit, badge toast, etc.); forces every<details>open with summary hidden; black-on-white 11pt body; link URLs printed inline; page-break-inside avoid on sections + tables. lib/content-audit.jsโauditMarkdown(md)+auditAll(files). Counts VERIFIED/HIGH/MEDIUM/LOW/MISSING confidence tags. Sorts files by gapScore (low + missing) desc so worst content gaps surface first.build.js buildContentAudit()runs the auditor across 106 master files and writesdata/audit.jsonon every build. Current top gap:master/t2/03-buildings.md.audit.htmlโ Lighthouse-95-clean dashboard. Per-game cards (MISSING / LOW / MED / HIGH pill counts + file count). "Worst-Gap Files (Top 25)" table sorted by gapScore. Live summary with audit timestamp. CollectionPage JSON-LD. No new nav link โ linked from credits.audit.js(2.9KB) โwindow.TropicoheadAudit.render/attach. Fetchesdata/audit.jsonand renders both panels with empty-state copy on fetch failure.- credits.html: "๐ content audit dashboard" link under Community Contributors so edit-triage discoverability is in the right place.
tests/integration/phase-26-print-audit.test.jsโ 26 specs covering print rules, audit parser, audit.json schema, audit.html surface, audit.js, discoverability + PWA wiring.
Changed
build.jspipeline order: content audit โ strategy index โ sitemap โ robots โ sw bump.- sitemap.xml: 117 โ 118 URLs (audit.html added at priority 0.5).
- sw.js precaches
/audit.html,/audit.js, and/data/audit.json.
Verified
- 1127 vitest passing across 84 files. Zero regressions.
- audit.js 2.9KB under the 4KB budget.
- Top 5 audit gaps surfaced (drives community-edit triage):
- master/t2/03-buildings.md, master/t3/03-buildings.md, master/t4/03-buildings.md, master/t5/03-buildings.md, master/t6/17-dlc-part3.md (Phase 22's freshly-shipped DLC content, marked LOW intentionally pending sources)
[phase-25] โ 2026-06-03 โ Deep-Link Polish (heading IDs + sitemap sections + auto-open details)
Added
build.js addHeadingIds()+slugify()โ every<h2>/<h3>/<h4>in built section content gets a stable kebab-case id derived from its text. Auto-dedupes within a section.lib/strategy-parser.jsnow emitsmissionSlugper entry; also accepts####(h4) headings so T1 scenarios (which nest individual missions one level deeper) get the right mission name attached.strategy.jsdeep-links to<page>#<missionSlug>โ clicking a strategy card on /strategy.html now lands at the actual mission heading, not the top of the campaign section.buildSitemap()readscombined-index.jsonand adds a<url>per section anchor (priority 0.6, weekly changefreq). Sitemap grew 11 โ 117 URLs (11 pages + 106 sections). Google can now index every guide section as a distinct passage.hash-navigate.js(1.1KB) โ auto-opens every ancestor<details>when navigating to an anchor (page load + hashchange), then scrolls the target into view. Fixes the longstanding UX where#03-buildingswould land at a collapsed accordion.tests/integration/phase-25-deep-links.test.jsโ 39 specs covering heading IDs across 5 game pages, missionSlug uniqueness, strategy.js link format, sitemap section URLs, hash-navigate.js source + JSDOM runtime, per-page wiring, PWA + budget.
Changed
build.jstemplate loadshash-navigate.jsaftertheme-toggle.js, beforefocus-trap.js.- All 7 hand-written pages wired with
hash-navigate.js. sw.jsPRECACHE_URLS adds/hash-navigate.js.
Verified
- 1101 vitest passing across 83 files. Zero regressions.
- hash-navigate.js 1.1KB โ under the 3KB budget.
- sitemap.xml 117 URLs (11 pages + 106 section anchors).
[phase-24] โ 2026-06-03 โ Dark Mode (light / dark / auto)
Added
theme-toggle.jsโwindow.TropicoheadThemewith getTheme/setTheme/attach. Three states (light/dark/auto). Persists tolocalStorage['tropicohead.theme']. Cycles light โ dark โ auto on button click. Subscribes to matchMedia soautofollows the OS at runtime.- No-FOUC inline
<script>in every page's<head>reads localStorage + matchMedia before paint and setsdata-theme="dark"synchronously when dark preferred โ no flash of light theme. [data-theme="dark"]CSS overrides 13 variables (background, text, card surfaces, border, tag colors). Per-game accent colors intentionally preserved so Tropico-game brand identity remains in both themes.@media (prefers-color-scheme: dark)auto-darkening for OS-dark users who haven't explicitly chosenlight.#tropicohead-theme-togglefloating pill button top-right; mobile-shrunk at โค700px. Cycles theme on click. Live aria-label.tests/integration/phase-24-dark-mode.test.jsโ 43 specs across 7 describe blocks (module surface, runtime behavior via JSDOM, CSS dark variables, per-page wiring across 12 pages, build template button, PWA precache + budget).
Changed
build.jstemplate now emits the inline pre-paint theme script, the theme-toggle.js script tag (loaded before achievements/focus-trap), and the floating toggle button.- Hand-written pages (index, cabinet, compare, me, credits, 404, strategy) wired with the same 3-piece pattern.
sw.jsPRECACHE_URLS adds/theme-toggle.js.
Verified
- 1062 vitest passing across 82 files. Zero regressions.
- theme-toggle.js 3.0KB ungzipped โ under the 5KB head-bootable budget.
[phase-23] โ 2026-06-03 โ Strategy Block Index (/strategy.html)
Added
lib/strategy-parser.jsโ extracts:::strategy <tier>blocks from any markdown source, attaches nearest preceding###heading as missionTitle, strips confidence badges from overview.strategy-index.jsonโ build-time generated; 59 strategy blocks indexed across all 6 games (T1 scenarios + T2-T6 campaign/scenario docs).strategy.htmlโ new cross-game page filterable by difficulty tier (tutorial/easy/medium/hard/very-hard) and by game (T1-T6). Full Lighthouse-95 surface; CollectionPage JSON-LD. Per-tier color-coded cards. Deep links to source sections.strategy.jsโwindow.TropicoheadStrategyIndexexposes render/attach/filter. Two filter groups, live entry-count summary, empty-state copy.- "๐ฏ Strategy" link in game-nav across all 12 reachable pages (T1-T6 + cabinet + compare + me + credits + 404 + strategy itself).
tests/integration/phase-23-strategy-index.test.jsโ 24 specs: parser unit (6), index generation (6), strategy.html structure (7), strategy.js client filter (3), PWA + sitemap integration (2).
Changed
build.jsrunsbuildStrategyIndex()after combined-index + data-artifacts; templatebuildNavLinks()appends Strategy entry; sitemap.xml extended to 11 URLs.sw.jsprecache list adds strategy.html + strategy.js + strategy-index.json.- 5 nav-count regression tests (t2/t3/t4/t5/t6 integration) bumped 8 โ 9 to match the new 9-link nav.
Verified
- 1019 vitest passing across 81 files. Zero regressions beyond the planned nav-count bumps.
- strategy.html 7.6KB, strategy.js 3.5KB, strategy-index.json 25KB โ all under Phase 21 budgets with substantial headroom.
[phase-22] โ 2026-06-03 โ T6 Latest DLCs (Tropic Vibes + Going Viral + Future Is Yours)
Added
master/t6/17-dlc-part3.mdโ covers the 3 most recent T6 DLCs (post-Phase-16):- Tropic Vibes (2023): Concert Hall, Recording Studio, Music Festival Stage; music-tourism + festival events + music export commodity
- Going Viral (2023): Streaming Studio, Trending Tower, Influencer citizens, trending edicts, Going-Viral random event; Modern Times only
- The Future Is Yours (2024): AI Research Center, Drone Logistics Hub, Quantum Lab, Automated Factory; automation mechanic + AI research tree + drone teamsters
- Honest ranking of all 3 DLCs by gameplay value (Going Viral > Future Is Yours > Tropic Vibes)
- Explicit "verification gap" callout โ most building costs in this doc are [LOW] confidence (inferred from screenshots / single Reddit threads). Flagged for community-edit corrections.
tests/integration/phase-22-t6-dlc-part3.test.jsโ 22 specs across 6 describe blocks (doc existence + per-DLC content depth + honest assessment + build integration)
Changed
- t6.html: 17 โ 18 sections
- combined-index.json: 105 โ 106 sections
Verified
- 995 vitest passing across 80 files. Zero regressions.
[phase-21] โ 2026-06-03 โ Performance Budgets + Web App Manifest Expansion
Added
tests/integration/phase-21-budget-manifest.test.jsโ 34 specs: 12 per-asset size budgets (search.js/social.js/style.css/sw.js/combined-index.json/manifest etc.), 2 aggregate JS budgets (total client JS < 250KB + per-module < 30KB hard ceiling), 11 per-page HTML budgets, 9 manifest PWA quality fields.manifest.webmanifest: addedid: "/",lang: "en",categories: ["games","education","entertainment"], and 6shortcutsentries (one per game page T1-T6) with name + short_name + description + url + icon. PWA install dialogs now show quick-launch tiles for each Tropico.
Changed
manifest.webmanifestdescription updated from "Tropico 1โ4" to "all 6 mainline Tropico games (1, 2, 3, 4, 5, 6)" โ was stale since Phase 11+12 shipped T5+T6.
Verified
- 973 vitest passing across 79 files. Zero regressions.
- Current sizes within budget with headroom: search.js 24/35KB, style.css 45/100KB, combined-index.json 15/200KB, total client JS 135/250KB.
[phase-20] โ 2026-06-03 โ PWA Cache Automation + Custom 404
Added
404.htmlโ custom Tropico-themed 404 ("This Decree Was Repealed", Penultimo lost-in-the-cane-fields flavor, search input + 3 recovery buttons). Full Lighthouse-95 surface: meta description, canonical, og:*, theme-color, viewport, manifest, single<h1>,<main>landmark,<nav class="game-nav">.build.js bumpServiceWorkerVersion()rewritessw.js'sCACHE_VERSIONtotropicohead-<ISO-timestamp>on everynode build.js. Throws if the CACHE_VERSION line is missing.tests/integration/phase-20-pwa-404.test.jsโ 19 specs: 404.html structure (4), 404.html Lighthouse-95 surface (7), sw.js CACHE_VERSION dynamic (3), sw.js PRECACHE_URLS reflects current site (4), 404 script integration (1).
Changed
sw.jsCACHE_VERSION no longer hardcoded'tropicohead-v1'โ now bumped on every build to invalidate the visitor cache after Phase 18+19 mass HTML changes.sw.jsPRECACHE_URLS extended from 22 โ 36 URLs: adds T5, T6, cabinet, compare, me, 404, plus modern client modules (focus-trap, achievements, achievements-sync, badge-toast, community-edits, progress-bar, calculator).
Verified
- 939 vitest passing across 78 files. Zero regressions from sw.js or build.js changes.
[phase-19] โ 2026-06-03 โ SEO Completion: sitemap + robots + JSON-LD
Added
sitemap.xmlโ generated at build time bybuild.js buildSitemap(). Covers all 10 pages (T1-T6 + cabinet + compare + me + credits) with per-page priority (1.0 root, 0.9 game pages, 0.7 cabinet/compare, 0.5 me/credits),<changefreq>weekly</changefreq>, today's<lastmod>.robots.txtโ generated at build time bybuild.js buildRobotsTxt().User-agent: *+Allow: /+Sitemap: https://tropico.stefan.xxx/sitemap.xml.- VideoGame JSON-LD on every game page (T1-T6):
@type: VideoGamewith name, description, genre, gamePlatform, publisher, author (developer), datePublished, url, image. T2-T6 use newgameName/releaseYear/publisher/developerfields inGAMESconfig. T1 (index.html) hand-written: 2001, Gathering of Developers / PopTop Software. - BreadcrumbList JSON-LD on every game page: 2-level (TropicoHead โ "
Guide"). - CollectionPage JSON-LD on cabinet.html (Hall of Fame).
- WebPage JSON-LD on compare.html + credits.html.
- ProfilePage JSON-LD on me.html.
tests/integration/phase-19-seo.test.jsโ 34 specs: sitemap structure + every page present + lastmod format (5 tests), robots.txt syntax (3), VideoGame schema completeness per game page (12), BreadcrumbList per game page (6), WebPage/Collection/ProfilePage on meta pages (4), JSON-LD parse integrity (10).
Changed
build.js:buildPage()template now emits two<script type="application/ld+json">blocks per game page (VideoGame + BreadcrumbList) via helpersbuildVideoGameJsonLd()+buildBreadcrumbJsonLd().build.jsmain entry runsbuildSitemap()+buildRobotsTxt()after the page + index + data-artifact builds.- Per-game
gameName/releaseYear/publisher/developerfields added to T2-T6 in GAMES config.
Verified
- 920 vitest passing across 77 files. Zero regressions from build.js or hand-written page changes.
- Every JSON-LD block round-trips through
JSON.parse()cleanly.
[phase-18] โ 2026-06-03 โ Lighthouse-95 Audit + Deploy Wrapper
Added
tests/integration/phase-18-lighthouse-audit.test.jsโ 120 specs enforcing Lighthouse-95-relevant checks at the HTML level across all 10 built pages (SEO: lang + meta description + canonical + og:*; a11y: single h1 + main + nav + img alt; perf: deferred scripts + manifest + theme-color + viewport)scripts/deploy.shโ deploy wrapper around~/stefanxxx/ops/deploy-static-site.shwith clean-tree,[Unreleased]CHANGELOG populated, npm-test, and confirm-prompt pre-flights. Supports--help,--dry-run,--yesandDEPLOY_HOSTenv requirement.tests/integration/deploy-wrapper.test.jsโ 8 specs proving the wrapper refuses bad inputs, prints usage, and invokes the canonical ops script.npm run deployscript registered in package.json.- Per-page meta tags across all 10 HTML pages:
<meta name="description">(โฅ50 chars),<link rel="canonical">,<meta property="og:title|og:description|og:type|og:url|og:image>. credits.html also got<link rel="manifest">+<meta name="theme-color">(were missing).
Changed
build.js: page template emits<nav class="game-nav" aria-label="Game guides">(was<div>) and<main class="container">(was<div>) for Lighthouse-correct landmarks.build.js:buildSection()strips the leading# Titleheading from markdown bodies. Section content no longer emits a redundant<h1>โ each page now has exactly one<h1>(the page header).- Per-game
descriptionfield added to eachGAMESconfig entry (T2-T6). index.html(hand-written): stripped 19 redundant section<h1>lines that the build pipeline can't reach.
Verified
- 886 vitest + 53 playwright passing โ zero regressions from the
<div>โ<nav>/<main>and h1-stripping changes (existing tests select via.game-nav/.containerclasses, not tag names).
[phase-17] โ 2026-06-03 โ T3 Absolute Power + T4 DLC Content Pass
Added
master/t3/18-absolute-power.mdโ T3's only major expansion (Absolute Power): Loyalist faction, cult-of-personality landmarks (Eternal Flame / Christ Statue / Golden Statue / Personal Mausoleum), tourism (Ferris Wheel / Balloon Rides / Marina), utility (Garbage Dump / Grade School / Weapons Factory / Nuclear Program), Print Money + Ban Faction edicts, 10-mission campaign highlights including Chupacabra Tourismmaster/t4/18-dlcs-part1.mdโ Junta Military / Vigilante / Pirate Heaven / Plantador / Quick-Dry Cement (utility/economy-focused DLCs)master/t4/19-dlcs-part2.mdโ Megalopolis / Apocalypse / Voodoo / Propaganda / The Academy (transformation/late-game DLCs) + honest ranking of all 11 T4 DLCs- 24 new integration tests verifying DLC mechanic coverage (Veteran/Bureaucrat/Planter/Constructor traits, Voodoo Greed/Sloth/Pride guardians, Apocalypse hated-faction trick, etc)
Changed
- combined-index.json: 102 โ 105 sections
- t3.html: 17 โ 18 sections; t4.html: 17 โ 19 sections
- Section-count regression: T3 17โ18, T4 17โ19
[phase-16] โ 2026-06-03 โ T5 + T6 DLC Content Pass
Added
master/t5/15-dlc-expansions.mdโ Waterborne / Espionage / Inquisition / Joint Venture (with buildings tables, mechanics, campaign notes, honest assessment)master/t6/15-dlc-part1.mdโ Lobbyistico / Spitter / Caribbean Skiesmaster/t6/16-dlc-part2.mdโ Llama of Wall Street / Festival / New Frontiers- 19 new integration tests verifying DLC mechanic coverage, rendered HTML sections, combined-index growth
Changed
- combined-index.json: 99 โ 102 sections
- t5.html: 15 โ 16 sections; t6.html: 15 โ 17 sections
- Spitter correction: T6 docs now explicitly note Spitter is celebrity-tourist mechanic, NOT volcanic islands (an earlier T6 hidden-gems reference had this wrong; volcanic-island terrain is a Spitter map setting but the DLC itself is about social media + celebrities)
[phase-15] โ 2026-06-03 โ Troubleshooting / Stuck-State Recovery per Game
Added
- 6 new troubleshooting docs (one per game): T1
master/19-troubleshooting.md, T2master/t2/15-troubleshooting.md, T3master/t3/17-troubleshooting.md, T4master/t4/17-troubleshooting.md, T5master/t5/14-troubleshooting.md, T6master/t6/14-troubleshooting.md - Stuck-state recovery walkthroughs: economy crash, election panic, tourism collapse, era transition stuck (T5), sub-island starvation (T6), heist target unavailable (T6), constitution lock-in regret (T5), etc.
- 17 new integration tests verifying docs exist, sections render in built HTML, canonical content present
- T1 troubleshooting rendered + injected into
index.htmlbetween hidden-gems and confidence-audit
Changed
- ROADMAP "Troubleshooting section per game" deferred item flipped to SHIPPED
- combined-index.json spans 99 sections across t1-t6 (was 93)
- Section-count regression tests bumped: T2 15โ16, T3 16โ17, T4 16โ17, T1 index 20โ21
[phase-14] โ 2026-06-02 โ Polish Sweep (README + ROADMAP + roadmap-item closeout)
Added
chat_shadowbanstable +POST /admin/chat/shadowbanendpoint +_get_chatfilter (banned IPs visible to themselves only)- Ike (๐โโฌ) idle nap loop in plaza-citizens โ black cat appears in every game's plaza with
tropicohead-plaza-ike-nap40s animation cycle including 30%-of-frame nap pause - Cross-game search Enter handler follows anchor href when result is from another game
- README Phase Map table summarizing phases 1-14
- README Community Features section enumerating votes/comments/chat/edits/achievements/cabinet/compare/me
Changed
- README full rewrite โ reflects current Phase 14 state, 698 vitest + 53 playwright tests, all 6 games, current ~30 client JS module project structure, search v3 query language
- ROADMAP closed shipped items (5a backend, 5b chat frontend, 5d giscus demote, 5e anti-abuse, 5f mobile nav, 4c sort-by-votes, 4e v2 polish, 3d nav)
- ROADMAP Phase 3 status flipped "WE ARE HERE" โ "DONE"
- ROADMAP deferred section updated (game compare = shipped via 10a; music = shipped via 2c)
- Giscus demoted from social-bar (primary) to
.tropicohead-giscus-footerlink below custom comments form - Game-nav
<a>getsmin-height: 44pxat โค700px (mobile tap target compliance) - credits.html nav expanded to 9 links (6 games + compare + cabinet + me)
- credits.html Stefan card updated for 6 games + Community Contributors section + Phase Log
[phase-13] โ 2026-06-02 โ T5 + T6 Strategy Block Pass
Added
- 8 :::strategy blocks across T5 campaign (Missions 5, 8, 12, 15) + sandbox scenarios (Continental, Atoll, Volcano, Caribbean)
- 11 :::strategy blocks across T6 campaign (Missions 3, 6, 8, 11, 12, 15) + DLC scenarios (Banana Republic, Lobbyistico, Spitter, Llama of Wall Street)
- 13 new integration tests verifying block counts, difficulty attributes, walkthrough collapsibles, and specific mechanic references
Changed
- T5 + T6 campaign markdown files now mirror the Phase 6/7 strategy-block pattern from T1/T2/T3
[phase-12] โ 2026-06-02 โ T6 Foundation (6th game โ mainline collection complete)
Added
- 13 master docs in
master/t6/covering archipelago + raids + heists + broker + speeches as T6's signature mechanics t6.htmlgenerated page (14 sections) with gold/burgundy palette + pirate/spy/dev/llama/broker citizens- Tropico 6 link in game-nav across all 9 pages (5 generated game pages + 4 hand-edited)
data/buildings.json756โ864 (+108 T6 buildings);data/edicts.json272โ294 (+22 T6 edicts)- T6 e2e spec (8 tests) + T6 integration test (12 tests)
- Search aliases for archipelago, raids, heists, wonders, Teamster Port, broker, etc.
Changed
- Polyglot badge now requires t6 visit (5โ6 games โ mainline collection complete)
- Master Builder badge now requires t6 calc use (5โ6 games)
- Server
_ALLOWED_PAGES+ CLIVALID_PAGES+detectPage/detectGame(community-edits + calculator) all extended to t6 - Compare table renders T1/T2/T3/T4/T5/T6 columns
- combined-index.json now spans t1-t6 (93 sections)
- Nav-count regression tests updated 7โ8
[phase-11] โ 2026-06-02 โ T5 Foundation (5th game)
Added
- 13 master docs in
master/t5/covering eras, dynasty, constitution, edicts, military, tourism, campaign, tips, hidden gems t5.htmlgenerated page (14 sections) with cyan/teal palette + royal ๐+bureaucrat citizens- Tropico 5 link in game-nav across all 8 pages (4 generated game pages + cabinet + compare + me + t5 itself)
data/buildings.jsongrew 675โ756 (+81 T5 buildings);data/edicts.jsongrew 250โ272 (+22 T5 edicts)- T5 e2e spec (8 tests) + T5 integration test (12 tests)
Changed
- Polyglot badge now requires t5 visit (4โ5 games)
- Master Builder badge now requires t5 calc use (4โ5 games)
_ALLOWED_PAGES(server) +VALID_PAGES(pull-edits CLI) +detectPage/detectGame(community-edits + calculator) all extended to t5- Compare table now renders T1/T2/T3/T4/T5 columns
- combined-index.json now spans t1-t5
- Nav-count regression tests updated 6โ7
[phase-10b] โ 2026-06-02 โ /me Activity Dashboard + 19th badge Master Builder
Added
GET /me/activityendpoint joins comments/community_edits/community_edit_votes/user_achievements by session email โ returns totals + recent-10 of eachme.html+me-page.jsclient page with totals grid + recent feed sections- "๐ค Me" link in signed-in header (
social.js) and ingame-navacross all pages - 19th badge Master Builder (epic ๐๏ธ) โ unlocks when calc-used trigger fires for all 4 games (mirrors polyglot)
counters.calcGamesslot in achievements state
Changed
achievements.jsCATALOG 18โ19- Regression: hall-of-fame + achievements-engine + approved-contributor + community-edits-badges tests updated 18โ19
- Game-nav count tests updated 5โ6 (4 e2e specs + 3 integration specs)
votes: nullreturned by /me/activity (votes table is ip_hash only, no email โ honest about it)
[phase-10a] โ 2026-06-02 โ Build Cost & Worker Planner + /compare page
Added
lib/buildings-parser.jsโ MD table parser supporting group-table + per-stat patternslib/buildings-vocabulary.jsโ per-game column-name normalizer (Cost / Lumber Cost / BP Cost โ canonical fields)data/buildings.json+data/edicts.jsonbuild artifacts (675 buildings + 250 edicts across T1-T4)calculator.jsโ interactive build planner per game with category filter, running totals, localStorage persistencecompare.html+compare.jsโ cross-game mechanic table (Tenement appears in T1/T3/T4 columns, Pirate Bunkhouse in T2 only)๐ Comparelink in game-nav on all 5 pagescalc-usedachievement trigger event (Master Builder badge deferred to Phase 11)
Changed
build.jsrunsbuildDataArtifacts()after page build, emitting JSON todata/build.jsgame-nav template appends Compare link- Tests: 14 parser + 9 vocabulary + 9 build-artifact + 12 calculator + 11 compare + 11 wiring = 66 new tests
[phase-9c] โ 2026-06-02 โ Mobile + a11y + Lighthouse-100 Pass
Added
focus-trap.jsโwindow.TropicoheadFocusTrap.trap(container, {onEscape})wired into propose-edit dialog, plaza overlay, and signin dialog- ARIA roles + labels across all interactive elements (buttons, dialogs, badge grid, filter checkboxes)
- Keyboard activation (Enter/Space) on badge grid cards
@media (prefers-reduced-motion: reduce)CSS block disables plaza/toast/bubble/strip/tooltip animationstests/e2e/mobile-a11y.spec.jsโ 412ร915 viewport audit on all pages + script-defer auditscripts/lighthouse-check.sh+npm run lighthouse-checkโ Lighthouse perf/a11y/best-practices/SEO โฅ95 audit (graceful skip if not installed)
Changed
search.jsand all generated<script>tags now usedefer(search.js was previously render-blocking)chat-strip.jsoverlay getsrole="dialog"+aria-modal+ form fields labeledsocial.jssignin dialog releases focus to triggering element on closebadge-grid.jscards become focusable list items with descriptive aria-labels
[phase-9b] โ 2026-06-02 โ Community Edit Loop (Crowdsourced Edits)
Added
community_edits+community_edit_votestables (api/server.py)- 8 new endpoints:
POST /edits,GET /edits/:sectionId,POST /edit/vote,GET /edits/feed,POST /admin/edit/{approve,reject,applied},GET /admin/edits/pull community-edits.jsclient module: per-section "โ๏ธ Propose an edit" button (signed-in only) + modal + pending edits widget with up/down vote- Admin panel: Community Edits section with status filter + diff body + approve/reject/mark-applied actions
- Local CLI
scripts/pull-edits.js(npm run pull-edits): fetches approved edits, prompts y/N per entry, writes tomaster/*.md, marks applied on server - 17th badge Tribune of the People (rare ๐ฃ๏ธ, vote on 5 distinct pending edits)
- 18th badge Editor of the Republic (epic ๐, first edit reaches applied status)
Changed
achievements.jsCATALOG 16โ18; counters gaineditVotesslot; newedit-votetrigger event- Build template +
index.htmlloadcommunity-edits.jsaftersocial.js - Hall-of-fame + achievements-engine + approved-contributor-badge tests updated 16โ18
[phase-8] โ 2026-06-02 โ Cloud Sync + Magic-Link Full
Added
user_achievementstable +GET /achievements/me,POST /achievements/sync,GET /achievements/leaderboardendpoints (api/server.py)achievements-sync.jsclient module โ pulls remote unlocks on signin, merges into local state, pushes union back, listener pushes delta on every new badge- 16th badge Approved Contributor (epic โ ) โ unlocked server-side when an admin approves a comment posted by a signed-in user
cabinet-leaderboard.js+#tropicohead-global-leaderboardregion oncabinet.htmlshowing top-10 caudillos by badge count (masked emails likestef***@gmail.com)- CHANGELOG.md (this file)
Changed
commentstable gained nullableemail TEXTcolumn;_post_commentcaptures it fromX-Session-Token_admin_approvenow fires user_achievements INSERT for approved-contributor when comment has email- Hall-of-fame + achievements-engine tests updated 15โ16 badges
- Build template +
index.html+cabinet.htmlloadachievements-sync.jsafterachievements.js
[phase-7] โ 2026-06-01 โ Engagement Loop + Content Push
Added
- Achievement engine (
achievements.js) โ 15-badge catalog, localStorage state, listener hooks - La Presidenta's Cabinet (
cabinet.html) withbadge-grid.js,progress-bar.js,badge-toast.js - Per-section viewed tracking + per-day visit streak
- T1 medium-tier
:::strategy mediumblocks (Jailhouse Rock, New Havana, Mi Corazon, The Good Earth, Triassic Park) - T2 tutorial/easy episodes 1-5
[phase-6] โ 2026-06-01 โ Power Trifecta + PWA
Added
- Search v3: multi-token AND,
-exclude,title:qualifier (search.jsparseQuery) - TOC hover previews (
toc-hover.js) - Recently-viewed sidebar (
recently-viewed.js) - TOC vote-sort toggle (
toc-vote-sort.js) - All-time leaderboard widget (
leaderboard.js+/topendpoint) - WoWhead-style confidence filter sidebar (
filter-sidebar.js) - PWA:
manifest.webmanifest+sw.js+pwa-install.js - Per-game OST YouTube embed IDs (T1/T2/T3/T4)
- T1 all-hard-missions strategy blocks (ร6), T2 hard episodes (ร7), T3 hard missions (ร7)
[plaza-v1] โ 2026-06-01 โ Plaza Animations + Cross-Game Search v2
Added
- Walking per-game emoji citizens on chat strip (
plaza-citizens.js) - Speech bubbles on new chat messages (
plaza-speech-bubbles) - Mobile-skip animations (Samsung S22 Ultra 412ร915 target)
- Cross-game search v2 grouped by game with per-game accent badges