--- 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

Cloud Upload

上传云图

页面描述

``` 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 保存 ``` 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.