Maka's frontend styling combines Astryx, @maka/ui product compositions, and renderer surface CSS. Cascade order is an explicit contract rather than an implementation detail.
apps/desktop/src/renderer/styles.cssis an entry file only.- It may contain
@importand other top-level orchestration statements. - New per-surface selector blocks belong in
apps/desktop/src/renderer/styles/**/*.css. - Historical recipes at the end of
maka-tokens.cssandreference-shell.cssare transitional exceptions. Do not add new surface rules to them.
- Shared renderer and
@maka/uiselectors use the kebab-case.maka-*dialect. - The established
styles/settings/**surface uses camelCase.settings*selectors. Keep that dialect for settings-local selectors instead of mixing both forms within one surface. - Moving existing settings selectors between concern files does not require a repository-wide rename; any future naming migration should be handled as an explicit compatibility change.
- Pure presentation rules should use
@layer baseor@layer componentswhere practical. - Use
@import "./file.css" layer(components)only when the build chain explicitly supports it. - Do not place
@importinside an@layerblock.
Astryx reset and component layers come first; Maka base tokens and product components come later. Keep layer ownership at the closest existing seam instead of adding a higher-priority compatibility layer.
!importantis allowed by default only for accessibility helpers such as.maka-visually-hidden, and for reduced-motion or e2e-fixture overrides.- Every other use requires an adjacent
Justified:comment. - Prefer fixing the primitive API or semantic class when it can express the behavior directly.
- Shared custom properties belong in
apps/desktop/src/renderer/maka-tokens.css. - Component-local properties are allowed only with a
/* local: ... */comment. - Do not add raw colors, radii, or ungoverned z-index values.
These rules are conventions enforced in review. Static correctness belongs to Biome, Knip, and typecheck; accessibility keeps its focused check. CSS usage and Story prose are not decided by repository-wide regex baselines.
- Renderer CSS behavior is verified where it renders: Storybook, the app, or an e2e assertion on the real surface.
- Remove selectors with the source or surface that owned them instead of maintaining an allowlist of strings that may be generated at runtime.
When changing renderer CSS:
- Move real rule blocks out of
styles.cssinto surface files. - Keep generic component chrome in Astryx and product composition in
@maka/uior the matching renderer surface. - Remove dead selectors.
- Remove remaining
!importantonly after primitive and layer ownership is stable.
- Delete dead CSS before aesthetic refactoring.
- Resolve shared
Button,Textarea, andEmptyStateoverrides at the component API seam instead of accumulating renderer specificity. - Every change to cascade order requires the narrowest relevant regression check on the rendered surface.