@efolusi/meridian 1.5.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/README.md +12 -0
- package/ai/AgentRun.d.ts +20 -0
- package/ai/AgentRun.js +100 -0
- package/ai/ChatMessage.d.ts +19 -0
- package/ai/ChatMessage.js +81 -0
- package/ai/Citation.d.ts +23 -0
- package/ai/Citation.js +146 -0
- package/ai/Confirmation.d.ts +26 -0
- package/ai/Confirmation.js +84 -0
- package/ai/Conversation.d.ts +15 -0
- package/ai/Conversation.js +81 -0
- package/ai/DocumentCard.d.ts +17 -0
- package/ai/DocumentCard.js +101 -0
- package/ai/FeedbackBar.d.ts +14 -0
- package/ai/FeedbackBar.js +84 -0
- package/ai/GeneratedImage.d.ts +22 -0
- package/ai/GeneratedImage.js +100 -0
- package/ai/ModelSelector.d.ts +21 -0
- package/ai/ModelSelector.js +112 -0
- package/ai/Player.d.ts +18 -0
- package/ai/Player.js +201 -0
- package/ai/PromptComposer.d.ts +28 -0
- package/ai/PromptComposer.js +111 -0
- package/ai/PromptSteps.d.ts +18 -0
- package/ai/PromptSteps.js +167 -0
- package/ai/Reasoning.d.ts +17 -0
- package/ai/Reasoning.js +57 -0
- package/ai/RichComposer.d.ts +25 -0
- package/ai/RichComposer.js +247 -0
- package/ai/Sandbox.d.ts +20 -0
- package/ai/Sandbox.js +96 -0
- package/ai/SelectionQuote.d.ts +15 -0
- package/ai/SelectionQuote.js +123 -0
- package/ai/SourceCard.d.ts +17 -0
- package/ai/SourceCard.js +57 -0
- package/ai/Suggestions.d.ts +10 -0
- package/ai/Suggestions.js +38 -0
- package/ai/Task.d.ts +15 -0
- package/ai/Task.js +49 -0
- package/ai/Todo.d.ts +13 -0
- package/ai/Todo.js +87 -0
- package/ai/ToolCall.d.ts +30 -0
- package/ai/ToolCall.js +147 -0
- package/ai/Transcript.d.ts +27 -0
- package/ai/Transcript.js +96 -0
- package/ai/UsageMeter.d.ts +21 -0
- package/ai/UsageMeter.js +81 -0
- package/ai/WebPreview.d.ts +19 -0
- package/ai/WebPreview.js +179 -0
- package/assets/fonts/BricolageGrotesque-Variable.ttf +0 -0
- package/assets/fonts/Figtree-Italic-Variable.ttf +0 -0
- package/assets/fonts/Figtree-Variable.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Italic-Variable.ttf +0 -0
- package/assets/fonts/JetBrainsMono-Variable.ttf +0 -0
- package/assets/fonts/OFL-BricolageGrotesque.txt +93 -0
- package/assets/fonts/OFL-Figtree.txt +93 -0
- package/assets/fonts/OFL-JetBrainsMono.txt +93 -0
- package/code/CodeBlock.d.ts +17 -0
- package/code/CodeBlock.js +99 -0
- package/code/Console.d.ts +19 -0
- package/code/Console.js +124 -0
- package/code/CopyField.d.ts +10 -0
- package/code/CopyField.js +54 -0
- package/code/Diff.d.ts +26 -0
- package/code/Diff.js +358 -0
- package/code/EnvList.d.ts +14 -0
- package/code/EnvList.js +89 -0
- package/code/Exception.d.ts +25 -0
- package/code/Exception.js +90 -0
- package/code/Terminal.d.ts +20 -0
- package/code/Terminal.js +58 -0
- package/data/BarChart.d.ts +14 -0
- package/data/BarChart.js +44 -0
- package/data/DonutChart.d.ts +17 -0
- package/data/DonutChart.js +114 -0
- package/data/EmptyState.d.ts +13 -0
- package/data/EmptyState.js +39 -0
- package/data/KeyValueList.d.ts +14 -0
- package/data/KeyValueList.js +34 -0
- package/data/LineChart.d.ts +15 -0
- package/data/LineChart.js +85 -0
- package/data/Skeleton.d.ts +11 -0
- package/data/Skeleton.js +49 -0
- package/data/Sparkline.d.ts +14 -0
- package/data/Sparkline.js +42 -0
- package/data/Stat.d.ts +14 -0
- package/data/Stat.js +40 -0
- package/data/StatusDot.d.ts +10 -0
- package/data/StatusDot.js +34 -0
- package/data/Table.d.ts +53 -0
- package/data/Table.js +174 -0
- package/dates/Calendar.d.ts +8 -0
- package/dates/Calendar.js +143 -0
- package/dates/DatePicker.d.ts +12 -0
- package/dates/DatePicker.js +118 -0
- package/display/Accordion.d.ts +15 -0
- package/display/Accordion.js +52 -0
- package/display/AspectRatio.d.ts +8 -0
- package/display/AspectRatio.js +24 -0
- package/display/Avatar.d.ts +17 -0
- package/display/Avatar.js +52 -0
- package/display/Badge.d.ts +10 -0
- package/display/Badge.js +34 -0
- package/display/Card.d.ts +17 -0
- package/display/Card.js +51 -0
- package/display/Carousel.d.ts +16 -0
- package/display/Carousel.js +97 -0
- package/display/Collapsible.d.ts +12 -0
- package/display/Collapsible.js +46 -0
- package/display/Divider.d.ts +9 -0
- package/display/Divider.js +33 -0
- package/display/Kbd.d.ts +7 -0
- package/display/Kbd.js +18 -0
- package/display/Link.d.ts +12 -0
- package/display/Link.js +41 -0
- package/display/ListItem.d.ts +19 -0
- package/display/ListItem.js +61 -0
- package/display/Resizable.d.ts +16 -0
- package/display/Resizable.js +90 -0
- package/display/ScrollArea.d.ts +8 -0
- package/display/ScrollArea.js +28 -0
- package/display/Tag.d.ts +9 -0
- package/display/Tag.js +41 -0
- package/display/Toolbar.d.ts +22 -0
- package/display/Toolbar.js +55 -0
- package/display/TreeList.d.ts +20 -0
- package/display/TreeList.js +101 -0
- package/feedback/Alert.d.ts +14 -0
- package/feedback/Alert.js +56 -0
- package/feedback/Banner.d.ts +15 -0
- package/feedback/Banner.js +49 -0
- package/feedback/ConfirmDialog.d.ts +18 -0
- package/feedback/ConfirmDialog.js +49 -0
- package/feedback/Dialog.d.ts +13 -0
- package/feedback/Dialog.js +107 -0
- package/feedback/Loader.d.ts +12 -0
- package/feedback/Loader.js +41 -0
- package/feedback/Progress.d.ts +15 -0
- package/feedback/Progress.js +48 -0
- package/feedback/Spinner.d.ts +9 -0
- package/feedback/Spinner.js +38 -0
- package/feedback/Toast.d.ts +70 -0
- package/feedback/Toast.js +216 -0
- package/feedback/Tooltip.d.ts +12 -0
- package/feedback/Tooltip.js +86 -0
- package/files/FileDrop.d.ts +15 -0
- package/files/FileDrop.js +75 -0
- package/files/FileTile.d.ts +19 -0
- package/files/FileTile.js +96 -0
- package/files/FileTypeIcon.d.ts +11 -0
- package/files/FileTypeIcon.js +121 -0
- package/finance/PaymentCard.d.ts +17 -0
- package/finance/PaymentCard.js +109 -0
- package/forms/Button.d.ts +15 -0
- package/forms/Button.js +82 -0
- package/forms/ButtonGroup.d.ts +5 -0
- package/forms/ButtonGroup.js +22 -0
- package/forms/ButtonTile.d.ts +21 -0
- package/forms/ButtonTile.js +69 -0
- package/forms/Checkbox.d.ts +6 -0
- package/forms/Checkbox.js +52 -0
- package/forms/Combobox.d.ts +17 -0
- package/forms/Combobox.js +162 -0
- package/forms/DigitEntry.d.ts +15 -0
- package/forms/DigitEntry.js +88 -0
- package/forms/FormField.d.ts +39 -0
- package/forms/FormField.js +127 -0
- package/forms/IconButton.d.ts +11 -0
- package/forms/IconButton.js +41 -0
- package/forms/Input.d.ts +14 -0
- package/forms/Input.js +75 -0
- package/forms/InputGroup.d.ts +15 -0
- package/forms/InputGroup.js +59 -0
- package/forms/Label.d.ts +11 -0
- package/forms/Label.js +29 -0
- package/forms/Radio.d.ts +6 -0
- package/forms/Radio.js +46 -0
- package/forms/Select.d.ts +10 -0
- package/forms/Select.js +68 -0
- package/forms/Slider.d.ts +18 -0
- package/forms/Slider.js +75 -0
- package/forms/Switch.d.ts +6 -0
- package/forms/Switch.js +46 -0
- package/forms/Textarea.d.ts +8 -0
- package/forms/Textarea.js +58 -0
- package/forms/Toggle.d.ts +26 -0
- package/forms/Toggle.js +85 -0
- package/icons/Icon.d.ts +13 -0
- package/icons/Icon.js +54 -0
- package/index.d.ts +106 -0
- package/index.js +106 -0
- package/navigation/Breadcrumbs.d.ts +12 -0
- package/navigation/Breadcrumbs.js +41 -0
- package/navigation/Menubar.d.ts +10 -0
- package/navigation/Menubar.js +173 -0
- package/navigation/PageControl.d.ts +11 -0
- package/navigation/PageControl.js +36 -0
- package/navigation/Pagination.d.ts +9 -0
- package/navigation/Pagination.js +68 -0
- package/navigation/SegmentedControl.d.ts +17 -0
- package/navigation/SegmentedControl.js +42 -0
- package/navigation/SideNav.d.ts +18 -0
- package/navigation/SideNav.js +87 -0
- package/navigation/Steps.d.ts +15 -0
- package/navigation/Steps.js +61 -0
- package/navigation/Tabs.d.ts +17 -0
- package/navigation/Tabs.js +76 -0
- package/navigation/TopNav.d.ts +10 -0
- package/navigation/TopNav.js +26 -0
- package/overlay/CommandPalette.d.ts +21 -0
- package/overlay/CommandPalette.js +164 -0
- package/overlay/ContextMenu.d.ts +11 -0
- package/overlay/ContextMenu.js +140 -0
- package/overlay/Drawer.d.ts +14 -0
- package/overlay/Drawer.js +99 -0
- package/overlay/HoverCard.d.ts +17 -0
- package/overlay/HoverCard.js +74 -0
- package/overlay/Menu.d.ts +24 -0
- package/overlay/Menu.js +153 -0
- package/overlay/Popover.d.ts +16 -0
- package/overlay/Popover.js +96 -0
- package/overlay/Portal.d.ts +10 -0
- package/overlay/Portal.js +127 -0
- package/package.json +41 -0
- package/styles.css +6 -0
- package/tokens/base.css +10 -0
- package/tokens/colors.css +38 -0
- package/tokens/effects.css +22 -0
- package/tokens/fonts.css +5 -0
- package/tokens/spacing.css +12 -0
- package/tokens/typography.css +9 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
// Bare imports are stripped by the bundle compiler, so this resolves to the
|
|
3
|
+
// window global there; in an ESM consumer it resolves normally. Both work.
|
|
4
|
+
import ReactDOM from 'react-dom';
|
|
5
|
+
import { injectEfCss } from "../forms/Button.js";
|
|
6
|
+
const CSS = `
|
|
7
|
+
.ef-portal{position:fixed;top:0;left:0;width:0;height:0}
|
|
8
|
+
`;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Renders children into document.body (or `container`).
|
|
12
|
+
*
|
|
13
|
+
* Every floating surface needs this. An overlay positioned inside its trigger's
|
|
14
|
+
* subtree is clipped by the first ancestor with overflow:auto|hidden — which in
|
|
15
|
+
* practice is the scrolling table, drawer, or card it was opened from.
|
|
16
|
+
*/
|
|
17
|
+
export function Portal({
|
|
18
|
+
children,
|
|
19
|
+
container
|
|
20
|
+
}) {
|
|
21
|
+
injectEfCss('ef-css-portal', CSS);
|
|
22
|
+
const hostRef = React.useRef(null);
|
|
23
|
+
if (hostRef.current === null && typeof document !== 'undefined') {
|
|
24
|
+
hostRef.current = document.createElement('div');
|
|
25
|
+
hostRef.current.className = 'ef-portal';
|
|
26
|
+
}
|
|
27
|
+
// Children mount into the host on the first render, while it is still detached,
|
|
28
|
+
// and this layout effect attaches it before paint. Gating the render on a
|
|
29
|
+
// "mounted" state instead would leave the panel absent when the parent measures
|
|
30
|
+
// it for placement, which puts every anchored overlay at the viewport origin.
|
|
31
|
+
React.useLayoutEffect(() => {
|
|
32
|
+
const host = hostRef.current;
|
|
33
|
+
if (!host) return;
|
|
34
|
+
const parent = container || document.body;
|
|
35
|
+
parent.appendChild(host);
|
|
36
|
+
return () => {
|
|
37
|
+
if (host.parentNode) host.parentNode.removeChild(host);
|
|
38
|
+
};
|
|
39
|
+
}, [container]);
|
|
40
|
+
if (!hostRef.current) return null;
|
|
41
|
+
return /*#__PURE__*/ReactDOM.createPortal(children, hostRef.current);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Position a portaled panel against its anchor, in viewport coordinates.
|
|
46
|
+
*
|
|
47
|
+
* Flips to the opposite side when the preferred one would overflow, then shifts
|
|
48
|
+
* along the cross axis to stay on screen. Returns { style, side } — the panel is
|
|
49
|
+
* hidden for the first frame so the measurement never flashes, and `side` is the
|
|
50
|
+
* placement actually resolved, which a caller drawing an arrow has to know.
|
|
51
|
+
*
|
|
52
|
+
* Not exported on the namespace — it is a building block for the overlay
|
|
53
|
+
* components, and is only useful with a panel ref you already control.
|
|
54
|
+
*/
|
|
55
|
+
export function useAnchoredStyle(anchorRef, panelRef, {
|
|
56
|
+
open,
|
|
57
|
+
placement = 'bottom',
|
|
58
|
+
align = 'start',
|
|
59
|
+
offset = 6,
|
|
60
|
+
matchWidth = false
|
|
61
|
+
} = {}) {
|
|
62
|
+
const [state, setState] = React.useState({
|
|
63
|
+
style: {
|
|
64
|
+
position: 'fixed',
|
|
65
|
+
top: 0,
|
|
66
|
+
left: 0,
|
|
67
|
+
visibility: 'hidden'
|
|
68
|
+
},
|
|
69
|
+
side: placement
|
|
70
|
+
});
|
|
71
|
+
React.useLayoutEffect(() => {
|
|
72
|
+
if (!open) {
|
|
73
|
+
setState(s => s.style.visibility === 'hidden' ? s : {
|
|
74
|
+
...s,
|
|
75
|
+
style: {
|
|
76
|
+
...s.style,
|
|
77
|
+
visibility: 'hidden'
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const place = () => {
|
|
83
|
+
const anchor = anchorRef.current;
|
|
84
|
+
const panel = panelRef.current;
|
|
85
|
+
if (!anchor || !panel) return;
|
|
86
|
+
const a = anchor.getBoundingClientRect();
|
|
87
|
+
const p = panel.getBoundingClientRect();
|
|
88
|
+
const vw = document.documentElement.clientWidth;
|
|
89
|
+
const vh = document.documentElement.clientHeight;
|
|
90
|
+
const edge = 8;
|
|
91
|
+
const roomBelow = vh - a.bottom - offset;
|
|
92
|
+
const roomAbove = a.top - offset;
|
|
93
|
+
const wantsTop = placement === 'top';
|
|
94
|
+
const side = wantsTop ? roomAbove >= p.height || roomAbove >= roomBelow ? 'top' : 'bottom' : roomBelow >= p.height || roomBelow >= roomAbove ? 'bottom' : 'top';
|
|
95
|
+
|
|
96
|
+
// a width-matched panel (a listbox under its input) is measured at the
|
|
97
|
+
// anchor's width, not its own, or the clamp below uses the wrong number
|
|
98
|
+
const width = matchWidth ? a.width : p.width;
|
|
99
|
+
let top = side === 'bottom' ? a.bottom + offset : a.top - offset - p.height;
|
|
100
|
+
let left = align === 'end' ? a.right - width : align === 'center' ? a.left + a.width / 2 - width / 2 : a.left;
|
|
101
|
+
left = Math.max(edge, Math.min(left, vw - width - edge));
|
|
102
|
+
top = Math.max(edge, Math.min(top, vh - p.height - edge));
|
|
103
|
+
const next = {
|
|
104
|
+
position: 'fixed',
|
|
105
|
+
top: Math.round(top),
|
|
106
|
+
left: Math.round(left),
|
|
107
|
+
right: 'auto',
|
|
108
|
+
bottom: 'auto',
|
|
109
|
+
visibility: 'visible'
|
|
110
|
+
};
|
|
111
|
+
if (matchWidth) next.width = Math.round(a.width);
|
|
112
|
+
setState({
|
|
113
|
+
style: next,
|
|
114
|
+
side
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
place();
|
|
118
|
+
// capture phase: any scrolling ancestor moves the anchor, not just the window
|
|
119
|
+
window.addEventListener('scroll', place, true);
|
|
120
|
+
window.addEventListener('resize', place);
|
|
121
|
+
return () => {
|
|
122
|
+
window.removeEventListener('scroll', place, true);
|
|
123
|
+
window.removeEventListener('resize', place);
|
|
124
|
+
};
|
|
125
|
+
}, [open, placement, align, offset, matchWidth, anchorRef, panelRef]);
|
|
126
|
+
return state;
|
|
127
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@efolusi/meridian",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "A general-purpose open-source design system by Efolusi: accessible React components, design tokens, blocks and example apps.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://meridian.efolusi.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/efolusi/meridian.git"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": [
|
|
13
|
+
"*.css"
|
|
14
|
+
],
|
|
15
|
+
"main": "./index.js",
|
|
16
|
+
"types": "./index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./index.d.ts",
|
|
20
|
+
"default": "./index.js"
|
|
21
|
+
},
|
|
22
|
+
"./styles.css": "./styles.css",
|
|
23
|
+
"./tokens/*": "./tokens/*",
|
|
24
|
+
"./*": {
|
|
25
|
+
"types": "./*.d.ts",
|
|
26
|
+
"default": "./*.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"react": ">=18",
|
|
31
|
+
"react-dom": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"design-system",
|
|
35
|
+
"react",
|
|
36
|
+
"components",
|
|
37
|
+
"accessible",
|
|
38
|
+
"design-tokens",
|
|
39
|
+
"meridian"
|
|
40
|
+
]
|
|
41
|
+
}
|
package/styles.css
ADDED
package/tokens/base.css
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
body{margin:0;font-family:var(--font-sans);font-size:var(--text-md);line-height:var(--leading-normal);color:var(--text-primary);background:var(--surface-page);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
|
|
2
|
+
h1,h2,h3,h4{font-family:var(--font-display);letter-spacing:var(--tracking-display);line-height:var(--leading-snug);margin:0}
|
|
3
|
+
p{margin:0}
|
|
4
|
+
a{color:var(--text-link);text-decoration:none;transition:color var(--dur-fast) var(--ease-out)}
|
|
5
|
+
a:hover{color:var(--accent-hover);text-decoration:underline;text-underline-offset:3px}
|
|
6
|
+
a:focus-visible{outline:none;box-shadow:var(--focus-ring);border-radius:var(--radius-sm)}
|
|
7
|
+
code,pre,kbd{font-family:var(--font-mono)}
|
|
8
|
+
::selection{background:var(--brand-100)}
|
|
9
|
+
*,*::before,*::after{box-sizing:border-box}
|
|
10
|
+
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
:root{
|
|
2
|
+
/* Sand — warm neutrals */
|
|
3
|
+
--sand-25:#FCFBF9;--sand-50:#FAF9F6;--sand-100:#F3F1EB;--sand-200:#E7E3D9;--sand-300:#D5CFC0;--sand-400:#B4AB97;--sand-500:#948A74;--sand-600:#786E59;--sand-700:#5E5545;--sand-800:#443D32;--sand-900:#2E2922;--sand-950:#1E1A14;
|
|
4
|
+
/* Brand — cream→peach→caramel→cocoa ramp sampled from the owl mark */
|
|
5
|
+
--brand-50:#F8F4E6;--brand-100:#F4E9D2;--brand-200:#EFCFAC;--brand-300:#DFB585;--brand-400:#CE9C66;--brand-500:#C08A5A;--brand-600:#A0693C;--brand-700:#7A4E2B;--brand-800:#5C3A1F;--brand-900:#482818;--brand-950:#2C1709;
|
|
6
|
+
/* Named logo tones (aliases into the ramp) */
|
|
7
|
+
--cocoa-950:var(--brand-950);--cocoa-900:#3A2012;--cocoa-700:var(--brand-900);--caramel-500:var(--brand-500);--peach-200:var(--brand-200);--cream-50:var(--brand-50);
|
|
8
|
+
/* Status — each 600 fg holds ≥4.5:1 on its 100 tint and on white */
|
|
9
|
+
--success-600:#2F7A40;--success-100:#EBF5EC;--success-300:#BFE0C6;
|
|
10
|
+
--warning-600:#B45309;--warning-100:#FDF3E0;--warning-300:#F3D9A8;
|
|
11
|
+
--danger-600:#C81E1E;--danger-700:#B91C1C;--danger-100:#FDEEEC;--danger-300:#F5C6C0;
|
|
12
|
+
/* Semantic aliases */
|
|
13
|
+
--surface-page:var(--sand-50);--surface-card:#FFFFFF;--surface-sunken:var(--sand-100);--surface-subtle:var(--sand-25);--surface-inverse:var(--sand-950);--surface-brand:var(--brand-900);
|
|
14
|
+
--surface-code:#14110B;--text-code:#E8E3D9;--border-code:rgba(240,235,225,.09);/* code/terminal surface — fixed dark espresso in BOTH themes (never remap) */
|
|
15
|
+
--overlay-scrim:rgba(31,26,20,.45);/* modal/drawer backdrop */--text-on-brand-muted:rgba(248,244,230,.75);/* muted text on brand/inverse surfaces */
|
|
16
|
+
--text-primary:var(--sand-950);--text-secondary:var(--sand-700);--text-muted:#746A55;/* between sand-600/700: ≥4.5:1 on page, card, and sunken */--text-inverse:var(--sand-50);--text-link:var(--brand-700);
|
|
17
|
+
--border-default:var(--sand-200);--border-strong:var(--sand-300);--border-inverse:rgba(250,249,246,.18);
|
|
18
|
+
--accent:var(--brand-950);--accent-hover:#1D0E04;--accent-active:#120801;--accent-subtle:var(--brand-50);--accent-subtle-border:var(--brand-200);--accent-contrast:#FFFFFF;
|
|
19
|
+
--danger-contrast:#FFFFFF;/* label on a solid --danger-600 fill; flips in dark where the red lightens */
|
|
20
|
+
/* Focus ring — opaque, two-layer. The inner offset ring is surface-coloured so the
|
|
21
|
+
indicator never sits directly against a control fill; the outer ring only ever needs
|
|
22
|
+
contrast against the surface, clearing WCAG 1.4.11 (3:1 non-text) on every background. */
|
|
23
|
+
--focus-ring-color:var(--brand-700);--focus-ring-offset:var(--surface-card);
|
|
24
|
+
--focus-ring:0 0 0 2px var(--focus-ring-offset),0 0 0 4px var(--focus-ring-color);
|
|
25
|
+
--focus-ring-danger:0 0 0 2px var(--focus-ring-offset),0 0 0 4px var(--danger-600);
|
|
26
|
+
}
|
|
27
|
+
/* Dark theme — semantic remap only; ramps stay fixed */
|
|
28
|
+
[data-theme="dark"]{
|
|
29
|
+
--surface-page:#191512;--surface-card:#211C17;--surface-sunken:#2A251E;--surface-subtle:#1D1814;--surface-inverse:var(--sand-50);--surface-brand:var(--brand-950);
|
|
30
|
+
--text-primary:#F3EFE7;--text-secondary:#C9C0B2;--text-muted:#9C9280;--text-inverse:var(--sand-950);--text-link:var(--brand-400);
|
|
31
|
+
--border-default:#332C24;--border-strong:#453C31;--border-inverse:rgba(30,26,20,.2);
|
|
32
|
+
--accent:#F3EFE7;--accent-hover:#FFFFFF;--accent-active:#D5CFC0;--accent-subtle:#2A2119;--accent-subtle-border:#453728;--accent-contrast:#1E1A14;
|
|
33
|
+
--success-600:#5FB86E;--success-100:#1C2B1F;--success-300:#2E4A34;
|
|
34
|
+
--warning-100:#2E2413;--warning-300:#4A3A1D;--warning-600:#D9822B;
|
|
35
|
+
--danger-100:#321B18;--danger-300:#54291F;--danger-600:#E85D4A;--danger-contrast:#1E1A14;
|
|
36
|
+
--focus-ring-color:var(--brand-400);/* offset + composite inherit from :root and re-resolve here */
|
|
37
|
+
}
|
|
38
|
+
[data-theme="dark"] ::selection{background:#453728}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
:root{
|
|
2
|
+
--shadow-xs:0 1px 2px rgba(46,41,34,.05);
|
|
3
|
+
--shadow-sm:0 1px 3px rgba(46,41,34,.07);
|
|
4
|
+
--shadow-md:0 4px 12px rgba(46,41,34,.08);
|
|
5
|
+
--shadow-lg:0 12px 28px rgba(46,41,34,.12);
|
|
6
|
+
--shadow-xl:0 16px 40px rgba(31,26,20,.18),0 2px 8px rgba(31,26,20,.08);
|
|
7
|
+
--shadow-pop:var(--shadow-xl);/* deprecated alias of --shadow-xl; kept one major */
|
|
8
|
+
/* Elevation scale — the single source of overlay stacking order */
|
|
9
|
+
--z-dropdown:1000;/* @kind other */
|
|
10
|
+
--z-sticky:1100;/* @kind other */
|
|
11
|
+
--z-overlay:1200;/* @kind other */
|
|
12
|
+
--z-modal:1300;/* @kind other */
|
|
13
|
+
--z-popover:1400;/* @kind other */
|
|
14
|
+
--z-toast:1500;/* @kind other */
|
|
15
|
+
--z-tooltip:1600;/* @kind other */
|
|
16
|
+
--ease-spring:cubic-bezier(.3,1.04,.35,1);/* @kind other */
|
|
17
|
+
--ease-out:cubic-bezier(.22,1,.36,1);/* @kind other */
|
|
18
|
+
--ease-in-out:cubic-bezier(.65,0,.35,1);/* @kind other */
|
|
19
|
+
--dur-fast:100ms;/* @kind other */
|
|
20
|
+
--dur-med:160ms;/* @kind other */
|
|
21
|
+
--dur-slow:240ms;/* @kind other */
|
|
22
|
+
}
|
package/tokens/fonts.css
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
@font-face{font-family:'Bricolage Grotesque';src:url('../assets/fonts/BricolageGrotesque-Variable.ttf') format('truetype-variations');font-weight:200 800;font-style:normal;font-display:swap}
|
|
2
|
+
@font-face{font-family:'Figtree';src:url('../assets/fonts/Figtree-Variable.ttf') format('truetype-variations');font-weight:300 900;font-style:normal;font-display:swap}
|
|
3
|
+
@font-face{font-family:'Figtree';src:url('../assets/fonts/Figtree-Italic-Variable.ttf') format('truetype-variations');font-weight:300 900;font-style:italic;font-display:swap}
|
|
4
|
+
@font-face{font-family:'JetBrains Mono';src:url('../assets/fonts/JetBrainsMono-Variable.ttf') format('truetype-variations');font-weight:100 800;font-style:normal;font-display:swap}
|
|
5
|
+
@font-face{font-family:'JetBrains Mono';src:url('../assets/fonts/JetBrainsMono-Italic-Variable.ttf') format('truetype-variations');font-weight:100 800;font-style:italic;font-display:swap}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
:root{
|
|
2
|
+
--space-0:0;--space-1:4px;--space-2:8px;--space-3:12px;--space-4:16px;--space-5:20px;--space-6:24px;--space-8:32px;--space-10:40px;--space-12:48px;--space-16:64px;--space-20:80px;--space-24:96px;--space-32:128px;
|
|
3
|
+
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;--radius-xl:16px;--radius-full:999px;
|
|
4
|
+
--container-max:1200px;--container-text:720px;
|
|
5
|
+
--control-h-sm:28px;--control-h-md:36px;--control-h-lg:44px;
|
|
6
|
+
--table-pad-y:12px;--table-pad-x:16px;
|
|
7
|
+
}
|
|
8
|
+
/* Compact density — data-heavy B2B views */
|
|
9
|
+
[data-density="compact"]{
|
|
10
|
+
--control-h-sm:24px;--control-h-md:30px;--control-h-lg:38px;
|
|
11
|
+
--table-pad-y:7px;--table-pad-x:12px;
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
:root{
|
|
2
|
+
--font-display:'Bricolage Grotesque','Figtree',ui-sans-serif,system-ui,sans-serif;
|
|
3
|
+
--font-sans:'Figtree',ui-sans-serif,system-ui,-apple-system,'Segoe UI',sans-serif;
|
|
4
|
+
--font-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace;
|
|
5
|
+
--text-2xs:11px;--text-xs:12px;--text-sm:13px;--text-md:14px;--text-lg:16px;--text-xl:18px;--text-2xl:21px;--text-3xl:26px;--text-4xl:34px;--text-5xl:44px;--text-6xl:60px;--text-7xl:76px;
|
|
6
|
+
--leading-tight:1.05;--leading-snug:1.25;--leading-normal:1.5;--leading-relaxed:1.65;
|
|
7
|
+
--tracking-display:-0.02em;--tracking-tight:-0.01em;--tracking-wide:0.06em;
|
|
8
|
+
--weight-regular:400;--weight-medium:500;--weight-semibold:600;--weight-bold:700;--weight-display:680;
|
|
9
|
+
}
|