@visns-studio/visns-components 6.1.3 → 6.1.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,16 +1,24 @@
1
- /* Grouped Report Base Styles */
1
+ /* Grouped report surfaces.
2
+ Same visual language as the rest of the report builder: white surfaces,
3
+ single hairlines, quiet uppercase column labels, one radius, muted ink.
4
+ Every custom property carries a literal fallback because consuming projects
5
+ define different subsets of the design tokens. */
2
6
  .grouped-report {
3
- --group-header-bg-primary: #2c5282;
4
- --group-header-bg-secondary: #4a5568;
5
- --group-header-bg-success: #38a169;
6
- --group-header-bg-warning: #d69e2e;
7
- --group-header-bg-danger: #e53e3e;
8
- --group-header-color: white;
9
- --empty-row-bg-light: #f8f9fa;
10
- --empty-row-bg-transparent: transparent;
11
- --border-color: #dee2e6;
12
- --border-color-light: #e2e8f0;
13
- --text-muted: #6c757d;
7
+ --gr-surface: var(--item-color, #fff);
8
+ --gr-surface-quiet: var(--bg-color, #f7f7f8);
9
+ --gr-line: var(--border-color, #e1e1e1);
10
+ --gr-radius: var(--br, 5px);
11
+ --gr-ink: var(--header-color, #212930);
12
+ --gr-ink-muted: rgba(var(--paragraph-rgb, 34, 30, 51), 0.6);
13
+ --gr-accent: var(--primary-color, #2c5282);
14
+
15
+ /* Group header accents stay config-driven (groupHeaderStyle) but read as a
16
+ thin rule rather than a saturated fill. */
17
+ --group-accent-primary: var(--primary-color, #2c5282);
18
+ --group-accent-secondary: var(--gr-line);
19
+ --group-accent-success: var(--success-color, #2f855a);
20
+ --group-accent-warning: var(--warning-color, #b7791f);
21
+ --group-accent-danger: var(--danger-color, #c53030);
14
22
  }
15
23
 
16
24
  .grouped-report * {
@@ -22,22 +30,33 @@
22
30
  display: flex;
23
31
  justify-content: space-between;
24
32
  align-items: center;
25
- margin-bottom: 1.5rem;
26
- padding: 1rem;
27
- background-color: #f8f9fa;
28
- border-radius: 0.375rem;
29
- border: 1px solid var(--border-color);
33
+ gap: 1rem;
34
+ margin-bottom: 1rem;
35
+ padding: 0.75rem 1rem;
36
+ background-color: var(--gr-surface);
37
+ border: 1px solid var(--gr-line);
38
+ border-radius: var(--gr-radius);
30
39
  }
31
40
 
32
41
  .grouped-report-summary {
33
42
  display: flex;
34
- align-items: center;
35
- gap: 1rem;
43
+ align-items: baseline;
44
+ gap: 0.5rem;
45
+ min-width: 0;
36
46
  }
37
47
 
38
- .summary-text {
39
- font-weight: 500;
40
- color: var(--text-muted);
48
+ .grouped-report-summary .group-title {
49
+ font-size: 0.75rem;
50
+ font-weight: 600;
51
+ letter-spacing: 0.06em;
52
+ text-transform: uppercase;
53
+ color: var(--gr-ink-muted);
54
+ }
55
+
56
+ .summary-text,
57
+ .grouped-report-summary .group-stats {
58
+ font-size: 0.8125rem;
59
+ color: var(--gr-ink-muted);
41
60
  }
42
61
 
43
62
  .grouped-report-actions {
@@ -46,18 +65,33 @@
46
65
  }
47
66
 
48
67
  .btn-export {
49
- background-color: #0d6efd;
50
- color: white;
51
- border: none;
52
- padding: 0.5rem 1rem;
53
- border-radius: 0.375rem;
68
+ display: inline-flex;
69
+ align-items: center;
70
+ gap: 6px;
71
+ background-color: var(--gr-surface);
72
+ color: var(--gr-ink);
73
+ border: 1px solid var(--gr-line);
74
+ padding: 8px 14px;
75
+ border-radius: var(--gr-radius);
54
76
  cursor: pointer;
77
+ font-size: 0.8125rem;
55
78
  font-weight: 500;
56
- transition: background-color 0.15s ease-in-out;
79
+ transition: color 0.2s ease, border-color 0.2s ease;
80
+ }
81
+
82
+ .btn-export:hover:not(:disabled) {
83
+ color: var(--gr-accent);
84
+ border-color: var(--gr-accent);
85
+ }
86
+
87
+ .btn-export:disabled {
88
+ opacity: 0.5;
89
+ cursor: not-allowed;
57
90
  }
58
91
 
59
- .btn-export:hover {
60
- background-color: #0b5ed7;
92
+ .btn-export:focus-visible {
93
+ outline: 2px solid var(--gr-accent);
94
+ outline-offset: 2px;
61
95
  }
62
96
 
63
97
  /* Section-based Grouping */
@@ -66,112 +100,142 @@
66
100
  }
67
101
 
68
102
  .grouped-report--sections .group-section {
69
- margin-bottom: 2rem;
103
+ margin-bottom: 1rem;
70
104
  page-break-inside: avoid;
71
- border: 1px solid var(--border-color);
72
- border-radius: 0.5rem;
105
+ background-color: var(--gr-surface);
106
+ border: 1px solid var(--gr-line);
107
+ border-radius: var(--gr-radius);
73
108
  overflow: hidden;
74
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
75
109
  }
76
110
 
77
111
  /* Group Headers */
78
112
  .group-header {
113
+ width: 100%;
79
114
  padding: 0.75rem 1rem;
80
- font-weight: 600;
81
115
  display: flex;
82
- justify-content: space-between;
83
116
  align-items: center;
84
- color: var(--group-header-color);
117
+ gap: 0.5rem;
118
+ background-color: var(--gr-surface);
119
+ border: 0;
120
+ border-bottom: 1px solid var(--gr-line);
121
+ border-left: 3px solid var(--group-accent-secondary);
122
+ color: var(--gr-ink);
123
+ font: inherit;
124
+ text-align: left;
125
+ cursor: pointer;
126
+ user-select: none;
127
+ }
128
+
129
+ .group-header:focus-visible {
130
+ outline: 2px solid var(--gr-accent);
131
+ outline-offset: -2px;
132
+ }
133
+
134
+ .group-header-toggle {
135
+ display: inline-flex;
136
+ align-items: center;
137
+ color: var(--gr-ink-muted);
85
138
  }
86
139
 
87
140
  .group-header-content {
88
141
  display: flex;
89
142
  justify-content: space-between;
90
143
  align-items: center;
144
+ gap: 0.75rem;
91
145
  width: 100%;
146
+ min-width: 0;
92
147
  }
93
148
 
94
149
  .group-title {
95
- font-size: 1rem;
150
+ font-size: 0.875rem;
151
+ font-weight: 600;
96
152
  margin: 0;
153
+ overflow: hidden;
154
+ text-overflow: ellipsis;
155
+ white-space: nowrap;
97
156
  }
98
157
 
99
158
  .group-stats {
100
- font-size: 0.875rem;
159
+ font-size: 0.8125rem;
101
160
  font-weight: 400;
102
- opacity: 0.9;
161
+ color: var(--gr-ink-muted);
162
+ white-space: nowrap;
103
163
  }
104
164
 
105
- /* Group Header Styles */
165
+ /* Group Header Styles — accent rule only, no heavy fills */
106
166
  .group-section--primary .group-header {
107
- background-color: var(--group-header-bg-primary);
167
+ border-left-color: var(--group-accent-primary);
108
168
  }
109
169
 
110
170
  .group-section--secondary .group-header {
111
- background-color: var(--group-header-bg-secondary);
171
+ border-left-color: var(--group-accent-secondary);
112
172
  }
113
173
 
114
174
  .group-section--success .group-header {
115
- background-color: var(--group-header-bg-success);
175
+ border-left-color: var(--group-accent-success);
116
176
  }
117
177
 
118
178
  .group-section--warning .group-header {
119
- background-color: var(--group-header-bg-warning);
179
+ border-left-color: var(--group-accent-warning);
120
180
  }
121
181
 
122
182
  .group-section--danger .group-header {
123
- background-color: var(--group-header-bg-danger);
183
+ border-left-color: var(--group-accent-danger);
124
184
  }
125
185
 
126
186
  /* Group Content */
127
187
  .group-content {
128
- background-color: white;
188
+ background-color: var(--gr-surface);
189
+ }
190
+
191
+ .group-content .table-container,
192
+ .grouped-table-container {
193
+ overflow: auto;
194
+ max-height: 80vh;
129
195
  }
130
196
 
131
197
  .group-table,
132
198
  .grouped-table {
133
199
  width: 100%;
200
+ min-width: 100%;
134
201
  border-collapse: collapse;
135
202
  margin: 0;
136
203
  }
137
204
 
138
205
  .group-table thead th,
139
206
  .grouped-table thead th {
140
- background-color: #f8f9fa;
141
- color: #495057;
207
+ position: sticky;
208
+ top: 0;
209
+ z-index: 1;
210
+ background-color: var(--gr-surface-quiet);
211
+ color: var(--gr-ink-muted);
142
212
  font-weight: 600;
143
- padding: 0.75rem;
213
+ padding: 0.625rem 0.75rem;
144
214
  text-align: left;
145
- border-bottom: 2px solid var(--border-color);
146
- border-right: 1px solid var(--border-color-light);
147
- font-size: 0.875rem;
215
+ white-space: nowrap;
216
+ border-bottom: 1px solid var(--gr-line);
217
+ font-size: 0.6875rem;
148
218
  text-transform: uppercase;
149
- letter-spacing: 0.05em;
150
- }
151
-
152
- .group-table thead th:last-child,
153
- .grouped-table thead th:last-child {
154
- border-right: none;
219
+ letter-spacing: 0.06em;
155
220
  }
156
221
 
157
222
  .group-table thead th.required-column,
158
223
  .grouped-table thead th.required-column {
159
- background-color: #e3f2fd;
160
- font-weight: 700;
224
+ color: var(--gr-ink);
161
225
  }
162
226
 
163
227
  .group-table tbody td,
164
228
  .grouped-table tbody td {
165
- padding: 0.75rem;
166
- border-bottom: 1px solid var(--border-color-light);
167
- border-right: 1px solid var(--border-color-light);
229
+ padding: 0.625rem 0.75rem;
230
+ border-bottom: 1px solid var(--gr-line);
168
231
  vertical-align: top;
169
- font-size: 0.875rem;
232
+ font-size: 0.8125rem;
233
+ color: var(--gr-ink);
170
234
  }
171
235
 
172
- .group-table tbody td:last-child,
173
- .grouped-table tbody td:last-child {
174
- border-right: none;
236
+ .group-table tbody tr:last-child td,
237
+ .grouped-table tbody tr:last-child td {
238
+ border-bottom: none;
175
239
  }
176
240
 
177
241
  .group-table tbody td.required-column,
@@ -181,90 +245,77 @@
181
245
 
182
246
  /* Data Rows */
183
247
  .data-row {
184
- background-color: white;
248
+ background-color: var(--gr-surface);
185
249
  transition: background-color 0.15s ease-in-out;
186
250
  }
187
251
 
188
252
  .data-row:hover {
189
- background-color: #f8f9fa;
190
- }
191
-
192
- .data-row:nth-child(even) {
193
- background-color: #fbfcfd;
194
- }
195
-
196
- .data-row:nth-child(even):hover {
197
- background-color: #f1f3f4;
253
+ background-color: var(--gr-surface-quiet);
198
254
  }
199
255
 
200
256
  /* Empty Rows */
201
257
  .empty-row td {
202
- height: 2.5rem;
203
- min-height: 2.5rem;
204
- border-bottom: 1px solid var(--border-color-light);
258
+ height: 2.25rem;
259
+ min-height: 2.25rem;
260
+ border-bottom: 1px solid var(--gr-line);
205
261
  }
206
262
 
207
263
  .empty-row--light {
208
- background-color: var(--empty-row-bg-light);
264
+ background-color: var(--gr-surface-quiet);
209
265
  }
210
266
 
211
267
  .empty-row--transparent {
212
- background-color: var(--empty-row-bg-transparent);
268
+ background-color: transparent;
213
269
  }
214
270
 
215
271
  .empty-row--striped:nth-child(even) {
216
- background-color: #f8f9fa;
272
+ background-color: var(--gr-surface-quiet);
217
273
  }
218
274
 
219
- /* Empty State */
220
- .grouped-report-empty {
275
+ /* Empty / error states */
276
+ .grouped-report-empty,
277
+ .grouped-report-error {
221
278
  text-align: center;
222
- padding: 3rem;
223
- color: var(--text-muted);
224
- background-color: #f8f9fa;
225
- border: 1px solid var(--border-color);
226
- border-radius: 0.5rem;
279
+ padding: 2.5rem 1.5rem;
280
+ color: var(--gr-ink-muted);
281
+ background-color: var(--gr-surface);
282
+ border: 1px solid var(--gr-line);
283
+ border-radius: var(--gr-radius);
227
284
  }
228
285
 
229
286
  .grouped-report-error {
230
- text-align: center;
231
- padding: 2rem;
232
- color: #dc3545;
233
- background-color: #f8d7da;
234
- border: 1px solid #f5c6cb;
235
- border-radius: 0.5rem;
287
+ border-left: 3px solid var(--danger-color, #c53030);
288
+ text-align: left;
289
+ }
290
+
291
+ .grouped-report-empty p,
292
+ .grouped-report-error p {
293
+ margin: 0;
294
+ font-size: 0.875rem;
236
295
  }
237
296
 
238
297
  /* Responsive Design */
239
298
  @media (max-width: 768px) {
240
299
  .grouped-report-header {
241
300
  flex-direction: column;
242
- gap: 1rem;
301
+ gap: 0.75rem;
243
302
  align-items: stretch;
244
303
  }
245
-
304
+
246
305
  .group-table,
247
306
  .grouped-table {
248
307
  font-size: 0.75rem;
249
308
  }
250
-
309
+
251
310
  .group-table thead th,
252
311
  .group-table tbody td,
253
312
  .grouped-table thead th,
254
313
  .grouped-table tbody td {
255
314
  padding: 0.5rem;
256
315
  }
257
-
316
+
258
317
  .group-header {
259
- padding: 0.5rem;
260
- }
261
-
262
- .group-title {
263
- font-size: 0.875rem;
264
- }
265
-
266
- .group-stats {
267
- font-size: 0.75rem;
318
+ padding: 0.625rem 0.75rem;
268
319
  }
269
320
  }
270
321
 
@@ -273,35 +324,28 @@
273
324
  .grouped-report-actions {
274
325
  display: none;
275
326
  }
276
-
327
+
277
328
  .group-section {
278
329
  page-break-inside: avoid;
279
330
  margin-bottom: 1rem;
280
331
  border: 1px solid #000;
281
332
  }
282
-
333
+
283
334
  .group-header {
284
- background-color: #000 !important;
285
- color: white !important;
286
- -webkit-print-color-adjust: exact;
287
- print-color-adjust: exact;
288
- }
289
-
290
- .group-table,
291
- .grouped-table {
292
- border-collapse: collapse;
335
+ border-left-width: 3px;
336
+ border-bottom: 1px solid #000;
293
337
  }
294
-
338
+
295
339
  .group-table thead th,
296
340
  .group-table tbody td,
297
341
  .grouped-table thead th,
298
342
  .grouped-table tbody td {
299
343
  border: 1px solid #000;
300
344
  }
301
-
345
+
302
346
  .empty-row--light {
303
347
  background-color: #f0f0f0 !important;
304
348
  -webkit-print-color-adjust: exact;
305
349
  print-color-adjust: exact;
306
350
  }
307
- }
351
+ }
@@ -1,5 +1,10 @@
1
1
  @use 'controls' as *;
2
2
 
3
+ /* The page header bar below (`.crmtitle`) is the same spec as the index
4
+ header in GenericIndex.module.scss, so the two pages share one header
5
+ language. The `--page-header-*` density hooks are documented once, at the
6
+ top of that file; keep the two rules in step. */
7
+
3
8
  .btn {
4
9
  @include button-primary;
5
10
  }
@@ -166,16 +171,21 @@
166
171
  /* Was a centred, tinted bar. A section heading is read at the start of
167
172
  the line like everything under it; centring it made the eye jump to the
168
173
  middle and back for every section on the page. */
169
- padding: 0 0 var(--spacing-sm);
170
- border-bottom: 1px solid var(--border-color);
174
+ /* Literal fallbacks throughout: --spacing-*, --font-size-sm,
175
+ --font-weight-semibold and --muted-color are not in every project's
176
+ token set, and a bare var() for a missing token is invalid at
177
+ computed-value time — the declaration is dropped and the quiet label
178
+ silently reverts to unpadded body text. */
179
+ padding: 0 0 var(--spacing-sm, 0.5rem);
180
+ border-bottom: 1px solid var(--border-color, #e1e1e1);
171
181
  border-radius: 0;
172
- margin-bottom: var(--spacing-md);
173
- font-size: var(--font-size-sm);
174
- font-weight: var(--font-weight-semibold);
182
+ margin-bottom: var(--spacing-md, 1rem);
183
+ font-size: var(--font-size-sm, 0.8rem);
184
+ font-weight: var(--font-weight-semibold, 600);
175
185
  letter-spacing: 0.06em;
176
186
  text-transform: uppercase;
177
187
  text-align: left;
178
- color: var(--muted-color);
188
+ color: var(--muted-color, rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.6));
179
189
  }
180
190
 
181
191
  .gridtxt__header span {
@@ -194,13 +204,17 @@
194
204
  margin: 0;
195
205
  }
196
206
 
207
+ /* Overview fields. These were chunky tinted boxes — a brand-tinted border and
208
+ fill around every single value, which turned a plain list of facts into two
209
+ columns of competing containers. A field needs only enough edge to show
210
+ where it ends: the shared hairline token, no fill, tighter padding. */
197
211
  .gridtxt > ul li {
198
212
  flex: 0 0 calc(50% - 10px);
199
- padding: 0.65rem;
213
+ padding: 0.5rem 0.65rem;
200
214
  box-sizing: border-box;
201
- border: 1px solid rgba(var(--primary-rgb), 0.095);
215
+ border: 1px solid var(--border-color, #e1e1e1);
202
216
  color: var(--paragraph-color);
203
- background: rgba(var(--primary-rgb), 0.015);
217
+ background: var(--surface-color, transparent);
204
218
  margin: 3px;
205
219
  border-radius: var(--br);
206
220
  line-height: 1.45;
@@ -217,8 +231,8 @@
217
231
  as an error; a left rule was only a quieter version of the same mistake.
218
232
  Emphasis should mean something, and here there is nothing to emphasise. */
219
233
  .gridtxt > ul .notecolor {
220
- border: 1px solid var(--border-color);
221
- background: var(--surface-color);
234
+ border: 1px solid var(--border-color, #e1e1e1);
235
+ background: var(--surface-color, transparent);
222
236
  }
223
237
 
224
238
  .titleInfo {
@@ -640,47 +654,77 @@
640
654
 
641
655
 
642
656
 
643
- .crmtitle {
657
+ /* The unified page header bar. Identical spec to `.crmtitle` in
658
+ GenericIndex.module.scss — see the `--page-header-*` hooks block at the top
659
+ of that file. This was a tall bordered white card with its own radius and
660
+ type scale, which is why the detail and index headers looked like two
661
+ different products; it is now the same bar as the index, carrying a
662
+ breadcrumb instead of a plain title.
663
+
664
+ `.crmtitle--alternate` is the non-`full` layout's variant (also used by
665
+ OAuthIntegrationsPage). It had no rule in this file, so it fell through to
666
+ the bare `.grid__full` card; it joins the same bar. */
667
+ .crmtitle,
668
+ .crmtitle--alternate {
644
669
  min-height: auto;
645
- padding: 1rem;
670
+ padding: var(--page-header-padding, var(--spacing-md, 1rem));
646
671
  margin: 0;
647
- background: white;
648
- border-radius: var(--br);
649
- border: 1px solid rgba(var(--primary-rgb), 0.15);
672
+ background: var(--item-color, #fff);
673
+ border-radius: 0;
674
+ border: none;
675
+ border-bottom: 1px solid var(--border-color, #e1e1e1);
676
+ box-shadow: none;
650
677
  position: relative;
651
678
  display: flex;
652
679
  align-items: center;
653
680
  justify-content: space-between;
681
+ gap: var(--page-header-gap, var(--spacing-md, 1rem));
654
682
 
655
683
  h1 {
656
684
  font-weight: 700;
657
- font-size: 1.25rem;
685
+ font-size: var(--page-header-title-size, 1.25rem);
658
686
  margin: 0;
659
687
  padding: 0;
660
- line-height: 1;
688
+ line-height: 1.25;
689
+ display: flex;
690
+ align-items: center;
691
+ min-width: 0;
692
+ }
661
693
 
662
- a {
663
- text-decoration: none;
664
- color: var(--secondary-color);
665
- font-weight: 400;
666
- }
694
+ /* The parent crumb. Same size and baseline as the entity it leads to, so
695
+ the breadcrumb reads as one line of type rather than a label glued to a
696
+ title — but quieter, because the current page is the subject. */
697
+ h1 a {
698
+ text-decoration: none;
699
+ color: var(--muted-color, rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.6));
700
+ font-weight: 500;
701
+ transition: color 0.15s ease;
702
+ }
667
703
 
668
- svg {
669
- color: rgba(var(--primary-rgb), 0.5);
670
- position: relative;
671
- top: 2px;
672
- margin: 0 0.5rem;
673
- max-width: 15px;
674
- }
704
+ h1 a:hover {
705
+ color: var(--paragraph-color, inherit);
706
+ text-decoration: underline;
707
+ }
708
+
709
+ h1 svg {
710
+ color: var(--muted-color, rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.45));
711
+ flex: 0 0 auto;
712
+ margin: 0 0.4rem;
713
+ max-width: 15px;
675
714
  }
676
715
 
677
716
  .titleInfo {
717
+ /* `.titleInfo` is absolutely positioned for other surfaces in this
718
+ file; in the bar it is an ordinary flex child, or it would float
719
+ out of the header it belongs to. */
720
+ position: static;
678
721
  width: max-content;
722
+ flex: 0 0 auto;
679
723
  }
680
724
 
681
725
  .titleInfo span {
682
- font-size: 0.875em;
683
- color: rgba(var(--primary-rgb), 0.65);
726
+ font-size: 0.875rem;
727
+ color: var(--muted-color, rgba(var(--paragraph-color-rgb, 34, 30, 51), 0.65));
684
728
  }
685
729
  }
686
730