@visns-studio/visns-components 6.17.2 → 6.20.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 (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 +134 -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
@@ -589,3 +589,199 @@ body.tablet-mode .InovuaReactDataGrid__cell.cell-word-wrap > div {
589
589
  .visns-native-date-filter__range .visns-native-date-filter {
590
590
  flex: 1 1 0;
591
591
  }
592
+
593
+ /* ==========================================================================
594
+ 2026 pass — the grid's cells
595
+ --------------------------------------------------------------------------
596
+ The grid itself is the vendored @visns-studio/visns-datagrid fork, whose
597
+ markup is not ours. It is styled from here rather than from that package,
598
+ because this file is already the override layer the library ships for it —
599
+ so a restyle costs no fork, no rebuild of a TypeScript+Babel+PostCSS
600
+ pipeline, and no npm publish.
601
+
602
+ `!important` throughout, reluctantly: the vendored theme's own selectors are
603
+ high-specificity and this file is imported before it. That is a property of
604
+ the host, not a preference.
605
+ ========================================================================== */
606
+
607
+ .InovuaReactDataGrid {
608
+ --dgx-ink: var(--paragraph-color, #2b2b2b);
609
+ --dgx-surface: var(--background-color, #fff);
610
+ --dgx-line: color-mix(in srgb, var(--dgx-ink) 10%, transparent);
611
+ --dgx-muted: color-mix(in srgb, var(--dgx-ink) 60%, transparent);
612
+ --dgx-hover: color-mix(in srgb, var(--primary-color, #1b3933) 4%, var(--dgx-surface));
613
+ --dgx-selected: color-mix(in srgb, var(--primary-color, #1b3933) 8%, var(--dgx-surface));
614
+
615
+ border: 0 !important;
616
+ background: var(--dgx-surface) !important;
617
+ font-family: inherit !important;
618
+ }
619
+
620
+ /* -- column header -------------------------------------------------------- */
621
+
622
+ .InovuaReactDataGrid__header,
623
+ .InovuaReactDataGrid__header-wrapper {
624
+ background: var(--dgx-surface) !important;
625
+ border-bottom: 1px solid var(--dgx-line) !important;
626
+ }
627
+
628
+ .InovuaReactDataGrid__column-header {
629
+ background: transparent !important;
630
+ border: 0 !important;
631
+ border-bottom: 0 !important;
632
+ }
633
+
634
+ .InovuaReactDataGrid__column-header__content {
635
+ padding: 0.65rem 0.85rem !important;
636
+ color: var(--dgx-muted) !important;
637
+ font-size: 0.6875rem !important;
638
+ font-weight: 600 !important;
639
+ letter-spacing: 0.05em !important;
640
+ text-transform: uppercase !important;
641
+ }
642
+
643
+ /* -- rows and cells ------------------------------------------------------- */
644
+
645
+ /* 44px rather than the vendored 36: a row a finger can hit on the iPad these
646
+ are used on, and enough air that a table of twelve does not read as a wall. */
647
+ .InovuaReactDataGrid__row {
648
+ min-height: 44px !important;
649
+ border: 0 !important;
650
+ background: var(--dgx-surface) !important;
651
+ transition: background 140ms cubic-bezier(0.4, 0, 0.2, 1) !important;
652
+ }
653
+
654
+ .InovuaReactDataGrid__row:hover,
655
+ .InovuaReactDataGrid__row--hover-target:hover {
656
+ background: var(--dgx-hover) !important;
657
+ }
658
+
659
+ .InovuaReactDataGrid__row--selected,
660
+ .InovuaReactDataGrid__row--active {
661
+ background: var(--dgx-selected) !important;
662
+ }
663
+
664
+ /* The vendored theme draws a border on every cell, so a table arrives as a
665
+ grid of boxes. One hairline under the row is all the separation a row needs;
666
+ the columns are separated by alignment. */
667
+ .InovuaReactDataGrid__cell {
668
+ border: 0 !important;
669
+ border-bottom: 1px solid var(--dgx-line) !important;
670
+ background: transparent !important;
671
+ color: var(--dgx-ink) !important;
672
+ font-size: 0.8125rem !important;
673
+ }
674
+
675
+ .InovuaReactDataGrid__cell__content {
676
+ padding: 0 0.85rem !important;
677
+ line-height: 1.45 !important;
678
+ }
679
+
680
+ /* Columns of numbers line up; everything else keeps proportional figures. */
681
+ .InovuaReactDataGrid__cell--align-end .InovuaReactDataGrid__cell__content,
682
+ .InovuaReactDataGrid__cell--align-right .InovuaReactDataGrid__cell__content {
683
+ font-variant-numeric: tabular-nums !important;
684
+ }
685
+
686
+ .InovuaReactDataGrid__row:last-child .InovuaReactDataGrid__cell {
687
+ border-bottom: 0 !important;
688
+ }
689
+
690
+ /* -- checkbox ------------------------------------------------------------- */
691
+
692
+ .InovuaReactDataGrid__checkbox {
693
+ accent-color: var(--primary-color, #1b3933) !important;
694
+ }
695
+
696
+ /* -- group header --------------------------------------------------------- */
697
+
698
+ .InovuaReactDataGrid__group-cell,
699
+ .InovuaReactDataGrid__group-row {
700
+ background: color-mix(in srgb, var(--dgx-ink) 3%, var(--dgx-surface)) !important;
701
+ color: var(--dgx-ink) !important;
702
+ font-weight: 600 !important;
703
+ }
704
+
705
+ /* -- column filter row ---------------------------------------------------- */
706
+
707
+ .InovuaReactDataGrid__column-header__filter input,
708
+ .InovuaReactDataGrid__column-header__filter select {
709
+ height: 28px !important;
710
+ padding: 0 0.5rem !important;
711
+ border: 1px solid var(--dgx-line) !important;
712
+ border-radius: 6px !important;
713
+ background: var(--dgx-surface) !important;
714
+ color: var(--dgx-ink) !important;
715
+ font: inherit !important;
716
+ font-size: 0.75rem !important;
717
+ }
718
+
719
+ /* The toolkit WRAPPER around that input drew its own box too: a 1px #cdcecd
720
+ border at 1px radius, with the styled 6px-radius input sitting inside it.
721
+ Two nested borders a pixel apart, which is what made the filter row read as
722
+ one enormous raw text box spanning the column rather than as a filter.
723
+
724
+ Only the input keeps an edge. The wrapper is a layout box. */
725
+ .InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-text-input,
726
+ .InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-numeric-input {
727
+ border: 0 !important;
728
+ border-radius: 0 !important;
729
+ background: none !important;
730
+ box-shadow: none !important;
731
+ }
732
+
733
+ /* A COMBO BOX is built the other way round, and it matters.
734
+
735
+ In a text or numeric filter the inner `<input>` fills the wrapper, so the
736
+ input carries the edge and the wrapper is a layout box. In a combo box the
737
+ inner `<input>` is only a narrow typing sliver sitting NEXT to a placeholder
738
+ span — measured at 18px wide inside a 130px control. Putting the edge on it
739
+ drew a bordered 18px box beside the word "ALL", which is why the ALL filters
740
+ looked like they had a stray empty checkbox in front of them.
741
+
742
+ So for combo boxes the wrapper carries the edge and the sliver gets none. */
743
+ .InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-combo-box {
744
+ /* min/max as well as height: the grid theme pins the filter cell to
745
+ `min-height: 32px`, and min-height beats height, so `height` alone left
746
+ the ALL dropdowns 4px taller than the text and date filters beside
747
+ them. */
748
+ height: 28px !important;
749
+ min-height: 28px !important;
750
+ max-height: 28px !important;
751
+ border: 1px solid var(--dgx-line) !important;
752
+ border-radius: 6px !important;
753
+ background: var(--dgx-surface) !important;
754
+ box-shadow: none !important;
755
+ }
756
+
757
+ .InovuaReactDataGrid__column-header__filter.inovua-react-toolkit-combo-box
758
+ .inovua-react-toolkit-combo-box__input {
759
+ border: 0 !important;
760
+ border-radius: 0 !important;
761
+ background: none !important;
762
+ }
763
+
764
+ /* The native date filter is the odd one out in the row.
765
+
766
+ Measured on /tickets: every other filter editor is 28px tall with a 6px
767
+ radius and the `--dgx-line` hairline, while this one was 34px with a 1px
768
+ radius and the toolkit's old #cdcecd border. Six pixels taller and squarer
769
+ than its neighbours is exactly what makes one control in a row look
770
+ "selected" or broken when nothing is wrong with it.
771
+
772
+ Note the edge lives on the WRAPPER here, not on the input — the input is
773
+ `border: none` because Chrome's date segments need to fill the box — so the
774
+ wrapper is what has to carry the 2026 treatment. */
775
+ .InovuaReactDataGrid__column-header__filter .visns-native-date-filter,
776
+ .visns-native-date-filter {
777
+ height: 28px !important;
778
+ min-height: 28px !important;
779
+ max-height: 28px !important;
780
+ border: 1px solid var(--dgx-line) !important;
781
+ border-radius: 6px !important;
782
+ background: var(--dgx-surface) !important;
783
+ }
784
+
785
+ .visns-native-date-filter__input {
786
+ font-size: 0.75rem !important;
787
+ }
@@ -228,13 +228,54 @@ ul {
228
228
  }
229
229
 
230
230
  a {
231
+ /* `outline: none` used to sit here alone, stripping the focus ring from
232
+ every link in every consuming app with nothing put back. The outline is
233
+ removed only for the mouse; keyboard focus keeps a real ring. */
231
234
  outline: none;
232
235
  }
233
236
 
237
+ a:focus-visible {
238
+ outline: 2px solid var(--highlight-color, #3cbf7d);
239
+ outline-offset: 2px;
240
+ border-radius: var(--radius-sm, 4px);
241
+ }
242
+
243
+ /* The two rules above force `appearance: none` and `outline: none !important`
244
+ on every checkbox and radio, which left them with a 14px hit target and NO
245
+ keyboard focus indicator anywhere in the library. Restoring the ring is
246
+ separated from the drawn control deliberately: other rules depend on the
247
+ custom box, but nothing depends on focus being invisible. */
248
+ input[type='checkbox']:focus-visible,
249
+ input[type='radio']:focus-visible,
250
+ .radio-input:focus-visible {
251
+ outline: 2px solid var(--highlight-color, #3cbf7d) !important;
252
+ outline-offset: 2px !important;
253
+ }
254
+
234
255
  .loginbg {
235
256
  background: var(--tertiary-color);
236
257
  }
237
258
 
259
+ /* The grid's own toolbar and column-filter fields opt out of this rule, same
260
+ as the Inovua toolkit inputs listed in it.
261
+
262
+ This selector carries about a dozen chained `:not()` clauses, and every one
263
+ of them adds specificity — so at roughly (0,13,1) it silently beat
264
+ `.searchInput` (0,1,0) in DataGrid.module.scss and imposed `padding: 1rem`
265
+ on a 34px-tall field, which is what pushed the magnifier glyph on top of the
266
+ placeholder text.
267
+
268
+ The exclusions match on a class SUBSTRING because these are CSS-module
269
+ classes: by the time this plain stylesheet applies, the name is
270
+ `_searchInput_17s7g_654`, so a bare `.searchInput` here would match nothing.
271
+
272
+ KEEP THE SELECTOR ON ONE UNBROKEN COMPOUND. A newline — or a comment, which
273
+ is whitespace — between two `:not()` clauses is a DESCENDANT COMBINATOR, and
274
+ it silently retargets the rule at descendants of an `<input>`, which do not
275
+ exist. That is not a hypothetical: it happened here, and every text field in
276
+ the app fell back to the browser's default 2px inset border while selects
277
+ and textareas kept their styling. Hence three different-looking controls in
278
+ one form. */
238
279
  textarea,
239
280
  select,
240
281
  input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
@@ -249,10 +290,10 @@ input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
249
290
  .react-datepicker__year-select
250
291
  ):not(.visns-native-date-filter__input):not([type='date']):not(
251
292
  [type='datetime-local']
252
- ):not([type='time']) {
293
+ ):not([type='time']):not([class*='searchInput']):not([class*='filterInput']):not([class*='rowActionPickerSearch']) {
253
294
  background: white;
254
295
  border-radius: var(--br);
255
- border: 1px solid rgba(var(--paragraph-color-rgb), 0.15);
296
+ border: 1px solid rgba(var(--paragraph-color-rgb, 43, 43, 43), 0.15);
256
297
  box-shadow: none;
257
298
  padding: 1rem;
258
299
  outline: none;
@@ -344,7 +385,7 @@ input[type='time'] {
344
385
  background-color: var(--tertiary-color);
345
386
  padding: 0;
346
387
  margin: 0;
347
- border: 1px solid rgba(var(--primary-rgb), 0.25);
388
+ border: 1px solid rgba(var(--primary-rgb, 27, 57, 51), 0.25);
348
389
  border-radius: var(--br);
349
390
  overflow: hidden;
350
391
  font-size: 1rem;
@@ -384,21 +425,17 @@ input[type='time'] {
384
425
 
385
426
  /* Async Select */
386
427
 
428
+ /* The control's appearance is defined once, further down, next to the rule
429
+ for native inputs it has to match. This rule keeps only the structural
430
+ properties — it used to also set `min-height: 50px`, a second border and a
431
+ 4px radius, all of which fought the later block. */
387
432
  .visns-select__control {
388
433
  width: 100%;
389
434
  cursor: default;
390
- min-height: 50px;
391
- outline: 0 !important;
392
435
  position: relative;
393
- -webkit-transition: all 100ms;
394
- transition: all 100ms;
395
- background-color: hsl(0, 0%, 100%);
396
- border-color: hsl(0, 0%, 80%);
397
- border-radius: 4px;
398
- border-style: solid;
399
- border-width: 1px;
436
+ outline: 0 !important;
400
437
  box-sizing: border-box;
401
- box-shadow: none !important;
438
+ transition: border-color 0.15s linear;
402
439
  }
403
440
 
404
441
  /* These were written as `&--is-focused` / `&--menu-is-open` nested inside the
@@ -661,10 +698,11 @@ input[type='time'] {
661
698
  }
662
699
 
663
700
  /* Fix for specific toggle in forms */
664
- form div:has(span:contains('Use T-Bar?')) .react-toggle {
665
- margin-right: 8px;
666
- vertical-align: middle;
667
- }
701
+ /* Removed: `form div:has(span:contains('Use T-Bar?'))` — `:contains()` is a
702
+ jQuery extension, not CSS, so this selector was invalid and the rule had
703
+ never applied to anything. Restore it with a real class or data attribute
704
+ on the toggle if the behaviour is still wanted. */
705
+
668
706
 
669
707
  /* Hide checkboxes when they're next to a toggle */
670
708
  .react-toggle + input[type='checkbox'],
@@ -998,3 +1036,116 @@ form div:has(.react-toggle) input[type='checkbox'] {
998
1036
  font-weight: bold !important;
999
1037
  }
1000
1038
  }
1039
+
1040
+ /* ---------------------------------------------------------------------------
1041
+ react-select, wearing the same clothes as every other field
1042
+ ---------------------------------------------------------------------------
1043
+ The dropdowns are react-select with `classNamePrefix="visns-select"`, so
1044
+ they arrive with react-select's OWN defaults: a #cccccc 1px border and a 4px
1045
+ radius. Everything else in a form gets the rule above — a
1046
+ `rgba(paragraph, .15)` hairline at `var(--br)`. Measured side by side in one
1047
+ form: 1px #cccccc / 4px on the selects, 1px rgba(68,60,43,.15) / 5px on the
1048
+ inputs.
1049
+
1050
+ One pixel of radius and a different grey is not something anyone can name
1051
+ when they look at it, which is exactly why it reads as "these don't match".
1052
+ ------------------------------------------------------------------------ */
1053
+
1054
+ .visns-select__control {
1055
+ /* Same token the native inputs below use. 51px was 3px taller than a text
1056
+ input, which is exactly the kind of difference nobody can name but
1057
+ everybody sees when the two sit side by side in one form. */
1058
+ min-height: var(--field-height, 51px);
1059
+ border: 1px solid rgba(var(--paragraph-rgb, 43, 43, 43), 0.15) !important;
1060
+ border-radius: var(--br, 5px) !important;
1061
+ background: var(--background-color, #fff);
1062
+ /* react-select paints its own shadow on focus; the app's focus ring is the
1063
+ one below, so this one goes. */
1064
+ box-shadow: none !important;
1065
+ }
1066
+
1067
+ .visns-select__control:hover {
1068
+ border-color: rgba(var(--paragraph-rgb, 43, 43, 43), 0.28) !important;
1069
+ }
1070
+
1071
+ .visns-select__control--is-focused {
1072
+ border-color: color-mix(
1073
+ in srgb,
1074
+ var(--primary-color, #1b3933) 45%,
1075
+ rgba(var(--paragraph-rgb, 43, 43, 43), 0.15)
1076
+ ) !important;
1077
+ box-shadow: 0 0 0 3px
1078
+ color-mix(in srgb, var(--highlight-color, #3cbf7d) 22%, transparent) !important;
1079
+ }
1080
+
1081
+ .visns-select__control--is-disabled {
1082
+ background: rgba(var(--paragraph-rgb, 43, 43, 43), 0.04);
1083
+ }
1084
+
1085
+ /* The menu is a surface like any other popover in the app, not a browser
1086
+ dropdown: same radius, same hairline, one shadow. */
1087
+ .visns-select__menu {
1088
+ border: 1px solid rgba(var(--paragraph-rgb, 43, 43, 43), 0.15);
1089
+ border-radius: var(--br, 5px);
1090
+ box-shadow: 0 12px 28px -12px rgba(0, 0, 0, 0.28);
1091
+ overflow: hidden;
1092
+ }
1093
+
1094
+ .visns-select__option--is-focused {
1095
+ background: color-mix(
1096
+ in srgb,
1097
+ var(--primary-color, #1b3933) 8%,
1098
+ transparent
1099
+ );
1100
+ }
1101
+
1102
+ .visns-select__option--is-selected {
1103
+ background: var(--primary-color, #1b3933);
1104
+ color: #fff;
1105
+ }
1106
+
1107
+ /* react-select builds the control out of nested boxes that each carry their
1108
+ own padding, so matching the outer height is not enough — the text still
1109
+ sits differently from a native input. These line the inner boxes up with
1110
+ the `padding: 1rem` / `font-size: 0.85rem` of the input rule below, and
1111
+ drop the indicator separator, a divider no other field in the app has. */
1112
+ .visns-select__value-container {
1113
+ padding: 0 1rem !important;
1114
+ }
1115
+
1116
+ .visns-select__input-container,
1117
+ .visns-select__single-value,
1118
+ .visns-select__placeholder {
1119
+ margin: 0 !important;
1120
+ padding: 0 !important;
1121
+ font-size: 0.85rem;
1122
+ line-height: 1;
1123
+ }
1124
+
1125
+ .visns-select__indicator-separator {
1126
+ display: none !important;
1127
+ }
1128
+
1129
+ /* react-select puts a real `<input>` inside the control so you can type to
1130
+ filter. It is an `input[type="text"]`, so the padded native-input rule
1131
+ further up was styling it as a form field in its own right: 1rem of padding
1132
+ and the full 48px control height, nested INSIDE the 48px control. That is
1133
+ what made every dropdown ~6px taller than the input beside it. */
1134
+ .visns-select__input {
1135
+ min-height: 0 !important;
1136
+ height: auto !important;
1137
+ padding: 0 !important;
1138
+ border: 0 !important;
1139
+ background: transparent !important;
1140
+ box-shadow: none !important;
1141
+ line-height: 1 !important;
1142
+ }
1143
+
1144
+ .visns-select__indicator {
1145
+ padding: 0 0.5rem !important;
1146
+ }
1147
+
1148
+ .visns-select__option {
1149
+ font-size: 0.85rem;
1150
+ }
1151
+