@turquoisehealth/pit-viper 2.182.1-dev.5 → 2.183.1-dev.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/skills/pit-viper/SKILL.md +28 -31
- package/package.json +1 -1
- package/pv-components/dist/stats/vue/visualizations/stats.html +1 -1
- package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/table-components/FilterGroupMenu.vue.d.ts +21 -0
- package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/types.d.ts +9 -0
- package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/useSetFilter.d.ts +1 -0
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs +1610 -1426
- package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs.map +1 -1
- package/claude-plugin/skills/pit-viper/references/design-language.md +0 -80
- package/claude-plugin/skills/pit-viper/references/design-rules.md +0 -265
- package/claude-plugin/skills/pit-viper/references/html-patterns.md +0 -468
- package/claude-plugin/skills/pit-viper/references/layout-patterns.md +0 -367
- package/claude-plugin/skills/pit-viper/references/patterns-core.md +0 -97
- package/claude-plugin/skills/pit-viper/references/theme-guide.md +0 -160
- package/claude-plugin/skills/pit-viper/references/vue-guidelines.md +0 -526
|
@@ -1,367 +0,0 @@
|
|
|
1
|
-
# Layout Patterns
|
|
2
|
-
|
|
3
|
-
Use this reference when building page-level layouts in any output mode.
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- Dashboard Pattern (sidebar + main + optional panel) — Vue
|
|
8
|
-
- Form Pattern (card with inputs and actions) — Vue
|
|
9
|
-
- Settings Pattern (tabs + accordion) — Vue
|
|
10
|
-
- Marketing Pattern (hero + features + CTA) — HTML
|
|
11
|
-
- List-Detail Pattern (table + drawer) — Vue
|
|
12
|
-
|
|
13
|
-
## Dashboard Pattern
|
|
14
|
-
|
|
15
|
-
Three-column layout with navigation sidebar, main content, and optional right panel.
|
|
16
|
-
|
|
17
|
-
### Vue Example
|
|
18
|
-
```vue
|
|
19
|
-
<script setup>
|
|
20
|
-
import { ref } from 'vue'
|
|
21
|
-
import { PvButton, PvSearchInput, PvIcon } from '@turquoisehealth/pit-viper/components'
|
|
22
|
-
import { PvDataTable } from '@turquoisehealth/pit-viper/components/visualizations'
|
|
23
|
-
import PvSidePanel from '@turquoisehealth/pit-viper/components/layout/PvSidePanel/PvSidePanel.vue'
|
|
24
|
-
|
|
25
|
-
const searchQuery = ref('')
|
|
26
|
-
const activeNav = ref('dashboard')
|
|
27
|
-
|
|
28
|
-
const navItems = [
|
|
29
|
-
{ id: 'dashboard', label: 'Dashboard', icon: 'home' },
|
|
30
|
-
{ id: 'users', label: 'Users', icon: 'user' },
|
|
31
|
-
{ id: 'settings', label: 'Settings', icon: 'gear' },
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
const colDefs = [
|
|
35
|
-
{ field: 'name', headerName: 'Name', flex: 1 },
|
|
36
|
-
{ field: 'email', headerName: 'Email', flex: 1 },
|
|
37
|
-
{ field: 'role', headerName: 'Role', width: 120 },
|
|
38
|
-
]
|
|
39
|
-
|
|
40
|
-
const rowData = [
|
|
41
|
-
{ name: 'Alice Johnson', email: 'alice@example.com', role: 'Admin' },
|
|
42
|
-
{ name: 'Bob Smith', email: 'bob@example.com', role: 'Editor' },
|
|
43
|
-
]
|
|
44
|
-
</script>
|
|
45
|
-
|
|
46
|
-
<template>
|
|
47
|
-
<div style="height: 100vh;">
|
|
48
|
-
<PvSidePanel :showLeftSidebar="true" :showRightSidebar="false">
|
|
49
|
-
<template #left-sidebar>
|
|
50
|
-
<nav class="pv-inset-square-16">
|
|
51
|
-
<p class="pv-text-title-md pv-stack-24">My App</p>
|
|
52
|
-
<ul style="list-style: none; padding: 0; margin: 0;" class="pv-flow-4">
|
|
53
|
-
<li
|
|
54
|
-
v-for="item in navItems"
|
|
55
|
-
:key="item.id"
|
|
56
|
-
class="pv-flex pv-inset-squish-8 pv-radius"
|
|
57
|
-
:class="{ 'pv-surface-highlight': activeNav === item.id }"
|
|
58
|
-
style="cursor: pointer; --flex-gap: 0.75rem;"
|
|
59
|
-
@click="activeNav = item.id"
|
|
60
|
-
>
|
|
61
|
-
<PvIcon :name="item.icon" :size="16" />
|
|
62
|
-
<span class="pv-text-body-md">{{ item.label }}</span>
|
|
63
|
-
</li>
|
|
64
|
-
</ul>
|
|
65
|
-
</nav>
|
|
66
|
-
</template>
|
|
67
|
-
|
|
68
|
-
<template #main>
|
|
69
|
-
<div class="pv-inset-square-24">
|
|
70
|
-
<div class="pv-flex pv-space-between pv-stack-24">
|
|
71
|
-
<h1 class="pv-heading-1">Users</h1>
|
|
72
|
-
<PvButton leftIcon="plus">Add User</PvButton>
|
|
73
|
-
</div>
|
|
74
|
-
|
|
75
|
-
<div class="pv-stack-16">
|
|
76
|
-
<PvSearchInput v-model="searchQuery" placeholder="Search users..." style="max-width: 300px;" />
|
|
77
|
-
</div>
|
|
78
|
-
|
|
79
|
-
<PvDataTable :rowData="rowData" :colDefs="colDefs" style="height: 400px;" />
|
|
80
|
-
</div>
|
|
81
|
-
</template>
|
|
82
|
-
</PvSidePanel>
|
|
83
|
-
</div>
|
|
84
|
-
</template>
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Form Pattern
|
|
88
|
-
|
|
89
|
-
Card-based form with header, body (inputs), and footer (actions).
|
|
90
|
-
|
|
91
|
-
### Vue Example
|
|
92
|
-
```vue
|
|
93
|
-
<script setup>
|
|
94
|
-
import { ref } from 'vue'
|
|
95
|
-
import { PvButton, PvInput, PvSelectButton, PvCard } from '@turquoisehealth/pit-viper/components'
|
|
96
|
-
|
|
97
|
-
const formData = ref({
|
|
98
|
-
name: '',
|
|
99
|
-
email: '',
|
|
100
|
-
role: null,
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
const roleOptions = [
|
|
104
|
-
{ label: 'Admin', value: 'admin' },
|
|
105
|
-
{ label: 'Editor', value: 'editor' },
|
|
106
|
-
{ label: 'Viewer', value: 'viewer' },
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
const handleSubmit = () => {
|
|
110
|
-
console.log('Submitting:', formData.value)
|
|
111
|
-
}
|
|
112
|
-
</script>
|
|
113
|
-
|
|
114
|
-
<template>
|
|
115
|
-
<PvCard style="max-width: 500px;">
|
|
116
|
-
<template #header>
|
|
117
|
-
<h2 class="pv-heading-2">Create User</h2>
|
|
118
|
-
</template>
|
|
119
|
-
|
|
120
|
-
<form @submit.prevent="handleSubmit" class="pv-flow-16">
|
|
121
|
-
<div>
|
|
122
|
-
<label class="pv-text-title-sm pv-stack-4">Name</label>
|
|
123
|
-
<PvInput v-model="formData.name" placeholder="Full name" />
|
|
124
|
-
</div>
|
|
125
|
-
|
|
126
|
-
<div>
|
|
127
|
-
<label class="pv-text-title-sm pv-stack-4">Email</label>
|
|
128
|
-
<PvInput v-model="formData.email" type="email" placeholder="email@example.com" />
|
|
129
|
-
</div>
|
|
130
|
-
|
|
131
|
-
<div>
|
|
132
|
-
<label class="pv-text-title-sm pv-stack-4">Role</label>
|
|
133
|
-
<PvSelectButton v-model="formData.role" :options="roleOptions" placeholder="Select role" />
|
|
134
|
-
</div>
|
|
135
|
-
</form>
|
|
136
|
-
|
|
137
|
-
<template #footer>
|
|
138
|
-
<div class="pv-flex" style="--flex-justify: flex-end; --flex-gap: 0.5rem;">
|
|
139
|
-
<PvButton variant="ghost">Cancel</PvButton>
|
|
140
|
-
<PvButton @click="handleSubmit">Create User</PvButton>
|
|
141
|
-
</div>
|
|
142
|
-
</template>
|
|
143
|
-
</PvCard>
|
|
144
|
-
</template>
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Settings Pattern
|
|
148
|
-
|
|
149
|
-
Tabbed interface with accordion sections for complex settings.
|
|
150
|
-
|
|
151
|
-
### Vue Example
|
|
152
|
-
```vue
|
|
153
|
-
<script setup>
|
|
154
|
-
import { ref } from 'vue'
|
|
155
|
-
import { PvTabs, PvAccordion, PvInput, PvSwitch, PvButton } from '@turquoisehealth/pit-viper/components'
|
|
156
|
-
|
|
157
|
-
const activeTab = ref('profile')
|
|
158
|
-
const profileExpanded = ref(true)
|
|
159
|
-
const notificationsExpanded = ref(false)
|
|
160
|
-
|
|
161
|
-
const settings = ref({
|
|
162
|
-
displayName: 'Alice Johnson',
|
|
163
|
-
email: 'alice@example.com',
|
|
164
|
-
emailNotifications: true,
|
|
165
|
-
slackNotifications: false,
|
|
166
|
-
})
|
|
167
|
-
</script>
|
|
168
|
-
|
|
169
|
-
<template>
|
|
170
|
-
<div class="pv-inset-square-24">
|
|
171
|
-
<h1 class="pv-heading-1 pv-stack-24">Settings</h1>
|
|
172
|
-
|
|
173
|
-
<PvTabs
|
|
174
|
-
v-model="activeTab"
|
|
175
|
-
:tabs="[
|
|
176
|
-
{ label: 'Profile', value: 'profile' },
|
|
177
|
-
{ label: 'Notifications', value: 'notifications' },
|
|
178
|
-
{ label: 'Security', value: 'security' },
|
|
179
|
-
]"
|
|
180
|
-
class="pv-stack-24"
|
|
181
|
-
/>
|
|
182
|
-
|
|
183
|
-
<div v-if="activeTab === 'profile'" class="pv-flow-16">
|
|
184
|
-
<PvAccordion v-model="profileExpanded" header="Personal Information">
|
|
185
|
-
<div class="pv-flow-16 pv-inset-square-16">
|
|
186
|
-
<div>
|
|
187
|
-
<label class="pv-text-title-sm pv-stack-4">Display Name</label>
|
|
188
|
-
<PvInput v-model="settings.displayName" />
|
|
189
|
-
</div>
|
|
190
|
-
<div>
|
|
191
|
-
<label class="pv-text-title-sm pv-stack-4">Email</label>
|
|
192
|
-
<PvInput v-model="settings.email" type="email" />
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
</PvAccordion>
|
|
196
|
-
</div>
|
|
197
|
-
|
|
198
|
-
<div v-if="activeTab === 'notifications'" class="pv-flow-16">
|
|
199
|
-
<PvAccordion v-model="notificationsExpanded" header="Notification Preferences">
|
|
200
|
-
<div class="pv-flow-16 pv-inset-square-16">
|
|
201
|
-
<div class="pv-flex pv-space-between">
|
|
202
|
-
<span class="pv-text-body-md">Email notifications</span>
|
|
203
|
-
<PvSwitch v-model="settings.emailNotifications" />
|
|
204
|
-
</div>
|
|
205
|
-
<div class="pv-flex pv-space-between">
|
|
206
|
-
<span class="pv-text-body-md">Slack notifications</span>
|
|
207
|
-
<PvSwitch v-model="settings.slackNotifications" />
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
</PvAccordion>
|
|
211
|
-
</div>
|
|
212
|
-
|
|
213
|
-
<div class="pv-stack-24">
|
|
214
|
-
<PvButton>Save Changes</PvButton>
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
</template>
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Marketing / Landing Pattern
|
|
221
|
-
|
|
222
|
-
Consumer theme with large typography, full-width sections, and prominent CTAs.
|
|
223
|
-
|
|
224
|
-
### HTML Example (Consumer Theme)
|
|
225
|
-
```html
|
|
226
|
-
<!DOCTYPE html>
|
|
227
|
-
<html lang="en">
|
|
228
|
-
<head>
|
|
229
|
-
<meta charset="UTF-8">
|
|
230
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
231
|
-
<title>Product Landing</title>
|
|
232
|
-
<link rel="stylesheet" href="https://pitviper.turquoise.health/assets/css/pit-viper-consumer.css">
|
|
233
|
-
<script src="https://unpkg.com/@turquoisehealth/pit-viper/pv-components/dist/web/pv-components.iife.js"></script>
|
|
234
|
-
</head>
|
|
235
|
-
<body>
|
|
236
|
-
<!-- Hero Section -->
|
|
237
|
-
<section class="pv-surface-brand-accent pv-inset-square-64">
|
|
238
|
-
<div class="pv-container-md" style="margin: 0 auto; text-align: center;">
|
|
239
|
-
<h1 class="pv-heading-1 pv-stack-24">Transform Your Healthcare Data</h1>
|
|
240
|
-
<p class="pv-text-body-xl pv-text-subdued pv-stack-32" style="max-width: 600px; margin: 0 auto;">
|
|
241
|
-
Unlock insights from your healthcare data with our powerful analytics platform.
|
|
242
|
-
</p>
|
|
243
|
-
<pv-button size="lg">Get Started</pv-button>
|
|
244
|
-
</div>
|
|
245
|
-
</section>
|
|
246
|
-
|
|
247
|
-
<!-- Features Section -->
|
|
248
|
-
<section class="pv-inset-square-64">
|
|
249
|
-
<div class="pv-container-lg" style="margin: 0 auto;">
|
|
250
|
-
<h2 class="pv-heading-2 pv-stack-32" style="text-align: center;">Features</h2>
|
|
251
|
-
<div class="pv-flex pv-flex-responsive" style="--flex-gap: 2rem;">
|
|
252
|
-
<pv-card style="flex: 1;">
|
|
253
|
-
<div slot="default" class="pv-inset-square-24">
|
|
254
|
-
<h3 class="pv-heading-3 pv-stack-8">Real-time Analytics</h3>
|
|
255
|
-
<p class="pv-text-body-md pv-text-subdued">
|
|
256
|
-
Monitor your data in real-time with customizable dashboards.
|
|
257
|
-
</p>
|
|
258
|
-
</div>
|
|
259
|
-
</pv-card>
|
|
260
|
-
<pv-card style="flex: 1;">
|
|
261
|
-
<div slot="default" class="pv-inset-square-24">
|
|
262
|
-
<h3 class="pv-heading-3 pv-stack-8">Secure & Compliant</h3>
|
|
263
|
-
<p class="pv-text-body-md pv-text-subdued">
|
|
264
|
-
HIPAA-compliant infrastructure with enterprise-grade security.
|
|
265
|
-
</p>
|
|
266
|
-
</div>
|
|
267
|
-
</pv-card>
|
|
268
|
-
<pv-card style="flex: 1;">
|
|
269
|
-
<div slot="default" class="pv-inset-square-24">
|
|
270
|
-
<h3 class="pv-heading-3 pv-stack-8">Easy Integration</h3>
|
|
271
|
-
<p class="pv-text-body-md pv-text-subdued">
|
|
272
|
-
Connect to your existing systems with our REST API.
|
|
273
|
-
</p>
|
|
274
|
-
</div>
|
|
275
|
-
</pv-card>
|
|
276
|
-
</div>
|
|
277
|
-
</div>
|
|
278
|
-
</section>
|
|
279
|
-
|
|
280
|
-
<!-- CTA Section -->
|
|
281
|
-
<section class="pv-surface-brand pv-inset-square-64">
|
|
282
|
-
<div class="pv-container-md" style="margin: 0 auto; text-align: center;">
|
|
283
|
-
<h2 class="pv-heading-2 pv-text-inverse pv-stack-16">Ready to get started?</h2>
|
|
284
|
-
<p class="pv-text-body-lg pv-text-inverse pv-stack-24" style="opacity: 0.8;">
|
|
285
|
-
Join thousands of healthcare organizations using our platform.
|
|
286
|
-
</p>
|
|
287
|
-
<pv-button variant="inverse" size="lg">Contact Sales</pv-button>
|
|
288
|
-
</div>
|
|
289
|
-
</section>
|
|
290
|
-
</body>
|
|
291
|
-
</html>
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## List-Detail Pattern
|
|
295
|
-
|
|
296
|
-
Table with a drawer or modal for viewing/editing details.
|
|
297
|
-
|
|
298
|
-
### Vue Example
|
|
299
|
-
```vue
|
|
300
|
-
<script setup>
|
|
301
|
-
import { ref } from 'vue'
|
|
302
|
-
import { PvButton, PvDrawer, PvInput } from '@turquoisehealth/pit-viper/components'
|
|
303
|
-
import { PvDataTable } from '@turquoisehealth/pit-viper/components/visualizations'
|
|
304
|
-
|
|
305
|
-
const selectedUser = ref(null)
|
|
306
|
-
const drawerOpen = ref(false)
|
|
307
|
-
|
|
308
|
-
const users = ref([
|
|
309
|
-
{ id: 1, name: 'Alice Johnson', email: 'alice@example.com', role: 'Admin' },
|
|
310
|
-
{ id: 2, name: 'Bob Smith', email: 'bob@example.com', role: 'Editor' },
|
|
311
|
-
])
|
|
312
|
-
|
|
313
|
-
const colDefs = [
|
|
314
|
-
{ field: 'name', headerName: 'Name', flex: 1 },
|
|
315
|
-
{ field: 'email', headerName: 'Email', flex: 1 },
|
|
316
|
-
{ field: 'role', headerName: 'Role', width: 120 },
|
|
317
|
-
{
|
|
318
|
-
headerName: 'Actions',
|
|
319
|
-
width: 100,
|
|
320
|
-
cellRenderer: 'actionCell',
|
|
321
|
-
},
|
|
322
|
-
]
|
|
323
|
-
|
|
324
|
-
const openDetail = (user) => {
|
|
325
|
-
selectedUser.value = { ...user }
|
|
326
|
-
drawerOpen.value = true
|
|
327
|
-
}
|
|
328
|
-
</script>
|
|
329
|
-
|
|
330
|
-
<template>
|
|
331
|
-
<div class="pv-inset-square-24">
|
|
332
|
-
<div class="pv-flex pv-space-between pv-stack-24">
|
|
333
|
-
<h1 class="pv-heading-1">Users</h1>
|
|
334
|
-
<PvButton leftIcon="plus">Add User</PvButton>
|
|
335
|
-
</div>
|
|
336
|
-
|
|
337
|
-
<PvDataTable
|
|
338
|
-
:rowData="users"
|
|
339
|
-
:colDefs="colDefs"
|
|
340
|
-
@row-clicked="openDetail($event.data)"
|
|
341
|
-
style="height: 400px;"
|
|
342
|
-
/>
|
|
343
|
-
|
|
344
|
-
<PvDrawer v-model="drawerOpen" header="Edit User">
|
|
345
|
-
<template v-if="selectedUser">
|
|
346
|
-
<div class="pv-flow-16">
|
|
347
|
-
<div>
|
|
348
|
-
<label class="pv-text-title-sm pv-stack-4">Name</label>
|
|
349
|
-
<PvInput v-model="selectedUser.name" />
|
|
350
|
-
</div>
|
|
351
|
-
<div>
|
|
352
|
-
<label class="pv-text-title-sm pv-stack-4">Email</label>
|
|
353
|
-
<PvInput v-model="selectedUser.email" type="email" />
|
|
354
|
-
</div>
|
|
355
|
-
</div>
|
|
356
|
-
</template>
|
|
357
|
-
|
|
358
|
-
<template #footer>
|
|
359
|
-
<div class="pv-flex" style="--flex-justify: flex-end; --flex-gap: 0.5rem;">
|
|
360
|
-
<PvButton variant="ghost" @click="drawerOpen = false">Cancel</PvButton>
|
|
361
|
-
<PvButton>Save</PvButton>
|
|
362
|
-
</div>
|
|
363
|
-
</template>
|
|
364
|
-
</PvDrawer>
|
|
365
|
-
</div>
|
|
366
|
-
</template>
|
|
367
|
-
```
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
# Core Patterns
|
|
2
|
-
|
|
3
|
-
Universal patterns for Pit Viper utility classes. These apply to both Vue and HTML output.
|
|
4
|
-
|
|
5
|
-
## Anti-Pattern: Tailwind Classes
|
|
6
|
-
|
|
7
|
-
Pit Viper has its own utility system. Never use Tailwind.
|
|
8
|
-
|
|
9
|
-
```html
|
|
10
|
-
<!-- BAD: Tailwind -->
|
|
11
|
-
<div class="flex gap-4 p-6 bg-gray-100 rounded-lg">
|
|
12
|
-
<h1 class="text-xl font-semibold mb-4">Title</h1>
|
|
13
|
-
<p class="text-sm text-gray-600">Description</p>
|
|
14
|
-
</div>
|
|
15
|
-
|
|
16
|
-
<!-- GOOD: Pit Viper -->
|
|
17
|
-
<div class="pv-flex pv-inset-square-24 pv-surface-accent pv-radius">
|
|
18
|
-
<h1 class="pv-heading-2 pv-stack-16">Title</h1>
|
|
19
|
-
<p class="pv-text-body-sm pv-text-subdued">Description</p>
|
|
20
|
-
</div>
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
| Tailwind | Pit Viper |
|
|
24
|
-
|----------|-----------|
|
|
25
|
-
| `flex` | `pv-flex` |
|
|
26
|
-
| `gap-4` | `--flex-gap: 1rem` or spacing class |
|
|
27
|
-
| `p-6` | `pv-inset-square-24` |
|
|
28
|
-
| `bg-gray-100` | `pv-surface-accent` |
|
|
29
|
-
| `rounded-lg` | `pv-radius` |
|
|
30
|
-
| `text-xl font-semibold` | `pv-heading-2` |
|
|
31
|
-
| `text-sm text-gray-600` | `pv-text-body-sm pv-text-subdued` |
|
|
32
|
-
| `mb-4` | `pv-stack-16` |
|
|
33
|
-
|
|
34
|
-
## Anti-Pattern: Components Without Spacing
|
|
35
|
-
|
|
36
|
-
Elements jammed together without breathing room look broken.
|
|
37
|
-
|
|
38
|
-
```html
|
|
39
|
-
<!-- BAD: No spacing -->
|
|
40
|
-
<div>
|
|
41
|
-
<h1>Settings</h1>
|
|
42
|
-
<p>Configure your preferences below.</p>
|
|
43
|
-
<pv-input placeholder="Name"></pv-input>
|
|
44
|
-
<pv-input placeholder="Email"></pv-input>
|
|
45
|
-
<pv-button label="Save"></pv-button>
|
|
46
|
-
</div>
|
|
47
|
-
|
|
48
|
-
<!-- GOOD: Proper spacing hierarchy -->
|
|
49
|
-
<div class="pv-inset-square-24">
|
|
50
|
-
<h1 class="pv-heading-1 pv-stack-8">Settings</h1>
|
|
51
|
-
<p class="pv-text-body-md pv-text-subdued pv-stack-24">Configure your preferences below.</p>
|
|
52
|
-
<div class="pv-flex-vertical pv-stack-24" style="--flex-gap: 1rem;">
|
|
53
|
-
<pv-input placeholder="Name"></pv-input>
|
|
54
|
-
<pv-input placeholder="Email"></pv-input>
|
|
55
|
-
</div>
|
|
56
|
-
<pv-button label="Save"></pv-button>
|
|
57
|
-
</div>
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Anti-Pattern: Hardcoded Colors
|
|
61
|
-
|
|
62
|
-
Never use hex values. Use semantic color classes.
|
|
63
|
-
|
|
64
|
-
```html
|
|
65
|
-
<!-- BAD: Hardcoded colors -->
|
|
66
|
-
<span style="color: #0E8019;">Success!</span>
|
|
67
|
-
<span style="color: #DA1E28;">Error!</span>
|
|
68
|
-
<div style="background: #F7F8F8;">Content</div>
|
|
69
|
-
|
|
70
|
-
<!-- GOOD: Semantic classes -->
|
|
71
|
-
<span class="pv-text-success">Success!</span>
|
|
72
|
-
<span class="pv-text-critical">Error!</span>
|
|
73
|
-
<div class="pv-surface-accent">Content</div>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Allowed Inline Styles
|
|
77
|
-
|
|
78
|
-
These inline styles are acceptable when no pv-* class exists:
|
|
79
|
-
|
|
80
|
-
| Style | Use Case |
|
|
81
|
-
|-------|----------|
|
|
82
|
-
| `style="max-width: 500px;"` | Constrain element width |
|
|
83
|
-
| `style="width: 298px;"` | Specific width for modals |
|
|
84
|
-
| `style="height: 400px;"` | Table/chart height |
|
|
85
|
-
| `style="--flex-gap: 1rem;"` | Flex gap override |
|
|
86
|
-
| `style="--flex-justify: flex-end;"` | Flex alignment |
|
|
87
|
-
| `style="--flow-size: 16px;"` | Flow spacing override |
|
|
88
|
-
| `style="text-decoration: none;"` | Link reset |
|
|
89
|
-
| `style="cursor: pointer;"` | Clickable non-button elements |
|
|
90
|
-
| `style="padding: 0px;"` | Reset default padding |
|
|
91
|
-
|
|
92
|
-
**Not allowed:**
|
|
93
|
-
- `style="color: #xxx;"` — use `pv-text-*` classes
|
|
94
|
-
- `style="background: #xxx;"` — use `pv-surface-*` classes
|
|
95
|
-
- `style="font-size: Xpx;"` — use `pv-heading-*` or `pv-text-*` classes
|
|
96
|
-
- `style="margin-bottom: Xpx;"` — use `pv-stack-*` classes
|
|
97
|
-
- `style="display: flex;"` — use `pv-flex` class
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
# Theme Selection Guide
|
|
2
|
-
|
|
3
|
-
Use this reference when choosing between Platform and Consumer themes or applying design tokens.
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- Theme Comparison (Platform vs Consumer)
|
|
8
|
-
- Theme URLs (CDN hrefs)
|
|
9
|
-
- Auto-Detection Keywords
|
|
10
|
-
- Typography Scale
|
|
11
|
-
- Spacing System (4px grid)
|
|
12
|
-
- Color Palette
|
|
13
|
-
- Border Radius
|
|
14
|
-
- Layout Classes
|
|
15
|
-
|
|
16
|
-
## Theme Comparison
|
|
17
|
-
|
|
18
|
-
| Aspect | Platform | Consumer |
|
|
19
|
-
|--------|----------|----------|
|
|
20
|
-
| **Use case** | Internal tools, dashboards, admin panels | Marketing sites, public pages, consumer apps |
|
|
21
|
-
| **CSS file** | `pit-viper-v2.css` | `pit-viper-consumer.css` |
|
|
22
|
-
| **Font** | Inter | GT Standard |
|
|
23
|
-
| **Body text** | 12px (compact) | 16px (spacious) |
|
|
24
|
-
| **Heading 1** | 20px | 62px |
|
|
25
|
-
| **Overall density** | Compact, data-dense | Spacious, content-focused |
|
|
26
|
-
| **Color warmth** | Cool blue-gray | Warmer teal |
|
|
27
|
-
|
|
28
|
-
## Theme URLs
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
Platform: https://pitviper.turquoise.health/assets/css/pit-viper-v2.css
|
|
32
|
-
Consumer: https://pitviper.turquoise.health/assets/css/pit-viper-consumer.css
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Do NOT use the `-scoped` variants.
|
|
36
|
-
|
|
37
|
-
## Auto-Detection Keywords
|
|
38
|
-
|
|
39
|
-
### Platform Theme (Default)
|
|
40
|
-
- "dashboard"
|
|
41
|
-
- "admin"
|
|
42
|
-
- "internal"
|
|
43
|
-
- "tool"
|
|
44
|
-
- "portal"
|
|
45
|
-
- "app"
|
|
46
|
-
- "settings"
|
|
47
|
-
- "management"
|
|
48
|
-
|
|
49
|
-
### Consumer Theme
|
|
50
|
-
- "marketing"
|
|
51
|
-
- "landing"
|
|
52
|
-
- "public"
|
|
53
|
-
- "consumer"
|
|
54
|
-
- "website"
|
|
55
|
-
- "customer-facing"
|
|
56
|
-
- "external"
|
|
57
|
-
- "hero"
|
|
58
|
-
|
|
59
|
-
If none of these keywords appear, default to **Platform**.
|
|
60
|
-
|
|
61
|
-
## Typography Scale
|
|
62
|
-
|
|
63
|
-
### Platform Theme
|
|
64
|
-
| Class | Size | Weight | Line Height |
|
|
65
|
-
|-------|------|--------|-------------|
|
|
66
|
-
| `.pv-heading-1` | 1.25rem (20px) | 600 | 1.2 |
|
|
67
|
-
| `.pv-heading-2` | 1rem (16px) | 600 | 1.5 |
|
|
68
|
-
| `.pv-heading-3` | 0.875rem (14px) | 600 | 1.43 |
|
|
69
|
-
| `.pv-heading-4` | 0.75rem (12px) | 600 | 1.33 |
|
|
70
|
-
| `.pv-text-body-xl` | 0.875rem (14px) | 400 | 1.14 |
|
|
71
|
-
| `.pv-text-body-lg` | 0.875rem (14px) | 400 | 1.14 |
|
|
72
|
-
| `.pv-text-body-md` | 0.75rem (12px) | 400 | 1.33 |
|
|
73
|
-
| `.pv-text-body-sm` | 0.6875rem (11px) | 400 | 1.45 |
|
|
74
|
-
|
|
75
|
-
### Consumer Theme
|
|
76
|
-
Heading 1 scales up dramatically (62px). Body text is larger (16px base). Use for marketing pages where readability at a glance matters more than information density.
|
|
77
|
-
|
|
78
|
-
## Spacing System
|
|
79
|
-
|
|
80
|
-
4px base grid. Valid values:
|
|
81
|
-
|
|
82
|
-
| Class | Value | Pixels |
|
|
83
|
-
|-------|-------|--------|
|
|
84
|
-
| `.pv-stack-0` | 0 | 0 |
|
|
85
|
-
| `.pv-stack-4` | 0.25rem | 4px |
|
|
86
|
-
| `.pv-stack-8` | 0.5rem | 8px |
|
|
87
|
-
| `.pv-stack-12` | 0.75rem | 12px |
|
|
88
|
-
| `.pv-stack-16` | 1rem | 16px |
|
|
89
|
-
| `.pv-stack-20` | 1.25rem | 20px |
|
|
90
|
-
| `.pv-stack-24` | 1.5rem | 24px |
|
|
91
|
-
| `.pv-stack-32` | 2rem | 32px |
|
|
92
|
-
| `.pv-stack-64` | 4rem | 64px |
|
|
93
|
-
| `.pv-stack-128` | 8rem | 128px |
|
|
94
|
-
|
|
95
|
-
Same values exist for `.pv-inset-square-*` (padding) and `.pv-flow-*` (gap).
|
|
96
|
-
|
|
97
|
-
## Color Palette
|
|
98
|
-
|
|
99
|
-
### Brand Colors
|
|
100
|
-
| Token | Hex | Usage |
|
|
101
|
-
|-------|-----|-------|
|
|
102
|
-
| Primary Brand | `#176F6F` | Interactive elements, links, primary buttons |
|
|
103
|
-
| Secondary Brand | `#02363D` | Body text, secondary buttons, dark surfaces |
|
|
104
|
-
| Brand Accent Light | `#A8E6E1` | Inverse buttons, AI button, tertiary |
|
|
105
|
-
| Brand Accent Bg | `#F3FCFB` | Light teal backgrounds |
|
|
106
|
-
|
|
107
|
-
### Text Colors
|
|
108
|
-
| Class | Usage |
|
|
109
|
-
|-------|-------|
|
|
110
|
-
| `.pv-text-default` | Primary body text |
|
|
111
|
-
| `.pv-text-subdued` | Secondary/helper text |
|
|
112
|
-
| `.pv-text-brand` | Links, brand-colored text |
|
|
113
|
-
| `.pv-text-inverse` | Text on dark surfaces |
|
|
114
|
-
| `.pv-text-critical` | Error messages |
|
|
115
|
-
| `.pv-text-warning` | Warning text |
|
|
116
|
-
| `.pv-text-success` | Success text |
|
|
117
|
-
|
|
118
|
-
### Surface Colors
|
|
119
|
-
| Class | Usage |
|
|
120
|
-
|-------|-------|
|
|
121
|
-
| `.pv-surface` | Default white background |
|
|
122
|
-
| `.pv-surface-accent` | Subtle alternate backgrounds |
|
|
123
|
-
| `.pv-surface-brand` | Dark brand surfaces |
|
|
124
|
-
| `.pv-surface-highlight` | Selection/highlight backgrounds |
|
|
125
|
-
| `.pv-surface-brand-accent` | Light teal backgrounds |
|
|
126
|
-
| `.pv-surface-critical` | Error backgrounds |
|
|
127
|
-
| `.pv-surface-warning` | Warning backgrounds |
|
|
128
|
-
| `.pv-surface-success` | Success backgrounds |
|
|
129
|
-
|
|
130
|
-
## Border Radius
|
|
131
|
-
|
|
132
|
-
| Class | Value | Use Case |
|
|
133
|
-
|-------|-------|----------|
|
|
134
|
-
| `.pv-radius-sm` | 2px | Tight, subtle rounding |
|
|
135
|
-
| `.pv-radius` | 5px | Default, most components |
|
|
136
|
-
| `.pv-radius-lg` | 12px | Cards, modals, prominent elements |
|
|
137
|
-
|
|
138
|
-
## Layout Classes
|
|
139
|
-
|
|
140
|
-
| Class | Description |
|
|
141
|
-
|-------|-------------|
|
|
142
|
-
| `.pv-flex` | `display: flex; gap: 0.5rem; align-items: center` |
|
|
143
|
-
| `.pv-flex-vertical` | Column direction |
|
|
144
|
-
| `.pv-flex-responsive` | Column on mobile, row at 768px+ |
|
|
145
|
-
| `.pv-space-between` | `justify-content: space-between` |
|
|
146
|
-
| `.pv-container-sm` | Max-width 768px |
|
|
147
|
-
| `.pv-container-md` | Max-width 972px |
|
|
148
|
-
| `.pv-container-lg` | Max-width 1448px |
|
|
149
|
-
|
|
150
|
-
Use CSS custom property `--flex-gap` to override gap.
|
|
151
|
-
|
|
152
|
-
## Responsive Breakpoint
|
|
153
|
-
|
|
154
|
-
Primary breakpoint: **768px**
|
|
155
|
-
|
|
156
|
-
- Below 768px: Mobile layout (sidebar collapses, flex stacks)
|
|
157
|
-
- 768px and above: Desktop layout
|
|
158
|
-
|
|
159
|
-
Use `.pv-flex-responsive` for automatic column-to-row behavior.
|
|
160
|
-
Use `.pv-stack-*-responsive` for half-size spacing on mobile.
|