Files
opencloud/.agents/skills/opencloud-style/SKILL.md
2026-07-28 21:31:38 +08:00

236 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: opencloud-style
description: "Maintain OpenCloud's current visual system when changing Vue templates, Tailwind classes, CSS, Naive UI theming, layout, typography, colors, buttons, cards, modals, maps, or responsive behavior. Preserve the clean sky-atlas language: airy sky-blue surfaces, fresh eucalyptus green, square atlas-like panels, pixel-cloud identity, and hard offset shadows."
---
# OpenCloud Visual Style
Treat the current design tokens and shared `oc-*` classes as the visual contract. Keep the interface airy, bright, observational, and slightly editorial—like a field atlas for clouds.
## Start From the Sources of Truth
Inspect these files before making a material visual change:
1. `src/styles/tokens.css` — palette remapping, semantic colors, gradients, shadows, motion.
2. `src/styles/base.css` — body baseline and the global square-corner rule.
3. `src/styles/components.css` — reusable page, surface, form, and interaction contracts.
4. `src/lib/theme.ts` — Naive UI overrides; keep semantic colors aligned with `tokens.css`.
5. `docs/style-system.md` — naming and implementation guidance.
6. `scripts/check-style-system.mjs` — prohibited legacy patterns.
Use `src/style.css` only as the stylesheet assembly point. Put stable values in `tokens.css`, cross-page patterns in `components.css`, and truly component-specific behavior in scoped styles.
## Visual Direction
- Use white, slate-50, sky-50, and soft translucent white for primary surfaces.
- Use sky blue for atmosphere, page heroes, upload/create actions, and the pixel-cloud brand surface.
- Use fresh eucalyptus green for identity, navigation selection, account access, confirmation, and interactive hover states.
- Use leaf green only for explicit success, approved, public, or completed states.
- Use amber for pending/review/uncommon states and rose/red for destructive/rejected states.
- Keep slate-900 text dominant. Do not turn normal page sections into dark panels.
- Avoid purple, indigo, generic gray utilities, neon green, and decorative color proliferation.
## Current Palette
Tailwind `teal-*` and `emerald-*` are compatibility names remapped in `tokens.css`; they are not Tailwind defaults.
| Role | Main | Dark | Light surface |
| --- | --- | --- | --- |
| Eucalyptus brand/interaction | `#34745d` | `#274c40` | `#f2faf6` |
| Leaf success | `#4d7f3b` | `#35522c` | `#f4faef` |
| Sky information/action | `#0369a1` | `#075985` | `#e0f2fe` |
| Canvas | `#eef4f8` | — | `#f8fbfd` |
| Primary text | `#0f172a` | — | — |
| Secondary text | `#334155` | — | — |
| Muted text | `#64748b` | — | — |
| Border | `#d9e3ee` | — | — |
Rules:
- Do not use Tailwind `green-*` or `lime-*`.
- Do not reintroduce Tailwind's vivid teal values such as `#14b8a6` or `#0f766e`.
- Use semantic tokens or existing `teal-*`/`emerald-*` compatibility utilities instead of new hard-coded greens.
- Keep green text and actions dark enough for readable contrast; use pale green primarily as a surface.
- Synchronize changes to brand or success colors between `tokens.css` and `src/lib/theme.ts`.
## Shape and Border Rules
The product is square by default. `src/styles/base.css` forces Tailwind `rounded*` utilities to `0px`.
- Use square corners for page panels, cards, buttons, inputs, navigation, dropdowns, map controls, and ordinary modals.
- Use a one-pixel slate or semantic-color border to define surfaces.
- Do not add rounded rectangles as a generic polish treatment.
Documented exceptions:
- Circular close/overlay controls in `ImageDetailModal`.
- Circular location/marker dots and AMap-generated marker bubbles.
- The media-focused `ImageDetailModal` shell.
- AMap-generated information cards and the deliberately organic timeline control details in `MapView`.
Do not treat map floating buttons as exceptions: `.oc-map-button` is a square `40px × 40px` control with `0px` radius and a hard shadow, including its disabled state.
## Shadows and Interaction
Use hard offset shadows with zero blur as the signature depth treatment:
| Token | Value | Typical use |
| --- | --- | --- |
| `--oc-shadow-xs` | `3px 3px` | Small controls and map buttons |
| `--oc-shadow-sm` | `4px 4px` | Header logo and compact CTAs |
| `--oc-shadow-md` | `6px 6px` | Standard cards and navigation |
| `--oc-shadow-lg` | `8px 8px` | Menus and floating panels |
| `--oc-shadow-xl` | `12px 12px` | Large system/auth cards |
| `--oc-shadow-sky` | sky-tinted `4px 4px` | Sky actions |
| `--oc-shadow-primary` | eucalyptus-tinted `4px 4px` | Green interactions |
- On hover, interactive controls may move `translate(-1px, -1px)` and grow the hard shadow.
- On active, return the control to its origin.
- Preserve a visible `2px` sky focus outline with offset.
- Do not replace the hard-shadow language with generic soft shadows across ordinary UI.
- Soft/blurred shadows remain acceptable for media overlays, AMap internals, and image hover depth.
## Backgrounds and Brand Identity
Use the semantic gradients in `tokens.css`:
- App shell: a subtle eucalyptus radial glow over the pale blue-gray canvas.
- Standard page hero: `#e0f2fe` to `#f8fafc`.
- Soft page hero: `#f2faf6` to `#f8fafc`.
- App grid: subtle slate lines at `32px`.
The header identity is fixed:
- Use the pixel-style cloud/sun SVG, not an emoji or unrelated icon set.
- Put the icon in a square `40px` container with `bg-sky-100`, `border-sky-200`, and a `4px 4px` neutral hard shadow.
- Keep “LIVE SKY ATLAS” as the small tracked eyebrow and “OpenCloud” as the bold brand name.
- Keep the header white/translucent; green belongs to navigation and account interaction, not the logo background.
## Typography
Use:
```text
"IBM Plex Sans", "Noto Sans SC", "PingFang SC", sans-serif
```
Use IBM Plex Mono for small atlas-like labels when a monospace accent is appropriate.
- Page eyebrow: `text-sm`, uppercase, `tracking-[0.24em]`, sky-700.
- Page title: `text-4xl`, bold, slate-900.
- Descriptions: `text-sm`, `leading-7`, slate-600.
- Section/stat labels: `text-xs`, uppercase, tracking `0.18em–0.20em`, slate-500.
- Header brand eyebrow: `text-[11px]`, uppercase, `tracking-[0.22em]`.
- Reserve `font-black` and very large display text for authentication hero statements.
## Layout and Responsive Behavior
Prefer the shared page structure:
```html
<section class="oc-page-hero">
<div class="oc-container oc-container--content oc-page-hero__inner">
<p class="oc-page-eyebrow">Cloud Upload</p>
<h1 class="oc-page-title">上传云图</h1>
<p class="oc-page-description">页面描述</p>
</div>
</section>
<main class="oc-container oc-container--content oc-page-content">
<!-- content -->
</main>
```
Container widths:
- `oc-container--narrow` — `max-w-4xl`
- `oc-container--content` — `max-w-6xl`
- `oc-container--wide` — `max-w-7xl`
Use `px-4 sm:px-6 lg:px-8` for page gutters. Validate at both desktop and a real `375px` mobile viewport. Do not accept horizontal overflow.
## Reusable Component Contracts
Use existing semantic classes before writing repeated Tailwind bundles:
- Page structure: `oc-page-hero`, `oc-page-hero--soft`, `oc-container`, `oc-page-content`.
- Typography: `oc-page-eyebrow`, `oc-page-title`, `oc-page-description`, `oc-section-label`, `oc-stat-label`, `oc-stat-value`, `oc-meta`.
- Forms: `oc-field-label`, `oc-field-required`, `oc-field-control`, `oc-field-help`, `oc-field-error`.
- Surfaces: `oc-surface`, `oc-inset-panel`, `oc-panel-card`, `oc-panel-card-soft`, `oc-empty-card`.
- Interaction: `oc-primary-button`, `oc-panel-button`, `oc-header-button`, `oc-icon-button`, `oc-map-button`, `oc-choice-button`, `oc-text-button`, `oc-menu-item`, `oc-nav-link`.
Class names describe function. Keep modifiers attached to their base class, for example:
```html
<NButton type="default" class="oc-panel-button oc-panel-button--sky">
保存
</NButton>
```
Available shared variants:
- Primary: `oc-primary-button--teal`, `oc-primary-button--sky`
- Panel: `--neutral`, `--sky`, `--teal`, `--amber`, `--danger`
- Header: `--neutral`, `--sky`, `--teal`
- Icon: `--small`, `--tiny`, `--sky`, `--danger`
- Text/menu: muted, amber, and danger variants where defined
## Button Semantics
- Teal/eucalyptus: login, account access, active toggle, confirm.
- Sky: register, create, upload, forward action.
- Neutral: cancel and utility actions.
- Amber: pending/review/state-toggle actions.
- Danger: deletion and destructive actions.
For Naive UI buttons:
- Use `type="default"` with the shared `oc-*` class when a custom visual variant is intended.
- Do not rely on Naive UI default primary/secondary styling for page CTAs or panel actions.
- Keep `src/lib/theme.ts` as the global Naive UI contract; it is mounted by `App.vue`.
- Use dark text on light primary surfaces. Do not assume primary buttons should have white text.
## Icons, Cards, and Modals
- Use `@vicons/tabler` through `NIcon` for interface icons.
- Preserve the pixel-cloud SVG for the primary brand mark.
- Use one bordered surface and one appropriate hard-shadow token for ordinary cards.
- Keep modal structure square unless it is a documented media exception.
- Use `oc-overlay-button` for controls over dark media and `oc-icon-button` for controls on light surfaces.
- Keep semantic status colors stable: emerald success, amber pending, rose rejected/destructive, slate hidden/neutral.
## Implementation Workflow
1. Inspect the source-of-truth files and the target component.
2. Reuse an existing semantic class if it expresses the intent.
3. Use Tailwind only for one-off layout and responsive composition.
4. Add a token before repeating a stable raw value.
5. Add a shared `oc-*` class only for cross-page patterns or product-wide rules.
6. Keep feature-specific AMap, slider, media, or transition details scoped to the component.
7. When changing a global color, audit all matching Tailwind utilities, hard-coded hex/RGB values, gradients, shadows, canvas drawing, and Naive UI tokens.
8. Preserve unrelated user changes in the worktree.
## Anti-Patterns
- Default Tailwind `green-*`, `lime-*`, vivid teal, purple, indigo, or generic `gray-*`.
- Ad hoc rounded cards, pills, or map buttons.
- Soft drop shadows replacing hard atlas shadows across normal UI.
- New button styling copied into templates instead of shared `oc-*` variants.
- `NButton type="primary"` used as a shortcut around the shared button contract.
- White text on pale green or sky action surfaces.
- Emoji used as the site identity.
- Flat page backgrounds where the shared hero/canvas gradient applies.
- Green used indiscriminately for both brand interaction and success state.
## Validation
After style changes, run:
```bash
npm run check:styles
git diff --check
npm run build
```
For material visual changes, render representative pages and inspect desktop and `375px` mobile screenshots. Check computed styles when shape, shadow, color token, or responsive overflow is part of the request.