# UI Theming and CM6 Highlight
## Theme Variables
- **Global tokens** (in `src/styles.css`):
- `--color-accent` main accent color (per-theme override via `[data-theme]`).
- `--cm-hl-bg` computed background for inline highlights (theme dependent).
- `--cm-hl-br` border radius for highlights (default 3px).
- **Button tokens**:
- `--btn-radius`, `--btn-padding-y`, `--btn-padding-x`, `--btn-font`, `--btn-shadow`, `--btn-ring`, `--btn-speed`.
- `--btn-bg`, `--btn-fg`, `--btn-bg-hover`, `--btn-bg-active`, `--btn-outline`.
### Defaults
```css
:root {
--color-accent: #3b82f6;
--cm-hl-bg: color-mix(in srgb, var(--color-accent) 28%, transparent);
--cm-hl-br: 3px;
}
[data-theme="dark"], .dark {
--cm-hl-bg: color-mix(in srgb, var(--color-accent) 22%, transparent);
}
[data-theme="nimbus"] { --color-accent: #7c3aed; }
[data-theme="emerald"] { --color-accent: #10b981; }
```
## CodeMirror 6 Highlight Extensions
Files in `src/app/shared/editor/extensions/`:
- `highlight-occurrences.extension.ts` – inline dynamic occurrences via regex.
- `ranged-highlights.extension.ts` – ranged highlights via `StateEffect`/`StateField`.
- `markdown-theme-highlight.extension.ts` – composes ranged + Markdown `HighlightStyle` and facet-driven CSS variable.
### CSS class
- `.cm-md-highlight { background: var(--cm-hl-bg); border-radius: var(--cm-hl-br, 3px); transition: background var(--btn-speed) ease; }`
## Angular Integration
Service: `EditorHighlightService` (`src/app/shared/editor/editor-highlight.service.ts`)
- `extensions: Extension[]` – base markdown theme highlight extensions to add at editor creation.
- `occurrencesExtension(pattern)` – build occurrences extension.
- `applyOccurrences(view, compartment, pattern)` – reconfigure a `Compartment` with occurrences.
- `setRanges(view, ranges)` / `clearRanges(view)` – ranged highlights via effects.
- `facet()` – access the facet to optionally override `--cm-hl-bg` per-view.
Example inside editor component:
```ts
// compartments
occurrencesCompartment = new Compartment();
highlightFacetCompartment = new Compartment();
// in EditorState.create extensions
...highlightService.extensions,
occurrencesCompartment.of([]),
highlightFacetCompartment.of([]),
// API usage
highlightOccurrences("TODO");
setHighlights([{ from: 10, to: 24 }]);
clearHighlights();
// optional color override
view.dispatch({ effects: highlightFacetCompartment.reconfigure([ highlightService.facet().of('color-mix(in srgb, var(--color-accent) 40%, transparent)') ])});
```
Live theme changes are applied by reconfiguring the theme compartment and calling `EditorView.requestMeasure(...)` to refresh decorations that rely on CSS variables.
## Button Utilities
Classes in `src/styles.css`:
- Base: `btn`
- Variants: `btn-solid`, `btn-outline`, `btn-ghost`
- Sizes: `btn-sm`, `btn-md`, `btn-lg`
Example:
```html
```
## Accessibility
- Buttons use focus ring via `--btn-outline`.
- Ensure icon-only buttons have `aria-label`.
## Performance Notes
- Occurrence highlights compute decorations only over visible ranges; cost is O(visibleText) per viewport update.
- Ranged highlights use a `StateField` and `tr.changes.mapPos` to keep ranges aligned after edits; updates are incremental.
- For large docs (≥5k lines), prefer ranged highlights for bulk operations; occurrences are fine for quick regex patterns like `TODO`.