@polyxd/react 0.2.2 → 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.
Files changed (75) hide show
  1. package/NOTICE +45 -0
  2. package/README.md +15 -2
  3. package/dist/components/avatar.js +5 -36
  4. package/dist/components/avatar.js.map +1 -1
  5. package/dist/components/chart.js +4 -87
  6. package/dist/components/chart.js.map +1 -1
  7. package/dist/components/content.d.ts +0 -8
  8. package/dist/components/content.js +27 -349
  9. package/dist/components/content.js.map +1 -1
  10. package/dist/components/filter.js +1 -1
  11. package/dist/components/filter.js.map +1 -1
  12. package/dist/components/flow.js +11 -85
  13. package/dist/components/flow.js.map +1 -1
  14. package/dist/components/index.js +6 -1
  15. package/dist/components/index.js.map +1 -1
  16. package/dist/components/inputs.d.ts +2 -12
  17. package/dist/components/inputs.js +5 -47
  18. package/dist/components/inputs.js.map +1 -1
  19. package/dist/components/marks.js +5 -20
  20. package/dist/components/marks.js.map +1 -1
  21. package/dist/components/navigation.d.ts +2 -0
  22. package/dist/components/navigation.js +31 -19
  23. package/dist/components/navigation.js.map +1 -1
  24. package/dist/components/pickers.js +12 -160
  25. package/dist/components/pickers.js.map +1 -1
  26. package/dist/components/shell.d.ts +41 -0
  27. package/dist/components/shell.js +190 -0
  28. package/dist/components/shell.js.map +1 -0
  29. package/dist/components/split.d.ts +11 -0
  30. package/dist/components/split.js +85 -0
  31. package/dist/components/split.js.map +1 -0
  32. package/dist/components/structure.d.ts +8 -0
  33. package/dist/components/structure.js +12 -1
  34. package/dist/components/structure.js.map +1 -1
  35. package/dist/components/table.js +10 -17
  36. package/dist/components/table.js.map +1 -1
  37. package/dist/components/tree.js +6 -57
  38. package/dist/components/tree.js.map +1 -1
  39. package/dist/context.d.ts +34 -46
  40. package/dist/context.js +10 -7
  41. package/dist/context.js.map +1 -1
  42. package/dist/data.d.ts +2 -26
  43. package/dist/data.js +2 -51
  44. package/dist/data.js.map +1 -1
  45. package/dist/format.d.ts +2 -14
  46. package/dist/format.js +2 -69
  47. package/dist/format.js.map +1 -1
  48. package/dist/frame.d.ts +19 -0
  49. package/dist/frame.js +21 -0
  50. package/dist/frame.js.map +1 -0
  51. package/dist/index.d.ts +2 -1
  52. package/dist/index.js +2 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/skeleton.d.ts +2 -1
  55. package/dist/skeleton.js +9 -25
  56. package/dist/skeleton.js.map +1 -1
  57. package/dist/surface.d.ts +7 -3
  58. package/dist/surface.js +15 -13
  59. package/dist/surface.js.map +1 -1
  60. package/package.json +11 -6
  61. package/preview/polyxd.css +2 -0
  62. package/preview/polyxd.js +56 -0
  63. package/src/styles.css +623 -8
  64. package/themes/brutalist.css +300 -0
  65. package/themes/civic.css +300 -0
  66. package/themes/editorial.css +300 -0
  67. package/themes/finance.css +300 -0
  68. package/themes/glass.css +300 -0
  69. package/themes/health.css +300 -0
  70. package/themes/mono.css +300 -0
  71. package/themes/neon.css +300 -0
  72. package/themes/pastel.css +300 -0
  73. package/themes/sketch.css +356 -0
  74. package/themes/terminal.css +300 -0
  75. package/themes/wireframe.css +328 -0
package/src/styles.css CHANGED
@@ -545,7 +545,7 @@
545
545
  flex: none;
546
546
  width: var(--pxd-size-icon-default);
547
547
  height: var(--pxd-size-icon-default);
548
- border-radius: 50%;
548
+ border-radius: var(--pxd-radius-full);
549
549
  border: 3px solid var(--pxd-color-border-default);
550
550
  border-top-color: var(--pxd-color-action-primary-background);
551
551
  animation: pxd-spin 800ms linear infinite;
@@ -687,7 +687,7 @@ textarea.pxd-input {
687
687
  cursor: pointer;
688
688
  }
689
689
  .pxd-radio {
690
- border-radius: 50%;
690
+ border-radius: var(--pxd-radius-full);
691
691
  }
692
692
  .pxd-checkbox {
693
693
  border-radius: var(--pxd-radius-small);
@@ -709,7 +709,7 @@ textarea.pxd-input {
709
709
  display: block;
710
710
  width: 12px;
711
711
  height: 12px;
712
- border-radius: 50%;
712
+ border-radius: var(--pxd-radius-full);
713
713
  background: var(--pxd-color-action-primary-background);
714
714
  }
715
715
  .pxd-segmented {
@@ -779,7 +779,7 @@ textarea.pxd-input {
779
779
  display: block;
780
780
  width: 16px;
781
781
  height: 16px;
782
- border-radius: 50%;
782
+ border-radius: var(--pxd-radius-full);
783
783
  background: var(--pxd-color-border-strong);
784
784
  transform: translateX(2px);
785
785
  transition: transform var(--pxd-motion-duration-short) var(--pxd-motion-easing-standard);
@@ -824,7 +824,7 @@ textarea.pxd-input {
824
824
  display: block;
825
825
  width: 20px;
826
826
  height: 20px;
827
- border-radius: 50%;
827
+ border-radius: var(--pxd-radius-full);
828
828
  background: var(--pxd-color-action-primary-background);
829
829
  box-shadow: var(--pxd-shadow-raised);
830
830
  cursor: grab;
@@ -943,6 +943,25 @@ textarea.pxd-input {
943
943
  .pxd-portal {
944
944
  display: contents;
945
945
  }
946
+ /* The Web renderer's overlays are native <dialog> elements: the browser's own dialog box steps
947
+ aside (zero specificity, so every .pxd-* rule above and below still wins) and the scrim is the
948
+ surface's .pxd-overlay, not the backdrop. */
949
+ :where(.pxd-portal > dialog) {
950
+ border: 0;
951
+ margin: 0;
952
+ padding: 0;
953
+ inset: auto;
954
+ width: auto;
955
+ height: auto;
956
+ max-width: none;
957
+ max-height: none;
958
+ color: inherit;
959
+ background: transparent;
960
+ overflow: visible;
961
+ }
962
+ :where(.pxd-portal > dialog)::backdrop {
963
+ background: transparent;
964
+ }
946
965
  .pxd-overlay {
947
966
  position: fixed;
948
967
  inset: 0;
@@ -1169,7 +1188,7 @@ textarea.pxd-input {
1169
1188
  display: inline-flex;
1170
1189
  align-items: center;
1171
1190
  justify-content: center;
1172
- border-radius: 50%;
1191
+ border-radius: var(--pxd-radius-full);
1173
1192
  object-fit: cover;
1174
1193
  font-weight: 600;
1175
1194
  }
@@ -1223,7 +1242,7 @@ textarea.pxd-input {
1223
1242
  justify-content: center;
1224
1243
  width: 22px;
1225
1244
  height: 22px;
1226
- border-radius: 50%;
1245
+ border-radius: var(--pxd-radius-full);
1227
1246
  border: 2px solid var(--pxd-color-surface-default);
1228
1247
  background: var(--pxd-color-action-primary-background);
1229
1248
  color: var(--pxd-color-action-primary-foreground);
@@ -1262,6 +1281,18 @@ textarea.pxd-input {
1262
1281
  .pxd-person-row[data-state="checked"] .pxd-option-description {
1263
1282
  color: inherit;
1264
1283
  }
1284
+ /* On a selected row the avatar's own tone can match the selection colour, so the face would vanish
1285
+ into the row. Tones built from the selection or neutral surfaces move to the plain surface, and
1286
+ every face gets a surface ring to keep its edge. */
1287
+ .pxd-person-row[data-state="checked"] .pxd-avatar {
1288
+ box-shadow: 0 0 0 var(--pxd-border-width-strong) var(--pxd-color-surface-default);
1289
+ }
1290
+ .pxd-person-row[data-state="checked"] .pxd-avatar-primary,
1291
+ .pxd-person-row[data-state="checked"] .pxd-avatar-secondary,
1292
+ .pxd-person-row[data-state="checked"] .pxd-avatar-tertiary {
1293
+ background: var(--pxd-color-surface-default);
1294
+ color: var(--pxd-color-text-default);
1295
+ }
1265
1296
  .pxd-person-text {
1266
1297
  flex: 1;
1267
1298
  display: flex;
@@ -2128,7 +2159,7 @@ textarea.pxd-input {
2128
2159
  top: 10px;
2129
2160
  width: 8px;
2130
2161
  height: 8px;
2131
- border-radius: 50%;
2162
+ border-radius: var(--pxd-radius-full);
2132
2163
  background: var(--pxd-color-border-strong);
2133
2164
  }
2134
2165
  .pxd-status-notice {
@@ -2257,8 +2288,16 @@ textarea.pxd-input {
2257
2288
  .pxd-detail-row-action {
2258
2289
  text-align: end;
2259
2290
  }
2291
+ /* A link-styled button still needs a full-size target; padding keeps the text on the baseline. */
2260
2292
  .pxd-detail-change {
2261
2293
  white-space: nowrap;
2294
+ display: inline-flex;
2295
+ align-items: center;
2296
+ min-height: var(--pxd-size-target-min);
2297
+ margin: calc((var(--pxd-size-target-min) - 1.5em) / -2) 0;
2298
+ }
2299
+ .pxd-detail-actions .pxd-detail-row {
2300
+ align-items: center;
2262
2301
  }
2263
2302
 
2264
2303
  /* Collection: carousel */
@@ -4407,3 +4446,579 @@ video.pxd-media {
4407
4446
  opacity: var(--pxd-opacity-state-disabled);
4408
4447
  cursor: not-allowed;
4409
4448
  }
4449
+
4450
+ /* ==== The shell (spec 0.3): Frame, AppBar, Navigation placements, Outlet, Footer, Custom ==== */
4451
+
4452
+ /* ---- Frame ---- */
4453
+ /* A shell is the product around its screens, so the surface's own padding and stack go: the
4454
+ Frame lays out its regions on its own width (data-pxd-layout) and the screens keep theirs.
4455
+ The frame fills the viewport unless the host says otherwise. */
4456
+ .pxd-surface-shell {
4457
+ display: flex;
4458
+ flex-direction: column;
4459
+ min-height: 100dvh;
4460
+ padding: 0;
4461
+ gap: 0;
4462
+ }
4463
+ .pxd-frame {
4464
+ /* How much of the top a sticky AppBar keeps, so a sticky navigation starts below it. */
4465
+ --polyxd-appbar-height: 0px;
4466
+ position: relative;
4467
+ flex: 1 1 auto;
4468
+ display: flex;
4469
+ flex-direction: column;
4470
+ min-width: 0;
4471
+ }
4472
+ .pxd-frame[data-pxd-appbar="standard"],
4473
+ .pxd-frame[data-pxd-appbar="large"] {
4474
+ --polyxd-appbar-height: 64px;
4475
+ }
4476
+ .pxd-frame[data-pxd-appbar="compact"] {
4477
+ --polyxd-appbar-height: 48px;
4478
+ }
4479
+ .pxd-frame:not([data-pxd-layout="compact"])[data-pxd-appbar="large"] {
4480
+ --polyxd-appbar-height: 120px;
4481
+ }
4482
+ /* The first focusable thing: off the top until it has focus, then a button over the header. */
4483
+ .pxd-skip-link {
4484
+ position: absolute;
4485
+ top: var(--pxd-space-inset-compact);
4486
+ inset-inline-start: var(--pxd-space-inset-compact);
4487
+ z-index: 8;
4488
+ display: inline-flex;
4489
+ align-items: center;
4490
+ min-height: var(--pxd-size-target-min);
4491
+ padding: 0 var(--pxd-space-inset-default);
4492
+ border-radius: var(--pxd-radius-control);
4493
+ background: var(--pxd-color-action-primary-background);
4494
+ color: var(--pxd-color-action-primary-foreground);
4495
+ font-family: var(--pxd-type-label-default-family);
4496
+ font-size: var(--pxd-type-label-default-size);
4497
+ font-weight: var(--pxd-type-label-default-weight);
4498
+ text-decoration: none;
4499
+ white-space: nowrap;
4500
+ transform: translateY(calc(-100% - var(--pxd-space-inset-comfortable) * 2));
4501
+ }
4502
+ .pxd-skip-link:focus-visible {
4503
+ transform: none;
4504
+ }
4505
+ .pxd-frame-banner .pxd-status {
4506
+ border-radius: 0;
4507
+ }
4508
+ /* Regions: navigation at the start, main beside it, an aside after; the footer below all.
4509
+ Wide keeps the three in one row; medium stacks the aside under main; compact stacks
4510
+ everything, with the navigation last on screen (a bottom bar) but still before main in
4511
+ reading order. */
4512
+ .pxd-frame-body {
4513
+ flex: 1 1 auto;
4514
+ display: grid;
4515
+ grid-template-columns: auto minmax(0, 1fr);
4516
+ grid-template-rows: minmax(0, 1fr);
4517
+ grid-template-areas: "nav main";
4518
+ align-items: stretch;
4519
+ }
4520
+ .pxd-frame-body:has(> .pxd-frame-aside) {
4521
+ grid-template-columns: auto minmax(0, 1fr) minmax(16rem, 20rem);
4522
+ grid-template-areas: "nav main aside";
4523
+ }
4524
+ .pxd-frame[data-pxd-layout="medium"] .pxd-frame-body:has(> .pxd-frame-aside) {
4525
+ grid-template-columns: auto minmax(0, 1fr);
4526
+ grid-template-rows: minmax(0, 1fr) auto;
4527
+ grid-template-areas: "nav main" "nav aside";
4528
+ }
4529
+ .pxd-frame[data-pxd-layout="compact"] .pxd-frame-body,
4530
+ .pxd-frame[data-pxd-layout="compact"] .pxd-frame-body:has(> .pxd-frame-aside) {
4531
+ grid-template-columns: minmax(0, 1fr);
4532
+ grid-template-rows: minmax(0, 1fr) auto auto;
4533
+ grid-template-areas: "main" "aside" "nav";
4534
+ }
4535
+ .pxd-frame-nav {
4536
+ grid-area: nav;
4537
+ min-width: 0;
4538
+ background: var(--pxd-color-surface-subtle);
4539
+ border-inline-end: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4540
+ }
4541
+ /* A drawer lives in the portal; its slot takes no room (an empty slot is a closed drawer). */
4542
+ .pxd-frame[data-pxd-nav="drawer"] .pxd-frame-nav {
4543
+ border: 0;
4544
+ background: transparent;
4545
+ }
4546
+ .pxd-frame[data-pxd-nav="drawer"] .pxd-frame-nav:empty {
4547
+ display: none;
4548
+ }
4549
+ .pxd-frame-main {
4550
+ grid-area: main;
4551
+ min-width: 0;
4552
+ width: 100%;
4553
+ background: var(--pxd-color-surface-default);
4554
+ }
4555
+ /* 'contained' centres main at measure.max × 1.6 (about 104 characters); 'full' uses everything. */
4556
+ .pxd-frame-width-contained .pxd-frame-main {
4557
+ max-width: calc(var(--pxd-measure-max) * 1.6ch);
4558
+ justify-self: center;
4559
+ }
4560
+ .pxd-frame-aside {
4561
+ grid-area: aside;
4562
+ min-width: 0;
4563
+ padding: var(--pxd-space-inset-comfortable);
4564
+ border-inline-start: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4565
+ background: var(--pxd-color-surface-subtle);
4566
+ }
4567
+ .pxd-frame[data-pxd-layout="medium"] .pxd-frame-aside,
4568
+ .pxd-frame[data-pxd-layout="compact"] .pxd-frame-aside {
4569
+ border-inline-start: 0;
4570
+ border-top: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4571
+ }
4572
+ .pxd-frame[data-pxd-layout="compact"] .pxd-frame-aside {
4573
+ padding: var(--pxd-space-inset-default);
4574
+ }
4575
+
4576
+ /* ---- Navigation placements ---- */
4577
+ /* Side (240px) and rail (80px) stay in view while the screen scrolls, below a sticky AppBar. */
4578
+ .pxd-nav-side,
4579
+ .pxd-nav-rail {
4580
+ position: sticky;
4581
+ top: var(--polyxd-appbar-height);
4582
+ max-height: calc(100dvh - var(--polyxd-appbar-height));
4583
+ overflow-y: auto;
4584
+ }
4585
+ .pxd-nav-side {
4586
+ width: 240px;
4587
+ padding: var(--pxd-space-inset-default) var(--pxd-space-inset-compact);
4588
+ }
4589
+ .pxd-nav-rail {
4590
+ width: 80px;
4591
+ padding: var(--pxd-space-stack-loose) 0;
4592
+ }
4593
+ .pxd-nav-rail ul {
4594
+ display: flex;
4595
+ flex-direction: column;
4596
+ gap: var(--pxd-space-stack-tight);
4597
+ }
4598
+ .pxd-nav-rail-item,
4599
+ .pxd-nav-bar-item {
4600
+ display: flex;
4601
+ flex-direction: column;
4602
+ align-items: center;
4603
+ justify-content: center;
4604
+ gap: var(--pxd-space-stack-tight);
4605
+ width: 100%;
4606
+ min-height: 56px;
4607
+ padding: var(--pxd-space-stack-tight) 0;
4608
+ border: 0;
4609
+ background: transparent;
4610
+ color: var(--pxd-color-text-muted);
4611
+ font-family: var(--pxd-type-label-small-family);
4612
+ font-size: var(--pxd-type-label-small-size);
4613
+ font-weight: var(--pxd-type-label-small-weight);
4614
+ line-height: var(--pxd-type-label-small-line-height);
4615
+ letter-spacing: var(--pxd-type-label-small-letter-spacing);
4616
+ cursor: pointer;
4617
+ }
4618
+ .pxd-nav-rail-icon,
4619
+ .pxd-nav-bar-icon {
4620
+ position: relative;
4621
+ display: inline-flex;
4622
+ align-items: center;
4623
+ justify-content: center;
4624
+ width: 56px;
4625
+ height: 32px;
4626
+ border-radius: var(--pxd-radius-full);
4627
+ transition: background var(--pxd-motion-duration-short) var(--pxd-motion-easing-standard);
4628
+ }
4629
+ .pxd-nav-rail-item:hover .pxd-nav-rail-icon,
4630
+ .pxd-nav-bar-item:hover .pxd-nav-bar-icon {
4631
+ background: color-mix(in srgb, var(--pxd-color-text-default) calc(var(--pxd-opacity-state-hover) * 100%), transparent);
4632
+ }
4633
+ /* The current item: the icon in a selection pill, the label in the default text colour. */
4634
+ .pxd-nav-rail-item.pxd-nav-current,
4635
+ .pxd-nav-bar-item.pxd-nav-current {
4636
+ background: transparent;
4637
+ color: var(--pxd-color-text-default);
4638
+ font-weight: var(--pxd-type-label-small-weight);
4639
+ }
4640
+ .pxd-nav-rail-item.pxd-nav-current .pxd-nav-rail-icon,
4641
+ .pxd-nav-bar-item.pxd-nav-current .pxd-nav-bar-icon {
4642
+ background: var(--pxd-color-selection-background);
4643
+ color: var(--pxd-color-selection-foreground);
4644
+ }
4645
+ .pxd-nav-rail .pxd-nav-label,
4646
+ .pxd-nav-bar .pxd-nav-label {
4647
+ flex: none;
4648
+ max-width: 100%;
4649
+ overflow: hidden;
4650
+ text-overflow: ellipsis;
4651
+ white-space: nowrap;
4652
+ text-align: center;
4653
+ }
4654
+ .pxd-nav-glyph {
4655
+ font-family: var(--pxd-type-label-default-family);
4656
+ font-size: var(--pxd-type-label-default-size);
4657
+ font-weight: var(--pxd-type-label-default-weight);
4658
+ }
4659
+ .pxd-nav-rail-icon .pxd-nav-badge,
4660
+ .pxd-nav-bar-icon .pxd-nav-badge {
4661
+ position: absolute;
4662
+ top: 0;
4663
+ inset-inline-start: calc(50% + 4px);
4664
+ min-width: 16px;
4665
+ height: 16px;
4666
+ padding: 0 var(--pxd-space-inline-tight);
4667
+ line-height: 16px;
4668
+ }
4669
+ /* Bar: 80px along the bottom, above the safe area; the slot sticks to the bottom of the view. */
4670
+ .pxd-frame[data-pxd-nav="bar"] .pxd-frame-nav {
4671
+ position: sticky;
4672
+ bottom: 0;
4673
+ z-index: 5;
4674
+ border-inline-end: 0;
4675
+ border-top: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4676
+ }
4677
+ .pxd-nav-bar {
4678
+ padding-bottom: env(safe-area-inset-bottom);
4679
+ }
4680
+ .pxd-nav-bar ul {
4681
+ display: flex;
4682
+ height: 80px;
4683
+ }
4684
+ .pxd-nav-bar li {
4685
+ flex: 1 1 0;
4686
+ min-width: 0;
4687
+ }
4688
+ .pxd-nav-bar-item {
4689
+ height: 100%;
4690
+ padding-inline: var(--pxd-space-inline-tight);
4691
+ }
4692
+
4693
+ /* ---- AppBar ---- */
4694
+ .pxd-appbar-sentinel {
4695
+ height: 0;
4696
+ }
4697
+ .pxd-appbar {
4698
+ display: flex;
4699
+ flex-direction: column;
4700
+ z-index: 6;
4701
+ background: var(--pxd-color-surface-default);
4702
+ border-bottom: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4703
+ transition: box-shadow var(--pxd-motion-duration-short) var(--pxd-motion-easing-standard);
4704
+ }
4705
+ .pxd-appbar-sticky {
4706
+ position: sticky;
4707
+ top: 0;
4708
+ }
4709
+ .pxd-appbar[data-pxd-scrolled] {
4710
+ box-shadow: var(--pxd-shadow-raised);
4711
+ }
4712
+ .pxd-appbar-row {
4713
+ display: flex;
4714
+ align-items: center;
4715
+ gap: var(--pxd-space-inline-default);
4716
+ min-height: 64px;
4717
+ padding: 0 var(--pxd-space-inset-default);
4718
+ }
4719
+ .pxd-appbar-compact .pxd-appbar-row {
4720
+ min-height: 48px;
4721
+ }
4722
+ .pxd-appbar-headline {
4723
+ display: flex;
4724
+ align-items: flex-end;
4725
+ min-height: 56px;
4726
+ padding: 0 var(--pxd-space-inset-comfortable) var(--pxd-space-stack-default);
4727
+ font-family: var(--pxd-type-title-page-family);
4728
+ font-size: var(--pxd-type-title-page-size);
4729
+ font-weight: var(--pxd-type-title-page-weight);
4730
+ line-height: var(--pxd-type-title-page-line-height);
4731
+ letter-spacing: var(--pxd-type-title-page-letter-spacing);
4732
+ }
4733
+ .pxd-appbar-leading,
4734
+ .pxd-appbar-menu {
4735
+ flex: none;
4736
+ }
4737
+ .pxd-appbar-brand {
4738
+ display: flex;
4739
+ align-items: center;
4740
+ gap: var(--pxd-space-inline-default);
4741
+ min-width: 0;
4742
+ }
4743
+ .pxd-appbar-title {
4744
+ font-family: var(--pxd-type-title-section-family);
4745
+ font-size: var(--pxd-type-title-section-size);
4746
+ font-weight: var(--pxd-type-title-section-weight);
4747
+ line-height: var(--pxd-type-title-section-line-height);
4748
+ letter-spacing: var(--pxd-type-title-section-letter-spacing);
4749
+ white-space: nowrap;
4750
+ overflow: hidden;
4751
+ text-overflow: ellipsis;
4752
+ }
4753
+ .pxd-appbar-logo {
4754
+ display: block;
4755
+ height: 32px;
4756
+ width: auto;
4757
+ }
4758
+ .pxd-appbar-mark {
4759
+ display: inline-flex;
4760
+ align-items: center;
4761
+ justify-content: center;
4762
+ flex: none;
4763
+ width: 32px;
4764
+ height: 32px;
4765
+ border-radius: var(--pxd-radius-small);
4766
+ background: var(--pxd-color-action-primary-background);
4767
+ color: var(--pxd-color-action-primary-foreground);
4768
+ font-family: var(--pxd-type-label-small-family);
4769
+ font-size: var(--pxd-type-label-small-size);
4770
+ font-weight: var(--pxd-type-label-small-weight);
4771
+ }
4772
+ /* Search grows in the middle on wide layouts; on compact it opens from an icon on its own row. */
4773
+ .pxd-appbar-search {
4774
+ flex: 1 1 auto;
4775
+ min-width: 0;
4776
+ max-width: 40rem;
4777
+ margin-inline: auto;
4778
+ }
4779
+ .pxd-appbar-search .pxd-field-label,
4780
+ .pxd-appbar-search .pxd-label {
4781
+ position: absolute;
4782
+ width: 1px;
4783
+ height: 1px;
4784
+ overflow: hidden;
4785
+ clip: rect(0 0 0 0);
4786
+ white-space: nowrap;
4787
+ }
4788
+ .pxd-appbar-search-toggle {
4789
+ flex: none;
4790
+ margin-inline-start: auto;
4791
+ }
4792
+ .pxd-appbar-search-row {
4793
+ flex: none;
4794
+ width: 100%;
4795
+ max-width: none;
4796
+ padding: 0 var(--pxd-space-inset-default) var(--pxd-space-inset-compact);
4797
+ }
4798
+ .pxd-appbar-end {
4799
+ display: flex;
4800
+ align-items: center;
4801
+ gap: var(--pxd-space-inline-default);
4802
+ flex: none;
4803
+ margin-inline-start: auto;
4804
+ }
4805
+ .pxd-appbar-search + .pxd-appbar-end,
4806
+ .pxd-appbar-search-toggle + .pxd-appbar-end {
4807
+ margin-inline-start: 0;
4808
+ }
4809
+ /* The bar's actions stay in one row whatever the width; the ActionBar folds the rest away. */
4810
+ .pxd-appbar .pxd-action-bar {
4811
+ flex-direction: row-reverse;
4812
+ flex-wrap: nowrap;
4813
+ align-items: center;
4814
+ }
4815
+ .pxd-appbar-account {
4816
+ display: flex;
4817
+ align-items: center;
4818
+ }
4819
+ .pxd-appbar-account .pxd-identity-name,
4820
+ .pxd-appbar-account .pxd-identity-detail {
4821
+ display: none;
4822
+ }
4823
+ .pxd-appbar-account .pxd-identity-button {
4824
+ margin: 0;
4825
+ min-width: var(--pxd-size-target-min);
4826
+ justify-content: center;
4827
+ }
4828
+
4829
+ /* ---- Outlet ---- */
4830
+ .pxd-outlet {
4831
+ display: flex;
4832
+ flex-direction: column;
4833
+ gap: var(--pxd-space-stack-loose);
4834
+ min-width: 0;
4835
+ padding: var(--pxd-space-inset-comfortable);
4836
+ outline: none;
4837
+ }
4838
+ .pxd-frame[data-pxd-layout="compact"] .pxd-outlet {
4839
+ padding: var(--pxd-space-inset-default);
4840
+ }
4841
+ .pxd-outlet:focus-visible {
4842
+ outline: var(--pxd-focus-ring-width) solid var(--pxd-color-border-focus);
4843
+ outline-offset: calc(-1 * var(--pxd-focus-ring-width));
4844
+ }
4845
+ /* A screen document inside the outlet is a screen, not a second frame: no padding of its own. */
4846
+ .pxd-outlet > .pxd-surface {
4847
+ padding: 0;
4848
+ }
4849
+ .pxd-outlet-skeleton {
4850
+ padding: 0;
4851
+ }
4852
+
4853
+ /* ---- Footer ---- */
4854
+ .pxd-footer {
4855
+ display: flex;
4856
+ flex-direction: column;
4857
+ gap: var(--pxd-space-stack-loose);
4858
+ padding: var(--pxd-space-inset-comfortable);
4859
+ border-top: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4860
+ background: var(--pxd-color-surface-subtle);
4861
+ }
4862
+ .pxd-footer-groups {
4863
+ display: grid;
4864
+ grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
4865
+ gap: var(--pxd-space-stack-loose) var(--pxd-space-inline-loose);
4866
+ }
4867
+ .pxd-frame[data-pxd-layout="compact"] .pxd-footer {
4868
+ padding: var(--pxd-space-inset-default);
4869
+ }
4870
+ .pxd-frame[data-pxd-layout="compact"] .pxd-footer-groups {
4871
+ grid-template-columns: minmax(0, 1fr);
4872
+ }
4873
+ .pxd-footer-group ul {
4874
+ display: flex;
4875
+ flex-direction: column;
4876
+ }
4877
+ .pxd-footer-heading {
4878
+ margin: 0 0 var(--pxd-space-stack-default);
4879
+ font-family: var(--pxd-type-label-default-family);
4880
+ font-size: var(--pxd-type-label-default-size);
4881
+ font-weight: var(--pxd-type-label-default-weight);
4882
+ line-height: var(--pxd-type-label-default-line-height);
4883
+ letter-spacing: var(--pxd-type-label-default-letter-spacing);
4884
+ }
4885
+ /* Links in the default text colour: the link colour is only guaranteed on surface.default and the
4886
+ footer sits on surface.subtle. Each is a full target tall, so a thumb reaches one at a time. */
4887
+ .pxd-footer-link {
4888
+ display: inline-flex;
4889
+ align-items: center;
4890
+ justify-content: flex-start;
4891
+ min-width: var(--polyxd-control);
4892
+ min-height: var(--polyxd-control);
4893
+ color: var(--pxd-color-text-default);
4894
+ }
4895
+ .pxd-footer-legal {
4896
+ display: flex;
4897
+ flex-wrap: wrap;
4898
+ align-items: center;
4899
+ justify-content: space-between;
4900
+ gap: var(--pxd-space-stack-default) var(--pxd-space-inline-loose);
4901
+ color: var(--pxd-color-text-muted);
4902
+ font-family: var(--pxd-type-body-small-family);
4903
+ font-size: var(--pxd-type-body-small-size);
4904
+ line-height: var(--pxd-type-body-small-line-height);
4905
+ }
4906
+ .pxd-footer-legal-text {
4907
+ margin: 0;
4908
+ }
4909
+ .pxd-footer-aside {
4910
+ display: flex;
4911
+ align-items: center;
4912
+ gap: var(--pxd-space-inline-default);
4913
+ }
4914
+
4915
+ /* ---- Custom ---- */
4916
+ /* A named slot only wraps when it has a label to give; otherwise the host's element stands alone. */
4917
+ .pxd-custom {
4918
+ display: contents;
4919
+ }
4920
+
4921
+ /* ---- Columns ---- */
4922
+ /* Side-by-side on the surface's width, a stack below the collapse point; the children's order
4923
+ is the reading order either way. */
4924
+ .pxd-columns {
4925
+ display: grid;
4926
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
4927
+ gap: var(--pxd-space-stack-loose) var(--pxd-space-inline-loose);
4928
+ align-items: stretch;
4929
+ }
4930
+ .pxd-columns-one-third { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
4931
+ .pxd-columns-halves { grid-template-columns: repeat(2, minmax(0, 1fr)); }
4932
+ .pxd-columns-thirds { grid-template-columns: repeat(3, minmax(0, 1fr)); }
4933
+ .pxd-columns-sidebar-start { grid-template-columns: minmax(16rem, 18rem) minmax(0, 1fr); }
4934
+ .pxd-columns-sidebar-end { grid-template-columns: minmax(0, 1fr) minmax(16rem, 18rem); }
4935
+ .pxd-columns-align-start { align-items: start; }
4936
+ .pxd-columns-align-center { align-items: center; }
4937
+ .pxd-columns > * {
4938
+ min-width: 0;
4939
+ }
4940
+ @container pxd (width < 40rem) {
4941
+ .pxd-columns-collapse-compact {
4942
+ grid-template-columns: minmax(0, 1fr);
4943
+ }
4944
+ }
4945
+ @container pxd (width < 64rem) {
4946
+ .pxd-columns-collapse-medium {
4947
+ grid-template-columns: minmax(0, 1fr);
4948
+ }
4949
+ }
4950
+
4951
+ /* ---- Split ---- */
4952
+ /* Two panes with a border between; the list scrolls on its own. The list's share follows the
4953
+ ratio, or the handle when the split is resizable. Compact shows one pane at a time. */
4954
+ .pxd-split {
4955
+ --polyxd-split-share: 33.333%;
4956
+ display: grid;
4957
+ grid-template-columns: minmax(16rem, 1fr) minmax(0, 2fr);
4958
+ align-items: stretch;
4959
+ min-height: 0;
4960
+ border: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4961
+ border-radius: var(--pxd-radius-default);
4962
+ overflow: hidden;
4963
+ }
4964
+ .pxd-split-balanced { grid-template-columns: repeat(2, minmax(0, 1fr)); }
4965
+ .pxd-split-wide { grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr); }
4966
+ .pxd-split-resizable {
4967
+ grid-template-columns: var(--polyxd-split-share) var(--pxd-size-target-min) minmax(0, 1fr);
4968
+ }
4969
+ .pxd-split-primary {
4970
+ min-width: 0;
4971
+ max-height: 100%;
4972
+ overflow-y: auto;
4973
+ padding: var(--pxd-space-inset-default);
4974
+ border-inline-end: var(--pxd-border-width-default) solid var(--pxd-color-border-default);
4975
+ }
4976
+ .pxd-split-resizable .pxd-split-primary {
4977
+ border-inline-end: 0;
4978
+ }
4979
+ .pxd-split-detail {
4980
+ display: flex;
4981
+ flex-direction: column;
4982
+ gap: var(--pxd-space-stack-loose);
4983
+ min-width: 0;
4984
+ padding: var(--pxd-space-inset-comfortable);
4985
+ outline: none;
4986
+ }
4987
+ .pxd-split-detail:focus-visible {
4988
+ outline: var(--pxd-focus-ring-width) solid var(--pxd-color-border-focus);
4989
+ outline-offset: calc(-1 * var(--pxd-focus-ring-width));
4990
+ }
4991
+ /* The handle is a full target wide, the line it draws is one border wide. */
4992
+ .pxd-split-handle {
4993
+ display: flex;
4994
+ align-items: stretch;
4995
+ justify-content: center;
4996
+ cursor: col-resize;
4997
+ touch-action: none;
4998
+ }
4999
+ .pxd-split-handle-line {
5000
+ width: var(--pxd-border-width-default);
5001
+ background: var(--pxd-color-border-default);
5002
+ transition: background var(--pxd-motion-duration-short) var(--pxd-motion-easing-standard);
5003
+ }
5004
+ .pxd-split-handle:hover .pxd-split-handle-line {
5005
+ width: var(--pxd-border-width-strong);
5006
+ background: var(--pxd-color-border-strong);
5007
+ }
5008
+ .pxd-split-handle:focus-visible {
5009
+ outline: var(--pxd-focus-ring-width) solid var(--pxd-color-border-focus);
5010
+ outline-offset: calc(-1 * var(--pxd-focus-ring-width));
5011
+ }
5012
+ .pxd-split-compact {
5013
+ grid-template-columns: minmax(0, 1fr);
5014
+ }
5015
+ .pxd-split-compact .pxd-split-primary {
5016
+ border-inline-end: 0;
5017
+ max-height: none;
5018
+ }
5019
+ .pxd-split-compact .pxd-split-detail {
5020
+ padding: var(--pxd-space-inset-default);
5021
+ }
5022
+ .pxd-split-back {
5023
+ align-self: flex-start;
5024
+ }