Ui Bugs
SVG via <img> cannot inherit currentColor; index.html cannot link workspace-package assets
SVG via <img> cannot inherit currentColor; index.html cannot link workspace-package assets
Problem
The shared brand mark (Mark A) ships as SVG assets in @spectral/design-tokens/assets/. Two consumption paths silently fail:
- A single-ink variant using
fill="currentColor"loaded with<img src={markUrl}>renders black — an SVG document loaded through<img>is an isolated document with no CSS inheritance, socurrentColorresolves to the initial value. - A favicon
<link rel="icon" href="@spectral/design-tokens/assets/favicon.svg">inindex.htmldoes not work — Vite resolves bare module specifiers in JS, not in HTML attribute URLs.
Root Cause
currentColor is resolved against the embedding context only when the SVG is part of the same DOM (inline <svg>) or used as a CSS mask/background with background-color: currentColor. <img>/favicon contexts isolate the SVG document. Separately, Vite’s HTML transform only rewrites relative asset paths, not workspace package specifiers.
Solution
- Single-ink in-app marks: render an inline React component (
<Mark mono>in@spectral/ui,packages/ui/src/mark.tsx) — the rects usefill="currentColor"with the 1/0.66/0.40 opacity falloff and genuinely inherit the surrounding color. - Favicon: import the asset URL in the entry module and inject the link at boot via the shared
installFavicon(faviconUrl)helper (@spectral/ui); the favicon SVG itself uses a fixed ink, nevercurrentColor. - The static
mark-mono.svgasset stays for mask/static use; its header comment states the inline/mask requirement.
Prevention
- Any “inherits currentColor” claim about an SVG asset must name the consumption mechanism (inline component or CSS mask).
<img>is never it. - New apps adopt the brand by depending on
@spectral/ui(<Mark>,installFavicon) rather than wiring raw assets.
References
- SPEC-603 review fix commit
7034d76; merge5570e9cb.