@brightweblabs/theme 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +26 -0
- package/src/base.css +33 -0
- package/src/index.css +5 -0
- package/src/surfaces.css +175 -0
- package/src/theme.css +120 -0
- package/src/tint.ts +22 -0
- package/src/tokens.css +274 -0
- package/src/typography.css +149 -0
- package/themes/mq-aliases.css +139 -0
- package/themes/mq.css +177 -0
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@brightweblabs/theme",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"main": "./src/tint.ts",
|
|
6
|
+
"types": "./src/tint.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"src",
|
|
9
|
+
"themes"
|
|
10
|
+
],
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/BWLeoRibeiro/brightweb-platform.git"
|
|
15
|
+
},
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": "./src/tint.ts",
|
|
21
|
+
"./css": "./src/index.css",
|
|
22
|
+
"./tint": "./src/tint.ts",
|
|
23
|
+
"./themes/mq": "./themes/mq.css",
|
|
24
|
+
"./themes/mq-aliases": "./themes/mq-aliases.css"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/base.css
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* Keep the reset layered so Tailwind utilities and component variants retain
|
|
2
|
+
precedence over these element defaults. */
|
|
3
|
+
@layer base {
|
|
4
|
+
*,
|
|
5
|
+
::before,
|
|
6
|
+
::after {
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
html,
|
|
11
|
+
body {
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 0;
|
|
14
|
+
background: var(--page-background);
|
|
15
|
+
color: var(--foreground);
|
|
16
|
+
font-family: var(--font-sans), sans-serif;
|
|
17
|
+
-webkit-font-smoothing: antialiased;
|
|
18
|
+
-moz-osx-font-smoothing: grayscale;
|
|
19
|
+
text-rendering: optimizeLegibility;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
a {
|
|
23
|
+
color: inherit;
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Unlayered, this shorthand beats @layer utilities and erases button
|
|
28
|
+
variant typography. */
|
|
29
|
+
button,
|
|
30
|
+
input {
|
|
31
|
+
font: inherit;
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/index.css
ADDED
package/src/surfaces.css
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/* ── Shared structural surfaces ───────────────────────────────────────── */
|
|
2
|
+
.surface-card {
|
|
3
|
+
border-radius: var(--radius-card);
|
|
4
|
+
border: 1px solid var(--border-hairline);
|
|
5
|
+
background: var(--surface-card);
|
|
6
|
+
padding: var(--surface-card-padding);
|
|
7
|
+
animation: surface-fade-in 640ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.surface-card.is-light {
|
|
11
|
+
background: var(--surface-card-light);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* A near-black panel has strong figure/ground in light mode. In dark mode it
|
|
15
|
+
elevates above the page through a lighter accent mix, border, and shadow. */
|
|
16
|
+
.brand-panel {
|
|
17
|
+
--row-sweep-tint: var(--brand-panel-foreground);
|
|
18
|
+
background: var(--brand-panel-surface);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.dark .brand-panel,
|
|
22
|
+
.theme-dark .brand-panel {
|
|
23
|
+
border: 1px solid var(--brand-panel-border);
|
|
24
|
+
box-shadow: var(--brand-shadow-lift);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.row-hover-sweep {
|
|
28
|
+
pointer-events: none;
|
|
29
|
+
position: absolute;
|
|
30
|
+
inset: 0;
|
|
31
|
+
border-radius: var(--radius-card);
|
|
32
|
+
opacity: 0;
|
|
33
|
+
transition: opacity 300ms ease;
|
|
34
|
+
background: linear-gradient(
|
|
35
|
+
90deg,
|
|
36
|
+
transparent,
|
|
37
|
+
color-mix(in srgb, var(--row-sweep-tint, var(--foreground)) 9%, transparent) 50%,
|
|
38
|
+
transparent
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.group:hover > .row-hover-sweep,
|
|
43
|
+
.group:focus-visible > .row-hover-sweep {
|
|
44
|
+
opacity: 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* ── Canonical tinted-pill recipes ────────────────────────────────────── */
|
|
48
|
+
@layer components {
|
|
49
|
+
.tint-soft {
|
|
50
|
+
border-color: color-mix(in srgb, var(--tint) 34%, transparent);
|
|
51
|
+
background-color: color-mix(in srgb, var(--tint) 10%, var(--card));
|
|
52
|
+
color: var(--tint-strong);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.tint-soft:hover {
|
|
56
|
+
background-color: color-mix(in srgb, var(--tint) 14%, var(--card));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.tint-hero {
|
|
60
|
+
border-color: color-mix(in srgb, var(--tint) 46%, transparent);
|
|
61
|
+
background-color: color-mix(in srgb, var(--tint) 16%, transparent);
|
|
62
|
+
color: color-mix(in srgb, var(--tint) 18%, white);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.tint-hero:hover {
|
|
66
|
+
background-color: color-mix(in srgb, var(--tint) 24%, transparent);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.section-icon {
|
|
71
|
+
display: flex;
|
|
72
|
+
width: 1.875rem;
|
|
73
|
+
height: 1.875rem;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
border-radius: 999px;
|
|
78
|
+
background: var(--muted);
|
|
79
|
+
color: var(--muted-foreground);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.stat-cell {
|
|
83
|
+
padding: var(--stat-cell-padding);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Skeleton shimmer respects reduced-motion with a quiet breathe fallback. */
|
|
87
|
+
@keyframes surface-fade-in {
|
|
88
|
+
from {
|
|
89
|
+
opacity: 0;
|
|
90
|
+
transform: translateY(10px);
|
|
91
|
+
}
|
|
92
|
+
to {
|
|
93
|
+
opacity: 1;
|
|
94
|
+
transform: translateY(0);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@keyframes skeleton-shimmer {
|
|
99
|
+
100% {
|
|
100
|
+
transform: translateX(100%);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@keyframes skeleton-breathe {
|
|
105
|
+
0%,
|
|
106
|
+
100% {
|
|
107
|
+
opacity: 1;
|
|
108
|
+
}
|
|
109
|
+
50% {
|
|
110
|
+
opacity: 0.6;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.skeleton-ghost {
|
|
115
|
+
position: relative;
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
background: var(--skeleton);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.skeleton-ghost::after {
|
|
121
|
+
content: "";
|
|
122
|
+
position: absolute;
|
|
123
|
+
inset: 0;
|
|
124
|
+
transform: translateX(-100%);
|
|
125
|
+
background: linear-gradient(90deg, transparent, var(--skeleton-highlight), transparent);
|
|
126
|
+
animation: skeleton-shimmer 1.6s ease-in-out infinite;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@media (prefers-reduced-motion: reduce) {
|
|
130
|
+
.skeleton-ghost::after {
|
|
131
|
+
display: none;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.skeleton-ghost {
|
|
135
|
+
animation: skeleton-breathe 2.4s ease-in-out infinite;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.eyebrow {
|
|
140
|
+
display: inline-flex;
|
|
141
|
+
width: fit-content;
|
|
142
|
+
padding: 6px 10px;
|
|
143
|
+
border-radius: 999px;
|
|
144
|
+
background: var(--brand-surface-tint);
|
|
145
|
+
color: var(--brand-accent);
|
|
146
|
+
font-size: var(--text-ui-label);
|
|
147
|
+
font-weight: var(--font-weight-bold);
|
|
148
|
+
letter-spacing: 0.04em;
|
|
149
|
+
text-transform: uppercase;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.status {
|
|
153
|
+
display: inline-flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: 8px;
|
|
156
|
+
padding: 8px 12px;
|
|
157
|
+
border-radius: 999px;
|
|
158
|
+
font-size: var(--text-ui-meta);
|
|
159
|
+
font-weight: var(--font-weight-bold);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.status.ok {
|
|
163
|
+
background: color-mix(in srgb, var(--semantic-success) 14%, transparent);
|
|
164
|
+
color: var(--semantic-success-strong);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.status.warn {
|
|
168
|
+
background: color-mix(in srgb, var(--semantic-warning) 14%, transparent);
|
|
169
|
+
color: var(--semantic-warning-strong);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.status.error {
|
|
173
|
+
background: color-mix(in srgb, var(--semantic-danger) 12%, transparent);
|
|
174
|
+
color: var(--semantic-danger-strong);
|
|
175
|
+
}
|
package/src/theme.css
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
@theme inline {
|
|
2
|
+
/* L1: shadcn semantics. */
|
|
3
|
+
--color-background: var(--background);
|
|
4
|
+
--color-foreground: var(--foreground);
|
|
5
|
+
--color-card: var(--card);
|
|
6
|
+
--color-card-foreground: var(--card-foreground);
|
|
7
|
+
--color-popover: var(--popover);
|
|
8
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
9
|
+
--color-primary: var(--primary);
|
|
10
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
11
|
+
--color-secondary: var(--secondary);
|
|
12
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
13
|
+
--color-muted: var(--muted);
|
|
14
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
15
|
+
--color-accent: var(--accent);
|
|
16
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
17
|
+
--color-destructive: var(--destructive);
|
|
18
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
19
|
+
--color-border: var(--border);
|
|
20
|
+
--color-input: var(--input);
|
|
21
|
+
--color-ring: var(--ring);
|
|
22
|
+
--color-foreground-inverse: var(--foreground-inverse);
|
|
23
|
+
--color-foreground-inverse-muted: var(--foreground-inverse-muted);
|
|
24
|
+
--color-foreground-inverse-subtle: var(--foreground-inverse-subtle);
|
|
25
|
+
|
|
26
|
+
/* L2: status hues. */
|
|
27
|
+
--color-semantic-info: var(--semantic-info);
|
|
28
|
+
--color-semantic-info-strong: var(--semantic-info-strong);
|
|
29
|
+
--color-semantic-special: var(--semantic-special);
|
|
30
|
+
--color-semantic-special-strong: var(--semantic-special-strong);
|
|
31
|
+
--color-semantic-warning: var(--semantic-warning);
|
|
32
|
+
--color-semantic-warning-strong: var(--semantic-warning-strong);
|
|
33
|
+
--color-semantic-success: var(--semantic-success);
|
|
34
|
+
--color-semantic-success-strong: var(--semantic-success-strong);
|
|
35
|
+
--color-semantic-danger: var(--semantic-danger);
|
|
36
|
+
--color-semantic-danger-strong: var(--semantic-danger-strong);
|
|
37
|
+
--color-semantic-danger-soft: var(--semantic-danger-soft);
|
|
38
|
+
--color-semantic-neutral: var(--semantic-neutral);
|
|
39
|
+
--color-semantic-neutral-strong: var(--semantic-neutral-strong);
|
|
40
|
+
|
|
41
|
+
/* L3: recipes, elevation, roles, and on-fill inks. */
|
|
42
|
+
--color-border-hairline: var(--border-hairline);
|
|
43
|
+
--color-border-hairline-soft: var(--border-hairline-soft);
|
|
44
|
+
--color-border-strong: var(--border-strong);
|
|
45
|
+
--color-surface-hover: var(--surface-hover);
|
|
46
|
+
--color-skeleton: var(--skeleton);
|
|
47
|
+
--color-skeleton-strong: var(--skeleton-strong);
|
|
48
|
+
--color-skeleton-highlight: var(--skeleton-highlight);
|
|
49
|
+
--color-elevate-1: var(--elevate-1);
|
|
50
|
+
--color-elevate-2: var(--elevate-2);
|
|
51
|
+
--color-elevate-3: var(--elevate-3);
|
|
52
|
+
--color-hairline: var(--hairline);
|
|
53
|
+
--color-hairline-strong: var(--hairline-strong);
|
|
54
|
+
--color-role-client: var(--role-client);
|
|
55
|
+
--color-role-client-strong: var(--role-client-strong);
|
|
56
|
+
--color-role-team: var(--role-team);
|
|
57
|
+
--color-role-team-strong: var(--role-team-strong);
|
|
58
|
+
--color-role-admin: var(--role-admin);
|
|
59
|
+
--color-role-admin-strong: var(--role-admin-strong);
|
|
60
|
+
--color-role-manager: var(--role-manager);
|
|
61
|
+
--color-role-manager-strong: var(--role-manager-strong);
|
|
62
|
+
--color-badge-count: var(--badge-count-bg);
|
|
63
|
+
--color-badge-count-foreground: var(--badge-count-fg);
|
|
64
|
+
--color-badge-count-bg: var(--badge-count-bg);
|
|
65
|
+
--color-badge-count-fg: var(--badge-count-fg);
|
|
66
|
+
--color-on-fill-danger: var(--on-fill-danger);
|
|
67
|
+
--color-on-fill-warning: var(--on-fill-warning);
|
|
68
|
+
--color-on-fill-success: var(--on-fill-success);
|
|
69
|
+
--color-surface-card: var(--surface-card);
|
|
70
|
+
--color-surface-card-light: var(--surface-card-light);
|
|
71
|
+
--color-brand-panel-foreground: var(--brand-panel-foreground);
|
|
72
|
+
--color-brand-panel-muted: var(--brand-panel-muted);
|
|
73
|
+
--color-brand-panel-subtle: var(--brand-panel-subtle);
|
|
74
|
+
--color-brand-panel-border: var(--brand-panel-border);
|
|
75
|
+
--color-brand-panel-surface-raised: var(--brand-panel-surface-raised);
|
|
76
|
+
--color-row-sweep-tint: var(--row-sweep-tint);
|
|
77
|
+
|
|
78
|
+
/* Collapse Tailwind's radius scale onto the three UI tiers. */
|
|
79
|
+
--radius-sm: var(--radius);
|
|
80
|
+
--radius-md: var(--radius);
|
|
81
|
+
--radius-lg: var(--radius-card);
|
|
82
|
+
--radius-xl: var(--radius-card);
|
|
83
|
+
--radius-2xl: var(--radius-panel);
|
|
84
|
+
--radius-3xl: var(--radius-panel);
|
|
85
|
+
|
|
86
|
+
/* Named spacing keys sit alongside Tailwind's numeric scale. */
|
|
87
|
+
--spacing-2xs: var(--space-2xs);
|
|
88
|
+
--spacing-xs: var(--space-xs);
|
|
89
|
+
--spacing-sm: var(--space-sm);
|
|
90
|
+
--spacing-md: var(--space-md);
|
|
91
|
+
--spacing-lg: var(--space-lg);
|
|
92
|
+
--spacing-lg-plus: var(--space-lg-plus);
|
|
93
|
+
--spacing-xl: var(--space-xl);
|
|
94
|
+
--spacing-2xl: var(--space-2xl);
|
|
95
|
+
--spacing-3xl: var(--space-3xl);
|
|
96
|
+
--spacing-4xl: var(--space-4xl);
|
|
97
|
+
--spacing-control: var(--space-control);
|
|
98
|
+
--spacing-button-y: var(--space-button-y);
|
|
99
|
+
--spacing-button-x: var(--space-button-x);
|
|
100
|
+
--spacing-card-pad-x: var(--space-card-pad-x);
|
|
101
|
+
--spacing-card-pad-x-tight: var(--space-card-pad-x-tight);
|
|
102
|
+
--spacing-copy-bottom: var(--space-copy-bottom);
|
|
103
|
+
--spacing-badge-y: var(--space-badge-y);
|
|
104
|
+
--spacing-badge-x: var(--space-badge-x);
|
|
105
|
+
|
|
106
|
+
/* Tailwind v4 uses --container-* for max-w-*. Keep spacing names from
|
|
107
|
+
shadowing the standard container widths. */
|
|
108
|
+
--container-2xs: 18rem;
|
|
109
|
+
--container-xs: 20rem;
|
|
110
|
+
--container-sm: 24rem;
|
|
111
|
+
--container-md: 28rem;
|
|
112
|
+
--container-lg: 32rem;
|
|
113
|
+
--container-xl: 36rem;
|
|
114
|
+
--container-2xl: 42rem;
|
|
115
|
+
--container-3xl: 48rem;
|
|
116
|
+
--container-4xl: 56rem;
|
|
117
|
+
--container-5xl: 64rem;
|
|
118
|
+
--container-6xl: 72rem;
|
|
119
|
+
--container-7xl: 80rem;
|
|
120
|
+
}
|
package/src/tint.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** The two canonical tint recipes provided by the theme CSS. */
|
|
2
|
+
export type TintVariant = "soft" | "hero";
|
|
3
|
+
|
|
4
|
+
export type TintPillResult = {
|
|
5
|
+
className: "tint-soft" | "tint-hero";
|
|
6
|
+
style: Record<string, string>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Pairs a semantic custom property with the canonical tinted-pill recipes.
|
|
11
|
+
* Pass the custom-property name without a var() wrapper.
|
|
12
|
+
*/
|
|
13
|
+
export function tintPill(token: string, variant: TintVariant = "soft"): TintPillResult {
|
|
14
|
+
const style: Record<string, string> = { "--tint": `var(${token})` };
|
|
15
|
+
|
|
16
|
+
if (variant === "soft") {
|
|
17
|
+
style["--tint-strong"] = `var(${token}-strong)`;
|
|
18
|
+
return { className: "tint-soft", style };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return { className: "tint-hero", style };
|
|
22
|
+
}
|
package/src/tokens.css
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/* ── L0: brand primitives ─────────────────────────────────────────────── */
|
|
2
|
+
:root {
|
|
3
|
+
color-scheme: light;
|
|
4
|
+
--font-body: "Mulish", "Mulish Fallback", "Segoe UI", Arial, sans-serif;
|
|
5
|
+
--font-heading: var(--font-body);
|
|
6
|
+
--font-sans: var(--font-body);
|
|
7
|
+
--font-display: var(--font-heading);
|
|
8
|
+
--font-mono: ui-monospace, "SF Mono", "JetBrains Mono", "Menlo", monospace;
|
|
9
|
+
|
|
10
|
+
--brand-accent: #4a7dbd;
|
|
11
|
+
--brand-accent-soft: #7196c4;
|
|
12
|
+
--brand-ink: #111827;
|
|
13
|
+
--brand-neutral-500: #64748b;
|
|
14
|
+
--brand-neutral-300: #cbd5e1;
|
|
15
|
+
--brand-neutral-200: #e2e8f0;
|
|
16
|
+
--brand-neutral-100: #f1f5f9;
|
|
17
|
+
--brand-white: #ffffff;
|
|
18
|
+
--brand-border-subtle: rgba(15, 23, 42, 0.1);
|
|
19
|
+
--brand-surface-tint: rgba(74, 125, 189, 0.09);
|
|
20
|
+
--brand-surface-dark: rgba(15, 23, 42, 0.95);
|
|
21
|
+
--brand-shadow-soft: 0 20px 44px rgba(15, 23, 42, 0.1);
|
|
22
|
+
--brand-shadow-lift: 0 18px 32px rgba(15, 23, 42, 0.22);
|
|
23
|
+
|
|
24
|
+
/* ── L1: shadcn semantic contract ──────────────────────────────────── */
|
|
25
|
+
--background: var(--brand-white);
|
|
26
|
+
--foreground: var(--brand-ink);
|
|
27
|
+
--card: var(--brand-white);
|
|
28
|
+
--card-foreground: var(--brand-ink);
|
|
29
|
+
--popover: var(--brand-white);
|
|
30
|
+
--popover-foreground: var(--brand-ink);
|
|
31
|
+
--primary: var(--brand-ink);
|
|
32
|
+
--primary-foreground: var(--brand-white);
|
|
33
|
+
--secondary: var(--brand-neutral-100);
|
|
34
|
+
--secondary-foreground: var(--brand-ink);
|
|
35
|
+
--muted: rgba(203, 213, 225, 0.25);
|
|
36
|
+
--muted-foreground: var(--brand-neutral-500);
|
|
37
|
+
--foreground-inverse: var(--brand-white);
|
|
38
|
+
--foreground-inverse-muted: rgba(255, 255, 255, 0.88);
|
|
39
|
+
--foreground-inverse-subtle: rgba(255, 255, 255, 0.84);
|
|
40
|
+
--accent: var(--brand-accent);
|
|
41
|
+
--accent-foreground: var(--brand-white);
|
|
42
|
+
--destructive: #b43f3f;
|
|
43
|
+
--destructive-foreground: var(--brand-white);
|
|
44
|
+
--border: var(--brand-border-subtle);
|
|
45
|
+
--input: rgba(15, 23, 42, 0.09);
|
|
46
|
+
--ring: rgba(74, 125, 189, 0.42);
|
|
47
|
+
|
|
48
|
+
/* ── L2: brand-agnostic semantic colour base ───────────────────────── */
|
|
49
|
+
--semantic-info: #0ea5e9;
|
|
50
|
+
--semantic-info-strong: #0369a1;
|
|
51
|
+
--semantic-special: #8b5cf6;
|
|
52
|
+
--semantic-special-strong: #6d28d9;
|
|
53
|
+
--semantic-warning: #eab034;
|
|
54
|
+
--semantic-warning-strong: #7a5c15;
|
|
55
|
+
--semantic-success: #10b981;
|
|
56
|
+
--semantic-success-strong: #047857;
|
|
57
|
+
--semantic-danger: #c9373a;
|
|
58
|
+
--semantic-danger-strong: #b72f33;
|
|
59
|
+
--semantic-danger-soft: #e55759;
|
|
60
|
+
--semantic-neutral: #71717a;
|
|
61
|
+
--semantic-neutral-strong: #52525b;
|
|
62
|
+
|
|
63
|
+
/* ── L3: experience tokens ─────────────────────────────────────────── */
|
|
64
|
+
--space-2xs: 0.25rem;
|
|
65
|
+
--space-xs: 0.5rem;
|
|
66
|
+
--space-sm: 0.75rem;
|
|
67
|
+
--space-md: 1rem;
|
|
68
|
+
--space-lg: 1.5rem;
|
|
69
|
+
--space-lg-plus: 1.75rem;
|
|
70
|
+
--space-xl: 2rem;
|
|
71
|
+
--space-2xl: 2.5rem;
|
|
72
|
+
--space-3xl: 3rem;
|
|
73
|
+
--space-4xl: 3.75rem;
|
|
74
|
+
--space-control: 2.8rem;
|
|
75
|
+
--space-button-y: 1.15rem;
|
|
76
|
+
--space-button-x: 2.35rem;
|
|
77
|
+
--space-card-pad-x: 1.5rem;
|
|
78
|
+
--space-card-pad-x-tight: 1.25rem;
|
|
79
|
+
--space-copy-bottom: 2.25rem;
|
|
80
|
+
--space-badge-y: 0.4rem;
|
|
81
|
+
--space-badge-x: 0.7rem;
|
|
82
|
+
|
|
83
|
+
/* Controls, cards, and large panels. Full radius remains for pills/avatars. */
|
|
84
|
+
--radius: 0.3125rem;
|
|
85
|
+
--radius-control: 0.625rem;
|
|
86
|
+
--radius-card: 0.75rem;
|
|
87
|
+
--radius-panel: 1rem;
|
|
88
|
+
|
|
89
|
+
--text-ui-micro: 0.625rem;
|
|
90
|
+
--text-ui-label: 0.6875rem;
|
|
91
|
+
--text-ui-meta: 0.75rem;
|
|
92
|
+
--text-ui-body: 0.875rem;
|
|
93
|
+
--text-ui-card-title: 0.9375rem;
|
|
94
|
+
--text-ui-subhead: 1.125rem;
|
|
95
|
+
--text-ui-panel-title: 1.25rem;
|
|
96
|
+
--text-ui-heading: 1.5rem;
|
|
97
|
+
--text-ui-title-sm: 1.875rem;
|
|
98
|
+
--text-ui-title: clamp(1.75rem, 1.6rem + 0.7vw, 2rem);
|
|
99
|
+
--text-ui-metric: 2.75rem;
|
|
100
|
+
--text-ui-metric-xl: 3.5rem;
|
|
101
|
+
--text-ui-metric-display: var(--text-ui-metric);
|
|
102
|
+
|
|
103
|
+
--elevate-1: color-mix(in srgb, var(--foreground) 3%, transparent);
|
|
104
|
+
--elevate-2: color-mix(in srgb, var(--foreground) 5%, transparent);
|
|
105
|
+
--elevate-3: color-mix(in srgb, var(--foreground) 8%, transparent);
|
|
106
|
+
--hairline: color-mix(in srgb, var(--foreground) 8%, transparent);
|
|
107
|
+
--hairline-strong: color-mix(in srgb, var(--foreground) 12%, transparent);
|
|
108
|
+
--border-hairline: color-mix(in srgb, var(--foreground) 14%, transparent);
|
|
109
|
+
--border-hairline-soft: color-mix(in srgb, var(--foreground) 12%, transparent);
|
|
110
|
+
--border-strong: color-mix(in srgb, var(--foreground) 24%, transparent);
|
|
111
|
+
--surface-hover: color-mix(in srgb, var(--foreground) 4%, var(--card) 96%);
|
|
112
|
+
|
|
113
|
+
--skeleton: color-mix(in srgb, var(--foreground) 7%, transparent);
|
|
114
|
+
--skeleton-strong: color-mix(in srgb, var(--foreground) 11%, transparent);
|
|
115
|
+
--skeleton-highlight: color-mix(in srgb, var(--brand-white) 65%, transparent);
|
|
116
|
+
|
|
117
|
+
--role-client: #5076a8;
|
|
118
|
+
--role-client-strong: #31527f;
|
|
119
|
+
--role-team: #398579;
|
|
120
|
+
--role-team-strong: #25665d;
|
|
121
|
+
--role-admin: #765c9f;
|
|
122
|
+
--role-admin-strong: #59417e;
|
|
123
|
+
--role-manager: #a36f2f;
|
|
124
|
+
--role-manager-strong: #7b501f;
|
|
125
|
+
|
|
126
|
+
--badge-count-bg: var(--semantic-danger);
|
|
127
|
+
--badge-count-fg: var(--brand-white);
|
|
128
|
+
--on-fill-danger: var(--brand-white);
|
|
129
|
+
--on-fill-warning: #3a2a05;
|
|
130
|
+
--on-fill-success: #06281e;
|
|
131
|
+
|
|
132
|
+
--page-background:
|
|
133
|
+
radial-gradient(circle at 14% 8%, color-mix(in srgb, var(--brand-accent) 14%, transparent), transparent 26%),
|
|
134
|
+
linear-gradient(180deg, var(--brand-white) 0%, color-mix(in srgb, var(--brand-accent) 4%, var(--brand-white)) 54%, var(--brand-white) 100%);
|
|
135
|
+
--brand-panel-surface: linear-gradient(
|
|
136
|
+
158deg,
|
|
137
|
+
color-mix(in srgb, var(--brand-surface-dark) 96%, var(--brand-accent)) 0%,
|
|
138
|
+
color-mix(in srgb, var(--brand-surface-dark) 86%, var(--brand-accent)) 55%,
|
|
139
|
+
color-mix(in srgb, var(--brand-surface-dark) 72%, var(--brand-accent)) 100%
|
|
140
|
+
);
|
|
141
|
+
--brand-panel-surface-raised: color-mix(in srgb, var(--brand-surface-dark) 76%, var(--brand-accent));
|
|
142
|
+
--brand-panel-foreground: var(--brand-white);
|
|
143
|
+
--brand-panel-muted: color-mix(in srgb, var(--brand-white) 68%, transparent);
|
|
144
|
+
--brand-panel-subtle: color-mix(in srgb, var(--brand-white) 48%, transparent);
|
|
145
|
+
--brand-panel-border: color-mix(in srgb, var(--brand-accent) 22%, transparent);
|
|
146
|
+
--row-sweep-tint: var(--foreground);
|
|
147
|
+
--surface-card: color-mix(in srgb, var(--foreground) 2%, var(--card) 98%);
|
|
148
|
+
--surface-card-light: var(--card);
|
|
149
|
+
--surface-card-padding: 1.25rem;
|
|
150
|
+
--stat-cell-padding: 1rem;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Dark mode redefines the primitives and semantic base before re-deriving L1. */
|
|
154
|
+
:root.dark,
|
|
155
|
+
:root[data-theme="dark"],
|
|
156
|
+
.theme-dark {
|
|
157
|
+
color-scheme: dark;
|
|
158
|
+
--brand-accent: #79a8df;
|
|
159
|
+
--brand-accent-soft: #9bbce2;
|
|
160
|
+
--brand-ink: #0b1220;
|
|
161
|
+
--brand-neutral-500: #9aa9bc;
|
|
162
|
+
--brand-neutral-300: #c7d2e1;
|
|
163
|
+
--brand-neutral-200: #dce4ee;
|
|
164
|
+
--brand-neutral-100: #111c2c;
|
|
165
|
+
--brand-white: #f8fafc;
|
|
166
|
+
--brand-border-subtle: rgba(148, 163, 184, 0.24);
|
|
167
|
+
--brand-surface-tint: rgba(121, 168, 223, 0.14);
|
|
168
|
+
--brand-surface-dark: rgba(8, 15, 27, 0.96);
|
|
169
|
+
--brand-shadow-soft: 0 20px 44px rgba(0, 0, 0, 0.44);
|
|
170
|
+
--brand-shadow-lift: 0 18px 36px rgba(0, 0, 0, 0.5);
|
|
171
|
+
|
|
172
|
+
--background: #0b1220;
|
|
173
|
+
--foreground: #edf2f8;
|
|
174
|
+
--card: #111c2c;
|
|
175
|
+
--card-foreground: #edf2f8;
|
|
176
|
+
--popover: #101a29;
|
|
177
|
+
--popover-foreground: #edf2f8;
|
|
178
|
+
--primary: #edf2f8;
|
|
179
|
+
--primary-foreground: #0b1220;
|
|
180
|
+
--secondary: #172438;
|
|
181
|
+
--secondary-foreground: #dce5f0;
|
|
182
|
+
--muted: rgba(148, 163, 184, 0.16);
|
|
183
|
+
--muted-foreground: #a6b4c6;
|
|
184
|
+
--foreground-inverse: #f8fafc;
|
|
185
|
+
--foreground-inverse-muted: rgba(248, 250, 252, 0.9);
|
|
186
|
+
--foreground-inverse-subtle: rgba(248, 250, 252, 0.84);
|
|
187
|
+
--accent: var(--brand-accent);
|
|
188
|
+
--accent-foreground: #0b1220;
|
|
189
|
+
--destructive: #d26969;
|
|
190
|
+
--destructive-foreground: #0b1220;
|
|
191
|
+
--border: rgba(148, 163, 184, 0.22);
|
|
192
|
+
--input: rgba(148, 163, 184, 0.17);
|
|
193
|
+
--ring: rgba(121, 168, 223, 0.4);
|
|
194
|
+
|
|
195
|
+
--semantic-info: #38bdf8;
|
|
196
|
+
--semantic-info-strong: #7dd3fc;
|
|
197
|
+
--semantic-special: #a78bfa;
|
|
198
|
+
--semantic-special-strong: #ddd6fe;
|
|
199
|
+
--semantic-warning: #fbbf24;
|
|
200
|
+
--semantic-warning-strong: #fde68a;
|
|
201
|
+
--semantic-success: #34d399;
|
|
202
|
+
--semantic-success-strong: #a7f3d0;
|
|
203
|
+
--semantic-danger: #fb7185;
|
|
204
|
+
--semantic-danger-strong: #fecdd3;
|
|
205
|
+
--semantic-danger-soft: #fda4af;
|
|
206
|
+
--semantic-neutral: #a1a1aa;
|
|
207
|
+
--semantic-neutral-strong: #d4d4d8;
|
|
208
|
+
|
|
209
|
+
--skeleton: color-mix(in srgb, var(--foreground) 9%, transparent);
|
|
210
|
+
--skeleton-strong: color-mix(in srgb, var(--foreground) 14%, transparent);
|
|
211
|
+
--skeleton-highlight: color-mix(in srgb, var(--brand-white) 12%, transparent);
|
|
212
|
+
--role-client: #79a8df;
|
|
213
|
+
--role-client-strong: #c5daf2;
|
|
214
|
+
--role-team: #5bc8b9;
|
|
215
|
+
--role-team-strong: #b8eee7;
|
|
216
|
+
--role-admin: #ad99d0;
|
|
217
|
+
--role-admin-strong: #ded5ed;
|
|
218
|
+
--role-manager: #e0aa61;
|
|
219
|
+
--role-manager-strong: #f4d6aa;
|
|
220
|
+
--badge-count-fg: #ffffff;
|
|
221
|
+
--on-fill-danger: #350a11;
|
|
222
|
+
--on-fill-warning: #3a2a05;
|
|
223
|
+
--on-fill-success: #06281e;
|
|
224
|
+
|
|
225
|
+
--page-background:
|
|
226
|
+
radial-gradient(circle at 14% 12%, color-mix(in srgb, var(--brand-accent) 17%, transparent), transparent 26%),
|
|
227
|
+
radial-gradient(circle at 82% 18%, color-mix(in srgb, var(--brand-accent) 10%, transparent), transparent 24%),
|
|
228
|
+
linear-gradient(180deg, var(--brand-surface-dark) 0%, var(--background) 100%);
|
|
229
|
+
--brand-panel-surface: linear-gradient(
|
|
230
|
+
158deg,
|
|
231
|
+
color-mix(in srgb, var(--card) 84%, var(--brand-accent)) 0%,
|
|
232
|
+
color-mix(in srgb, var(--card) 72%, var(--brand-accent)) 52%,
|
|
233
|
+
color-mix(in srgb, var(--card) 60%, var(--brand-accent)) 100%
|
|
234
|
+
);
|
|
235
|
+
--brand-panel-surface-raised: color-mix(in srgb, var(--card) 72%, var(--brand-accent));
|
|
236
|
+
--surface-card: color-mix(in srgb, var(--foreground) 2%, var(--card) 98%);
|
|
237
|
+
--surface-card-light: color-mix(in srgb, var(--card) 92%, var(--brand-white) 8%);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* Explicit light scope wins when a theme class/attribute is toggled at runtime. */
|
|
241
|
+
:root.light,
|
|
242
|
+
:root[data-theme="light"],
|
|
243
|
+
.theme-light {
|
|
244
|
+
color-scheme: light;
|
|
245
|
+
--background: var(--brand-white);
|
|
246
|
+
--foreground: var(--brand-ink);
|
|
247
|
+
--card: var(--brand-white);
|
|
248
|
+
--card-foreground: var(--brand-ink);
|
|
249
|
+
--popover: var(--brand-white);
|
|
250
|
+
--popover-foreground: var(--brand-ink);
|
|
251
|
+
--primary: var(--brand-ink);
|
|
252
|
+
--primary-foreground: var(--brand-white);
|
|
253
|
+
--secondary: var(--brand-neutral-100);
|
|
254
|
+
--secondary-foreground: var(--brand-ink);
|
|
255
|
+
--muted: rgba(203, 213, 225, 0.25);
|
|
256
|
+
--muted-foreground: var(--brand-neutral-500);
|
|
257
|
+
--foreground-inverse: var(--brand-white);
|
|
258
|
+
--foreground-inverse-muted: rgba(255, 255, 255, 0.88);
|
|
259
|
+
--foreground-inverse-subtle: rgba(255, 255, 255, 0.84);
|
|
260
|
+
--accent: var(--brand-accent);
|
|
261
|
+
--accent-foreground: var(--brand-white);
|
|
262
|
+
--destructive: #b43f3f;
|
|
263
|
+
--destructive-foreground: var(--brand-white);
|
|
264
|
+
--border: var(--brand-border-subtle);
|
|
265
|
+
--input: rgba(15, 23, 42, 0.09);
|
|
266
|
+
--ring: rgba(74, 125, 189, 0.42);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@media (max-width: 640px) {
|
|
270
|
+
:root {
|
|
271
|
+
--space-card-pad-x: 1.25rem;
|
|
272
|
+
--space-copy-bottom: 1.75rem;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--font-weight-regular: 400;
|
|
3
|
+
/* Mulish weight 500 is not loaded; medium deliberately resolves to 600. */
|
|
4
|
+
--font-weight-medium: 600;
|
|
5
|
+
--font-weight-bold: 700;
|
|
6
|
+
--font-weight-heavy: 800;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@utility text-ui-micro {
|
|
10
|
+
font-family: var(--font-body), sans-serif;
|
|
11
|
+
font-size: var(--text-ui-micro);
|
|
12
|
+
font-weight: var(--font-weight-medium);
|
|
13
|
+
line-height: 1.3;
|
|
14
|
+
color: var(--muted-foreground);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@utility text-ui-label {
|
|
18
|
+
font-family: var(--font-body), sans-serif;
|
|
19
|
+
font-size: var(--text-ui-label);
|
|
20
|
+
font-weight: var(--font-weight-medium);
|
|
21
|
+
line-height: 1;
|
|
22
|
+
text-transform: uppercase;
|
|
23
|
+
letter-spacing: 0.14em;
|
|
24
|
+
color: var(--muted-foreground);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@utility text-ui-meta {
|
|
28
|
+
font-family: var(--font-body), sans-serif;
|
|
29
|
+
font-size: var(--text-ui-meta);
|
|
30
|
+
font-weight: var(--font-weight-regular);
|
|
31
|
+
line-height: 1.4;
|
|
32
|
+
color: var(--muted-foreground);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@utility text-ui-body {
|
|
36
|
+
font-family: var(--font-body), sans-serif;
|
|
37
|
+
font-size: var(--text-ui-body);
|
|
38
|
+
font-weight: var(--font-weight-regular);
|
|
39
|
+
line-height: 1.5;
|
|
40
|
+
color: var(--foreground);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@utility text-ui-card-title {
|
|
44
|
+
font-family: var(--font-body), sans-serif;
|
|
45
|
+
font-size: var(--text-ui-card-title);
|
|
46
|
+
font-weight: var(--font-weight-medium);
|
|
47
|
+
line-height: 1.3;
|
|
48
|
+
letter-spacing: -0.025em;
|
|
49
|
+
color: var(--foreground);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@utility text-ui-subhead {
|
|
53
|
+
font-family: var(--font-display), sans-serif;
|
|
54
|
+
font-size: var(--text-ui-subhead);
|
|
55
|
+
font-weight: var(--font-weight-bold);
|
|
56
|
+
line-height: 1.25;
|
|
57
|
+
letter-spacing: -0.02em;
|
|
58
|
+
color: var(--foreground);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@utility text-ui-panel-title {
|
|
62
|
+
font-family: var(--font-display), sans-serif;
|
|
63
|
+
font-size: var(--text-ui-panel-title);
|
|
64
|
+
font-weight: var(--font-weight-bold);
|
|
65
|
+
line-height: 1.2;
|
|
66
|
+
letter-spacing: -0.02em;
|
|
67
|
+
color: var(--foreground);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@utility text-ui-heading {
|
|
71
|
+
font-family: var(--font-display), sans-serif;
|
|
72
|
+
font-size: var(--text-ui-heading);
|
|
73
|
+
font-weight: var(--font-weight-bold);
|
|
74
|
+
line-height: 1.15;
|
|
75
|
+
letter-spacing: -0.02em;
|
|
76
|
+
color: var(--foreground);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@utility text-ui-title-sm {
|
|
80
|
+
font-family: var(--font-display), sans-serif;
|
|
81
|
+
font-size: var(--text-ui-title-sm);
|
|
82
|
+
font-weight: var(--font-weight-heavy);
|
|
83
|
+
line-height: 1.1;
|
|
84
|
+
letter-spacing: -0.03em;
|
|
85
|
+
color: var(--foreground);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@utility text-ui-title {
|
|
89
|
+
font-family: var(--font-display), sans-serif;
|
|
90
|
+
font-size: var(--text-ui-title);
|
|
91
|
+
font-weight: var(--font-weight-heavy);
|
|
92
|
+
line-height: 1.05;
|
|
93
|
+
letter-spacing: -0.03em;
|
|
94
|
+
color: var(--foreground);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@utility text-ui-metric {
|
|
98
|
+
font-family: var(--font-mono);
|
|
99
|
+
font-variant-numeric: tabular-nums;
|
|
100
|
+
font-size: var(--text-ui-metric);
|
|
101
|
+
font-weight: var(--font-weight-heavy);
|
|
102
|
+
line-height: 1;
|
|
103
|
+
letter-spacing: -0.04em;
|
|
104
|
+
color: var(--foreground);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@utility text-ui-metric-xl {
|
|
108
|
+
font-family: var(--font-display), sans-serif;
|
|
109
|
+
font-variant-numeric: tabular-nums;
|
|
110
|
+
font-size: var(--text-ui-metric-xl);
|
|
111
|
+
font-weight: var(--font-weight-heavy);
|
|
112
|
+
line-height: 0.95;
|
|
113
|
+
letter-spacing: -0.04em;
|
|
114
|
+
color: var(--foreground);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@utility text-ui-metric-display {
|
|
118
|
+
font-family: var(--font-display), sans-serif;
|
|
119
|
+
font-variant-numeric: tabular-nums;
|
|
120
|
+
font-size: var(--text-ui-metric-display);
|
|
121
|
+
font-weight: var(--font-weight-heavy);
|
|
122
|
+
line-height: 1;
|
|
123
|
+
letter-spacing: -0.04em;
|
|
124
|
+
color: var(--foreground);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/* Thin scrollbar for bounded surface lists. */
|
|
128
|
+
@utility scroll-thin {
|
|
129
|
+
overflow-y: auto;
|
|
130
|
+
overflow-y: overlay;
|
|
131
|
+
overflow-x: hidden;
|
|
132
|
+
scrollbar-width: thin;
|
|
133
|
+
scrollbar-color: color-mix(in srgb, var(--foreground) 18%, transparent) transparent;
|
|
134
|
+
|
|
135
|
+
&::-webkit-scrollbar {
|
|
136
|
+
width: 6px;
|
|
137
|
+
height: 6px;
|
|
138
|
+
}
|
|
139
|
+
&::-webkit-scrollbar-track {
|
|
140
|
+
background: transparent;
|
|
141
|
+
}
|
|
142
|
+
&::-webkit-scrollbar-thumb {
|
|
143
|
+
background-color: color-mix(in srgb, var(--foreground) 18%, transparent);
|
|
144
|
+
border-radius: 9999px;
|
|
145
|
+
}
|
|
146
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
147
|
+
background-color: color-mix(in srgb, var(--foreground) 30%, transparent);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* Legacy MQ primitive aliases for incremental consumer migration. */
|
|
2
|
+
:root {
|
|
3
|
+
--mq-ink-950: var(--brand-ink);
|
|
4
|
+
--mq-brand-500: var(--brand-accent);
|
|
5
|
+
--mq-brand-400: var(--brand-accent-soft);
|
|
6
|
+
--mq-neutral-500: var(--brand-neutral-500);
|
|
7
|
+
--mq-neutral-300: var(--brand-neutral-300);
|
|
8
|
+
--mq-neutral-200: var(--brand-neutral-200);
|
|
9
|
+
--mq-neutral-100: var(--brand-neutral-100);
|
|
10
|
+
--mq-white: var(--brand-white);
|
|
11
|
+
--mq-border-subtle: var(--brand-border-subtle);
|
|
12
|
+
--mq-surface-tint: var(--brand-surface-tint);
|
|
13
|
+
--mq-surface-dark: var(--brand-surface-dark);
|
|
14
|
+
--mq-shadow-soft: var(--brand-shadow-soft);
|
|
15
|
+
--mq-shadow-lift: var(--brand-shadow-lift);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@utility portal-micro {
|
|
19
|
+
font-family: var(--font-body), sans-serif;
|
|
20
|
+
font-size: var(--text-ui-micro);
|
|
21
|
+
font-weight: var(--font-weight-medium);
|
|
22
|
+
line-height: 1.3;
|
|
23
|
+
color: var(--muted-foreground);
|
|
24
|
+
}
|
|
25
|
+
@utility portal-label {
|
|
26
|
+
font-family: var(--font-body), sans-serif;
|
|
27
|
+
font-size: var(--text-ui-label);
|
|
28
|
+
font-weight: var(--font-weight-medium);
|
|
29
|
+
line-height: 1;
|
|
30
|
+
text-transform: uppercase;
|
|
31
|
+
letter-spacing: 0.14em;
|
|
32
|
+
color: var(--muted-foreground);
|
|
33
|
+
}
|
|
34
|
+
@utility portal-meta {
|
|
35
|
+
font-family: var(--font-body), sans-serif;
|
|
36
|
+
font-size: var(--text-ui-meta);
|
|
37
|
+
font-weight: var(--font-weight-regular);
|
|
38
|
+
line-height: 1.4;
|
|
39
|
+
color: var(--muted-foreground);
|
|
40
|
+
}
|
|
41
|
+
@utility portal-body {
|
|
42
|
+
font-family: var(--font-body), sans-serif;
|
|
43
|
+
font-size: var(--text-ui-body);
|
|
44
|
+
font-weight: var(--font-weight-regular);
|
|
45
|
+
line-height: 1.5;
|
|
46
|
+
color: var(--foreground);
|
|
47
|
+
}
|
|
48
|
+
@utility portal-card-title {
|
|
49
|
+
font-family: var(--font-body), sans-serif;
|
|
50
|
+
font-size: var(--text-ui-card-title);
|
|
51
|
+
font-weight: var(--font-weight-medium);
|
|
52
|
+
line-height: 1.3;
|
|
53
|
+
letter-spacing: -0.025em;
|
|
54
|
+
color: var(--foreground);
|
|
55
|
+
}
|
|
56
|
+
@utility portal-subhead {
|
|
57
|
+
font-family: var(--font-display), sans-serif;
|
|
58
|
+
font-size: var(--text-ui-subhead);
|
|
59
|
+
font-weight: var(--font-weight-bold);
|
|
60
|
+
line-height: 1.25;
|
|
61
|
+
letter-spacing: -0.02em;
|
|
62
|
+
color: var(--foreground);
|
|
63
|
+
}
|
|
64
|
+
@utility portal-panel-title {
|
|
65
|
+
font-family: var(--font-display), sans-serif;
|
|
66
|
+
font-size: var(--text-ui-panel-title);
|
|
67
|
+
font-weight: var(--font-weight-bold);
|
|
68
|
+
line-height: 1.2;
|
|
69
|
+
letter-spacing: -0.02em;
|
|
70
|
+
color: var(--foreground);
|
|
71
|
+
}
|
|
72
|
+
@utility portal-heading {
|
|
73
|
+
font-family: var(--font-display), sans-serif;
|
|
74
|
+
font-size: var(--text-ui-heading);
|
|
75
|
+
font-weight: var(--font-weight-bold);
|
|
76
|
+
line-height: 1.15;
|
|
77
|
+
letter-spacing: -0.02em;
|
|
78
|
+
color: var(--foreground);
|
|
79
|
+
}
|
|
80
|
+
@utility portal-title-sm {
|
|
81
|
+
font-family: var(--font-display), sans-serif;
|
|
82
|
+
font-size: var(--text-ui-title-sm);
|
|
83
|
+
font-weight: var(--font-weight-heavy);
|
|
84
|
+
line-height: 1.1;
|
|
85
|
+
letter-spacing: -0.03em;
|
|
86
|
+
color: var(--foreground);
|
|
87
|
+
}
|
|
88
|
+
@utility portal-title {
|
|
89
|
+
font-family: var(--font-display), sans-serif;
|
|
90
|
+
font-size: var(--text-ui-title);
|
|
91
|
+
font-weight: var(--font-weight-heavy);
|
|
92
|
+
line-height: 1.05;
|
|
93
|
+
letter-spacing: -0.03em;
|
|
94
|
+
color: var(--foreground);
|
|
95
|
+
}
|
|
96
|
+
@utility portal-metric {
|
|
97
|
+
font-family: var(--font-mono);
|
|
98
|
+
font-variant-numeric: tabular-nums;
|
|
99
|
+
font-size: var(--text-ui-metric);
|
|
100
|
+
font-weight: var(--font-weight-heavy);
|
|
101
|
+
line-height: 1;
|
|
102
|
+
letter-spacing: -0.04em;
|
|
103
|
+
color: var(--foreground);
|
|
104
|
+
}
|
|
105
|
+
@utility portal-metric-xl {
|
|
106
|
+
font-family: var(--font-display), sans-serif;
|
|
107
|
+
font-variant-numeric: tabular-nums;
|
|
108
|
+
font-size: var(--text-ui-metric-xl);
|
|
109
|
+
font-weight: var(--font-weight-heavy);
|
|
110
|
+
line-height: 0.95;
|
|
111
|
+
letter-spacing: -0.04em;
|
|
112
|
+
color: var(--foreground);
|
|
113
|
+
}
|
|
114
|
+
@utility portal-metric-display {
|
|
115
|
+
font-family: var(--font-display), sans-serif;
|
|
116
|
+
font-variant-numeric: tabular-nums;
|
|
117
|
+
font-size: var(--text-ui-metric-display);
|
|
118
|
+
font-weight: var(--font-weight-heavy);
|
|
119
|
+
line-height: 1;
|
|
120
|
+
letter-spacing: -0.04em;
|
|
121
|
+
color: var(--foreground);
|
|
122
|
+
}
|
|
123
|
+
@utility portal-scroll {
|
|
124
|
+
overflow-y: auto;
|
|
125
|
+
overflow-y: overlay;
|
|
126
|
+
overflow-x: hidden;
|
|
127
|
+
scrollbar-width: thin;
|
|
128
|
+
scrollbar-color: color-mix(in srgb, var(--foreground) 18%, transparent) transparent;
|
|
129
|
+
|
|
130
|
+
&::-webkit-scrollbar { width: 6px; height: 6px; }
|
|
131
|
+
&::-webkit-scrollbar-track { background: transparent; }
|
|
132
|
+
&::-webkit-scrollbar-thumb {
|
|
133
|
+
background-color: color-mix(in srgb, var(--foreground) 18%, transparent);
|
|
134
|
+
border-radius: 9999px;
|
|
135
|
+
}
|
|
136
|
+
&::-webkit-scrollbar-thumb:hover {
|
|
137
|
+
background-color: color-mix(in srgb, var(--foreground) 30%, transparent);
|
|
138
|
+
}
|
|
139
|
+
}
|
package/themes/mq.css
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/* MQ compatibility palette. Import after @brightweblabs/theme/css. */
|
|
2
|
+
:root {
|
|
3
|
+
--brand-accent: #5bc5f2;
|
|
4
|
+
--brand-accent-soft: #6fc4e7;
|
|
5
|
+
--brand-ink: #0a151a;
|
|
6
|
+
--brand-neutral-500: #8e8f9a;
|
|
7
|
+
--brand-neutral-300: #bfc0cf;
|
|
8
|
+
--brand-neutral-200: #e9e9e9;
|
|
9
|
+
--brand-neutral-100: #f4f8fb;
|
|
10
|
+
--brand-white: #ffffff;
|
|
11
|
+
--brand-border-subtle: rgba(10, 21, 26, 0.09);
|
|
12
|
+
--brand-surface-tint: rgba(91, 197, 242, 0.08);
|
|
13
|
+
--brand-surface-dark: rgba(10, 21, 26, 0.94);
|
|
14
|
+
--brand-shadow-soft: 0 20px 44px rgba(10, 21, 26, 0.1);
|
|
15
|
+
--brand-shadow-lift: 0 15px 20px rgba(84, 84, 84, 0.5);
|
|
16
|
+
|
|
17
|
+
--background: var(--brand-white);
|
|
18
|
+
--foreground: var(--brand-ink);
|
|
19
|
+
--card: var(--brand-white);
|
|
20
|
+
--card-foreground: var(--brand-ink);
|
|
21
|
+
--popover: var(--brand-white);
|
|
22
|
+
--popover-foreground: var(--brand-ink);
|
|
23
|
+
--primary: var(--brand-ink);
|
|
24
|
+
--primary-foreground: var(--brand-white);
|
|
25
|
+
--secondary: var(--brand-neutral-100);
|
|
26
|
+
--secondary-foreground: var(--brand-ink);
|
|
27
|
+
--muted: rgba(191, 192, 207, 0.18);
|
|
28
|
+
--muted-foreground: var(--brand-neutral-500);
|
|
29
|
+
--foreground-inverse: var(--brand-white);
|
|
30
|
+
--foreground-inverse-muted: rgba(255, 255, 255, 0.88);
|
|
31
|
+
--foreground-inverse-subtle: rgba(255, 255, 255, 0.84);
|
|
32
|
+
--accent: var(--brand-accent);
|
|
33
|
+
--accent-foreground: var(--brand-ink);
|
|
34
|
+
--destructive: #b43f3f;
|
|
35
|
+
--destructive-foreground: var(--brand-white);
|
|
36
|
+
--border: var(--brand-border-subtle);
|
|
37
|
+
--input: rgba(10, 21, 26, 0.08);
|
|
38
|
+
--ring: rgba(91, 197, 242, 0.42);
|
|
39
|
+
|
|
40
|
+
--role-client: #3b82f6;
|
|
41
|
+
--role-client-strong: #1e40af;
|
|
42
|
+
--role-team: #0d9488;
|
|
43
|
+
--role-team-strong: #0f766e;
|
|
44
|
+
--role-admin: #7c3aed;
|
|
45
|
+
--role-admin-strong: #6d28d9;
|
|
46
|
+
--role-manager: #d97706;
|
|
47
|
+
--role-manager-strong: #b45309;
|
|
48
|
+
--badge-count-fg: #ffffff;
|
|
49
|
+
--on-fill-danger: #ffffff;
|
|
50
|
+
--on-fill-warning: #3a2a05;
|
|
51
|
+
--on-fill-success: #06281e;
|
|
52
|
+
|
|
53
|
+
--page-background:
|
|
54
|
+
radial-gradient(circle at top left, rgba(91, 197, 242, 0.12), transparent 24%),
|
|
55
|
+
linear-gradient(180deg, #ffffff 0%, #f7fbff 54%, #ffffff 100%);
|
|
56
|
+
--brand-panel-surface: linear-gradient(158deg, #02070d 0%, #06111c 30%, #071d2b 63%, #123747 100%);
|
|
57
|
+
--brand-panel-surface-raised: #0b2634;
|
|
58
|
+
--brand-panel-foreground: #f6fbff;
|
|
59
|
+
--brand-panel-muted: rgba(246, 251, 255, 0.66);
|
|
60
|
+
--brand-panel-subtle: rgba(246, 251, 255, 0.46);
|
|
61
|
+
--brand-panel-border: rgba(145, 211, 241, 0.2);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:root.dark,
|
|
65
|
+
:root[data-theme="dark"],
|
|
66
|
+
.theme-dark {
|
|
67
|
+
--brand-accent: #5bc5f2;
|
|
68
|
+
--brand-accent-soft: #6fc4e7;
|
|
69
|
+
--brand-ink: #061118;
|
|
70
|
+
--brand-neutral-500: #9ca5b5;
|
|
71
|
+
--brand-neutral-300: #c9d5e6;
|
|
72
|
+
--brand-neutral-200: #dee6f2;
|
|
73
|
+
--brand-neutral-100: #0f1b25;
|
|
74
|
+
--brand-white: #ffffff;
|
|
75
|
+
--brand-border-subtle: rgba(153, 184, 206, 0.26);
|
|
76
|
+
--brand-surface-tint: rgba(91, 197, 242, 0.08);
|
|
77
|
+
--brand-surface-dark: rgba(10, 21, 26, 0.94);
|
|
78
|
+
--brand-shadow-soft: 0 20px 44px rgba(0, 0, 0, 0.45);
|
|
79
|
+
--brand-shadow-lift: 0 16px 44px rgba(0, 0, 0, 0.5);
|
|
80
|
+
|
|
81
|
+
--background: #08131b;
|
|
82
|
+
--foreground: #edf6ff;
|
|
83
|
+
--card: #0d1d29;
|
|
84
|
+
--card-foreground: #edf6ff;
|
|
85
|
+
--popover: #0c1a25;
|
|
86
|
+
--popover-foreground: #edf6ff;
|
|
87
|
+
--primary: #edf6ff;
|
|
88
|
+
--primary-foreground: #08131b;
|
|
89
|
+
--secondary: #112433;
|
|
90
|
+
--secondary-foreground: #dceaf7;
|
|
91
|
+
--muted: rgba(132, 170, 198, 0.16);
|
|
92
|
+
--muted-foreground: #9eb6cd;
|
|
93
|
+
--foreground-inverse: #f7fbff;
|
|
94
|
+
--foreground-inverse-muted: rgba(247, 251, 255, 0.9);
|
|
95
|
+
--foreground-inverse-subtle: rgba(247, 251, 255, 0.84);
|
|
96
|
+
--accent: #7bd8ff;
|
|
97
|
+
--accent-foreground: #061118;
|
|
98
|
+
--destructive: #d26969;
|
|
99
|
+
--destructive-foreground: #08131c;
|
|
100
|
+
--border: rgba(132, 170, 198, 0.22);
|
|
101
|
+
--input: rgba(132, 170, 198, 0.16);
|
|
102
|
+
--ring: rgba(123, 216, 255, 0.38);
|
|
103
|
+
|
|
104
|
+
--semantic-info: #38bdf8;
|
|
105
|
+
--semantic-info-strong: #7dd3fc;
|
|
106
|
+
--semantic-special: #a78bfa;
|
|
107
|
+
--semantic-special-strong: #ddd6fe;
|
|
108
|
+
--semantic-warning: #fbbf24;
|
|
109
|
+
--semantic-warning-strong: #fde68a;
|
|
110
|
+
--semantic-success: #34d399;
|
|
111
|
+
--semantic-success-strong: #a7f3d0;
|
|
112
|
+
--semantic-danger: #fb7185;
|
|
113
|
+
--semantic-danger-strong: #fecdd3;
|
|
114
|
+
--semantic-danger-soft: #fda4af;
|
|
115
|
+
--semantic-neutral: #a1a1aa;
|
|
116
|
+
--semantic-neutral-strong: #d4d4d8;
|
|
117
|
+
--role-client: #60a5fa;
|
|
118
|
+
--role-client-strong: #bfdbfe;
|
|
119
|
+
--role-team: #2dd4bf;
|
|
120
|
+
--role-team-strong: #99f6e4;
|
|
121
|
+
--role-admin: #a78bfa;
|
|
122
|
+
--role-admin-strong: #ddd6fe;
|
|
123
|
+
--role-manager: #fbbf24;
|
|
124
|
+
--role-manager-strong: #fde68a;
|
|
125
|
+
--badge-count-fg: #ffffff;
|
|
126
|
+
--on-fill-danger: #350a11;
|
|
127
|
+
--on-fill-warning: #3a2a05;
|
|
128
|
+
--on-fill-success: #06281e;
|
|
129
|
+
|
|
130
|
+
--page-background:
|
|
131
|
+
radial-gradient(circle at 14% 12%, rgba(123, 216, 255, 0.17), transparent 26%),
|
|
132
|
+
radial-gradient(circle at 82% 18%, rgba(54, 123, 164, 0.18), transparent 24%),
|
|
133
|
+
linear-gradient(180deg, #071119 0%, #0b1621 48%, #08121c 100%);
|
|
134
|
+
--brand-panel-surface: linear-gradient(158deg, #0c2433 0%, #143b4e 52%, #1b4f66 100%);
|
|
135
|
+
--brand-panel-surface-raised: #0b2634;
|
|
136
|
+
--brand-panel-foreground: #f6fbff;
|
|
137
|
+
--brand-panel-muted: rgba(246, 251, 255, 0.66);
|
|
138
|
+
--brand-panel-subtle: rgba(246, 251, 255, 0.46);
|
|
139
|
+
--brand-panel-border: color-mix(in srgb, var(--accent) 20%, transparent);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:root.light,
|
|
143
|
+
:root[data-theme="light"],
|
|
144
|
+
.theme-light {
|
|
145
|
+
--brand-accent: #5bc5f2;
|
|
146
|
+
--brand-accent-soft: #6fc4e7;
|
|
147
|
+
--brand-ink: #0a151a;
|
|
148
|
+
--brand-neutral-500: #8e8f9a;
|
|
149
|
+
--brand-neutral-300: #bfc0cf;
|
|
150
|
+
--brand-neutral-200: #e9e9e9;
|
|
151
|
+
--brand-neutral-100: #f4f8fb;
|
|
152
|
+
--brand-white: #ffffff;
|
|
153
|
+
--brand-border-subtle: rgba(10, 21, 26, 0.09);
|
|
154
|
+
--brand-surface-tint: rgba(91, 197, 242, 0.08);
|
|
155
|
+
--brand-surface-dark: rgba(10, 21, 26, 0.94);
|
|
156
|
+
--brand-shadow-soft: 0 20px 44px rgba(10, 21, 26, 0.1);
|
|
157
|
+
--brand-shadow-lift: 0 15px 20px rgba(84, 84, 84, 0.5);
|
|
158
|
+
--background: var(--brand-white);
|
|
159
|
+
--foreground: var(--brand-ink);
|
|
160
|
+
--card: var(--brand-white);
|
|
161
|
+
--card-foreground: var(--brand-ink);
|
|
162
|
+
--popover: var(--brand-white);
|
|
163
|
+
--popover-foreground: var(--brand-ink);
|
|
164
|
+
--primary: var(--brand-ink);
|
|
165
|
+
--primary-foreground: var(--brand-white);
|
|
166
|
+
--secondary: var(--brand-neutral-100);
|
|
167
|
+
--secondary-foreground: var(--brand-ink);
|
|
168
|
+
--muted: rgba(191, 192, 207, 0.18);
|
|
169
|
+
--muted-foreground: var(--brand-neutral-500);
|
|
170
|
+
--accent: var(--brand-accent);
|
|
171
|
+
--accent-foreground: var(--brand-ink);
|
|
172
|
+
--destructive: #b43f3f;
|
|
173
|
+
--destructive-foreground: var(--brand-white);
|
|
174
|
+
--border: var(--brand-border-subtle);
|
|
175
|
+
--input: rgba(10, 21, 26, 0.08);
|
|
176
|
+
--ring: rgba(91, 197, 242, 0.42);
|
|
177
|
+
}
|