@hattisar/design-tokens 0.3.31 → 0.3.33

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 +113 -34
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hattisar/design-tokens",
3
- "version": "0.3.31",
3
+ "version": "0.3.33",
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
@@ -136,7 +136,6 @@
136
136
  rather than their own literal hex, so the secondary button always
137
137
  tracks the same neutral scale as the rest of the page. */
138
138
  --color-secondary-fill: var(--color-background-card);
139
- --color-secondary-border: var(--color-border-strong);
140
139
  --color-secondary-text: var(--color-text-primary);
141
140
  --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 3%, var(--color-secondary-fill));
142
141
  --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
@@ -223,7 +222,6 @@
223
222
  --banner-danger-bg: #fdeaed;
224
223
  --banner-danger-border: var(--color-danger);
225
224
  --banner-success-bg: #e2f7e6;
226
- --banner-success-border: var(--color-success);
227
225
 
228
226
  /* A restrained scale, not flat — every step deliberately small, since
229
227
  most controls here are compact (30-36px buttons/inputs, smaller
@@ -234,12 +232,24 @@
234
232
  remove-buttons inside chips, the settings toggle switch) — never
235
233
  applied to a badge/tag/chip just for a rounder look; those use
236
234
  --radius-sm like everything else (see .status-badge and friends). */
235
+ --radius-2xs: 3px; /* the smallest rounding: a keyboard hint, a scrollbar thumb, a highlighted word, the top of a tab's indicator */
237
236
  --radius-xs: 6px;
238
237
  --radius-sm: 8px;
239
238
  --radius-md: 11px;
240
239
  --radius-lg: 14px;
241
240
  --radius-xl: 17px;
242
241
  --radius-full: 9999px;
242
+ /* Roles. Stylesheets say what a corner is FOR, so changing the look of every control or every container is one
243
+ edit here: a control is anything you press or type into (buttons, fields, the search bar); a container holds
244
+ other things (cards, tiles, the table card, popovers); a chip is a small label. */
245
+ --radius-control: var(--radius-sm);
246
+ --radius-container: var(--radius-md);
247
+ --radius-chip: var(--radius-xs);
248
+
249
+ /* The width of a rule or a border: a hairline everywhere, a heavier one where a line has to carry weight (a print rule, a
250
+ highlighted edge). Stated here so no stylesheet or component writes "1px" for a border. */
251
+ --border-width: 1px;
252
+ --border-width-thick: 2px;
243
253
 
244
254
  /* The horizontal tab block (Tabs.tsx) — one frame for every context it
245
255
  appears in, whether wrapped in .card (document forms) or
@@ -249,15 +259,15 @@
249
259
  frame (white) hid both. It was transparent, which only worked while
250
260
  the page canvas behind it was gray; it is a fill of its own now. */
251
261
  --tabs-frame-bg: var(--color-table-header);
252
- --tabs-frame-border: 1px solid var(--color-border);
253
- --tabs-frame-radius: var(--radius-sm);
262
+ --tabs-frame-border: var(--border-width) solid var(--color-border);
263
+ --tabs-frame-radius: var(--radius-control);
254
264
 
255
265
  /* Anything that floats over the page: dropdown and action menus, the
256
266
  global-search results, combobox lists, the profile/notification
257
267
  drawer, tooltips and modal dialogs. Their surface already had a
258
268
  border and a shadow but no radius, so every popup was a hard
259
269
  rectangle beside the rounded buttons and cards that opened it. */
260
- --popup-radius: var(--radius-sm);
270
+ --popup-radius: var(--radius-container);
261
271
 
262
272
  /* The header row shared by every titled card (WidgetCard) and the tab
263
273
  strip that stands in for one, and the control that sits inside it (a
@@ -274,9 +284,9 @@
274
284
  colour and radius tokens, so they follow the theme without a block of
275
285
  their own. */
276
286
  --widget-bg: var(--color-table-header);
277
- --widget-border-width: 1px;
287
+ --widget-border-width: var(--border-width);
278
288
  --widget-border-color: var(--color-border-strong);
279
- --widget-radius: var(--radius-sm);
289
+ --widget-radius: var(--radius-container);
280
290
  --widget-shadow: var(--shadow-sm);
281
291
  --widget-header-height: var(--card-header-height);
282
292
  --widget-header-padding: 6px var(--space-3);
@@ -328,7 +338,7 @@
328
338
 
329
339
  /* The big rounded containers on a list page, after Shopify's Orders
330
340
  page: the KPI strip, the search bar and the table card all share it. */
331
- --list-card-radius: var(--radius-xl);
341
+ --list-card-radius: var(--radius-container);
332
342
  /* The outline of a list page's three containers (summary tiles, search
333
343
  bar, table): the quiet row-divider grey, not the strong one, so the
334
344
  frames read as surfaces rather than drawn boxes. */
@@ -359,7 +369,6 @@
359
369
  inset 0 0 4px 1px var(--color-cta),
360
370
  inset 0 0 4px 2px rgba(255, 255, 255, 0.1),
361
371
  inset 0 0 12px -6px rgba(255, 255, 255, 0.75);
362
- --shadow-btn-secondary: 0 1px 2px rgba(9, 9, 11, 0.05);
363
372
  --button-primary-sheen:
364
373
  radial-gradient(50% 50% at 50% 0%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%),
365
374
  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%);
@@ -372,7 +381,7 @@
372
381
  /* The picture picker (ImagePicker.tsx) behind an item image, the org
373
382
  logo and both user photos. Named so those four can't drift apart. */
374
383
  --image-picker-size: 96px;
375
- --image-picker-border: 1px dashed var(--color-border);
384
+ --image-picker-border: var(--border-width) dashed var(--color-border);
376
385
  --image-picker-overlay: color-mix(in srgb, var(--color-background-card) 55%, transparent);
377
386
 
378
387
  /* The measurement row: three sizes and their unit, a weight and its
@@ -446,6 +455,9 @@
446
455
  the input ends up 6px taller than the field it contains, which is
447
456
  how an overlaid control centres itself slightly high. */
448
457
  --field-label-gap: 6px;
458
+ /* The vertical padding of a text field, select or textarea. 8px (a 38px field) is the shared default; the staff app sets it
459
+ from a field height (data-views.css), so the height is one number and the padding follows from the line height. */
460
+ --field-pad-y: 8px;
449
461
  --space-12: 48px;
450
462
  /* Two steps past the old ceiling, for the gaps that separate whole
451
463
  regions of a page rather than elements inside one. Without them
@@ -470,7 +482,6 @@
470
482
  /* A control sharing a line with others — the second and third field
471
483
  of a header row. Narrower than a control that owns its row, because
472
484
  three of those do not fit and a date needs far less than 340px. */
473
- --form-control-width-compact: 200px;
474
485
  /* The label beside it. Fixed rather than sized to each label's own
475
486
  text — "Order date", "Due date" and "Tax rate" all sit in this
476
487
  position on different rows of the same header, and letting each
@@ -524,6 +535,31 @@
524
535
  --duration-fast: 100ms;
525
536
  --duration-base: 150ms;
526
537
  --duration-slow: 250ms;
538
+ /* Panels that move as a whole (the sidebar collapsing, a Settings menu opening beside it): longer than a control's
539
+ hover, with an ease-out that lands softly, so the layout glides instead of snapping. */
540
+ --duration-panel: 350ms;
541
+ --ease-panel: cubic-bezier(0.32, 0.72, 0, 1);
542
+ /* Things that arrive (the menu on load): 400ms on a long ease-out, which lands most of the way in the first
543
+ moments. The same curve as --ease-button. A row starts --nav-enter-shift to the left and --nav-enter-blur
544
+ out of focus, and each row follows the one above by --stagger-step. */
545
+ --duration-enter: 400ms;
546
+ --ease-enter: cubic-bezier(0.2, 0.8, 0, 1);
547
+ --stagger-step: 10ms;
548
+ /* The frame first, then what is in it: the sidebar column, the page and their backgrounds are on screen at once,
549
+ and every arriving thing waits this long before it starts, as Shopify's does (its contents begin well after
550
+ the shell is up). */
551
+ --enter-delay: 200ms;
552
+ /* A section's sub-items arriving when you open it: the same recipe, gentler. They only step 4px and follow each
553
+ other 25ms apart, measured off Shopify's sub-menus. */
554
+ --sub-enter-shift: -4px;
555
+ --sub-stagger-step: 25ms;
556
+ --nav-enter-shift: -60px;
557
+ --nav-enter-blur: 2px;
558
+ --page-enter-rise: 60px;
559
+ /* What happens when you point at or press something: quick, on the browser's own `ease`, which is the curve
560
+ Shopify's admin uses for every hover colour fade. Arrivals above are slow; reactions are not. */
561
+ --duration-hover: 150ms;
562
+ --ease-hover: ease;
527
563
 
528
564
  /* 58px, not 52 — asked for directly, matched against a reference
529
565
  layout's own header height so this app's chrome proportions read
@@ -553,7 +589,6 @@
553
589
  /* The row you are on: the full ink on the same fill hover uses, the
554
590
  weight doing the rest. */
555
591
  --sidebar-active-ink: var(--sidebar-active-text);
556
- --sidebar-rail-bg: var(--sidebar-bg);
557
592
  /* The one background every popout shares (account menu, notifications,
558
593
  support, the collapsed rail's hover menu, the search popup): the
559
594
  sidebar colour one step lighter, so a popout reads as lifted off
@@ -561,16 +596,22 @@
561
596
  --popout-bg: color-mix(in srgb, var(--sidebar-active-text) 12%, var(--sidebar-bg));
562
597
 
563
598
  /* Sidebar and popout dimensions, named once. */
564
- --sidebar-icon-size: 20px;
599
+ /* A menu icon: 18px, drawn at 1.5px (--sidebar-icon-stroke on the 24-unit grid it is drawn on, 2 is 1.5px at this
600
+ size), as Shopify's admin does at 16px with text a size smaller. The inset below is chosen so the icon sits at
601
+ the same place in the 48px collapsed rail: 2 * 8 + 2 * 7 + 18. The slot is the 20px column the Settings and
602
+ Reports rows were built around; their icon is centred in it so their text does not move. */
603
+ --sidebar-icon-size: 18px;
604
+ --sidebar-icon-stroke: 2;
605
+ --sidebar-icon-slot: 20px;
565
606
  --sidebar-control-height: 36px;
566
607
  --sidebar-item-height: 30px;
567
608
  /* The sidebar's search field: a short, rounder pill on a lighter fill,
568
609
  lifted by a faint inner highlight and a hairline edge so it reads as a
569
610
  raised control on the dark rail rather than a flat patch. */
570
611
  --sidebar-search-height: 30px;
571
- --sidebar-search-radius: var(--radius-lg);
612
+ --sidebar-search-radius: var(--radius-control);
572
613
  --sidebar-search-shadow:
573
- inset 0 0 0 1px color-mix(in srgb, var(--sidebar-active-text) 2%, transparent),
614
+ inset 0 0 0 var(--border-width) color-mix(in srgb, var(--sidebar-active-text) 2%, transparent),
574
615
  inset 0 1px 1px 0 color-mix(in srgb, var(--sidebar-active-text) 6%, transparent),
575
616
  inset 0 0 12px 1px color-mix(in srgb, var(--sidebar-active-text) 6%, transparent),
576
617
  0 1px 2px 0 rgba(0, 0, 0, 0.1),
@@ -580,7 +621,7 @@
580
621
  same padding, icon-to-label gap, weight and active weight, so the same
581
622
  row looks the same wherever it sits. A sub-item's text starts under its
582
623
  parent's text: left padding + the icon + the gap. */
583
- --sidebar-icon-inset: 6px;
624
+ --sidebar-icon-inset: 7px;
584
625
  --sidebar-row-padding: 5px 8px 5px var(--sidebar-icon-inset);
585
626
  --sidebar-row-gap: var(--space-2);
586
627
  /* The space between one row and the next, at every level, so a top-level
@@ -588,10 +629,11 @@
588
629
  --sidebar-row-spacing: 6px;
589
630
  --sidebar-sub-indent: calc(var(--sidebar-icon-inset) + var(--sidebar-icon-size) + var(--sidebar-row-gap));
590
631
  --sidebar-active-weight: var(--font-weight-medium);
591
- --sidebar-badge-size: 22px;
592
632
  --sidebar-avatar-size: 28px;
593
633
  --popout-min-width: 180px;
594
- --search-popup-width: 640px;
634
+ --search-popup-width: 650px;
635
+ --search-popup-field-height: 64px;
636
+ --search-popup-min-height: 420px;
595
637
  --mobile-nav-width: 350px;
596
638
 
597
639
  /* Every left-hand nav rail in an app sharing this one width instead
@@ -727,12 +769,10 @@
727
769
  --color-cta-text: var(--color-brand-text);
728
770
 
729
771
  --shadow-btn-primary: 0 1px 2px rgba(0, 0, 0, 0.4);
730
- --shadow-btn-secondary: 0 1px 2px rgba(0, 0, 0, 0.3);
731
772
  --button-primary-sheen: none;
732
773
  --button-secondary-shadow: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 1px 2px rgba(0, 0, 0, 0.3);
733
774
 
734
775
  --color-secondary-fill: var(--color-surface-tint);
735
- --color-secondary-border: var(--color-border-strong);
736
776
  --color-secondary-text: var(--color-text-primary);
737
777
  --color-secondary-hover: color-mix(in srgb, white 6%, var(--color-secondary-fill));
738
778
  --color-secondary-active: color-mix(in srgb, white 12%, var(--color-secondary-fill));
@@ -787,7 +827,6 @@
787
827
  --banner-danger-bg: #4a1119;
788
828
  --banner-danger-border: var(--color-danger);
789
829
  --banner-success-bg: #0a3129;
790
- --banner-success-border: var(--color-success);
791
830
 
792
831
  /* A dark surface cannot be lifted by a soft grey shadow — there is
793
832
  nothing lighter behind it to catch the light. So these go darker
@@ -858,7 +897,6 @@
858
897
  inset 0 0 4px 1px var(--color-cta),
859
898
  inset 0 0 4px 2px rgba(255, 255, 255, 0.1),
860
899
  inset 0 0 12px -6px rgba(255, 255, 255, 0.75);
861
- --shadow-btn-secondary: 0 1px 2px rgba(9, 9, 11, 0.05);
862
900
  --button-primary-sheen:
863
901
  radial-gradient(50% 50% at 50% 0%, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%),
864
902
  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%);
@@ -869,7 +907,6 @@
869
907
  0 8px 60px 0 rgba(0, 0, 0, 0.03);
870
908
 
871
909
  --color-secondary-fill: var(--color-background-card);
872
- --color-secondary-border: var(--color-border-strong);
873
910
  --color-secondary-text: var(--color-text-primary);
874
911
  --color-secondary-hover: color-mix(in srgb, var(--color-text-primary) 3%, var(--color-secondary-fill));
875
912
  --color-secondary-active: color-mix(in srgb, var(--color-text-primary) 6%, var(--color-secondary-fill));
@@ -928,7 +965,6 @@
928
965
  --banner-danger-bg: #fdeaed;
929
966
  --banner-danger-border: var(--color-danger);
930
967
  --banner-success-bg: #e2f7e6;
931
- --banner-success-border: #047b5d;
932
968
 
933
969
  /* Deliberately still flat, unlike :root's. The only thing that pins
934
970
  itself to light is a print page, and a shadow on paper is a grey
@@ -973,7 +1009,7 @@
973
1009
 
974
1010
  *::-webkit-scrollbar-thumb {
975
1011
  background: var(--color-border-strong);
976
- border: 2px solid transparent;
1012
+ border: var(--border-width-thick) solid transparent;
977
1013
  background-clip: padding-box;
978
1014
  }
979
1015
 
@@ -1238,10 +1274,10 @@ textarea {
1238
1274
  font-weight: var(--font-weight-regular);
1239
1275
  line-height: 1.4;
1240
1276
  width: 100%;
1241
- padding: 8px 12px;
1277
+ padding: var(--field-pad-y) 12px;
1242
1278
  margin-top: var(--field-label-gap);
1243
- border: 1px solid var(--color-border-strong);
1244
- border-radius: var(--radius-sm);
1279
+ border: var(--border-width) solid var(--color-border-strong);
1280
+ border-radius: var(--radius-control);
1245
1281
  background: var(--color-input);
1246
1282
  color: var(--color-text-primary);
1247
1283
  transition:
@@ -1528,7 +1564,7 @@ input[type="radio"] {
1528
1564
  job. */
1529
1565
  .card {
1530
1566
  background: var(--color-background-card);
1531
- border: 1px solid var(--color-border-strong);
1567
+ border: var(--border-width) solid var(--color-border-strong);
1532
1568
  border-radius: var(--radius-sm);
1533
1569
  box-shadow: var(--shadow-sm);
1534
1570
  padding: 16px;
@@ -1790,7 +1826,7 @@ a.card:hover {
1790
1826
 
1791
1827
  .modal-panel {
1792
1828
  background: var(--color-surface-raised);
1793
- border: 1px solid var(--color-border-raised);
1829
+ border: 0;
1794
1830
  box-shadow: var(--shadow-popover);
1795
1831
  width: 100%;
1796
1832
  max-width: 640px;
@@ -1803,7 +1839,6 @@ a.card:hover {
1803
1839
 
1804
1840
  .modal-panel-header {
1805
1841
  padding: 12px 16px;
1806
- border-bottom: 1px solid var(--color-border);
1807
1842
  display: flex;
1808
1843
  align-items: center;
1809
1844
  gap: 12px;
@@ -1821,7 +1856,6 @@ a.card:hover {
1821
1856
 
1822
1857
  .modal-panel-footer {
1823
1858
  padding: 12px 16px;
1824
- border-top: 1px solid var(--color-border);
1825
1859
  display: flex;
1826
1860
  justify-content: flex-end;
1827
1861
  gap: 10px;
@@ -1842,6 +1876,36 @@ a.card:hover {
1842
1876
  --ui-accent-hover: #0b5f58;
1843
1877
  --ui-accent-ink: #fff;
1844
1878
  --ui-accent-soft: color-mix(in srgb, var(--ui-accent) var(--ui-wash), transparent);
1879
+ /* The monochrome action: near-black on light, near-white on dark, with its hover and the ink that sits on it.
1880
+ The staff app points --ui-accent at these (data-views.css); the Storefront keeps the accent above, which a
1881
+ seller can swap. */
1882
+ --ui-action: #1a1a1a;
1883
+ --ui-action-hover: #303030;
1884
+ --ui-action-ink: #ffffff;
1885
+ /* The cool-grey look's surfaces and edges, by role. data-views.css maps the staff app's --ui-* tokens onto these,
1886
+ so no stylesheet writes a grey of its own. */
1887
+ --surface-canvas: #eef0f4;
1888
+ --surface-paper: #ffffff;
1889
+ --surface-band: #f6f7f9;
1890
+ --surface-tray: #eceef2;
1891
+ --edge-hairline: #dfe2e8;
1892
+ --edge-strong: #cfd3da;
1893
+ --edge-raised: #dcdfe5;
1894
+ --grid-line: #e9ebef;
1895
+ /* What a shadow is drawn in, and the two pure ends for a highlight or a scrim. */
1896
+ --shadow-ink: #101828;
1897
+ --ui-white: #ffffff;
1898
+ --ui-black: #000000;
1899
+ /* The light-grey guide line a label or barcode preview draws around its cell. Paper, so it is the same in every
1900
+ theme (it is not in the dark block). */
1901
+ --paper-guide: #999999;
1902
+ /* Data colours for chart series 2 to 5 (series 1 follows the action colour). Distinct, sharing one saturation. */
1903
+ --chart-2: #4f46e5;
1904
+ --chart-3: #0284c7;
1905
+ --chart-4: #9333ea;
1906
+ --chart-5: #d97706;
1907
+ /* The Storefront's muted text on a light page: a notch darker than the shared muted token, for contrast. */
1908
+ --sf-muted-light: #52525b;
1845
1909
  --ui-surface: var(--color-background-page);
1846
1910
  --ui-card: color-mix(in srgb, var(--color-text-primary) var(--ui-tint-card), var(--ui-surface));
1847
1911
  --ui-tray: color-mix(in srgb, var(--color-text-primary) var(--ui-tint-tray), var(--ui-card));
@@ -1852,7 +1916,6 @@ a.card:hover {
1852
1916
  --ui-field-bg-hover: color-mix(in srgb, var(--color-text-primary) var(--ui-tint-field-hover), var(--ui-card));
1853
1917
  --ui-row-alt: color-mix(in srgb, var(--color-text-primary) 3%, transparent);
1854
1918
  /* Every other row of a table, laid over its surface: what tells one row from the next now that no rule does. */
1855
- --ui-row-zebra: color-mix(in srgb, var(--color-text-primary) 4%, transparent);
1856
1919
  /* A rule between rows: present enough to follow a line across, quiet enough not to read as a grid. */
1857
1920
  --ui-divider: color-mix(in srgb, var(--color-text-primary) 8%, transparent);
1858
1921
  /* The one hairline that stays when borders do not: a thin line blended into the surface, where two panels of the same tone meet. */
@@ -1871,7 +1934,7 @@ a.card:hover {
1871
1934
  /* One button for every app that reads this tier: a rounded rectangle that matches the fields beside it, a
1872
1935
  32px target (the height of a field), medium-weight type. Apps map their own --button-* onto these. */
1873
1936
  --ui-btn-height: 32px;
1874
- --ui-btn-radius: var(--radius-sm);
1937
+ --ui-btn-radius: var(--radius-control);
1875
1938
  --ui-btn-px: var(--space-4);
1876
1939
  --ui-btn-weight: var(--font-weight-medium);
1877
1940
  --ui-ctl: 32px;
@@ -1898,6 +1961,22 @@ a.card:hover {
1898
1961
  --ui-accent: #2dd4bf;
1899
1962
  --ui-accent-hover: #5eead4;
1900
1963
  --ui-accent-ink: #04201d;
1964
+ --ui-action: #f1f1f1;
1965
+ --ui-action-hover: #d4d4d4;
1966
+ --ui-action-ink: #1a1a1a;
1967
+ --surface-canvas: #0c0c0f;
1968
+ --surface-paper: #15161a;
1969
+ --surface-band: #1a1b20;
1970
+ --surface-tray: #1f2026;
1971
+ --edge-hairline: #2a2c33;
1972
+ --edge-strong: #3a3d46;
1973
+ --edge-raised: #31343c;
1974
+ --grid-line: #24262c;
1975
+ --shadow-ink: #000000;
1976
+ --chart-2: #818cf8;
1977
+ --chart-3: #38bdf8;
1978
+ --chart-4: #c084fc;
1979
+ --chart-5: #fbbf24;
1901
1980
  --ui-surface: var(--color-background-global);
1902
1981
  --ui-tint-card: 5%;
1903
1982
  --ui-card: color-mix(in srgb, var(--color-text-primary) var(--ui-tint-card), var(--color-background-page));