236 lines
11 KiB
Markdown
236 lines
11 KiB
Markdown
---
|
||
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.
|