@kanunilabs/datagrid 1.9.1 → 1.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/datagrid.umd.js +8 -8
  2. package/dist/index.cjs +2 -2
  3. package/dist/index.d.cts +52 -4
  4. package/dist/index.d.ts +52 -4
  5. package/dist/index.js +2 -2
  6. package/dist/styles.css +411 -1
  7. package/dist/themes/all.css +108 -0
  8. package/dist/themes/amber.css +3 -0
  9. package/dist/themes/aubergine.css +3 -0
  10. package/dist/themes/azure.css +3 -0
  11. package/dist/themes/burgundy.css +3 -0
  12. package/dist/themes/charcoal.css +3 -0
  13. package/dist/themes/contrast-dark.css +3 -0
  14. package/dist/themes/contrast-light.css +3 -0
  15. package/dist/themes/coral.css +3 -0
  16. package/dist/themes/corporate.css +3 -0
  17. package/dist/themes/deep-sea.css +3 -0
  18. package/dist/themes/editorial.css +3 -0
  19. package/dist/themes/ember.css +3 -0
  20. package/dist/themes/emerald.css +3 -0
  21. package/dist/themes/forest.css +3 -0
  22. package/dist/themes/glacier.css +3 -0
  23. package/dist/themes/graphite.css +3 -0
  24. package/dist/themes/indigo-night.css +3 -0
  25. package/dist/themes/indigo.css +3 -0
  26. package/dist/themes/ivory.css +3 -0
  27. package/dist/themes/lagoon.css +3 -0
  28. package/dist/themes/linen.css +3 -0
  29. package/dist/themes/midnight.css +3 -0
  30. package/dist/themes/mist.css +3 -0
  31. package/dist/themes/monochrome.css +3 -0
  32. package/dist/themes/onyx.css +3 -0
  33. package/dist/themes/orchid.css +3 -0
  34. package/dist/themes/porcelain.css +3 -0
  35. package/dist/themes/rose.css +3 -0
  36. package/dist/themes/sandstone.css +3 -0
  37. package/dist/themes/slate-night.css +3 -0
  38. package/dist/themes/slate.css +3 -0
  39. package/dist/themes/steel.css +3 -0
  40. package/dist/themes/stone.css +3 -0
  41. package/dist/themes/taupe.css +3 -0
  42. package/dist/themes/teal.css +3 -0
  43. package/dist/themes/terminal.css +3 -0
  44. package/package.json +3 -3
package/dist/styles.css CHANGED
@@ -84,6 +84,9 @@
84
84
  --dg-danger: #dc2626; /* red-600 — borders, solid fills */
85
85
  --dg-danger-text: #b91c1c; /* red-700 — text on a light surface */
86
86
  --dg-on-danger: #ffffff; /* text ON a solid --dg-danger fill */
87
+ --dg-success: #15803d; /* green-700 — fills ("saved" marks) */
88
+ --dg-success-text: #166534; /* success as text on a light surface */
89
+ --dg-on-success: #ffffff; /* text ON a solid --dg-success fill */
87
90
  --dg-warning: #b45309; /* amber-700 */
88
91
  --dg-selected-bg: var(--dg-primary-soft);
89
92
  /* Search highlight (P2.4). Amber rather than the accent: the accent already
@@ -171,10 +174,20 @@
171
174
  color: var(--dg-text);
172
175
  }
173
176
 
177
+ /* Typeface. Inherited from the page unless --dg-font-family names one — set
178
+ it once (on :root, or in a palette class) and the grid, the Enterprise
179
+ chrome around it and every popup portalled to <body> use it. Without the
180
+ variable, a font set only on the grid's container never reached the menus
181
+ and dialogs, which inherit from <body> (2026-10-16, customer request). */
182
+ .kanuni-datagrid-enterprise,
183
+ .kanuni-datagrid-detached {
184
+ font-family: var(--dg-font-family, inherit);
185
+ }
186
+
174
187
  /* The grid's own box. */
175
188
  .kanuni-datagrid-root {
176
189
  box-sizing: border-box;
177
- font-family: inherit;
190
+ font-family: var(--dg-font-family, inherit);
178
191
  -webkit-font-smoothing: antialiased;
179
192
  -moz-osx-font-smoothing: grayscale;
180
193
  position: relative;
@@ -229,6 +242,9 @@
229
242
  /* The dark danger is a LIGHT red, so what sits on it has to be dark. White
230
243
  on #f87171 measures 2.4:1 — the delete button's own label. */
231
244
  --dg-on-danger: #450a0a;
245
+ --dg-success: #4ade80;
246
+ --dg-success-text: #86efac;
247
+ --dg-on-success: #0d2817;
232
248
  --dg-warning: #fbbf24;
233
249
  --dg-overlay: rgba(2, 6, 23, 0.7);
234
250
  --dg-scrollbar-thumb: #475569;
@@ -663,6 +679,48 @@
663
679
  font-size: 11px;
664
680
  }
665
681
 
682
+ /* The search box's own refusal (`toolbar.search.validate`), right after it. */
683
+ .kanuni-datagrid-toolbar-search-error {
684
+ color: var(--dg-danger-text);
685
+ font-size: 11px;
686
+ }
687
+
688
+ .kanuni-datagrid-toolbar-search[aria-invalid='true'] {
689
+ border-color: var(--dg-danger);
690
+ }
691
+
692
+ /* An app's own button (GridToolbarButton / toolbarButton()), drawn like the
693
+ grid's commands wherever it sits: the toolbar's rule above reaches only its
694
+ DIRECT children, and the status bar has none. */
695
+ .kanuni-datagrid-app-button {
696
+ display: inline-flex;
697
+ align-items: center;
698
+ justify-content: center;
699
+ gap: 5px;
700
+ padding: 3px 10px;
701
+ border: 1px solid var(--dg-border-strong);
702
+ border-radius: var(--dg-radius-control);
703
+ background: var(--dg-surface);
704
+ color: inherit;
705
+ font: inherit;
706
+ font-size: var(--dg-control-font-size);
707
+ cursor: pointer;
708
+ }
709
+
710
+ .kanuni-datagrid-app-button.kanuni-datagrid-toolbar-icon-button {
711
+ padding: 0;
712
+ }
713
+
714
+ .kanuni-datagrid-app-button:hover:not([aria-disabled='true']) {
715
+ background: var(--dg-surface-hover);
716
+ }
717
+
718
+ /* Unavailable but still focusable, so its reason can be read. */
719
+ .kanuni-datagrid-app-button[aria-disabled='true'] {
720
+ opacity: 0.6;
721
+ cursor: not-allowed;
722
+ }
723
+
666
724
  /*
667
725
  * The same message, but floating where a context menu just was — the cell
668
726
  * menu's Export entries have nowhere else to report a missing optional peer.
@@ -1870,6 +1928,17 @@
1870
1928
  flex: none;
1871
1929
  }
1872
1930
 
1931
+ /* A row of a server's list whose piece has not arrived: the slot is held (the
1932
+ scroll bar describes the whole list), the value is not known yet. */
1933
+ .kanuni-datagrid-filter-item--pending {
1934
+ color: var(--dg-text-muted);
1935
+ cursor: default;
1936
+ }
1937
+
1938
+ .kanuni-datagrid-filter-item--pending:hover {
1939
+ background: transparent;
1940
+ }
1941
+
1873
1942
  .kanuni-datagrid-filter-item:hover,
1874
1943
  .kanuni-datagrid-filter-item--active {
1875
1944
  background: var(--dg-surface-hover);
@@ -2830,6 +2899,19 @@
2830
2899
  margin: 0 calc(var(--dg-cell-padding-x) * -1);
2831
2900
  }
2832
2901
 
2902
+ /* ...but the TEXT stays where the cell drew it. Widened to the cell's edges
2903
+ with only 4px of padding, the value jumped left by the cell padding as the
2904
+ editor opened; in row mode, with every cell open, no value lined up with the
2905
+ column above it (2026-10-19, content session). The date editor's own input
2906
+ keeps its 4px, so its wrapper makes up the rest. */
2907
+ .kanuni-datagrid-root .kanuni-datagrid-cell > .kanuni-datagrid-editor:not([type='checkbox']) {
2908
+ padding-inline: var(--dg-cell-padding-x);
2909
+ }
2910
+
2911
+ .kanuni-datagrid-root .kanuni-datagrid-cell > .kanuni-datagrid-date-editor {
2912
+ padding-inline: max(0px, calc(var(--dg-cell-padding-x) - 4px)) 0;
2913
+ }
2914
+
2833
2915
  /* In a WRAPPED cell the editor takes the LINE BOX, not the row height.
2834
2916
  A wrapping cell is as tall as its own text: one line of it is
2835
2917
  `padding-block x2 + --dg-wrap-line-height`, which is shorter than a standard
@@ -2867,6 +2949,38 @@
2867
2949
  background: var(--dg-surface);
2868
2950
  }
2869
2951
 
2952
+ /* Row mode opens every cell of the row at once and marks none of them
2953
+ `--editing`, so the focused one kept its ring around the underlined editor —
2954
+ the double rectangle above, on one cell of the row (2026-10-19, content
2955
+ session). Any cell that holds an editor drops the ring. */
2956
+ .kanuni-datagrid-root .kanuni-datagrid-cell--focused:has(> .kanuni-datagrid-editor),
2957
+ .kanuni-datagrid-root .kanuni-datagrid-cell--focused:has(> .kanuni-datagrid-date-editor) {
2958
+ outline: none;
2959
+ }
2960
+
2961
+ /* A number is typed where it is read: right-aligned, as the cell shows it.
2962
+ Left-aligned editors made the value jump across the column the moment the
2963
+ cell opened, and in row mode two number editors side by side read as one
2964
+ field. */
2965
+ .kanuni-datagrid-root .kanuni-datagrid-cell--number > .kanuni-datagrid-editor {
2966
+ text-align: right;
2967
+ }
2968
+
2969
+ /* Chrome keeps ~15px at the end of a number input for its spin buttons, shown
2970
+ or not, so a right-aligned value still stopped short of the column's
2971
+ numbers. In a row-high cell the arrows are too small to use anyway; the
2972
+ keyboard's arrow keys move between cells here. */
2973
+ .kanuni-datagrid-root input.kanuni-datagrid-editor[type='number'] {
2974
+ appearance: textfield;
2975
+ -moz-appearance: textfield;
2976
+ }
2977
+
2978
+ .kanuni-datagrid-root input.kanuni-datagrid-editor[type='number']::-webkit-inner-spin-button,
2979
+ .kanuni-datagrid-root input.kanuni-datagrid-editor[type='number']::-webkit-outer-spin-button {
2980
+ -webkit-appearance: none;
2981
+ margin: 0;
2982
+ }
2983
+
2870
2984
  .kanuni-datagrid-root input.kanuni-datagrid-editor[type='checkbox'] {
2871
2985
  width: auto;
2872
2986
  height: auto;
@@ -3350,6 +3464,51 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
3350
3464
  outline-offset: -1px;
3351
3465
  }
3352
3466
 
3467
+ /* The date and lookup editors in a form are the CELL editors (one control per
3468
+ column), whose look is an underline sized to a row. In a form that read as a
3469
+ different kind of field from its boxed neighbours (2026-10-19, content
3470
+ session), so here they take the form's box: on the date editor's wrapper,
3471
+ which holds the calendar button too, and on a lookup's input directly. */
3472
+ .kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor,
3473
+ .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor {
3474
+ height: auto;
3475
+ padding: 4px 6px;
3476
+ border: 1px solid var(--dg-border-strong);
3477
+ border-radius: var(--dg-radius-control);
3478
+ background: var(--dg-surface);
3479
+ }
3480
+
3481
+ .kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor > .kanuni-datagrid-editor {
3482
+ height: auto;
3483
+ padding: 0;
3484
+ border: none;
3485
+ }
3486
+
3487
+ .kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor:focus,
3488
+ .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor:focus-within {
3489
+ outline: 2px solid var(--dg-primary);
3490
+ outline-offset: -1px;
3491
+ }
3492
+
3493
+ /* A field the user cannot change must not look like one they can.
3494
+ `editable: false` columns were drawn as disabled inputs with the same
3495
+ surface, border and text as the open ones: readers clicked them and nothing
3496
+ happened (2026-10-19, content session). Recessed surface, muted text, a
3497
+ lighter border and the not-allowed cursor — the value stays readable. */
3498
+ .kanuni-datagrid-edit-form-input:disabled,
3499
+ .kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-editor:disabled,
3500
+ .kanuni-datagrid-edit-form-lookup > .kanuni-datagrid-date-editor:has(.kanuni-datagrid-editor:disabled) {
3501
+ border-color: var(--dg-border);
3502
+ background: var(--dg-surface-header);
3503
+ color: var(--dg-text-muted);
3504
+ cursor: not-allowed;
3505
+ }
3506
+
3507
+ .kanuni-datagrid-root .kanuni-datagrid-edit-form-lookup .kanuni-datagrid-date-editor .kanuni-datagrid-editor:disabled {
3508
+ color: var(--dg-text-muted);
3509
+ cursor: not-allowed;
3510
+ }
3511
+
3353
3512
  .kanuni-datagrid-edit-form-field[data-invalid] .kanuni-datagrid-edit-form-input {
3354
3513
  border-color: var(--dg-danger);
3355
3514
  }
@@ -3454,6 +3613,218 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
3454
3613
  pointer-events: none;
3455
3614
  }
3456
3615
 
3616
+ /* ─────────────────────────────────────────────────────────────
3617
+ Row save status (`rowStatus`, Community, 2026-10-16).
3618
+ ─────────────────────────────────────────────────────────────
3619
+ A customer whose grid saves every edit at once asked to see each row's
3620
+ save: unsaved, in flight, saved, refused. Both renderers put
3621
+ `data-row-status` and `kanuni-datagrid-row--status-<status>` on the ROW
3622
+ element — one element per row, pinned cells included — so the marker is
3623
+ drawn once per row and cannot repeat per pinned block.
3624
+
3625
+ The marker is the row's own `::before`: a sticky flex item at the inline
3626
+ start that gives its width back with a negative margin. Sticky, because
3627
+ the row is as wide as all its columns and scrolls sideways — a plain left
3628
+ border or inset shadow on the row would scroll out of view with the first
3629
+ column, and under a pinned-left column it would be painted over. It sits
3630
+ above pinned cells (z-index) and moves no cell content. `inset-inline-start`
3631
+ puts it on the right edge under `dir="rtl"`. The focused row keeps its own
3632
+ inset bar; at the leading edge the status marker covers it, which is the
3633
+ more urgent of the two. */
3634
+ .kanuni-datagrid-root,
3635
+ .kanuni-datagrid-enterprise,
3636
+ .kanuni-datagrid-detached {
3637
+ --dg-row-status-width: 3px;
3638
+ --dg-row-status-changed: var(--dg-warning);
3639
+ --dg-row-status-saving: var(--dg-primary);
3640
+ /* The success fill: every palette and scheme sets it, dark ones included. */
3641
+ --dg-row-status-saved: var(--dg-success);
3642
+ --dg-row-status-error: var(--dg-danger);
3643
+ /* How strongly `tint: true` washes the row. */
3644
+ --dg-row-status-tint: 8%;
3645
+ }
3646
+
3647
+ .kanuni-datagrid-row--status-changed {
3648
+ --dg-row-status-color: var(--dg-row-status-changed);
3649
+ }
3650
+
3651
+ .kanuni-datagrid-row--status-saving {
3652
+ --dg-row-status-color: var(--dg-row-status-saving);
3653
+ }
3654
+
3655
+ .kanuni-datagrid-row--status-saved {
3656
+ --dg-row-status-color: var(--dg-row-status-saved);
3657
+ }
3658
+
3659
+ .kanuni-datagrid-row--status-error {
3660
+ --dg-row-status-color: var(--dg-row-status-error);
3661
+ }
3662
+
3663
+ .kanuni-datagrid-row[data-row-status]::before {
3664
+ content: '';
3665
+ position: sticky;
3666
+ inset-inline-start: 0;
3667
+ /* Above pinned cells (2), below the row being edited (4): at 6 the next
3668
+ row's marker cut through the editor's error bubble, which hangs one row
3669
+ down (pre-release review, 2026-10-16). */
3670
+ z-index: 3;
3671
+ flex: none;
3672
+ align-self: stretch;
3673
+ width: var(--dg-row-status-width);
3674
+ margin-inline-end: calc(-1 * var(--dg-row-status-width));
3675
+ background: var(--dg-row-status-color);
3676
+ pointer-events: none;
3677
+ }
3678
+
3679
+ /* The tint is a translucent IMAGE over whatever colour the row already has —
3680
+ stripe, hover, selection or focus — so those still read through it. Pinned
3681
+ cells inherit the row's background but the hover rule resets theirs, so
3682
+ they are named here too (three classes + an attribute: above the hover and
3683
+ selection rules, which are two classes). */
3684
+ .kanuni-datagrid-row.kanuni-datagrid-row--status-tint[data-row-status],
3685
+ .kanuni-datagrid-row.kanuni-datagrid-row--status-tint[data-row-status] .kanuni-datagrid-cell--pinned {
3686
+ background-image: linear-gradient(
3687
+ color-mix(in srgb, var(--dg-row-status-color) var(--dg-row-status-tint), transparent),
3688
+ color-mix(in srgb, var(--dg-row-status-color) var(--dg-row-status-tint), transparent)
3689
+ );
3690
+ }
3691
+
3692
+ /* High contrast drops background colours; the marker is the whole signal,
3693
+ so it keeps its own. */
3694
+ @media (forced-colors: active) {
3695
+ .kanuni-datagrid-row[data-row-status]::before {
3696
+ forced-color-adjust: none;
3697
+ }
3698
+ }
3699
+
3700
+ /* ── Message rows (`rowStatus.messages`, 2026-10-16) ─────────
3701
+ A refused save's reason in a row under it, with Retry and Delete row. The
3702
+ in-grid edit form's shape: sticky to the scroller's inline start and as wide
3703
+ as the VIEWPORT, so it stays in view while the columns scroll. The ground
3704
+ stays the surface — the text is the danger TEXT colour, measured at 4.5:1
3705
+ on it — and the row's own marker colour runs down its leading edge. */
3706
+ .kanuni-datagrid-message-row {
3707
+ background: var(--dg-surface);
3708
+ border-bottom: 1px solid var(--dg-border);
3709
+ }
3710
+
3711
+ .kanuni-datagrid-message-cell {
3712
+ position: sticky;
3713
+ inset-inline-start: 0;
3714
+ box-sizing: border-box;
3715
+ width: var(--dg-viewport-width, 100%);
3716
+ height: 100%;
3717
+ border-inline-start: var(--dg-row-status-width) solid var(--dg-row-status-error);
3718
+ user-select: text;
3719
+ }
3720
+
3721
+ .kanuni-datagrid-row-message {
3722
+ display: flex;
3723
+ align-items: center;
3724
+ gap: 8px;
3725
+ height: 100%;
3726
+ padding: 0 var(--dg-cell-padding-x);
3727
+ color: var(--dg-danger-text);
3728
+ font-size: var(--dg-chrome-font-size);
3729
+ }
3730
+
3731
+ .kanuni-datagrid-row-message-icon {
3732
+ flex: none;
3733
+ }
3734
+
3735
+ .kanuni-datagrid-row-message-text {
3736
+ flex: 1 1 auto;
3737
+ min-width: 0;
3738
+ overflow: hidden;
3739
+ text-overflow: ellipsis;
3740
+ white-space: nowrap;
3741
+ }
3742
+
3743
+ .kanuni-datagrid-root .kanuni-datagrid-row-message-button {
3744
+ flex: none;
3745
+ height: min(var(--dg-control-height), calc(100% - 6px));
3746
+ padding: 0 8px;
3747
+ border: 1px solid var(--dg-border-strong);
3748
+ border-radius: var(--dg-radius-control);
3749
+ background: var(--dg-surface);
3750
+ color: var(--dg-text);
3751
+ font: inherit;
3752
+ cursor: pointer;
3753
+ }
3754
+
3755
+ .kanuni-datagrid-root .kanuni-datagrid-row-message-button:hover {
3756
+ background: var(--dg-surface-hover);
3757
+ }
3758
+
3759
+ .kanuni-datagrid-root .kanuni-datagrid-row-message-button:focus-visible {
3760
+ outline: 2px solid var(--dg-focus-ring);
3761
+ outline-offset: 1px;
3762
+ }
3763
+
3764
+ /* ── Status column (`rowStatus.icons`, 2026-10-16) ───────────
3765
+ A glyph per status so it does not rest on colour alone: a dot while
3766
+ changed, a turning ring while saving, a tick when saved, a triangle when
3767
+ refused. Drawn as a MASK filled with the status colour, so a palette or a
3768
+ scheme recolours it like the marker. The cell exists on every row (an empty
3769
+ one where there is no status) so the columns beside it never step. */
3770
+ .kanuni-datagrid-status-cell {
3771
+ display: flex;
3772
+ align-items: center;
3773
+ justify-content: center;
3774
+ padding: 0;
3775
+ }
3776
+
3777
+ .kanuni-datagrid-status-icon {
3778
+ display: none;
3779
+ width: 12px;
3780
+ height: 12px;
3781
+ background: var(--dg-row-status-color);
3782
+ -webkit-mask: var(--dg-row-status-glyph) center / contain no-repeat;
3783
+ mask: var(--dg-row-status-glyph) center / contain no-repeat;
3784
+ }
3785
+
3786
+ .kanuni-datagrid-row[data-row-status] .kanuni-datagrid-status-icon {
3787
+ display: block;
3788
+ }
3789
+
3790
+ .kanuni-datagrid-row--status-changed {
3791
+ --dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='8' r='3.5'/%3E%3C/svg%3E");
3792
+ }
3793
+
3794
+ .kanuni-datagrid-row--status-saving {
3795
+ --dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 2a6 6 0 1 1-6 6' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'/%3E%3C/svg%3E");
3796
+ }
3797
+
3798
+ .kanuni-datagrid-row--status-saved {
3799
+ --dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2.5 8.5 6.5 12.5 13.5 3.5' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
3800
+ }
3801
+
3802
+ .kanuni-datagrid-row--status-error {
3803
+ --dg-row-status-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1 15.5 14.5H.5z M7 6v4.5h2V6z M7 11.5v2h2v-2z' fill-rule='evenodd'/%3E%3C/svg%3E");
3804
+ }
3805
+
3806
+ .kanuni-datagrid-row--status-saving .kanuni-datagrid-status-icon {
3807
+ animation: kanuni-datagrid-status-spin 0.9s linear infinite;
3808
+ }
3809
+
3810
+ @keyframes kanuni-datagrid-status-spin {
3811
+ to {
3812
+ transform: rotate(360deg);
3813
+ }
3814
+ }
3815
+
3816
+ @media (prefers-reduced-motion: reduce) {
3817
+ .kanuni-datagrid-row--status-saving .kanuni-datagrid-status-icon {
3818
+ animation: none;
3819
+ }
3820
+ }
3821
+
3822
+ @media (forced-colors: active) {
3823
+ .kanuni-datagrid-status-icon {
3824
+ background: CanvasText;
3825
+ }
3826
+ }
3827
+
3457
3828
  /* ─────────────────────────────────────────────────────────────
3458
3829
  KANUNILABS DataGrid — packaged themes
3459
3830
  ─────────────────────────────────────────────────────────────
@@ -3920,6 +4291,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
3920
4291
  --dg-danger: #f87171;
3921
4292
  --dg-danger-text: #fca5a5;
3922
4293
  --dg-on-danger: #450a0a;
4294
+ --dg-success: #4ade80;
4295
+ --dg-success-text: #86efac;
4296
+ --dg-on-success: #0d2817;
3923
4297
  --dg-warning: #fbbf24;
3924
4298
  --dg-overlay: rgba(12, 10, 9, 0.72);
3925
4299
 
@@ -4268,6 +4642,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4268
4642
  --dg-danger: #a2515a; /* Aurora nord11, deepened for white text */
4269
4643
  --dg-danger-text: #8f4149;
4270
4644
  --dg-on-danger: #ffffff;
4645
+ --dg-success: #687a5a;
4646
+ --dg-success-text: #5d6c50;
4647
+ --dg-on-success: #ffffff;
4271
4648
  --dg-warning: #8a6220; /* nord13 family */
4272
4649
  }
4273
4650
 
@@ -4296,6 +4673,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4296
4673
  /* nord11 is a muted red, so the label on it has to go further down than the
4297
4674
  usual near-black: #2b1113 measured 4.31:1 and this is 5.17:1. */
4298
4675
  --dg-on-danger: #170709;
4676
+ --dg-success: #a3be8c;
4677
+ --dg-success-text: #adc599;
4678
+ --dg-on-success: #1d2219;
4299
4679
  --dg-warning: #ebcb8b; /* nord13 */
4300
4680
  --dg-overlay: rgba(24, 28, 36, 0.72);
4301
4681
  }
@@ -4329,6 +4709,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4329
4709
  --dg-danger: #b03a5b; /* Pink #ff79c6 / Red #ff5555 family */
4330
4710
  --dg-danger-text: #98304d;
4331
4711
  --dg-on-danger: #ffffff;
4712
+ --dg-success: #2a8441;
4713
+ --dg-success-text: #257339;
4714
+ --dg-on-success: #ffffff;
4332
4715
  --dg-warning: #8a5a1c;
4333
4716
  }
4334
4717
 
@@ -4355,6 +4738,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4355
4738
  --dg-danger: #ff5555; /* Red */
4356
4739
  --dg-danger-text: #ff8a8a;
4357
4740
  --dg-on-danger: #3b0000;
4741
+ --dg-success: #50fa7b;
4742
+ --dg-success-text: #50fa7b;
4743
+ --dg-on-success: #0e2d16;
4358
4744
  --dg-warning: #f1fa8c; /* Yellow */
4359
4745
  --dg-overlay: rgba(18, 19, 26, 0.74);
4360
4746
  }
@@ -4388,6 +4774,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4388
4774
  --dg-danger: #b3372c; /* red #dc322f, deepened */
4389
4775
  --dg-danger-text: #9c2f25;
4390
4776
  --dg-on-danger: #ffffff;
4777
+ --dg-success: #6c7c00;
4778
+ --dg-success-text: #5a6800;
4779
+ --dg-on-success: #ffffff;
4391
4780
  --dg-warning: #8a5a00; /* yellow #b58900, deepened */
4392
4781
  }
4393
4782
 
@@ -4414,6 +4803,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4414
4803
  --dg-danger: #e07a72;
4415
4804
  --dg-danger-text: #f0a49e;
4416
4805
  --dg-on-danger: #34110d;
4806
+ --dg-success: #859900;
4807
+ --dg-success-text: #a4b240;
4808
+ --dg-on-success: #181c00;
4417
4809
  --dg-warning: #d5a63b;
4418
4810
  --dg-overlay: rgba(0, 20, 26, 0.74);
4419
4811
  }
@@ -4446,6 +4838,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4446
4838
  --dg-danger: #9d0006; /* light red */
4447
4839
  --dg-danger-text: #9d0006;
4448
4840
  --dg-on-danger: #ffffff;
4841
+ --dg-success: #79740e;
4842
+ --dg-success-text: #605c0b;
4843
+ --dg-on-success: #ffffff;
4449
4844
  /* The scheme's light yellow (#b57614) is 3.33:1 on this cream ground — the
4450
4845
  warmth that makes Gruvbox work is also what makes its yellow weak here.
4451
4846
  Same hue, two steps down, 4.72:1. */
@@ -4475,6 +4870,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4475
4870
  --dg-danger: #fb4934; /* dark red */
4476
4871
  --dg-danger-text: #fb8b7f;
4477
4872
  --dg-on-danger: #2c0500;
4873
+ --dg-success: #b8bb26;
4874
+ --dg-success-text: #bfc23c;
4875
+ --dg-on-success: #212207;
4478
4876
  --dg-warning: #fabd2f; /* dark yellow */
4479
4877
  --dg-overlay: rgba(20, 20, 20, 0.74);
4480
4878
  }
@@ -4508,6 +4906,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4508
4906
  --dg-danger: #c4304a; /* red #d20f39, deepened for white text */
4509
4907
  --dg-danger-text: #b02540;
4510
4908
  --dg-on-danger: #ffffff;
4909
+ --dg-success: #358524;
4910
+ --dg-success-text: #2d701e;
4911
+ --dg-on-success: #ffffff;
4511
4912
  --dg-warning: #995f14; /* peach, deepened */
4512
4913
  }
4513
4914
 
@@ -4534,6 +4935,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4534
4935
  --dg-danger: #f38ba8; /* red */
4535
4936
  --dg-danger-text: #f5a3ba;
4536
4937
  --dg-on-danger: #3d0b1a;
4938
+ --dg-success: #a6e3a1;
4939
+ --dg-success-text: #a6e3a1;
4940
+ --dg-on-success: #1e291d;
4537
4941
  --dg-warning: #fab387; /* peach */
4538
4942
  --dg-overlay: rgba(14, 14, 22, 0.74);
4539
4943
  }
@@ -4570,6 +4974,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4570
4974
  --dg-danger: #b1364a;
4571
4975
  --dg-danger-text: #9d2c3f;
4572
4976
  --dg-on-danger: #ffffff;
4977
+ --dg-success: #587539;
4978
+ --dg-success-text: #455b2c;
4979
+ --dg-on-success: #ffffff;
4573
4980
  --dg-warning: #8a5a12;
4574
4981
  }
4575
4982
 
@@ -4596,6 +5003,9 @@ input[type='checkbox'].kanuni-datagrid-edit-form-input {
4596
5003
  --dg-danger: #f7768e; /* red */
4597
5004
  --dg-danger-text: #f993a6;
4598
5005
  --dg-on-danger: #3a0713;
5006
+ --dg-success: #9ece6a;
5007
+ --dg-success-text: #9ece6a;
5008
+ --dg-on-success: #1c2513;
4599
5009
  --dg-warning: #e0af68; /* yellow */
4600
5010
  --dg-overlay: rgba(10, 11, 18, 0.76);
4601
5011
  }