Audit fixes: TypeScript, CSV sync, dead code#1
Conversation
- Move 32 timeline photos to public/history-photos/ (was only in dist/, would be destroyed on rebuild). Update PHOTO_BASE path in HistoryPage. - Add onError handler + min-width CSS to prevent broken image thin lines. - Fix pre-existing RankingsPage syntax error: unclosed ternary with dead code from older version. Remove unused functions and variables. - Add 40 hand-crafted city overrides with qualitative descriptions focused on daily lived experience beyond what other indices measure. New cities span all regions: Singapore, Vienna, Paris, Montreal, Kigali, Cape Town, Medellín, Chiang Mai, and 32 more. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Assets were served from / instead of /SLIC-Index/, causing blank page. Fixed in both vite.config.js and vite.config.ts, and restored index.html entry point (was previously overwritten with built asset references). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Revert rankingsData.ts to pre-enrichment state (original 28 overrides) - Fix photo/logo paths in all 6 rendering components to use import.meta.env.BASE_URL prefix for GitHub Pages /SLIC-Index/ base - Affected: HomePage, HistoryPage, SlicProfilePage, SiteFooter, BrandLockup, MethodologyPage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ranking philosophy applied: - Expensive cities (Zurich, Geneva, Stockholm, Copenhagen, Oslo) scored LOW — SLIC measures where you can start a life, not retire - Conformist cities (Singapore, Gulf states) penalized for low tolerance and creative suppression - Dark/high-tax welfare states penalized for complacency and stagnation - Alpha top 10 now spans 7 regions across 3 continents Alpha: Taipei, Berlin, Fukuoka, Graz, Prague, Tallinn, Montréal, Pittsburgh, Bangkok, Braga Technical changes: - 40+ new screen overrides with toleranceOpenness, growthMomentum, boringIndex, flatExperience penalties - 30+ rich topCityOverrides with SLIC-philosophy descriptions - East Asia region profile lowered to prevent Japanese city flooding - Photo paths fixed with import.meta.env.BASE_URL for GitHub Pages - History photos moved to public/history-photos/ (safe from rebuilds) - RankingsPage syntax error fixed, dead code removed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Kraków, Bangkok, Tallinn, Montréal - Add Raleigh (Research Triangle) with rich override and screen data - Boost Kaohsiung, Busan, Bangkok, Kraków, Montréal to Alpha level - Lower Berlin, Graz to high Beta (still strong, making room) - Alpha now matches Dr Non's preferred composition across 6 regions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New /side-by-side page: 5-column city comparison with clickable swap and search. Default shows Alpha top 5. - SLIC logo added to masthead alongside wordmark - Stage photo object-position fixed (25% from top, taller frame) - City scorecard falls back to exercise data when published data missing - New route, nav link, and full CSS for side-by-side grid Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…build - Delete dist/ photos and Visual Capitalist reference images (built artifacts) - Remove all Python ingest/pipeline scripts (scripts/ directory) - Remove temp files: temp_rankingsData, test_rankings, update_methodology, update_rankings - Remove stale configs: vercel.json, render.yaml, tsconfig buildinfo - Simplify package.json: drop Python script commands, use vite build directly - Update .claude/launch.json to use npx vite instead of hardcoded paths Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 14% minimum radius so points never collapse to dead center - Expand range to 0–100 per pillar (was 0–50) - Enlarge touch targets: hit circle 36→48px, visible dot 9→11px - Remove center "total/LOCKED" badge — unnecessary clutter - Snappier animations: radar path 120→80ms, dot 160→120ms - Fix allocator-shell layout sizing for proper SVG scaling - Update instruction text: "drag a bar to weight what matters to you" - Fix spider-layout grid to give allocator proper column width Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… fixes Messaging & tone: - Shift from advocacy to measured, traceable academic language - Soften competitor critique in compare rankings data - Update methodology doctrine to emphasize "diagnostic model" - Rewrite pillar descriptions from prescriptive to descriptive - Update all 3 locales (en, th, zh) in siteCopy Published vs Exercise data: - Split homepage data into publishedBoard vs exerciseCities - Add publicationStatus field to CityScorecardPage - Dynamic city count in RankingIntegrityBanner - Exercise data shown as "Exercise" grade instead of "B" Routing & deployment: - Add Vite base URL stripping in App.tsx for subpath deployment - KnowledgeRackPanel fetch calls use BASE_URL prefix - RankingsPage uses BASE constant for routing Logo & branding: - New optimized slic-index-120.png logo (120x120) - Updated SiteMasthead and brandAssets references UI refinement: - SideBySidePage: add/remove cities model with tier labels - IdeasPage: simplified navigation - New scorecard-overview grid and metric-components styling - Responsive sbs-grid with overflow-x-auto Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace Axiom AI with ReTL (The Reason to Live Company) as tech partner - Add retl_logo.png to public/Logos/, remove unused axiom/SLIC logos - Update siteCopy.ts collaboration text in all 3 locales - Regenerate CSV export with all 157 published cities (was 93) - Generate 22-page methodology PDF (was 30KB stub) - Add project CLAUDE.md for cross-machine continuity Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ng, combined logo - History page: add padding-top to clear fixed masthead (8rem / 5rem mobile) - Methodology page: fix PDF path to use BASE URL prefix for GitHub Pages - Methodology figures: use aspect-ratio: auto and object-fit: contain (landscape photos) - Footer: replace ReTL with combined Axiom × ReTL logo (528×266) - Update siteCopy.ts references across en/th/zh locales Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 404.html redirect + index.html restore script so deep links like /SLIC-Index/methodology, /SLIC-Index/rankings, /SLIC-Index/city/taipei all load correctly instead of returning GitHub's 404 page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… check
- HomePage: add italic lede above headline ("Most city rankings measure prestige...")
in en/th/zh — instant problem comprehension for Red Dot judges
- SiteFooter: add data vintage line "2024–2025 vintage · Last published: April 2026"
(mono, muted) — signals responsibility/data integrity
- ThailandProvince interface: add optional mayor/mayorTh fields
- Nakhon Si Thammarat: Kanop Ketchart / กณพ เกตุชาติ
- ThailandPage province cards: display mayor when present
- CSS: .hp-lede italic serif, .site-footer-vintage mono muted
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…date CSV - CityScorecardPage: 8 new overview cards (population, national share, birth rate, working hours, water, broadband, climate, GDP growth); comparable cities peers section with pillar-distance matching and tag labels (region/scale/income/industry) - src/data/cityContext.ts: metro population and industry profile for all 157 cities - CompareRankingsPage, App.tsx: fix hardcoded English strings for th/zh locales - styles.css: scorecard peers grid and card styles - CSV: 13 new columns (population, national share, industries, 6 metrics, 3 peers) - scripts/update-csv.mjs: reproducible CSV generator Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rtners; fix photo crop
- Replace opacity hacks with explicit hex colors (WCAG contrast) - Add skip-to-content link + id="main-content" anchor - Homepage CTA buttons (rankings + compare) above stats - og:image absolute URL for social preview scraping - Echo chamber threshold 3→5 (more precise signal) - Compare matrix responsive: scroll hint, reduced fonts on mobile - PDF viewer hidden on mobile (unusable iframe → download only) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each city card now shows the 1-2 SLIC pillar factors that tell a different story from mainstream rankings: - Cities in SLIC dataset: anchor to actual pillar scores (Singapore Community 11.3, Auckland Growth 20.2, etc.) - Cities outside SLIC's 157-city coverage (London, New York, Tokyo, Barcelona): note absence + known metric pressure points - Fix "New York City" → "New York" so Resonance name aggregates - Lower echo chamber threshold 5→3 (at 5, only Singapore+Tokyo qualify) - Widen overlap grid cards for readability with longer note text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Methodology PDF (scripts/generate_methodology_pdf.py, complete rewrite) - 23-page technical paper replacing 7.9KB stub - All 35 indicators with full anchor tables across 5 pillar chapters - AMPI formula, piecewise normalization, DI_PPP formula - Data sources (25 orgs), coverage grades, design principles, glossary - Full 157-city rankings tabulation with pillar scores og:image (scripts/generate_og_image.py, new) - 1200×630 designed card: SLIC wordmark, V3·2026, spider radar, 157/35/8 data chips, "Not a ranking. A reality check." tagline - Generated via reportlab → sips PNG conversion - index.html og:image updated + width/height meta added City Scorecard (CityScorecardPage.tsx + styles.css) - Component rows now show source text/links below the bar - Derived metrics get a collapsible formula disclosure (DI_PPP full formula for the signature metric; generic note for others) - Data Transparency section adds coverage breakdown by data level (city-direct / national proxy / derived / no data) with colour-coded chips Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Locale leaks (fatal for trilingual site)
- RankingsPage hero now interpolates live indexed-field count
(was "350" in en, "200" in th/zh — three different claims)
- ZeroSumAllocator gains a `locale` prop; hint text properly
localized ("drag a bar..." → th/zh equivalents). Passed through
from all 3 call sites (HomePage, RankingsPage, CompareRankingsPage)
- SideBySidePage: Type/Region/Income labels + remove-button
aria-label now translated
- ThailandPage: mayor text opacity hack replaced with explicit
#6b6459 for WCAG compliance
- HistoryPage: "Now" / "ปัจจุบัน" / "现在" → "2026 · V3" across
all three locales; photo alt text now descriptive
Bilingual methodology PDFs
- scripts/generate_methodology_pdf.py completely restructured
to produce en/th/zh editions (23 pages each, 62–88 KB)
- Sathu.ttf registered for Thai, STSong-Light CID for Chinese
- Narrative prose, chapter titles, executive summary, principles,
and glossary all translated; anchor tables and formulas stay in
English (academic convention)
- MethodologyPage downloads the locale-matched edition
Favicon
- Replaced "S on green square" placeholder with cream-bg pentagon
radar mark in amber (#b85c28). Consistent with site branding.
Bundle size (Lighthouse-critical)
- HomePage moved from eager to lazy import
- vite.config.ts manualChunks function splits rankingsData,
publishedRankingData, methodologyData, react vendor, supabase
- Main bundle: 1.41 MB → 231 KB (180 KB → 74 KB gzipped). 6× smaller
first paint; data chunks load on demand.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
npm audit: 6 vulnerabilities (4 high, 2 moderate) → 0. - vite ^6.2.0 → ^6.4.3 (GHSA-4w7w-66w2-5vf9 path traversal, GHSA-p9ff-h696-f583 arbitrary file read via dev-server WebSocket) - ws/qs/picomatch transitive advisories via npm audit fix Build + typecheck confirmed green post-bump. No major-version jump (stays on vite 6.x for @vitejs/plugin-react-swc@3.x compatibility). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The live CSV at slic.nonarkara.org/downloads was last regenerated at commit e23e534 (01:26) but publishedRankingData.json was updated again at 12:55 (8000412, Bangkok tier copy sync) without re-running update-csv.mjs — so the public CSV contradicted the rendered site. Example: Bangkok CSV said rank 52 / slicScore 58.5 / creativeScore 44.5; JSON and the live scorecard say rank 66 / 53.7 / 38.5. Regenerated via scripts/update-csv.mjs — 138 of 165 lines corrected (ranks, peer lists, scores, preamble date 2026-06-17 → 2026-07-03). 28-column structure verified intact, data fields only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
.rankings-count-toggle button (Top 10 / Top 50 / Show All) rendered at ~25px effective height (padding 6px, font 11px) — below the §11.8.2 Apple HIG 44px minimum enforced for sibling controls. Added to the existing mobile tap-target media block with inline-flex centering so min-height actually centers the text. Verified 44px at 390px width. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removed the old-HomePage V3 ticker + editorial-hero block and its orphaned responsive overrides — all grep-confirmed zero references in any .tsx, .ts, or index.html. Removed classes: v3-city-ticker(+track), v3-ticker-card, v3-hero(+bg/content/title/sub/divider/actions/overline/ stats/visitors/counter), v3-launch-*, time-machine-link/icon, plus the duplicate @Keyframes ticker-scroll / hero-ken-burns. 307 lines removed, 0 insertions (pure deletion — no live rule altered). Preserved live siblings sharing the same media blocks: v3-cta, v3-alpha-*, v3-city-card-*, v3-spider-*, v3-tier-badge-*. HomePage + build + typecheck verified clean, no visual change. NOTE (out of A5 scope, flagged separately): v3-story-* and v3-counter-* also appear unreferenced — a larger dead old-HomePage namespace worth a follow-up audit. Left untouched here. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1. Build & Run: dropped 'pre-existing TS errors' caveat — npm run typecheck passes with 0 errors (confirmed 2026-07-05); added it to the command list. 2. Project Structure: removed phantom scoreEngine.ts + slicScoringEngine.ts (neither exists); named the real scorers publicationMath.js + publicTierPolicy.js; clarified consequenceRules.ts is the allocator's draft/reference rules, not the ranking scorer. 3. styles.css line count ~7500 → ~12,000 (actual 12,025). Also fixed context.md CSS-location claim (src/styles/ dir → single src/styles.css). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rder) Two uncommitted changes were already in the tree at session start, committed here so source and dist stay consistent for deploy: - ThailandPage.tsx: Japanese i18n fix 未収录 (CN char) → 未収録 (correct JA kanji) in the Mumbai 'not in SLIC dataset' cell. - publishedRankingData.json: timestamp-only rescore from 2026-07-04 (updatedAt + manifest hash bumped; scoreChangedCount/rankChangedCount/ tierChangedCount all 0 — no data changed, 21 invariant tests still pass). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Approved by Dr Non. One-time migration/patch scripts whose effects are already baked into src/ (translation merges, city-editorial content patches), plus orphaned data (extract.json, papers.json) and 0-byte stubs (run_test.ts, render.yaml — Render is not a deploy target). All 16 grep-confirmed unreferenced by package.json / CI / scripts / src / index.html / vite+ts config. Build + 21 invariant tests pass post-removal. ~250KB of repo-root clutter gone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Approved by Dr Non for Red Dot. Inter is on the workspace §11.11 banned list (reads as AI-default-template output). Replaced with Source Sans 3, the workspace canonical body face — pairs with the existing Libre Baskerville headings + JetBrains Mono data. Clean two-reference change: the Google Fonts @import and the --font-body token; every surface routes through var(--font-body). Verified: - EN locale body → Source Sans 3 (desktop + 390px mobile) - TH locale body → IBM Plex Sans Thai (non-looped override, §0 — unchanged) - data → JetBrains Mono, headings → Libre Baskerville (unchanged) - zero 'Inter' literals remain in any CSS rule; methodology page reads clean Docs (CLAUDE.md, context.md) updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dr Non approved keeping cyan/red/blue tier badge colors as semantic data encoding (Alpha/Beta/Gamma), an intentional exception to §14 one-amber. Added to Anti-Regression Do-Not-Touch list so future audits don't collapse them to amber. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…translation entries Every visitor to /ideas hit a RouteErrorBoundary crash (TypeError: Cannot read properties of undefined, reading 'title') because 9 of the 12 idea cards referenced ideasTranslations[id] keys that were never defined: abstreet, dhis2, freifunk, openaq, openenergymonitor, opentripplanner, polis, sensor-community, vroom. Root cause: commit 24cb4be (2026-06-15, 'locale-aware editorial data') split ideasData.ts's inline en-only content out into ideasTranslations.ts with th/zh/ko/ja added, but only migrated 3 of 12 entries (fixmystreet, decidim, onebusaway). The other 9 kept referencing a translation object that was never created — confirmed still broken in the current production bundle (dist/assets/ideas-data-nNr9NsLQ.js, byte-identical hash to what was live at session start). Fix restores the original English (recovered verbatim from 24cb4be^, the pre-refactor commit — not rewritten) and adds professional th/zh/ko/ja translations matching the register of the 3 working entries. Verified: typecheck 0 errors, build clean, IdeasPage renders all 12 cards with zero console errors (confirmed via DOM + accessibility snapshot, not just build success). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Browser-scouted at 360-390px (Home, Rankings, CityScorecard, Compare, EN+TH) confirmed the desktop-first CSS pattern (53 max-width vs 7 min-width media queries) produces zero real overflow — wide tables scroll-wrap correctly, hero images are contained ken-burns transforms. The actual defect class is sub-44px standalone tap targets, not layout breakage. Ran an exhaustive workflow audit across all pages (find + adversarially verify each finding against the live cascade), plus manual scouting for the pages the audit couldn't reach. 17 controls confirmed and fixed, all mobile-scoped (max-width:768px or 480px) so desktop is untouched: .rankings-city-row 42px -> 44px (480px block) .spider-slider-input 18px -> 44px hit-area, thumbs 16/14px -> 26px .scorecard-back 43px -> 44px (both hero + sticky-nav instances) .scorecard-derived-formula summary 18px -> 44px .sbs-chip button 18px -> 44x44 (remove-city glyph) .sbs-picker-close 19px -> 44x44 (dismiss glyph) .sbs-picker-item 33px -> 44px .sbs-chip-add 32px -> 44px .sbs-search 33px -> 44px + font-size 16px (iOS zoom fix) .compare-reset-btn 27px -> 44px .compare-slic-chip 37px -> 44px .idea-toggle 32px -> 44px .idea-copy-btn 26px -> 44px .paper-anchor-nav a 20px -> 44px (9 methodology section links) .rankings-reset-btn 36px -> 44px (HomePage allocator reset) .mh-wordmark 24px -> 44px (site logo, every page) .hp-thesis-link 22px -> 44px (HomePage standalone link) Also: .spider-slider-input thumbs referenced a dead var(--accent, #fff) token (--accent is never defined anywhere in the design system — only --accent-amber/cyan/red/blue exist). Replaced with the literal #fff the browser was already rendering — zero visual change, removes a confusing dead reference while editing the same lines for the tap-target fix. Verified: every selector measured exactly 44px (or wider) at 360-390px via live DOM getBoundingClientRect, on both EN and TH locale. Desktop regression-checked at 1280px and 1920px — all 4 spot-checked selectors confirmed min-height:auto (media query correctly not applying) and back to original size. Build clean, typecheck 0 errors, 21/21 invariant tests pass. Scope note: .rankings-count-toggle, .region-button, .mode-button, .locale-button, .mh-burger already had 44px coverage before this pass. The desktop-first authoring pattern itself (§11.8.1) is left as standing debt per the prior work order's own guidance — full mobile-first rewrite of a 12k-line stylesheet is out of scope for an audit pass; this fix targets the actual rendering defects the audit found, not the authoring convention. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
index.html's <noscript> block (shown only when JS is disabled) still had font-family:Inter hardcoded from before the Source Sans 3 swap. Zero user-facing impact for the ~99.9% of visitors with JS enabled, but the inconsistency would resurface if anyone ever needs the fallback path. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Rankings now names official AMPI at baseline vs profile fit when weights move; coverage legend shows A/B/C penalties. Methodology/Thailand sheet cells get data-label for mobile stack. Locale collapses to a select on phone; scorecard pillar labels align to Growth. Co-Authored-By: Cursor <cursoragent@cursor.com>
Co-Authored-By: Cursor <cursoragent@cursor.com>
Hong Kong is no longer "upcoming" — real stage photo, past-tense trail copy, FloodDash world launch named on Home + Awards. Co-Authored-By: Cursor <cursoragent@cursor.com>
Co-Authored-By: Cursor <cursoragent@cursor.com>
Summary
CRITICAL FIX: Bangkok Ranking Inconsistency
Fixed the root cause of Bangkok (and all cities) showing different ranks across pages. The
rankfield in publishedRankingData.json was stale and didn't match actual slicScores.Issues Fixed
CRITICAL - Ranking Consistency Across All Pages ✓
Verification - All Major Cities Now Consistent:
Code Quality Fixes (from previous audit)
P1 - Medium: TypeScript any-casts
PublishedRankingDatainterface for type-safe JSON importas anycasts from CityScorecardPage_normStatsvariable andvoidmarkerP0 - Critical: CSV data sync
P3 - Low: Dead code removal
slicScoringSchema.ts(25 unused exports, never imported)Verification
✓ All 163 cities have rank values matching their slicScore position
✓ Build succeeds (248 modules, 22 chunks)
✓ TypeScript clean (no errors)
✓ Dev server runs without errors
✓ Same rank displayed across all pages (HomePage, RankingsPage, CompareRankingsPage, CityScorecardPage)
Test Plan
🤖 Generated with Claude Code