clio-design-system 0.1.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.
@@ -0,0 +1,191 @@
1
+ /* ============================================================
2
+ DARK MODE
3
+ Activation: BOTH mechanisms are supported, and a manual class always
4
+ wins over the system preference:
5
+ 1. Automatic — the OS/browser reports `prefers-color-scheme: dark`.
6
+ 2. Manual — add `.theme-dark` to <html>/<body> to force dark
7
+ regardless of system preference, or `.theme-light` to force
8
+ light regardless of system preference (it's declared last, so
9
+ it always wins the tie against the automatic block below).
10
+
11
+ Scope of this pass: tokens + all 40 components (they all consume
12
+ CSS custom properties, so flipping the aliases below re-skins every
13
+ one of them with no component code changes). UI kits and foundation
14
+ cards were intentionally left untouched this round — see readme.md.
15
+
16
+ Surfaces stay flat — one background + one surface color, matching
17
+ the light theme's flat 2-surface system (no elevation scale). The
18
+ code block gets its own, darker surface so it still reads as an
19
+ inset panel rather than blending into the card behind it.
20
+
21
+ The 8 topic colors and the 4 brand-theme accents are NOT reused
22
+ as-is — each has a lightened `-dark` primitive (tokens/colors.css)
23
+ for legibility as text/badges against the dark surfaces.
24
+ ============================================================ */
25
+
26
+ /* ---------- 1. Automatic: OS reports dark ---------- */
27
+ @media (prefers-color-scheme: dark) {
28
+ :root {
29
+ --color-background: var(--color-dark-bg);
30
+ --color-background-mobile: var(--color-dark-bg);
31
+ --color-surface: var(--color-dark-surface);
32
+ --color-surface-sunken: var(--color-dark-surface-sunken);
33
+ --color-surface-inverse: var(--color-dark-text-900);
34
+ --color-surface-code: var(--color-dark-surface-code);
35
+
36
+ --color-text-primary: var(--color-dark-text-900);
37
+ --color-text-body: var(--color-dark-text-800);
38
+ --color-text-secondary: var(--color-dark-text-700);
39
+ --color-text-tertiary: var(--color-dark-text-600);
40
+ --color-text-muted: var(--color-dark-text-500);
41
+ --color-text-faint: var(--color-dark-text-400);
42
+ --color-text-disabled: var(--color-dark-text-400);
43
+ --color-text-on-inverse: var(--color-dark-bg);
44
+ --color-text-on-code: var(--color-ink-200);
45
+
46
+ --color-success: var(--color-success-dark);
47
+ --color-danger: var(--color-danger-dark);
48
+ --color-warning: var(--color-warning-dark);
49
+
50
+ --color-annotation-text: var(--color-annotation-text-dark);
51
+ --color-annotation-label: var(--color-annotation-label-dark);
52
+ --color-annotation-border: var(--color-annotation-border-dark);
53
+ --color-annotation-fill: color-mix(in srgb, var(--color-annotation-border-dark) 12%, transparent);
54
+
55
+ --border-hairline: rgba(255, 255, 255, 0.07);
56
+ --border-subtle: rgba(255, 255, 255, 0.08);
57
+ --border-default: rgba(255, 255, 255, 0.10);
58
+ --border-medium: rgba(255, 255, 255, 0.14);
59
+ --border-strong: rgba(255, 255, 255, 0.18);
60
+
61
+ --color-topic-red: var(--color-topic-red-dark);
62
+ --color-topic-orange: var(--color-topic-orange-dark);
63
+ --color-topic-ochre: var(--color-topic-ochre-dark);
64
+ --color-topic-blue: var(--color-topic-blue-dark);
65
+ --color-topic-green: var(--color-topic-green-dark);
66
+ --color-topic-violet: var(--color-topic-violet-dark);
67
+ --color-topic-teal: var(--color-topic-teal-dark);
68
+ --color-topic-magenta: var(--color-topic-magenta-dark);
69
+
70
+ --color-accent: var(--color-indigo-600-dark);
71
+ }
72
+ .theme-teal { --color-accent: var(--color-teal-700-dark); }
73
+ .theme-orange { --color-accent: var(--color-orange-600-dark); }
74
+ .theme-violet { --color-accent: var(--color-violet-700-dark); }
75
+ }
76
+
77
+ /* ---------- 2. Manual: .theme-dark forces dark regardless of system ---------- */
78
+ .theme-dark {
79
+ --color-background: var(--color-dark-bg);
80
+ --color-background-mobile: var(--color-dark-bg);
81
+ --color-surface: var(--color-dark-surface);
82
+ --color-surface-sunken: var(--color-dark-surface-sunken);
83
+ --color-surface-inverse: var(--color-dark-text-900);
84
+ --color-surface-code: var(--color-dark-surface-code);
85
+
86
+ --color-text-primary: var(--color-dark-text-900);
87
+ --color-text-body: var(--color-dark-text-800);
88
+ --color-text-secondary: var(--color-dark-text-700);
89
+ --color-text-tertiary: var(--color-dark-text-600);
90
+ --color-text-muted: var(--color-dark-text-500);
91
+ --color-text-faint: var(--color-dark-text-400);
92
+ --color-text-disabled: var(--color-dark-text-400);
93
+ --color-text-on-inverse: var(--color-dark-bg);
94
+ --color-text-on-code: var(--color-ink-200);
95
+
96
+ --color-success: var(--color-success-dark);
97
+ --color-danger: var(--color-danger-dark);
98
+ --color-warning: var(--color-warning-dark);
99
+
100
+ --color-annotation-text: var(--color-annotation-text-dark);
101
+ --color-annotation-label: var(--color-annotation-label-dark);
102
+ --color-annotation-border: var(--color-annotation-border-dark);
103
+ --color-annotation-fill: color-mix(in srgb, var(--color-annotation-border-dark) 12%, transparent);
104
+
105
+ --border-hairline: rgba(255, 255, 255, 0.07);
106
+ --border-subtle: rgba(255, 255, 255, 0.08);
107
+ --border-default: rgba(255, 255, 255, 0.10);
108
+ --border-medium: rgba(255, 255, 255, 0.14);
109
+ --border-strong: rgba(255, 255, 255, 0.18);
110
+
111
+ --color-topic-red: var(--color-topic-red-dark);
112
+ --color-topic-orange: var(--color-topic-orange-dark);
113
+ --color-topic-ochre: var(--color-topic-ochre-dark);
114
+ --color-topic-blue: var(--color-topic-blue-dark);
115
+ --color-topic-green: var(--color-topic-green-dark);
116
+ --color-topic-violet: var(--color-topic-violet-dark);
117
+ --color-topic-teal: var(--color-topic-teal-dark);
118
+ --color-topic-magenta: var(--color-topic-magenta-dark);
119
+
120
+ --color-accent: var(--color-indigo-600-dark);
121
+ }
122
+ .theme-dark.theme-teal { --color-accent: var(--color-teal-700-dark); }
123
+ .theme-dark.theme-orange { --color-accent: var(--color-orange-600-dark); }
124
+ .theme-dark.theme-violet { --color-accent: var(--color-violet-700-dark); }
125
+
126
+ /* ---------- 3. Manual: .theme-light forces light regardless of system ----------
127
+ Declared last so it wins the specificity tie against block 1 above when the
128
+ system prefers dark but the page explicitly opts back out. */
129
+ .theme-light {
130
+ --color-background: var(--color-cream-50);
131
+ --color-background-mobile: var(--color-stone-200);
132
+ --color-surface: var(--color-white);
133
+ --color-surface-sunken: var(--color-stone-100);
134
+ --color-surface-inverse: var(--color-ink-900);
135
+ --color-surface-code: var(--color-ink-850);
136
+
137
+ --color-text-primary: var(--color-ink-900);
138
+ --color-text-body: var(--color-ink-800);
139
+ --color-text-secondary: var(--color-ink-700);
140
+ --color-text-tertiary: var(--color-ink-600);
141
+ --color-text-muted: var(--color-ink-500);
142
+ --color-text-faint: var(--color-ink-400);
143
+ --color-text-disabled: var(--color-ink-300);
144
+ --color-text-on-inverse: var(--color-cream-50);
145
+ --color-text-on-code: var(--color-ink-200);
146
+
147
+ --color-success: var(--color-green-600);
148
+ --color-danger: var(--color-red-700);
149
+ --color-warning: var(--color-amber-700);
150
+
151
+ --color-annotation-text: #7A5B10;
152
+ --color-annotation-label: var(--color-amber-700);
153
+ --color-annotation-border: var(--color-amber-500);
154
+ --color-annotation-fill: var(--color-amber-tint);
155
+
156
+ --border-hairline: rgba(17, 17, 17, 0.06);
157
+ --border-subtle: rgba(17, 17, 17, 0.07);
158
+ --border-default: rgba(17, 17, 17, 0.09);
159
+ --border-medium: rgba(17, 17, 17, 0.12);
160
+ --border-strong: rgba(17, 17, 17, 0.15);
161
+
162
+ --color-topic-red: var(--color-red-600);
163
+ --color-topic-orange: var(--color-orange-700);
164
+ --color-topic-ochre: var(--color-amber-700);
165
+ --color-topic-blue: var(--color-blue-600);
166
+ --color-topic-green: var(--color-green-700);
167
+ --color-topic-violet: var(--color-violet-600);
168
+ --color-topic-teal: var(--color-teal-600);
169
+ --color-topic-magenta: var(--color-pink-600);
170
+
171
+ --color-accent: var(--color-indigo-600);
172
+ }
173
+ .theme-light.theme-teal { --color-accent: var(--color-teal-700); }
174
+ .theme-light.theme-orange { --color-accent: var(--color-orange-600); }
175
+ .theme-light.theme-violet { --color-accent: var(--color-violet-700); }
176
+
177
+ /* ---------- image-slot dark-mode legibility ----------
178
+ image-slot.js (assets/js/image-slot.js) is a vendored utility whose
179
+ empty-state text/icon color and frame/ring tints are hardcoded as
180
+ literal black-based rgba() in its own shadow stylesheet — they don't
181
+ read CSS custom properties, so token overrides alone can't reach them.
182
+ It exposes shadow parts specifically for this: restyle them from the
183
+ outside instead of editing the vendored file. */
184
+ @media (prefers-color-scheme: dark) {
185
+ image-slot::part(empty) { color: rgba(255, 255, 255, 0.55); }
186
+ image-slot::part(frame) { background: rgba(255, 255, 255, 0.06); }
187
+ image-slot::part(ring) { border-color: rgba(255, 255, 255, 0.25); }
188
+ }
189
+ .theme-dark image-slot::part(empty) { color: rgba(255, 255, 255, 0.55); }
190
+ .theme-dark image-slot::part(frame) { background: rgba(255, 255, 255, 0.06); }
191
+ .theme-dark image-slot::part(ring) { border-color: rgba(255, 255, 255, 0.25); }
@@ -0,0 +1,6 @@
1
+ /* ============================================================
2
+ FONT FACES
3
+ Clio ships three Google Fonts, loaded exactly as the product does
4
+ (no local binaries were found in the source — see readme.md).
5
+ ============================================================ */
6
+ @import url('https://fonts.googleapis.com/css2?family=Figtree:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&family=Kalam:wght@400;700&display=swap');
@@ -0,0 +1,15 @@
1
+ /* ============================================================
2
+ RADIUS TOKENS — Layer 1 primitives
3
+ ============================================================ */
4
+ :root {
5
+ --radius-xs: 4px; /* table cell accents, small tags */
6
+ --radius-sm: 6px; /* menu items, inline chips */
7
+ --radius-md: 8px; /* inputs, small buttons, icon buttons */
8
+ --radius-lg: 10px; /* topic/note rows, image slots */
9
+ --radius-xl: 12px; /* dropdown menus, tag-manage popovers */
10
+ --radius-2xl: 14px; /* content cards (equation, code, table, quiz…) */
11
+ --radius-3xl: 18px; /* modal, flashcard, bottom-sheet top corners */
12
+ --radius-full: 9999px; /* pill buttons, tab bar, capsule badges */
13
+ --radius-circle: 50%; /* avatar, dot indicators, circular icon buttons */
14
+ --radius-device: 44px; /* phone bezel only — not for UI content */
15
+ }
@@ -0,0 +1,75 @@
1
+ /* ============================================================
2
+ SEMANTIC TOKENS — Layer 2 (light mode / default)
3
+ What components actually consume. Every value here is an alias to
4
+ a Layer-1 primitive. Swap the aliases (e.g. point --color-background
5
+ at a different primitive) and the whole product re-skins without
6
+ touching a single component.
7
+
8
+ This file defines the LIGHT (default) values. Dark mode overrides
9
+ every alias below — see tokens/dark-mode.css, imported after this
10
+ file and after topic-accent.css/brand-theme.css.
11
+ ============================================================ */
12
+ :root {
13
+ /* Surfaces */
14
+ --color-background: var(--color-cream-50); /* desktop app canvas */
15
+ --color-background-mobile: var(--color-stone-200); /* area behind the phone bezel */
16
+ --color-surface: var(--color-white); /* cards, rows-list panel, modal, sheet */
17
+ --color-surface-sunken: var(--color-stone-100); /* selected row, active tag-bg track */
18
+ --color-surface-inverse: var(--color-ink-900); /* avatar mark, primary/download buttons */
19
+ --color-surface-code: var(--color-ink-850); /* code block */
20
+
21
+ /* Text */
22
+ --color-text-primary: var(--color-ink-900); /* headings, titles, selected row text */
23
+ --color-text-body: var(--color-ink-800); /* paragraph copy */
24
+ --color-text-secondary: var(--color-ink-700); /* menu items, icon-button glyphs */
25
+ --color-text-tertiary: var(--color-ink-600); /* de-emphasized labels */
26
+ --color-text-muted: var(--color-ink-500); /* meta text, mono captions, placeholders */
27
+ --color-text-faint: var(--color-ink-400); /* timestamps, unselected tab labels */
28
+ --color-text-disabled: var(--color-ink-300); /* chevrons, disabled marks */
29
+ --color-text-on-inverse: var(--color-cream-50); /* text on avatar / primary button */
30
+ --color-text-on-code: var(--color-ink-200); /* code block body text */
31
+ --color-text-code-accent: var(--color-code-green); /* "CODE" eyebrow label */
32
+
33
+ /* Accent — see the "Dynamic accent" pattern below. This is the
34
+ fallback/base value; it is overridden per-topic at runtime. */
35
+ --color-accent: var(--color-indigo-600);
36
+ --color-accent-tint: color-mix(in srgb, var(--color-accent) 8%, transparent); /* quiz/checkpoint card fill */
37
+
38
+ /* Feedback — derived via color-mix from the base hue so dark-mode's
39
+ lightened success/danger/warning automatically retint these too */
40
+ --color-success: var(--color-green-600);
41
+ --color-success-tint: color-mix(in srgb, var(--color-success) 7%, transparent);
42
+ --color-success-border: color-mix(in srgb, var(--color-success) 45%, transparent);
43
+ --color-danger: var(--color-red-700);
44
+ --color-danger-tint: color-mix(in srgb, var(--color-danger) 7%, transparent);
45
+ --color-danger-border: color-mix(in srgb, var(--color-danger) 45%, transparent);
46
+ --color-warning: var(--color-amber-700);
47
+ --color-warning-tint: color-mix(in srgb, var(--color-warning) 7%, transparent);
48
+ --color-warning-border: color-mix(in srgb, var(--color-warning) 20%, transparent);
49
+
50
+ /* Annotation ("My note") — always amber, independent of topic accent */
51
+ --color-annotation-text: #7A5B10;
52
+ --color-annotation-label: var(--color-amber-700);
53
+ --color-annotation-border: var(--color-amber-500);
54
+ --color-annotation-fill: var(--color-amber-tint);
55
+
56
+ /* Borders — hairline scale, all alpha-black */
57
+ --border-hairline: rgba(17, 17, 17, 0.06); /* topbar / header dividers */
58
+ --border-subtle: rgba(17, 17, 17, 0.07); /* card / table-row dividers */
59
+ --border-default: rgba(17, 17, 17, 0.09); /* card outlines */
60
+ --border-medium: rgba(17, 17, 17, 0.12); /* inputs, secondary buttons */
61
+ --border-strong: rgba(17, 17, 17, 0.15); /* dashed add-buttons, flashcard outline */
62
+ --border-focus: var(--color-accent);
63
+
64
+ /* Radii aliases by role (still just pointing at Layer 1) */
65
+ --radius-control: var(--radius-md); /* buttons, inputs */
66
+ --radius-row: var(--radius-lg); /* list rows */
67
+ --radius-card: var(--radius-2xl); /* content cards */
68
+ --radius-surface: var(--radius-3xl); /* modal / sheet / flashcard */
69
+ --radius-pill: var(--radius-full); /* tabs, capsule buttons, tag chips */
70
+
71
+ /* Motion */
72
+ --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
73
+ --duration-fast: 0.15s;
74
+ --duration-standard: 0.28s;
75
+ }
@@ -0,0 +1,14 @@
1
+ /* ============================================================
2
+ SHADOW / ELEVATION TOKENS — Layer 1 primitives
3
+ Clio is a flat, matte product — shadows are used sparingly, only to
4
+ lift transient/floating surfaces (menus, modals, sheets, the phone
5
+ bezel itself). Cards and rows use a hairline border, never a shadow.
6
+ ============================================================ */
7
+ :root {
8
+ --shadow-sm: 0 2px 12px rgba(17, 17, 17, 0.05); /* flashcard resting state */
9
+ --shadow-md: 0 8px 24px rgba(17, 17, 17, 0.14); /* dropdown / context menus */
10
+ --shadow-lg: 0 24px 64px rgba(17, 17, 17, 0.30); /* centered modal (import/export) */
11
+ --shadow-sheet: 0 -12px 32px rgba(17, 17, 17, 0.20); /* bottom action sheet, casts upward */
12
+ --shadow-fab: 0 6px 16px rgba(17, 17, 17, 0.30); /* mobile TOC FAB */
13
+ --shadow-device: 0 30px 60px rgba(17, 17, 17, 0.30); /* phone bezel on desktop canvas */
14
+ }
@@ -0,0 +1,20 @@
1
+ /* ============================================================
2
+ SPACING TOKENS — Layer 1 primitives
3
+ ============================================================ */
4
+ :root {
5
+ --space-1: 2px;
6
+ --space-2: 4px;
7
+ --space-3: 6px;
8
+ --space-4: 8px;
9
+ --space-5: 10px;
10
+ --space-6: 12px;
11
+ --space-7: 14px;
12
+ --space-8: 16px;
13
+ --space-9: 18px;
14
+ --space-10: 20px;
15
+ --space-12: 24px;
16
+ --space-14: 28px;
17
+ --space-16: 32px;
18
+ --space-20: 40px;
19
+ --space-24: 48px;
20
+ }
@@ -0,0 +1,28 @@
1
+ /* ============================================================
2
+ TOPIC ACCENT PATTERN
3
+ --color-accent is dynamic: Clio recolors the entire active-topic
4
+ context by overriding this one variable — the descent-lemma note
5
+ accents everything in violet, the phase-diagram note in orange, etc.
6
+ Components never hardcode a topic color; they all read var(--color-accent).
7
+
8
+ USAGE — set it inline, scoped to whatever subtree is "in" that topic:
9
+
10
+ <div style="--color-accent: var(--color-topic-violet);">
11
+ ...entire Learn pane for a Machine Learning note...
12
+ </div>
13
+
14
+ The 8 values below are the ONLY colors ever assigned to a topic —
15
+ treat this as a closed palette, not a suggestion; do not invent new
16
+ topic hues. Order matches the product's assignment order (new topics
17
+ cycle through this list).
18
+ ============================================================ */
19
+ :root {
20
+ --color-topic-red: var(--color-red-600); /* 1. Terracotta Red */
21
+ --color-topic-orange: var(--color-orange-700); /* 2. Rust Orange */
22
+ --color-topic-ochre: var(--color-amber-700); /* 3. Ochre */
23
+ --color-topic-blue: var(--color-blue-600); /* 4. Steel Blue */
24
+ --color-topic-green: var(--color-green-700); /* 5. Forest Green */
25
+ --color-topic-violet: var(--color-violet-600); /* 6. Violet */
26
+ --color-topic-teal: var(--color-teal-600); /* 7. Teal */
27
+ --color-topic-magenta: var(--color-pink-600); /* 8. Magenta */
28
+ }
@@ -0,0 +1,40 @@
1
+ /* ============================================================
2
+ TYPE TOKENS — Layer 1 primitives (families, weights, raw sizes)
3
+ ============================================================ */
4
+ :root {
5
+ /* Families — three-role system: UI sans, mono for labels/data, hand
6
+ script reserved exclusively for the user's own annotations */
7
+ --font-family-sans: 'Figtree', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
8
+ --font-family-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;
9
+ --font-family-hand: 'Kalam', cursive;
10
+
11
+ --font-weight-regular: 400;
12
+ --font-weight-medium: 500;
13
+ --font-weight-semibold: 600;
14
+ --font-weight-bold: 700;
15
+
16
+ /* Raw size scale — systematized from the prototype's ad-hoc sizes
17
+ (9 / 9.5 / 10 / 10.5 / 11 / 11.5 / 12 / 12.5 / 13 / 13.5 / 14 / 14.5 /
18
+ 15 / 15.5 / 17 / 21 / 22 / 26 / 29px) into one clean named scale. */
19
+ --font-size-2xs: 9px; /* diff-dots, mcq check/x marks, credit overlays */
20
+ --font-size-xs: 10px; /* mono nav labels, badges, toc labels */
21
+ --font-size-sm: 11px; /* secondary mono labels, button text, meta */
22
+ --font-size-md: 12px; /* dense mono body (code, table refs) */
23
+ --font-size-base: 13px; /* compact UI copy, chips, table cells */
24
+ --font-size-lg: 14px; /* default paragraph copy */
25
+ --font-size-xl: 15px; /* app base font size, sidebar row titles */
26
+ --font-size-2xl: 17px; /* flashcard prompt */
27
+ --font-size-3xl: 21px; /* mobile note H1 */
28
+ --font-size-4xl: 26px; /* practice / review H1 */
29
+ --font-size-5xl: 29px; /* desktop note H1 */
30
+
31
+ --line-height-tight: 1.25;
32
+ --line-height-snug: 1.35;
33
+ --line-height-normal: 1.55;
34
+ --line-height-relaxed: 1.7;
35
+
36
+ --letter-spacing-mono-label: 0.1em; /* nav tabs, badges */
37
+ --letter-spacing-mono-wide: 0.14em; /* CLIO wordmark, section eyebrows */
38
+ --letter-spacing-mono-wider: 0.18em; /* sidebar section headers (TOPICS) */
39
+ --letter-spacing-tight: -0.015em; /* H1 headings */
40
+ }