@turquoisehealth/pit-viper 2.179.1-dev.0 → 2.181.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude-plugin/.claude-plugin/plugin.json +8 -2
- package/claude-plugin/.mcp.json +8 -0
- package/claude-plugin/CLAUDE.md +71 -250
- package/claude-plugin/README.md +123 -69
- package/claude-plugin/skills/pit-viper/SKILL.md +180 -0
- package/claude-plugin/skills/pit-viper/references/design-language.md +80 -0
- package/claude-plugin/skills/pit-viper/references/design-rules.md +254 -0
- package/claude-plugin/skills/pit-viper/references/html-patterns.md +451 -0
- package/claude-plugin/skills/pit-viper/references/layout-patterns.md +359 -0
- package/claude-plugin/skills/pit-viper/references/patterns-core.md +97 -0
- package/claude-plugin/skills/pit-viper/references/theme-guide.md +149 -0
- package/claude-plugin/skills/pit-viper/references/vue-guidelines.md +513 -0
- package/package.json +3 -3
- package/pv-components/dist/stats/vue/base/stats.html +1 -1
- package/pv-components/dist/stats/vue/visualizations/stats.html +1 -1
- package/pv-components/dist/stats/web/pv-menu-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-multi-select-button-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-query-builder-input-stats.html +1 -1
- package/pv-components/dist/stats/web/pv-select-button-stats.html +1 -1
- package/pv-components/dist/vue/base/pv-components-base.mjs +2 -2
- package/pv-components/dist/vue/base/pv-components-base.mjs.map +1 -1
- package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/filters/filterHelpers.d.ts +1 -1
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs +5 -5
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs.map +1 -1
- package/pv-components/dist/web/components/pv-menu/pv-menu.js +2 -2
- package/pv-components/dist/web/components/pv-multi-select-button/pv-multi-select-button.js +2 -2
- package/pv-components/dist/web/components/pv-query-builder-input/pv-query-builder-input.js +2 -2
- package/pv-components/dist/web/components/pv-select-button/pv-select-button.js +2 -2
- package/pv-components/dist/web/pv-components.iife.js +1 -1
- package/pv-components/dist/web/pv-components.iife.js.map +1 -1
- package/claude-plugin/skills/audit/SKILL.md +0 -125
- package/claude-plugin/skills/create/SKILL.md +0 -389
- package/claude-plugin/skills/resolve/SKILL.md +0 -142
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pit-viper
|
|
3
|
+
description: Use for all frontend work in a Turquoise Health codebase — UI building, Vue/HTML editing, component usage, and visual interface work.
|
|
4
|
+
allowed-tools: Read Glob Grep Write Edit WebFetch
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Pit Viper Design System
|
|
8
|
+
|
|
9
|
+
Use Pit Viper for all frontend work. This skill grounds you in what actually exists in the design system — no hallucinating components or inventing variants.
|
|
10
|
+
|
|
11
|
+
## Workflow
|
|
12
|
+
|
|
13
|
+
### Step 0: Detect Output Mode
|
|
14
|
+
|
|
15
|
+
Read context signals to determine the appropriate output:
|
|
16
|
+
|
|
17
|
+
| Mode | Signals | Output |
|
|
18
|
+
|------|---------|--------|
|
|
19
|
+
| **Engineer** | Editing .vue files, mentions "props", "emit", "component", Vue project context | Idiomatic Vue 3 Composition API code |
|
|
20
|
+
| **Prototype** | "Quick prototype", "HTML", "no framework", non-technical user, unclear technical level | Plain HTML with pv-* classes and web components |
|
|
21
|
+
| **Design Review** | "What component for...", "does this work with...", design discussion | Component selection rationale only — no code |
|
|
22
|
+
|
|
23
|
+
If unclear, ask. If still unclear, default to **Prototype Mode** (most portable).
|
|
24
|
+
|
|
25
|
+
### Step 1: Search for Components
|
|
26
|
+
|
|
27
|
+
Search across Vue components and CSS utilities:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
WebFetch https://pitviper.turquoise.health/llm/search?q=dropdown
|
|
31
|
+
WebFetch https://pitviper.turquoise.health/llm/search?q=data%20table
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Returns matching components with names, descriptions, and categories.
|
|
35
|
+
|
|
36
|
+
### Step 2: Get Component Details
|
|
37
|
+
|
|
38
|
+
Get props, argTypes, stories, and source code for a specific component:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
WebFetch https://pitviper.turquoise.health/llm/component/PvSelectButton
|
|
42
|
+
WebFetch https://pitviper.turquoise.health/llm/component/PvDataTable
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For web components, add `?web_component=true`:
|
|
46
|
+
```
|
|
47
|
+
WebFetch https://pitviper.turquoise.health/llm/component/PvButton?web_component=true
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Step 3: Fetch CSS Utilities
|
|
51
|
+
|
|
52
|
+
Get CSS component documentation:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
WebFetch https://pitviper.turquoise.health/llm/css/flex
|
|
56
|
+
WebFetch https://pitviper.turquoise.health/llm/css/spacing
|
|
57
|
+
WebFetch https://pitviper.turquoise.health/llm/css/buttons
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Get design tokens (colors, spacing, typography):
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
WebFetch https://pitviper.turquoise.health/llm/tokens
|
|
64
|
+
WebFetch https://pitviper.turquoise.health/llm/tokens?category=color
|
|
65
|
+
WebFetch https://pitviper.turquoise.health/llm/tokens?category=spacing
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### LLM Endpoints Reference
|
|
69
|
+
|
|
70
|
+
Base URL: `https://pitviper.turquoise.health`
|
|
71
|
+
|
|
72
|
+
| Endpoint | Purpose |
|
|
73
|
+
|----------|---------|
|
|
74
|
+
| `GET /llm` | API index |
|
|
75
|
+
| `GET /llm/search?q={query}` | Search Vue + CSS components |
|
|
76
|
+
| `GET /llm/component` | List all Vue components |
|
|
77
|
+
| `GET /llm/component/{name}` | Get component details (props, stories, source) |
|
|
78
|
+
| `GET /llm/css` | List all CSS components |
|
|
79
|
+
| `GET /llm/css/{component}` | Get CSS component docs |
|
|
80
|
+
| `GET /llm/css/themes` | Get theme CDN URLs |
|
|
81
|
+
| `GET /llm/tokens` | List design tokens |
|
|
82
|
+
| `GET /llm/tokens?category={cat}` | Filter tokens (color, spacing, typography, border, shadow) |
|
|
83
|
+
|
|
84
|
+
Add `?web_component=true` to component endpoints for web component variants.
|
|
85
|
+
|
|
86
|
+
### Step 4: Generate Output
|
|
87
|
+
|
|
88
|
+
Based on detected mode, read the appropriate reference and generate:
|
|
89
|
+
|
|
90
|
+
- **Engineer Mode**: Read `references/vue-guidelines.md`, produce Vue 3 SFC
|
|
91
|
+
- **Prototype Mode**: Read `references/html-patterns.md`, produce HTML with pv-* classes
|
|
92
|
+
- **Design Review Mode**: Read `references/design-language.md`, explain component selection
|
|
93
|
+
|
|
94
|
+
For page-level layouts, also read `references/layout-patterns.md`.
|
|
95
|
+
For theme decisions, also read `references/theme-guide.md`.
|
|
96
|
+
|
|
97
|
+
## Anti-Patterns
|
|
98
|
+
|
|
99
|
+
These are non-negotiable. Do not:
|
|
100
|
+
|
|
101
|
+
- **Reach for Tailwind** — Pit Viper has its own utility system (pv-* classes)
|
|
102
|
+
- **Invent component variants** — If it's not in Storybook, it doesn't exist. Search first.
|
|
103
|
+
- **Use raw HTML form elements** — `<button>`, `<input>`, `<select>` have Pv equivalents
|
|
104
|
+
- **Build custom tables** — Use PvDataTable (Vue) or pv-table classes (HTML). Never raw `<table>` with custom styling.
|
|
105
|
+
- **Use third-party charting** — Use PvChart or PvDataTableWithChart (Vue only). No D3, Chart.js, or ApexCharts.
|
|
106
|
+
- **Write custom CSS** — If a pv-* class doesn't exist, verify twice before adding styles
|
|
107
|
+
- **Write custom table/chart CSS** — Tables and charts have complete Pit Viper styling. No custom styles.
|
|
108
|
+
- **Guess icon names** — Verify at https://pitviper.turquoise.health/visual-style/icons/
|
|
109
|
+
- **Import from barrel exports** — Import directly from component paths
|
|
110
|
+
|
|
111
|
+
## When a Component Doesn't Exist
|
|
112
|
+
|
|
113
|
+
If `/llm/search` returns no match for a legitimate UI need:
|
|
114
|
+
|
|
115
|
+
1. Use the **closest existing component** + pv-* utility classes
|
|
116
|
+
2. **Flag the gap** to the user: "Pit Viper doesn't have a dedicated X component — using PvY with custom layout. Consider requesting this from the design system team."
|
|
117
|
+
3. Do NOT invent a fake component or silently use raw HTML
|
|
118
|
+
|
|
119
|
+
## References
|
|
120
|
+
|
|
121
|
+
Load these only when the specific condition applies:
|
|
122
|
+
|
|
123
|
+
| File | Load when... |
|
|
124
|
+
|------|--------------|
|
|
125
|
+
| `references/design-rules.md` | **ALWAYS** — mandatory rules for spacing, typography, colors, layout |
|
|
126
|
+
| `references/patterns-core.md` | **ALWAYS** — universal utility class patterns and anti-patterns |
|
|
127
|
+
| `references/vue-guidelines.md` | Engineer Mode — Vue setup, patterns, and anti-patterns |
|
|
128
|
+
| `references/html-patterns.md` | Prototype Mode — HTML/web component patterns and anti-patterns |
|
|
129
|
+
| `references/design-language.md` | Design Review Mode — validating tokens or explaining layout rationale |
|
|
130
|
+
| `references/layout-patterns.md` | Building a full page or multi-component layout (not single components) |
|
|
131
|
+
| `references/theme-guide.md` | Choosing between Platform/Consumer CSS, or token values are ambiguous |
|
|
132
|
+
|
|
133
|
+
**Important:** `design-rules.md` and `patterns-core.md` must be loaded for ANY code generation (Engineer or Prototype mode). Mode-specific files (`vue-guidelines.md` or `html-patterns.md`) contain both patterns and anti-patterns for that output format.
|
|
134
|
+
|
|
135
|
+
## Quick Component Map
|
|
136
|
+
|
|
137
|
+
Common UI needs and their Pit Viper equivalents:
|
|
138
|
+
|
|
139
|
+
| Need | Component | Import | Notes |
|
|
140
|
+
|------|-----------|--------|-------|
|
|
141
|
+
| Button | `PvButton` | `@turquoisehealth/pit-viper/components` | |
|
|
142
|
+
| Text input | `PvInput` | `@turquoisehealth/pit-viper/components` | |
|
|
143
|
+
| Dropdown (single) | `PvSelectButton` | `@turquoisehealth/pit-viper/components` | |
|
|
144
|
+
| Dropdown (multi) | `PvMultiSelectButton` | `@turquoisehealth/pit-viper/components` | |
|
|
145
|
+
| Checkbox | `PvCheckbox` | `@turquoisehealth/pit-viper/components` | |
|
|
146
|
+
| Toggle | `PvSwitch` | `@turquoisehealth/pit-viper/components` | |
|
|
147
|
+
| Data table | `PvDataTable` | `@turquoisehealth/pit-viper/components/visualizations` | AG Grid wrapper — sorting, filtering, grouping |
|
|
148
|
+
| Table + chart | `PvDataTableWithChart` | `@turquoisehealth/pit-viper/components/visualizations` | Combined table with integrated chart |
|
|
149
|
+
| Chart | `PvChart` | `@turquoisehealth/pit-viper/components/visualizations` | AG Charts wrapper — bar, line, pie, etc. |
|
|
150
|
+
| Modal | `PvModal` | `@turquoisehealth/pit-viper/components` | |
|
|
151
|
+
| Drawer | `PvDrawer` | `@turquoisehealth/pit-viper/components` | |
|
|
152
|
+
| Tabs | `PvTabs` | `@turquoisehealth/pit-viper/components` | |
|
|
153
|
+
| Card | `PvCard` | `@turquoisehealth/pit-viper/components` | |
|
|
154
|
+
| Toast | `PvToast` | `@turquoisehealth/pit-viper/components` | |
|
|
155
|
+
| Tooltip | `PvTooltipV2` | `@turquoisehealth/pit-viper/components` | |
|
|
156
|
+
|
|
157
|
+
**Tables & Charts (Vue only):** Always use PvDataTable for tabular data. Use PvChart for standalone charts. Use PvDataTableWithChart when you need both together. Never use D3, Chart.js, ApexCharts, or custom `<table>` markup.
|
|
158
|
+
|
|
159
|
+
**Tables (HTML/Prototype):** Use `.pv-table` CSS classes for static tables. Charting is NOT available in HTML mode — charts require Vue components.
|
|
160
|
+
|
|
161
|
+
Always verify with `/llm/component/{name}` before using — props and APIs may have changed.
|
|
162
|
+
|
|
163
|
+
## Rules Summary
|
|
164
|
+
|
|
165
|
+
1. **Pit Viper first** — Always use Pit Viper components and classes
|
|
166
|
+
2. **Search before assuming** — Use `/llm/search` to verify components exist
|
|
167
|
+
3. **Match the audience** — Engineer gets Vue, prototype gets HTML, design review gets rationale
|
|
168
|
+
4. **No custom CSS** — Only pv-* utility classes
|
|
169
|
+
5. **No guessing** — Verify icons, classes, and component names exist
|
|
170
|
+
|
|
171
|
+
## Resources
|
|
172
|
+
|
|
173
|
+
| Resource | URL |
|
|
174
|
+
|----------|-----|
|
|
175
|
+
| Storybook (setup, component docs) | https://pit-viper-storybook.netlify.app/?path=/docs/introduction--documentation |
|
|
176
|
+
| CSS Documentation | https://pitviper.turquoise.health/ |
|
|
177
|
+
| Icons | https://pitviper.turquoise.health/visual-style/icons/ |
|
|
178
|
+
| LLM API | https://pitviper.turquoise.health/llm |
|
|
179
|
+
| Vue + Vite Sandbox | https://stackblitz.com/edit/pv-sandbox-vue-vite |
|
|
180
|
+
| Vue Browser Sandbox | https://stackblitz.com/edit/pv-sandbox-vue-browser |
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Design Language Reference
|
|
2
|
+
|
|
3
|
+
Use this reference in Design Review Mode — when validating designs or explaining layout rationale without generating code.
|
|
4
|
+
|
|
5
|
+
For component selection, use `/llm/search` first. This reference covers layout patterns and token validation.
|
|
6
|
+
|
|
7
|
+
## Layout Patterns
|
|
8
|
+
|
|
9
|
+
| Pattern | Structure | Best For |
|
|
10
|
+
|---------|-----------|----------|
|
|
11
|
+
| **Dashboard** | `PvSidePanel` (nav) + main content area | Multi-page apps with persistent navigation |
|
|
12
|
+
| **Form** | `PvCard` with header/body/footer slots | Data entry, settings, editing |
|
|
13
|
+
| **List-detail** | Table on left, `PvDrawer` or `PvModal` for details | Browse-and-edit workflows |
|
|
14
|
+
| **Settings** | `PvTabs` with `PvAccordion` sections | Complex configuration with many options |
|
|
15
|
+
| **Marketing** | Full-width sections, Consumer theme | Public-facing, consumer-oriented pages |
|
|
16
|
+
|
|
17
|
+
## Token Validation
|
|
18
|
+
|
|
19
|
+
When reviewing designs for Pit Viper compliance:
|
|
20
|
+
|
|
21
|
+
### Colors
|
|
22
|
+
|
|
23
|
+
Fetch current palette:
|
|
24
|
+
```
|
|
25
|
+
WebFetch https://pitviper.turquoise.health/llm/tokens?category=color
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Key values:
|
|
29
|
+
- Primary Brand: `#176F6F` (interactive elements, links)
|
|
30
|
+
- Secondary Brand: `#02363D` (body text, dark surfaces)
|
|
31
|
+
- Error: `#DA1E28`
|
|
32
|
+
- Warning: `#896000`
|
|
33
|
+
- Success: `#0E6027`
|
|
34
|
+
|
|
35
|
+
### Spacing
|
|
36
|
+
|
|
37
|
+
4px base grid. Valid values: 4, 8, 12, 16, 20, 24, 32, 64, 128 pixels.
|
|
38
|
+
|
|
39
|
+
| Value | Use Case |
|
|
40
|
+
|-------|----------|
|
|
41
|
+
| 4-8px | Tight spacing, icons, inline elements |
|
|
42
|
+
| 12-16px | Component padding, section spacing |
|
|
43
|
+
| 24-32px | Major sections, page-level spacing |
|
|
44
|
+
| 64-128px | Hero sections, large separators |
|
|
45
|
+
|
|
46
|
+
### Typography
|
|
47
|
+
|
|
48
|
+
| Style | Platform Size | Consumer Size | Weight |
|
|
49
|
+
|-------|---------------|---------------|--------|
|
|
50
|
+
| Heading 1 | 20px | 62px | 600 |
|
|
51
|
+
| Heading 2 | 16px | 16px | 600 |
|
|
52
|
+
| Body MD | 12px | 16px | 400 |
|
|
53
|
+
| Body SM | 11px | 11px | 400 |
|
|
54
|
+
|
|
55
|
+
### Border Radius
|
|
56
|
+
|
|
57
|
+
- Small: 2px
|
|
58
|
+
- Default: 5px
|
|
59
|
+
- Large: 12px
|
|
60
|
+
|
|
61
|
+
### Shadows
|
|
62
|
+
|
|
63
|
+
Four elevation levels exist (button, popover, elevated hover, modal). Don't invent custom shadows.
|
|
64
|
+
|
|
65
|
+
## Review Checklist
|
|
66
|
+
|
|
67
|
+
1. **Does the component exist?** Search `/llm/search?q={name}` first.
|
|
68
|
+
2. **Are tokens valid?** Check colors, spacing, typography against values above.
|
|
69
|
+
3. **Is the pattern established?** Match to layout patterns table.
|
|
70
|
+
4. **Is the 4px grid respected?** Flag spacing values that aren't multiples of 4.
|
|
71
|
+
|
|
72
|
+
## When to Escalate
|
|
73
|
+
|
|
74
|
+
Flag for design system review if the design requires:
|
|
75
|
+
- Colors not in the palette
|
|
76
|
+
- Spacing values not on the 4px grid
|
|
77
|
+
- Components that don't exist in Pit Viper
|
|
78
|
+
- Patterns that diverge significantly from established layouts
|
|
79
|
+
|
|
80
|
+
Don't silently work around these — they indicate a design system gap.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# Design Rules
|
|
2
|
+
|
|
3
|
+
Prescriptive rules for consistent visual output. These are mandatory — follow them exactly.
|
|
4
|
+
|
|
5
|
+
## Spacing
|
|
6
|
+
|
|
7
|
+
Use pv-* spacing classes. Never use raw `padding`, `margin`, `gap`, or pixel values.
|
|
8
|
+
|
|
9
|
+
### Vertical Spacing (pv-stack-*)
|
|
10
|
+
|
|
11
|
+
| Context | Class | When |
|
|
12
|
+
|---------|-------|------|
|
|
13
|
+
| Page sections | `pv-stack-32` | Between major content blocks |
|
|
14
|
+
| Within sections | `pv-stack-24` | Between card/groups inside a section |
|
|
15
|
+
| Related elements | `pv-stack-16` | Between form fields, list items |
|
|
16
|
+
| Tight coupling | `pv-stack-8` | Label to input, heading to description |
|
|
17
|
+
| Minimal | `pv-stack-4` | Icon to text, inline elements |
|
|
18
|
+
|
|
19
|
+
### Padding (pv-inset-*)
|
|
20
|
+
|
|
21
|
+
| Context | Class |
|
|
22
|
+
|---------|-------|
|
|
23
|
+
| Page wrapper | `pv-inset-square-24` |
|
|
24
|
+
| Card body | `pv-inset-square-16` |
|
|
25
|
+
| Compact card | `pv-inset-square-12` |
|
|
26
|
+
| Button-like elements | `pv-inset-squish-8` or `pv-inset-squish-12` |
|
|
27
|
+
| Dense lists | `pv-inset-square-8` |
|
|
28
|
+
|
|
29
|
+
### Flow (pv-flow-*)
|
|
30
|
+
|
|
31
|
+
Use `pv-flow-*` for horizontal/flex gaps:
|
|
32
|
+
|
|
33
|
+
| Context | Class |
|
|
34
|
+
|---------|-------|
|
|
35
|
+
| Button groups | `pv-flow-8` |
|
|
36
|
+
| Card grids | `pv-flow-16` or `pv-flow-24` |
|
|
37
|
+
| Nav items | `pv-flow-4` or `pv-flow-8` |
|
|
38
|
+
|
|
39
|
+
## Typography
|
|
40
|
+
|
|
41
|
+
Use pv-* typography classes. Never use raw `font-size`, `font-weight`, or `line-height`.
|
|
42
|
+
|
|
43
|
+
### Heading Hierarchy
|
|
44
|
+
|
|
45
|
+
| Level | Class | Use |
|
|
46
|
+
|-------|-------|-----|
|
|
47
|
+
| Page title | `pv-heading-1` | One per page, top of content |
|
|
48
|
+
| Section title | `pv-heading-2` | Major sections within page |
|
|
49
|
+
| Card/panel title | `pv-heading-3` | Card headers, modal titles |
|
|
50
|
+
| Subsection | `pv-heading-4` | Nested sections, accordion headers |
|
|
51
|
+
| Small heading | `pv-heading-5` | Rarely used |
|
|
52
|
+
|
|
53
|
+
### Body Text
|
|
54
|
+
|
|
55
|
+
| Context | Class |
|
|
56
|
+
|---------|-------|
|
|
57
|
+
| Default body | `pv-text-body-md` |
|
|
58
|
+
| Secondary info | `pv-text-body-sm` |
|
|
59
|
+
| Fine print | `pv-text-body-xs` |
|
|
60
|
+
| Large intro | `pv-text-body-lg` (Consumer theme only) |
|
|
61
|
+
|
|
62
|
+
### Labels & Titles
|
|
63
|
+
|
|
64
|
+
| Context | Class |
|
|
65
|
+
|---------|-------|
|
|
66
|
+
| Form label | `pv-text-title-sm` |
|
|
67
|
+
| Card header text | `pv-text-title-md` |
|
|
68
|
+
| Emphasized inline | `pv-text-title-sm` |
|
|
69
|
+
|
|
70
|
+
### Text Modifiers
|
|
71
|
+
|
|
72
|
+
| Purpose | Class |
|
|
73
|
+
|---------|-------|
|
|
74
|
+
| De-emphasize | `pv-text-subdued` |
|
|
75
|
+
| On dark backgrounds | `pv-text-inverse` |
|
|
76
|
+
| Brand color | `pv-text-brand` |
|
|
77
|
+
| Error message | `pv-text-error` |
|
|
78
|
+
| Success message | `pv-text-success` |
|
|
79
|
+
| Warning message | `pv-text-warning` |
|
|
80
|
+
|
|
81
|
+
## Colors
|
|
82
|
+
|
|
83
|
+
Use semantic classes. Never hardcode hex values.
|
|
84
|
+
|
|
85
|
+
### Backgrounds (pv-surface-*)
|
|
86
|
+
|
|
87
|
+
| Purpose | Class |
|
|
88
|
+
|---------|-------|
|
|
89
|
+
| Default page | `pv-surface` |
|
|
90
|
+
| Elevated card | `pv-surface-raised` |
|
|
91
|
+
| Subtle highlight | `pv-surface-accent` |
|
|
92
|
+
| Brand header | `pv-surface-brand` |
|
|
93
|
+
| Error state | `pv-surface-error` |
|
|
94
|
+
| Success state | `pv-surface-success` |
|
|
95
|
+
| Warning state | `pv-surface-warning` |
|
|
96
|
+
| Code/mono areas | `pv-surface-gray` or background token |
|
|
97
|
+
|
|
98
|
+
### Status Colors
|
|
99
|
+
|
|
100
|
+
| State | Text Class | Background Class |
|
|
101
|
+
|-------|------------|------------------|
|
|
102
|
+
| Success | `pv-text-success` | `pv-surface-success` |
|
|
103
|
+
| Error | `pv-text-error` | `pv-surface-error` |
|
|
104
|
+
| Warning | `pv-text-warning` | `pv-surface-warning` |
|
|
105
|
+
| Info | `pv-text-brand` | `pv-surface-accent` |
|
|
106
|
+
|
|
107
|
+
## Layout
|
|
108
|
+
|
|
109
|
+
### Page Structure
|
|
110
|
+
|
|
111
|
+
Every page should follow this structure:
|
|
112
|
+
|
|
113
|
+
```html
|
|
114
|
+
<body class="pv-surface">
|
|
115
|
+
<header class="pv-surface-brand pv-inset-square-24">
|
|
116
|
+
<!-- Header content -->
|
|
117
|
+
</header>
|
|
118
|
+
|
|
119
|
+
<main class="pv-container-lg pv-inset-square-24">
|
|
120
|
+
<!-- Page content -->
|
|
121
|
+
</main>
|
|
122
|
+
</body>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Container Widths
|
|
126
|
+
|
|
127
|
+
| Size | Class | Use |
|
|
128
|
+
|------|-------|-----|
|
|
129
|
+
| Small | `pv-container-sm` | Forms, narrow content |
|
|
130
|
+
| Medium | `pv-container-md` | Articles, single-column |
|
|
131
|
+
| Large | `pv-container-lg` | Dashboards, data tables |
|
|
132
|
+
|
|
133
|
+
Always center containers: add `style="margin: 0 auto;"` or wrap in flex parent.
|
|
134
|
+
|
|
135
|
+
### Flex Layouts
|
|
136
|
+
|
|
137
|
+
| Pattern | Classes |
|
|
138
|
+
|---------|---------|
|
|
139
|
+
| Horizontal row | `pv-flex` |
|
|
140
|
+
| Vertical stack | `pv-flex pv-flex-vertical` |
|
|
141
|
+
| Space between | `pv-flex pv-space-between` |
|
|
142
|
+
| Centered | `pv-flex pv-center` |
|
|
143
|
+
| Responsive wrap | `pv-flex pv-flex-responsive` |
|
|
144
|
+
|
|
145
|
+
Set flex gap with `pv-flow-*` or `--flex-gap` custom property.
|
|
146
|
+
|
|
147
|
+
## Cards
|
|
148
|
+
|
|
149
|
+
Always use proper card structure:
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<div class="pv-card">
|
|
153
|
+
<div class="pv-card-header">
|
|
154
|
+
<h3 class="pv-heading-3">Title</h3>
|
|
155
|
+
</div>
|
|
156
|
+
<div class="pv-card-body pv-flow-16">
|
|
157
|
+
<!-- Content -->
|
|
158
|
+
</div>
|
|
159
|
+
<div class="pv-card-footer pv-flex pv-flow-8" style="justify-content: flex-end;">
|
|
160
|
+
<!-- Actions -->
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Don't use:
|
|
166
|
+
- Raw `<div>` with padding for card-like containers
|
|
167
|
+
- Inline styles for card padding
|
|
168
|
+
- Custom border/shadow styles
|
|
169
|
+
|
|
170
|
+
## Forms
|
|
171
|
+
|
|
172
|
+
### Field Structure
|
|
173
|
+
|
|
174
|
+
```html
|
|
175
|
+
<div>
|
|
176
|
+
<label class="pv-text-title-sm pv-stack-4">Label</label>
|
|
177
|
+
<pv-input placeholder="..."></pv-input>
|
|
178
|
+
</div>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
- Always use `pv-stack-4` between label and input
|
|
182
|
+
- Use `pv-flow-16` or `pv-stack-16` between fields
|
|
183
|
+
- Group related fields in `<fieldset>` with `pv-stack-24` between groups
|
|
184
|
+
|
|
185
|
+
### Actions
|
|
186
|
+
|
|
187
|
+
```html
|
|
188
|
+
<div class="pv-flex pv-flow-8" style="--flex-justify: flex-end;">
|
|
189
|
+
<pv-button variant="ghost" label="Cancel"></pv-button>
|
|
190
|
+
<pv-button label="Submit"></pv-button>
|
|
191
|
+
</div>
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
- Primary action on right
|
|
195
|
+
- Secondary/cancel on left
|
|
196
|
+
- Use `pv-flow-8` between buttons
|
|
197
|
+
|
|
198
|
+
## Tables
|
|
199
|
+
|
|
200
|
+
For data tables, always use `PvDataTable` (Vue) or `pv-table` classes (HTML).
|
|
201
|
+
|
|
202
|
+
HTML table structure:
|
|
203
|
+
```html
|
|
204
|
+
<table class="pv-table">
|
|
205
|
+
<thead>
|
|
206
|
+
<tr>
|
|
207
|
+
<th>Header</th>
|
|
208
|
+
</tr>
|
|
209
|
+
</thead>
|
|
210
|
+
<tbody>
|
|
211
|
+
<tr>
|
|
212
|
+
<td>Cell</td>
|
|
213
|
+
</tr>
|
|
214
|
+
</tbody>
|
|
215
|
+
</table>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Never add custom styling to tables.
|
|
219
|
+
|
|
220
|
+
## Borders & Radius
|
|
221
|
+
|
|
222
|
+
| Purpose | Class |
|
|
223
|
+
|---------|-------|
|
|
224
|
+
| Subtle divider | `pv-border-bottom` |
|
|
225
|
+
| Card-like border | `pv-border` |
|
|
226
|
+
| Rounded corners | `pv-radius` (default 5px) |
|
|
227
|
+
| Small radius | `pv-radius-sm` (2px) |
|
|
228
|
+
| Large radius | `pv-radius-lg` (12px) |
|
|
229
|
+
|
|
230
|
+
## Allowed Inline Styles
|
|
231
|
+
|
|
232
|
+
Only these inline styles are acceptable (when no class exists):
|
|
233
|
+
|
|
234
|
+
- `style="max-width: Npx;"` — constrain element width
|
|
235
|
+
- `style="height: Npx;"` — set explicit height (tables, charts)
|
|
236
|
+
- `style="flex: 1;"` — flex grow in layouts
|
|
237
|
+
- `style="margin: 0 auto;"` — center container
|
|
238
|
+
- `style="justify-content: flex-end;"` — align flex children
|
|
239
|
+
- `style="--flex-gap: Nrem;"` — set flex gap
|
|
240
|
+
|
|
241
|
+
Everything else must use pv-* classes. If you need a style that doesn't exist, flag it as a design system gap.
|
|
242
|
+
|
|
243
|
+
## Checklist
|
|
244
|
+
|
|
245
|
+
Before finalizing output, verify:
|
|
246
|
+
|
|
247
|
+
1. [ ] No raw `padding`, `margin`, `font-size`, `color` in styles
|
|
248
|
+
2. [ ] No hardcoded hex colors
|
|
249
|
+
3. [ ] No `<style>` blocks
|
|
250
|
+
4. [ ] Headings follow hierarchy (h1 > h2 > h3)
|
|
251
|
+
5. [ ] Cards use `pv-card` + `pv-card-header` + `pv-card-body`
|
|
252
|
+
6. [ ] Page wrapped in `pv-container-*` with `pv-inset-square-24`
|
|
253
|
+
7. [ ] Spacing uses `pv-stack-*` or `pv-flow-*`
|
|
254
|
+
8. [ ] Status colors use semantic classes, not hardcoded values
|