@visns-studio/visns-components 6.0.4 → 6.0.5

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,3 +1,8 @@
1
+ @use 'controls' as *;
2
+
3
+ .btn {
4
+ @include button-primary;
5
+ }
1
6
  .grid {
2
7
  &__row {
3
8
  width: 100%;
@@ -138,7 +143,10 @@
138
143
  border: 1px solid var(--border-color);
139
144
  box-sizing: border-box;
140
145
  padding: 0;
141
- margin: 5px;
146
+ /* Zero, not 5px: the breadcrumb above uses .crmtitle, which sets
147
+ margin:0 and therefore sits 5px wider on each side. The two panels
148
+ have to share an edge or the page looks misaligned. */
149
+ margin: 0;
142
150
  height: auto;
143
151
  position: relative;
144
152
 
@@ -777,28 +785,9 @@ select:not(:placeholder-shown) + .fi__span {
777
785
  }
778
786
 
779
787
  /* Adding btn class */
780
- .btn {
781
- width: max-content;
782
- display: inline-block;
783
- position: relative;
784
- padding: 0.65rem 1rem;
785
- cursor: pointer;
786
- font-size: 1rem;
787
- color: var(--tertiary-color);
788
- text-decoration: none;
789
- overflow: hidden;
790
- background: var(--primary-color);
791
- border: 1px solid rgba(var(--primary-rgb), 1.1);
792
- border-radius: var(--br);
793
- outline: none;
794
- transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
795
- }
796
788
 
797
- .btn:hover {
798
- color: var(--tertiary-color);
799
- background: var(--secondary-color);
800
- border: 1px solid rgba(var(--secondary-color-rgb), 1.1);
801
- }
789
+
790
+
802
791
 
803
792
  /* Floating action buttons */
804
793
  .polActions {
@@ -1594,17 +1583,43 @@ select:not(:placeholder-shown) + .fi__span {
1594
1583
  }
1595
1584
 
1596
1585
  .emptyState {
1597
- padding: 4rem 2rem;
1586
+ /* Full width of the panel. It previously sat inside a two-column grid and
1587
+ inherited the 216px rail column, which squeezed the message into a
1588
+ narrow box with every word on its own line. */
1589
+ width: 100%;
1590
+ max-width: 460px;
1591
+ margin: 3rem auto;
1592
+ padding: 2.5rem 2rem;
1598
1593
  text-align: center;
1599
- color: rgba(var(--paragraph-color-rgb), 0.5);
1600
- font-size: 0.95rem;
1601
- background: rgba(var(--primary-rgb), 0.02);
1602
- border: 2px dashed rgba(var(--primary-rgb), 0.12);
1603
- border-radius: var(--br);
1604
- margin: 1.5rem;
1594
+ background: rgba(var(--primary-rgb), 0.03);
1595
+ border: 1px dashed rgba(var(--primary-rgb), 0.2);
1596
+ border-radius: 12px;
1597
+
1598
+ &__icon {
1599
+ display: inline-flex;
1600
+ align-items: center;
1601
+ justify-content: center;
1602
+ width: 52px;
1603
+ height: 52px;
1604
+ border-radius: 50%;
1605
+ background: rgba(var(--primary-rgb), 0.1);
1606
+ color: var(--primary-color);
1607
+ margin-bottom: 1rem;
1608
+ }
1609
+
1610
+ h3 {
1611
+ margin: 0 0 0.4rem;
1612
+ font-size: 15px;
1613
+ font-weight: 700;
1614
+ color: var(--paragraph-color);
1615
+ }
1605
1616
 
1606
1617
  p {
1607
- margin: 0;
1618
+ margin: 0 auto 1.25rem;
1619
+ max-width: 320px;
1620
+ font-size: 13px;
1621
+ line-height: 1.55;
1622
+ color: rgba(var(--paragraph-rgb), 0.6);
1608
1623
  }
1609
1624
  }
1610
1625
 
@@ -2269,3 +2284,503 @@ select:not(:placeholder-shown) + .fi__span {
2269
2284
  background: rgba(var(--paragraph-color-rgb), 0.15) !important;
2270
2285
  }
2271
2286
  }
2287
+
2288
+ /* ============================================================
2289
+ Builder layout: outline rail, compact rows, mode switch
2290
+ ============================================================ */
2291
+
2292
+ /* Only the page header, never a section bar — the two share
2293
+ .gridtxt__header, so these rules must not be applied to it directly. */
2294
+ .builderBar {
2295
+ display: flex;
2296
+ align-items: center;
2297
+ justify-content: space-between;
2298
+ gap: 1rem;
2299
+ flex-wrap: wrap;
2300
+ /* Full-bleed across the panel.
2301
+ width must be auto: .gridtxt__header sets width:100%, which pins the
2302
+ box to the parent's content width, so negative margins SHIFT it left
2303
+ instead of widening it — leaving a gap on the right only. */
2304
+ width: auto !important;
2305
+ margin: 0 -1.15rem !important;
2306
+ padding: 0.7rem 1.15rem !important;
2307
+ border-radius: 0 !important;
2308
+ }
2309
+
2310
+ .builderTools {
2311
+ display: flex;
2312
+ align-items: center;
2313
+ gap: 0.6rem;
2314
+ font-weight: 400;
2315
+ }
2316
+
2317
+ .fieldCount {
2318
+ font-size: 11.5px;
2319
+ color: rgba(var(--paragraph-rgb), 0.65);
2320
+ white-space: nowrap;
2321
+ }
2322
+
2323
+ .toolBtn {
2324
+ display: inline-flex;
2325
+ align-items: center;
2326
+ gap: 0.35rem;
2327
+ height: 28px;
2328
+ padding: 0 0.6rem;
2329
+ border: 1px solid rgba(var(--primary-rgb), 0.25);
2330
+ border-radius: 6px;
2331
+ background: #fff;
2332
+ color: var(--primary-color);
2333
+ font: inherit;
2334
+ font-size: 12px;
2335
+ font-weight: 600;
2336
+ cursor: pointer;
2337
+ }
2338
+
2339
+ .toolBtnOn {
2340
+ background: var(--primary-color);
2341
+ color: #fff;
2342
+ border-color: var(--primary-color);
2343
+ }
2344
+
2345
+ /* Edit / Preview. Compact editing is the default; the live render is the
2346
+ thing you opt into, not the thing you scroll past. */
2347
+ .modeSwitch {
2348
+ display: inline-flex;
2349
+ border: 1px solid rgba(var(--primary-rgb), 0.25);
2350
+ border-radius: 6px;
2351
+ overflow: hidden;
2352
+
2353
+ button {
2354
+ height: 28px;
2355
+ padding: 0 0.7rem;
2356
+ border: none;
2357
+ background: #fff;
2358
+ color: var(--primary-color);
2359
+ font: inherit;
2360
+ font-size: 12px;
2361
+ font-weight: 600;
2362
+ cursor: pointer;
2363
+ }
2364
+ }
2365
+
2366
+ .modeOn {
2367
+ background: var(--primary-color) !important;
2368
+ color: #fff !important;
2369
+ }
2370
+
2371
+ /* ---- outline rail ---- */
2372
+
2373
+ /* Base layout. Spacing lives here rather than only on the with-rail variant,
2374
+ so hiding the outline does not drop the padding and jump the list up
2375
+ against the toolbar. */
2376
+ /* Body inset.
2377
+ No top padding: the grey toolbar is the first child of this container, so
2378
+ padding-top lands ABOVE the bar rather than between it and the content —
2379
+ which is why the chips ended up flush against it. Spacing below the bar is
2380
+ owned by whatever follows it. */
2381
+ .formSplit {
2382
+ padding: 0 1.15rem 1.5rem;
2383
+ }
2384
+
2385
+ /**
2386
+ * Toolbar and section strip pinned together.
2387
+ *
2388
+ * One sticky element rather than two: separately, the strip's offset had to
2389
+ * equal the toolbar's height, a number that breaks silently whenever the
2390
+ * toolbar's padding or type size changes.
2391
+ *
2392
+ * The offset is the app header's measured height — it is position:fixed in
2393
+ * the host project with no declared height, so top:0 parks this underneath
2394
+ * it. See the measuring effect in GenericFormBuilder.
2395
+ */
2396
+ .stickyHead {
2397
+ position: sticky;
2398
+ top: var(--fb-sticky-top, 0px);
2399
+ z-index: 30;
2400
+ /* Below the app header's own stacking context (995). */
2401
+ background: #fff;
2402
+ margin: 0 -1.15rem;
2403
+ padding: 0 1.15rem;
2404
+ }
2405
+
2406
+ /* Children already carry their own full-bleed margins; inside the wrapper
2407
+ that would double up. */
2408
+ .stickyHead > .builderBar,
2409
+ .stickyHead > .sectionNav {
2410
+ margin-left: -1.15rem !important;
2411
+ margin-right: -1.15rem !important;
2412
+ }
2413
+
2414
+
2415
+ /* The header and search span both columns; only the rail and canvas sit
2416
+ side by side. */
2417
+
2418
+ /* ---- section chips ----
2419
+ Five short sections did not justify a 216px column, and the rail's tinted
2420
+ surface stopped dead after the last item. A strip costs about 40px of
2421
+ height and hands the full width back to the list. */
2422
+ .sectionNav {
2423
+ display: flex;
2424
+ flex-wrap: wrap;
2425
+ align-items: center;
2426
+ gap: 0.4rem;
2427
+ /* Clear air below the toolbar, and the rule pulled out to the panel edges
2428
+ so it divides the strip from the list rather than floating inside it. */
2429
+ width: auto;
2430
+ margin: 0 -1.15rem 1.15rem;
2431
+ padding: 1rem 1.15rem;
2432
+ /* Opaque: a translucent tint would let field rows show through while
2433
+ this is stuck. */
2434
+ background: #f7f9fc;
2435
+ border-bottom: 1px solid var(--border-color);
2436
+ }
2437
+
2438
+ .sectionChip {
2439
+ display: inline-flex;
2440
+ align-items: center;
2441
+ gap: 0.4rem;
2442
+ height: 30px;
2443
+ padding: 0 0.5rem 0 0.65rem;
2444
+ border: 1px solid rgba(var(--primary-rgb), 0.22);
2445
+ /* Matches the buttons and rows around it. */
2446
+ border-radius: 7px;
2447
+ background: #fff;
2448
+ color: var(--paragraph-color);
2449
+ font: inherit;
2450
+ font-size: 12px;
2451
+ cursor: pointer;
2452
+ max-width: 260px;
2453
+
2454
+ &:hover {
2455
+ border-color: var(--primary-color);
2456
+ background: rgba(var(--primary-rgb), 0.06);
2457
+ }
2458
+
2459
+ &__label {
2460
+ overflow: hidden;
2461
+ text-overflow: ellipsis;
2462
+ white-space: nowrap;
2463
+ }
2464
+
2465
+ &__count {
2466
+ font-size: 10.5px;
2467
+ font-variant-numeric: tabular-nums;
2468
+ font-weight: 700;
2469
+ color: rgba(var(--paragraph-rgb), 0.5);
2470
+ background: rgba(var(--paragraph-rgb), 0.08);
2471
+ border-radius: 4px;
2472
+ padding: 1px 5px;
2473
+ }
2474
+ }
2475
+
2476
+ .sectionChipActive {
2477
+ background: var(--primary-color);
2478
+ border-color: var(--primary-color);
2479
+ color: #fff;
2480
+ font-weight: 600;
2481
+
2482
+ .sectionChip__count {
2483
+ color: #fff;
2484
+ background: rgba(255, 255, 255, 0.22);
2485
+ }
2486
+
2487
+ &:hover {
2488
+ background: var(--primary-dark-color, var(--primary-color));
2489
+ }
2490
+ }
2491
+
2492
+ /* A collapsed section is still navigable, but should not look the same as
2493
+ one you can actually see. */
2494
+ .sectionChipCollapsed {
2495
+ border-style: dashed;
2496
+ opacity: 0.65;
2497
+ }
2498
+
2499
+ /* ---- search ---- */
2500
+
2501
+ .searchBarTop {
2502
+ /* Inline in the toolbar: no band, no divider, sized to sit beside the
2503
+ other controls rather than above them. */
2504
+ background: transparent !important;
2505
+ border-bottom: none !important;
2506
+ padding: 0 !important;
2507
+ margin: 0 !important;
2508
+ position: relative;
2509
+ width: 240px;
2510
+ flex: 0 0 auto;
2511
+
2512
+ .searchIcon {
2513
+ position: absolute;
2514
+ left: 9px;
2515
+ top: 50%;
2516
+ transform: translateY(-50%);
2517
+ z-index: 1;
2518
+ pointer-events: none;
2519
+ color: rgba(var(--paragraph-rgb), 0.45);
2520
+ }
2521
+
2522
+ .searchInput {
2523
+ width: 100%;
2524
+ padding: 0 2rem 0 1.9rem !important;
2525
+ height: 28px !important;
2526
+ min-height: 28px !important;
2527
+ border-radius: 6px !important;
2528
+ border-color: rgba(var(--primary-rgb), 0.25) !important;
2529
+ font-size: 12px !important;
2530
+
2531
+ &::placeholder {
2532
+ color: rgba(var(--paragraph-rgb), 0.45);
2533
+ }
2534
+
2535
+ &:focus {
2536
+ border-color: var(--primary-color) !important;
2537
+ box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12) !important;
2538
+ }
2539
+ }
2540
+
2541
+ .searchCount {
2542
+ position: absolute;
2543
+ right: 1.9rem;
2544
+ top: 50%;
2545
+ transform: translateY(-50%);
2546
+ background: none;
2547
+ padding: 0;
2548
+ font-size: 10.5px;
2549
+ font-weight: 600;
2550
+ color: rgba(var(--paragraph-rgb), 0.5);
2551
+ }
2552
+
2553
+ .searchClear {
2554
+ position: absolute;
2555
+ right: 0.3rem;
2556
+ top: 50%;
2557
+ transform: translateY(-50%);
2558
+ padding: 2px;
2559
+ }
2560
+ }
2561
+
2562
+ /* ---- compact rows ---- */
2563
+
2564
+
2565
+
2566
+
2567
+ .duplicateBtn {
2568
+ display: flex;
2569
+ align-items: center;
2570
+ padding: 2px;
2571
+ border: none;
2572
+ background: none;
2573
+ color: rgba(var(--paragraph-rgb), 0.55);
2574
+ cursor: pointer;
2575
+
2576
+ &:hover {
2577
+ color: var(--primary-color);
2578
+ }
2579
+ }
2580
+
2581
+ @media (max-width: 900px) {
2582
+ /* Chips scroll sideways rather than stacking into a tall block that
2583
+ pushes the list off screen. */
2584
+ .sectionNav {
2585
+ flex-wrap: nowrap;
2586
+ overflow-x: auto;
2587
+ padding-bottom: 0.65rem;
2588
+ }
2589
+
2590
+ .sectionChip {
2591
+ flex: 0 0 auto;
2592
+ }
2593
+ }
2594
+
2595
+ .cRow {
2596
+ display: flex;
2597
+ align-items: center;
2598
+ gap: 0.5rem;
2599
+ width: 100%;
2600
+ min-height: 34px;
2601
+ padding: 0 0.5rem;
2602
+ box-sizing: border-box;
2603
+ background: #fff;
2604
+ border: 1px solid var(--border-color);
2605
+ border-radius: 6px;
2606
+ font-size: 13px;
2607
+
2608
+ &:hover {
2609
+ border-color: rgba(var(--primary-rgb), 0.45);
2610
+ background: rgba(var(--primary-rgb), 0.03);
2611
+ }
2612
+ }
2613
+
2614
+ .cRowDragging {
2615
+ opacity: 0.5;
2616
+ box-shadow: 0 8px 20px -8px rgba(0, 0, 0, 0.3);
2617
+ }
2618
+
2619
+ /* Sections read as headings, not as another entry in the list. */
2620
+ .cRowSection {
2621
+ margin-top: 0.75rem;
2622
+ background: rgba(var(--primary-rgb), 0.09);
2623
+ border: none;
2624
+ border-left: 3px solid var(--primary-color);
2625
+ border-radius: 4px;
2626
+ min-height: 36px;
2627
+
2628
+ .cLabel {
2629
+ font-weight: 700;
2630
+ text-transform: uppercase;
2631
+ letter-spacing: 0.04em;
2632
+ font-size: 11.5px;
2633
+ color: var(--primary-color);
2634
+ }
2635
+
2636
+ &:hover {
2637
+ background: rgba(var(--primary-rgb), 0.14);
2638
+ }
2639
+ }
2640
+
2641
+ .cGrip {
2642
+ flex: 0 0 auto;
2643
+ display: flex;
2644
+ align-items: center;
2645
+ color: rgba(var(--paragraph-rgb), 0.4);
2646
+ cursor: grab;
2647
+
2648
+ &:active {
2649
+ cursor: grabbing;
2650
+ }
2651
+ }
2652
+
2653
+ .cNum {
2654
+ flex: 0 0 auto;
2655
+ min-width: 24px;
2656
+ text-align: right;
2657
+ font-size: 10.5px;
2658
+ color: rgba(var(--paragraph-rgb), 0.45);
2659
+ font-variant-numeric: tabular-nums;
2660
+ }
2661
+
2662
+ .cCollapse {
2663
+ flex: 0 0 auto;
2664
+ display: flex;
2665
+ align-items: center;
2666
+ padding: 0;
2667
+ border: none;
2668
+ background: none;
2669
+ color: var(--primary-color);
2670
+ cursor: pointer;
2671
+ }
2672
+
2673
+ .cLabel {
2674
+ flex: 1 1 auto;
2675
+ min-width: 0;
2676
+ font-weight: 600;
2677
+ color: var(--paragraph-color);
2678
+ overflow: hidden;
2679
+ text-overflow: ellipsis;
2680
+ white-space: nowrap;
2681
+
2682
+ em {
2683
+ font-weight: 400;
2684
+ opacity: 0.55;
2685
+ }
2686
+ }
2687
+
2688
+ .cMeta {
2689
+ flex: 0 0 auto;
2690
+ font-size: 10.5px;
2691
+ color: rgba(var(--paragraph-rgb), 0.55);
2692
+ white-space: nowrap;
2693
+ }
2694
+
2695
+ /* Actions stay out of the way until the row is hovered, so 87 rows are not
2696
+ 87 clusters of icons competing with the labels. */
2697
+ .cActions {
2698
+ flex: 0 0 auto;
2699
+ display: flex;
2700
+ align-items: center;
2701
+ gap: 1px;
2702
+ opacity: 0;
2703
+ transition: opacity 0.12s linear;
2704
+
2705
+ button {
2706
+ display: flex;
2707
+ align-items: center;
2708
+ padding: 4px;
2709
+ border: none;
2710
+ background: none;
2711
+ color: rgba(var(--paragraph-rgb), 0.55);
2712
+ cursor: pointer;
2713
+ border-radius: 4px;
2714
+
2715
+ &:hover {
2716
+ color: var(--primary-color);
2717
+ background: rgba(var(--primary-rgb), 0.1);
2718
+ }
2719
+ }
2720
+ }
2721
+
2722
+ .cRow:hover .cActions,
2723
+ .cActions:focus-within {
2724
+ opacity: 1;
2725
+ }
2726
+
2727
+ .cDelete:hover {
2728
+ color: var(--secondary-color) !important;
2729
+ background: rgba(var(--secondary-rgb), 0.1) !important;
2730
+ }
2731
+
2732
+ /* ============================================================
2733
+ Preview mode — the form as a supervisor sees it
2734
+ ============================================================ */
2735
+
2736
+ .pvForm {
2737
+ /* Sections span the full width and break the row, so each group starts
2738
+ on its own line the way it will in the field app. */
2739
+ align-items: flex-start;
2740
+ padding: 0.5rem 0.25rem 1rem;
2741
+ }
2742
+
2743
+ .pvItem {
2744
+ padding: 0.35rem 0.5rem;
2745
+ box-sizing: border-box;
2746
+
2747
+ /* None of the authoring affordances belong here: no hover outline, no
2748
+ grab cursor, nothing that suggests this view is editable. */
2749
+ cursor: default;
2750
+
2751
+ &:hover {
2752
+ background: none;
2753
+ border-color: transparent;
2754
+ }
2755
+
2756
+ /* Any editing furniture that a shared child style might still emit. */
2757
+ .fieldIndex,
2758
+ .fieldInfo,
2759
+ .fieldControls,
2760
+ .dragHandle {
2761
+ display: none !important;
2762
+ }
2763
+
2764
+ .fieldContent {
2765
+ padding-top: 0 !important;
2766
+ border: none;
2767
+ min-height: 0;
2768
+ }
2769
+ }
2770
+
2771
+ /* Section bars read as headings in preview, full width and self-contained. */
2772
+ .pvForm .fwBuilderItem:has(.gridtxt__header) {
2773
+ width: 100% !important;
2774
+ margin: 1.25rem 0 0.35rem;
2775
+ padding-left: 0;
2776
+ padding-right: 0;
2777
+ }
2778
+
2779
+ /* A dynamic template is not an unfinished one — it should not wear the
2780
+ dashed "something is missing" treatment. */
2781
+ .emptyStateDynamic {
2782
+ border-style: solid;
2783
+ border-color: rgba(var(--primary-rgb), 0.15);
2784
+ background: rgba(var(--primary-rgb), 0.04);
2785
+ max-width: 520px;
2786
+ }
@@ -1,3 +1,8 @@
1
+ @use 'controls' as *;
2
+
3
+ .btn {
4
+ @include button-primary;
5
+ }
1
6
  .grid__row {
2
7
  width: 100%;
3
8
  display: flex;
@@ -196,36 +201,11 @@
196
201
  margin: 0 0 30px 0;
197
202
  }
198
203
 
199
- .btn {
200
- width: max-content;
201
- display: inline-block;
202
- position: relative;
203
- padding: 0.65rem 1rem;
204
- cursor: pointer;
205
- font-size: 1rem;
206
- color: var(--tertiary-color);
207
- text-decoration: none;
208
- overflow: hidden;
209
- background: var(--primary-color);
210
- border: 1px solid rgba(var(--primary-color--rgb), 1.1);
211
- border-radius: var(--br);
212
- outline: none;
213
- transition: all 0.2s cubic-bezier(0.85, 0, 0.15, 1) 0s;
214
- }
215
204
 
216
- .btn:hover:not(:disabled) {
217
- color: var(--primary-color);
218
- background: var(--highlight-color);
219
- border: 1px solid rgba(var(--highlight-color-rgb), 1.05);
220
- }
221
205
 
222
- .btn:disabled {
223
- opacity: 0.5;
224
- cursor: not-allowed;
225
- background: var(--primary-color);
226
- color: var(--tertiary-color);
227
- border: 1px solid rgba(var(--primary-color--rgb), 0.5);
228
- }
206
+
207
+
208
+
229
209
 
230
210
  .polActions {
231
211
  position: fixed;
@@ -743,11 +723,16 @@
743
723
 
744
724
  .crmtitle {
745
725
  min-height: auto;
746
- padding: 1rem;
726
+ /* Was a flat 1rem inside a tinted-navy border, which made the page title
727
+ look like another card competing with the grid below it. A page header
728
+ is not a card: no border, no fill, just the title and its count sitting
729
+ on the page. */
730
+ padding: 0 0 var(--spacing-md);
747
731
  margin: 0;
748
- background: white;
749
- border-radius: var(--br);
750
- border: 1px solid rgba(var(--primary-rgb), 0.15);
732
+ background: none;
733
+ border-radius: 0;
734
+ border: none;
735
+ border-bottom: 1px solid var(--border-color);
751
736
  position: relative;
752
737
  display: flex;
753
738
  align-items: center;
@@ -5,7 +5,11 @@
5
5
  top: 0;
6
6
  width: 100%;
7
7
  z-index: 995;
8
- padding: 0.35rem 1rem;
8
+ /* Was 0.35rem — too tight to read as a deliberate bar. Enough room that
9
+ the nav sits in it rather than being crushed by it. */
10
+ padding: var(--spacing-sm) var(--spacing-md);
11
+ /* Separates the bar from the page when content scrolls under it. */
12
+ box-shadow: var(--shadow-sm);
9
13
  }
10
14
 
11
15
  .headerAlternate {
@@ -82,10 +86,18 @@
82
86
  }
83
87
  }
84
88
 
85
- .padding {
86
- padding: 1rem;
87
- }
88
-
89
+ /* Content gutter. A single flat 1rem before, which on a wide monitor left
90
+ tables running the full width of the glass with no margin to rest against,
91
+ and on a phone gave the same gutter as a desktop. */
92
+ .padding,
89
93
  .paddingSimple {
90
- padding: 1rem;
94
+ padding: var(--spacing-lg) clamp(var(--spacing-md), 3vw, var(--spacing-xl));
95
+ /* Long lines of data are hard to track across an ultrawide screen. This
96
+ is generous enough never to bite on a laptop. */
97
+ max-width: 2200px;
98
+ margin: 0 auto;
99
+
100
+ @media (max-width: 960px) {
101
+ padding: var(--spacing-md) var(--spacing-md);
102
+ }
91
103
  }