@nim.zone/ui 0.6.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/LICENSE +21 -0
- package/README.md +681 -0
- package/dist/components/admin-shell.d.ts +121 -0
- package/dist/components/app-shell.d.ts +23 -0
- package/dist/components/auth-screen.d.ts +33 -0
- package/dist/components/avatar.d.ts +10 -0
- package/dist/components/badge.d.ts +14 -0
- package/dist/components/banner.d.ts +11 -0
- package/dist/components/breadcrumb.d.ts +12 -0
- package/dist/components/button.d.ts +21 -0
- package/dist/components/card.d.ts +15 -0
- package/dist/components/chat-composer.d.ts +52 -0
- package/dist/components/chat.d.ts +77 -0
- package/dist/components/checkout.d.ts +79 -0
- package/dist/components/choice.d.ts +15 -0
- package/dist/components/combobox.d.ts +31 -0
- package/dist/components/date-field.d.ts +58 -0
- package/dist/components/dialog.d.ts +20 -0
- package/dist/components/empty-state.d.ts +9 -0
- package/dist/components/feedback.d.ts +18 -0
- package/dist/components/field.d.ts +47 -0
- package/dist/components/icon-button.d.ts +12 -0
- package/dist/components/icon.d.ts +72 -0
- package/dist/components/layout.d.ts +13 -0
- package/dist/components/list.d.ts +16 -0
- package/dist/components/menu.d.ts +56 -0
- package/dist/components/onboarding.d.ts +50 -0
- package/dist/components/otp-input.d.ts +29 -0
- package/dist/components/pagination.d.ts +12 -0
- package/dist/components/password-field.d.ts +33 -0
- package/dist/components/phone-field.d.ts +44 -0
- package/dist/components/plan-card.d.ts +45 -0
- package/dist/components/plan-picker.d.ts +52 -0
- package/dist/components/profile-header.d.ts +47 -0
- package/dist/components/profile-screen.d.ts +44 -0
- package/dist/components/resource-meter.d.ts +22 -0
- package/dist/components/section-header.d.ts +8 -0
- package/dist/components/segmented.d.ts +18 -0
- package/dist/components/sheet.d.ts +18 -0
- package/dist/components/sign-in-flow.d.ts +60 -0
- package/dist/components/slider.d.ts +10 -0
- package/dist/components/stat.d.ts +10 -0
- package/dist/components/stepper.d.ts +17 -0
- package/dist/components/tab-bar.d.ts +40 -0
- package/dist/components/table.d.ts +33 -0
- package/dist/components/tabs.d.ts +23 -0
- package/dist/components/task-progress.d.ts +38 -0
- package/dist/components/theme.d.ts +49 -0
- package/dist/components/toast.d.ts +17 -0
- package/dist/components/tooltip.d.ts +18 -0
- package/dist/components/typography.d.ts +18 -0
- package/dist/components/wizard.d.ts +70 -0
- package/dist/index.d.ts +104 -0
- package/dist/lib/calendars.d.ts +81 -0
- package/dist/lib/cn.d.ts +7 -0
- package/dist/lib/countries.d.ts +33 -0
- package/dist/lib/use-anchor.d.ts +22 -0
- package/dist/nim.css +1 -0
- package/dist/nim.js +3266 -0
- package/package.json +83 -0
- package/src/components/admin-shell.tsx +338 -0
- package/src/components/app-shell.tsx +36 -0
- package/src/components/auth-screen.tsx +71 -0
- package/src/components/avatar.tsx +32 -0
- package/src/components/badge.tsx +44 -0
- package/src/components/banner.tsx +47 -0
- package/src/components/breadcrumb.tsx +45 -0
- package/src/components/button.tsx +64 -0
- package/src/components/card.tsx +46 -0
- package/src/components/chat-composer.tsx +331 -0
- package/src/components/chat.tsx +352 -0
- package/src/components/checkout.tsx +173 -0
- package/src/components/choice.tsx +46 -0
- package/src/components/combobox.tsx +157 -0
- package/src/components/date-field.tsx +394 -0
- package/src/components/dialog.tsx +77 -0
- package/src/components/empty-state.tsx +23 -0
- package/src/components/feedback.tsx +61 -0
- package/src/components/field.tsx +177 -0
- package/src/components/icon-button.tsx +35 -0
- package/src/components/icon.tsx +167 -0
- package/src/components/layout.tsx +38 -0
- package/src/components/list.tsx +78 -0
- package/src/components/menu.tsx +172 -0
- package/src/components/onboarding.tsx +157 -0
- package/src/components/otp-input.tsx +144 -0
- package/src/components/pagination.tsx +86 -0
- package/src/components/password-field.tsx +112 -0
- package/src/components/phone-field.tsx +242 -0
- package/src/components/plan-card.tsx +124 -0
- package/src/components/plan-picker.tsx +144 -0
- package/src/components/profile-header.tsx +134 -0
- package/src/components/profile-screen.tsx +104 -0
- package/src/components/resource-meter.tsx +60 -0
- package/src/components/section-header.tsx +31 -0
- package/src/components/segmented.tsx +53 -0
- package/src/components/sheet.tsx +74 -0
- package/src/components/sign-in-flow.tsx +322 -0
- package/src/components/slider.tsx +50 -0
- package/src/components/stat.tsx +30 -0
- package/src/components/stepper.tsx +77 -0
- package/src/components/tab-bar.tsx +82 -0
- package/src/components/table.tsx +81 -0
- package/src/components/tabs.tsx +72 -0
- package/src/components/task-progress.tsx +111 -0
- package/src/components/theme.tsx +112 -0
- package/src/components/toast.tsx +87 -0
- package/src/components/tooltip.tsx +30 -0
- package/src/components/typography.tsx +65 -0
- package/src/components/wizard.tsx +192 -0
- package/src/index.ts +216 -0
- package/src/lib/calendars.ts +227 -0
- package/src/lib/cn.ts +8 -0
- package/src/lib/countries.ts +110 -0
- package/src/lib/use-anchor.ts +92 -0
- package/src/theme/colorways/coral.css +62 -0
- package/src/theme/colorways/oxblood.css +23 -0
- package/src/theme/colorways/paper.css +68 -0
- package/src/theme/colorways/teal.css +56 -0
- package/src/theme/colorways/vermilion.css +21 -0
- package/src/theme/components.css +4606 -0
- package/src/theme/contract.css +204 -0
- package/src/theme/fonts.css +67 -0
- package/src/theme/index.css +33 -0
- package/src/theme/persian.css +47 -0
- package/src/theme/reset.css +118 -0
- package/src/theme/styles/ledger.css +106 -0
- package/src/theme/styles/vlora.css +91 -0
- package/src/vite-env.d.ts +1 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
nim — TOKEN CONTRACT
|
|
3
|
+
|
|
4
|
+
This file declares the vocabulary every nim component is allowed to speak.
|
|
5
|
+
Components reference these names and nothing else; a theme file is the only
|
|
6
|
+
place a literal colour, radius, shadow, or type value may appear.
|
|
7
|
+
|
|
8
|
+
The contract is split in two:
|
|
9
|
+
|
|
10
|
+
· Invariants (below) — scale, rhythm, motion, geometry of touch. These are
|
|
11
|
+
ergonomic facts rather than brand decisions, so they are identical in
|
|
12
|
+
every theme and are set here once.
|
|
13
|
+
· Personality (themes/*.css) — colour, shape, elevation, and type voice.
|
|
14
|
+
A theme MUST define every `--nim-*` name listed in the "required of a
|
|
15
|
+
theme" block at the bottom of this file, or components will fall back to
|
|
16
|
+
an unstyled value.
|
|
17
|
+
|
|
18
|
+
Naming: `--nim-<role>-<modifier>`. Roles are semantic (canvas, surface, ink,
|
|
19
|
+
line, accent), never literal (never `--nim-orange`, never `--nim-gray-300`).
|
|
20
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
21
|
+
|
|
22
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
+
SCHEME
|
|
24
|
+
|
|
25
|
+
Every colour in a colourway is a `light-dark()` pair, and `color-scheme` is
|
|
26
|
+
what picks a side. Setting it here means a colourway is ONE block: no
|
|
27
|
+
duplicated dark rule, no `prefers-color-scheme` query per palette, and no
|
|
28
|
+
hand-maintained exclusion list to fall behind — which is exactly how a theme
|
|
29
|
+
ended up inheriting another one's dark palette before 0.2.
|
|
30
|
+
|
|
31
|
+
Unset follows the OS. `data-nim-scheme` pins it.
|
|
32
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
33
|
+
|
|
34
|
+
:where(:root),
|
|
35
|
+
:where(.nim-root) {
|
|
36
|
+
color-scheme: light dark;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[data-nim-scheme='light'] {
|
|
40
|
+
color-scheme: light;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[data-nim-scheme='dark'] {
|
|
44
|
+
color-scheme: dark;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
:root {
|
|
48
|
+
/* ─── Space ────────────────────────────────────────────────────────────
|
|
49
|
+
A 4px base. Components use steps, never raw pixels, so density can be
|
|
50
|
+
retuned globally by overriding this scale alone. */
|
|
51
|
+
--nim-space-0: 0px;
|
|
52
|
+
--nim-space-1: 4px;
|
|
53
|
+
--nim-space-2: 8px;
|
|
54
|
+
--nim-space-3: 12px;
|
|
55
|
+
--nim-space-4: 16px;
|
|
56
|
+
--nim-space-5: 20px;
|
|
57
|
+
--nim-space-6: 24px;
|
|
58
|
+
--nim-space-7: 32px;
|
|
59
|
+
--nim-space-8: 40px;
|
|
60
|
+
--nim-space-9: 48px;
|
|
61
|
+
--nim-space-10: 64px;
|
|
62
|
+
--nim-space-11: 80px;
|
|
63
|
+
--nim-space-12: 104px;
|
|
64
|
+
|
|
65
|
+
/* ─── Type scale ───────────────────────────────────────────────────────
|
|
66
|
+
Absolute sizes, named by their pixel value at the browser default. The
|
|
67
|
+
composite `--nim-type-*` roles in a theme are built from these. */
|
|
68
|
+
--nim-text-11: 0.6875rem;
|
|
69
|
+
--nim-text-12: 0.75rem;
|
|
70
|
+
--nim-text-13: 0.8125rem;
|
|
71
|
+
--nim-text-14: 0.875rem;
|
|
72
|
+
--nim-text-15: 0.9375rem;
|
|
73
|
+
--nim-text-16: 1rem;
|
|
74
|
+
--nim-text-18: 1.125rem;
|
|
75
|
+
--nim-text-20: 1.25rem;
|
|
76
|
+
--nim-text-24: 1.5rem;
|
|
77
|
+
--nim-text-28: 1.75rem;
|
|
78
|
+
--nim-text-32: 2rem;
|
|
79
|
+
--nim-text-40: 2.5rem;
|
|
80
|
+
|
|
81
|
+
--nim-weight-regular: 400;
|
|
82
|
+
--nim-weight-medium: 500;
|
|
83
|
+
--nim-weight-semibold: 600;
|
|
84
|
+
--nim-weight-bold: 700;
|
|
85
|
+
|
|
86
|
+
/* ─── Motion ───────────────────────────────────────────────────────────
|
|
87
|
+
Three durations and three curves is the whole budget. `spring` overshoots
|
|
88
|
+
and is reserved for elements that enter; `standard` is everything else. */
|
|
89
|
+
--nim-dur-fast: 140ms;
|
|
90
|
+
--nim-dur-base: 240ms;
|
|
91
|
+
--nim-dur-slow: 400ms;
|
|
92
|
+
--nim-ease-standard: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
93
|
+
--nim-ease-decelerate: cubic-bezier(0, 0, 0.2, 1);
|
|
94
|
+
--nim-ease-spring: cubic-bezier(0.34, 1.5, 0.64, 1);
|
|
95
|
+
|
|
96
|
+
/* ─── Density ──────────────────────────────────────────────────────────
|
|
97
|
+
One multiplier retunes the whole interface at once. It scales the control
|
|
98
|
+
heights below and the block padding of anything row-shaped (list rows,
|
|
99
|
+
table cells), so a data-dense screen and a mobile flow stay the same
|
|
100
|
+
system rather than the same components at hand-tuned sizes.
|
|
101
|
+
|
|
102
|
+
Set it on any subtree: `style="--nim-density: 0.82"`. It never scales
|
|
103
|
+
type, and it never scales `--nim-touch-min`, which is a floor.
|
|
104
|
+
|
|
105
|
+
The multiplication lives in `components.css`, at each place a height is
|
|
106
|
+
used — `calc(var(--nim-control-md) * var(--nim-density))` — and not in the
|
|
107
|
+
control tokens below. A custom property that references another custom
|
|
108
|
+
property is substituted where it is DECLARED, so folding density into
|
|
109
|
+
`--nim-control-md` here would freeze it at the root's value and a subtree
|
|
110
|
+
override would silently do nothing. */
|
|
111
|
+
--nim-density: 1;
|
|
112
|
+
|
|
113
|
+
/* ─── Control geometry ─────────────────────────────────────────────────
|
|
114
|
+
Heights are shared across every control so a button, an input, and a
|
|
115
|
+
select line up on the same row without per-component nudging. 44px is the
|
|
116
|
+
minimum touch target and is never reduced, only visually inset. */
|
|
117
|
+
--nim-control-sm: 36px;
|
|
118
|
+
--nim-control-md: 44px;
|
|
119
|
+
--nim-control-lg: 52px;
|
|
120
|
+
--nim-touch-min: 44px;
|
|
121
|
+
--nim-border-width: 1px;
|
|
122
|
+
|
|
123
|
+
/* ─── Fixed sizes ──────────────────────────────────────────────────────
|
|
124
|
+
Geometry that is neither a space step nor a control height: the diameter
|
|
125
|
+
of a dot, the side of an avatar, the thickness of a track. These lived as
|
|
126
|
+
literals inside `components.css` until 0.2, which put them outside the
|
|
127
|
+
contract — a theme could not answer them, so an icon set drawn at a
|
|
128
|
+
different optical weight had no way in. */
|
|
129
|
+
--nim-size-dot: 6px;
|
|
130
|
+
--nim-size-icon-xs: 14px;
|
|
131
|
+
--nim-size-icon-sm: 16px;
|
|
132
|
+
--nim-size-icon-md: 20px;
|
|
133
|
+
--nim-size-icon-lg: 24px;
|
|
134
|
+
--nim-size-icon-xl: 32px;
|
|
135
|
+
--nim-size-avatar-sm: 28px;
|
|
136
|
+
--nim-size-avatar-md: 40px;
|
|
137
|
+
--nim-size-avatar-lg: 56px;
|
|
138
|
+
--nim-size-track: 6px;
|
|
139
|
+
--nim-size-handle: 36px;
|
|
140
|
+
--nim-size-handle-thickness: 4px;
|
|
141
|
+
--nim-size-focus-ring: 2px;
|
|
142
|
+
--nim-size-focus-offset: 2px;
|
|
143
|
+
|
|
144
|
+
/* ─── Layout ───────────────────────────────────────────────────────────
|
|
145
|
+
`frame` is the mobile app frame on a desktop viewport; `content` is a
|
|
146
|
+
comfortable column; `measure` is the reading measure for prose. */
|
|
147
|
+
--nim-frame-max: 768px;
|
|
148
|
+
--nim-content-max: 680px;
|
|
149
|
+
--nim-measure: 34rem;
|
|
150
|
+
--nim-safe-top: env(safe-area-inset-top, 0px);
|
|
151
|
+
--nim-safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
152
|
+
|
|
153
|
+
/* ─── Z layers ─────────────────────────────────────────────────────────
|
|
154
|
+
Named so no component invents its own number. */
|
|
155
|
+
--nim-z-sticky: 20;
|
|
156
|
+
--nim-z-nav: 40;
|
|
157
|
+
--nim-z-scrim: 60;
|
|
158
|
+
--nim-z-sheet: 70;
|
|
159
|
+
--nim-z-toast: 90;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
163
|
+
REQUIRED OF A STYLE · REQUIRED OF A COLOURWAY
|
|
164
|
+
|
|
165
|
+
nim has two independent axes, and each answers half of this list. A style
|
|
166
|
+
owns how the interface is SHAPED; a colourway owns how it is COLOURED. That
|
|
167
|
+
split is why `oxblood` is six declarations rather than a 220-line theme, and
|
|
168
|
+
why a new palette cannot accidentally change a radius.
|
|
169
|
+
|
|
170
|
+
Both are listed here as documentation — deliberately without values, so a
|
|
171
|
+
missing token fails loudly in review rather than silently inheriting a
|
|
172
|
+
neutral grey.
|
|
173
|
+
|
|
174
|
+
── A STYLE must define (`styles/*.css`) ───────────────────────────────
|
|
175
|
+
Shape --nim-radius-xs · -sm · -md · -lg · -xl · -pill
|
|
176
|
+
Elevation --nim-shadow-sm · -md · -lg (geometry; drawn in the
|
|
177
|
+
colourway's --nim-shadow-tint-*)
|
|
178
|
+
--nim-shadow-focus · --nim-shadow-focus-danger
|
|
179
|
+
Type --nim-font-sans · --nim-font-mono · --nim-font-numeric
|
|
180
|
+
--nim-type-display-* · --nim-type-title-* · --nim-type-body-*
|
|
181
|
+
--nim-type-control-* · --nim-type-label-* · --nim-type-caption-*
|
|
182
|
+
--nim-tracking-tight · -normal · -wide
|
|
183
|
+
--nim-leading-base · -tight · -normal · -relaxed
|
|
184
|
+
Voice --nim-label-transform · --nim-label-tracking
|
|
185
|
+
--nim-press-scale · --nim-press-translate
|
|
186
|
+
|
|
187
|
+
── A COLOURWAY must define (`colorways/*.css`) ────────────────────────
|
|
188
|
+
Every value as a `light-dark()` pair.
|
|
189
|
+
|
|
190
|
+
Surfaces --nim-canvas · --nim-canvas-sunken · --nim-surface
|
|
191
|
+
--nim-surface-raised · --nim-surface-muted · --nim-scrim
|
|
192
|
+
Ink --nim-ink · --nim-ink-secondary · --nim-ink-tertiary
|
|
193
|
+
--nim-ink-inverse · --nim-on-accent
|
|
194
|
+
Lines --nim-line · --nim-line-soft · --nim-line-strong
|
|
195
|
+
Accent --nim-accent · --nim-accent-hover · --nim-accent-strong
|
|
196
|
+
--nim-accent-soft · --nim-accent-line
|
|
197
|
+
Status --nim-success · --nim-success-soft · --nim-warning
|
|
198
|
+
--nim-warning-soft · --nim-danger · --nim-danger-hover
|
|
199
|
+
--nim-danger-soft · --nim-info · --nim-info-soft
|
|
200
|
+
Elevation --nim-shadow-tint-sm · -md · -lg
|
|
201
|
+
|
|
202
|
+
Colourways that share a neutral half state it once under a grouped
|
|
203
|
+
selector — see `colorways/paper.css`.
|
|
204
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
nim — VAZIRMATN (optional)
|
|
3
|
+
|
|
4
|
+
The Persian face used across this repo's Farsi products (vlora-app,
|
|
5
|
+
vlora-web, vlora-admin, iranianlawclub-web). It is NOT part of
|
|
6
|
+
`nim/styles.css`: a stylesheet that requests font files the host does not
|
|
7
|
+
serve produces four 404s and a flash of fallback, so loading the face is an
|
|
8
|
+
explicit decision.
|
|
9
|
+
|
|
10
|
+
import 'nim/fonts.css'
|
|
11
|
+
|
|
12
|
+
Then serve the three subsets at `/fonts/` — the convention every Farsi app
|
|
13
|
+
in this repo already follows:
|
|
14
|
+
|
|
15
|
+
public/fonts/vazirmatn-arabic.woff2
|
|
16
|
+
public/fonts/vazirmatn-latin-ext.woff2
|
|
17
|
+
public/fonts/vazirmatn-latin.woff2
|
|
18
|
+
|
|
19
|
+
An app that serves them elsewhere skips this file and declares its own
|
|
20
|
+
`@font-face`; nothing else in the kit depends on it. `--nim-font-sans` on
|
|
21
|
+
the `vlora` style already names 'Vazirmatn' first, so the face is picked up
|
|
22
|
+
as soon as it loads.
|
|
23
|
+
|
|
24
|
+
One variable file per subset, weight 100–900, so a single request covers
|
|
25
|
+
every weight the kit uses. Vazirmatn is licensed under the SIL Open Font
|
|
26
|
+
License 1.1.
|
|
27
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
28
|
+
|
|
29
|
+
/* Arabic subset — every Persian/Arabic character, all weights. */
|
|
30
|
+
@font-face {
|
|
31
|
+
font-family: 'Vazirmatn';
|
|
32
|
+
font-style: normal;
|
|
33
|
+
font-weight: 100 900;
|
|
34
|
+
font-display: swap;
|
|
35
|
+
src: url('/fonts/vazirmatn-arabic.woff2') format('woff2');
|
|
36
|
+
unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF,
|
|
37
|
+
U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC,
|
|
38
|
+
U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F,
|
|
39
|
+
U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42,
|
|
40
|
+
U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59,
|
|
41
|
+
U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72,
|
|
42
|
+
U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3,
|
|
43
|
+
U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Latin-ext subset, all weights. */
|
|
47
|
+
@font-face {
|
|
48
|
+
font-family: 'Vazirmatn';
|
|
49
|
+
font-style: normal;
|
|
50
|
+
font-weight: 100 900;
|
|
51
|
+
font-display: swap;
|
|
52
|
+
src: url('/fonts/vazirmatn-latin-ext.woff2') format('woff2');
|
|
53
|
+
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
|
|
54
|
+
U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
|
|
55
|
+
U+2113, U+2C60-2C7F, U+A720-A7FF;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Latin subset, all weights. */
|
|
59
|
+
@font-face {
|
|
60
|
+
font-family: 'Vazirmatn';
|
|
61
|
+
font-style: normal;
|
|
62
|
+
font-weight: 100 900;
|
|
63
|
+
font-display: swap;
|
|
64
|
+
src: url('/fonts/vazirmatn-latin.woff2') format('woff2');
|
|
65
|
+
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
|
|
66
|
+
U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
|
67
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
nim — stylesheet entry
|
|
3
|
+
|
|
4
|
+
Import order is load-bearing:
|
|
5
|
+
1. the contract — invariants every component relies on, and the
|
|
6
|
+
`color-scheme` switch that resolves `light-dark()`
|
|
7
|
+
2. styles — shape, elevation geometry, type voice, press
|
|
8
|
+
3. colourways — surfaces, ink, lines, accent, status, shadow tint
|
|
9
|
+
4. persian — script corrections that must outrank a style
|
|
10
|
+
5. reset — scoped to `.nim-root`, never global
|
|
11
|
+
6. components — the only file that draws anything
|
|
12
|
+
|
|
13
|
+
Style and colourway are two independent axes. A product that wants one
|
|
14
|
+
pairing can import `contract.css`, its style, its colourway, `reset.css`
|
|
15
|
+
and `components.css` directly and skip the rest.
|
|
16
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
17
|
+
|
|
18
|
+
@import './contract.css';
|
|
19
|
+
|
|
20
|
+
@import './styles/ledger.css';
|
|
21
|
+
@import './styles/vlora.css';
|
|
22
|
+
|
|
23
|
+
@import './colorways/paper.css';
|
|
24
|
+
@import './colorways/vermilion.css';
|
|
25
|
+
@import './colorways/oxblood.css';
|
|
26
|
+
@import './colorways/coral.css';
|
|
27
|
+
@import './colorways/teal.css';
|
|
28
|
+
|
|
29
|
+
/* Script corrections come after the styles so they win on source order. */
|
|
30
|
+
@import './persian.css';
|
|
31
|
+
|
|
32
|
+
@import './reset.css';
|
|
33
|
+
@import './components.css';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
nim — PERSIAN / ARABIC SCRIPT CORRECTIONS
|
|
3
|
+
|
|
4
|
+
Two of nim's type tokens are actively harmful to Persian, and neither is a
|
|
5
|
+
style's fault — they are correct for Latin and wrong for a joined script:
|
|
6
|
+
|
|
7
|
+
· `--nim-label-tracking` (0.12em on the ledger style) pulls apart letters
|
|
8
|
+
that must stay connected. Tracking a Persian word does not space it out,
|
|
9
|
+
it breaks it.
|
|
10
|
+
· negative tracking on display and title sizes does the same thing more
|
|
11
|
+
subtly.
|
|
12
|
+
|
|
13
|
+
`text-transform: uppercase` is a no-op on Persian glyphs, but it still
|
|
14
|
+
shouts at any Latin mixed into the same label, so it goes too.
|
|
15
|
+
|
|
16
|
+
Scoped to the LANGUAGE, not the direction: `dir="rtl"` says which way the
|
|
17
|
+
line runs, `lang="fa"` says which script is being set, and only the second
|
|
18
|
+
one implies these corrections. An RTL page of Latin text wants none of them.
|
|
19
|
+
|
|
20
|
+
Unlayered and imported after the styles, so it wins on source order rather
|
|
21
|
+
than by inflating specificity — a style could otherwise re-break it.
|
|
22
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
23
|
+
|
|
24
|
+
:is(:lang(fa), :lang(ar), [lang='fa'], [lang='ar']) {
|
|
25
|
+
--nim-label-transform: none;
|
|
26
|
+
--nim-label-tracking: 0;
|
|
27
|
+
--nim-tracking-tight: 0;
|
|
28
|
+
--nim-tracking-normal: 0;
|
|
29
|
+
--nim-tracking-wide: 0;
|
|
30
|
+
--nim-type-display-tracking: 0;
|
|
31
|
+
--nim-type-control-tracking: 0;
|
|
32
|
+
--nim-type-control-transform: none;
|
|
33
|
+
|
|
34
|
+
/* `calt` and `kern` shape the joins; `ss01` is Vazirmatn's Persian-preferred
|
|
35
|
+
forms (the four-dot heh, the Persian kaf and yeh). */
|
|
36
|
+
font-feature-settings: 'calt' 1, 'kern' 1, 'ss01' 1;
|
|
37
|
+
word-spacing: normal;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* Persian text is read at a looser rhythm than Latin at the same size. The
|
|
41
|
+
ledger style is set for Latin, so a Farsi page on it gets the room the
|
|
42
|
+
vlora style already builds in. */
|
|
43
|
+
:is(:lang(fa), :lang(ar), [lang='fa'], [lang='ar']):is([data-nim-style='ledger'], :not([data-nim-style])) {
|
|
44
|
+
--nim-leading-base: 1.7;
|
|
45
|
+
--nim-leading-tight: 1.35;
|
|
46
|
+
--nim-leading-relaxed: 1.9;
|
|
47
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
nim — RESET
|
|
3
|
+
Only what the kit depends on. It is deliberately small: nim is meant to drop
|
|
4
|
+
into an existing app without repainting that app's own markup.
|
|
5
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
6
|
+
|
|
7
|
+
@layer base {
|
|
8
|
+
*,
|
|
9
|
+
*::before,
|
|
10
|
+
*::after {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.nim-root,
|
|
15
|
+
.nim-root * {
|
|
16
|
+
margin: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* The scoped root. Applying it to <body> themes the whole app; applying it
|
|
20
|
+
to a subtree lets nim live beside another design system. */
|
|
21
|
+
.nim-root {
|
|
22
|
+
background: var(--nim-canvas);
|
|
23
|
+
color: var(--nim-ink);
|
|
24
|
+
font-family: var(--nim-font-sans);
|
|
25
|
+
font-size: var(--nim-type-body-size);
|
|
26
|
+
line-height: var(--nim-type-body-line);
|
|
27
|
+
letter-spacing: var(--nim-tracking-normal);
|
|
28
|
+
text-rendering: optimizeLegibility;
|
|
29
|
+
-webkit-font-smoothing: antialiased;
|
|
30
|
+
-moz-osx-font-smoothing: grayscale;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Portalled surfaces mount on <body>, outside `.nim-root` — so they inherit
|
|
34
|
+
the document's default serif rather than the kit's typography. Every
|
|
35
|
+
component that portals is listed here and given the same ground the root
|
|
36
|
+
establishes. Missing this is invisible in Latin at a glance and glaring in
|
|
37
|
+
Persian, where the fallback has no matching face at all. */
|
|
38
|
+
.nim-sheet__panel,
|
|
39
|
+
.nim-menu,
|
|
40
|
+
.nim-popover,
|
|
41
|
+
.nim-toast-stack {
|
|
42
|
+
color: var(--nim-ink);
|
|
43
|
+
font-family: var(--nim-font-sans);
|
|
44
|
+
font-size: var(--nim-type-body-size);
|
|
45
|
+
line-height: var(--nim-type-body-line);
|
|
46
|
+
letter-spacing: var(--nim-tracking-normal);
|
|
47
|
+
text-rendering: optimizeLegibility;
|
|
48
|
+
-webkit-font-smoothing: antialiased;
|
|
49
|
+
-moz-osx-font-smoothing: grayscale;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.nim-sheet__panel :is(input, button, textarea, select),
|
|
53
|
+
.nim-menu :is(input, button, textarea, select),
|
|
54
|
+
.nim-popover :is(input, button, textarea, select) {
|
|
55
|
+
font: inherit;
|
|
56
|
+
color: inherit;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.nim-root img,
|
|
60
|
+
.nim-root svg,
|
|
61
|
+
.nim-root video,
|
|
62
|
+
.nim-root canvas {
|
|
63
|
+
display: block;
|
|
64
|
+
max-inline-size: 100%;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.nim-root :is(input, button, textarea, select) {
|
|
68
|
+
font: inherit;
|
|
69
|
+
color: inherit;
|
|
70
|
+
letter-spacing: inherit;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.nim-root :is(ul, ol):where([class*='nim-']) {
|
|
74
|
+
list-style: none;
|
|
75
|
+
padding: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* One focus treatment for the entire kit, drawn outside the box so it never
|
|
79
|
+
shifts layout and never gets clipped by an overflow container. */
|
|
80
|
+
.nim-root :focus-visible {
|
|
81
|
+
outline: none;
|
|
82
|
+
box-shadow: var(--nim-shadow-focus);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.nim-root ::selection {
|
|
86
|
+
background: var(--nim-accent);
|
|
87
|
+
color: var(--nim-on-accent);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/* Numerals are tabular wherever nim prints a figure, so columns of values
|
|
91
|
+
line up and a counting number never reflows its neighbours. */
|
|
92
|
+
.nim-root :is(.nim-stat__value, .nim-badge, time, [data-nim-numeric]) {
|
|
93
|
+
font-variant-numeric: tabular-nums;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
@media (prefers-reduced-motion: reduce) {
|
|
97
|
+
.nim-root *,
|
|
98
|
+
.nim-root *::before,
|
|
99
|
+
.nim-root *::after {
|
|
100
|
+
animation-duration: 0.01ms !important;
|
|
101
|
+
animation-iteration-count: 1 !important;
|
|
102
|
+
transition-duration: 0.01ms !important;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@layer utilities {
|
|
108
|
+
.nim-visually-hidden {
|
|
109
|
+
position: absolute;
|
|
110
|
+
inline-size: 1px;
|
|
111
|
+
block-size: 1px;
|
|
112
|
+
padding: 0;
|
|
113
|
+
overflow: hidden;
|
|
114
|
+
clip-path: inset(50%);
|
|
115
|
+
white-space: nowrap;
|
|
116
|
+
border: 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
STYLE · LEDGER — the nim house style
|
|
3
|
+
|
|
4
|
+
A style owns SHAPE, ELEVATION GEOMETRY, TYPE VOICE and PRESS. It owns no
|
|
5
|
+
colour at all: every value below that looks coloured is a reference to a
|
|
6
|
+
token the active colourway answers. Swapping the colourway under this style
|
|
7
|
+
changes the palette and nothing else; swapping the style changes the
|
|
8
|
+
physics.
|
|
9
|
+
|
|
10
|
+
Ledger: square corners, hairline rules, hard offset shadows like a print
|
|
11
|
+
register mark, mono type for anything machine-shaped, and a press that
|
|
12
|
+
shifts into the shadow — a key being struck, not a surface being squeezed.
|
|
13
|
+
|
|
14
|
+
Selected with `data-nim-style="ledger"`, and used when no style is set.
|
|
15
|
+
`:where(:root)` contributes no specificity, so the bare-root default never
|
|
16
|
+
outranks an explicit style set further down the tree.
|
|
17
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
18
|
+
|
|
19
|
+
:where(:root),
|
|
20
|
+
[data-nim-style='ledger'] {
|
|
21
|
+
/* ─── Shape ──────────────────────────────────────────────────────────
|
|
22
|
+
Square. Nothing rounds "a little bit"; only genuinely pill-shaped
|
|
23
|
+
affordances (the status dot, the toggle track) use `pill`. */
|
|
24
|
+
--nim-radius-xs: 0px;
|
|
25
|
+
--nim-radius-sm: 0px;
|
|
26
|
+
--nim-radius-md: 0px;
|
|
27
|
+
--nim-radius-lg: 0px;
|
|
28
|
+
--nim-radius-xl: 0px;
|
|
29
|
+
--nim-radius-pill: 999px;
|
|
30
|
+
|
|
31
|
+
/* ─── Elevation ──────────────────────────────────────────────────────
|
|
32
|
+
Paper does not float. Depth is a hard offset and a control presses into
|
|
33
|
+
it rather than lifting off it. The offsets are the style's; the colour
|
|
34
|
+
they are drawn in is the colourway's. */
|
|
35
|
+
--nim-shadow-sm: 0 1px 0 var(--nim-shadow-tint-sm);
|
|
36
|
+
--nim-shadow-md: 3px 3px 0 var(--nim-shadow-tint-md);
|
|
37
|
+
--nim-shadow-lg: 6px 6px 0 var(--nim-shadow-tint-lg);
|
|
38
|
+
|
|
39
|
+
/* A ring drawn outside the box, on the canvas, so it reads on any surface.
|
|
40
|
+
An invalid field focuses in danger, so the ring never contradicts the
|
|
41
|
+
message printed under it. */
|
|
42
|
+
--nim-shadow-focus: 0 0 0 2px var(--nim-canvas), 0 0 0 4px var(--nim-accent);
|
|
43
|
+
--nim-shadow-focus-danger: 0 0 0 2px var(--nim-canvas), 0 0 0 4px var(--nim-danger);
|
|
44
|
+
|
|
45
|
+
/* ─── Type ───────────────────────────────────────────────────────────
|
|
46
|
+
One sans for substance, one mono for anything machine-shaped. An app
|
|
47
|
+
with its own brand face overrides these two on its provider; the rest of
|
|
48
|
+
the scale is stated in relative terms and follows. */
|
|
49
|
+
--nim-font-sans: 'Geist', 'Vazirmatn', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
50
|
+
--nim-font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
51
|
+
--nim-font-numeric: var(--nim-font-mono);
|
|
52
|
+
|
|
53
|
+
--nim-tracking-tight: -0.026em;
|
|
54
|
+
--nim-tracking-normal: -0.008em;
|
|
55
|
+
--nim-tracking-wide: 0.12em;
|
|
56
|
+
|
|
57
|
+
/* `base` is this style's resting leading; tight and relaxed are stated
|
|
58
|
+
against it, which is what keeps the three names ordered in every style
|
|
59
|
+
rather than only in this one. */
|
|
60
|
+
--nim-leading-base: 1.45;
|
|
61
|
+
--nim-leading-tight: 1.12;
|
|
62
|
+
--nim-leading-normal: var(--nim-leading-base);
|
|
63
|
+
--nim-leading-relaxed: 1.66;
|
|
64
|
+
|
|
65
|
+
--nim-type-display-size: clamp(2.25rem, 6vw, 3.25rem);
|
|
66
|
+
--nim-type-display-line: 1;
|
|
67
|
+
--nim-type-display-weight: var(--nim-weight-medium);
|
|
68
|
+
--nim-type-display-tracking: -0.036em;
|
|
69
|
+
--nim-type-display-family: var(--nim-font-sans);
|
|
70
|
+
|
|
71
|
+
--nim-type-title-lg-size: var(--nim-text-24);
|
|
72
|
+
--nim-type-title-lg-line: var(--nim-leading-tight);
|
|
73
|
+
--nim-type-title-lg-weight: var(--nim-weight-medium);
|
|
74
|
+
--nim-type-title-md-size: var(--nim-text-18);
|
|
75
|
+
--nim-type-title-md-line: 1.25;
|
|
76
|
+
--nim-type-title-md-weight: var(--nim-weight-medium);
|
|
77
|
+
|
|
78
|
+
--nim-type-body-size: var(--nim-text-16);
|
|
79
|
+
--nim-type-body-line: var(--nim-leading-relaxed);
|
|
80
|
+
--nim-type-body-weight: var(--nim-weight-regular);
|
|
81
|
+
--nim-type-body-sm-size: var(--nim-text-14);
|
|
82
|
+
|
|
83
|
+
/* Labels are set as rules: mono, uppercase, wide-tracked. This pair of
|
|
84
|
+
tokens is most of what makes the style sound like a ledger. */
|
|
85
|
+
--nim-type-label-size: var(--nim-text-12);
|
|
86
|
+
--nim-type-label-weight: var(--nim-weight-medium);
|
|
87
|
+
--nim-type-label-family: var(--nim-font-mono);
|
|
88
|
+
--nim-label-transform: uppercase;
|
|
89
|
+
--nim-label-tracking: var(--nim-tracking-wide);
|
|
90
|
+
|
|
91
|
+
/* A label is a legend printed beside a thing; a control is a thing you
|
|
92
|
+
press. Controls do not borrow the label voice. */
|
|
93
|
+
--nim-type-control-size: var(--nim-text-14);
|
|
94
|
+
--nim-type-control-family: var(--nim-font-sans);
|
|
95
|
+
--nim-type-control-weight: var(--nim-weight-medium);
|
|
96
|
+
--nim-type-control-tracking: var(--nim-tracking-normal);
|
|
97
|
+
--nim-type-control-transform: none;
|
|
98
|
+
|
|
99
|
+
--nim-type-caption-size: var(--nim-text-12);
|
|
100
|
+
--nim-type-caption-line: 1.5;
|
|
101
|
+
|
|
102
|
+
/* ─── Voice ──────────────────────────────────────────────────────────
|
|
103
|
+
How a control answers a press. */
|
|
104
|
+
--nim-press-scale: 1;
|
|
105
|
+
--nim-press-translate: 2px;
|
|
106
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
STYLE · VLORA — soft, rounded, Persian-first
|
|
3
|
+
|
|
4
|
+
Ledger's opposite on every axis a style owns: generous radii, soft ambient
|
|
5
|
+
shadows, sentence-case labels, looser leading, and a press that compresses
|
|
6
|
+
rather than strikes. Carried over from `vlora-app` so an app on this style
|
|
7
|
+
keeps its exact feel while moving onto nim's contract.
|
|
8
|
+
|
|
9
|
+
Like every style it owns no colour. Pair it with the `coral` colourway for
|
|
10
|
+
Vlora's palette or `teal` for Fatemifar's.
|
|
11
|
+
|
|
12
|
+
Selected with `data-nim-style="vlora"`.
|
|
13
|
+
═══════════════════════════════════════════════════════════════════════════ */
|
|
14
|
+
|
|
15
|
+
[data-nim-style='vlora'] {
|
|
16
|
+
/* ─── Shape ──────────────────────────────────────────────────────────
|
|
17
|
+
Rounded and soft. This block is most of what separates the two styles. */
|
|
18
|
+
--nim-radius-xs: 6px;
|
|
19
|
+
--nim-radius-sm: 8px;
|
|
20
|
+
--nim-radius-md: 12px;
|
|
21
|
+
--nim-radius-lg: 20px;
|
|
22
|
+
--nim-radius-xl: 24px;
|
|
23
|
+
--nim-radius-pill: 999px;
|
|
24
|
+
|
|
25
|
+
/* ─── Elevation ────────────────────────────────────────────────────── */
|
|
26
|
+
--nim-shadow-sm: 0 1px 4px var(--nim-shadow-tint-sm);
|
|
27
|
+
--nim-shadow-md: 0 4px 14px var(--nim-shadow-tint-md);
|
|
28
|
+
--nim-shadow-lg: 0 8px 28px var(--nim-shadow-tint-lg);
|
|
29
|
+
|
|
30
|
+
/* A soft halo rather than a drawn ring, mixed from whatever accent the
|
|
31
|
+
colourway supplies. */
|
|
32
|
+
--nim-shadow-focus: 0 0 0 3px color-mix(in srgb, var(--nim-accent) 24%, transparent);
|
|
33
|
+
--nim-shadow-focus-danger: 0 0 0 3px color-mix(in srgb, var(--nim-danger) 24%, transparent);
|
|
34
|
+
|
|
35
|
+
/* ─── Type ───────────────────────────────────────────────────────────
|
|
36
|
+
Persian-first: Vazirmatn leads. An app with its own face — Fatemifar's
|
|
37
|
+
YekanBakh, say — overrides these two names on its provider. */
|
|
38
|
+
--nim-font-sans: 'Vazirmatn', system-ui, -apple-system, sans-serif;
|
|
39
|
+
--nim-font-mono: 'Vazirmatn', ui-monospace, SFMono-Regular, monospace;
|
|
40
|
+
--nim-font-numeric: var(--nim-font-sans);
|
|
41
|
+
|
|
42
|
+
--nim-tracking-tight: -0.018em;
|
|
43
|
+
--nim-tracking-normal: -0.012em;
|
|
44
|
+
--nim-tracking-wide: -0.004em;
|
|
45
|
+
|
|
46
|
+
/* Persian needs the room, so every rung sits higher than Ledger's — but the
|
|
47
|
+
three stay ordered, which they were not before 0.2. */
|
|
48
|
+
--nim-leading-base: 1.84;
|
|
49
|
+
--nim-leading-tight: 1.48;
|
|
50
|
+
--nim-leading-normal: var(--nim-leading-base);
|
|
51
|
+
--nim-leading-relaxed: 1.96;
|
|
52
|
+
|
|
53
|
+
--nim-type-display-size: clamp(2.25rem, 6vw, 3.5rem);
|
|
54
|
+
--nim-type-display-line: 1.48;
|
|
55
|
+
--nim-type-display-weight: var(--nim-weight-semibold);
|
|
56
|
+
--nim-type-display-tracking: -0.03em;
|
|
57
|
+
--nim-type-display-family: var(--nim-font-sans);
|
|
58
|
+
|
|
59
|
+
--nim-type-title-lg-size: var(--nim-text-24);
|
|
60
|
+
--nim-type-title-lg-line: 1.76;
|
|
61
|
+
--nim-type-title-lg-weight: var(--nim-weight-semibold);
|
|
62
|
+
--nim-type-title-md-size: var(--nim-text-20);
|
|
63
|
+
--nim-type-title-md-line: 1.84;
|
|
64
|
+
--nim-type-title-md-weight: var(--nim-weight-semibold);
|
|
65
|
+
|
|
66
|
+
--nim-type-body-size: var(--nim-text-16);
|
|
67
|
+
--nim-type-body-line: var(--nim-leading-relaxed);
|
|
68
|
+
--nim-type-body-weight: var(--nim-weight-regular);
|
|
69
|
+
--nim-type-body-sm-size: var(--nim-text-14);
|
|
70
|
+
|
|
71
|
+
/* Persian has no case, and letterspacing damages its joined forms, so this
|
|
72
|
+
style neither uppercases nor tracks its labels. */
|
|
73
|
+
--nim-type-label-size: var(--nim-text-12);
|
|
74
|
+
--nim-type-label-weight: var(--nim-weight-medium);
|
|
75
|
+
--nim-type-label-family: var(--nim-font-sans);
|
|
76
|
+
--nim-label-transform: none;
|
|
77
|
+
--nim-label-tracking: var(--nim-tracking-wide);
|
|
78
|
+
|
|
79
|
+
--nim-type-control-size: var(--nim-text-15);
|
|
80
|
+
--nim-type-control-family: var(--nim-font-sans);
|
|
81
|
+
--nim-type-control-weight: var(--nim-weight-medium);
|
|
82
|
+
--nim-type-control-tracking: var(--nim-tracking-normal);
|
|
83
|
+
--nim-type-control-transform: none;
|
|
84
|
+
|
|
85
|
+
--nim-type-caption-size: var(--nim-text-13);
|
|
86
|
+
--nim-type-caption-line: 1.76;
|
|
87
|
+
|
|
88
|
+
/* ─── Voice ────────────────────────────────────────────────────────── */
|
|
89
|
+
--nim-press-scale: 0.97;
|
|
90
|
+
--nim-press-translate: 0px;
|
|
91
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|