@nadicodeai/design-system 0.10.1 → 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.
Files changed (51) hide show
  1. package/AGENTS.md +30 -101
  2. package/CONTEXT.md +75 -0
  3. package/DESIGN.md +180 -345
  4. package/README.md +27 -54
  5. package/dist/assets/logo-mark.svg +6 -0
  6. package/dist/assets/logo-wordmark.svg +4 -0
  7. package/dist/assets/nadia-canonical-face.png +0 -0
  8. package/dist/css/chat-autoplay.js +18 -27
  9. package/dist/css/index.css +2540 -56
  10. package/dist/favicon/apple-touch-icon.png +0 -0
  11. package/dist/favicon/favicon.ico +0 -0
  12. package/dist/favicon/favicon.svg +6 -16
  13. package/dist/favicon/icon-192.png +0 -0
  14. package/dist/favicon/icon-512.png +0 -0
  15. package/dist/favicon/site.webmanifest +2 -2
  16. package/dist/tailwind/nadicode.tailwind.json +98 -143
  17. package/dist/tokens/nadicode.dtcg.json +413 -908
  18. package/package.json +19 -11
  19. package/src/assets/logo-geometry.d.ts +27 -0
  20. package/src/assets/logo-geometry.js +204 -0
  21. package/src/assets/nadia-canonical-face.d.ts +2 -0
  22. package/dist/css/components/.gitkeep +0 -0
  23. package/dist/css/components/agent-avatar.css +0 -52
  24. package/dist/css/components/approval-gate.css +0 -145
  25. package/dist/css/components/artifact-preview.css +0 -81
  26. package/dist/css/components/chat-bubble-agent.css +0 -63
  27. package/dist/css/components/chat-bubble-user.css +0 -28
  28. package/dist/css/components/chat-thread.css +0 -159
  29. package/dist/css/components/handoff-banner.css +0 -37
  30. package/dist/css/components/image.css +0 -87
  31. package/dist/css/components/memory-item.css +0 -36
  32. package/dist/css/components/run-timeline.css +0 -160
  33. package/dist/css/components/state-row.css +0 -64
  34. package/dist/css/components/state-tag.css +0 -67
  35. package/dist/css/components/status-tag.css +0 -101
  36. package/dist/css/components/tool-call-trace.css +0 -36
  37. package/dist/css/components/typing-dots.css +0 -54
  38. package/dist/css/components/usage-meter.css +0 -63
  39. package/dist/css/foundation.css +0 -177
  40. package/dist/css/layout.css +0 -657
  41. package/dist/css/motion.css +0 -225
  42. package/dist/css/primitives.css +0 -333
  43. package/dist/css/reset.css +0 -22
  44. package/dist/css/tokens.generated.css +0 -349
  45. package/dist/css/tokens.local.css +0 -11
  46. package/dist/tailwind/nadicode.theme.css +0 -596
  47. package/src/assets/favicon.svg +0 -17
  48. package/src/assets/logo-mark.svg +0 -15
  49. package/src/assets/logo-wordmark.svg +0 -26
  50. package/src/assets/nadia.d.ts +0 -9
  51. package/src/assets/nadia.png +0 -0
@@ -1,657 +0,0 @@
1
- /* layout layer — page-system, 12-column field, grid guides, stage scaffolds (renamed from grid.css per D12).
2
- *
3
- * Structural-geometry foundation (kept through the Tailwind+shadcn migration; see
4
- * index.css). This layer owns the kernel grid and the single-owner seam model:
5
- * every visible border/seam at a given coordinate is drawn by exactly one rule
6
- * here (the frame owns top+left, one `::after` closes right+bottom; each row owns
7
- * its own top seam; the first row's top is suppressed so the frame's own top is
8
- * not doubled). Column spans, row tracks, and seam placement are computed from
9
- * explicit grid math — `grid-column`/`grid-row` line indices and the
10
- * `--nc-grid-*` track counts — never hand-placed by eye. Every dimension, gap,
11
- * and color references an emitted `--nc-*` token; no raw literal lives here. */
12
-
13
- /* Responsive token switching (policy per ADR 0005: breakpoints live in the
14
- application layer, never in the generated token layer).
15
- tokens.generated.css emits faithful per-breakpoint dimension tokens
16
- (--nc-<name>-mobile/-tablet/-desktop, 1:1 with the export); these :root
17
- aliases collapse each consumed name to the active breakpoint value, exactly
18
- reproducing the previous diff-suppressed cascade. Aliases exist ONLY for the
19
- 10 collapsed names that have real src/css consumers (h-strip joined when
20
- image's strip form became its first consumer). The two emitted-but-
21
- unconsumed dimension families (h-visual, h-precision) get no alias —
22
- an alias nothing reads is noise; their per-breakpoint tokens are still emitted
23
- to satisfy the faithful-projection mandate, and a future consumer can add the
24
- collapsed alias when it actually needs it. Custom-prop resolution is
25
- cascade-global, so these layout-layer aliases resolve for foundation-layer
26
- consumers (e.g. .nc-page max-width) regardless of import order. */
27
- :root {
28
- --nc-page-max: var(--nc-page-max-mobile);
29
- --nc-cross-size: var(--nc-cross-size-mobile);
30
- --nc-h-cell-md: var(--nc-h-cell-md-mobile);
31
- --nc-h-cell-lg: var(--nc-h-cell-lg-mobile);
32
- --nc-h-hero: var(--nc-h-hero-mobile);
33
- --nc-h-strip: var(--nc-h-strip-mobile);
34
- --nc-h-action-strip: var(--nc-h-action-strip-mobile);
35
- --nc-h-action-body: var(--nc-h-action-body-mobile);
36
- --nc-h-feature: var(--nc-h-feature-mobile);
37
- --nc-h-editorial-feature: var(--nc-h-editorial-feature-mobile);
38
- }
39
-
40
- @media (min-width: 600px) {
41
- :root {
42
- --nc-page-max: var(--nc-page-max-tablet);
43
- --nc-cross-size: var(--nc-cross-size-tablet);
44
- --nc-h-cell-md: var(--nc-h-cell-md-tablet);
45
- --nc-h-strip: var(--nc-h-strip-tablet);
46
- --nc-h-action-body: var(--nc-h-action-body-tablet);
47
- --nc-h-feature: var(--nc-h-feature-tablet);
48
- --nc-h-editorial-feature: var(--nc-h-editorial-feature-tablet);
49
- /* h-cell-lg, h-hero, h-action-strip have no tablet token — omit, so they
50
- inherit the mobile value until desktop (matching the previous cascade). */
51
- }
52
- }
53
-
54
- @media (min-width: 960px) {
55
- :root {
56
- --nc-page-max: var(--nc-page-max-desktop);
57
- --nc-cross-size: var(--nc-cross-size-desktop);
58
- --nc-h-cell-md: var(--nc-h-cell-md-desktop);
59
- --nc-h-cell-lg: var(--nc-h-cell-lg-desktop);
60
- --nc-h-hero: var(--nc-h-hero-desktop);
61
- --nc-h-strip: var(--nc-h-strip-desktop);
62
- --nc-h-action-strip: var(--nc-h-action-strip-desktop);
63
- --nc-h-feature: var(--nc-h-feature-desktop);
64
- --nc-h-editorial-feature: var(--nc-h-editorial-feature-desktop);
65
- /* h-action-body has no desktop token — omit, so it stays at the tablet
66
- value (matching the previous cascade). */
67
- }
68
- }
69
-
70
- .nc-page-system {
71
- width: 100%;
72
- padding-inline: var(--nc-page-pad);
73
- /* The frame floats clear of the page chrome on both ends: a band of empty
74
- canvas above (below the sticky nav) and below (above the footer) — the
75
- reference container model, where the bordered module never touches a
76
- chrome hairline. {spacing.4xl}, matching the nav's 64px bar. */
77
- padding-block: var(--nc-4xl);
78
- }
79
-
80
- .nc-page-frame {
81
- position: relative;
82
- width: 100%;
83
- max-width: var(--nc-frame-max);
84
- margin-inline: auto;
85
- border-top: var(--nc-guide) solid var(--nc-line);
86
- border-left: var(--nc-guide) solid var(--nc-line);
87
- background: var(--nc-canvas);
88
- }
89
-
90
- /* Single perimeter closer: the frame owns top+left; one ::after closes the
91
- trailing right+bottom edges ONCE. This removes the old border-right (which
92
- doubled the right edge) and supplies a single bottom owner for the whole
93
- frame, so no coordinate is painted twice. */
94
- .nc-page-frame::after {
95
- content: "";
96
- position: absolute;
97
- inset: 0;
98
- /* Single owner of the right+bottom perimeter. It must paint ABOVE row content
99
- (stage-stack z-index:1, index-card z-index:2) so the frame edge stays visible
100
- where content reaches it — e.g. a terminal full-bleed row (bento as the last
101
- row) whose bottom seam isn't supplied by a following row's border-top. */
102
- z-index: 3;
103
- border-right: var(--nc-guide) solid var(--nc-line);
104
- border-bottom: var(--nc-guide) solid var(--nc-line);
105
- pointer-events: none;
106
- }
107
-
108
- .nc-page-row {
109
- --nc-row-min-height: var(--nc-h-cell-lg);
110
- --nc-row-bleed-surface: var(--nc-canvas);
111
- position: relative;
112
- display: grid;
113
- grid-template-columns: minmax(0, 1fr);
114
- min-height: var(--nc-row-min-height);
115
- border-top: var(--nc-guide) solid var(--nc-line);
116
- background: var(--nc-canvas);
117
- }
118
-
119
- /* Each row owns its own top seam (one owner per inter-row line); the frame's
120
- own border-top owns the very top, so suppress the first row's top to avoid
121
- doubling it. The last row's bottom is owned by .nc-page-frame::after. */
122
- .nc-page-frame > .nc-page-row:first-child {
123
- border-top: 0;
124
- }
125
-
126
- .nc-page-row[data-nc-bleed="surface"]::before {
127
- content: "";
128
- position: absolute;
129
- z-index: 0;
130
- inset-block: 0;
131
- left: 50%;
132
- width: 100vw;
133
- transform: translateX(-50%);
134
- background: var(--nc-row-bleed-surface);
135
- pointer-events: none;
136
- }
137
-
138
- .nc-page-row[data-nc-bleed="surface"] > * {
139
- position: relative;
140
- z-index: 1;
141
- }
142
-
143
- .nc-row-lane {
144
- display: grid;
145
- min-width: 0;
146
- min-height: 0;
147
- }
148
-
149
- .nc-row-lane[data-lane="active"],
150
- .nc-row-lane[data-lane="full"] {
151
- grid-column: 1 / -1;
152
- }
153
-
154
- .nc-grid-field {
155
- --nc-grid-columns: 1;
156
- --nc-grid-rows: 1;
157
- --nc-grid-line: var(--nc-line);
158
- position: relative;
159
- display: grid;
160
- grid-template-columns: repeat(var(--nc-grid-columns), minmax(0, 1fr));
161
- grid-template-rows: repeat(var(--nc-grid-rows), minmax(0, 1fr));
162
- min-width: 0;
163
- /* visible so an edge crosshair (a .nc-marker grid child placed on a perimeter
164
- track line) is never clipped. A variant that must clip its payload
165
- re-asserts overflow:hidden in its recipe. */
166
- overflow: visible;
167
- background: var(--nc-canvas);
168
- }
169
-
170
- .nc-grid-field[data-grid-field="full-hero"] {
171
- --nc-grid-columns: 1;
172
- --nc-grid-rows: 2;
173
- height: var(--nc-h-hero);
174
- }
175
-
176
- .nc-grid-guides {
177
- display: contents;
178
- pointer-events: none;
179
- }
180
-
181
- .nc-grid-guide-v,
182
- .nc-grid-guide-h {
183
- position: relative;
184
- z-index: 1;
185
- display: none;
186
- min-width: 0;
187
- min-height: 0;
188
- pointer-events: none;
189
- }
190
-
191
- .nc-grid-guide-v {
192
- grid-column: var(--line);
193
- grid-row: 1 / -1;
194
- border-left: var(--nc-guide) solid var(--nc-grid-line);
195
- }
196
-
197
- .nc-grid-guide-h {
198
- grid-column: 1 / -1;
199
- grid-row: var(--line);
200
- border-top: var(--nc-guide) solid var(--nc-grid-line);
201
- }
202
-
203
- .nc-grid-slot {
204
- position: relative;
205
- z-index: 2;
206
- min-width: 0;
207
- }
208
-
209
- .nc-side-fill {
210
- display: none;
211
- min-width: 0;
212
- min-height: 0;
213
- background: repeating-linear-gradient(
214
- 125deg,
215
- var(--nc-canvas) 0,
216
- var(--nc-canvas) 6px,
217
- var(--nc-line) 6px,
218
- var(--nc-line) 7px
219
- );
220
- }
221
-
222
- /* The fill owns its single inner boundary rail so the texture is bounded on
223
- both sides — frame perimeter outside, this rail inside. One owner: the lane
224
- paints nothing at this coordinate. (Hidden by default; see the quiet-gutter
225
- doctrine at the desktop block.) */
226
- .nc-side-fill[data-side="start"] {
227
- grid-column: 1;
228
- border-inline-end: var(--nc-guide) solid var(--nc-line);
229
- }
230
-
231
- .nc-side-fill[data-side="end"] {
232
- grid-column: 12;
233
- border-inline-start: var(--nc-guide) solid var(--nc-line);
234
- }
235
-
236
- .nc-row-grid {
237
- display: grid;
238
- min-width: 0;
239
- background: var(--nc-line);
240
- column-gap: var(--nc-guide);
241
- row-gap: var(--nc-guide);
242
- padding-inline: var(--nc-guide);
243
- }
244
-
245
- /* Gap-only variant for nesting: a hairline grid sitting flush inside an edge
246
- another owner already draws (an outer cell-grid's column-gap, or a framed
247
- lane's side rail) must contribute internal seams only. Dropping its inline
248
- padding removes the perimeter line that would otherwise stack onto the owner's
249
- line and render 2px. The base grid already carries no padding-block, so the
250
- horizontal edges already defer to the row seams; this closes the vertical pair. */
251
- .nc-row-grid[data-edges="inner"] {
252
- padding-inline: 0;
253
- }
254
-
255
- .nc-row-grid[data-grid="2"],
256
- .nc-row-grid[data-grid="3"],
257
- .nc-row-grid[data-grid="4"],
258
- .nc-row-grid[data-grid="5"],
259
- .nc-row-grid[data-grid="6"] {
260
- grid-template-columns: minmax(0, 1fr);
261
- }
262
-
263
- .nc-index-grid {
264
- --nc-index-columns: 1;
265
- --nc-index-rows: auto;
266
- position: relative;
267
- display: grid;
268
- grid-template-columns: repeat(var(--nc-index-columns), minmax(0, 1fr));
269
- min-width: 0;
270
- }
271
-
272
- .nc-index-guides {
273
- position: absolute;
274
- inset: 0;
275
- z-index: 1;
276
- display: grid;
277
- grid-template-columns: inherit;
278
- pointer-events: none;
279
- }
280
-
281
- .nc-index-guide {
282
- min-width: 0;
283
- border-right: var(--nc-guide) solid var(--nc-line);
284
- }
285
-
286
- .nc-index-guide:last-child {
287
- border-right: 0;
288
- }
289
-
290
- .nc-index-card {
291
- position: relative;
292
- z-index: 2;
293
- display: grid;
294
- min-width: 0;
295
- min-height: var(--nc-h-cell-lg);
296
- padding: var(--nc-cell-padding);
297
- align-content: start;
298
- gap: 14px;
299
- overflow: hidden;
300
- background: var(--nc-canvas);
301
- color: var(--nc-ink);
302
- text-decoration: none;
303
- }
304
-
305
- .nc-index-card[data-featured="true"] {
306
- min-height: var(--nc-h-editorial-feature);
307
- }
308
-
309
- .nc-article-shell {
310
- display: grid;
311
- min-width: 0;
312
- background: var(--nc-line);
313
- column-gap: var(--nc-guide);
314
- row-gap: var(--nc-guide);
315
- padding-inline: var(--nc-guide);
316
- }
317
-
318
- .nc-article-header,
319
- .nc-article-body,
320
- .nc-article-side,
321
- .nc-article-footer {
322
- display: grid;
323
- min-width: 0;
324
- padding: var(--nc-cell-padding);
325
- gap: 12px;
326
- background: var(--nc-canvas);
327
- }
328
-
329
- .nc-article-header {
330
- min-height: 280px;
331
- align-content: center;
332
- }
333
-
334
- .nc-article-side {
335
- color: var(--nc-muted);
336
- }
337
-
338
- .nc-article-footer {
339
- background: var(--nc-ink);
340
- color: var(--nc-canvas);
341
- }
342
-
343
- .nc-span-12,
344
- .nc-span-10 {
345
- grid-column: 1 / -1;
346
- }
347
-
348
- .nc-stage-frame {
349
- --nc-stage-active-column: 1 / -1;
350
- --nc-stage-frame-gutter: 0px;
351
- --nc-stage-surface: var(--nc-canvas);
352
- --nc-stage-frame-color: var(--nc-line);
353
- --nc-stage-filler-color: var(--nc-canvas-soft-2);
354
- position: relative;
355
- min-width: 0;
356
- background: var(--nc-stage-surface);
357
- }
358
-
359
- .nc-stage-frame[data-frame-lines="true"]::before,
360
- .nc-stage-frame[data-frame-lines="true"]::after {
361
- content: "";
362
- position: absolute;
363
- top: 0;
364
- bottom: 0;
365
- z-index: 2;
366
- width: var(--nc-guide);
367
- background: var(--nc-stage-frame-color);
368
- pointer-events: none;
369
- }
370
-
371
- .nc-stage-frame[data-frame-lines="true"]::before {
372
- left: 0;
373
- }
374
-
375
- .nc-stage-frame[data-frame-lines="true"]::after {
376
- right: 0;
377
- }
378
-
379
- .nc-stage-fill {
380
- position: absolute;
381
- inset-inline: 0;
382
- top: var(--nc-stage-fill-top, 0px);
383
- bottom: var(--nc-stage-fill-bottom, 0px);
384
- display: grid;
385
- grid-template-columns: repeat(12, minmax(0, 1fr));
386
- column-gap: var(--nc-stage-frame-gutter);
387
- pointer-events: none;
388
- }
389
-
390
- .nc-stage-fill::before,
391
- .nc-stage-fill::after {
392
- content: "";
393
- min-width: 0;
394
- background:
395
- repeating-linear-gradient(
396
- 125deg,
397
- transparent,
398
- transparent 6px,
399
- var(--nc-stage-filler-color) 6px,
400
- var(--nc-stage-filler-color) 7px
401
- ),
402
- var(--nc-canvas);
403
- }
404
-
405
- .nc-stage-fill::before {
406
- grid-column: 1;
407
- margin-right: calc(var(--nc-stage-frame-gutter) * -1);
408
- }
409
-
410
- .nc-stage-fill::after {
411
- grid-column: 12;
412
- margin-left: calc(var(--nc-stage-frame-gutter) * -1);
413
- }
414
-
415
- .nc-stage-stack {
416
- position: relative;
417
- z-index: 1;
418
- min-width: 0;
419
- }
420
-
421
- .nc-stage-grid,
422
- .nc-connector-strip {
423
- display: grid;
424
- grid-template-columns: minmax(0, 1fr);
425
- column-gap: var(--nc-stage-frame-gutter);
426
- min-width: 0;
427
- }
428
-
429
- .nc-stage-active,
430
- .nc-connector-track {
431
- grid-column: var(--nc-stage-active-column);
432
- }
433
-
434
- .nc-connector-strip {
435
- height: calc(var(--nc-connector-height, var(--nc-h-action-strip)) + var(--nc-guide));
436
- }
437
-
438
- .nc-connector-strip[data-edge="start"] {
439
- border-bottom: var(--nc-guide) solid var(--nc-connector-frame-color, var(--nc-stage-frame-color));
440
- }
441
-
442
- .nc-connector-strip[data-edge="end"] {
443
- border-top: var(--nc-guide) solid var(--nc-connector-frame-color, var(--nc-stage-frame-color));
444
- }
445
-
446
- .nc-connector-track {
447
- position: relative;
448
- display: grid;
449
- grid-template-columns: minmax(0, 1fr);
450
- gap: 0;
451
- height: var(--nc-connector-height, var(--nc-h-action-strip));
452
- min-width: 0;
453
- padding-inline: var(--nc-guide);
454
- overflow: hidden;
455
- }
456
-
457
- .nc-connector-track > div {
458
- min-width: 0;
459
- height: var(--nc-connector-height, var(--nc-h-action-strip));
460
- }
461
-
462
- .nc-connector-track > div:nth-child(n + 2) {
463
- display: none;
464
- }
465
-
466
- .nc-connector-strip svg {
467
- color: var(--nc-connector-color, var(--nc-seam));
468
- overflow: visible;
469
- }
470
-
471
- .nc-connector-strip line {
472
- stroke: currentColor;
473
- stroke-dasharray: var(--nc-connector-dash, 4 6);
474
- stroke-linecap: round;
475
- }
476
-
477
- .nc-connector-track div svg {
478
- display: block;
479
- width: var(--nc-guide);
480
- height: var(--nc-connector-height, var(--nc-h-action-strip));
481
- margin-left: calc(var(--nc-guide) * -1);
482
- }
483
-
484
- .nc-connector-track > svg {
485
- position: absolute;
486
- top: 0;
487
- right: 0;
488
- display: block;
489
- width: var(--nc-guide);
490
- height: var(--nc-connector-height, var(--nc-h-action-strip));
491
- }
492
-
493
- @media (min-width: 600px) {
494
- .nc-grid-field[data-grid-field="full-hero"] {
495
- --nc-grid-columns: 8;
496
- --nc-grid-rows: 4;
497
- }
498
-
499
- .nc-grid-guide-v,
500
- .nc-grid-guide-h {
501
- display: block;
502
- }
503
-
504
- .nc-grid-guide-v[data-min="desktop"],
505
- .nc-grid-guide-h[data-min="desktop"] {
506
- display: none;
507
- }
508
-
509
- .nc-row-grid[data-grid="2"],
510
- .nc-row-grid[data-grid="3"],
511
- .nc-row-grid[data-grid="4"] {
512
- grid-template-columns: repeat(2, minmax(0, 1fr));
513
- }
514
-
515
- .nc-row-grid[data-grid="5"],
516
- .nc-row-grid[data-grid="6"] {
517
- grid-template-columns: repeat(3, minmax(0, 1fr));
518
- }
519
-
520
- .nc-index-grid {
521
- --nc-index-columns: 2;
522
- }
523
- }
524
-
525
- @media (min-width: 960px) {
526
- .nc-grid-field[data-grid-field="full-hero"] {
527
- --nc-grid-columns: 12;
528
- --nc-grid-rows: 8;
529
- }
530
-
531
- .nc-grid-guide-v,
532
- .nc-grid-guide-h,
533
- .nc-grid-guide-v[data-min="desktop"],
534
- .nc-grid-guide-h[data-min="desktop"] {
535
- display: block;
536
- }
537
-
538
- .nc-page-row {
539
- grid-template-columns: repeat(12, minmax(0, 1fr));
540
- column-gap: var(--nc-frame-gap);
541
- }
542
-
543
- .nc-row-lane[data-lane="active"] {
544
- grid-column: 2 / 12;
545
- }
546
-
547
- .nc-row-lane[data-lane="full"] {
548
- grid-column: 1 / -1;
549
- }
550
-
551
- /* Framed active lane: a single owner for the lane's own left/right hairlines so
552
- side framing is a deliberate choice, not a side effect of whichever block
553
- sits inside. Scoped to desktop because the active lane is inset (2 / 12) only
554
- here; below this breakpoint the lane fills the row and the frame border
555
- already owns those edges, so rails would double against it. Framed-lane
556
- content must not paint its own perimeter on the same edge — nest a cell-grid
557
- as data-edges="inner" so the lane owns the sides and the grid owns the
558
- interior seams. */
559
- .nc-row-lane[data-lane="active"][data-frame-lines="true"] {
560
- position: relative;
561
- }
562
-
563
- .nc-row-lane[data-lane="active"][data-frame-lines="true"]::before,
564
- .nc-row-lane[data-lane="active"][data-frame-lines="true"]::after {
565
- content: "";
566
- position: absolute;
567
- top: 0;
568
- bottom: 0;
569
- z-index: 2;
570
- width: var(--nc-guide);
571
- background: var(--nc-line);
572
- pointer-events: none;
573
- }
574
-
575
- .nc-row-lane[data-lane="active"][data-frame-lines="true"]::before {
576
- left: 0;
577
- }
578
-
579
- .nc-row-lane[data-lane="active"][data-frame-lines="true"]::after {
580
- right: 0;
581
- }
582
-
583
- .nc-stage-frame {
584
- --nc-stage-active-column: 2 / 12;
585
- --nc-stage-frame-gutter: var(--nc-frame-gap);
586
- }
587
-
588
- .nc-stage-grid,
589
- .nc-connector-strip {
590
- grid-template-columns: repeat(12, minmax(0, 1fr));
591
- }
592
-
593
- /* Quiet-gutter doctrine: columns 1 and 12 are empty canvas by default — the
594
- whitespace IS the margin (the reference container model: structure lives
595
- inside bounded modules, never as page-length gutter texture). The diagonal
596
- fill is a scarce structural accent a row opts into with
597
- data-rails="hatch"; reserve it for the page's anchor rows (opening hero,
598
- closing conversion), where its own inner rail and the frame perimeter
599
- bound it on both sides. */
600
- .nc-page-row[data-rails="hatch"] .nc-side-fill {
601
- display: block;
602
- }
603
-
604
- .nc-side-fill[data-side="start"] {
605
- margin-right: calc(var(--nc-frame-gap) * -1);
606
- }
607
-
608
- .nc-side-fill[data-side="end"] {
609
- margin-left: calc(var(--nc-frame-gap) * -1);
610
- }
611
-
612
- .nc-row-grid[data-grid="3"] {
613
- grid-template-columns: repeat(3, minmax(0, 1fr));
614
- }
615
-
616
- .nc-row-grid[data-grid="4"] {
617
- grid-template-columns: repeat(4, minmax(0, 1fr));
618
- }
619
-
620
- .nc-row-grid[data-grid="5"] {
621
- grid-template-columns: repeat(5, minmax(0, 1fr));
622
- }
623
-
624
- .nc-row-grid[data-grid="6"] {
625
- grid-template-columns: repeat(6, minmax(0, 1fr));
626
- }
627
-
628
- .nc-index-grid {
629
- --nc-index-columns: 3;
630
- }
631
-
632
- .nc-index-card[data-featured="true"] {
633
- grid-column: span 2;
634
- }
635
-
636
- .nc-article-shell {
637
- grid-template-columns: repeat(12, minmax(0, 1fr));
638
- }
639
-
640
- .nc-article-header,
641
- .nc-article-footer {
642
- grid-column: 1 / -1;
643
- }
644
-
645
- .nc-article-side {
646
- grid-column: 1 / 3;
647
- grid-row: 2;
648
- }
649
-
650
- .nc-article-body {
651
- grid-column: 3 / -1;
652
- }
653
-
654
- .nc-span-10 {
655
- grid-column: 2 / 12;
656
- }
657
- }