Design Lounge
Install

Nº 212 of 520

Dark mono repository card

A code repository card in dark mono: star toggle with a ring pop, a growing language bar with legend highlight, and a 52-week commit sparkline you can scrub.

Preview

Open full size
1280 × 800 · 14.3 KB · 219 lines

Use it

Free to use · credit appreciated

1 Once, in your project

npx skills add SusanAcharya/Design-Lounge

2 Then ask

Using the Design Lounge skill, build "Dark mono repository card" (piece social-repo-card) in my stack. Match its brief; restyle it onto my product's theme.

No skill? Paste the brief instead. It carries the numbers, tokens and behaviour.

Brief

201 lines

Build brief for a coding agent. Rebuild this piece in the reader’s stack. If they haven’t said which stack, ask once, then default to semantic HTML + CSS + a little vanilla JS. Match the numbers below; don’t “improve” them.

What it is

A repository card for an invented code host. Use it as an embed, a search result or a profile “pinned” item. The repo is heronry / brackwater, an embedded time-series store. Everything structural is in IBM Plex Mono: the repo path, counts, topics, labels and the last-commit line. The description alone is set in Plex Sans so it reads as prose. One amber accent (#F2B84B) marks things you can act on or that belong to you: topics, the starred state and the sparkline. Language colours are the only other hues. The details worth copying are the sparkline, which draws itself once and can be scrubbed by pointer or arrow keys with the header readout changing to “Week of 29 Jun · 71 commits”, and the language legend, which dims every other segment when you point at one.

Reference behaviour

  1. Initial state: card centred on a near-black page with a 24px dot grid. The language bar segments grow from 0 to their share over 600ms. The sparkline stroke draws left to right over 1200ms (200ms delay), and its amber area fill fades in at 700ms.
  2. The header readout to the right of “COMMIT ACTIVITY · 52 WEEKS” shows the total, “1,721 commits”.
  3. Click Star. The button turns amber-tinted (border rgba(242,184,75,.5), fill rgba(242,184,75,.14), text amber), the star icon fills, the label becomes “Starred”, the count goes 12,418 → 12,419. The icon pops (scale .6 → 1.2 → 1, rotate −30° → 0, 420ms) and a 20px amber ring expands to 1.7× and fades over 500ms.
  4. Click again to unstar. The label goes back to “Star”, the count to 12,418, and there is no pop.
  5. Hover or focus a language in the legend, or hover its bar segment. Every other segment and legend item drops to 28% opacity over 200ms.
  6. Move the pointer over the sparkline. A dashed vertical cursor and a 4px amber-ringed dot snap to the nearest of 52 weeks, and the readout says “Week of {d Mon} · {n} commits”. Leaving restores the total.
  7. Tab to the sparkline. The cursor appears on the last week. ←/→ move one week, Home/End jump to the ends, and a polite live region repeats the readout.
  8. Hover a topic chip and its tint deepens from 14% to 24% amber.
  9. Reduced motion: bars render at full width, the line and area are fully drawn, and there is no pop or ring.

Structure

page 1280 × 800, #0C1011 + 24px dot grid; card 580 wide, radius 8, centred
┌──────────────────────────────────────────────────────────────────────┐
│ ▤ heronry / brackwater  (Public)            [* Star 12,418][Y Fork 864] │ pad 20/22
│ Embedded time-series store for edge devices. Append-only WAL, …      │ Plex Sans 14.5
│ (time-series)(embedded)(storage-engine)(wal)(edge)                   │ amber chips
│ ──────────────────────────────────────────────────────────────────── │
│ LANGUAGES                                                            │
│ ████████████████████████████████▌██████████▌█████▌███   8px, 2px gaps│
│ ● Rust 62.4%  ● Go 20.8%  ● TypeScript 11.3%  ● Shell 5.5%           │
│ ──────────────────────────────────────────────────────────────────── │
│ COMMIT ACTIVITY · 52 WEEKS                          1,721 commits    │
│ ╱╲_╱‾‾╲__╱‾╲___╱‾‾‾╲__/\__╱‾‾‾‾  64px tall sparkline + area           │
│ Oct 2025                Apr 2026                     This week       │
├──────────────────────────────────────────────────────────────────────┤
│ (OF) orla-f  fix(wal): close compaction race on segm…  a3f9c1e  2h ago│ raised row
├──────────────────────────────────────────────────────────────────────┤
│ ⓘ 37 issues   ⇅ 9 pull requests   § Apache-2.0   ⌖ v0.14.2           │
└──────────────────────────────────────────────────────────────────────┘
  • article.card labelled by the h1 repo path.
  • Actions: two buttons. Star has aria-pressed and an aria-label that includes the count.
  • Topics: ul aria-label="Topics" of links.
  • Languages: section with a decorative bar and a ul of buttons (focusable so keyboard users get the highlight).
  • Activity: section with an output readout and a focusable div role="img" wrapping the SVG.
  • Last commit: one row. The message truncates with an ellipsis.
  • Footer: metadata spans with 14px icons.

Tokens

:root {
  --bg: #0c1011;          /* page */
  --card: #12181a;        /* card */
  --raise: #182023;       /* buttons, commit row */
  --ink: #dfe6e3;
  --ink-2: #a3aeab;
  --ink-3: #7c8784;
  --line: #243033;        /* section rules */
  --line-2: #2f3d40;      /* button borders */
  --accent: #f2b84b;      /* amber: star, topics, sparkline, focus */
  --accent-dim: rgba(242,184,75,.14);
  --l1: #e08a5b;          /* Rust */
  --l2: #5fb3b3;          /* Go */
  --l3: #7a9cdb;          /* TypeScript */
  --l4: #9bb56a;          /* Shell */
  --mono: "IBM Plex Mono", ui-monospace, monospace;
  --sans: "IBM Plex Sans", system-ui, sans-serif;
  --r-card: 8px; --r-btn: 6px; --r-chip: 999px;
  --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 22px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --expo: cubic-bezier(0.16, 1, 0.3, 1);
}

Typography

RoleFamilySize / lineWeightTrackingColour
Repo pathPlex Mono17 / 1.3500 (owner 400)−0.01emink, owner ink-2, slash ink-3
BadgePlex Mono11px5000ink-3, 1px line-2 border
ButtonPlex Mono13px5000ink, count ink-2 on bg chip
DescriptionPlex Sans14.5 / 1.54000ink-2, max 52ch
TopicPlex Mono12px5000accent on accent-dim
Section labelPlex Mono11px5000.08emink-3, uppercase
ReadoutPlex Mono12px5000ink-2
LegendPlex Mono12.5px400, name 5000ink-2 / ink
Commit rowPlex Mono12.5 / 1.34000author ink 500, hash ink-3
FooterPlex Mono12px4000ink-3

Motion

ThingTriggerPropertyFrom → toDurationEasingReduced motion
Language barloadflex-grow0 → share600ms--expofinal widths
Sparkline strokeloadstroke-dashoffsetlen → 01200ms, 200ms delay--expodrawn
Sparkline arealoadopacity0 → 1600ms, 700ms delay--easevisible
Star iconstar ontransformscale .6 rot −30° → 1.2 → 1420ms--exponone
Star ringstar onscale, opacity.4/1 → 1.7/0500ms--exponone
Star buttonaria-pressedborder, backgroundneutral ↔ amber160ms--easeinstant
Legend dimhover/focusopacity1 → .28200ms--easeinstant
Cursorpointer/keysopacity0 → 1120ms--easeinstant

States

  • Button hover: border #41545a.
  • Star pressed: amber tint, filled star, “Starred”, count +1.
  • Topic hover: background 24% amber.
  • Legend item active (.on): full opacity, siblings at .28. The card gets .hl while any item is active.
  • Sparkline active (.on): cursor line --ink-3 dashed 2/3, dot r=4 with fill --card and stroke amber 2px.
  • Focus-visible: 2px amber outline, offset 2px, on buttons, chips, legend items and the sparkline.
  • Empty activity: if all 52 weeks are zero, draw a flat line at the baseline and set the readout to “No commits this year”.

Accessibility

  • Star aria-label updates to “Unstar heronry/brackwater, 12,419 stars” when pressed. A polite live region says “Starred” or “Star removed”.
  • The sparkline is role="img" with tabindex="0" and the label “Weekly commits, use left and right arrow keys to inspect weeks”. Arrow keys update the visible readout and the live region. Pointer movement does not announce.
  • Legend items are buttons so focus gets the same highlight as hover.
  • The language bar is aria-hidden. The legend carries the data as text.
  • Contrast: #a3aeab on #12181a ≈ 8:1. #7c8784 ≈ 4.8:1. Amber on accent-dim over card ≈ 9:1.
  • Buttons are 32px tall. That is acceptable on desktop. Make them 40px on touch layouts.

Responsive rules

  • ≥1024: card 580px.
  • 768: unchanged.
  • <520: the header stacks (name row, then actions row), topics wrap to two lines, the legend wraps to two rows, the commit row hides “2h ago” and keeps the hash, and the footer wraps.
  • The sparkline is width: 100% with preserveAspectRatio="none" and vector-effect: non-scaling-stroke so the stroke stays 1.5px at any width. The cursor dot is drawn in a separate pixel-space SVG so it stays round.

Acceptance checklist

Always

  • All structural text is monospace. Only the description is sans.
  • One accent colour, used for star-on, topics, sparkline and focus.
  • Star toggles aria-pressed, label, count (±1) and accessible name.
  • Star pop and ring play only when starring, not unstarring.
  • Language bar is 8px tall with 2px gaps and grows in on load.
  • Hovering a language dims the others to .28 opacity, and so does keyboard focus.
  • Sparkline has 52 points, draws once, and is scrubbable by pointer and by ←/→/Home/End.
  • Readout returns to the total on leave or blur.
  • Commit message truncates with an ellipsis on one line.
  • No horizontal scroll at 375px.

This demo

  • Repo heronry / brackwater, Public, 12,418 stars, 864 forks.
  • Languages Rust 62.4%, Go 20.8%, TypeScript 11.3%, Shell 5.5%.
  • Topics: time-series, embedded, storage-engine, wal, edge.
  • Last commit: orla-f, “fix(wal): close compaction race on segment rotate”, a3f9c1e, 2h ago.
  • Footer: 37 issues, 9 pull requests, Apache-2.0, v0.14.2.

Implementation notes

Draw the line with a dash trick. Set --len larger than the path length and animate the offset:

.spark .ln { fill: none; stroke: var(--accent); stroke-width: 1.5;
  stroke-dasharray: var(--len); stroke-dashoffset: var(--len);
  animation: draw 1.2s var(--expo) .2s forwards; }
@keyframes draw { to { stroke-dashoffset: 0 } }

Snap the cursor to a week, not to the raw pointer x:

const X = i => i * 520 / 51, Y = v => 60 - v / max * 54;
spark.addEventListener('pointermove', e => {
  const r = spark.getBoundingClientRect();
  show(Math.round((e.clientX - r.left) / r.width * 51));
});
function show(i) {
  idx = Math.max(0, Math.min(51, i));
  cl.setAttribute('x1', X(idx)); cl.setAttribute('x2', X(idx));
  dot.setAttribute('cx', X(idx) / 520 * spark.clientWidth);
  dot.setAttribute('cy', Y(W[idx]));
  out.textContent = `Week of ${fmt(idx)} · ${W[idx]} commits`;
}

Restart the star pop by removing the class, forcing reflow, and re-adding it: star.classList.remove('pop'); void star.offsetWidth; star.classList.add('pop');.

Grow the language bar with flex-grow from 0 to the percentage after two animation frames, so the browser paints the 0 state first.

Common mistakes:

  • Using a different hue per topic chip. They are all amber.
  • A gradient on the language bar. It is flat segments.
  • Drawing the dot inside the stretched SVG, where it turns into an ellipse.
  • Making the readout aria-live and announcing every pointer move.
  • Copying a real host’s logo or octocat-like mark. The repo icon is a plain book outline.

Details

Palette
Type
IBM Plex Mono · IBM Plex Sans
Motion
Subtle motion
Build
One session
Designed bySusan AcharyaKathmandu

Studied

Stripe

A control. It studies this site for quiet, not for a show.

All sources

On the shelves