@keenmate/pure-admin-core 2.7.0 → 2.8.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/css/main.css CHANGED
@@ -16651,6 +16651,1752 @@ code {
16651
16651
  height: 0.3rem;
16652
16652
  }
16653
16653
 
16654
+ /* ========================================
16655
+ KPI · shared base
16656
+ Cross-cutting building blocks used by every pa-kpi-* showcase.
16657
+ Tokens (--pa-positive, --pa-detail-bg, --pa-chart-trendline-*) live in
16658
+ _base-css-variables.scss; this file only defines the shared class
16659
+ surface that consumes them.
16660
+ ======================================== */
16661
+ /* ----- LIVE indicator (title-bar pulse) ---------------------------------
16662
+ Used in every KPI card header — a small mono "LIVE" caption with a
16663
+ pulsing green dot. Sits next to the card title. */
16664
+ .pa-kpi-live {
16665
+ display: inline-flex;
16666
+ align-items: center;
16667
+ gap: 0.6rem;
16668
+ font-family: var(--base-font-family-mono);
16669
+ font-size: 1.2rem;
16670
+ font-weight: 600;
16671
+ letter-spacing: 0.06em;
16672
+ color: var(--pa-text-secondary);
16673
+ }
16674
+ .pa-kpi-live__dot {
16675
+ width: 0.8rem;
16676
+ height: 0.8rem;
16677
+ border-radius: 50%;
16678
+ background: var(--pa-positive);
16679
+ box-shadow: 0 0 6px var(--pa-positive);
16680
+ animation: pa-kpi-pulse 1.6s ease-in-out infinite;
16681
+ }
16682
+
16683
+ @keyframes pa-kpi-pulse {
16684
+ 50% {
16685
+ opacity: 0.35;
16686
+ }
16687
+ }
16688
+ /* ----- Card header row --------------------------------------------------
16689
+ Title (h2/h3 by author choice) on one side, controls + LIVE on the other.
16690
+ Wraps onto multiple rows on narrow cards. Every showcase uses this shape. */
16691
+ .pa-kpi-header {
16692
+ display: flex;
16693
+ justify-content: space-between;
16694
+ align-items: center;
16695
+ gap: 1.6rem;
16696
+ flex-wrap: wrap;
16697
+ }
16698
+
16699
+ /* ----- Card footer caption ---------------------------------------------
16700
+ Two-line mono caption row at the bottom of the card (left: data source,
16701
+ right: timestamp). Strong text inside picks up the focal color so things
16702
+ like a metric name or count stand out. */
16703
+ .pa-kpi-footer {
16704
+ display: flex;
16705
+ justify-content: space-between;
16706
+ align-items: center;
16707
+ flex-wrap: wrap;
16708
+ gap: 1rem;
16709
+ font-family: var(--base-font-family-mono);
16710
+ font-size: 1.2rem;
16711
+ color: var(--pa-text-secondary);
16712
+ }
16713
+ .pa-kpi-footer strong {
16714
+ color: var(--pa-text-color-1);
16715
+ font-weight: 700;
16716
+ }
16717
+
16718
+ /* ----- Sparkline endpoint dot ------------------------------------------
16719
+ The SVG circle that marks the end of a sparkline is converted to a CSS
16720
+ span at init time — the SVG uses preserveAspectRatio="none" so an
16721
+ embedded <circle> renders as an oval at non-square aspect ratios.
16722
+ See kpi-showcases.js for the conversion; here we only style the result. */
16723
+ .pa-kpi-spark-dot {
16724
+ position: absolute;
16725
+ width: 6px;
16726
+ height: 6px;
16727
+ margin: -3px 0 0 -3px; /* centre on the (left, top) anchor */
16728
+ border-radius: 50%;
16729
+ background: currentColor; /* inherits sentiment color from chart wrapper */
16730
+ pointer-events: none;
16731
+ }
16732
+
16733
+ /* Wrapper inserted around an SVG sparkline at init time when its parent
16734
+ isn't already a positioned anchor — so the .pa-kpi-spark-dot can be
16735
+ absolutely positioned relative to the chart. */
16736
+ .pa-kpi-spark-wrap {
16737
+ display: block;
16738
+ position: relative;
16739
+ width: 100%;
16740
+ }
16741
+
16742
+ /* ----- Hover detail popover --------------------------------------------
16743
+ Bloomberg-dark by default regardless of host theme (terminal/data-dashboard
16744
+ aesthetic). Override the --pa-detail-* tokens at :root or .pa-kpi-detail
16745
+ level for a light/theme-aware variant.
16746
+
16747
+ Positioned by Floating UI anchored to a virtual element at the cursor —
16748
+ the JS appends each popover to <body> at init so ancestor overflow:hidden
16749
+ doesn't clip it. position: fixed because cursor coords are viewport-
16750
+ relative; pointer-events:none so the cursor passes through cleanly and
16751
+ tile mouseleave fires reliably. */
16752
+ .pa-kpi-detail {
16753
+ position: fixed;
16754
+ top: 0;
16755
+ left: 0;
16756
+ visibility: hidden;
16757
+ pointer-events: none;
16758
+ z-index: 9000;
16759
+ min-width: 26rem;
16760
+ max-width: 32rem;
16761
+ background: var(--pa-detail-bg);
16762
+ color: var(--pa-detail-text);
16763
+ padding: 1.2rem 1.5rem;
16764
+ font-family: var(--base-font-family-mono);
16765
+ font-size: 1.25rem;
16766
+ line-height: 1.5;
16767
+ border-radius: 0.4rem;
16768
+ box-shadow: var(--pa-detail-shadow);
16769
+ }
16770
+ .pa-kpi-detail[data-show] {
16771
+ visibility: visible;
16772
+ }
16773
+ .pa-kpi-detail__title {
16774
+ text-transform: uppercase;
16775
+ letter-spacing: 0.08em;
16776
+ font-size: 1.05rem;
16777
+ font-weight: 700;
16778
+ color: var(--pa-detail-title);
16779
+ margin-bottom: 0.6rem;
16780
+ }
16781
+ .pa-kpi-detail dl {
16782
+ display: grid;
16783
+ grid-template-columns: 1fr auto;
16784
+ gap: 0.35rem 1.6rem;
16785
+ margin: 0;
16786
+ }
16787
+ .pa-kpi-detail dt {
16788
+ margin: 0;
16789
+ color: var(--pa-detail-row-label);
16790
+ font-weight: 400;
16791
+ }
16792
+ .pa-kpi-detail dd {
16793
+ margin: 0;
16794
+ text-align: end;
16795
+ font-weight: 600;
16796
+ font-variant-numeric: tabular-nums;
16797
+ }
16798
+ .pa-kpi-detail {
16799
+ /* Inline sentiment hints for dd content (e.g. <dd>+12% <span class="pos">…</span></dd>) */
16800
+ }
16801
+ .pa-kpi-detail .pos {
16802
+ color: var(--pa-positive);
16803
+ }
16804
+ .pa-kpi-detail .neg {
16805
+ color: var(--pa-negative);
16806
+ }
16807
+ .pa-kpi-detail .warn {
16808
+ color: var(--pa-warning);
16809
+ }
16810
+
16811
+ /* ----- Section heading strip used outside card chrome -------------------
16812
+ The 7 showcases each render a "stress-test" section that places tiles
16813
+ directly inside .pa-col-* page-grid cells (no card wrapper). The strip
16814
+ above those layouts hosts a label or LIVE indicator at the row's end. */
16815
+ .pa-kpi-sectionhead {
16816
+ display: flex;
16817
+ justify-content: flex-end;
16818
+ align-items: center;
16819
+ gap: 1.6rem;
16820
+ margin-bottom: 1.2rem;
16821
+ }
16822
+
16823
+ /* ========================================
16824
+ KPI · Terminal grid
16825
+ Bloomberg-style dense panel: mono numbers, status pills, inline SVG
16826
+ sparklines, ▲▼ deltas, optional segmented tab strip for swapping
16827
+ the body content (different tile sets / grids per tab).
16828
+ Shared chrome (header, live, footer, detail popover, spark-dot) is in
16829
+ _kpi-base.scss.
16830
+ ======================================== */
16831
+ /* ----- Tab strip (segmented button group) ------------------------------
16832
+ Generalised tabs — each `.pa-kpi-terminal__tab` carries a `data-tab`
16833
+ slug that matches a `.pa-kpi-terminal__pane[data-tab="…"]` in the body.
16834
+ JS toggles `.is-active` on the clicked tab + matching pane; tabs and
16835
+ panes are otherwise independent so each pane can hold a completely
16836
+ different grid (different tile count, different grid modifier). */
16837
+ .pa-kpi-terminal__controls {
16838
+ display: inline-flex;
16839
+ align-items: center;
16840
+ gap: 1.6rem;
16841
+ }
16842
+
16843
+ .pa-kpi-terminal__tabs {
16844
+ display: inline-flex;
16845
+ border: 1px solid var(--pa-border-color);
16846
+ border-radius: 0.4rem;
16847
+ overflow: hidden;
16848
+ }
16849
+
16850
+ .pa-kpi-terminal__tab {
16851
+ background: transparent;
16852
+ border: 0;
16853
+ color: var(--pa-text-color-2);
16854
+ padding: 0.4rem 1.1rem;
16855
+ font-family: var(--base-font-family-mono);
16856
+ font-size: 1.1rem;
16857
+ font-weight: 600;
16858
+ letter-spacing: 0.06em;
16859
+ cursor: pointer;
16860
+ transition: background-color 0.1s ease-out, color 0.1s ease-out;
16861
+ }
16862
+ .pa-kpi-terminal__tab:hover {
16863
+ color: var(--pa-text-color-1);
16864
+ }
16865
+ .pa-kpi-terminal__tab.is-active {
16866
+ background: var(--pa-text-color-1);
16867
+ color: var(--pa-card-bg);
16868
+ }
16869
+
16870
+ /* ----- Pane visibility ------------------------------------------------- */
16871
+ .pa-kpi-terminal__pane {
16872
+ display: none;
16873
+ }
16874
+ .pa-kpi-terminal__pane.is-active {
16875
+ display: block;
16876
+ }
16877
+
16878
+ /* ----- Grid + tile borders ----------------------------------------------
16879
+ Hairline 1px borders between tiles, no gap. Last-row/last-column
16880
+ borders suppressed via :nth-last-child / :nth-child selectors. */
16881
+ .pa-kpi-terminal__body {
16882
+ padding: 0;
16883
+ }
16884
+
16885
+ .pa-kpi-terminal__grid {
16886
+ display: grid;
16887
+ grid-template-columns: repeat(2, 1fr);
16888
+ }
16889
+ .pa-kpi-terminal__grid .pa-kpi-tile {
16890
+ border-bottom: 1px solid var(--pa-border-color);
16891
+ border-right: 1px solid var(--pa-border-color);
16892
+ }
16893
+
16894
+ .pa-kpi-terminal__grid--2col .pa-kpi-tile:nth-child(2n) {
16895
+ border-right: 0;
16896
+ }
16897
+ .pa-kpi-terminal__grid--2col .pa-kpi-tile:nth-last-child(-n+2) {
16898
+ border-bottom: 0;
16899
+ }
16900
+
16901
+ /* ----- Tile (per-KPI panel) --------------------------------------------- */
16902
+ .pa-kpi-tile {
16903
+ position: relative;
16904
+ padding: 1.4rem 1.8rem 1.6rem;
16905
+ min-height: 16rem;
16906
+ display: flex;
16907
+ flex-direction: column;
16908
+ /* Standalone modifier: tile lives directly inside a .pa-col-* (no
16909
+ neighbour cells in a parent grid) — gets a full border + card bg so
16910
+ it doesn't look orphaned. */
16911
+ }
16912
+ .pa-kpi-tile--standalone {
16913
+ background: var(--pa-card-bg);
16914
+ border: 1px solid var(--pa-border-color);
16915
+ margin-bottom: 1.2rem;
16916
+ }
16917
+ .pa-kpi-tile--standalone:last-child {
16918
+ margin-bottom: 0;
16919
+ }
16920
+
16921
+ /* ----- Tile head: ID · period + status pill ----------------------------- */
16922
+ .pa-kpi-tile__head {
16923
+ display: flex;
16924
+ justify-content: space-between;
16925
+ align-items: center;
16926
+ font-family: var(--base-font-family-mono);
16927
+ font-size: 1.3rem;
16928
+ letter-spacing: 0.04em;
16929
+ margin-bottom: 0.3rem;
16930
+ }
16931
+
16932
+ .pa-kpi-tile__id {
16933
+ color: var(--pa-text-tertiary);
16934
+ font-weight: 600;
16935
+ }
16936
+
16937
+ .pa-kpi-tile__status {
16938
+ font-family: var(--base-font-family-mono);
16939
+ font-size: 1.2rem;
16940
+ font-weight: 700;
16941
+ letter-spacing: 0.08em;
16942
+ padding: 0.3rem 0.9rem;
16943
+ line-height: 1.3;
16944
+ }
16945
+ .pa-kpi-tile__status--warn {
16946
+ background: var(--pa-warning-bg);
16947
+ color: var(--pa-btn-warning-text);
16948
+ }
16949
+ .pa-kpi-tile__status {
16950
+ /* GOOD is the "default" state — text-only, no chrome */
16951
+ }
16952
+ .pa-kpi-tile__status--good {
16953
+ background: transparent;
16954
+ color: var(--pa-text-color-1);
16955
+ padding: 0.2rem 0;
16956
+ }
16957
+ .pa-kpi-tile__status--neutral {
16958
+ background: color-mix(in srgb, var(--pa-text-color-2) 25%, transparent);
16959
+ color: var(--pa-text-color-1);
16960
+ }
16961
+
16962
+ /* ----- Label ------------------------------------------------------------ */
16963
+ .pa-kpi-tile__label {
16964
+ font-family: var(--base-font-family-mono);
16965
+ font-size: 1.4rem;
16966
+ font-weight: 700;
16967
+ letter-spacing: 0.1em;
16968
+ text-transform: uppercase;
16969
+ color: var(--pa-text-strong);
16970
+ margin-bottom: 0.8rem;
16971
+ }
16972
+
16973
+ /* ----- Big value -------------------------------------------------------
16974
+ One value per tile — sentiment colour set via `--very-positive` /
16975
+ `--positive` / `--neutral` / `--negative` / `--very-negative` modifier
16976
+ on the value element. */
16977
+ .pa-kpi-tile__values {
16978
+ margin-bottom: 0.4rem;
16979
+ }
16980
+
16981
+ .pa-kpi-tile__value {
16982
+ display: inline-flex;
16983
+ align-items: baseline;
16984
+ gap: 0.3rem;
16985
+ font-family: var(--base-font-family-mono);
16986
+ line-height: 1;
16987
+ }
16988
+ .pa-kpi-tile__value--very-positive .pa-kpi-tile__num {
16989
+ color: var(--pa-very-positive);
16990
+ }
16991
+ .pa-kpi-tile__value--positive .pa-kpi-tile__num {
16992
+ color: var(--pa-positive);
16993
+ }
16994
+ .pa-kpi-tile__value--neutral .pa-kpi-tile__num {
16995
+ color: var(--pa-neutral);
16996
+ }
16997
+ .pa-kpi-tile__value--negative .pa-kpi-tile__num {
16998
+ color: var(--pa-negative);
16999
+ }
17000
+ .pa-kpi-tile__value--very-negative .pa-kpi-tile__num {
17001
+ color: var(--pa-very-negative);
17002
+ }
17003
+
17004
+ .pa-kpi-tile__num {
17005
+ font-size: 3.8rem;
17006
+ font-weight: 700;
17007
+ letter-spacing: -0.02em;
17008
+ color: var(--pa-text-color-1);
17009
+ }
17010
+
17011
+ .pa-kpi-tile__unit {
17012
+ font-size: 1.6rem;
17013
+ font-weight: 500;
17014
+ color: var(--pa-text-secondary);
17015
+ }
17016
+
17017
+ /* ----- Previous-value + delta row -------------------------------------- */
17018
+ .pa-kpi-tile__prev {
17019
+ display: flex;
17020
+ justify-content: space-between;
17021
+ align-items: center;
17022
+ font-family: var(--base-font-family-mono);
17023
+ font-size: 1.3rem;
17024
+ margin-top: auto; /* push to bottom of flex column */
17025
+ margin-bottom: 0.4rem;
17026
+ color: var(--pa-text-tertiary);
17027
+ }
17028
+
17029
+ .pa-kpi-tile__delta--very-positive {
17030
+ color: var(--pa-very-positive);
17031
+ }
17032
+ .pa-kpi-tile__delta--positive {
17033
+ color: var(--pa-positive);
17034
+ }
17035
+ .pa-kpi-tile__delta--neutral {
17036
+ color: var(--pa-neutral);
17037
+ }
17038
+ .pa-kpi-tile__delta--negative {
17039
+ color: var(--pa-negative);
17040
+ }
17041
+ .pa-kpi-tile__delta--very-negative {
17042
+ color: var(--pa-very-negative);
17043
+ }
17044
+
17045
+ /* ----- Sparkline -------------------------------------------------------- */
17046
+ .pa-kpi-tile__spark {
17047
+ display: block;
17048
+ width: 100%;
17049
+ height: var(--pa-chart-trendline-height);
17050
+ overflow: visible;
17051
+ }
17052
+ .pa-kpi-tile__spark polyline {
17053
+ fill: none;
17054
+ stroke: currentColor;
17055
+ stroke-width: var(--pa-chart-trendline-stroke);
17056
+ stroke-linecap: round;
17057
+ stroke-linejoin: round;
17058
+ }
17059
+
17060
+ /* Sentiment-coloured sparkline. Class names use up/down wording but pick
17061
+ colours from the sentiment-of-the-change axis, not line shape — so an
17062
+ error-rate metric whose line is falling but the change is good uses
17063
+ --up. See showcase docs for the rationale. Colour is set on both the
17064
+ SVG and the JS-inserted .pa-kpi-spark-wrap so currentColor resolves
17065
+ for the SVG content (line) and the HTML dot (inside the wrap). */
17066
+ .pa-kpi-tile--up-strong .pa-kpi-tile__spark, .pa-kpi-tile--up-strong .pa-kpi-spark-wrap {
17067
+ color: var(--pa-very-positive);
17068
+ }
17069
+ .pa-kpi-tile--up .pa-kpi-tile__spark, .pa-kpi-tile--up .pa-kpi-spark-wrap {
17070
+ color: var(--pa-positive);
17071
+ }
17072
+ .pa-kpi-tile--flat .pa-kpi-tile__spark, .pa-kpi-tile--flat .pa-kpi-spark-wrap {
17073
+ color: var(--pa-neutral);
17074
+ }
17075
+ .pa-kpi-tile--down .pa-kpi-tile__spark, .pa-kpi-tile--down .pa-kpi-spark-wrap {
17076
+ color: var(--pa-negative);
17077
+ }
17078
+ .pa-kpi-tile--down-strong .pa-kpi-tile__spark, .pa-kpi-tile--down-strong .pa-kpi-spark-wrap {
17079
+ color: var(--pa-very-negative);
17080
+ }
17081
+
17082
+ /* ========================================
17083
+ KPI · Sparkline list
17084
+ Each KPI is one row: label · sparkline · value · Δ%. Built for vertical
17085
+ scanning rather than per-tile depth — no view-mode toggle, no status
17086
+ pills. Container queries collapse 4-col → 2-row → 3-row as the card
17087
+ narrows.
17088
+
17089
+ Row template uses local SCSS variables for the four column widths
17090
+ (`$spark-col-label`, `$spark-col-chart`, `$spark-col-value`,
17091
+ `$spark-col-delta`) so all responsive overrides reference the same
17092
+ widths — change one and every breakpoint follows. The `--no-delta`
17093
+ modifier drops the rightmost column; the other three are load-bearing
17094
+ (a sparkline list without label, chart, or value is a different
17095
+ design).
17096
+ ======================================== */
17097
+ /* Per-column track widths — referenced from every template selector. */
17098
+ /* Card is a query container so rows react to *card* width, not viewport. */
17099
+ .pa-kpi-spark-list {
17100
+ container-type: inline-size;
17101
+ }
17102
+
17103
+ .pa-kpi-spark-list__body {
17104
+ padding: 0;
17105
+ }
17106
+
17107
+ /* ----- Row: wide 4-column grid (label · chart · value · delta) ---------- */
17108
+ .pa-kpi-spark-row {
17109
+ display: grid;
17110
+ grid-template-columns: minmax(14rem, 28%) minmax(10rem, 1fr) minmax(8rem, 18%) minmax(7rem, 12%);
17111
+ align-items: center;
17112
+ gap: 1.6rem;
17113
+ padding: 1.4rem 2rem;
17114
+ border-bottom: 1px solid var(--pa-border-color);
17115
+ }
17116
+ .pa-kpi-spark-row:last-child {
17117
+ border-bottom: 0;
17118
+ }
17119
+
17120
+ /* Modifier: --no-delta — drops the rightmost column. label · chart ·
17121
+ value only. Useful when the chart's slope already conveys direction
17122
+ and the delta would be redundant. Hides the delta element and shrinks
17123
+ the row template to 3 columns. */
17124
+ .pa-kpi-spark-list--no-delta .pa-kpi-spark-row {
17125
+ grid-template-columns: minmax(14rem, 28%) minmax(10rem, 1fr) minmax(8rem, 18%);
17126
+ }
17127
+
17128
+ .pa-kpi-spark-list--no-delta .pa-kpi-spark-row__delta {
17129
+ display: none;
17130
+ }
17131
+
17132
+ /* Mid-narrow card (1×3 page-grid + 45% column): stack to 2 rows.
17133
+ Label/value/delta on top, full-width chart below. Default order is
17134
+ value-above-chart; use .pa-kpi-spark-list--chart-first to flip. */
17135
+ @container (max-width: 640px) {
17136
+ .pa-kpi-spark-row {
17137
+ grid-template-columns: minmax(0, 1fr) auto auto;
17138
+ grid-template-rows: auto auto;
17139
+ grid-template-areas: "label value delta" "chart chart chart";
17140
+ column-gap: 1.2rem;
17141
+ row-gap: 0.4rem;
17142
+ align-items: baseline;
17143
+ padding: 1.2rem 1.6rem;
17144
+ }
17145
+ .pa-kpi-spark-row__label {
17146
+ grid-area: label;
17147
+ align-self: center;
17148
+ font-size: 1.25rem;
17149
+ }
17150
+ .pa-kpi-spark-row__value {
17151
+ grid-area: value;
17152
+ }
17153
+ .pa-kpi-spark-row__delta {
17154
+ grid-area: delta;
17155
+ font-size: 1.25rem;
17156
+ }
17157
+ .pa-kpi-spark-row__chart {
17158
+ grid-area: chart;
17159
+ }
17160
+ .pa-kpi-spark-row__num {
17161
+ font-size: 2rem;
17162
+ }
17163
+ /* --chart-first: rotates the canonical L→R order 90°. Label on top,
17164
+ chart in the middle, value+delta side-by-side at the bottom. */
17165
+ .pa-kpi-spark-list--chart-first .pa-kpi-spark-row {
17166
+ grid-template-columns: 1fr auto;
17167
+ grid-template-rows: auto auto auto;
17168
+ grid-template-areas: "label label" "chart chart" "value delta";
17169
+ row-gap: 0.5rem;
17170
+ column-gap: 1rem;
17171
+ padding: 1.2rem 1.6rem;
17172
+ }
17173
+ .pa-kpi-spark-list--chart-first .pa-kpi-spark-row__label {
17174
+ align-self: start;
17175
+ }
17176
+ .pa-kpi-spark-list--chart-first .pa-kpi-spark-row__value {
17177
+ text-align: start;
17178
+ align-self: baseline;
17179
+ }
17180
+ .pa-kpi-spark-list--chart-first .pa-kpi-spark-row__delta {
17181
+ align-self: baseline;
17182
+ }
17183
+ /* --no-delta at mid-narrow: 2-row layout, top row is label+value only. */
17184
+ .pa-kpi-spark-list--no-delta .pa-kpi-spark-row {
17185
+ grid-template-columns: minmax(0, 1fr) auto;
17186
+ grid-template-areas: "label value" "chart chart";
17187
+ }
17188
+ /* --no-delta + --chart-first: 3-row single-column stack. */
17189
+ .pa-kpi-spark-list--no-delta.pa-kpi-spark-list--chart-first .pa-kpi-spark-row {
17190
+ grid-template-columns: 1fr;
17191
+ grid-template-areas: "label" "chart" "value";
17192
+ }
17193
+ }
17194
+ /* Very narrow card (~280–360px, 25% page-grid stress test): force the
17195
+ chart-first 3-row layout regardless of modifier. */
17196
+ @container (max-width: 360px) {
17197
+ .pa-kpi-spark-row {
17198
+ grid-template-columns: 1fr auto;
17199
+ grid-template-rows: auto auto auto;
17200
+ grid-template-areas: "label label" "chart chart" "value delta";
17201
+ row-gap: 0.5rem;
17202
+ column-gap: 1rem;
17203
+ padding: 1.2rem 1.4rem;
17204
+ }
17205
+ .pa-kpi-spark-row__label {
17206
+ grid-area: label;
17207
+ align-self: start;
17208
+ }
17209
+ .pa-kpi-spark-row__chart {
17210
+ grid-area: chart;
17211
+ }
17212
+ .pa-kpi-spark-row__value {
17213
+ grid-area: value;
17214
+ text-align: start;
17215
+ align-self: baseline;
17216
+ }
17217
+ .pa-kpi-spark-row__delta {
17218
+ grid-area: delta;
17219
+ align-self: baseline;
17220
+ }
17221
+ /* --no-delta at very-narrow: 3-row single-column stack (no delta cell). */
17222
+ .pa-kpi-spark-list--no-delta .pa-kpi-spark-row {
17223
+ grid-template-columns: 1fr;
17224
+ grid-template-areas: "label" "chart" "value";
17225
+ }
17226
+ }
17227
+ /* ----- Cell typography -------------------------------------------------- */
17228
+ .pa-kpi-spark-row__label {
17229
+ font-family: var(--base-font-family-mono);
17230
+ font-size: 1.4rem;
17231
+ font-weight: 700;
17232
+ letter-spacing: 0.1em;
17233
+ text-transform: uppercase;
17234
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17235
+ }
17236
+
17237
+ /* Sparkline cell — line + filled area + trailing dot (the dot is rendered
17238
+ as a CSS span by the JS init pass; see kpi-showcases.js). */
17239
+ .pa-kpi-spark-row__chart {
17240
+ position: relative; /* anchor for .pa-kpi-spark-dot */
17241
+ }
17242
+ .pa-kpi-spark-row__chart svg {
17243
+ display: block;
17244
+ width: 100%;
17245
+ height: var(--pa-chart-trendline-height);
17246
+ overflow: visible;
17247
+ }
17248
+ .pa-kpi-spark-row__chart polyline {
17249
+ fill: none;
17250
+ stroke: currentColor;
17251
+ stroke-width: var(--pa-chart-trendline-stroke);
17252
+ stroke-linecap: round;
17253
+ stroke-linejoin: round;
17254
+ }
17255
+ .pa-kpi-spark-row__chart polygon {
17256
+ fill: currentColor;
17257
+ fill-opacity: 0.18; /* same hue as line, soft area shading */
17258
+ stroke: none;
17259
+ }
17260
+
17261
+ /* Sentiment-coloured sparkline. Color is set on the chart wrapper so
17262
+ currentColor resolves for both the SVG content (line/area) and the
17263
+ dot inside the wrapper. */
17264
+ .pa-kpi-spark-row--up-strong .pa-kpi-spark-row__chart {
17265
+ color: var(--pa-very-positive);
17266
+ }
17267
+ .pa-kpi-spark-row--up .pa-kpi-spark-row__chart {
17268
+ color: var(--pa-positive);
17269
+ }
17270
+ .pa-kpi-spark-row--flat .pa-kpi-spark-row__chart {
17271
+ color: var(--pa-neutral);
17272
+ }
17273
+ .pa-kpi-spark-row--down .pa-kpi-spark-row__chart {
17274
+ color: var(--pa-negative);
17275
+ }
17276
+ .pa-kpi-spark-row--down-strong .pa-kpi-spark-row__chart {
17277
+ color: var(--pa-very-negative);
17278
+ }
17279
+
17280
+ /* ----- Value (focal white number + muted unit) ------------------------- */
17281
+ .pa-kpi-spark-row__value {
17282
+ font-family: var(--base-font-family-mono);
17283
+ text-align: end;
17284
+ line-height: 1;
17285
+ }
17286
+
17287
+ .pa-kpi-spark-row__num {
17288
+ font-size: 2.6rem;
17289
+ font-weight: 700;
17290
+ letter-spacing: -0.02em;
17291
+ color: var(--pa-text-color-1);
17292
+ }
17293
+
17294
+ .pa-kpi-spark-row__unit {
17295
+ font-size: 1.3rem;
17296
+ font-weight: 500;
17297
+ color: var(--pa-text-secondary);
17298
+ margin-left: 0.2rem;
17299
+ }
17300
+
17301
+ /* ----- Delta (sentiment-coloured) -------------------------------------- */
17302
+ .pa-kpi-spark-row__delta {
17303
+ font-family: var(--base-font-family-mono);
17304
+ font-size: 1.4rem;
17305
+ font-weight: 600;
17306
+ text-align: end;
17307
+ font-variant-numeric: tabular-nums;
17308
+ }
17309
+ .pa-kpi-spark-row__delta--very-positive {
17310
+ color: var(--pa-very-positive);
17311
+ }
17312
+ .pa-kpi-spark-row__delta--positive {
17313
+ color: var(--pa-positive);
17314
+ }
17315
+ .pa-kpi-spark-row__delta--neutral {
17316
+ color: var(--pa-neutral);
17317
+ }
17318
+ .pa-kpi-spark-row__delta--negative {
17319
+ color: var(--pa-negative);
17320
+ }
17321
+ .pa-kpi-spark-row__delta--very-negative {
17322
+ color: var(--pa-very-negative);
17323
+ }
17324
+
17325
+ /* ========================================
17326
+ KPI · Comparison gauges
17327
+ Goal-oriented progress bars. Each KPI shows label · value, a bar with a
17328
+ target tick, and a 0 · tgt scale below. Bar fill = value/target * 100%,
17329
+ capped visually so overshoots are signalled by colour, not overflow.
17330
+
17331
+ Layout is a cell-min-driven `auto-fit` grid — cells stay at least
17332
+ `--pa-kpi-gauge-cell-min` wide, the grid fits as many columns as the
17333
+ container allows, and the responsive cascade is intrinsic to the grid
17334
+ template (no `@container` queries). `--max-N` cap modifiers cap the
17335
+ column count at N while still collapsing below the cell-min × N
17336
+ threshold. Same pattern as `_kpi-editorial-minimal.scss`.
17337
+ ======================================== */
17338
+ .pa-kpi-gauge-list__body {
17339
+ padding: 0;
17340
+ }
17341
+
17342
+ /* ----- Grid + hairline rules -------------------------------------------
17343
+ Cell-min-driven responsive layout. Override `--pa-kpi-gauge-cell-min`
17344
+ per instance to change density (smaller min → more columns at the same
17345
+ container width).
17346
+
17347
+ `gap: 1px` over `background: var(--pa-border-color)` with each tile
17348
+ painting `background: var(--pa-card-bg)` on top — only the gap shows
17349
+ through, giving single-pixel hairlines on every interior boundary
17350
+ regardless of column count. The card's outer border supplies the
17351
+ perimeter. Replaces the previous per-tile `border-right` +
17352
+ `border-bottom` + nth-child suppression machinery, which only worked
17353
+ for the hardcoded 2-col layout. */
17354
+ .pa-kpi-gauge-list__grid {
17355
+ display: grid;
17356
+ grid-template-columns: repeat(auto-fit, minmax(var(--pa-kpi-gauge-cell-min, 20rem), 1fr));
17357
+ gap: 1px;
17358
+ background: var(--pa-border-color);
17359
+ }
17360
+
17361
+ /* Modifier: force exactly 2 columns regardless of cell-min or container
17362
+ width. For placements wanting a deterministic 2×N layout. */
17363
+ .pa-kpi-gauge-list__grid--2col {
17364
+ grid-template-columns: repeat(2, 1fr);
17365
+ }
17366
+
17367
+ /* Cap-at-N modifiers: combine auto-fit with a ceiling on the column
17368
+ count. Cells stay at least --pa-kpi-gauge-cell-min wide, but the grid
17369
+ never exceeds N columns even when the container is wide enough to fit
17370
+ more. Below the cell-min × N threshold the grid still collapses
17371
+ responsively — these modifiers cap the maximum, not the minimum.
17372
+
17373
+ How the calc reads: each track's effective min is
17374
+ max(cell-min, (container − total-gap) / N)
17375
+ On a wide container the calc wins (so tracks grow, you stay at N).
17376
+ On a narrow container cell-min wins (so the grid collapses).
17377
+
17378
+ Pick the cap so your item count divides into clean rows. */
17379
+ .pa-kpi-gauge-list__grid--max-2 {
17380
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-gauge-cell-min, 20rem), (100% - 1px) / 2), 1fr));
17381
+ }
17382
+
17383
+ .pa-kpi-gauge-list__grid--max-3 {
17384
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-gauge-cell-min, 20rem), (100% - 2px) / 3), 1fr));
17385
+ }
17386
+
17387
+ .pa-kpi-gauge-list__grid--max-4 {
17388
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-gauge-cell-min, 20rem), (100% - 3px) / 4), 1fr));
17389
+ }
17390
+
17391
+ .pa-kpi-gauge-list__grid--max-5 {
17392
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-gauge-cell-min, 20rem), (100% - 4px) / 5), 1fr));
17393
+ }
17394
+
17395
+ .pa-kpi-gauge-list__grid--max-6 {
17396
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-gauge-cell-min, 20rem), (100% - 5px) / 6), 1fr));
17397
+ }
17398
+
17399
+ /* ----- Gauge tile (label/value head · bar · 0/tgt scale) ---------------- */
17400
+ .pa-kpi-gauge {
17401
+ position: relative;
17402
+ background: var(--pa-card-bg);
17403
+ padding: 1.6rem 2rem;
17404
+ min-width: 0;
17405
+ /* Per-tile bar colour cascade — modifiers below set the var, the fill
17406
+ reads it. Cleaner than per-modifier-per-element rules; host apps can
17407
+ override at the tile level via inline style="--pa-kpi-bar-color: …". */
17408
+ --pa-kpi-bar-color: var(--pa-positive);
17409
+ }
17410
+ .pa-kpi-gauge--positive {
17411
+ --pa-kpi-bar-color: var(--pa-positive);
17412
+ }
17413
+ .pa-kpi-gauge--warning {
17414
+ --pa-kpi-bar-color: var(--pa-warning);
17415
+ }
17416
+ .pa-kpi-gauge--negative {
17417
+ --pa-kpi-bar-color: var(--pa-negative);
17418
+ }
17419
+ .pa-kpi-gauge--neutral {
17420
+ --pa-kpi-bar-color: color-mix(in srgb, var(--pa-text-color-1) 70%, transparent);
17421
+ }
17422
+
17423
+ /* ----- Head: label left, value right (baseline-aligned) ----------------- */
17424
+ .pa-kpi-gauge__head {
17425
+ display: flex;
17426
+ justify-content: space-between;
17427
+ align-items: baseline;
17428
+ gap: 1.2rem;
17429
+ margin-bottom: 0.8rem;
17430
+ }
17431
+
17432
+ .pa-kpi-gauge__label {
17433
+ font-family: var(--base-font-family-mono);
17434
+ font-size: 1.4rem;
17435
+ font-weight: 700;
17436
+ letter-spacing: 0.1em;
17437
+ text-transform: uppercase;
17438
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17439
+ }
17440
+
17441
+ .pa-kpi-gauge__value {
17442
+ font-family: var(--base-font-family-mono);
17443
+ line-height: 1;
17444
+ }
17445
+
17446
+ .pa-kpi-gauge__num {
17447
+ font-size: 2.6rem;
17448
+ font-weight: 700;
17449
+ letter-spacing: -0.02em;
17450
+ color: var(--pa-text-color-1);
17451
+ }
17452
+
17453
+ .pa-kpi-gauge__unit {
17454
+ font-size: 1.3rem;
17455
+ font-weight: 500;
17456
+ color: var(--pa-text-secondary);
17457
+ margin-left: 0.2rem;
17458
+ }
17459
+
17460
+ /* ----- Bar (track + sentiment-coloured fill + target tick) -------------- */
17461
+ .pa-kpi-gauge__bar {
17462
+ /* Author-controlled tick position (default 100% — the target sits at the
17463
+ right edge of the bar's "0 → target" scale). Override per-tile via
17464
+ style="--pa-kpi-gauge-tick-pos: 80%" if the bar represents a wider
17465
+ scale where the target sits inside the bar. */
17466
+ --pa-kpi-gauge-tick-pos: 100%;
17467
+ --pa-kpi-gauge-tick-color: var(--pa-text-color-1);
17468
+ position: relative;
17469
+ height: 0.7rem;
17470
+ background: var(--pa-surface-track);
17471
+ margin-bottom: 0.5rem;
17472
+ overflow: visible; /* tick can sit just outside the track */
17473
+ /* Target tick — small bar slightly taller than the track. Centred on
17474
+ --pa-kpi-gauge-tick-pos via the negative margin-left (matches half
17475
+ the tick width). Full opacity so it stays readable on dark themes
17476
+ against bright orange/green fills. */
17477
+ }
17478
+ .pa-kpi-gauge__bar::after {
17479
+ content: "";
17480
+ position: absolute;
17481
+ left: var(--pa-kpi-gauge-tick-pos);
17482
+ margin-left: -0.15rem;
17483
+ top: -0.2rem;
17484
+ bottom: -0.2rem;
17485
+ width: 0.3rem;
17486
+ background: var(--pa-kpi-gauge-tick-color);
17487
+ }
17488
+
17489
+ .pa-kpi-gauge__fill {
17490
+ height: 100%;
17491
+ background: var(--pa-kpi-bar-color);
17492
+ /* Width set inline per tile via style="width: X%". */
17493
+ transition: width 0.3s ease;
17494
+ }
17495
+
17496
+ /* ----- Scale row (0 left · tgt XYZ right) ------------------------------- */
17497
+ .pa-kpi-gauge__scale {
17498
+ display: flex;
17499
+ justify-content: space-between;
17500
+ font-family: var(--base-font-family-mono);
17501
+ font-size: 1.2rem;
17502
+ color: var(--pa-text-tertiary);
17503
+ }
17504
+
17505
+ /* ========================================
17506
+ KPI · Hero + supporting
17507
+ Marketing/exec dashboard pattern: one headline metric on the left (huge
17508
+ container-query-relative value, inline meta row, big filled-area
17509
+ sparkline), and a vertical rail of compact supporting tiles on the
17510
+ right. Container query collapses to single column on narrow cards.
17511
+ ======================================== */
17512
+ .pa-kpi-hero-list {
17513
+ container-type: inline-size;
17514
+ }
17515
+
17516
+ .pa-kpi-hero-list__body {
17517
+ padding: 1.6rem;
17518
+ }
17519
+
17520
+ /* ----- Layout: hero left, rail right ------------------------------------
17521
+ Default split is 1:1 (50% hero / 50% rail). Modifiers below shift the
17522
+ weight to the hero, which is the more common "executive dashboard"
17523
+ shape — one big headline, supporting tiles compressed into a narrower
17524
+ rail. Pick a modifier per instance; the markup stays unchanged. */
17525
+ .pa-kpi-hero-list__layout {
17526
+ display: grid;
17527
+ grid-template-columns: 1fr 1fr;
17528
+ gap: 1.4rem;
17529
+ }
17530
+
17531
+ /* Hero 2/3, rail 1/3. */
17532
+ .pa-kpi-hero-list__layout--hero-2-3 {
17533
+ grid-template-columns: 2fr 1fr;
17534
+ }
17535
+
17536
+ /* Hero 3/4, rail 1/4 — hero-dominant; rail is a thin sidebar. */
17537
+ .pa-kpi-hero-list__layout--hero-3-4 {
17538
+ grid-template-columns: 3fr 1fr;
17539
+ }
17540
+
17541
+ /* Narrow card → stack to single column. Overrides any --hero-N-M modifier
17542
+ that lives on the same element. */
17543
+ @container (max-width: 700px) {
17544
+ .pa-kpi-hero-list__layout {
17545
+ grid-template-columns: 1fr;
17546
+ }
17547
+ }
17548
+ .pa-kpi-hero-list__rail {
17549
+ display: flex;
17550
+ flex-direction: column;
17551
+ gap: 1rem;
17552
+ }
17553
+
17554
+ /* ----- HERO panel (label · big value · meta row · sparkline) ------------ */
17555
+ .pa-kpi-hero-main {
17556
+ position: relative;
17557
+ padding: 1.8rem 2rem;
17558
+ border: 1px solid var(--pa-border-color);
17559
+ display: flex;
17560
+ flex-direction: column;
17561
+ gap: 0.6rem;
17562
+ /* Sentiment cascade — chart and delta inherit via currentColor. */
17563
+ --pa-kpi-accent: var(--pa-positive);
17564
+ }
17565
+ .pa-kpi-hero-main--positive {
17566
+ --pa-kpi-accent: var(--pa-positive);
17567
+ }
17568
+ .pa-kpi-hero-main--negative {
17569
+ --pa-kpi-accent: var(--pa-negative);
17570
+ }
17571
+ .pa-kpi-hero-main--neutral {
17572
+ --pa-kpi-accent: var(--pa-neutral);
17573
+ }
17574
+ .pa-kpi-hero-main--up-strong {
17575
+ --pa-kpi-accent: var(--pa-very-positive);
17576
+ }
17577
+
17578
+ .pa-kpi-hero-main__label {
17579
+ font-family: var(--base-font-family-mono);
17580
+ font-size: 1.4rem;
17581
+ font-weight: 700;
17582
+ letter-spacing: 0.1em;
17583
+ text-transform: uppercase;
17584
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17585
+ }
17586
+
17587
+ .pa-kpi-hero-main__value {
17588
+ display: inline-flex;
17589
+ align-items: baseline;
17590
+ font-family: var(--base-font-family-mono);
17591
+ line-height: 1;
17592
+ margin: 0.4rem 0 0.6rem;
17593
+ }
17594
+
17595
+ .pa-kpi-hero-main__num {
17596
+ /* Container-query-relative: scales with the hero panel's width.
17597
+ Floor keeps it readable in narrow page-grid cards. */
17598
+ font-size: clamp(4rem, 17cqi, 7rem);
17599
+ font-weight: 700;
17600
+ letter-spacing: -0.02em;
17601
+ color: var(--pa-text-color-1);
17602
+ }
17603
+
17604
+ .pa-kpi-hero-main__unit {
17605
+ font-size: clamp(1.8rem, 8cqi, 3rem);
17606
+ font-weight: 500;
17607
+ color: var(--pa-text-secondary);
17608
+ margin: 0 0.1rem;
17609
+ }
17610
+
17611
+ /* Meta row: inline delta + period text + target on one baseline. */
17612
+ .pa-kpi-hero-main__meta {
17613
+ display: grid;
17614
+ grid-template-columns: auto minmax(0, 1fr) auto;
17615
+ align-items: baseline;
17616
+ gap: 0.4rem 1.4rem;
17617
+ font-family: var(--base-font-family-mono);
17618
+ font-size: 1.3rem;
17619
+ }
17620
+
17621
+ .pa-kpi-hero-main__delta {
17622
+ display: inline-flex;
17623
+ align-items: baseline;
17624
+ gap: 0.4rem;
17625
+ color: var(--pa-kpi-accent);
17626
+ font-weight: 700;
17627
+ font-size: 1.5rem;
17628
+ line-height: 1.2;
17629
+ }
17630
+
17631
+ .pa-kpi-hero-main__period {
17632
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17633
+ line-height: 1.3;
17634
+ }
17635
+
17636
+ .pa-kpi-hero-main__target {
17637
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
17638
+ text-align: end;
17639
+ }
17640
+
17641
+ /* Hero sparkline — chart container fills extra vertical space (when the
17642
+ rail forces a tall row); SVG inside stays at fixed pixel height so the
17643
+ line shape is never distorted along Y. The SVG uses
17644
+ preserveAspectRatio="none", so any element that should keep its shape
17645
+ needs to live outside that scaling or have fixed pixel dimensions. */
17646
+ .pa-kpi-hero-main__chart {
17647
+ flex: 1 1 10rem;
17648
+ min-height: 10rem;
17649
+ margin-top: 0.6rem;
17650
+ color: var(--pa-kpi-accent);
17651
+ display: flex;
17652
+ align-items: flex-end; /* SVG wrap pinned to bottom */
17653
+ }
17654
+ .pa-kpi-hero-main__chart polyline {
17655
+ fill: none;
17656
+ stroke: currentColor;
17657
+ stroke-width: var(--pa-chart-trendline-stroke);
17658
+ stroke-linecap: round;
17659
+ stroke-linejoin: round;
17660
+ }
17661
+ .pa-kpi-hero-main__chart polygon {
17662
+ fill: currentColor;
17663
+ fill-opacity: 0.18;
17664
+ stroke: none;
17665
+ }
17666
+
17667
+ .pa-kpi-hero-main__chart-svg {
17668
+ position: relative;
17669
+ display: block;
17670
+ width: 100%;
17671
+ height: var(--pa-chart-trendline-height);
17672
+ }
17673
+ .pa-kpi-hero-main__chart-svg svg {
17674
+ display: block;
17675
+ width: 100%;
17676
+ height: 100%;
17677
+ overflow: visible;
17678
+ }
17679
+
17680
+ /* ----- SIDE rail tile (2×2 grid, value spans both rows on right) -------- */
17681
+ .pa-kpi-hero-side {
17682
+ position: relative;
17683
+ padding: 1.2rem 1.4rem;
17684
+ border: 1px solid var(--pa-border-color);
17685
+ display: grid;
17686
+ grid-template-columns: minmax(0, 1fr) auto;
17687
+ grid-template-areas: "label value" "delta value";
17688
+ column-gap: 1.2rem;
17689
+ row-gap: 0.4rem;
17690
+ align-items: center;
17691
+ --pa-kpi-accent: var(--pa-positive);
17692
+ }
17693
+ .pa-kpi-hero-side--positive {
17694
+ --pa-kpi-accent: var(--pa-positive);
17695
+ }
17696
+ .pa-kpi-hero-side--negative {
17697
+ --pa-kpi-accent: var(--pa-negative);
17698
+ }
17699
+ .pa-kpi-hero-side--neutral {
17700
+ --pa-kpi-accent: var(--pa-neutral);
17701
+ }
17702
+ .pa-kpi-hero-side--up-strong {
17703
+ --pa-kpi-accent: var(--pa-very-positive);
17704
+ }
17705
+
17706
+ .pa-kpi-hero-side__label {
17707
+ grid-area: label;
17708
+ align-self: end; /* tucks against the vertically-centred value */
17709
+ font-family: var(--base-font-family-mono);
17710
+ font-size: 1.3rem;
17711
+ font-weight: 700;
17712
+ letter-spacing: 0.1em;
17713
+ text-transform: uppercase;
17714
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17715
+ line-height: 1.25;
17716
+ }
17717
+
17718
+ .pa-kpi-hero-side__value {
17719
+ grid-area: value;
17720
+ align-self: center;
17721
+ font-family: var(--base-font-family-mono);
17722
+ line-height: 1;
17723
+ white-space: nowrap;
17724
+ display: inline-flex;
17725
+ align-items: baseline;
17726
+ }
17727
+
17728
+ .pa-kpi-hero-side__num {
17729
+ font-size: 2.4rem;
17730
+ font-weight: 700;
17731
+ letter-spacing: -0.02em;
17732
+ color: var(--pa-text-color-1);
17733
+ }
17734
+
17735
+ .pa-kpi-hero-side__unit {
17736
+ font-size: 1.5rem;
17737
+ font-weight: 500;
17738
+ color: var(--pa-text-secondary);
17739
+ margin: 0 0.35rem;
17740
+ }
17741
+
17742
+ .pa-kpi-hero-side__delta {
17743
+ grid-area: delta;
17744
+ align-self: start;
17745
+ font-family: var(--base-font-family-mono);
17746
+ font-size: 1.2rem;
17747
+ font-weight: 600;
17748
+ color: var(--pa-kpi-accent);
17749
+ }
17750
+
17751
+ /* ========================================
17752
+ KPI · Bento layout
17753
+ Magazine-style asymmetric tile sizing with sparklines as soft background
17754
+ fills behind the values. Default 6-tile layout on a 6-col × 3-row grid
17755
+ (hero left-half × 2 rows, two stacked right-half × 2 rows, three equal
17756
+ tiles bottom row). Tile placement is by source order via :nth-child, so
17757
+ markup stays identical across layout modifiers.
17758
+
17759
+ Layout modifiers (below) swap `grid-template-areas` to provide
17760
+ alternative compositions:
17761
+ · default (no modifier) — 6 tiles, hero on the left
17762
+ · `--hero-right` — 6 tiles, mirror of default (hero on right)
17763
+ · `--5-tile` — 5 tiles, hero + 4 supporting
17764
+ Row height is a CSS variable (`--pa-kpi-bento-row-height`, default
17765
+ `12rem`) so authors can dial tile height per instance.
17766
+ ======================================== */
17767
+ .pa-kpi-bento {
17768
+ container-type: inline-size;
17769
+ --pa-kpi-bento-row-height: 12rem;
17770
+ }
17771
+
17772
+ .pa-kpi-bento__body {
17773
+ padding: 1.6rem;
17774
+ }
17775
+
17776
+ /* ----- Bento grid (default: 6 tiles, hero on left) ---------------------- */
17777
+ .pa-kpi-bento__grid {
17778
+ display: grid;
17779
+ grid-template-columns: repeat(6, 1fr);
17780
+ grid-template-rows: repeat(3, var(--pa-kpi-bento-row-height));
17781
+ grid-template-areas: "hero hero hero a a a" "hero hero hero b b b" "c c d d e e";
17782
+ gap: 1rem;
17783
+ }
17784
+ .pa-kpi-bento__grid > :nth-child(1) {
17785
+ grid-area: hero;
17786
+ }
17787
+ .pa-kpi-bento__grid > :nth-child(2) {
17788
+ grid-area: a;
17789
+ }
17790
+ .pa-kpi-bento__grid > :nth-child(3) {
17791
+ grid-area: b;
17792
+ }
17793
+ .pa-kpi-bento__grid > :nth-child(4) {
17794
+ grid-area: c;
17795
+ }
17796
+ .pa-kpi-bento__grid > :nth-child(5) {
17797
+ grid-area: d;
17798
+ }
17799
+ .pa-kpi-bento__grid > :nth-child(6) {
17800
+ grid-area: e;
17801
+ }
17802
+
17803
+ /* Modifier: --hero-right — mirror of default. Hero on the right half,
17804
+ two stacked tiles on the left of rows 1-2, three equal tiles below.
17805
+ Same 6-tile contract as default; only the template flips. Source
17806
+ order stays unchanged (1st = hero, 2nd = a, …). */
17807
+ .pa-kpi-bento__grid--hero-right {
17808
+ grid-template-areas: "a a a hero hero hero" "b b b hero hero hero" "c c d d e e";
17809
+ }
17810
+
17811
+ /* Modifier: --5-tile — hero + 4 supporting. Hero spans the left half ×
17812
+ 2 rows, two stacked tiles on the right (rows 1-2), two equal halves on
17813
+ the bottom row. Requires exactly 5 tiles — a 6th tile (if present)
17814
+ would be auto-placed in a new row and break the layout. */
17815
+ .pa-kpi-bento__grid--5-tile {
17816
+ grid-template-areas: "hero hero hero a a a" "hero hero hero b b b" "c c c d d d";
17817
+ }
17818
+
17819
+ /* Narrow card → stack everything single column. Resets `grid-area: auto`
17820
+ on every tile so the same markup works regardless of which layout
17821
+ modifier the grid carries (the @container override sets
17822
+ `grid-template-areas: none` and the `grid-area: auto` on nth-child
17823
+ together neutralise any modifier's template). */
17824
+ @container (max-width: 700px) {
17825
+ .pa-kpi-bento__grid {
17826
+ grid-template-columns: 1fr;
17827
+ grid-template-rows: auto;
17828
+ grid-template-areas: none;
17829
+ gap: 0.8rem;
17830
+ }
17831
+ .pa-kpi-bento__grid > :nth-child(n) {
17832
+ grid-area: auto;
17833
+ }
17834
+ .pa-kpi-bento-tile {
17835
+ min-height: 10rem;
17836
+ }
17837
+ .pa-kpi-bento-tile--hero {
17838
+ min-height: 14rem;
17839
+ }
17840
+ }
17841
+ /* ----- Tile (per-KPI bento cell) ---------------------------------------- */
17842
+ .pa-kpi-bento-tile {
17843
+ /* Per-tile inline-size container so the value font-size scales with
17844
+ *this* tile's width via cqi (not the outer card's width). The hero
17845
+ and the smaller bottom tiles each scale to their own column. */
17846
+ container-type: inline-size;
17847
+ position: relative;
17848
+ overflow: hidden;
17849
+ padding: 1.3rem 1.5rem;
17850
+ border: 1px solid var(--pa-border-color);
17851
+ background: var(--pa-card-bg);
17852
+ display: grid;
17853
+ grid-template-columns: minmax(0, 1fr) auto;
17854
+ grid-template-rows: auto 1fr auto;
17855
+ grid-template-areas: "label delta" ". . " "value value";
17856
+ gap: 0.4rem 1rem;
17857
+ /* Sparkline + delta sentiment cascade via currentColor. */
17858
+ --pa-kpi-accent: var(--pa-positive);
17859
+ }
17860
+ .pa-kpi-bento-tile--positive {
17861
+ --pa-kpi-accent: var(--pa-positive);
17862
+ }
17863
+ .pa-kpi-bento-tile--negative {
17864
+ --pa-kpi-accent: var(--pa-negative);
17865
+ }
17866
+ .pa-kpi-bento-tile--neutral {
17867
+ --pa-kpi-accent: var(--pa-neutral);
17868
+ }
17869
+ .pa-kpi-bento-tile--up-strong {
17870
+ --pa-kpi-accent: var(--pa-very-positive);
17871
+ }
17872
+ .pa-kpi-bento-tile--down-strong {
17873
+ --pa-kpi-accent: var(--pa-very-negative);
17874
+ }
17875
+ .pa-kpi-bento-tile--hero {
17876
+ padding: 1.6rem 1.8rem;
17877
+ }
17878
+ .pa-kpi-bento-tile--hero .pa-kpi-bento-tile__num {
17879
+ font-size: clamp(3.6rem, 22cqi, 7rem);
17880
+ }
17881
+ .pa-kpi-bento-tile--hero .pa-kpi-bento-tile__unit {
17882
+ font-size: clamp(1.6rem, 9cqi, 2.6rem);
17883
+ }
17884
+ .pa-kpi-bento-tile--hero .pa-kpi-bento-tile__label,
17885
+ .pa-kpi-bento-tile--hero .pa-kpi-bento-tile__delta {
17886
+ font-size: 1.4rem;
17887
+ }
17888
+ .pa-kpi-bento-tile--hero .pa-kpi-bento-tile__chart {
17889
+ height: 70%;
17890
+ }
17891
+
17892
+ /* ----- Top row: label + delta, both layered over the chart -------------- */
17893
+ .pa-kpi-bento-tile__label {
17894
+ grid-area: label;
17895
+ font-family: var(--base-font-family-mono);
17896
+ font-size: 1.3rem;
17897
+ font-weight: 700;
17898
+ letter-spacing: 0.1em;
17899
+ text-transform: uppercase;
17900
+ color: color-mix(in srgb, var(--pa-text-color-1) 60%, transparent);
17901
+ z-index: 1;
17902
+ line-height: 1.2;
17903
+ }
17904
+
17905
+ .pa-kpi-bento-tile__delta {
17906
+ grid-area: delta;
17907
+ font-family: var(--base-font-family-mono);
17908
+ font-size: 1.3rem;
17909
+ font-weight: 700;
17910
+ color: var(--pa-kpi-accent);
17911
+ z-index: 1;
17912
+ align-self: start;
17913
+ line-height: 1.2;
17914
+ }
17915
+
17916
+ /* ----- Value (bottom of grid, layered over chart) ----------------------- */
17917
+ .pa-kpi-bento-tile__value {
17918
+ grid-area: value;
17919
+ align-self: end;
17920
+ position: relative;
17921
+ z-index: 1;
17922
+ font-family: var(--base-font-family-mono);
17923
+ display: inline-flex;
17924
+ align-items: baseline;
17925
+ line-height: 1;
17926
+ white-space: nowrap;
17927
+ }
17928
+
17929
+ .pa-kpi-bento-tile__num {
17930
+ font-size: clamp(2rem, 14cqi, 3.2rem);
17931
+ font-weight: 700;
17932
+ letter-spacing: -0.02em;
17933
+ color: var(--pa-text-color-1);
17934
+ }
17935
+
17936
+ .pa-kpi-bento-tile__unit {
17937
+ font-size: clamp(1.2rem, 7cqi, 1.6rem);
17938
+ font-weight: 500;
17939
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
17940
+ margin: 0 0.3rem;
17941
+ }
17942
+
17943
+ /* ----- Sparkline background ---------------------------------------------
17944
+ Absolutely positioned, fills the bottom 65% of the tile. The value sits
17945
+ over it (z-index: 1 above). The line/area read through behind the
17946
+ digits at lower opacity so the value remains the focal point. SVG is
17947
+ nested in a fixed-height wrapper so taller tiles don't distort the line
17948
+ shape (preserveAspectRatio="none" would otherwise stretch the Y axis). */
17949
+ .pa-kpi-bento-tile__chart {
17950
+ position: absolute;
17951
+ left: 0;
17952
+ right: 0;
17953
+ bottom: 0;
17954
+ height: 65%;
17955
+ pointer-events: none;
17956
+ color: var(--pa-kpi-accent);
17957
+ z-index: 0;
17958
+ display: flex;
17959
+ align-items: flex-end;
17960
+ }
17961
+ .pa-kpi-bento-tile__chart svg {
17962
+ display: block;
17963
+ width: 100%;
17964
+ height: 100%;
17965
+ overflow: visible;
17966
+ }
17967
+ .pa-kpi-bento-tile__chart polyline {
17968
+ fill: none;
17969
+ stroke: currentColor;
17970
+ stroke-opacity: 0.55;
17971
+ stroke-width: var(--pa-chart-trendline-stroke);
17972
+ stroke-linecap: round;
17973
+ stroke-linejoin: round;
17974
+ }
17975
+ .pa-kpi-bento-tile__chart polygon {
17976
+ fill: currentColor;
17977
+ fill-opacity: 0.1;
17978
+ stroke: none;
17979
+ }
17980
+
17981
+ .pa-kpi-bento-tile__chart-svg {
17982
+ position: relative;
17983
+ display: block;
17984
+ width: 100%;
17985
+ height: var(--pa-chart-trendline-height);
17986
+ }
17987
+
17988
+ /* ========================================
17989
+ KPI · Numeric strip (densest)
17990
+ Tabular "spreadsheet-style" table card with metric / now / prev / Δ% /
17991
+ target columns — most data per pixel, no chart chrome. Each row is its
17992
+ own grid sharing the same column template so cells align across rows
17993
+ without needing subgrid. Wide-only by design — no responsive collapse;
17994
+ narrow placements should use Comparison gauges instead.
17995
+
17996
+ Column contract: `metric` + `now` are always present; `prev`, `delta`,
17997
+ and `target` are independently optional via toggle modifiers on the
17998
+ strip (`--no-prev`, `--no-delta`, `--no-target`). Modifiers compose, so
17999
+ the visible column count ranges from 2 (all three optional columns
18000
+ dropped) to 5 (none dropped). Each combination has its own template
18001
+ selector below so the grid tracks always match the visible cell count.
18002
+ ======================================== */
18003
+ /* Per-column track widths — referenced from every template selector. */
18004
+ .pa-kpi-strip__body {
18005
+ padding: 0;
18006
+ }
18007
+
18008
+ /* ----- Table layout ----------------------------------------------------- */
18009
+ .pa-kpi-strip__row,
18010
+ .pa-kpi-strip__head-row {
18011
+ display: grid;
18012
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.6fr);
18013
+ column-gap: 1.6rem;
18014
+ align-items: center;
18015
+ position: relative;
18016
+ padding: 1.1rem 1.6rem;
18017
+ }
18018
+
18019
+ /* Divider between data rows / between head and first row only. */
18020
+ .pa-kpi-strip__row + .pa-kpi-strip__row,
18021
+ .pa-kpi-strip__head-row + .pa-kpi-strip__row {
18022
+ border-top: 1px solid var(--pa-border-color);
18023
+ }
18024
+
18025
+ /* Hover host: subtle row highlight so the cursor-anchored popover has a
18026
+ clear "this row" anchor. */
18027
+ .pa-kpi-strip__row:hover {
18028
+ background: var(--pa-surface-hover);
18029
+ }
18030
+
18031
+ /* ----- Header cells (uppercase mono captions) --------------------------- */
18032
+ .pa-kpi-strip__head {
18033
+ font-family: var(--base-font-family-mono);
18034
+ font-size: 1.1rem;
18035
+ font-weight: 700;
18036
+ letter-spacing: 0.1em;
18037
+ text-transform: uppercase;
18038
+ color: var(--pa-text-tertiary);
18039
+ }
18040
+ .pa-kpi-strip__head--num {
18041
+ text-align: end;
18042
+ }
18043
+
18044
+ /* ----- Metric label ----------------------------------------------------- */
18045
+ .pa-kpi-strip__metric {
18046
+ font-family: var(--base-font-family-mono);
18047
+ font-size: 1.4rem;
18048
+ font-weight: 700;
18049
+ letter-spacing: 0.08em;
18050
+ text-transform: uppercase;
18051
+ color: color-mix(in srgb, var(--pa-text-color-1) 78%, transparent);
18052
+ line-height: 1.2;
18053
+ }
18054
+
18055
+ /* ----- NOW (focal value) ------------------------------------------------ */
18056
+ .pa-kpi-strip__now {
18057
+ font-family: var(--base-font-family-mono);
18058
+ font-size: 1.8rem;
18059
+ font-weight: 700;
18060
+ text-align: end;
18061
+ display: flex;
18062
+ align-items: baseline;
18063
+ justify-content: flex-end;
18064
+ color: var(--pa-text-color-1);
18065
+ white-space: nowrap;
18066
+ line-height: 1;
18067
+ }
18068
+ .pa-kpi-strip__now .pa-kpi-strip__num {
18069
+ font-weight: 700;
18070
+ }
18071
+ .pa-kpi-strip__now .pa-kpi-strip__unit {
18072
+ font-size: 1.1rem;
18073
+ font-weight: 500;
18074
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
18075
+ margin: 0 0.2rem;
18076
+ }
18077
+
18078
+ /* ----- PREV (reference data, low contrast) ------------------------------ */
18079
+ .pa-kpi-strip__prev {
18080
+ font-family: var(--base-font-family-mono);
18081
+ font-size: 1.5rem;
18082
+ font-weight: 500;
18083
+ color: var(--pa-text-tertiary);
18084
+ text-align: end;
18085
+ white-space: nowrap;
18086
+ }
18087
+
18088
+ /* ----- Δ% (sentiment-coloured) ------------------------------------------ */
18089
+ .pa-kpi-strip__delta {
18090
+ font-family: var(--base-font-family-mono);
18091
+ font-size: 1.5rem;
18092
+ font-weight: 700;
18093
+ text-align: end;
18094
+ white-space: nowrap;
18095
+ color: var(--pa-positive);
18096
+ }
18097
+ .pa-kpi-strip__delta--positive {
18098
+ color: var(--pa-positive);
18099
+ }
18100
+ .pa-kpi-strip__delta--negative {
18101
+ color: var(--pa-negative);
18102
+ }
18103
+ .pa-kpi-strip__delta--neutral {
18104
+ color: var(--pa-neutral);
18105
+ }
18106
+ .pa-kpi-strip__delta--up-strong {
18107
+ color: var(--pa-very-positive);
18108
+ }
18109
+ .pa-kpi-strip__delta--down-strong {
18110
+ color: var(--pa-very-negative);
18111
+ }
18112
+
18113
+ /* ----- VS TARGET (bar + pct stacked, capped at 100% visual) -------------
18114
+ Theme-neutral grey fill — the pct value itself signals overshoot /
18115
+ undershoot ("97" vs "108" vs "54") so colour reinforcement isn't
18116
+ needed. The bar visually caps at 100% via overflow: hidden so an
18117
+ over-target metric reads as "fully filled" rather than overflowing. */
18118
+ .pa-kpi-strip__target {
18119
+ display: flex;
18120
+ flex-direction: column;
18121
+ gap: 0.35rem;
18122
+ }
18123
+
18124
+ .pa-kpi-strip__bar {
18125
+ position: relative;
18126
+ height: 0.5rem;
18127
+ background: var(--pa-surface-track);
18128
+ overflow: hidden;
18129
+ border-radius: 0.1rem;
18130
+ }
18131
+
18132
+ .pa-kpi-strip__fill {
18133
+ position: absolute;
18134
+ top: 0;
18135
+ left: 0;
18136
+ bottom: 0;
18137
+ background: color-mix(in srgb, var(--pa-text-color-1) 40%, transparent);
18138
+ }
18139
+
18140
+ .pa-kpi-strip__bar-pct {
18141
+ font-family: var(--base-font-family-mono);
18142
+ font-size: 1.05rem;
18143
+ font-weight: 600;
18144
+ color: var(--pa-text-secondary);
18145
+ align-self: flex-end;
18146
+ line-height: 1;
18147
+ }
18148
+
18149
+ /* ----- Toggle modifiers ------------------------------------------------
18150
+ `--no-prev`, `--no-delta`, `--no-target` are independently composable.
18151
+ Each hides its column's cells (data + header) and the matching template
18152
+ selector below adjusts `grid-template-columns` to the visible cell
18153
+ count, so source order (metric, now, prev, delta, target) is preserved
18154
+ and the remaining cells slot into the right tracks.
18155
+
18156
+ `metric` and `now` are mandatory — no toggle drops them. If a strip
18157
+ doesn't need a focal value, it's a different design (use comparison
18158
+ gauges or editorial-minimal). */
18159
+ .pa-kpi-strip--no-prev .pa-kpi-strip__prev,
18160
+ .pa-kpi-strip--no-prev .pa-kpi-strip__head--prev {
18161
+ display: none;
18162
+ }
18163
+
18164
+ .pa-kpi-strip--no-delta .pa-kpi-strip__delta,
18165
+ .pa-kpi-strip--no-delta .pa-kpi-strip__head--delta {
18166
+ display: none;
18167
+ }
18168
+
18169
+ .pa-kpi-strip--no-target .pa-kpi-strip__target,
18170
+ .pa-kpi-strip--no-target .pa-kpi-strip__head--target {
18171
+ display: none;
18172
+ }
18173
+
18174
+ /* ----- Grid templates per visible-column combination -------------------
18175
+ 8 combos (1 default + 3 single-drops + 3 double-drops + 1 triple-drop).
18176
+ Each lists the visible columns in source order with their declared
18177
+ `$strip-col-*` width. */
18178
+ /* 4-col: one optional column dropped */
18179
+ .pa-kpi-strip--no-prev .pa-kpi-strip__row,
18180
+ .pa-kpi-strip--no-prev .pa-kpi-strip__head-row {
18181
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1.6fr);
18182
+ }
18183
+
18184
+ .pa-kpi-strip--no-delta .pa-kpi-strip__row,
18185
+ .pa-kpi-strip--no-delta .pa-kpi-strip__head-row {
18186
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1.6fr);
18187
+ }
18188
+
18189
+ .pa-kpi-strip--no-target .pa-kpi-strip__row,
18190
+ .pa-kpi-strip--no-target .pa-kpi-strip__head-row {
18191
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr);
18192
+ }
18193
+
18194
+ /* 3-col: two optional columns dropped */
18195
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-delta .pa-kpi-strip__row,
18196
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-delta .pa-kpi-strip__head-row {
18197
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1.6fr);
18198
+ }
18199
+
18200
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-target .pa-kpi-strip__row,
18201
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-target .pa-kpi-strip__head-row {
18202
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr);
18203
+ }
18204
+
18205
+ .pa-kpi-strip--no-delta.pa-kpi-strip--no-target .pa-kpi-strip__row,
18206
+ .pa-kpi-strip--no-delta.pa-kpi-strip--no-target .pa-kpi-strip__head-row {
18207
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) minmax(0, 1fr);
18208
+ }
18209
+
18210
+ /* 2-col: all three optional columns dropped (metric + now only) */
18211
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-delta.pa-kpi-strip--no-target .pa-kpi-strip__row,
18212
+ .pa-kpi-strip--no-prev.pa-kpi-strip--no-delta.pa-kpi-strip--no-target .pa-kpi-strip__head-row {
18213
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr);
18214
+ }
18215
+
18216
+ /* ========================================
18217
+ KPI · Editorial minimal
18218
+ KPI tiles in a responsive grid with hairline rules between cells,
18219
+ generous space, and an extra-light-weight number as the focal point per
18220
+ tile. No charts, no pills — the design's whole identity is the thin
18221
+ numeral. Renders as a table card (zero card-body padding) so hairlines
18222
+ go edge-to-edge.
18223
+ ======================================== */
18224
+ .pa-kpi-edit__body {
18225
+ padding: 0;
18226
+ }
18227
+
18228
+ /* ----- Grid + hairline rules -------------------------------------------
18229
+ Cell-min-driven responsive layout: cells stay at least
18230
+ --pa-kpi-edit-cell-min wide; the grid fits as many columns as the
18231
+ container allows. No @container queries — `auto-fit + minmax` handles
18232
+ the cascade intrinsically. Override the min per instance to change
18233
+ density (smaller min → more columns at the same container width).
18234
+
18235
+ `gap: 1px` over `background: var(--pa-border-color)` with each tile
18236
+ painting `background: var(--pa-card-bg)` on top — only the gap shows
18237
+ through, giving single-pixel hairlines on every interior boundary
18238
+ regardless of column count. The card's outer border supplies the
18239
+ perimeter. */
18240
+ .pa-kpi-edit__grid {
18241
+ display: grid;
18242
+ grid-template-columns: repeat(auto-fit, minmax(var(--pa-kpi-edit-cell-min, 14rem), 1fr));
18243
+ gap: 1px;
18244
+ background: var(--pa-border-color);
18245
+ }
18246
+
18247
+ /* Modifier: force exactly 2 columns regardless of cell-min or container
18248
+ width. For placements wanting a deterministic 2×N layout (e.g. 4 tiles
18249
+ as a clean 2×2 even when the container is wide enough for more). */
18250
+ .pa-kpi-edit__grid--2col {
18251
+ grid-template-columns: repeat(2, 1fr);
18252
+ }
18253
+
18254
+ /* Cap-at-N modifiers: combine auto-fit with a ceiling on the column
18255
+ count. Cells stay at least --pa-kpi-edit-cell-min wide, but the grid
18256
+ never exceeds N columns even when the container is wide enough to fit
18257
+ more. Below the cell-min × N threshold the grid still collapses
18258
+ responsively — these modifiers cap the maximum, not the minimum.
18259
+
18260
+ How the calc reads: each track's effective min is
18261
+ max(cell-min, (container − total-gap) / N)
18262
+ On a wide container the calc wins (so tracks grow, you stay at N).
18263
+ On a narrow container cell-min wins (so the grid collapses).
18264
+
18265
+ Why this matters for the gray-void edge case: `auto-fit` keeps as many
18266
+ tracks as fit the container, then only collapses tracks empty across
18267
+ the *whole* grid. With 6 items at 4-col auto-fit, tracks 1–4 all have
18268
+ row-1 items, so row 2's tracks 3–4 stay (and show the gap background).
18269
+ Capping at 3 makes 6 items pack 3×2 cleanly. Pick the cap so your item
18270
+ count divides into clean rows. */
18271
+ .pa-kpi-edit__grid--max-2 {
18272
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-edit-cell-min, 14rem), (100% - 1px) / 2), 1fr));
18273
+ }
18274
+
18275
+ .pa-kpi-edit__grid--max-3 {
18276
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-edit-cell-min, 14rem), (100% - 2px) / 3), 1fr));
18277
+ }
18278
+
18279
+ .pa-kpi-edit__grid--max-4 {
18280
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-edit-cell-min, 14rem), (100% - 3px) / 4), 1fr));
18281
+ }
18282
+
18283
+ .pa-kpi-edit__grid--max-5 {
18284
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-edit-cell-min, 14rem), (100% - 4px) / 5), 1fr));
18285
+ }
18286
+
18287
+ .pa-kpi-edit__grid--max-6 {
18288
+ grid-template-columns: repeat(auto-fit, minmax(max(var(--pa-kpi-edit-cell-min, 14rem), (100% - 5px) / 6), 1fr));
18289
+ }
18290
+
18291
+ /* ----- Tile (editorial spacing leans on the 2.4rem padding) -------------
18292
+ Per-cell container: the value's `cqi`-based font-size scales with
18293
+ *this* tile's width, not the whole grid's. Keeps typography legible as
18294
+ the grid packs more cells into the same row. */
18295
+ .pa-kpi-edit__tile {
18296
+ container-type: inline-size;
18297
+ background: var(--pa-card-bg);
18298
+ padding: 2.4rem 2rem;
18299
+ display: flex;
18300
+ flex-direction: column;
18301
+ gap: 1.2rem;
18302
+ position: relative;
18303
+ min-width: 0;
18304
+ /* Hover host: faint wash so the cursor-anchored popover has a clear
18305
+ "this tile" anchor. */
18306
+ }
18307
+ .pa-kpi-edit__tile:hover {
18308
+ background: color-mix(in srgb, var(--pa-text-color-1) 4%, var(--pa-card-bg));
18309
+ }
18310
+
18311
+ /* ----- Label (uppercase mono caption) ----------------------------------- */
18312
+ .pa-kpi-edit__label {
18313
+ font-family: var(--base-font-family-mono);
18314
+ font-size: 1.2rem;
18315
+ font-weight: 600;
18316
+ letter-spacing: 0.12em;
18317
+ text-transform: uppercase;
18318
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
18319
+ line-height: 1.3;
18320
+ }
18321
+
18322
+ /* ----- Value (the editorial signature) ---------------------------------
18323
+ - NOT mono — mono fonts rarely have a true 200 weight; using the body
18324
+ sans gives proper thin glyphs that read as "editorial" rather than
18325
+ "monospace at low contrast".
18326
+ - font-weight: 200 (extra-light). 300 was tested first but didn't read
18327
+ distinctly enough as "light" against the body's 400 default.
18328
+ - clamp() lets the number shrink in narrow cells without manual
18329
+ breakpoints. `cqi` measures per-cell (tile is a container) so the
18330
+ value tracks each cell's actual width as the grid packs more
18331
+ columns into a wider container. */
18332
+ .pa-kpi-edit__value {
18333
+ font-family: var(--base-font-family);
18334
+ font-size: clamp(3.2rem, 22cqi, 5.6rem);
18335
+ font-weight: 200;
18336
+ letter-spacing: -0.02em;
18337
+ line-height: 1;
18338
+ color: var(--pa-text-color-1);
18339
+ display: flex;
18340
+ align-items: baseline;
18341
+ gap: 0.2rem;
18342
+ flex-wrap: wrap;
18343
+ }
18344
+
18345
+ .pa-kpi-edit__num {
18346
+ font-weight: 200;
18347
+ font-variant-numeric: tabular-nums;
18348
+ }
18349
+
18350
+ .pa-kpi-edit__unit {
18351
+ font-size: 0.4em;
18352
+ font-weight: 300;
18353
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
18354
+ letter-spacing: 0;
18355
+ }
18356
+
18357
+ /* ----- Meta row (delta + tgt) ------------------------------------------ */
18358
+ .pa-kpi-edit__meta {
18359
+ display: flex;
18360
+ align-items: baseline;
18361
+ gap: 1.4rem;
18362
+ font-family: var(--base-font-family-mono);
18363
+ font-size: 1.3rem;
18364
+ line-height: 1.3;
18365
+ flex-wrap: wrap;
18366
+ }
18367
+
18368
+ .pa-kpi-edit__delta {
18369
+ font-weight: 700;
18370
+ white-space: nowrap;
18371
+ color: var(--pa-positive);
18372
+ }
18373
+ .pa-kpi-edit__delta--positive {
18374
+ color: var(--pa-positive);
18375
+ }
18376
+ .pa-kpi-edit__delta--negative {
18377
+ color: var(--pa-negative);
18378
+ }
18379
+ .pa-kpi-edit__delta--neutral {
18380
+ color: var(--pa-neutral);
18381
+ }
18382
+ .pa-kpi-edit__delta--up-strong {
18383
+ color: var(--pa-very-positive);
18384
+ }
18385
+ .pa-kpi-edit__delta--down-strong {
18386
+ color: var(--pa-very-negative);
18387
+ }
18388
+
18389
+ .pa-kpi-edit__target {
18390
+ font-weight: 500;
18391
+ color: color-mix(in srgb, var(--pa-text-color-1) 50%, transparent);
18392
+ white-space: nowrap;
18393
+ }
18394
+ .pa-kpi-edit__target em {
18395
+ font-style: normal;
18396
+ color: color-mix(in srgb, var(--pa-text-color-1) 38%, transparent);
18397
+ margin-right: 0.5rem;
18398
+ }
18399
+
16654
18400
  /* ========================================
16655
18401
  Utility Components
16656
18402
  Font utilities, compact mode, component showcase
@@ -17542,3 +19288,314 @@ html.pa-font-base-12 {
17542
19288
  .text-end {
17543
19289
  text-align: end;
17544
19290
  }
19291
+
19292
+ /* Pure Admin Visual Framework - Core Styles */
19293
+ :root,
19294
+ .pa-mode-light,
19295
+ .pa-mode-dark {
19296
+ --pa-text-strong: color-mix(in srgb, var(--pa-text-color-1) 85%, transparent);
19297
+ --pa-text-secondary: color-mix(in srgb, var(--pa-text-color-1) 70%, transparent);
19298
+ --pa-text-tertiary: color-mix(in srgb, var(--pa-text-color-1) 55%, transparent);
19299
+ --pa-surface-hover: color-mix(in srgb, var(--pa-text-color-1) 4%, transparent);
19300
+ --pa-surface-track: color-mix(in srgb, var(--pa-text-color-1) 12%, transparent);
19301
+ }
19302
+
19303
+ :root {
19304
+ --base-accent-color: #007bff;
19305
+ --base-accent-color-hover: rgb(51, 149.4, 255);
19306
+ --base-accent-color-active: rgb(102, 175.8, 255);
19307
+ --base-accent-color-light: rgba(0, 123, 255, 0.05);
19308
+ --base-accent-color-light-hover: rgba(0, 123, 255, 0.12);
19309
+ --base-text-color-1: #2c3e50;
19310
+ --base-text-color-2: #6c757d;
19311
+ --base-text-color-3: #7a8a99;
19312
+ --base-text-color-4: #a3b1bf;
19313
+ --base-text-color-on-accent: #ffffff;
19314
+ --base-main-bg: #ffffff;
19315
+ --base-page-bg: #f8f9fa;
19316
+ --base-subtle-bg: #e9ecef;
19317
+ --base-inverse-bg: #2c3e50;
19318
+ --base-overlay-bg: rgba(0, 0, 0, 0.5);
19319
+ --base-shadow-color: rgba(0, 0, 0, 0.15);
19320
+ --base-hover-bg: #e9ecef;
19321
+ --base-active-bg: rgb(218.2368421053, 223.25, 228.2631578947);
19322
+ --base-disabled-bg: #e9ecef;
19323
+ --base-elevated-bg: #f5f5f5;
19324
+ --base-surface-1: #ffffff;
19325
+ --base-surface-2: #f8f9fa;
19326
+ --base-surface-3: #e9ecef;
19327
+ --base-surface-inverse: #2c3e50;
19328
+ --base-primary-bg: #ffffff;
19329
+ --base-primary-bg-hover: rgb(242.25, 242.25, 242.25);
19330
+ --base-border-color: #e1e5e9;
19331
+ --base-border: 1px solid #e1e5e9;
19332
+ --base-input-bg: #ffffff;
19333
+ --base-input-color: #495057;
19334
+ --base-input-border: 1px solid #ced4da;
19335
+ --base-input-border-hover: 1px solid #b8bfc6;
19336
+ --base-input-border-focus: 1px solid #007bff;
19337
+ --base-input-placeholder-color: #a3b1bf;
19338
+ --base-input-bg-disabled: rgba(255, 255, 255, 0.5);
19339
+ --base-input-size-xs-height: 3.1;
19340
+ --base-input-size-sm-height: 3.3;
19341
+ --base-input-size-md-height: 3.5;
19342
+ --base-input-size-lg-height: 3.8;
19343
+ --base-input-size-xl-height: 4.1;
19344
+ --base-dropdown-bg: #ffffff;
19345
+ --base-dropdown-border: 1px solid #e1e5e9;
19346
+ --base-dropdown-box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
19347
+ --base-tooltip-bg: #2c3e50;
19348
+ --base-tooltip-text-color: #ffffff;
19349
+ --base-success-color: #22c55e;
19350
+ --base-success-color-hover: rgb(26.4935064935, 153.5064935065, 73.2467532468);
19351
+ --base-success-bg-light: rgba(34, 197, 94, 0.1);
19352
+ --base-success-bg-subtle: rgba(34, 197, 94, 0.08);
19353
+ --base-success-border: rgba(34, 197, 94, 0.2);
19354
+ --base-success-text: #155724;
19355
+ --base-success-text-light: #d4edda;
19356
+ --base-text-on-success: #ffffff;
19357
+ --base-danger-color: #ef4444;
19358
+ --base-danger-color-hover: rgb(234.9802955665, 21.0197044335, 21.0197044335);
19359
+ --base-danger-bg-light: rgba(239, 68, 68, 0.1);
19360
+ --base-danger-bg-subtle: rgba(239, 68, 68, 0.08);
19361
+ --base-danger-border: rgba(239, 68, 68, 0.2);
19362
+ --base-danger-text: #721c24;
19363
+ --base-danger-text-light: #f8d7da;
19364
+ --base-text-on-danger: #ffffff;
19365
+ --base-warning-color: #f97316;
19366
+ --base-warning-color-hover: rgb(214.4769874477, 91.129707113, 5.5230125523);
19367
+ --base-warning-bg-light: rgba(249, 115, 22, 0.1);
19368
+ --base-warning-bg-subtle: rgba(249, 115, 22, 0.08);
19369
+ --base-warning-border: rgba(249, 115, 22, 0.2);
19370
+ --base-warning-text: #856404;
19371
+ --base-warning-text-light: #fff3cd;
19372
+ --base-text-on-warning: #212529;
19373
+ --base-info-color: #17a2b8;
19374
+ --base-info-color-hover: rgb(17.3333333333, 122.0869565217, 138.6666666667);
19375
+ --base-info-bg-light: rgba(23, 162, 184, 0.1);
19376
+ --base-info-bg-subtle: rgba(23, 162, 184, 0.08);
19377
+ --base-info-border: rgba(23, 162, 184, 0.2);
19378
+ --base-info-text: #0c5460;
19379
+ --base-info-text-light: #d1ecf1;
19380
+ --base-text-on-info: #ffffff;
19381
+ --base-hover-overlay: rgba(0, 0, 0, 0.04);
19382
+ --base-active-overlay: rgba(0, 0, 0, 0.08);
19383
+ --base-focus-ring-color: #007bff;
19384
+ --base-focus-ring-width: 3px;
19385
+ --base-font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif;
19386
+ --base-font-family-mono: SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace;
19387
+ --base-font-size-2xs: 1;
19388
+ --base-font-size-xs: 1.2;
19389
+ --base-font-size-sm: 1.4;
19390
+ --base-font-size-base: 1.6;
19391
+ --base-font-size-lg: 1.8;
19392
+ --base-font-size-xl: 2;
19393
+ --base-font-size-2xl: 2.4;
19394
+ --base-font-weight-normal: 400;
19395
+ --base-font-weight-medium: 500;
19396
+ --base-font-weight-semibold: 600;
19397
+ --base-font-weight-bold: 700;
19398
+ --base-line-height-tight: 1.25;
19399
+ --base-line-height-normal: 1.5;
19400
+ --base-line-height-relaxed: 1.75;
19401
+ --base-border-radius-sm: 0.4;
19402
+ --base-border-radius-md: 0.6;
19403
+ --base-border-radius-lg: 0.8;
19404
+ --pa-main-bg: #f8f9fa;
19405
+ --pa-page-bg: #f8f9fa;
19406
+ --pa-subtle-bg: #ffffff;
19407
+ --pa-text-color-1: #2c3e50;
19408
+ --pa-text-color-2: #6c757d;
19409
+ --pa-accent: #007bff;
19410
+ --pa-accent-hover: rgba(0, 123, 255, 0.12);
19411
+ --pa-accent-light: color-mix(in srgb, var(--pa-accent) 5%, transparent);
19412
+ --pa-link-color: var(--pa-accent);
19413
+ --pa-link-color-hover: color-mix(in srgb, var(--pa-link-color), currentColor 50%);
19414
+ --pa-link-color-visited: var(--pa-link-color);
19415
+ --pa-border-color: #e1e5e9;
19416
+ --pa-success: #22c55e;
19417
+ --pa-warning: #f97316;
19418
+ --pa-danger: #ef4444;
19419
+ --pa-info: #17a2b8;
19420
+ --pa-very-positive: #16a34a;
19421
+ --pa-positive: var(--pa-success);
19422
+ --pa-neutral: #9ca3af;
19423
+ --pa-negative: var(--pa-danger);
19424
+ --pa-very-negative: #dc2626;
19425
+ --pa-chart-trendline-height: 3rem;
19426
+ --pa-chart-trendline-stroke: 2.1;
19427
+ --pa-detail-bg: rgba(15, 17, 21, 0.97);
19428
+ --pa-detail-text: #ffffff;
19429
+ --pa-detail-row-label: rgba(255, 255, 255, 0.75);
19430
+ --pa-detail-title: rgba(255, 255, 255, 0.55);
19431
+ --pa-detail-shadow: 0 1.4rem 3.6rem rgba(0, 0, 0, 0.55);
19432
+ --pa-header-bg: #ffffff;
19433
+ --pa-header-border-color: #e1e5e9;
19434
+ --pa-header-text: #2c3e50;
19435
+ --pa-header-text-secondary: #6c757d;
19436
+ --pa-header-profile-name-color: #2c3e50;
19437
+ --pa-sidebar-bg: #f8f9fa;
19438
+ --pa-sidebar-text: #2c3e50;
19439
+ --pa-sidebar-text-secondary: #6c757d;
19440
+ --pa-sidebar-submenu-bg: #e9ecef;
19441
+ --pa-sidebar-submenu-hover-bg: rgb(218.2368421053, 223.25, 228.2631578947);
19442
+ --pa-sidebar-submenu-active-bg: rgb(203.4736842105, 210.5, 217.5263157895);
19443
+ --pa-sidebar-submenu-active-text: #2c3e50;
19444
+ --pa-footer-bg: #ffffff;
19445
+ --pa-footer-border-color: #e1e5e9;
19446
+ --pa-btn-primary-bg: #007bff;
19447
+ --pa-btn-primary-bg-hover: rgb(51, 149.4, 255);
19448
+ --pa-btn-primary-bg-light: color-mix(in srgb, var(--pa-btn-primary-bg) 5%, transparent);
19449
+ --pa-btn-primary-text: #ffffff;
19450
+ --pa-btn-secondary-bg: #6c757d;
19451
+ --pa-btn-secondary-bg-hover: #545b62;
19452
+ --pa-btn-secondary-text: #ffffff;
19453
+ --pa-btn-secondary-outline-color: var(--pa-btn-secondary-bg);
19454
+ --pa-btn-success-bg: var(--pa-success);
19455
+ --pa-btn-success-bg-hover: rgb(26.4935064935, 153.5064935065, 73.2467532468);
19456
+ --pa-btn-success-text: #ffffff;
19457
+ --pa-btn-danger-bg: var(--pa-danger);
19458
+ --pa-btn-danger-bg-hover: rgb(234.9802955665, 21.0197044335, 21.0197044335);
19459
+ --pa-btn-danger-text: #ffffff;
19460
+ --pa-btn-warning-bg: var(--pa-warning);
19461
+ --pa-btn-warning-bg-hover: rgb(214.4769874477, 91.129707113, 5.5230125523);
19462
+ --pa-btn-warning-text: #212529;
19463
+ --pa-btn-info-bg: var(--pa-info);
19464
+ --pa-btn-info-bg-hover: rgb(17.3333333333, 122.0869565217, 138.6666666667);
19465
+ --pa-btn-info-text: #ffffff;
19466
+ --pa-btn-light-bg: #f8f9fa;
19467
+ --pa-btn-light-bg-hover: #e9ecef;
19468
+ --pa-btn-light-text: #2c3e50;
19469
+ --pa-btn-dark-bg: #343a40;
19470
+ --pa-btn-dark-bg-hover: #1d2124;
19471
+ --pa-btn-dark-text: #ffffff;
19472
+ --pa-success-bg: var(--pa-success);
19473
+ --pa-success-bg-hover: rgb(26.4935064935, 153.5064935065, 73.2467532468);
19474
+ --pa-success-bg-light: color-mix(in srgb, var(--pa-success) 10%, transparent);
19475
+ --pa-success-bg-subtle: color-mix(in srgb, var(--pa-success) 8%, transparent);
19476
+ --pa-success-border: color-mix(in srgb, var(--pa-success) 20%, transparent);
19477
+ --pa-success-text: #155724;
19478
+ --pa-success-text-light: #d4edda;
19479
+ --pa-danger-bg: var(--pa-danger);
19480
+ --pa-danger-bg-hover: rgb(234.9802955665, 21.0197044335, 21.0197044335);
19481
+ --pa-danger-bg-light: color-mix(in srgb, var(--pa-danger) 10%, transparent);
19482
+ --pa-danger-bg-subtle: color-mix(in srgb, var(--pa-danger) 8%, transparent);
19483
+ --pa-danger-border: color-mix(in srgb, var(--pa-danger) 20%, transparent);
19484
+ --pa-danger-text: #721c24;
19485
+ --pa-danger-text-light: #f8d7da;
19486
+ --pa-warning-bg: var(--pa-warning);
19487
+ --pa-warning-bg-hover: rgb(214.4769874477, 91.129707113, 5.5230125523);
19488
+ --pa-warning-bg-light: color-mix(in srgb, var(--pa-warning) 10%, transparent);
19489
+ --pa-warning-bg-subtle: color-mix(in srgb, var(--pa-warning) 8%, transparent);
19490
+ --pa-warning-border: color-mix(in srgb, var(--pa-warning) 20%, transparent);
19491
+ --pa-warning-text: #856404;
19492
+ --pa-warning-text-light: #fff3cd;
19493
+ --pa-info-bg: var(--pa-info);
19494
+ --pa-info-bg-hover: rgb(17.3333333333, 122.0869565217, 138.6666666667);
19495
+ --pa-info-bg-light: color-mix(in srgb, var(--pa-info) 10%, transparent);
19496
+ --pa-info-bg-subtle: color-mix(in srgb, var(--pa-info) 8%, transparent);
19497
+ --pa-info-border: color-mix(in srgb, var(--pa-info) 20%, transparent);
19498
+ --pa-info-text: #0c5460;
19499
+ --pa-info-text-light: #d1ecf1;
19500
+ --pa-card-bg: #ffffff;
19501
+ --pa-card-header-bg: #f8f9fa;
19502
+ --pa-card-footer-bg: #ffffff;
19503
+ --pa-card-tabs-bg: #f8f9fa;
19504
+ --pa-input-bg: #ffffff;
19505
+ --pa-input-border: #ced4da;
19506
+ --pa-input-text: #495057;
19507
+ --pa-input-focus-border-color: #007bff;
19508
+ --pa-select-focus-border-color: #007bff;
19509
+ --pa-textarea-focus-border-color: #007bff;
19510
+ --pa-checkbox-border-color: #e1e5e9;
19511
+ --pa-checkbox-border-color-hover: #007bff;
19512
+ --pa-checkbox-border-color-checked: #007bff;
19513
+ --pa-checkbox-bg: #ffffff;
19514
+ --pa-checkbox-bg-checked: #007bff;
19515
+ --pa-checkbox-bg-indeterminate: #007bff;
19516
+ --pa-checkbox-checkmark-color: white;
19517
+ --pa-checkbox-focus-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
19518
+ --pa-input-group-prepend-bg: #6c757d;
19519
+ --pa-input-group-prepend-text: #6c757d;
19520
+ --pa-input-group-append-bg: #6c757d;
19521
+ --pa-input-group-append-text: #6c757d;
19522
+ --pa-table-bg: #ffffff;
19523
+ --pa-table-header-bg: #f8f9fa;
19524
+ --pa-table-stripe: #f8f9fa;
19525
+ --pa-table-hover-bg: #f8f9fa;
19526
+ --pa-table-hover-accent-color: #007bff;
19527
+ --pa-modal-overlay-bg: rgba(0, 0, 0, 0.5);
19528
+ --pa-modal-content-bg: #ffffff;
19529
+ --pa-badge-success-bg: #d4edda;
19530
+ --pa-badge-success-text: #155724;
19531
+ --pa-badge-warning-bg: #fff3cd;
19532
+ --pa-badge-warning-text: #856404;
19533
+ --pa-badge-info-bg: #d1ecf1;
19534
+ --pa-badge-info-text: #0c5460;
19535
+ --pa-badge-danger-bg: #f8d7da;
19536
+ --pa-badge-danger-text: #721c24;
19537
+ --pa-composite-badge-icon-bg: #6c757d;
19538
+ --pa-composite-badge-label-bg: #e9ecef;
19539
+ --pa-composite-badge-label-text: #2c3e50;
19540
+ --pa-composite-badge-label-hover-bg: #e9ecef;
19541
+ --pa-tooltip-bg: #2c3e50;
19542
+ --pa-tooltip-text: #ffffff;
19543
+ --pa-popover-content-bg: #ffffff;
19544
+ --pa-popover-text-light: #ffffff;
19545
+ --pa-popover-text-dark: #000000;
19546
+ --pa-loader-overlay-bg: rgba(255, 255, 255, 0.8);
19547
+ --pa-profile-overlay-bg: rgba(0, 0, 0, 0.3);
19548
+ --pa-detail-panel-overlay-bg: rgba(0, 0, 0, 0.3);
19549
+ --pa-detail-panel-selected-bg: rgba(0, 123, 255, 0.08);
19550
+ --pa-detail-panel-z-index: 4500;
19551
+ --pa-command-palette-backdrop-bg: rgba(0, 0, 0, 0.5);
19552
+ --pa-command-palette-item-hover-bg: rgba(0, 123, 255, 0.05);
19553
+ --pa-command-palette-item-active-bg: rgba(0, 123, 255, 0.1);
19554
+ --pa-command-palette-highlight-bg: rgba(0, 123, 255, 0.2);
19555
+ --pa-command-palette-highlight-text: #007bff;
19556
+ --pa-command-palette-key-bg: #ffffff;
19557
+ --pa-command-palette-key-text: #2c3e50;
19558
+ --pa-command-palette-key-font-size: 1.2rem;
19559
+ --pa-command-palette-key-font-weight: 600;
19560
+ --pa-multiselect-dropdown-bg: #ffffff;
19561
+ --pa-multiselect-dropdown-border: #e1e5e9;
19562
+ --pa-multiselect-dropdown-text: #2c3e50;
19563
+ --pa-multiselect-hint-bg: #f8f9fa;
19564
+ --pa-multiselect-hint-border: #e1e5e9;
19565
+ --pa-multiselect-option-hover-bg: #f8f9fa;
19566
+ --pa-multiselect-pill-bg: rgba(0, 123, 255, 0.05);
19567
+ --pa-multiselect-pill-border: #007bff;
19568
+ --pa-color-1: transparent;
19569
+ --pa-color-2: transparent;
19570
+ --pa-color-3: transparent;
19571
+ --pa-color-4: transparent;
19572
+ --pa-color-5: transparent;
19573
+ --pa-color-6: transparent;
19574
+ --pa-color-7: transparent;
19575
+ --pa-color-8: transparent;
19576
+ --pa-color-9: transparent;
19577
+ --pa-color-1-text: #ffffff;
19578
+ --pa-color-2-text: #ffffff;
19579
+ --pa-color-3-text: #ffffff;
19580
+ --pa-color-4-text: #ffffff;
19581
+ --pa-color-5-text: #ffffff;
19582
+ --pa-color-6-text: #ffffff;
19583
+ --pa-color-7-text: #ffffff;
19584
+ --pa-color-8-text: #ffffff;
19585
+ --pa-color-9-text: #ffffff;
19586
+ --pa-border-radius-sm: 2px;
19587
+ --pa-border-radius: 4px;
19588
+ --pa-border-radius-lg: 8px;
19589
+ --pa-alert-success-text: color-mix(in srgb, var(--pa-success-bg) 60%, black);
19590
+ --pa-alert-success-bg: color-mix(in srgb, var(--pa-success-bg) 15%, transparent);
19591
+ --pa-alert-success-border: color-mix(in srgb, var(--pa-success-bg) 30%, transparent);
19592
+ --pa-alert-danger-text: color-mix(in srgb, var(--pa-danger-bg) 60%, black);
19593
+ --pa-alert-danger-bg: color-mix(in srgb, var(--pa-danger-bg) 15%, transparent);
19594
+ --pa-alert-danger-border: color-mix(in srgb, var(--pa-danger-bg) 30%, transparent);
19595
+ --pa-alert-warning-text: color-mix(in srgb, var(--pa-warning-bg) 60%, black);
19596
+ --pa-alert-warning-bg: color-mix(in srgb, var(--pa-warning-bg) 15%, transparent);
19597
+ --pa-alert-warning-border: color-mix(in srgb, var(--pa-warning-bg) 30%, transparent);
19598
+ --pa-alert-info-text: color-mix(in srgb, var(--pa-info-bg) 60%, black);
19599
+ --pa-alert-info-bg: color-mix(in srgb, var(--pa-info-bg) 15%, transparent);
19600
+ --pa-alert-info-border: color-mix(in srgb, var(--pa-info-bg) 30%, transparent);
19601
+ }