@cosxai/ui 0.24.0 → 1.0.0-alpha.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/CHANGELOG.md +577 -0
- package/NOTICE +11 -0
- package/README.md +52 -0
- package/package.json +33 -7
- package/src/fonts.css +20 -0
- package/src/index.ts +8 -25
- package/src/lib/cn.ts +23 -6
- package/src/styles.css +17 -0
- package/src/theme.css +132 -0
- package/src/tokens/colors.css +112 -0
- package/src/tokens/compat.css +36 -0
- package/src/tokens/elevation.css +14 -0
- package/src/tokens/motion.css +42 -0
- package/src/tokens/spacing.css +55 -0
- package/src/tokens/typography-cjk.css +42 -0
- package/src/tokens/typography.css +81 -0
- package/src/actionbar/ActionBar.tsx +0 -837
- package/src/actionbar/ActionBarButton.tsx +0 -111
- package/src/actionbar/ActionBarMenuGroup.tsx +0 -116
- package/src/actionbar/ActionBarModeHandle.tsx +0 -171
- package/src/actionbar/ActionBarProvider.tsx +0 -91
- package/src/actionbar/actionbar-context.ts +0 -45
- package/src/actionbar/index.ts +0 -28
- package/src/actionbar/types.ts +0 -147
- package/src/actionbar/useActionBarItems.ts +0 -60
- package/src/actionbar/useActionBarMode.ts +0 -144
- package/src/actionbar/useActionBarPanel.ts +0 -56
- package/src/actionbar/useActionBarStatusDot.ts +0 -49
- package/src/actionbar/useActionBarToast.ts +0 -33
- package/src/ambient/AmbientBackdrop.tsx +0 -74
- package/src/ambient/CommandInput.tsx +0 -107
- package/src/ambient/SuperbarStrip.tsx +0 -36
- package/src/ambient/index.ts +0 -6
- package/src/bento/BentoCell.tsx +0 -66
- package/src/bento/BentoGrid.tsx +0 -42
- package/src/bento/index.ts +0 -2
- package/src/command/CommandPalette.tsx +0 -329
- package/src/command/CommandProvider.tsx +0 -57
- package/src/command/command-context.ts +0 -12
- package/src/command/index.ts +0 -6
- package/src/command/rank.ts +0 -50
- package/src/command/types.ts +0 -37
- package/src/command/useCommandSource.ts +0 -37
- package/src/dialogs/DialogsProvider.tsx +0 -216
- package/src/dialogs/Modal.tsx +0 -260
- package/src/dialogs/Toast.tsx +0 -85
- package/src/dialogs/dialogs-context.ts +0 -6
- package/src/dialogs/index.ts +0 -10
- package/src/dialogs/types.ts +0 -37
- package/src/dialogs/useDialogs.ts +0 -8
- package/src/editorial/EditorialSpotlight.tsx +0 -63
- package/src/editorial/Folio.tsx +0 -52
- package/src/editorial/PlateMarker.tsx +0 -33
- package/src/editorial/RomanSection.tsx +0 -65
- package/src/editorial/RunningMarginalia.tsx +0 -65
- package/src/editorial/index.ts +0 -10
- package/src/hooks/index.ts +0 -5
- package/src/hooks/useKeyboardHotkey.ts +0 -93
- package/src/hooks/useReducedMotion.ts +0 -20
- package/src/hooks/useViewport.ts +0 -61
- package/src/layout/Breadcrumb.tsx +0 -74
- package/src/layout/LeftNavRail.tsx +0 -139
- package/src/layout/MobileTabBar.tsx +0 -101
- package/src/layout/NavItem.tsx +0 -128
- package/src/layout/NavSearchTrigger.tsx +0 -88
- package/src/layout/NavSection.tsx +0 -40
- package/src/layout/RightSidebarPanel.tsx +0 -111
- package/src/layout/Shell.tsx +0 -91
- package/src/layout/SidePanel.tsx +0 -316
- package/src/layout/StickyBanner.tsx +0 -83
- package/src/layout/Topbar.tsx +0 -68
- package/src/layout/index.ts +0 -24
- package/src/layout/useNavRailState.ts +0 -69
- package/src/lib/time-utils.ts +0 -44
- package/src/neobrutalism/Marquee.tsx +0 -81
- package/src/neobrutalism/Sticker.tsx +0 -71
- package/src/neobrutalism/index.ts +0 -4
- package/src/primitives/Avatar.tsx +0 -53
- package/src/primitives/Button.tsx +0 -67
- package/src/primitives/Card.tsx +0 -41
- package/src/primitives/Checkbox.tsx +0 -87
- package/src/primitives/Chip.tsx +0 -177
- package/src/primitives/Combobox.tsx +0 -475
- package/src/primitives/CopyField.tsx +0 -139
- package/src/primitives/CountBadge.tsx +0 -50
- package/src/primitives/Input.tsx +0 -161
- package/src/primitives/Kbd.tsx +0 -45
- package/src/primitives/MentionCombobox.tsx +0 -612
- package/src/primitives/MultiCombobox.tsx +0 -179
- package/src/primitives/PageHeader.tsx +0 -77
- package/src/primitives/Radio.tsx +0 -131
- package/src/primitives/SegmentedControl.tsx +0 -135
- package/src/primitives/Select.tsx +0 -779
- package/src/primitives/SignaturePad.tsx +0 -461
- package/src/primitives/Tag.tsx +0 -56
- package/src/primitives/Textarea.tsx +0 -62
- package/src/primitives/ToggleSwitch.tsx +0 -79
- package/src/primitives/Tooltip.tsx +0 -213
- package/src/primitives/index.ts +0 -48
- package/src/pwa/InstallPromptBanner.tsx +0 -132
- package/src/pwa/index.ts +0 -4
- package/src/pwa/manifest.template.json +0 -20
- package/src/pwa/registerSW.ts +0 -55
- package/src/riso/Halftone.tsx +0 -85
- package/src/riso/Misregister.tsx +0 -63
- package/src/riso/RisoStamp.tsx +0 -76
- package/src/riso/index.ts +0 -3
- package/src/sketch/HandUnderline.tsx +0 -53
- package/src/sketch/RoughArrow.tsx +0 -91
- package/src/sketch/RoughBox.tsx +0 -73
- package/src/sketch/StickyNote.tsx +0 -56
- package/src/sketch/index.ts +0 -4
- package/src/styles/base.css +0 -186
- package/src/styles/chrome-ambient.css +0 -235
- package/src/styles/chrome-bento.css +0 -192
- package/src/styles/chrome-editorial.css +0 -168
- package/src/styles/chrome-neobrutalism.css +0 -326
- package/src/styles/chrome-riso.css +0 -339
- package/src/styles/chrome-sketch.css +0 -362
- package/src/styles/chrome-swiss.css +0 -265
- package/src/styles/chrome-terminal.css +0 -272
- package/src/styles/fonts.css +0 -1034
- package/src/styles/index.css +0 -306
- package/src/styles/tokens.css +0 -941
- package/src/terminal/AsciiBox.tsx +0 -65
- package/src/terminal/BrailleSpinner.tsx +0 -46
- package/src/terminal/index.ts +0 -4
- package/src/theme/ThemeProvider.tsx +0 -99
- package/src/theme/index.ts +0 -6
- package/src/theme/inline-script.ts +0 -40
- package/src/theme/theme-context.ts +0 -7
- package/src/theme/types.ts +0 -39
- package/src/theme/useTheme.ts +0 -8
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosxai/ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "COSX
|
|
3
|
+
"version": "1.0.0-alpha.0",
|
|
4
|
+
"description": "COSX Design System 3.0 — tokens, Tailwind v4 theme and React components",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./src/index.ts",
|
|
8
8
|
"types": "./src/index.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./src/index.ts",
|
|
11
|
-
"./styles.css": "./src/styles
|
|
11
|
+
"./styles.css": "./src/styles.css",
|
|
12
|
+
"./theme.css": "./src/theme.css",
|
|
13
|
+
"./tokens/*": "./src/tokens/*"
|
|
12
14
|
},
|
|
13
15
|
"files": [
|
|
14
16
|
"src",
|
|
15
|
-
"
|
|
17
|
+
"!src/**/*.test.ts",
|
|
18
|
+
"README.md",
|
|
19
|
+
"CHANGELOG.md",
|
|
20
|
+
"NOTICE"
|
|
16
21
|
],
|
|
17
22
|
"repository": {
|
|
18
23
|
"type": "git",
|
|
@@ -24,15 +29,36 @@
|
|
|
24
29
|
"registry": "https://registry.npmjs.org/"
|
|
25
30
|
},
|
|
26
31
|
"scripts": {
|
|
27
|
-
"typecheck": "tsc --noEmit"
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"check:css": "tailwindcss -i test/fixture.css -o test/out.css"
|
|
28
35
|
},
|
|
29
36
|
"peerDependencies": {
|
|
30
37
|
"react": "^19.0.0",
|
|
31
|
-
"react-dom": "^19.0.0"
|
|
38
|
+
"react-dom": "^19.0.0",
|
|
39
|
+
"tailwindcss": "^4.0.0"
|
|
32
40
|
},
|
|
33
41
|
"devDependencies": {
|
|
42
|
+
"@tailwindcss/cli": "^4",
|
|
43
|
+
"@types/node": "^26.6.3",
|
|
34
44
|
"@types/react": "^19.0.0",
|
|
35
45
|
"@types/react-dom": "^19.0.0",
|
|
36
|
-
"
|
|
46
|
+
"tailwindcss": "^4",
|
|
47
|
+
"typescript": "^5.6.0",
|
|
48
|
+
"vitest": "^3.2.0"
|
|
49
|
+
},
|
|
50
|
+
"sideEffects": [
|
|
51
|
+
"**/*.css"
|
|
52
|
+
],
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@fontsource-variable/geist": "^5.3.0",
|
|
55
|
+
"@fontsource-variable/noto-sans-sc": "^5.3.0",
|
|
56
|
+
"clsx": "^2.1.1",
|
|
57
|
+
"tailwind-merge": "^3.3.1"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"tailwindcss": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
37
63
|
}
|
|
38
64
|
}
|
package/src/fonts.css
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/* @cosxai/ui — self-hosted fonts.
|
|
2
|
+
*
|
|
3
|
+
* The 3.0 tokens load Geist and Noto Sans SC from Google Fonts
|
|
4
|
+
* (tokens/fonts.css in the design system, not shipped here). The kit
|
|
5
|
+
* serves them from the consumer's own bundle instead: Fontsource
|
|
6
|
+
* variable builds, OFL-1.1, split by unicode range so a page downloads
|
|
7
|
+
* only the glyphs it shows.
|
|
8
|
+
*
|
|
9
|
+
* Fontsource names the families "… Variable"; the stacks below put those
|
|
10
|
+
* first and keep the design system's own names after them. Loaded after
|
|
11
|
+
* the tokens (styles.css), so these stacks are the ones in effect.
|
|
12
|
+
*/
|
|
13
|
+
@import "@fontsource-variable/geist";
|
|
14
|
+
@import "@fontsource-variable/noto-sans-sc";
|
|
15
|
+
|
|
16
|
+
:root {
|
|
17
|
+
--font-sans: "Geist Variable", "Geist", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
18
|
+
--font-cjk: "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
19
|
+
--font-sans-cjk: "Geist Variable", "Geist", "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
20
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export * from "./primitives";
|
|
10
|
-
export * from "./lib/cn";
|
|
11
|
-
export * from "./lib/time-utils";
|
|
12
|
-
export * from "./theme";
|
|
13
|
-
export * from "./hooks";
|
|
14
|
-
export * from "./layout";
|
|
15
|
-
export * from "./dialogs";
|
|
16
|
-
export * from "./actionbar";
|
|
17
|
-
export * from "./command";
|
|
18
|
-
export * from "./pwa";
|
|
19
|
-
export * from "./editorial";
|
|
20
|
-
export * from "./neobrutalism";
|
|
21
|
-
export * from "./ambient";
|
|
22
|
-
export * from "./terminal";
|
|
23
|
-
export * from "./bento";
|
|
24
|
-
export * from "./riso";
|
|
25
|
-
export * from "./sketch";
|
|
1
|
+
/**
|
|
2
|
+
* @cosxai/ui 1.x — the COSX Design System 3.0 in React.
|
|
3
|
+
*
|
|
4
|
+
* Foundations: import "@cosxai/ui/styles.css" (tokens + fonts) and, in a
|
|
5
|
+
* Tailwind v4 app, "@cosxai/ui/theme.css". Components arrive in the 1.0
|
|
6
|
+
* alphas (docs/workdocs/2026-09-29_feature-ui-1.0).
|
|
7
|
+
*/
|
|
8
|
+
export { cn } from './lib/cn';
|
package/src/lib/cn.ts
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { clsx, type ClassValue } from 'clsx';
|
|
2
|
+
import { extendTailwindMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* cn — join class names and let the later Tailwind class win on conflict
|
|
6
|
+
* (`cn('p-2', cond && 'p-4')` → `p-4`).
|
|
7
|
+
*
|
|
8
|
+
* tailwind-merge only knows Tailwind's default scales; the kit's theme
|
|
9
|
+
* (theme.css) replaces font sizes with its own names, taught here so
|
|
10
|
+
* `text-ui` and `text-fg` are not mistaken for each other (one is a
|
|
11
|
+
* size, one a colour).
|
|
12
|
+
*/
|
|
13
|
+
const merge = extendTailwindMerge({
|
|
14
|
+
extend: {
|
|
15
|
+
theme: {
|
|
16
|
+
text: ['meta', 'small', 'ui', 'body', 'h3', 'lede', 'title', 'figure', 'h2', 'h1', 'display'],
|
|
17
|
+
radius: ['xs', 'sm', 'md', 'lg', 'xl', 'pill'],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export function cn(...inputs: ClassValue[]): string {
|
|
23
|
+
return merge(clsx(inputs));
|
|
7
24
|
}
|
package/src/styles.css
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/* @cosxai/ui — the COSX Design System 3.0 foundations.
|
|
2
|
+
*
|
|
3
|
+
* tokens/ are the design system's own files, copied unchanged from the
|
|
4
|
+
* "COSX Design System 3.0" project. Edit them there and copy again; the
|
|
5
|
+
* kit's additions live in fonts.css and theme.css.
|
|
6
|
+
*
|
|
7
|
+
* Ink (dark) mode: set data-mode="ink" on <html>, or put .ink-mode on a
|
|
8
|
+
* subtree (colors.css).
|
|
9
|
+
*/
|
|
10
|
+
@import "./tokens/colors.css";
|
|
11
|
+
@import "./tokens/typography.css";
|
|
12
|
+
@import "./tokens/typography-cjk.css";
|
|
13
|
+
@import "./tokens/spacing.css";
|
|
14
|
+
@import "./tokens/elevation.css";
|
|
15
|
+
@import "./tokens/motion.css";
|
|
16
|
+
@import "./tokens/compat.css";
|
|
17
|
+
@import "./fonts.css";
|
package/src/theme.css
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* @cosxai/ui — Tailwind v4 theme for the COSX Design System 3.0.
|
|
2
|
+
*
|
|
3
|
+
* @import "tailwindcss";
|
|
4
|
+
* @import "@cosxai/ui/theme.css";
|
|
5
|
+
* @import "@cosxai/ui/styles.css";
|
|
6
|
+
* @source "../node_modules/@cosxai/ui/src"; (so the kit's classes are generated)
|
|
7
|
+
*
|
|
8
|
+
* Utilities point at the 3.0 variables ("inline"), so ink mode —
|
|
9
|
+
* data-mode="ink" / .ink-mode — switches them with no dark: variants.
|
|
10
|
+
*
|
|
11
|
+
* Tailwind's own palette, radii, shadows, fonts and easings are cleared:
|
|
12
|
+
* only what the design system defines exists (no bg-blue-500, no
|
|
13
|
+
* shadow-lg — 3.0 has no shadows).
|
|
14
|
+
*
|
|
15
|
+
* Names never collide with a 3.0 variable unless the value is the same
|
|
16
|
+
* (theme.test.ts). In particular font sizes avoid --text-primary /
|
|
17
|
+
* --text-secondary / --text-label, which are colours in 3.0.
|
|
18
|
+
*/
|
|
19
|
+
@theme inline {
|
|
20
|
+
--color-*: initial;
|
|
21
|
+
--radius-*: initial;
|
|
22
|
+
--shadow-*: initial;
|
|
23
|
+
--inset-shadow-*: initial;
|
|
24
|
+
--drop-shadow-*: initial;
|
|
25
|
+
--font-*: initial;
|
|
26
|
+
--ease-*: initial;
|
|
27
|
+
--text-*: initial;
|
|
28
|
+
--font-weight-*: initial;
|
|
29
|
+
--tracking-*: initial;
|
|
30
|
+
|
|
31
|
+
/* Materials — fixed, do not switch with ink mode */
|
|
32
|
+
--color-paper: var(--paper);
|
|
33
|
+
--color-linen: var(--linen);
|
|
34
|
+
--color-sunk-2: var(--sunk-2);
|
|
35
|
+
--color-sunk-3: var(--sunk-3);
|
|
36
|
+
--color-ink: var(--ink);
|
|
37
|
+
--color-ink-raised: var(--ink-raised);
|
|
38
|
+
--color-grey: var(--grey);
|
|
39
|
+
--color-grey-inverse: var(--grey-inverse);
|
|
40
|
+
|
|
41
|
+
/* The yellow — one hue, by area */
|
|
42
|
+
--color-yellow: var(--yellow);
|
|
43
|
+
--color-yellow-accent: var(--yellow-accent);
|
|
44
|
+
--color-yellow-accent-hover: var(--yellow-accent-hover);
|
|
45
|
+
--color-yellow-light: var(--yellow-light);
|
|
46
|
+
--color-yellow-hover: var(--yellow-hover);
|
|
47
|
+
--color-yellow-1: var(--yellow-1);
|
|
48
|
+
--color-yellow-2: var(--yellow-2);
|
|
49
|
+
--color-yellow-3: var(--yellow-3);
|
|
50
|
+
--color-yellow-4: var(--yellow-4);
|
|
51
|
+
--color-yellow-5: var(--yellow-5);
|
|
52
|
+
--color-yellow-wash-12: var(--yellow-12);
|
|
53
|
+
--color-yellow-wash-20: var(--yellow-20);
|
|
54
|
+
--color-yellow-wash-32: var(--yellow-32);
|
|
55
|
+
--color-yellow-wash-50: var(--yellow-50);
|
|
56
|
+
--color-marker: var(--marker);
|
|
57
|
+
|
|
58
|
+
/* Semantic — switch with ink mode. Product code uses these. */
|
|
59
|
+
--color-page: var(--bg-page);
|
|
60
|
+
--color-sunk: var(--bg-sunk);
|
|
61
|
+
--color-well: var(--bg-well);
|
|
62
|
+
--color-chrome: var(--bg-chrome);
|
|
63
|
+
--color-field: var(--bg-field);
|
|
64
|
+
--color-fg: var(--text-primary);
|
|
65
|
+
--color-fg-secondary: var(--text-secondary);
|
|
66
|
+
--color-fg-label: var(--text-label);
|
|
67
|
+
--color-fg-on-yellow-secondary: var(--text-on-yellow-secondary);
|
|
68
|
+
--color-rule: var(--rule);
|
|
69
|
+
--color-rule-soft: var(--rule-soft);
|
|
70
|
+
--color-hover: var(--hover);
|
|
71
|
+
--color-scrim: var(--scrim);
|
|
72
|
+
|
|
73
|
+
/* On an ink surface inside a paper page */
|
|
74
|
+
--color-inv: var(--inv-bg);
|
|
75
|
+
--color-inv-raised: var(--inv-bg-raised);
|
|
76
|
+
--color-inv-fg: var(--inv-text);
|
|
77
|
+
--color-inv-fg-secondary: var(--inv-text-secondary);
|
|
78
|
+
--color-inv-rule: var(--inv-rule);
|
|
79
|
+
|
|
80
|
+
/* Product status: yellow, ink and one red. Progress is an ink outline and
|
|
81
|
+
complete a grey dot — they take no colour of their own. */
|
|
82
|
+
--color-attention: var(--status-attention);
|
|
83
|
+
--color-attention-wash: var(--status-attention-wash);
|
|
84
|
+
--color-error: var(--status-error);
|
|
85
|
+
--color-error-text: var(--status-error-text);
|
|
86
|
+
--color-error-wash: var(--status-error-wash);
|
|
87
|
+
|
|
88
|
+
--color-transparent: transparent;
|
|
89
|
+
--color-current: currentColor;
|
|
90
|
+
--color-white: #fff;
|
|
91
|
+
|
|
92
|
+
/* Radius ladder — same names and values as 3.0 spacing.css */
|
|
93
|
+
--radius-xs: 4px;
|
|
94
|
+
--radius-sm: 6px;
|
|
95
|
+
--radius-md: 8px;
|
|
96
|
+
--radius-lg: 16px;
|
|
97
|
+
--radius-xl: 24px;
|
|
98
|
+
--radius-pill: 999px;
|
|
99
|
+
|
|
100
|
+
/* One family. Same stacks as fonts.css (the ones in effect): font-sans
|
|
101
|
+
for Latin, font-sans-cjk for Chinese pages (Geist for Latin and
|
|
102
|
+
figures, Noto Sans SC for hanzi). */
|
|
103
|
+
--font-sans: "Geist Variable", "Geist", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
104
|
+
--font-sans-cjk: "Geist Variable", "Geist", "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
105
|
+
|
|
106
|
+
--font-weight-normal: 400;
|
|
107
|
+
--font-weight-medium: 500;
|
|
108
|
+
--font-weight-semibold: 600;
|
|
109
|
+
--font-weight-bold: 700;
|
|
110
|
+
|
|
111
|
+
/* Type scale (typography.css). Product UI body is 14px, content 15px. */
|
|
112
|
+
--text-meta: 12px;
|
|
113
|
+
--text-small: 13.5px;
|
|
114
|
+
--text-ui: 14px;
|
|
115
|
+
--text-body: 15px;
|
|
116
|
+
--text-h3: 18px;
|
|
117
|
+
--text-lede: 20px;
|
|
118
|
+
--text-title: 22px;
|
|
119
|
+
--text-figure: 32px;
|
|
120
|
+
--text-h2: var(--size-h2);
|
|
121
|
+
--text-h1: var(--size-h1);
|
|
122
|
+
--text-display: var(--size-display);
|
|
123
|
+
|
|
124
|
+
--tracking-display: -0.025em;
|
|
125
|
+
--tracking-heading: -0.015em;
|
|
126
|
+
--tracking-figure: -0.03em;
|
|
127
|
+
|
|
128
|
+
/* Motion — flat for state, ease-out for entry; nothing bounces */
|
|
129
|
+
--ease-standard: cubic-bezier(.2,0,.2,1);
|
|
130
|
+
--ease-out: cubic-bezier(.16,1,.3,1);
|
|
131
|
+
--ease-in: cubic-bezier(.4,0,1,1);
|
|
132
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* COSX 3.0 — colour. Warm white is the page, ink is every letter, yellow is the only
|
|
2
|
+
thing that is neither. Every value has one job. */
|
|
3
|
+
:root {
|
|
4
|
+
/* Light end */
|
|
5
|
+
--paper: #FEFDFB; /* the page. Ink 18.57:1 */
|
|
6
|
+
--linen: #F5F2EC; /* sunk 1 — sidebars, table heads, inputs */
|
|
7
|
+
--sunk-2: #ECE9E3; /* wells, disabled fields */
|
|
8
|
+
--sunk-3: #E3E0DA; /* deepest chrome */
|
|
9
|
+
|
|
10
|
+
/* Dark end */
|
|
11
|
+
--ink: #111111; /* all type. The dark ground. */
|
|
12
|
+
--ink-raised: #1B1B1B; /* raised surface on the ink ground */
|
|
13
|
+
|
|
14
|
+
/* Two greys, one per end — never interchangeable */
|
|
15
|
+
--grey: #696969; /* secondary text on paper. 5.40:1 */
|
|
16
|
+
--grey-inverse: #9E9E9E; /* secondary text on ink. 7.05:1 */
|
|
17
|
+
|
|
18
|
+
/* Structure — ink at low alpha adopts whichever paper it sits on */
|
|
19
|
+
--rule: rgba(17,17,17,.10);
|
|
20
|
+
--rule-soft: rgba(17,17,17,.06);
|
|
21
|
+
--rule-inverse: rgba(245,242,236,.18);
|
|
22
|
+
--rule-soft-inverse: rgba(245,242,236,.09);
|
|
23
|
+
--hover: #F7F6F4; /* ink 3% over paper. Hover goes darker. */
|
|
24
|
+
--scrim: rgba(17,17,17,.40);
|
|
25
|
+
|
|
26
|
+
/* The yellow. One material: a warm paper, OKLCH L .92 C .09 h 85. Every variant changes
|
|
27
|
+
lightness only, never chroma, so all of them read as the same sheet at different depths.
|
|
28
|
+
Grounds, selected tabs, panels on ink. It never writes a letter on paper. Contrast is ink's job.
|
|
29
|
+
On INK the area rule flips: headline type, marker blocks and buttons are small against the dark
|
|
30
|
+
ground and take the accent; the field there reads as cream. */
|
|
31
|
+
--yellow: #FFE3A0; /* ink on it 15:1 — large areas */
|
|
32
|
+
--yellow-accent: #FFD166; /* same hue, more chroma, for SMALL areas only: marker, chart blocks, dots,
|
|
33
|
+
and everything yellow on ink (headline, marker block, button). Small areas need more chroma to read as the same
|
|
34
|
+
colour as a large field; at field size it would shout. Ink on it 13:1 */
|
|
35
|
+
--yellow-accent-hover: #F5C455;
|
|
36
|
+
--yellow-light: #FFF1D6; /* row washes, the pale end of a ladder */
|
|
37
|
+
--yellow-hover: #F7D98F; /* hover on a yellow fill — same chroma, one step down */
|
|
38
|
+
--yellow-field: var(--yellow); /* alias */
|
|
39
|
+
--yellow-mark: var(--yellow-accent); /* alias */
|
|
40
|
+
--yellow-deep: var(--yellow-hover); /* retired */
|
|
41
|
+
--amber: var(--yellow-accent); /* retired */
|
|
42
|
+
|
|
43
|
+
/* Marker — the highlighter stroke behind a headline phrase. Small area: accent. */
|
|
44
|
+
--marker: var(--yellow-accent);
|
|
45
|
+
|
|
46
|
+
/* Wash ladder over paper — rows and areas. Lightness steps toward the yellow. */
|
|
47
|
+
--yellow-12: #FFFAF0;
|
|
48
|
+
--yellow-20: #FFF6E3;
|
|
49
|
+
--yellow-32: #FFF1D6;
|
|
50
|
+
--yellow-50: #FFEBC2;
|
|
51
|
+
|
|
52
|
+
/* Intensity ladder — treemaps, single-hue series. Light = less; the accent = most.
|
|
53
|
+
Step 4 is the yellow itself. Monotonic in luminance. */
|
|
54
|
+
--yellow-1: #FFF8EA;
|
|
55
|
+
--yellow-2: #FFF3DC;
|
|
56
|
+
--yellow-3: #FFEECE;
|
|
57
|
+
--yellow-4: #FFE3A0;
|
|
58
|
+
--yellow-5: #FFD166;
|
|
59
|
+
--yellow-6: #F5C455; /* hover only */
|
|
60
|
+
--yellow-7: #EAB84A; /* pressed only */
|
|
61
|
+
--series-hairline: rgba(17,17,17,.12); /* pale blocks take this so they hold on paper */
|
|
62
|
+
|
|
63
|
+
/* Product status — PRODUCT UI ONLY. Never on brand, marketing or deck surfaces. */
|
|
64
|
+
--status-error: #E0362F; /* white on it 4.6 · ink on wash */
|
|
65
|
+
--status-error-text: #C4261F; /* 5.9 on paper */
|
|
66
|
+
--status-error-wash: #FDE4E2;
|
|
67
|
+
--status-attention: var(--yellow-accent); /* ink on it 13:1 · never as type on paper */
|
|
68
|
+
--status-attention-wash: var(--yellow-32);
|
|
69
|
+
--status-progress: #2A7DE1; /* white on it 4.5 */
|
|
70
|
+
--status-progress-text: #1F63B8; /* 5.8 on paper */
|
|
71
|
+
--status-progress-wash: #DCEAFB;
|
|
72
|
+
--status-complete: #17A96A; /* ink on it 6.3 */
|
|
73
|
+
--status-complete-text: #0E7A4A; /* 5.5 on paper */
|
|
74
|
+
--status-complete-wash: #D6F3E5;
|
|
75
|
+
|
|
76
|
+
/* Semantic aliases — product code consumes these */
|
|
77
|
+
--bg-page: var(--paper);
|
|
78
|
+
--bg-sunk: var(--linen);
|
|
79
|
+
--bg-well: var(--sunk-2);
|
|
80
|
+
--bg-chrome: var(--sunk-3);
|
|
81
|
+
--text-primary: var(--ink);
|
|
82
|
+
--text-secondary: var(--grey);
|
|
83
|
+
--text-label: var(--grey);
|
|
84
|
+
--highlight: var(--yellow);
|
|
85
|
+
--bg-field: var(--yellow-field);
|
|
86
|
+
--focus-ring: 0 0 0 3px var(--bg-page), 0 0 0 5px var(--ink);
|
|
87
|
+
--text-on-yellow-secondary: rgba(17,17,17,.7); /* secondary text on the yellow; --grey fails there */
|
|
88
|
+
--disabled-opacity: 0.4; /* @kind other */
|
|
89
|
+
|
|
90
|
+
/* Inverted-surface aliases, for a component placed on ink inside a paper page */
|
|
91
|
+
--inv-bg: var(--ink);
|
|
92
|
+
--inv-bg-raised: var(--ink-raised);
|
|
93
|
+
--inv-text: var(--linen);
|
|
94
|
+
--inv-text-secondary: var(--grey-inverse);
|
|
95
|
+
--inv-rule: var(--rule-inverse);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Ink mode. The dark page. Yellow carries the headline here. */
|
|
99
|
+
:root[data-mode="ink"],
|
|
100
|
+
.ink-mode {
|
|
101
|
+
--bg-page: var(--ink);
|
|
102
|
+
--bg-sunk: var(--ink-raised);
|
|
103
|
+
--bg-well: #232221;
|
|
104
|
+
--bg-chrome: #2B2A28;
|
|
105
|
+
--text-primary: var(--linen);
|
|
106
|
+
--text-secondary: var(--grey-inverse);
|
|
107
|
+
--text-label: var(--grey-inverse);
|
|
108
|
+
--rule: var(--rule-inverse);
|
|
109
|
+
--rule-soft: var(--rule-soft-inverse);
|
|
110
|
+
--hover: #1F1E1D;
|
|
111
|
+
--focus-ring: 0 0 0 3px var(--ink), 0 0 0 5px var(--yellow);
|
|
112
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* COSX 3.0 — older token names mapped onto current values. Do not use in new work. */
|
|
2
|
+
:root {
|
|
3
|
+
--stone: var(--grey);
|
|
4
|
+
--brass: var(--grey);
|
|
5
|
+
--white: var(--paper);
|
|
6
|
+
--brass-30: var(--rule);
|
|
7
|
+
--brass-20: var(--rule);
|
|
8
|
+
--brass-12: var(--rule-soft);
|
|
9
|
+
--brass-07: var(--rule-soft);
|
|
10
|
+
--ink-08: rgba(17,17,17,.08);
|
|
11
|
+
--ink-04: rgba(17,17,17,.04);
|
|
12
|
+
--marigold: var(--yellow);
|
|
13
|
+
--marigold-hover: var(--yellow-deep);
|
|
14
|
+
--marigold-press: var(--yellow-7);
|
|
15
|
+
--marigold-tint: var(--yellow-12);
|
|
16
|
+
--ink-hover: #2A2825;
|
|
17
|
+
--ink-press: #000000;
|
|
18
|
+
--status-ok: var(--status-complete);
|
|
19
|
+
--status-warn: var(--status-attention);
|
|
20
|
+
--status-info: var(--status-progress);
|
|
21
|
+
--status-ok-tint: var(--status-complete-wash);
|
|
22
|
+
--status-error-tint: var(--status-error-wash);
|
|
23
|
+
--surface-card: var(--paper);
|
|
24
|
+
--hairline: var(--rule);
|
|
25
|
+
--hairline-soft: var(--rule-soft);
|
|
26
|
+
--grid-line: var(--rule-soft);
|
|
27
|
+
--grid-line-inv: var(--rule-soft-inverse);
|
|
28
|
+
--accent: var(--yellow);
|
|
29
|
+
--inv-text-strong: var(--paper);
|
|
30
|
+
--inv-structure: var(--grey-inverse);
|
|
31
|
+
--inv-hairline: var(--rule-inverse);
|
|
32
|
+
/* amber-era names from the 3.0 draft */
|
|
33
|
+
--amber-12: var(--yellow-12); --amber-20: var(--yellow-20); --amber-32: var(--yellow-32); --amber-50: var(--yellow-50);
|
|
34
|
+
--amber-critical: var(--yellow-7); --amber-high: var(--yellow-6); --amber-medium: var(--yellow-5); --amber-low: var(--yellow-3); --amber-clear: var(--yellow-1);
|
|
35
|
+
--series-1: var(--yellow-1); --series-2: var(--yellow-2); --series-3: var(--yellow-3); --series-4: var(--yellow-4); --series-5: var(--yellow-5); --series-6: var(--yellow-6);
|
|
36
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* COSX 3.0 — elevation. There are no shadows. Depth is cut into the page, so this
|
|
2
|
+
scale runs downward only. An overlay is lifted by the scrim behind it. */
|
|
3
|
+
:root {
|
|
4
|
+
--elev-page: var(--bg-page);
|
|
5
|
+
--elev-sunk-1: var(--bg-sunk);
|
|
6
|
+
--elev-sunk-2: var(--bg-well);
|
|
7
|
+
--elev-sunk-3: var(--bg-chrome);
|
|
8
|
+
--shadow-none: none;
|
|
9
|
+
/* v2 shadow tokens resolve to nothing — kept so old surfaces do not break */
|
|
10
|
+
--shadow-card: none;
|
|
11
|
+
--shadow-raised: none;
|
|
12
|
+
--shadow-overlay: none;
|
|
13
|
+
--shadow-hairline: inset 0 0 0 1px var(--rule);
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* COSX 3.0 — motion. "Paper settling." Two registers:
|
|
2
|
+
state quick and flat — colour, border, opacity on hover/focus/toggle. 120–320ms.
|
|
3
|
+
entry one choreographed settle when a surface appears — blocks rise a few px, the marker
|
|
4
|
+
draws, figures count, the pill glides. Each element ≤ 640ms; a whole sequence ≤ 1.4s
|
|
5
|
+
with a 70ms stagger. Ease-out only: things arrive and stop, they never bounce. */
|
|
6
|
+
:root {
|
|
7
|
+
--motion-colour: 120ms; /* @kind other */
|
|
8
|
+
--motion-fade: 180ms; /* @kind other */
|
|
9
|
+
--motion-max: 320ms; /* @kind other */
|
|
10
|
+
--motion-reveal: 640ms; /* @kind other */ /* entry: rise, draw, glide */
|
|
11
|
+
--motion-count: 1400ms; /* @kind other */ /* figures counting up */
|
|
12
|
+
--motion-stagger: 70ms; /* @kind other */
|
|
13
|
+
--easing: cubic-bezier(.2,0,.2,1); /* @kind other */
|
|
14
|
+
--easing-out: cubic-bezier(.16,1,.3,1); /* @kind other */
|
|
15
|
+
--rise-distance: 10px;
|
|
16
|
+
/* v2 aliases */
|
|
17
|
+
--dur-fast: var(--motion-colour); /* @kind other */
|
|
18
|
+
--dur-base: var(--motion-fade); /* @kind other */
|
|
19
|
+
--dur-slow: var(--motion-max); /* @kind other */
|
|
20
|
+
--ease-standard: var(--easing); /* @kind other */
|
|
21
|
+
--ease-out: var(--easing-out); /* @kind other */
|
|
22
|
+
--ease-in: cubic-bezier(.4,0,1,1); /* @kind other */
|
|
23
|
+
--press-inset: none;
|
|
24
|
+
}
|
|
25
|
+
/* Entry vocabulary */
|
|
26
|
+
@keyframes cosx-rise { from { opacity: 0; transform: translateY(var(--rise-distance)); } to { opacity: 1; transform: none; } }
|
|
27
|
+
@keyframes cosx-draw { from { background-size: 0% 100%; } to { background-size: 100% 100%; } }
|
|
28
|
+
@keyframes cosx-settle { from { opacity: 0; transform: scale(.92); } to { opacity: 1; transform: none; } }
|
|
29
|
+
@keyframes cosx-grow { from { transform: scaleY(0); } to { transform: none; } }
|
|
30
|
+
@keyframes cosx-wipe { from { clip-path: inset(0 100% 0 0 round 8px); } to { clip-path: inset(0 0 0 0 round 8px); } }
|
|
31
|
+
.rise { animation: cosx-rise var(--motion-reveal) var(--easing-out) both; }
|
|
32
|
+
.marker.draw { background-repeat: no-repeat; animation: cosx-draw var(--motion-reveal) var(--easing-out) .35s both; }
|
|
33
|
+
.settle { animation: cosx-settle var(--motion-reveal) var(--easing-out) both; } /* chart blocks, tiles — staggered */
|
|
34
|
+
.grow { transform-origin: bottom; animation: cosx-grow var(--motion-reveal) var(--easing-out) both; } /* columns */
|
|
35
|
+
.wipe { animation: cosx-wipe var(--motion-reveal) var(--easing-out) both; } /* yellow field or strip revealing left→right */
|
|
36
|
+
/* Stagger helper: set --i on each child */
|
|
37
|
+
.rise, .settle, .grow, .wipe { animation-delay: calc(var(--i, 0) * var(--motion-stagger) + var(--delay, 0ms)); }
|
|
38
|
+
/* Glide: the selected pill / active indicator moves, it does not blink */
|
|
39
|
+
.glide { transition: transform var(--motion-reveal) var(--easing-out), width var(--motion-reveal) var(--easing-out), left var(--motion-reveal) var(--easing-out); }
|
|
40
|
+
@media (prefers-reduced-motion: reduce) {
|
|
41
|
+
:root { --motion-colour: 0ms; /* @kind other */ --motion-fade: 0ms; /* @kind other */ --motion-max: 0ms; /* @kind other */ --motion-reveal: 0ms; /* @kind other */ --motion-count: 0ms; /* @kind other */ --motion-stagger: 0ms; /* @kind other */ }
|
|
42
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/* COSX 3.0 — spacing, shape, rules. Rounded, not square: 8px is the system radius. */
|
|
2
|
+
:root {
|
|
3
|
+
--space-1: 4px;
|
|
4
|
+
--space-2: 8px;
|
|
5
|
+
--space-3: 12px;
|
|
6
|
+
--space-4: 16px;
|
|
7
|
+
--space-5: 22px;
|
|
8
|
+
--space-6: 32px;
|
|
9
|
+
--space-7: 48px;
|
|
10
|
+
--space-8: 72px;
|
|
11
|
+
|
|
12
|
+
/* Shape */
|
|
13
|
+
--radius-0: 0;
|
|
14
|
+
--radius-xs: 4px; /* checkboxes, tiny chips */
|
|
15
|
+
--radius-sm: 6px; /* tags, badges */
|
|
16
|
+
--radius-md: 8px; /* buttons, inputs, chart blocks */
|
|
17
|
+
--radius-lg: 16px; /* panels, dialogs, cards, social blocks */
|
|
18
|
+
--radius-xl: 24px; /* whole sections and page-level fields */
|
|
19
|
+
--radius-pill: 999px; /* dots, switch tracks */
|
|
20
|
+
|
|
21
|
+
/* Rules come in three widths */
|
|
22
|
+
--rule-hair: 1px;
|
|
23
|
+
--rule-accent: 4px; /* yellow underline under the wordmark or an eyebrow; status left-rule */
|
|
24
|
+
--rule-band: 8px;
|
|
25
|
+
|
|
26
|
+
--border-hairline: 1px solid var(--rule);
|
|
27
|
+
--border-soft: 1px solid var(--rule-soft);
|
|
28
|
+
--border-ink: 1px solid var(--ink);
|
|
29
|
+
|
|
30
|
+
/* Layout */
|
|
31
|
+
--grid-cols: 12; /* @kind other */
|
|
32
|
+
--grid-gutter: 24px;
|
|
33
|
+
--grid-max: 1180px;
|
|
34
|
+
|
|
35
|
+
/* Social artboard 1080x1350 */
|
|
36
|
+
--social-w: 1080px;
|
|
37
|
+
--social-h: 1350px;
|
|
38
|
+
--social-margin: 72px;
|
|
39
|
+
|
|
40
|
+
/* Deck grid, at the 1280x720 artboard */
|
|
41
|
+
--deck-w: 1280px;
|
|
42
|
+
--deck-h: 720px;
|
|
43
|
+
--deck-margin: 72px;
|
|
44
|
+
--deck-content: 1136px;
|
|
45
|
+
--deck-y-eyebrow: 44px;
|
|
46
|
+
--deck-y-heading: 96px;
|
|
47
|
+
--deck-y-body: 200px;
|
|
48
|
+
--deck-y-footrule: 648px;
|
|
49
|
+
|
|
50
|
+
/* v2 aliases */
|
|
51
|
+
--s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 22px; --s-6: 32px; --s-7: 48px; --s-8: 72px; --s-9: 96px; --s-10: 128px;
|
|
52
|
+
--pad-card: 32px;
|
|
53
|
+
--pad-compact: 16px 20px;
|
|
54
|
+
--r-none: 0px; --r-sm: 6px; --r-md: 8px; --r-pill: 999px;
|
|
55
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/* COSX 3.0 — Chinese typography (Noto Sans SC). Everything hangs off :lang(zh): mark a page or an element
|
|
2
|
+
lang="zh" (or zh-CN / zh-Hans) and the face, leading, tracking and marker switch over.
|
|
3
|
+
Latin, digits and ASCII punctuation stay in Geist; hanzi fall through to Noto Sans SC. */
|
|
4
|
+
:root {
|
|
5
|
+
--font-cjk: "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
6
|
+
--font-sans-cjk: "Geist", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
7
|
+
--fw-cjk-body: 400; /* @kind font */
|
|
8
|
+
--fw-cjk-heading: 500; /* @kind font */
|
|
9
|
+
--size-body-cjk: 16px; /* Latin body 15 + 1 */
|
|
10
|
+
--size-small-cjk: 14px;
|
|
11
|
+
--size-label-cjk: 12px; /* same as Latin: sentence-style, untracked */
|
|
12
|
+
--leading-body-cjk: 1.8; /* @kind font */
|
|
13
|
+
--leading-heading-cjk: 1.3; /* @kind font */
|
|
14
|
+
--leading-display-cjk: 1.2; /* @kind font */
|
|
15
|
+
--track-cjk: 0; /* @kind font */ /* never the Latin's negative tracking */
|
|
16
|
+
--measure-cjk: 36em; /* ≈ 30–38 hanzi per line */
|
|
17
|
+
--marker-start-cjk: 50%; /* hanzi fill the em box; the band starts lower than Latin's 40% */
|
|
18
|
+
--bilingual-secondary: .72em; /* English line under a Chinese lead */
|
|
19
|
+
}
|
|
20
|
+
:lang(zh) {
|
|
21
|
+
font-family: var(--font-sans-cjk);
|
|
22
|
+
letter-spacing: var(--track-cjk);
|
|
23
|
+
line-height: var(--leading-body-cjk);
|
|
24
|
+
text-autospace: normal; /* quarter-space between hanzi and Latin/digits */
|
|
25
|
+
text-spacing-trim: normal; /* trims doubled full-width punctuation */
|
|
26
|
+
font-synthesis: none; /* no fake bold, no fake italic */
|
|
27
|
+
line-break: strict;
|
|
28
|
+
word-break: normal;
|
|
29
|
+
}
|
|
30
|
+
:lang(zh) h1, :lang(zh) h2, :lang(zh) h3, :lang(zh) .cjk-heading {
|
|
31
|
+
letter-spacing: var(--track-cjk);
|
|
32
|
+
line-height: var(--leading-heading-cjk);
|
|
33
|
+
font-weight: var(--fw-cjk-heading);
|
|
34
|
+
}
|
|
35
|
+
:lang(zh) em, :lang(zh) i { font-style: normal; font-weight: var(--fw-cjk-heading); }
|
|
36
|
+
:lang(zh) b, :lang(zh) strong { font-weight: var(--fw-cjk-heading); }
|
|
37
|
+
:lang(zh) .tabular, :lang(zh) .figure { letter-spacing: 0; font-variant-numeric: tabular-nums; }
|
|
38
|
+
:lang(zh) .marker {
|
|
39
|
+
background: linear-gradient(transparent var(--marker-start-cjk), var(--marker) var(--marker-start-cjk), var(--marker) 96%, transparent 96%);
|
|
40
|
+
}
|
|
41
|
+
:lang(zh) .ink-mode .marker, .ink-mode :lang(zh) .marker, :lang(zh) .marker.on-ink { background: none; }
|
|
42
|
+
.bilingual-en { display: block; font-family: var(--font-sans); font-size: var(--bilingual-secondary); line-height: 1.4; letter-spacing: 0; color: var(--text-secondary); margin-top: .35em; font-weight: 400; }
|