devglide 0.1.1
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/LICENSE +21 -0
- package/README.md +338 -0
- package/bin/claude-md-template.js +94 -0
- package/bin/devglide.js +387 -0
- package/package.json +85 -0
- package/pnpm-workspace.yaml +3 -0
- package/src/apps/coder/.turbo/turbo-lint.log +5 -0
- package/src/apps/coder/package.json +16 -0
- package/src/apps/coder/public/favicon.svg +7 -0
- package/src/apps/coder/public/page.css +275 -0
- package/src/apps/coder/public/page.js +528 -0
- package/src/apps/coder/server.js +3 -0
- package/src/apps/documentation/public/page.css +597 -0
- package/src/apps/documentation/public/page.js +609 -0
- package/src/apps/kanban/.turbo/turbo-lint.log +97 -0
- package/src/apps/kanban/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/kanban/package.json +32 -0
- package/src/apps/kanban/public/favicon.svg +7 -0
- package/src/apps/kanban/public/page.css +1010 -0
- package/src/apps/kanban/public/page.js +1730 -0
- package/src/apps/kanban/public/vendor/marked.min.js +6 -0
- package/src/apps/kanban/public/vendor/sortable.min.js +2 -0
- package/src/apps/kanban/src/db.ts +319 -0
- package/src/apps/kanban/src/index.ts +14 -0
- package/src/apps/kanban/src/mcp-helpers.test.ts +88 -0
- package/src/apps/kanban/src/mcp-helpers.ts +60 -0
- package/src/apps/kanban/src/mcp.ts +59 -0
- package/src/apps/kanban/src/routes/attachments.ts +161 -0
- package/src/apps/kanban/src/routes/features.ts +233 -0
- package/src/apps/kanban/src/routes/issues.ts +373 -0
- package/src/apps/kanban/src/tools/feature-tools.ts +164 -0
- package/src/apps/kanban/src/tools/item-tools.ts +307 -0
- package/src/apps/kanban/src/tools/versioned-entry-tools.ts +72 -0
- package/src/apps/kanban/tsconfig.check.json +9 -0
- package/src/apps/kanban/tsconfig.json +9 -0
- package/src/apps/keymap/.turbo/turbo-lint.log +5 -0
- package/src/apps/keymap/package.json +16 -0
- package/src/apps/keymap/public/page.css +275 -0
- package/src/apps/keymap/public/page.js +294 -0
- package/src/apps/keymap/server.js +25 -0
- package/src/apps/log/.turbo/turbo-build.log +5 -0
- package/src/apps/log/.turbo/turbo-lint.log +45 -0
- package/src/apps/log/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/log/node_modules/.bin/tsc +21 -0
- package/src/apps/log/node_modules/.bin/tsserver +21 -0
- package/src/apps/log/node_modules/.bin/tsx +21 -0
- package/src/apps/log/package.json +36 -0
- package/src/apps/log/public/console-sniffer.js +221 -0
- package/src/apps/log/public/favicon.svg +7 -0
- package/src/apps/log/public/page.css +322 -0
- package/src/apps/log/public/page.js +463 -0
- package/src/apps/log/src/index.ts +9 -0
- package/src/apps/log/src/mcp.ts +122 -0
- package/src/apps/log/src/routes/log.ts +333 -0
- package/src/apps/log/src/routes/status.ts +25 -0
- package/src/apps/log/src/server-sniffer.ts +118 -0
- package/src/apps/log/src/services/file-patterns.ts +39 -0
- package/src/apps/log/src/services/file-tailer.ts +228 -0
- package/src/apps/log/src/services/line-parser.ts +94 -0
- package/src/apps/log/src/services/log-writer.ts +39 -0
- package/src/apps/log/tsconfig.json +8 -0
- package/src/apps/prompts/.turbo/turbo-build.log +5 -0
- package/src/apps/prompts/.turbo/turbo-lint.log +24 -0
- package/src/apps/prompts/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/prompts/mcp.ts +175 -0
- package/src/apps/prompts/node_modules/.bin/tsc +21 -0
- package/src/apps/prompts/node_modules/.bin/tsserver +21 -0
- package/src/apps/prompts/node_modules/.bin/tsx +21 -0
- package/src/apps/prompts/package.json +25 -0
- package/src/apps/prompts/public/page.css +315 -0
- package/src/apps/prompts/public/page.js +541 -0
- package/src/apps/prompts/services/prompt-store.ts +212 -0
- package/src/apps/prompts/src/index.ts +9 -0
- package/src/apps/prompts/tsconfig.json +8 -0
- package/src/apps/prompts/types.ts +27 -0
- package/src/apps/shell/.turbo/turbo-build.log +5 -0
- package/src/apps/shell/.turbo/turbo-lint.log +34 -0
- package/src/apps/shell/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/shell/package.json +35 -0
- package/src/apps/shell/public/favicon.svg +7 -0
- package/src/apps/shell/public/page.css +407 -0
- package/src/apps/shell/public/page.js +1577 -0
- package/src/apps/shell/src/index.ts +150 -0
- package/src/apps/shell/src/mcp.ts +398 -0
- package/src/apps/shell/src/shell-types.ts +41 -0
- package/src/apps/shell/tsconfig.json +8 -0
- package/src/apps/test/.turbo/turbo-build.log +5 -0
- package/src/apps/test/.turbo/turbo-lint.log +27 -0
- package/src/apps/test/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/test/node_modules/.bin/tsc +21 -0
- package/src/apps/test/node_modules/.bin/tsserver +21 -0
- package/src/apps/test/node_modules/.bin/tsx +21 -0
- package/src/apps/test/node_modules/.bin/uuid +21 -0
- package/src/apps/test/package.json +35 -0
- package/src/apps/test/public/favicon.svg +7 -0
- package/src/apps/test/public/page.css +499 -0
- package/src/apps/test/public/page.js +417 -0
- package/src/apps/test/public/scenario-runner.js +450 -0
- package/src/apps/test/src/index.ts +9 -0
- package/src/apps/test/src/mcp.ts +192 -0
- package/src/apps/test/src/routes/trigger.ts +285 -0
- package/src/apps/test/src/services/scenario-broadcaster.ts +60 -0
- package/src/apps/test/src/services/scenario-manager.ts +361 -0
- package/src/apps/test/src/services/scenario-store.ts +145 -0
- package/src/apps/test/tsconfig.json +8 -0
- package/src/apps/vocabulary/.turbo/turbo-build.log +5 -0
- package/src/apps/vocabulary/.turbo/turbo-lint.log +25 -0
- package/src/apps/vocabulary/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/vocabulary/mcp.ts +173 -0
- package/src/apps/vocabulary/node_modules/.bin/tsc +21 -0
- package/src/apps/vocabulary/node_modules/.bin/tsserver +21 -0
- package/src/apps/vocabulary/node_modules/.bin/tsx +21 -0
- package/src/apps/vocabulary/package.json +25 -0
- package/src/apps/vocabulary/public/page.css +247 -0
- package/src/apps/vocabulary/public/page.js +444 -0
- package/src/apps/vocabulary/services/vocabulary-store.ts +179 -0
- package/src/apps/vocabulary/src/index.ts +10 -0
- package/src/apps/vocabulary/tsconfig.json +8 -0
- package/src/apps/vocabulary/types.ts +22 -0
- package/src/apps/voice/.turbo/turbo-build.log +5 -0
- package/src/apps/voice/.turbo/turbo-lint.log +43 -0
- package/src/apps/voice/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/voice/node_modules/.bin/openai +21 -0
- package/src/apps/voice/node_modules/.bin/tsc +21 -0
- package/src/apps/voice/node_modules/.bin/tsserver +21 -0
- package/src/apps/voice/node_modules/.bin/tsx +21 -0
- package/src/apps/voice/package.json +35 -0
- package/src/apps/voice/public/favicon.svg +7 -0
- package/src/apps/voice/public/page.css +388 -0
- package/src/apps/voice/public/page.js +718 -0
- package/src/apps/voice/src/index.ts +10 -0
- package/src/apps/voice/src/mcp.ts +70 -0
- package/src/apps/voice/src/providers/index.ts +85 -0
- package/src/apps/voice/src/providers/openai-compatible.ts +94 -0
- package/src/apps/voice/src/providers/types.ts +27 -0
- package/src/apps/voice/src/routes/config.ts +118 -0
- package/src/apps/voice/src/routes/transcribe.ts +90 -0
- package/src/apps/voice/src/services/config-store.ts +129 -0
- package/src/apps/voice/src/services/stats.ts +108 -0
- package/src/apps/voice/src/transcribe.ts +11 -0
- package/src/apps/voice/src/utils/mime.ts +16 -0
- package/src/apps/voice/tsconfig.json +8 -0
- package/src/apps/workflow/.turbo/turbo-build.log +5 -0
- package/src/apps/workflow/.turbo/turbo-lint.log +96 -0
- package/src/apps/workflow/.turbo/turbo-typecheck.log +5 -0
- package/src/apps/workflow/engine/executors/decision-executor.ts +87 -0
- package/src/apps/workflow/engine/executors/file-executor.ts +90 -0
- package/src/apps/workflow/engine/executors/git-executor.ts +137 -0
- package/src/apps/workflow/engine/executors/http-executor.ts +65 -0
- package/src/apps/workflow/engine/executors/index.ts +28 -0
- package/src/apps/workflow/engine/executors/kanban-executor.ts +154 -0
- package/src/apps/workflow/engine/executors/llm-executor.ts +46 -0
- package/src/apps/workflow/engine/executors/log-executor.ts +62 -0
- package/src/apps/workflow/engine/executors/loop-executor.ts +14 -0
- package/src/apps/workflow/engine/executors/shell-executor.ts +107 -0
- package/src/apps/workflow/engine/executors/sub-workflow-executor.ts +61 -0
- package/src/apps/workflow/engine/executors/test-executor.ts +73 -0
- package/src/apps/workflow/engine/executors/trigger-executor.ts +39 -0
- package/src/apps/workflow/engine/expression-evaluator.ts +117 -0
- package/src/apps/workflow/engine/graph-runner.ts +438 -0
- package/src/apps/workflow/engine/node-executor.ts +104 -0
- package/src/apps/workflow/engine/node-registry.ts +15 -0
- package/src/apps/workflow/engine/variable-resolver.ts +109 -0
- package/src/apps/workflow/mcp.ts +223 -0
- package/src/apps/workflow/node_modules/.bin/tsc +21 -0
- package/src/apps/workflow/node_modules/.bin/tsserver +21 -0
- package/src/apps/workflow/node_modules/.bin/tsx +21 -0
- package/src/apps/workflow/package.json +25 -0
- package/src/apps/workflow/public/editor/canvas.js +366 -0
- package/src/apps/workflow/public/editor/drag-manager.js +326 -0
- package/src/apps/workflow/public/editor/edge-renderer.js +235 -0
- package/src/apps/workflow/public/editor/history-manager.js +147 -0
- package/src/apps/workflow/public/editor/layout-engine.js +159 -0
- package/src/apps/workflow/public/editor/node-renderer.js +199 -0
- package/src/apps/workflow/public/editor/selection-manager.js +193 -0
- package/src/apps/workflow/public/favicon.svg +7 -0
- package/src/apps/workflow/public/models/node-types.js +300 -0
- package/src/apps/workflow/public/models/workflow-model.js +257 -0
- package/src/apps/workflow/public/page.css +406 -0
- package/src/apps/workflow/public/page.js +658 -0
- package/src/apps/workflow/public/panels/inspector.js +360 -0
- package/src/apps/workflow/public/panels/palette.js +106 -0
- package/src/apps/workflow/public/panels/run-view.js +275 -0
- package/src/apps/workflow/public/panels/toolbar.js +232 -0
- package/src/apps/workflow/public/panels/workflow-list.js +237 -0
- package/src/apps/workflow/public/state/store.js +47 -0
- package/src/apps/workflow/services/custom-node-loader.ts +48 -0
- package/src/apps/workflow/services/legacy-converter.ts +72 -0
- package/src/apps/workflow/services/run-manager.ts +190 -0
- package/src/apps/workflow/services/workflow-store.ts +424 -0
- package/src/apps/workflow/services/workflow-validator.test.ts +103 -0
- package/src/apps/workflow/services/workflow-validator.ts +98 -0
- package/src/apps/workflow/src/index.ts +10 -0
- package/src/apps/workflow/templates/ci-pipeline.json +18 -0
- package/src/apps/workflow/templates/code-review.json +22 -0
- package/src/apps/workflow/templates/kanban-testing.json +24 -0
- package/src/apps/workflow/tsconfig.json +8 -0
- package/src/apps/workflow/types.ts +268 -0
- package/src/packages/auth-middleware.ts +14 -0
- package/src/packages/design-tokens/.turbo/turbo-build.log +10 -0
- package/src/packages/design-tokens/STYLEGUIDE.md +414 -0
- package/src/packages/design-tokens/build.js +413 -0
- package/src/packages/design-tokens/demo/index.html +1367 -0
- package/src/packages/design-tokens/demo/proposition-a.html +717 -0
- package/src/packages/design-tokens/demo/proposition-b.html +1239 -0
- package/src/packages/design-tokens/demo/proposition-c.html +1049 -0
- package/src/packages/design-tokens/dist/tailwind-preset.js +115 -0
- package/src/packages/design-tokens/dist/tokens.css +345 -0
- package/src/packages/design-tokens/dist/tokens.d.ts +229 -0
- package/src/packages/design-tokens/dist/tokens.js +386 -0
- package/src/packages/design-tokens/package.json +25 -0
- package/src/packages/design-tokens/tokens.json +228 -0
- package/src/packages/devtools-middleware.ts +22 -0
- package/src/packages/eslint-config/index.js +63 -0
- package/src/packages/eslint-config/node_modules/.bin/eslint +21 -0
- package/src/packages/eslint-config/package.json +18 -0
- package/src/packages/json-file-store.ts +232 -0
- package/src/packages/mcp-utils/.turbo/turbo-build.log +5 -0
- package/src/packages/mcp-utils/dist/index.d.ts +33 -0
- package/src/packages/mcp-utils/dist/index.d.ts.map +1 -0
- package/src/packages/mcp-utils/dist/index.js +126 -0
- package/src/packages/mcp-utils/dist/index.js.map +1 -0
- package/src/packages/mcp-utils/node_modules/.bin/tsc +21 -0
- package/src/packages/mcp-utils/node_modules/.bin/tsserver +21 -0
- package/src/packages/mcp-utils/package.json +32 -0
- package/src/packages/mcp-utils/src/index.ts +171 -0
- package/src/packages/mcp-utils/tsconfig.json +9 -0
- package/src/packages/paths.ts +18 -0
- package/src/packages/project-context/index.js +55 -0
- package/src/packages/project-context/package.json +13 -0
- package/src/packages/project-store.ts +127 -0
- package/src/packages/server-sniffer.ts +132 -0
- package/src/packages/shared-assets/favicon.svg +7 -0
- package/src/packages/shared-assets/keymap-registry.js +512 -0
- package/src/packages/shared-assets/logo.svg +6 -0
- package/src/packages/shared-assets/package.json +11 -0
- package/src/packages/shared-assets/ui-utils.js +48 -0
- package/src/packages/shared-assets/voice-widget.d.ts +37 -0
- package/src/packages/shared-assets/voice-widget.js +695 -0
- package/src/packages/shared-types/.turbo/turbo-build.log +5 -0
- package/src/packages/shared-types/dist/index.d.ts +39 -0
- package/src/packages/shared-types/dist/index.d.ts.map +1 -0
- package/src/packages/shared-types/node_modules/.bin/tsc +21 -0
- package/src/packages/shared-types/node_modules/.bin/tsserver +21 -0
- package/src/packages/shared-types/package.json +25 -0
- package/src/packages/shared-types/src/index.ts +41 -0
- package/src/packages/shared-types/tsconfig.json +11 -0
- package/src/packages/tsconfig/base.json +15 -0
- package/src/packages/tsconfig/next.json +14 -0
- package/src/packages/tsconfig/node.json +11 -0
- package/src/packages/tsconfig/package.json +10 -0
- package/turbo.json +25 -0
|
@@ -0,0 +1,1367 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Devglide Design System v2.0</title>
|
|
7
|
+
<link rel="stylesheet" href="../dist/tokens.css">
|
|
8
|
+
<style>
|
|
9
|
+
/* ── Reset ─────────────────────────────────────────────────────────── */
|
|
10
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
11
|
+
|
|
12
|
+
/* ── Base ──────────────────────────────────────────────────────────── */
|
|
13
|
+
html {
|
|
14
|
+
font-size: 13px;
|
|
15
|
+
scroll-behavior: smooth;
|
|
16
|
+
color-scheme: dark;
|
|
17
|
+
}
|
|
18
|
+
body {
|
|
19
|
+
background: var(--df-color-bg-base);
|
|
20
|
+
color: var(--df-color-text-primary);
|
|
21
|
+
font-family: var(--df-font-mono);
|
|
22
|
+
min-height: 100vh;
|
|
23
|
+
line-height: 1.5;
|
|
24
|
+
-webkit-font-smoothing: antialiased;
|
|
25
|
+
-moz-osx-font-smoothing: grayscale;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ── Layout ────────────────────────────────────────────────────────── */
|
|
29
|
+
.page {
|
|
30
|
+
max-width: 1080px;
|
|
31
|
+
margin: 0 auto;
|
|
32
|
+
padding: 0 24px 96px;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* ── Hero ──────────────────────────────────────────────────────────── */
|
|
36
|
+
.hero {
|
|
37
|
+
padding: 80px 0 64px;
|
|
38
|
+
border-bottom: 1px solid var(--df-color-border-default);
|
|
39
|
+
margin-bottom: 64px;
|
|
40
|
+
position: relative;
|
|
41
|
+
}
|
|
42
|
+
.hero::before {
|
|
43
|
+
content: '';
|
|
44
|
+
position: absolute;
|
|
45
|
+
inset: 0;
|
|
46
|
+
background: radial-gradient(ellipse at 30% 20%, color-mix(in srgb, var(--df-color-accent-default) 4%, transparent), transparent 70%);
|
|
47
|
+
pointer-events: none;
|
|
48
|
+
}
|
|
49
|
+
.hero h1 {
|
|
50
|
+
font-size: 36px;
|
|
51
|
+
font-weight: normal;
|
|
52
|
+
letter-spacing: 0.2em;
|
|
53
|
+
text-transform: uppercase;
|
|
54
|
+
color: var(--df-color-accent-default);
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
.hero .sub {
|
|
58
|
+
font-size: 11px;
|
|
59
|
+
letter-spacing: 0.15em;
|
|
60
|
+
color: var(--df-color-text-secondary);
|
|
61
|
+
text-transform: uppercase;
|
|
62
|
+
margin-top: 8px;
|
|
63
|
+
position: relative;
|
|
64
|
+
}
|
|
65
|
+
.hero .version {
|
|
66
|
+
display: inline-block;
|
|
67
|
+
padding: 2px 8px;
|
|
68
|
+
border: 1px solid var(--df-color-accent-muted);
|
|
69
|
+
color: var(--df-color-accent-default);
|
|
70
|
+
font-size: 10px;
|
|
71
|
+
letter-spacing: 0.15em;
|
|
72
|
+
margin-top: 16px;
|
|
73
|
+
position: relative;
|
|
74
|
+
}
|
|
75
|
+
.hero .stats {
|
|
76
|
+
margin-top: 24px;
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 32px;
|
|
79
|
+
flex-wrap: wrap;
|
|
80
|
+
position: relative;
|
|
81
|
+
}
|
|
82
|
+
.hero .stat {
|
|
83
|
+
font-size: 10px;
|
|
84
|
+
letter-spacing: 0.12em;
|
|
85
|
+
text-transform: uppercase;
|
|
86
|
+
color: var(--df-color-text-muted);
|
|
87
|
+
}
|
|
88
|
+
.hero .stat strong {
|
|
89
|
+
font-weight: normal;
|
|
90
|
+
color: var(--df-color-text-primary);
|
|
91
|
+
font-size: 20px;
|
|
92
|
+
display: block;
|
|
93
|
+
margin-bottom: 2px;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* ── Nav ───────────────────────────────────────────────────────────── */
|
|
97
|
+
.nav {
|
|
98
|
+
position: sticky;
|
|
99
|
+
top: 0;
|
|
100
|
+
z-index: 50;
|
|
101
|
+
background: color-mix(in srgb, var(--df-color-bg-base) 90%, transparent);
|
|
102
|
+
backdrop-filter: blur(8px);
|
|
103
|
+
-webkit-backdrop-filter: blur(8px);
|
|
104
|
+
border-bottom: 1px solid var(--df-color-border-subtle);
|
|
105
|
+
padding: 8px 0;
|
|
106
|
+
margin-bottom: 64px;
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-wrap: wrap;
|
|
109
|
+
gap: 2px;
|
|
110
|
+
overflow-x: auto;
|
|
111
|
+
}
|
|
112
|
+
.nav a {
|
|
113
|
+
font-size: 10px;
|
|
114
|
+
letter-spacing: 0.12em;
|
|
115
|
+
text-transform: uppercase;
|
|
116
|
+
color: var(--df-color-text-secondary);
|
|
117
|
+
text-decoration: none;
|
|
118
|
+
padding: 6px 10px;
|
|
119
|
+
border: 1px solid transparent;
|
|
120
|
+
transition: all var(--df-duration-fast) var(--df-easing-default);
|
|
121
|
+
white-space: nowrap;
|
|
122
|
+
border-radius: var(--df-radius-xs);
|
|
123
|
+
}
|
|
124
|
+
.nav a:hover {
|
|
125
|
+
color: var(--df-color-accent-default);
|
|
126
|
+
background: color-mix(in srgb, var(--df-color-accent-default) 6%, transparent);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ── Section ───────────────────────────────────────────────────────── */
|
|
130
|
+
.section { margin-bottom: 80px; }
|
|
131
|
+
.section-title {
|
|
132
|
+
font-size: 10px;
|
|
133
|
+
letter-spacing: 0.25em;
|
|
134
|
+
text-transform: uppercase;
|
|
135
|
+
color: var(--df-color-accent-default);
|
|
136
|
+
border-left: 2px solid var(--df-color-accent-default);
|
|
137
|
+
padding-left: 10px;
|
|
138
|
+
margin-bottom: 24px;
|
|
139
|
+
}
|
|
140
|
+
.section-desc {
|
|
141
|
+
font-size: 11px;
|
|
142
|
+
color: var(--df-color-text-secondary);
|
|
143
|
+
letter-spacing: 0.05em;
|
|
144
|
+
margin-bottom: 24px;
|
|
145
|
+
margin-top: -12px;
|
|
146
|
+
max-width: 700px;
|
|
147
|
+
line-height: 1.6;
|
|
148
|
+
}
|
|
149
|
+
.subsection {
|
|
150
|
+
margin-top: 32px;
|
|
151
|
+
}
|
|
152
|
+
.group-label {
|
|
153
|
+
font-size: 9px;
|
|
154
|
+
letter-spacing: 0.2em;
|
|
155
|
+
text-transform: uppercase;
|
|
156
|
+
color: var(--df-color-text-muted);
|
|
157
|
+
margin-bottom: 8px;
|
|
158
|
+
margin-top: 20px;
|
|
159
|
+
}
|
|
160
|
+
.group-label:first-child { margin-top: 0; }
|
|
161
|
+
|
|
162
|
+
/* ── Interactive Hue Control ───────────────────────────────────────── */
|
|
163
|
+
.hue-control {
|
|
164
|
+
background: var(--df-color-bg-surface);
|
|
165
|
+
border: 1px solid var(--df-color-border-default);
|
|
166
|
+
padding: 24px;
|
|
167
|
+
margin-bottom: 40px;
|
|
168
|
+
clip-path: var(--df-clip-md);
|
|
169
|
+
}
|
|
170
|
+
.hue-control label {
|
|
171
|
+
font-size: 10px;
|
|
172
|
+
letter-spacing: 0.15em;
|
|
173
|
+
text-transform: uppercase;
|
|
174
|
+
color: var(--df-color-text-secondary);
|
|
175
|
+
display: block;
|
|
176
|
+
margin-bottom: 12px;
|
|
177
|
+
}
|
|
178
|
+
.hue-row {
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
gap: 16px;
|
|
182
|
+
}
|
|
183
|
+
.hue-control input[type="range"] {
|
|
184
|
+
flex: 1;
|
|
185
|
+
height: 4px;
|
|
186
|
+
-webkit-appearance: none;
|
|
187
|
+
background: linear-gradient(to right,
|
|
188
|
+
oklch(0.83 0.18 0),
|
|
189
|
+
oklch(0.83 0.18 60),
|
|
190
|
+
oklch(0.83 0.18 120),
|
|
191
|
+
oklch(0.83 0.18 180),
|
|
192
|
+
oklch(0.83 0.18 240),
|
|
193
|
+
oklch(0.83 0.18 300),
|
|
194
|
+
oklch(0.83 0.18 360)
|
|
195
|
+
);
|
|
196
|
+
border-radius: var(--df-radius-full);
|
|
197
|
+
outline: none;
|
|
198
|
+
}
|
|
199
|
+
.hue-control input[type="range"]::-webkit-slider-thumb {
|
|
200
|
+
-webkit-appearance: none;
|
|
201
|
+
width: 16px; height: 16px;
|
|
202
|
+
border-radius: var(--df-radius-full);
|
|
203
|
+
background: var(--df-color-accent-default);
|
|
204
|
+
border: 2px solid var(--df-color-bg-base);
|
|
205
|
+
cursor: pointer;
|
|
206
|
+
box-shadow: 0 0 8px rgba(126,231,135,0.4);
|
|
207
|
+
}
|
|
208
|
+
.hue-preview {
|
|
209
|
+
width: 32px; height: 32px;
|
|
210
|
+
border-radius: var(--df-radius-sm);
|
|
211
|
+
border: 1px solid var(--df-color-border-default);
|
|
212
|
+
transition: background var(--df-duration-fast);
|
|
213
|
+
}
|
|
214
|
+
.hue-value {
|
|
215
|
+
font-size: 12px;
|
|
216
|
+
color: var(--df-color-accent-default);
|
|
217
|
+
min-width: 40px;
|
|
218
|
+
text-align: right;
|
|
219
|
+
}
|
|
220
|
+
.hue-note {
|
|
221
|
+
font-size: 10px;
|
|
222
|
+
color: var(--df-color-text-muted);
|
|
223
|
+
margin-top: 12px;
|
|
224
|
+
letter-spacing: 0.05em;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* ── Color swatches ────────────────────────────────────────────────── */
|
|
228
|
+
.swatch-grid {
|
|
229
|
+
display: grid;
|
|
230
|
+
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
|
231
|
+
gap: 6px;
|
|
232
|
+
}
|
|
233
|
+
.swatch-grid-wide {
|
|
234
|
+
grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
|
|
235
|
+
}
|
|
236
|
+
.swatch {
|
|
237
|
+
padding: 12px 8px;
|
|
238
|
+
font-size: 9px;
|
|
239
|
+
letter-spacing: 0.08em;
|
|
240
|
+
text-transform: uppercase;
|
|
241
|
+
border-radius: var(--df-radius-xs);
|
|
242
|
+
position: relative;
|
|
243
|
+
}
|
|
244
|
+
.swatch-label { opacity: 0.85; display: block; margin-top: 6px; }
|
|
245
|
+
.swatch-hex { opacity: 0.5; font-size: 8px; display: block; margin-top: 2px; }
|
|
246
|
+
|
|
247
|
+
/* ── Typography ────────────────────────────────────────────────────── */
|
|
248
|
+
.type-sample {
|
|
249
|
+
border-bottom: 1px solid var(--df-color-border-subtle);
|
|
250
|
+
padding: 14px 0;
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: baseline;
|
|
253
|
+
justify-content: space-between;
|
|
254
|
+
gap: 16px;
|
|
255
|
+
flex-wrap: wrap;
|
|
256
|
+
}
|
|
257
|
+
.type-meta {
|
|
258
|
+
font-size: 10px;
|
|
259
|
+
color: var(--df-color-text-muted);
|
|
260
|
+
letter-spacing: 0.1em;
|
|
261
|
+
text-transform: uppercase;
|
|
262
|
+
flex-shrink: 0;
|
|
263
|
+
width: 100px;
|
|
264
|
+
}
|
|
265
|
+
.type-specimen { flex: 1; min-width: 200px; }
|
|
266
|
+
|
|
267
|
+
/* ── Spacing ───────────────────────────────────────────────────────── */
|
|
268
|
+
.space-row { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
|
|
269
|
+
.space-bar {
|
|
270
|
+
background: linear-gradient(90deg, var(--df-color-accent-dim), var(--df-color-accent-muted));
|
|
271
|
+
height: 6px; flex-shrink: 0;
|
|
272
|
+
border-radius: var(--df-radius-xs);
|
|
273
|
+
}
|
|
274
|
+
.space-meta { font-size: 10px; color: var(--df-color-text-secondary); letter-spacing: 0.1em; }
|
|
275
|
+
|
|
276
|
+
/* ── Radius / Clip ─────────────────────────────────────────────────── */
|
|
277
|
+
.shape-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
|
|
278
|
+
.shape-demo {
|
|
279
|
+
background: var(--df-color-bg-raised);
|
|
280
|
+
border: 1px solid var(--df-color-border-strong);
|
|
281
|
+
padding: 20px;
|
|
282
|
+
text-align: center;
|
|
283
|
+
font-size: 10px;
|
|
284
|
+
letter-spacing: 0.12em;
|
|
285
|
+
text-transform: uppercase;
|
|
286
|
+
color: var(--df-color-text-secondary);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/* ── Shadow demos ──────────────────────────────────────────────────── */
|
|
290
|
+
.shadow-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 20px; }
|
|
291
|
+
.shadow-demo {
|
|
292
|
+
background: var(--df-color-bg-surface);
|
|
293
|
+
border: 1px solid var(--df-color-border-subtle);
|
|
294
|
+
padding: 24px 16px;
|
|
295
|
+
text-align: center;
|
|
296
|
+
font-size: 10px;
|
|
297
|
+
letter-spacing: 0.12em;
|
|
298
|
+
text-transform: uppercase;
|
|
299
|
+
color: var(--df-color-text-secondary);
|
|
300
|
+
border-radius: var(--df-radius-sm);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* ── Buttons ───────────────────────────────────────────────────────── */
|
|
304
|
+
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
|
|
305
|
+
.btn {
|
|
306
|
+
font-family: var(--df-font-mono);
|
|
307
|
+
font-size: 11px;
|
|
308
|
+
letter-spacing: 0.15em;
|
|
309
|
+
text-transform: uppercase;
|
|
310
|
+
padding: 8px 20px;
|
|
311
|
+
cursor: pointer;
|
|
312
|
+
border: 1px solid;
|
|
313
|
+
transition: all var(--df-duration-base) var(--df-easing-spring);
|
|
314
|
+
outline: none;
|
|
315
|
+
}
|
|
316
|
+
.btn:focus-visible {
|
|
317
|
+
outline: var(--df-focus-ring-width) solid var(--df-focus-ring-color);
|
|
318
|
+
outline-offset: var(--df-focus-ring-offset);
|
|
319
|
+
}
|
|
320
|
+
.btn-primary {
|
|
321
|
+
background: var(--df-color-accent-default);
|
|
322
|
+
border-color: var(--df-color-accent-default);
|
|
323
|
+
color: var(--df-color-text-inverse);
|
|
324
|
+
clip-path: var(--df-clip-sm);
|
|
325
|
+
}
|
|
326
|
+
.btn-primary:hover {
|
|
327
|
+
background: var(--df-color-accent-bright);
|
|
328
|
+
box-shadow: var(--df-glow-accent);
|
|
329
|
+
}
|
|
330
|
+
.btn-outline {
|
|
331
|
+
background: transparent;
|
|
332
|
+
border-color: var(--df-color-border-strong);
|
|
333
|
+
color: var(--df-color-text-primary);
|
|
334
|
+
clip-path: var(--df-clip-sm);
|
|
335
|
+
}
|
|
336
|
+
.btn-outline:hover {
|
|
337
|
+
border-color: var(--df-color-accent-default);
|
|
338
|
+
color: var(--df-color-accent-default);
|
|
339
|
+
}
|
|
340
|
+
.btn-ghost {
|
|
341
|
+
background: transparent;
|
|
342
|
+
border-color: transparent;
|
|
343
|
+
color: var(--df-color-text-secondary);
|
|
344
|
+
}
|
|
345
|
+
.btn-ghost:hover {
|
|
346
|
+
color: var(--df-color-accent-default);
|
|
347
|
+
background: color-mix(in srgb, var(--df-color-accent-default) 6%, transparent);
|
|
348
|
+
}
|
|
349
|
+
.btn-danger {
|
|
350
|
+
background: color-mix(in srgb, var(--df-color-state-error) 10%, transparent);
|
|
351
|
+
border-color: var(--df-color-state-error);
|
|
352
|
+
color: var(--df-color-state-error);
|
|
353
|
+
clip-path: var(--df-clip-sm);
|
|
354
|
+
}
|
|
355
|
+
.btn-danger:hover {
|
|
356
|
+
background: color-mix(in srgb, var(--df-color-state-error) 20%, transparent);
|
|
357
|
+
}
|
|
358
|
+
.btn:disabled {
|
|
359
|
+
opacity: 0.3;
|
|
360
|
+
cursor: not-allowed;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/* ── Inputs ────────────────────────────────────────────────────────── */
|
|
364
|
+
.input-group { display: flex; flex-direction: column; gap: 6px; max-width: 360px; }
|
|
365
|
+
.input-label {
|
|
366
|
+
font-size: 10px;
|
|
367
|
+
letter-spacing: 0.2em;
|
|
368
|
+
text-transform: uppercase;
|
|
369
|
+
color: var(--df-color-text-secondary);
|
|
370
|
+
}
|
|
371
|
+
.input {
|
|
372
|
+
background: var(--df-color-bg-surface);
|
|
373
|
+
border: 1px solid var(--df-color-border-default);
|
|
374
|
+
color: var(--df-color-text-primary);
|
|
375
|
+
font-family: var(--df-font-mono);
|
|
376
|
+
font-size: 12px;
|
|
377
|
+
padding: 8px 12px;
|
|
378
|
+
outline: none;
|
|
379
|
+
transition: border-color var(--df-duration-fast), box-shadow var(--df-duration-fast);
|
|
380
|
+
clip-path: var(--df-clip-sm);
|
|
381
|
+
}
|
|
382
|
+
.input:focus {
|
|
383
|
+
border-color: var(--df-color-accent-default);
|
|
384
|
+
box-shadow: 0 0 8px color-mix(in srgb, var(--df-color-accent-default) 30%, transparent);
|
|
385
|
+
}
|
|
386
|
+
.input::placeholder { color: var(--df-color-text-muted); }
|
|
387
|
+
.input-rounded {
|
|
388
|
+
clip-path: none;
|
|
389
|
+
border-radius: var(--df-radius-md);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/* ── Badges ────────────────────────────────────────────────────────── */
|
|
393
|
+
.badge-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
394
|
+
.badge {
|
|
395
|
+
font-size: 9px;
|
|
396
|
+
letter-spacing: 0.2em;
|
|
397
|
+
text-transform: uppercase;
|
|
398
|
+
padding: 3px 8px;
|
|
399
|
+
border: 1px solid;
|
|
400
|
+
}
|
|
401
|
+
.badge-idle { color: var(--df-color-state-idle); border-color: var(--df-color-state-idle); background: color-mix(in srgb, var(--df-color-state-idle) 10%, transparent); }
|
|
402
|
+
.badge-active { color: var(--df-color-state-active); border-color: var(--df-color-state-active); background: color-mix(in srgb, var(--df-color-state-active) 10%, transparent); }
|
|
403
|
+
.badge-recording { color: var(--df-color-state-recording); border-color: var(--df-color-state-recording); background: color-mix(in srgb, var(--df-color-state-recording) 10%, transparent); animation: df-alert-pulse 1.2s ease-in-out infinite; }
|
|
404
|
+
.badge-processing { color: var(--df-color-state-processing); border-color: var(--df-color-state-processing); background: color-mix(in srgb, var(--df-color-state-processing) 10%, transparent); animation: df-processing-pulse 2s ease-in-out infinite; }
|
|
405
|
+
.badge-success { color: var(--df-color-state-success); border-color: var(--df-color-state-success); background: color-mix(in srgb, var(--df-color-state-success) 10%, transparent); }
|
|
406
|
+
.badge-error { color: var(--df-color-state-error); border-color: var(--df-color-state-error); background: color-mix(in srgb, var(--df-color-state-error) 10%, transparent); }
|
|
407
|
+
.badge-warning { color: var(--df-color-state-warning); border-color: var(--df-color-state-warning); background: color-mix(in srgb, var(--df-color-state-warning) 10%, transparent); }
|
|
408
|
+
.badge-info { color: var(--df-color-state-info); border-color: var(--df-color-state-info); background: color-mix(in srgb, var(--df-color-state-info) 10%, transparent); }
|
|
409
|
+
.badge-rounded {
|
|
410
|
+
border-radius: var(--df-radius-full);
|
|
411
|
+
padding: 3px 12px;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* ── Cards ─────────────────────────────────────────────────────────── */
|
|
415
|
+
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
|
|
416
|
+
.card {
|
|
417
|
+
background: var(--df-color-bg-surface);
|
|
418
|
+
border: 1px solid var(--df-color-border-default);
|
|
419
|
+
padding: 20px;
|
|
420
|
+
transition: border-color var(--df-duration-fast), box-shadow var(--df-duration-base) var(--df-easing-spring);
|
|
421
|
+
}
|
|
422
|
+
.card:hover {
|
|
423
|
+
border-color: var(--df-color-border-strong);
|
|
424
|
+
box-shadow: var(--df-shadow-md);
|
|
425
|
+
}
|
|
426
|
+
.card-clipped { clip-path: var(--df-clip-md); }
|
|
427
|
+
.card-rounded { border-radius: var(--df-radius-lg); }
|
|
428
|
+
.card-title {
|
|
429
|
+
font-size: 11px;
|
|
430
|
+
letter-spacing: 0.15em;
|
|
431
|
+
text-transform: uppercase;
|
|
432
|
+
color: var(--df-color-accent-default);
|
|
433
|
+
margin-bottom: 8px;
|
|
434
|
+
}
|
|
435
|
+
.card-body {
|
|
436
|
+
font-size: 12px;
|
|
437
|
+
color: var(--df-color-text-secondary);
|
|
438
|
+
line-height: 1.6;
|
|
439
|
+
}
|
|
440
|
+
.card-footer {
|
|
441
|
+
margin-top: 16px;
|
|
442
|
+
padding-top: 12px;
|
|
443
|
+
border-top: 1px solid var(--df-color-border-subtle);
|
|
444
|
+
font-size: 10px;
|
|
445
|
+
color: var(--df-color-text-muted);
|
|
446
|
+
letter-spacing: 0.1em;
|
|
447
|
+
text-transform: uppercase;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/* ── Alerts ────────────────────────────────────────────────────────── */
|
|
451
|
+
.alert {
|
|
452
|
+
padding: 12px 16px;
|
|
453
|
+
border-left: 3px solid;
|
|
454
|
+
font-size: 12px;
|
|
455
|
+
margin-bottom: 12px;
|
|
456
|
+
display: flex;
|
|
457
|
+
align-items: center;
|
|
458
|
+
gap: 10px;
|
|
459
|
+
}
|
|
460
|
+
.alert-success { border-color: var(--df-color-state-success); background: color-mix(in srgb, var(--df-color-state-success) 6%, var(--df-color-bg-surface)); color: var(--df-color-state-success); }
|
|
461
|
+
.alert-error { border-color: var(--df-color-state-error); background: color-mix(in srgb, var(--df-color-state-error) 6%, var(--df-color-bg-surface)); color: var(--df-color-state-error); }
|
|
462
|
+
.alert-warning { border-color: var(--df-color-state-warning); background: color-mix(in srgb, var(--df-color-state-warning) 6%, var(--df-color-bg-surface)); color: var(--df-color-state-warning); }
|
|
463
|
+
.alert-info { border-color: var(--df-color-state-info); background: color-mix(in srgb, var(--df-color-state-info) 6%, var(--df-color-bg-surface)); color: var(--df-color-state-info); }
|
|
464
|
+
|
|
465
|
+
/* ── State indicators ──────────────────────────────────────────────── */
|
|
466
|
+
.state-grid {
|
|
467
|
+
display: grid;
|
|
468
|
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
469
|
+
gap: 8px;
|
|
470
|
+
}
|
|
471
|
+
.state-card {
|
|
472
|
+
background: var(--df-color-bg-surface);
|
|
473
|
+
border: 1px solid var(--df-color-border-default);
|
|
474
|
+
padding: 12px 16px;
|
|
475
|
+
display: flex;
|
|
476
|
+
align-items: center;
|
|
477
|
+
gap: 10px;
|
|
478
|
+
clip-path: var(--df-clip-sm);
|
|
479
|
+
}
|
|
480
|
+
.state-dot { width: 8px; height: 8px; border-radius: var(--df-radius-full); flex-shrink: 0; }
|
|
481
|
+
.state-name { font-size: 10px; letter-spacing: 0.15em; text-transform: uppercase; }
|
|
482
|
+
|
|
483
|
+
/* ── Animation demos ───────────────────────────────────────────────── */
|
|
484
|
+
.anim-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
|
|
485
|
+
.anim-card {
|
|
486
|
+
background: var(--df-color-bg-surface);
|
|
487
|
+
border: 1px solid var(--df-color-border-default);
|
|
488
|
+
padding: 28px 20px;
|
|
489
|
+
text-align: center;
|
|
490
|
+
font-size: 10px;
|
|
491
|
+
letter-spacing: 0.15em;
|
|
492
|
+
text-transform: uppercase;
|
|
493
|
+
color: var(--df-color-text-secondary);
|
|
494
|
+
position: relative; overflow: hidden;
|
|
495
|
+
clip-path: var(--df-clip-sm);
|
|
496
|
+
}
|
|
497
|
+
.anim-crt::after {
|
|
498
|
+
content: '';
|
|
499
|
+
position: absolute; inset: 0;
|
|
500
|
+
background: linear-gradient(to bottom, transparent 0%, rgba(126,231,135,0.03) 50%, transparent 100%);
|
|
501
|
+
background-size: 100% 40px;
|
|
502
|
+
animation: df-crt-sweep 4s linear infinite;
|
|
503
|
+
pointer-events: none;
|
|
504
|
+
}
|
|
505
|
+
.anim-glow { animation: df-glow-pulse 2s ease-in-out infinite; }
|
|
506
|
+
.anim-brackets { position: relative; }
|
|
507
|
+
.anim-brackets::before, .anim-brackets::after {
|
|
508
|
+
content: '';
|
|
509
|
+
position: absolute;
|
|
510
|
+
width: 12px; height: 12px;
|
|
511
|
+
border-color: var(--df-color-accent-default);
|
|
512
|
+
border-style: solid;
|
|
513
|
+
pointer-events: none;
|
|
514
|
+
}
|
|
515
|
+
.anim-brackets::before { top: 6px; left: 6px; border-width: 2px 0 0 2px; }
|
|
516
|
+
.anim-brackets::after { bottom: 6px; right: 6px; border-width: 0 2px 2px 0; }
|
|
517
|
+
.cursor-blink {
|
|
518
|
+
display: inline-block;
|
|
519
|
+
width: 8px; height: 14px;
|
|
520
|
+
background: var(--df-color-accent-default);
|
|
521
|
+
vertical-align: text-bottom;
|
|
522
|
+
animation: df-blink 1s step-start infinite;
|
|
523
|
+
margin-left: 2px;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/* Spring animation demo */
|
|
527
|
+
.spring-demo {
|
|
528
|
+
display: flex;
|
|
529
|
+
gap: 16px;
|
|
530
|
+
align-items: flex-end;
|
|
531
|
+
}
|
|
532
|
+
.spring-box {
|
|
533
|
+
width: 48px; height: 48px;
|
|
534
|
+
background: var(--df-color-accent-dim);
|
|
535
|
+
border: 1px solid var(--df-color-accent-muted);
|
|
536
|
+
border-radius: var(--df-radius-sm);
|
|
537
|
+
cursor: pointer;
|
|
538
|
+
transition: transform 500ms var(--df-easing-default);
|
|
539
|
+
}
|
|
540
|
+
.spring-box:hover { transform: scale(1.15); }
|
|
541
|
+
.spring-box[data-easing="spring"] {
|
|
542
|
+
transition-timing-function: var(--df-easing-spring);
|
|
543
|
+
}
|
|
544
|
+
.spring-box[data-easing="spring-bouncy"] {
|
|
545
|
+
transition-timing-function: var(--df-easing-spring-bouncy);
|
|
546
|
+
}
|
|
547
|
+
.spring-label {
|
|
548
|
+
font-size: 9px;
|
|
549
|
+
color: var(--df-color-text-muted);
|
|
550
|
+
text-align: center;
|
|
551
|
+
margin-top: 4px;
|
|
552
|
+
letter-spacing: 0.08em;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/* ── Focus demo ────────────────────────────────────────────────────── */
|
|
556
|
+
.focus-demo-row { display: flex; flex-wrap: wrap; gap: 16px; align-items: center; }
|
|
557
|
+
.focus-demo-btn {
|
|
558
|
+
font-family: var(--df-font-mono);
|
|
559
|
+
font-size: 11px;
|
|
560
|
+
letter-spacing: 0.12em;
|
|
561
|
+
text-transform: uppercase;
|
|
562
|
+
padding: 8px 16px;
|
|
563
|
+
background: var(--df-color-bg-raised);
|
|
564
|
+
border: 1px solid var(--df-color-border-default);
|
|
565
|
+
color: var(--df-color-text-primary);
|
|
566
|
+
cursor: pointer;
|
|
567
|
+
}
|
|
568
|
+
.focus-demo-btn:focus-visible {
|
|
569
|
+
outline: var(--df-focus-ring-width) solid var(--df-focus-ring-color);
|
|
570
|
+
outline-offset: var(--df-focus-ring-offset);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/* ── Code block ────────────────────────────────────────────────────── */
|
|
574
|
+
pre {
|
|
575
|
+
background: var(--df-color-bg-sunken);
|
|
576
|
+
border: 1px solid var(--df-color-border-default);
|
|
577
|
+
border-left: 2px solid var(--df-color-accent-default);
|
|
578
|
+
padding: 16px 20px;
|
|
579
|
+
overflow-x: auto;
|
|
580
|
+
font-size: 11px;
|
|
581
|
+
line-height: 1.7;
|
|
582
|
+
color: var(--df-color-text-primary);
|
|
583
|
+
margin-top: 16px;
|
|
584
|
+
border-radius: 0 var(--df-radius-sm) var(--df-radius-sm) 0;
|
|
585
|
+
}
|
|
586
|
+
code { font-family: var(--df-font-mono); }
|
|
587
|
+
.c-comment { color: var(--df-color-text-muted); }
|
|
588
|
+
.c-key { color: var(--df-color-accent-default); }
|
|
589
|
+
.c-val { color: var(--df-color-accent-bright); }
|
|
590
|
+
.c-str { color: var(--df-color-state-success); }
|
|
591
|
+
.c-punct { color: var(--df-color-text-secondary); }
|
|
592
|
+
.c-fn { color: var(--df-color-state-info); }
|
|
593
|
+
|
|
594
|
+
/* ── Table ─────────────────────────────────────────────────────────── */
|
|
595
|
+
table { width: 100%; border-collapse: collapse; font-size: 11px; }
|
|
596
|
+
th, td { text-align: left; padding: 8px 12px; border-bottom: 1px solid var(--df-color-border-subtle); }
|
|
597
|
+
th { font-size: 9px; letter-spacing: 0.2em; text-transform: uppercase; color: var(--df-color-text-secondary); }
|
|
598
|
+
tr:hover td { background: var(--df-color-bg-raised); }
|
|
599
|
+
td code { color: var(--df-color-accent-default); font-size: 10px; }
|
|
600
|
+
td .swatch-inline { display: inline-block; width: 12px; height: 12px; border-radius: 2px; vertical-align: middle; margin-right: 6px; }
|
|
601
|
+
|
|
602
|
+
/* ── Token search ──────────────────────────────────────────────────── */
|
|
603
|
+
.token-search {
|
|
604
|
+
background: var(--df-color-bg-surface);
|
|
605
|
+
border: 1px solid var(--df-color-border-default);
|
|
606
|
+
color: var(--df-color-text-primary);
|
|
607
|
+
font-family: var(--df-font-mono);
|
|
608
|
+
font-size: 12px;
|
|
609
|
+
padding: 8px 12px;
|
|
610
|
+
width: 100%;
|
|
611
|
+
max-width: 400px;
|
|
612
|
+
outline: none;
|
|
613
|
+
margin-bottom: 16px;
|
|
614
|
+
border-radius: var(--df-radius-sm);
|
|
615
|
+
}
|
|
616
|
+
.token-search:focus {
|
|
617
|
+
border-color: var(--df-color-accent-default);
|
|
618
|
+
box-shadow: 0 0 8px color-mix(in srgb, var(--df-color-accent-default) 20%, transparent);
|
|
619
|
+
}
|
|
620
|
+
.token-search::placeholder { color: var(--df-color-text-muted); }
|
|
621
|
+
|
|
622
|
+
/* ── Opacity demos ─────────────────────────────────────────────────── */
|
|
623
|
+
.opacity-grid {
|
|
624
|
+
display: flex;
|
|
625
|
+
gap: 8px;
|
|
626
|
+
flex-wrap: wrap;
|
|
627
|
+
}
|
|
628
|
+
.opacity-demo {
|
|
629
|
+
width: 64px; height: 48px;
|
|
630
|
+
background: var(--df-color-accent-default);
|
|
631
|
+
display: flex;
|
|
632
|
+
align-items: center;
|
|
633
|
+
justify-content: center;
|
|
634
|
+
font-size: 10px;
|
|
635
|
+
color: var(--df-color-text-inverse);
|
|
636
|
+
border-radius: var(--df-radius-xs);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/* ── Architecture diagram ──────────────────────────────────────────── */
|
|
640
|
+
.arch-layers {
|
|
641
|
+
display: flex;
|
|
642
|
+
flex-direction: column;
|
|
643
|
+
gap: 4px;
|
|
644
|
+
max-width: 500px;
|
|
645
|
+
}
|
|
646
|
+
.arch-layer {
|
|
647
|
+
padding: 10px 16px;
|
|
648
|
+
font-size: 10px;
|
|
649
|
+
letter-spacing: 0.12em;
|
|
650
|
+
text-transform: uppercase;
|
|
651
|
+
display: flex;
|
|
652
|
+
justify-content: space-between;
|
|
653
|
+
align-items: center;
|
|
654
|
+
}
|
|
655
|
+
.arch-layer-priority {
|
|
656
|
+
font-size: 9px;
|
|
657
|
+
color: var(--df-color-text-muted);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/* ── Helpers ───────────────────────────────────────────────────────── */
|
|
661
|
+
.text-accent { color: var(--df-color-accent-default); }
|
|
662
|
+
.text-muted { color: var(--df-color-text-secondary); }
|
|
663
|
+
.text-dim { color: var(--df-color-text-muted); }
|
|
664
|
+
.text-success { color: var(--df-color-state-success); }
|
|
665
|
+
.text-error { color: var(--df-color-state-error); }
|
|
666
|
+
.text-info { color: var(--df-color-state-info); }
|
|
667
|
+
.inline-code {
|
|
668
|
+
background: var(--df-color-bg-raised);
|
|
669
|
+
padding: 1px 6px;
|
|
670
|
+
font-size: 11px;
|
|
671
|
+
color: var(--df-color-accent-default);
|
|
672
|
+
border-radius: var(--df-radius-xs);
|
|
673
|
+
}
|
|
674
|
+
hr {
|
|
675
|
+
border: none;
|
|
676
|
+
border-top: 1px solid var(--df-color-border-subtle);
|
|
677
|
+
margin: 8px 0 24px;
|
|
678
|
+
}
|
|
679
|
+
.flex-row { display: flex; flex-wrap: wrap; gap: 12px; }
|
|
680
|
+
.flex-col { display: flex; flex-direction: column; gap: 12px; }
|
|
681
|
+
|
|
682
|
+
/* ── Spinner demo ──────────────────────────────────────────────────── */
|
|
683
|
+
.df-spinner-demo {
|
|
684
|
+
width: 20px; height: 20px;
|
|
685
|
+
border: 2px solid var(--df-color-border-default);
|
|
686
|
+
border-top-color: var(--df-color-accent-default);
|
|
687
|
+
border-radius: var(--df-radius-full);
|
|
688
|
+
animation: df-spin 0.6s linear infinite;
|
|
689
|
+
display: inline-block;
|
|
690
|
+
}
|
|
691
|
+
</style>
|
|
692
|
+
</head>
|
|
693
|
+
<body>
|
|
694
|
+
<div class="page">
|
|
695
|
+
|
|
696
|
+
<!-- ══════ Hero ══════ -->
|
|
697
|
+
<header class="hero">
|
|
698
|
+
<h1>Devglide Design System</h1>
|
|
699
|
+
<div class="sub">v2.0 — Modern CSS architecture with @layer, OKLCH awareness, spring physics, and WCAG 2.2 focus patterns</div>
|
|
700
|
+
<div class="version">@devglide/design-tokens</div>
|
|
701
|
+
<div class="stats">
|
|
702
|
+
<div class="stat"><strong id="token-count">143</strong>Design tokens</div>
|
|
703
|
+
<div class="stat"><strong>5</strong>Color scales</div>
|
|
704
|
+
<div class="stat"><strong>4</strong>CSS layers</div>
|
|
705
|
+
<div class="stat"><strong>4</strong>Output formats</div>
|
|
706
|
+
</div>
|
|
707
|
+
</header>
|
|
708
|
+
|
|
709
|
+
<!-- ══════ Nav ══════ -->
|
|
710
|
+
<nav class="nav" id="nav">
|
|
711
|
+
<a href="#oklch">OKLCH</a>
|
|
712
|
+
<a href="#primitives">Primitives</a>
|
|
713
|
+
<a href="#colors">Colors</a>
|
|
714
|
+
<a href="#typography">Typography</a>
|
|
715
|
+
<a href="#spacing">Spacing</a>
|
|
716
|
+
<a href="#shapes">Shapes</a>
|
|
717
|
+
<a href="#shadows">Shadows</a>
|
|
718
|
+
<a href="#states">States</a>
|
|
719
|
+
<a href="#buttons">Buttons</a>
|
|
720
|
+
<a href="#inputs">Inputs</a>
|
|
721
|
+
<a href="#badges">Badges</a>
|
|
722
|
+
<a href="#cards">Cards</a>
|
|
723
|
+
<a href="#alerts">Alerts</a>
|
|
724
|
+
<a href="#motion">Motion</a>
|
|
725
|
+
<a href="#accessibility">A11y</a>
|
|
726
|
+
<a href="#architecture">@layer</a>
|
|
727
|
+
<a href="#tokens">Tokens</a>
|
|
728
|
+
</nav>
|
|
729
|
+
|
|
730
|
+
<!-- ══════ 01 / OKLCH Interactive ══════ -->
|
|
731
|
+
<section class="section" id="oklch">
|
|
732
|
+
<div class="section-title">01 / OKLCH Color Exploration</div>
|
|
733
|
+
<p class="section-desc">
|
|
734
|
+
OKLCH (Oklch Lightness-Chroma-Hue) is a perceptually uniform color space.
|
|
735
|
+
Adjusting the hue rotates the entire accent color while maintaining the same perceived brightness and saturation.
|
|
736
|
+
This is the foundation for building adaptive, themeable design systems.
|
|
737
|
+
</p>
|
|
738
|
+
|
|
739
|
+
<div class="hue-control">
|
|
740
|
+
<label>Accent hue rotation <span class="text-dim">(OKLCH hue 0-360)</span></label>
|
|
741
|
+
<div class="hue-row">
|
|
742
|
+
<input type="range" min="0" max="360" value="150" id="hue-slider" />
|
|
743
|
+
<div class="hue-preview" id="hue-preview" style="background: oklch(0.83 0.18 150)"></div>
|
|
744
|
+
<div class="hue-value" id="hue-value">150</div>
|
|
745
|
+
</div>
|
|
746
|
+
<div class="hue-note">
|
|
747
|
+
Default hue: 150 (green). Try 0 (red), 60 (amber), 210 (blue), 280 (violet).
|
|
748
|
+
The production tokens use hex values for maximum browser compatibility. This demo shows the OKLCH-powered approach for future adoption.
|
|
749
|
+
</div>
|
|
750
|
+
</div>
|
|
751
|
+
|
|
752
|
+
<div id="oklch-swatches" class="swatch-grid swatch-grid-wide" style="margin-bottom:16px"></div>
|
|
753
|
+
|
|
754
|
+
<pre><code><span class="c-comment">/* Define accent with OKLCH — adjust hue to re-theme everything */</span>
|
|
755
|
+
<span class="c-key">@property</span> <span class="c-val">--df-hue</span> <span class="c-punct">{</span>
|
|
756
|
+
<span class="c-key">syntax</span>: <span class="c-str">'<number>'</span>;
|
|
757
|
+
<span class="c-key">initial-value</span>: <span class="c-val">150</span>;
|
|
758
|
+
<span class="c-key">inherits</span>: <span class="c-val">true</span>;
|
|
759
|
+
<span class="c-punct">}</span>
|
|
760
|
+
<span class="c-key">:root</span> <span class="c-punct">{</span>
|
|
761
|
+
<span class="c-key">--accent</span>: <span class="c-fn">oklch</span>(<span class="c-val">0.83 0.18</span> <span class="c-fn">var</span>(<span class="c-val">--df-hue</span>));
|
|
762
|
+
<span class="c-punct">}</span></code></pre>
|
|
763
|
+
</section>
|
|
764
|
+
|
|
765
|
+
<!-- ══════ 02 / Primitive Palette ══════ -->
|
|
766
|
+
<section class="section" id="primitives">
|
|
767
|
+
<div class="section-title">02 / Primitive Palette</div>
|
|
768
|
+
<p class="section-desc">
|
|
769
|
+
Raw color scales organized by hue family. Primitives are the foundation from which semantic tokens are derived.
|
|
770
|
+
13-step neutral scale + 4 chromatic scales (green, red, amber, blue).
|
|
771
|
+
</p>
|
|
772
|
+
|
|
773
|
+
<div class="group-label">Neutral (0-12)</div>
|
|
774
|
+
<div id="neutral-swatches" class="swatch-grid swatch-grid-wide"></div>
|
|
775
|
+
|
|
776
|
+
<div class="group-label">Green (1-9)</div>
|
|
777
|
+
<div id="green-swatches" class="swatch-grid swatch-grid-wide"></div>
|
|
778
|
+
|
|
779
|
+
<div class="group-label">Red (1-6)</div>
|
|
780
|
+
<div id="red-swatches" class="swatch-grid swatch-grid-wide"></div>
|
|
781
|
+
|
|
782
|
+
<div class="group-label">Amber (1-6)</div>
|
|
783
|
+
<div id="amber-swatches" class="swatch-grid swatch-grid-wide"></div>
|
|
784
|
+
|
|
785
|
+
<div class="group-label">Blue (1-5)</div>
|
|
786
|
+
<div id="blue-swatches" class="swatch-grid swatch-grid-wide"></div>
|
|
787
|
+
</section>
|
|
788
|
+
|
|
789
|
+
<!-- ══════ 03 / Semantic Colors ══════ -->
|
|
790
|
+
<section class="section" id="colors">
|
|
791
|
+
<div class="section-title">03 / Semantic Colors</div>
|
|
792
|
+
<p class="section-desc">
|
|
793
|
+
Semantic tokens map primitives to UI roles. Apps reference these — never primitives directly.
|
|
794
|
+
This indirection enables theme switching without touching component code.
|
|
795
|
+
</p>
|
|
796
|
+
|
|
797
|
+
<div class="group-label">Backgrounds</div>
|
|
798
|
+
<div class="swatch-grid">
|
|
799
|
+
<div class="swatch" style="background:var(--df-color-bg-sunken);border:1px solid var(--df-color-border-default)"><span class="swatch-label">bg-sunken</span><span class="swatch-hex" data-var="--df-color-bg-sunken"></span></div>
|
|
800
|
+
<div class="swatch" style="background:var(--df-color-bg-base);border:1px solid var(--df-color-border-default)"><span class="swatch-label">bg-base</span><span class="swatch-hex" data-var="--df-color-bg-base"></span></div>
|
|
801
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)"><span class="swatch-label">bg-surface</span><span class="swatch-hex" data-var="--df-color-bg-surface"></span></div>
|
|
802
|
+
<div class="swatch" style="background:var(--df-color-bg-raised);border:1px solid var(--df-color-border-default)"><span class="swatch-label">bg-raised</span><span class="swatch-hex" data-var="--df-color-bg-raised"></span></div>
|
|
803
|
+
<div class="swatch" style="background:var(--df-color-bg-overlay);border:1px solid var(--df-color-border-default)"><span class="swatch-label">bg-overlay</span><span class="swatch-hex" data-var="--df-color-bg-overlay"></span></div>
|
|
804
|
+
</div>
|
|
805
|
+
|
|
806
|
+
<div class="group-label">Accent Scale</div>
|
|
807
|
+
<div class="swatch-grid">
|
|
808
|
+
<div class="swatch" style="background:var(--df-color-accent-subtle);border:1px solid var(--df-color-border-default)"><span class="swatch-label">accent-subtle</span><span class="swatch-hex" data-var="--df-color-accent-subtle"></span></div>
|
|
809
|
+
<div class="swatch" style="background:var(--df-color-accent-dim);border:1px solid var(--df-color-border-default)"><span class="swatch-label">accent-dim</span><span class="swatch-hex" data-var="--df-color-accent-dim"></span></div>
|
|
810
|
+
<div class="swatch" style="background:var(--df-color-accent-muted);border:1px solid var(--df-color-border-default)"><span class="swatch-label">accent-muted</span><span class="swatch-hex" data-var="--df-color-accent-muted"></span></div>
|
|
811
|
+
<div class="swatch" style="background:var(--df-color-accent-default);border:1px solid var(--df-color-accent-default)"><span class="swatch-label" style="color:var(--df-color-text-inverse)">accent-default</span><span class="swatch-hex" style="color:var(--df-color-text-inverse)" data-var="--df-color-accent-default"></span></div>
|
|
812
|
+
<div class="swatch" style="background:var(--df-color-accent-bright);border:1px solid var(--df-color-accent-bright)"><span class="swatch-label" style="color:var(--df-color-text-inverse)">accent-bright</span><span class="swatch-hex" style="color:var(--df-color-text-inverse)" data-var="--df-color-accent-bright"></span></div>
|
|
813
|
+
</div>
|
|
814
|
+
|
|
815
|
+
<div class="group-label">Text</div>
|
|
816
|
+
<div class="swatch-grid">
|
|
817
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)">
|
|
818
|
+
<span style="color:var(--df-color-text-primary)">Primary text</span><span class="swatch-hex" data-var="--df-color-text-primary"></span>
|
|
819
|
+
</div>
|
|
820
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)">
|
|
821
|
+
<span style="color:var(--df-color-text-secondary)">Secondary text</span><span class="swatch-hex" data-var="--df-color-text-secondary"></span>
|
|
822
|
+
</div>
|
|
823
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)">
|
|
824
|
+
<span style="color:var(--df-color-text-muted)">Muted text</span><span class="swatch-hex" data-var="--df-color-text-muted"></span>
|
|
825
|
+
</div>
|
|
826
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)">
|
|
827
|
+
<span style="color:var(--df-color-text-accent)">Accent text</span><span class="swatch-hex" data-var="--df-color-text-accent"></span>
|
|
828
|
+
</div>
|
|
829
|
+
<div class="swatch" style="background:var(--df-color-bg-surface);border:1px solid var(--df-color-border-default)">
|
|
830
|
+
<span style="color:var(--df-color-text-link)">Link text</span><span class="swatch-hex" data-var="--df-color-text-link"></span>
|
|
831
|
+
</div>
|
|
832
|
+
</div>
|
|
833
|
+
|
|
834
|
+
<div class="group-label">State Colors</div>
|
|
835
|
+
<div class="swatch-grid">
|
|
836
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-idle) 15%, transparent);border:1px solid var(--df-color-state-idle)"><span class="swatch-label" style="color:var(--df-color-state-idle)">idle</span><span class="swatch-hex" style="color:var(--df-color-state-idle)" data-var="--df-color-state-idle"></span></div>
|
|
837
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-success) 15%, transparent);border:1px solid var(--df-color-state-success)"><span class="swatch-label" style="color:var(--df-color-state-success)">success</span><span class="swatch-hex" style="color:var(--df-color-state-success)" data-var="--df-color-state-success"></span></div>
|
|
838
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-error) 15%, transparent);border:1px solid var(--df-color-state-error)"><span class="swatch-label" style="color:var(--df-color-state-error)">error</span><span class="swatch-hex" style="color:var(--df-color-state-error)" data-var="--df-color-state-error"></span></div>
|
|
839
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-warning) 15%, transparent);border:1px solid var(--df-color-state-warning)"><span class="swatch-label" style="color:var(--df-color-state-warning)">warning</span><span class="swatch-hex" style="color:var(--df-color-state-warning)" data-var="--df-color-state-warning"></span></div>
|
|
840
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-info) 15%, transparent);border:1px solid var(--df-color-state-info)"><span class="swatch-label" style="color:var(--df-color-state-info)">info</span><span class="swatch-hex" style="color:var(--df-color-state-info)" data-var="--df-color-state-info"></span></div>
|
|
841
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-recording) 15%, transparent);border:1px solid var(--df-color-state-recording)"><span class="swatch-label" style="color:var(--df-color-state-recording)">recording</span><span class="swatch-hex" style="color:var(--df-color-state-recording)" data-var="--df-color-state-recording"></span></div>
|
|
842
|
+
<div class="swatch" style="background:color-mix(in srgb, var(--df-color-state-processing) 15%, transparent);border:1px solid var(--df-color-state-processing)"><span class="swatch-label" style="color:var(--df-color-state-processing)">processing</span><span class="swatch-hex" style="color:var(--df-color-state-processing)" data-var="--df-color-state-processing"></span></div>
|
|
843
|
+
</div>
|
|
844
|
+
|
|
845
|
+
<div class="group-label">Borders</div>
|
|
846
|
+
<div class="swatch-grid">
|
|
847
|
+
<div class="swatch" style="background:var(--df-color-bg-base);border:2px solid var(--df-color-border-subtle)"><span class="swatch-label">border-subtle</span><span class="swatch-hex" data-var="--df-color-border-subtle"></span></div>
|
|
848
|
+
<div class="swatch" style="background:var(--df-color-bg-base);border:2px solid var(--df-color-border-default)"><span class="swatch-label">border-default</span><span class="swatch-hex" data-var="--df-color-border-default"></span></div>
|
|
849
|
+
<div class="swatch" style="background:var(--df-color-bg-base);border:2px solid var(--df-color-border-strong)"><span class="swatch-label">border-strong</span><span class="swatch-hex" data-var="--df-color-border-strong"></span></div>
|
|
850
|
+
<div class="swatch" style="background:var(--df-color-bg-base);border:2px solid var(--df-color-border-accent)"><span class="swatch-label">border-accent</span><span class="swatch-hex" data-var="--df-color-border-accent"></span></div>
|
|
851
|
+
</div>
|
|
852
|
+
</section>
|
|
853
|
+
|
|
854
|
+
<!-- ══════ 04 / Typography ══════ -->
|
|
855
|
+
<section class="section" id="typography">
|
|
856
|
+
<div class="section-title">04 / Typography</div>
|
|
857
|
+
<p class="section-desc">
|
|
858
|
+
Three font stacks: <span class="inline-code">mono</span> (Courier New) for terminal UI,
|
|
859
|
+
<span class="inline-code">ui</span> (system-ui) for body copy,
|
|
860
|
+
<span class="inline-code">display</span> (Inter Variable) for marketing/headings.
|
|
861
|
+
Uppercase labels with wide letter-spacing define the design language.
|
|
862
|
+
</p>
|
|
863
|
+
|
|
864
|
+
<div class="type-sample"><div class="type-meta">3xl / 36px</div><div class="type-specimen" style="font-size:36px;letter-spacing:0.2em;text-transform:uppercase;color:var(--df-color-accent-default)">DEVGLIDE</div></div>
|
|
865
|
+
<div class="type-sample"><div class="type-meta">2xl / 28px</div><div class="type-specimen" style="font-size:28px;letter-spacing:0.2em;text-transform:uppercase">System Ready</div></div>
|
|
866
|
+
<div class="type-sample"><div class="type-meta">xl / 20px</div><div class="type-specimen" style="font-size:20px;letter-spacing:0.15em;text-transform:uppercase">Project Title</div></div>
|
|
867
|
+
<div class="type-sample"><div class="type-meta">lg / 16px</div><div class="type-specimen" style="font-size:16px;letter-spacing:0.12em">Section heading — all caps labels</div></div>
|
|
868
|
+
<div class="type-sample"><div class="type-meta">md / 13px</div><div class="type-specimen" style="font-size:13px;letter-spacing:0.05em">Body text — readable paragraph copy. Terminal output and log lines.</div></div>
|
|
869
|
+
<div class="type-sample"><div class="type-meta">sm / 12px</div><div class="type-specimen" style="font-size:12px;letter-spacing:0.05em">Small text — metadata, timestamps, labels.</div></div>
|
|
870
|
+
<div class="type-sample"><div class="type-meta">xs / 10px</div><div class="type-specimen" style="font-size:10px;letter-spacing:0.2em;text-transform:uppercase">XS — badges, captions, section headers</div></div>
|
|
871
|
+
|
|
872
|
+
<div class="subsection">
|
|
873
|
+
<div class="group-label">Letter Spacing Scale</div>
|
|
874
|
+
<div style="display:flex;flex-direction:column;gap:8px;margin-top:8px">
|
|
875
|
+
<div style="font-size:12px;letter-spacing:0">Tight (0) — terminal output, code</div>
|
|
876
|
+
<div style="font-size:12px;letter-spacing:0.05em">Normal (0.05em) — body text</div>
|
|
877
|
+
<div style="font-size:12px;letter-spacing:0.12em">Wide (0.12em) — labels, sub-headings</div>
|
|
878
|
+
<div style="font-size:12px;letter-spacing:0.2em;text-transform:uppercase">Wider (0.2em) — section titles, badges</div>
|
|
879
|
+
</div>
|
|
880
|
+
</div>
|
|
881
|
+
</section>
|
|
882
|
+
|
|
883
|
+
<!-- ══════ 05 / Spacing ══════ -->
|
|
884
|
+
<section class="section" id="spacing">
|
|
885
|
+
<div class="section-title">05 / Spacing</div>
|
|
886
|
+
<p class="section-desc">4px base unit. 13 steps from 1px to 96px. Use the scale consistently for padding, margins, and gaps.</p>
|
|
887
|
+
<div>
|
|
888
|
+
<div class="space-row"><div class="space-bar" style="width:1px"></div><div class="space-meta">px — 1px</div></div>
|
|
889
|
+
<div class="space-row"><div class="space-bar" style="width:4px"></div><div class="space-meta">1 — 4px</div></div>
|
|
890
|
+
<div class="space-row"><div class="space-bar" style="width:8px"></div><div class="space-meta">2 — 8px</div></div>
|
|
891
|
+
<div class="space-row"><div class="space-bar" style="width:12px"></div><div class="space-meta">3 — 12px</div></div>
|
|
892
|
+
<div class="space-row"><div class="space-bar" style="width:16px"></div><div class="space-meta">4 — 16px</div></div>
|
|
893
|
+
<div class="space-row"><div class="space-bar" style="width:20px"></div><div class="space-meta">5 — 20px</div></div>
|
|
894
|
+
<div class="space-row"><div class="space-bar" style="width:24px"></div><div class="space-meta">6 — 24px</div></div>
|
|
895
|
+
<div class="space-row"><div class="space-bar" style="width:32px"></div><div class="space-meta">8 — 32px</div></div>
|
|
896
|
+
<div class="space-row"><div class="space-bar" style="width:40px"></div><div class="space-meta">10 — 40px</div></div>
|
|
897
|
+
<div class="space-row"><div class="space-bar" style="width:48px"></div><div class="space-meta">12 — 48px</div></div>
|
|
898
|
+
<div class="space-row"><div class="space-bar" style="width:64px"></div><div class="space-meta">16 — 64px</div></div>
|
|
899
|
+
<div class="space-row"><div class="space-bar" style="width:80px"></div><div class="space-meta">20 — 80px</div></div>
|
|
900
|
+
<div class="space-row"><div class="space-bar" style="width:96px"></div><div class="space-meta">24 — 96px</div></div>
|
|
901
|
+
</div>
|
|
902
|
+
</section>
|
|
903
|
+
|
|
904
|
+
<!-- ══════ 06 / Shapes (Radius + Clips) ══════ -->
|
|
905
|
+
<section class="section" id="shapes">
|
|
906
|
+
<div class="section-title">06 / Shapes — Radius & Clip Panels</div>
|
|
907
|
+
<p class="section-desc">
|
|
908
|
+
Two shape systems: standard <span class="inline-code">border-radius</span> for rounded elements,
|
|
909
|
+
and angular <span class="inline-code">clip-path</span> bevels for the signature Devglide aesthetic.
|
|
910
|
+
</p>
|
|
911
|
+
|
|
912
|
+
<div class="group-label">Border Radius</div>
|
|
913
|
+
<div class="shape-grid">
|
|
914
|
+
<div class="shape-demo" style="border-radius:0">none<br><span class="text-dim" style="font-size:9px">0</span></div>
|
|
915
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-xs)">xs<br><span class="text-dim" style="font-size:9px">2px</span></div>
|
|
916
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-sm)">sm<br><span class="text-dim" style="font-size:9px">4px</span></div>
|
|
917
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-md)">md<br><span class="text-dim" style="font-size:9px">6px</span></div>
|
|
918
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-lg)">lg<br><span class="text-dim" style="font-size:9px">8px</span></div>
|
|
919
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-xl)">xl<br><span class="text-dim" style="font-size:9px">12px</span></div>
|
|
920
|
+
<div class="shape-demo" style="border-radius:var(--df-radius-full);width:80px;height:80px;display:flex;align-items:center;justify-content:center">full<br><span class="text-dim" style="font-size:9px">pill</span></div>
|
|
921
|
+
</div>
|
|
922
|
+
|
|
923
|
+
<div class="group-label" style="margin-top:32px">Angular Clip Panels</div>
|
|
924
|
+
<div class="shape-grid">
|
|
925
|
+
<div class="shape-demo" style="clip-path:var(--df-clip-sm)">clip-sm<br><span class="text-dim" style="font-size:9px">8px bevel</span></div>
|
|
926
|
+
<div class="shape-demo" style="clip-path:var(--df-clip-md);border-color:var(--df-color-accent-dim)">clip-md<br><span class="text-dim" style="font-size:9px">12px bevel</span></div>
|
|
927
|
+
<div class="shape-demo" style="clip-path:var(--df-clip-lg);border-color:var(--df-color-accent-muted)">clip-lg<br><span class="text-dim" style="font-size:9px">16px bevel</span></div>
|
|
928
|
+
<div class="shape-demo" style="clip-path:var(--df-clip-xl);border-color:var(--df-color-accent-default);color:var(--df-color-accent-default)">clip-xl<br><span style="font-size:9px">24px bevel</span></div>
|
|
929
|
+
</div>
|
|
930
|
+
</section>
|
|
931
|
+
|
|
932
|
+
<!-- ══════ 07 / Shadows & Glows ══════ -->
|
|
933
|
+
<section class="section" id="shadows">
|
|
934
|
+
<div class="section-title">07 / Shadows & Glows</div>
|
|
935
|
+
<p class="section-desc">Dark-optimized shadows with high opacity for visibility on dark backgrounds. Accent glows for interactive state feedback.</p>
|
|
936
|
+
|
|
937
|
+
<div class="group-label">Shadows</div>
|
|
938
|
+
<div class="shadow-grid">
|
|
939
|
+
<div class="shadow-demo" style="box-shadow:var(--df-shadow-sm)">shadow-sm</div>
|
|
940
|
+
<div class="shadow-demo" style="box-shadow:var(--df-shadow-md)">shadow-md</div>
|
|
941
|
+
<div class="shadow-demo" style="box-shadow:var(--df-shadow-lg)">shadow-lg</div>
|
|
942
|
+
<div class="shadow-demo" style="box-shadow:var(--df-shadow-xl)">shadow-xl</div>
|
|
943
|
+
</div>
|
|
944
|
+
|
|
945
|
+
<div class="group-label">Glows</div>
|
|
946
|
+
<div class="shadow-grid">
|
|
947
|
+
<div class="shadow-demo" style="box-shadow:var(--df-glow-accent);border-color:var(--df-color-accent-dim)">glow-accent</div>
|
|
948
|
+
<div class="shadow-demo" style="box-shadow:var(--df-glow-accent-strong);border-color:var(--df-color-accent-muted)">glow-accent-strong</div>
|
|
949
|
+
<div class="shadow-demo" style="box-shadow:var(--df-glow-error);border-color:color-mix(in srgb, var(--df-color-state-error) 40%, transparent)">glow-error</div>
|
|
950
|
+
<div class="shadow-demo" style="box-shadow:var(--df-glow-success);border-color:color-mix(in srgb, var(--df-color-state-success) 40%, transparent)">glow-success</div>
|
|
951
|
+
<div class="shadow-demo" style="box-shadow:var(--df-glow-processing);border-color:color-mix(in srgb, var(--df-color-state-processing) 40%, transparent)">glow-processing</div>
|
|
952
|
+
</div>
|
|
953
|
+
|
|
954
|
+
<div class="group-label">Opacity Scale</div>
|
|
955
|
+
<div class="opacity-grid">
|
|
956
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-5)">5%</div><div class="spring-label">0.05</div></div>
|
|
957
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-10)">10%</div><div class="spring-label">0.1</div></div>
|
|
958
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-20)">20%</div><div class="spring-label">0.2</div></div>
|
|
959
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-40)">40%</div><div class="spring-label">0.4</div></div>
|
|
960
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-60)">60%</div><div class="spring-label">0.6</div></div>
|
|
961
|
+
<div><div class="opacity-demo" style="opacity:var(--df-opacity-80)">80%</div><div class="spring-label">0.8</div></div>
|
|
962
|
+
</div>
|
|
963
|
+
</section>
|
|
964
|
+
|
|
965
|
+
<!-- ══════ 08 / States ══════ -->
|
|
966
|
+
<section class="section" id="states">
|
|
967
|
+
<div class="section-title">08 / State System</div>
|
|
968
|
+
<p class="section-desc">Eight states with distinct colors and glow values. Used for UI elements reflecting system or recording status.</p>
|
|
969
|
+
<div class="state-grid">
|
|
970
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-idle);box-shadow:0 0 6px var(--df-color-state-idle)"></div><div><div class="state-name" style="color:var(--df-color-state-idle)">Idle</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-idle"></div></div></div>
|
|
971
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-active);box-shadow:0 0 6px var(--df-color-state-active)"></div><div><div class="state-name" style="color:var(--df-color-state-active)">Active</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-active"></div></div></div>
|
|
972
|
+
<div class="state-card" style="animation:df-alert-pulse 1.2s ease-in-out infinite"><div class="state-dot" style="background:var(--df-color-state-recording);box-shadow:0 0 8px var(--df-color-state-recording)"></div><div><div class="state-name" style="color:var(--df-color-state-recording)">Recording</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em"><span data-var="--df-color-state-recording"></span> · pulsing</div></div></div>
|
|
973
|
+
<div class="state-card" style="animation:df-processing-pulse 2s ease-in-out infinite"><div class="state-dot" style="background:var(--df-color-state-processing);box-shadow:0 0 6px var(--df-color-state-processing)"></div><div><div class="state-name" style="color:var(--df-color-state-processing)">Processing</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-processing"></div></div></div>
|
|
974
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-success);box-shadow:0 0 6px var(--df-color-state-success)"></div><div><div class="state-name" style="color:var(--df-color-state-success)">Success</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-success"></div></div></div>
|
|
975
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-error);box-shadow:0 0 6px var(--df-color-state-error)"></div><div><div class="state-name" style="color:var(--df-color-state-error)">Error</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-error"></div></div></div>
|
|
976
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-warning);box-shadow:0 0 6px var(--df-color-state-warning)"></div><div><div class="state-name" style="color:var(--df-color-state-warning)">Warning</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-warning"></div></div></div>
|
|
977
|
+
<div class="state-card"><div class="state-dot" style="background:var(--df-color-state-info);box-shadow:0 0 6px var(--df-color-state-info)"></div><div><div class="state-name" style="color:var(--df-color-state-info)">Info</div><div style="font-size:9px;color:var(--df-color-text-muted);letter-spacing:0.1em" data-var="--df-color-state-info"></div></div></div>
|
|
978
|
+
</div>
|
|
979
|
+
</section>
|
|
980
|
+
|
|
981
|
+
<!-- ══════ 09 / Buttons ══════ -->
|
|
982
|
+
<section class="section" id="buttons">
|
|
983
|
+
<div class="section-title">09 / Buttons</div>
|
|
984
|
+
<p class="section-desc">Angular clip-path on interactive buttons. Spring physics easing on hover transitions. Four variants: primary, outline, ghost, danger.</p>
|
|
985
|
+
<div class="btn-row">
|
|
986
|
+
<button class="btn btn-primary">Execute</button>
|
|
987
|
+
<button class="btn btn-outline">Cancel</button>
|
|
988
|
+
<button class="btn btn-ghost">Details</button>
|
|
989
|
+
<button class="btn btn-danger">Destroy</button>
|
|
990
|
+
<button class="btn btn-primary" disabled>Disabled</button>
|
|
991
|
+
</div>
|
|
992
|
+
<pre><code><span class="c-comment">/* Spring-eased transitions on buttons */</span>
|
|
993
|
+
<span class="c-key">.btn</span> <span class="c-punct">{</span>
|
|
994
|
+
<span class="c-key">transition</span>: <span class="c-val">all var(--df-duration-base) var(--df-easing-spring)</span>;
|
|
995
|
+
<span class="c-key">clip-path</span>: <span class="c-val">var(--df-clip-sm)</span>;
|
|
996
|
+
<span class="c-punct">}</span>
|
|
997
|
+
<span class="c-key">.btn:focus-visible</span> <span class="c-punct">{</span>
|
|
998
|
+
<span class="c-key">outline</span>: <span class="c-val">var(--df-focus-ring-width) solid var(--df-focus-ring-color)</span>;
|
|
999
|
+
<span class="c-key">outline-offset</span>: <span class="c-val">var(--df-focus-ring-offset)</span>;
|
|
1000
|
+
<span class="c-punct">}</span></code></pre>
|
|
1001
|
+
</section>
|
|
1002
|
+
|
|
1003
|
+
<!-- ══════ 10 / Inputs ══════ -->
|
|
1004
|
+
<section class="section" id="inputs">
|
|
1005
|
+
<div class="section-title">10 / Inputs</div>
|
|
1006
|
+
<p class="section-desc">Two styles: angular clip-path (default) and rounded. Accent focus glow with <span class="inline-code">color-mix()</span> for theme-aware transparency.</p>
|
|
1007
|
+
<div class="flex-row">
|
|
1008
|
+
<div class="input-group">
|
|
1009
|
+
<label class="input-label">Angular (default)</label>
|
|
1010
|
+
<input class="input" type="text" placeholder="Search issues..." />
|
|
1011
|
+
</div>
|
|
1012
|
+
<div class="input-group">
|
|
1013
|
+
<label class="input-label">Rounded variant</label>
|
|
1014
|
+
<input class="input input-rounded" type="text" placeholder="Filter by name..." />
|
|
1015
|
+
</div>
|
|
1016
|
+
</div>
|
|
1017
|
+
<pre><code><span class="c-comment">/* color-mix() for theme-aware focus glow */</span>
|
|
1018
|
+
<span class="c-key">.input:focus</span> <span class="c-punct">{</span>
|
|
1019
|
+
<span class="c-key">border-color</span>: <span class="c-val">var(--df-color-accent-default)</span>;
|
|
1020
|
+
<span class="c-key">box-shadow</span>: 0 0 8px <span class="c-fn">color-mix</span>(<span class="c-val">in srgb</span>, <span class="c-val">var(--df-color-accent-default) 30%</span>, <span class="c-val">transparent</span>);
|
|
1021
|
+
<span class="c-punct">}</span></code></pre>
|
|
1022
|
+
</section>
|
|
1023
|
+
|
|
1024
|
+
<!-- ══════ 11 / Badges ══════ -->
|
|
1025
|
+
<section class="section" id="badges">
|
|
1026
|
+
<div class="section-title">11 / Badges</div>
|
|
1027
|
+
<p class="section-desc">Status badges with <span class="inline-code">color-mix()</span> backgrounds. Two shapes: angular (default) and rounded pill.</p>
|
|
1028
|
+
|
|
1029
|
+
<div class="group-label">Angular</div>
|
|
1030
|
+
<div class="badge-row">
|
|
1031
|
+
<span class="badge badge-idle">Idle</span>
|
|
1032
|
+
<span class="badge badge-active">Active</span>
|
|
1033
|
+
<span class="badge badge-recording">Recording</span>
|
|
1034
|
+
<span class="badge badge-processing">Processing</span>
|
|
1035
|
+
<span class="badge badge-success">Success</span>
|
|
1036
|
+
<span class="badge badge-error">Error</span>
|
|
1037
|
+
<span class="badge badge-warning">Warning</span>
|
|
1038
|
+
<span class="badge badge-info">Info</span>
|
|
1039
|
+
</div>
|
|
1040
|
+
|
|
1041
|
+
<div class="group-label">Rounded Pill</div>
|
|
1042
|
+
<div class="badge-row">
|
|
1043
|
+
<span class="badge badge-rounded badge-success">Online</span>
|
|
1044
|
+
<span class="badge badge-rounded badge-error">Offline</span>
|
|
1045
|
+
<span class="badge badge-rounded badge-processing">Syncing</span>
|
|
1046
|
+
<span class="badge badge-rounded badge-info">v2.0</span>
|
|
1047
|
+
</div>
|
|
1048
|
+
</section>
|
|
1049
|
+
|
|
1050
|
+
<!-- ══════ 12 / Cards ══════ -->
|
|
1051
|
+
<section class="section" id="cards">
|
|
1052
|
+
<div class="section-title">12 / Cards & Panels</div>
|
|
1053
|
+
<p class="section-desc">Content containers with hover elevation using spring-eased transitions. Angular and rounded variants.</p>
|
|
1054
|
+
<div class="card-grid">
|
|
1055
|
+
<div class="card card-clipped">
|
|
1056
|
+
<div class="card-title">Angular Panel</div>
|
|
1057
|
+
<div class="card-body">The signature Devglide card style with clip-path bevels and border elevation on hover.</div>
|
|
1058
|
+
<div class="card-footer">clip-path: var(--df-clip-md)</div>
|
|
1059
|
+
</div>
|
|
1060
|
+
<div class="card card-rounded">
|
|
1061
|
+
<div class="card-title">Rounded Card</div>
|
|
1062
|
+
<div class="card-body">Alternative style for contexts where rounded corners are preferred, like settings panels.</div>
|
|
1063
|
+
<div class="card-footer">border-radius: var(--df-radius-lg)</div>
|
|
1064
|
+
</div>
|
|
1065
|
+
<div class="card card-clipped df-brackets" style="border-color:var(--df-color-accent-dim)">
|
|
1066
|
+
<div class="card-title">Bracketed Panel</div>
|
|
1067
|
+
<div class="card-body">Corner brackets add emphasis for active or selected state. Uses <code class="inline-code">.df-brackets</code> utility.</div>
|
|
1068
|
+
<div class="card-footer">accent corner decorations</div>
|
|
1069
|
+
</div>
|
|
1070
|
+
</div>
|
|
1071
|
+
</section>
|
|
1072
|
+
|
|
1073
|
+
<!-- ══════ 13 / Alerts ══════ -->
|
|
1074
|
+
<section class="section" id="alerts">
|
|
1075
|
+
<div class="section-title">13 / Alerts & Toasts</div>
|
|
1076
|
+
<p class="section-desc">Contextual messages with left border accent and <span class="inline-code">color-mix()</span> tinted backgrounds.</p>
|
|
1077
|
+
<div style="max-width:600px">
|
|
1078
|
+
<div class="alert alert-success">Transcription completed successfully (2.4s)</div>
|
|
1079
|
+
<div class="alert alert-error">Connection to faster-whisper server failed</div>
|
|
1080
|
+
<div class="alert alert-warning">API key expires in 3 days</div>
|
|
1081
|
+
<div class="alert alert-info">New model available: whisper-large-v3-turbo</div>
|
|
1082
|
+
</div>
|
|
1083
|
+
<pre><code><span class="c-comment">/* color-mix() for theme-aware alert backgrounds */</span>
|
|
1084
|
+
<span class="c-key">.alert-error</span> <span class="c-punct">{</span>
|
|
1085
|
+
<span class="c-key">border-color</span>: <span class="c-val">var(--df-color-state-error)</span>;
|
|
1086
|
+
<span class="c-key">background</span>: <span class="c-fn">color-mix</span>(<span class="c-val">in srgb</span>, <span class="c-val">var(--df-color-state-error) 6%</span>, <span class="c-val">var(--df-color-bg-surface)</span>);
|
|
1087
|
+
<span class="c-punct">}</span></code></pre>
|
|
1088
|
+
</section>
|
|
1089
|
+
|
|
1090
|
+
<!-- ══════ 14 / Motion ══════ -->
|
|
1091
|
+
<section class="section" id="motion">
|
|
1092
|
+
<div class="section-title">14 / Motion & Animation</div>
|
|
1093
|
+
<p class="section-desc">
|
|
1094
|
+
Spring physics via <span class="inline-code">linear()</span> easing function.
|
|
1095
|
+
CRT scanline sweep, accent glow pulse, cursor blink, and loading spinners.
|
|
1096
|
+
All animations respect <span class="inline-code">prefers-reduced-motion</span>.
|
|
1097
|
+
</p>
|
|
1098
|
+
|
|
1099
|
+
<div class="group-label">Spring Physics (hover the boxes)</div>
|
|
1100
|
+
<div class="spring-demo" style="margin-bottom:24px">
|
|
1101
|
+
<div>
|
|
1102
|
+
<div class="spring-box" data-easing="ease" style="background:var(--df-color-bg-overlay);border-color:var(--df-color-border-strong)"></div>
|
|
1103
|
+
<div class="spring-label">ease</div>
|
|
1104
|
+
</div>
|
|
1105
|
+
<div>
|
|
1106
|
+
<div class="spring-box" data-easing="spring" style="background:var(--df-color-accent-dim);border-color:var(--df-color-accent-muted)"></div>
|
|
1107
|
+
<div class="spring-label">spring</div>
|
|
1108
|
+
</div>
|
|
1109
|
+
<div>
|
|
1110
|
+
<div class="spring-box" data-easing="spring-bouncy" style="background:var(--df-color-accent-dim);border-color:var(--df-color-accent-default)"></div>
|
|
1111
|
+
<div class="spring-label">bouncy</div>
|
|
1112
|
+
</div>
|
|
1113
|
+
</div>
|
|
1114
|
+
|
|
1115
|
+
<div class="group-label">Signature Animations</div>
|
|
1116
|
+
<div class="anim-grid">
|
|
1117
|
+
<div class="anim-card anim-crt anim-brackets">CRT Scanline<br><span class="text-muted" style="font-size:9px">4s linear infinite</span></div>
|
|
1118
|
+
<div class="anim-card anim-glow anim-brackets" style="color:var(--df-color-accent-default)">Glow Pulse<br><span style="font-size:9px;color:var(--df-color-accent-muted)">2s ease infinite</span></div>
|
|
1119
|
+
<div class="anim-card" style="letter-spacing:0.2em;font-size:11px">SYSTEM READY<span class="cursor-blink"></span><br><span class="text-dim" style="font-size:9px">1s step-start blink</span></div>
|
|
1120
|
+
<div class="anim-card" style="display:flex;align-items:center;justify-content:center;gap:10px"><div class="df-spinner-demo"></div><span>Loading</span><br><span class="text-dim" style="font-size:9px">0.6s linear spin</span></div>
|
|
1121
|
+
</div>
|
|
1122
|
+
|
|
1123
|
+
<pre><code><span class="c-comment">/* Spring easing via linear() — native CSS, no JS needed */</span>
|
|
1124
|
+
<span class="c-key">--df-easing-spring</span>: <span class="c-fn">linear</span>(<span class="c-val">0, 0.009, 0.035 2.1%, 0.141 4.4%, ...</span>);
|
|
1125
|
+
|
|
1126
|
+
<span class="c-comment">/* Use it on any transition */</span>
|
|
1127
|
+
<span class="c-key">.element</span> <span class="c-punct">{</span>
|
|
1128
|
+
<span class="c-key">transition</span>: <span class="c-val">transform 300ms var(--df-easing-spring)</span>;
|
|
1129
|
+
<span class="c-punct">}</span>
|
|
1130
|
+
|
|
1131
|
+
<span class="c-comment">/* Respect user motion preferences */</span>
|
|
1132
|
+
<span class="c-key">@media</span> (<span class="c-val">prefers-reduced-motion: reduce</span>) <span class="c-punct">{</span>
|
|
1133
|
+
<span class="c-key">.df-crt::after</span> <span class="c-punct">{</span> <span class="c-key">animation</span>: <span class="c-val">none</span>; <span class="c-punct">}</span>
|
|
1134
|
+
<span class="c-punct">}</span></code></pre>
|
|
1135
|
+
</section>
|
|
1136
|
+
|
|
1137
|
+
<!-- ══════ 15 / Accessibility ══════ -->
|
|
1138
|
+
<section class="section" id="accessibility">
|
|
1139
|
+
<div class="section-title">15 / Accessibility</div>
|
|
1140
|
+
<p class="section-desc">
|
|
1141
|
+
WCAG 2.2 AA compliant focus indicators using <span class="inline-code">:focus-visible</span>.
|
|
1142
|
+
Screen reader utilities. Reduced motion support. Semantic color contrast ratios.
|
|
1143
|
+
</p>
|
|
1144
|
+
|
|
1145
|
+
<div class="group-label">Focus Ring (Tab through these buttons)</div>
|
|
1146
|
+
<div class="focus-demo-row">
|
|
1147
|
+
<button class="focus-demo-btn">Tab to me</button>
|
|
1148
|
+
<button class="focus-demo-btn" style="clip-path:var(--df-clip-sm)">Clipped button</button>
|
|
1149
|
+
<button class="focus-demo-btn" style="border-radius:var(--df-radius-md)">Rounded button</button>
|
|
1150
|
+
</div>
|
|
1151
|
+
|
|
1152
|
+
<pre><code><span class="c-comment">/* WCAG 2.2 compliant focus ring */</span>
|
|
1153
|
+
<span class="c-key">:focus-visible</span> <span class="c-punct">{</span>
|
|
1154
|
+
<span class="c-key">outline</span>: <span class="c-val">var(--df-focus-ring-width) solid var(--df-focus-ring-color)</span>; <span class="c-comment">/* 2px green */</span>
|
|
1155
|
+
<span class="c-key">outline-offset</span>: <span class="c-val">var(--df-focus-ring-offset)</span>; <span class="c-comment">/* 2px gap */</span>
|
|
1156
|
+
<span class="c-punct">}</span>
|
|
1157
|
+
|
|
1158
|
+
<span class="c-comment">/* Screen reader only */</span>
|
|
1159
|
+
<span class="c-key">.df-sr-only</span> <span class="c-punct">{</span>
|
|
1160
|
+
<span class="c-key">position</span>: <span class="c-val">absolute</span>; <span class="c-key">width</span>: <span class="c-val">1px</span>; <span class="c-key">height</span>: <span class="c-val">1px</span>;
|
|
1161
|
+
<span class="c-key">clip</span>: <span class="c-fn">rect</span>(<span class="c-val">0, 0, 0, 0</span>); <span class="c-key">overflow</span>: <span class="c-val">hidden</span>;
|
|
1162
|
+
<span class="c-punct">}</span></code></pre>
|
|
1163
|
+
</section>
|
|
1164
|
+
|
|
1165
|
+
<!-- ══════ 16 / CSS Architecture ══════ -->
|
|
1166
|
+
<section class="section" id="architecture">
|
|
1167
|
+
<div class="section-title">16 / CSS Architecture</div>
|
|
1168
|
+
<p class="section-desc">
|
|
1169
|
+
Tokens are organized using <span class="inline-code">@layer</span> cascade layers for predictable specificity.
|
|
1170
|
+
<span class="inline-code">@property</span> declarations enable animatable custom properties.
|
|
1171
|
+
</p>
|
|
1172
|
+
|
|
1173
|
+
<div class="group-label">Layer Stack (lowest to highest priority)</div>
|
|
1174
|
+
<div class="arch-layers">
|
|
1175
|
+
<div class="arch-layer" style="background:color-mix(in srgb, var(--df-color-state-info) 8%, var(--df-color-bg-surface));border-left:3px solid var(--df-color-state-info)">
|
|
1176
|
+
<span>df-tokens</span><span class="arch-layer-priority">Custom properties + @property</span>
|
|
1177
|
+
</div>
|
|
1178
|
+
<div class="arch-layer" style="background:color-mix(in srgb, var(--df-color-accent-default) 8%, var(--df-color-bg-surface));border-left:3px solid var(--df-color-accent-default)">
|
|
1179
|
+
<span>df-keyframes</span><span class="arch-layer-priority">@keyframes definitions</span>
|
|
1180
|
+
</div>
|
|
1181
|
+
<div class="arch-layer" style="background:color-mix(in srgb, var(--df-color-state-processing) 8%, var(--df-color-bg-surface));border-left:3px solid var(--df-color-state-processing)">
|
|
1182
|
+
<span>df-components</span><span class="arch-layer-priority">.df-crt, .df-brackets, .df-panel</span>
|
|
1183
|
+
</div>
|
|
1184
|
+
<div class="arch-layer" style="background:color-mix(in srgb, var(--df-color-state-warning) 8%, var(--df-color-bg-surface));border-left:3px solid var(--df-color-state-warning)">
|
|
1185
|
+
<span>df-utilities</span><span class="arch-layer-priority">.df-sr-only, reduced-motion</span>
|
|
1186
|
+
</div>
|
|
1187
|
+
</div>
|
|
1188
|
+
|
|
1189
|
+
<pre><code><span class="c-comment">/* CSS @layer declaration order — tokens.css */</span>
|
|
1190
|
+
<span class="c-key">@layer</span> <span class="c-val">df-tokens, df-keyframes, df-components, df-utilities</span>;
|
|
1191
|
+
|
|
1192
|
+
<span class="c-comment">/* Your app styles cascade ABOVE all token layers */</span>
|
|
1193
|
+
<span class="c-comment">/* No !important needed — layers handle specificity cleanly */</span>
|
|
1194
|
+
|
|
1195
|
+
<span class="c-comment">/* @property makes custom props animatable */</span>
|
|
1196
|
+
<span class="c-key">@property</span> <span class="c-val">--df-hue</span> <span class="c-punct">{</span>
|
|
1197
|
+
<span class="c-key">syntax</span>: <span class="c-str">'<number>'</span>;
|
|
1198
|
+
<span class="c-key">initial-value</span>: <span class="c-val">150</span>;
|
|
1199
|
+
<span class="c-key">inherits</span>: <span class="c-val">true</span>;
|
|
1200
|
+
<span class="c-punct">}</span></code></pre>
|
|
1201
|
+
</section>
|
|
1202
|
+
|
|
1203
|
+
<!-- ══════ 17 / Token Reference ══════ -->
|
|
1204
|
+
<section class="section" id="tokens">
|
|
1205
|
+
<div class="section-title">17 / Token Reference</div>
|
|
1206
|
+
<p class="section-desc">All <span id="semantic-count"></span> CSS custom properties. Import <span class="inline-code">@devglide/design-tokens/css</span> to use them.</p>
|
|
1207
|
+
<input type="text" class="token-search" id="token-search" placeholder="Search tokens..." />
|
|
1208
|
+
<table>
|
|
1209
|
+
<thead><tr><th>Token</th><th>Value</th></tr></thead>
|
|
1210
|
+
<tbody id="token-table"></tbody>
|
|
1211
|
+
</table>
|
|
1212
|
+
</section>
|
|
1213
|
+
|
|
1214
|
+
<!-- Footer -->
|
|
1215
|
+
<footer style="border-top:1px solid var(--df-color-border-subtle);padding-top:20px;margin-top:24px;font-size:10px;letter-spacing:0.15em;text-transform:uppercase;color:var(--df-color-text-muted);display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px">
|
|
1216
|
+
<span>@devglide/design-tokens v2.0</span>
|
|
1217
|
+
<span id="footer-count"></span>
|
|
1218
|
+
</footer>
|
|
1219
|
+
|
|
1220
|
+
</div>
|
|
1221
|
+
|
|
1222
|
+
<script>
|
|
1223
|
+
// ── OKLCH hue slider ──────────────────────────────────────────────────────
|
|
1224
|
+
var hueSlider = document.getElementById('hue-slider');
|
|
1225
|
+
var huePreview = document.getElementById('hue-preview');
|
|
1226
|
+
var hueValue = document.getElementById('hue-value');
|
|
1227
|
+
var oklchContainer = document.getElementById('oklch-swatches');
|
|
1228
|
+
|
|
1229
|
+
function updateHue(h) {
|
|
1230
|
+
hueValue.textContent = h;
|
|
1231
|
+
huePreview.style.background = 'oklch(0.83 0.18 ' + h + ')';
|
|
1232
|
+
// Generate lightness scale for current hue
|
|
1233
|
+
var html = '';
|
|
1234
|
+
var steps = [0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.83, 0.90];
|
|
1235
|
+
var chroma = [0.04, 0.06, 0.08, 0.12, 0.14, 0.16, 0.18, 0.18, 0.12];
|
|
1236
|
+
for (var i = 0; i < steps.length; i++) {
|
|
1237
|
+
var c = 'oklch(' + steps[i] + ' ' + chroma[i] + ' ' + h + ')';
|
|
1238
|
+
var textColor = steps[i] > 0.6 ? 'var(--df-color-text-inverse)' : 'var(--df-color-text-primary)';
|
|
1239
|
+
html += '<div class="swatch" style="background:' + c + ';border:1px solid rgba(255,255,255,0.08);color:' + textColor + '">';
|
|
1240
|
+
html += '<span class="swatch-label">L' + Math.round(steps[i]*100) + '</span>';
|
|
1241
|
+
html += '<span class="swatch-hex" style="color:' + textColor + '">' + steps[i].toFixed(2) + '</span>';
|
|
1242
|
+
html += '</div>';
|
|
1243
|
+
}
|
|
1244
|
+
oklchContainer.innerHTML = html;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
hueSlider.addEventListener('input', function(e) { updateHue(e.target.value); });
|
|
1248
|
+
updateHue(150);
|
|
1249
|
+
|
|
1250
|
+
// ── Primitive palette renderer ────────────────────────────────────────────
|
|
1251
|
+
function renderPrimitivePalette(containerId, prefix, count) {
|
|
1252
|
+
var container = document.getElementById(containerId);
|
|
1253
|
+
var style = getComputedStyle(document.documentElement);
|
|
1254
|
+
var html = '';
|
|
1255
|
+
var keys = [];
|
|
1256
|
+
// Collect all matching vars
|
|
1257
|
+
for (var i = 0; i <= 12; i++) {
|
|
1258
|
+
var varName = '--df-primitive-' + prefix + '-' + i;
|
|
1259
|
+
var val = style.getPropertyValue(varName).trim();
|
|
1260
|
+
if (val) keys.push({ key: i, val: val, varName: varName });
|
|
1261
|
+
}
|
|
1262
|
+
for (var j = 0; j < keys.length; j++) {
|
|
1263
|
+
var item = keys[j];
|
|
1264
|
+
var lum = relativeLuminance(item.val);
|
|
1265
|
+
var textColor = lum > 0.18 ? 'var(--df-color-text-inverse)' : 'var(--df-color-text-primary)';
|
|
1266
|
+
html += '<div class="swatch" style="background:' + item.val + ';border:1px solid rgba(255,255,255,0.06);color:' + textColor + '">';
|
|
1267
|
+
html += '<span class="swatch-label">' + item.key + '</span>';
|
|
1268
|
+
html += '<span class="swatch-hex" style="color:' + textColor + '">' + item.val + '</span>';
|
|
1269
|
+
html += '</div>';
|
|
1270
|
+
}
|
|
1271
|
+
container.innerHTML = html;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
function relativeLuminance(hex) {
|
|
1275
|
+
if (!hex || hex.charAt(0) !== '#') return 0;
|
|
1276
|
+
var r = parseInt(hex.slice(1,3), 16) / 255;
|
|
1277
|
+
var g = parseInt(hex.slice(3,5), 16) / 255;
|
|
1278
|
+
var b = parseInt(hex.slice(5,7), 16) / 255;
|
|
1279
|
+
r = r <= 0.03928 ? r/12.92 : Math.pow((r+0.055)/1.055, 2.4);
|
|
1280
|
+
g = g <= 0.03928 ? g/12.92 : Math.pow((g+0.055)/1.055, 2.4);
|
|
1281
|
+
b = b <= 0.03928 ? b/12.92 : Math.pow((b+0.055)/1.055, 2.4);
|
|
1282
|
+
return 0.2126*r + 0.7152*g + 0.0722*b;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
renderPrimitivePalette('neutral-swatches', 'neutral', 13);
|
|
1286
|
+
renderPrimitivePalette('green-swatches', 'green', 9);
|
|
1287
|
+
renderPrimitivePalette('red-swatches', 'red', 6);
|
|
1288
|
+
renderPrimitivePalette('amber-swatches', 'amber', 6);
|
|
1289
|
+
renderPrimitivePalette('blue-swatches', 'blue', 5);
|
|
1290
|
+
|
|
1291
|
+
// ── Dynamic values ────────────────────────────────────────────────────────
|
|
1292
|
+
function updateDynamicValues() {
|
|
1293
|
+
var style = getComputedStyle(document.documentElement);
|
|
1294
|
+
document.querySelectorAll('[data-var]').forEach(function(el) {
|
|
1295
|
+
var val = style.getPropertyValue(el.dataset.var).trim();
|
|
1296
|
+
el.textContent = val;
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
// ── Token table with search ───────────────────────────────────────────────
|
|
1301
|
+
function buildTokenTable(filter) {
|
|
1302
|
+
var style = getComputedStyle(document.documentElement);
|
|
1303
|
+
// Get all --df- variables from the stylesheet
|
|
1304
|
+
var allVars = [];
|
|
1305
|
+
for (var i = 0; i < document.styleSheets.length; i++) {
|
|
1306
|
+
try {
|
|
1307
|
+
var rules = document.styleSheets[i].cssRules;
|
|
1308
|
+
for (var j = 0; j < rules.length; j++) {
|
|
1309
|
+
var rule = rules[j];
|
|
1310
|
+
// Check in @layer rules
|
|
1311
|
+
if (rule.cssRules) {
|
|
1312
|
+
for (var k = 0; k < rule.cssRules.length; k++) {
|
|
1313
|
+
var innerRule = rule.cssRules[k];
|
|
1314
|
+
if (innerRule.selectorText === ':root' && innerRule.style) {
|
|
1315
|
+
for (var l = 0; l < innerRule.style.length; l++) {
|
|
1316
|
+
var prop = innerRule.style[l];
|
|
1317
|
+
if (prop.startsWith('--df-')) allVars.push(prop);
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
if (rule.selectorText === ':root' && rule.style) {
|
|
1323
|
+
for (var m = 0; m < rule.style.length; m++) {
|
|
1324
|
+
var prop2 = rule.style[m];
|
|
1325
|
+
if (prop2.startsWith('--df-')) allVars.push(prop2);
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
} catch(e) {}
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
// Dedupe and sort
|
|
1333
|
+
allVars = Array.from(new Set(allVars)).sort();
|
|
1334
|
+
|
|
1335
|
+
var tbody = document.getElementById('token-table');
|
|
1336
|
+
tbody.innerHTML = '';
|
|
1337
|
+
var filterLower = (filter || '').toLowerCase();
|
|
1338
|
+
var count = 0;
|
|
1339
|
+
|
|
1340
|
+
for (var n = 0; n < allVars.length; n++) {
|
|
1341
|
+
var name = allVars[n];
|
|
1342
|
+
if (filterLower && name.toLowerCase().indexOf(filterLower) === -1) continue;
|
|
1343
|
+
var v = style.getPropertyValue(name).trim();
|
|
1344
|
+
var isColor = v.startsWith('#') || v.startsWith('rgb');
|
|
1345
|
+
var preview = isColor
|
|
1346
|
+
? '<span class="swatch-inline" style="background:' + v + ';border:1px solid rgba(255,255,255,.1)"></span>' + v
|
|
1347
|
+
: '<span style="color:var(--df-color-text-secondary)">' + (v.length > 80 ? v.substring(0,80) + '...' : v) + '</span>';
|
|
1348
|
+
tbody.insertAdjacentHTML('beforeend', '<tr><td><code>' + name + '</code></td><td>' + preview + '</td></tr>');
|
|
1349
|
+
count++;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
document.getElementById('token-count').textContent = allVars.length;
|
|
1353
|
+
document.getElementById('semantic-count').textContent = count + ' of ' + allVars.length;
|
|
1354
|
+
document.getElementById('footer-count').textContent = allVars.length + ' tokens \u00b7 4 @layers \u00b7 5 color scales';
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// Search
|
|
1358
|
+
document.getElementById('token-search').addEventListener('input', function(e) {
|
|
1359
|
+
buildTokenTable(e.target.value);
|
|
1360
|
+
});
|
|
1361
|
+
|
|
1362
|
+
// Initial render
|
|
1363
|
+
updateDynamicValues();
|
|
1364
|
+
buildTokenTable();
|
|
1365
|
+
</script>
|
|
1366
|
+
</body>
|
|
1367
|
+
</html>
|