@visns-studio/visns-components 6.17.2 → 6.20.1

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 (83) hide show
  1. package/package.json +10 -7
  2. package/src/components/AssociationManager.jsx +344 -177
  3. package/src/components/AsyncSelect.jsx +2 -2
  4. package/src/components/Autocomplete.jsx +57 -12
  5. package/src/components/Breadcrumb.jsx +23 -4
  6. package/src/components/ClientAssociationManager.jsx +321 -145
  7. package/src/components/DataGrid.jsx +625 -20
  8. package/src/components/DropZone.jsx +4 -1
  9. package/src/components/Form.jsx +233 -6
  10. package/src/components/MultiSelect.jsx +2 -2
  11. package/src/components/Navigation.jsx +39 -23
  12. package/src/components/TableFilter.jsx +172 -12
  13. package/src/components/UniversalSearch.jsx +390 -0
  14. package/src/components/auth/Login.jsx +164 -8
  15. package/src/components/auth/Profile.jsx +209 -22
  16. package/src/components/auth/authEndpoints.js +4 -0
  17. package/src/components/auth/webauthn.js +194 -0
  18. package/src/components/columns/ColumnRenderers.jsx +6 -1
  19. package/src/components/controls/DataGridSearch.jsx +11 -5
  20. package/src/components/generic/GenericAuth.jsx +6 -0
  21. package/src/components/generic/GenericDashboard.jsx +93 -36
  22. package/src/components/generic/GenericDetail.jsx +146 -61
  23. package/src/components/generic/GenericIndex.jsx +142 -38
  24. package/src/components/generic/GenericSettings.jsx +220 -0
  25. package/src/components/generic/StandardModal.jsx +165 -8
  26. package/src/components/generic/dashboardChartDefaults.js +230 -0
  27. package/src/components/generic/shared/indexLayout.js +38 -0
  28. package/src/components/settings/IntegrationsManager.jsx +474 -0
  29. package/src/components/sms/SmsLineSettings.jsx +16 -12
  30. package/src/components/styles/AssociationManager.module.scss +4 -363
  31. package/src/components/styles/AuditLog.module.scss +6 -6
  32. package/src/components/styles/AuditLogs.module.scss +3 -3
  33. package/src/components/styles/Autocomplete.module.scss +7 -7
  34. package/src/components/styles/BusinessCardOcr.module.scss +6 -1
  35. package/src/components/styles/CallQueueSettings.module.scss +4 -1
  36. package/src/components/styles/CameraPlacement.module.scss +19 -19
  37. package/src/components/styles/CategorizedDropZone.module.scss +6 -1
  38. package/src/components/styles/ClientAssociationManager.module.scss +5 -289
  39. package/src/components/styles/ClientAuth.module.scss +1 -1
  40. package/src/components/styles/DataGrid.module.scss +455 -8
  41. package/src/components/styles/Field.module.scss +32 -24
  42. package/src/components/styles/Form.module.scss +123 -3
  43. package/src/components/styles/GenericDashboard.module.scss +612 -825
  44. package/src/components/styles/GenericDetail.module.scss +406 -61
  45. package/src/components/styles/GenericDynamic.module.scss +25 -25
  46. package/src/components/styles/GenericEditableTable.module.scss +33 -33
  47. package/src/components/styles/GenericFormBuilder.module.scss +119 -119
  48. package/src/components/styles/GenericIndex.module.scss +483 -38
  49. package/src/components/styles/GenericMain.module.scss +6 -3
  50. package/src/components/styles/GenericQuote.module.scss +399 -81
  51. package/src/components/styles/GenericReport.module.scss +8 -8
  52. package/src/components/styles/GenericSettings.module.scss +209 -0
  53. package/src/components/styles/GenericSort.module.scss +9 -9
  54. package/src/components/styles/Integrations.module.scss +321 -0
  55. package/src/components/styles/List.module.scss +4 -4
  56. package/src/components/styles/Login.module.scss +57 -0
  57. package/src/components/styles/MultiSelect.module.scss +4 -4
  58. package/src/components/styles/Navigation.module.scss +12 -12
  59. package/src/components/styles/Notification.module.scss +12 -8
  60. package/src/components/styles/NotificationList.module.scss +5 -5
  61. package/src/components/styles/Profile.module.scss +5 -5
  62. package/src/components/styles/QrCode.module.scss +4 -4
  63. package/src/components/styles/QuickAction.module.scss +20 -20
  64. package/src/components/styles/SortableQuoteItems.module.scss +4 -4
  65. package/src/components/styles/TableFilter.module.scss +128 -17
  66. package/src/components/styles/TicketConversation.module.scss +497 -0
  67. package/src/components/styles/UniversalSearch.module.scss +229 -0
  68. package/src/components/styles/Vault.module.scss +413 -0
  69. package/src/components/styles/_associationManager.scss +467 -0
  70. package/src/components/styles/_authBrandPanel.scss +15 -9
  71. package/src/components/styles/_controls.scss +43 -39
  72. package/src/components/styles/global-datagrid.css +196 -0
  73. package/src/components/styles/global.css +168 -17
  74. package/src/components/tickets/TicketConversation.jsx +455 -0
  75. package/src/components/utils/rowActionSettings.js +117 -0
  76. package/src/components/vault/VaultClientPicker.jsx +183 -0
  77. package/src/components/vault/VaultEntryForm.jsx +23 -0
  78. package/src/components/vault/VaultManager.jsx +382 -34
  79. package/src/components/vault/VaultShareModal.jsx +454 -0
  80. package/src/components/vault/vaultEndpoints.js +16 -2
  81. package/src/components/vault/vaultShares.js +247 -0
  82. package/src/index.js +35 -0
  83. package/src/utils/fetchUtil.js +38 -14
@@ -153,8 +153,9 @@
153
153
  }
154
154
 
155
155
  .editButton {
156
- background: #4fbfa5;
157
- color: white;
156
+ /* Was #4fbfa5 — a mint that belongs to no palette here. */
157
+ background: var(--primary-color, #1b3933);
158
+ color: #fff;
158
159
 
159
160
  &:hover:not(:disabled) {
160
161
  background: #3da389;
@@ -278,8 +279,8 @@
278
279
  justify-content: space-between;
279
280
  align-items: center;
280
281
  padding: 24px 30px;
281
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
282
- background: linear-gradient(135deg, var(--primary-color) 0%, rgba(var(--primary-rgb), 0.9) 100%);
282
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
283
+ background: linear-gradient(135deg, var(--primary-color) 0%, rgba(var(--primary-rgb, 27, 57, 51), 0.9) 100%);
283
284
  border-radius: 12px 12px 0 0;
284
285
 
285
286
  h3 {
@@ -294,11 +295,11 @@
294
295
  }
295
296
 
296
297
  .closeEditor {
297
- background: rgba(var(--tertiary-rgb), 0.9);
298
- border: 1px solid rgba(var(--tertiary-rgb), 0.3);
298
+ background: rgba(var(--tertiary-rgb, 255, 255, 255), 0.9);
299
+ border: 1px solid rgba(var(--tertiary-rgb, 255, 255, 255), 0.3);
299
300
  font-size: 18px;
300
301
  cursor: pointer;
301
- color: rgba(var(--primary-rgb), 0.7);
302
+ color: rgba(var(--primary-rgb, 27, 57, 51), 0.7);
302
303
  padding: 8px;
303
304
  border-radius: 8px;
304
305
  transition: all 0.2s ease;
@@ -331,8 +332,8 @@
331
332
  background: var(--item-color);
332
333
  padding: 16px 20px;
333
334
  border-radius: var(--br);
334
- border: 1px solid rgba(var(--primary-rgb), 0.1);
335
- box-shadow: 0 5px 20px rgba(var(--primary-rgb), 0.05);
335
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
336
+ box-shadow: 0 5px 20px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
336
337
  flex-shrink: 0; /* Don't shrink this section */
337
338
  }
338
339
 
@@ -349,7 +350,7 @@
349
350
  .sectionTypeSelect {
350
351
  width: 240px;
351
352
  padding: 12px 16px;
352
- border: 2px solid rgba(var(--primary-rgb), 0.15);
353
+ border: 2px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
353
354
  border-radius: 8px;
354
355
  font-size: 14px;
355
356
  font-weight: 500;
@@ -361,20 +362,20 @@
361
362
  &:focus {
362
363
  outline: none;
363
364
  border-color: var(--primary-color);
364
- box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.1);
365
+ box-shadow: 0 0 0 3px rgba(var(--primary-rgb, 27, 57, 51), 0.1);
365
366
  transform: translateY(-1px);
366
367
  }
367
368
 
368
369
  &:hover {
369
- border-color: rgba(var(--primary-rgb), 0.25);
370
+ border-color: rgba(var(--primary-rgb, 27, 57, 51), 0.25);
370
371
  }
371
372
  }
372
373
 
373
374
  .editorContainer {
374
- border: 2px solid rgba(var(--primary-rgb), 0.15);
375
+ border: 2px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
375
376
  border-radius: 12px;
376
377
  overflow: hidden;
377
- box-shadow: 0 4px 12px rgba(var(--primary-rgb), 0.08);
378
+ box-shadow: 0 4px 12px rgba(var(--primary-rgb, 27, 57, 51), 0.08);
378
379
  background: var(--tertiary-color);
379
380
  flex: 1; /* Take all remaining space */
380
381
  display: flex;
@@ -393,7 +394,7 @@
393
394
  }
394
395
 
395
396
  :global(.tox-editor-header) {
396
- border-bottom: 2px solid rgba(var(--primary-rgb), 0.1) !important;
397
+ border-bottom: 2px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1) !important;
397
398
  background: linear-gradient(135deg, var(--item-color) 0%, var(--tertiary-color) 100%) !important;
398
399
  padding: 12px 16px !important;
399
400
  }
@@ -409,11 +410,11 @@
409
410
  margin: 0 8px !important;
410
411
  padding: 4px 8px !important;
411
412
  border-radius: 6px !important;
412
- background: rgba(var(--primary-rgb), 0.05) !important;
413
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.05) !important;
413
414
  }
414
415
 
415
416
  :global(.tox-toolbar__group:hover) {
416
- background: rgba(var(--primary-rgb), 0.1) !important;
417
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.1) !important;
417
418
  }
418
419
 
419
420
  :global(.tox-tbtn) {
@@ -423,7 +424,7 @@
423
424
  }
424
425
 
425
426
  :global(.tox-tbtn:hover) {
426
- background: rgba(var(--primary-rgb), 0.15) !important;
427
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.15) !important;
427
428
  transform: translateY(-1px) !important;
428
429
  }
429
430
 
@@ -447,7 +448,7 @@
447
448
  }
448
449
 
449
450
  :global(.tox-statusbar) {
450
- border-top: 1px solid rgba(var(--primary-rgb), 0.1) !important;
451
+ border-top: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1) !important;
451
452
  background: var(--item-color) !important;
452
453
  border-radius: 0 0 12px 12px !important;
453
454
  }
@@ -459,8 +460,8 @@
459
460
  align-items: center;
460
461
  gap: 16px;
461
462
  padding: 24px 30px;
462
- border-top: 1px solid rgba(var(--primary-rgb), 0.1);
463
- background: linear-gradient(135deg, var(--item-color) 0%, rgba(var(--primary-rgb), 0.05) 100%);
463
+ border-top: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
464
+ background: linear-gradient(135deg, var(--item-color) 0%, rgba(var(--primary-rgb, 27, 57, 51), 0.05) 100%);
464
465
  border-radius: 0 0 12px 12px;
465
466
  }
466
467
 
@@ -508,19 +509,19 @@
508
509
  border-color: var(--secondary-color);
509
510
 
510
511
  &:hover {
511
- background: rgba(var(--secondary-rgb), 0.9);
512
- border-color: rgba(var(--secondary-rgb), 0.9);
512
+ background: rgba(var(--secondary-rgb, 60, 191, 125), 0.9);
513
+ border-color: rgba(var(--secondary-rgb, 60, 191, 125), 0.9);
513
514
  }
514
515
  }
515
516
 
516
517
  .saveButton {
517
- background: linear-gradient(135deg, var(--primary-color) 0%, rgba(var(--primary-rgb), 0.9) 100%);
518
+ background: linear-gradient(135deg, var(--primary-color) 0%, rgba(var(--primary-rgb, 27, 57, 51), 0.9) 100%);
518
519
  color: var(--tertiary-color);
519
520
  border-color: var(--primary-color);
520
521
 
521
522
  &:hover {
522
- background: linear-gradient(135deg, rgba(var(--primary-rgb), 0.9) 0%, rgba(var(--primary-rgb), 0.8) 100%);
523
- border-color: rgba(var(--primary-rgb), 0.9);
523
+ background: linear-gradient(135deg, rgba(var(--primary-rgb, 27, 57, 51), 0.9) 0%, rgba(var(--primary-rgb, 27, 57, 51), 0.8) 100%);
524
+ border-color: rgba(var(--primary-rgb, 27, 57, 51), 0.9);
524
525
  }
525
526
  }
526
527
 
@@ -548,13 +549,13 @@
548
549
  width: 33%;
549
550
  background: var(--item-color);
550
551
  border-radius: var(--br);
551
- border: 1px solid rgba(var(--item-color-rgb), 1.15);
552
+ border: 1px solid rgba(var(--item-color-rgb, 255, 255, 255), 1);
552
553
  box-sizing: border-box;
553
554
  overflow: visible;
554
555
  position: relative;
555
556
  padding: 20px;
556
557
  margin: 8px 0;
557
- box-shadow: 0 10px 50px rgba(var(--primary-rgb), 0.05);
558
+ box-shadow: 0 10px 50px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
558
559
  }
559
560
 
560
561
  .grid__half {
@@ -567,20 +568,20 @@
567
568
  position: relative;
568
569
  padding: 20px;
569
570
  margin: 8px 0;
570
- box-shadow: 0 10px 50px rgba(var(--primary-rgb), 0.05);
571
+ box-shadow: 0 10px 50px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
571
572
  }
572
573
 
573
574
  .grid__full {
574
575
  width: 100%;
575
576
  background: var(--item-color);
576
577
  border-radius: var(--br);
577
- border: 1px solid rgba(var(--item-color-rgb), 1.15);
578
+ border: 1px solid rgba(var(--item-color-rgb, 255, 255, 255), 1);
578
579
  box-sizing: border-box;
579
580
  overflow: visible;
580
581
  position: relative;
581
582
  padding: 2px;
582
583
  margin: 4px 0;
583
- box-shadow: 0 5px 20px rgba(var(--primary-rgb), 0.05);
584
+ box-shadow: 0 5px 20px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
584
585
  }
585
586
 
586
587
  .grid__dashfull {
@@ -593,7 +594,7 @@
593
594
  position: relative;
594
595
  padding: 20px;
595
596
  margin: 8px 0;
596
- box-shadow: 0 10px 50px rgba(var(--primary-rgb), 0.05);
597
+ box-shadow: 0 10px 50px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
597
598
  }
598
599
 
599
600
  .grid__subrow {
@@ -618,13 +619,13 @@
618
619
  flex: 1;
619
620
  background: var(--tertiary-color);
620
621
  border-radius: var(--br);
621
- border: 1px solid rgba(var(--primary-rgb), 0.1);
622
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
622
623
  box-sizing: border-box;
623
624
  padding: 0;
624
625
  margin: 4px 0;
625
626
  height: auto;
626
627
  position: relative;
627
- box-shadow: 0 3px 10px rgba(var(--primary-rgb), 0.05);
628
+ box-shadow: 0 3px 10px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
628
629
  overflow: hidden;
629
630
  }
630
631
 
@@ -638,7 +639,7 @@
638
639
  .gridtxt__header {
639
640
  width: 100%;
640
641
  display: block;
641
- background: rgba(var(--primary-rgb), 0.05);
642
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.05);
642
643
  box-sizing: border-box;
643
644
  padding: 10px 20px;
644
645
  border-radius: var(--br);
@@ -668,9 +669,9 @@
668
669
  flex: 0 0 calc(50% - 10px);
669
670
  padding: 0.65rem;
670
671
  box-sizing: border-box;
671
- border: 1px solid rgba(var(--primary-rgb), 0.095);
672
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.095);
672
673
  color: var(--paragraph-color);
673
- background: rgba(var(--primary-rgb), 0.015);
674
+ background: rgba(var(--primary-rgb, 27, 57, 51), 0.015);
674
675
  margin: 3px;
675
676
  border-radius: var(--br);
676
677
  line-height: 1.45;
@@ -695,7 +696,7 @@
695
696
  margin: 0;
696
697
  background: white;
697
698
  border-radius: var(--br);
698
- border: 1px solid rgba(var(--primary-rgb), 0.15);
699
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
699
700
  position: relative;
700
701
  display: flex;
701
702
  align-items: center;
@@ -715,7 +716,7 @@
715
716
  }
716
717
 
717
718
  svg {
718
- color: rgba(var(--primary-rgb), 0.5);
719
+ color: rgba(var(--primary-rgb, 27, 57, 51), 0.5);
719
720
  position: relative;
720
721
  top: 2px;
721
722
  margin: 0 0.5rem;
@@ -742,7 +743,7 @@
742
743
  padding: 25px;
743
744
  box-sizing: border-box;
744
745
  margin-bottom: 0;
745
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
746
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
746
747
  }
747
748
 
748
749
  .quoteIdentifier {
@@ -779,7 +780,7 @@
779
780
 
780
781
  span {
781
782
  font-size: 0.875em;
782
- color: rgba(var(--background-color-rgb), 0.65);
783
+ color: rgba(var(--background-color-rgb, 255, 255, 255), 0.65);
783
784
  }
784
785
  }
785
786
 
@@ -791,10 +792,10 @@
791
792
  box-sizing: border-box;
792
793
  display: flex;
793
794
  flex-wrap: wrap;
794
- border: 1px solid rgba(var(--primary-rgb), 0.2);
795
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.2);
795
796
  border-radius: var(--br);
796
797
  background-color: white;
797
- box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.05);
798
+ box-shadow: 0 2px 8px rgba(var(--primary-rgb, 27, 57, 51), 0.05);
798
799
  }
799
800
 
800
801
  .qitem {
@@ -803,7 +804,7 @@
803
804
  flex-wrap: wrap;
804
805
  box-sizing: border-box;
805
806
  padding: 15px 20px;
806
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.15);
807
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.15);
807
808
  color: var(--paragraph-color);
808
809
 
809
810
  &:last-child {
@@ -906,10 +907,10 @@
906
907
  display: flex;
907
908
  justify-content: space-between;
908
909
  margin: 25px 0;
909
- border-top: 1px solid rgba(var(--primary-rgb), 0.1);
910
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
910
+ border-top: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
911
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
911
912
  padding: 20px 0;
912
- background-color: rgba(var(--primary-rgb), 0.02);
913
+ background-color: rgba(var(--primary-rgb, 27, 57, 51), 0.02);
913
914
  border-radius: var(--br, 4px);
914
915
  }
915
916
 
@@ -932,7 +933,7 @@
932
933
  color: var(--primary-color);
933
934
  margin: 0 0 8px 0;
934
935
  padding-bottom: 5px;
935
- border-bottom: 1px dashed rgba(var(--primary-rgb), 0.1);
936
+ border-bottom: 1px dashed rgba(var(--primary-rgb, 27, 57, 51), 0.1);
936
937
  text-align: inherit; /* Inherit text alignment from parent */
937
938
  }
938
939
 
@@ -1032,8 +1033,8 @@
1032
1033
  .termsSection {
1033
1034
  margin-top: 30px;
1034
1035
  padding: 20px;
1035
- border-top: 1px solid rgba(var(--primary-rgb), 0.1);
1036
- background-color: rgba(var(--primary-rgb), 0.02);
1036
+ border-top: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.1);
1037
+ background-color: rgba(var(--primary-rgb, 27, 57, 51), 0.02);
1037
1038
  border-radius: var(--br, 4px);
1038
1039
  }
1039
1040
 
@@ -1043,7 +1044,7 @@
1043
1044
  color: var(--primary-color);
1044
1045
  margin: 0 0 15px 0;
1045
1046
  padding-bottom: 8px;
1046
- border-bottom: 1px dashed rgba(var(--primary-rgb), 0.1);
1047
+ border-bottom: 1px dashed rgba(var(--primary-rgb, 27, 57, 51), 0.1);
1047
1048
  }
1048
1049
 
1049
1050
  .termsContent {
@@ -1141,21 +1142,29 @@
1141
1142
  font-size: 14px;
1142
1143
  border-radius: 0;
1143
1144
  overflow: hidden;
1144
- border: 2px solid #333333;
1145
+ /* 2026: was a 2px #333333 outline with a drop shadow, boxing the table
1146
+ inside an already-carded document. A hairline is all the edge it needs. */
1147
+ border: 1px solid color-mix(in srgb, var(--paragraph-color, #2b2b2b) 12%, transparent);
1145
1148
  box-sizing: border-box;
1146
- box-shadow: 0 2px 8px rgba(0,0,0,0.1);
1149
+ box-shadow: none;
1147
1150
  margin-bottom: 25px;
1148
1151
  background: white;
1149
1152
  }
1150
1153
 
1151
1154
  .tableHeader {
1152
- background-color: #4fbfa5 !important;
1153
- color: white !important;
1155
+ /* 2026: was #4fbfa5 with white type — a saturated mint unrelated to any
1156
+ brand, and the loudest thing on the page. A column header labels the
1157
+ column below it; it is not a feature. */
1158
+ background-color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 3%, var(--background-color, #fff)) !important;
1159
+ color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 62%, transparent) !important;
1154
1160
  text-align: left;
1155
- font-weight: bold;
1156
- font-size: 14px;
1157
- padding: 16px 15px;
1158
- border: 1px solid #333333;
1161
+ font-weight: 600;
1162
+ font-size: 11px;
1163
+ letter-spacing: 0.05em;
1164
+ text-transform: uppercase;
1165
+ padding: 10px 15px;
1166
+ border: 0;
1167
+ border-bottom: 1px solid color-mix(in srgb, var(--paragraph-color, #2b2b2b) 12%, transparent);
1159
1168
 
1160
1169
  &:first-child {
1161
1170
  border-top-left-radius: 0;
@@ -1176,16 +1185,16 @@
1176
1185
 
1177
1186
  .dragHandleHeader {
1178
1187
  width: 30px;
1179
- background-color: #4fbfa5;
1180
- color: white;
1188
+ background-color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 3%, var(--background-color, #fff));
1189
+ color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 62%, transparent);
1181
1190
  padding: 10px 5px !important;
1182
1191
  border-bottom: none;
1183
1192
  }
1184
1193
 
1185
1194
  .actionHeader {
1186
1195
  width: 80px;
1187
- background-color: #4fbfa5;
1188
- color: white;
1196
+ background-color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 3%, var(--background-color, #fff));
1197
+ color: color-mix(in srgb, var(--paragraph-color, #2b2b2b) 62%, transparent);
1189
1198
  text-align: center;
1190
1199
  font-weight: 600;
1191
1200
  font-size: 0.85rem;
@@ -1194,12 +1203,12 @@
1194
1203
  }
1195
1204
 
1196
1205
  .tableRow {
1197
- border-bottom: 1px solid rgba(var(--primary-rgb), 0.05);
1206
+ border-bottom: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.05);
1198
1207
  transition: background-color 0.2s ease;
1199
1208
  background-color: white;
1200
1209
 
1201
1210
  &:hover {
1202
- background-color: rgba(var(--primary-rgb), 0.02);
1211
+ background-color: rgba(var(--primary-rgb, 27, 57, 51), 0.02);
1203
1212
  }
1204
1213
 
1205
1214
  &:last-child {
@@ -1213,11 +1222,15 @@
1213
1222
 
1214
1223
  .tableCell {
1215
1224
  padding: 14px 15px;
1216
- color: #374151;
1225
+ color: var(--paragraph-color, #2b2b2b);
1217
1226
  font-size: 14px;
1218
1227
  line-height: 1.4;
1219
1228
  vertical-align: middle;
1220
- border: 1px solid #333333;
1229
+ /* Was a full 1px #333333 box on every cell — the table read as a grid of
1230
+ boxes. One hairline under the row; the columns are separated by
1231
+ alignment. */
1232
+ border: 0;
1233
+ border-bottom: 1px solid color-mix(in srgb, var(--paragraph-color, #2b2b2b) 10%, transparent);
1221
1234
  font-weight: 500;
1222
1235
 
1223
1236
  &[style*='text-align: right'] {
@@ -1229,26 +1242,42 @@
1229
1242
  }
1230
1243
  }
1231
1244
 
1245
+ /* 2026: the last subtotal row filled itself #333 — a near-black band closing
1246
+ the table, and the third heavy stripe in a component that already had a dark
1247
+ title row and a saturated column header. Emphasis now comes from a 2px brand
1248
+ rule and weight, which is what a total actually needs.
1249
+
1250
+ Rewritten here rather than overridden below, because the old rule was
1251
+ `.subtotalRow:last-child { ... !important }` — a specificity an appended
1252
+ override could only beat by escalating, and a stylesheet that argues with
1253
+ itself is worse than one that says a thing once. */
1232
1254
  .subtotalRow {
1233
- background-color: #f3f4f6;
1234
- border-top: 2px solid #333333;
1255
+ background-color: color-mix(
1256
+ in srgb,
1257
+ var(--paragraph-color, #2b2b2b) 3%,
1258
+ var(--background-color, #fff)
1259
+ );
1260
+ border-top: 2px solid var(--primary-color, #1b3933);
1235
1261
 
1236
1262
  &:hover {
1237
- background-color: #f3f4f6;
1263
+ background-color: color-mix(
1264
+ in srgb,
1265
+ var(--paragraph-color, #2b2b2b) 3%,
1266
+ var(--background-color, #fff)
1267
+ );
1238
1268
  }
1239
-
1269
+
1240
1270
  .subtotalLabel,
1241
1271
  .subtotalValue {
1242
- color: #333 !important;
1272
+ background-color: transparent;
1273
+ color: var(--paragraph-color, #2b2b2b);
1243
1274
  }
1244
-
1275
+
1276
+ /* The grand total, when there is more than one subtotal row. */
1245
1277
  &:last-child {
1246
- background-color: #333333 !important;
1247
-
1248
1278
  .subtotalLabel,
1249
1279
  .subtotalValue {
1250
- color: white !important;
1251
- background-color: #333333 !important;
1280
+ color: var(--heading-color, var(--primary-color, #1b3933));
1252
1281
  }
1253
1282
  }
1254
1283
  }
@@ -1257,9 +1286,10 @@
1257
1286
  padding: 12px 15px;
1258
1287
  text-align: right;
1259
1288
  font-weight: bold;
1260
- color: #374151;
1289
+ /* Was #374151 with a 1px #333333 border boxing every subtotal cell. */
1290
+ color: var(--paragraph-color, #2b2b2b);
1261
1291
  font-size: 14px;
1262
- border: 1px solid #333333;
1292
+ border: 0;
1263
1293
  background: inherit;
1264
1294
  }
1265
1295
 
@@ -1267,10 +1297,10 @@
1267
1297
  padding: 12px 15px;
1268
1298
  text-align: right;
1269
1299
  font-weight: bold;
1270
- color: #374151;
1300
+ color: var(--paragraph-color, #2b2b2b);
1271
1301
  font-size: 14px;
1272
1302
  white-space: nowrap;
1273
- border: 1px solid #333333;
1303
+ border: 0;
1274
1304
  background: inherit;
1275
1305
  }
1276
1306
 
@@ -1416,3 +1446,291 @@
1416
1446
  line-height: 1.3;
1417
1447
  }
1418
1448
  }
1449
+
1450
+ /* ==========================================================================
1451
+ 2026 pass — the quote / purchase order document
1452
+ --------------------------------------------------------------------------
1453
+ This screen serves quotes AND purchase orders (consumers route both through
1454
+ GenericQuote), so everything here lands on both.
1455
+
1456
+ What was wrong: the page was five full-width colour bands stacked on top of
1457
+ each other — a dark status strip, a dark table title bar, a saturated mint
1458
+ column header, a near-black total row, and a row of action buttons in three
1459
+ unrelated colours. Three of those bands are inside ONE table, which meant
1460
+ the table shouted three different ways before a single figure was read.
1461
+
1462
+ A quote is a document. It should read like one: a single sheet, with
1463
+ emphasis carried by weight and rule rather than by filling every band with a
1464
+ different colour.
1465
+
1466
+ Also fixed: `.tableTitleRow` and `.subtotalRow` inherited `color` from the
1467
+ page (the paragraph brown, ~1.15:1 against their own dark fills). Nothing
1468
+ rendered at that colour — every text node inside sets white explicitly — so
1469
+ it was a latent trap rather than a live fault, but any text added directly
1470
+ to those rows would have been invisible. They now set their own colour.
1471
+ ========================================================================== */
1472
+
1473
+ .quoteWrapper {
1474
+ --q-surface: var(--background-color, #fff);
1475
+ --q-ink: var(--paragraph-color, #2b2b2b);
1476
+ --q-brand: var(--primary-color, #1b3933);
1477
+ --q-line: color-mix(in srgb, var(--q-ink) 12%, transparent);
1478
+ --q-muted: color-mix(in srgb, var(--q-ink) 62%, transparent);
1479
+ --q-quiet: color-mix(in srgb, var(--q-ink) 3%, var(--q-surface));
1480
+ --q-radius: var(--quote-card-radius, 14px);
1481
+ --q-motion: var(--speed, 160ms) var(--ease, cubic-bezier(0.4, 0, 0.2, 1));
1482
+
1483
+ border: 1px solid var(--q-line);
1484
+ border-radius: var(--q-radius);
1485
+ background: var(--q-surface);
1486
+ box-shadow:
1487
+ 0 1px 2px color-mix(in srgb, var(--q-brand) 8%, transparent),
1488
+ 0 8px 24px -12px color-mix(in srgb, var(--q-brand) 18%, transparent);
1489
+ overflow: hidden;
1490
+ }
1491
+
1492
+ /* -- status strip --------------------------------------------------------- */
1493
+
1494
+ /* Was a full-width fill of the brand colour. The status is one word; it does
1495
+ not need a band the width of the page. A quiet strip with a real status pill
1496
+ says the same thing without competing with the document. */
1497
+ .quotestatus {
1498
+ display: flex;
1499
+ align-items: center;
1500
+ justify-content: space-between;
1501
+ gap: 1rem;
1502
+ padding: 0.6rem 1.25rem;
1503
+ border-bottom: 1px solid var(--q-line);
1504
+ background: var(--q-quiet) !important;
1505
+ color: var(--q-muted) !important;
1506
+ font-size: 0.8125rem;
1507
+ }
1508
+
1509
+ .quotestatus > :first-child {
1510
+ display: inline-flex;
1511
+ align-items: center;
1512
+ padding: 0.2rem 0.7rem;
1513
+ border-radius: var(--radius-pill, 999px);
1514
+ font-size: 0.75rem;
1515
+ font-weight: 600;
1516
+ letter-spacing: 0.01em;
1517
+ }
1518
+
1519
+ /* -- the line-item table -------------------------------------------------- */
1520
+
1521
+ .tableTitleRow {
1522
+ display: flex;
1523
+ align-items: center;
1524
+ justify-content: space-between;
1525
+ gap: 1rem;
1526
+ padding: 0.7rem 1rem;
1527
+ border: 1px solid var(--q-line);
1528
+ border-bottom: 0;
1529
+ border-radius: var(--radius-sm, 10px) var(--radius-sm, 10px) 0 0;
1530
+ background: var(--q-quiet) !important;
1531
+ /* The inherited paragraph colour was ~1.15:1 here — see the header note. */
1532
+ color: var(--heading-color, var(--q-brand)) !important;
1533
+ }
1534
+
1535
+ .tableTitle {
1536
+ margin: 0;
1537
+ color: inherit !important;
1538
+ font-size: 0.8125rem;
1539
+ font-weight: 600;
1540
+ letter-spacing: 0.02em;
1541
+ text-transform: uppercase;
1542
+ }
1543
+
1544
+ /* Was #4fbfa5 — a saturated mint with white type, the loudest thing on the
1545
+ page and unrelated to the brand. A column header is a label for the column
1546
+ below it, not a feature. */
1547
+ .tableHeader {
1548
+ background: var(--q-quiet) !important;
1549
+ border-bottom: 1px solid var(--q-line);
1550
+ color: var(--q-muted) !important;
1551
+ font-size: 0.6875rem !important;
1552
+ font-weight: 600 !important;
1553
+ letter-spacing: 0.05em;
1554
+ text-transform: uppercase;
1555
+ }
1556
+
1557
+ .tableHeader th,
1558
+ .tableHeader td,
1559
+ .actionHeader,
1560
+ .dragHandleHeader {
1561
+ background: transparent !important;
1562
+ color: inherit !important;
1563
+ border: 0 !important;
1564
+ padding: 0.6rem 0.75rem !important;
1565
+ }
1566
+
1567
+ .tableRow {
1568
+ background: var(--q-surface);
1569
+ transition: background var(--q-motion);
1570
+ }
1571
+
1572
+ .tableRow:hover {
1573
+ background: color-mix(in srgb, var(--q-brand) 4%, var(--q-surface));
1574
+ }
1575
+
1576
+ .tableCell {
1577
+ padding: 0.6rem 0.75rem !important;
1578
+ border: 0 !important;
1579
+ border-bottom: 1px solid var(--q-line) !important;
1580
+ color: var(--q-ink);
1581
+ font-size: 0.8125rem;
1582
+ }
1583
+
1584
+ /* Money and quantities are columns of numbers, so they align. */
1585
+ .tableCell[align='right'],
1586
+ .tableCell:nth-last-child(-n + 3) {
1587
+ font-variant-numeric: tabular-nums;
1588
+ }
1589
+
1590
+ .subtotalLabel,
1591
+ .subtotalValue {
1592
+ color: var(--q-ink) !important;
1593
+ font-weight: 700;
1594
+ font-variant-numeric: tabular-nums;
1595
+ }
1596
+
1597
+ .subtotalValue {
1598
+ font-size: 1rem;
1599
+ color: var(--heading-color, var(--q-brand)) !important;
1600
+ }
1601
+
1602
+ /* -- actions -------------------------------------------------------------- */
1603
+
1604
+ /* Edit Content / Preview / Generate PDF were #4fbfa5, #2563eb and #1a3d66 —
1605
+ a mint, a generic blue and a navy, none of them this brand's, and no
1606
+ hierarchy between them. One primary, the rest secondary. */
1607
+ .proposalActions button,
1608
+ .proposalControls button,
1609
+ .actionButtonsContainer button,
1610
+ .footerButtons button {
1611
+ display: inline-flex;
1612
+ align-items: center;
1613
+ justify-content: center;
1614
+ gap: 0.4rem;
1615
+ height: 34px;
1616
+ padding: 0 0.9rem;
1617
+ border: 1px solid var(--q-line);
1618
+ border-radius: var(--btn-br, 8px);
1619
+ background: var(--q-surface);
1620
+ color: var(--q-brand);
1621
+ font: inherit;
1622
+ font-size: 0.8125rem;
1623
+ font-weight: 600;
1624
+ line-height: 1;
1625
+ text-transform: none;
1626
+ cursor: pointer;
1627
+ transition: background var(--q-motion), border-color var(--q-motion);
1628
+ }
1629
+
1630
+ .proposalActions button:hover,
1631
+ .proposalControls button:hover,
1632
+ .actionButtonsContainer button:hover,
1633
+ .footerButtons button:hover {
1634
+ background: color-mix(in srgb, var(--q-brand) 5%, var(--q-surface));
1635
+ border-color: color-mix(in srgb, var(--q-brand) 35%, var(--q-line));
1636
+ }
1637
+
1638
+ .proposalActions button:focus-visible,
1639
+ .proposalControls button:focus-visible,
1640
+ .actionButtonsContainer button:focus-visible,
1641
+ .footerButtons button:focus-visible {
1642
+ outline: 2px solid var(--highlight-color, #3cbf7d);
1643
+ outline-offset: 2px;
1644
+ }
1645
+
1646
+ /* The one primary action per group. */
1647
+ .pdfButton,
1648
+ .saveButton,
1649
+ .addItemButton {
1650
+ background: var(--q-brand) !important;
1651
+ border-color: var(--q-brand) !important;
1652
+ color: #fff !important;
1653
+ }
1654
+
1655
+ .pdfButton:hover,
1656
+ .saveButton:hover,
1657
+ .addItemButton:hover {
1658
+ background: color-mix(in srgb, #000 10%, var(--q-brand)) !important;
1659
+ }
1660
+
1661
+ /* Destructive stays destructive, and says so in words as well as colour. */
1662
+ .cancelButton {
1663
+ color: var(--danger-color, #be3e3e) !important;
1664
+ }
1665
+
1666
+ /* -- document body -------------------------------------------------------- */
1667
+
1668
+ .quoteTopSection,
1669
+ .quoteParties,
1670
+ .termsSection {
1671
+ padding: 1.25rem;
1672
+ }
1673
+
1674
+ .partyTitle {
1675
+ color: var(--q-muted);
1676
+ font-size: 0.6875rem;
1677
+ font-weight: 600;
1678
+ letter-spacing: 0.05em;
1679
+ text-transform: uppercase;
1680
+ }
1681
+
1682
+ .termsSection {
1683
+ border-top: 1px solid var(--q-line);
1684
+ background: var(--q-quiet);
1685
+ }
1686
+
1687
+ .termsTitle {
1688
+ color: var(--heading-color, var(--q-brand));
1689
+ font-size: 0.8125rem;
1690
+ font-weight: 600;
1691
+ }
1692
+
1693
+ .termsContent {
1694
+ color: var(--q-muted);
1695
+ font-size: 0.8125rem;
1696
+ line-height: 1.6;
1697
+ }
1698
+
1699
+ .quoteBigNumber,
1700
+ .quoteNumber {
1701
+ /* A standalone display figure uses proportional figures — tabular gives
1702
+ every digit the width of a zero and looks loose at this size. */
1703
+ font-variant-numeric: proportional-nums;
1704
+ color: var(--heading-color, var(--q-brand));
1705
+ }
1706
+
1707
+ /* -- the template / proposal strip ---------------------------------------- */
1708
+
1709
+ .proposalControls,
1710
+ .proposalSelectors {
1711
+ display: flex;
1712
+ flex-wrap: wrap;
1713
+ align-items: center;
1714
+ gap: 0.5rem;
1715
+ padding: 0.75rem 1.25rem;
1716
+ border-bottom: 1px solid var(--q-line);
1717
+ background: var(--q-surface);
1718
+ }
1719
+
1720
+ .proposalSelect,
1721
+ .sectionTypeSelect {
1722
+ height: 34px;
1723
+ padding: 0 0.6rem;
1724
+ border: 1px solid var(--q-line);
1725
+ border-radius: var(--radius-sm, 8px);
1726
+ background: var(--q-surface);
1727
+ color: var(--q-ink);
1728
+ font: inherit;
1729
+ font-size: 0.8125rem;
1730
+ }
1731
+
1732
+ .editorLabel {
1733
+ color: var(--q-muted);
1734
+ font-size: 0.75rem;
1735
+ font-weight: 600;
1736
+ }