refactor: components read the obsidian surface from its token, not a typed rgba (3108)

Thirteen rgba(20, 23, 26, ...) across six components (the task counted
eleven). They now use --v-theme-background, which Vuetify maps to obsidian;
ArtistHeader's banner fade uses --fc-chrome-rgb, since it is nav-style
chrome. A spec fails if the literal reappears outside a comment. Values are
unchanged, so nothing should render differently.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVjrnpQjRgHdvq95rASoiR
This commit is contained in:
2026-09-24 16:37:49 -04:00
co-authored by Claude Opus 5.5
parent f2e4ee4d17
commit 0842df46e9
7 changed files with 53 additions and 13 deletions
+40
View File
@@ -0,0 +1,40 @@
// The obsidian surface written out as a number instead of read from its token.
//
// fabled-tokens.js is the palette's single copy ("do not hand-edit hexes;
// re-mirror here"). Thirteen hand-typed `rgba(20, 23, 26, …)` across six
// components meant a changed obsidian would miss most of the UI (#3108).
// Components read `--v-theme-background` (Vuetify maps background → obsidian)
// or, for nav-style chrome, `--fc-chrome-rgb`. Comments may still name it.
import { readdirSync, readFileSync, statSync } from 'node:fs'
import { join, relative } from 'node:path'
import { fileURLToPath } from 'node:url'
import { describe, expect, it } from 'vitest'
const SRC = fileURLToPath(new URL('../src', import.meta.url))
const LITERAL = /rgba?\(\s*20\s*,\s*23\s*,\s*26\b/
function vueFiles (dir) {
return readdirSync(dir).flatMap((name) => {
const path = join(dir, name)
if (statSync(path).isDirectory()) return vueFiles(path)
return name.endsWith('.vue') ? [path] : []
})
}
function stripComments (text) {
return text.replace(/\/\*[\s\S]*?\*\//g, '').replace(/<!--[\s\S]*?-->/g, '')
}
describe('palette literals', () => {
it('no component hand-types the obsidian surface', () => {
const offenders = vueFiles(SRC).flatMap((path) =>
stripComments(readFileSync(path, 'utf8'))
.split('\n')
.filter((line) => LITERAL.test(line))
.map((line) => `${relative(SRC, path)}: ${line.trim()}`)
)
expect(offenders).toEqual([])
})
})