barua-ui 0.2.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.
@@ -0,0 +1,370 @@
1
+ /* ==========================================================================
2
+ Barua UI — Data Visualization
3
+ Chart frame, Legend, Axis, CSS bar/column charts, pie/donut/gauge via
4
+ conic-gradient, heatmap, sparkline & SVG line/area/scatter/radar styling,
5
+ progress chart, chart tooltip.
6
+ Series colors: --b-chart-1 … --b-chart-6.
7
+ ========================================================================== */
8
+
9
+ @layer components {
10
+ :root {
11
+ --b-chart-1: var(--b-color-accent);
12
+ --b-chart-2: var(--b-color-teal);
13
+ --b-chart-3: var(--b-color-purple);
14
+ --b-chart-4: var(--b-color-orange);
15
+ --b-chart-5: var(--b-color-pink);
16
+ --b-chart-6: var(--b-color-green);
17
+ }
18
+
19
+ /* ---- Chart frame -------------------------------------------------------- */
20
+ .b-chart {
21
+ display: flex;
22
+ flex-direction: column;
23
+ gap: var(--b-space-3);
24
+ }
25
+ .b-chart__title { font-size: var(--b-text-subheadline); font-weight: var(--b-weight-semibold); }
26
+ .b-chart__canvas { position: relative; }
27
+
28
+ /* ---- Legend ------------------------------------------------------------- */
29
+ .b-legend {
30
+ display: flex;
31
+ flex-wrap: wrap;
32
+ gap: var(--b-space-2) var(--b-space-4);
33
+ font-size: var(--b-text-caption);
34
+ color: var(--b-text-secondary);
35
+ list-style: none;
36
+ padding: 0;
37
+ margin: 0;
38
+ }
39
+ .b-legend li { display: inline-flex; align-items: center; gap: var(--b-space-1); }
40
+ .b-legend__swatch {
41
+ width: 0.6rem; height: 0.6rem;
42
+ border-radius: 2px;
43
+ background: var(--b-chart-1);
44
+ flex: none;
45
+ }
46
+
47
+ /* ---- Axis --------------------------------------------------------------- */
48
+ .b-axis {
49
+ display: flex;
50
+ justify-content: space-between;
51
+ font-size: var(--b-text-caption2);
52
+ color: var(--b-text-tertiary);
53
+ font-variant-numeric: tabular-nums;
54
+ }
55
+ .b-axis--y {
56
+ flex-direction: column;
57
+ text-align: end;
58
+ justify-content: space-between;
59
+ }
60
+ .b-gridlines {
61
+ position: absolute;
62
+ inset: 0;
63
+ display: flex;
64
+ flex-direction: column;
65
+ justify-content: space-between;
66
+ pointer-events: none;
67
+ }
68
+ .b-gridlines > i { border-top: 1px dashed var(--b-separator); }
69
+
70
+ /* ---- Column chart (vertical bars) ---------------------------------------
71
+ <div class="b-columns" style="--b-chart-h: 10rem">
72
+ <div class="b-columns__bar" style="--v: 62%" data-label="Mon"></div>…
73
+ --------------------------------------------------------------------------- */
74
+ .b-columns {
75
+ display: flex;
76
+ align-items: flex-end;
77
+ justify-content: space-evenly;
78
+ gap: var(--b-space-2);
79
+ height: var(--b-chart-h, 10rem);
80
+ padding-block-end: 1.4rem;
81
+ position: relative;
82
+ }
83
+ .b-columns__bar {
84
+ position: relative;
85
+ flex: 1 1 0;
86
+ height: var(--v, 50%);
87
+ min-width: 0.5rem;
88
+ /* A column is a mark, not a slab: past this width a bar stops reading as
89
+ data and starts reading as a shape, especially when rounded. */
90
+ max-width: var(--b-column-w, 3rem);
91
+ background: var(--b-chart-color, var(--b-chart-1));
92
+ border-radius: var(--b-radius-xs) var(--b-radius-xs) 0 0;
93
+ transition: height var(--b-duration-slow) var(--b-ease-out),
94
+ opacity var(--b-duration-fast);
95
+ }
96
+ .b-columns__bar:hover { opacity: 0.85; }
97
+ .b-columns__bar::after {
98
+ content: attr(data-label);
99
+ position: absolute;
100
+ top: calc(100% + 0.25rem);
101
+ inset-inline: 0;
102
+ text-align: center;
103
+ font-size: var(--b-text-caption2);
104
+ color: var(--b-text-tertiary);
105
+ white-space: nowrap;
106
+ }
107
+ .b-columns--rounded .b-columns__bar { border-radius: var(--b-radius-full); min-width: 0.625rem; }
108
+
109
+ /* Stacked segment inside a column */
110
+ .b-columns__bar > i {
111
+ position: absolute;
112
+ inset-inline: 0;
113
+ bottom: 0;
114
+ height: var(--v, 30%);
115
+ background: var(--b-chart-color, var(--b-chart-2));
116
+ border-radius: inherit;
117
+ }
118
+
119
+ /* ---- Bar chart (horizontal) ----------------------------------------------
120
+ <div class="b-bars">
121
+ <div class="b-bars__row"><span class="b-bars__label">Kenya</span>
122
+ <div class="b-bars__track"><i style="--v: 80%"></i></div>
123
+ <span class="b-bars__value">80%</span></div>…
124
+ --------------------------------------------------------------------------- */
125
+ .b-bars { display: flex; flex-direction: column; gap: var(--b-space-2); }
126
+ .b-bars__row {
127
+ display: grid;
128
+ grid-template-columns: var(--b-bars-label-w, 6rem) 1fr max-content;
129
+ align-items: center;
130
+ gap: var(--b-space-3);
131
+ font-size: var(--b-text-caption);
132
+ }
133
+ .b-bars__label { color: var(--b-text-secondary); text-align: end; }
134
+ .b-bars__track {
135
+ height: 0.625rem;
136
+ background: var(--b-fill-quaternary);
137
+ border-radius: var(--b-radius-full);
138
+ overflow: hidden;
139
+ }
140
+ .b-bars__track > i {
141
+ display: block;
142
+ height: 100%;
143
+ width: var(--v, 50%);
144
+ background: var(--b-chart-color, var(--b-chart-1));
145
+ border-radius: inherit;
146
+ transition: width var(--b-duration-slow) var(--b-ease-out);
147
+ }
148
+ .b-bars__value { font-variant-numeric: tabular-nums; color: var(--b-text-secondary); }
149
+
150
+ /* ---- Pie / Donut ----------------------------------------------------------
151
+ <div class="b-pie" style="--b-pie:
152
+ var(--b-chart-1) 0 45%, var(--b-chart-2) 45% 78%, var(--b-chart-3) 78% 100%">
153
+ --------------------------------------------------------------------------- */
154
+ .b-pie {
155
+ width: var(--b-pie-size, 9rem);
156
+ aspect-ratio: 1;
157
+ border-radius: 50%;
158
+ background: conic-gradient(var(--b-pie));
159
+ }
160
+ .b-donut {
161
+ position: relative;
162
+ display: grid;
163
+ place-items: center;
164
+ }
165
+ .b-donut > .b-pie {
166
+ -webkit-mask: radial-gradient(farthest-side, transparent var(--b-donut-hole, 62%),
167
+ #000 calc(var(--b-donut-hole, 62%) + 0.5px));
168
+ mask: radial-gradient(farthest-side, transparent var(--b-donut-hole, 62%),
169
+ #000 calc(var(--b-donut-hole, 62%) + 0.5px));
170
+ grid-area: 1 / 1;
171
+ }
172
+ .b-donut__center {
173
+ grid-area: 1 / 1;
174
+ text-align: center;
175
+ }
176
+ .b-donut__center .b-stat__value { font-size: var(--b-text-title2); }
177
+
178
+ /* ---- Gauge (half donut) ---------------------------------------------------- */
179
+ .b-gauge {
180
+ position: relative;
181
+ width: var(--b-gauge-size, 10rem);
182
+ aspect-ratio: 2 / 1;
183
+ overflow: hidden;
184
+ }
185
+ .b-gauge::before {
186
+ content: "";
187
+ position: absolute;
188
+ inset: 0 0 -100% 0;
189
+ border-radius: 50%;
190
+ background: conic-gradient(from -90deg,
191
+ var(--b-chart-color, var(--b-chart-1)) calc(var(--b-progress, 60) * 0.5%),
192
+ var(--b-fill-tertiary) 0 50%,
193
+ transparent 50%);
194
+ -webkit-mask: radial-gradient(farthest-side, transparent 64%, #000 64.5%);
195
+ mask: radial-gradient(farthest-side, transparent 64%, #000 64.5%);
196
+ }
197
+ .b-gauge__value {
198
+ position: absolute;
199
+ inset-inline: 0;
200
+ bottom: 0;
201
+ text-align: center;
202
+ font-size: var(--b-text-title2);
203
+ font-weight: var(--b-weight-bold);
204
+ font-variant-numeric: tabular-nums;
205
+ }
206
+ .b-gauge__label {
207
+ position: absolute;
208
+ inset-inline: 0;
209
+ bottom: -1.4rem;
210
+ text-align: center;
211
+ font-size: var(--b-text-caption);
212
+ color: var(--b-text-secondary);
213
+ }
214
+
215
+ /* ---- Heatmap ---------------------------------------------------------------
216
+ <div class="b-heatmap" style="--b-heatmap-cols: 12">
217
+ <i style="--v: 0.4"></i>… (v: 0–1 intensity)
218
+ --------------------------------------------------------------------------- */
219
+ .b-heatmap {
220
+ display: grid;
221
+ /* A heatmap cell is a mark to be scanned, not a tile to be filled: without
222
+ a ceiling, a square cell in a wide card grows until the chart is taller
223
+ than the screen and drags the height of everything beside it. */
224
+ grid-template-columns: repeat(var(--b-heatmap-cols, 7), minmax(0, var(--b-heatmap-cell, 2rem)));
225
+ justify-content: start;
226
+ gap: 3px;
227
+ }
228
+ .b-heatmap > i {
229
+ aspect-ratio: 1;
230
+ border-radius: 3px;
231
+ background: color-mix(in srgb, var(--b-chart-color, var(--b-chart-1))
232
+ calc(var(--v, 0) * 100%), var(--b-fill-quaternary));
233
+ transition: scale var(--b-duration-fast) var(--b-ease-standard);
234
+ }
235
+ .b-heatmap > i:hover { scale: 1.2; }
236
+
237
+ /* ---- Sparkline & SVG chart styling ------------------------------------------ */
238
+ .b-sparkline { width: 100%; height: 2rem; overflow: visible; }
239
+ .b-sparkline path, .b-line-svg path.b-series, .b-area-svg path.b-series {
240
+ fill: none;
241
+ stroke: var(--b-chart-color, var(--b-chart-1));
242
+ stroke-width: 2;
243
+ stroke-linecap: round;
244
+ stroke-linejoin: round;
245
+ vector-effect: non-scaling-stroke;
246
+ }
247
+ .b-line-svg, .b-area-svg, .b-scatter-svg, .b-radar-svg {
248
+ width: 100%;
249
+ height: auto;
250
+ /* A viewBox scales everything it contains, labels included: without a
251
+ ceiling the same chart that reads correctly in a narrow card renders
252
+ its axis type at twice the size in a wide one. */
253
+ max-height: var(--b-chart-h, 13rem);
254
+ overflow: visible;
255
+ }
256
+ .b-area-fill {
257
+ fill: color-mix(in srgb, var(--b-chart-color, var(--b-chart-1)) 18%, transparent);
258
+ stroke: none;
259
+ }
260
+ .b-svg-grid { stroke: var(--b-separator); stroke-dasharray: 3 4; stroke-width: 1; }
261
+ .b-svg-axis-label {
262
+ fill: var(--b-text-tertiary);
263
+ font-size: 0.625rem;
264
+ font-family: var(--b-font-sans);
265
+ }
266
+ .b-dot {
267
+ fill: var(--b-chart-color, var(--b-chart-1));
268
+ stroke: var(--b-bg);
269
+ stroke-width: 1.5;
270
+ transition: r var(--b-duration-fast);
271
+ }
272
+ .b-dot:hover { r: 6; }
273
+ .b-radar-svg polygon.b-series {
274
+ fill: color-mix(in srgb, var(--b-chart-color, var(--b-chart-1)) 22%, transparent);
275
+ stroke: var(--b-chart-color, var(--b-chart-1));
276
+ stroke-width: 2;
277
+ stroke-linejoin: round;
278
+ }
279
+ .b-radar-svg polygon.b-web, .b-radar-svg line.b-web {
280
+ fill: none;
281
+ stroke: var(--b-separator);
282
+ stroke-width: 1;
283
+ }
284
+
285
+ /* ---- Progress chart (multi progress rows) ------------------------------------ */
286
+ .b-progress-chart { display: flex; flex-direction: column; gap: var(--b-space-3); }
287
+ .b-progress-chart__row { display: flex; flex-direction: column; gap: var(--b-space-1); }
288
+ .b-progress-chart__head {
289
+ display: flex;
290
+ justify-content: space-between;
291
+ font-size: var(--b-text-caption);
292
+ color: var(--b-text-secondary);
293
+ }
294
+
295
+ /* ---- Rule mark (Swift Charts RuleMark) — a goal/threshold line ----------- */
296
+ .b-rule {
297
+ position: absolute;
298
+ inset-inline: 0;
299
+ border-top: 1.5px dashed var(--b-color-danger);
300
+ pointer-events: none;
301
+ }
302
+ .b-rule--accent { border-top-color: var(--b-color-accent); }
303
+ .b-rule__label {
304
+ position: absolute;
305
+ inset-inline-end: 0;
306
+ translate: 0 -100%;
307
+ padding: 0 var(--b-space-1);
308
+ font-size: var(--b-text-caption2);
309
+ font-weight: var(--b-weight-semibold);
310
+ color: inherit;
311
+ background: var(--b-surface);
312
+ border-radius: var(--b-radius-xs);
313
+ }
314
+ .b-rule { color: var(--b-color-danger); }
315
+ .b-rule--accent { color: var(--b-color-accent-text); }
316
+
317
+ /* ---- Linear gauge (SwiftUI Gauge, linear style) --------------------------- */
318
+ .b-gauge-linear { display: flex; flex-direction: column; gap: var(--b-space-1); }
319
+ .b-gauge-linear__track {
320
+ position: relative;
321
+ height: 0.375rem;
322
+ border-radius: var(--b-radius-full);
323
+ background: linear-gradient(90deg, var(--b-color-green), var(--b-color-yellow), var(--b-color-red));
324
+ }
325
+ .b-gauge-linear__track--plain { background: var(--b-fill-tertiary); }
326
+ .b-gauge-linear__marker {
327
+ position: absolute;
328
+ top: 50%;
329
+ inset-inline-start: var(--v, 50%);
330
+ translate: -50% -50%;
331
+ width: 0.85rem;
332
+ height: 0.85rem;
333
+ background: light-dark(#fff, #f5f6fa);
334
+ border-radius: 50%;
335
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3), 0 0 0 0.5px rgba(0, 0, 0, 0.08);
336
+ }
337
+ .b-gauge-linear__labels {
338
+ display: flex;
339
+ justify-content: space-between;
340
+ font-size: var(--b-text-caption2);
341
+ color: var(--b-text-tertiary);
342
+ font-variant-numeric: tabular-nums;
343
+ }
344
+
345
+ /* ---- Chart Tooltip (data point) ----------------------------------------------- */
346
+ .b-chart-tip {
347
+ position: absolute;
348
+ z-index: var(--b-z-tooltip);
349
+ padding: var(--b-space-1) var(--b-space-2);
350
+ font-size: var(--b-text-caption);
351
+ font-weight: var(--b-weight-medium);
352
+ font-variant-numeric: tabular-nums;
353
+ white-space: nowrap;
354
+ color: light-dark(#fff, #0c0c10);
355
+ background: light-dark(rgba(24, 26, 34, 0.92), rgba(245, 246, 250, 0.95));
356
+ border-radius: var(--b-radius-sm);
357
+ box-shadow: var(--b-shadow-sm);
358
+ translate: -50% calc(-100% - 6px);
359
+ pointer-events: none;
360
+ }
361
+ .b-chart-tip::after {
362
+ content: "";
363
+ position: absolute;
364
+ top: 100%;
365
+ inset-inline-start: 50%;
366
+ translate: -50% 0;
367
+ border: 4px solid transparent;
368
+ border-top-color: light-dark(rgba(24, 26, 34, 0.92), rgba(245, 246, 250, 0.95));
369
+ }
370
+ }