@nadicodeai/design-system 0.10.2 → 0.11.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/AGENTS.md +30 -101
- package/CONTEXT.md +75 -0
- package/DESIGN.md +180 -345
- package/README.md +27 -54
- package/dist/assets/logo-mark.svg +6 -0
- package/dist/assets/logo-wordmark.svg +4 -0
- package/dist/assets/nadia-canonical-face.png +0 -0
- package/dist/css/chat-autoplay.js +18 -27
- package/dist/css/index.css +2540 -56
- package/dist/favicon/apple-touch-icon.png +0 -0
- package/dist/favicon/favicon.ico +0 -0
- package/dist/favicon/favicon.svg +6 -16
- package/dist/favicon/icon-192.png +0 -0
- package/dist/favicon/icon-512.png +0 -0
- package/dist/favicon/site.webmanifest +2 -2
- package/dist/tailwind/nadicode.tailwind.json +98 -143
- package/dist/tokens/nadicode.dtcg.json +413 -908
- package/package.json +19 -11
- package/src/assets/logo-geometry.d.ts +27 -0
- package/src/assets/logo-geometry.js +204 -0
- package/src/assets/nadia-canonical-face.d.ts +2 -0
- package/dist/css/components/.gitkeep +0 -0
- package/dist/css/components/agent-avatar.css +0 -52
- package/dist/css/components/approval-gate.css +0 -145
- package/dist/css/components/artifact-preview.css +0 -81
- package/dist/css/components/chat-bubble-agent.css +0 -63
- package/dist/css/components/chat-bubble-user.css +0 -28
- package/dist/css/components/chat-thread.css +0 -159
- package/dist/css/components/handoff-banner.css +0 -37
- package/dist/css/components/image.css +0 -87
- package/dist/css/components/memory-item.css +0 -36
- package/dist/css/components/run-timeline.css +0 -160
- package/dist/css/components/state-row.css +0 -64
- package/dist/css/components/state-tag.css +0 -67
- package/dist/css/components/status-tag.css +0 -101
- package/dist/css/components/tool-call-trace.css +0 -36
- package/dist/css/components/typing-dots.css +0 -54
- package/dist/css/components/usage-meter.css +0 -63
- package/dist/css/foundation.css +0 -177
- package/dist/css/layout.css +0 -657
- package/dist/css/motion.css +0 -225
- package/dist/css/primitives.css +0 -333
- package/dist/css/reset.css +0 -22
- package/dist/css/tokens.generated.css +0 -349
- package/dist/css/tokens.local.css +0 -11
- package/dist/tailwind/nadicode.theme.css +0 -596
- package/src/assets/favicon.svg +0 -17
- package/src/assets/logo-mark.svg +0 -15
- package/src/assets/logo-wordmark.svg +0 -26
- package/src/assets/nadia.d.ts +0 -9
- package/src/assets/nadia.png +0 -0
package/dist/css/motion.css
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* motion layer — the brand's motion contract, defined once and reused.
|
|
3
|
-
*
|
|
4
|
-
* REGISTER: the page breathes; it never performs. Every moment of movement
|
|
5
|
-
* has one owner and one meaning; motion that cannot say what it means is
|
|
6
|
-
* decoration and is cut.
|
|
7
|
-
*
|
|
8
|
-
* THE FOUR MOVES (the complete vocabulary — nothing else animates):
|
|
9
|
-
* Settle — entrance. A row's content rises in once on scroll-into-view,
|
|
10
|
-
* as ONE unit, never element-by-element. (.nc-settle, opt-in)
|
|
11
|
-
* Type — the demonstration. chat-autoplay's staggered message/trace
|
|
12
|
-
* rhythm. The only sustained animation; it is content, not effect.
|
|
13
|
-
* Confirm — state change. Approval and state surfaces transition at
|
|
14
|
-
* --nc-duration-confirm; color arrives WITH the meaning, never
|
|
15
|
-
* before it.
|
|
16
|
-
* Invite — hover/press. Surface and underline shifts on hover, gated
|
|
17
|
-
* behind @media (hover: hover) and (pointer: fine); :active press
|
|
18
|
-
* feedback at scale(0.97). Nothing changes position on hover.
|
|
19
|
-
*
|
|
20
|
-
* CRAFT RULES:
|
|
21
|
-
* - Entrances and exits ease OUT (--nc-ease-emphasized for Settle,
|
|
22
|
-
* --nc-ease-out-strong for feedback); never ease-in, never a weak
|
|
23
|
-
* built-in where a brand curve exists.
|
|
24
|
-
* - State feedback completes in 150–200 ms; press <= 160 ms; only the
|
|
25
|
-
* demonstration (Type) may run longer.
|
|
26
|
-
* - DURATION TIERS: UI feedback stays under 300 ms.
|
|
27
|
-
* --nc-duration-msg-in (360 ms) is reserved for the one-time Settle
|
|
28
|
-
* entrance, never for motion the operator meets on every refetch. No
|
|
29
|
-
* reflow/count-up timing is adopted; the deprecated compatibility token
|
|
30
|
-
* below is not an approved semantic use.
|
|
31
|
-
* - ASYMMETRIC TIMING: a deliberate action opens slower than it dismisses.
|
|
32
|
-
* Popovers/menus/dialogs open at --nc-duration-open (220 ms) and close at
|
|
33
|
-
* --nc-duration-close (140 ms); the open invites, the close gets out of the
|
|
34
|
-
* way.
|
|
35
|
-
* - ORIGIN-AWARE: a surface that springs from a trigger scales FROM that
|
|
36
|
-
* trigger (transform-origin at the anchor), not from its own centre — a
|
|
37
|
-
* popover grows out of the button that opened it.
|
|
38
|
-
* - INTERRUPTIBLE: gesture- or toast-driven motion retargets from its
|
|
39
|
-
* current position; it is never restarted from a fixed keyframe mid-flight.
|
|
40
|
-
* - Nothing enters from scale(0) or from nothing.
|
|
41
|
-
* - PROPERTY DISCIPLINE: shared product primitive feedback and overlays use
|
|
42
|
-
* compositor-only opacity and individual translate/scale properties; they
|
|
43
|
-
* never take over a consumer's full transform. The opt-in Settle/Type
|
|
44
|
-
* presentation hooks below retain their legacy keyframes.
|
|
45
|
-
* The Confirm move may additionally transition background-color,
|
|
46
|
-
* border-color, and color at --nc-duration-confirm — colour is the state
|
|
47
|
-
* change itself, and a paint-only transition triggers no reflow. Never
|
|
48
|
-
* animate a property that shifts surrounding layout; no will-change;
|
|
49
|
-
* zero CLS.
|
|
50
|
-
* - FREQUENCY RULE: motion a user meets repeatedly (product UI, keyboard-
|
|
51
|
-
* triggered actions) does not animate. Delight is reserved for rarely-
|
|
52
|
-
* seen surfaces (marketing pages, first runs). Product surfaces that
|
|
53
|
-
* grow from this kit inherit THIS rule, not the marketing motion.
|
|
54
|
-
*
|
|
55
|
-
* BANNED: parallax, scroll-jacking, floating/bobbing idle loops, gradient
|
|
56
|
-
* shimmer, staggered letter reveals, anything that moves a seam or hairline
|
|
57
|
-
* after it settles, more than one theatrical moment per page, and
|
|
58
|
-
* `transition: all` / `transition-property: all` (name the properties you
|
|
59
|
-
* animate — a blanket transition drags unintended props off the compositor).
|
|
60
|
-
*
|
|
61
|
-
* REDUCED MOTION: prefers-reduced-motion removes movement entirely — Settle
|
|
62
|
-
* and Type loops gone, Confirm instant, press transforms removed. Immediate
|
|
63
|
-
* state and focus semantics remain. The page must read identically motionless.
|
|
64
|
-
*
|
|
65
|
-
* BOUNDARY: nc-pulse is the live running-state indicator on agentic surfaces
|
|
66
|
-
* ONLY (state-row / run-timeline, running kind). DESIGN.md bans pulses for
|
|
67
|
-
* state communication on state-tag; the two never blur.
|
|
68
|
-
*
|
|
69
|
-
* Provenance: duration/ease token values extracted from the archived prototype
|
|
70
|
-
* `docs/experiments/design-canvas/chat-anim.jsx`. The prototype defined three
|
|
71
|
-
* keyframes (nc-msg-in, nc-typing, nc-pulse) but only wired nc-typing;
|
|
72
|
-
* nc-msg-in was defined-but-dead and nc-pulse's state dot was never rendered,
|
|
73
|
-
* and there was NO reduced-motion handling. This layer finishes the motion.
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
:root {
|
|
77
|
-
/* Durations — extracted from chat-anim.jsx applied timings.
|
|
78
|
-
--nc-duration-stagger : 160ms ← `nc-typing 1s ${i*160}ms` per-dot stagger step
|
|
79
|
-
(also the per-message rise-in delay step);
|
|
80
|
-
the smallest brand cadence unit.
|
|
81
|
-
--nc-duration-msg-in : 360ms ← the brand transition rhythm; the prototype's
|
|
82
|
-
rise-in had no explicit duration, so it is
|
|
83
|
-
mapped to the footer's 360ms transition.
|
|
84
|
-
--nc-duration-transition: 360ms ← footer `width 360ms cubic-bezier(.3,.7,.2,1)`.
|
|
85
|
-
--nc-duration-typing : 1s ← `nc-typing 1s ... infinite` dot bounce loop.
|
|
86
|
-
--nc-duration-pulse : 1.6s ← `nc-pulse 1.6s ease-out infinite` ring loop.
|
|
87
|
-
--nc-duration-confirm : 180ms ← state feedback; 150–200 ms band (Confirm move). */
|
|
88
|
-
--nc-duration-stagger: 160ms;
|
|
89
|
-
--nc-duration-msg-in: 360ms;
|
|
90
|
-
--nc-duration-transition: 360ms;
|
|
91
|
-
--nc-duration-typing: 1s;
|
|
92
|
-
--nc-duration-pulse: 1.6s;
|
|
93
|
-
--nc-duration-confirm: 180ms;
|
|
94
|
-
|
|
95
|
-
/* Deprecated 0.10.x compatibility token; remove in a breaking release.
|
|
96
|
-
It remains defined only so patch upgrades do not invalidate existing
|
|
97
|
-
consumer CSS. Do not use it for reflow, count-up, or new runtime motion. */
|
|
98
|
-
--nc-duration-reflow: 250ms;
|
|
99
|
-
|
|
100
|
-
/* Asymmetric open/close cadence (craft-rule tokens for the ASYMMETRIC TIMING
|
|
101
|
-
rule above — a deliberate action opens slower than it dismisses).
|
|
102
|
-
--nc-duration-open : 220ms drives a popover/menu/dialog opening; the open
|
|
103
|
-
invites.
|
|
104
|
-
--nc-duration-close: 140ms drives its dismissal; the close gets out of the
|
|
105
|
-
way. Both stay under the 300ms UI-feedback ceiling. */
|
|
106
|
-
--nc-duration-open: 220ms;
|
|
107
|
-
--nc-duration-close: 140ms;
|
|
108
|
-
|
|
109
|
-
/* Easings — extracted from chat-anim.jsx.
|
|
110
|
-
--nc-ease-emphasized : cubic-bezier(.3,.7,.2,1) ← footer width transition;
|
|
111
|
-
the brand's settle curve.
|
|
112
|
-
--nc-ease-bounce : ease-in-out ← `nc-typing ... ease-in-out` dot bounce.
|
|
113
|
-
--nc-ease-out : ease-out ← `nc-pulse 1.6s ease-out` ring decay;
|
|
114
|
-
the weak built-in stays only where
|
|
115
|
-
nc-pulse already uses it.
|
|
116
|
-
--nc-ease-out-strong : cubic-bezier(0.23, 1, 0.32, 1) ← the strong exit/
|
|
117
|
-
feedback curve (Confirm, Invite, press). */
|
|
118
|
-
--nc-ease-emphasized: cubic-bezier(0.3, 0.7, 0.2, 1);
|
|
119
|
-
--nc-ease-bounce: ease-in-out;
|
|
120
|
-
--nc-ease-out: ease-out;
|
|
121
|
-
--nc-ease-out-strong: cubic-bezier(0.23, 1, 0.32, 1);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/* ── Keyframes ────────────────────────────────────────────────────────────
|
|
125
|
-
Three REAL keyframes, all wired below via the `.nc-anim-*` hooks. */
|
|
126
|
-
|
|
127
|
-
/* Message bubble rise-in — opacity 0→1 + translateY(4px)→0.
|
|
128
|
-
Was defined-but-dead in the prototype; now real. */
|
|
129
|
-
@keyframes nc-msg-in {
|
|
130
|
-
from {
|
|
131
|
-
opacity: 0;
|
|
132
|
-
transform: translateY(4px);
|
|
133
|
-
}
|
|
134
|
-
to {
|
|
135
|
-
opacity: 1;
|
|
136
|
-
transform: translateY(0);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/* Typing-indicator dot bounce — the only keyframe the prototype actually applied. */
|
|
141
|
-
@keyframes nc-typing {
|
|
142
|
-
0%,
|
|
143
|
-
80%,
|
|
144
|
-
100% {
|
|
145
|
-
opacity: 0.25;
|
|
146
|
-
transform: translateY(0);
|
|
147
|
-
}
|
|
148
|
-
40% {
|
|
149
|
-
opacity: 1;
|
|
150
|
-
transform: translateY(-2px);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/* Running-state pulse — a deliberate, subtle expanding ring. Drawn with
|
|
155
|
-
`currentColor` so the consuming atom owns the hue (no hard-coded color here);
|
|
156
|
-
for the running state only, not every dot. */
|
|
157
|
-
@keyframes nc-pulse {
|
|
158
|
-
0% {
|
|
159
|
-
box-shadow: 0 0 0 0 currentColor;
|
|
160
|
-
}
|
|
161
|
-
70% {
|
|
162
|
-
box-shadow: 0 0 0 6px transparent;
|
|
163
|
-
}
|
|
164
|
-
100% {
|
|
165
|
-
box-shadow: 0 0 0 0 transparent;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
/* ── Animation utility hooks (the reuse mechanism, D5) ─────────────────────
|
|
170
|
-
Each keyframe name appears here in an `animation` declaration so it is wired,
|
|
171
|
-
not just defined (AC-013). M6 chat atoms opt into these classes. Every hook
|
|
172
|
-
exposes `--nc-anim-delay` (default 0ms) so atoms can stagger by setting it,
|
|
173
|
-
e.g. `style="--nc-anim-delay: calc(var(--i) * var(--nc-duration-stagger))"`. */
|
|
174
|
-
|
|
175
|
-
.nc-anim-msg-in {
|
|
176
|
-
animation: nc-msg-in var(--nc-duration-msg-in) var(--nc-ease-emphasized) both;
|
|
177
|
-
animation-delay: var(--nc-anim-delay, 0ms);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.nc-anim-typing {
|
|
181
|
-
animation: nc-typing var(--nc-duration-typing) var(--nc-ease-bounce) infinite;
|
|
182
|
-
animation-delay: var(--nc-anim-delay, 0ms);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.nc-anim-pulse {
|
|
186
|
-
animation: nc-pulse var(--nc-duration-pulse) var(--nc-ease-out) infinite;
|
|
187
|
-
animation-delay: var(--nc-anim-delay, 0ms);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/* ── Settle — enhancer-armed entrance (opt-in) ────────────────────────────
|
|
191
|
-
.nc-settle is the layout-container opt-in for scroll-driven entrance.
|
|
192
|
-
Base state is FULLY VISIBLE — no opacity rule on .nc-settle itself — so
|
|
193
|
-
no-JS and reduced-motion users get the complete static page.
|
|
194
|
-
|
|
195
|
-
Mechanism: enhancer-armed, run-once (no view() scrubbing).
|
|
196
|
-
chat-autoplay.js sets data-nc-settle="armed" on elements that are fully
|
|
197
|
-
below the viewport at init, then switches to data-nc-settle="in" on first
|
|
198
|
-
intersection (IntersectionObserver, threshold ~0.1). The observer unobserves
|
|
199
|
-
immediately after firing — the rise-in plays once and is never re-triggered
|
|
200
|
-
on re-entry or reversed on scroll-back. Elements already in or above the
|
|
201
|
-
viewport at load are never armed (no flash, hero region untouched).
|
|
202
|
-
No JS → no attribute → page fully visible. */
|
|
203
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
204
|
-
[data-nc-settle="armed"] {
|
|
205
|
-
opacity: 0;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
[data-nc-settle="in"] {
|
|
209
|
-
animation: nc-msg-in var(--nc-duration-msg-in) var(--nc-ease-emphasized) both;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/* ── Reduced motion (mandatory, D5) ───────────────────────────────────────
|
|
214
|
-
Neutralize every hook: no animation, and a static, fully-visible end-state
|
|
215
|
-
so rise-in content is not stuck hidden at opacity 0. */
|
|
216
|
-
@media (prefers-reduced-motion: reduce) {
|
|
217
|
-
.nc-anim-msg-in,
|
|
218
|
-
.nc-anim-typing,
|
|
219
|
-
.nc-anim-pulse {
|
|
220
|
-
animation: none;
|
|
221
|
-
opacity: 1;
|
|
222
|
-
transform: none;
|
|
223
|
-
box-shadow: none;
|
|
224
|
-
}
|
|
225
|
-
}
|
package/dist/css/primitives.css
DELETED
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
/* primitives layer — atoms and molecules that sit on the layout-layer grid.
|
|
2
|
-
*
|
|
3
|
-
* Structural-geometry foundation (kept through the Tailwind+shadcn migration; see
|
|
4
|
-
* index.css). The `.nc-marker` crosshair is the brand's corner mark: it stays
|
|
5
|
-
* corners-only (placed via the `data-position` → grid-line-index map below,
|
|
6
|
-
* never auto-placed), monochrome (a single `--nc-cross` color on both arms), and
|
|
7
|
-
* token-weighted (`--nc-guide` line weight). Its position is derived from grid
|
|
8
|
-
* placement (`grid-column-start`/`grid-row-start` against the field's track
|
|
9
|
-
* lines), never a frame-relative pixel offset measured by eye. Every value in
|
|
10
|
-
* this layer references an emitted `--nc-*` token; no raw color/radius/dimension
|
|
11
|
-
* literal lives here. */
|
|
12
|
-
.nc-cell {
|
|
13
|
-
position: relative;
|
|
14
|
-
z-index: 2;
|
|
15
|
-
display: grid;
|
|
16
|
-
min-width: 0;
|
|
17
|
-
min-height: var(--nc-h-cell-sm);
|
|
18
|
-
margin-right: var(--nc-guide);
|
|
19
|
-
margin-bottom: var(--nc-guide);
|
|
20
|
-
padding: var(--nc-cell-padding);
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
overflow-wrap: anywhere;
|
|
23
|
-
place-content: center;
|
|
24
|
-
background: var(--nc-canvas);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.nc-cell-flush {
|
|
28
|
-
padding: 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.nc-diagonal-fill,
|
|
32
|
-
.nc-cell-filler {
|
|
33
|
-
background:
|
|
34
|
-
repeating-linear-gradient(
|
|
35
|
-
-45deg,
|
|
36
|
-
var(--nc-canvas-soft) 0,
|
|
37
|
-
var(--nc-canvas-soft) 7px,
|
|
38
|
-
var(--nc-line) 7px,
|
|
39
|
-
var(--nc-line) 8px
|
|
40
|
-
),
|
|
41
|
-
var(--nc-canvas);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.nc-dotted-field {
|
|
45
|
-
background:
|
|
46
|
-
radial-gradient(var(--nc-line) 0.8px, transparent 0.8px) 0 0 / 12px 12px,
|
|
47
|
-
var(--nc-canvas);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.nc-marker {
|
|
51
|
-
/* Centering offset built ONLY from the marker's own size + the universal line
|
|
52
|
-
token — never a sibling box. The marker is placed as a grid child so its box
|
|
53
|
-
corner lands on a track-line intersection (grid-column-start/grid-row-start);
|
|
54
|
-
pulling it back by half-its-size + half-a-line centers the crosshair arms
|
|
55
|
-
exactly on that intersection. This replaces the deleted seam-offset model,
|
|
56
|
-
which floated the crosshair off the frame border-half. */
|
|
57
|
-
--nc-cross-half: calc((var(--nc-cross-size) / 2) + (var(--nc-guide) / 2));
|
|
58
|
-
position: absolute;
|
|
59
|
-
z-index: 4;
|
|
60
|
-
grid-column-start: var(--nc-cross-column);
|
|
61
|
-
grid-row-start: var(--nc-cross-row);
|
|
62
|
-
width: var(--nc-cross-size);
|
|
63
|
-
height: var(--nc-cross-size);
|
|
64
|
-
inset: calc(var(--nc-cross-half) * -1);
|
|
65
|
-
pointer-events: none;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/* data-position is the declarative placement API: it maps the four frame
|
|
69
|
-
corners to the grid-line indices .nc-marker already consumes, so authored
|
|
70
|
-
markup that names a corner actually lands there. Inline --nc-cross-column /
|
|
71
|
-
--nc-cross-row still win (inline styles beat stylesheet rules), keeping an
|
|
72
|
-
explicit escape hatch for internal-track markers. -1 is the last grid line,
|
|
73
|
-
so corners track the grid across breakpoints — never a hardcoded 13/9. */
|
|
74
|
-
.nc-marker[data-position="top-left"] {
|
|
75
|
-
--nc-cross-column: 1;
|
|
76
|
-
--nc-cross-row: 1;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.nc-marker[data-position="top-right"] {
|
|
80
|
-
--nc-cross-column: -1;
|
|
81
|
-
--nc-cross-row: 1;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.nc-marker[data-position="bottom-left"] {
|
|
85
|
-
--nc-cross-column: 1;
|
|
86
|
-
--nc-cross-row: -1;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.nc-marker[data-position="bottom-right"] {
|
|
90
|
-
--nc-cross-column: -1;
|
|
91
|
-
--nc-cross-row: -1;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.nc-marker::before,
|
|
95
|
-
.nc-marker::after {
|
|
96
|
-
content: "";
|
|
97
|
-
position: absolute;
|
|
98
|
-
display: block;
|
|
99
|
-
background: var(--nc-cross);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.nc-marker::before {
|
|
103
|
-
top: 0;
|
|
104
|
-
bottom: 0;
|
|
105
|
-
left: 50%;
|
|
106
|
-
width: var(--nc-guide);
|
|
107
|
-
transform: translateX(-50%);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.nc-marker::after {
|
|
111
|
-
left: 0;
|
|
112
|
-
right: 0;
|
|
113
|
-
top: 50%;
|
|
114
|
-
height: var(--nc-guide);
|
|
115
|
-
transform: translateY(-50%);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.nc-blueprint-field {
|
|
119
|
-
/* The structural grid drawn as a background texture instead of bordered DOM
|
|
120
|
-
guide elements. Lines are painted at STRUCTURAL pitch — one tile per column
|
|
121
|
-
and row — so the 12-column reading is preserved (a fixed px pitch would read
|
|
122
|
-
as graph paper). Pitch reuses the surrounding grid field's column/row count.
|
|
123
|
-
This is the same technique nc-action-visual already uses; nc-blueprint-field
|
|
124
|
-
generalizes it so any surface can carry the blueprint without DOM guides. */
|
|
125
|
-
--nc-blueprint-columns: var(--nc-grid-columns, 12);
|
|
126
|
-
--nc-blueprint-rows: var(--nc-grid-rows, 8);
|
|
127
|
-
--nc-blueprint-line: var(--nc-line);
|
|
128
|
-
background-image:
|
|
129
|
-
linear-gradient(to right, var(--nc-blueprint-line) var(--nc-guide), transparent var(--nc-guide)),
|
|
130
|
-
linear-gradient(
|
|
131
|
-
to bottom,
|
|
132
|
-
var(--nc-blueprint-line) var(--nc-guide),
|
|
133
|
-
transparent var(--nc-guide)
|
|
134
|
-
);
|
|
135
|
-
background-size:
|
|
136
|
-
calc(100% / var(--nc-blueprint-columns)) calc(100% / var(--nc-blueprint-rows)),
|
|
137
|
-
calc(100% / var(--nc-blueprint-columns)) calc(100% / var(--nc-blueprint-rows));
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/* Opt-in feather: soften the blueprint so it reads as atmosphere, not
|
|
141
|
-
scaffolding (used by atmospheric surfaces like the brand hero). */
|
|
142
|
-
.nc-blueprint-field[data-feather="top"] {
|
|
143
|
-
-webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 22%, black 100%);
|
|
144
|
-
mask-image: linear-gradient(to bottom, transparent 0%, black 22%, black 100%);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
.nc-rule-svg {
|
|
148
|
-
color: var(--nc-seam);
|
|
149
|
-
overflow: visible;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.nc-rule-svg line {
|
|
153
|
-
stroke: currentColor;
|
|
154
|
-
stroke-dasharray: 4 6;
|
|
155
|
-
stroke-linecap: round;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.nc-panel-cell {
|
|
159
|
-
display: grid;
|
|
160
|
-
min-width: 0;
|
|
161
|
-
min-height: var(--nc-h-cell-md);
|
|
162
|
-
padding: var(--nc-cell-padding);
|
|
163
|
-
align-content: center;
|
|
164
|
-
gap: 12px;
|
|
165
|
-
overflow: hidden;
|
|
166
|
-
overflow-wrap: anywhere;
|
|
167
|
-
background: var(--nc-canvas);
|
|
168
|
-
color: var(--nc-body);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.nc-artifact-surface {
|
|
172
|
-
display: grid;
|
|
173
|
-
gap: 12px;
|
|
174
|
-
min-width: 0;
|
|
175
|
-
border: var(--nc-guide) solid var(--nc-line);
|
|
176
|
-
padding: 18px;
|
|
177
|
-
/* The retired gradient tokens (Italia color contract §6) are gone; the artifact
|
|
178
|
-
surface keeps a calm, scale-driven dot-grid atmosphere on canvas. */
|
|
179
|
-
background:
|
|
180
|
-
radial-gradient(var(--nc-line) 0.8px, transparent 0.8px) 0 0 / 12px 12px,
|
|
181
|
-
var(--nc-canvas);
|
|
182
|
-
color: var(--nc-body);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
.nc-artifact-bar {
|
|
186
|
-
height: 10px;
|
|
187
|
-
background: var(--nc-line);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
.nc-artifact-bar:nth-of-type(1) {
|
|
191
|
-
width: 76%;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
.nc-artifact-bar:nth-of-type(2) {
|
|
195
|
-
width: 56%;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
.nc-artifact-bar:nth-of-type(3) {
|
|
199
|
-
width: 38%;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/* nc-icon — the icon slot. Icons are derived from Lucide (ISC) by a build
|
|
203
|
-
transform that bakes the house render into the SVG (see scripts/generate-icons.ts).
|
|
204
|
-
This primitive renders an INLINE <svg> child and re-asserts that key — 1.5px
|
|
205
|
-
stroke, butt caps, miter joins, currentColor — so a raw upstream icon dropped in
|
|
206
|
-
here also conforms. Size is set by [data-size] (sm 12 / md 16 / lg 24); md is the
|
|
207
|
-
default. Inline SVG is required for currentColor inheritance — an <img> renders in
|
|
208
|
-
isolation and cannot read it. */
|
|
209
|
-
.nc-icon {
|
|
210
|
-
display: inline-flex;
|
|
211
|
-
flex: none;
|
|
212
|
-
width: 16px;
|
|
213
|
-
height: 16px;
|
|
214
|
-
color: inherit;
|
|
215
|
-
vertical-align: middle;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
.nc-icon[data-size="sm"] {
|
|
219
|
-
width: 12px;
|
|
220
|
-
height: 12px;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
.nc-icon[data-size="lg"] {
|
|
224
|
-
width: 24px;
|
|
225
|
-
height: 24px;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
.nc-icon svg {
|
|
229
|
-
display: block;
|
|
230
|
-
width: 100%;
|
|
231
|
-
height: 100%;
|
|
232
|
-
fill: none;
|
|
233
|
-
stroke: currentColor;
|
|
234
|
-
stroke-width: 1.5;
|
|
235
|
-
stroke-linecap: butt;
|
|
236
|
-
stroke-linejoin: miter;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/* nc-badge-secondary — a small fully-rounded metadata badge for "New", "Beta",
|
|
240
|
-
"Live", or similar labels (DESIGN.md badge-secondary). It carries the
|
|
241
|
-
{colors.canvas-soft} surface, {colors.body} text, and the {rounded.full}
|
|
242
|
-
radius; the caption type is applied in markup via .nc-type-caption so the
|
|
243
|
-
contract is the single source of the type. It is an inline chip with no seam
|
|
244
|
-
of its own beyond its hairline border. */
|
|
245
|
-
.nc-badge-secondary {
|
|
246
|
-
display: inline-flex;
|
|
247
|
-
width: fit-content;
|
|
248
|
-
align-items: center;
|
|
249
|
-
justify-content: center;
|
|
250
|
-
gap: 6px;
|
|
251
|
-
border: var(--nc-guide) solid var(--nc-line);
|
|
252
|
-
border-radius: var(--nc-rounded-full);
|
|
253
|
-
padding: 1px 8px;
|
|
254
|
-
background: var(--nc-canvas-soft);
|
|
255
|
-
color: var(--nc-body);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/* nc-filter-chip — removable selected-filter label (DESIGN.md filter-chip).
|
|
259
|
-
It uses neutral chrome only: applied filter state is not workflow, lifecycle,
|
|
260
|
-
or taxonomy state, so color is reserved for the remove affordance focus ring. */
|
|
261
|
-
.nc-filter-chip {
|
|
262
|
-
display: inline-flex;
|
|
263
|
-
width: fit-content;
|
|
264
|
-
min-height: var(--nc-filter-chip-height);
|
|
265
|
-
align-items: center;
|
|
266
|
-
justify-content: center;
|
|
267
|
-
gap: var(--nc-filter-chip-gap);
|
|
268
|
-
border: var(--nc-guide) solid var(--nc-line);
|
|
269
|
-
border-radius: var(--nc-rounded-sm);
|
|
270
|
-
padding: 0 var(--nc-xs);
|
|
271
|
-
background: var(--nc-canvas-soft);
|
|
272
|
-
color: var(--nc-body);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
.nc-filter-chip svg {
|
|
276
|
-
width: var(--nc-filter-chip-icon);
|
|
277
|
-
height: var(--nc-filter-chip-icon);
|
|
278
|
-
flex: none;
|
|
279
|
-
stroke: currentColor;
|
|
280
|
-
stroke-width: 1.5;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.dark .nc-filter-chip {
|
|
284
|
-
border-color: var(--nc-dark-line);
|
|
285
|
-
background: var(--nc-dark-canvas-soft);
|
|
286
|
-
color: var(--nc-dark-body);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
.nc-filter-chip:focus-visible {
|
|
290
|
-
outline: var(--nc-focus-ring-width) solid var(--nc-focus-ring);
|
|
291
|
-
outline-offset: 0;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/* nc-link-inline — the inline body link style (DESIGN.md link-inline). It reads
|
|
295
|
-
in the {colors.link} accent against the body rhythm (the body type is applied
|
|
296
|
-
in markup via .nc-type-body-md), keeps the natural underline so it stays
|
|
297
|
-
recognisable in running prose, and exposes a contrast-safe focus ring. It is
|
|
298
|
-
an inline atom, never a block. */
|
|
299
|
-
.nc-link-inline {
|
|
300
|
-
color: var(--nc-link);
|
|
301
|
-
text-decoration: underline;
|
|
302
|
-
text-underline-offset: 2px;
|
|
303
|
-
text-decoration-thickness: var(--nc-guide);
|
|
304
|
-
transition:
|
|
305
|
-
background-color var(--nc-duration-stagger) var(--nc-ease-out-strong),
|
|
306
|
-
border-color var(--nc-duration-stagger) var(--nc-ease-out-strong),
|
|
307
|
-
color var(--nc-duration-stagger) var(--nc-ease-out-strong),
|
|
308
|
-
opacity var(--nc-duration-stagger) var(--nc-ease-out-strong);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
@media (hover: hover) and (pointer: fine) {
|
|
312
|
-
.nc-link-inline:hover {
|
|
313
|
-
color: var(--nc-link-deep);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
.nc-link-inline:focus-visible {
|
|
318
|
-
outline: var(--nc-focus-ring-width) solid var(--nc-focus-ring);
|
|
319
|
-
outline-offset: 0;
|
|
320
|
-
border-radius: var(--nc-rounded-md);
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/* nc-label-mono — the mono eyebrow/kicker for section labels and low-priority
|
|
324
|
-
metadata (DESIGN.md label-mono). It reads in the {colors.muted} tone and the
|
|
325
|
-
caption-mono scale (applied in markup via .nc-type-caption-mono); this rule
|
|
326
|
-
adds only the uppercase eyebrow treatment, which is presentation the type
|
|
327
|
-
scale does not carry. It owns no box and no seam. */
|
|
328
|
-
.nc-label-mono {
|
|
329
|
-
display: block;
|
|
330
|
-
margin: 0;
|
|
331
|
-
color: var(--nc-muted);
|
|
332
|
-
text-transform: uppercase;
|
|
333
|
-
}
|
package/dist/css/reset.css
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/* reset layer — box-sizing, html/body, heading margins (split from old foundation per D10). */
|
|
2
|
-
* {
|
|
3
|
-
box-sizing: border-box;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
html {
|
|
7
|
-
min-width: 320px;
|
|
8
|
-
overflow-x: clip;
|
|
9
|
-
text-rendering: optimizeLegibility;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
body {
|
|
13
|
-
margin: 0;
|
|
14
|
-
overflow-x: clip;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
h1,
|
|
18
|
-
h2,
|
|
19
|
-
h3,
|
|
20
|
-
p {
|
|
21
|
-
margin: 0;
|
|
22
|
-
}
|