Almanac Visual QA — 2026-05

Defect register for the Almanac theme across phareim.no, 19 pages × {light, dark}, pinned to `phareim.no @ 8657770`


Almanac visual QA — 2026-05

Pass run on 2026-05-12, phareim.no @ 8657770 (the QA commit itself). Rig: scripts/almanac-qa.mjs. Captures: ~/github/phareim.no/.qa/almanac/<page>-<mode>.png + .vars.json per cell + status.json + index.json.

Why this exists

Almanac is the newest of four themes in [[phareim.no]] (scandi, hacker, space, almanac), added in commit c70bba1. The older three accumulated per-page CSS overrides one page at a time; Almanac inherits the override mechanism but not the overrides, so each page reveals whether anyone remembered to think about it. This pass is the baseline — next pass diffs against it.

Surfaced from sfl meta WF236ulE (priority HIGH).

Methodology (reproducible)

Known rig bug, not a defect: the overlay-detection selector (.nuxt-error, nuxt-error) does not match Nuxt's actual dev error overlay, which is visible bottom-right of error-light.png. Fix the selector before the next pass.

Out of scope (explicit non-goals)

Almanac correctness checklist (derived from DESIGN.md)

  1. hairline-not-box — cards/sections use 1px rules (--almanac-rule-light / --almanac-rule-dark), no shadows, no rounded panels (--theme-card-radius: 0 per assets/themes/almanac.css).
  2. accent-only-at-attention--almanac-rust (light) / --almanac-amber (dark) appears at most once per primary view, at the moment of attention.
  3. serif-body-always — body type is the Georgia stack (--font-almanac-body).
  4. stars-dark-onlyAlmanacPaper stars render only in dark, sparse.
  5. no-chrome — no gradients (except midnight bg), no shadows, no synthetic window decoration.
  6. paper / midnight bg--almanac-paper (#f4f0e8) in light, midnight gradient in dark.
  7. CSS vars propagate — canvas/SVG elements read theme via CSS custom properties or inline overrides. Cross-checked via the per-cell .vars.json sidecars.
  8. link discipline — links read as ink, accent only on hover (color rule; hover behavior out of scope).

The .vars.json sidecars confirm the page-level wrapper (.almanac-page) propagates all eight semantic tokens correctly on all 19 routes in both modes — i.e. the theme system itself is sound. Every defect below is a per-page override that ignores those tokens.

Page × mode status table

Page Light Dark Notes
/ (index) broken broken hardcoded saturated canvas circles, both modes (green/tan light, blue/purple dark)
/about ok ok best-in-class Almanac fit
/activity minor minor accent overuse (rule 2); dark cards near-invisible
/clock ok broken dark: second hand has no visible accent (rust hardcoded, --theme-accent not applied)
/colophon ok ok alignment baseline
/feed ok ok
/focus minor broken dark: 25:00 timer near-illegible, ring nearly invisible
/gallery ok ok clean empty state
/guestbook minor minor input radius non-zero; dark borders too subtle
/lab broken broken green LIVE badges + red-dot emoji-style decoration + rounded cards — off-theme
/meta minor minor commit cards rounded; dark borders too subtle
/morse minor minor reference letter cards rounded; dark cards near-invisible
/now ok ok best-in-class
/playground minor minor filled rust/amber button (defensible); textarea + selects + image-frame rounded
/projects minor minor cards rounded; dark cards near-invisible; title low contrast in dark
/stats minor minor metric cards rounded; dark borders too subtle
/terminal broken broken macOS-style window chrome (stoplight buttons + chrome bar + rounded frame) violates no-chrome
/uses ok ok
/this-does-not-existerror.vue ok ok the 404 page itself is Almanac-correct; the dev-only error overlay in light is rig artifact, not a defect

Tally: 9 cells broken, 18 minor, 11 ok, 0 known-gap.

The zero-known-gap count matters: it falsifies a prior assumption. The "Almanac scoped overrides for canvas/SVG pages" meta assumed canvas/SVG would fail to read CSS variables. The .vars.json sidecars and clock-light + morse + terminal text show the opposite — Almanac reaches SVG paint fine via currentColor and direct token reads. The canvas defects that remain (index circles, clock-dark second hand) are page-specific hardcoded colors, not a propagation gap. That meta needs re-scoping or closing — see cross-references.

Defects (ranked by leverage)

1. Landing page canvas decoration ignores Almanac — severity: blocker

File: pages/index.vue (canvas/SVG decoration logic). Rule violated: 5 (no-chrome) and 7 (CSS vars propagate). Evidence: .qa/almanac/index-light.png, .qa/almanac/index-dark.png — saturated green/tan (light) and blue/purple (dark) circles dominate the viewport, completely off-theme. Why blocker: this is the first impression for every visitor on /. Under Almanac the landing page should be paper-with-restraint, not '90s-Geocities-circles. Proposed fix: make the decoration theme-aware — either swap to an Almanac-specific variant (sparse stars from AlmanacPaper.vue already covers this aesthetic) or hide it entirely when activeTheme === 'almanac', mirroring how <SpaceStarfield v-if="activeTheme === 'space'" /> is conditional in app.vue.

2. Terminal page hardcodes macOS window chrome — severity: blocker

File: pages/terminal.vue (terminal-window decoration). Rule violated: 5 (no-chrome). Evidence: terminal-{light,dark}.png — red/yellow/green stoplight buttons, chrome title bar with phareim@phareim.no — bash, rounded window frame. The hacker/space themes are clearly bleeding through. Proposed fix: when activeTheme === 'almanac', render the terminal flat — drop the stoplights and the chrome bar, render the prompt as plain serif body text on paper / midnight. Could also keep bash-style monospace inside but lose the OS window decoration.

3. pages/clock.vue second hand has no Almanac-dark accent — severity: visible

Rule violated: 2 (accent-only-at-attention). Evidence: clock-light.png shows rust second hand (correct moment-of-attention). clock-dark.png shows monochrome cream face — the second hand is either hardcoded rust (invisible against the midnight-similar value) or doesn't read --theme-accent (amber #d4a574 in dark). Proposed fix: change second-hand stroke to var(--theme-accent) (or var(--almanac-amber) when dark mode is the only consumer). getComputedStyle on .almanac-page already returns --theme-accent: #d4a574 in dark — the page just isn't reading it.

4. Dark-mode hairline rule is too subtle — severity: visible (systemic)

File: assets/themes/almanac.css — the token --almanac-rule-dark: rgba(255, 255, 255, 0.10). Rule violated: 1 (hairline-not-box) — the rule is technically present but visually absent on cards across activity, stats, projects, meta, morse, guestbook, focus. Evidence: every *-dark.png cell with cards has near-zero card definition; cards float as untethered text. Proposed fix: raise --almanac-rule-dark opacity to ~`0.180.22, OR split into --almanac-rule-dark-card(stronger) and--almanac-rule-dark-separator` (subtle, for short rules between sections). Cross-check that 0.18 doesn't muddy the "hairline" intent — DESIGN.md should be the arbiter.

5. pages/lab.vue has off-theme decoration — severity: visible

Rule violated: 7 (CSS vars propagate) and arguably 2. Evidence: lab-{light,dark}.png — saturated green LIVE pill badges (color stays the same in both modes), red-dot emoji-style red circle as decoration for the /red-dot/ tool card. Proposed fix: render LIVE badges as hairline pills with --almanac-ink-mute text (or --theme-accent if "this is live" is the moment-of-attention). The red-dot emoji is illustrative content for the project itself, so keep it but render under [data-theme="almanac"] with currentColor: var(--theme-accent) if it should harmonize.

6. pages/focus.vue dark-mode timer contrast — severity: visible

Rule violated: body text contrast (rule 3 implied via legibility). Evidence: focus-dark.png25:00 numerals rendered in --theme-text-subtle (#5a6a7a) range, near-illegible against #0e1219 midnight. Light mode is fine. Proposed fix: use var(--theme-text) (#ebe4d4 in dark) for the primary timer numerals, reserve subtle tones for the "ready" / state label.

7. Per-page border-radius overrides ignore --theme-card-radius: 0severity: nit (systemic, many sites)

Rule violated: 1 (hairline-not-box — Almanac is flat-rectangular by design). Evidence: project cards, morse letter chips, playground textarea/selects/image-frame, stats metric cards, meta commit cards, focus keyboard-shortcut chips, guestbook inputs — all visibly rounded (~6–12px). Likely each has a per-page border-radius: <px> instead of reading var(--theme-card-radius, 0). Proposed fix: grep border-radius: in pages/ + components/, replace literal radius values with var(--theme-card-radius, <fallback>). Set the fallback to whatever the other three themes want (likely 6–8px). Note: this is a nit only because the visual offense per cell is small. As a pattern across 8+ pages it's the most ubiquitous Almanac violation, so the fix is one PR that touches many files. May be cheaper to address before the per-page bug fixes above.

Cross-references to sibling sfl metas

Follow-up sfl metas filed

After this pass, the following meta items have been added to github.com/phareim/phareim.no (clustered by root cause, not per cell):

Reproducing this pass

cd ~/github/phareim.no
git checkout 8657770    # or HEAD if conventions remain stable
npm install
npm run dev &           # binds :3030
npm run qa:almanac      # writes to .qa/almanac/

Outputs: 38 PNGs + 38 .vars.json + index.json + status.json in .qa/almanac/. Re-grade by walking status.json against the checklist above.

See also

— GRAPH
— 0 RELATED