@nqlib/nqui 0.5.6 → 0.6.1

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 (76) hide show
  1. package/dist/{command-palette-DhoWGyk_.js → command-palette-CHUiGh5m.js} +2 -2
  2. package/dist/{command-palette-D24rOeE6.cjs → command-palette-DsvP2QNP.cjs} +2 -2
  3. package/dist/command.cjs.js +1 -1
  4. package/dist/command.es.js +1 -1
  5. package/dist/components/custom/table-of-contents.d.ts +2 -2
  6. package/dist/components/custom/table-of-contents.d.ts.map +1 -1
  7. package/dist/components/index.d.ts +3 -0
  8. package/dist/components/index.d.ts.map +1 -1
  9. package/dist/components/theme-appearance-menu.d.ts +9 -0
  10. package/dist/components/theme-appearance-menu.d.ts.map +1 -0
  11. package/dist/components/theme-toggle.d.ts +2 -0
  12. package/dist/components/theme-toggle.d.ts.map +1 -0
  13. package/dist/components/ui/checkbox.d.ts.map +1 -1
  14. package/dist/components/ui/combobox.d.ts +5 -3
  15. package/dist/components/ui/combobox.d.ts.map +1 -1
  16. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  17. package/dist/{debug-panel-BjfW-YVo.js → debug-panel-BcYzsTp2.js} +1 -1
  18. package/dist/{debug-panel-CpqsKuxd.cjs → debug-panel-mwtujy5J.cjs} +1 -1
  19. package/dist/debug.cjs.js +1 -1
  20. package/dist/debug.es.js +1 -1
  21. package/dist/elevation-debate.html +286 -0
  22. package/dist/{input-shared-CDgy_NdJ.cjs → input-shared-C9Try5fg.cjs} +1 -1
  23. package/dist/{input-shared-NnOiyHpu.js → input-shared-DXf3Edqt.js} +1 -1
  24. package/dist/lib/floating-surface.d.ts +6 -2
  25. package/dist/lib/floating-surface.d.ts.map +1 -1
  26. package/dist/nqui.cjs.js +15 -13
  27. package/dist/nqui.es.js +2752 -2646
  28. package/dist/styles.css +151 -255
  29. package/docs/components/README.md +4 -1
  30. package/docs/components/nqui-combobox.md +15 -2
  31. package/docs/components/nqui-command-palette.md +7 -0
  32. package/docs/components/nqui-command.md +41 -0
  33. package/docs/components/nqui-scroll-area.md +69 -0
  34. package/docs/nqui-skills/AGENT_PROMPT.md +190 -0
  35. package/docs/nqui-skills/COMPONENTS_INDEX.md +51 -1
  36. package/docs/nqui-skills/COMPOSITION.md +321 -0
  37. package/docs/nqui-skills/ELEVATION.md +181 -0
  38. package/docs/nqui-skills/EVAL.md +148 -0
  39. package/docs/nqui-skills/HUMAN_GUIDE.md +18 -0
  40. package/docs/nqui-skills/MIGRATION.md +133 -0
  41. package/docs/nqui-skills/MOTION.md +189 -0
  42. package/docs/nqui-skills/README.md +2 -0
  43. package/docs/nqui-skills/READ_BUDGET.md +60 -0
  44. package/docs/nqui-skills/RECIPES.md +820 -0
  45. package/docs/nqui-skills/SKILL.md +58 -1
  46. package/docs/nqui-skills/STATES.md +154 -0
  47. package/docs/nqui-skills/THEMING.md +203 -0
  48. package/docs/nqui-skills/WRITING.md +205 -0
  49. package/docs/nqui-skills/_claude-commands/README.md +50 -0
  50. package/docs/nqui-skills/_claude-commands/design/SKILL.md +111 -0
  51. package/docs/nqui-skills/_claude-commands/edit/SKILL.md +97 -0
  52. package/docs/nqui-skills/adapt/SKILL.md +5 -2
  53. package/docs/nqui-skills/animate/SKILL.md +5 -2
  54. package/docs/nqui-skills/audit/SKILL.md +5 -2
  55. package/docs/nqui-skills/bolder/SKILL.md +5 -2
  56. package/docs/nqui-skills/clarify/SKILL.md +5 -2
  57. package/docs/nqui-skills/colorize/SKILL.md +5 -2
  58. package/docs/nqui-skills/delight/SKILL.md +5 -4
  59. package/docs/nqui-skills/distill/SKILL.md +5 -2
  60. package/docs/nqui-skills/impeccable/SKILL.md +0 -16
  61. package/docs/nqui-skills/impeccable/reference/INDEX.md +26 -0
  62. package/docs/nqui-skills/layout/SKILL.md +5 -2
  63. package/docs/nqui-skills/nqui-components/SKILL.md +33 -9
  64. package/docs/nqui-skills/nqui-composition/SKILL.md +148 -0
  65. package/docs/nqui-skills/nqui-data-tables/SKILL.md +127 -0
  66. package/docs/nqui-skills/nqui-design-system/SKILL.md +22 -1
  67. package/docs/nqui-skills/nqui-install/SKILL.md +1 -0
  68. package/docs/nqui-skills/overdrive/SKILL.md +5 -2
  69. package/docs/nqui-skills/polish/SKILL.md +5 -4
  70. package/docs/nqui-skills/quieter/SKILL.md +5 -2
  71. package/docs/nqui-skills/shape/SKILL.md +5 -2
  72. package/docs/nqui-skills/typeset/SKILL.md +5 -2
  73. package/package.json +2 -1
  74. package/scripts/build-styles.js +4 -3
  75. package/scripts/cli.js +2 -0
  76. package/scripts/install-claude-skills.js +148 -0
package/dist/styles.css CHANGED
@@ -49,7 +49,7 @@
49
49
  @source inline("focus:bg-primary/80 focus:bg-secondary/80 focus:bg-destructive/80 focus:bg-success/80 focus:bg-warning/80 focus:bg-info/80 focus:border-primary/80 focus:border-secondary/80 focus:border-destructive/80 focus:border-success/80 focus:border-warning/80 focus:border-info/80 focus:border-border focus:outline-0 focus-visible:outline-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-destructive");
50
50
 
51
51
  /* Active state utilities */
52
- @source inline("active:bg-primary/75 active:bg-secondary/75 active:bg-destructive/75 active:bg-success/75 active:bg-warning/75 active:bg-info/75 active:border-primary/75 active:border-secondary/75 active:border-destructive/75 active:border-success/75 active:border-warning/75 active:border-info/75 active:border-border active:bg-none active:shadow-[inset_0_3px_5px_rgba(0,0,0,0.125)] active:scale-95");
52
+ @source inline("active:bg-primary/75 active:bg-secondary/75 active:bg-destructive/75 active:bg-success/75 active:bg-warning/75 active:bg-info/75 active:border-primary/75 active:border-secondary/75 active:border-destructive/75 active:border-success/75 active:border-warning/75 active:border-info/75 active:border-border active:bg-none active:shadow-[inset_0_3px_5px_rgb(0_0_0/0.125)] active:scale-95");
53
53
 
54
54
  /* Disabled state utilities */
55
55
  @source inline("disabled:bg-transparent disabled:shadow-none disabled:opacity-65 disabled:pointer-events-none");
@@ -57,6 +57,9 @@
57
57
  /* Interaction & Cursor utilities */
58
58
  @source inline("cursor-pointer select-none touch-manipulation opacity-90 overflow-hidden");
59
59
 
60
+ /* cmdk row selection (React 19 — aria-selected, not data-selected) */
61
+ @source inline("aria-selected:bg-accent aria-selected:text-accent-foreground data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground");
62
+
60
63
  /* Transition utilities */
61
64
  @source inline("transition-[color,background-color,border-color,box-shadow,opacity,transform] duration-150 ease-in-out");
62
65
 
@@ -66,13 +69,16 @@
66
69
  /* Group & State utilities */
67
70
  @source inline("group/badge has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 light:aria-invalid:ring-destructive/40 aria-invalid:border-destructive");
68
71
 
69
- /* Z-index elevation utilities */
70
- @source inline("z-[var(--z-debug)] z-[var(--z-sticky-page)] z-[var(--z-background)] z-[var(--z-content)] z-[var(--z-popover)] z-[var(--z-modal-backdrop)] z-[var(--z-modal)] z-[var(--z-tooltip)] z-[var(--z-sticky-content)] z-[var(--z-floating)]");
71
-
72
72
  /* Hit-area utilities (referenced from TSX / docs; @utility defines behavior) */
73
73
  @source inline("hit-area-4 hit-area-6 hit-area-debug");
74
74
 
75
-
75
+ /* Token system — split for clarity. Each file owns one concern.
76
+ * Loaded order matters: base tokens before utilities that may reference them. */
77
+ @import "./styles/colors.css"; /* palette + semantic color tokens */
78
+ @import "./styles/motion.css"; /* duration + easing tokens (MOTION.md) */
79
+ @import "./styles/shadows.css"; /* elevated-surface shadow tokens */
80
+ @import "./styles/z-index.css"; /* stacking only — not surface depth */
81
+ @import "./styles/hit-area.css"; /* expanded pointer targets */
76
82
 
77
83
  /* Custom dark mode variant - matches when .dark class is on element or ancestor */
78
84
  /* Non-dark theme — .light (warm paper) uses light: utilities */
@@ -252,6 +258,18 @@
252
258
  --color-card: var(--card);
253
259
  --color-foreground: var(--foreground);
254
260
  --color-background: var(--background);
261
+ /* ─── Radius scale ──────────────────────────────────────────────────
262
+ * Lives in @theme (not a separate file) because Tailwind v4 requires
263
+ * --radius-* tokens here to generate the `rounded-*` utilities.
264
+ * Base: --radius = 0.45rem (see merged theme variables).
265
+ *
266
+ * Usage convention:
267
+ * rounded-sm — kbd, small inline pills, dense controls
268
+ * rounded-md — inputs, buttons (default)
269
+ * rounded-lg — Cards, panels (default Card radius)
270
+ * rounded-xl — modals, sheets (heavier focus surfaces)
271
+ * rounded-2xl+ — marketing/decorative only; avoid in product UI
272
+ */
255
273
  --radius-sm: calc(var(--radius) - 4px);
256
274
  --radius-md: calc(var(--radius) - 2px);
257
275
  --radius-lg: var(--radius);
@@ -798,165 +816,6 @@
798
816
  ============================================ */
799
817
 
800
818
  :root {
801
- /* ============================================
802
- Z-Index Elevation Scale
803
- ============================================
804
-
805
- Z-Index Scale Reference Table:
806
- ┌─────────────────────┬──────┬─────────────────────────────────────────────┐
807
- │ Variable │ Value│ Use Case │
808
- ├─────────────────────┼──────┼─────────────────────────────────────────────┤
809
- │ --z-base │ 0 │ Base layer, default stacking │
810
- │ --z-background │ 0 │ Background decorative elements │
811
- │ --z-content │ 10 │ Standard content layer │
812
- │ --z-sticky-content │ 15 │ Sticky content within containers │
813
- │ │ │ (card headers, table headers) │
814
- │ --z-sticky-page │ 20 │ Page-level sticky elements │
815
- │ │ │ (page headers, navigation bars) │
816
- │ --z-floating │ 30 │ Floating panels, sidebars │
817
- │ --z-modal-backdrop │ 40 │ Modal backdrops/overlays │
818
- │ --z-modal │ 50 │ Modal content (dialogs, sheets) │
819
- │ --z-popover │ 60 │ Dropdowns, select menus, popovers │
820
- │ --z-tooltip │ 70 │ Tooltips (highest interactive layer) │
821
- │ --z-debug │ 9999 │ Debug tools (development only) │
822
- └─────────────────────┴──────┴─────────────────────────────────────────────┘
823
-
824
- Stacking Context Hierarchy (bottom to top):
825
- ┌─────────────────────────────────────────────────────────────────────────┐
826
- │ │
827
- │ ┌───────────────────────────────────────────────────────────────┐ │
828
- │ │ z-debug (9999) - Debug tools │ │
829
- │ └───────────────────────────────────────────────────────────────┘ │
830
- │ │
831
- │ ┌───────────────────────────────────────────────────────────────┐ │
832
- │ │ z-tooltip (70) - Tooltips │ │
833
- │ └───────────────────────────────────────────────────────────────┘ │
834
- │ │
835
- │ ┌───────────────────────────────────────────────────────────────┐ │
836
- │ │ z-popover (60) - Dropdowns, selects, popovers │ │
837
- │ └───────────────────────────────────────────────────────────────┘ │
838
- │ │
839
- │ ┌───────────────────────────────────────────────────────────────┐ │
840
- │ │ z-modal (50) - Modal content │ │
841
- │ └───────────────────────────────────────────────────────────────┘ │
842
- │ │
843
- │ ┌───────────────────────────────────────────────────────────────┐ │
844
- │ │ z-modal-backdrop (40) - Modal backdrops │ │
845
- │ └───────────────────────────────────────────────────────────────┘ │
846
- │ │
847
- │ ┌───────────────────────────────────────────────────────────────┐ │
848
- │ │ z-floating (30) - Sidebars, floating panels │ │
849
- │ └───────────────────────────────────────────────────────────────┘ │
850
- │ │
851
- │ ┌───────────────────────────────────────────────────────────────┐ │
852
- │ │ z-sticky-page (20) - Page headers, navigation │ │
853
- │ └───────────────────────────────────────────────────────────────┘ │
854
- │ │
855
- │ ┌───────────────────────────────────────────────────────────────┐ │
856
- │ │ z-sticky-content (15) - Card headers, table headers │ │
857
- │ └───────────────────────────────────────────────────────────────┘ │
858
- │ │
859
- │ ┌───────────────────────────────────────────────────────────────┐ │
860
- │ │ z-content (10) - Standard content │ │
861
- │ └───────────────────────────────────────────────────────────────┘ │
862
- │ │
863
- │ ┌───────────────────────────────────────────────────────────────┐ │
864
- │ │ z-base / z-background (0) - Base layer, backgrounds │ │
865
- │ └───────────────────────────────────────────────────────────────┘ │
866
- │ │
867
- └─────────────────────────────────────────────────────────────────────────┘
868
-
869
- Component Mapping Table (Before Refactoring):
870
- ┌─────────────────────────────────────┬──────────┬──────────────────────────┐
871
- │ Component │ Old Value│ New Variable │
872
- ├─────────────────────────────────────┼──────────┼──────────────────────────┤
873
- │ Card sticky header │ z-20 │ --z-sticky-content (15) │
874
- │ Page header (AppLayout) │ z-10 │ --z-sticky-page (20) │
875
- │ Sidebar │ z-10 │ --z-floating (30) │
876
- │ Sidebar handle │ z-20 │ --z-sticky-page (20) │
877
- │ Dialog overlay │ z-50 │ --z-modal-backdrop (40) │
878
- │ Dialog content │ z-50 │ --z-modal (50) │
879
- │ Sheet content │ z-50 │ --z-modal (50) │
880
- │ Dropdown menu │ z-50 │ --z-popover (60) │
881
- │ Select dropdown │ z-50 │ --z-popover (60) │
882
- │ Popover │ z-50 │ --z-popover (60) │
883
- │ Tooltip │ z-50 │ --z-tooltip (70) │
884
- │ Combobox │ z-50 │ --z-popover (60) │
885
- │ Enhanced select │ z-50 │ --z-popover (60) │
886
- │ Separator decorations │ z-index:1│ --z-content (10) │
887
- │ Frosted glass backgrounds │ z-0 │ --z-background (0) │
888
- │ Card content layer │ z-10 │ --z-content (10) │
889
- │ Debug panel │ z-[9997] │ --z-debug (9999) │
890
- │ Color picker │ z-[9999] │ --z-popover (60) │
891
- └─────────────────────────────────────┴──────────┴──────────────────────────┘
892
-
893
- Key Relationships:
894
- - Card sticky headers (15) < Page headers (20) - Prevents scroll conflicts
895
- - Sticky content (15) < Sticky page (20) - Ensures page nav stays on top
896
- - Floating panels (30) > Page headers (20) - Sidebars overlay content
897
- - Modals (50) > Floating (30) - Modals overlay everything
898
- - Popovers (60) > Modals (50) - Dropdowns can appear in modals
899
- - Tooltips (70) > Popovers (60) - Tooltips are highest interactive layer
900
- */
901
-
902
- /* Base layer - default stacking context */
903
- --z-base: 0;
904
-
905
- /* Background layer - decorative elements behind content */
906
- --z-background: 0;
907
-
908
- /* Content layer - standard content elements */
909
- --z-content: 10;
910
-
911
- /* Sticky content layer - sticky elements within containers
912
- * Used for: card headers, table headers, section headers
913
- * Must be below page-level sticky elements to prevent conflicts
914
- */
915
- --z-sticky-content: 15;
916
-
917
- /* Sticky page layer - page-level sticky elements
918
- * Used for: page headers, navigation bars, top bars
919
- * Must be above sticky-content to ensure page navigation works
920
- */
921
- --z-sticky-page: 20;
922
-
923
- /* Floating layer - floating panels and sidebars
924
- * Used for: sidebars, floating panels, slide-out menus
925
- * Positioned above page content but below modals
926
- */
927
- --z-floating: 30;
928
-
929
- /* Modal backdrop layer - modal overlays and backdrops
930
- * Used for: dialog overlays, sheet backdrops
931
- * Positioned below modal content but above floating panels
932
- */
933
- --z-modal-backdrop: 40;
934
-
935
- /* Modal layer - modal content
936
- * Used for: dialog content, sheet content, alert dialogs
937
- * Positioned above backdrops but below popovers
938
- */
939
- --z-modal: 50;
940
-
941
- /* Popover layer - dropdowns and popovers
942
- * Used for: dropdown menus, select dropdowns, popovers, comboboxes
943
- * Positioned above modals to allow dropdowns in modal contexts
944
- */
945
- --z-popover: 60;
946
-
947
- /* Tooltip layer - tooltips (highest interactive layer)
948
- * Used for: tooltips, hover cards
949
- * Highest interactive layer to ensure tooltips appear above all UI
950
- */
951
- --z-tooltip: 9998;
952
-
953
- /* Debug layer - debug tools (development only)
954
- * Used for: debug panels, debug overlays, development tools
955
- * Extremely high value to ensure debug tools are always visible
956
- */
957
- --z-debug: 9999;
958
-
959
- /* Color system variables from colors.css */
960
819
  /* Primary scale — blue hue 240; toned down vs prior (lower L / slightly less chroma on saturated stops) */
961
820
  --primary-100: oklch(0.655 0.11 240);
962
821
  --primary-200: oklch(0.655 0.135 240);
@@ -969,21 +828,24 @@
969
828
  Semantic Color Scales — classic light (success / warning / danger / info)
970
829
  ============================================ */
971
830
 
972
- /* Success Color Scale (Light Mode) - Green (Hue 142) */
973
- --success-100: oklch(0.95 0.08 142);
974
- --success-200: oklch(0.90 0.10 142);
975
- --success-300: oklch(0.75 0.12 142);
976
- --success-400: oklch(0.60 0.14 142);
977
- --success-500: oklch(0.50 0.15 142);
978
- --success-600: oklch(0.40 0.18 142);
979
-
980
- /* Warning Color Scale (Light Mode) - Orange (Hue 65) */
981
- --warning-100: oklch(0.95 0.08 65);
982
- --warning-200: oklch(0.90 0.10 65);
983
- --warning-300: oklch(0.85 0.12 65);
984
- --warning-400: oklch(0.75 0.14 65);
985
- --warning-500: oklch(0.70 0.15 65);
986
- --warning-600: oklch(0.60 0.18 65);
831
+ /* Success Color Scale (Light Mode) - Green (Hue 135)
832
+ Was 142 (cool emerald), shifted to 135 — slightly warmer to harmonize
833
+ with the warm-paper background (hue 95). */
834
+ --success-100: oklch(0.95 0.08 135);
835
+ --success-200: oklch(0.90 0.10 135);
836
+ --success-300: oklch(0.75 0.12 135);
837
+ --success-400: oklch(0.60 0.14 135);
838
+ --success-500: oklch(0.50 0.15 135);
839
+ --success-600: oklch(0.40 0.18 135);
840
+
841
+ /* Warning Color Scale (Light Mode) - Amber (Hue 80)
842
+ Was hue 65 which is olive/khaki in OKLCH, not orange — fixed to true amber. */
843
+ --warning-100: oklch(0.95 0.08 80);
844
+ --warning-200: oklch(0.90 0.10 80);
845
+ --warning-300: oklch(0.85 0.12 80);
846
+ --warning-400: oklch(0.75 0.14 80);
847
+ --warning-500: oklch(0.70 0.15 80);
848
+ --warning-600: oklch(0.60 0.18 80);
987
849
 
988
850
  /* Destructive Color Scale (Light Mode) - Red (Hue 25) */
989
851
  --danger-100: oklch(0.95 0.08 25);
@@ -1023,42 +885,73 @@
1023
885
  --info-foreground: oklch(0.98 0 0);
1024
886
 
1025
887
  /* Additional variables from index.css */
1026
- /* Light / system UI — Claude-adjacent warm paper (#FAF9F5 ≈ oklch(0.982 0.0054 95)) */
888
+ /* ============================================
889
+ Light / system UI — Claude-adjacent warm paper
890
+ (#FAF9F5 ≈ oklch(0.982 0.0054 95))
891
+
892
+ Surface model (per ELEVATION.md — the 2+1 rule):
893
+ --surface-a = --background (page, the "outer" surface)
894
+ --surface-b = --muted (card/panel, the "inner" surface)
895
+ --surface-elevated = --popover (modals, sheets, popovers, dropdowns)
896
+ Cap inline nesting at 2 surfaces (A then B). Past that, use spacing
897
+ and uppercase labels, NOT a third shade.
898
+ ============================================ */
899
+
1027
900
  --background: oklch(0.982 0.0054 95);
1028
901
  --foreground: oklch(0.2416 0.0219 57);
1029
- /* Surfaces: stepped darker than page bg for readable elevation */
1030
- --card: oklch(0.966 0.0054 95);
902
+
903
+ /* Card === popover by value. Aliased so the relationship is honest.
904
+ Visual elevation for popover comes from .nqui-elevated (shadow), not color. */
905
+ --card: oklch(0.993 0.003 95);
1031
906
  --card-foreground: oklch(0.2416 0.0219 57);
1032
- --popover: oklch(0.966 0.0054 95);
1033
- --popover-foreground: oklch(0.2416 0.0219 57);
1034
- --secondary: oklch(0.928 0.008 95);
907
+ --popover: var(--card);
908
+ --popover-foreground: var(--card-foreground);
909
+
910
+ /* Secondary — softer interactive surface (secondary button, badge bg).
911
+ Lighter than muted so the two read as distinct roles. */
912
+ --secondary: oklch(0.950 0.006 95);
1035
913
  --secondary-foreground: oklch(0.3067 0.0309 56.81);
914
+
915
+ /* Muted — surface B in the 2+1 rule. Used as the inner panel color. */
1036
916
  --muted: oklch(0.914 0.007 95);
1037
917
  --muted-foreground: oklch(0.5576 0.0222 57.81);
1038
- /* Slightly deeper than sidebar/card so row hovers read on pale paper */
1039
- --accent: oklch(0.932 0.007 95);
918
+
919
+ /* Accent — hover/selection state. Must be distinct from BOTH muted (0.914)
920
+ AND border (0.892). Bumped from 0.895 to 0.880 for clear edge separation. */
921
+ --accent: oklch(0.880 0.008 95);
1040
922
  --accent-foreground: oklch(0.2416 0.0219 57);
923
+
1041
924
  --border: oklch(0.892 0.006 95);
1042
925
  --input: oklch(0.892 0.006 95);
1043
926
 
1044
- /* Chart colors */
1045
- --chart-1: oklch(0.809 0.105 251.813);
1046
- --chart-2: oklch(0.623 0.214 259.815);
1047
- --chart-3: oklch(0.546 0.245 262.881);
1048
- --chart-4: oklch(0.488 0.243 264.376);
1049
- --chart-5: oklch(0.424 0.199 265.638);
927
+ /* ─── Semantic surface aliases (the 2+1 model) ──────────────────────── */
928
+ --surface-a: var(--background);
929
+ --surface-b: var(--muted);
930
+ --surface-elevated: var(--popover);
931
+
932
+ /* Chart colors — CATEGORICAL palette. Distinct hues at matched lightness
933
+ so multi-series charts are actually readable. For SEQUENTIAL (ordinal)
934
+ data use shades of --primary instead. */
935
+ --chart-1: oklch(0.605 0.215 240); /* blue (primary) */
936
+ --chart-2: oklch(0.680 0.180 35); /* orange */
937
+ --chart-3: oklch(0.620 0.165 150); /* green */
938
+ --chart-4: oklch(0.580 0.220 295); /* purple */
939
+ --chart-5: oklch(0.760 0.155 80); /* amber */
1050
940
 
1051
941
  /* Layout */
1052
942
  --radius: 0.45rem;
1053
943
 
1054
- /* Sidebar — darker than page so rail + row hovers read clearly */
1055
- --sidebar: oklch(0.953 0.006 95);
944
+ /* Sidebar — slightly LIGHTER than page (lifts forward, matches dark mode
945
+ direction). Was 0.953 (darker than page) which inverted the convention
946
+ used by macOS / Linear / Vercel. */
947
+ --sidebar: oklch(0.988 0.004 95);
1056
948
  --sidebar-foreground: oklch(0.2416 0.0219 57);
1057
949
  --sidebar-primary: var(--primary);
1058
950
  --sidebar-primary-foreground: var(--primary-foreground);
1059
- --sidebar-accent: oklch(0.904 0.009 95);
951
+ /* Sidebar-accent (hover) needs to be visible against the now-lighter sidebar */
952
+ --sidebar-accent: oklch(0.940 0.007 95);
1060
953
  --sidebar-accent-foreground: oklch(0.205 0.015 55);
1061
- --sidebar-border: oklch(0.878 0.007 95);
954
+ --sidebar-border: oklch(0.920 0.006 95);
1062
955
  --sidebar-ring: var(--ring);
1063
956
  }
1064
957
 
@@ -1081,21 +974,22 @@
1081
974
  Semantic Color Scales - Dark Mode
1082
975
  ============================================ */
1083
976
 
1084
- /* Success Color Scale (Dark Mode) - Green (Hue 142) */
1085
- --success-100: oklch(0.40 0.15 142);
1086
- --success-200: oklch(0.45 0.18 142);
1087
- --success-300: oklch(0.50 0.20 142);
1088
- --success-400: oklch(0.55 0.22 142);
1089
- --success-500: oklch(0.65 0.20 142);
1090
- --success-600: oklch(0.70 0.22 142);
1091
-
1092
- /* Warning Color Scale (Dark Mode) - Orange (Hue 65) */
1093
- --warning-100: oklch(0.50 0.15 65);
1094
- --warning-200: oklch(0.55 0.18 65);
1095
- --warning-300: oklch(0.60 0.20 65);
1096
- --warning-400: oklch(0.65 0.22 65);
1097
- --warning-500: oklch(0.75 0.15 65);
1098
- --warning-600: oklch(0.80 0.18 65);
977
+ /* Success Color Scale (Dark Mode) - Green (Hue 135 — matches light) */
978
+ --success-100: oklch(0.40 0.15 135);
979
+ --success-200: oklch(0.45 0.18 135);
980
+ --success-300: oklch(0.50 0.20 135);
981
+ --success-400: oklch(0.55 0.22 135);
982
+ --success-500: oklch(0.65 0.20 135);
983
+ --success-600: oklch(0.70 0.22 135);
984
+
985
+ /* Warning Color Scale (Dark Mode) - Amber (Hue 80)
986
+ Was hue 65 which is olive/khaki in OKLCH, not orange — fixed to true amber. */
987
+ --warning-100: oklch(0.50 0.15 80);
988
+ --warning-200: oklch(0.55 0.18 80);
989
+ --warning-300: oklch(0.60 0.20 80);
990
+ --warning-400: oklch(0.65 0.22 80);
991
+ --warning-500: oklch(0.75 0.15 80);
992
+ --warning-600: oklch(0.80 0.18 80);
1099
993
 
1100
994
  /* Destructive Color Scale (Dark Mode) - Red (Hue 25) */
1101
995
  --danger-100: oklch(0.40 0.15 25);
@@ -1117,77 +1011,79 @@
1117
1011
  System Color Mappings - Dark Mode
1118
1012
  ============================================ */
1119
1013
 
1120
- /* Primary Colors - Mapped to color scales */
1014
+ /* Primary Colors - Mapped to color scales.
1015
+ Foregrounds aligned with global --foreground (0.92) for eye-strain
1016
+ consistency. Was 0.98 (harsh on dark backgrounds). */
1121
1017
  --primary: var(--primary-500);
1122
- --primary-foreground: oklch(0.98 0 0); /* Light text for contrast */
1018
+ --primary-foreground: oklch(0.92 0 0);
1123
1019
  --primary-hover: var(--primary-400);
1124
- --ring: var(--primary-500); /* Focus ring uses primary color */
1020
+ --ring: var(--primary-500);
1125
1021
 
1126
1022
  /* Semantic Colors - Mapped to color scales */
1127
1023
  --success: var(--success-500);
1128
- --success-foreground: oklch(0.98 0 0);
1024
+ --success-foreground: oklch(0.92 0 0);
1129
1025
 
1130
1026
  --warning: var(--warning-500);
1131
- --warning-foreground: oklch(0.985 0 0);
1027
+ --warning-foreground: oklch(0.92 0 0);
1132
1028
 
1133
1029
  --destructive: var(--danger-500);
1134
- --destructive-foreground: oklch(0.98 0 0);
1030
+ --destructive-foreground: oklch(0.92 0 0);
1135
1031
 
1136
1032
  --info: var(--info-500);
1137
- --info-foreground: oklch(0.98 0 0);
1033
+ --info-foreground: oklch(0.92 0 0);
1138
1034
 
1139
1035
  /* Additional variables from index.css */
1140
1036
  /* System UI colors for dark mode (unique to index.css)
1141
- Softened foreground (oklch 0.92 ≈ #e6e6e6) for reduced eye strain vs near-pure white */
1037
+ Softened foreground (oklch 0.92 ≈ #e6e6e6) for reduced eye strain vs near-pure white.
1038
+ Surface model — see ELEVATION.md (the 2+1 rule). */
1142
1039
  --background: oklch(0.16 0 0);
1143
1040
  --foreground: oklch(0.92 0 0);
1041
+
1042
+ /* Card === popover by value (aliased — visual lift via .nqui-elevated shadow) */
1144
1043
  --card: oklch(0.205 0 0);
1145
1044
  --card-foreground: oklch(0.92 0 0);
1146
- --popover: oklch(0.205 0 0);
1147
- --popover-foreground: oklch(0.92 0 0);
1148
- --secondary: oklch(0.274 0.003 0);
1045
+ --popover: var(--card);
1046
+ --popover-foreground: var(--card-foreground);
1047
+
1048
+ /* Secondary — softer interactive surface. Lighter than muted so the two
1049
+ read as distinct roles (was 0.274, too close to muted 0.24). */
1050
+ --secondary: oklch(0.30 0.003 0);
1149
1051
  --secondary-foreground: oklch(0.92 0 0);
1052
+
1053
+ /* Muted — surface B in the 2+1 rule */
1150
1054
  --muted: oklch(0.24 0.002 0);
1151
1055
  --muted-foreground: oklch(0.708 0 0);
1152
- --accent: oklch(0.27 0.003 0);
1056
+
1057
+ /* Accent — hover/selection. More prominent than muted AND distinct from border. */
1058
+ --accent: oklch(0.32 0.003 0);
1153
1059
  --accent-foreground: oklch(0.92 0 0);
1154
- --border: oklch(0.34 0.004 0);
1155
- --input: oklch(0.30 0.003 0);
1156
1060
 
1157
- /* Chart colors (same for both modes) */
1158
- --chart-1: oklch(0.809 0.105 251.813);
1159
- --chart-2: oklch(0.623 0.214 259.815);
1160
- --chart-3: oklch(0.546 0.245 262.881);
1161
- --chart-4: oklch(0.488 0.243 264.376);
1162
- --chart-5: oklch(0.424 0.199 265.638);
1061
+ /* Border softened from 0.34 to 0.27 so edges read as a "fold" rather than
1062
+ a drawn line. Closer to Linear / Vercel dark-mode convention. */
1063
+ --border: oklch(0.27 0.004 0);
1064
+ --input: oklch(0.30 0.003 0);
1163
1065
 
1164
- /* Sidebar for dark mode */
1066
+ /* ─── Semantic surface aliases (the 2+1 model) ──────────────────────── */
1067
+ --surface-a: var(--background);
1068
+ --surface-b: var(--muted);
1069
+ --surface-elevated: var(--popover);
1070
+
1071
+ /* Chart colors — CATEGORICAL palette (matches light mode hues, brighter L
1072
+ for dark-mode legibility). For SEQUENTIAL data use shades of --primary. */
1073
+ --chart-1: oklch(0.700 0.180 240); /* blue */
1074
+ --chart-2: oklch(0.740 0.160 35); /* orange */
1075
+ --chart-3: oklch(0.700 0.150 150); /* green */
1076
+ --chart-4: oklch(0.680 0.190 295); /* purple */
1077
+ --chart-5: oklch(0.820 0.140 80); /* amber */
1078
+
1079
+ /* Sidebar — slightly lighter than page (lifts forward). Matches existing
1080
+ direction; light mode now matches this convention too. */
1165
1081
  --sidebar: oklch(0.205 0.001 0);
1166
1082
  --sidebar-foreground: oklch(0.92 0 0);
1167
1083
  --sidebar-primary: var(--primary);
1168
1084
  --sidebar-primary-foreground: var(--primary-foreground);
1169
1085
  --sidebar-accent: oklch(0.269 0.003 0);
1170
1086
  --sidebar-accent-foreground: oklch(0.92 0 0);
1171
- --sidebar-border: oklch(0.34 0.004 0);
1087
+ --sidebar-border: oklch(0.27 0.004 0);
1172
1088
  --sidebar-ring: oklch(0.556 0 0);
1173
- }
1174
-
1175
- /* Elevation component styles from elevation.css */
1176
- /**
1177
- * Card surface elevation — semantic --border + light shadow stack.
1178
- * Dark mode matches v0.4.x (no inset / multi-stack drop shadows).
1179
- * Lives here with the elevation system (was JS-injected from card.tsx).
1180
- */
1181
- .nqui-card {
1182
- border: 1px solid color-mix(in oklch, var(--border) 50%, transparent);
1183
- box-shadow:
1184
- 0 1px 0 0 color-mix(in oklch, var(--border) 40%, transparent),
1185
- 0 1px 2px 0 oklch(0.15 0 0 / 0.05);
1186
- }
1187
-
1188
- .dark .nqui-card {
1189
- border: 1px solid color-mix(in oklch, var(--border) 50%, transparent);
1190
- box-shadow:
1191
- 0 1px 0 0 color-mix(in oklch, var(--border) 40%, transparent),
1192
- 0 1px 2px 0 oklch(0 0 0 / 0.3);
1193
- }
1089
+ }
@@ -14,7 +14,8 @@ Implementation guides for each component. **AI Skill:** Optimized for AI/LLM con
14
14
 
15
15
  ## Start here (humans)
16
16
 
17
- 1. **Know your task?** Open **`docs/nqui-skills/HUMAN_GUIDE.md`** (in the package) or **`node_modules/@nqlib/nqui/docs/nqui-skills/HUMAN_GUIDE.md`** after install maps *forms, toolbar, dashboard, empty/loading, …*which doc to open first.
17
+ 1. **Building a screen (not looking up one prop)?** Read **`docs/nqui-skills/COMPOSITION.md`** and run the dev app **Recipes** hub (`npm run dev` `/`).
18
+ 2. **Know your task?** Open **`docs/nqui-skills/HUMAN_GUIDE.md`** (in the package) or **`node_modules/@nqlib/nqui/docs/nqui-skills/HUMAN_GUIDE.md`** after install — maps *forms, toolbar, dashboard, empty/loading, …* → which doc to open first.
18
19
  2. **Pick one component** → **`nqui-<kebab-case>.md`** in this folder (e.g. `nqui-combobox.md`). Don’t load every file.
19
20
  3. **Need “which component?” tables** → scroll to **When to Use (Selection & Action Components)** and **Shared Conventions** below; skip **Prerequisites** until you wire build/CSS.
20
21
  4. **Deep layout / scroll / sticky** → **Layout & Scroll Patterns** (implementation-heavy; skip if you’re only choosing a component).
@@ -351,6 +352,8 @@ Use these rules to choose the right component. **Selection** = user picks from o
351
352
  | CommandPalette | [nqui-command-palette.md](./nqui-command-palette.md) | Full Cmd+K palette. |
352
353
  | TableOfContents | [nqui-table-of-contents.md](./nqui-table-of-contents.md) | Doc section links from headings. |
353
354
 
355
+ **Cmd+K / cmdk row highlight (React 19):** Fixed in **nqui ≥ 0.6.1** (`aria-selected:bg-accent` in `floatingListItemInteractive`). If every row still looks selected on an older version, see [nqui-command-palette.md](./nqui-command-palette.md).
356
+
354
357
  ---
355
358
 
356
359
  ## Overlays – When to Use
@@ -130,16 +130,29 @@ When `**showPanelSearch**` is false, the panel `**CommandInput**` is wrapped in
130
130
  ## cmdk constraints
131
131
 
132
132
  - **List `id`:** cmdk **overwrites** the `id` on `Command.List`. Do not assume `useId()` matches the DOM — the combobox mirrors the mounted list element’s id into context for `**aria-controls`**.
133
- - **Selection styling:** Prefer `**aria-selected`** / `**data-selected**` (boolean) utilities. Patterns like `**data-[selected=true]:**` can fail because the attribute is not always the string `"true"`.
134
133
  - **Panel input:** Keep the cmdk input **mounted** when filtering (see `**sr-only`** branch above).
135
134
 
135
+ ### Row selection styling (React 19 + cmdk)
136
+
137
+ cmdk sets `data-selected` / `aria-selected` on **every** row. **React 19** renders booleans as strings (`data-selected="false"`, `aria-selected="false"`), not absent attributes.
138
+
139
+ | Tailwind utility | Compiled selector | Safe with React 19? |
140
+ | ---------------- | ----------------- | ------------------- |
141
+ | `data-selected:bg-accent` | `[data-selected]` | **No** — matches `"false"` too → all rows highlighted |
142
+ | `data-[selected=true]:bg-accent` | `[data-selected=true]` | Yes — selected row only |
143
+ | `data-[selected=false]:bg-transparent` | `[data-selected=false]` | Yes — reset unselected rows when overriding CommandItem |
144
+ | `aria-selected:bg-accent` | `[aria-selected=true]` | **Yes** — preferred (used by `ComboboxItem` in source) |
145
+
146
+ nqui **ComboboxItem** and **CommandItem** (≥ 0.6.1) use `aria-selected:bg-accent` via `floatingListItemInteractive`.
147
+
136
148
  ## Troubleshooting
137
149
 
138
150
 
139
151
  | Symptom | What to check |
140
152
  | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
141
153
  | Trigger `**aria-controls**` missing or wrong | `**ComboboxList**` must mount while the popover is open so the list ref can read `**id**`. |
142
- | Row highlight / keyboard selection looks wrong | Styles targeting only `**data-[selected=true]**`; use `**aria-selected:**` or boolean `**data-selected**` variants. |
154
+ | **Every row** has muted/accent background (looks all selected) | DevTools: unselected rows have `data-selected="false"`. Bare `data-selected:` / `[data-selected]` CSS matches them. Use `aria-selected:bg-accent` or `data-[selected=true]:` + `data-[selected=false]:bg-transparent`. See `nqui-command.md`. |
155
+ | Row highlight / keyboard selection looks wrong | Not only `data-[selected=true]` — with React 19, also avoid `data-selected:bg-accent`. Prefer `aria-selected:bg-accent`. |
143
156
  | **Mouse hover / click on rows does nothing; keyboard works** | Row styles must not use a broad `**data-[disabled]:pointer-events-none`** (can match any `data-disabled` value). Use `**aria-disabled:**` (or `**data-[disabled=true]:**`) so only disabled items drop pointer events. Hidden panel search is wrapped with `**sr-only**` + `**pointer-events-none**`; the cmdk `**CommandInput**` keeps `**pointer-events-auto**`. |
144
157
  | Filter feels out of sync | Avoid hiding the panel `**CommandInput**` with `**display: none**`. |
145
158
 
@@ -23,7 +23,14 @@ import { CommandPalette } from "@nqlib/nqui"
23
23
  <CommandPalette shortcutEnabled={false} ... />
24
24
  ```
25
25
 
26
+ ## Row highlight (Cmd+K list)
27
+
28
+ `CommandItem` uses `floatingListItemInteractive` with **`aria-selected:bg-accent`** (nqui ≥ 0.6.1). Do not add `data-selected:bg-accent` on custom rows — React 19 sets `data-selected="false"` on unselected cmdk items, and `[data-selected]` would highlight every row.
29
+
30
+ If an older nqui version still shows all rows filled: upgrade to **0.6.1+** or see `nqui-command.md` for a temporary `CommandItem` className override.
31
+
26
32
  ## Notes
27
33
 
28
34
  - Keyboard listener on window. May conflict with other global shortcuts.
29
35
  - Custom title/description for accessibility.
36
+ - Prefer plain `CommandList` in the showcase; wrap in `ScrollArea` only when you need a bounded height — scroll behavior is separate from row highlight.
@@ -37,3 +37,44 @@ import {
37
37
  <CommandList>...</CommandList>
38
38
  </CommandDialog>
39
39
  ```
40
+
41
+ ## CommandItem selection styling (cmdk + React 19)
42
+
43
+ Default `CommandItem` classes come from `floatingListItemInteractive` in `lib/floating-surface.ts`:
44
+
45
+ - `data-selected:bg-accent` → CSS **`[data-selected]`** (any value)
46
+ - `data-[highlighted]:bg-accent` — Radix pointer highlight
47
+ - `focus:bg-accent` — keyboard focus
48
+
49
+ cmdk sets **`data-selected` and `aria-selected` on every row**. With **React 19**, unselected rows render as `data-selected="false"` / `aria-selected="false"` (strings), not omitted attributes.
50
+
51
+ ### Symptom
52
+
53
+ Every list row has a muted/accent pill background; hover/keyboard should highlight **one** row only.
54
+
55
+ ### What to check
56
+
57
+ 1. Inspect an idle row: `data-selected="false"` present → bare `data-selected:` utilities will still match.
58
+ 2. Only **one** row should have `aria-selected="true"` (unless two items share the same cmdk `value`).
59
+ 3. Do not assume “only one selected” in the DOM means correct CSS — check computed `background-color`.
60
+
61
+ ### Do / don't (Tailwind)
62
+
63
+ | Do | Don't |
64
+ | -- | ----- |
65
+ | `aria-selected:bg-accent` | `data-selected:bg-accent` |
66
+ | `data-[selected=true]:bg-accent` | `data-[selected]:bg-accent` |
67
+ | `data-[selected=false]:bg-transparent` when overriding defaults | `bg-muted` on every row “to match design” |
68
+
69
+ **nqui ≥ 0.6.1:** `floatingListItemInteractive` uses `aria-selected:bg-accent` (same as ComboboxItem).
70
+
71
+ ### Consumer override (nqui &lt; 0.6.1 only)
72
+
73
+ ```tsx
74
+ <CommandItem
75
+ className="bg-transparent data-[selected=false]:!bg-transparent aria-selected:bg-accent aria-selected:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground"
76
+ ...
77
+ >
78
+ ```
79
+
80
+ See `nqui-command-palette.md` for Cmd+K-specific notes.