mirror of
https://github.com/tiennm99/ghglance.git
synced 2026-10-20 00:15:14 +00:00
docs: add project documentation set
Seven canonical docs under docs/ per the project structure convention: - project-overview-pdr.md users, non-goals, requirements - codebase-summary.md directory layout, module responsibilities - system-architecture.md runtime phases, GraphQL flow, SVG primitives - code-standards.md YAGNI/KISS/DRY, Go conventions, commit rules - design-guidelines.md frame dimensions, theme roles, per-card specs - deployment-guide.md Action/binary/Docker paths, release process - project-roadmap.md done phases (0-5), planned phases (6-9) All files under the 800-line cap. Each leans on tables; grammar sacrificed for concision per project rules.
This commit is contained in:
1 parent
0168fd1f56
commit
8b3a8e1932
7 files changed
+740
No files matched your search
@@ -0,0 +1,108 @@
|
||||
# Design Guidelines
|
||||
|
||||
Visual conventions for ghstats SVG cards. All cards share a single frame shape so they stack cleanly in a README.
|
||||
|
||||
## Card frame
|
||||
|
||||
| Property | Value |
|
||||
| --- | --- |
|
||||
| Width × Height | **500 × 220** |
|
||||
| Corner radius | 8 px |
|
||||
| Stroke | `theme.Stroke` at `theme.StrokeOpacity` |
|
||||
| Fill | `theme.Background` |
|
||||
| Font family | `'Segoe UI', Ubuntu, Sans-Serif` |
|
||||
| Title | 18 px, weight 600, `theme.Title`, anchored at `(25, 35)` |
|
||||
|
||||
Generated by `header(width, height, bg, stroke, strokeOpacity, titleColor, title)` in `internal/card/svg.go`.
|
||||
|
||||
## Theme role mapping
|
||||
|
||||
| Theme field | Used for |
|
||||
| --- | --- |
|
||||
| `Title` | Card title text |
|
||||
| `Text` | Primary content (values, names) |
|
||||
| `Background` | Card fill + stroke around donut slices to separate colors |
|
||||
| `Stroke` + `StrokeOpacity` | Card outline |
|
||||
| `Muted` | Axis lines, axis labels, icons, legend metadata |
|
||||
| `Accent` | Bars, area fills, stat values, fallback slice color |
|
||||
|
||||
Cards MUST NOT hardcode colors outside these fields. If a new visual needs a shade, pick the closest existing field — don't extend the schema without a strong reason.
|
||||
|
||||
## Row-based cards (profile, stats)
|
||||
|
||||
Single-column rows of `icon + label` or `icon + label + value`.
|
||||
|
||||
| Metric | Value |
|
||||
| --- | --- |
|
||||
| First row baseline (y) | 70 |
|
||||
| Row spacing | 24 px |
|
||||
| Icon scale | `14/16 = 0.875` from 16×16 Octicon viewBox |
|
||||
| Icon color | `theme.Muted` |
|
||||
| Right-aligned value anchor (stats) | `x = 475`, `text-anchor="end"` |
|
||||
| Value font weight | 600 |
|
||||
| Value color | `theme.Accent` |
|
||||
|
||||
Cap rows at what fits: 7 for profile, 7 for stats (commits row splits into lifetime + last-year).
|
||||
|
||||
## Donut cards (language breakdowns)
|
||||
|
||||
| Metric | Value |
|
||||
| --- | --- |
|
||||
| Donut centre | `(380, 120)` |
|
||||
| Outer radius | 70 |
|
||||
| Inner radius | 38 |
|
||||
| Top-N entries shown | 6 (overflow collapses into "Other") |
|
||||
| Slice stroke | `theme.Background`, 1.5 px (gap between slices) |
|
||||
| Legend origin | `(30, 70)` |
|
||||
| Legend row height | 22 px |
|
||||
| Swatch size | 12 × 12 |
|
||||
|
||||
Language colors come from linguist via GraphQL (`repo.languages.edges[].node.color`). Missing colors fall back to `theme.Accent`.
|
||||
|
||||
## Bar-chart cards (productive time)
|
||||
|
||||
| Metric | Value |
|
||||
| --- | --- |
|
||||
| Chart area | `x ∈ [50, 475]`, `y ∈ [60, 170]` (110 tall) |
|
||||
| Bars | 24 bars, 2 px gap |
|
||||
| Bar fill | `theme.Accent` |
|
||||
| Y-axis ticks | `niceTicks(max, 5)` — 1/2/5 × 10^k ladder |
|
||||
| X-axis labels | Hours 0, 6, 12, 18, 23 |
|
||||
| Axis caption | "hour of day" bottom-center |
|
||||
| Title format | `Commits by Hour (<window>, UTC±N.NN)` |
|
||||
| Hover | `<title>HH:00 — N commits</title>` inside each bar |
|
||||
|
||||
## Area-chart cards (contributions)
|
||||
|
||||
| Metric | Value |
|
||||
| --- | --- |
|
||||
| Chart area | `x ∈ [35, 465]`, `y ∈ [60, 180]` (120 tall) |
|
||||
| Curve | Catmull-Rom → cubic Bezier (tension 0.5) |
|
||||
| Fill | `theme.Accent` at 25% opacity |
|
||||
| Stroke | `theme.Accent`, 2 px |
|
||||
| Y-axis | **Both sides**, mirrored, same tick values |
|
||||
| X-axis labels | `mm/yy`, stride-thinned to ~6 labels regardless of bucket count |
|
||||
| Axis caption | "mm/yy" bottom-center |
|
||||
| First/last labels | Always printed (pinned endpoints) |
|
||||
|
||||
Missing months in the `[first, last]` range are inserted as zero-count rows to keep the curve time-continuous.
|
||||
|
||||
## Icons
|
||||
|
||||
- Sourced from [Primer Octicons](https://primer.style/octicons/) 16×16 set.
|
||||
- Stored as raw `<path d="…"/>` strings in `internal/card/icons.go`.
|
||||
- Rendered inside `<g transform="translate(x,y) scale(0.875)" fill="muted">…</g>`.
|
||||
- Used: `iconRepos`, `iconCompany`, `iconLocation`, `iconClock`, `iconLink`, `iconPeople`, `iconStar`, `iconCommit`, `iconPR`, `iconIssue`, `iconReview`.
|
||||
|
||||
Add new icons by copying the `<path>` from Octicons and appending to `icons.go`. Keep them to the same 16×16 viewBox so the existing scale math applies.
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Contrast is the theme author's responsibility — we don't validate at runtime.
|
||||
- Tooltips (`<title>`) on productive-time bars let screen readers announce counts.
|
||||
- No motion, no `<animate>` elements — profile READMEs render statically.
|
||||
|
||||
## Text overflow
|
||||
|
||||
- Long strings (bio, repo names) are **not truncated**; they're XML-escaped and printed as-is.
|
||||
- If a card looks crowded at 500 px width, that's a card design problem — fix the layout, not the data.
|
||||
Reference in new issue
Block a user