Legend at x=20-155 fits 7 rows (y=55 to y=175); donut at cx=250, cy=110
is unaffected. Update the design-guidelines table to match. Stress test
still passes — the legend column never leaves its left-side gutter.
Three cards overflowed the 340×200 frame for realistic profile data:
- contributions-heatmap: the classic case — 53 weeks at 9px cellSize + 2px
gap pushed the grid out to x≈611. Shrink to cellSize=5, cellGap=1 so
leftPad(22) + 53*6 = 340 (exact fit). Drop month labels within 20 px of
the right edge so "Dec"/"Apr" can't stick past the frame.
- streak: the third column rendered "N / M" at font-size 28, centered at
x=282. For 4+ digit totals (e.g. 584 / 3031) the text extended to x≈347.
Refactor to show the active-days integer by itself in the big slot and
push "of N total (P%)" into the small detail line that the other two
columns already use.
- top-starred-repos: the per-row star icon sat at x=306 while the right-
anchored number ended at x=334, so 5+ digit star counts collided with
the icon. Drop the icon (card title already says "Top Starred Repos"),
emit the count as "N ★", right-anchor at x=334 with a 6 px safety gap.
Add a new TestCardsFitFrame stress test that renders every card against an
adversarial profile (10-digit counts, 40-char names, 20 active years,
53-week span) and asserts every positional attribute stays inside the
frame. This is the automated half of the new "fit-the-frame invariant"
added to docs/design-guidelines.md + a pre-release review checklist in
docs/code-standards.md.
Bug reports will still surface text-overflow cases that the coordinate
check can't see (a text-anchor="middle" element has a single x attribute
but renders outward), so the docs also spell out the human-review step:
render dracula against tiny/typical/adversarial fixtures before release.
The dracula sample under output/dracula/ was a reference render for the
README. Now that demo/ auto-generates every card × every theme on each
push, the sample is redundant — and keeping it trackers means every
behavioral tweak shows up as a diff in committed SVGs.
- Delete output/dracula/*.svg.
- .gitignore: collapse `output/*` + `!output/dracula/` to a plain `output/`.
- demo.yml: drop `output/**` from paths-ignore (no longer part of any push).
- README / docs: point readers at demo/ instead of output/dracula/.
Five new cards, all derived from data FetchProductive / FetchProfile already
pull, so zero additional API calls:
- contributions-heatmap: 7×53 calendar grid with a 5-bucket intensity ramp
mixed from each theme's Background→Accent so palettes with no dedicated
heat ramp still render sensibly.
- streak: current streak, longest streak with date ranges, active/total days.
- contributions-by-year: one bar per active year, peak year highlighted.
- productive-weekday + -all-time: 7-bar day-of-week mirror of the hour-of-day
cards; FetchProductive now also fills Weekday / WeekdayAllTime histograms
during the same commit-history pass.
- top-starred-repos: top 5 owned non-fork repos by stargazer count; threads
Stars through RepoInfo.
Card count: 9 → 14. Registered in allCards grouped by recency (last-year
block, then all-time block). Render test extended to cover all new files
and realistic daily-series inputs.
- README points to demo/ as an auto-generated theme preview.
- Bump "60+ / 61 themes" references to the actual 65.
- Record Phase 7.5 in roadmap and list demo.yml + demo/ in layout.
This reverts commit 399a3dc. Repo stays as tiennm99/ghstats; the
Marketplace display name ("ghstats-cards" in action.yml) is the only
place the new name remains, since that field requires uniqueness on
the Marketplace.
plans/reports/* were added alongside the rename in the same commit
and are preserved by not deleting them in this revert.
Matches the Marketplace name; repo is being renamed in lockstep.
- go.mod module path: github.com/tiennm99/ghstats →
github.com/tiennm99/ghstats-cards
- Import paths across every .go file updated.
- README badges, install snippets, and the 'go install' line point
to the new URL/path.
- docs/deployment-guide.md workflow template, Docker image path, and
release edit URL updated.
Breaking for consumers pinned to the old URL; they need to swap
tiennm99/ghstats → tiennm99/ghstats-cards in workflows and switch
Docker pulls to ghcr.io/tiennm99/ghstats-cards. GitHub's HTTP
redirect covers git clones but GHCR does NOT redirect — users must
update image URIs manually.
- Fetcher signatures across codebase-summary and system-architecture
now show the ctx-first arguments and document the rate-limit retry
loop in Client.query.
- Attribution pseudo-code hoists the per-repo total out of the commit
loop to match the current implementation (I6).
- Failure-modes table enumerates primary rate-limit retry, per-year
nil-user warn, and -timeout / Ctrl-C cancellation.
- design-guidelines notes the single-slice donut special case.
- deployment-guide's release section documents the new test gate and
the SHA-pinned Docker/GHA actions; troubleshooting adds the
rate-limit-reset-too-long error. Rate-limit section describes the
sleep-and-retry policy and -timeout flag.
- project-roadmap records Phase 6 (code-review remediation) as done,
renumbers later planned phases, links the new review report.
Files now land at output/<theme>/profile-details.svg etc., without
leading 0-8 prefixes. README authors embed cards by name, so the
lexicographic-sort rationale for the prefix no longer applies.
- All Filename() methods + the allCards ordering comment updated.
- Tests updated to expect the 9 unnumbered filenames.
- README, deployment-guide, codebase-summary, roadmap references
refreshed.
- Dracula sample SVGs regenerated under new names.