# Theme Package Specification This repository accepts two formats. DreamSkin is the authoring and import format for new themes. Legacy DSH is retained for existing local themes and is not the format to extend for new features. ## DreamSkin Format (Primary) Required files: - `manifest.json` with `packageVersion: 1` and `themeId` - `theme.json` with a flat `colors` object Optional for a directory installed with the CLI: - one declared image in `manifest.files[]` - `theme.css`, validated by the Safe CSS policy - `LICENSE.txt` A DreamSkin ZIP is a distribution artifact and must contain both one declared background image and a non-empty `theme.css`. This stricter import boundary prevents incomplete authoring directories from being accepted as releases. Example: ```json // manifest.json { "themeId": "nord-dark", "name": "Nord Dark", "version": "1.0.0", "packageVersion": 1, "files": [ { "path": "background.jpg", "mediaType": "image/jpeg" } ] } ``` ```json // theme.json { "appearance": "dark", "colors": { "background": "#1e1e2e", "panel": "#313244", "panelAlt": "#45475a", "accent": "#cba6f7", "accentAlt": "#b4befe", "text": "#cdd6f4", "muted": "#a6adc8", "line": "#45475a", "highlight": "#585b70" }, "art": { "focusX": 0.5, "focusY": 0.4, "taskMode": "fill" }, "backgroundOpacity": 1, "backgroundBlur": 0 } ``` `src/lib/theme-manager.mjs` normalizes `manifest.themeId` to `manifest.id`. `src/lib/safe-css.mjs` maps the flat colors to DSH-compatible tokens and renders the optional background layer. Generated backgrounds use a non-interactive `body::before` layer inside an isolated body stacking context; the renderer must not assign a z-index to `#root`, because that would break Harness-owned modal portals. ## Legacy DSH Format (Compatibility) Required files: - `manifest.json` with `schema: 1`, `id`, `name`, and `version` - `theme.json` with `colors.light` and/or `colors.dark` Legacy colors are CSS custom properties, for example: ```json { "colors": { "dark": { "--dsw-alias-bg-base": "#1e1e2e", "--dsw-alias-brand-primary": "#cba6f7" } } } ``` Do not add new DreamSkin fields to the legacy schema. Add new authoring capabilities to DreamSkin and keep normalization in the theme manager. ## Safe CSS Contract Custom `theme.css` is rejected unless it uses approved custom-property prefixes or approved presentation properties. DreamSkin presentation longhands are supported for each border side (`color`, `width`, `style`) plus `transition-property` and `transition-duration`. The official bounded typography and spacing subset is also supported: `font-size` 12–20px, `font-weight` 400–700, `line-height` 1.1–1.8, `letter-spacing` 0–2px, `gap`/`row-gap`/`column-gap` 0–24px, and directional radii 0–28px. Other layout and animation properties remain outside the contract. For illustrated themes, the compatibility adapter keeps the author's semantic background token, makes only DSH's base canvas transparent, and uses its original glass defaults (`panel` 0.72, `panelAlt` 0.65). Custom CSS is appended last. Source contrast is audited and reported, but the runtime does not rewrite text, accents, surface brightness, or `appearance: auto` to satisfy a global target. It must not contain: - `javascript:`, `expression()`, `data:` or `file:` URLs - `@import`, `