@hattisar/design-tokens 0.3.25 → 0.3.27

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 (2) hide show
  1. package/package.json +1 -1
  2. package/tokens.css +155 -26
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hattisar/design-tokens",
3
- "version": "0.3.25",
3
+ "version": "0.3.27",
4
4
  "description": "Shared design tokens (colors, type, radius, spacing, motion) and base primitives (reset, buttons, inputs, cards, modals, auth shell) for every Hattisar frontend.",
5
5
  "main": "tokens.css",
6
6
  "files": [
package/tokens.css CHANGED
@@ -138,8 +138,8 @@
138
138
  --color-secondary-fill: var(--color-background-card);
139
139
  --color-secondary-border: var(--color-border-strong);
140
140
  --color-secondary-text: var(--color-text-primary);
141
- --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
142
- --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 12%, var(--color-secondary-fill));
141
+ --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 3%, var(--color-secondary-fill));
142
+ --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
143
143
 
144
144
  /* Destructive button — irreversible actions only (delete, void). */
145
145
  --color-destructive-fill: #c70a24;
@@ -193,6 +193,24 @@
193
193
  --status-overdue-text: var(--color-danger);
194
194
  --status-overdue-bg: #feebec;
195
195
 
196
+ /* The badge palette: what a status pill is painted with, kept apart from
197
+ the --status-* accents above (those colour dashboard accents and row
198
+ bars). Quiet gray for anything healthy or finished, so a long column
199
+ of them stays calm; colour only where something is in progress or
200
+ needs a look. */
201
+ --badge-neutral-bg: rgba(0, 0, 0, 0.05);
202
+ --badge-neutral-text: #4a4a4a;
203
+ --badge-progress-bg: #8ce1f8;
204
+ --badge-progress-text: #01596f;
205
+ --badge-attention-bg: #ffe45c;
206
+ --badge-attention-text: #574100;
207
+ --badge-caution-bg: #ffc58a;
208
+ --badge-caution-text: #5c2f00;
209
+ --badge-critical-bg: #fed3d1;
210
+ --badge-critical-text: #8e0b21;
211
+ --badge-success-bg: #dcf5c9;
212
+ --badge-success-text: #214b03;
213
+
196
214
  /* Page-level warning/danger/success banners — distinct from the row
197
215
  badges above: a border plus a matching soft fill, no separate text
198
216
  color (banner text uses --color-text-primary as usual). Warning/
@@ -225,11 +243,12 @@
225
243
 
226
244
  /* The horizontal tab block (Tabs.tsx) — one frame for every context it
227
245
  appears in, whether wrapped in .card (document forms) or
228
- .form-section-tabs (Customer/Vendor/Item). Transparent on purpose:
229
- the frame shows the page canvas, so the strip reads as a gray band
230
- and the active tab's white pill and the white panel below stand out
231
- against it. A .card frame (white) hid both. */
232
- --tabs-frame-bg: transparent;
246
+ .form-section-tabs (Customer/Vendor/Item). The same gray as a widget
247
+ card's frame, so the strip reads as a gray band and the active tab's
248
+ white pill and the white panel below stand out against it. A .card
249
+ frame (white) hid both. It was transparent, which only worked while
250
+ the page canvas behind it was gray; it is a fill of its own now. */
251
+ --tabs-frame-bg: var(--color-table-header);
233
252
  --tabs-frame-border: 1px solid var(--color-border);
234
253
  --tabs-frame-radius: var(--radius-sm);
235
254
 
@@ -260,13 +279,13 @@
260
279
  --print-paper: #ffffff;
261
280
  --print-ink: #0f172a;
262
281
 
263
- /* The row a list page's summary tiles and search/filter toolbar share.
264
- 48px, not the 36px table-header/tab-strip row: those are dense
265
- header bands; this one holds a text field and a view switcher you
266
- click into, and at 36px the icon and text sat against the card edge
267
- and the gray column-header band right below ("search area look very
268
- tight"). One token so the tiles and the toolbar can't drift apart. */
269
- --toolbar-row-height: 48px;
282
+ /* The row a list page's search/filter toolbar sits in: the same 36px as
283
+ the table-header and tab-strip rows. It was 48px, once, after the
284
+ icon and text sat against the card edge at 36px ("search area look
285
+ very tight"); the bar has its own border and a margin below it now,
286
+ which is what that was missing, so the shorter row is back — asked
287
+ for directly, to match a compact admin search field. */
288
+ --toolbar-row-height: 36px;
270
289
  /* The pinned page header on a list page (title + actions), and what the
271
290
  table's column headers stick beneath. */
272
291
  --page-heading-height: 52px;
@@ -283,6 +302,10 @@
283
302
  /* The big rounded containers on a list page, after Shopify's Orders
284
303
  page: the KPI strip, the search bar and the table card all share it. */
285
304
  --list-card-radius: var(--radius-xl);
305
+ /* The outline of a list page's three containers (summary tiles, search
306
+ bar, table): the quiet row-divider grey, not the strong one, so the
307
+ frames read as surfaces rather than drawn boxes. */
308
+ --list-frame-border: var(--color-border);
286
309
  /* A table row under the cursor: a faint veil of the ink, deliberately
287
310
  lighter than the header band (--color-surface-tint) so the two never
288
311
  read as the same grey. */
@@ -294,7 +317,30 @@
294
317
  hairline of its own to read against the page. Primary is simply the
295
318
  bare `button` rule (--color-cta). */
296
319
  --button-secondary-bg: var(--color-secondary-fill);
297
- --button-secondary-shadow: var(--shadow-btn-secondary), 0 0 0 1px var(--color-border);
320
+ /* The press and hover motion every button shares: a long ease-out, which
321
+ reads as snappy because most of the change lands in the first moments. */
322
+ --ease-button: cubic-bezier(0.2, 0.8, 0, 1);
323
+ /* An icon-only button with no fill at rest (the edit pencil): a round tint of
324
+ the ink on hover, 8% like the reference's. */
325
+ --button-tertiary-hover-bg: color-mix(in srgb, var(--color-text-primary) 8%, transparent);
326
+ --duration-button: 0.4s;
327
+ --shadow-btn-primary:
328
+ 0 1px 0.5px -0.5px rgba(0, 0, 0, 0.13),
329
+ 0 1px 2px -0.5px rgba(0, 0, 0, 0.13),
330
+ 0 4px 6px -2px rgba(0, 0, 0, 0.13),
331
+ 0 2px 3px -1.5px rgba(0, 0, 0, 0.13),
332
+ inset 0 0 4px 1px var(--color-cta),
333
+ inset 0 0 4px 2px rgba(255, 255, 255, 0.1),
334
+ inset 0 0 12px -6px rgba(255, 255, 255, 0.75);
335
+ --shadow-btn-secondary: 0 1px 2px rgba(9, 9, 11, 0.05);
336
+ --button-primary-sheen:
337
+ radial-gradient(50% 50% at 50% 0%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%),
338
+ radial-gradient(49.59% 37.11% at 50.41% 101.56%, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 66.46%);
339
+ --button-secondary-shadow:
340
+ 0 0 0 1px rgba(0, 0, 0, 0.07),
341
+ 0 2px 20px 0 rgba(0, 0, 0, 0.03),
342
+ 0 5px 20px 0 rgba(0, 0, 0, 0.03),
343
+ 0 8px 60px 0 rgba(0, 0, 0, 0.03);
298
344
 
299
345
  /* The picture picker (ImagePicker.tsx) behind an item image, the org
300
346
  logo and both user photos. Named so those four can't drift apart. */
@@ -482,7 +528,30 @@
482
528
  --sidebar-icon-size: 20px;
483
529
  --sidebar-control-height: 36px;
484
530
  --sidebar-item-height: 30px;
531
+ /* The sidebar's search field: a short, rounder pill on a lighter fill,
532
+ lifted by a faint inner highlight and a hairline edge so it reads as a
533
+ raised control on the dark rail rather than a flat patch. */
534
+ --sidebar-search-height: 30px;
535
+ --sidebar-search-radius: var(--radius-lg);
536
+ --sidebar-search-shadow:
537
+ inset 0 0 0 1px color-mix(in srgb, var(--sidebar-active-text) 2%, transparent),
538
+ inset 0 1px 1px 0 color-mix(in srgb, var(--sidebar-active-text) 6%, transparent),
539
+ inset 0 0 12px 1px color-mix(in srgb, var(--sidebar-active-text) 6%, transparent),
540
+ 0 1px 2px 0 rgba(0, 0, 0, 0.1),
541
+ 0 0 0 1px rgba(0, 0, 0, 0.1);
485
542
  --sidebar-item-weight: 450;
543
+ /* One row for all three rails (the main sidebar, Settings, Reports): the
544
+ same padding, icon-to-label gap, weight and active weight, so the same
545
+ row looks the same wherever it sits. A sub-item's text starts under its
546
+ parent's text: left padding + the icon + the gap. */
547
+ --sidebar-icon-inset: 6px;
548
+ --sidebar-row-padding: 5px 8px 5px var(--sidebar-icon-inset);
549
+ --sidebar-row-gap: var(--space-2);
550
+ /* The space between one row and the next, at every level, so a top-level
551
+ row and a sub-item sit the same distance from their neighbours. */
552
+ --sidebar-row-spacing: 6px;
553
+ --sidebar-sub-indent: calc(var(--sidebar-icon-inset) + var(--sidebar-icon-size) + var(--sidebar-row-gap));
554
+ --sidebar-active-weight: var(--font-weight-medium);
486
555
  --sidebar-badge-size: 22px;
487
556
  --sidebar-avatar-size: 28px;
488
557
  --popout-min-width: 180px;
@@ -495,7 +564,11 @@
495
564
  layout's own sidebar width, the same reason --header-height above
496
565
  moved too. */
497
566
  --sidebar-width: 220px;
498
- --sidebar-width-collapsed: 56px;
567
+ /* The collapsed rail is exactly the width of its icon column: the row's
568
+ icon inset, the icon, and the same inset again, inside the rail's own
569
+ padding — so an icon is in the same place whether the rail is open or
570
+ closed. */
571
+ --sidebar-width-collapsed: calc(2 * var(--space-2) + 2 * var(--sidebar-icon-inset) + var(--sidebar-icon-size));
499
572
  --sidebar-height: calc(100vh - var(--header-height));
500
573
 
501
574
  /* Two widths, because a page is one of two things.
@@ -611,8 +684,10 @@
611
684
  --color-cta-active: var(--color-brand-active);
612
685
  --color-cta-text: var(--color-brand-text);
613
686
 
614
- --shadow-btn-primary: 0 1px 2px rgba(9, 9, 11, 0.12);
615
- --shadow-btn-secondary: 0 1px 2px rgba(9, 9, 11, 0.05);
687
+ --shadow-btn-primary: 0 1px 2px rgba(0, 0, 0, 0.4);
688
+ --shadow-btn-secondary: 0 1px 2px rgba(0, 0, 0, 0.3);
689
+ --button-primary-sheen: none;
690
+ --button-secondary-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.3);
616
691
 
617
692
  --color-secondary-fill: var(--color-surface-tint);
618
693
  --color-secondary-border: var(--color-border-strong);
@@ -652,6 +727,19 @@
652
727
  --status-overdue-text: var(--color-danger);
653
728
  --status-overdue-bg: #401d21;
654
729
 
730
+ --badge-neutral-bg: rgba(255, 255, 255, 0.08);
731
+ --badge-neutral-text: #d4d4d8;
732
+ --badge-progress-bg: #0f3341;
733
+ --badge-progress-text: #8ce1f8;
734
+ --badge-attention-bg: #4a3b00;
735
+ --badge-attention-text: #ffe45c;
736
+ --badge-caution-bg: #4d2c0a;
737
+ --badge-caution-text: #ffc58a;
738
+ --badge-critical-bg: #4d1218;
739
+ --badge-critical-text: #fda4a8;
740
+ --badge-success-bg: #1f3a0f;
741
+ --badge-success-text: #b3f782;
742
+
655
743
  --banner-warning-bg: #3a2907;
656
744
  --banner-warning-border: var(--color-warning);
657
745
  --banner-danger-bg: #4a1119;
@@ -720,14 +808,29 @@
720
808
  --color-cta-active: var(--color-brand-active);
721
809
  --color-cta-text: var(--color-brand-text);
722
810
 
723
- --shadow-btn-primary: 0 1px 2px rgba(0, 0, 0, 0.4);
724
- --shadow-btn-secondary: 0 1px 2px rgba(0, 0, 0, 0.3);
811
+ --shadow-btn-primary:
812
+ 0 1px 0.5px -0.5px rgba(0, 0, 0, 0.13),
813
+ 0 1px 2px -0.5px rgba(0, 0, 0, 0.13),
814
+ 0 4px 6px -2px rgba(0, 0, 0, 0.13),
815
+ 0 2px 3px -1.5px rgba(0, 0, 0, 0.13),
816
+ inset 0 0 4px 1px var(--color-cta),
817
+ inset 0 0 4px 2px rgba(255, 255, 255, 0.1),
818
+ inset 0 0 12px -6px rgba(255, 255, 255, 0.75);
819
+ --shadow-btn-secondary: 0 1px 2px rgba(9, 9, 11, 0.05);
820
+ --button-primary-sheen:
821
+ radial-gradient(50% 50% at 50% 0%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%),
822
+ radial-gradient(49.59% 37.11% at 50.41% 101.56%, rgba(255, 255, 255, 0.15) 0%, rgba(255, 255, 255, 0) 66.46%);
823
+ --button-secondary-shadow:
824
+ 0 0 0 1px rgba(0, 0, 0, 0.07),
825
+ 0 2px 20px 0 rgba(0, 0, 0, 0.03),
826
+ 0 5px 20px 0 rgba(0, 0, 0, 0.03),
827
+ 0 8px 60px 0 rgba(0, 0, 0, 0.03);
725
828
 
726
829
  --color-secondary-fill: var(--color-background-card);
727
830
  --color-secondary-border: var(--color-border-strong);
728
831
  --color-secondary-text: var(--color-text-primary);
729
- --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
730
- --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 12%, var(--color-secondary-fill));
832
+ --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 3%, var(--color-secondary-fill));
833
+ --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
731
834
 
732
835
  --color-destructive-fill: #c70a24;
733
836
  --color-destructive-hover: #a30a24;
@@ -760,6 +863,24 @@
760
863
  --status-overdue-text: var(--color-danger);
761
864
  --status-overdue-bg: #feebec;
762
865
 
866
+ /* The badge palette: what a status pill is painted with, kept apart from
867
+ the --status-* accents above (those colour dashboard accents and row
868
+ bars). Quiet gray for anything healthy or finished, so a long column
869
+ of them stays calm; colour only where something is in progress or
870
+ needs a look. */
871
+ --badge-neutral-bg: rgba(0, 0, 0, 0.05);
872
+ --badge-neutral-text: #4a4a4a;
873
+ --badge-progress-bg: #8ce1f8;
874
+ --badge-progress-text: #01596f;
875
+ --badge-attention-bg: #ffe45c;
876
+ --badge-attention-text: #574100;
877
+ --badge-caution-bg: #ffc58a;
878
+ --badge-caution-text: #5c2f00;
879
+ --badge-critical-bg: #fed3d1;
880
+ --badge-critical-text: #8e0b21;
881
+ --badge-success-bg: #dcf5c9;
882
+ --badge-success-text: #214b03;
883
+
763
884
  --banner-warning-bg: #fff3e6;
764
885
  --banner-warning-border: var(--color-warning);
765
886
  --banner-danger-bg: #fdeaed;
@@ -931,21 +1052,29 @@ button {
931
1052
  font-size: var(--button-font-size);
932
1053
  font-weight: var(--button-font-weight);
933
1054
  background: var(--color-cta);
1055
+ /* A soft light at the top edge and a fainter one at the bottom, the way
1056
+ the reference admin lifts its primary button off the page. Anything that
1057
+ sets its own `background:` shorthand clears this along with the colour. */
1058
+ background-image: var(--button-primary-sheen);
934
1059
  color: var(--color-cta-text);
935
1060
  box-shadow: var(--shadow-btn-primary);
936
1061
  transition:
937
- transform 0.05s ease,
938
- background 0.15s ease,
939
- box-shadow 0.15s ease;
1062
+ background-color var(--duration-button) var(--ease-button),
1063
+ box-shadow var(--duration-button) var(--ease-button),
1064
+ transform var(--duration-button) var(--ease-button);
940
1065
  }
941
1066
 
942
1067
  button:hover {
943
1068
  background: var(--color-cta-hover);
1069
+ background-image: var(--button-primary-sheen);
944
1070
  }
945
1071
 
1072
+ /* Pressed is a darker fill, not a shrink: the button stays the size it is,
1073
+ which is what made the old one feel busy. */
946
1074
  button:active {
947
1075
  background: var(--color-cta-active);
948
- transform: scale(0.97);
1076
+ background-image: var(--button-primary-sheen);
1077
+ transform: none;
949
1078
  }
950
1079
 
951
1080
  button:disabled {