ReviewOS

also looking at this

loghqorg/loghq

Promote main to production: signed-out chrome and the subscriber tables

#17
Merged glennmichael123 wants to merge main into production
54 files +4252 -1353

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

config/crosswind.tsmodified+16-1
Changes to config/crosswind.ts
@@ -101,7 +101,22 @@ export default {
101101 'fg': 'var(--text)',
102102 'fg-strong': 'var(--text)',
103103 'fg-muted': 'var(--text-2)',
104 'fg-soft': 'var(--text-2)',
104 /*
105 * The library's quiet text scale is four steps - fg, fg-muted, fg-soft,
106 * fg-subtle - and this palette has three, so two roles share a value.
107 * They used to share at the WRONG end: fg-soft was byte-identical to
108 * fg-muted, which makes "quieter than muted" exactly as loud as muted.
109 *
110 * Nothing renders it today, which is why it was invisible: of the 53
111 * <EmptyState> sites in the estate none passes an `icon` (the only
112 * thing there that reads fg-soft) and there is no <Badge dot>. But
113 * <Breadcrumb> paints separators with fg-soft and links with fg-muted,
114 * so the two being equal is a divider as loud as the labels it divides.
115 *
116 * Doubling up at the quiet end keeps the scale monotonic, so a
117 * component asking for a quieter grey gets one.
118 */
119 'fg-soft': 'var(--text-3)',
105120 'fg-subtle': 'var(--text-3)',
106121 'line-strong': 'color-mix(in srgb, var(--text-3) 55%, var(--border))',
107122 'line-hover': 'color-mix(in srgb, var(--text-2) 70%, var(--border))',
tests/unit/component-theme.test.tsmodified+29-0
Changes to tests/unit/component-theme.test.ts
@@ -5,6 +5,8 @@ import { loadCssEngine } from '../../node_modules/@stacksjs/stx/dist/dev-server/
55import { SEMANTIC_TOKENS, SHAPE_TOKENS } from '../../node_modules/@stacksjs/stx/dist/theme-tokens.js'
66import { mergeCssConfig } from '../../node_modules/@stacksjs/stx/dist/ts-css-config.js'
77
8const colors: Record<string, string> = theme.theme.extend.colors
9
810describe('component palette contract', () => {
911 test('every component color and radius emits an app-owned utility', async () => {
1012 const engine = await loadCssEngine()
@@ -21,4 +23,31 @@ describe('component palette contract', () => {
2123 expect(css).toContain('.rounded-control {\n border-radius: 10px;')
2224 expect(css).toContain('.rounded-panel {\n border-radius: 0.75rem;')
2325 })
26
27 test('the quiet text scale stays monotonic, so a separator cannot shout', () => {
28 /*
29 * The library asks for four steps of quiet text and this palette has three,
30 * so two roles share a value. Which two is the whole point.
31 *
32 * fg-soft used to equal fg-muted. Nothing rendered it -- none of the 53
33 * <EmptyState> sites passes an `icon` and there is no <Badge dot> -- so it
34 * was invisible, and the contract test above could not see it either: that
35 * one asserts every role is MAPPED, not that the mapping means anything.
36 * <Breadcrumb> paints separators with fg-soft and its links with fg-muted,
37 * so the two being equal is a divider as loud as the labels it divides.
38 *
39 * Asserted as an ordering rather than as literal values so re-theming the
40 * palette cannot quietly reintroduce it.
41 */
42 const steps = ['fg', 'fg-muted', 'fg-soft', 'fg-subtle'] as const
43 const rank: Record<string, number> = { 'var(--text)': 0, 'var(--text-2)': 1, 'var(--text-3)': 2 }
44 const ordered = steps.map((role) => {
45 const value = colors[role] ?? colors['fg-strong']
46 expect(rank[value]).toBeDefined()
47 return rank[value]
48 })
49 for (let i = 1; i < ordered.length; i++)
50 expect(ordered[i]).toBeGreaterThanOrEqual(ordered[i - 1])
51 expect(colors['fg-soft']).not.toBe(colors['fg-muted'])
52 })
2453})