@actionexec/dashboards 0.10.0 → 0.12.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.
- package/dist/{ColorPaletteSelector-CsByaRmM.js → ColorPaletteSelector-DJge9VhO.js} +101 -97
- package/dist/ColorPaletteSelector-DJge9VhO.js.map +1 -0
- package/dist/index.js +362 -339
- package/dist/index.js.map +1 -1
- package/dist/internals.d.ts +2 -2
- package/dist/internals.js +42 -41
- package/dist/styles.css +1 -1
- package/dist/types/index.d.ts +40 -7
- package/package.json +1 -1
- package/dist/ColorPaletteSelector-CsByaRmM.js.map +0 -1
package/dist/internals.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { T, y as
|
|
2
|
-
import { z as I, B as R, w as r, E as n, F as P, H as D, s as m, I as F, C as M, J as N, K as g, L as C, N as G, O as c, P as i, Q as U, D as
|
|
1
|
+
import { T as L, y as T } from "./ColorPaletteSelector-DJge9VhO.js";
|
|
2
|
+
import { z as I, B as R, w as r, E as n, F as P, H as D, s as m, I as F, C as M, J as N, K as g, L as C, N as G, O as c, P as i, Q as U, D as W, R as l, U as p, V as u, W as B, X as h, v as Y, G as H, Y as d, Z as k, x as X, _ as f, k as V, M as b, $, a0 as w, a1 as x, a2 as y, a3 as j, S as q, a4 as v, a5 as z, a6 as J, a7 as K, c as Q, b as Z, t as aa, d as sa, u as ea, a8 as Ea, a9 as _a, e as La, g as Ta, o as ta, aa as Sa, n as Aa, l as Oa, r as oa, q as Ia, ab as Ra, ac as ra, h as na, i as Pa, ad as Da, j as ma, m as Fa, ae as Ma, p as Na, af as ga } from "./ColorPaletteSelector-DJge9VhO.js";
|
|
3
3
|
const t = "−";
|
|
4
4
|
function A(a) {
|
|
5
5
|
const s = a.amount ?? 0;
|
|
6
6
|
if (s === 0) return "";
|
|
7
|
-
const e = Math.abs(s), [E, _] = a.mode === "window" ?
|
|
7
|
+
const e = Math.abs(s), [E, _] = a.mode === "window" ? L : T[a.unit ?? "month"];
|
|
8
8
|
return `${s < 0 ? t : "+"}${e} ${e === 1 ? E : _}`;
|
|
9
9
|
}
|
|
10
10
|
export {
|
|
@@ -24,56 +24,57 @@ export {
|
|
|
24
24
|
c as DEFAULT_GRID_ROWS,
|
|
25
25
|
i as DEFAULT_PALETTE,
|
|
26
26
|
U as DEFAULT_PALETTE_COLORS,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
W as DashboardDatePicker,
|
|
28
|
+
l as EMPTY_LAYOUT,
|
|
29
|
+
p as FILTER_OPERATOR_LABELS,
|
|
30
|
+
u as FILTER_TYPE_LABELS,
|
|
31
|
+
B as FORMAT_LABELS,
|
|
32
|
+
h as GOOD_WHEN_LABELS,
|
|
33
33
|
Y as GRID_GAP_PX,
|
|
34
34
|
H as GRID_PADDING_PX,
|
|
35
35
|
d as LIST_FILTER_OPERATORS,
|
|
36
36
|
k as MAX_CELL_HEIGHT_PX,
|
|
37
37
|
X as MIN_CELL_HEIGHT_PX,
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
f as MONTH_NAMES_FULL,
|
|
39
|
+
V as MONTH_NAMES_SHORT,
|
|
40
|
+
b as MULTI_VALUE_SEPARATOR,
|
|
41
41
|
$ as NUMERIC_FORMAT_OPTIONS,
|
|
42
42
|
w as PALETTES,
|
|
43
43
|
x as SERIES_COUNT,
|
|
44
44
|
y as SLOT_INDEX,
|
|
45
45
|
j as SLOT_LABELS,
|
|
46
46
|
q as SearchableSelect,
|
|
47
|
-
|
|
48
|
-
T as
|
|
49
|
-
|
|
50
|
-
z as
|
|
51
|
-
J as
|
|
52
|
-
K as
|
|
53
|
-
Q as
|
|
54
|
-
Z as
|
|
55
|
-
aa as
|
|
56
|
-
sa as
|
|
57
|
-
ea as
|
|
58
|
-
Ea as
|
|
59
|
-
_a as
|
|
47
|
+
v as TABLE_OVERFLOW_LABELS,
|
|
48
|
+
T as TIME_OFFSET_UNIT_LABELS,
|
|
49
|
+
L as TIME_OFFSET_WINDOW_LABEL,
|
|
50
|
+
z as TOTAL_SLOTS,
|
|
51
|
+
J as VALUELESS_FILTER_OPERATORS,
|
|
52
|
+
K as WIDGET_TYPE_LABELS,
|
|
53
|
+
Q as computeCellHeight,
|
|
54
|
+
Z as computeCellWidth,
|
|
55
|
+
aa as computeGridHeight,
|
|
56
|
+
sa as computeStackThreshold,
|
|
57
|
+
ea as computeWidgetAspect,
|
|
58
|
+
Ea as dateToIso,
|
|
59
|
+
_a as ensurePaletteShape,
|
|
60
|
+
La as formatCompact,
|
|
60
61
|
A as formatTimeOffset,
|
|
61
62
|
Ta as formatValue,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
ta as getFullYearRange,
|
|
64
|
+
Sa as getISOWeek,
|
|
65
|
+
Aa as getMonthRange,
|
|
66
|
+
Oa as getMonthWeeks,
|
|
67
|
+
oa as getPaletteCssVars,
|
|
68
|
+
Ia as getSeries,
|
|
69
|
+
Ra as getWeekRange,
|
|
70
|
+
ra as getWeeksInMonth,
|
|
71
|
+
na as getYearRange,
|
|
72
|
+
Pa as isNumericFormat,
|
|
73
|
+
Da as isoToDate,
|
|
74
|
+
ma as parseMonthFromRange,
|
|
75
|
+
Fa as parseMonthWeekFromRange,
|
|
76
|
+
Ma as parseWeekFromRange,
|
|
77
|
+
Na as parseYearFromRange,
|
|
78
|
+
ga as setApiUrl
|
|
78
79
|
};
|
|
79
80
|
//# sourceMappingURL=internals.js.map
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";.react-datepicker__navigation-icon:before,.react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view--down-arrow{border-color:#ccc;border-style:solid;border-width:3px 3px 0 0;content:"";display:block;height:9px;position:absolute;top:6px;width:9px}.react-datepicker__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.react-datepicker-wrapper{display:inline-block;padding:0;border:0}.react-datepicker{font-family:Helvetica Neue,helvetica,arial,sans-serif;font-size:.8rem;background-color:#fff;color:#000;border:1px solid #aeaeae;border-radius:.3rem;display:inline-block;position:relative;line-height:initial}.react-datepicker--time-only .react-datepicker__time-container{border-left:0}.react-datepicker--time-only .react-datepicker__time,.react-datepicker--time-only .react-datepicker__time-box{border-bottom-left-radius:.375em;border-bottom-right-radius:.375em}.react-datepicker-popper{z-index:1;line-height:0}.react-datepicker-popper .react-datepicker__triangle{stroke:#aeaeae}.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle{fill:#f0f0f0;color:#f0f0f0}.react-datepicker-popper[data-placement^=top] .react-datepicker__triangle,.react-datepicker-popper--header-middle[data-placement^=bottom] .react-datepicker__triangle,.react-datepicker-popper--header-bottom[data-placement^=bottom] .react-datepicker__triangle{fill:#fff;color:#fff}.react-datepicker-popper--header-bottom[data-placement^=top] .react-datepicker__triangle{fill:#f0f0f0;color:#f0f0f0}.react-datepicker__header{text-align:center;background-color:#f0f0f0;border-bottom:1px solid #aeaeae;border-top-left-radius:.3rem;padding:8px 0;position:relative}.react-datepicker__header--time{padding-bottom:8px;padding-left:5px;padding-right:5px}.react-datepicker__header--time:not(.react-datepicker__header--time--only){border-top-left-radius:0}.react-datepicker__header:not(.react-datepicker__header--has-time-select,.react-datepicker__header--middle,.react-datepicker__header--bottom){border-top-right-radius:.3rem}.react-datepicker__header--middle{border-top:1px solid #aeaeae;border-radius:0;margin-top:4px}.react-datepicker__header--bottom{border-bottom:none;border-top:1px solid #aeaeae;border-radius:0 0 .3rem .3rem}.react-datepicker__header-wrapper{position:relative}.react-datepicker__header-wrapper .react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button){right:2px}.react-datepicker__year-dropdown-container--select,.react-datepicker__month-dropdown-container--select,.react-datepicker__month-year-dropdown-container--select,.react-datepicker__year-dropdown-container--scroll,.react-datepicker__month-dropdown-container--scroll,.react-datepicker__month-year-dropdown-container--scroll{display:inline-block;margin:0 15px}.react-datepicker__month-select,.react-datepicker__year-select,.react-datepicker__month-year-select{background-color:transparent;border:1px solid #aeaeae;border-radius:.3rem;color:inherit;cursor:pointer;font-family:inherit;font-size:inherit;margin-top:5px;padding:2px 5px}.react-datepicker__month-select:focus-visible,.react-datepicker__year-select:focus-visible,.react-datepicker__month-year-select:focus-visible{outline:auto 1px}.react-datepicker__current-month,.react-datepicker-time__header,.react-datepicker-year-header{margin-top:0;color:#000;font-weight:700;font-size:.944rem}h2.react-datepicker__current-month{padding:0;margin:0}.react-datepicker-time__header{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.react-datepicker__navigation{align-items:center;background:none;display:flex;justify-content:center;text-align:center;cursor:pointer;position:absolute;top:2px;padding:0;border:none;z-index:1;height:32px;width:32px;text-indent:-999em;overflow:hidden}.react-datepicker__navigation--previous{left:2px}.react-datepicker__navigation--next{right:2px}.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button){right:85px}.react-datepicker__navigation--years{position:relative;top:0;display:block;margin-left:auto;margin-right:auto}.react-datepicker__navigation--years-previous{top:4px}.react-datepicker__navigation--years-upcoming{top:-4px}.react-datepicker__navigation:hover *:before{border-color:#a6a6a6}.react-datepicker__navigation-icon{position:relative;top:-1px;font-size:20px;width:0}.react-datepicker__navigation-icon--next{left:-2px}.react-datepicker__navigation-icon--next:before{transform:rotate(45deg);left:-7px}.react-datepicker__navigation-icon--previous{right:-2px}.react-datepicker__navigation-icon--previous:before{transform:rotate(225deg);right:-7px}.react-datepicker__month-container{float:left}.react-datepicker__year{margin:.5em;text-align:center}.react-datepicker__year-wrapper{display:flex;flex-wrap:wrap;max-width:180px}.react-datepicker__year .react-datepicker__year-text{display:inline-block;width:5em;margin:2px}.react-datepicker__month{margin:.5em;text-align:center}.react-datepicker__month .react-datepicker__month-text,.react-datepicker__month .react-datepicker__quarter-text{display:inline-block;width:5em;margin:2px}.react-datepicker__input-time-container{clear:both;width:100%;float:left;margin:5px 0 10px 15px;text-align:left}.react-datepicker__input-time-container .react-datepicker-time__caption,.react-datepicker__input-time-container .react-datepicker-time__input-container{display:inline-block}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input{display:inline-block;margin-left:10px}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input{width:auto}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]::-webkit-inner-spin-button,.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]{-moz-appearance:textfield}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__delimiter{margin-left:5px;display:inline-block}.react-datepicker__time-container{float:right;border-left:1px solid #aeaeae;width:85px}.react-datepicker__time-container--with-today-button{display:inline;border:1px solid #aeaeae;border-radius:.375em;position:absolute;right:-87px;top:0}.react-datepicker__time-container .react-datepicker__time{position:relative;background:#fff;border-bottom-right-radius:.375em}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box{width:85px;overflow-x:hidden;margin:0 auto;text-align:center;border-bottom-right-radius:.375em}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list{list-style:none;margin:0;height:calc(195px + 1.0625em);overflow-y:scroll;padding-right:0;padding-left:0;width:100%;box-sizing:content-box}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item{height:30px;padding:5px 10px;white-space:nowrap}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover{cursor:pointer;background-color:#f0f0f0}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected{background-color:#216ba5;color:#fff;font-weight:700}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover{background-color:#216ba5}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--disabled{color:#ccc}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--disabled:hover{cursor:default;background-color:transparent}.react-datepicker__week-number{color:#ccc;display:inline-block;width:2.125em;line-height:2.125em;text-align:center;margin:.208em}.react-datepicker__week-number.react-datepicker__week-number--clickable{cursor:pointer}.react-datepicker__week-number.react-datepicker__week-number--clickable:not(.react-datepicker__week-number--selected):hover{border-radius:.3rem;background-color:#f0f0f0}.react-datepicker__week-number--selected{border-radius:.3rem;background-color:#216ba5;color:#fff}.react-datepicker__week-number--selected:hover{background-color:#1d5d90}.react-datepicker__day-names{text-align:center;white-space:nowrap;margin-bottom:-8px}.react-datepicker__week{white-space:nowrap}.react-datepicker__day-name,.react-datepicker__day,.react-datepicker__time-name{color:#000;display:inline-block;width:2.125em;line-height:2.125em;text-align:center;margin:.208em}.react-datepicker__day-name--disabled,.react-datepicker__day--disabled,.react-datepicker__time-name--disabled{cursor:default;color:#ccc}.react-datepicker__day,.react-datepicker__month-text,.react-datepicker__quarter-text,.react-datepicker__year-text{cursor:pointer}.react-datepicker__day:not([aria-disabled=true]):hover,.react-datepicker__month-text:not([aria-disabled=true]):hover,.react-datepicker__quarter-text:not([aria-disabled=true]):hover,.react-datepicker__year-text:not([aria-disabled=true]):hover{border-radius:.3rem;background-color:#f0f0f0}.react-datepicker__day--today,.react-datepicker__month-text--today,.react-datepicker__quarter-text--today,.react-datepicker__year-text--today{font-weight:700}.react-datepicker__day--highlighted,.react-datepicker__month-text--highlighted,.react-datepicker__quarter-text--highlighted,.react-datepicker__year-text--highlighted{border-radius:.3rem;background-color:#3dcc4a;color:#fff}.react-datepicker__day--highlighted:not([aria-disabled=true]):hover,.react-datepicker__month-text--highlighted:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--highlighted:not([aria-disabled=true]):hover,.react-datepicker__year-text--highlighted:not([aria-disabled=true]):hover{background-color:#32be3f}.react-datepicker__day--highlighted-custom-1,.react-datepicker__month-text--highlighted-custom-1,.react-datepicker__quarter-text--highlighted-custom-1,.react-datepicker__year-text--highlighted-custom-1{color:#f0f}.react-datepicker__day--highlighted-custom-2,.react-datepicker__month-text--highlighted-custom-2,.react-datepicker__quarter-text--highlighted-custom-2,.react-datepicker__year-text--highlighted-custom-2{color:green}.react-datepicker__day--holidays,.react-datepicker__month-text--holidays,.react-datepicker__quarter-text--holidays,.react-datepicker__year-text--holidays{position:relative;border-radius:.3rem;background-color:#ff6803;color:#fff}.react-datepicker__day--holidays .overlay,.react-datepicker__month-text--holidays .overlay,.react-datepicker__quarter-text--holidays .overlay,.react-datepicker__year-text--holidays .overlay{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px;border-radius:4px;white-space:nowrap;visibility:hidden;opacity:0;transition:visibility 0s,opacity .3s ease-in-out}.react-datepicker__day--holidays:not([aria-disabled=true]):hover,.react-datepicker__month-text--holidays:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--holidays:not([aria-disabled=true]):hover,.react-datepicker__year-text--holidays:not([aria-disabled=true]):hover{background-color:#cf5300}.react-datepicker__day--holidays:hover .overlay,.react-datepicker__month-text--holidays:hover .overlay,.react-datepicker__quarter-text--holidays:hover .overlay,.react-datepicker__year-text--holidays:hover .overlay{visibility:visible;opacity:1}.react-datepicker__day--selected,.react-datepicker__day--in-selecting-range,.react-datepicker__day--in-range,.react-datepicker__month-text--selected,.react-datepicker__month-text--in-selecting-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--selected,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--selected,.react-datepicker__year-text--in-selecting-range,.react-datepicker__year-text--in-range{border-radius:.3rem;background-color:#216ba5;color:#fff}.react-datepicker__day--selected:not([aria-disabled=true]):hover,.react-datepicker__day--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__day--in-range:not([aria-disabled=true]):hover,.react-datepicker__month-text--selected:not([aria-disabled=true]):hover,.react-datepicker__month-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__month-text--in-range:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--selected:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--in-range:not([aria-disabled=true]):hover,.react-datepicker__year-text--selected:not([aria-disabled=true]):hover,.react-datepicker__year-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__year-text--in-range:not([aria-disabled=true]):hover{background-color:#1d5d90}.react-datepicker__day--keyboard-selected,.react-datepicker__month-text--keyboard-selected,.react-datepicker__quarter-text--keyboard-selected,.react-datepicker__year-text--keyboard-selected{border-radius:.3rem;background-color:#bad9f1;color:#000}.react-datepicker__day--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__month-text--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__year-text--keyboard-selected:not([aria-disabled=true]):hover{background-color:#1d5d90;color:#fff}.react-datepicker__day--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__month-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__quarter-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__year-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range){background-color:#216ba580}.react-datepicker__month--selecting-range .react-datepicker__day--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__day--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__month-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__month-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__quarter-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__quarter-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__year-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__year-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range){background-color:#f0f0f0;color:#000}.react-datepicker__day--disabled,.react-datepicker__month-text--disabled,.react-datepicker__quarter-text--disabled,.react-datepicker__year-text--disabled{cursor:default;color:#ccc}.react-datepicker__day--disabled .overlay,.react-datepicker__month-text--disabled .overlay,.react-datepicker__quarter-text--disabled .overlay,.react-datepicker__year-text--disabled .overlay{position:absolute;bottom:70%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px;border-radius:4px;white-space:nowrap;visibility:hidden;opacity:0;transition:visibility 0s,opacity .3s ease-in-out}.react-datepicker__input-container{position:relative;display:inline-block;width:100%}.react-datepicker__input-container .react-datepicker__calendar-icon{position:absolute;padding:.625em;box-sizing:content-box}.react-datepicker__view-calendar-icon input{padding:6px 10px 5px 25px}.react-datepicker__year-read-view,.react-datepicker__month-read-view,.react-datepicker__month-year-read-view{border:1px solid transparent;border-radius:.3rem;position:relative}.react-datepicker__year-read-view:hover,.react-datepicker__month-read-view:hover,.react-datepicker__month-year-read-view:hover{cursor:pointer}.react-datepicker__year-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__year-read-view:hover .react-datepicker__month-read-view--down-arrow,.react-datepicker__month-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view:hover .react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__month-year-read-view:hover .react-datepicker__month-read-view--down-arrow{border-top-color:#b3b3b3}.react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view--down-arrow{transform:rotate(135deg);right:-16px;top:0}.react-datepicker__year-dropdown,.react-datepicker__month-dropdown,.react-datepicker__month-year-dropdown{background-color:#f0f0f0;position:absolute;width:50%;left:25%;top:30px;z-index:1;text-align:center;border-radius:.3rem;border:1px solid #aeaeae}.react-datepicker__year-dropdown:hover,.react-datepicker__month-dropdown:hover,.react-datepicker__month-year-dropdown:hover{cursor:pointer}.react-datepicker__year-dropdown--scrollable,.react-datepicker__month-dropdown--scrollable,.react-datepicker__month-year-dropdown--scrollable{height:150px;overflow-y:scroll}.react-datepicker__year-option,.react-datepicker__month-option,.react-datepicker__month-year-option{line-height:20px;width:100%;display:block;margin-left:auto;margin-right:auto}.react-datepicker__year-option:first-of-type,.react-datepicker__month-option:first-of-type,.react-datepicker__month-year-option:first-of-type{border-top-left-radius:.3rem;border-top-right-radius:.3rem}.react-datepicker__year-option:last-of-type,.react-datepicker__month-option:last-of-type,.react-datepicker__month-year-option:last-of-type{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom-left-radius:.3rem;border-bottom-right-radius:.3rem}.react-datepicker__year-option:hover,.react-datepicker__month-option:hover,.react-datepicker__month-year-option:hover{background-color:#ccc}.react-datepicker__year-option:hover .react-datepicker__navigation--years-upcoming,.react-datepicker__month-option:hover .react-datepicker__navigation--years-upcoming,.react-datepicker__month-year-option:hover .react-datepicker__navigation--years-upcoming{border-bottom-color:#b3b3b3}.react-datepicker__year-option:hover .react-datepicker__navigation--years-previous,.react-datepicker__month-option:hover .react-datepicker__navigation--years-previous,.react-datepicker__month-year-option:hover .react-datepicker__navigation--years-previous{border-top-color:#b3b3b3}.react-datepicker__year-option--selected,.react-datepicker__month-option--selected,.react-datepicker__month-year-option--selected{position:absolute;left:15px}.react-datepicker__close-icon{cursor:pointer;background-color:transparent;border:0;outline:0;padding:0 6px 0 0;position:absolute;top:0;right:0;height:100%;display:table-cell;vertical-align:middle}.react-datepicker__close-icon:after{cursor:pointer;background-color:#216ba5;color:#fff;border-radius:50%;height:16px;width:16px;padding:2px;font-size:12px;line-height:1;text-align:center;display:table-cell;vertical-align:middle;content:"×"}.react-datepicker__close-icon--disabled{cursor:default}.react-datepicker__close-icon--disabled:after{cursor:default;background-color:#ccc}.react-datepicker__today-button{background:#f0f0f0;border-top:1px solid #aeaeae;cursor:pointer;text-align:center;font-weight:700;padding:5px 0;clear:left}.react-datepicker__portal{position:fixed;width:100vw;height:100vh;background-color:#000c;left:0;top:0;justify-content:center;align-items:center;display:flex;z-index:2147483647}.react-datepicker__children-container{width:17.25em;margin:.5em;padding-right:.25em;padding-left:.25em;height:auto}.react-datepicker__aria-live{position:absolute;clip-path:circle(0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;width:1px;white-space:nowrap}.react-datepicker__calendar-icon{width:1em;height:1em;vertical-align:-.125em}.react-datepicker-popper-offset{margin-top:-.7em}:where(.preview-tab,.widget,.palette-selector,.ddp-field){--spacing-xs: 4px;--spacing-sm: 8px;--spacing-md: 16px;--spacing-lg: 24px;--spacing-xl: 32px;--spacing-2xl: 48px;--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--transition-fast: .15s ease;--shadow-lg: 0 10px 25px rgba(0, 0, 0, .4)}.preview-tab{display:flex;flex-direction:column;gap:var(--spacing-md);position:relative}.preview-tab__empty{display:flex;align-items:center;justify-content:center;min-height:300px;color:var(--text-muted);font-size:.9rem;border:2px dashed var(--bg-elevated);border-radius:var(--radius-lg)}.preview-tab__loading{display:flex;align-items:center;justify-content:center;padding:var(--spacing-2xl) 0;color:var(--text-secondary)}.preview-tab__error{padding:var(--spacing-md);background:#f443361a;border:1px solid var(--color-error);border-radius:var(--radius-md);color:var(--color-error);font-size:.875rem;text-align:center}.preview-tab__grid{display:grid;grid-template-columns:repeat(var(--dash-cols, 30),1fr);grid-template-rows:repeat(var(--dash-rows, 10),var(--dash-cell-h, 40px));grid-auto-rows:var(--dash-cell-h, 40px);gap:var(--dash-gap, 6px);padding:var(--dash-pad, 16px);background:var(--bg-dark);border-radius:var(--radius-lg)}.preview-tab__grid--stacked{grid-template-columns:1fr;grid-template-rows:none;grid-auto-rows:auto}.preview-tab__widget{display:flex;background:var(--bg-elevated);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius-md);overflow:hidden;min-height:0;container-type:size}.preview-tab__widget--control{background:var(--bg-elevated);border:1px dashed rgba(255,255,255,.15)}.preview-tab__widget-loading{display:flex;align-items:center;justify-content:center;height:100%;min-height:80px;color:var(--text-muted);font-size:.8125rem}.preview-tab__recalculating{position:fixed;bottom:var(--spacing-lg);right:var(--spacing-lg);padding:var(--spacing-sm) var(--spacing-lg);background:var(--bg-elevated);border:1px solid var(--action-orange);border-radius:var(--radius-md);color:var(--action-orange);font-size:.8125rem;font-weight:var(--font-weight-medium);box-shadow:var(--shadow-lg);z-index:50}.palette-selector{display:flex;flex-direction:column;gap:var(--spacing-sm)}.palette-selector--disabled{opacity:.5;pointer-events:none}.palette-selector__options{display:flex;flex-direction:column;gap:var(--spacing-xs)}.palette-selector__option{display:flex;flex-direction:column;gap:var(--spacing-xs);padding:var(--spacing-xs);background:transparent;border:1.5px solid var(--bg-elevated);border-radius:var(--radius-sm);cursor:pointer;transition:border-color var(--transition-fast)}.palette-selector__option:hover:not(:disabled){border-color:var(--text-muted)}.palette-selector__option--active{border-color:var(--action-orange)}.palette-selector__bar{display:flex;width:100%;height:18px;border-radius:3px;overflow:hidden}.palette-selector__bar--theme{height:12px;opacity:.85}.palette-selector__swatch{flex:1;min-width:0}.palette-selector__label{font-size:.7rem;color:var(--text-muted);text-align:left}.palette-selector__custom{display:flex;flex-direction:column;gap:6px}.palette-selector__row{display:flex;flex-direction:column;gap:4px}.palette-selector__row-label{font-size:.6rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;font-weight:var(--font-weight-semibold)}.palette-selector__row-slots{display:flex;gap:4px;flex-wrap:wrap}.palette-selector__color-input{width:24px;height:24px;padding:0;border:1.5px solid rgba(255,255,255,.25);border-radius:var(--radius-sm);background:transparent;cursor:pointer;transition:border-color var(--transition-fast);flex-shrink:0}.palette-selector__color-input:hover:not(:disabled){border-color:#ffffff80}.palette-selector__color-input:hover:not(:disabled){border-color:var(--action-orange)}.palette-selector__color-input::-webkit-color-swatch-wrapper{padding:2px}.palette-selector__color-input::-webkit-color-swatch{border:none;border-radius:2px}.ddp-field{width:100%;min-width:0;display:block}.ddp-field .react-datepicker-wrapper,.ddp-field .react-datepicker__input-container{width:100%;display:block}.ddp-field .react-datepicker__input-container input{width:100%;padding:var(--spacing-sm) var(--spacing-md);background:var(--bg-elevated);border:1.5px solid var(--bg-elevated);border-radius:var(--radius-sm);font-size:.8125rem;color:var(--text-primary);box-sizing:border-box;transition:border-color var(--transition-fast)}.ddp-field .react-datepicker__input-container input:focus{outline:none;border-color:var(--action-orange)}.ddp-field .react-datepicker__input-container input::placeholder{color:var(--text-muted)}.ddp-field .react-datepicker__input-container input:disabled{opacity:.6;cursor:not-allowed}.ddp-field .react-datepicker__month{min-height:168px}.react-datepicker-popper{z-index:1100!important}.widget{flex:1;display:flex;flex-direction:column;padding:var(--spacing-sm);background:var(--bg-elevated);border-radius:var(--radius-md);overflow:hidden;box-sizing:border-box;min-height:0;min-width:0}.widget__title{flex-shrink:0;margin:0 0 clamp(2px,1cqmin,8px);font-size:clamp(.5rem,4cqi,.9rem);font-weight:var(--font-weight-semibold);color:var(--text-secondary);line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget__state{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;padding:var(--spacing-xs);font-size:clamp(.45rem,2.5cqi,.85rem);color:var(--text-muted)}.widget__state--error{color:var(--color-error)}.widget-filter,.widget-palette{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:clamp(4px,1.5cqi,12px);padding:clamp(4px,1cqi,8px) clamp(6px,1.5cqi,12px);box-sizing:border-box;min-height:0;min-width:0;overflow:hidden}.widget-variable{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;box-sizing:border-box;min-height:0;min-width:0;overflow:hidden}.widget-filter__label,.widget-palette__label,.widget-variable__label{flex-shrink:0;font-size:clamp(.45rem,6cqi,3rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-kpi{justify-content:center;align-items:center;text-align:center;gap:clamp(2px,1cqmin,10px);padding:clamp(4px,2cqmin,16px)}.widget-kpi .widget__title{margin:0;font-size:clamp(.45rem,min(12cqi,12cqb),6rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-kpi__value{font-size:clamp(.85rem,min(22cqi,22cqb),8rem);font-weight:var(--font-weight-bold);color:var(--text-primary);line-height:1.1;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.widget-kpi__trend{display:flex;align-items:center;justify-content:center;gap:.35em .7em;font-size:clamp(.4rem,min(8cqi,8cqb),2rem);max-width:100%;overflow:hidden;flex-wrap:wrap}.widget-kpi__trend--good{color:var(--color-success)}.widget-kpi__trend--bad{color:var(--color-error)}.widget-kpi__trend--muted{opacity:.75;font-size:.9em}.widget-kpi__variance{font-weight:var(--font-weight-semibold);white-space:nowrap}.widget-kpi__trend-label{color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@container (max-width: 180px){.widget-kpi__trend-label{display:none}}@container (max-height: 70px){.widget-kpi .widget__title{display:none}}.widget-gauge{align-items:center;gap:0;overflow:hidden}.widget-gauge .widget__title{margin:0;font-size:clamp(.5rem,6cqi,3rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-gauge__chart{position:relative;width:100%;flex:1;min-height:0}.widget-gauge__chart svg{margin-top:5%;display:block;width:100%;height:100%}.widget-gauge__center{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;margin-top:25%}.widget-gauge__percent{font-size:clamp(.5rem,9cqi,4rem);font-weight:var(--font-weight-bold);color:var(--text-primary);line-height:1}.widget-gauge__comparison{font-size:clamp(.4rem,3.5cqi,2rem);color:var(--text-muted)}.widget-gauge__badge{font-size:clamp(.35rem,3cqi,1.25rem);font-weight:var(--font-weight-semibold);text-transform:uppercase;letter-spacing:.3px;padding:1px var(--spacing-xs);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.widget-chart{gap:var(--spacing-xs)}.widget-chart .widget__title{color:var(--text-primary)}.widget-chart__container{flex:1;min-height:0;overflow:hidden}.widget-composition{gap:var(--spacing-xs)}.widget-composition .widget__title{color:var(--text-primary)}.widget-composition__container{flex:1;min-height:0;overflow:hidden}.widget-composition__tooltip{display:flex;flex-direction:column;gap:2px;padding:6px 10px;border:1px solid var(--bg-paper);border-radius:6px;background-color:var(--bg-elevated);font-size:.75rem;line-height:1.3}.widget-composition__tooltip-label{color:var(--text-primary);font-weight:var(--font-weight-semibold)}.widget-composition__tooltip-value{color:var(--text-secondary)}.widget-table{display:flex;flex-direction:column;gap:.4rem;height:100%;overflow:hidden;padding:.5rem .6rem;box-sizing:border-box}.widget-table__td--placeholder{color:var(--text-muted, #999);text-align:center;padding:.75rem .5rem}.widget-table__tabs{flex:0 0 auto;display:flex;gap:.25rem;border-bottom:1px solid var(--border, rgba(255, 255, 255, .12))}.widget-table__tab{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:none;border-bottom:2px solid transparent;color:var(--text-muted, #999);font:inherit;font-size:.78rem;font-weight:600;padding:.25rem .6rem;cursor:pointer}.widget-table__tab:hover{color:var(--text-primary, #f5f5f5)}.widget-table__tab--active{color:var(--color-accent, #f9812a);border-bottom-color:var(--color-accent, #f9812a)}.widget-table__scroll{flex:1 1 auto;min-height:0;overflow:auto}.widget-table__table{width:100%;border-collapse:collapse;font-size:.78rem}.widget-table__th{position:sticky;top:0;z-index:1;text-align:left;font-weight:600;color:var(--text-secondary, #ccc);background:var(--bg-elevated, #333);padding:.35rem .5rem;border-bottom:1px solid var(--border, rgba(255, 255, 255, .12));white-space:nowrap}.widget-table__th--num{text-align:right}.widget-table__td{padding:.3rem .5rem;color:var(--text-primary, #f5f5f5);border-bottom:1px solid var(--border, rgba(255, 255, 255, .06));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:26ch}.widget-table__td--num{text-align:right;font-variant-numeric:tabular-nums}.widget-table__td--up{color:var(--color-success, #a4c639);font-weight:600}.widget-table__td--down{color:var(--color-error, #e5534b);font-weight:600}.widget-table__table tbody tr:hover{background:#ffffff08}.widget-filter__date-range{display:flex;align-items:center;gap:clamp(2px,1cqi,8px);flex:1;min-width:0}.widget-filter__date-range--stacked{flex-direction:column;align-items:stretch;gap:clamp(4px,1.5cqmin,10px);width:100%;padding:clamp(2px,1cqmin,8px) 0}.widget-filter__date-range .ddp-field{flex:1;min-width:0;width:100%}.widget-filter__date-range .ddp-field .react-datepicker__input-container input,.widget-filter__select{padding:clamp(8px,4cqmin,22px) clamp(6px,1.5cqmin,12px);font-size:clamp(.5rem,10cqmin,2rem);background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);color:var(--text-primary);flex:1;min-width:0;width:100%;box-sizing:border-box;text-align:center;font-variant-numeric:tabular-nums}.widget-filter__date-sep{font-size:clamp(.35rem,2.5cqi,.8rem);color:var(--text-muted)}.widget-filter__multi{display:flex;flex-direction:column;align-items:stretch;justify-content:space-around;gap:clamp(4px,1.5cqmin,14px);flex:1;min-height:0;width:100%;padding:clamp(6px,2cqmin,14px) clamp(4px,2cqmin,12px);box-sizing:border-box;overflow-y:auto}.widget-filter__multi::-webkit-scrollbar{width:6px}.widget-filter__multi::-webkit-scrollbar-track{background:transparent}.widget-filter__multi::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}.widget-filter__multi::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.widget-filter__multi-clear{flex-shrink:0;width:100%;padding:clamp(3px,1cqmin,8px) clamp(8px,2.5cqmin,14px);background:transparent;border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);color:var(--action-orange);font-size:clamp(.4rem,7cqmin,1rem);font-weight:var(--font-weight-semibold);text-align:center;cursor:pointer;transition:background-color var(--transition-fast),border-color var(--transition-fast)}.widget-filter__multi-clear:hover{background-color:var(--bg-elevated);border-color:var(--action-orange)}.widget-filter__multi-option{display:flex;align-items:center;gap:clamp(6px,4cqmin,14px);padding:clamp(4px,1.5cqmin,12px) clamp(8px,2.5cqmin,14px);height:clamp(20px,18cqb,120px);background:var(--bg-paper);border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);cursor:pointer;transition:border-color var(--transition-fast),background-color var(--transition-fast);font-size:clamp(.45rem,8cqmin,1.2rem);font-weight:var(--font-weight-medium);color:var(--text-primary);line-height:1;flex-shrink:0;box-sizing:border-box}.widget-filter__multi-option:hover{border-color:var(--text-muted);background-color:var(--bg-elevated)}.widget-filter__multi-option:has(input[type=checkbox]:checked){border-color:var(--text-muted);background-color:var(--bg-elevated)}.widget-filter__multi-option input[type=checkbox]{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:clamp(12px,7cqmin,22px);height:clamp(12px,7cqmin,22px);border:1.5px solid var(--text-muted);border-radius:3px;background:var(--bg-elevated);cursor:pointer;position:relative;flex-shrink:0;transition:border-color var(--transition-fast),background-color var(--transition-fast);margin:0}.widget-filter__multi-option input[type=checkbox]:hover{border-color:var(--action-orange)}.widget-filter__multi-option input[type=checkbox]:checked{background:var(--action-orange);border-color:var(--action-orange)}.widget-filter__multi-option input[type=checkbox]:checked:after{content:"";position:absolute;left:30%;top:8%;width:30%;height:60%;border:solid var(--bg-dark);border-width:0 2px 2px 0;transform:rotate(45deg)}.widget-filter__select{width:95%;max-height:45%;margin-top:2%;flex:1;font-size:clamp(.4rem,5cqi,1.5rem);font-weight:var(--font-weight-semibold);color:var(--text-primary);text-align:left;padding:clamp(8px,4cqi,22px) clamp(6px,1.5cqi,12px);min-width:0;box-sizing:border-box}.widget-filter>.widget-filter__select,.widget-filter__date-range--year .widget-filter__select,.widget-filter__date-range--month .widget-filter__select,.widget-filter__date-range--week .widget-filter__select{text-align:center;text-align-last:center;font-weight:var(--font-weight-semibold);color:var(--text-primary);background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:none;transition:border-color var(--transition-fast),background-color var(--transition-fast);box-sizing:border-box;width:100%;margin-top:0;max-height:none;padding:clamp(2px,.8cqmin,6px) clamp(6px,1.5cqmin,12px);line-height:1}.widget-filter>.widget-filter__select:hover,.widget-filter>.widget-filter__select:focus,.widget-filter__date-range--year .widget-filter__select:hover,.widget-filter__date-range--year .widget-filter__select:focus,.widget-filter__date-range--month .widget-filter__select:hover,.widget-filter__date-range--month .widget-filter__select:focus,.widget-filter__date-range--week .widget-filter__select:hover,.widget-filter__date-range--week .widget-filter__select:focus{outline:none;border-color:var(--action-orange);background-color:var(--bg-elevated)}.widget-filter>.widget-filter__select option,.widget-filter__date-range--year .widget-filter__select option,.widget-filter__date-range--month .widget-filter__select option,.widget-filter__date-range--week .widget-filter__select option{background:var(--bg-paper);color:var(--text-primary);font-size:.875rem;font-weight:var(--font-weight-normal);text-align:left;padding:6px 10px}.widget-filter>.widget-filter__select{flex:0 1 auto;height:clamp(50px,22cqmin,140px);max-height:75%;margin-block:auto;align-self:center;font-size:clamp(.6rem,12cqmin,2.2rem)}.widget-filter__date-range--year,.widget-filter__date-range--month,.widget-filter__date-range--week{display:flex;flex-direction:column;align-items:stretch;justify-content:center;gap:clamp(6px,2.5cqmin,16px);flex:1;width:100%;padding:clamp(6px,2cqmin,16px) clamp(4px,2cqmin,14px);box-sizing:border-box}.widget-filter__date-range--year .widget-filter__select{flex:0 1 auto;height:clamp(50px,22cqmin,140px);font-size:clamp(.6rem,12cqmin,2.2rem)}.widget-filter__date-range--month .widget-filter__select{flex:0 1 auto;height:clamp(30px,10cqmin,66px);font-size:clamp(.5rem,10cqmin,1.4rem)}.widget-filter__date-range--week .widget-filter__select{flex:0 1 auto;height:clamp(22px,12cqmin,48px);font-size:clamp(.45rem,8cqmin,3rem)}.widget-filter__search{position:relative;display:flex;align-items:center;flex:1;min-width:0;width:100%;padding:clamp(2px,1cqmin,8px) 0}.widget-filter .widget-filter__search-field{width:100%;padding:clamp(6px,3cqmin,18px) clamp(8px,2cqmin,14px);background:var(--bg-dark);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);color:var(--text-primary);font-size:clamp(.55rem,10cqmin,1.8rem);font-weight:var(--font-weight-semibold);text-align:center;box-sizing:border-box;cursor:text;transition:border-color var(--transition-fast),background-color var(--transition-fast)}.widget-filter .widget-filter__search-field::placeholder{color:var(--text-muted);font-weight:var(--font-weight-normal)}.widget-filter .widget-filter__search-field:hover,.widget-filter .widget-filter__search-field:focus{outline:none;border-color:var(--action-orange);background-color:var(--bg-paper)}.widget-filter__search-panel{z-index:10000;display:flex;flex-direction:column;background:var(--bg-paper);border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);box-shadow:var(--shadow-md, 0 8px 28px rgba(0, 0, 0, .45));overflow:hidden}.widget-filter__search-list{display:flex;flex-direction:column;gap:2px;padding:6px;overflow-y:auto}.widget-filter__search-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-left:3px solid transparent;border-radius:var(--radius-sm);color:var(--text-primary);font-size:.85rem;font-weight:var(--font-weight-medium);text-align:left;cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast)}.widget-filter__search-option:hover{background-color:var(--bg-elevated)}.widget-filter__search-option.is-selected{background-color:var(--bg-elevated);border-left-color:var(--action-orange);color:var(--action-orange)}.widget-filter__search-check{flex-shrink:0;width:1em;color:var(--action-orange);font-weight:var(--font-weight-semibold)}.widget-filter__search-option input[type=checkbox]{width:16px;height:16px;flex-shrink:0;accent-color:var(--action-orange);cursor:pointer}.widget-filter__search-clear{width:100%;margin-bottom:4px;padding:8px 10px;background:transparent;border:none;border-bottom:1px solid var(--bg-elevated);border-radius:0;color:var(--action-orange);font-size:.8rem;font-weight:var(--font-weight-semibold);text-align:left;cursor:pointer;transition:background-color var(--transition-fast)}.widget-filter__search-clear:hover{background-color:var(--bg-elevated)}.widget-filter__search-empty{padding:12px;color:var(--text-muted);font-size:.85rem;text-align:center}.widget-filter__search-list::-webkit-scrollbar{width:6px}.widget-filter__search-list::-webkit-scrollbar-track{background:transparent}.widget-filter__search-list::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}.widget-filter__search-list::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.widget-variable__input-wrapper{display:flex;align-items:center;margin-top:2%;width:90%;background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);overflow:hidden}.widget-variable__input{flex:1;font-size:clamp(.4rem,5cqi,1.5rem);font-weight:var(--font-weight-semibold);background:transparent;border:none;outline:none;color:var(--text-primary);text-align:left;padding:clamp(2px,1cqi,6px) clamp(4px,1.5cqi,8px);min-width:0;box-sizing:border-box}.widget-variable__input::-webkit-outer-spin-button,.widget-variable__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.widget-variable__input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.widget-variable__input:disabled{opacity:.6;cursor:not-allowed}.widget-variable__suffix{font-size:clamp(.4rem,4cqi,1.25rem);color:var(--text-muted);white-space:nowrap;padding:0 clamp(4px,1.5cqi,8px);border-left:1px solid rgba(255,255,255,.1);flex-shrink:0}.widget-variable__lock-icon{font-size:clamp(.45rem,2.5cqi,.75rem)}.widget-variable--locked .widget-variable__input-wrapper{border-style:dashed}.widget-palette{flex-direction:column;justify-content:flex-start;align-items:stretch;padding:clamp(4px,1.5cqmin,12px);gap:clamp(2px,1cqmin,8px);overflow:auto}.widget-palette__label{text-align:center;flex-shrink:0}.widget-palette__lock-icon{font-size:clamp(.45rem,2.5cqmin,.75rem);align-self:center}.widget-palette--locked .palette-selector__color-input{opacity:.6;cursor:not-allowed}.widget-palette .palette-selector{gap:clamp(2px,3cqmin,28px);flex:1;min-height:0;justify-content:center}.widget-palette .palette-selector__row{gap:clamp(1px,1.2cqmin,10px);min-height:0}.widget-palette .palette-selector__row-label{font-size:clamp(.35rem,1.8cqmin,.7rem);line-height:1}.widget-palette .palette-selector__row-slots{gap:clamp(1px,.8cqmin,6px);flex-wrap:nowrap;justify-content:space-between;width:100%;min-height:0}.widget-palette .palette-selector__color-input{flex:1 1 0;min-width:0;min-height:0;width:auto;height:clamp(8px,10cqmin,60px);border:1px solid rgba(255,255,255,.2);padding:0}.widget-palette .palette-selector__color-input:hover:not(:disabled){border-color:#fff6}
|
|
1
|
+
@charset "UTF-8";.react-datepicker__navigation-icon:before,.react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view--down-arrow{border-color:#ccc;border-style:solid;border-width:3px 3px 0 0;content:"";display:block;height:9px;position:absolute;top:6px;width:9px}.react-datepicker__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.react-datepicker-wrapper{display:inline-block;padding:0;border:0}.react-datepicker{font-family:Helvetica Neue,helvetica,arial,sans-serif;font-size:.8rem;background-color:#fff;color:#000;border:1px solid #aeaeae;border-radius:.3rem;display:inline-block;position:relative;line-height:initial}.react-datepicker--time-only .react-datepicker__time-container{border-left:0}.react-datepicker--time-only .react-datepicker__time,.react-datepicker--time-only .react-datepicker__time-box{border-bottom-left-radius:.375em;border-bottom-right-radius:.375em}.react-datepicker-popper{z-index:1;line-height:0}.react-datepicker-popper .react-datepicker__triangle{stroke:#aeaeae}.react-datepicker-popper[data-placement^=bottom] .react-datepicker__triangle{fill:#f0f0f0;color:#f0f0f0}.react-datepicker-popper[data-placement^=top] .react-datepicker__triangle,.react-datepicker-popper--header-middle[data-placement^=bottom] .react-datepicker__triangle,.react-datepicker-popper--header-bottom[data-placement^=bottom] .react-datepicker__triangle{fill:#fff;color:#fff}.react-datepicker-popper--header-bottom[data-placement^=top] .react-datepicker__triangle{fill:#f0f0f0;color:#f0f0f0}.react-datepicker__header{text-align:center;background-color:#f0f0f0;border-bottom:1px solid #aeaeae;border-top-left-radius:.3rem;padding:8px 0;position:relative}.react-datepicker__header--time{padding-bottom:8px;padding-left:5px;padding-right:5px}.react-datepicker__header--time:not(.react-datepicker__header--time--only){border-top-left-radius:0}.react-datepicker__header:not(.react-datepicker__header--has-time-select,.react-datepicker__header--middle,.react-datepicker__header--bottom){border-top-right-radius:.3rem}.react-datepicker__header--middle{border-top:1px solid #aeaeae;border-radius:0;margin-top:4px}.react-datepicker__header--bottom{border-bottom:none;border-top:1px solid #aeaeae;border-radius:0 0 .3rem .3rem}.react-datepicker__header-wrapper{position:relative}.react-datepicker__header-wrapper .react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button){right:2px}.react-datepicker__year-dropdown-container--select,.react-datepicker__month-dropdown-container--select,.react-datepicker__month-year-dropdown-container--select,.react-datepicker__year-dropdown-container--scroll,.react-datepicker__month-dropdown-container--scroll,.react-datepicker__month-year-dropdown-container--scroll{display:inline-block;margin:0 15px}.react-datepicker__month-select,.react-datepicker__year-select,.react-datepicker__month-year-select{background-color:transparent;border:1px solid #aeaeae;border-radius:.3rem;color:inherit;cursor:pointer;font-family:inherit;font-size:inherit;margin-top:5px;padding:2px 5px}.react-datepicker__month-select:focus-visible,.react-datepicker__year-select:focus-visible,.react-datepicker__month-year-select:focus-visible{outline:auto 1px}.react-datepicker__current-month,.react-datepicker-time__header,.react-datepicker-year-header{margin-top:0;color:#000;font-weight:700;font-size:.944rem}h2.react-datepicker__current-month{padding:0;margin:0}.react-datepicker-time__header{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.react-datepicker__navigation{align-items:center;background:none;display:flex;justify-content:center;text-align:center;cursor:pointer;position:absolute;top:2px;padding:0;border:none;z-index:1;height:32px;width:32px;text-indent:-999em;overflow:hidden}.react-datepicker__navigation--previous{left:2px}.react-datepicker__navigation--next{right:2px}.react-datepicker__navigation--next--with-time:not(.react-datepicker__navigation--next--with-today-button){right:85px}.react-datepicker__navigation--years{position:relative;top:0;display:block;margin-left:auto;margin-right:auto}.react-datepicker__navigation--years-previous{top:4px}.react-datepicker__navigation--years-upcoming{top:-4px}.react-datepicker__navigation:hover *:before{border-color:#a6a6a6}.react-datepicker__navigation-icon{position:relative;top:-1px;font-size:20px;width:0}.react-datepicker__navigation-icon--next{left:-2px}.react-datepicker__navigation-icon--next:before{transform:rotate(45deg);left:-7px}.react-datepicker__navigation-icon--previous{right:-2px}.react-datepicker__navigation-icon--previous:before{transform:rotate(225deg);right:-7px}.react-datepicker__month-container{float:left}.react-datepicker__year{margin:.5em;text-align:center}.react-datepicker__year-wrapper{display:flex;flex-wrap:wrap;max-width:180px}.react-datepicker__year .react-datepicker__year-text{display:inline-block;width:5em;margin:2px}.react-datepicker__month{margin:.5em;text-align:center}.react-datepicker__month .react-datepicker__month-text,.react-datepicker__month .react-datepicker__quarter-text{display:inline-block;width:5em;margin:2px}.react-datepicker__input-time-container{clear:both;width:100%;float:left;margin:5px 0 10px 15px;text-align:left}.react-datepicker__input-time-container .react-datepicker-time__caption,.react-datepicker__input-time-container .react-datepicker-time__input-container{display:inline-block}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input{display:inline-block;margin-left:10px}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input{width:auto}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]::-webkit-inner-spin-button,.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__input input[type=time]{-moz-appearance:textfield}.react-datepicker__input-time-container .react-datepicker-time__input-container .react-datepicker-time__delimiter{margin-left:5px;display:inline-block}.react-datepicker__time-container{float:right;border-left:1px solid #aeaeae;width:85px}.react-datepicker__time-container--with-today-button{display:inline;border:1px solid #aeaeae;border-radius:.375em;position:absolute;right:-87px;top:0}.react-datepicker__time-container .react-datepicker__time{position:relative;background:#fff;border-bottom-right-radius:.375em}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box{width:85px;overflow-x:hidden;margin:0 auto;text-align:center;border-bottom-right-radius:.375em}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list{list-style:none;margin:0;height:calc(195px + 1.0625em);overflow-y:scroll;padding-right:0;padding-left:0;width:100%;box-sizing:content-box}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item{height:30px;padding:5px 10px;white-space:nowrap}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item:hover{cursor:pointer;background-color:#f0f0f0}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected{background-color:#216ba5;color:#fff;font-weight:700}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--selected:hover{background-color:#216ba5}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--disabled{color:#ccc}.react-datepicker__time-container .react-datepicker__time .react-datepicker__time-box ul.react-datepicker__time-list li.react-datepicker__time-list-item--disabled:hover{cursor:default;background-color:transparent}.react-datepicker__week-number{color:#ccc;display:inline-block;width:2.125em;line-height:2.125em;text-align:center;margin:.208em}.react-datepicker__week-number.react-datepicker__week-number--clickable{cursor:pointer}.react-datepicker__week-number.react-datepicker__week-number--clickable:not(.react-datepicker__week-number--selected):hover{border-radius:.3rem;background-color:#f0f0f0}.react-datepicker__week-number--selected{border-radius:.3rem;background-color:#216ba5;color:#fff}.react-datepicker__week-number--selected:hover{background-color:#1d5d90}.react-datepicker__day-names{text-align:center;white-space:nowrap;margin-bottom:-8px}.react-datepicker__week{white-space:nowrap}.react-datepicker__day-name,.react-datepicker__day,.react-datepicker__time-name{color:#000;display:inline-block;width:2.125em;line-height:2.125em;text-align:center;margin:.208em}.react-datepicker__day-name--disabled,.react-datepicker__day--disabled,.react-datepicker__time-name--disabled{cursor:default;color:#ccc}.react-datepicker__day,.react-datepicker__month-text,.react-datepicker__quarter-text,.react-datepicker__year-text{cursor:pointer}.react-datepicker__day:not([aria-disabled=true]):hover,.react-datepicker__month-text:not([aria-disabled=true]):hover,.react-datepicker__quarter-text:not([aria-disabled=true]):hover,.react-datepicker__year-text:not([aria-disabled=true]):hover{border-radius:.3rem;background-color:#f0f0f0}.react-datepicker__day--today,.react-datepicker__month-text--today,.react-datepicker__quarter-text--today,.react-datepicker__year-text--today{font-weight:700}.react-datepicker__day--highlighted,.react-datepicker__month-text--highlighted,.react-datepicker__quarter-text--highlighted,.react-datepicker__year-text--highlighted{border-radius:.3rem;background-color:#3dcc4a;color:#fff}.react-datepicker__day--highlighted:not([aria-disabled=true]):hover,.react-datepicker__month-text--highlighted:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--highlighted:not([aria-disabled=true]):hover,.react-datepicker__year-text--highlighted:not([aria-disabled=true]):hover{background-color:#32be3f}.react-datepicker__day--highlighted-custom-1,.react-datepicker__month-text--highlighted-custom-1,.react-datepicker__quarter-text--highlighted-custom-1,.react-datepicker__year-text--highlighted-custom-1{color:#f0f}.react-datepicker__day--highlighted-custom-2,.react-datepicker__month-text--highlighted-custom-2,.react-datepicker__quarter-text--highlighted-custom-2,.react-datepicker__year-text--highlighted-custom-2{color:green}.react-datepicker__day--holidays,.react-datepicker__month-text--holidays,.react-datepicker__quarter-text--holidays,.react-datepicker__year-text--holidays{position:relative;border-radius:.3rem;background-color:#ff6803;color:#fff}.react-datepicker__day--holidays .overlay,.react-datepicker__month-text--holidays .overlay,.react-datepicker__quarter-text--holidays .overlay,.react-datepicker__year-text--holidays .overlay{position:absolute;bottom:100%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px;border-radius:4px;white-space:nowrap;visibility:hidden;opacity:0;transition:visibility 0s,opacity .3s ease-in-out}.react-datepicker__day--holidays:not([aria-disabled=true]):hover,.react-datepicker__month-text--holidays:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--holidays:not([aria-disabled=true]):hover,.react-datepicker__year-text--holidays:not([aria-disabled=true]):hover{background-color:#cf5300}.react-datepicker__day--holidays:hover .overlay,.react-datepicker__month-text--holidays:hover .overlay,.react-datepicker__quarter-text--holidays:hover .overlay,.react-datepicker__year-text--holidays:hover .overlay{visibility:visible;opacity:1}.react-datepicker__day--selected,.react-datepicker__day--in-selecting-range,.react-datepicker__day--in-range,.react-datepicker__month-text--selected,.react-datepicker__month-text--in-selecting-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--selected,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--selected,.react-datepicker__year-text--in-selecting-range,.react-datepicker__year-text--in-range{border-radius:.3rem;background-color:#216ba5;color:#fff}.react-datepicker__day--selected:not([aria-disabled=true]):hover,.react-datepicker__day--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__day--in-range:not([aria-disabled=true]):hover,.react-datepicker__month-text--selected:not([aria-disabled=true]):hover,.react-datepicker__month-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__month-text--in-range:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--selected:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--in-range:not([aria-disabled=true]):hover,.react-datepicker__year-text--selected:not([aria-disabled=true]):hover,.react-datepicker__year-text--in-selecting-range:not([aria-disabled=true]):hover,.react-datepicker__year-text--in-range:not([aria-disabled=true]):hover{background-color:#1d5d90}.react-datepicker__day--keyboard-selected,.react-datepicker__month-text--keyboard-selected,.react-datepicker__quarter-text--keyboard-selected,.react-datepicker__year-text--keyboard-selected{border-radius:.3rem;background-color:#bad9f1;color:#000}.react-datepicker__day--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__month-text--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__quarter-text--keyboard-selected:not([aria-disabled=true]):hover,.react-datepicker__year-text--keyboard-selected:not([aria-disabled=true]):hover{background-color:#1d5d90;color:#fff}.react-datepicker__day--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__month-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__quarter-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range),.react-datepicker__year-text--in-selecting-range:not(.react-datepicker__day--in-range,.react-datepicker__month-text--in-range,.react-datepicker__quarter-text--in-range,.react-datepicker__year-text--in-range){background-color:#216ba580}.react-datepicker__month--selecting-range .react-datepicker__day--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__day--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__month-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__month-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__quarter-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__quarter-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__month--selecting-range .react-datepicker__year-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range),.react-datepicker__year--selecting-range .react-datepicker__year-text--in-range:not(.react-datepicker__day--in-selecting-range,.react-datepicker__month-text--in-selecting-range,.react-datepicker__quarter-text--in-selecting-range,.react-datepicker__year-text--in-selecting-range){background-color:#f0f0f0;color:#000}.react-datepicker__day--disabled,.react-datepicker__month-text--disabled,.react-datepicker__quarter-text--disabled,.react-datepicker__year-text--disabled{cursor:default;color:#ccc}.react-datepicker__day--disabled .overlay,.react-datepicker__month-text--disabled .overlay,.react-datepicker__quarter-text--disabled .overlay,.react-datepicker__year-text--disabled .overlay{position:absolute;bottom:70%;left:50%;transform:translate(-50%);background-color:#333;color:#fff;padding:4px;border-radius:4px;white-space:nowrap;visibility:hidden;opacity:0;transition:visibility 0s,opacity .3s ease-in-out}.react-datepicker__input-container{position:relative;display:inline-block;width:100%}.react-datepicker__input-container .react-datepicker__calendar-icon{position:absolute;padding:.625em;box-sizing:content-box}.react-datepicker__view-calendar-icon input{padding:6px 10px 5px 25px}.react-datepicker__year-read-view,.react-datepicker__month-read-view,.react-datepicker__month-year-read-view{border:1px solid transparent;border-radius:.3rem;position:relative}.react-datepicker__year-read-view:hover,.react-datepicker__month-read-view:hover,.react-datepicker__month-year-read-view:hover{cursor:pointer}.react-datepicker__year-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__year-read-view:hover .react-datepicker__month-read-view--down-arrow,.react-datepicker__month-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view:hover .react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view:hover .react-datepicker__year-read-view--down-arrow,.react-datepicker__month-year-read-view:hover .react-datepicker__month-read-view--down-arrow{border-top-color:#b3b3b3}.react-datepicker__year-read-view--down-arrow,.react-datepicker__month-read-view--down-arrow,.react-datepicker__month-year-read-view--down-arrow{transform:rotate(135deg);right:-16px;top:0}.react-datepicker__year-dropdown,.react-datepicker__month-dropdown,.react-datepicker__month-year-dropdown{background-color:#f0f0f0;position:absolute;width:50%;left:25%;top:30px;z-index:1;text-align:center;border-radius:.3rem;border:1px solid #aeaeae}.react-datepicker__year-dropdown:hover,.react-datepicker__month-dropdown:hover,.react-datepicker__month-year-dropdown:hover{cursor:pointer}.react-datepicker__year-dropdown--scrollable,.react-datepicker__month-dropdown--scrollable,.react-datepicker__month-year-dropdown--scrollable{height:150px;overflow-y:scroll}.react-datepicker__year-option,.react-datepicker__month-option,.react-datepicker__month-year-option{line-height:20px;width:100%;display:block;margin-left:auto;margin-right:auto}.react-datepicker__year-option:first-of-type,.react-datepicker__month-option:first-of-type,.react-datepicker__month-year-option:first-of-type{border-top-left-radius:.3rem;border-top-right-radius:.3rem}.react-datepicker__year-option:last-of-type,.react-datepicker__month-option:last-of-type,.react-datepicker__month-year-option:last-of-type{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-bottom-left-radius:.3rem;border-bottom-right-radius:.3rem}.react-datepicker__year-option:hover,.react-datepicker__month-option:hover,.react-datepicker__month-year-option:hover{background-color:#ccc}.react-datepicker__year-option:hover .react-datepicker__navigation--years-upcoming,.react-datepicker__month-option:hover .react-datepicker__navigation--years-upcoming,.react-datepicker__month-year-option:hover .react-datepicker__navigation--years-upcoming{border-bottom-color:#b3b3b3}.react-datepicker__year-option:hover .react-datepicker__navigation--years-previous,.react-datepicker__month-option:hover .react-datepicker__navigation--years-previous,.react-datepicker__month-year-option:hover .react-datepicker__navigation--years-previous{border-top-color:#b3b3b3}.react-datepicker__year-option--selected,.react-datepicker__month-option--selected,.react-datepicker__month-year-option--selected{position:absolute;left:15px}.react-datepicker__close-icon{cursor:pointer;background-color:transparent;border:0;outline:0;padding:0 6px 0 0;position:absolute;top:0;right:0;height:100%;display:table-cell;vertical-align:middle}.react-datepicker__close-icon:after{cursor:pointer;background-color:#216ba5;color:#fff;border-radius:50%;height:16px;width:16px;padding:2px;font-size:12px;line-height:1;text-align:center;display:table-cell;vertical-align:middle;content:"×"}.react-datepicker__close-icon--disabled{cursor:default}.react-datepicker__close-icon--disabled:after{cursor:default;background-color:#ccc}.react-datepicker__today-button{background:#f0f0f0;border-top:1px solid #aeaeae;cursor:pointer;text-align:center;font-weight:700;padding:5px 0;clear:left}.react-datepicker__portal{position:fixed;width:100vw;height:100vh;background-color:#000c;left:0;top:0;justify-content:center;align-items:center;display:flex;z-index:2147483647}.react-datepicker__children-container{width:17.25em;margin:.5em;padding-right:.25em;padding-left:.25em;height:auto}.react-datepicker__aria-live{position:absolute;clip-path:circle(0);border:0;height:1px;margin:-1px;overflow:hidden;padding:0;width:1px;white-space:nowrap}.react-datepicker__calendar-icon{width:1em;height:1em;vertical-align:-.125em}.react-datepicker-popper-offset{margin-top:-.7em}:where(.preview-tab,.widget,.palette-selector,.ddp-field){--spacing-xs: 4px;--spacing-sm: 8px;--spacing-md: 16px;--spacing-lg: 24px;--spacing-xl: 32px;--spacing-2xl: 48px;--radius-sm: 4px;--radius-md: 8px;--radius-lg: 12px;--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--transition-fast: .15s ease;--shadow-lg: 0 10px 25px rgba(0, 0, 0, .4)}.preview-tab{display:flex;flex-direction:column;gap:var(--spacing-md);position:relative}.preview-tab__empty{display:flex;align-items:center;justify-content:center;min-height:300px;color:var(--text-muted);font-size:.9rem;border:2px dashed var(--bg-elevated);border-radius:var(--radius-lg)}.preview-tab__loading{display:flex;align-items:center;justify-content:center;padding:var(--spacing-2xl) 0;color:var(--text-secondary)}.preview-tab__error{padding:var(--spacing-md);background:#f443361a;border:1px solid var(--color-error);border-radius:var(--radius-md);color:var(--color-error);font-size:.875rem;text-align:center}.preview-tab__grid{display:grid;grid-template-columns:repeat(var(--dash-cols, 30),1fr);grid-template-rows:repeat(var(--dash-rows, 10),var(--dash-cell-h, 40px));grid-auto-rows:var(--dash-cell-h, 40px);gap:var(--dash-gap, 6px);padding:var(--dash-pad, 16px);background:var(--bg-dark);border-radius:var(--radius-lg)}.preview-tab__grid--stacked{grid-template-columns:1fr;grid-template-rows:none;grid-auto-rows:auto}.preview-tab__widget{display:flex;background:var(--bg-elevated);border:1px solid rgba(255,255,255,.08);border-radius:var(--radius-md);overflow:hidden;min-height:0;container-type:size}.preview-tab__widget--control{background:var(--bg-elevated);border:1px dashed rgba(255,255,255,.15)}.preview-tab__widget-loading{display:flex;align-items:center;justify-content:center;height:100%;min-height:80px;color:var(--text-muted);font-size:.8125rem}.preview-tab__recalculating{position:fixed;bottom:var(--spacing-lg);right:var(--spacing-lg);padding:var(--spacing-sm) var(--spacing-lg);background:var(--bg-elevated);border:1px solid var(--action-orange);border-radius:var(--radius-md);color:var(--action-orange);font-size:.8125rem;font-weight:var(--font-weight-medium);box-shadow:var(--shadow-lg);z-index:50}.palette-selector{display:flex;flex-direction:column;gap:var(--spacing-sm)}.palette-selector--disabled{opacity:.5;pointer-events:none}.palette-selector__options{display:flex;flex-direction:column;gap:var(--spacing-xs)}.palette-selector__option{display:flex;flex-direction:column;gap:var(--spacing-xs);padding:var(--spacing-xs);background:transparent;border:1.5px solid var(--bg-elevated);border-radius:var(--radius-sm);cursor:pointer;transition:border-color var(--transition-fast)}.palette-selector__option:hover:not(:disabled){border-color:var(--text-muted)}.palette-selector__option--active{border-color:var(--action-orange)}.palette-selector__bar{display:flex;width:100%;height:18px;border-radius:3px;overflow:hidden}.palette-selector__bar--theme{height:12px;opacity:.85}.palette-selector__swatch{flex:1;min-width:0}.palette-selector__label{font-size:.7rem;color:var(--text-muted);text-align:left}.palette-selector__custom{display:flex;flex-direction:column;gap:6px}.palette-selector__row{display:flex;flex-direction:column;gap:4px}.palette-selector__row-label{font-size:.6rem;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;font-weight:var(--font-weight-semibold)}.palette-selector__row-slots{display:flex;gap:4px;flex-wrap:wrap}.palette-selector__color-input{width:24px;height:24px;padding:0;border:1.5px solid rgba(255,255,255,.25);border-radius:var(--radius-sm);background:transparent;cursor:pointer;transition:border-color var(--transition-fast);flex-shrink:0}.palette-selector__color-input:hover:not(:disabled){border-color:#ffffff80}.palette-selector__color-input:hover:not(:disabled){border-color:var(--action-orange)}.palette-selector__color-input::-webkit-color-swatch-wrapper{padding:2px}.palette-selector__color-input::-webkit-color-swatch{border:none;border-radius:2px}.ddp-field{width:100%;min-width:0;display:block}.ddp-field .react-datepicker-wrapper,.ddp-field .react-datepicker__input-container{width:100%;display:block}.ddp-field .react-datepicker__input-container input{width:100%;padding:var(--spacing-sm) var(--spacing-md);background:var(--bg-elevated);border:1.5px solid var(--bg-elevated);border-radius:var(--radius-sm);font-size:.8125rem;color:var(--text-primary);box-sizing:border-box;transition:border-color var(--transition-fast)}.ddp-field .react-datepicker__input-container input:focus{outline:none;border-color:var(--action-orange)}.ddp-field .react-datepicker__input-container input::placeholder{color:var(--text-muted)}.ddp-field .react-datepicker__input-container input:disabled{opacity:.6;cursor:not-allowed}.ddp-field .react-datepicker__month{min-height:168px}.react-datepicker-popper{z-index:1100!important}.widget{flex:1;display:flex;flex-direction:column;padding:var(--spacing-sm);background:var(--bg-elevated);border-radius:var(--radius-md);overflow:hidden;box-sizing:border-box;min-height:0;min-width:0}.widget__title{flex-shrink:0;margin:0 0 clamp(2px,1cqmin,8px);font-size:clamp(.5rem,4cqi,.9rem);font-weight:var(--font-weight-semibold);color:var(--text-secondary);line-height:1.2;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.widget__state{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;padding:var(--spacing-xs);font-size:clamp(.45rem,2.5cqi,.85rem);color:var(--text-muted)}.widget__state--error{color:var(--color-error)}.widget-filter,.widget-palette{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:clamp(4px,1.5cqi,12px);padding:clamp(4px,1cqi,8px) clamp(6px,1.5cqi,12px);box-sizing:border-box;min-height:0;min-width:0;overflow:hidden}.widget-variable{flex:1;display:flex;flex-direction:column;justify-content:center;align-items:center;box-sizing:border-box;min-height:0;min-width:0;overflow:hidden}.widget-filter__label,.widget-palette__label,.widget-variable__label{flex-shrink:0;font-size:clamp(.45rem,6cqi,3rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-kpi{justify-content:center;align-items:center;text-align:center;gap:clamp(2px,1cqmin,10px);padding:clamp(4px,2cqmin,16px)}.widget-kpi .widget__title{margin:0;font-size:clamp(.45rem,min(12cqi,12cqb),6rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-kpi__value{font-size:clamp(.85rem,min(22cqi,22cqb),8rem);font-weight:var(--font-weight-bold);color:var(--text-primary);line-height:1.1;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.widget-kpi__trend{display:flex;align-items:center;justify-content:center;gap:.35em .7em;font-size:clamp(.4rem,min(8cqi,8cqb),2rem);max-width:100%;overflow:hidden;flex-wrap:wrap}.widget-kpi__trend--good{color:var(--color-success)}.widget-kpi__trend--bad{color:var(--color-error)}.widget-kpi__trend--muted{opacity:.75;font-size:.9em}.widget-kpi__variance{font-weight:var(--font-weight-semibold);white-space:nowrap}.widget-kpi__trend-label{color:var(--text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@container (max-width: 180px){.widget-kpi__trend-label{display:none}}@container (max-height: 70px){.widget-kpi .widget__title{display:none}}.widget-gauge{align-items:center;gap:0;overflow:hidden}.widget-gauge .widget__title{margin:0;font-size:clamp(.5rem,6cqi,3rem);color:var(--text-muted);font-weight:var(--font-weight-medium)}.widget-gauge__chart{position:relative;width:100%;flex:1;min-height:0}.widget-gauge__chart svg{margin-top:5%;display:block;width:100%;height:100%}.widget-gauge__center{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;margin-top:25%}.widget-gauge__percent{font-size:clamp(.5rem,9cqi,4rem);font-weight:var(--font-weight-bold);color:var(--text-primary);line-height:1}.widget-gauge__comparison{font-size:clamp(.4rem,3.5cqi,2rem);color:var(--text-muted)}.widget-gauge__badge{font-size:clamp(.35rem,3cqi,1.25rem);font-weight:var(--font-weight-semibold);text-transform:uppercase;letter-spacing:.3px;padding:1px var(--spacing-xs);border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-success) 15%,transparent);color:var(--color-success)}.widget-chart{gap:var(--spacing-xs)}.widget-chart .widget__title{color:var(--text-primary)}.widget-chart__container{flex:1;min-height:0;overflow:hidden}.widget-composition{gap:var(--spacing-xs)}.widget-composition .widget__title{color:var(--text-primary)}.widget-composition__container{flex:1;min-height:0;overflow:hidden}.widget-composition__tooltip{display:flex;flex-direction:column;gap:2px;padding:6px 10px;border:1px solid var(--bg-paper);border-radius:6px;background-color:var(--bg-elevated);font-size:.75rem;line-height:1.3}.widget-composition__tooltip-label{color:var(--text-primary);font-weight:var(--font-weight-semibold)}.widget-composition__tooltip-value{color:var(--text-secondary)}.widget-table{display:flex;flex-direction:column;gap:.4rem;height:100%;overflow:hidden;padding:.5rem .6rem;box-sizing:border-box}.widget-table__td--placeholder{color:var(--text-muted, #999);text-align:center;padding:.75rem .5rem}.widget-table__scroll{flex:1 1 auto;min-height:0;overflow:auto}.widget-table__scroll--clip{overflow:hidden}.widget-table__table{width:100%;border-collapse:collapse;font-size:clamp(.78rem,1.5cqmin,1.25rem)}.widget-table__table--fill{height:100%}.widget-table__th--index,.widget-table__td--index{width:1%;text-align:right;color:var(--text-muted, #999);font-variant-numeric:tabular-nums;white-space:nowrap}.widget-table__th{position:sticky;top:0;z-index:1;text-align:left;font-weight:600;color:var(--text-secondary, #ccc);background:var(--bg-elevated, #333);padding:.35rem .5rem;border-bottom:1px solid var(--border, rgba(255, 255, 255, .12));white-space:nowrap}.widget-table__th--num{text-align:right}.widget-table__td{padding:.3rem .5rem;color:var(--text-primary, #f5f5f5);border-bottom:1px solid var(--border, rgba(255, 255, 255, .06));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:26ch}.widget-table__td--num{text-align:right;font-variant-numeric:tabular-nums}.widget-table__td--up{color:var(--color-success, #a4c639);font-weight:600}.widget-table__td--down{color:var(--color-error, #e5534b);font-weight:600}.widget-table__table tbody tr:hover{background:#ffffff08}.widget-filter__date-range{display:flex;align-items:center;gap:clamp(2px,1cqi,8px);flex:1;min-width:0}.widget-filter__date-range--stacked{flex-direction:column;align-items:stretch;gap:clamp(4px,1.5cqmin,10px);width:100%;padding:clamp(2px,1cqmin,8px) 0}.widget-filter__date-range .ddp-field{flex:1;min-width:0;width:100%}.widget-filter__date-range .ddp-field .react-datepicker__input-container input,.widget-filter__select{padding:clamp(8px,4cqmin,22px) clamp(6px,1.5cqmin,12px);font-size:clamp(.5rem,10cqmin,2rem);background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);color:var(--text-primary);flex:1;min-width:0;width:100%;box-sizing:border-box;text-align:center;font-variant-numeric:tabular-nums}.widget-filter__date-sep{font-size:clamp(.35rem,2.5cqi,.8rem);color:var(--text-muted)}.widget-filter__multi{display:flex;flex-direction:column;align-items:stretch;justify-content:space-around;gap:clamp(4px,1.5cqmin,14px);flex:1;min-height:0;width:100%;padding:clamp(6px,2cqmin,14px) clamp(4px,2cqmin,12px);box-sizing:border-box;overflow-y:auto}.widget-filter__multi::-webkit-scrollbar{width:6px}.widget-filter__multi::-webkit-scrollbar-track{background:transparent}.widget-filter__multi::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}.widget-filter__multi::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.widget-filter__multi-clear{flex-shrink:0;width:100%;padding:clamp(3px,1cqmin,8px) clamp(8px,2.5cqmin,14px);background:transparent;border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);color:var(--action-orange);font-size:clamp(.4rem,7cqmin,1rem);font-weight:var(--font-weight-semibold);text-align:center;cursor:pointer;transition:background-color var(--transition-fast),border-color var(--transition-fast)}.widget-filter__multi-clear:hover{background-color:var(--bg-elevated);border-color:var(--action-orange)}.widget-filter__multi-option{display:flex;align-items:center;gap:clamp(6px,4cqmin,14px);padding:clamp(4px,1.5cqmin,12px) clamp(8px,2.5cqmin,14px);height:clamp(20px,18cqb,120px);background:var(--bg-paper);border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);cursor:pointer;transition:border-color var(--transition-fast),background-color var(--transition-fast);font-size:clamp(.45rem,8cqmin,1.2rem);font-weight:var(--font-weight-medium);color:var(--text-primary);line-height:1;flex-shrink:0;box-sizing:border-box}.widget-filter__multi-option:hover{border-color:var(--text-muted);background-color:var(--bg-elevated)}.widget-filter__multi-option:has(input[type=checkbox]:checked){border-color:var(--text-muted);background-color:var(--bg-elevated)}.widget-filter__multi-option input[type=checkbox]{appearance:none;-webkit-appearance:none;-moz-appearance:none;width:clamp(12px,7cqmin,22px);height:clamp(12px,7cqmin,22px);border:1.5px solid var(--text-muted);border-radius:3px;background:var(--bg-elevated);cursor:pointer;position:relative;flex-shrink:0;transition:border-color var(--transition-fast),background-color var(--transition-fast);margin:0}.widget-filter__multi-option input[type=checkbox]:hover{border-color:var(--action-orange)}.widget-filter__multi-option input[type=checkbox]:checked{background:var(--action-orange);border-color:var(--action-orange)}.widget-filter__multi-option input[type=checkbox]:checked:after{content:"";position:absolute;left:30%;top:8%;width:30%;height:60%;border:solid var(--bg-dark);border-width:0 2px 2px 0;transform:rotate(45deg)}.widget-filter__select{width:95%;max-height:45%;margin-top:2%;flex:1;font-size:clamp(.4rem,5cqi,1.5rem);font-weight:var(--font-weight-semibold);color:var(--text-primary);text-align:left;padding:clamp(8px,4cqi,22px) clamp(6px,1.5cqi,12px);min-width:0;box-sizing:border-box}.widget-filter>.widget-filter__select,.widget-filter__date-range--year .widget-filter__select,.widget-filter__date-range--month .widget-filter__select,.widget-filter__date-range--week .widget-filter__select{text-align:center;text-align-last:center;font-weight:var(--font-weight-semibold);color:var(--text-primary);background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none;background-image:none;transition:border-color var(--transition-fast),background-color var(--transition-fast);box-sizing:border-box;width:100%;margin-top:0;max-height:none;padding:clamp(2px,.8cqmin,6px) clamp(6px,1.5cqmin,12px);line-height:1}.widget-filter>.widget-filter__select:hover,.widget-filter>.widget-filter__select:focus,.widget-filter__date-range--year .widget-filter__select:hover,.widget-filter__date-range--year .widget-filter__select:focus,.widget-filter__date-range--month .widget-filter__select:hover,.widget-filter__date-range--month .widget-filter__select:focus,.widget-filter__date-range--week .widget-filter__select:hover,.widget-filter__date-range--week .widget-filter__select:focus{outline:none;border-color:var(--action-orange);background-color:var(--bg-elevated)}.widget-filter>.widget-filter__select option,.widget-filter__date-range--year .widget-filter__select option,.widget-filter__date-range--month .widget-filter__select option,.widget-filter__date-range--week .widget-filter__select option{background:var(--bg-paper);color:var(--text-primary);font-size:.875rem;font-weight:var(--font-weight-normal);text-align:left;padding:6px 10px}.widget-filter>.widget-filter__select{flex:0 1 auto;height:clamp(50px,22cqmin,140px);max-height:75%;margin-block:auto;align-self:center;font-size:clamp(.6rem,12cqmin,2.2rem)}.widget-filter__date-range--year,.widget-filter__date-range--month,.widget-filter__date-range--week{display:flex;flex-direction:column;align-items:stretch;justify-content:center;gap:clamp(6px,2.5cqmin,16px);flex:1;width:100%;padding:clamp(6px,2cqmin,16px) clamp(4px,2cqmin,14px);box-sizing:border-box}.widget-filter__date-range--year .widget-filter__select{flex:0 1 auto;height:clamp(50px,22cqmin,140px);font-size:clamp(.6rem,12cqmin,2.2rem)}.widget-filter__date-range--month .widget-filter__select{flex:0 1 auto;height:clamp(30px,10cqmin,66px);font-size:clamp(.5rem,10cqmin,1.4rem)}.widget-filter__date-range--week .widget-filter__select{flex:0 1 auto;height:clamp(22px,12cqmin,48px);font-size:clamp(.45rem,8cqmin,3rem)}.widget-filter__search{position:relative;display:flex;align-items:center;flex:1;min-width:0;width:100%;padding:clamp(2px,1cqmin,8px) 0}.widget-filter .widget-filter__search-field{width:100%;padding:clamp(6px,3cqmin,18px) clamp(8px,2cqmin,14px);background:var(--bg-dark);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);color:var(--text-primary);font-size:clamp(.55rem,10cqmin,1.8rem);font-weight:var(--font-weight-semibold);text-align:center;box-sizing:border-box;cursor:text;transition:border-color var(--transition-fast),background-color var(--transition-fast)}.widget-filter .widget-filter__search-field::placeholder{color:var(--text-muted);font-weight:var(--font-weight-normal)}.widget-filter .widget-filter__search-field:hover,.widget-filter .widget-filter__search-field:focus{outline:none;border-color:var(--action-orange);background-color:var(--bg-paper)}.widget-filter__search-panel{z-index:10000;display:flex;flex-direction:column;background:var(--bg-paper);border:1px solid var(--bg-elevated);border-radius:var(--radius-sm);box-shadow:var(--shadow-md, 0 8px 28px rgba(0, 0, 0, .45));overflow:hidden}.widget-filter__search-list{display:flex;flex-direction:column;gap:2px;padding:6px;overflow-y:auto}.widget-filter__search-option{display:flex;align-items:center;gap:8px;width:100%;padding:8px 10px;background:transparent;border:none;border-left:3px solid transparent;border-radius:var(--radius-sm);color:var(--text-primary);font-size:.85rem;font-weight:var(--font-weight-medium);text-align:left;cursor:pointer;transition:background-color var(--transition-fast),color var(--transition-fast)}.widget-filter__search-option:hover{background-color:var(--bg-elevated)}.widget-filter__search-option.is-selected{background-color:var(--bg-elevated);border-left-color:var(--action-orange);color:var(--action-orange)}.widget-filter__search-check{flex-shrink:0;width:1em;color:var(--action-orange);font-weight:var(--font-weight-semibold)}.widget-filter__search-option input[type=checkbox]{width:16px;height:16px;flex-shrink:0;accent-color:var(--action-orange);cursor:pointer}.widget-filter__search-clear{width:100%;margin-bottom:4px;padding:8px 10px;background:transparent;border:none;border-bottom:1px solid var(--bg-elevated);border-radius:0;color:var(--action-orange);font-size:.8rem;font-weight:var(--font-weight-semibold);text-align:left;cursor:pointer;transition:background-color var(--transition-fast)}.widget-filter__search-clear:hover{background-color:var(--bg-elevated)}.widget-filter__search-empty{padding:12px;color:var(--text-muted);font-size:.85rem;text-align:center}.widget-filter__search-list::-webkit-scrollbar{width:6px}.widget-filter__search-list::-webkit-scrollbar-track{background:transparent}.widget-filter__search-list::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}.widget-filter__search-list::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}.widget-variable__input-wrapper{display:flex;align-items:center;margin-top:2%;width:90%;background:var(--bg-paper);border:1px solid rgba(255,255,255,.1);border-radius:var(--radius-sm);overflow:hidden}.widget-variable__input{flex:1;font-size:clamp(.4rem,5cqi,1.5rem);font-weight:var(--font-weight-semibold);background:transparent;border:none;outline:none;color:var(--text-primary);text-align:left;padding:clamp(2px,1cqi,6px) clamp(4px,1.5cqi,8px);min-width:0;box-sizing:border-box}.widget-variable__input::-webkit-outer-spin-button,.widget-variable__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.widget-variable__input[type=number]{-moz-appearance:textfield;-webkit-appearance:textfield;appearance:textfield}.widget-variable__input:disabled{opacity:.6;cursor:not-allowed}.widget-variable__suffix{font-size:clamp(.4rem,4cqi,1.25rem);color:var(--text-muted);white-space:nowrap;padding:0 clamp(4px,1.5cqi,8px);border-left:1px solid rgba(255,255,255,.1);flex-shrink:0}.widget-variable__lock-icon{font-size:clamp(.45rem,2.5cqi,.75rem)}.widget-variable--locked .widget-variable__input-wrapper{border-style:dashed}.widget-palette{flex-direction:column;justify-content:flex-start;align-items:stretch;padding:clamp(4px,1.5cqmin,12px);gap:clamp(2px,1cqmin,8px);overflow:auto}.widget-palette__label{text-align:center;flex-shrink:0}.widget-palette__lock-icon{font-size:clamp(.45rem,2.5cqmin,.75rem);align-self:center}.widget-palette--locked .palette-selector__color-input{opacity:.6;cursor:not-allowed}.widget-palette .palette-selector{gap:clamp(2px,3cqmin,28px);flex:1;min-height:0;justify-content:center}.widget-palette .palette-selector__row{gap:clamp(1px,1.2cqmin,10px);min-height:0}.widget-palette .palette-selector__row-label{font-size:clamp(.35rem,1.8cqmin,.7rem);line-height:1}.widget-palette .palette-selector__row-slots{gap:clamp(1px,.8cqmin,6px);flex-wrap:nowrap;justify-content:space-between;width:100%;min-height:0}.widget-palette .palette-selector__color-input{flex:1 1 0;min-width:0;min-height:0;width:auto;height:clamp(8px,10cqmin,60px);border:1px solid rgba(255,255,255,.2);padding:0}.widget-palette .palette-selector__color-input:hover:not(:disabled){border-color:#fff6}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -188,21 +188,51 @@ export interface CompositionConfig extends WidgetFilterTargeting {
|
|
|
188
188
|
totalLabel?: string;
|
|
189
189
|
filterExpression?: WidgetFilter;
|
|
190
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Coluna de tabela: a fonte da célula, antes de qualquer agregação.
|
|
193
|
+
*
|
|
194
|
+
* A agregação não vive aqui: cada nível declara o modo de cada coluna, porque a
|
|
195
|
+
* mesma coluna pode somar num nível e ser mediada no seguinte.
|
|
196
|
+
*/
|
|
191
197
|
export interface TableColumnConfig {
|
|
192
|
-
|
|
198
|
+
id: string;
|
|
199
|
+
column?: string;
|
|
200
|
+
kpiTerms?: KpiTerm[];
|
|
193
201
|
label?: string;
|
|
194
202
|
format?: FormatType;
|
|
195
203
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
204
|
+
/**
|
|
205
|
+
* Um nível de agregação: por quais colunas agrupa e como cada coluna colapsa.
|
|
206
|
+
*
|
|
207
|
+
* Os níveis se encadeiam na ordem declarada — o primeiro colapsa os registros, o
|
|
208
|
+
* seguinte re-agrega o resultado do anterior. É o que separa "soma por dia" de
|
|
209
|
+
* "média das somas por dia".
|
|
210
|
+
*/
|
|
211
|
+
export interface TableAggregationLevel {
|
|
212
|
+
groupBy?: string[];
|
|
213
|
+
/** Modo por id de coluna — a coluna pode ser uma fórmula, sem nome no dataset. */
|
|
214
|
+
modes?: Record<string, AggregationType>;
|
|
215
|
+
}
|
|
216
|
+
/** Um nível de ordenamento: cita uma coluna da tabela ou uma do dataset. */
|
|
217
|
+
export interface TableSortLevel {
|
|
218
|
+
columnId?: string;
|
|
219
|
+
column?: string;
|
|
220
|
+
direction?: 'asc' | 'desc';
|
|
199
221
|
}
|
|
222
|
+
/** O que fazer quando as linhas passam da altura do widget. */
|
|
223
|
+
export type TableOverflow = 'scroll' | 'clip';
|
|
200
224
|
export interface TableConfig extends WidgetFilterTargeting {
|
|
201
225
|
label: string;
|
|
202
226
|
columns?: TableColumnConfig[];
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Níveis de agregação, aplicados em cadeia. Vazio = um registro por linha. As
|
|
229
|
+
* colunas agrupadas não precisam estar entre as exibidas.
|
|
230
|
+
*/
|
|
231
|
+
aggregations?: TableAggregationLevel[];
|
|
232
|
+
sort?: TableSortLevel[];
|
|
233
|
+
/** Coluna extra à esquerda com a posição da linha (1, 2, 3...). */
|
|
234
|
+
indexColumn?: boolean;
|
|
235
|
+
overflow?: TableOverflow;
|
|
206
236
|
limit?: number;
|
|
207
237
|
filterExpression?: WidgetFilter;
|
|
208
238
|
}
|
|
@@ -284,6 +314,8 @@ export interface FilterValuesResponse {
|
|
|
284
314
|
filter_options: Record<string, string[]>;
|
|
285
315
|
headers: string[];
|
|
286
316
|
column_types: Record<string, string>;
|
|
317
|
+
/** Apresentacao declarada por coluna (currency_brl, percent...). */
|
|
318
|
+
column_presentations?: Record<string, string>;
|
|
287
319
|
/** Coluna que é o eixo temporal do dataset — a que os filtros de data recortam. */
|
|
288
320
|
date_column?: string | null;
|
|
289
321
|
}
|
|
@@ -320,6 +352,7 @@ export declare const AGGREGATION_LABELS: Record<AggregationType, string>;
|
|
|
320
352
|
export declare const FORMAT_LABELS: Record<FormatType, string>;
|
|
321
353
|
export declare const NUMERIC_FORMAT_OPTIONS: [FormatType, string][];
|
|
322
354
|
export declare const COMPARISON_DISPLAY_LABELS: Record<ComparisonDisplay, string>;
|
|
355
|
+
export declare const TABLE_OVERFLOW_LABELS: Record<TableOverflow, string>;
|
|
323
356
|
export declare const GOOD_WHEN_LABELS: Record<GoodWhen, string>;
|
|
324
357
|
export declare const FILTER_OPERATOR_LABELS: Record<FilterOperator, string>;
|
|
325
358
|
/** Operadores que dispensam valor — a condição se resolve só pela coluna. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actionexec/dashboards",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Biblioteca de renderizacao de dashboards da plataforma Action — componente <Dashboard> unico, consumindo /external/dashboards.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ColorPaletteSelector-CsByaRmM.js","sources":["../src/api/fetcher.ts","../src/palettes/index.ts","../src/types/index.ts","../src/utils/grid.ts","../src/utils/format.ts","../src/utils/date.ts","../src/components/DashboardDatePicker.tsx","../src/components/SearchableSelect.tsx","../src/components/ColorPaletteSelector.tsx"],"sourcesContent":["// Purpose: Client HTTP interno da API Action (endpoints /external/dashboards).\n// Scope: Infraestrutura da lib — nao exportado no index publico. Consumidor\n// externo usa <Dashboard token /> que encapsula tudo.\n// Public API (interno): fetchLayout, fetchRender, ApiError, setApiUrl\n\nimport type { LayoutResponse, RenderResponse } from '../types';\n\nconst DEFAULT_API_URL = 'https://action-data-api-7mbrztperq-rj.a.run.app';\nconst ENDPOINT_PREFIX = '/external/dashboards';\n\n// URL efetiva — pode ser sobrescrita via `setApiUrl` (uso interno em dev).\nlet apiUrl = DEFAULT_API_URL;\n\n/** Sobrescreve a URL base da API. Destinado ao builder da plataforma em dev —\n * consumidores externos nao devem chamar (usam a URL de producao por default). */\nexport function setApiUrl(url: string): void {\n apiUrl = url.replace(/\\/$/, '');\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public status?: number,\n public payload?: unknown,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nasync function get<T>(path: string, token: string, params?: Record<string, string>): Promise<T> {\n const url = new URL(`${apiUrl}${ENDPOINT_PREFIX}${path}`);\n if (params) {\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n }\n\n const res = await fetch(url.toString(), {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!res.ok) {\n let payload: unknown;\n try { payload = await res.json(); } catch { /* non-json */ }\n throw new ApiError(\n `Requisicao falhou (${res.status}) em ${path}`,\n res.status,\n payload,\n );\n }\n return (await res.json()) as T;\n}\n\nexport const fetchLayout = (token: string) =>\n get<LayoutResponse>('/layout', token);\n\nexport const fetchRender = (token: string, params?: Record<string, string>) =>\n get<RenderResponse>('/render', token, params);\n","// Purpose: Paletas de cores completas para dashboards (series de dados + cores de UI).\n// Scope: Define paletas com 13 slots semanticos (5 series + 8 cores de UI) e helpers\n// para extrair series e gerar CSS variables aplicaveis ao escopo do dashboard.\n// Public API: PALETTES, PaletteKey, Palette, getSeries, getPaletteCssVars,\n// SLOT_INDEX, SLOT_LABELS, DEFAULT_PALETTE_COLORS, ensurePaletteShape\n\nexport interface Palette {\n label: string;\n colors: string[]; // 13 cores ordenadas pelos slots semanticos\n}\n\nexport type PaletteKey = 'action' | 'westCoast' | 'mono' | 'ocean' | 'princess';\n\n// -------Slots semanticos (indices fixos no array de cores)-------\n//\n// Convencao posicional para manter o storage como string[] (compativel com schemas\n// Pydantic e o tipo `PaletteConfig.paletteColors`). Cada paleta deve ter 13 cores.\n\nexport const SLOT_INDEX = {\n series0: 0,\n series1: 1,\n series2: 2,\n series3: 3,\n series4: 4,\n bgDark: 5,\n bgPaper: 6,\n bgElevated: 7,\n textPrimary: 8,\n textMuted: 9,\n accent: 10,\n success: 11,\n error: 12,\n // Alerta e informacao tem slot proprio: derivá-los de cores de serie fazia\n // trocar a cor de uma serie mudar o significado semantico de \"atencao\".\n warning: 13,\n info: 14,\n} as const;\n\nexport const SERIES_COUNT = 5;\nexport const TOTAL_SLOTS = 15;\n\nexport const SLOT_LABELS: Record<keyof typeof SLOT_INDEX, string> = {\n series0: 'Série 1',\n series1: 'Série 2',\n series2: 'Série 3',\n series3: 'Série 4',\n series4: 'Série 5',\n bgDark: 'Fundo Escuro',\n bgPaper: 'Fundo Cartão',\n bgElevated: 'Fundo Elevado',\n textPrimary: 'Texto Primário',\n textMuted: 'Texto Secundário',\n accent: 'Destaque',\n success: 'Sucesso',\n error: 'Erro',\n warning: 'Alerta',\n info: 'Informação',\n};\n\n// -------Presets-------\n\nexport const PALETTES: Record<PaletteKey, Palette> = {\n action: {\n label: 'Action',\n colors: [\n '#ff6b00', '#a3e635', '#e3f544', '#65ffd1', '#ff0404',\n '#1a1a1a',\n '#262626',\n '#333333',\n '#f5f5f5',\n '#999999',\n '#ff6b00',\n '#a3e635',\n '#ef4444',\n '#f59e0b',\n '#38bdf8',\n ],\n },\n westCoast: {\n label: 'West Coast',\n colors: [\n '#a3b86c', '#c89b3c', '#8b6f47', '#6b8e23', '#d2691e',\n '#1f1a14',\n '#2a241b',\n '#3a3225',\n '#e8dcc4',\n '#a89878',\n '#c89b3c',\n '#a3b86c',\n '#c44536',\n '#d99a2b',\n '#7c9bb5',\n ],\n },\n mono: {\n label: 'Monocromático',\n colors: [\n '#f8fafc', '#cbd5e1', '#94a3b8', '#64748b', '#475569',\n '#0a0a0a',\n '#171717',\n '#262626',\n '#fafafa',\n '#a3a3a3',\n '#e5e5e5',\n '#cbd5e1',\n '#ef4444',\n '#facc15',\n '#7dd3fc',\n ],\n },\n ocean: {\n label: 'Ocean',\n colors: [\n '#0ea5e9', '#06b6d4', '#0891b2', '#3b82f6', '#22d3ee',\n '#0a1929',\n '#0f2740',\n '#173554',\n '#e0f2fe',\n '#7dd3fc',\n '#22d3ee',\n '#10b981',\n '#f43f5e',\n '#fbbf24',\n '#60a5fa',\n ],\n },\n princess: {\n label: 'Cute Pink',\n colors: [\n '#ff79bc', '#a855f7', '#f472b6', '#d946ef', '#fb7185',\n '#fff0f6',\n '#ffe4ec',\n '#ffffff',\n '#ff4099',\n '#ffadd5',\n '#ec4899',\n '#10b981',\n '#e11d48',\n '#f59e0b',\n '#8b5cf6',\n ],\n },\n};\n\nexport const DEFAULT_PALETTE: PaletteKey = 'action';\n\n// Array de cores default expandido (13 slots)\nexport const DEFAULT_PALETTE_COLORS: string[] = PALETTES.action.colors;\n\n// -------Helpers-------\n\n/** Garante que a paleta tem TOTAL_SLOTS cores. Preenche faltantes com fallback do default. */\nexport function ensurePaletteShape(colors?: string[]): string[] {\n const fallback = DEFAULT_PALETTE_COLORS;\n if (!colors || colors.length === 0) return [...fallback];\n if (colors.length >= TOTAL_SLOTS) return colors.slice(0, TOTAL_SLOTS);\n const result = [...colors];\n for (let i = colors.length; i < TOTAL_SLOTS; i++) result.push(fallback[i]);\n return result;\n}\n\n/** Extrai apenas as cores de series (uso em charts/gauge). */\nexport function getSeries(colors?: string[]): string[] {\n const full = ensurePaletteShape(colors);\n return full.slice(0, SERIES_COUNT);\n}\n\n/** Gera objeto de CSS variables para aplicar inline no escopo do dashboard. */\nexport function getPaletteCssVars(colors?: string[]): Record<string, string> {\n const c = ensurePaletteShape(colors);\n return {\n '--bg-dark': c[SLOT_INDEX.bgDark],\n '--bg-paper': c[SLOT_INDEX.bgPaper],\n '--bg-elevated': c[SLOT_INDEX.bgElevated],\n '--text-primary': c[SLOT_INDEX.textPrimary],\n '--text-secondary': c[SLOT_INDEX.textMuted],\n '--text-muted': c[SLOT_INDEX.textMuted],\n '--color-accent': c[SLOT_INDEX.accent],\n '--color-success': c[SLOT_INDEX.success],\n '--color-error': c[SLOT_INDEX.error],\n '--color-warning': c[SLOT_INDEX.warning],\n '--color-info': c[SLOT_INDEX.info],\n // Aliases historicos, mantidos para nao quebrar CSS de consumidores.\n '--action-orange': c[SLOT_INDEX.accent],\n '--action-green': c[SLOT_INDEX.success],\n };\n}\n","// Purpose: Tipos compartilhados entre backend Python (schemas Pydantic) e frontend.\r\n// Scope: Union discriminada de WidgetDefinition, configs por tipo, respostas da API.\r\n// Public API: Todos os tipos e interfaces exportados + defaults + labels.\r\n\r\nimport { DEFAULT_PALETTE_COLORS } from '../palettes';\r\n\r\n// -------Enums como string literals-------\r\n\r\nexport type AggregationType = 'sum' | 'avg' | 'count' | 'min' | 'max' | 'count_distinct';\r\n/** Como ler a diferença entre o valor do widget e a linha de base. */\r\nexport type ComparisonDisplay = 'variance' | 'difference' | 'ratio' | 'value';\r\n\r\n/** Sentido do indicador: separa a direção (a seta) do julgamento (a cor). */\r\nexport type GoodWhen = 'higher' | 'lower' | 'neutral';\r\nexport type FilterType = 'date_range' | 'select' | 'multi_select';\r\nexport type WidgetType = 'kpi_card' | 'gauge' | 'chart' | 'composition' | 'filter' | 'variable' | 'color_palette' | 'table';\r\nexport type DataWidgetType = 'kpi_card' | 'gauge' | 'chart' | 'composition' | 'table';\r\nexport type ControlWidgetType = 'filter' | 'variable' | 'color_palette';\r\n// Pizza nao esta aqui: virou o widget `composition`, que reparte uma medida\r\n// entre as categorias de uma coluna e nao tem eixo X.\r\nexport type ChartType = 'bar' | 'line' | 'area';\r\nexport type CompositionDisplay = 'pie' | 'bridge';\r\nexport type BridgeDirection = 'ascending' | 'descending';\r\nexport type FormatType = 'currency' | 'number' | 'integer' | 'percentage' | 'date' | 'text';\r\nexport type DateFilterMode = 'range' | 'monthly' | 'weekly' | 'yearly';\r\nexport type Granularity = 'day' | 'week' | 'month' | 'year' | 'weekday';\r\n\r\n// -------Pedacos compartilhados pelos configs-------\r\n\r\nexport interface FilterDefinition {\r\n id: string;\r\n type: FilterType;\r\n label: string;\r\n column?: string | null;\r\n defaultValue?: unknown;\r\n}\r\n\r\nexport interface TargetDefinition {\r\n id: string;\r\n label: string;\r\n value: number;\r\n format: FormatType;\r\n}\r\n\r\nexport interface GridPosition {\r\n x: number;\r\n y: number;\r\n w: number;\r\n h: number;\r\n}\r\n\r\n/**\r\n * Uma linha de base para o valor do widget, e como ler a diferença.\r\n *\r\n * A base é sempre uma fórmula — a mesma plataforma do valor principal. Não há\r\n * tipos de comparação: \"mês anterior\" é a fórmula do widget com desvio nos\r\n * operandos, e \"vs meta\" é uma fórmula de um operando de variável.\r\n */\r\nexport interface Comparison {\r\n id: string;\r\n label?: string;\r\n formula: KpiTerm[];\r\n display?: ComparisonDisplay;\r\n goodWhen?: GoodWhen;\r\n}\r\n\r\nexport interface AggregationStep {\r\n aggregation: AggregationType;\r\n groupBy: string;\r\n groupGranularity?: Granularity;\r\n}\r\n\r\nexport interface ColumnExpressionTerm {\r\n column: string;\r\n operator?: '+' | '-' | '*' | '/';\r\n}\r\n\r\n// -------Filtro proprio do widget-------\r\n\r\nexport type FilterOperator =\r\n | 'eq' | 'neq' | 'in' | 'not_in'\r\n | 'gt' | 'gte' | 'lt' | 'lte' | 'between'\r\n | 'contains' | 'not_contains' | 'is_empty' | 'not_empty';\r\n\r\nexport interface FilterCondition {\r\n column: string;\r\n op?: FilterOperator;\r\n /** Escalar, lista (in/not_in), par [min, max] (between) ou ausente (is_empty/not_empty). */\r\n value?: unknown;\r\n}\r\n\r\nexport interface WidgetFilter {\r\n conditions: FilterCondition[];\r\n /** all = E entre as condicoes; any = OU. Default: all. */\r\n match?: 'all' | 'any';\r\n}\r\n\r\nexport type TimeOffsetUnit = 'day' | 'week' | 'month' | 'quarter' | 'year';\r\nexport type TimeOffsetMode = 'calendar' | 'window';\r\n\r\n/**\r\n * Desvio da janela de data lida por UM operando.\r\n *\r\n * `amount` negativo olha para tras. Em `calendar` as duas pontas da janela\r\n * recuam `amount` unidades — e o \"mesmo periodo no mes anterior\". Em `window` a\r\n * janela recua blocos contiguos de mesma duracao, e `unit` nao participa.\r\n */\r\nexport interface TimeOffset {\r\n amount: number;\r\n unit?: TimeOffsetUnit;\r\n mode?: TimeOffsetMode;\r\n}\r\n\r\n/**\r\n * Um numero dentro da formula. Tres origens, nesta ordem de precedencia:\r\n * `constant`, `variableId` (widget `variable`) e a cadeia sobre `column`.\r\n */\r\nexport interface KpiOperand {\r\n column?: string;\r\n columnExpression?: ColumnExpressionTerm[];\r\n /** Id de um widget `variable` — valor ajustavel por quem ve o dashboard. */\r\n variableId?: string;\r\n intermediateSteps?: AggregationStep[];\r\n finalAggregation?: AggregationType;\r\n constant?: number;\r\n /** Move a janela de data deste operando, sem afetar os demais termos. */\r\n timeOffset?: TimeOffset;\r\n}\r\n\r\nexport interface KpiTerm {\r\n operand: KpiOperand;\r\n operator?: '+' | '-' | '*' | '/'; // undefined apenas no primeiro termo\r\n}\r\n\r\nexport interface ChartSeriesConfig {\r\n label: string;\r\n // Formula simples\r\n column?: string;\r\n aggregation?: AggregationType;\r\n // Formula composta (pipeline identico ao KPI card, avaliado por grupo do eixo X)\r\n kpiTerms?: KpiTerm[];\r\n}\r\n\r\nexport interface ChartAxisConfig {\r\n column: string;\r\n granularity: Granularity;\r\n}\r\n\r\n// -------Config por tipo de widget-------\r\n\r\n// IDs de widgets de filtro que NAO se aplicam ao widget (default: todos aplicam).\r\n// Compartilhado pelos widgets de dados (kpi_card, gauge, chart).\r\nexport interface WidgetFilterTargeting {\r\n excludedFilters?: string[];\r\n}\r\n\r\nexport interface KpiCardConfig extends WidgetFilterTargeting {\r\n label: string;\r\n format?: FormatType;\r\n column?: string;\r\n aggregation?: AggregationType;\r\n groupBy?: string;\r\n groupGranularity?: Granularity;\r\n outerAggregation?: AggregationType;\r\n kpiTerms?: KpiTerm[];\r\n comparisons?: Comparison[];\r\n filterExpression?: WidgetFilter;\r\n}\r\n\r\n/**\r\n * O gauge não tem conceito próprio de meta: o arco é a primeira comparação lida\r\n * como proporção. Mesma config e mesmo motor do card.\r\n */\r\nexport interface GaugeConfig extends WidgetFilterTargeting {\r\n label: string;\r\n format?: FormatType;\r\n column?: string;\r\n aggregation?: AggregationType;\r\n kpiTerms?: KpiTerm[];\r\n comparisons?: Comparison[];\r\n groupBy?: string;\r\n groupGranularity?: Granularity;\r\n outerAggregation?: AggregationType;\r\n filterExpression?: WidgetFilter;\r\n}\r\n\r\nexport interface ChartConfig extends WidgetFilterTargeting {\r\n label: string;\r\n chartType?: ChartType;\r\n xAxis?: ChartAxisConfig;\r\n series?: ChartSeriesConfig[];\r\n format?: FormatType;\r\n filterExpression?: WidgetFilter;\r\n}\r\n\r\n/**\r\n * Categoria curada da coluna de decomposicao.\r\n *\r\n * `value` e o valor bruto no dataset (`DESP_ADM`, `03.02.001`); `label` e o que\r\n * aparece na barra. A posicao na lista importa so na ponte.\r\n */\r\nexport interface CompositionCategory {\r\n value: string;\r\n label?: string;\r\n}\r\n\r\n/**\r\n * Decomposicao de UMA medida pelas categorias de UMA coluna.\r\n *\r\n * `categories` e a curadoria: quais entram, com que rotulo e — na ponte — em que\r\n * ordem. O que ficar de fora cai em \"Outros\", somado e nunca descartado.\r\n *\r\n * A ponte nao tem ancoras: `direction` decide as duas pontas.\r\n *\r\n * ascending 0 -> +cat1 -> +cat2 -> [total]\r\n * descending [total] -> -cat1 -> -cat2 -> 0\r\n *\r\n * Nos dois sentidos o total e a soma das proprias categorias, entao a ponte\r\n * fecha exatamente — nao ha sobra a explicar.\r\n */\r\nexport interface CompositionConfig extends WidgetFilterTargeting {\r\n label: string;\r\n display?: CompositionDisplay;\r\n categoryColumn?: string;\r\n /** Mesma plataforma de fórmula do KPI card, avaliada por categoria. */\r\n kpiTerms?: KpiTerm[];\r\n /** Vazio = todas as categorias encontradas, por valor decrescente. */\r\n categories?: CompositionCategory[];\r\n /** Nome da barra que agrupa o que ficou fora da curadoria (default \"Outros\"). */\r\n otherLabel?: string;\r\n format?: FormatType;\r\n // Somente ponte\r\n direction?: BridgeDirection;\r\n totalLabel?: string;\r\n filterExpression?: WidgetFilter;\r\n}\r\n\r\nexport interface TableColumnConfig {\r\n column: string; // chave da coluna no row_data\r\n label?: string; // rotulo do cabecalho (default: column)\r\n format?: FormatType; // formatacao da celula (default: text)\r\n}\r\n\r\nexport interface TableTabConfig {\r\n label: string; // rotulo da aba\r\n filterExpression?: WidgetFilter; // filtro proprio da aba (soma ao do widget)\r\n}\r\n\r\nexport interface TableConfig extends WidgetFilterTargeting {\r\n label: string;\r\n columns?: TableColumnConfig[]; // colunas a exibir (vazio = todas do dataset)\r\n tabs?: TableTabConfig[]; // abas que trocam o filtro (vazio = tabela unica)\r\n sortBy?: string; // coluna de ordenacao\r\n sortDir?: 'asc' | 'desc';\r\n limit?: number; // maximo de linhas\r\n filterExpression?: WidgetFilter;\r\n}\r\n\r\nexport interface FilterConfig {\r\n label: string;\r\n filterType: FilterType;\r\n filterColumn?: string;\r\n defaultValue?: unknown;\r\n dateFilterMode?: DateFilterMode;\r\n // Apresentacao categorica: true = lista com busca por digitacao; ausente = padrao\r\n // (select unico / checkboxes). Aplica-se a select e multi_select; nao afeta a query.\r\n searchable?: boolean;\r\n // Valores distintos da coluna, preenchidos pelo /layout (select e multi_select).\r\n // Sao estruturais — nao mudam com os filtros aplicados —, por isso viajam no\r\n // layout cacheavel e nao no payload de /render.\r\n availableValues?: string[];\r\n}\r\n\r\nexport interface VariableConfig {\r\n label: string;\r\n variableValue?: number;\r\n variableFormat?: FormatType;\r\n locked?: boolean;\r\n}\r\n\r\nexport interface PaletteConfig {\r\n paletteColors: string[];\r\n label?: string;\r\n locked?: boolean;\r\n}\r\n\r\nexport type AnyWidgetConfig =\r\n | KpiCardConfig | GaugeConfig | ChartConfig | CompositionConfig | TableConfig\r\n | FilterConfig | VariableConfig | PaletteConfig;\r\n\r\n// -------Union discriminada de WidgetDefinition-------\r\n\r\nexport type WidgetDefinition =\r\n | { id: string; type: 'kpi_card'; grid: GridPosition; config: KpiCardConfig }\r\n | { id: string; type: 'gauge'; grid: GridPosition; config: GaugeConfig }\r\n | { id: string; type: 'chart'; grid: GridPosition; config: ChartConfig }\r\n | { id: string; type: 'composition'; grid: GridPosition; config: CompositionConfig }\r\n | { id: string; type: 'table'; grid: GridPosition; config: TableConfig }\r\n | { id: string; type: 'filter'; grid: GridPosition; config: FilterConfig }\r\n | { id: string; type: 'variable'; grid: GridPosition; config: VariableConfig }\r\n | { id: string; type: 'color_palette'; grid: GridPosition; config: PaletteConfig };\r\n\r\nexport type WidgetConfigOf<T extends WidgetType> = Extract<WidgetDefinition, { type: T }>['config'];\r\n\r\n// -------Layout completo-------\r\n\r\nexport interface DashboardLayout {\r\n gridColumns: number;\r\n gridRows: number;\r\n widgets: WidgetDefinition[];\r\n}\r\n\r\n// -------Respostas da API-------\r\n\r\nexport interface FilterValuesResponse {\r\n date_bounds: { min: string | null; max: string | null };\r\n filter_options: Record<string, string[]>;\r\n headers: string[];\r\n column_types: Record<string, string>;\r\n /** Coluna que é o eixo temporal do dataset — a que os filtros de data recortam. */\r\n date_column?: string | null;\r\n}\r\n\r\nexport interface RenderResponse {\r\n date_bounds: { min: string; max: string };\r\n applied: Record<string, unknown>;\r\n widgets: Record<string, Record<string, unknown>>;\r\n}\r\n\r\nexport interface LayoutResponse {\r\n name: string;\r\n palette: string[];\r\n gridColumns: number;\r\n gridRows: number;\r\n dateBounds: { min: string; max: string };\r\n widgets: WidgetDefinition[];\r\n}\r\n\r\n// -------Defaults-------\r\n\r\n// Re-export para compatibilidade com codigo existente que importa de dashboardLayout\r\nexport const DEFAULT_PALETTE = DEFAULT_PALETTE_COLORS;\r\n\r\nexport const DEFAULT_GRID_COLUMNS = 30;\r\nexport const DEFAULT_GRID_ROWS = 10;\r\n\r\nexport const EMPTY_LAYOUT: DashboardLayout = {\r\n gridColumns: DEFAULT_GRID_COLUMNS,\r\n gridRows: DEFAULT_GRID_ROWS,\r\n widgets: [],\r\n};\r\n\r\nexport const WIDGET_TYPE_LABELS: Record<WidgetType, string> = {\r\n kpi_card: 'Card',\r\n gauge: 'Gauge',\r\n chart: 'Gráfico',\r\n composition: 'Composição',\r\n table: 'Tabela',\r\n filter: 'Filtro',\r\n variable: 'Variável',\r\n color_palette: 'Paleta de Cores',\r\n};\r\n\r\nexport const DATA_WIDGET_TYPES: DataWidgetType[] = ['kpi_card', 'gauge', 'chart', 'composition', 'table'];\r\nexport const CONTROL_WIDGET_TYPES: ControlWidgetType[] = ['filter', 'variable', 'color_palette'];\r\nexport const CONTROL_WIDGET_SET = new Set<WidgetType>(['filter', 'variable', 'color_palette']);\r\n\r\n// Singular e plural: o desvio aparece como \"−1 mês\" e \"−2 meses\"\r\nexport const TIME_OFFSET_UNIT_LABELS: Record<TimeOffsetUnit, [string, string]> = {\r\n day: ['dia', 'dias'],\r\n week: ['semana', 'semanas'],\r\n month: ['mês', 'meses'],\r\n quarter: ['trimestre', 'trimestres'],\r\n year: ['ano', 'anos'],\r\n};\r\n\r\n// A unidade do modo `window` e a duracao do proprio periodo filtrado: \"−1 período\"\r\n// recua um bloco do tamanho do recorte de datas em vigor.\r\nexport const TIME_OFFSET_WINDOW_LABEL: [string, string] = ['período', 'períodos'];\r\n\r\nexport const AGGREGATION_LABELS: Record<AggregationType, string> = {\r\n sum: 'Soma',\r\n avg: 'Média',\r\n count: 'Contagem',\r\n min: 'Mínimo',\r\n max: 'Máximo',\r\n count_distinct: 'Contagem Distinta',\r\n};\r\n\r\nexport const FORMAT_LABELS: Record<FormatType, string> = {\r\n currency: 'Moeda (R$)',\r\n number: 'Número',\r\n integer: 'Inteiro',\r\n percentage: 'Porcentagem',\r\n date: 'Data',\r\n text: 'Texto',\r\n};\r\n\r\n// Subset de formatos numericos — usado nos configs de KPI, Gauge, Variable\r\nexport const NUMERIC_FORMAT_OPTIONS = Object.entries(FORMAT_LABELS)\r\n .filter(([k]) => k !== 'date' && k !== 'text') as [FormatType, string][];\r\n\r\nexport const COMPARISON_DISPLAY_LABELS: Record<ComparisonDisplay, string> = {\r\n variance: 'Variação %',\r\n difference: 'Diferença',\r\n ratio: 'Proporção',\r\n value: 'Base',\r\n};\r\n\r\nexport const GOOD_WHEN_LABELS: Record<GoodWhen, string> = {\r\n higher: 'Positivo',\r\n lower: 'Negativo',\r\n neutral: 'Neutro',\r\n};\r\n\r\nexport const FILTER_OPERATOR_LABELS: Record<FilterOperator, string> = {\r\n eq: 'Igual a',\r\n neq: 'Diferente de',\r\n in: 'Está entre os valores',\r\n not_in: 'Não está entre os valores',\r\n gt: 'Maior que',\r\n gte: 'Maior ou igual a',\r\n lt: 'Menor que',\r\n lte: 'Menor ou igual a',\r\n between: 'Entre (faixa numérica)',\r\n contains: 'Contém',\r\n not_contains: 'Não contém',\r\n is_empty: 'Está vazio',\r\n not_empty: 'Não está vazio',\r\n};\r\n\r\n/** Operadores que dispensam valor — a condição se resolve só pela coluna. */\r\nexport const VALUELESS_FILTER_OPERATORS: FilterOperator[] = ['is_empty', 'not_empty'];\r\n\r\n/** Operadores cujo valor é uma lista de opções. */\r\nexport const LIST_FILTER_OPERATORS: FilterOperator[] = ['in', 'not_in'];\r\n\r\nexport const CHART_TYPE_LABELS: Record<ChartType, string> = {\r\n bar: 'Barras',\r\n line: 'Linhas',\r\n area: 'Área',\r\n};\r\n\r\nexport const COMPOSITION_DISPLAY_LABELS: Record<CompositionDisplay, string> = {\r\n pie: 'Pizza',\r\n bridge: 'Ponte',\r\n};\r\n\r\nexport const BRIDGE_DIRECTION_LABELS: Record<BridgeDirection, string> = {\r\n descending: 'Descendente',\r\n ascending: 'Ascendente',\r\n};\r\n\r\n\r\nexport const FILTER_TYPE_LABELS: Record<FilterType, string> = {\r\n date_range: 'Periodo',\r\n select: 'Seleção Única',\r\n multi_select: 'Seleção Múltipla',\r\n};\r\n\r\n// Separador interno dos valores de filtros multi_select. Usa o caractere de controle\r\n// Unit Separator (U+001F), que nunca aparece em nomes de produtos — evita a colisao\r\n// que a virgula causava quando o proprio valor continha virgula.\r\n// DEVE ser identico ao separador usado no backend (filters.py).\r\nexport const MULTI_VALUE_SEPARATOR = '\\u001f';\r\n\r\n// -------Default grid sizes por tipo de widget-------\r\n\r\nexport const DEFAULT_GRID: Record<WidgetType, GridPosition> = {\r\n kpi_card: { x: 0, y: 0, w: 6, h: 3 },\r\n gauge: { x: 0, y: 0, w: 6, h: 5 },\r\n chart: { x: 0, y: 0, w: 6, h: 6 },\r\n composition: { x: 0, y: 0, w: 6, h: 6 },\r\n table: { x: 0, y: 0, w: 12, h: 7 },\r\n filter: { x: 0, y: 0, w: 4, h: 2 },\r\n variable: { x: 0, y: 0, w: 4, h: 2 },\r\n color_palette: { x: 0, y: 0, w: 4, h: 2 },\r\n};\r\n\r\nexport const DEFAULT_CONFIG: { [K in WidgetType]: Partial<WidgetConfigOf<K>> } = {\r\n kpi_card: { label: 'Novo card', aggregation: 'sum', format: 'number' },\r\n gauge: { label: 'Novo Gauge', aggregation: 'sum' },\r\n chart: { label: 'Novo gráfico', chartType: 'bar', xAxis: { column: '', granularity: 'day' }, series: [] },\r\n composition: {\r\n label: 'Nova composição', display: 'pie',\r\n categories: [], direction: 'descending',\r\n },\r\n table: { label: 'Nova Tabela', columns: [] },\r\n filter: { label: 'Novo Filtro', filterType: 'select' },\r\n variable: { label: 'Nova Variavel', variableValue: 0, variableFormat: 'number', locked: false },\r\n color_palette: { label: 'Paleta de Cores', paletteColors: DEFAULT_PALETTE, locked: false },\r\n};\r\n","// Purpose: Geometria do grid — fonte unica compartilhada pelo runtime (Dashboard)\n// e pelo editor de layout da plataforma Action (CanvasEditor).\n// Scope: Constantes de espacamento e funcoes puras que projetam celulas do grid\n// em pixels. Nenhuma dependencia de React ou DOM.\n// Public API: GRID_GAP_PX, GRID_PADDING_PX, CELL_ASPECT, MIN_CELL_HEIGHT_PX,\n// MAX_CELL_HEIGHT_PX, computeCellWidth, computeCellHeight,\n// computeGridHeight, computeWidgetAspect, computeStackThreshold,\n// DashboardGeometry.\n\n/** Espaco entre celulas, em px. Absoluto de proposito: ver nota de proporcao abaixo. */\nexport const GRID_GAP_PX = 6;\n\n/** Recuo interno do grid, em px. Deve espelhar --spacing-md dos tokens. */\nexport const GRID_PADDING_PX = 16;\n\n/**\n * Proporcao largura/altura da celula. 1 = celula quadrada.\n *\n * A largura da celula e sempre fluida (largura disponivel / numero de colunas).\n * Fixar a proporcao faz a altura acompanhar, de modo que o dashboard mantenha\n * a mesma forma em qualquer aplicacao que o embuta — que e o unico jeito de o\n * editor ser WYSIWYG.\n *\n * O valor 1 nao e arbitrario: com 30 colunas num container de 1440px a coluna\n * mede ~41px, praticamente a altura de linha fixa de 40px usada ate a v0.6.\n * Adotar celula quadrada preserva a aparencia dos dashboards ja montados.\n */\nexport const CELL_ASPECT = 1;\n\n/**\n * Trilhos de seguranca da altura da celula.\n *\n * Fora dessa faixa a proporcao deixa de valer de proposito: abaixo do minimo o\n * dashboard seria pequeno demais para ser lido (container estreito), acima do\n * maximo seria alto demais para caber na viewport (monitor ultrawide). Uma forma\n * levemente distorcida e preferivel a um dashboard inutilizavel.\n *\n * Com 30 colunas, os limites entram abaixo de ~930px e acima de ~2600px de\n * container — ou seja, a proporcao se mantem intacta em toda a faixa de desktop.\n */\nexport const MIN_CELL_HEIGHT_PX = 24;\nexport const MAX_CELL_HEIGHT_PX = 80;\n\nconst clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\n\n/**\n * Medida utilizavel: positiva e finita.\n *\n * `cellAspect` e prop publica tipada `number`, e o numero de colunas vem da API —\n * nenhum dos dois barra NaN ou Infinity. Sem esta guarda um NaN atravessa\n * `value <= 0` (que e falso para NaN) e contamina todo o calculo ate virar\n * `--dash-cell-h: NaNpx`, que invalida a declaracao e derruba o grid inteiro.\n */\nconst isUsable = (value: number) => Number.isFinite(value) && value > 0;\n\n/**\n * Largura de uma coluna do grid.\n *\n * `outerWidth` e a largura de borda do elemento do grid (inclui o recuo interno).\n * Identica a formula do react-grid-layout (calcGridColWidth), o que garante que\n * editor e runtime cheguem ao mesmo numero.\n */\nexport function computeCellWidth(\n outerWidth: number,\n columns: number,\n gap: number = GRID_GAP_PX,\n padding: number = GRID_PADDING_PX,\n): number {\n if (!isUsable(columns) || !Number.isFinite(outerWidth)) return 0;\n const available = outerWidth - padding * 2 - gap * (columns - 1);\n return Math.max(0, available / columns);\n}\n\n/** Altura de linha que preserva a proporcao da celula, respeitando os trilhos. */\nexport function computeCellHeight(cellWidth: number, aspect: number = CELL_ASPECT): number {\n if (!isUsable(cellWidth) || !isUsable(aspect)) return MIN_CELL_HEIGHT_PX;\n return clamp(cellWidth / aspect, MIN_CELL_HEIGHT_PX, MAX_CELL_HEIGHT_PX);\n}\n\n/** Altura total ocupada por `rows` linhas, incluindo gaps e recuo interno. */\nexport function computeGridHeight(\n rows: number,\n cellHeight: number,\n gap: number = GRID_GAP_PX,\n padding: number = GRID_PADDING_PX,\n): number {\n if (rows <= 0) return padding * 2;\n return rows * cellHeight + (rows - 1) * gap + padding * 2;\n}\n\n/**\n * Proporcao largura/altura de um widget de `w` x `h` celulas.\n *\n * Ignora o gap interno do widget de proposito: incluir o termo tornaria a\n * proporcao dependente da largura da celula, e portanto nao seria constante.\n * O desvio e o mesmo ~2% que a celula quadrada ja tem, e em troca a proporcao\n * pode ser expressa em CSS puro (`aspect-ratio`), sem medicao.\n */\nexport function computeWidgetAspect(w: number, h: number, aspect: number = CELL_ASPECT): number {\n if (!isUsable(w) || !isUsable(h) || !isUsable(aspect)) return 1;\n return (w * aspect) / h;\n}\n\n/**\n * Largura de container abaixo da qual a proporcao deixa de ser respeitada —\n * o ponto em que a celula bateria em MIN_CELL_HEIGHT_PX.\n *\n * E o limiar natural para trocar de modo: abaixo dele o layout em colunas ja\n * esta distorcido, e empilhar passa a ser a apresentacao mais fiel.\n *\n * Depende da proporcao: como a altura e `cellWidth / aspect`, o piso e atingido\n * quando a largura da celula chega a `MIN_CELL_HEIGHT_PX * aspect`, nao a\n * MIN_CELL_HEIGHT_PX. Ignorar o aspect erraria o limiar para qualquer valor\n * diferente de 1 — com aspect 2 e 30 colunas, por 720px.\n */\nexport function computeStackThreshold(\n columns: number,\n aspect: number = CELL_ASPECT,\n gap: number = GRID_GAP_PX,\n padding: number = GRID_PADDING_PX,\n): number {\n if (!isUsable(columns) || !isUsable(aspect)) return 0;\n return MIN_CELL_HEIGHT_PX * aspect * columns + gap * (columns - 1) + padding * 2;\n}\n\n/** Geometria corrente do grid, reportada ao consumidor via `onGeometryChange`. */\nexport interface DashboardGeometry {\n /** Largura de borda do container do dashboard, em px. */\n containerWidth: number;\n /** Largura da celula do grid. Sem efeito enquanto `stacked` for true. */\n cellWidth: number;\n /** Altura da celula do grid. Sem efeito enquanto `stacked` for true. */\n cellHeight: number;\n /** Altura renderizada do grid, em px — o que o host precisa acomodar. */\n gridHeight: number;\n /** Se o dashboard esta renderizando em coluna unica. */\n stacked: boolean;\n}\n","// Purpose: Formatacao de valores exibidos pelos widgets.\n// Scope: Fonte unica de formatacao no frontend — antes cada widget tinha a sua,\n// e tabela e KPI divergiam no significado de `percentage`. Espelha\n// backend/app/dashboards/widgets/format.py: o backend ja manda `formatted`\n// pronto nos escalares; isto cobre o que e formatado no cliente (celulas de\n// tabela, eixos, rotulos compactos).\n// Public API: formatValue, formatCompact, PERCENTAGE_SCALE\n\nimport type { FormatType } from '../types';\n\nconst LOCALE = 'pt-BR';\n\n/**\n * Percentuais trafegam como fracao (0,153 = 15,3%), igual ao backend\n * (format_value multiplica por 100). Manter a mesma escala nos dois lados evita\n * que a mesma coluna apareca como \"15,3%\" num KPI e \"0%\" numa tabela.\n */\nexport const PERCENTAGE_SCALE = 100;\n\nconst NUMERIC_FORMATS: ReadonlySet<string> = new Set(['currency', 'number', 'integer', 'percentage']);\n\n/** True quando o formato representa um numero (alinhamento a direita, sort numerico). */\nexport function isNumericFormat(format?: string): boolean {\n return !!format && NUMERIC_FORMATS.has(format);\n}\n\n/** Converte para numero finito, ou null se o valor nao for numerico. */\nfunction toNumber(value: unknown): number | null {\n if (value === null || value === undefined || value === '') return null;\n const n = typeof value === 'number' ? value : Number(value);\n return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Formata um valor conforme o tipo de formatacao do widget.\n *\n * `fallback` e devolvido quando o valor esta ausente; valores nao numericos em\n * formato numerico voltam como texto, para nao esconder dado sujo do dataset.\n */\nexport function formatValue(value: unknown, format?: FormatType | string, fallback = '-'): string {\n if (value === null || value === undefined || value === '') return fallback;\n\n const n = toNumber(value);\n if (n === null) return String(value);\n\n switch (format) {\n case 'currency':\n return n.toLocaleString(LOCALE, { style: 'currency', currency: 'BRL' });\n case 'integer':\n return Math.round(n).toLocaleString(LOCALE);\n case 'percentage':\n return `${(n * PERCENTAGE_SCALE).toLocaleString(LOCALE, { maximumFractionDigits: 1 })}%`;\n case 'number':\n return n.toLocaleString(LOCALE, { maximumFractionDigits: 2 });\n default:\n return String(value);\n }\n}\n\n/**\n * Versao abreviada para espacos estreitos (centro do gauge, rotulos de eixo).\n * Preserva o simbolo da moeda quando o formato e monetario.\n */\nexport function formatCompact(value: unknown, format?: FormatType | string): string {\n const n = toNumber(value);\n if (n === null) return '-';\n\n if (format === 'percentage') return formatValue(n, 'percentage');\n\n const prefix = format === 'currency' ? 'R$ ' : '';\n const abs = Math.abs(n);\n\n if (abs >= 1_000_000_000) return `${prefix}${(n / 1_000_000_000).toFixed(1)}B`;\n if (abs >= 1_000_000) return `${prefix}${(n / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${prefix}${(n / 1_000).toFixed(1)}K`;\n\n return `${prefix}${n.toLocaleString(LOCALE, { maximumFractionDigits: 2 })}`;\n}\n","// Purpose: Utilitarios de data para filtros temporais de dashboards.\n// Scope: Calculo de intervalos anuais/mensais/semanais, parse de ranges, ISO week.\n// Public API: MONTH_NAMES_*, getFullYearRange, getMonthRange, getWeekRange, getISOWeek,\n// getWeeksInMonth, parseYearFromRange, parseMonthFromRange, parseWeekFromRange,\n// getYearRange, getMonthWeeks, MonthWeek\n\nexport const MONTH_NAMES_SHORT = [\n 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun',\n 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez',\n];\n\nexport const MONTH_NAMES_FULL = [\n 'Janeiro', 'Fevereiro', 'Marco', 'Abril', 'Maio', 'Junho',\n 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro',\n];\n\nexport function getFullYearRange(year: number): { start: string; end: string } {\n return { start: `${year}-01-01`, end: `${year}-12-31` };\n}\n\nexport function parseYearFromRange(start: string): { year: number } | null {\n if (!start) return null;\n const m = start.match(/^(\\d{4})/);\n return m ? { year: parseInt(m[1]) } : null;\n}\n\nexport function getMonthRange(year: number, month: number): { start: string; end: string } {\n const lastDay = new Date(year, month, 0).getDate();\n const pad = (n: number) => String(n).padStart(2, '0');\n return {\n start: `${year}-${pad(month)}-01`,\n end: `${year}-${pad(month)}-${pad(lastDay)}`,\n };\n}\n\nexport function getISOWeek(dt: Date): number {\n const d = new Date(Date.UTC(dt.getFullYear(), dt.getMonth(), dt.getDate()));\n d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));\n const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));\n return Math.ceil(((d.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n}\n\nexport function getWeekRange(year: number, week: number): { start: string; end: string } {\n const jan4 = new Date(year, 0, 4);\n const dayOfWeek = (jan4.getDay() + 6) % 7;\n const firstMonday = new Date(jan4.getTime() - dayOfWeek * 86400000);\n const start = new Date(firstMonday.getTime() + (week - 1) * 7 * 86400000);\n const end = new Date(start.getTime() + 6 * 86400000);\n const pad = (n: number) => String(n).padStart(2, '0');\n const fmt = (d: Date) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n return { start: fmt(start), end: fmt(end) };\n}\n\nexport function getWeeksInMonth(year: number, month: number): number[] {\n const weeks: Set<number> = new Set();\n const daysInMonth = new Date(year, month, 0).getDate();\n for (let d = 1; d <= daysInMonth; d++) {\n weeks.add(getISOWeek(new Date(year, month - 1, d)));\n }\n return Array.from(weeks).sort((a, b) => a - b);\n}\n\nexport interface MonthWeek {\n index: number;\n startDay: number;\n endDay: number;\n start: string;\n end: string;\n label: string;\n}\n\nexport function getMonthWeeks(year: number, month: number): MonthWeek[] {\n const daysInMonth = new Date(year, month, 0).getDate();\n const pad = (n: number) => String(n).padStart(2, '0');\n const weeks: MonthWeek[] = [];\n let day = 1;\n let index = 1;\n\n while (day <= daysInMonth) {\n const startDay = day;\n const endDay = Math.min(day + 6, daysInMonth);\n const start = `${year}-${pad(month)}-${pad(startDay)}`;\n const end = `${year}-${pad(month)}-${pad(endDay)}`;\n const label = `${index}° Semana (${pad(startDay)}/${pad(month)} - ${pad(endDay)}/${pad(month)})`;\n weeks.push({ index, startDay, endDay, start, end, label });\n day = endDay + 1;\n index++;\n }\n\n return weeks;\n}\n\nexport function parseMonthWeekFromRange(start: string, year: number, month: number): number {\n if (!start) return 1;\n const pad = (n: number) => String(n).padStart(2, '0');\n const dayMatch = start.match(new RegExp(`^${year}-${pad(month)}-(\\\\d{2})`));\n if (!dayMatch) return 1;\n const day = parseInt(dayMatch[1]);\n return Math.ceil(day / 7);\n}\n\nexport function parseMonthFromRange(start: string): { year: number; month: number } | null {\n if (!start) return null;\n const m = start.match(/^(\\d{4})-(\\d{2})/);\n return m ? { year: parseInt(m[1]), month: parseInt(m[2]) } : null;\n}\n\nexport function parseWeekFromRange(start: string): { year: number; week: number } | null {\n if (!start) return null;\n const d = new Date(start + 'T00:00:00');\n if (isNaN(d.getTime())) return null;\n return { year: d.getFullYear(), week: getISOWeek(d) };\n}\n\nexport function getYearRange(dateBounds?: { min: string | null; max: string | null } | null): number[] {\n const now = new Date();\n const minYear = dateBounds?.min ? parseInt(dateBounds.min.slice(0, 4)) : now.getFullYear() - 2;\n const maxYear = dateBounds?.max ? parseInt(dateBounds.max.slice(0, 4)) : now.getFullYear();\n const years: number[] = [];\n for (let y = maxYear; y >= minYear; y--) years.push(y);\n return years;\n}\n","// Purpose: Wrapper react-datepicker para dashboards.\n// Scope: Converte YYYY-MM-DD <-> Date, aplica estilos escopados via .ddp-field.\n// Public API: DashboardDatePicker, isoToDate, dateToIso\n\nimport DatePicker from 'react-datepicker';\nimport 'react-datepicker/dist/react-datepicker.css';\n\n// -------Helpers ISO <-> Date-------\n// Usam local-time para evitar timezone shift (toISOString() converte para UTC).\n\nexport function isoToDate(iso?: string | null): Date | null {\n if (!iso) return null;\n const [y, m, d] = iso.split('-').map(Number);\n if (!y || !m || !d) return null;\n return new Date(y, m - 1, d);\n}\n\nexport function dateToIso(date?: Date | null): string {\n if (!date) return '';\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n// -------Componente-------\n\ninterface Props {\n value: string; // 'YYYY-MM-DD' ou ''\n onChange: (iso: string) => void; // emite '' quando limpo\n minIso?: string | null;\n maxIso?: string | null;\n placeholder?: string;\n selectsStart?: boolean;\n selectsEnd?: boolean;\n startIso?: string | null;\n endIso?: string | null;\n className?: string;\n disabled?: boolean;\n}\n\nexport function DashboardDatePicker({\n value, onChange, minIso, maxIso, placeholder,\n selectsStart, selectsEnd, startIso, endIso, className, disabled,\n}: Props) {\n return (\n <div className={`ddp-field ${className ?? ''}`}>\n <DatePicker\n selected={isoToDate(value)}\n onChange={(d: Date | null) => onChange(dateToIso(d))}\n selectsStart={selectsStart}\n selectsEnd={selectsEnd}\n startDate={isoToDate(startIso) ?? undefined}\n endDate={isoToDate(endIso) ?? undefined}\n minDate={isoToDate(minIso) ?? undefined}\n maxDate={isoToDate(maxIso) ?? undefined}\n dateFormat=\"dd/MM/yyyy\"\n placeholderText={placeholder ?? 'Selecione...'}\n disabled={disabled}\n portalId=\"ddp-portal\"\n popperPlacement=\"bottom-start\"\n popperModifiers={[\n {\n name: 'flip',\n options: { fallbackPlacements: ['bottom-end', 'top-start', 'top-end'] },\n fn: (state) => state,\n },\n ]}\n />\n </div>\n );\n}\n","// Purpose: Seletor categorico com busca por digitacao (selecao unica e multipla).\r\n// Scope: Reaproveitado pelo FilterWidget (runtime) e pelo builder (valor padrao do filtro).\r\n// O proprio campo e a barra de busca (combobox): digitar filtra; a lista abre\r\n// abaixo em portal no document.body (escapa de overflow:hidden e nao rola o widget).\r\n// Formato de valor: unica = string da opcao ('' = Todos); multipla = csv das opcoes.\r\n// Public API: SearchableSelect\r\n\r\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { MULTI_VALUE_SEPARATOR } from '../types';\r\n\r\ninterface Props {\r\n options: string[];\r\n value: string;\r\n multi: boolean;\r\n onChange: (value: string) => void;\r\n}\r\n\r\n// Posicao da lista em coordenadas de viewport (position: fixed)\r\ninterface PanelPos {\r\n left: number;\r\n width: number;\r\n top?: number;\r\n bottom?: number;\r\n maxHeight: number;\r\n}\r\n\r\nexport function SearchableSelect({ options, value, multi, onChange }: Props) {\r\n const [open, setOpen] = useState(false);\r\n const [query, setQuery] = useState('');\r\n const [pos, setPos] = useState<PanelPos | null>(null);\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n\r\n const selected = useMemo(\r\n () => (value ? value.split(MULTI_VALUE_SEPARATOR).filter(Boolean) : []),\r\n [value],\r\n );\r\n\r\n const filtered = useMemo(() => {\r\n const q = query.trim().toLowerCase();\r\n if (!q) return options;\r\n return options.filter((opt) => opt.toLowerCase().includes(q));\r\n }, [options, query]);\r\n\r\n // Recalcula a posicao da lista a partir do retangulo do campo.\r\n // Abre para cima quando nao ha espaco suficiente abaixo.\r\n const reposition = () => {\r\n const el = inputRef.current;\r\n if (!el) return;\r\n const r = el.getBoundingClientRect();\r\n const gap = 4;\r\n const spaceBelow = window.innerHeight - r.bottom - gap;\r\n const spaceAbove = r.top - gap;\r\n const openUp = spaceBelow < 200 && spaceAbove > spaceBelow;\r\n const maxHeight = Math.max(150, Math.min(360, openUp ? spaceAbove : spaceBelow));\r\n setPos({\r\n left: r.left,\r\n width: r.width,\r\n maxHeight,\r\n ...(openUp\r\n ? { bottom: window.innerHeight - r.top + gap }\r\n : { top: r.bottom + gap }),\r\n });\r\n };\r\n\r\n useLayoutEffect(() => {\r\n if (!open) return;\r\n reposition();\r\n const handler = () => reposition();\r\n window.addEventListener('scroll', handler, true);\r\n window.addEventListener('resize', handler);\r\n return () => {\r\n window.removeEventListener('scroll', handler, true);\r\n window.removeEventListener('resize', handler);\r\n };\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [open]);\r\n\r\n // Fecha ao clicar fora — checa o campo e a lista (que vive no portal)\r\n useEffect(() => {\r\n if (!open) return;\r\n const onPointerDown = (e: MouseEvent) => {\r\n const target = e.target as Node;\r\n if (inputRef.current?.contains(target) || panelRef.current?.contains(target)) return;\r\n setOpen(false);\r\n };\r\n document.addEventListener('mousedown', onPointerDown);\r\n return () => document.removeEventListener('mousedown', onPointerDown);\r\n }, [open]);\r\n\r\n const closePanel = () => {\r\n setOpen(false);\r\n setQuery('');\r\n };\r\n\r\n const commitSingle = (opt: string) => {\r\n onChange(opt);\r\n setQuery('');\r\n setOpen(false);\r\n inputRef.current?.blur();\r\n };\r\n\r\n const toggleMulti = (opt: string) => {\r\n const next = selected.includes(opt)\r\n ? selected.filter((s) => s !== opt)\r\n : [...selected, opt];\r\n onChange(next.join(MULTI_VALUE_SEPARATOR));\r\n };\r\n\r\n const handleFocus = () => {\r\n setOpen(true);\r\n // Selecao unica: limpa para digitar; o valor atual volta a aparecer ao fechar\r\n if (!multi) setQuery('');\r\n };\r\n\r\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (e.key === 'Escape') {\r\n closePanel();\r\n inputRef.current?.blur();\r\n } else if (e.key === 'Enter' && filtered.length > 0) {\r\n e.preventDefault();\r\n if (multi) {\r\n toggleMulti(filtered[0]);\r\n setQuery('');\r\n } else {\r\n commitSingle(filtered[0]);\r\n }\r\n }\r\n };\r\n\r\n // Texto do campo: multi sempre mostra a busca; unica mostra o valor quando fechado.\r\n const inputValue = multi ? query : (open ? query : (value || ''));\r\n // Multi vazio = todos (sem filtro). Fechado mostra o estado; aberto convida a buscar.\r\n const placeholder = multi\r\n ? (selected.length > 0 ? `${selected.length} selecionado(s)` : (open ? 'Buscar...' : 'Todos'))\r\n : (open ? 'Buscar...' : 'Todos');\r\n\r\n const panel = open && pos ? createPortal(\r\n <div\r\n ref={panelRef}\r\n className=\"widget-filter__search-panel\"\r\n style={{\r\n position: 'fixed',\r\n left: pos.left,\r\n width: pos.width,\r\n top: pos.top,\r\n bottom: pos.bottom,\r\n maxHeight: pos.maxHeight,\r\n }}\r\n >\r\n <div className=\"widget-filter__search-list\">\r\n {/* Selecao multipla: limpar toda a selecao (vazio = todos) */}\r\n {multi && selected.length > 0 && (\r\n <button\r\n type=\"button\"\r\n className=\"widget-filter__search-clear\"\r\n onClick={() => onChange('')}\r\n >\r\n Limpar seleção\r\n </button>\r\n )}\r\n\r\n {/* Selecao unica: opcao explicita para limpar o filtro */}\r\n {!multi && (\r\n <button\r\n type=\"button\"\r\n className={`widget-filter__search-option${value ? '' : ' is-selected'}`}\r\n onClick={() => commitSingle('')}\r\n >\r\n <span className=\"widget-filter__search-check\" aria-hidden>{value ? '' : '✓'}</span>\r\n Todos\r\n </button>\r\n )}\r\n\r\n {filtered.length === 0 ? (\r\n <span className=\"widget-filter__search-empty\">Nenhuma opção</span>\r\n ) : (\r\n filtered.map((opt) =>\r\n multi ? (\r\n <label\r\n key={opt}\r\n className={`widget-filter__search-option${selected.includes(opt) ? ' is-selected' : ''}`}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={selected.includes(opt)}\r\n onChange={() => toggleMulti(opt)}\r\n />\r\n {opt}\r\n </label>\r\n ) : (\r\n <button\r\n key={opt}\r\n type=\"button\"\r\n className={`widget-filter__search-option${value === opt ? ' is-selected' : ''}`}\r\n onClick={() => commitSingle(opt)}\r\n >\r\n <span className=\"widget-filter__search-check\" aria-hidden>{value === opt ? '✓' : ''}</span>\r\n {opt}\r\n </button>\r\n ),\r\n )\r\n )}\r\n </div>\r\n </div>,\r\n document.body,\r\n ) : null;\r\n\r\n return (\r\n <div className=\"widget-filter__search\">\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n className=\"widget-filter__search-field\"\r\n value={inputValue}\r\n placeholder={placeholder}\r\n onFocus={handleFocus}\r\n onClick={() => setOpen(true)}\r\n onChange={(e) => { setQuery(e.target.value); setOpen(true); }}\r\n onKeyDown={handleKeyDown}\r\n />\r\n {panel}\r\n </div>\r\n );\r\n}\r\n","// Purpose: Seletor de paleta de cores (13 slots semanticos).\n// Scope: Presets pre-definidos + modo customizado com color pickers nomeados por slot.\n// Public API: ColorPaletteSelector\n\nimport {\n PALETTES, ensurePaletteShape, getSeries, SLOT_INDEX, SLOT_LABELS, TOTAL_SLOTS,\n type PaletteKey,\n} from '../palettes';\n\n// Slots de tema usados para a segunda barra de preview do preset\nconst THEME_PREVIEW_SLOTS = [\n SLOT_INDEX.bgDark,\n SLOT_INDEX.bgPaper,\n SLOT_INDEX.bgElevated,\n SLOT_INDEX.accent,\n SLOT_INDEX.success,\n];\n\ninterface Props {\n selected?: string[];\n onSelect: (colors: string[]) => void;\n customMode?: boolean;\n onCustomModeChange?: (custom: boolean) => void;\n disabled?: boolean;\n}\n\nfunction isPreset(colors?: string[]): boolean {\n if (!colors) return true;\n const normalized = ensurePaletteShape(colors);\n return Object.values(PALETTES).some(\n (p) => JSON.stringify(p.colors) === JSON.stringify(normalized)\n );\n}\n\n// Slots agrupados por categoria para a UI customizada\nconst SLOT_ROWS: { label: string; slots: (keyof typeof SLOT_INDEX)[] }[] = [\n { label: 'Series', slots: ['series0', 'series1', 'series2', 'series3', 'series4'] },\n { label: 'Tema', slots: ['bgDark', 'bgPaper', 'bgElevated', 'textPrimary', 'textMuted'] },\n { label: 'Estados', slots: ['accent', 'success', 'error'] },\n];\n\nexport function ColorPaletteSelector({\n selected, onSelect, customMode, onCustomModeChange, disabled,\n}: Props) {\n const isCustom = customMode ?? !isPreset(selected);\n const colors = ensurePaletteShape(selected);\n\n const selectedKey = !isCustom\n ? (Object.entries(PALETTES).find(\n ([, p]) => JSON.stringify(p.colors) === JSON.stringify(colors)\n )?.[0] as PaletteKey | undefined)\n : undefined;\n\n const handleSlotChange = (slotIdx: number, color: string) => {\n const updated = [...colors];\n while (updated.length < TOTAL_SLOTS) updated.push('#000000');\n updated[slotIdx] = color;\n onSelect(updated);\n };\n\n return (\n <div className={`palette-selector ${disabled ? 'palette-selector--disabled' : ''}`}>\n {onCustomModeChange && (\n <label className=\"config-panel__checkbox\">\n <input\n type=\"checkbox\"\n checked={isCustom}\n onChange={(e) => onCustomModeChange(e.target.checked)}\n disabled={disabled}\n />\n Customizar\n </label>\n )}\n\n {isCustom ? (\n <div className=\"palette-selector__custom\">\n {SLOT_ROWS.map((row) => (\n <div key={row.label} className=\"palette-selector__row\">\n <span className=\"palette-selector__row-label\">{row.label}</span>\n <div className=\"palette-selector__row-slots\">\n {row.slots.map((slotName) => {\n const slotIdx = SLOT_INDEX[slotName];\n return (\n <input\n key={slotName}\n type=\"color\"\n className=\"palette-selector__color-input\"\n value={colors[slotIdx] || '#000000'}\n onChange={(e) => handleSlotChange(slotIdx, e.target.value)}\n disabled={disabled}\n title={SLOT_LABELS[slotName]}\n />\n );\n })}\n </div>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"palette-selector__options\">\n {(Object.entries(PALETTES) as [PaletteKey, typeof PALETTES[PaletteKey]][]).map(([key, palette]) => {\n const fullColors = ensurePaletteShape(palette.colors);\n return (\n <button\n key={key}\n className={`palette-selector__option ${selectedKey === key ? 'palette-selector__option--active' : ''}`}\n onClick={() => onSelect(palette.colors)}\n disabled={disabled}\n >\n <div className=\"palette-selector__bar\">\n {getSeries(palette.colors).map((color, i) => (\n <span\n key={i}\n className=\"palette-selector__swatch\"\n style={{ backgroundColor: color }}\n />\n ))}\n </div>\n <div className=\"palette-selector__bar palette-selector__bar--theme\">\n {THEME_PREVIEW_SLOTS.map((slotIdx, i) => (\n <span\n key={i}\n className=\"palette-selector__swatch\"\n style={{ backgroundColor: fullColors[slotIdx] }}\n />\n ))}\n </div>\n <span className=\"palette-selector__label\">{palette.label}</span>\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"],"names":["DEFAULT_API_URL","ENDPOINT_PREFIX","apiUrl","setApiUrl","url","ApiError","message","status","payload","get","path","token","params","k","v","res","fetchLayout","fetchRender","SLOT_INDEX","SERIES_COUNT","TOTAL_SLOTS","SLOT_LABELS","PALETTES","DEFAULT_PALETTE_COLORS","ensurePaletteShape","colors","fallback","result","i","getSeries","getPaletteCssVars","c","DEFAULT_PALETTE","DEFAULT_GRID_COLUMNS","DEFAULT_GRID_ROWS","EMPTY_LAYOUT","WIDGET_TYPE_LABELS","DATA_WIDGET_TYPES","CONTROL_WIDGET_TYPES","CONTROL_WIDGET_SET","TIME_OFFSET_UNIT_LABELS","TIME_OFFSET_WINDOW_LABEL","AGGREGATION_LABELS","FORMAT_LABELS","NUMERIC_FORMAT_OPTIONS","COMPARISON_DISPLAY_LABELS","GOOD_WHEN_LABELS","FILTER_OPERATOR_LABELS","VALUELESS_FILTER_OPERATORS","LIST_FILTER_OPERATORS","CHART_TYPE_LABELS","COMPOSITION_DISPLAY_LABELS","BRIDGE_DIRECTION_LABELS","FILTER_TYPE_LABELS","MULTI_VALUE_SEPARATOR","DEFAULT_GRID","DEFAULT_CONFIG","GRID_GAP_PX","GRID_PADDING_PX","CELL_ASPECT","MIN_CELL_HEIGHT_PX","MAX_CELL_HEIGHT_PX","clamp","value","min","max","isUsable","computeCellWidth","outerWidth","columns","gap","padding","available","computeCellHeight","cellWidth","aspect","computeGridHeight","rows","cellHeight","computeWidgetAspect","w","h","computeStackThreshold","LOCALE","PERCENTAGE_SCALE","NUMERIC_FORMATS","isNumericFormat","format","toNumber","n","formatValue","formatCompact","prefix","abs","MONTH_NAMES_SHORT","MONTH_NAMES_FULL","getFullYearRange","year","parseYearFromRange","start","m","getMonthRange","month","lastDay","pad","getISOWeek","dt","d","yearStart","getWeekRange","week","jan4","dayOfWeek","firstMonday","end","fmt","getWeeksInMonth","weeks","daysInMonth","a","b","getMonthWeeks","day","index","startDay","endDay","label","parseMonthWeekFromRange","dayMatch","parseMonthFromRange","parseWeekFromRange","getYearRange","dateBounds","now","minYear","maxYear","years","y","isoToDate","iso","dateToIso","date","DashboardDatePicker","onChange","minIso","maxIso","placeholder","selectsStart","selectsEnd","startIso","endIso","className","disabled","jsx","DatePicker","state","SearchableSelect","options","multi","open","setOpen","useState","query","setQuery","pos","setPos","inputRef","useRef","panelRef","selected","useMemo","filtered","q","opt","reposition","el","r","spaceBelow","spaceAbove","openUp","maxHeight","useLayoutEffect","handler","useEffect","onPointerDown","e","target","_a","_b","closePanel","commitSingle","toggleMulti","next","s","handleFocus","handleKeyDown","inputValue","panel","createPortal","jsxs","THEME_PREVIEW_SLOTS","isPreset","normalized","p","SLOT_ROWS","ColorPaletteSelector","onSelect","customMode","onCustomModeChange","isCustom","selectedKey","handleSlotChange","slotIdx","color","updated","row","slotName","key","palette","fullColors"],"mappings":"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"}
|