Skip to content

jflamb/ledger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ledger

Ledger is the shared CSS foundation for jflamb.com, Assistant Workbench, and the Retirement Dashboard. It gives the three products one visual identity: ink on warm paper, a viridian brand, serif prose, mono figures, and rules instead of decorative shadows.

The package is intentionally small. It provides versioned design tokens, themes, accessibility defaults, and a stable contract for site-local components. It does not force the three products into one component library.

Install

npm install @jflamb/ledger

Import the stylesheet from application CSS:

@import "@jflamb/ledger/ledger.css";

Or import it from JavaScript when the bundler handles CSS:

import "@jflamb/ledger/ledger.css";

For a site without npm tooling, use a version-pinned CDN URL or vendor the file into the site repository:

<link rel="stylesheet" href="https://unpkg.com/@jflamb/ledger@0.1.0/ledger.css">

Pin the version in production. Do not load an unversioned latest URL.

Use semantic tokens

Site components should use semantic roles rather than palette values:

.panel {
  color: var(--color-text-primary);
  background: var(--color-surface-panel);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-static);
  padding: var(--space-4);
}

.primary-action {
  min-block-size: var(--control-min-block-size);
  color: var(--color-text-on-action);
  background: var(--color-action);
  border-radius: var(--radius-control);
}

.primary-action:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-ring-offset);
}

Palette primitives such as --viridian and --paper are implementation details. Keeping components on semantic tokens lets Ledger improve contrast or rebalance themes without requiring component rewrites.

Rules of consumption

  1. Components consume only layer-2 semantic tokens (--color-*, --font-*, --text-*, --space-*, --radius-*, --control-*, --focus-*, --shadow-*). Layer-1 primitives (--paper, --ink, --viridian, …) are private to ledger.css and are the only values that change per theme.
  2. Color never carries meaning alone. Every status has a text label; selection changes border weight and adds a check, not just a fill.
  3. Square is static, round is interactive. --radius-static for panels and tables; --radius-control / --radius-selectable mark what can be operated.
  4. Shadows are for overlays only (--shadow-overlay): menus, tooltips, dialogs. Static grouping uses rules and the one-step paper raise.
  5. Type roles: --font-prose (serif) for display and explanatory text, --font-ui (system sans) for controls/navigation/dense labels, --font-mono for figures, dates, codes, and short statuses (with font-variant-numeric: tabular-nums).
  6. Site-local tokens (e.g. the dashboard's --chart-*) may alias down to Ledger tokens; they may not redefine shared names.

Token families

  • --color-*: text, surfaces, borders, actions, focus, and statuses
  • --font-*: prose, interface, and numeric roles
  • --text-*: type scale
  • --space-*: 4px spacing scale
  • --radius-*: static, tag, control, selectable, and pill shapes
  • --control-*: interaction sizing
  • --focus-*: keyboard focus treatment
  • --shadow-*: overlays only

The full token list and values live in ledger.css.

Theming

ledger.css defines light (default), dark (prefers-color-scheme and :root[data-theme="dark"], so a manual toggle beats the system), high contrast (prefers-contrast: more), and print. The theme preference is shared across subdomains via a first-party cookie — localStorage is origin-scoped and serves only as a same-origin fallback:

// set on toggle — readable by every *.jflamb.com origin
document.cookie =
  "jflamb-theme=dark; Domain=.jflamb.com; Path=/; Max-Age=31536000; SameSite=Lax; Secure";

// no-flash bootstrap (inline in <head>): cookie → localStorage → system
const t = document.cookie.match(/(?:^|; )jflamb-theme=(dark|light)/)?.[1]
       ?? localStorage.getItem("jflamb-theme");
if (t) document.documentElement.dataset.theme = t;

Use data-theme="light" or data-theme="dark" for a manual override. Without an override, Ledger follows prefers-color-scheme. The stylesheet also includes prefers-contrast: more and print values.

CI

npm test runs the contrast gate: it parses ledger.css itself and verifies every text-role/surface pair at ≥ 4.5:1 and every interactive-border/focus pair at ≥ 3:1, across light, dark, and high-contrast, and confirms the two dark blocks never diverge. A palette change that regresses accessibility fails the build.

Run the local checks before committing:

npm test
npm run check:package

npm run sync:site -- /path/to/jflamb.com vendors the canonical stylesheet into a zero-tooling site. npm run check:drift -- /path/to/jflamb.com verifies that copy byte-for-byte.

Versioning

Semver. Renaming or removing a primitive or semantic token is major; adding or re-pointing a semantic alias is minor; value tweaks that pass the gate are patch.

Publishing

  1. Update version in package.json and add a dated entry to CHANGELOG.md.
  2. Merge the change to main.
  3. Create a GitHub release whose tag exactly matches v<package version>.
  4. The publish workflow validates the tag, reruns the accessibility and package checks, and uses npm trusted publishing to stage the package with provenance.
  5. Review the package under Staged Packages on npmjs.com and approve it with 2FA.

The trusted publisher is restricted to publish.yml in jflamb/ledger and may only run npm stage publish. The repository stores no npm publishing token. Ordinary pushes and pull requests cannot stage or publish packages, and a staged release does not become public until a maintainer approves it with 2FA.

License

MIT

About

Shared CSS foundations and design tokens for jflamb.com projects

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages