@twentyfirstmedia/pro 0.5.0 → 0.6.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.
package/dist/styles.css CHANGED
@@ -303,6 +303,11 @@
303
303
  --chart-lilac: var(--fg-300);
304
304
  --chart-butter: var(--fg-200);
305
305
  --chart-blush: var(--line-300);
306
+ --ramp-1: color-mix(in oklab, var(--chart-1) 12%, var(--background));
307
+ --ramp-2: color-mix(in oklab, var(--chart-1) 28%, var(--background));
308
+ --ramp-3: color-mix(in oklab, var(--chart-1) 46%, var(--background));
309
+ --ramp-4: color-mix(in oklab, var(--chart-1) 66%, var(--background));
310
+ --ramp-5: color-mix(in oklab, var(--chart-1) 88%, var(--background));
306
311
  --ok: #5cc28f;
307
312
  --ok-bg: rgba(92,194,143,0.12);
308
313
  --info: #7aa7f5;
@@ -451,6 +456,11 @@
451
456
  --chart-lilac: var(--fg-300);
452
457
  --chart-butter: var(--fg-200);
453
458
  --chart-blush: var(--line-300);
459
+ --ramp-1: color-mix(in oklab, var(--chart-1) 12%, var(--background));
460
+ --ramp-2: color-mix(in oklab, var(--chart-1) 28%, var(--background));
461
+ --ramp-3: color-mix(in oklab, var(--chart-1) 46%, var(--background));
462
+ --ramp-4: color-mix(in oklab, var(--chart-1) 66%, var(--background));
463
+ --ramp-5: color-mix(in oklab, var(--chart-1) 88%, var(--background));
454
464
  --ok: #5cc28f;
455
465
  --ok-bg: rgba(92,194,143,0.12);
456
466
  --info: #7aa7f5;
@@ -600,6 +610,11 @@
600
610
  --chart-lilac: var(--fg-300);
601
611
  --chart-butter: var(--fg-200);
602
612
  --chart-blush: var(--line-300);
613
+ --ramp-1: color-mix(in oklab, var(--chart-1) 12%, var(--background));
614
+ --ramp-2: color-mix(in oklab, var(--chart-1) 28%, var(--background));
615
+ --ramp-3: color-mix(in oklab, var(--chart-1) 46%, var(--background));
616
+ --ramp-4: color-mix(in oklab, var(--chart-1) 66%, var(--background));
617
+ --ramp-5: color-mix(in oklab, var(--chart-1) 88%, var(--background));
603
618
  --ok: #177447;
604
619
  --ok-bg: rgba(23,116,71,0.09);
605
620
  --info: #2856b0;
@@ -748,6 +763,11 @@
748
763
  --chart-lilac: var(--fg-300);
749
764
  --chart-butter: var(--fg-200);
750
765
  --chart-blush: var(--line-300);
766
+ --ramp-1: color-mix(in oklab, var(--chart-1) 12%, var(--background));
767
+ --ramp-2: color-mix(in oklab, var(--chart-1) 28%, var(--background));
768
+ --ramp-3: color-mix(in oklab, var(--chart-1) 46%, var(--background));
769
+ --ramp-4: color-mix(in oklab, var(--chart-1) 66%, var(--background));
770
+ --ramp-5: color-mix(in oklab, var(--chart-1) 88%, var(--background));
751
771
  --ok: #5cc28f;
752
772
  --ok-bg: rgba(92,194,143,0.12);
753
773
  --info: #7aa7f5;
@@ -895,6 +915,11 @@
895
915
  --chart-lilac: var(--fg-300);
896
916
  --chart-butter: var(--fg-200);
897
917
  --chart-blush: var(--line-300);
918
+ --ramp-1: color-mix(in oklab, var(--chart-1) 12%, var(--background));
919
+ --ramp-2: color-mix(in oklab, var(--chart-1) 28%, var(--background));
920
+ --ramp-3: color-mix(in oklab, var(--chart-1) 46%, var(--background));
921
+ --ramp-4: color-mix(in oklab, var(--chart-1) 66%, var(--background));
922
+ --ramp-5: color-mix(in oklab, var(--chart-1) 88%, var(--background));
898
923
  --ok: #177447;
899
924
  --ok-bg: rgba(23,116,71,0.09);
900
925
  --info: #2856b0;
@@ -1450,7 +1475,8 @@ select.tf-input {
1450
1475
  border-radius: var(--radius-pill);
1451
1476
  background: var(--surface-sunken);
1452
1477
  color: var(--ink-muted);
1453
- min-width: 220px;
1478
+ min-width: min(220px, 100%);
1479
+ box-sizing: border-box;
1454
1480
  }
1455
1481
  .tf-search input {
1456
1482
  border: 0;
@@ -1459,6 +1485,7 @@ select.tf-input {
1459
1485
  font: 500 14px/20px var(--font-sans);
1460
1486
  color: var(--ink);
1461
1487
  width: 100%;
1488
+ min-width: 0;
1462
1489
  }
1463
1490
  .tf-search input::placeholder {
1464
1491
  color: var(--ink-subtle);
@@ -1540,7 +1567,7 @@ select.tf-input {
1540
1567
  display: flex;
1541
1568
  }
1542
1569
  .tf-tabs-block .tf-tab {
1543
- flex: 1;
1570
+ flex: 1 1 0;
1544
1571
  }
1545
1572
 
1546
1573
  /* StatTile */
@@ -1857,6 +1884,36 @@ select.tf-input {
1857
1884
  background: var(--accent);
1858
1885
  color: var(--accent-foreground);
1859
1886
  }
1887
+ /* expanded: names next to the icons (the sheet's first column follows the rail's width) */
1888
+ .tf-rail {
1889
+ transition: width var(--dur-base) var(--ease-out);
1890
+ }
1891
+ .tf-rail.expanded {
1892
+ width: 200px;
1893
+ }
1894
+ .tf-rail.expanded .tf-rail-group {
1895
+ align-items: stretch;
1896
+ }
1897
+ .tf-rail.expanded .tf-rail-btn {
1898
+ display: flex;
1899
+ align-items: center;
1900
+ gap: 12px;
1901
+ width: 100%;
1902
+ padding: 0 10px;
1903
+ box-sizing: border-box;
1904
+ border-radius: var(--radius-pill);
1905
+ }
1906
+ .tf-rail-label {
1907
+ min-width: 0;
1908
+ overflow: hidden;
1909
+ text-overflow: ellipsis;
1910
+ white-space: nowrap;
1911
+ font: 500 13px/18px var(--font-sans);
1912
+ }
1913
+ .tf-rail.expanded .tf-dotcount {
1914
+ position: static;
1915
+ margin-left: auto;
1916
+ }
1860
1917
  .tf-rail-btn[aria-current="page"] {
1861
1918
  background: var(--primary);
1862
1919
  color: var(--primary-foreground);
@@ -2006,9 +2063,28 @@ select.tf-input {
2006
2063
  .tf-shell .tf-topbar {
2007
2064
  padding: 0 var(--space-6);
2008
2065
  }
2066
+ /* AppShell with navigation="sidebar": the labelled sidebar on the frame, the sheet beside it */
2067
+ .tf-shell.tf-shell-sidebar {
2068
+ display: grid;
2069
+ grid-template-columns: auto minmax(0, 1fr);
2070
+ align-items: stretch;
2071
+ padding: 8px;
2072
+ }
2073
+ .tf-shell-tools {
2074
+ display: flex;
2075
+ justify-content: flex-end;
2076
+ flex-wrap: wrap;
2077
+ gap: 8px;
2078
+ }
2079
+ .tf-sheet.tf-sheet-norail {
2080
+ grid-template-columns: minmax(0, 1fr) 300px;
2081
+ }
2082
+ .tf-sheet.tf-sheet-norail.tf-sheet-2 {
2083
+ grid-template-columns: minmax(0, 1fr);
2084
+ }
2009
2085
  .tf-sheet {
2010
2086
  display: grid;
2011
- grid-template-columns: 44px 1fr 300px;
2087
+ grid-template-columns: auto 1fr 300px;
2012
2088
  gap: var(--space-6);
2013
2089
  padding: var(--space-6);
2014
2090
  background: var(--canvas);
@@ -2525,6 +2601,64 @@ select.tf-input {
2525
2601
  background: var(--accent);
2526
2602
  color: var(--accent-foreground);
2527
2603
  }
2604
+ a.tf-row-item {
2605
+ text-decoration: none;
2606
+ }
2607
+ .tf-row-text {
2608
+ min-width: 0;
2609
+ }
2610
+ /* not interactive: no hover, no pointer */
2611
+ .tf-row-item.static {
2612
+ cursor: default;
2613
+ }
2614
+ .tf-row-item.static:hover {
2615
+ background: transparent;
2616
+ color: var(--ink);
2617
+ }
2618
+ /* own buttons: the title is the link or button and its hit area stretches over the row */
2619
+ .tf-row-item.has-hit {
2620
+ position: relative;
2621
+ }
2622
+ .tf-row-item.has-hit:hover {
2623
+ background: transparent;
2624
+ color: var(--ink);
2625
+ }
2626
+ .tf-row-item.has-hit:has(.tf-row-hit:hover) {
2627
+ background: var(--accent);
2628
+ color: var(--accent-foreground);
2629
+ }
2630
+ .tf-row-item.has-hit:has(.tf-row-hit:focus-visible) {
2631
+ outline: 2px solid var(--focus);
2632
+ outline-offset: 2px;
2633
+ }
2634
+ .tf-row-hit {
2635
+ display: block;
2636
+ padding: 0;
2637
+ border: 0;
2638
+ background: none;
2639
+ color: inherit;
2640
+ font: inherit;
2641
+ text-align: left;
2642
+ text-decoration: none;
2643
+ cursor: pointer;
2644
+ outline: none;
2645
+ }
2646
+ .tf-row-hit::after {
2647
+ content: "";
2648
+ position: absolute;
2649
+ inset: 0;
2650
+ border-radius: inherit;
2651
+ }
2652
+ .tf-row-item.has-actions {
2653
+ grid-template-columns: auto 1fr auto auto;
2654
+ }
2655
+ .tf-row-actions {
2656
+ position: relative;
2657
+ z-index: 1;
2658
+ display: flex;
2659
+ align-items: center;
2660
+ gap: 4px;
2661
+ }
2528
2662
  .tf-row-item[aria-current="true"] {
2529
2663
  background: var(--surface);
2530
2664
  box-shadow: 0 0 0 var(--line-width) var(--line);
@@ -2536,12 +2670,27 @@ select.tf-input {
2536
2670
  gap: 8px;
2537
2671
  }
2538
2672
  .tf-row-sub {
2673
+ display: block;
2539
2674
  font: 500 13px/18px var(--font-sans);
2540
2675
  color: var(--ink-muted);
2541
2676
  white-space: nowrap;
2542
2677
  overflow: hidden;
2543
2678
  text-overflow: ellipsis;
2544
2679
  }
2680
+ /* titleLines / subtitleLines: wrap, then end in an ellipsis after that many lines */
2681
+ .tf-row-sub.clamp,
2682
+ .tf-row-clamp {
2683
+ display: -webkit-box;
2684
+ -webkit-box-orient: vertical;
2685
+ -webkit-line-clamp: var(--lines, 2);
2686
+ line-clamp: var(--lines, 2);
2687
+ white-space: normal;
2688
+ overflow: hidden;
2689
+ min-width: 0;
2690
+ }
2691
+ .tf-row-title.clamp {
2692
+ align-items: flex-start;
2693
+ }
2545
2694
  .tf-row-meta {
2546
2695
  font: 500 12px/16px var(--font-sans);
2547
2696
  color: var(--ink-muted);
@@ -2728,6 +2877,13 @@ select.tf-input {
2728
2877
  font: 500 13px/1 var(--font-sans);
2729
2878
  cursor: pointer;
2730
2879
  }
2880
+ a.tf-page {
2881
+ display: inline-flex;
2882
+ align-items: center;
2883
+ justify-content: center;
2884
+ box-sizing: border-box;
2885
+ text-decoration: none;
2886
+ }
2731
2887
  .tf-page:hover {
2732
2888
  background: var(--accent);
2733
2889
  color: var(--ink);
@@ -2738,18 +2894,42 @@ select.tf-input {
2738
2894
  }
2739
2895
  .tf-crumbs {
2740
2896
  display: flex;
2897
+ flex-wrap: wrap;
2741
2898
  align-items: center;
2742
2899
  gap: 6px;
2900
+ min-width: 0;
2743
2901
  font: 500 13px/18px var(--font-sans);
2744
2902
  color: var(--ink-muted);
2745
2903
  }
2746
- .tf-crumbs a {
2904
+ /* links and buttons get a 24px target without moving the text */
2905
+ .tf-crumb {
2906
+ display: inline-flex;
2907
+ align-items: center;
2908
+ min-height: 24px;
2909
+ max-width: 100%;
2910
+ padding: 0 4px;
2911
+ /* the target grows to 24px around the 18px line without moving the text */
2912
+ margin: -3px -4px;
2913
+ border: 0;
2914
+ border-radius: var(--radius-sm);
2915
+ background: none;
2747
2916
  color: inherit;
2917
+ font: inherit;
2748
2918
  text-decoration: none;
2919
+ overflow-wrap: anywhere;
2920
+ }
2921
+ a.tf-crumb,
2922
+ button.tf-crumb {
2923
+ cursor: pointer;
2749
2924
  }
2750
- .tf-crumbs a:hover {
2925
+ a.tf-crumb:hover,
2926
+ button.tf-crumb:hover {
2751
2927
  color: var(--ink);
2752
2928
  }
2929
+ .tf-crumb:focus-visible {
2930
+ outline: 2px solid var(--focus);
2931
+ outline-offset: 0;
2932
+ }
2753
2933
  .tf-crumbs [aria-current] {
2754
2934
  color: var(--ink);
2755
2935
  }
@@ -2791,7 +2971,7 @@ select.tf-input {
2791
2971
  cursor: pointer;
2792
2972
  }
2793
2973
  .tf-sheet-2 {
2794
- grid-template-columns: 44px 1fr;
2974
+ grid-template-columns: auto 1fr;
2795
2975
  }
2796
2976
  .tf-main {
2797
2977
  display: flex;
@@ -2861,6 +3041,26 @@ select.tf-input {
2861
3041
  justify-content: center;
2862
3042
  }
2863
3043
  }
3044
+ /* the TopBar measured that the labels do not fit: icons only, at any width */
3045
+ .tf-nav.tight .tf-nav-label {
3046
+ display: none;
3047
+ }
3048
+ .tf-nav.tight .tf-nav-item {
3049
+ position: relative;
3050
+ width: 36px;
3051
+ padding: 0;
3052
+ justify-content: center;
3053
+ }
3054
+ .tf-nav.tight .tf-nav-item .tf-nav-count {
3055
+ position: absolute;
3056
+ top: -2px;
3057
+ right: -4px;
3058
+ min-width: 16px;
3059
+ height: 16px;
3060
+ padding: 0 4px;
3061
+ font-size: 10px;
3062
+ line-height: 16px;
3063
+ }
2864
3064
  .tf-main {
2865
3065
  animation: none;
2866
3066
  }
@@ -2986,6 +3186,19 @@ select.tf-input {
2986
3186
  .tf-user-text {
2987
3187
  display: flex;
2988
3188
  flex-direction: column;
3189
+ min-width: 0;
3190
+ max-width: 200px;
3191
+ }
3192
+ /* a long name or address ends in an ellipsis instead of pushing the nav out (title has it whole) */
3193
+ .tf-user-name,
3194
+ .tf-user-mail {
3195
+ overflow: hidden;
3196
+ text-overflow: ellipsis;
3197
+ white-space: nowrap;
3198
+ }
3199
+ .tf-user {
3200
+ min-width: 0;
3201
+ flex-shrink: 1;
2989
3202
  }
2990
3203
 
2991
3204
  /* Checkbox: real box + SVG check (no pseudo-elements on the input) */
@@ -2998,9 +3211,12 @@ select.tf-input {
2998
3211
  }
2999
3212
  .tf-checkbox input {
3000
3213
  position: absolute;
3001
- inset: 0;
3002
- width: 100%;
3003
- height: 100%;
3214
+ /* the box keeps its size; the hit area is at least 24px (WCAG 2.2 target size) */
3215
+ top: 50%;
3216
+ left: 50%;
3217
+ translate: -50% -50%;
3218
+ width: max(24px, 100%);
3219
+ height: max(24px, 100%);
3004
3220
  margin: 0;
3005
3221
  opacity: 0;
3006
3222
  cursor: pointer;
@@ -4075,6 +4291,23 @@ select.tf-input {
4075
4291
  font: 500 13px/18px var(--font-sans);
4076
4292
  pointer-events: none;
4077
4293
  }
4294
+ /* an interactive control at the end (reveal password, clear, copy) */
4295
+ .tf-input-action {
4296
+ position: absolute;
4297
+ right: 4px;
4298
+ top: 50%;
4299
+ transform: translateY(-50%);
4300
+ display: inline-flex;
4301
+ }
4302
+ .tf-inputwrap.has-action .tf-input {
4303
+ padding-right: 44px;
4304
+ }
4305
+ .tf-inputwrap.has-action.has-suffix .tf-input {
4306
+ padding-right: 72px;
4307
+ }
4308
+ .tf-inputwrap.has-action .tf-input-suffix {
4309
+ right: 44px;
4310
+ }
4078
4311
  .tf-input-suffix.err {
4079
4312
  color: var(--blush-ink);
4080
4313
  }
@@ -4234,7 +4467,7 @@ select.tf-input {
4234
4467
  display: flex;
4235
4468
  }
4236
4469
  .tf-seg.block .tf-seg-item {
4237
- flex: 1;
4470
+ flex: 1 1 0;
4238
4471
  }
4239
4472
  .tf-seg-item {
4240
4473
  position: relative;
@@ -4846,6 +5079,10 @@ label.tf-menu-item {
4846
5079
  border-color var(--dur-fast) ease,
4847
5080
  background-color var(--dur-fast) ease;
4848
5081
  }
5082
+ .tf-drop.disabled {
5083
+ opacity: 0.5;
5084
+ cursor: not-allowed;
5085
+ }
4849
5086
  .tf-drop b {
4850
5087
  font: 500 14px/20px var(--font-sans);
4851
5088
  margin-top: 4px;
@@ -4908,6 +5145,7 @@ label.tf-menu-item {
4908
5145
  /* Alert, confirm, toaster */
4909
5146
  .tf-alert {
4910
5147
  display: flex;
5148
+ flex-wrap: wrap;
4911
5149
  align-items: flex-start;
4912
5150
  gap: 12px;
4913
5151
  padding: 12px 12px 12px 16px;
@@ -4951,7 +5189,8 @@ label.tf-menu-item {
4951
5189
  color: var(--lilac-ink);
4952
5190
  }
4953
5191
  .tf-alert-body {
4954
- flex: 1;
5192
+ /* when the alert is too narrow for text and actions, the actions move to their own line */
5193
+ flex: 1 1 200px;
4955
5194
  min-width: 0;
4956
5195
  display: flex;
4957
5196
  flex-direction: column;
@@ -4967,8 +5206,11 @@ label.tf-menu-item {
4967
5206
  .tf-alert-actions {
4968
5207
  flex: none;
4969
5208
  display: flex;
5209
+ flex-wrap: wrap;
4970
5210
  align-items: center;
4971
5211
  gap: 4px;
5212
+ max-width: 100%;
5213
+ margin-left: auto;
4972
5214
  }
4973
5215
  .tf-alert .tf-iconbtn-ghost {
4974
5216
  background: transparent;
@@ -5973,14 +6215,29 @@ label.tf-menu-item {
5973
6215
  display: inline-flex;
5974
6216
  align-items: center;
5975
6217
  gap: 8px;
5976
- height: var(--control-sm);
5977
- padding: 0 12px 0 4px;
6218
+ /* grows with a long title (two lines at most) instead of spilling over */
6219
+ min-height: var(--control-sm);
6220
+ box-sizing: border-box;
6221
+ padding: 4px 12px 4px 4px;
5978
6222
  border-radius: var(--radius-pill);
5979
6223
  background: var(--surface-sunken);
5980
6224
  color: var(--ink);
5981
6225
  text-decoration: none;
5982
6226
  font: 500 12px/16px var(--font-sans);
5983
- max-width: 260px;
6227
+ max-width: min(260px, 100%);
6228
+ }
6229
+ .tf-source-title {
6230
+ min-width: 0;
6231
+ display: -webkit-box;
6232
+ -webkit-box-orient: vertical;
6233
+ -webkit-line-clamp: 2;
6234
+ line-clamp: 2;
6235
+ overflow: hidden;
6236
+ overflow-wrap: anywhere;
6237
+ }
6238
+ .tf-source > .tf-ico,
6239
+ .tf-source-n {
6240
+ flex: none;
5984
6241
  }
5985
6242
  .tf-source:hover {
5986
6243
  background: var(--line);
@@ -7103,17 +7360,25 @@ label.tf-menu-item {
7103
7360
  color: var(--ink-muted);
7104
7361
  }
7105
7362
  .tf-csteps {
7363
+ /* one row at every width: steps shrink to their numbers instead of wrapping */
7364
+ container: tf-csteps / inline-size;
7106
7365
  display: flex;
7107
7366
  gap: 8px;
7108
7367
  margin: 0;
7109
7368
  padding: 0;
7110
7369
  list-style: none;
7111
- flex-wrap: wrap;
7112
7370
  }
7113
7371
  .tf-csteps li {
7114
7372
  display: flex;
7115
7373
  align-items: center;
7116
7374
  gap: 8px;
7375
+ min-width: 0;
7376
+ }
7377
+ .tf-cstep-label {
7378
+ min-width: 0;
7379
+ overflow: hidden;
7380
+ text-overflow: ellipsis;
7381
+ white-space: nowrap;
7117
7382
  }
7118
7383
  .tf-csteps li + li::before {
7119
7384
  content: "";
@@ -7142,6 +7407,40 @@ label.tf-menu-item {
7142
7407
  .tf-csteps button:disabled {
7143
7408
  cursor: default;
7144
7409
  }
7410
+ .tf-csteps button {
7411
+ min-width: 0;
7412
+ max-width: 100%;
7413
+ }
7414
+ .tf-csteps.compact li:not(.cur) .tf-cstep-label {
7415
+ position: absolute;
7416
+ width: 1px;
7417
+ height: 1px;
7418
+ overflow: hidden;
7419
+ clip-path: inset(50%);
7420
+ white-space: nowrap;
7421
+ }
7422
+ .tf-csteps.compact li:not(.cur) button {
7423
+ padding: 0 4px;
7424
+ }
7425
+ .tf-csteps.compact li + li::before {
7426
+ width: 12px;
7427
+ }
7428
+ @container tf-csteps (max-width: 560px) {
7429
+ .tf-csteps li:not(.cur) .tf-cstep-label {
7430
+ position: absolute;
7431
+ width: 1px;
7432
+ height: 1px;
7433
+ overflow: hidden;
7434
+ clip-path: inset(50%);
7435
+ white-space: nowrap;
7436
+ }
7437
+ .tf-csteps li:not(.cur) button {
7438
+ padding: 0 4px;
7439
+ }
7440
+ .tf-csteps li + li::before {
7441
+ width: 12px;
7442
+ }
7443
+ }
7145
7444
  .tf-csteps li.cur button {
7146
7445
  background: var(--surface);
7147
7446
  color: var(--ink);
@@ -7308,7 +7607,7 @@ label.tf-menu-item {
7308
7607
  color: var(--on-frame);
7309
7608
  box-shadow: var(--shadow-float), 0 0 0 var(--line-width) var(--line);
7310
7609
  }
7311
- .tf-plan.featured .tf-plan-head span,
7610
+ .tf-plan.featured .tf-plan-head span:not(.tf-badge),
7312
7611
  .tf-plan.featured .tf-plan-price span,
7313
7612
  .tf-plan.featured .tf-plan-price s,
7314
7613
  .tf-plan.featured .tf-plan-feats li.no {
@@ -7339,10 +7638,22 @@ label.tf-menu-item {
7339
7638
  .tf-plan-head b {
7340
7639
  font: 600 18px/24px var(--font-sans);
7341
7640
  }
7342
- .tf-plan-head span {
7641
+ .tf-plan-head span:not(.tf-badge) {
7343
7642
  font: 500 13px/18px var(--font-sans);
7344
7643
  color: var(--ink-muted);
7345
7644
  }
7645
+ /* "Current plan" next to the name, and the note under the price */
7646
+ .tf-plan-head .tf-plan-current {
7647
+ align-self: flex-start;
7648
+ }
7649
+ .tf-plan-note {
7650
+ margin: -4px 0 0;
7651
+ font: 500 12px/16px var(--font-sans);
7652
+ color: var(--ink-muted);
7653
+ }
7654
+ a.tf-plan-cta {
7655
+ text-decoration: none;
7656
+ }
7346
7657
  .tf-plan-price {
7347
7658
  display: flex;
7348
7659
  align-items: baseline;
@@ -9443,7 +9754,7 @@ label.tf-menu-item {
9443
9754
  .tf-tabbar {
9444
9755
  display: grid;
9445
9756
  grid-auto-flow: column;
9446
- grid-auto-columns: 1fr;
9757
+ grid-auto-columns: minmax(0, 1fr);
9447
9758
  padding: 4px 8px calc(4px + env(safe-area-inset-bottom, 0px));
9448
9759
  background: var(--frame);
9449
9760
  border-radius: var(--radius-1) var(--radius-1) 0 0;
@@ -9462,6 +9773,17 @@ label.tf-menu-item {
9462
9773
  cursor: pointer;
9463
9774
  border-radius: var(--radius-1);
9464
9775
  }
9776
+ .tf-tabbar-item {
9777
+ min-width: 0;
9778
+ }
9779
+ .tf-tabbar-label {
9780
+ max-width: 100%;
9781
+ padding: 0 4px;
9782
+ box-sizing: border-box;
9783
+ overflow: hidden;
9784
+ text-overflow: ellipsis;
9785
+ white-space: nowrap;
9786
+ }
9465
9787
  .tf-tabbar-item.on {
9466
9788
  color: var(--on-frame);
9467
9789
  background: var(--frame-hover);
@@ -9770,6 +10092,22 @@ label.tf-menu-item {
9770
10092
  padding-bottom: 10px;
9771
10093
  color: var(--ink-muted);
9772
10094
  }
10095
+ /* in a narrow column (a filter sidebar) the number fields give their padding to the digits */
10096
+ .tf-range {
10097
+ container: tf-range / inline-size;
10098
+ }
10099
+ @container tf-range (max-width: 280px) {
10100
+ .tf-range-inputs {
10101
+ gap: 4px;
10102
+ }
10103
+ .tf-range-num .tf-input {
10104
+ padding-left: 10px;
10105
+ padding-right: 24px;
10106
+ }
10107
+ .tf-range-num > span {
10108
+ right: 10px;
10109
+ }
10110
+ }
9773
10111
  .tf-range-vals {
9774
10112
  display: flex;
9775
10113
  justify-content: space-between;
@@ -9923,6 +10261,31 @@ label.tf-menu-item {
9923
10261
  font: 500 12px/16px var(--font-sans);
9924
10262
  color: var(--ink-muted);
9925
10263
  }
10264
+ /* layout="list": compact rows */
10265
+ .tf-tiles.list {
10266
+ grid-template-columns: minmax(0, 1fr);
10267
+ gap: 8px;
10268
+ }
10269
+ .tf-tiles.list .tf-tile {
10270
+ flex-direction: row;
10271
+ align-items: center;
10272
+ gap: 12px;
10273
+ padding: 8px 44px 8px 8px;
10274
+ }
10275
+ .tf-tiles.list .tf-tile-art {
10276
+ flex: none;
10277
+ width: 40px;
10278
+ height: var(--density-control);
10279
+ aspect-ratio: auto;
10280
+ }
10281
+ .tf-tiles.list .tf-tile-label {
10282
+ min-width: 0;
10283
+ padding: 0;
10284
+ }
10285
+ .tf-tiles.list .tf-tile-check {
10286
+ top: 50%;
10287
+ translate: 0 -50%;
10288
+ }
9926
10289
  .tf-tile-check {
9927
10290
  position: absolute;
9928
10291
  top: 14px;
@@ -11032,6 +11395,16 @@ button.tf-runs-main[aria-expanded]:hover {
11032
11395
  color: var(--paper-ink);
11033
11396
  box-shadow: inset 0 0 0 1px var(--line);
11034
11397
  }
11398
+ /* QrCode: dark modules on paper, in every theme (scanners expect dark on light) */
11399
+ .tf-qr {
11400
+ display: block;
11401
+ width: 100%;
11402
+ height: auto;
11403
+ color: var(--paper-ink);
11404
+ }
11405
+ .tf-qr-bg {
11406
+ fill: var(--paper);
11407
+ }
11035
11408
  .tf-2fa-qr > * {
11036
11409
  max-width: 100%;
11037
11410
  max-height: 100%;
@@ -11283,7 +11656,8 @@ button.tf-runs-main[aria-expanded]:hover {
11283
11656
  border-radius: var(--radius-md);
11284
11657
  overflow: hidden;
11285
11658
  background: var(--surface-sunken);
11286
- touch-action: none;
11659
+ /* sideways drags move the divider; the page still scrolls up and down over it */
11660
+ touch-action: pan-y;
11287
11661
  user-select: none;
11288
11662
  cursor: ew-resize;
11289
11663
  }
@@ -12183,6 +12557,14 @@ button.tf-runs-main[aria-expanded]:hover {
12183
12557
  .tf-togglegroup .tf-toggle {
12184
12558
  height: var(--control-sm);
12185
12559
  }
12560
+ .tf-togglegroup.block {
12561
+ display: flex;
12562
+ flex-wrap: nowrap;
12563
+ width: auto;
12564
+ }
12565
+ .tf-togglegroup.block .tf-toggle {
12566
+ flex: 1 1 0;
12567
+ }
12186
12568
  .tf-togglegroup .tf-toggle.icon {
12187
12569
  width: 32px;
12188
12570
  }
@@ -12393,6 +12775,11 @@ button.tf-runs-main[aria-expanded]:hover {
12393
12775
  text-align: left;
12394
12776
  cursor: pointer;
12395
12777
  }
12778
+ .tf-selectmenu.sm {
12779
+ height: var(--control-sm);
12780
+ padding: 0 12px;
12781
+ font-size: 13px;
12782
+ }
12396
12783
  .tf-selectmenu.empty .tf-selectmenu-value {
12397
12784
  color: var(--ink-subtle);
12398
12785
  }
@@ -12669,26 +13056,44 @@ button.tf-runs-main[aria-expanded]:hover {
12669
13056
  outline-offset: -2px;
12670
13057
  }
12671
13058
 
12672
- /* Sidebar */
13059
+ /* Sidebar: floating (a card), attached (flush with the screen's edge) or on the AppShell frame */
12673
13060
  .tf-sidebar {
12674
13061
  display: flex;
12675
13062
  flex-direction: column;
12676
- gap: 16px;
13063
+ flex: none;
13064
+ gap: 12px;
12677
13065
  width: 248px;
12678
13066
  padding: 12px;
12679
13067
  box-sizing: border-box;
12680
13068
  border-radius: var(--radius-lg);
12681
13069
  background: var(--surface);
12682
13070
  box-shadow: 0 0 0 var(--line-width) var(--line);
13071
+ color: var(--ink);
12683
13072
  transition: width var(--dur-base) var(--ease-out);
12684
13073
  }
12685
13074
  .tf-sidebar.collapsed {
12686
13075
  width: 64px;
12687
13076
  }
13077
+ .tf-sidebar.attached {
13078
+ align-self: stretch;
13079
+ min-height: 100%;
13080
+ border-radius: 0;
13081
+ box-shadow: none;
13082
+ background: var(--sidebar);
13083
+ border-right: 1px solid var(--sidebar-border);
13084
+ }
13085
+ .tf-sidebar-head {
13086
+ display: flex;
13087
+ align-items: center;
13088
+ gap: 8px;
13089
+ min-height: var(--density-control);
13090
+ padding: 0 4px;
13091
+ }
12688
13092
  .tf-sidebar-body {
12689
13093
  display: flex;
12690
13094
  flex-direction: column;
12691
- gap: 16px;
13095
+ /* groups sit clearly apart; a label sits close to its own items */
13096
+ gap: 20px;
12692
13097
  flex: 1;
12693
13098
  min-height: 0;
12694
13099
  overflow-y: auto;
@@ -12701,13 +13106,49 @@ button.tf-runs-main[aria-expanded]:hover {
12701
13106
  padding: 0;
12702
13107
  list-style: none;
12703
13108
  }
13109
+ .tf-sidebar-grouphead {
13110
+ display: flex;
13111
+ align-items: center;
13112
+ gap: 4px;
13113
+ min-height: 24px;
13114
+ margin-bottom: 8px;
13115
+ padding: 0 4px 0 12px;
13116
+ }
12704
13117
  .tf-sidebar-grouplabel {
12705
- padding: 0 12px 6px;
13118
+ display: flex;
13119
+ align-items: center;
13120
+ gap: 4px;
13121
+ flex: 1;
13122
+ min-width: 0;
13123
+ padding: 0;
13124
+ border: 0;
13125
+ background: none;
12706
13126
  font: 500 11px/14px var(--font-sans);
12707
13127
  letter-spacing: 0.06em;
12708
13128
  text-transform: uppercase;
13129
+ text-align: left;
12709
13130
  color: var(--ink-muted);
12710
13131
  }
13132
+ button.tf-sidebar-grouplabel {
13133
+ cursor: pointer;
13134
+ }
13135
+ button.tf-sidebar-grouplabel:hover {
13136
+ color: var(--ink);
13137
+ }
13138
+ button.tf-sidebar-grouplabel:focus-visible {
13139
+ outline: 2px solid var(--focus);
13140
+ outline-offset: 2px;
13141
+ }
13142
+ .tf-sidebar-grouplabel[aria-expanded="false"] .tf-sidebar-chev {
13143
+ transform: rotate(-90deg);
13144
+ }
13145
+ .tf-sidebar-groupaction {
13146
+ flex: none;
13147
+ margin-left: auto;
13148
+ }
13149
+ .tf-sidebar-li {
13150
+ position: relative;
13151
+ }
12711
13152
  .tf-sidebar-item {
12712
13153
  display: flex;
12713
13154
  align-items: center;
@@ -12715,15 +13156,86 @@ button.tf-runs-main[aria-expanded]:hover {
12715
13156
  width: 100%;
12716
13157
  height: var(--density-control);
12717
13158
  padding: 0 12px;
13159
+ box-sizing: border-box;
12718
13160
  border: 0;
12719
13161
  border-radius: var(--radius-pill);
12720
13162
  background: transparent;
12721
13163
  color: var(--ink-muted);
12722
13164
  font: 500 13px/18px var(--font-sans);
12723
13165
  text-align: left;
13166
+ text-decoration: none;
12724
13167
  cursor: pointer;
12725
13168
  }
12726
- .tf-sidebar-item:hover {
13169
+ /* Filter options (Sidebar as="aside"): a checkbox or radio mark, the label and a count */
13170
+ .tf-sidebar-option {
13171
+ position: relative;
13172
+ }
13173
+ .tf-sidebar-option.disabled {
13174
+ opacity: 0.45;
13175
+ cursor: default;
13176
+ }
13177
+ .tf-sidebar-input {
13178
+ position: absolute;
13179
+ width: 1px;
13180
+ height: 1px;
13181
+ margin: 0;
13182
+ opacity: 0;
13183
+ pointer-events: none;
13184
+ }
13185
+ .tf-sidebar-mark {
13186
+ display: grid;
13187
+ place-items: center;
13188
+ flex: none;
13189
+ width: 18px;
13190
+ height: 18px;
13191
+ box-sizing: border-box;
13192
+ border-radius: var(--radius-1);
13193
+ border: 1.5px solid var(--line-strong);
13194
+ background: var(--surface);
13195
+ color: var(--primary-foreground);
13196
+ transition:
13197
+ background-color var(--dur-fast) var(--ease-out),
13198
+ border-color var(--dur-fast) var(--ease-out);
13199
+ }
13200
+ .tf-sidebar-mark.radio {
13201
+ border-radius: var(--radius-full);
13202
+ }
13203
+ .tf-sidebar-mark svg {
13204
+ opacity: 0;
13205
+ }
13206
+ .tf-sidebar-input:checked + .tf-sidebar-mark {
13207
+ background: var(--primary);
13208
+ border-color: var(--primary);
13209
+ }
13210
+ .tf-sidebar-input:checked + .tf-sidebar-mark.radio {
13211
+ box-shadow: inset 0 0 0 3px var(--surface);
13212
+ }
13213
+ .tf-sidebar-input:checked + .tf-sidebar-mark svg {
13214
+ opacity: 1;
13215
+ }
13216
+ .tf-sidebar-input:focus-visible + .tf-sidebar-mark {
13217
+ outline: 2px solid var(--focus);
13218
+ outline-offset: 2px;
13219
+ }
13220
+ .tf-sidebar-option:has(.tf-sidebar-input:checked) {
13221
+ color: var(--ink);
13222
+ }
13223
+ /* free content in a group (sliders, date fields, chips) */
13224
+ .tf-sidebar-content {
13225
+ display: flex;
13226
+ flex-direction: column;
13227
+ gap: 12px;
13228
+ padding: 4px 12px 0;
13229
+ min-width: 0;
13230
+ }
13231
+ .tf-sidebar-groupbody {
13232
+ display: flex;
13233
+ flex-direction: column;
13234
+ gap: 2px;
13235
+ min-width: 0;
13236
+ }
13237
+ .tf-sidebar-item:hover,
13238
+ .tf-sidebar-item.flying {
12727
13239
  background: var(--sidebar-accent);
12728
13240
  color: var(--ink);
12729
13241
  }
@@ -12738,10 +13250,21 @@ button.tf-runs-main[aria-expanded]:hover {
12738
13250
  outline: 2px solid var(--focus);
12739
13251
  outline-offset: 2px;
12740
13252
  }
13253
+ .tf-sidebar-item:disabled {
13254
+ opacity: 0.45;
13255
+ cursor: not-allowed;
13256
+ }
13257
+ .tf-sidebar-item:disabled:hover {
13258
+ background: transparent;
13259
+ color: var(--ink-muted);
13260
+ }
12741
13261
  .tf-sidebar-item.nested {
12742
13262
  height: var(--control-sm);
12743
13263
  padding-left: 40px;
12744
13264
  }
13265
+ .tf-sidebar-sub {
13266
+ margin-top: 2px !important;
13267
+ }
12745
13268
  .tf-sidebar-label {
12746
13269
  flex: 1;
12747
13270
  min-width: 0;
@@ -12750,22 +13273,107 @@ button.tf-runs-main[aria-expanded]:hover {
12750
13273
  white-space: nowrap;
12751
13274
  }
12752
13275
  .tf-sidebar-chev {
13276
+ flex: none;
12753
13277
  transition: transform var(--dur-base) var(--ease-out);
12754
13278
  }
12755
13279
  .tf-sidebar-item[aria-expanded="true"] .tf-sidebar-chev {
12756
13280
  transform: rotate(180deg);
12757
13281
  }
13282
+ .tf-sidebar-ext {
13283
+ flex: none;
13284
+ opacity: 0.7;
13285
+ }
13286
+ .tf-sidebar-count {
13287
+ flex: none;
13288
+ min-width: 20px;
13289
+ height: 20px;
13290
+ padding: 0 6px;
13291
+ box-sizing: border-box;
13292
+ border-radius: var(--radius-pill);
13293
+ background: var(--count);
13294
+ color: var(--on-count);
13295
+ font: 600 11px/20px var(--font-sans);
13296
+ text-align: center;
13297
+ }
13298
+ .tf-sidebar-badge {
13299
+ flex: none;
13300
+ height: 20px;
13301
+ padding: 0 8px;
13302
+ box-sizing: border-box;
13303
+ border-radius: var(--radius-pill);
13304
+ background: var(--count);
13305
+ color: var(--on-count);
13306
+ font: 600 10px/20px var(--font-sans);
13307
+ letter-spacing: 0.04em;
13308
+ text-transform: uppercase;
13309
+ }
13310
+ .tf-sidebar-dot {
13311
+ flex: none;
13312
+ width: 8px;
13313
+ height: 8px;
13314
+ border-radius: var(--radius-full);
13315
+ background: var(--count);
13316
+ }
13317
+ .tf-sidebar-sr {
13318
+ position: absolute;
13319
+ width: 1px;
13320
+ height: 1px;
13321
+ overflow: hidden;
13322
+ clip-path: inset(50%);
13323
+ white-space: nowrap;
13324
+ }
13325
+ /* the "…" menu of an item shows on hover and focus */
13326
+ .tf-sidebar-li.with-actions > .tf-sidebar-item {
13327
+ padding-right: 40px;
13328
+ }
13329
+ .tf-sidebar-more {
13330
+ position: absolute;
13331
+ top: 4px;
13332
+ right: 4px;
13333
+ opacity: 0;
13334
+ transition: opacity var(--dur-fast) var(--ease-out);
13335
+ }
13336
+ .tf-sidebar-li:hover > .tf-sidebar-more,
13337
+ .tf-sidebar-more:focus-visible,
13338
+ .tf-sidebar-more[aria-expanded="true"] {
13339
+ opacity: 1;
13340
+ }
12758
13341
  .tf-sidebar-foot {
12759
13342
  display: flex;
12760
13343
  align-items: center;
12761
- justify-content: space-between;
12762
13344
  gap: 8px;
12763
13345
  padding-top: 12px;
12764
13346
  border-top: 1px solid var(--sidebar-border);
12765
13347
  }
13348
+ .tf-sidebar-foot > :not(.tf-sidebar-toggle) {
13349
+ flex: 1;
13350
+ min-width: 0;
13351
+ }
13352
+ .tf-sidebar-toggle {
13353
+ flex: none;
13354
+ margin-left: auto;
13355
+ }
13356
+ .tf-sidebar-head .tf-pop-anchor,
13357
+ .tf-sidebar-foot .tf-pop-anchor {
13358
+ display: block;
13359
+ min-width: 0;
13360
+ }
13361
+ .tf-sidebar-head .tf-wssw {
13362
+ width: 100%;
13363
+ }
13364
+ .tf-sidebar-head .tf-wssw .tf-option-text {
13365
+ flex: 1;
13366
+ min-width: 0;
13367
+ }
13368
+
13369
+ /* collapsed: icons only; labels stay the accessible names, tooltips and flyouts show them */
13370
+ .tf-sidebar.collapsed .tf-sidebar-body {
13371
+ gap: 12px;
13372
+ }
12766
13373
  .tf-sidebar.collapsed .tf-sidebar-label,
12767
13374
  .tf-sidebar.collapsed .tf-sidebar-chev,
12768
- .tf-sidebar.collapsed .tf-sidebar-grouplabel {
13375
+ .tf-sidebar.collapsed .tf-sidebar-ext,
13376
+ .tf-sidebar.collapsed .tf-sidebar-grouphead {
12769
13377
  position: absolute;
12770
13378
  width: 1px;
12771
13379
  height: 1px;
@@ -12773,12 +13381,19 @@ button.tf-runs-main[aria-expanded]:hover {
12773
13381
  clip-path: inset(50%);
12774
13382
  white-space: nowrap;
12775
13383
  }
13384
+ .tf-sidebar.collapsed .tf-sidebar-group + .tf-sidebar-group {
13385
+ padding-top: 12px;
13386
+ border-top: 1px solid var(--sidebar-border);
13387
+ }
12776
13388
  .tf-sidebar.collapsed .tf-sidebar-item {
12777
13389
  position: relative;
12778
13390
  justify-content: center;
12779
13391
  padding: 0;
12780
13392
  }
12781
- .tf-sidebar.collapsed .tf-subnav-count {
13393
+ .tf-sidebar.collapsed .tf-sidebar-item.has-current {
13394
+ background: var(--sidebar-accent);
13395
+ }
13396
+ .tf-sidebar.collapsed .tf-sidebar-count {
12782
13397
  position: absolute;
12783
13398
  top: -2px;
12784
13399
  right: -2px;
@@ -12788,13 +13403,273 @@ button.tf-runs-main[aria-expanded]:hover {
12788
13403
  font-size: 10px;
12789
13404
  line-height: 16px;
12790
13405
  }
13406
+ .tf-sidebar.collapsed .tf-sidebar-dot,
13407
+ .tf-sidebar.collapsed .tf-sidebar-badge {
13408
+ position: absolute;
13409
+ top: 6px;
13410
+ right: 8px;
13411
+ width: 8px;
13412
+ height: 8px;
13413
+ padding: 0;
13414
+ font-size: 0;
13415
+ }
13416
+ .tf-sidebar.collapsed .tf-sidebar-head {
13417
+ justify-content: center;
13418
+ padding: 0;
13419
+ }
12791
13420
  .tf-sidebar.collapsed .tf-sidebar-foot {
12792
13421
  flex-direction: column;
12793
13422
  }
13423
+ .tf-sidebar.collapsed .tf-sidebar-foot > :not(.tf-sidebar-toggle) {
13424
+ flex: none;
13425
+ }
13426
+ .tf-sidebar.collapsed .tf-sidebar-toggle {
13427
+ margin-left: 0;
13428
+ }
13429
+
13430
+ /* tooltips, flyouts and item menus float in the portal, so the scrolling body does not clip them */
13431
+ .tf-sidebar-layer {
13432
+ position: fixed;
13433
+ z-index: var(--z-palette);
13434
+ }
13435
+ .tf-sidebar-tip {
13436
+ display: inline-flex;
13437
+ align-items: center;
13438
+ gap: 8px;
13439
+ padding: 4px 8px;
13440
+ border-radius: var(--radius-sm);
13441
+ background: var(--frame);
13442
+ color: var(--on-frame);
13443
+ font: 500 12px/16px var(--font-sans);
13444
+ white-space: nowrap;
13445
+ pointer-events: none;
13446
+ animation: tf-fade var(--dur-fast) var(--ease-out) both;
13447
+ }
13448
+ .tf-sidebar-tipcount {
13449
+ color: var(--on-frame-muted);
13450
+ }
13451
+ .tf-sidebar-flyout {
13452
+ min-width: 200px;
13453
+ padding: 6px;
13454
+ border-radius: var(--radius-md);
13455
+ background: var(--surface);
13456
+ color: var(--ink);
13457
+ box-shadow: var(--shadow-float), 0 0 0 var(--line-width) var(--line);
13458
+ animation: tf-fade var(--dur-fast) var(--ease-out) both;
13459
+ }
13460
+ .tf-sidebar-flyout ul {
13461
+ display: flex;
13462
+ flex-direction: column;
13463
+ gap: 2px;
13464
+ margin: 0;
13465
+ padding: 0;
13466
+ list-style: none;
13467
+ }
13468
+ .tf-sidebar-flytitle {
13469
+ padding: 6px 12px 8px;
13470
+ font: 500 11px/14px var(--font-sans);
13471
+ letter-spacing: 0.06em;
13472
+ text-transform: uppercase;
13473
+ color: var(--ink-muted);
13474
+ }
13475
+ .tf-sidebar-flyout .tf-sidebar-item.nested {
13476
+ padding-left: 12px;
13477
+ }
13478
+
13479
+ /* on the AppShell frame */
13480
+ .tf-sidebar.shell {
13481
+ align-self: stretch;
13482
+ padding: 16px 8px 8px;
13483
+ border-radius: 0;
13484
+ background: transparent;
13485
+ box-shadow: none;
13486
+ color: var(--on-frame);
13487
+ }
13488
+ .tf-sidebar.shell .tf-sidebar-item,
13489
+ .tf-sidebar.shell .tf-sidebar-grouplabel {
13490
+ color: var(--on-frame-muted);
13491
+ }
13492
+ .tf-sidebar.shell .tf-sidebar-item:hover,
13493
+ .tf-sidebar.shell .tf-sidebar-item.flying,
13494
+ .tf-sidebar.shell.collapsed .tf-sidebar-item.has-current {
13495
+ background: var(--frame-hover);
13496
+ color: var(--on-frame);
13497
+ }
13498
+ .tf-sidebar.shell .tf-sidebar-item.has-current,
13499
+ .tf-sidebar.shell button.tf-sidebar-grouplabel:hover {
13500
+ color: var(--on-frame);
13501
+ }
13502
+ .tf-sidebar.shell .tf-sidebar-item[aria-current="page"] {
13503
+ background: var(--frame-active);
13504
+ color: var(--on-frame);
13505
+ }
13506
+ .tf-sidebar.shell .tf-sidebar-item:disabled:hover {
13507
+ background: transparent;
13508
+ color: var(--on-frame-muted);
13509
+ }
13510
+ .tf-sidebar.shell .tf-sidebar-foot,
13511
+ .tf-sidebar.shell.collapsed .tf-sidebar-group + .tf-sidebar-group {
13512
+ border-color: var(--frame-hover);
13513
+ }
13514
+ .tf-sidebar.shell .tf-iconbtn-ghost {
13515
+ color: var(--on-frame-muted);
13516
+ }
13517
+ .tf-sidebar.shell .tf-iconbtn-ghost:hover {
13518
+ background: var(--frame-hover);
13519
+ color: var(--on-frame);
13520
+ }
13521
+ .tf-sidebar.shell .tf-sidebar-head {
13522
+ min-height: 44px;
13523
+ }
13524
+
13525
+ /* UserMenu: the signed-in person, opening their account menu */
13526
+ .tf-usermenu {
13527
+ display: flex;
13528
+ align-items: center;
13529
+ gap: 10px;
13530
+ width: 100%;
13531
+ min-height: 44px;
13532
+ padding: 4px 8px 4px 4px;
13533
+ box-sizing: border-box;
13534
+ border: 0;
13535
+ border-radius: var(--radius-pill);
13536
+ background: transparent;
13537
+ color: var(--ink);
13538
+ font: inherit;
13539
+ text-align: left;
13540
+ cursor: pointer;
13541
+ }
13542
+ .tf-usermenu.compact {
13543
+ width: auto;
13544
+ padding: 4px;
13545
+ }
13546
+ .tf-usermenu:hover,
13547
+ .tf-usermenu[aria-expanded="true"] {
13548
+ background: var(--sidebar-accent);
13549
+ }
13550
+ .tf-usermenu:focus-visible {
13551
+ outline: 2px solid var(--focus);
13552
+ outline-offset: 2px;
13553
+ }
13554
+ .tf-usermenu-avatar {
13555
+ display: inline-flex;
13556
+ flex: none;
13557
+ }
13558
+ .tf-usermenu-text {
13559
+ display: flex;
13560
+ flex-direction: column;
13561
+ flex: 1;
13562
+ min-width: 0;
13563
+ }
13564
+ .tf-usermenu-name {
13565
+ font: 500 13px/18px var(--font-sans);
13566
+ overflow: hidden;
13567
+ text-overflow: ellipsis;
13568
+ white-space: nowrap;
13569
+ }
13570
+ .tf-usermenu-mail {
13571
+ font: 500 11px/14px var(--font-sans);
13572
+ color: var(--ink-muted);
13573
+ overflow: hidden;
13574
+ text-overflow: ellipsis;
13575
+ white-space: nowrap;
13576
+ }
13577
+ .tf-sidebar.shell .tf-usermenu {
13578
+ color: var(--on-frame);
13579
+ }
13580
+ .tf-sidebar.shell .tf-usermenu:hover,
13581
+ .tf-sidebar.shell .tf-usermenu[aria-expanded="true"] {
13582
+ background: var(--frame-hover);
13583
+ }
13584
+ .tf-sidebar.shell .tf-usermenu-mail {
13585
+ color: var(--on-frame-muted);
13586
+ }
13587
+ .tf-wssw.compact {
13588
+ padding: 4px;
13589
+ }
13590
+
13591
+ /* the bar that opens the sidebar as a drawer on phones */
13592
+ .tf-sidebar-bar,
13593
+ .tf-sidebar-scrim {
13594
+ display: none;
13595
+ }
12794
13596
  @media (max-width: 760px) {
12795
- .tf-sidebar {
12796
- width: 100%;
13597
+ .tf-sidebar-bar {
13598
+ display: flex;
13599
+ align-items: center;
13600
+ gap: 8px;
13601
+ min-height: 52px;
13602
+ padding: 6px 12px 6px 6px;
13603
+ box-sizing: border-box;
13604
+ border-radius: var(--radius-lg);
13605
+ background: var(--surface);
13606
+ box-shadow: 0 0 0 var(--line-width) var(--line);
13607
+ color: var(--ink);
12797
13608
  }
13609
+ .tf-sidebar-bar.attached {
13610
+ border-radius: 0;
13611
+ box-shadow: none;
13612
+ background: var(--sidebar);
13613
+ border-bottom: 1px solid var(--sidebar-border);
13614
+ }
13615
+ .tf-sidebar-bar.shell {
13616
+ min-height: 56px;
13617
+ padding: 8px 8px 8px 0;
13618
+ border-radius: 0;
13619
+ box-shadow: none;
13620
+ background: transparent;
13621
+ color: var(--on-frame);
13622
+ }
13623
+ .tf-sidebar-bar.shell .tf-iconbtn-ghost {
13624
+ color: var(--on-frame);
13625
+ }
13626
+ .tf-sidebar-bar > :not(.tf-iconbtn) {
13627
+ min-width: 0;
13628
+ }
13629
+ .tf-sidebar,
13630
+ .tf-sidebar.attached,
13631
+ .tf-sidebar.shell {
13632
+ position: fixed;
13633
+ top: 0;
13634
+ bottom: 0;
13635
+ left: 0;
13636
+ z-index: var(--z-overlay);
13637
+ width: min(300px, 86vw);
13638
+ min-height: 0;
13639
+ padding: 12px;
13640
+ border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
13641
+ box-shadow: var(--shadow-float), 0 0 0 var(--line-width) var(--line);
13642
+ transform: translateX(-105%);
13643
+ visibility: hidden;
13644
+ transition:
13645
+ transform var(--dur-base) var(--ease-out),
13646
+ visibility 0s linear var(--dur-base);
13647
+ }
13648
+ .tf-sidebar.shell {
13649
+ background: var(--frame);
13650
+ }
13651
+ .tf-sidebar.attached {
13652
+ background: var(--sidebar);
13653
+ }
13654
+ .tf-sidebar.open {
13655
+ transform: none;
13656
+ visibility: visible;
13657
+ transition: transform var(--dur-base) var(--ease-out);
13658
+ }
13659
+ .tf-sidebar-toggle {
13660
+ display: none;
13661
+ }
13662
+ .tf-sidebar-scrim {
13663
+ display: block;
13664
+ position: fixed;
13665
+ inset: 0;
13666
+ z-index: var(--z-overlay);
13667
+ background: var(--scrim-strong);
13668
+ animation: tf-fade var(--dur-base) var(--ease-out) both;
13669
+ }
13670
+ }
13671
+
13672
+ @media (max-width: 760px) {
12798
13673
  .tf-navmenu-panel.with-feature {
12799
13674
  grid-template-columns: minmax(0, 1fr);
12800
13675
  }
@@ -12977,7 +13852,7 @@ a.tf-iconbtn {
12977
13852
  /* Tablet: asides move below the main column, nav labels and the page nav shrink to icons */
12978
13853
  @container tf-shell (max-width: 1180px) {
12979
13854
  .tf-sheet:not(.tf-sheet-2):not(.tf-sheet-nav) {
12980
- grid-template-columns: 44px minmax(0, 1fr);
13855
+ grid-template-columns: auto minmax(0, 1fr);
12981
13856
  }
12982
13857
  .tf-sheet-nav.tf-sheet-aside {
12983
13858
  grid-template-columns: 208px minmax(0, 1fr);
@@ -12985,6 +13860,13 @@ a.tf-iconbtn {
12985
13860
  .tf-sheet > .tf-main ~ :not(.tf-dock-float) {
12986
13861
  grid-column: 2;
12987
13862
  }
13863
+ /* with the sidebar there is no rail column: asides go below the main column */
13864
+ .tf-sheet.tf-sheet-norail:not(.tf-sheet-2) {
13865
+ grid-template-columns: minmax(0, 1fr);
13866
+ }
13867
+ .tf-sheet-norail > .tf-main ~ :not(.tf-dock-float) {
13868
+ grid-column: 1;
13869
+ }
12988
13870
  /* the dock floats over the end of the sheet, not of the main column (asides follow it) */
12989
13871
  .tf-main-dock {
12990
13872
  padding-bottom: 0;
@@ -13015,7 +13897,7 @@ a.tf-iconbtn {
13015
13897
  @container tf-shell (max-width: 1040px) {
13016
13898
  .tf-sheet-nav,
13017
13899
  .tf-sheet-nav.tf-sheet-aside {
13018
- grid-template-columns: 44px minmax(0, 1fr);
13900
+ grid-template-columns: auto minmax(0, 1fr);
13019
13901
  }
13020
13902
  .tf-subnav-eyebrow {
13021
13903
  display: none;
@@ -13112,6 +13994,21 @@ a.tf-iconbtn {
13112
13994
  .tf-rail-group {
13113
13995
  flex-direction: row;
13114
13996
  }
13997
+ /* on phones the rail is a row of icons, expanded or not */
13998
+ .tf-rail.expanded {
13999
+ width: auto;
14000
+ }
14001
+ .tf-rail.expanded .tf-rail-btn {
14002
+ display: grid;
14003
+ width: 40px;
14004
+ padding: 0;
14005
+ }
14006
+ .tf-rail.expanded .tf-rail-label {
14007
+ display: none;
14008
+ }
14009
+ .tf-rail.expanded .tf-dotcount {
14010
+ position: absolute;
14011
+ }
13115
14012
  .tf-main {
13116
14013
  gap: var(--space-4);
13117
14014
  }
@@ -13203,6 +14100,56 @@ a.tf-iconbtn {
13203
14100
  max-width: 100%;
13204
14101
  overflow-x: auto;
13205
14102
  }
14103
+ /* Table stack: narrow boxes show every row as a card, each cell with its column label */
14104
+ .tf-table-stackbox {
14105
+ container: tf-table / inline-size;
14106
+ }
14107
+ @container tf-table (max-width: 600px) {
14108
+ .tf-table.stack thead {
14109
+ position: absolute;
14110
+ width: 1px;
14111
+ height: 1px;
14112
+ overflow: hidden;
14113
+ clip-path: inset(50%);
14114
+ }
14115
+ .tf-table.stack,
14116
+ .tf-table.stack tbody,
14117
+ .tf-table.stack tr {
14118
+ display: block;
14119
+ }
14120
+ .tf-table.stack tr {
14121
+ padding: 8px 0;
14122
+ border-bottom: 1px solid var(--line);
14123
+ }
14124
+ .tf-table.stack tr:last-child {
14125
+ border-bottom: 0;
14126
+ }
14127
+ .tf-table.stack td {
14128
+ display: flex;
14129
+ align-items: center;
14130
+ justify-content: space-between;
14131
+ gap: 16px;
14132
+ height: auto;
14133
+ min-height: var(--control-sm);
14134
+ padding: 4px 0;
14135
+ border-bottom: 0;
14136
+ text-align: right;
14137
+ white-space: normal;
14138
+ }
14139
+ .tf-table.stack td::before {
14140
+ content: attr(data-label);
14141
+ flex: none;
14142
+ max-width: 50%;
14143
+ text-align: left;
14144
+ font: 500 11px/14px var(--font-sans);
14145
+ letter-spacing: 0.06em;
14146
+ text-transform: uppercase;
14147
+ color: var(--ink-muted);
14148
+ }
14149
+ .tf-table.stack tbody tr:hover td {
14150
+ background: transparent;
14151
+ }
14152
+ }
13206
14153
 
13207
14154
  /* ── Phone: components ── */
13208
14155
  @media (max-width: 760px) {
@@ -13237,15 +14184,15 @@ a.tf-iconbtn {
13237
14184
  height: 52px;
13238
14185
  }
13239
14186
 
13240
- /* segmented controls and tabs scroll sideways when the labels do not fit */
13241
- .tf-seg,
13242
- .tf-tabs {
14187
+ /* segmented controls and tabs scroll sideways when the labels do not fit (block ones shrink) */
14188
+ .tf-seg:not(.block),
14189
+ .tf-tabs:not(.tf-tabs-block) {
13243
14190
  max-width: 100%;
13244
14191
  overflow-x: auto;
13245
14192
  scrollbar-width: none;
13246
14193
  }
13247
- .tf-seg-item,
13248
- .tf-tab {
14194
+ .tf-seg:not(.block) .tf-seg-item,
14195
+ .tf-tabs:not(.tf-tabs-block) .tf-tab {
13249
14196
  flex: none;
13250
14197
  }
13251
14198
  .tf-seg,
@@ -13394,6 +14341,40 @@ a.tf-iconbtn {
13394
14341
  }
13395
14342
  }
13396
14343
 
14344
+ /* AppShell with a sidebar on phones: the sidebar's bar on top of the frame, the sheet below */
14345
+ @media (max-width: 760px) {
14346
+ .tf-shell.tf-shell-sidebar {
14347
+ grid-template-columns: minmax(0, 1fr);
14348
+ padding: 0 8px 8px;
14349
+ }
14350
+ }
14351
+
14352
+ /* Fluid at every width: segmented controls, tabs and toggle groups never push past their
14353
+ container. When space runs short the items shrink and their labels end in an ellipsis. */
14354
+ .tf-tabs {
14355
+ max-width: 100%;
14356
+ box-sizing: border-box;
14357
+ }
14358
+ .tf-seg-item,
14359
+ .tf-tab,
14360
+ .tf-togglegroup .tf-toggle {
14361
+ min-width: 0;
14362
+ }
14363
+ .tf-seg-label,
14364
+ .tf-tab,
14365
+ .tf-toggle-label {
14366
+ overflow: hidden;
14367
+ text-overflow: ellipsis;
14368
+ white-space: nowrap;
14369
+ }
14370
+
14371
+ /* key hints mean nothing on touch screens */
14372
+ @media (pointer: coarse) {
14373
+ .tf-search .tf-kbd {
14374
+ display: none;
14375
+ }
14376
+ }
14377
+
13397
14378
  /* 07-polish.css */
13398
14379
  /* Generated by scripts/pro-css.ts from packages/halo/css. Do not edit; the Pro look lives in 90-pro-look.css. */
13399
14380
  /* ───────────── Polish ─────────────
@@ -13825,11 +14806,13 @@ textarea.tf-input,
13825
14806
  inset: 0;
13826
14807
  z-index: 1;
13827
14808
  display: grid;
13828
- grid-template-columns: minmax(0, 320px) minmax(0, 1fr) minmax(0, 340px);
14809
+ grid-template-columns:
14810
+ minmax(0, var(--floating-start, 320px)) minmax(0, 1fr)
14811
+ minmax(0, var(--floating-end, 340px));
13829
14812
  grid-template-rows: auto minmax(0, 1fr) auto;
13830
14813
  grid-template-areas:
13831
14814
  "top top top"
13832
- "start . end"
14815
+ "start controls end"
13833
14816
  "bottom bottom bottom";
13834
14817
  gap: var(--space-4);
13835
14818
  padding: var(--space-4);
@@ -13860,6 +14843,32 @@ textarea.tf-input,
13860
14843
  grid-area: bottom;
13861
14844
  justify-self: center;
13862
14845
  }
14846
+ /* background controls and source notes: the free corner, clear of the panels and the dock */
14847
+ .tf-floating-ui > .tf-floating-controls {
14848
+ grid-area: controls;
14849
+ align-self: end;
14850
+ justify-self: end;
14851
+ display: flex;
14852
+ flex-direction: column;
14853
+ align-items: flex-end;
14854
+ gap: var(--space-2);
14855
+ pointer-events: none;
14856
+ }
14857
+ .tf-floating-controls > * {
14858
+ pointer-events: auto;
14859
+ }
14860
+ .tf-floating-attribution {
14861
+ max-width: 100%;
14862
+ padding: 2px 8px;
14863
+ border-radius: var(--radius-sm);
14864
+ background: var(--surface);
14865
+ color: var(--ink-muted);
14866
+ font: 500 11px/16px var(--font-sans);
14867
+ overflow-wrap: anywhere;
14868
+ }
14869
+ .tf-floating-handle {
14870
+ display: none;
14871
+ }
13863
14872
  .tf-floating-ui > :is(.tf-floating-top, .tf-floating-bottom) {
13864
14873
  pointer-events: none;
13865
14874
  }
@@ -13885,6 +14894,75 @@ textarea.tf-input,
13885
14894
  gap: var(--space-3);
13886
14895
  padding: var(--space-3);
13887
14896
  }
14897
+ .tf-floating-ui > .tf-floating-controls {
14898
+ grid-area: auto;
14899
+ grid-row: 3;
14900
+ }
14901
+ /* the end slot as a bottom sheet over the background: a peek, or most of the height */
14902
+ .tf-floating.has-sheet .tf-floating-ui {
14903
+ grid-template-rows: auto auto minmax(120px, 1fr) auto;
14904
+ grid-template-areas:
14905
+ "top"
14906
+ "start"
14907
+ "."
14908
+ "bottom";
14909
+ padding-bottom: calc(var(--space-3) + 96px);
14910
+ }
14911
+ .tf-floating.has-sheet .tf-floating-end {
14912
+ position: absolute;
14913
+ left: var(--space-3);
14914
+ right: var(--space-3);
14915
+ bottom: 0;
14916
+ z-index: 2;
14917
+ max-height: 96px;
14918
+ overflow: hidden;
14919
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
14920
+ background: var(--surface);
14921
+ box-shadow: 0 0 0 var(--line-width) var(--line);
14922
+ transition: max-height var(--dur-base) var(--ease-out);
14923
+ }
14924
+ [data-surface="glass"].tf-floating.has-sheet .tf-floating-end {
14925
+ background: var(--glass);
14926
+ -webkit-backdrop-filter: var(--glass-filter);
14927
+ backdrop-filter: var(--glass-filter);
14928
+ }
14929
+ .tf-floating.has-sheet.sheet-full .tf-floating-end {
14930
+ max-height: 75%;
14931
+ overflow-y: auto;
14932
+ }
14933
+ .tf-floating.has-sheet .tf-floating-handle {
14934
+ display: block;
14935
+ position: sticky;
14936
+ top: 0;
14937
+ z-index: 1;
14938
+ width: 100%;
14939
+ height: 24px;
14940
+ margin: 0;
14941
+ padding: 0;
14942
+ border: 0;
14943
+ background: transparent;
14944
+ cursor: pointer;
14945
+ }
14946
+ .tf-floating.has-sheet .tf-floating-handle::before {
14947
+ content: "";
14948
+ display: block;
14949
+ width: 40px;
14950
+ height: 4px;
14951
+ margin: 10px auto;
14952
+ border-radius: var(--radius-pill);
14953
+ background: var(--line-strong);
14954
+ }
14955
+ .tf-floating.has-sheet .tf-floating-handle:focus-visible {
14956
+ outline: 2px solid var(--focus);
14957
+ outline-offset: -2px;
14958
+ }
14959
+ }
14960
+
14961
+ /* in a glass layout the attribution is glass too */
14962
+ [data-surface="glass"] .tf-floating-attribution {
14963
+ background: var(--glass);
14964
+ -webkit-backdrop-filter: var(--glass-filter);
14965
+ backdrop-filter: var(--glass-filter);
13888
14966
  }
13889
14967
 
13890
14968
  /* 09-motion.css */
@@ -14510,6 +15588,14 @@ select.tf-input {
14510
15588
  gap: var(--line-width);
14511
15589
  box-shadow: 0 0 0 var(--line-width) var(--line);
14512
15590
  }
15591
+ /* with the sidebar, the sidebar and the sheet sit side by side on the same hairline */
15592
+ .tf-shell.tf-shell-sidebar {
15593
+ padding: 0;
15594
+ gap: var(--line-width);
15595
+ }
15596
+ .tf-shell-sidebar > .tf-sidebar.shell {
15597
+ border-radius: 0;
15598
+ }
14513
15599
  .tf-topbar,
14514
15600
  .tf-shell .tf-topbar {
14515
15601
  border-radius: 0;