Summary
Preview currently has a standards/cascade issue for top-level user at-rules (notably @import) and lacks a first-class way to mirror app-global font families without adding temporary font-loading CSS in every PR.
This proposal combines:
- B: Separate runtime base CSS and user CSS into distinct style elements.
- A: Add optional workspace font configuration so preview can load known app fonts once and let user code stay DRY.
Problem
- User
@import rules can be ignored when runtime base CSS is prepended in the same stylesheet.
- Teams often rely on app-global typography; in preview they currently need extra
@font-face/@import glue that would not exist in real app code.
- This encourages non-DRY preview-specific PR changes.
Goals
- Standards-compliant user CSS behavior in preview.
- Typography parity with real applications.
- Minimal preview-only CSS boilerplate in component PRs.
- Preserve current isolation and rendering behavior.
Non-goals
- Building a complex font marketplace UI.
- Supporting arbitrary third-party providers without clear constraints.
- Changing iframe isolation model.
Preferred implementation order
- Phase 1 (B - correctness): split style injection into two elements.
- Phase 2 (A - DX): add optional workspace-level font configuration and runtime font preload/injection.
Rationale:
- Phase 1 removes the current standards/cascade bug safely and independently.
- Phase 2 then layers in DRY typography support on stable styling semantics.
Proposed implementation
Phase 1 (B)
- Maintain two dedicated style nodes in preview document head:
knighted-preview-base-styles
knighted-preview-user-styles
- Keep deterministic order: base first, user second.
- Update patch/render paths to mutate text content only (no duplicate nodes).
- Preserve existing render lifecycle and mode behavior (React/DOM).
Phase 2 (A)
- Introduce optional workspace font config (e.g. list of families/sources/weights/styles).
- Load configured fonts once per preview document.
- Allow component and style tabs to reference configured family names directly.
- Surface load failures in diagnostics/status (network, CORS, invalid source).
Acceptance criteria
- Top-level user
@import is no longer ignored in preview.
- Existing user-overrides-over-base cascade behavior remains intact.
- No duplicate style tags across repeated renders/config patches.
- Optional workspace font config loads fonts and enables direct
font-family usage without per-PR font glue CSS.
- React and DOM mode behavior remains unchanged aside from expected typography improvements.
- Add regression coverage:
@import works at top of user CSS.
- Cascade order is stable.
- Configured font family becomes available in computed styles when source is valid.
- Document preview font behavior and configuration.
Risks
- Cascade regressions if style element order changes.
- Slight startup/render cost when workspace font config includes large font payloads.
- Provider/CORS/network variability for remote font assets.
Mitigations
- Lock style ordering in implementation + tests.
- Keep font config opt-in and optionally cap number of configured families.
- Add clear diagnostics for failed font loads and fallback behavior.
Notes
@font-face currently works as a temporary workaround, but this issue targets a robust and DRY long-term path for preview typography parity.
Summary
Preview currently has a standards/cascade issue for top-level user at-rules (notably
@import) and lacks a first-class way to mirror app-global font families without adding temporary font-loading CSS in every PR.This proposal combines:
Problem
@importrules can be ignored when runtime base CSS is prepended in the same stylesheet.@font-face/@importglue that would not exist in real app code.Goals
Non-goals
Preferred implementation order
Rationale:
Proposed implementation
Phase 1 (B)
knighted-preview-base-stylesknighted-preview-user-stylesPhase 2 (A)
Acceptance criteria
@importis no longer ignored in preview.font-familyusage without per-PR font glue CSS.@importworks at top of user CSS.Risks
Mitigations
Notes
@font-facecurrently works as a temporary workaround, but this issue targets a robust and DRY long-term path for preview typography parity.