@nurix/etna 0.19.51 → 0.19.53

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 (156) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/apollo/.mcp.json +8 -0
  3. package/data/harnesses/apollo/harness.json +3 -2
  4. package/data/harnesses/apollo/skills/design/SKILL.md +45 -50
  5. package/data/harnesses/apollo/skills/design/data/blueprints/browse.md +38 -0
  6. package/data/harnesses/apollo/skills/design/data/blueprints/creation-flow.md +38 -0
  7. package/data/harnesses/apollo/skills/design/data/blueprints/dashboard.md +38 -0
  8. package/data/harnesses/apollo/skills/design/data/blueprints/grid.md +38 -0
  9. package/data/harnesses/apollo/skills/design/data/blueprints/queue.md +38 -0
  10. package/data/harnesses/apollo/skills/design/data/blueprints/record-detail.md +38 -0
  11. package/data/harnesses/apollo/skills/design/data/blueprints/settings.md +38 -0
  12. package/data/harnesses/apollo/skills/design/data/charts/census.csv +58 -0
  13. package/data/harnesses/apollo/skills/design/data/checklists/browse.md +21 -0
  14. package/data/harnesses/apollo/skills/design/data/checklists/creation-flow.md +20 -0
  15. package/data/harnesses/apollo/skills/design/data/checklists/dashboard.md +21 -0
  16. package/data/harnesses/apollo/skills/design/data/checklists/grid.md +21 -0
  17. package/data/harnesses/apollo/skills/design/data/checklists/queue.md +21 -0
  18. package/data/harnesses/apollo/skills/design/data/checklists/record-detail.md +21 -0
  19. package/data/harnesses/apollo/skills/design/data/checklists/settings.md +21 -0
  20. package/data/harnesses/apollo/skills/design/data/chrome/board-column.md +68 -0
  21. package/data/harnesses/apollo/skills/design/data/chrome/data-table.md +63 -0
  22. package/data/harnesses/apollo/skills/design/data/chrome/side-panel.md +60 -0
  23. package/data/harnesses/apollo/skills/design/data/chrome/sidebar.md +78 -0
  24. package/data/harnesses/apollo/skills/design/data/chrome/stat-cards.md +62 -0
  25. package/data/harnesses/apollo/skills/design/data/chrome/topbar.md +65 -0
  26. package/data/harnesses/apollo/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  27. package/data/harnesses/apollo/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  28. package/data/harnesses/apollo/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  29. package/data/harnesses/apollo/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  30. package/data/harnesses/apollo/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  31. package/data/harnesses/apollo/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  32. package/data/harnesses/apollo/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  33. package/data/harnesses/apollo/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  34. package/data/harnesses/apollo/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  35. package/data/harnesses/apollo/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  36. package/data/harnesses/apollo/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  37. package/data/harnesses/apollo/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  38. package/data/harnesses/apollo/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  39. package/data/harnesses/apollo/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  40. package/data/harnesses/apollo/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  41. package/data/harnesses/apollo/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  42. package/data/harnesses/apollo/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  43. package/data/harnesses/apollo/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  44. package/data/harnesses/apollo/skills/design/data/iconography.md +199 -0
  45. package/data/harnesses/apollo/skills/design/data/motion/accordion-expand.md +18 -0
  46. package/data/harnesses/apollo/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  47. package/data/harnesses/apollo/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  48. package/data/harnesses/apollo/skills/design/data/motion/empty-state-arrive.md +18 -0
  49. package/data/harnesses/apollo/skills/design/data/motion/hover-lift.md +18 -0
  50. package/data/harnesses/apollo/skills/design/data/motion/modal-center-arrive.md +18 -0
  51. package/data/harnesses/apollo/skills/design/data/motion/number-ticker-roll.md +18 -0
  52. package/data/harnesses/apollo/skills/design/data/motion/onboarding-bounce.md +18 -0
  53. package/data/harnesses/apollo/skills/design/data/motion/panel-slide.md +18 -0
  54. package/data/harnesses/apollo/skills/design/data/motion/press-feedback.md +18 -0
  55. package/data/harnesses/apollo/skills/design/data/motion/progress-linear-loop.md +18 -0
  56. package/data/harnesses/apollo/skills/design/data/motion/route-crossfade.md +18 -0
  57. package/data/harnesses/apollo/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  58. package/data/harnesses/apollo/skills/design/data/motion/skeleton-shimmer.md +18 -0
  59. package/data/harnesses/apollo/skills/design/data/motion/stagger-arrive.md +18 -0
  60. package/data/harnesses/apollo/skills/design/data/motion/toast-enter-stack.md +18 -0
  61. package/data/harnesses/apollo/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  62. package/data/harnesses/apollo/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  63. package/data/harnesses/apollo/skills/design/data/tells.csv +34 -0
  64. package/data/harnesses/apollo/skills/design/data/voices/bright-collaborator.md +29 -0
  65. package/data/harnesses/apollo/skills/design/data/voices/direct-operator.md +29 -0
  66. package/data/harnesses/apollo/skills/design/data/voices/earnest-helper.md +29 -0
  67. package/data/harnesses/apollo/skills/design/data/voices/editorial-composed.md +29 -0
  68. package/data/harnesses/apollo/skills/design/data/voices/quiet-concierge.md +29 -0
  69. package/data/harnesses/apollo/skills/design/data/voices/warm-guide.md +29 -0
  70. package/data/harnesses/apollo/skills/design/references/compose.md +3 -7
  71. package/data/harnesses/apollo/skills/design/references/content.md +4 -4
  72. package/data/harnesses/apollo/skills/design/references/existing-apps.md +1 -1
  73. package/data/harnesses/apollo/skills/design/references/foundations.md +57 -0
  74. package/data/harnesses/apollo/skills/design/references/intake.md +11 -11
  75. package/data/harnesses/apollo/skills/design/references/object-pass.md +1 -1
  76. package/data/harnesses/apollo/skills/design/references/ship-gate.md +1 -1
  77. package/data/harnesses/apollo/skills/design/scripts/select-chart.mjs +14 -8
  78. package/data/harnesses/apollo/skills/design/scripts/validate-design-md.mjs +1 -1
  79. package/data/harnesses/code/.mcp.json +8 -0
  80. package/data/harnesses/code/harness.json +4 -2
  81. package/data/harnesses/code/skills/design/SKILL.md +45 -50
  82. package/data/harnesses/code/skills/design/data/blueprints/browse.md +38 -0
  83. package/data/harnesses/code/skills/design/data/blueprints/creation-flow.md +38 -0
  84. package/data/harnesses/code/skills/design/data/blueprints/dashboard.md +38 -0
  85. package/data/harnesses/code/skills/design/data/blueprints/grid.md +38 -0
  86. package/data/harnesses/code/skills/design/data/blueprints/queue.md +38 -0
  87. package/data/harnesses/code/skills/design/data/blueprints/record-detail.md +38 -0
  88. package/data/harnesses/code/skills/design/data/blueprints/settings.md +38 -0
  89. package/data/harnesses/code/skills/design/data/charts/census.csv +58 -0
  90. package/data/harnesses/code/skills/design/data/checklists/browse.md +21 -0
  91. package/data/harnesses/code/skills/design/data/checklists/creation-flow.md +20 -0
  92. package/data/harnesses/code/skills/design/data/checklists/dashboard.md +21 -0
  93. package/data/harnesses/code/skills/design/data/checklists/grid.md +21 -0
  94. package/data/harnesses/code/skills/design/data/checklists/queue.md +21 -0
  95. package/data/harnesses/code/skills/design/data/checklists/record-detail.md +21 -0
  96. package/data/harnesses/code/skills/design/data/checklists/settings.md +21 -0
  97. package/data/harnesses/code/skills/design/data/chrome/board-column.md +68 -0
  98. package/data/harnesses/code/skills/design/data/chrome/data-table.md +63 -0
  99. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +60 -0
  100. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +78 -0
  101. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +62 -0
  102. package/data/harnesses/code/skills/design/data/chrome/topbar.md +65 -0
  103. package/data/harnesses/code/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  104. package/data/harnesses/code/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  105. package/data/harnesses/code/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  106. package/data/harnesses/code/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  107. package/data/harnesses/code/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  108. package/data/harnesses/code/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  109. package/data/harnesses/code/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  110. package/data/harnesses/code/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  111. package/data/harnesses/code/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  112. package/data/harnesses/code/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  113. package/data/harnesses/code/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  114. package/data/harnesses/code/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  115. package/data/harnesses/code/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  116. package/data/harnesses/code/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  117. package/data/harnesses/code/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  118. package/data/harnesses/code/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  119. package/data/harnesses/code/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  120. package/data/harnesses/code/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  121. package/data/harnesses/code/skills/design/data/iconography.md +199 -0
  122. package/data/harnesses/code/skills/design/data/motion/accordion-expand.md +18 -0
  123. package/data/harnesses/code/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  124. package/data/harnesses/code/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  125. package/data/harnesses/code/skills/design/data/motion/empty-state-arrive.md +18 -0
  126. package/data/harnesses/code/skills/design/data/motion/hover-lift.md +18 -0
  127. package/data/harnesses/code/skills/design/data/motion/modal-center-arrive.md +18 -0
  128. package/data/harnesses/code/skills/design/data/motion/number-ticker-roll.md +18 -0
  129. package/data/harnesses/code/skills/design/data/motion/onboarding-bounce.md +18 -0
  130. package/data/harnesses/code/skills/design/data/motion/panel-slide.md +18 -0
  131. package/data/harnesses/code/skills/design/data/motion/press-feedback.md +18 -0
  132. package/data/harnesses/code/skills/design/data/motion/progress-linear-loop.md +18 -0
  133. package/data/harnesses/code/skills/design/data/motion/route-crossfade.md +18 -0
  134. package/data/harnesses/code/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  135. package/data/harnesses/code/skills/design/data/motion/skeleton-shimmer.md +18 -0
  136. package/data/harnesses/code/skills/design/data/motion/stagger-arrive.md +18 -0
  137. package/data/harnesses/code/skills/design/data/motion/toast-enter-stack.md +18 -0
  138. package/data/harnesses/code/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  139. package/data/harnesses/code/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  140. package/data/harnesses/code/skills/design/data/tells.csv +34 -0
  141. package/data/harnesses/code/skills/design/data/voices/bright-collaborator.md +29 -0
  142. package/data/harnesses/code/skills/design/data/voices/direct-operator.md +29 -0
  143. package/data/harnesses/code/skills/design/data/voices/earnest-helper.md +29 -0
  144. package/data/harnesses/code/skills/design/data/voices/editorial-composed.md +29 -0
  145. package/data/harnesses/code/skills/design/data/voices/quiet-concierge.md +29 -0
  146. package/data/harnesses/code/skills/design/data/voices/warm-guide.md +29 -0
  147. package/data/harnesses/code/skills/design/references/compose.md +3 -7
  148. package/data/harnesses/code/skills/design/references/content.md +4 -4
  149. package/data/harnesses/code/skills/design/references/existing-apps.md +1 -1
  150. package/data/harnesses/code/skills/design/references/foundations.md +57 -0
  151. package/data/harnesses/code/skills/design/references/intake.md +11 -11
  152. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  153. package/data/harnesses/code/skills/design/references/ship-gate.md +1 -1
  154. package/data/harnesses/code/skills/design/scripts/select-chart.mjs +14 -8
  155. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +1 -1
  156. package/package.json +2 -2
@@ -0,0 +1,38 @@
1
+ ---
2
+ id: settings
3
+ class: d3
4
+ sourced: 2026-07-12
5
+ source: "design-skill-phase1 D3 sweep — distilled from GitHub repository settings, Slack admin console, Stripe Dashboard settings, Salesforce Setup Quick Find, common SaaS account-settings patterns"
6
+ license: open
7
+ ---
8
+ Composition shapes for the settings archetype — configuration surfaces organized by scope, subject, and risk. The size and depth of the settings surface picks the shape.
9
+
10
+ ## Shape: Left Category Nav + Detail Pane
11
+ Regions: left navigation (fixed width, expandable category tree) / detail pane (remaining width, shows the form or table for the selected category only).
12
+ The eye lands on: the highlighted item in the left nav, then the pane's section heading.
13
+ When to use: settings span many unrelated categories that users navigate between rather than read straight through.
14
+ Seen in: GitHub repository settings, Slack's admin console left-nav category tree.
15
+
16
+ ## Shape: Top Tab Strip Sections
17
+ Regions: horizontal tab strip (top, full-width, a handful of top-level categories) / one scrollable panel per tab filling the rest of the page.
18
+ The eye lands on: the active tab label.
19
+ When to use: the number of top-level categories is small enough to stay visible at once without a side nav's real estate cost.
20
+ Seen in: Stripe Dashboard settings, split into Personal / Account / Product tabs.
21
+
22
+ ## Shape: Search-Driven Settings
23
+ Regions: a quick-find search box (top, prominent) over an otherwise large, unbrowsed index of setting pages / results filter the index live as the user types.
24
+ The eye lands on: the search box itself before any content.
25
+ When to use: the settings surface is too large or too deep to browse by category reliably, and users usually know the setting's name.
26
+ Seen in: Salesforce's Setup home with Quick Find search over the full Setup/Object Manager index.
27
+
28
+ ## Shape: Long Scrolling Anchored Page
29
+ Regions: a single continuous page (full-width, no separate nav pane or tabs) with settings grouped into vertically stacked sections / optional anchor links jump to a section.
30
+ The eye lands on: whichever section heading is nearest the top of the current scroll position.
31
+ When to use: the total settings surface is modest enough that scrolling beats clicking between categories.
32
+ Seen in: common single-page "Account settings" patterns across SaaS admin surfaces (the pattern GitHub and Stripe both fall back to for smaller settings areas nested inside their larger nav/tab shells).
33
+
34
+ ## Shape: Master-Detail Settings List
35
+ Regions: a table of configuration records (full-width or left-majority — API keys, webhooks, members, roles) with an "add" action above it / clicking a row opens that record's own edit form, inline or in a panel.
36
+ The eye lands on: the most recently created or most active row in the table.
37
+ When to use: the "setting" is really a collection of independent records (keys, integrations, members) rather than a single configuration object.
38
+ Seen in: Stripe's API keys and webhooks pages, GitHub's collaborators and webhooks settings pages.
@@ -0,0 +1,58 @@
1
+ id,family,min_measures,max_measures,min_dims,max_dims,requires_flags,excludes_flags,viewport_min,notes
2
+ bar,bar,1,1,1,1,,,mobile,zero-anchored value axis; one value per category; comfort cap 12 categories (K2)
3
+ grouped-bar,bar,1,1,2,2,,,tablet,series cap 4 (K7); cross-group comparison of non-adjacent bars is hard
4
+ stacked-bar,bar,1,1,2,2,parts-form-whole,negative-values,mobile,additive parts of one total; totals cap 10 (K4); middle segments lack a shared baseline
5
+ diverging-bar,bar,1,1,1,2,negative-values,,mobile,meaningful zero or midpoint; Likert and population pyramid fold here
6
+ lollipop,bar,1,1,1,1,,,mobile,less ink than a bar; right when values are large and similar
7
+ dot-plot,bar,1,2,1,1,,mixed-units,mobile,common scale required; the no-zero-baseline escape
8
+ dumbbell,bar,2,2,1,1,,mixed-units,mobile,exactly two points per category; start and end must share a unit
9
+ pictogram,bar,1,1,1,1,whole-units,negative-values,tablet,one icon equals k units; stated unit scale; decorative
10
+ line-basic,line,1,1,1,1,temporal|ordered-progression,,mobile,one series over ordered axis
11
+ line-multi,line,1,1,2,2,temporal|ordered-progression,,mobile,series cap 6 (K3); beyond cap facet into small multiples
12
+ line-with-target,line,2,2,1,1,temporal|ordered-progression|target-exists,mixed-units,mobile,series + target band
13
+ area,line,1,1,1,1,temporal,negative-values|irregular-temporal,mobile,zero baseline; magnitude emphasis
14
+ stacked-area,line,1,1,2,2,temporal|parts-form-whole,negative-values|irregular-temporal,tablet,additive parts over time; middle-layer trends unreadable
15
+ streamgraph,line,1,1,2,2,temporal,negative-values|irregular-temporal,desktop,pattern only; wants many smooth series; no precise reading
16
+ slope,line,1,1,2,2,temporal|ordered-progression,,mobile,exactly 2 or 3 x positions; rank-change emphasis
17
+ bump,line,1,1,2,2,temporal|ordered-progression,,tablet,plots rank not value; series cap 12
18
+ sparkline,line,1,1,1,1,temporal,,mobile,inline miniature; needs an adjacent number for scale
19
+ pie,part-to-whole,1,1,1,1,parts-form-whole,temporal|negative-values,desktop,max 6 slices
20
+ waffle,part-to-whole,1,1,1,1,parts-form-whole,negative-values,tablet,10x10 grid (K8); whole-cell rounding drops sub-1% parts
21
+ treemap,part-to-whole,1,1,1,2,parts-form-whole,negative-values,tablet,children sum to parents; a flat one-level list degenerates fine
22
+ sunburst,part-to-whole,1,1,0,2,tree|parts-form-whole,negative-values,desktop,hierarchy on concentric rings; outer-ring distortion caveat
23
+ marimekko,part-to-whole,1,2,2,2,parts-form-whole,negative-values|mixed-units,desktop,two area dimensions; expert audiences
24
+ funnel,part-to-whole,1,1,1,1,ordered-progression,negative-values,mobile,genuine ordered pipeline only; typically monotone decreasing
25
+ histogram,distribution,1,1,0,1,raw-observations,,mobile,bins derived not supplied; never category-value pairs
26
+ density,distribution,1,1,0,1,raw-observations,,tablet,KDE; bandwidth can oversmooth; needs large n
27
+ box-plot,distribution,1,1,0,1,raw-observations,,mobile,five-number summary; hides multimodality
28
+ violin,distribution,1,1,0,1,raw-observations,,tablet,mirrored KDE; needs enough n per group
29
+ strip-plot,distribution,1,1,0,1,raw-observations,,mobile,every point drawn; jitter for ties; moderate n
30
+ scatter,correlation,2,2,0,1,,,mobile,point-level rows; overplotting escape to hexbin at scale (K5)
31
+ bubble,correlation,3,3,0,1,,,tablet,size maps to area never radius; size measure non-negative
32
+ hexbin,correlation,2,2,0,1,raw-observations,,tablet,the overplotting escape; binned 2D density
33
+ splom,correlation,3,8,0,1,raw-observations,,desktop,pairwise panels grow O(k^2); variable cap 8 (K9)
34
+ parallel-coordinates,correlation,3,12,0,1,,,desktop,axes normalized individually; axis order changes visible structure
35
+ radar,correlation,3,8,0,1,,mixed-units,tablet,shared or normalized axes; spurious area reading; entity cap 3
36
+ ordered-bar,ranking,1,1,1,1,,,mobile,sorted by value not label; inherits bar constraints (K2)
37
+ pareto,ranking,1,1,1,1,parts-form-whole,negative-values,desktop,descending bars + cumulative percent line; additive counts only
38
+ sankey,flow,1,1,2,2,edges|ordered-progression,negative-values,desktop,conservation reads best; no cycles; stage-ordered nodes
39
+ chord,flow,1,1,2,2,edges|matrix,negative-values,desktop,pairwise flows; dense matrices become ribbon spaghetti
40
+ waterfall,flow,1,1,1,1,ordered-progression,,tablet,ordered decomposition start to end; signed contributions welcome
41
+ network-graph,network,0,1,2,2,edges,,desktop,visible-node cap ~300 (K10); beyond that use an adjacency matrix
42
+ tree-diagram,network,0,1,0,2,tree,,tablet,parent-child hierarchy; dendrogram adds merge height
43
+ choropleth,geo,1,1,1,1,geo,no-color-encoding,tablet,rates never raw totals
44
+ symbol-map,geo,1,1,1,1,geo,negative-values,tablet,totals; size to area; complement of choropleth
45
+ flow-map,geo,0,1,2,2,geo,,desktop,origin-destination movement across geography
46
+ point-map,geo,0,0,1,2,geo,,mobile,position only; no value encoding
47
+ gantt,temporal-event,0,1,1,2,interval,,desktop,true start AND end per row
48
+ event-timeline,temporal-event,0,0,1,2,temporal,,mobile,point events not intervals; labels not measures; optional track dimension
49
+ calendar-heatmap,temporal-event,1,1,1,1,temporal,no-color-encoding,tablet,daily grain on a calendar grid; pattern over precision
50
+ kpi-card,kpi,1,2,0,0,,,mobile,needs comparison context; delta or target welcome
51
+ gauge,kpi,1,1,0,0,target-exists,,tablet,defined domain required; space-hungry; decorative
52
+ progress-bar,kpi,1,1,0,0,target-exists,negative-values,mobile,one part-versus-whole fact; meaningless without a goal
53
+ bullet,kpi,1,2,0,1,target-exists,mixed-units,mobile,target marker + qualitative bands; compact gauge replacement
54
+ heatmap,matrix,1,1,2,2,,no-color-encoding,tablet,one value per cell; aggregate first; replaces spaghetti lines at high series counts
55
+ table,table,0,99,0,99,,,mobile,universal fallback; exact values over comparison
56
+ table-hybrid,table,1,99,0,99,,,tablet,data bars; cell heat; inline sparklines; the bridge leaf
57
+ candlestick,specialized,4,4,1,1,temporal,irregular-temporal,desktop,strict OHLC tuple per period
58
+ error-bands,specialized,1,3,0,2,uncertainty,,mobile,composite overlay; attaches to line or bar or scatter; never standalone
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: browse
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (page archetypes, table mechanics, state matrix chapters)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a browse surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - A visible result count adjacent to the search/filter controls that reflects the active filter set ("1–50 of 1,204").
11
+ - Every active filter rendered as a dismissible chip or token near the results, so the current slice is readable at a glance.
12
+ - A search or quick-filter input whose placeholder names what is searchable ("Search by name, email, or ID…").
13
+ - Saved or standing views surfaced as named tabs or a view switcher, with the active view visibly marked.
14
+ - Real pagination or an explicit total with position — never an unbounded, unlabeled scroll.
15
+ - Sort state visible on the sorted column or control (direction indicator on the header).
16
+ - Status values rendered as colored chips or badges, one distinct color per state, consistent everywhere the status appears.
17
+ - Table columns aligned by type: numbers right-aligned in tabular figures, text left-aligned, dates in one consistent format.
18
+ - Each result row or card leads with the record's human identity (name/title), not its internal ID.
19
+ - Row or card hover affordance: a background shift, revealed actions, or both, on every result.
20
+ - A designed zero-results state that names the active filters and offers a one-click clear-filters action.
21
+ - A designed true-empty state (no records exist yet) distinct from zero-results, with a path to create or import.
@@ -0,0 +1,20 @@
1
+ ---
2
+ id: creation-flow
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (creation-path catalog, modes, state matrix chapters)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a creation-flow surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - The first input focused on entry (visible focus ring), with field order matching reading order.
11
+ - Required and optional fields visibly distinguished — one convention, applied to every field.
12
+ - A progress indicator whenever the flow has steps: current step named, completed steps visually distinct, completed steps re-enterable.
13
+ - Fields grouped into labeled sections rather than one undifferentiated column.
14
+ - Sensible defaults pre-filled wherever one exists (owner = current user, date = today, visible and editable).
15
+ - Inline validation rendered beside the offending field, with a message that names the fix ("Must be a work email"), not just an error color.
16
+ - The primary action labeled verb + object ("Create ticket", "Invite member") — never a bare "Submit".
17
+ - A visible cancel or close path, with draft preservation signaled when the flow is dismissed mid-entry.
18
+ - On failed submit, an error summary that names each problem and points (link or scroll) to its field.
19
+ - Helper text under any field whose format or effect isn't self-evident.
20
+ - Success hands the user the created object: navigation to it or a named link, with confirmation copy naming what was created.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: dashboard
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (dashboards chapter: every tile is number + comparison + trend + state + door)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a dashboard surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - Every KPI tile carries all five parts: the number, a comparison (vs. prior period or target), a trend (sparkline or delta), a state (good/warn/bad treatment), and a door (a click-through to the detail behind it).
11
+ - Numbers formatted for scanning: tabular figures, thousands separators, units or currency attached, consistent decimal places across tiles.
12
+ - Deltas signed and colored by meaning — down can be green when down is good — never colored by direction alone.
13
+ - One time-range control visible and visibly applied to every widget it scopes ("Last 30 days" readable on the surface).
14
+ - Every chart titled with the measure and dimension in plain words ("Revenue by region"), not an internal metric name.
15
+ - Chart axes labeled or self-evident, with an honest baseline on value axes.
16
+ - A legend wherever more than one series shares a plot, with legend colors matching the marks.
17
+ - Data freshness stamped somewhere fixed ("Updated 4 min ago" / "As of 09:00").
18
+ - Any metric in a breach or alert state visibly different at a glance — the surface points the eye at what's wrong.
19
+ - Widgets aligned to a shared grid with consistent gutters; region edges line up across the page.
20
+ - Each widget owning a designed loading state (skeleton in the widget's own footprint) and a designed empty state naming what's missing.
21
+ - Every table or list widget cut to a readable size with a door to the full view ("View all 214").
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: grid
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (table mechanics, container choice, state matrix chapters)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a grid surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - An identity column (or columns) frozen against horizontal scroll, anchoring every row.
11
+ - Column headers sticky against vertical scroll, so field names never leave the screen.
12
+ - Cell rendering differentiated by type: numbers right-aligned in tabular figures, dates in one format, enums as chips, booleans as checks — never everything as plain left-aligned text.
13
+ - A selection checkbox column with a select-all control in the header.
14
+ - A bulk-action bar that appears with a visible selection count once rows are selected, naming the actions it applies.
15
+ - An add-record affordance pinned to a fixed location (bottom edge or toolbar), visible without scrolling.
16
+ - Group headers carrying aggregates (count, sum, or average) whenever grouping is active.
17
+ - A visible cell focus state distinct from row hover, so the editing target is unambiguous.
18
+ - A density or row-height control in the toolbar.
19
+ - The total record count visible somewhere fixed (toolbar or footer).
20
+ - Inline save-state feedback on edited cells: saving, saved, or error, each visually distinct.
21
+ - A designed empty state for a grid with no rows, with a create or import path — never a bare header row over whitespace.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: queue
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (page archetypes, verbs, state matrix chapters)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a queue surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - The queue's ordering key (priority, age, SLA) readable from the first screen — the operator can say why the top item is on top.
11
+ - Claim/ownership state on every item: an assignee avatar or name, or an explicit unclaimed marker.
12
+ - An aging or SLA indicator per item (time in queue, due-in countdown) whose color shifts as the deadline degrades.
13
+ - Visible keyboard affordances for advancing: shortcut hints on the primary actions or a reachable shortcuts overlay (J/K-style next/previous).
14
+ - Item counts visible per view or group, so backlog size is readable without scrolling.
15
+ - Unprocessed items visually distinct from processed ones (weight, dot, or background — more than color alone).
16
+ - The selected item highlighted in the list while its detail is open, so the operator keeps their place.
17
+ - The primary triage verbs (resolve, approve, reassign, escalate) reachable from the item without leaving the queue — a pinned action bar, not a buried menu.
18
+ - Item status rendered as a colored chip, consistent with the same status colors used elsewhere in the product.
19
+ - Priority or escalation markers visually ranked — urgent reads heavier than high, high heavier than normal.
20
+ - A designed queue-cleared state (celebratory or calm, but authored) distinct from a zero-results filter state.
21
+ - A designed degraded state when items fail to load, with a retry affordance.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: record-detail
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (attributes/lifecycle/history, verbs, standard pages chapters)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a record-detail surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - The record's human identity (name/title) and its lifecycle status both visible in the header without scrolling.
11
+ - A highlights band carrying the 3–7 most-referenced fields at the top of the page.
12
+ - The primary verbs for the record's current state rendered as visible buttons in the header — the top actions are not buried in an overflow menu.
13
+ - An activity or history timeline where every entry carries an actor and a timestamp.
14
+ - Related records surfaced (rail, tabs, or cards) with a count per relationship type.
15
+ - A tab strip or section navigation when content exceeds one screen, with the active section visibly marked.
16
+ - Every field value paired with a visible label — no orphan values the reader must guess at.
17
+ - Empty fields rendered as a designed "not set" affordance (muted dash or add prompt), never blank space.
18
+ - Editable fields showing an edit affordance on hover or focus.
19
+ - Timestamps rendered consistently, with relative age ("2h ago") where recency drives decisions.
20
+ - The status chip using the same color and label the collection view uses for that state.
21
+ - A breadcrumb or back affordance naming the collection this record came from.
@@ -0,0 +1,21 @@
1
+ ---
2
+ id: settings
3
+ class: e2
4
+ sourced: 2026-07-12
5
+ source: "derived from the D3 blueprint sweep + the b2b-ux-patterns distillation (settings chapter: scope → subject → risk)"
6
+ license: open
7
+ ---
8
+ Positive obligations for a settings surface — what every good instance has, each checkable from a rendered screen.
9
+
10
+ - The scope visibly labeled on every page: whether these settings apply to the person, the workspace, or the organization.
11
+ - A navigation surface (category nav, tab strip, or quick-find) with the active category visibly marked.
12
+ - Every setting carrying a label and a one-line description of its effect — the control alone never has to explain itself.
13
+ - Current values readable without entering an edit mode.
14
+ - Save semantics explicit: a save bar that enables on change, or per-control auto-save with a visible saved confirmation — one convention for the whole surface.
15
+ - Toggle and radio states distinguishable by more than color alone (position, label, or icon).
16
+ - Risky settings preceded by a consequence note ("Applies to all 34 members") before the control.
17
+ - Destructive actions isolated in a visually distinct danger zone, each gated by a confirmation that requires intent (typing the name, not just OK).
18
+ - Collection-type settings (API keys, webhooks, members, roles) rendered as a table with a labeled add action and per-row management.
19
+ - Secrets shown masked, with reveal and copy affordances.
20
+ - A quick-find search over settings when the category list exceeds one viewport.
21
+ - Settings the viewer cannot change shown disabled with a note naming who can — not silently hidden.
@@ -0,0 +1,68 @@
1
+ ---
2
+ id: board-column
3
+ class: d2
4
+ sourced: 2026-07-12
5
+ source: "spec authored from scratch — @nurix/components ships no board/kanban primitive; closest building blocks: Sortable (dnd-kit compound), Card, Badge, ScrollArea, Avatar, EmptyState — ~/dev/components"
6
+ license: open
7
+ ---
8
+
9
+ # Chrome recipe — board column
10
+
11
+ > **Library gap.** `@nurix/components` has no board/kanban component (verified 2026-07-12: no kanban/board export; the docs note the name collision with Kibo UI's kanban-style "List" as a warning, not a feature). This recipe is therefore a from-scratch specification in both switch modes; under `nurix` it composes the library's `Sortable` drag-and-drop compound with `Card`/`Badge`/`ScrollArea`. Flagged as a curation candidate for library admission.
12
+
13
+ One column of a kanban/work board: a workflow state rendered as a vertical lane of draggable cards with a counted header, an add affordance, and drop semantics. The board is a view-type projection of a queue — columns are states, cards are work items.
14
+
15
+ ## Anatomy
16
+
17
+ | Slot | Spec | nurix building block |
18
+ | --- | --- | --- |
19
+ | Column shell | Fixed width (280–320px), full board height, vertical flex; a quiet wash distinguishing the lane from the canvas and from its cards; rounded per the package radius scale. | `div` + tokens |
20
+ | Column header | Pinned: state dot or icon (the column's identity color), title, count badge (live: cards currently in the lane), optional WIP limit rendered as `count / limit`, trailing overflow menu (rename, set limit, collapse), optional collapse toggle. | `Badge`, `DropdownMenu` |
21
+ | Card list | The only scrolling region — each column scrolls independently; consistent card gap from the spacing scale. | `ScrollArea` + `SortableContent` (dnd-kit `SortableContext`, `orientation="vertical"`) |
22
+ | Card | The unit of drag: title (2-line clamp), meta row (assignee `Avatar`, due date, priority pill), optional label chips and a progress/checklist hint. Whole-card drag (`SortableItem asHandle`) or an explicit grip (`SortableItemHandle`) — with an explicit handle, the card body remains a plain click target for opening the record. | `Card` + `SortableItem` |
23
+ | Drop indicator | An insertion line (or ghost slot) at the projected index while a drag is over the column. | dnd-kit collision feedback |
24
+ | Drag overlay | The dragged card's floating preview, portaled above the board at overlay elevation, slightly scaled/tilted per the package's motion vocabulary; the origin card stays in place at reduced opacity. | `SortableOverlay` |
25
+ | Footer | "+ Add card" ghost affordance pinned under the list; activating it opens an inline title input at the column tail. | `Button variant="ghost"` |
26
+ | Empty slot | An empty column keeps a dashed placeholder slot so it remains an obvious drop target. | `EmptyState` (quiet) |
27
+
28
+ Board-level contract the column participates in: `Sortable` root (`DndContext`) owns `value`/`onValueChange` and `onMove({ activeIndex, overIndex })`; state changes commit through the consumer's data layer — the column never owns item data.
29
+
30
+ ## The eight states
31
+
32
+ | State | Spec | Token roles |
33
+ | --- | --- | --- |
34
+ | default | Lane on a low-alpha muted wash with a hairline edge; cards on the card surface with hairline borders; count badge quiet. | `muted` (wash), `card` + `card-foreground`, `border` |
35
+ | hover | A hovered card lifts one step on the package elevation ramp; the add affordance and card grips sharpen from rest. | elevation system, `accent` |
36
+ | focus | Focused card (or its handle) shows a focus-visible ring; the roving position is always visible. | `ring` |
37
+ | active | Mid-drag: origin card at ~40–50% opacity in place; overlay elevated above everything; the hovered target column's wash intensifies and the drop indicator renders in the primary role at the exact insertion index. | `primary` (indicator), `accent` (target wash) |
38
+ | disabled | WIP limit reached: the count reads `n / limit` in the warning role and the column rejects drops (indicator suppressed, "limit reached" hint). A locked/terminal column renders muted and non-droppable. | `warning`, reduced-alpha |
39
+ | loading | Header renders immediately with title; 2–3 skeleton cards hold the lane's shape; counts appear only when true. | `muted` |
40
+ | error / empty | Empty: the dashed drop slot plus a one-line hint — the lane never collapses to zero height. A failed move animates the card back to its origin and raises a toast; the board never shows a state the server rejected. | `muted-foreground`; `destructive` (failure toast) |
41
+ | success | A completed drop settles with a brief interruptible settle animation; both columns' counts update in the same frame. A card entering a terminal "done" column may flash its status chip on the success role. | `success` status role (transient) |
42
+
43
+ ## Keyboard behavior
44
+
45
+ Grounded in the shipped `Sortable`'s keyboard sensor and screen-reader announcements (grab / move / drop / cancel are announced):
46
+
47
+ - **Tab** reaches each card (or its handle) in column order, then the column's add affordance and menu. Every card is focusable — the library note that `SortableItem` dropped its `tabIndex` fallback means the spec requires `asHandle` or an explicit focusable handle on every card; a pointer-only board is a defect.
48
+ - **Enter / Space** on a focused card picks it up; **arrow up/down** moves it within the column; **arrow left/right** moves it to the adjacent column (same relative index, clamped); **Enter / Space** drops; **Escape** cancels and returns the card to its origin.
49
+ - Each move is announced to assistive tech ("moved to Review, position 2 of 5"); drop and cancel are announced likewise.
50
+ - **Enter** on the card body (when a separate handle exists) opens the record — typically in the side-panel recipe.
51
+ - The add affordance opens an inline input: **Enter** commits the new card, **Escape** dismisses.
52
+ - **cmdk path**: bulk and precise moves ("Move PROJ-142 to Done") belong in the command palette; the board's own keys cover local, one-card moves.
53
+
54
+ ## Token reach
55
+
56
+ - `muted` — the lane wash (the column is a *region*, not a card: it stays one step quieter than its cards); `card` / `card-foreground` — the cards; `border` — lane and card hairlines.
57
+ - `primary` — the drop indicator and the add affordance's hover emphasis; `ring` — focus; `accent` — hover fills and the active drop-target wash.
58
+ - **Column identity colors** (the state dot, an optional header tint) resolve from `chart-1..5` or the status roles — a board with per-column hex literals re-skins wrong on package switch and renders light-in-dark; this is the token-reach report's target on this component.
59
+ - Priority pills and label chips on cards consume status roles / `chart-1..5` exactly as in the data-table recipe — the same option object must render identically in both projections.
60
+ - `warning` — WIP-limit breach; `destructive` — failed-move feedback; `success` — transient completion.
61
+ - Overlay elevation comes from the package's shadow ramp (brand-tinted per the elevation doctrine), never an ad-hoc black shadow.
62
+
63
+ ## When to use / composition notes
64
+
65
+ A board is the right projection when workflow state is the primary axis the operator thinks in and moving items between states is a frequent, deliberate act — triage, pipeline stages, content review. It is a projection of the queue/browse archetype, never an archetype itself: the same items must remain reachable as a table, and the switch between projections belongs to the page, not the component. Keep visible cards per column modest (order of tens; virtualize beyond) and card content to what the move decision needs — title, owner, urgency; everything else lives one click away in the side panel. Columns are few and stable (a board with twelve columns is a table wearing a costume); WIP limits are the one piece of process the chrome itself should enforce visibly.
66
+
67
+ - **`primitives: nurix`** — composed (no single import; library gap flagged above): `import { Sortable, SortableContent, SortableItem, SortableItemHandle, SortableOverlay } from "@nurix/components/sortable"; import { Card } from "@nurix/components/card"; import { Badge } from "@nurix/components/badge"; import { ScrollArea } from "@nurix/components/scroll-area";` — `Sortable` supplies `value`/`onValueChange`, `orientation`, `onMove`, mouse/touch/keyboard sensors, and screen-reader announcements out of the box.
68
+ - **`primitives: native`** — this recipe is the full build spec: fixed-width independently-scrolling lanes, drag-and-drop with the complete keyboard path and live announcements above (the stack's own dnd library or an existing design-system board), optimistic moves with revert-on-failure, WIP-limit rejection, and all column/priority color resolved from the token artifact.
@@ -0,0 +1,63 @@
1
+ ---
2
+ id: data-table
3
+ class: d2
4
+ sourced: 2026-07-12
5
+ source: "@nurix/components Table + defineColumn (on the UiTable primitive layer, @tanstack/react-table engine) — ~/dev/components"
6
+ license: open
7
+ ---
8
+
9
+ # Chrome recipe — data table
10
+
11
+ The operator data table: column-definition-driven, read-only by default, with opt-in selection, sorting, pagination, density, borders, resize, and editable cells that write back through a single callback. Governing invariant: a zero-config `<Table data columns />` renders DOM equivalent to a hand-written semantic table — every feature is purely additive.
12
+
13
+ ## Anatomy
14
+
15
+ | Slot | Library part | Spec |
16
+ | --- | --- | --- |
17
+ | Shells | `LoadingShell` → `FooterShell` → `AutoHeightShell` | Opt-in wrappers composed around the bare table, gated on `tableConfig` flags (`loading`, `pagination`, `autoHeight`). |
18
+ | Header row | `ColumnHeader` | One cell per column; sortable columns (`display.sortable`, defaulted from type) render a sort dropdown when `tableConfig.sort` is on. `header: false` removes the row entirely. |
19
+ | Selection column | id `__select__` | Prepended when `tableConfig.rowSelection`: tri-state header checkbox (page-scoped, indeterminate) + per-row checkboxes; selection accumulates across pages and emits `onSelect(selectedIds)`. |
20
+ | Body rows | `UiTableRow` | Keyed by `row.id` (`TData extends { id: string }`); selected rows carry `data-state="selected"`. |
21
+ | Cells | 13 renderers | Dispatched on the column `component`: `text`, `number`, `boolean`, `date`, `date-range`, `select`, `multiselect`, `slider`, `rating`, `status`, `priority`, `assignee`, `sparkline`. Each has a **display** variant (default — static, no popovers) and an **editable** variant (`editable: true`); a custom `cell(row)` function wins over everything. |
22
+ | Column contract | `defineColumn({ slug, label, type, component?, editable?, hidden?, metadata?, display?, cell? })` | `type: "text" \| "number" \| "boolean" \| "date" \| "enum" \| "user"` drives the default component and sortability; enum-family options are `metadata.options: [{ value, label, color }]`; explicit `display.width` is honored independent of resize. |
23
+ | Pagination footer | `TablePagination` | Controlled `{ current, size, total, onChange }`, 1-indexed; page numbers collapse with ellipses past seven pages. Sorting and pagination are always external — the table never owns that state. |
24
+ | Config | `tableConfig` | `preset: "classic"` (comfortable density + pagination + full borders + muted header wash), `density: "compact" \| "comfortable" \| "spacious"`, `columnBorders`, `tableBorders`, `resize` (drag handles, 50px floor). |
25
+ | Write-back | `onCellChange({ rowId, columnId, slug, value })` | Fires only from editable cells at each widget's natural commit; the table never mutates `data`. |
26
+
27
+ ## The eight states
28
+
29
+ | State | Spec | Token roles |
30
+ | --- | --- | --- |
31
+ | default | Rows on the canvas with hairline row separators; header optionally on a low-alpha muted wash (classic preset); numerals tabular. | `background`/`card`, `border`, `muted` at low alpha, `foreground` |
32
+ | hover | Row takes a quiet muted wash; sort triggers and checkboxes reveal on hover where hidden at rest. | `muted` |
33
+ | focus | Focus-visible ring on each interactive control — checkboxes, sort triggers, editable widgets, pagination buttons. | `ring` |
34
+ | active | Selected rows fill via `data-state="selected"`; checked boxes fill with the primary role; an open editable cell shows its live widget with ring emphasis; the sorted column's header shows direction. | `muted` (row), `primary` (checkbox), `ring` |
35
+ | disabled | The default **is** read-only — display cells are static, not "disabled". Truly disabled controls (a locked toggle, a non-permitted action) render at ~50% opacity with no pointer events. | reduced-alpha foreground |
36
+ | loading | `loading: true` overlays a centered spinner while retaining rendered rows beneath (no layout collapse); a first load with no data renders skeleton rows at the configured density. | `muted` (skeleton), `muted-foreground` (spinner) |
37
+ | error / empty | Zero rows render an empty-state block in the body — message + optional action — never a bare void. Row-level degradation is expressed through status pills (e.g. a failed sync status) on status roles, and stale data through a caption, not through reddened rows. | `muted-foreground`; `destructive`/`warning` status roles |
38
+ | success | A committed edit re-renders through parent state immediately (single source of truth); positive statuses render as status-role pills. Transient save confirmation belongs to a toast, not the grid. | `success` status role |
39
+
40
+ ## Keyboard behavior
41
+
42
+ - **Tab** moves through interactive elements in DOM order: header checkbox → sort triggers → row checkboxes → editable widgets → pagination. Display cells are not focus stops.
43
+ - **Enter/Space** toggles checkboxes and opens a sort dropdown; inside the dropdown, arrows move, Enter applies, **Escape** closes to the trigger. Up to 3 simultaneously sorted columns share one direction, FIFO-evicted.
44
+ - **Editable commit semantics** (what fires `onCellChange`): text/number commit on **Enter or blur**, **Escape** reverts the uncommitted value; select/status/priority/assignee commit on selection; multiselect on popover close after a change; boolean on toggle; slider on release; rating on star activation; date on selection; date-range on full-range selection.
45
+ - **Enum-family cells** open a searchable listbox (the compound Select): type to filter, arrows to move, Enter to select, Escape to close — the cmdk interaction grammar applied per-cell.
46
+ - Pagination controls are plain buttons — Enter/Space activate; no custom arrow-key handling.
47
+
48
+ ## Token reach
49
+
50
+ - `background` / `card` — the table surface; `border` — row separators, opt-in column/table borders, resize handles.
51
+ - `foreground` / `muted-foreground` — cell text vs secondary text (dates, captions, empty state).
52
+ - `muted` — hover wash, selected-row fill, classic header wash, skeletons.
53
+ - `primary` — checkbox fills and the focused edit widget's emphasis; `ring` — focus.
54
+ - **Status/enum pills** — the `metadata.options` `color` field is specified as a token role (status roles or `chart-1..5`), never a hex literal; the pill resolves its tint from the role so package switches re-skin every pill. A table whose status column embeds literals renders wrong in the other theme while every other check stays green — this is the token-reach report's primary target.
55
+ - **Sparkline cells** — `metadata.sparklineColors` defaults must resolve to `chart-1..5`; a sparkline never carries a color literal.
56
+ - Destructive row actions use `destructive`. Numeric cells render with tabular numerals.
57
+
58
+ ## When to use / composition notes
59
+
60
+ The data table is the default projection for browse and queue archetypes — reach for it whenever rows are the unit of work and columns are attributes the operator scans, sorts, or edits in place. Real pagination and status chips are positive obligations for any believable table. Start read-only (the default) and make columns editable one at a time only where in-place editing is the actual workflow; keep sorting/pagination state in the page (the table is deliberately stateless about both) so URLs and refreshes preserve the operator's position. For bespoke markup the recipe's DOM contract is the semantic-table layer itself (`UiTable` under `nurix`), not a div grid.
61
+
62
+ - **`primitives: nurix`** — `import { Table, defineColumn } from "@nurix/components/table";` (escape hatches: cell renderers like `StatusPill` are exported from the same subpath; the bare primitive layer is `@nurix/components/ui-table`).
63
+ - **`primitives: native`** — this recipe is the build spec: a semantic `<table>` (never a div grid) with a sticky header, tabular numerals, externally controlled sort (max 3 columns) and 1-indexed pagination with ellipsis collapse, an opt-in checkbox selection column with a tri-state header, read-only-by-default cells with the commit/revert keyboard semantics above, and every status/spark color resolved from the token artifact.
@@ -0,0 +1,60 @@
1
+ ---
2
+ id: side-panel
3
+ class: d2
4
+ sourced: 2026-07-12
5
+ source: "@nurix/components Sheet (shadcn sheet on @radix-ui/react-dialog, extended with size variants + SheetBody) — ~/dev/components"
6
+ license: open
7
+ ---
8
+
9
+ # Chrome recipe — side panel
10
+
11
+ The slide-in detail/edit panel: a modal surface anchored to a screen edge with a fixed header → scrollable body → pinned footer skeleton. Built on dialog semantics (focus trap, Escape, overlay), so it inherits correct modality for free.
12
+
13
+ ## Anatomy
14
+
15
+ | Slot | Library part | Spec |
16
+ | --- | --- | --- |
17
+ | Root | `Sheet` | Open-state owner; controlled (`open`/`onOpenChange`) or uncontrolled via trigger. |
18
+ | Trigger | `SheetTrigger` | Any element (`asChild`) that opens the panel — a table row's action, a card, a button. |
19
+ | Overlay | `SheetOverlay` | Full-viewport scrim behind the panel; fades with open state; click closes. |
20
+ | Panel | `SheetContent { side: "right" (default) \| "left" \| "top" \| "bottom", size: "sm" 320px \| "md" 384px \| "default" 480px \| "lg" 640px \| "xl" 800px \| "full", showCloseButton?, showOverlay? }` | Fixed to the chosen edge, full-height (left/right), hairline border on the attached edge, elevated shadow, vertical flex column. Below the small breakpoint it takes ~full width regardless of size. |
21
+ | Header | `SheetHeader { showDivider? }` | Shrink-to-content top region: `SheetTitle` (the accessible name — a visually hidden fallback title exists, but a real one is the spec) + `SheetDescription` in muted text. |
22
+ | Body | `SheetBody { noPadding? }` | `flex-1` scroll region — the only part that scrolls; long content never pushes the footer off-screen. |
23
+ | Footer | `SheetFooter { showDivider? }` | Bottom-anchored action row (`mt-auto`): primary commit right, secondary/cancel beside it. |
24
+ | Close | `SheetClose` + built-in ✕ | Corner close button (top-right, 70% opacity at rest) plus any element wrapped in `SheetClose`. |
25
+
26
+ ## The eight states
27
+
28
+ | State | Spec | Token roles |
29
+ | --- | --- | --- |
30
+ | default | Open at rest: panel on the base surface over the scrim; header/body/footer stacked; hairline dividers where opted in. | `background`, `border`, `foreground`, `muted-foreground` (description) |
31
+ | hover | Corner close sharpens from 70% to full opacity; interior controls follow their own recipes. | control-level roles |
32
+ | focus | Focus is trapped inside the open panel; the close button and every control show a focus-visible ring. | `ring` |
33
+ | active | Open/closed is expressed as `data-state` driving the slide + fade transition. The library ships 500ms in / 300ms out; the A6 panel budget (200–280ms, interruptible) governs — the package motion base overrides the stock duration, and a non-interruptible slide is a bug, not a style. | — |
34
+ | disabled | The commit action disables (~50% opacity, no pointer events) while the form is invalid or a save is in flight; the panel itself never disables — Escape and close always work. | reduced-alpha on controls |
35
+ | loading | Record still resolving: header renders immediately with the known title, body shows skeleton blocks, footer actions disabled. The panel never opens empty-then-jumps. | `muted` (skeleton) |
36
+ | error / empty | Save failure: inline error summary at the top of the body plus per-field errors — the panel stays open, input preserved. A missing record renders an empty state in the body with a close affordance. | `destructive`, `muted-foreground` |
37
+ | success | A committed save closes the panel and confirmation lands as a toast in the parent context; a multi-step flow may show transient inline success on the footer action before advancing. | `success` status role |
38
+
39
+ ## Keyboard behavior
40
+
41
+ - Activating the trigger opens the panel; focus moves inside (first focusable element, else the close button).
42
+ - **Tab / Shift+Tab** cycle within the panel only — a full focus trap; background content is inert (`aria-modal="true"`, `role="dialog"`, labeled by the title).
43
+ - **Escape** closes and returns focus to the element that opened it. Overlay click does the same. If the body holds unsaved edits, close asks before discarding — Escape never silently destroys input.
44
+ - **Enter** in a single-field form commits; the footer's primary action is the default submit.
45
+ - **cmdk path**: a command-palette action that opens a record panel behaves exactly like a pointer trigger — the panel takes focus on open and restores it to the palette's invoking context on close.
46
+
47
+ ## Token reach
48
+
49
+ - `background` — the panel surface; `border` — the attached-edge hairline and the header/footer dividers.
50
+ - `foreground` / `muted-foreground` — title / description and secondary text.
51
+ - `ring` — the focus trap's visible rings, including the corner close.
52
+ - Scrim: the library hardcodes `black/50` — as a specification the scrim derives from a token (an overlay role, or `foreground` at low alpha) so dark themes don't double-darken; the token-reach report flags a literal scrim.
53
+ - Footer actions consume the button recipe's roles (`primary`/`primary-foreground`, `secondary`, `destructive`); inline errors consume `destructive`; skeletons consume `muted`.
54
+
55
+ ## When to use / composition notes
56
+
57
+ The side panel is edit-in-context: opening a record's detail or a scoped form beside a table, board, or list without losing the operator's position — the list stays visible under the scrim and scroll position survives the round trip. It is the wrong container for destructive confirmation (centered dialog), for navigation (sidebar), and for content that deserves its own URL (a full page — if operators share links to it, it's a page). Pick `size` by content: `sm`/`md` for quick property edits, `default`/`lg` for record detail, `xl` for side-by-side comparison; nested panels are a smell — a second level of depth means the flow wants a page. Footer actions: one primary commit, right-aligned; cancel is quiet, never a second primary.
58
+
59
+ - **`primitives: nurix`** — `import { Sheet, SheetTrigger, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetBody, SheetFooter, SheetClose } from "@nurix/components/sheet";`
60
+ - **`primitives: native`** — this recipe is the build spec: a portal-rendered fixed aside on the chosen edge with the size ramp above, dialog semantics (`role="dialog"`, `aria-modal`, labeled by the title), a real focus trap with focus restore, Escape + overlay close, a fixed-header / scrollable-body / pinned-footer column, and an interruptible slide within the panel motion budget — implemented with the incumbent stack's own dialog/drawer primitive.
@@ -0,0 +1,78 @@
1
+ ---
2
+ id: sidebar
3
+ class: d2
4
+ sourced: 2026-07-12
5
+ source: "@nurix/components Sidebar + opinionated layer (Brand, Switcher, ItemGroup, UserMenu, Callout, FileTree, SidebarCommandTrigger) — ~/dev/components"
6
+ license: open
7
+ ---
8
+
9
+ # Chrome recipe — sidebar
10
+
11
+ The complete app-nav sidebar: brand block, searchable sections, badged items, promo slot, user footer, icon-collapse rail. One import path (`@nurix/components/sidebar`) carries both the unstyled shell primitives and the opinionated content layer.
12
+
13
+ ## Anatomy
14
+
15
+ **Shell** (state + regions):
16
+
17
+ | Slot | Library part | Spec |
18
+ | --- | --- | --- |
19
+ | Provider | `SidebarProvider` | Owns open/collapsed state; persists it in a cookie (`sidebar_state`, 7 days); registers the global toggle shortcut. |
20
+ | Frame | `Sidebar` | `collapsible: "icon" \| "offcanvas" \| "none"`. Widths: 16rem expanded, 3rem icon rail, 18rem as a mobile drawer below the `md` breakpoint (mobile renders as an overlay sheet, not an inline column). |
21
+ | Header | `SidebarHeader` | Pinned top region — hosts the brand block or switcher, and the search trigger. |
22
+ | Content | `SidebarContent` | The scrollable middle — one or more item groups. |
23
+ | Footer | `SidebarFooter` | Pinned bottom region — promo slot and/or user footer. |
24
+ | Rail | `SidebarRail` | Thin edge hit-area that toggles collapse on click. |
25
+ | Inset | `SidebarInset` | The main-content wrapper beside the sidebar. |
26
+ | Trigger | `SidebarTrigger` | Icon button (lives in the topbar) toggling the same state. |
27
+
28
+ **Content layer** (each grounded in the shipped props):
29
+
30
+ - **Brand block** — `Brand { logo, name, caption?, href? }`: a 32px logo tile filled with `sidebar-primary` / `sidebar-primary-foreground`, name (medium weight) over an optional caption. Collapses to logo-only in icon mode.
31
+ - **Switcher** — `Switcher { render: "simple" | "rich", drop: "bottom" | "right", options, activeId, onSelect, addAction?, menuLabel? }`: header dropdown for team/workspace/version. Options carry `{ id, label, sublabel?, icon?, shortcut? }`; an optional add-action row sits under a separator.
32
+ - **Search trigger** — `SidebarCommandTrigger { placeholder, shortcut }`: a ⌘K search chip pinned to 32px height; in icon mode it swaps to a matched-height icon button with a tooltip, so the rail never shifts on collapse.
33
+ - **Sections** — `ItemGroup { label?, render: "list" | "tree" | "rich", collapsible?, defaultOpen?, showMore?, items, itemsCollapsible?, compact?, collapsedLabel: "hide" | "divider" }`. `list` = flat rows with optional inline collapsible submenu; `tree` = recursive chevron tree; `rich` = two-line rows (label + sublabel + trailing hint). `collapsedLabel: "divider"` keeps a 32px hairline footprint in icon mode so groups stay separated without rail shift. `compact` halves group padding and tightens item gap.
34
+ - **Item** — `{ id, label, icon?, badge?, state?, emoji?, avatar?, sublabel?, trailing?, isActive?, href?, onClick?, children? }`: one leading decoration (icon, emoji, or avatar), the label, and a trailing badge/state pill rendered outside the button (`SidebarMenuBadge`). `children` makes it a branch.
35
+ - **Promo slot** — `Callout { title, description?, action?, input?: { kind: "email" | "text", placeholder?, onSubmit? } }`: a bordered card on a low-alpha `sidebar-accent` wash with title, description, optional single input + full-width action button. Hidden entirely in icon mode.
36
+ - **User footer** — `UserMenu { user: { name, email, avatar? }, menuItems? }`: avatar (initials fallback) + name/email + up-down chevron; opens a dropdown (right of the rail on desktop, below on mobile) with an identity header and action items (`{ id, label, icon?, shortcut?, destructive? }`).
37
+
38
+ ## The eight states
39
+
40
+ | State | Spec | Token roles |
41
+ | --- | --- | --- |
42
+ | default | Rows at rest: transparent fill, quiet text, 16px icons. | `sidebar` (surface), `sidebar-foreground` |
43
+ | hover | Row fills; text sharpens. Group labels with collapse affordance show a pointer + chevron. | `sidebar-accent`, `sidebar-accent-foreground` |
44
+ | focus | Focus-visible ring on the focused row/control; same fill as hover. Never suppressed. | `sidebar-ring` |
45
+ | active | The current destination: persistent fill + medium weight, exposed via `data-active` / `aria-current`. Open branch parents show a rotated chevron; an open dropdown trigger holds the accent fill (`data-state="open"`). | `sidebar-accent`, `sidebar-accent-foreground` |
46
+ | disabled | ~50% opacity, no pointer events, removed from tab order; label still legible. | `sidebar-foreground` at reduced alpha |
47
+ | loading | `SidebarMenuSkeleton` rows — icon square + text bar shimmer — while nav data resolves; header and footer regions render immediately so the frame never jumps. | `muted` (skeleton), `sidebar-border` |
48
+ | error / empty | A group with nothing to show renders a one-line hint in muted text or is omitted; the sidebar itself carries no error surface — failures belong to content. Attention counts ride item badges. | `muted-foreground`; `destructive` on alert badges |
49
+ | success | No persistent success state; confirmation is expressed as badge-count change or a status-role pill on the relevant item. | status roles via badge |
50
+
51
+ ## Keyboard behavior
52
+
53
+ - **Cmd/Ctrl+B** toggles collapse globally (registered by `SidebarProvider`); `SidebarTrigger` and `SidebarRail` are the pointer equivalents.
54
+ - **Tab order**: header (brand/switcher → search trigger) → groups top-to-bottom, items in visual order → footer user menu. Items are real links or buttons — **Enter** activates, **Space** activates buttons.
55
+ - **Branches**: Enter/Space on a collapsible parent toggles it; the chevron rotation mirrors `data-state`.
56
+ - **Dropdowns** (Switcher, UserMenu): Enter/Space opens; arrow keys move through options; Enter selects; **Escape** closes and returns focus to the trigger.
57
+ - **cmdk path**: the search chip opens the command palette (⌘K); deep or infrequent destinations live in the palette — the sidebar carries the trigger, not a second search UI.
58
+ - **Icon mode**: focus order is unchanged; each item surfaces its label as a tooltip on focus/hover so keyboard users are never navigating unlabeled glyphs.
59
+
60
+ ## Token reach
61
+
62
+ The sidebar consumes the eight dedicated sidebar roles — the active package's emission must cover all eight in both themes:
63
+
64
+ - `sidebar` — the rail/panel surface (distinct from content `background`).
65
+ - `sidebar-foreground` — item and label text.
66
+ - `sidebar-primary` / `sidebar-primary-foreground` — the brand logo tile and any primary emphasis.
67
+ - `sidebar-accent` / `sidebar-accent-foreground` — hover, active, and open-menu fills.
68
+ - `sidebar-border` — hairlines: the panel edge, icon-mode group dividers.
69
+ - `sidebar-ring` — focus rings.
70
+
71
+ Secondary reach: the Callout uses `sidebar-border` + a low-alpha `sidebar-accent` wash + `muted-foreground`; dropdown menus render on `popover` / `popover-foreground`; destructive menu items use `destructive`; skeletons use `muted`. No color literal appears anywhere in the recipe — badge and state-pill colors resolve to status roles.
72
+
73
+ ## When to use / composition notes
74
+
75
+ The sidebar is the primary navigation for any operator shell with more than a handful of destinations; icon-collapse earns its place on dense screens where horizontal space is the scarce resource, and the cookie-persisted state means the user's choice survives reloads. Canonical composition: `Brand` **or** `Switcher` in the header (both only when the product truly has workspace switching), the search trigger under it, one to three `ItemGroup`s in the content (label them once there are two), and the footer stacking `Callout` (optional, promotional, dismissible by omission) above `UserMenu`. Icons on every item are a positive obligation — a bare, icon-less nav is a known judge complaint. Density: `compact` on data-heavy operator tools, default elsewhere.
76
+
77
+ - **`primitives: nurix`** — `import { SidebarProvider, Sidebar, SidebarHeader, SidebarContent, SidebarFooter, SidebarRail, SidebarInset, SidebarTrigger, Brand, Switcher, ItemGroup, UserMenu, Callout, SidebarCommandTrigger } from "@nurix/components/sidebar";`
78
+ - **`primitives: native`** — this recipe is the build spec: a fixed aside (256px expanded / 48px icon rail) with pinned header/footer and an independently scrolling middle, collapse state persisted (cookie or localStorage), a global Cmd/Ctrl+B toggle, an overlay drawer below 768px, tooltips on rail items, and the state/keyboard/token contracts above implemented with the incumbent stack's own nav primitives.