@digiko-npm/designsystem 0.3.33 → 0.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.
@@ -1,4 +1,4 @@
1
- /* @ds/designsystem v0.3.32 */
1
+ /* @ds/designsystem v0.4.0 */
2
2
  /* ==========================================================================
3
3
  @digiko-npm/designsystem
4
4
 
@@ -361,10 +361,39 @@
361
361
  --ds-ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
362
362
  --ds-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
363
363
 
364
+ /* --- Backdrop Blur --- */
365
+ --ds-blur-sm: 4px;
366
+ --ds-blur-md: 12px;
367
+ --ds-blur-lg: 20px;
368
+
369
+ /* --- Indicator Sizes --- */
370
+ --ds-dot-size: 6px;
371
+
372
+ /* --- Accent Border --- */
373
+ --ds-accent-border-width: 3px;
374
+
375
+ /* --- Popover/Tooltip Offset --- */
376
+ --ds-offset-sm: 4px;
377
+ --ds-offset-md: 8px;
378
+
364
379
  /* --- Opacity --- */
365
380
  --ds-opacity-disabled: 0.5;
366
381
  }
367
382
 
383
+ /* --- Reduced Motion ---
384
+ Zero out duration tokens so every component that uses
385
+ var(--ds-duration-*) transitions instantly.
386
+ Keyframe animations are handled per-component.
387
+ -------------------------------------------------------- */
388
+ @media (prefers-reduced-motion: reduce) {
389
+ :root {
390
+ --ds-duration-fast: 0s;
391
+ --ds-duration-normal: 0s;
392
+ --ds-duration-slow: 0s;
393
+ --ds-duration-slower: 0s;
394
+ }
395
+ }
396
+
368
397
 
369
398
  /* ==========================================================================
370
399
  Base: Reset
@@ -470,14 +499,11 @@ input[type="number"]::-webkit-inner-spin-button {
470
499
  .ds-no-scrollbar::-webkit-scrollbar { display: none; }
471
500
  .ds-no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
472
501
 
473
- /* Reduce motion */
502
+ /* Reduce motion — scroll only.
503
+ Transitions are handled via --ds-duration-* tokens in shadows.css.
504
+ Keyframe animations are handled per-component. */
474
505
  @media (prefers-reduced-motion: reduce) {
475
- *, *::before, *::after {
476
- animation-duration: 0.01ms !important;
477
- animation-iteration-count: 1 !important;
478
- transition-duration: 0.01ms !important;
479
- scroll-behavior: auto !important;
480
- }
506
+ html { scroll-behavior: auto !important; }
481
507
  }
482
508
 
483
509
  /* ==========================================================================
@@ -685,8 +711,8 @@ hr {
685
711
  }
686
712
 
687
713
  .ds-btn:focus-visible {
688
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
689
- outline-offset: var(--ds-ring-offset);
714
+ outline: none;
715
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
690
716
  }
691
717
 
692
718
  .ds-btn:disabled,
@@ -842,6 +868,10 @@ hr {
842
868
  to { transform: rotate(360deg); }
843
869
  }
844
870
 
871
+ @media (prefers-reduced-motion: reduce) {
872
+ .ds-btn--loading::after { animation: none; opacity: 0.6; }
873
+ }
874
+
845
875
  /* ==========================================================================
846
876
  Component: Card
847
877
  Surface + border, hover with shadow lift, rounded-xl.
@@ -864,6 +894,13 @@ hr {
864
894
  box-shadow: var(--ds-shadow-lg);
865
895
  transform: translateY(-4px);
866
896
  }
897
+ .ds-card--interactive:focus-visible {
898
+ outline: none;
899
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
900
+ }
901
+ .ds-card--interactive:hover:focus-visible {
902
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color), var(--ds-shadow-lg);
903
+ }
867
904
 
868
905
  /* Elevated card — visible shadow */
869
906
  .ds-card--elevated {
@@ -914,6 +951,9 @@ hr {
914
951
  object-fit: cover;
915
952
  background-color: var(--ds-color-bg-elevated);
916
953
  }
954
+ .ds-card__media--square { aspect-ratio: 1; }
955
+ .ds-card__media--video { aspect-ratio: 16/9; }
956
+ .ds-card__media--auto { aspect-ratio: auto; }
917
957
 
918
958
  /* Compact */
919
959
  .ds-card--compact .ds-card__header,
@@ -977,10 +1017,14 @@ hr {
977
1017
  margin-bottom: var(--ds-space-1-5);
978
1018
  }
979
1019
 
1020
+ .ds-input,
1021
+ .ds-textarea {
1022
+ width: 100%;
1023
+ }
1024
+
980
1025
  .ds-input,
981
1026
  .ds-textarea,
982
1027
  .ds-select {
983
- width: 100%;
984
1028
  padding: 0 var(--ds-space-4);
985
1029
  font-family: var(--ds-font-sans);
986
1030
  font-size: var(--ds-text-base); /* 16px — prevents iOS auto-zoom on focus */
@@ -989,7 +1033,11 @@ hr {
989
1033
  background-color: var(--ds-color-surface);
990
1034
  border: 1px solid var(--ds-color-border);
991
1035
  border-radius: var(--ds-radius-lg);
992
- transition: all var(--ds-duration-fast) var(--ds-ease-default);
1036
+ outline: none;
1037
+ transition:
1038
+ border-color var(--ds-duration-fast) var(--ds-ease-default),
1039
+ box-shadow var(--ds-duration-fast) var(--ds-ease-default),
1040
+ background-color var(--ds-duration-fast) var(--ds-ease-default);
993
1041
  }
994
1042
 
995
1043
  .ds-input,
@@ -997,18 +1045,22 @@ hr {
997
1045
  height: var(--ds-size-3);
998
1046
  }
999
1047
 
1048
+ /* Hover */
1000
1049
  .ds-input:hover,
1001
1050
  .ds-textarea:hover,
1002
1051
  .ds-select:hover {
1003
1052
  border-color: var(--ds-color-border-hover);
1004
1053
  }
1005
1054
 
1006
- .ds-input:focus,
1007
- .ds-textarea:focus,
1008
- .ds-select:focus {
1009
- border-color: var(--ds-color-border-active);
1010
- box-shadow: inset 0 0 0 1px var(--ds-color-border-active);
1011
- outline: none;
1055
+ /* Focus — box-shadow ring instead of outline.
1056
+ Inputs always trigger :focus-visible (browser heuristic for text entry),
1057
+ so outline creates unavoidable double-border with offset.
1058
+ box-shadow follows border-radius perfectly and has no gap. */
1059
+ .ds-input:focus-visible,
1060
+ .ds-textarea:focus-visible,
1061
+ .ds-select:focus-visible {
1062
+ border-color: var(--ds-ring-color);
1063
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1012
1064
  }
1013
1065
 
1014
1066
  .ds-input::placeholder,
@@ -1016,19 +1068,32 @@ hr {
1016
1068
  color: var(--ds-color-text-tertiary);
1017
1069
  }
1018
1070
 
1019
- /* States */
1071
+ /* States — error: border + ring match the semantic color */
1020
1072
  .ds-input--error,
1021
1073
  .ds-textarea--error {
1022
1074
  border-color: var(--ds-color-error);
1023
1075
  }
1024
- .ds-input--error:focus,
1025
- .ds-textarea--error:focus {
1026
- box-shadow: inset 0 0 0 1px var(--ds-color-error);
1076
+ .ds-input--error:hover,
1077
+ .ds-textarea--error:hover {
1078
+ border-color: var(--ds-color-error);
1079
+ }
1080
+ .ds-input--error:focus-visible,
1081
+ .ds-textarea--error:focus-visible {
1082
+ border-color: var(--ds-color-error);
1083
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-color-error);
1027
1084
  }
1028
1085
 
1086
+ /* States — success: border + ring match the semantic color */
1029
1087
  .ds-input--success {
1030
1088
  border-color: var(--ds-color-success);
1031
1089
  }
1090
+ .ds-input--success:hover {
1091
+ border-color: var(--ds-color-success);
1092
+ }
1093
+ .ds-input--success:focus-visible {
1094
+ border-color: var(--ds-color-success);
1095
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-color-success);
1096
+ }
1032
1097
 
1033
1098
  /* Sizes */
1034
1099
  .ds-input--xs,
@@ -1075,6 +1140,50 @@ hr {
1075
1140
  padding-right: var(--ds-space-8);
1076
1141
  }
1077
1142
 
1143
+ /* --- Layout Modifiers ---
1144
+ Override default width/display/chrome assumptions. */
1145
+
1146
+ /* Full width (opt-in for select, already default for input/textarea) */
1147
+ .ds-select--full {
1148
+ width: 100%;
1149
+ }
1150
+
1151
+ /* Flush — naked input inside a styled container.
1152
+ No border, no background, no padding, no focus ring.
1153
+ The container handles visual chrome. */
1154
+ .ds-input--flush {
1155
+ background: transparent;
1156
+ border: none;
1157
+ padding: 0;
1158
+ border-radius: 0;
1159
+ box-shadow: none;
1160
+ height: auto;
1161
+ }
1162
+ .ds-input--flush:hover {
1163
+ border-color: transparent;
1164
+ }
1165
+ .ds-input--flush:focus-visible {
1166
+ border-color: transparent;
1167
+ box-shadow: none;
1168
+ }
1169
+
1170
+ /* Inline — auto-width for use in flex rows */
1171
+ .ds-input--inline {
1172
+ width: auto;
1173
+ display: inline-flex;
1174
+ }
1175
+
1176
+ /* --- Input Group: icon-right ---
1177
+ Move icon to the right side, flip input padding. */
1178
+ .ds-input-group--icon-right .ds-input-group__icon {
1179
+ left: auto;
1180
+ right: var(--ds-space-3);
1181
+ }
1182
+ .ds-input-group--icon-right .ds-input {
1183
+ padding-left: var(--ds-space-4);
1184
+ padding-right: calc(var(--ds-space-3) + 1rem + var(--ds-space-2));
1185
+ }
1186
+
1078
1187
  /* Help text */
1079
1188
  .ds-help {
1080
1189
  font-size: var(--ds-text-xs);
@@ -1205,8 +1314,8 @@ hr {
1205
1314
  /* Dot indicator */
1206
1315
  .ds-badge--dot::before {
1207
1316
  content: '';
1208
- width: 6px;
1209
- height: 6px;
1317
+ width: var(--ds-dot-size);
1318
+ height: var(--ds-dot-size);
1210
1319
  border-radius: var(--ds-radius-full);
1211
1320
  background-color: currentColor;
1212
1321
  }
@@ -1236,8 +1345,8 @@ hr {
1236
1345
  height: 4rem;
1237
1346
  background-color: var(--ds-color-nav-bg);
1238
1347
  border-bottom: 1px solid var(--ds-color-nav-border);
1239
- backdrop-filter: blur(20px) saturate(1.5);
1240
- -webkit-backdrop-filter: blur(20px) saturate(1.5);
1348
+ backdrop-filter: blur(var(--ds-blur-lg)) saturate(1.5);
1349
+ -webkit-backdrop-filter: blur(var(--ds-blur-lg)) saturate(1.5);
1241
1350
  }
1242
1351
 
1243
1352
  .ds-nav--static {
@@ -1280,6 +1389,11 @@ hr {
1280
1389
  }
1281
1390
  }
1282
1391
 
1392
+ .ds-nav__link:focus-visible {
1393
+ outline: none;
1394
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1395
+ }
1396
+
1283
1397
  .ds-nav__link--active {
1284
1398
  color: var(--ds-color-text);
1285
1399
  }
@@ -1309,13 +1423,18 @@ hr {
1309
1423
  }
1310
1424
  }
1311
1425
 
1426
+ .ds-nav__icon-btn:focus-visible {
1427
+ outline: none;
1428
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1429
+ }
1430
+
1312
1431
  /* --- Mobile nav overlay --- */
1313
1432
  .ds-nav__mobile {
1314
1433
  overflow: hidden;
1315
1434
  max-height: 0;
1316
1435
  border-bottom: 0 solid var(--ds-color-nav-border);
1317
1436
  background-color: var(--ds-color-nav-bg);
1318
- backdrop-filter: blur(20px);
1437
+ backdrop-filter: blur(var(--ds-blur-lg));
1319
1438
  transition: all var(--ds-duration-slow) var(--ds-ease-out-expo);
1320
1439
  }
1321
1440
 
@@ -1383,6 +1502,11 @@ hr {
1383
1502
  }
1384
1503
  }
1385
1504
 
1505
+ .ds-sidebar__link:focus-visible {
1506
+ outline: none;
1507
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1508
+ }
1509
+
1386
1510
  .ds-sidebar__link--active {
1387
1511
  color: var(--ds-color-text);
1388
1512
  background-color: var(--ds-color-bg-elevated);
@@ -1402,8 +1526,8 @@ hr {
1402
1526
  justify-content: center;
1403
1527
  padding: var(--ds-space-4);
1404
1528
  background-color: var(--ds-color-overlay);
1405
- backdrop-filter: blur(4px);
1406
- -webkit-backdrop-filter: blur(4px);
1529
+ backdrop-filter: blur(var(--ds-blur-sm));
1530
+ -webkit-backdrop-filter: blur(var(--ds-blur-sm));
1407
1531
  opacity: 0;
1408
1532
  visibility: hidden;
1409
1533
  transition:
@@ -1472,6 +1596,10 @@ hr {
1472
1596
  .ds-modal__close:hover {
1473
1597
  color: var(--ds-color-text);
1474
1598
  }
1599
+ .ds-modal__close:focus-visible {
1600
+ outline: none;
1601
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1602
+ }
1475
1603
 
1476
1604
  .ds-modal__body {
1477
1605
  padding: var(--ds-space-5);
@@ -1529,10 +1657,10 @@ hr {
1529
1657
  animation: ds-toast-in var(--ds-duration-slow) var(--ds-ease-out-expo) forwards;
1530
1658
  }
1531
1659
 
1532
- .ds-toast--info { border-left: 3px solid var(--ds-color-info); }
1533
- .ds-toast--success { border-left: 3px solid var(--ds-color-success); }
1534
- .ds-toast--warning { border-left: 3px solid var(--ds-color-warning); }
1535
- .ds-toast--error { border-left: 3px solid var(--ds-color-error); }
1660
+ .ds-toast--info { border-left: var(--ds-accent-border-width) solid var(--ds-color-info); }
1661
+ .ds-toast--success { border-left: var(--ds-accent-border-width) solid var(--ds-color-success); }
1662
+ .ds-toast--warning { border-left: var(--ds-accent-border-width) solid var(--ds-color-warning); }
1663
+ .ds-toast--error { border-left: var(--ds-accent-border-width) solid var(--ds-color-error); }
1536
1664
 
1537
1665
  .ds-toast__message {
1538
1666
  flex: 1;
@@ -1549,6 +1677,10 @@ hr {
1549
1677
  .ds-toast__close:hover {
1550
1678
  color: var(--ds-color-text);
1551
1679
  }
1680
+ .ds-toast__close:focus-visible {
1681
+ outline: none;
1682
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1683
+ }
1552
1684
 
1553
1685
  @keyframes ds-toast-in {
1554
1686
  from { opacity: 0; transform: translateY(-8px); }
@@ -1563,6 +1695,11 @@ hr {
1563
1695
  to { opacity: 0; transform: translateX(100%); }
1564
1696
  }
1565
1697
 
1698
+ @media (prefers-reduced-motion: reduce) {
1699
+ .ds-toast { animation: none; }
1700
+ .ds-toast--exit { animation: none; opacity: 0; }
1701
+ }
1702
+
1566
1703
  /* ==========================================================================
1567
1704
  Component: Table
1568
1705
  ========================================================================== */
@@ -1722,8 +1859,8 @@ hr {
1722
1859
  }
1723
1860
 
1724
1861
  .ds-tab:focus-visible {
1725
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
1726
- outline-offset: var(--ds-ring-offset);
1862
+ outline: none;
1863
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1727
1864
  border-radius: var(--ds-radius-sm);
1728
1865
  }
1729
1866
 
@@ -1792,7 +1929,7 @@ hr {
1792
1929
  border: 1px solid var(--ds-color-border);
1793
1930
  border-radius: var(--ds-radius-lg);
1794
1931
  background-color: var(--ds-color-surface);
1795
- border-left: 3px solid var(--ds-color-border);
1932
+ border-left: var(--ds-accent-border-width) solid var(--ds-color-border);
1796
1933
  }
1797
1934
 
1798
1935
  /* --- Semantic Variants --- */
@@ -1887,8 +2024,8 @@ hr {
1887
2024
  }
1888
2025
 
1889
2026
  .ds-alert__close:focus-visible {
1890
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
1891
- outline-offset: var(--ds-ring-offset);
2027
+ outline: none;
2028
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
1892
2029
  }
1893
2030
 
1894
2031
  /* --- Compact Variant --- */
@@ -2061,6 +2198,11 @@ hr {
2061
2198
  transform-origin: bottom right;
2062
2199
  }
2063
2200
 
2201
+ /* --- Width variants --- */
2202
+ .ds-dropdown__menu--sm { min-width: 8rem; }
2203
+ .ds-dropdown__menu--lg { min-width: 20rem; }
2204
+ .ds-dropdown__menu--auto { min-width: auto; }
2205
+
2064
2206
  /* --- Menu item --- */
2065
2207
 
2066
2208
  .ds-dropdown__item {
@@ -2083,6 +2225,10 @@ hr {
2083
2225
  background-color: var(--ds-color-bg-elevated);
2084
2226
  color: var(--ds-color-text);
2085
2227
  }
2228
+ .ds-dropdown__item:focus-visible {
2229
+ outline: none;
2230
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2231
+ }
2086
2232
 
2087
2233
  .ds-dropdown__item--active {
2088
2234
  background-color: var(--ds-color-bg-elevated);
@@ -2200,7 +2346,7 @@ hr {
2200
2346
 
2201
2347
  .ds-tooltip .ds-tooltip__content,
2202
2348
  .ds-tooltip--top .ds-tooltip__content {
2203
- bottom: calc(100% + 8px);
2349
+ bottom: calc(100% + var(--ds-offset-md));
2204
2350
  left: 50%;
2205
2351
  transform: translateX(-50%) translateY(4px);
2206
2352
  }
@@ -2224,7 +2370,7 @@ hr {
2224
2370
  ============================================= */
2225
2371
 
2226
2372
  .ds-tooltip--bottom .ds-tooltip__content {
2227
- top: calc(100% + 8px);
2373
+ top: calc(100% + var(--ds-offset-md));
2228
2374
  bottom: auto;
2229
2375
  left: 50%;
2230
2376
  transform: translateX(-50%) translateY(-4px);
@@ -2249,7 +2395,7 @@ hr {
2249
2395
  ============================================= */
2250
2396
 
2251
2397
  .ds-tooltip--left .ds-tooltip__content {
2252
- right: calc(100% + 8px);
2398
+ right: calc(100% + var(--ds-offset-md));
2253
2399
  left: auto;
2254
2400
  bottom: auto;
2255
2401
  top: 50%;
@@ -2276,7 +2422,7 @@ hr {
2276
2422
  ============================================= */
2277
2423
 
2278
2424
  .ds-tooltip--right .ds-tooltip__content {
2279
- left: calc(100% + 8px);
2425
+ left: calc(100% + var(--ds-offset-md));
2280
2426
  right: auto;
2281
2427
  bottom: auto;
2282
2428
  top: 50%;
@@ -2505,6 +2651,10 @@ hr {
2505
2651
  }
2506
2652
  }
2507
2653
 
2654
+ @media (prefers-reduced-motion: reduce) {
2655
+ .ds-skeleton { animation: none; }
2656
+ }
2657
+
2508
2658
  /* ==========================================================================
2509
2659
  Component: Empty State
2510
2660
  Centered message for when there's no data to display.
@@ -2575,6 +2725,12 @@ hr {
2575
2725
  border-radius: var(--ds-radius-xl);
2576
2726
  }
2577
2727
 
2728
+ /* --- Left-aligned variant --- */
2729
+ .ds-empty-state--left {
2730
+ align-items: flex-start;
2731
+ text-align: left;
2732
+ }
2733
+
2578
2734
 
2579
2735
  /* === Tier 2 — Common === */
2580
2736
  /* ==========================================================================
@@ -2636,11 +2792,16 @@ hr {
2636
2792
  line-height: 1;
2637
2793
  }
2638
2794
 
2795
+ .ds-datepicker__trigger:focus-visible {
2796
+ outline: none;
2797
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2798
+ }
2799
+
2639
2800
  /* Calendar panel */
2640
2801
  .ds-datepicker__panel {
2641
2802
  position: absolute;
2642
2803
  z-index: var(--ds-z-dropdown);
2643
- top: calc(100% + 4px);
2804
+ top: calc(100% + var(--ds-offset-sm));
2644
2805
  left: 0;
2645
2806
  background-color: var(--ds-color-surface);
2646
2807
  border: 1px solid var(--ds-color-border);
@@ -2652,8 +2813,8 @@ hr {
2652
2813
  visibility: hidden;
2653
2814
  transform: scale(0.96);
2654
2815
  transition:
2655
- opacity var(--ds-duration-fast) var(--ds-ease),
2656
- visibility var(--ds-duration-fast) var(--ds-ease),
2816
+ opacity var(--ds-duration-fast) var(--ds-ease-default),
2817
+ visibility var(--ds-duration-fast) var(--ds-ease-default),
2657
2818
  transform var(--ds-duration-fast) var(--ds-ease-out-expo);
2658
2819
  }
2659
2820
 
@@ -2674,7 +2835,7 @@ hr {
2674
2835
 
2675
2836
  .ds-datepicker__title {
2676
2837
  font-size: var(--ds-text-sm);
2677
- font-weight: 600;
2838
+ font-weight: var(--ds-weight-semibold);
2678
2839
  color: var(--ds-color-text);
2679
2840
  user-select: none;
2680
2841
  }
@@ -2691,13 +2852,17 @@ hr {
2691
2852
  color: var(--ds-color-text-secondary);
2692
2853
  cursor: pointer;
2693
2854
  font-size: var(--ds-text-base);
2694
- transition: all var(--ds-duration-fast) var(--ds-ease);
2855
+ transition: all var(--ds-duration-fast) var(--ds-ease-default);
2695
2856
  }
2696
2857
 
2697
2858
  .ds-datepicker__nav:hover {
2698
2859
  background-color: var(--ds-color-bg-elevated);
2699
2860
  color: var(--ds-color-text);
2700
2861
  }
2862
+ .ds-datepicker__nav:focus-visible {
2863
+ outline: none;
2864
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2865
+ }
2701
2866
 
2702
2867
  /* Weekday header row */
2703
2868
  .ds-datepicker__weekdays {
@@ -2712,7 +2877,7 @@ hr {
2712
2877
  text-align: center;
2713
2878
  padding: var(--ds-space-1) 0;
2714
2879
  user-select: none;
2715
- font-weight: 500;
2880
+ font-weight: var(--ds-weight-medium);
2716
2881
  }
2717
2882
 
2718
2883
  /* Day grid */
@@ -2734,7 +2899,7 @@ hr {
2734
2899
  font-size: var(--ds-text-sm);
2735
2900
  color: var(--ds-color-text);
2736
2901
  cursor: pointer;
2737
- transition: all var(--ds-duration-fast) var(--ds-ease);
2902
+ transition: all var(--ds-duration-fast) var(--ds-ease-default);
2738
2903
  padding: 0;
2739
2904
  line-height: 1;
2740
2905
  user-select: none;
@@ -2743,18 +2908,22 @@ hr {
2743
2908
  .ds-datepicker__day:hover {
2744
2909
  background-color: var(--ds-color-bg-elevated);
2745
2910
  }
2911
+ .ds-datepicker__day:focus-visible {
2912
+ outline: none;
2913
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2914
+ }
2746
2915
 
2747
2916
  /* Today — subtle ring */
2748
2917
  .ds-datepicker__day--today {
2749
2918
  box-shadow: inset 0 0 0 1px var(--ds-color-border-active);
2750
- font-weight: 600;
2919
+ font-weight: var(--ds-weight-semibold);
2751
2920
  }
2752
2921
 
2753
2922
  /* Selected — inverted fill */
2754
2923
  .ds-datepicker__day--selected {
2755
2924
  background-color: var(--ds-color-text);
2756
2925
  color: var(--ds-color-bg);
2757
- font-weight: 600;
2926
+ font-weight: var(--ds-weight-semibold);
2758
2927
  }
2759
2928
 
2760
2929
  .ds-datepicker__day--selected:hover {
@@ -2779,14 +2948,14 @@ hr {
2779
2948
 
2780
2949
  .ds-datepicker__today {
2781
2950
  font-size: var(--ds-text-xs);
2782
- font-weight: 500;
2951
+ font-weight: var(--ds-weight-medium);
2783
2952
  color: var(--ds-color-text-secondary);
2784
2953
  background: none;
2785
2954
  border: 1px solid var(--ds-color-border);
2786
2955
  border-radius: var(--ds-radius-full);
2787
2956
  padding: var(--ds-space-1) var(--ds-space-3);
2788
2957
  cursor: pointer;
2789
- transition: all var(--ds-duration-fast) var(--ds-ease);
2958
+ transition: all var(--ds-duration-fast) var(--ds-ease-default);
2790
2959
  }
2791
2960
 
2792
2961
  .ds-datepicker__today:hover {
@@ -2794,6 +2963,10 @@ hr {
2794
2963
  color: var(--ds-color-text);
2795
2964
  border-color: var(--ds-color-border-hover);
2796
2965
  }
2966
+ .ds-datepicker__today:focus-visible {
2967
+ outline: none;
2968
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2969
+ }
2797
2970
 
2798
2971
  /* Step arrows — prev/next day buttons beside the date text */
2799
2972
  .ds-datepicker__step {
@@ -2808,7 +2981,7 @@ hr {
2808
2981
  color: var(--ds-color-text-tertiary);
2809
2982
  cursor: pointer;
2810
2983
  font-size: var(--ds-text-xs);
2811
- transition: all var(--ds-duration-fast) var(--ds-ease);
2984
+ transition: all var(--ds-duration-fast) var(--ds-ease-default);
2812
2985
  padding: 0;
2813
2986
  flex-shrink: 0;
2814
2987
  }
@@ -2817,6 +2990,10 @@ hr {
2817
2990
  background-color: var(--ds-color-bg-elevated);
2818
2991
  color: var(--ds-color-text);
2819
2992
  }
2993
+ .ds-datepicker__step:focus-visible {
2994
+ outline: none;
2995
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2996
+ }
2820
2997
 
2821
2998
  /* Compact mode — for inline table cells */
2822
2999
  .ds-datepicker--compact .ds-datepicker__panel {
@@ -2835,7 +3012,7 @@ hr {
2835
3012
  }
2836
3013
 
2837
3014
  .ds-datepicker--compact .ds-datepicker__weekday {
2838
- font-size: 0.625rem;
3015
+ font-size: var(--ds-text-2xs);
2839
3016
  }
2840
3017
 
2841
3018
  .ds-datepicker--compact .ds-datepicker__day {
@@ -2843,7 +3020,7 @@ hr {
2843
3020
  }
2844
3021
 
2845
3022
  .ds-datepicker--compact .ds-datepicker__today {
2846
- font-size: 0.625rem;
3023
+ font-size: var(--ds-text-2xs);
2847
3024
  padding: 2px var(--ds-space-2);
2848
3025
  }
2849
3026
 
@@ -2937,8 +3114,8 @@ hr {
2937
3114
  --------------------------------------------------------------------------- */
2938
3115
 
2939
3116
  .ds-toggle:focus-visible {
2940
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
2941
- outline-offset: var(--ds-ring-offset);
3117
+ outline: none;
3118
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
2942
3119
  }
2943
3120
 
2944
3121
  /* ---------------------------------------------------------------------------
@@ -3057,8 +3234,8 @@ hr {
3057
3234
  }
3058
3235
 
3059
3236
  .ds-breadcrumb__link:focus-visible {
3060
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
3061
- outline-offset: var(--ds-ring-offset);
3237
+ outline: none;
3238
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3062
3239
  border-radius: var(--ds-radius-sm);
3063
3240
  }
3064
3241
 
@@ -3143,8 +3320,8 @@ hr {
3143
3320
  }
3144
3321
 
3145
3322
  .ds-pagination__item:focus-visible {
3146
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
3147
- outline-offset: var(--ds-ring-offset);
3323
+ outline: none;
3324
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3148
3325
  }
3149
3326
 
3150
3327
  /* ---------------------------------------------------------------------------
@@ -3202,8 +3379,8 @@ hr {
3202
3379
 
3203
3380
  .ds-pagination__prev:focus-visible,
3204
3381
  .ds-pagination__next:focus-visible {
3205
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
3206
- outline-offset: var(--ds-ring-offset);
3382
+ outline: none;
3383
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3207
3384
  }
3208
3385
 
3209
3386
  .ds-pagination__prev:disabled,
@@ -3295,6 +3472,7 @@ hr {
3295
3472
  /* Tags used as <button> for selection — no focus ring on click */
3296
3473
  button.ds-tag:focus-visible {
3297
3474
  outline: none;
3475
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3298
3476
  }
3299
3477
 
3300
3478
  /* ---------------------------------------------------------------------------
@@ -3377,8 +3555,8 @@ button.ds-tag:focus-visible {
3377
3555
  }
3378
3556
 
3379
3557
  .ds-tag__remove:focus-visible {
3380
- outline: var(--ds-ring-width) solid var(--ds-ring-color);
3381
- outline-offset: var(--ds-ring-offset);
3558
+ outline: none;
3559
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3382
3560
  opacity: 1;
3383
3561
  }
3384
3562
 
@@ -3498,6 +3676,10 @@ button.ds-tag:focus-visible {
3498
3676
  .ds-accordion__trigger:hover {
3499
3677
  background-color: var(--ds-color-overlay);
3500
3678
  }
3679
+ .ds-accordion__trigger:focus-visible {
3680
+ outline: none;
3681
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3682
+ }
3501
3683
 
3502
3684
  /* Open state – rotate chevron */
3503
3685
  .ds-accordion__item--open .ds-accordion__trigger::after {
@@ -3758,6 +3940,10 @@ button.ds-tag:focus-visible {
3758
3940
  background-color: var(--ds-color-overlay);
3759
3941
  color: var(--ds-color-text);
3760
3942
  }
3943
+ .ds-drawer__close:focus-visible {
3944
+ outline: none;
3945
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
3946
+ }
3761
3947
 
3762
3948
  /* ==========================================================================
3763
3949
  * Body
@@ -4042,6 +4228,10 @@ button.ds-tag:focus-visible {
4042
4228
  transition:
4043
4229
  background-color var(--ds-duration-fast) var(--ds-ease-default);
4044
4230
  }
4231
+ .ds-drop-zone:focus-visible {
4232
+ outline: none;
4233
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
4234
+ }
4045
4235
 
4046
4236
  :root:not(.dark) .ds-drop-zone {
4047
4237
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25'%3E%3Crect x='1' y='1' width='99%25' height='99%25' rx='16' ry='16' fill='none' stroke='%23d4d4d8' stroke-width='2' stroke-dasharray='10 8'/%3E%3C/svg%3E");
@@ -4173,6 +4363,12 @@ button.ds-tag:focus-visible {
4173
4363
  border-color: var(--ds-color-border-hover);
4174
4364
  }
4175
4365
 
4366
+ .ds-custom-select__trigger:focus-visible {
4367
+ border-color: var(--ds-color-border-active);
4368
+ outline: none;
4369
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
4370
+ }
4371
+
4176
4372
  .ds-custom-select__trigger--open {
4177
4373
  border-color: var(--ds-color-border-active);
4178
4374
  box-shadow: inset 0 0 0 1px var(--ds-color-border-active);
@@ -4336,6 +4532,10 @@ button.ds-tag:focus-visible {
4336
4532
  background-color: var(--ds-color-bg-elevated);
4337
4533
  color: var(--ds-color-text);
4338
4534
  }
4535
+ .ds-custom-select__option:focus-visible {
4536
+ outline: none;
4537
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
4538
+ }
4339
4539
 
4340
4540
  .ds-custom-select__option--selected {
4341
4541
  background-color: var(--ds-color-bg-elevated);
@@ -4445,6 +4645,15 @@ button.ds-tag:focus-visible {
4445
4645
  }
4446
4646
  }
4447
4647
 
4648
+ @media (prefers-reduced-motion: reduce) {
4649
+ .ds-custom-select__panel {
4650
+ animation: none;
4651
+ opacity: 1;
4652
+ transform: scale(1);
4653
+ }
4654
+ .ds-custom-select__backdrop { animation: none; opacity: 1; }
4655
+ }
4656
+
4448
4657
  /* ==========================================================================
4449
4658
  Component: Sortable
4450
4659
  Optional drag-to-reorder styles for table rows or list items.
@@ -4478,6 +4687,12 @@ tr:hover .ds-sortable__handle,
4478
4687
  opacity: 1;
4479
4688
  }
4480
4689
 
4690
+ .ds-sortable__handle:focus-visible {
4691
+ outline: none;
4692
+ box-shadow: 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
4693
+ border-radius: var(--ds-radius-sm);
4694
+ }
4695
+
4481
4696
  tr:hover .ds-sortable__handle,
4482
4697
  .ds-sortable-row:hover .ds-sortable__handle {
4483
4698
  color: var(--ds-color-text-secondary);
@@ -4557,7 +4772,7 @@ tr:hover .ds-sortable__handle,
4557
4772
  /* Placement: bottom (default) */
4558
4773
  .ds-popover__content,
4559
4774
  .ds-popover--bottom .ds-popover__content {
4560
- top: calc(100% + 8px);
4775
+ top: calc(100% + var(--ds-offset-md));
4561
4776
  left: 50%;
4562
4777
  transform: translateX(-50%) scale(0.96);
4563
4778
  }
@@ -4569,7 +4784,7 @@ tr:hover .ds-sortable__handle,
4569
4784
 
4570
4785
  /* Placement: top */
4571
4786
  .ds-popover--top .ds-popover__content {
4572
- bottom: calc(100% + 8px);
4787
+ bottom: calc(100% + var(--ds-offset-md));
4573
4788
  top: auto;
4574
4789
  left: 50%;
4575
4790
  transform: translateX(-50%) scale(0.96);
@@ -4581,7 +4796,7 @@ tr:hover .ds-sortable__handle,
4581
4796
 
4582
4797
  /* Placement: left */
4583
4798
  .ds-popover--left .ds-popover__content {
4584
- right: calc(100% + 8px);
4799
+ right: calc(100% + var(--ds-offset-md));
4585
4800
  top: 50%;
4586
4801
  left: auto;
4587
4802
  transform: translateY(-50%) scale(0.96);
@@ -4593,7 +4808,7 @@ tr:hover .ds-sortable__handle,
4593
4808
 
4594
4809
  /* Placement: right */
4595
4810
  .ds-popover--right .ds-popover__content {
4596
- left: calc(100% + 8px);
4811
+ left: calc(100% + var(--ds-offset-md));
4597
4812
  top: 50%;
4598
4813
  transform: translateY(-50%) scale(0.96);
4599
4814
  }
@@ -4688,12 +4903,12 @@ tr:hover .ds-sortable__handle,
4688
4903
  /* Focus ring */
4689
4904
  .ds-slider input[type="range"]:focus-visible::-webkit-slider-thumb {
4690
4905
  outline: var(--ds-ring-width) solid var(--ds-ring-color);
4691
- outline-offset: var(--ds-ring-offset);
4906
+ outline-offset: 0;
4692
4907
  }
4693
4908
 
4694
4909
  .ds-slider input[type="range"]:focus-visible::-moz-range-thumb {
4695
4910
  outline: var(--ds-ring-width) solid var(--ds-ring-color);
4696
- outline-offset: var(--ds-ring-offset);
4911
+ outline-offset: 0;
4697
4912
  }
4698
4913
 
4699
4914
  /* Labels row */
@@ -5071,6 +5286,10 @@ tr:hover .ds-sortable__handle,
5071
5286
  background-color: var(--ds-color-bg-elevated);
5072
5287
  color: var(--ds-color-text);
5073
5288
  }
5289
+ .ds-command__item:focus-visible {
5290
+ outline: none;
5291
+ box-shadow: inset 0 0 0 var(--ds-ring-width) var(--ds-ring-color);
5292
+ }
5074
5293
 
5075
5294
  /* Item icon */
5076
5295
  .ds-command__item-icon {
@@ -5304,11 +5523,15 @@ tr:hover .ds-sortable__handle,
5304
5523
  .ds-z-60 { z-index: var(--ds-z-sticky); }
5305
5524
 
5306
5525
  /* --- Inset / Position Values --- */
5307
- .ds-inset-0 { inset: 0; }
5308
- .ds-top-0 { top: 0; }
5309
- .ds-right-0 { right: 0; }
5310
- .ds-bottom-0 { bottom: 0; }
5311
- .ds-left-0 { left: 0; }
5526
+ .ds-inset-0 { inset: 0; }
5527
+ .ds-inset-x-0 { left: 0; right: 0; }
5528
+ .ds-inset-y-0 { top: 0; bottom: 0; }
5529
+ .ds-top-0 { top: 0; }
5530
+ .ds-top-full { top: 100%; }
5531
+ .ds-right-0 { right: 0; }
5532
+ .ds-bottom-0 { bottom: 0; }
5533
+ .ds-bottom-full { bottom: 100%; }
5534
+ .ds-left-0 { left: 0; }
5312
5535
  .ds-top-2 { top: var(--ds-space-2); }
5313
5536
  .ds-right-2 { right: var(--ds-space-2); }
5314
5537
  .ds-left-2 { left: var(--ds-space-2); }