first commit

This commit is contained in:
npc0-hue
2026-07-11 14:56:10 +08:00
commit 7e05d0a4e7
660 changed files with 78119 additions and 0 deletions
@@ -0,0 +1,35 @@
# Design
## Overview
Theme accessories are implemented as generated SVG data URLs stored in palette variables. Shared CSS primitives consume the variables so cards, panels, tables, drawers, dialogs, plugin groups, operation history, and active sidebar entries gain theme-specific corner ornaments without page-level decoration.
## Theme Assets
The new variables are:
- `--frame-accessory-top`
- `--frame-accessory-bottom`
- `--frame-accessory-opacity`
- `--frame-accessory-size`
`mecha-black` uses compact SVG motifs for spacecraft, robot/vehicle silhouettes, radar rings, and planet-like targeting circles.
`magical-girl` uses compact SVG motifs for winged hearts, stars, wands, ribbons, and magic-circle rings.
## CSS Application
Shared `::after` layers compose:
- Top accessory.
- Bottom accessory.
- Existing shine/jelly material.
Table wrappers, plugin groups, and operation items get matching `::after` layers so dense operational surfaces still inherit the theme identity. The layers remain pointer-events disabled and non-interactive.
## Constraints
- Keep all ornaments in shared theme CSS/tokens.
- Preserve 8px-or-less frame radii for repeated surfaces.
- Avoid external iconfont dependency unless generated assets become insufficient.
- Keep operational text readable by using transparent SVG backgrounds and controlled opacity.
@@ -0,0 +1,34 @@
# Polish theme frame accessories
## Summary
Add theme-specific ornamental accessories to shared platform web frames so each first-party theme has distinct border personality beyond color swaps.
## Motivation
The current black mecha and magical-girl themes already differ in palette, material, and global effects, but repeated cards and panels still share a similar decorative language. The requested direction calls for each theme border to carry its own accessories:
- Mecha frames should read as robot, ship, planet, radar, and cockpit hardware.
- Magical-girl frames should read as hearts, stars, wands, ribbons, and magic-circle motifs.
These ornaments should remain in the shared theme system rather than page-local decorations.
## Scope
- Add generated SVG accessory assets as CSS theme variables in `platform_web/theme/tokens.ts`.
- Apply accessory variables to shared framed surfaces in `platform_web/theme/base.css`.
- Include active sidebar item ornamentation so navigation states also inherit the theme identity.
- Update token tests to lock the accessory variables.
## Out of Scope
- New third-party icon dependencies or bundled recognizable character art.
- Page-local fixed decorative spans.
- New theme families, route changes, or backend behavior.
## Verification
- Run platform web tests and build.
- Run `scripts/check-structure.sh`.
- Run `openspec validate polish-theme-frame-accessories --strict`.
- Perform a browser walkthrough of the platform web shell in both themes.
@@ -0,0 +1,72 @@
# platform-web-theme-accessories Specification
## ADDED Requirements
### Requirement: Theme frame accessories
Shared platform web framed surfaces SHALL render theme-specific ornamental accessories.
#### Scenario: Black mecha theme is active
- **WHEN** the active palette is `mecha-black`
- **THEN** shared framed surfaces include mecha accessory motifs such as spacecraft, robot hardware, radar, planet, or cockpit details
- **AND** the motifs are provided through shared theme variables rather than page-local decorative DOM
#### Scenario: Magical-girl theme is active
- **WHEN** the active palette is `magical-girl`
- **THEN** shared framed surfaces include magical accessory motifs such as hearts, stars, magic wands, ribbons, or magic circles
- **AND** the motifs are provided through shared theme variables rather than page-local decorative DOM
- **AND** repeated sibling items rotate through distinct motifs instead of repeating one identical accessory
- **AND** each framed item uses one compact edge badge rather than multiple oversized illustrations
### Requirement: Navigation active frame accessories
Active sidebar navigation entries SHALL inherit the active theme's frame accessory language.
#### Scenario: User changes theme while a route is active
- **WHEN** a sidebar route is active
- **AND** the user switches between first-party themes
- **THEN** the active sidebar frame changes accessory motifs to match the selected theme
- **AND** route order and labels remain unchanged
### Requirement: Live theme isolation
Theme switching SHALL replace the complete active palette without retaining visual variables or shell labels from the previous palette.
#### Scenario: User switches from magical-girl to black mecha
- **WHEN** the active palette is `magical-girl`
- **AND** the user selects `mecha-black`
- **THEN** the root theme marker, shared surface materials, sidebar subtitle, and palette strip update to black mecha immediately
- **AND** magical-girl accessory variables from the previous palette do not remain active on mecha surfaces
### Requirement: Single frame ownership
An operational content region SHALL render at most one ornamental frame at each visual hierarchy level.
#### Scenario: State view is nested inside a shared framed surface
- **WHEN** an empty, loading, or error state is rendered inside a `console-panel`, card, table wrapper, plugin group, or operation item
- **THEN** the parent surface retains the active theme frame and accessory
- **AND** the nested state view renders as unframed content without a second border, panel fill, or accessory pseudo-element
### Requirement: Uploaded background frame visibility
Uploaded backgrounds SHALL remain visually legible while preserving the selected theme's frame identity.
#### Scenario: Magical-girl theme uses an uploaded background
- **WHEN** the active palette is `magical-girl`
- **AND** the user has configured an uploaded background
- **THEN** shared foreground surfaces use translucent neutral-pink crystal glass rather than an opaque maroon color mask
- **AND** the uploaded image remains recognizable behind the foreground surfaces
- **AND** compact heart, star, wand, moon, ribbon, crystal, and magic-circle accessories visibly cross the panel border instead of being hidden inside the panel
- **AND** accessory pseudo-elements do not add a color wash over the configured background
#### Scenario: Magical-girl theme uses a built-in background
- **WHEN** the active palette is `magical-girl`
- **AND** no uploaded background is configured
- **THEN** shared framed surfaces retain compact, immediately visible magical accessories that extend beyond their borders without crowding content
@@ -0,0 +1,37 @@
# Tasks
- [x] Add generated mecha and magical-girl SVG accessory variables to theme tokens.
- [x] Apply accessory variables to shared framed surfaces and active sidebar states.
- [x] Extend theme token tests for accessory variables.
- [x] Run tests, structure check, OpenSpec validation, and browser walkthrough.
- [x] Recalibrate uploaded-background glass so configured artwork remains recognizable.
- [x] Enlarge and strengthen magical-girl frame accessories across shared surfaces.
- [x] Repeat browser walkthrough and all repository validation after the correction.
- [x] Reduce magical-girl accessories to compact single-motif edge badges.
- [x] Rotate distinct heart, wand, moon, ribbon, crystal, and circle assets across repeated items.
- [x] Verify uploaded backgrounds remain unobscured after the decoration-density correction.
- [x] Clear stale palette variables and synchronize shell chrome after live theme switches.
- [x] Suppress nested state-view frames when a shared parent already owns the decoration.
- [x] Re-run browser theme switching and repository validation for the isolation fix.
## Evidence
- `npm test`: 11 files passed, 49 tests passed.
- `npm run typecheck`: passed.
- `npm run build`: passed.
- `scripts/check-structure.sh`: passed.
- `openspec validate polish-theme-frame-accessories --strict`: passed.
- Browser walkthrough: entered local fallback workbench, verified mecha active navigation uses generated spacecraft/radar accessories, then switched through Profile Settings to magical-girl / 粉月魔法阵 and verified shared panels render heart/star/wand/magic-circle accessories.
- Follow-up browser walkthrough after visual feedback: reduced magical-girl accessory size to `70px 42px, 78px 54px`, lowered opacity to `0.44`, moved frame accessories under content (`::after z-index: 0`, content z-index above), and confirmed the custom-background overlay token is `transparent`.
- Second follow-up after screenshot feedback: converted the SVG accessories to small line-art edge accents, locked token accessory sizes to max `48px`, reduced custom-background surface blur to `4px`, removed theme color tint from uploaded-background panel material, lowered custom-background ambient particles to `0.08`, and verified a headless Chrome screenshot at `.tmp/theme-visual-check/profile-custom-background.png` with `data-custom-background="true"`, `--custom-background-overlay: transparent`, and profile panels using `blur(4px) saturate(1.02)`.
- Final color audit after palette feedback: rebalanced uploaded-background mode so the page uses `--custom-background-overlay: transparent`, keeps controls on readable dark glass, and removes large-panel blur in favor of low-opacity ink glass; verified fresh headless screenshots at `.tmp/theme-color-audit/mecha-uploaded.png` and `.tmp/theme-color-audit/magical-uploaded.png` where uploaded artwork remains visible behind the profile/settings panels.
- Custom-background readability pass after latest screenshots: removed the visible theme-color mask from uploaded backgrounds while dimming the wallpaper layer itself, increased content-panel opacity/blur only on foreground surfaces, added dark glass treatment for server toolbars and state/error panels, and added a compact title backplate so bright uploads do not wash out page headers; verified screenshots at `.tmp/custom-background-audit/servers.png` and `.tmp/custom-background-audit/profile-settings.png` with `data-custom-background="true"`, `filter: saturate(0.72) contrast(0.88) brightness(0.82)`, and panel backdrop `blur(16px) saturate(0.78)`.
- Magical-girl correction after latest feedback: restored visible pink moonlight panel material and frame accessories under custom uploaded backgrounds, prevented the generic custom-background opacity rule from suppressing magical-girl decorations, and moved magical-girl frame accessories outside the panel border with larger edge-overhanging assets; verified screenshots at `.tmp/magical-custom-background-check.png` and `.tmp/magical-preset-border-check.png`.
- Final uploaded-background correction: replaced opaque maroon surfaces with low-opacity neutral-pink crystal glass, restored the uploaded artwork to `saturate(0.92) contrast(0.96) brightness(0.94)`, removed backdrop blur from large magical-girl custom-background panels, added real `::after` accessory layers for server toolbars and state views, and strengthened generated heart/star/wand/magic-circle SVGs so they cross the border at `132-154px` with `0.80-0.84` opacity. Browser walkthrough at `1440x1000` confirmed the configured anime artwork remains recognizable, accessories are immediately visible outside the frame, and the browser console has no errors; evidence saved at `.tmp/magical-custom-background-final.png`.
- Final verification: `npm --prefix platform_web test` passed 11 files and 49 tests; `npm --prefix platform_web run typecheck`, `npm --prefix platform_web run build`, and `scripts/check-structure.sh` passed; `openspec validate polish-theme-frame-accessories --strict` reported the change valid with exit code `0` (telemetry flush warnings only).
- Decoration-density correction after item-level feedback: replaced the two oversized magical illustrations on each surface with one `68px × 44px` edge-overhanging badge, generated six distinct inline SVG motifs (heart wings, star wand, crescent moon, ribbon, crystal, and magic circle), and rotate them through repeated cards with shared CSS variables and `:nth-child()` rules. In-app browser verification on `#/profile` with `data-theme-palette="magical-girl"` and `data-custom-background="true"` confirmed the three metric items resolve to `heart`, `wand`, and `moon`, lower settings panels resolve to different motifs, the configured background remains fully recognizable, and browser console errors are empty.
- Decoration-density verification: `npm --prefix platform_web test` passed 11 files and 49 tests; `npm --prefix platform_web run typecheck`, `npm --prefix platform_web run build`, `scripts/check-structure.sh`, and `openspec validate polish-theme-frame-accessories --strict` passed (OpenSpec telemetry flush warnings only).
- Theme-isolation correction: `applyThemePalette` now removes the union of prior palette variables before applying the selected palette and publishes a live palette-change event so AppShell updates its subtitle and swatch strip without a remount.
- Single-frame correction: nested `.state-view` elements inside shared framed surfaces now resolve to transparent, borderless, shadowless content with both pseudo-elements disabled, while the parent surface keeps the active theme accessory.
- Browser walkthrough with an uploaded custom background: switched `magical-girl` to `mecha-black` and confirmed `data-theme-palette="mecha-black"`, sidebar subtitle `黑色机甲 / OPS`, cyan `--accent: #48e6ff`, and no remaining inline `--frame-accessory-heart`; switched back to magical-girl and confirmed only parent panel accessories render; restored mecha as the final state. Two nested home-page state views resolved to `border: 0px`, transparent backgrounds, and `::after content: none`; browser warnings/errors were empty.
- Isolation verification: `npm --prefix platform_web test` passed 12 files and 51 tests; `npm --prefix platform_web run typecheck`, `npm --prefix platform_web run build`, and `scripts/check-structure.sh` passed; strict OpenSpec validation reported the change valid (telemetry flush warnings only).