{"total":1,"changes":3,"files":[{"path":"openspec/specs/style-topics/spec.md","content":"# style-topics Specification\n\n## Purpose\n\nLet a user change how every d2 page looks by asking their AI (the colours, the fonts and the logo text) with nothing to install and no code to change. This is [[AiSpec:style-topics]] in OpenSpec's requirement-and-scenario format.\n\n## Requirements\n\n### Requirement: Stylesheets as topics\nThe system SHALL accept a stylesheet written as a topic in category `Style`, through the ordinary topics API.\n\n#### Scenario: AI makes a stylesheet\n- **WHEN** the user's AI saves `Style:yahoo` with valid tokens and `brand: YAHOO`\n- **THEN** the save reply has `style: {ok: true}`\n- **AND** the stylesheet is listed under Style topics on the Styles page\n\n### Requirement: Logo text\nThe system SHALL show a Style topic's `brand` as the logo text on every page while that stylesheet is in use.\n\n#### Scenario: Picking a branded stylesheet\n- **WHEN** the user picks `Style:yahoo` on the Styles page\n- **THEN** every page shows YAHOO next to the logo\n\n### Requirement: Broken stylesheets are harmless\nThe system MUST NOT apply a Style topic that has errors; it SHALL list it with its errors instead.\n\n#### Scenario: Unknown token\n- **WHEN** a Style topic sets a token that doesn't exist\n- **THEN** the save reply lists the error\n- **AND** the Styles page shows the topic as \"Has errors\" with no button to use it\n\n#### Scenario: A broken stylesheet in the cookie\n- **WHEN** the browser's cookie names a Style topic that has errors\n- **THEN** pages use the default stylesheet\n","topic":"OpenSpec:style-topics","check":{"ok":true,"errors":[],"warnings":[]}},{"path":"openspec/changes/add-contrast-check/proposal.md","content":"## Why\n\nAn AI asked for \"magenta text on dark green\" will do exactly that, readable or not. The save reply should say when text and background are too close, so the AI can adjust before the user squints.\n\n## What Changes\n\n- Saving a Style topic checks the contrast of `--ink` and `--soft` against `--paper` and `--card`, in light and dark mode.\n- Below 4.5:1 (the usual guideline for body text) is a warning, not an error: the stylesheet can still be picked.\n- The Styles page shows the warnings under the stylesheet.\n\n## Impact\n\n- Affected specs: [[OpenSpec:style-topics]].\n- Affected code: `src/styles.ts`, `src/stylespage.ts`.\n","topic":"OpenSpecChange:add-contrast-check"},{"path":"openspec/changes/add-contrast-check/tasks.md","content":"## 1. Build\n\n- [x] 1.1 Compute contrast ratios from hex colours\n- [x] 1.2 Add `warnings` to the save reply's `style` field\n- [ ] 1.3 Show warnings on the Styles page\n- [ ] 1.4 Tell the AI about it in Skill:diesel2\n","topic":"OpenSpecChange:add-contrast-check"},{"path":"openspec/changes/add-contrast-check/design.md","content":"- Only hex colours are checked; a named colour or `rgb(…)` is skipped rather than guessed.\n- Warnings never block: taste is the user's call.\n","topic":"OpenSpecChange:add-contrast-check"},{"path":"openspec/changes/add-contrast-check/specs/style-topics/spec.md","content":"## ADDED Requirements\n\n### Requirement: Readable text\nThe system SHALL warn, without refusing the stylesheet, when a Style topic's text colours have a contrast ratio below 4.5:1 against its backgrounds.\n\n#### Scenario: Low contrast\n- **WHEN** a Style topic sets `--ink: #2a5c3a` on `--paper: #0b3d1e`\n- **THEN** the save reply's `style.warnings` names `--ink` on `--paper` and the ratio\n- **AND** the stylesheet can still be picked\n\n#### Scenario: Good contrast\n- **WHEN** a Style topic sets `--ink: #ffffff` on `--paper: #0b3d1e`\n- **THEN** there is no contrast warning\n","topic":"OpenSpecChange:add-contrast-check"},{"path":"openspec/changes/archive/2026-09-24-add-style-topics/proposal.md","content":"## Why\n\nThe two built-in stylesheets were the only looks d2 had, and changing one meant changing code. A user should be able to ask their AI for a new look (colours, fonts, the logo text) and get it without an install or a deploy.\n\n## What Changes\n\n- New topic category `Style`: a stylesheet written as a topic, through the ordinary topics API.\n- `brand` in its frontmatter replaces the logo text on every page.\n- The save reply checks it (`style: {ok, errors}`); a broken one is listed with its errors and can't be picked.\n- Help gets \"Make your own stylesheet\"; the diesel2 skill gets \"Make a stylesheet\".\n\n## Impact\n\n- Affected specs: [[OpenSpec:style-topics]] (new).\n- Affected code: `src/styles.ts`, `src/stylespage.ts`, the top bar, the topics API.\n","topic":"OpenSpecChange:add-style-topics"},{"path":"openspec/changes/archive/2026-09-24-add-style-topics/tasks.md","content":"## 1. Build\n\n- [x] 1.1 Parse and check Style topics\n- [x] 1.2 List them on the Styles page, broken ones with their errors\n- [x] 1.3 Apply `brand` in the top bar and on the landing page\n- [x] 1.4 Report `style: {ok, errors}` on save\n\n## 2. Document\n\n- [x] 2.1 Help: Make your own stylesheet\n- [x] 2.2 Skill:diesel2: Make a stylesheet\n- [x] 2.3 Try it end to end: `Style:yahoo`\n","topic":"OpenSpecChange:add-style-topics"},{"path":"openspec/changes/archive/2026-09-24-add-style-topics/design.md","content":"- A broken Style topic is stored anyway and never applied, so a mistake can't break a page.\n- The choice stays in the `d2style` cookie, now holding the topic id (`Style:yahoo`), until real login brings user preferences.\n","topic":"OpenSpecChange:add-style-topics"},{"path":"openspec/changes/archive/2026-09-24-add-style-topics/specs/style-topics/spec.md","content":"## ADDED Requirements\n\n### Requirement: Stylesheets as topics\nThe system SHALL accept a stylesheet written as a topic in category `Style`, through the ordinary topics API.\n\n#### Scenario: AI makes a stylesheet\n- **WHEN** the user's AI saves `Style:yahoo` with valid tokens and `brand: YAHOO`\n- **THEN** the save reply has `style: {ok: true}`\n- **AND** the stylesheet is listed under Style topics on the Styles page\n\n### Requirement: Logo text\nThe system SHALL show a Style topic's `brand` as the logo text on every page while that stylesheet is in use.\n\n#### Scenario: Picking a branded stylesheet\n- **WHEN** the user picks `Style:yahoo` on the Styles page\n- **THEN** every page shows YAHOO next to the logo\n\n### Requirement: Broken stylesheets are harmless\nThe system MUST NOT apply a Style topic that has errors; it SHALL list it with its errors instead.\n\n#### Scenario: Unknown token\n- **WHEN** a Style topic sets a token that doesn't exist\n- **THEN** the save reply lists the error\n- **AND** the Styles page shows the topic as \"Has errors\" with no button to use it\n\n#### Scenario: A broken stylesheet in the cookie\n- **WHEN** the browser's cookie names a Style topic that has errors\n- **THEN** pages use the default stylesheet\n","topic":"OpenSpecChange:add-style-topics"},{"path":"openspec/changes/add-user-default-style/proposal.md","content":"## Why\n\nThe chosen stylesheet lives in a browser cookie, so a user who picks `Style:yahoo` on the iPad still sees the default on the laptop. Once real login exists, the choice belongs with the user.\n\n## What Changes\n\n- The chosen stylesheet is stored as a user preference when the user is logged in.\n- The cookie stays for visitors who aren't logged in.\n- A broken stylesheet in the user's preference falls back to the default, like one in the cookie.\n\n## Impact\n\n- Affected specs: [[OpenSpec:style-topics]].\n- Depends on real login (not built yet).\n","topic":"OpenSpecChange:add-user-default-style"},{"path":"openspec/changes/add-user-default-style/tasks.md","content":"## 1. Build\n\n- [ ] 1.1 Store the choice as a user preference on \"Use this stylesheet\"\n- [ ] 1.2 Read the preference before the cookie\n- [ ] 1.3 Move an existing cookie choice into the preference on first login\n\n## 2. Test\n\n- [ ] 2.1 Pick on one device, see it on another\n- [ ] 2.2 A broken preferred stylesheet falls back to the default\n","topic":"OpenSpecChange:add-user-default-style"},{"path":"openspec/changes/add-user-default-style/specs/style-topics/spec.md","content":"## ADDED Requirements\n\n### Requirement: Stylesheet follows the user\nThe system SHALL keep a logged-in user's chosen stylesheet with their account and apply it on every device they use.\n\n#### Scenario: Two devices\n- **WHEN** a logged-in user picks `Style:yahoo` on one device\n- **AND** opens d2 on another device, logged in as the same user\n- **THEN** pages there use `Style:yahoo`\n\n## MODIFIED Requirements\n\n### Requirement: Broken stylesheets are harmless\nThe system MUST NOT apply a Style topic that has errors; it SHALL list it with its errors instead, and pages SHALL fall back to the default stylesheet.\n\n#### Scenario: Unknown token\n- **WHEN** a Style topic sets a token that doesn't exist\n- **THEN** the save reply lists the error\n- **AND** the Styles page shows the topic as \"Has errors\" with no button to use it\n\n#### Scenario: A broken stylesheet in the cookie\n- **WHEN** the browser's cookie names a Style topic that has errors\n- **THEN** pages use the default stylesheet\n\n#### Scenario: A broken stylesheet as the user's preference\n- **WHEN** the stylesheet a user chose later gets an error\n- **THEN** pages use the default stylesheet\n- **AND** the user's choice is kept, so fixing the topic brings it back\n","topic":"OpenSpecChange:add-user-default-style"}]}