diff --git a/CLAUDE.md b/CLAUDE.md
index adf19a6..9180a87 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -123,118 +123,9 @@ This is a monorepo containing:
For detailed server-specific instructions (restart policy, testing, etc.), see:
- `server/CLAUDE.md`
-## UI Conventions for Dialogs
+## Frontend (HTML, CSS, JS, i18n)
-### Hints
-
-Every form field in a modal should have a hint. Use the `.label-row` wrapper with a `?` toggle button:
-
-```html
-
-```
-
-Add hint text to both `en.json` and `ru.json` locale files using a `.hint` suffix on the label key.
-
-### Select dropdowns
-
-Do **not** add placeholder options like `-- Select something --`. Populate the `` with real options only and let the first one be selected by default.
-
-### Enhanced selectors (IconSelect & EntitySelect)
-
-Plain `` dropdowns should be enhanced with visual selectors depending on the data type:
-
-- **Predefined options** (source types, effect types, palettes, waveforms, viz modes) → use `IconSelect` from `js/core/icon-select.js`. This replaces the `` with a visual grid of icon+label+description cells. See `_ensureCSSTypeIconSelect()`, `_ensureEffectTypeIconSelect()`, `_ensureInterpolationIconSelect()` in `color-strips.js` for examples.
-
-- **Entity references** (picture sources, audio sources, devices, templates, clocks) → use `EntitySelect` from `js/core/entity-palette.js`. This replaces the `` with a searchable command-palette-style picker. See `_cssPictureSourceEntitySelect` in `color-strips.js` or `_lineSourceEntitySelect` in `advanced-calibration.js` for examples.
-
-Both widgets hide the native `` but keep it in the DOM with its value in sync. After programmatically changing the `` value, call `.refresh()` (EntitySelect) or `.setValue(val)` (IconSelect) to update the trigger display. Call `.destroy()` when the modal closes.
-
-### Modal dirty check (discard unsaved changes)
-
-Every editor modal **must** have a dirty check so closing with unsaved changes shows a "Discard unsaved changes?" confirmation. Use the `Modal` base class pattern from `js/core/modal.js`:
-
-1. **Subclass Modal** with `snapshotValues()` returning an object of all tracked field values:
-
- ```javascript
- class MyEditorModal extends Modal {
- constructor() { super('my-modal-id'); }
- snapshotValues() {
- return {
- name: document.getElementById('my-name').value,
- // ... all form fields
- };
- }
- onForceClose() {
- // Optional: cleanup (reset flags, clear state, etc.)
- }
- }
- const myModal = new MyEditorModal();
- ```
-
-2. **Call `modal.snapshot()`** after the form is fully populated (after `modal.open()`).
-3. **Close/cancel button** calls `await modal.close()` — triggers dirty check + confirmation.
-4. **Save function** calls `modal.forceClose()` after successful save — skips dirty check.
-5. For complex/dynamic state (filter lists, schedule rows, conditions), serialize to JSON string in `snapshotValues()`.
-
-The base class handles: `isDirty()` comparison, confirmation dialog, backdrop click, ESC key, focus trapping, and body scroll lock.
-
-### Card appearance
-
-When creating or modifying entity cards (devices, targets, CSS sources, streams, audio/value sources, templates), **always reference existing cards** of the same or similar type for visual consistency. Cards should have:
-
-- Clone (📋) and Edit (✏️) icon buttons in `.template-card-actions`
-- Delete (✕) button as `.card-remove-btn`
-- Property badges in `.stream-card-props` with emoji icons
-- **Crosslinks**: When a card references another entity (audio source, picture source, capture template, PP template, etc.), make the property badge a clickable link using the `stream-card-link` CSS class and an `onclick` handler calling `navigateToCard(tab, subTab, sectionKey, cardAttr, cardValue)`. Only add the link when the referenced entity is found (to avoid broken navigation). Example: `🎵 Name `
-
-### Modal footer buttons
-
-Use **icon-only** buttons (✓ / ✕) matching the device settings modal pattern, **not** text buttons:
-
-```html
-
-```
-
-### Slider value display
-
-For range sliders, display the current value **inside the label** (not in a separate wrapper). This keeps the value visible next to the property name:
-
-```html
-Speed: 1.0
-...
-
-```
-
-Do **not** use a `range-with-value` wrapper div.
-
-### Tutorials
-
-The app has an interactive tutorial system (`static/js/features/tutorials.js`) with a generic engine, spotlight overlay, tooltip positioning, and keyboard navigation. Tutorials exist for:
-- **Getting started** (header-level walkthrough of all tabs and controls)
-- **Per-tab tutorials** (Dashboard, Targets, Sources, Profiles) triggered by `?` buttons
-- **Device card tutorial** and **Calibration tutorial** (context-specific)
-
-When adding **new tabs, sections, or major UI elements**, update the corresponding tutorial step array in `tutorials.js` and add `tour.*` i18n keys to all 3 locale files (`en.json`, `ru.json`, `zh.json`).
-
-## Localization (i18n)
-
-**Every user-facing string must be localized.** Never use hardcoded English strings in `showToast()`, `error.textContent`, modal messages, or any other UI-visible text. Always use `t('key')` from `../core/i18n.js` and add the corresponding key to **all three** locale files (`en.json`, `ru.json`, `zh.json`).
-
-- In JS modules: `import { t } from '../core/i18n.js';` then `showToast(t('my.key'), 'error')`
-- In inline `