Skip to content

feat(design): converge foreground text tiers 5→3 (issue #430 PR4) - #479

Merged
Astro-Han merged 15 commits into
mainfrom
opencode/foreground-tier-converge
Jul 3, 2026
Merged

feat(design): converge foreground text tiers 5→3 (issue #430 PR4)#479
Astro-Han merged 15 commits into
mainfrom
opencode/foreground-tier-converge

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Collapse the 7-step foreground text ladder (40/50/60/70/80/90/95) into 3 semantic tiers:

  • --foreground — primary text (100% ink)
  • --foreground-secondary — secondary text (80% ink, new alias)
  • --muted-foreground — muted text (50% ink, existing alias)

--foreground-90/--foreground-95 had zero call sites; deleted. --foreground-40/50/60/70/80 are also fully deleted from maka-tokens.css — the aliases now compute directly via color-mix(in oklch, var(--foreground) N%, var(--background)) instead of pointing at intermediate stops. Surface wash stops (--foreground-2/3/5/8/10) remain for non-text use only.

Closes #430 (PR4 — foreground tier converge).

Why

The 7-step text ladder was the single biggest source of "layer hierarchy blur" in the UI. 40% and 50% are barely distinguishable to the eye; 60/70/80 are all "supporting text" that must stay readable. Industry research (WCAG, Material, Apple HIG) converges on 3 readable text tiers; a 4th (if any) is reserved for disabled/decorative. Desktop tools don't need fine granularity within "unimportant" — they need clear separation between primary, secondary, and muted.

Scope

Changed:

  • maka-tokens.css: new --foreground-secondary alias (80% color-mix) and updated --muted-foreground (50% color-mix); deleted all raw text stops --foreground-40/50/60/70/80/90/95 (definitions + @theme mirror); surface wash stops (--foreground-2/3/5/8/10) kept for non-text use
  • styles.css: shadcn @theme exports only surface wash + semantic aliases (--color-foreground-secondary, --color-muted-foreground); --color-muted-foreground maps to --muted-foreground (not retargeted to secondary)
  • 444 text call sites replaced across 20 CSS files (styles/), 3 TSX files (packages/ui/src, provider-connection-detail.tsx), 8 storybook stories
  • 4 existing test files updated to pin the new alias names
  • New contract test foreground-tier-contract.test.ts (100 tests) bans:
    • Raw --foreground-40..95 and --color-foreground-40..95 (theme mirror) in renderer CSS, maka-tokens.css, and TS/TSX (any context, strip comments)
    • Surface wash --foreground-2/3/5/8/10 (and --color-foreground-N mirror) used as text color in TS/TSX (token-based prefix classification, handles all Tailwind variants, complex arbitrary values, quoted inline styles, camelCase props, SVG attrs, @apply utility lists)
    • CSS text props (color/fill/stroke/caret-color/text-decoration-color/column-rule-color) referencing any --foreground-N (multi-line values supported)
    • Bare arbitrary properties [fill:...] / [stroke:...] / [color:...] in TS/TSX
    • Unquoted JS expressions in inline style / JSX attributes (bracket-depth-aware scanning)
  • docs/design-system.md §1.1 color table updated (raw text stops row removed)
  • docs/design-refinement-roadmap-2026-07.md §1.6 + §3 updated

Not included:

  • Surface wash stops (-2/-3/-5/-8/-10) — 187 call sites untouched (they're backgrounds/borders, not text)
  • --foreground-dimmed — kept as-is (1 @theme mirror, 0 call sites)
  • Light mode secondary AA normal contrast (3.97:1) — structural issue (foreground oklch 0.17 too deep), deferred to a separate PR
  • Pre-existing chat-primitives.test.ts failures (gap-[6px]/gap-[3px] pin mismatch) — unrelated to this change, fails on main too

Verification

  • npm run typecheck — all 6 workspaces pass
  • npm --workspace @maka/desktop test — 1821 tests pass, 0 fail
  • npm --workspace @maka/ui test — 13 pass, 2 fail (pre-existing, same on main)
  • npm run build — succeeds
  • Screenshot harness turn-narrative × 8 variants (light/dark × 1280/990 × motion/reduced) — all succeed
  • New contract test foreground-tier-contract.test.ts — 100 tests pass

User-facing impact

No visual regression. All text color changes go darker/clearer (40→50, 60→80, 70→80), never lighter. The 3-tier hierarchy reads crisper: primary, secondary, and muted are now clearly separable where the 7-step ladder had ambiguous neighbors.

Reviewer notes

  • The --foreground-secondary alias is new; --muted-foreground already existed and is now the canonical muted tier.
  • styles.css --color-muted-foreground (shadcn mapping) maps to --muted-foreground (50% mix), not --foreground-secondary. shadcn components that need secondary text use text-foreground-secondary (17 call sites migrated in packages/ui/src/ui.tsx).
  • Raw text stops (--foreground-40..95) are fully deleted from maka-tokens.css; the contract test ensures they cannot be re-introduced in CSS or TS/TSX.

@Astro-Han
Astro-Han force-pushed the opencode/foreground-tier-converge branch from 0fccae8 to 844cbb3 Compare July 3, 2026 11:27
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…und conflict

Address code review feedback on PR #479:

P1: contract test TSX scanner missed real-world Tailwind syntax.
  The regex only matched text-[color:var(--foreground-N)] (with
  color: prefix), missing text-[var(--foreground-N)] (no prefix),
  disabled:text-[var(--foreground-N)] (variant prefix), and
  text-foreground-N (utility class). Fixed regex to cover all
  forms; added 4 negative-case tests proving each is caught.

P2: @theme still exported --color-foreground-40/50/60/70/80 as
  Tailwind utilities, creating an entry point the contract test had
  to plug. Removed the raw text-stop exports; only surface wash
  (2/3/5/8/10) and semantic aliases (foreground-secondary,
  muted-foreground) remain. Added contract assertion.

P2: --color-muted-foreground had two conflicting definitions —
  maka-tokens.css pointed at --muted-foreground (-50, true muted)
  while styles.css pointed at --foreground-secondary (-80). Fixed:
  styles.css now aligns with tokens (--muted-foreground). Shadcn
  components that used text-muted-foreground for secondary text
  (button quiet, menu label, field description, etc.) switched to
  text-foreground-secondary. Placeholder, shortcut, and empty-icon
  usages remain text-muted-foreground (correct muted semantics).

P3: contract test now scans packages/ui/stories alongside src and
  renderer.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…n scan

Address second-round review on PR #479:

P1: TSX contract still missed real-world forms. The Tailwind-syntax
  regex approach kept growing but never covered all shapes (quoted
  className, cn() strings, template literals, Tailwind shorthand
  text-(--foreground-N)). Replaced with a raw-token scan: ban
  --foreground-40/50/60/70/80/90/95 from appearing in TS/TSX at all,
  plus a UTILITY_CLASS_RE for the --less form text-foreground-60.
  11 negative-case tests cover every syntax variant the reviewer
  listed.

P2: @theme raw-stop export assertion had a variable-name bug
  (--color- + --foreground-60 = --color---foreground-60, never
  matched). Fixed to --color-foreground-N.

P3: deleted --foreground-40/50/60/70/80 entirely. --muted-foreground
  and --foreground-secondary are now direct color-mix() definitions,
  not aliases pointing at raw stops. No production code references
  the raw stops.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…ners

Address third-round review on PR #479:

P2: surface wash tokens (foreground-2/3/5/8/10) could still be used
  as text color via text-foreground-5, text-[color:var(--foreground-
  5)], text-(--foreground-5). Added TEXT_UTILITY_RE (bans all N in
  text-foreground-N), TEXT_ARBITRARY_RE, TEXT_SHORTHAND_RE, and
  TEXT_INLINE_RE to catch surface wash in text context only; bg/
  border context remains allowed. Fixed 2 real violations in
  chat.tsx (load-tool-count/footer used --foreground-2 as text color,
  now --muted-foreground).

P2: CSS text scanner only banned 40/50/60/70/80, missing 90/95.
  Unified all scanners to use BANNED_TEXT_NUMS = 40..95; CSS, TSX
  raw scan, TSX utility scan, and @theme export scan all derive
  from the same set.

P3: updated contract header comment — old description of raw mix
  stops staying in maka-tokens.css and aliases pointing at
  --foreground-50/80 was stale.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
Address fourth-round review on PR #479:

P2: scattered regex approach still missed forms: arbitrary
  property [color:var(--foreground-5)], type-hint shorthand
  text-(color:--foreground-5), fill/stroke/caret/decoration
  utility classes, and var() with fallback
  (var(--foreground-5, currentColor)). Replaced 5 separate
  regexes with a unified TEXT_CONTEXT_RE that matches any
  text-like context prefix (text/fill/stroke/caret/decoration/
  color:) followed by --foreground-N, regardless of Tailwind
  syntax or var() closure. Surface context (bg/border/ring/
  from/to/via) remains allowed. 11 new negative cases.

P3: maka-tokens.css solid mix scale comment still described
  stops as 'body text, captions, dividers' — updated to state
  they are surface-only; text uses the 3 semantic aliases.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…ary fix

Address fifth-round review on PR #479:

P2: CSS text scanner still required var() to close —
  color: var(--foreground-5, currentColor) bypassed it.
  Changed FOREGROUND_TOKEN_RE from matching var(--foreground-N)
  to matching --foreground-N directly (no var() dependency).
  Found 1 real violation in onboarding.css (used
  --foreground-80 with oklch fallback as text color); fixed to
  --foreground-secondary.

P3: TEXT_CONTEXT_RE inline-style alternative (D) matched any
  substring containing color:/fill:/stroke:,误杀ing
  [border-color:...] and [background-color:...]. Added
  declaration-boundary requirement (^, whitespace, ;, {, quote)
  so only bare color/fill/stroke properties are caught. Added
  alternative E for hyphenated text-like properties
  ([caret-color:...], [text-decoration-color:...]).
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…ead code

Address sixth-round review on PR #479:

P2-a: Added global raw-stop ban for renderer CSS and maka-tokens.css
  (strip comments, then assert no --foreground-40..95 in any context).
  Previously CSS scanner only checked text props; raw stops could
  linger in bg/border and fail at runtime.

P2-b: TSX scanner replaced the single mega-regex (TEXT_CONTEXT_RE,
  5 alternatives) with a token-based approach: split source into
  class-like tokens, classify by prefix (text/fill/stroke/caret/
  decoration vs bg/border/ring), then search for --foreground-N
  anywhere inside text-like tokens. Catches complex arbitrary values
  like text-[color:color-mix(...,var(--foreground-5),...)] that the
  old regex missed (token no longer needs to be right after prefix).
  CSS declaration value regex changed from [^;}\n] to [^;}] so
  multi-line values (color-mix with line breaks) are scanned.

P3-a: [color:] arbitrary property is now classified by utility
  prefix — bg-[color:...], border-[color:...], ring-[color:...] pass
  (surface context), bare [color:...] still fails (text context).

P3-b: Deleted unused ALL_BANNED_NUMS constant and its stale comment
  (claimed TSX can't distinguish context — the new scanner does).
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…nline style

Address seventh-round review on PR #479:

P2-a: stripVariant now scans right-to-left tracking bracket/paren
  depth and cuts at the last ':' outside any nesting. Uniformly
  handles data-[state=open]:, group-hover/item:, [&.is-dragging]:
  without per-variant regexes.

P2-b: INLINE_STYLE_RE now accepts optional quote (", ', `) between
  the property name and var(, so style={{ color: "var(--fg-5)" }}
  and template-literal values are caught. Surface wash stops can no
  longer hide behind quoted inline-style values.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…x inline values

Address eighth-round review on PR #479:

P2-a: Token regexes unified to --(?:color-)?foreground-N so the
  @theme mirror form (--color-foreground-N) cannot bypass the text-
  context scanner. RAW_STOP_THEME_RE now bans --color-foreground-40..95
  globally alongside --foreground-40..95. @theme surface wash exports
  (--color-foreground-2/3/5/8/10) remain allowed in non-text context.

P2-b: New findCssApplyOffenders reuses the TSX token classifier on
  each @apply utility list, banning text-foreground-N / fill-foreground-N
  / text-[color:var(--foreground-N)] while allowing bg/border/ring.
  Added production scan for renderer CSS @apply directives.

P2-c: scanTextPropValue replaces INLINE_STYLE_RE. Locates text-like
  property names (color/fill/stroke/caretColor/textDecorationColor/
  columnRuleColor in kebab-case and camelCase), extracts the full
  value (quoted or bare, including commas inside quotes), and scans
  for foreground tokens. Catches complex values (color-mix(...)),
  camelCase props (caretColor), and JSX SVG attributes (fill="...",
  stroke={...}).
Astro-Han added a commit that referenced this pull request Jul 3, 2026
… expressions, dedupe property list

Address ninth-round review on PR #479:

P2-a: BARE_TEXT_PROP_RE now includes fill and stroke — Tailwind
  arbitrary properties [fill:var(--foreground-5)] and [stroke:...]
  (SVG color props) are caught as text-like context. Surface bare
  properties ([background:...], [border-color:...]) still pass.

P2-b: scanTextPropValue unquoted branch now tracks bracket/paren
  depth and scans to the matching }, so commas inside function
  calls (e.g. pick(base, "var(--foreground-5)")) are included
  instead of truncating at the first comma.

P3-a: Deleted unused TEXT_PROP_NAMES_RE; scanTextPropValue now
  generates its regex from the shared TEXT_PROP_NAMES array, so
  there is a single property-name list.
Astro-Han added a commit that referenced this pull request Jul 3, 2026
…ine style values

Address tenth-round review on PR #479:

P2: scanTextPropValue's unquoted branch now uses readExpressionValue,
a helper that tracks quote, (), [], and {} depth. Stops at the real
end of the current property/attribute (depth-0 comma, semicolon, or
closing brace), not at the first newline. Opening { at the start of
a JSX expression is treated as part of the value, so fill={pick(...)}
is fully scanned. Multi-line expressions like colorMix(\n base,\n
"var(--foreground-5)"\n) are caught. Surface properties after a
text property (color: semantic, background: "var(--foreground-5)")
are no longer误报ed because the comma at depth 0 terminates the
text property's value before the surface property begins.
Astro-Han added 15 commits July 4, 2026 00:59
…0/-95

Add --foreground-secondary (→ --foreground-80) as the canonical
secondary text tier alongside the existing --muted-foreground (→
--foreground-50). Delete --foreground-90/-95 which had zero call
sites. Update shadcn --color-muted-foreground mapping to target
--foreground-secondary so the Tailwind utility aligns with maka's
secondary tier. Update maka-tokens.css internal call sites to use
the new aliases. Update docs/design-system.md §1.1 color table.

Part of issue #430 PR4 (foreground tier converge).
New foreground-tier-contract.test.ts bans text props (color/fill/
stroke) from referencing raw --foreground-40/50/60/70/80 directly,
enforcing the 3-tier semantic aliases. Verify --foreground-secondary
targets -80, --muted-foreground targets -50, -90/-95 not defined.
Update design-refinement-roadmap-2026-07.md §1.6 (4-tier → 3-tier)
and §3 (mark foreground-tier-converge done).

Part of issue #430 PR4 (foreground tier converge).
…und conflict

Address code review feedback on PR #479:

P1: contract test TSX scanner missed real-world Tailwind syntax.
  The regex only matched text-[color:var(--foreground-N)] (with
  color: prefix), missing text-[var(--foreground-N)] (no prefix),
  disabled:text-[var(--foreground-N)] (variant prefix), and
  text-foreground-N (utility class). Fixed regex to cover all
  forms; added 4 negative-case tests proving each is caught.

P2: @theme still exported --color-foreground-40/50/60/70/80 as
  Tailwind utilities, creating an entry point the contract test had
  to plug. Removed the raw text-stop exports; only surface wash
  (2/3/5/8/10) and semantic aliases (foreground-secondary,
  muted-foreground) remain. Added contract assertion.

P2: --color-muted-foreground had two conflicting definitions —
  maka-tokens.css pointed at --muted-foreground (-50, true muted)
  while styles.css pointed at --foreground-secondary (-80). Fixed:
  styles.css now aligns with tokens (--muted-foreground). Shadcn
  components that used text-muted-foreground for secondary text
  (button quiet, menu label, field description, etc.) switched to
  text-foreground-secondary. Placeholder, shortcut, and empty-icon
  usages remain text-muted-foreground (correct muted semantics).

P3: contract test now scans packages/ui/stories alongside src and
  renderer.
…n scan

Address second-round review on PR #479:

P1: TSX contract still missed real-world forms. The Tailwind-syntax
  regex approach kept growing but never covered all shapes (quoted
  className, cn() strings, template literals, Tailwind shorthand
  text-(--foreground-N)). Replaced with a raw-token scan: ban
  --foreground-40/50/60/70/80/90/95 from appearing in TS/TSX at all,
  plus a UTILITY_CLASS_RE for the --less form text-foreground-60.
  11 negative-case tests cover every syntax variant the reviewer
  listed.

P2: @theme raw-stop export assertion had a variable-name bug
  (--color- + --foreground-60 = --color---foreground-60, never
  matched). Fixed to --color-foreground-N.

P3: deleted --foreground-40/50/60/70/80 entirely. --muted-foreground
  and --foreground-secondary are now direct color-mix() definitions,
  not aliases pointing at raw stops. No production code references
  the raw stops.
…ners

Address third-round review on PR #479:

P2: surface wash tokens (foreground-2/3/5/8/10) could still be used
  as text color via text-foreground-5, text-[color:var(--foreground-
  5)], text-(--foreground-5). Added TEXT_UTILITY_RE (bans all N in
  text-foreground-N), TEXT_ARBITRARY_RE, TEXT_SHORTHAND_RE, and
  TEXT_INLINE_RE to catch surface wash in text context only; bg/
  border context remains allowed. Fixed 2 real violations in
  chat.tsx (load-tool-count/footer used --foreground-2 as text color,
  now --muted-foreground).

P2: CSS text scanner only banned 40/50/60/70/80, missing 90/95.
  Unified all scanners to use BANNED_TEXT_NUMS = 40..95; CSS, TSX
  raw scan, TSX utility scan, and @theme export scan all derive
  from the same set.

P3: updated contract header comment — old description of raw mix
  stops staying in maka-tokens.css and aliases pointing at
  --foreground-50/80 was stale.
Address fourth-round review on PR #479:

P2: scattered regex approach still missed forms: arbitrary
  property [color:var(--foreground-5)], type-hint shorthand
  text-(color:--foreground-5), fill/stroke/caret/decoration
  utility classes, and var() with fallback
  (var(--foreground-5, currentColor)). Replaced 5 separate
  regexes with a unified TEXT_CONTEXT_RE that matches any
  text-like context prefix (text/fill/stroke/caret/decoration/
  color:) followed by --foreground-N, regardless of Tailwind
  syntax or var() closure. Surface context (bg/border/ring/
  from/to/via) remains allowed. 11 new negative cases.

P3: maka-tokens.css solid mix scale comment still described
  stops as 'body text, captions, dividers' — updated to state
  they are surface-only; text uses the 3 semantic aliases.
…ary fix

Address fifth-round review on PR #479:

P2: CSS text scanner still required var() to close —
  color: var(--foreground-5, currentColor) bypassed it.
  Changed FOREGROUND_TOKEN_RE from matching var(--foreground-N)
  to matching --foreground-N directly (no var() dependency).
  Found 1 real violation in onboarding.css (used
  --foreground-80 with oklch fallback as text color); fixed to
  --foreground-secondary.

P3: TEXT_CONTEXT_RE inline-style alternative (D) matched any
  substring containing color:/fill:/stroke:,误杀ing
  [border-color:...] and [background-color:...]. Added
  declaration-boundary requirement (^, whitespace, ;, {, quote)
  so only bare color/fill/stroke properties are caught. Added
  alternative E for hyphenated text-like properties
  ([caret-color:...], [text-decoration-color:...]).
--foreground-40/50/60/70/80 were deleted in a prior commit but
design-system.md still listed them as internal mix stops. Removed
the stale row; only surface wash (2/3/5/8/10) and semantic aliases
(foreground/foreground-secondary/muted-foreground) remain.
…ead code

Address sixth-round review on PR #479:

P2-a: Added global raw-stop ban for renderer CSS and maka-tokens.css
  (strip comments, then assert no --foreground-40..95 in any context).
  Previously CSS scanner only checked text props; raw stops could
  linger in bg/border and fail at runtime.

P2-b: TSX scanner replaced the single mega-regex (TEXT_CONTEXT_RE,
  5 alternatives) with a token-based approach: split source into
  class-like tokens, classify by prefix (text/fill/stroke/caret/
  decoration vs bg/border/ring), then search for --foreground-N
  anywhere inside text-like tokens. Catches complex arbitrary values
  like text-[color:color-mix(...,var(--foreground-5),...)] that the
  old regex missed (token no longer needs to be right after prefix).
  CSS declaration value regex changed from [^;}\n] to [^;}] so
  multi-line values (color-mix with line breaks) are scanned.

P3-a: [color:] arbitrary property is now classified by utility
  prefix — bg-[color:...], border-[color:...], ring-[color:...] pass
  (surface context), bare [color:...] still fails (text context).

P3-b: Deleted unused ALL_BANNED_NUMS constant and its stale comment
  (claimed TSX can't distinguish context — the new scanner does).
…nline style

Address seventh-round review on PR #479:

P2-a: stripVariant now scans right-to-left tracking bracket/paren
  depth and cuts at the last ':' outside any nesting. Uniformly
  handles data-[state=open]:, group-hover/item:, [&.is-dragging]:
  without per-variant regexes.

P2-b: INLINE_STYLE_RE now accepts optional quote (", ', `) between
  the property name and var(, so style={{ color: "var(--fg-5)" }}
  and template-literal values are caught. Surface wash stops can no
  longer hide behind quoted inline-style values.
…x inline values

Address eighth-round review on PR #479:

P2-a: Token regexes unified to --(?:color-)?foreground-N so the
  @theme mirror form (--color-foreground-N) cannot bypass the text-
  context scanner. RAW_STOP_THEME_RE now bans --color-foreground-40..95
  globally alongside --foreground-40..95. @theme surface wash exports
  (--color-foreground-2/3/5/8/10) remain allowed in non-text context.

P2-b: New findCssApplyOffenders reuses the TSX token classifier on
  each @apply utility list, banning text-foreground-N / fill-foreground-N
  / text-[color:var(--foreground-N)] while allowing bg/border/ring.
  Added production scan for renderer CSS @apply directives.

P2-c: scanTextPropValue replaces INLINE_STYLE_RE. Locates text-like
  property names (color/fill/stroke/caretColor/textDecorationColor/
  columnRuleColor in kebab-case and camelCase), extracts the full
  value (quoted or bare, including commas inside quotes), and scans
  for foreground tokens. Catches complex values (color-mix(...)),
  camelCase props (caretColor), and JSX SVG attributes (fill="...",
  stroke={...}).
… expressions, dedupe property list

Address ninth-round review on PR #479:

P2-a: BARE_TEXT_PROP_RE now includes fill and stroke — Tailwind
  arbitrary properties [fill:var(--foreground-5)] and [stroke:...]
  (SVG color props) are caught as text-like context. Surface bare
  properties ([background:...], [border-color:...]) still pass.

P2-b: scanTextPropValue unquoted branch now tracks bracket/paren
  depth and scans to the matching }, so commas inside function
  calls (e.g. pick(base, "var(--foreground-5)")) are included
  instead of truncating at the first comma.

P3-a: Deleted unused TEXT_PROP_NAMES_RE; scanTextPropValue now
  generates its regex from the shared TEXT_PROP_NAMES array, so
  there is a single property-name list.
…ine style values

Address tenth-round review on PR #479:

P2: scanTextPropValue's unquoted branch now uses readExpressionValue,
a helper that tracks quote, (), [], and {} depth. Stops at the real
end of the current property/attribute (depth-0 comma, semicolon, or
closing brace), not at the first newline. Opening { at the start of
a JSX expression is treated as part of the value, so fill={pick(...)}
is fully scanned. Multi-line expressions like colorMix(\n base,\n
"var(--foreground-5)"\n) are caught. Surface properties after a
text property (color: semantic, background: "var(--foreground-5)")
are no longer误报ed because the comma at depth 0 terminates the
text property's value before the surface property begins.
…d aliases to main's new CSS files

Address tenth-round review P3: readExpressionValue now treats a
depth-0 opening brace as a function/class body boundary and stops,
preventing the text-prop scanner from reading into function bodies
after a type annotation like fill: string) { ... }.

Also re-applies foreground alias replacement (40/50→muted-foreground,
60/70/80→foreground-secondary) to CSS files introduced by main's
#485 (module-pages/skills.css, module-pages/capability-audit.css,
module-pages/plan-reminders.css, module-pages/module-shell.css,
model-switcher.css).
@Astro-Han
Astro-Han force-pushed the opencode/foreground-tier-converge branch from 9766780 to 5c639d0 Compare July 3, 2026 17:02
@Astro-Han
Astro-Han merged commit 3d7d766 into main Jul 3, 2026
@Astro-Han
Astro-Han deleted the opencode/foreground-tier-converge branch July 3, 2026 17:09
jackwener added a commit that referenced this pull request Jul 4, 2026
…code cleanup (round 4) (#492)

* fix(ui): unify chat panel surface + kill startup empty-state flash

- .maka-main painted solid var(--background) over only the chat scroll
  area, so on darwin glass (--agents-content-area-bg #fafafa) the
  composer region below read as a THIRD color band (shell / chat /
  composer). Now transparent: one panel, one surface, both themes.
- remove the dead theme-glass darwin .maka-panel-detail override — it
  always lost to the .agents-content-area rule on specificity (0,3,0
  vs 0,2,1) and its half-applied intent is what created the band.
- snapshot session seeding moves useEffect → useLayoutEffect: the
  snapshot render un-gates the loading state while sessions is still
  [], and a passive effect seeds after paint — users with history saw
  a one-frame empty-state hero flash on every startup (闪屏).
  permission-response-ipc-boundary contract updated to accept the
  layout effect on the boot path.

* refactor(ui): skills marketplace static 即将上线 tag + dead export cleanup

- marketplace card 安装 was a permanently-disabled button — a dead
  control that promises interactivity (the codebase already replaced
  the filter pills for the same reason). Now a static 即将上线 pill.
- drop 6 never-imported lucide icon re-exports from @maka/ui/icons.
- un-export 4 internal-only helpers (plan-reminder sort ranks,
  createAbsoluteTimeFormat) — file-local implementation details.
  smooth-stream helpers stay exported: they're unit-tested.

* refactor(daily-review): single time-context header, unboxed hint (IA pass 1)

Owner feedback: 页面太乱、不直观. Root of the mess was time context
split across the page — date stepper at top, 今日/本周/本月 tabs
floating mid-page above the stats they control, with a two-paragraph
explainer card pushing everything below the fold.

- header is now the one time bar: stepper + day label left, range
  tabs right (tabs relocated from the mid-page nav, which is gone).
- explainer card unboxed to a single quiet hint line.
- export actions (复制/粘到输入框/保存) keep their conditional but now
  sit directly above the stats they export, right-aligned.
- radius contract entry for the retired info card removed.

* fix(skills): 即将上线 pill uses semantic text alias (post-#479 tier ban)

* fix(plan-reminders): retire two dead controls on the cron page

- 保持系统唤醒 was a permanently-disabled Switch (checked=false,
  aria-label literally said 暂未启用) — a dead toggle promising
  interactivity. Now a static 即将支持 pill in the info-alert tint,
  same precedent as the skills marketplace 即将上线 tag.
- completed one-shot reminders showed a disabled OFF switch that read
  as 'paused', not 'done' — a terminal state can't be re-enabled, so
  the card chrome now shows an 已完成 badge instead of the toggle.

* refactor(daily-review): report section rhythm (IA pass 2)

The four report blocks (对话摘要/遗漏提醒/使用洞察/代码建议) sat at a
uniform 8px cadence and read as one slab. 8px within a section, 16px +
hairline divider between sections — divider over nested cards per the
anti-nested-box rule.

* feat(daily-review): render report sections through the shared Markdown pipeline

Reports are LLM-generated markdown; flat pre-wrap <p> text turned
bullet lists and inline code into mush. Reuse the chat Markdown
component (lazy pipeline, secret redaction, link gating included) and
restore list markers locally (preflight strips them).

* fix(settings): workspace path renders as mono block, not ragged right-aligned prose

SettingRow gains an opt-in mono value mode (data-mono) — long machine
values like the workspace path wrapped into a ragged right-aligned
3-line block in proportional type. Mono + left-aligned + caption size
reads as the file path it is. First consumer: 数据 page 工作区路径.

* fix(settings/memory): anchor the floating MEMORY.md meta strip

The path + backup/draft/count status words floated unboxed between two
cards and read as orphaned fragments. A hairline top border + breathing
room marks the strip as the editor's status footnote (divider over a
nested card, per the anti-nested-box rule).

* fix(chat): lineage badge no longer doubles the word turn

shortId sliced the raw turnId, but real ids start with turn- and the
labels interpolate as turn ${shortId} — badges rendered「已重新生成 →
turn turn-r」with one useful character of id. Strip the prefix first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(ui): converge design-token magic numbers (motion, typography, spacing)

1 participant