` or Vue mounting points
+
+#### Scenario: XSS prevention via output escaping
+- GIVEN dynamic values are rendered in the template
+- WHEN token set data is output in HTML attributes
+- THEN `p(json_encode(...))` MUST be used for the `data-token-sets` attribute (the `p()` helper HTML-escapes the JSON output)
+- AND `p()` helper MUST be used for individual value output (escapes HTML)
+- AND localized strings MUST use `p($l->t(...))` for safe output
+
+#### Scenario: No build step required
+- GIVEN a developer modifies the admin template or JavaScript
+- WHEN they want to test the changes
+- THEN the changes MUST take effect immediately without running any build command
+- AND no `node_modules/`, `package.json`, or webpack config MUST be required for the admin UI
+
+### REQ-ASET-009: Admin-Only Access Control
+All settings endpoints and the settings panel MUST be restricted to administrators.
+
+#### Scenario: Settings panel restricted to admin
+- GIVEN a non-admin user navigates to the admin settings area
+- WHEN Nextcloud checks the `ISettings` implementation
+- THEN the NL Design settings panel MUST NOT be visible to non-admin users
+
+#### Scenario: API endpoints restricted to admin via annotation
+- GIVEN the `@AuthorizedAdminSetting(settings=OCA\NLDesign\Settings\Admin)` annotation on all controller methods
+- WHEN a non-admin user calls any `/settings/*` endpoint
+- THEN the request MUST be rejected with an appropriate error response
+- AND no configuration changes MUST be persisted
+
+#### Scenario: Admin with valid session can access all endpoints
+- GIVEN an admin user is authenticated with a valid session
+- WHEN any `/settings/*` endpoint is called
+- THEN the request MUST be processed normally
+- AND the response MUST include the expected data
+
+### REQ-ASET-010: Token Editor Panel Integration
+The settings panel MUST include a mount point for the token editor that allows customizing individual Nextcloud CSS tokens.
+
+#### Scenario: Token editor mount point rendered
+- GIVEN the settings panel is loaded
+- WHEN the template renders
+- THEN a `
` element MUST be present
+- AND it MUST have a loading indicator text "Loading token editor..." (localized)
+- AND the JavaScript MUST populate this element with the token editor UI on page load
+
+#### Scenario: Token editor loads override data from API
+- GIVEN the settings panel loads and JavaScript initializes
+- WHEN the token editor mounts
+- THEN it MUST call `GET /apps/nldesign/settings/overrides` to fetch the registry, tabs, and current overrides
+- AND it MUST render a tabbed interface for browsing tokens by category
+
+#### Scenario: Token editor saves changes via API
+- GIVEN the admin modifies a token value in the editor
+- WHEN the save action is triggered
+- THEN it MUST call `POST /apps/nldesign/settings/overrides` with the updated overrides map
+- AND the response MUST confirm success before applying changes
+
+### REQ-ASET-011: Settings Hint Text
+The settings panel MUST include instructional text explaining the purpose of the controls.
+
+#### Scenario: Settings hint rendered
+- GIVEN the settings panel is loaded
+- WHEN the hint section renders
+- THEN a `
` element MUST display the text "Select a Dutch government design token set as a base, or customize individual Nextcloud CSS tokens below." (localized)
+- AND the hint MUST appear between the header and the token set selector
+
+#### Scenario: Hint text is localized
+- GIVEN the admin has their Nextcloud language set to Dutch
+- WHEN the settings panel loads
+- THEN the hint text MUST be displayed in Dutch via the `$l->t()` localization function
+
+#### Scenario: Hint text provides sufficient context
+- GIVEN a first-time admin user opens the settings panel
+- WHEN they read the hint text
+- THEN they MUST understand that they can either select a preset token set OR customize individual tokens
+- AND the two-action guidance prevents confusion about the panel's dual purpose
+
+### REQ-ASET-012: Data Attributes for JavaScript Initialization
+The settings panel MUST pass configuration data to JavaScript via HTML data attributes.
+
+#### Scenario: Token sets data attribute
+- GIVEN the settings panel renders
+- WHEN the `#nldesign-settings` div is output
+- THEN it MUST have a `data-token-sets` attribute containing JSON-encoded array of all token sets
+- AND the JSON MUST be HTML-escaped via `p(json_encode(...))` to prevent XSS
+
+#### Scenario: Current token set data attribute
+- GIVEN the active token set is "amsterdam"
+- WHEN the `#nldesign-settings` div is output
+- THEN it MUST have a `data-current-token-set` attribute with value "amsterdam"
+- AND the value MUST be HTML-escaped via `p()`
+
+#### Scenario: JavaScript reads data attributes on initialization
+- GIVEN the admin.js script loads
+- WHEN it initializes the settings panel
+- THEN it MUST read token set data from `data-token-sets` and parse it as JSON
+- AND it MUST read the current token set from `data-current-token-set`
+- AND these values MUST drive the initial state of the dropdown and preview
+
+### REQ-ASET-013: Localization Support
+All user-visible text in the settings panel MUST be localizable via Nextcloud's l10n system.
+
+#### Scenario: All static text uses l10n
+- GIVEN the settings template renders
+- WHEN user-visible text is output
+- THEN every string MUST use `$l->t()` or `p($l->t())` for localization
+- AND this includes: section title, button labels, checkbox labels, hint text, link text, and loading text
+
+#### Scenario: Dutch translation available
+- GIVEN the admin has Nextcloud set to Dutch language
+- WHEN the settings panel loads
+- THEN all localizable strings MUST display in Dutch if translations are provided
+- AND the app MUST include Dutch (nl) as a supported locale
+
+#### Scenario: English fallback
+- GIVEN the admin has a language set for which no translation exists
+- WHEN the settings panel loads
+- THEN all strings MUST fall back to English (the source strings)
+
+### Current Implementation Status
+
+**Fully implemented:**
+- Settings panel registration in the `theming` section with priority 50 (`lib/Settings/Admin.php`: `getSection()` returns `'theming'`, `getPriority()` returns `50`)
+- `Admin::getForm()` returns a `TemplateResponse` for `settings/admin` with all four required parameters: `tokenSets`, `currentTokenSet`, `hideSlogan`, `showMenuLabels` (`lib/Settings/Admin.php` lines 73-106)
+- Token set dropdown populated from `TokenSetService::getAvailableTokenSets()` with `