@godxjp/ui 19.2.0 → 19.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/dist/components/data-display/badge.d.ts +26 -2
  2. package/dist/components/data-display/badge.js +20 -5
  3. package/dist/components/data-display/index.d.ts +2 -0
  4. package/dist/components/data-display/index.js +2 -0
  5. package/dist/components/data-display/popover.d.ts +13 -1
  6. package/dist/components/data-display/popover.js +3 -1
  7. package/dist/components/data-display/table.d.ts +19 -2
  8. package/dist/components/data-display/table.js +4 -1
  9. package/dist/components/data-display/timeline-grid.d.ts +18 -0
  10. package/dist/components/data-display/timeline-grid.js +222 -0
  11. package/dist/components/data-entry/cascader.js +4 -6
  12. package/dist/components/data-entry/checkbox.js +1 -1
  13. package/dist/components/data-entry/search-select.js +5 -7
  14. package/dist/components/data-entry/select.js +32 -28
  15. package/dist/components/data-entry/tree-select.js +4 -6
  16. package/dist/components/general/inert-background.d.ts +5 -0
  17. package/dist/components/general/inert-background.js +48 -0
  18. package/dist/components/layout/auth-shell.d.ts +4 -2
  19. package/dist/components/layout/auth-shell.js +7 -1
  20. package/dist/components/layout/centered-shell.d.ts +2 -2
  21. package/dist/components/layout/flex.d.ts +1 -1
  22. package/dist/components/layout/flex.js +2 -1
  23. package/dist/components/layout/index.d.ts +3 -0
  24. package/dist/components/layout/index.js +2 -0
  25. package/dist/components/layout/mobile-shell.d.ts +21 -0
  26. package/dist/components/layout/mobile-shell.js +43 -0
  27. package/dist/components/layout/sidebar-link.d.ts +1 -1
  28. package/dist/components/navigation/context-menu.js +13 -9
  29. package/dist/components/navigation/dropdown-menu.js +17 -13
  30. package/dist/inertia/index.d.ts +1 -1
  31. package/dist/lib/variants.d.ts +3 -3
  32. package/dist/lib/variants.js +1 -0
  33. package/dist/props/components/data-display.prop.d.ts +72 -0
  34. package/dist/props/components/data-entry.prop.d.ts +1 -1
  35. package/dist/props/components/layout.prop.d.ts +93 -6
  36. package/dist/props/registry.d.ts +113 -2
  37. package/dist/props/registry.js +155 -1
  38. package/dist/props/vocabulary/data.prop.d.ts +6 -0
  39. package/dist/props/vocabulary/index.d.ts +3 -3
  40. package/dist/props/vocabulary/layout.prop.d.ts +17 -2
  41. package/dist/props/vocabulary/shared.prop.d.ts +7 -0
  42. package/dist/styles/badge-layout.css +15 -0
  43. package/dist/styles/control.css +18 -1
  44. package/dist/styles/data-display-layout.css +167 -0
  45. package/dist/styles/layout.css +7 -0
  46. package/dist/styles/shell-layout.css +148 -0
  47. package/dist/styles/table-layout.css +23 -4
  48. package/dist/tokens/components/badge.css +8 -0
  49. package/dist/tokens/components/control.css +1 -0
  50. package/dist/tokens/components/data-display.css +20 -0
  51. package/dist/tokens/components/shell.css +22 -0
  52. package/dist/tokens/components/table.css +2 -0
  53. package/docs/SPACING.md +19 -6
  54. package/docs/charts/compact-bar-trend.tsx +5 -6
  55. package/docs/data-display/avatar.tsx +7 -9
  56. package/docs/data-display/badge.tsx +37 -1
  57. package/docs/data-display/card/index.tsx +6 -4
  58. package/docs/data-display/carousel.tsx +8 -4
  59. package/docs/data-display/data-table/examples/approval-queue.tsx +1 -1
  60. package/docs/data-display/data-table/examples/grid-features.tsx +1 -1
  61. package/docs/data-display/data-table/index.tsx +1 -1
  62. package/docs/data-display/permission-matrix.tsx +15 -11
  63. package/docs/data-display/popover.tsx +2 -1
  64. package/docs/data-display/scroll-area.tsx +108 -76
  65. package/docs/data-display/table.tsx +2 -2
  66. package/docs/data-display/timeline-grid.tsx +119 -0
  67. package/docs/data-entry/branch-scope-picker.tsx +1 -1
  68. package/docs/data-entry/calendar.tsx +1 -1
  69. package/docs/data-entry/checkbox.tsx +1 -1
  70. package/docs/data-entry/country-picker-recipe.tsx +11 -6
  71. package/docs/data-entry/form-field/index.tsx +33 -29
  72. package/docs/data-entry/form-root.tsx +1 -1
  73. package/docs/data-entry/input-otp.tsx +1 -1
  74. package/docs/data-entry/password-input.tsx +1 -5
  75. package/docs/data-entry/select.tsx +7 -7
  76. package/docs/data-entry/textarea.tsx +3 -3
  77. package/docs/data-entry/toggle-count.tsx +1 -1
  78. package/docs/feedback/alert.tsx +1 -1
  79. package/docs/feedback/banner.tsx +1 -1
  80. package/docs/feedback/sheet.tsx +112 -102
  81. package/docs/feedback/skeleton.tsx +2 -2
  82. package/docs/foundation/colors.tsx +8 -6
  83. package/docs/foundation/email-tokens.tsx +83 -66
  84. package/docs/foundation/radius-shadow.tsx +13 -11
  85. package/docs/general/activity.tsx +1 -1
  86. package/docs/layout/app-shell.tsx +2 -2
  87. package/docs/layout/aspect-ratio.tsx +30 -14
  88. package/docs/layout/auth-account-summary.tsx +1 -1
  89. package/docs/layout/auth-recovery/examples/mobile-390.tsx +1 -1
  90. package/docs/layout/auth-recovery/examples/password-recovery.tsx +0 -2
  91. package/docs/layout/auth-shell-context.tsx +1 -1
  92. package/docs/layout/auth-shell-device.tsx +2 -2
  93. package/docs/layout/auth-shell-registration.tsx +1 -1
  94. package/docs/layout/auth-shell.tsx +1 -1
  95. package/docs/layout/flex.tsx +6 -2
  96. package/docs/layout/master-detail.tsx +2 -2
  97. package/docs/layout/mobile-shell.tsx +101 -0
  98. package/docs/layout/page-container.tsx +15 -7
  99. package/docs/layout/responsive-grid.tsx +12 -4
  100. package/docs/layout/separator.tsx +2 -2
  101. package/docs/layout/service-role-panel.tsx +1 -1
  102. package/docs/layout/sidebar.tsx +175 -152
  103. package/docs/layout/split-pane.tsx +45 -28
  104. package/docs/layout/topbar.tsx +19 -23
  105. package/docs/navigation/app-setting-picker.tsx +5 -4
  106. package/docs/navigation/breadcrumb.tsx +12 -5
  107. package/docs/navigation/context-menu.tsx +10 -4
  108. package/docs/navigation/filter-bar.tsx +2 -2
  109. package/docs/navigation/navigation-menu.tsx +89 -96
  110. package/docs/navigation/pagination.tsx +2 -2
  111. package/docs/navigation/steps.tsx +13 -11
  112. package/docs/navigation/tabs.tsx +27 -21
  113. package/docs/navigation/toolbar.tsx +15 -15
  114. package/docs/providers/format-date.tsx +2 -2
  115. package/docs/showcase/acme-portal.tsx +41 -28
  116. package/docs/showcase/acme-website.tsx +67 -61
  117. package/docs/showcase/case1-warehouse-dashboard.tsx +46 -31
  118. package/docs/showcase/case2-employee-me.tsx +33 -36
  119. package/docs/showcase/case3-approval-workflow.tsx +34 -32
  120. package/docs/showcase/case4-login.tsx +95 -101
  121. package/docs/showcase/case5-shift-calendar.tsx +182 -281
  122. package/docs/showcase/case6-agency-handy.tsx +514 -470
  123. package/docs/showcase/futurelastic-web.tsx +32 -29
  124. package/docs/showcase/org-switcher.tsx +20 -13
  125. package/docs/showcase/permission-matrix.tsx +20 -17
  126. package/docs/showcase/public-landing.tsx +1 -1
  127. package/docs/showcase/settings-account-sections.tsx +2 -2
  128. package/docs/showcase/settings-security-mfa.tsx +3 -3
  129. package/docs/showcase/table-approval-queue.tsx +1 -1
  130. package/docs/showcase/table-bulk-actions.tsx +49 -52
  131. package/docs/showcase/table-conditional-format.tsx +9 -9
  132. package/docs/showcase/table-crud-list.tsx +4 -4
  133. package/docs/showcase/table-density.tsx +49 -42
  134. package/docs/showcase/table-expandable-rows.tsx +112 -100
  135. package/docs/showcase/table-filter-chips.tsx +78 -71
  136. package/docs/showcase/table-footer-totals.tsx +30 -23
  137. package/docs/showcase/table-grouped-subtotals.tsx +31 -25
  138. package/docs/showcase/table-master-detail.tsx +27 -24
  139. package/docs/showcase/table-pagination.tsx +34 -27
  140. package/docs/showcase/table-states.tsx +42 -34
  141. package/docs/showcase/table-sticky-columns.tsx +11 -7
  142. package/docs/showcase/table-tree-rows.tsx +22 -15
  143. package/docs/showcase/table-view-tabs.tsx +12 -14
  144. package/package.json +7 -7
@@ -897,3 +897,170 @@
897
897
  border-block-start: var(--stroke-hairline) solid hsl(var(--border));
898
898
  }
899
899
  }
900
+
901
+ @layer components {
902
+ .ui-timeline-grid {
903
+ overflow-x: auto;
904
+ }
905
+
906
+ .ui-timeline-grid-frame {
907
+ display: grid;
908
+ grid-template-columns:
909
+ var(--timeline-grid-axis-width)
910
+ repeat(var(--timeline-grid-columns, 1), minmax(var(--timeline-grid-column-min-width), 1fr));
911
+ }
912
+
913
+ .ui-timeline-grid-corner {
914
+ border-block-end: 1px solid hsl(var(--border));
915
+ }
916
+
917
+ .ui-timeline-grid-head {
918
+ display: flex;
919
+ flex-direction: column;
920
+ align-items: center;
921
+ padding: var(--space-1);
922
+ border-block-end: 1px solid hsl(var(--border));
923
+ border-inline-start: 1px solid hsl(var(--border));
924
+ background: hsl(var(--secondary));
925
+ font-size: var(--timeline-grid-head-font-size);
926
+ font-weight: var(--font-weight-medium);
927
+ line-height: var(--line-height-tight);
928
+ text-align: center;
929
+ }
930
+
931
+ .ui-timeline-grid-head[data-current="true"] {
932
+ background: var(--timeline-grid-current-tint, hsl(var(--primary) / 0.08));
933
+ }
934
+
935
+ .ui-timeline-grid-head-description {
936
+ color: hsl(var(--muted-foreground));
937
+ font-size: var(--timeline-grid-axis-font-size);
938
+ font-weight: var(--font-weight-normal);
939
+ }
940
+
941
+ .ui-timeline-grid-axis,
942
+ .ui-timeline-grid-column {
943
+ position: relative;
944
+ block-size: calc(var(--timeline-grid-hour-height) * var(--timeline-grid-hours, 24));
945
+ }
946
+
947
+ .ui-timeline-grid-tick {
948
+ position: absolute;
949
+ inset-inline-end: var(--space-1);
950
+ inset-block-start: calc(var(--timeline-grid-hour-height) * var(--timeline-grid-tick-offset, 0));
951
+ color: hsl(var(--muted-foreground));
952
+ font-size: var(--timeline-grid-axis-font-size);
953
+ font-variant-numeric: tabular-nums;
954
+ line-height: 1;
955
+ transform: translateY(-50%);
956
+ white-space: nowrap;
957
+ }
958
+
959
+ .ui-timeline-grid-column {
960
+ margin: 0;
961
+ padding: 0;
962
+ border-inline-start: 1px solid hsl(var(--border));
963
+ background-image: repeating-linear-gradient(
964
+ to bottom,
965
+ var(--timeline-grid-line-color, hsl(var(--border))) 0 1px,
966
+ transparent 1px calc(var(--timeline-grid-hour-height) * var(--timeline-grid-interval, 1))
967
+ );
968
+ list-style: none;
969
+ }
970
+
971
+ .ui-timeline-grid-column[data-current="true"] {
972
+ background-color: var(--timeline-grid-current-tint, hsl(var(--primary) / 0.05));
973
+ }
974
+
975
+ .ui-timeline-grid-event {
976
+ position: absolute;
977
+ inset-block-start: calc(
978
+ var(--timeline-grid-hour-height) * var(--timeline-grid-event-offset, 0)
979
+ );
980
+ inset-inline-start: calc(
981
+ var(--timeline-grid-event-lane, 0) / var(--timeline-grid-event-lanes, 1) * 100%
982
+ );
983
+ box-sizing: border-box;
984
+ inline-size: calc(100% / var(--timeline-grid-event-lanes, 1));
985
+ block-size: calc(var(--timeline-grid-hour-height) * var(--timeline-grid-event-span, 0));
986
+ min-block-size: var(--timeline-grid-event-min-height);
987
+ padding-inline-end: var(--timeline-grid-event-gap);
988
+ padding-block-end: var(--timeline-grid-event-gap);
989
+ }
990
+
991
+ .ui-timeline-grid-event-body {
992
+ display: flex;
993
+ overflow: hidden;
994
+ box-sizing: border-box;
995
+ flex-direction: column;
996
+ inline-size: 100%;
997
+ block-size: 100%;
998
+ padding: var(--timeline-grid-event-space-inset);
999
+ border-inline-start: var(--timeline-grid-event-border-width) solid
1000
+ var(--timeline-grid-event-color, hsl(var(--primary)));
1001
+ border-radius: var(--timeline-grid-event-radius);
1002
+
1003
+ background-color: color-mix(
1004
+ in srgb,
1005
+ hsl(var(--background)),
1006
+ var(--timeline-grid-event-color, hsl(var(--primary))) 12%
1007
+ );
1008
+ color: hsl(var(--foreground));
1009
+ font-size: var(--timeline-grid-event-font-size);
1010
+ line-height: var(--line-height-tight);
1011
+ text-align: start;
1012
+ }
1013
+
1014
+ .ui-timeline-grid-event[data-clipped="start"] .ui-timeline-grid-event-body,
1015
+ .ui-timeline-grid-event[data-clipped="both"] .ui-timeline-grid-event-body {
1016
+ border-start-start-radius: 0;
1017
+ border-start-end-radius: 0;
1018
+ }
1019
+
1020
+ .ui-timeline-grid-event[data-clipped="end"] .ui-timeline-grid-event-body,
1021
+ .ui-timeline-grid-event[data-clipped="both"] .ui-timeline-grid-event-body {
1022
+ border-end-start-radius: 0;
1023
+ border-end-end-radius: 0;
1024
+ }
1025
+
1026
+ .ui-timeline-grid-event-time {
1027
+ color: var(--timeline-grid-event-muted-color);
1028
+ font-variant-numeric: tabular-nums;
1029
+ white-space: nowrap;
1030
+ }
1031
+
1032
+ .ui-timeline-grid-event-title {
1033
+ overflow: hidden;
1034
+ font-weight: var(--font-weight-medium);
1035
+ text-overflow: ellipsis;
1036
+ white-space: nowrap;
1037
+ }
1038
+
1039
+ .ui-timeline-grid-event-description {
1040
+ overflow: hidden;
1041
+ color: var(--timeline-grid-event-muted-color);
1042
+ text-overflow: ellipsis;
1043
+ white-space: nowrap;
1044
+ }
1045
+
1046
+ button.ui-timeline-grid-event-body {
1047
+ cursor: pointer;
1048
+ }
1049
+
1050
+ button.ui-timeline-grid-event-body:hover {
1051
+ background-color: color-mix(
1052
+ in srgb,
1053
+ hsl(var(--background)),
1054
+ var(--timeline-grid-event-color, hsl(var(--primary))) 20%
1055
+ );
1056
+ }
1057
+
1058
+ .ui-timeline-grid-now {
1059
+ position: absolute;
1060
+ inset-inline: 0;
1061
+ inset-block-start: calc(var(--timeline-grid-hour-height) * var(--timeline-grid-now-offset, 0));
1062
+ block-size: var(--timeline-grid-now-width);
1063
+ background: var(--timeline-grid-now-color, hsl(var(--destructive)));
1064
+ pointer-events: none;
1065
+ }
1066
+ }
@@ -158,6 +158,10 @@
158
158
  justify-content: space-evenly;
159
159
  }
160
160
 
161
+ .ui-flex-gap-none {
162
+ gap: 0;
163
+ }
164
+
161
165
  .ui-flex-gap-xs {
162
166
  gap: var(--space-stack-xs);
163
167
  }
@@ -238,6 +242,9 @@
238
242
  grid-template-columns: minmax(0, 1fr);
239
243
  }
240
244
 
245
+ .ui-responsive-grid[data-gap="none"] {
246
+ gap: 0;
247
+ }
241
248
  .ui-responsive-grid[data-gap="xs"] {
242
249
  gap: var(--space-stack-xs);
243
250
  }
@@ -112,9 +112,19 @@
112
112
  .ui-auth-shell-bar {
113
113
  display: flex;
114
114
  align-items: center;
115
+
116
+ flex-wrap: wrap;
117
+ gap: var(--auth-shell-bar-gap);
115
118
  padding: var(--auth-shell-bar-padding);
116
119
  }
117
120
 
121
+ .ui-auth-shell-bar-actions {
122
+ display: flex;
123
+ align-items: center;
124
+ gap: var(--auth-shell-bar-gap);
125
+ margin-inline-start: auto;
126
+ }
127
+
118
128
  .ui-auth-shell-main {
119
129
  display: flex;
120
130
  flex: 1 1 auto;
@@ -142,6 +152,15 @@
142
152
  --auth-shell-main-padding: var(--auth-shell-canonical-main-padding);
143
153
  }
144
154
 
155
+ .ui-auth-shell[data-measure="wide"]:not([data-preset]) {
156
+ --auth-shell-card-max-width: var(--auth-shell-wide-card-max-width);
157
+ --auth-shell-main-align: flex-start;
158
+ }
159
+
160
+ .ui-auth-shell[data-measure="wide"]:not([data-preset]) .ui-auth-shell-card {
161
+ margin-block: auto;
162
+ }
163
+
145
164
  .ui-auth-shell[data-preset] .ui-auth-shell-card {
146
165
  display: flex;
147
166
  flex-direction: column;
@@ -1417,6 +1436,135 @@
1417
1436
  }
1418
1437
  }
1419
1438
 
1439
+ @layer components {
1440
+ .ui-mobile-shell {
1441
+ --control-height: var(--mobile-shell-control-height);
1442
+
1443
+ --mobile-shell-padding-inline: calc(
1444
+ var(--mobile-shell-inset-inline) + var(--mobile-shell-safe-inset-inline)
1445
+ );
1446
+ display: flex;
1447
+
1448
+ block-size: var(--mobile-shell-block-size);
1449
+ flex-direction: column;
1450
+ overflow: hidden;
1451
+ background: hsl(var(--background));
1452
+ }
1453
+
1454
+ .ui-mobile-shell[data-height="fill"] {
1455
+ --mobile-shell-block-size: 100%;
1456
+ }
1457
+
1458
+ .ui-mobile-shell-chrome {
1459
+ display: flex;
1460
+ min-inline-size: 0;
1461
+ flex: 0 0 auto;
1462
+ flex-direction: column;
1463
+ }
1464
+
1465
+ .ui-mobile-shell-status {
1466
+ display: flex;
1467
+ min-block-size: calc(
1468
+ var(--mobile-shell-status-bar-height) + var(--mobile-shell-safe-inset-block-start)
1469
+ );
1470
+ flex: 0 0 auto;
1471
+ align-items: center;
1472
+ justify-content: space-between;
1473
+ gap: var(--mobile-shell-region-gap);
1474
+ padding-block-start: var(--mobile-shell-safe-inset-block-start);
1475
+ padding-inline: var(--mobile-shell-padding-inline);
1476
+ background: hsl(var(--card));
1477
+ }
1478
+
1479
+ .ui-mobile-shell-header {
1480
+ display: flex;
1481
+ min-block-size: var(--mobile-shell-header-bar-height);
1482
+ min-inline-size: 0;
1483
+ flex: 0 0 auto;
1484
+
1485
+ overflow: clip;
1486
+ overflow-clip-margin: var(--focus-ring-clip-margin);
1487
+ align-items: center;
1488
+ gap: var(--mobile-shell-region-gap);
1489
+ padding-inline: var(--mobile-shell-padding-inline);
1490
+ border-block-end: 1px solid hsl(var(--border));
1491
+ background: hsl(var(--card));
1492
+ background-image: var(--topbar-gradient);
1493
+ }
1494
+
1495
+ .ui-mobile-shell-header:first-child {
1496
+ min-block-size: calc(
1497
+ var(--mobile-shell-header-bar-height) + var(--mobile-shell-safe-inset-block-start)
1498
+ );
1499
+ padding-block-start: var(--mobile-shell-safe-inset-block-start);
1500
+ }
1501
+
1502
+ .ui-mobile-shell-main {
1503
+ display: flex;
1504
+ min-block-size: 0;
1505
+ min-inline-size: 0;
1506
+
1507
+ flex: 1 1 auto;
1508
+ flex-direction: column;
1509
+ overflow-y: auto;
1510
+
1511
+ overscroll-behavior-block: contain;
1512
+
1513
+ contain: paint;
1514
+ padding-block: var(--mobile-shell-main-padding-block);
1515
+ padding-inline: var(--mobile-shell-padding-inline);
1516
+ background-image: var(--gradient-glow);
1517
+ }
1518
+
1519
+ .ui-mobile-shell-main:focus-visible {
1520
+ outline: none;
1521
+ box-shadow: inset 0 0 0 var(--region-focus-ring-width)
1522
+ var(--region-focus-ring-color, hsl(var(--focus-ring-color, var(--ring))));
1523
+ }
1524
+
1525
+ .ui-mobile-shell-actions {
1526
+ display: flex;
1527
+ min-inline-size: 0;
1528
+ flex: 0 0 auto;
1529
+ align-items: center;
1530
+ gap: var(--mobile-shell-region-gap);
1531
+ padding-block: var(--mobile-shell-actions-padding-block);
1532
+ padding-inline: var(--mobile-shell-padding-inline);
1533
+ border-block-start: 1px solid hsl(var(--border));
1534
+ background: hsl(var(--card));
1535
+ }
1536
+
1537
+ .ui-mobile-shell-tabbar {
1538
+ display: flex;
1539
+ min-block-size: calc(
1540
+ var(--mobile-shell-tab-bar-height) + var(--mobile-shell-safe-inset-block-end)
1541
+ );
1542
+ min-inline-size: 0;
1543
+ flex: 0 0 auto;
1544
+ padding-block-end: var(--mobile-shell-safe-inset-block-end);
1545
+ padding-inline: var(--mobile-shell-safe-inset-inline);
1546
+ border-block-start: 1px solid hsl(var(--border));
1547
+ background: hsl(var(--card));
1548
+ }
1549
+
1550
+ .ui-mobile-shell-tabbar > * {
1551
+ min-inline-size: 0;
1552
+ flex: 1 1 0;
1553
+ }
1554
+
1555
+ .ui-mobile-shell-actions:last-child {
1556
+ padding-block-end: calc(
1557
+ var(--mobile-shell-actions-padding-block) + var(--mobile-shell-safe-inset-block-end)
1558
+ );
1559
+ }
1560
+
1561
+ .ui-mobile-shell-main:last-child {
1562
+ padding-block-end: calc(
1563
+ var(--mobile-shell-main-padding-block) + var(--mobile-shell-safe-inset-block-end)
1564
+ );
1565
+ }
1566
+ }
1567
+
1420
1568
  @layer components {
1421
1569
 
1422
1570
  .ui-centered-shell[data-preset="public-landing"] {
@@ -46,6 +46,17 @@
46
46
  padding-inline-end: 0;
47
47
  }
48
48
 
49
+ [data-slot="table-cell"][data-indent] {
50
+ padding-inline-start: calc(
51
+ var(--table-cell-space-x) + var(--table-cell-indent-level, 0) *
52
+ var(--table-cell-indent-space-step)
53
+ );
54
+ }
55
+
56
+ [data-slot="table-cell"][data-flush] {
57
+ padding: 0;
58
+ }
59
+
49
60
  .ui-data-table-toolbar {
50
61
  display: flex;
51
62
  flex-wrap: wrap;
@@ -520,7 +531,9 @@
520
531
 
521
532
  [data-collapse-below="sm"] .ui-table-row {
522
533
  display: block;
523
- border: 1px solid hsl(var(--border));
534
+
535
+ height: auto;
536
+ border: var(--stroke-hairline) solid hsl(var(--border));
524
537
  border-radius: var(--radius-md);
525
538
  padding: var(--table-stacked-collection-card-padding-y)
526
539
  var(--table-stacked-collection-card-padding-x);
@@ -562,7 +575,9 @@
562
575
 
563
576
  [data-collapse-below="md"] .ui-table-row {
564
577
  display: block;
565
- border: 1px solid hsl(var(--border));
578
+
579
+ height: auto;
580
+ border: var(--stroke-hairline) solid hsl(var(--border));
566
581
  border-radius: var(--radius-md);
567
582
  padding: var(--table-stacked-collection-card-padding-y)
568
583
  var(--table-stacked-collection-card-padding-x);
@@ -604,7 +619,9 @@
604
619
 
605
620
  [data-collapse-below="lg"] .ui-table-row {
606
621
  display: block;
607
- border: 1px solid hsl(var(--border));
622
+
623
+ height: auto;
624
+ border: var(--stroke-hairline) solid hsl(var(--border));
608
625
  border-radius: var(--radius-md);
609
626
  padding: var(--table-stacked-collection-card-padding-y)
610
627
  var(--table-stacked-collection-card-padding-x);
@@ -646,7 +663,9 @@
646
663
 
647
664
  [data-collapse-below="xl"] .ui-table-row {
648
665
  display: block;
649
- border: 1px solid hsl(var(--border));
666
+
667
+ height: auto;
668
+ border: var(--stroke-hairline) solid hsl(var(--border));
650
669
  border-radius: var(--radius-md);
651
670
  padding: var(--table-stacked-collection-card-padding-y)
652
671
  var(--table-stacked-collection-card-padding-x);
@@ -10,4 +10,12 @@
10
10
  --badge-line-height: calc(1 / 0.75);
11
11
 
12
12
  --badge-icon-size: var(--icon-size-xs);
13
+
14
+ --badge-tint-fill: 18%;
15
+ --badge-tint-edge: 45%;
16
+
17
+ --badge-tint-surface: hsl(var(--card));
18
+ --badge-tint-foreground: hsl(var(--card-foreground));
19
+
20
+ --badge-color: var(--badge-tint-surface);
13
21
  }
@@ -31,6 +31,7 @@
31
31
 
32
32
  --rating-focus-ring-offset: 2px;
33
33
 
34
+ --checkbox-border-width: var(--stroke-hairline);
34
35
  --checkbox-size: calc(1rem * var(--scaling));
35
36
  --checkbox-size-compact: 0.875rem;
36
37
  --checkbox-size-comfortable: 1.125rem;
@@ -83,6 +83,26 @@
83
83
  --scroll-area-bar-padding: 1px;
84
84
  --scroll-area-thumb-radius: var(--radius-pill);
85
85
 
86
+ --timeline-grid-hour-height: 2.5rem;
87
+ --timeline-grid-axis-width: 3.25rem;
88
+ --timeline-grid-column-min-width: 6rem;
89
+ --timeline-grid-event-min-height: 1.5rem;
90
+ --timeline-grid-axis-font-size: var(--font-size-2xs);
91
+ --timeline-grid-head-font-size: var(--font-size-xs);
92
+ --timeline-grid-event-font-size: var(--font-size-2xs);
93
+ --timeline-grid-event-gap: var(--space-1);
94
+ --timeline-grid-event-space-inset: var(--space-1);
95
+ --timeline-grid-event-radius: var(--radius-sm);
96
+ --timeline-grid-event-border-width: var(--stroke-md);
97
+ --timeline-grid-now-width: var(--stroke-sm);
98
+
99
+ --timeline-grid-line-color: initial;
100
+ --timeline-grid-event-color: initial;
101
+
102
+ --timeline-grid-event-muted-color: hsl(var(--foreground));
103
+ --timeline-grid-now-color: initial;
104
+ --timeline-grid-current-tint: initial;
105
+
86
106
  --permission-matrix-label-width: 16rem;
87
107
  --permission-matrix-role-space-gap: var(--space-1);
88
108
  --permission-matrix-name-space-gap: 0.375rem;
@@ -107,6 +107,10 @@
107
107
  --auth-shell-main-padding: var(--space-6);
108
108
  --auth-shell-footer-padding: var(--space-3) var(--space-6) var(--space-4);
109
109
 
110
+ --auth-shell-bar-gap: var(--space-inline-sm);
111
+
112
+ --auth-shell-wide-card-max-width: 64rem;
113
+
110
114
  --auth-shell-canonical-control-height: var(--band-height-lg);
111
115
  --auth-shell-canonical-card-max-width: 22.5rem;
112
116
  --auth-shell-canonical-heading-size: var(--font-size-base);
@@ -228,3 +232,21 @@
228
232
  --app-shell-bar-height: var(--band-height-3xl);
229
233
  }
230
234
  }
235
+
236
+ :root {
237
+ --mobile-shell-block-size: 100dvh;
238
+ --mobile-shell-safe-inset-block-start: env(safe-area-inset-top);
239
+ --mobile-shell-safe-inset-block-end: env(safe-area-inset-bottom);
240
+ --mobile-shell-safe-inset-inline: max(env(safe-area-inset-left), env(safe-area-inset-right));
241
+
242
+ --mobile-shell-inset-inline: var(--space-4);
243
+
244
+ --mobile-shell-control-height: var(--control-height-comfortable);
245
+ --mobile-shell-region-gap: var(--space-2);
246
+ --mobile-shell-status-bar-height: var(--band-height-lg);
247
+ --mobile-shell-header-bar-height: var(--band-height-3xl);
248
+
249
+ --mobile-shell-tab-bar-height: calc(var(--band-height-3xl) + var(--space-2));
250
+ --mobile-shell-main-padding-block: var(--space-4);
251
+ --mobile-shell-actions-padding-block: var(--space-3);
252
+ }
@@ -8,6 +8,8 @@
8
8
  --table-cell-padding-y: var(--space-2);
9
9
  --table-cell-space-x: var(--control-padding-x);
10
10
 
11
+ --table-cell-indent-space-step: var(--space-4);
12
+
11
13
  --table-border-color: initial;
12
14
  --table-pagination-padding-y: initial;
13
15
  --table-pagination-padding-x: initial;
package/docs/SPACING.md CHANGED
@@ -42,15 +42,28 @@ Implementation: `src/tokens/base.css` (values) · layout owners: `src/styles/*-l
42
42
  | `--card-space-body-y` | `--space-section-active` | Header↔body gap |
43
43
  | `--card-space-header-y` / `--card-space-footer-y` | `--space-stack-sm` | Banded header + separated footer band |
44
44
 
45
- | Component | Use |
46
- | ------------------------- | -------------------------------------------------- |
47
- | `StatCard` | KPI / stat tile (`solo` path) |
48
- | `CardContent solo` | Body-only card (same padding as `StatCard`) |
49
- | `CardContent flush tight` | Edge-to-edge table/tabs in card |
50
- | `ui-card-inset-x` | Align nested cells to shell (tables in flush body) |
45
+ | Component | Use |
46
+ | ------------------------- | ------------------------------------------- |
47
+ | `StatCard` | KPI / stat tile (`solo` path) |
48
+ | `CardContent solo` | Body-only card (same padding as `StatCard`) |
49
+ | `CardContent flush tight` | Edge-to-edge table/tabs in card |
51
50
 
52
51
  See preview **Data Display → Card** for live examples.
53
52
 
53
+ ### Inset classes (padding on something that is not a `Card*` slot)
54
+
55
+ `Card*` slots get their padding from `data-slot`. Everything else that must sit on the same rhythm (a table cell, a grid header strip, a scroll body, a sticky action row, a full-bleed toolbar) uses one of three public classes. They are the only legal way to take card-token padding onto a plain element, because the audit rejects Tailwind `p-*` / `px-*` (`no-utility-spacing`).
56
+
57
+ Pick by AXIS, and note that the three do **not** share one value: each reads a different card token, so `ui-card-inset` is not `ui-card-inset-x` plus `ui-card-inset-y`.
58
+
59
+ | Class | Axis | Token | Use when |
60
+ | ----------------- | ------------------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
61
+ | `ui-card-inset-x` | inline (start/end) | `--card-space-inset` | The element must line up with the card shell edge, and the block axis is owned by something else (a fixed row height, a table cell). Rows in a `CardContent flush` table, a header strip in a bordered grid. |
62
+ | `ui-card-inset-y` | block (top/bottom) | `--card-space-header-y` | The element runs edge to edge inline but needs the band rhythm of a banded header / separated footer. A weekday header strip, a full-bleed toolbar cell. |
63
+ | `ui-card-inset` | all four sides | `--card-space-body-y` | A self-contained panel that owns its own padding on every side: a scrollable body, a sticky action bar, an expanded row panel below a table row. |
64
+
65
+ Because `ui-card-inset-x` reads `--card-space-inset`, it follows the card it sits in: a `Card density="tight"` or `"cozy"` moves those cells with the shell. The other two read fixed steps (band and body) and do not.
66
+
54
67
  ## MCP
55
68
 
56
69
  `get_pattern page-sections` (a page of Cards, spaced by the page) · `get_rule 40` (mobile-first spacing) · `list_audit_rules` (the spacing rules the CLI enforces).
@@ -13,13 +13,12 @@ import { Text } from "@godxjp/ui/general";
13
13
  import { Flex, PageContainer, ResponsiveGrid } from "@godxjp/ui/layout";
14
14
 
15
15
  /**
16
- * CompactBarTrend — the DEPENDENCY-FREE compact bar trend (gh#218).
16
+ * CompactBarTrend — the DEPENDENCY-FREE compact bar trend.
17
17
  *
18
- * `BarChart` needs the `recharts` optional peer; a platform whose policy forbids screen
19
- * implementers from adding dependencies cannot use it, and used to fall back to a page-local
20
- * grid with inline heights. `CompactBarTrend` closes that gap: the marks are token-sized CSS
21
- * blocks, so the canonical SCR-201 admin dashboard gets a real framework chart with zero
22
- * consumer CSS, zero inline height math and zero hardcoded colour.
18
+ * `BarChart` needs the `recharts` optional peer, so a platform whose policy forbids screen
19
+ * implementers from adding dependencies cannot use it. The marks here are token-sized CSS
20
+ * blocks instead, so a dashboard gets a real framework chart with zero consumer CSS, zero
21
+ * inline height math and zero hardcoded colour.
23
22
  *
24
23
  * Everything below is composed from real @godxjp/ui primitives only.
25
24
  */
@@ -25,12 +25,10 @@ import portraitSlate from "../assets/portrait-slate.svg";
25
25
  * URL against PREVIEW_BASE — an absolute "/assets/…" would 404 wherever the site is served from a
26
26
  * sub-path.
27
27
  *
28
- * They used to be `https://picsum.photos/...`. A docs page that fetches a THIRD-PARTY image cannot
29
- * render without the public internet, and on CI it does not merely look wrong it hangs: the
30
- * request never settles, `networkidle` never fires, and `page.goto` times out at 30s. That is what
31
- * failed `data-display-avatar` and `data-display-card-index` at every viewport in both the axe and
32
- * geometry sweeps (gh#333), long after the preview server itself was fixed. Committed files cost
33
- * no request that can hang and no service that can disappear.
28
+ * A docs page must never fetch a THIRD-PARTY image: without the public internet it cannot render,
29
+ * and on CI it does not merely look wrong, it hangs the request never settles, `networkidle`
30
+ * never fires, and `page.goto` times out. Committed files cost no request that can hang and no
31
+ * service that can disappear.
34
32
  */
35
33
 
36
34
  /**
@@ -93,7 +91,7 @@ export default function Demo() {
93
91
  </CardContent>
94
92
  </Card>
95
93
 
96
- {/* shape="square" — the entity-header organization / service mark (gh#249) */}
94
+ {/* shape="square" — the entity-header organization / service mark */}
97
95
  <Card>
98
96
  <CardHeader>
99
97
  <CardTitle level={2}>エンティティヘッダー · shape=&quot;square&quot;</CardTitle>
@@ -136,7 +134,7 @@ export default function Demo() {
136
134
  </CardContent>
137
135
  </Card>
138
136
 
139
- {/* appearance="tinted" — the capability medallion (gh#12) */}
137
+ {/* appearance="tinted" — the capability medallion */}
140
138
  <Card>
141
139
  <CardHeader>
142
140
  <CardTitle level={2}>
@@ -192,7 +190,7 @@ export default function Demo() {
192
190
  </CardContent>
193
191
  </Card>
194
192
 
195
- {/* presence — the realtime reachability dot (gh#309) */}
193
+ {/* presence — the realtime reachability dot */}
196
194
  <Card>
197
195
  <CardHeader>
198
196
  <CardTitle level={2}>プレゼンス · presence</CardTitle>
@@ -30,6 +30,21 @@ const shapes = [
30
30
  { shape: "sharp" as const, label: "角 Sharp" },
31
31
  ];
32
32
 
33
+ /**
34
+ * Colours a person picked, not colours that mean something — a status and an
35
+ * issue type out of a project's own settings screen, plus the two ends of the
36
+ * range an administrator can still type. `#488a5a` is here because it is the
37
+ * worst case for a SOLID chip: near-black and white measure equal on it, both
38
+ * 4.15:1, under the 4.5 badge-sized text needs. Washed, it clears 8.52.
39
+ */
40
+ const dataColours = [
41
+ { color: "#4488c5", label: "処理中 In progress" },
42
+ { color: "#ea9a10", label: "未対応 Open" },
43
+ { color: "#488a5a", label: "完了 Done" },
44
+ { color: "#000000", label: "黒 Black" },
45
+ { color: "#ffffff", label: "白 White" },
46
+ ];
47
+
33
48
  const tones = [
34
49
  { tone: "default" as const, label: "既定 Default" },
35
50
  { tone: "primary" as const, label: "ブランド Brand" },
@@ -44,7 +59,7 @@ const tones = [
44
59
  const statuses = ["active", "draft", "pending", "cancelled", "failed", "scheduled"];
45
60
 
46
61
  /**
47
- * Subscription/billing lifecycle keys (gh#216). They ship the SAME canonical status→tone→icon
62
+ * Subscription/billing lifecycle keys. They ship the SAME canonical status→tone→icon
48
63
  * map as every other key, so a billing screen never keeps a page-local colour table. They are
49
64
  * demoed explicitly because their i18n labels were once missing. A missing key renders the raw
50
65
  * `status.trialing` string, and only a rendered demo makes that regression visible.
@@ -120,6 +135,27 @@ export default function Demo() {
120
135
  </CardContent>
121
136
  </Card>
122
137
 
138
+ <Card>
139
+ <CardHeader>
140
+ <CardTitle level={2}>The record&rsquo;s own colour</CardTitle>
141
+ <CardDescription>
142
+ color carries DATA: a status an administrator coloured, an issue type, a tag. The chip
143
+ is washed into the surface rather than filled, because a solid chip has to choose a
144
+ foreground and no choice is readable for every colour a picker can produce. Retune the
145
+ wash with --badge-tint-fill / --badge-tint-edge.
146
+ </CardDescription>
147
+ </CardHeader>
148
+ <CardContent>
149
+ <Flex direction="row" wrap align="center" gap="sm">
150
+ {dataColours.map((c) => (
151
+ <Badge key={c.color} shape="pill" color={c.color}>
152
+ {c.label}
153
+ </Badge>
154
+ ))}
155
+ </Flex>
156
+ </CardContent>
157
+ </Card>
158
+
123
159
  <Card>
124
160
  <CardHeader>
125
161
  <CardTitle level={2}>Semantic tones</CardTitle>