@ahmetilhn/hanui 4.1.0 → 5.3.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.
Files changed (75) hide show
  1. package/README.md +259 -39
  2. package/build/charts.cjs +2 -0
  3. package/build/charts.cjs.map +1 -0
  4. package/build/charts.css +1 -0
  5. package/build/charts.js +1843 -0
  6. package/build/charts.js.map +1 -0
  7. package/build/chat.cjs +3 -0
  8. package/build/chat.cjs.map +1 -0
  9. package/build/chat.css +1 -0
  10. package/build/chat.js +707 -0
  11. package/build/chat.js.map +1 -0
  12. package/build/index.cjs +7 -7
  13. package/build/index.cjs.map +1 -1
  14. package/build/index.d.ts +472 -222
  15. package/build/index.js +3336 -3096
  16. package/build/index.js.map +1 -1
  17. package/build/scss/_colors.generated.scss +119 -0
  18. package/build/scss/_index.scss +6 -0
  19. package/build/scss/_metrics.generated.scss +49 -0
  20. package/build/scss/_mixins.scss +675 -0
  21. package/build/scss/_variables.scss +51 -0
  22. package/build/styles.css +1 -1
  23. package/build/types/charts/AreaChart/index.d.ts +14 -0
  24. package/build/types/charts/BarChart/index.d.ts +16 -0
  25. package/build/types/charts/BoxPlot/index.d.ts +43 -0
  26. package/build/types/charts/ComposedChart/index.d.ts +16 -0
  27. package/build/types/charts/Heatmap/index.d.ts +30 -0
  28. package/build/types/charts/Histogram/index.d.ts +29 -0
  29. package/build/types/charts/LineChart/index.d.ts +14 -0
  30. package/build/types/charts/PieChart/index.d.ts +36 -0
  31. package/build/types/charts/RadarChart/index.d.ts +40 -0
  32. package/build/types/charts/ScatterPlot/index.d.ts +41 -0
  33. package/build/types/charts/core/CartesianChart.d.ts +43 -0
  34. package/build/types/charts/core/ChartFrame.d.ts +55 -0
  35. package/build/types/charts/core/axes.d.ts +34 -0
  36. package/build/types/charts/core/cartesian.d.ts +79 -0
  37. package/build/types/charts/core/format.d.ts +9 -0
  38. package/build/types/charts/core/margins.d.ts +9 -0
  39. package/build/types/charts/core/palette.d.ts +13 -0
  40. package/build/types/charts/core/path.d.ts +24 -0
  41. package/build/types/charts/core/scale.d.ts +40 -0
  42. package/build/types/charts/core/series.d.ts +11 -0
  43. package/build/types/charts/core/spatial.d.ts +12 -0
  44. package/build/types/charts/core/stats.d.ts +34 -0
  45. package/build/types/charts/core/types.d.ts +31 -0
  46. package/build/types/charts/core/useChartWidth.d.ts +7 -0
  47. package/build/types/charts/index.d.ts +21 -0
  48. package/build/types/chat/ActionList/index.d.ts +46 -0
  49. package/build/types/chat/AppBar/index.d.ts +21 -0
  50. package/build/types/chat/ChatMessage/index.d.ts +24 -0
  51. package/build/types/chat/ChatThread/index.d.ts +24 -0
  52. package/build/types/chat/Citation/index.d.ts +15 -0
  53. package/build/types/chat/CodeBlock/index.d.ts +27 -0
  54. package/build/types/chat/DescriptionList/index.d.ts +16 -0
  55. package/build/types/chat/Legend/index.d.ts +20 -0
  56. package/build/types/chat/MessageActions/index.d.ts +21 -0
  57. package/build/types/chat/PromptInput/index.d.ts +47 -0
  58. package/build/types/chat/PromptSuggestions/index.d.ts +25 -0
  59. package/build/types/chat/Prose/index.d.ts +15 -0
  60. package/build/types/chat/ReasoningBlock/index.d.ts +24 -0
  61. package/build/types/chat/ReasoningText/index.d.ts +14 -0
  62. package/build/types/chat/SegmentBar/index.d.ts +46 -0
  63. package/build/types/chat/SourceList/index.d.ts +25 -0
  64. package/build/types/chat/TerminalOutput/index.d.ts +25 -0
  65. package/build/types/chat/ToolCall/index.d.ts +41 -0
  66. package/build/types/chat/index.d.ts +26 -0
  67. package/build/types/helpers/class-name.helper.d.ts +3 -0
  68. package/build/types/helpers/component.helper.d.ts +13 -0
  69. package/build/types/helpers/label.helper.d.ts +12 -0
  70. package/build/types/theme/palette.d.ts +203 -0
  71. package/build/types/theme/tokens.d.ts +208 -0
  72. package/build/types/types/common-element-props.type.d.ts +8 -0
  73. package/build/types/types/link.type.d.ts +14 -0
  74. package/build/types/types/theme.type.d.ts +223 -0
  75. package/package.json +19 -2
@@ -0,0 +1,675 @@
1
+ @use 'sass:list';
2
+ @use 'variables' as *;
3
+
4
+ @mixin for-mobile {
5
+ @media (max-width: #{$breakpoint-mobile}) {
6
+ @content;
7
+ }
8
+ }
9
+
10
+ @mixin for-tablet-portrait {
11
+ @media (max-width: #{$breakpoint-tablet-portrait}) {
12
+ @content;
13
+ }
14
+ }
15
+
16
+ @mixin for-tablet {
17
+ @media (max-width: #{$breakpoint-tablet}) {
18
+ @content;
19
+ }
20
+ }
21
+
22
+ @mixin for-desktop-up {
23
+ @media (min-width: #{$breakpoint-tablet + 1px}) {
24
+ @content;
25
+ }
26
+ }
27
+
28
+ @mixin for-touch {
29
+ @media (hover: none) and (pointer: coarse) {
30
+ @content;
31
+ }
32
+ }
33
+
34
+ @mixin reduced-motion {
35
+ @media (prefers-reduced-motion: reduce) {
36
+ @content;
37
+ }
38
+ }
39
+
40
+ @mixin for-rtl {
41
+ [dir='rtl'] & {
42
+ @content;
43
+ }
44
+ }
45
+
46
+ @mixin surface-transition($shift: 6px, $duration: $duration-fast, $has-shift: true) {
47
+ opacity: 0;
48
+
49
+ @if $has-shift {
50
+ translate: 0 $shift;
51
+ }
52
+
53
+ transition:
54
+ opacity $duration $ease-out,
55
+ translate $duration $ease-out,
56
+ overlay $duration allow-discrete,
57
+ display $duration allow-discrete;
58
+
59
+ &[open] {
60
+ opacity: 1;
61
+
62
+ @if $has-shift {
63
+ translate: 0 0;
64
+ }
65
+ }
66
+
67
+ @starting-style {
68
+ &[open] {
69
+ opacity: 0;
70
+
71
+ @if $has-shift {
72
+ translate: 0 $shift;
73
+ }
74
+ }
75
+ }
76
+
77
+ @include reduced-motion {
78
+ transition: none;
79
+ }
80
+ }
81
+
82
+ // Koyu temaya özgü kural — açık seçim ve sistem tercihi, `_tokens.generated.scss` ile AYNI seçiciler.
83
+ // ⚠ Tema alt ağaca kapsamlandırılamaz (bkz. CLAUDE.md "Marka şeridi"); bu yalnızca KÖKE bakar.
84
+ @mixin for-dark {
85
+ :root[data-hanui-theme='dark'] & {
86
+ @content;
87
+ }
88
+
89
+ @media (prefers-color-scheme: dark) {
90
+ :root:not([data-hanui-theme]) & {
91
+ @content;
92
+ }
93
+ }
94
+ }
95
+
96
+ @mixin interactive-surface($rest: transparent, $hover: $surface-2, $pressed: $surface-3) {
97
+ background-color: $rest;
98
+ transition:
99
+ background-color $duration-fast $ease-out,
100
+ translate $duration-instant $ease-out;
101
+
102
+ &:hover:not(:disabled):not([aria-disabled='true']) {
103
+ background-color: $hover;
104
+ }
105
+
106
+ &:active:not(:disabled):not([aria-disabled='true']) {
107
+ background-color: $pressed;
108
+ translate: 0 1px;
109
+ }
110
+
111
+ @include reduced-motion {
112
+ transition: none;
113
+
114
+ &:active:not(:disabled):not([aria-disabled='true']) {
115
+ translate: none;
116
+ }
117
+ }
118
+ }
119
+
120
+ @mixin backdrop-transition($duration: $duration-fast) {
121
+ &::backdrop {
122
+ opacity: 0;
123
+ transition:
124
+ opacity $duration $ease-out,
125
+ overlay $duration allow-discrete,
126
+ display $duration allow-discrete;
127
+ }
128
+
129
+ &[open]::backdrop {
130
+ opacity: 1;
131
+ }
132
+
133
+ @starting-style {
134
+ &[open]::backdrop {
135
+ opacity: 0;
136
+ }
137
+ }
138
+
139
+ @include reduced-motion {
140
+ &::backdrop {
141
+ transition: none;
142
+ }
143
+ }
144
+ }
145
+
146
+ @mixin mirror-in-rtl {
147
+ @include for-rtl {
148
+ transform: scaleX(-1);
149
+ }
150
+ }
151
+
152
+ @mixin safe-inline($padding: $space-4) {
153
+ padding-left: max(#{$padding}, env(safe-area-inset-left, 0px));
154
+ padding-right: max(#{$padding}, env(safe-area-inset-right, 0px));
155
+ }
156
+
157
+ $sheet-lift: #{'max(env(safe-area-inset-bottom, 0px), var(--hanui-sheet-inset-bottom, 0px))'};
158
+
159
+ @mixin safe-bottom($padding: $space-3) {
160
+ padding-bottom: max(#{$padding}, calc(env(safe-area-inset-bottom, 0px) - #{$sheet-lift}));
161
+ }
162
+
163
+ @mixin container($width: $container-max-width) {
164
+ width: 100%;
165
+ max-width: $width;
166
+ margin-inline: auto;
167
+
168
+ @include safe-inline($desktop-padding);
169
+
170
+ @include for-tablet {
171
+ @include safe-inline($tablet-padding);
172
+ }
173
+
174
+ @include for-mobile {
175
+ @include safe-inline($mobile-padding);
176
+ }
177
+ }
178
+
179
+ @mixin page($width: $container-max-width, $gap: $space-6) {
180
+ @include container($width);
181
+
182
+ display: flex;
183
+ flex-direction: column;
184
+ gap: $gap;
185
+ padding-block: $space-6 $space-9;
186
+
187
+ @include for-tablet {
188
+ gap: $space-5;
189
+ padding-block: $space-5 $space-8;
190
+ }
191
+
192
+ @include for-mobile {
193
+ gap: $space-4;
194
+ padding-block: $space-4 $space-7;
195
+ }
196
+ }
197
+
198
+ @mixin stack($gap: $space-4) {
199
+ display: flex;
200
+ flex-direction: column;
201
+ gap: $gap;
202
+ }
203
+
204
+ @mixin row($gap: $space-3, $align: center) {
205
+ display: flex;
206
+ align-items: $align;
207
+ gap: $gap;
208
+ }
209
+
210
+ @mixin wrap-row($gap: $space-3, $align: center) {
211
+ display: flex;
212
+ flex-wrap: wrap;
213
+ align-items: $align;
214
+ gap: $gap;
215
+ }
216
+
217
+ @mixin auto-grid($min: 240px, $gap: $space-4) {
218
+ display: grid;
219
+ grid-template-columns: repeat(auto-fill, minmax($min, 1fr));
220
+ gap: $gap;
221
+ }
222
+
223
+ @mixin sticky-below-header($gap: $space-4) {
224
+ position: sticky;
225
+
226
+ @if $gap == 0 or $gap == 0px {
227
+ top: $header-offset;
228
+ } @else {
229
+ top: calc(#{$header-offset} + #{$gap});
230
+ }
231
+ }
232
+
233
+ // ⚠ Kart ve panel DURURKEN gölge taşımaz: derinliği renk bloğu (krem sayfa / açık kart) ve
234
+ // kenarlık kurar. Gölge yalnızca geçici katmanda, kipsel yüzeyde ve tıklanabilir kartın hover'ında.
235
+ @mixin card($interactive: false, $radius: $radius-lg) {
236
+ background-color: $surface;
237
+ border: 1px solid $border;
238
+ border-radius: $radius;
239
+
240
+ @include for-mobile {
241
+ border-radius: $radius-md;
242
+ }
243
+
244
+ @if $interactive {
245
+ transition:
246
+ border-color $duration-fast $ease-out,
247
+ box-shadow $duration-fast $ease-out,
248
+ transform $duration-fast $ease-out;
249
+
250
+ &:hover {
251
+ border-color: $border-strong;
252
+ box-shadow: $shadow-md;
253
+ transform: translateY(-2px);
254
+ }
255
+
256
+ &:active {
257
+ transform: translateY(0);
258
+ box-shadow: $shadow-xs;
259
+ }
260
+
261
+ @include reduced-motion {
262
+ transition: none;
263
+
264
+ &:hover,
265
+ &:active {
266
+ transform: none;
267
+ }
268
+ }
269
+ }
270
+ }
271
+
272
+ @mixin bottom-sheet($max-height: 88dvh, $duration: $duration-normal) {
273
+ display: flex;
274
+ flex-direction: column;
275
+ position: fixed;
276
+ inset: auto 0 #{$sheet-lift} 0;
277
+ width: 100%;
278
+ max-width: none;
279
+ max-height: max(
280
+ min(50dvh, 320px),
281
+ min(#{$max-height}, calc(#{$sheet-height} - #{$space-5} - env(safe-area-inset-top, 0px)))
282
+ );
283
+ margin: 0;
284
+ padding: 0;
285
+ border: none;
286
+ border-radius: $radius-xl $radius-xl 0 0;
287
+ background-color: $surface;
288
+ color: $text;
289
+ box-shadow: $shadow-xl;
290
+ overflow: hidden;
291
+ animation: $anim-slide-up $duration $ease-out;
292
+
293
+ &::backdrop {
294
+ background-color: $scrim;
295
+ animation: $anim-fade-in $duration $ease-out;
296
+ }
297
+
298
+ @include reduced-motion {
299
+ animation: none;
300
+
301
+ &::backdrop {
302
+ animation: none;
303
+ }
304
+ }
305
+ }
306
+
307
+ @mixin panel($radius: $radius-lg) {
308
+ background-color: $surface;
309
+ border: 1px solid $border;
310
+ border-radius: $radius;
311
+ overflow: hidden;
312
+
313
+ @include for-mobile {
314
+ border-radius: $radius-md;
315
+ }
316
+ }
317
+
318
+ @mixin panel-header {
319
+ @include wrap-row($space-3);
320
+
321
+ justify-content: space-between;
322
+ padding: $space-4 $space-5;
323
+ border-bottom: 1px solid $border;
324
+ background-color: $surface;
325
+
326
+ @include for-mobile {
327
+ padding: $space-3 $space-4;
328
+ }
329
+ }
330
+
331
+ @mixin panel-body($gap: $space-4) {
332
+ @include stack($gap);
333
+
334
+ padding: $space-5;
335
+
336
+ @include for-mobile {
337
+ padding: $space-4;
338
+ }
339
+ }
340
+
341
+ @mixin tint($tone: neutral) {
342
+ @if $tone == success {
343
+ background-color: $ok-bg;
344
+ border: 1px solid $ok-line;
345
+ color: $ok-fg;
346
+ } @else if $tone == warning {
347
+ background-color: $warn-bg;
348
+ border: 1px solid $warn-line;
349
+ color: $warn-fg;
350
+ } @else if $tone == danger {
351
+ background-color: $bad-bg;
352
+ border: 1px solid $bad-line;
353
+ color: $bad-fg;
354
+ } @else if $tone == oem {
355
+ background-color: $oem-bg;
356
+ border: 1px solid $oem-line;
357
+ color: $oem-fg;
358
+ } @else if $tone == alt {
359
+ background-color: $alt-bg;
360
+ border: 1px solid $alt-line;
361
+ color: $alt-fg;
362
+ } @else if $tone == info {
363
+ // Bilgi NÖTR: anlamı ikon taşır (1.4.1). 4.x'te yeşil rol tintiydi ve Alert'in varsayılan tonu
364
+ // olduğu için yeşili her uyarıya taşıyordu.
365
+ background-color: $selected-tint;
366
+ border: 1px solid $border-strong;
367
+ color: $text;
368
+ } @else {
369
+ background-color: $off-bg;
370
+ border: 1px solid $off-line;
371
+ color: $off-fg;
372
+ }
373
+ }
374
+
375
+ @mixin heading($step: xl, $weight: $weight-semibold) {
376
+ $index: list.index($font-steps, $step);
377
+
378
+ @if $index == null {
379
+ @error 'heading(): bilinmeyen kademe `#{$step}`. Gecerli olanlar: #{$font-steps}.';
380
+ }
381
+
382
+ $lg-index: list.index($font-steps, lg);
383
+ $xxl-index: list.index($font-steps, 2xl);
384
+
385
+ font-size: var(--hanui-font-size-#{$step});
386
+ font-weight: $weight;
387
+ line-height: $leading-tight;
388
+ color: $text;
389
+
390
+ @if $index >= $lg-index {
391
+ font-family: $font-heading;
392
+ } @else {
393
+ font-family: $font-ui;
394
+ line-height: $leading-snug;
395
+ }
396
+
397
+ @if $index >= $xxl-index {
398
+ letter-spacing: $tracking-tight;
399
+ } @else if $index >= $lg-index {
400
+ letter-spacing: $tracking-snug;
401
+ } @else {
402
+ letter-spacing: normal;
403
+ }
404
+ }
405
+
406
+ @mixin page-title {
407
+ font-family: $font-heading;
408
+ font-size: clamp(#{$font-size-2xl}, 2.2vw + 1rem, #{$font-size-3xl});
409
+ font-weight: $weight-bold;
410
+ line-height: $leading-tight;
411
+ letter-spacing: $tracking-tight;
412
+ color: $text;
413
+ text-wrap: balance;
414
+ }
415
+
416
+ @mixin overline {
417
+ font-family: $font-ui;
418
+ font-size: $font-size-2xs;
419
+ font-weight: $weight-semibold;
420
+ letter-spacing: $tracking-wide;
421
+ text-transform: uppercase;
422
+ color: $text-2;
423
+ }
424
+
425
+ @mixin label {
426
+ font-family: $font-ui;
427
+ font-size: $font-size-sm;
428
+ font-weight: $weight-medium;
429
+ line-height: $leading-snug;
430
+ color: $text;
431
+ }
432
+
433
+ @mixin muted($size: $font-size-sm) {
434
+ font-size: $size;
435
+ line-height: $leading-normal;
436
+ color: $text-2;
437
+ }
438
+
439
+ @mixin technical-text($size: $font-size-sm) {
440
+ font-family: $font-mono;
441
+ font-size: $size;
442
+ letter-spacing: 0.02em;
443
+ font-variant-numeric: tabular-nums;
444
+ }
445
+
446
+ @mixin money($size: $font-size-lg) {
447
+ font-family: $font-heading;
448
+ font-size: $size;
449
+ font-weight: $weight-bold;
450
+ font-variant-numeric: tabular-nums;
451
+ letter-spacing: $tracking-tight;
452
+ white-space: nowrap;
453
+ color: $text;
454
+ }
455
+
456
+ @mixin truncate {
457
+ overflow: hidden;
458
+ text-overflow: ellipsis;
459
+ white-space: nowrap;
460
+ min-width: 0;
461
+ }
462
+
463
+ @mixin focus-ring-shape($color: $ring-color, $offset: 2px) {
464
+ outline: 2px solid $color;
465
+ outline-offset: $offset;
466
+ }
467
+
468
+ @mixin focus-ring($color: $ring-color, $offset: 2px) {
469
+ &:focus-visible {
470
+ @include focus-ring-shape($color, $offset);
471
+ }
472
+ }
473
+
474
+ @mixin tap-target($size: $tap-target-size) {
475
+ position: relative;
476
+
477
+ &::after {
478
+ content: '';
479
+ position: absolute;
480
+ top: 50%;
481
+ left: 50%;
482
+ transform: translate(-50%, -50%);
483
+ width: max(100%, #{$size});
484
+ height: max(100%, #{$size});
485
+ }
486
+ }
487
+
488
+ // PASIF YUZEY: pasiflik dolgunun geri cekilmesiyle bildirilir, metnin silinmesiyle degil.
489
+ // `opacity` YASAK: metni de soluklastirip kontrast esigini sessizce dusuruyor; `text-3` /
490
+ // `surface-2` cifti ise `check-contrast`te olculuyor.
491
+ //
492
+ // Zorlanmis renk kipinde token'lar sistem rengine eziliyor ve `text-3` CanvasText olur, yani
493
+ // opacity'nin o kipte de verdigi pasif ipucu kaybolur. Sistem rengi EBEVEYNDEN MIRAS KALMAZ:
494
+ // kendi rengini yazan her cocuk ayri ayri GrayText ister (olculdu: pasif `fieldset` GrayText,
495
+ // icindeki `legend` CanvasText).
496
+ @mixin passive-text {
497
+ color: $text-3;
498
+
499
+ @media (forced-colors: active) {
500
+ color: GrayText;
501
+
502
+ @content;
503
+ }
504
+ }
505
+
506
+ @mixin passive-surface {
507
+ background-color: $surface-2;
508
+ border-color: $border;
509
+ cursor: not-allowed;
510
+
511
+ @include passive-text {
512
+ border-color: GrayText;
513
+ }
514
+ }
515
+
516
+ @mixin input-base {
517
+ width: 100%;
518
+ font-family: $font-ui;
519
+ font-size: $font-size-control;
520
+ line-height: $leading-snug;
521
+ color: $text;
522
+ background-color: $surface;
523
+ border: 1px solid $border-strong;
524
+ border-radius: $radius-md;
525
+ padding: $space-3 $space-4;
526
+ min-height: $tap-target-size;
527
+ transition:
528
+ border-color $duration-fast $ease-out,
529
+ box-shadow $duration-fast $ease-out;
530
+
531
+ &::placeholder {
532
+ color: $text-3;
533
+ }
534
+
535
+ &:hover:not(:disabled):not([aria-invalid='true']) {
536
+ border-color: $text-3;
537
+ }
538
+
539
+ &:focus {
540
+ outline: none;
541
+ border-color: $ring-color;
542
+ box-shadow: $ring;
543
+ }
544
+
545
+ &:disabled {
546
+ @include passive-surface;
547
+ }
548
+
549
+ &[aria-invalid='true'] {
550
+ border-color: $danger-solid;
551
+
552
+ &:focus {
553
+ box-shadow: $ring-danger;
554
+ }
555
+ }
556
+
557
+ @include reduced-motion {
558
+ transition: none;
559
+ }
560
+ }
561
+
562
+ @mixin filter-surface {
563
+ display: flex;
564
+ flex-wrap: wrap;
565
+ align-items: flex-end;
566
+ gap: $space-3;
567
+ background-color: $surface;
568
+ border: 1px solid $border;
569
+ border-radius: $radius-md;
570
+ padding: $space-3;
571
+ }
572
+
573
+ @mixin data-table {
574
+ width: 100%;
575
+ border-collapse: collapse;
576
+ font-family: $font-ui;
577
+ font-size: $font-size-sm;
578
+
579
+ th,
580
+ td {
581
+ padding: $space-3;
582
+ text-align: start;
583
+ border-bottom: 1px solid $border;
584
+ vertical-align: middle;
585
+ }
586
+
587
+ thead th {
588
+ background-color: $surface-2;
589
+ font-weight: $weight-semibold;
590
+ color: $text-2;
591
+ white-space: nowrap;
592
+ }
593
+
594
+ tbody tr:hover {
595
+ background-color: $surface-inset;
596
+ }
597
+ }
598
+
599
+ @mixin visually-hidden {
600
+ position: absolute;
601
+ width: 1px;
602
+ height: 1px;
603
+ padding: 0;
604
+ margin: -1px;
605
+ overflow: hidden;
606
+ clip-path: inset(50%);
607
+ white-space: nowrap;
608
+ border: 0;
609
+ }
610
+
611
+ @mixin hide-scrollbar {
612
+ scrollbar-width: none;
613
+ -ms-overflow-style: none;
614
+
615
+ &::-webkit-scrollbar {
616
+ display: none;
617
+ }
618
+ }
619
+
620
+ @mixin custom-scrollbar {
621
+ scrollbar-width: thin;
622
+ scrollbar-color: $border-strong transparent;
623
+
624
+ &::-webkit-scrollbar {
625
+ width: 8px;
626
+ height: 8px;
627
+ }
628
+
629
+ &::-webkit-scrollbar-track {
630
+ background: transparent;
631
+ }
632
+
633
+ &::-webkit-scrollbar-thumb {
634
+ background-color: $border-strong;
635
+ border-radius: $radius-pill;
636
+ border: 2px solid transparent;
637
+ background-clip: content-box;
638
+ }
639
+
640
+ &::-webkit-scrollbar-thumb:hover {
641
+ background-color: $text-3;
642
+ }
643
+ }
644
+
645
+ @mixin scroll-row($gap: $space-4) {
646
+ display: flex;
647
+ gap: $gap;
648
+ overflow-x: auto;
649
+ scroll-snap-type: x proximity;
650
+ -webkit-overflow-scrolling: touch;
651
+ padding-block: $space-1 $space-3;
652
+
653
+ @include hide-scrollbar;
654
+
655
+ > * {
656
+ scroll-snap-align: start;
657
+ flex-shrink: 0;
658
+ }
659
+ }
660
+
661
+ @mixin skeleton {
662
+ background: linear-gradient(
663
+ 90deg,
664
+ var(--hanui-skeleton-a) 0%,
665
+ var(--hanui-skeleton-b) 50%,
666
+ var(--hanui-skeleton-a) 100%
667
+ );
668
+ background-size: 200% 100%;
669
+ animation: $anim-shimmer $duration-shimmer ease-in-out infinite;
670
+ border-radius: $radius-sm;
671
+
672
+ @include reduced-motion {
673
+ animation: none;
674
+ }
675
+ }
@@ -0,0 +1,51 @@
1
+ @forward 'colors.generated';
2
+ @forward 'metrics.generated';
3
+
4
+ $tracking-logo: 0.13em;
5
+ $tracking-tight: -0.022em;
6
+ $tracking-snug: -0.011em;
7
+ $tracking-wide: 0.045em;
8
+
9
+ $weight-regular: 400;
10
+ $weight-medium: 500;
11
+ $weight-semibold: 600;
12
+ $weight-bold: 700;
13
+
14
+ $font-steps: 2xs, xs, sm, base, body, lg, xl, 2xl, 3xl, 4xl;
15
+
16
+ $measure: 68ch;
17
+ $measure-narrow: 56ch;
18
+
19
+ $desktop-padding: 32px;
20
+ $tablet-padding: 24px;
21
+ $mobile-padding: 16px;
22
+
23
+ $container-max-width: 1360px;
24
+ $container-narrow: 880px;
25
+ $container-split: 1000px;
26
+ $container-prose: 720px;
27
+
28
+ $sidebar-width: 272px;
29
+
30
+ $tap-target-size: 44px;
31
+
32
+ $breakpoint-mobile: 640px;
33
+ $breakpoint-tablet-portrait: 768px;
34
+ $breakpoint-tablet: 1024px;
35
+ $breakpoint-desktop: 1360px;
36
+
37
+ $z-base: 1;
38
+ $z-raised: 10;
39
+ $z-dropdown: 200;
40
+
41
+ $z-tooltip: 450;
42
+ $z-toast: 500;
43
+
44
+ $anim-shimmer: var(--hanui-anim-shimmer);
45
+ $anim-spin: var(--hanui-anim-spin);
46
+ $anim-fade-in-up: var(--hanui-anim-fade-in-up);
47
+ $anim-fade-in-down: var(--hanui-anim-fade-in-down);
48
+ $anim-fade-in: var(--hanui-anim-fade-in);
49
+ $anim-slide-up: var(--hanui-anim-slide-up);
50
+ $anim-pulse: var(--hanui-anim-pulse);
51
+ $anim-progress-slide: var(--hanui-anim-progress-slide);