tyrell-components 1.0.0-TC23 → 1.0.0-TC24
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/css/tyrell-brand.css +176 -78
- package/css/tyrell-simple.css +257 -0
- package/css/tyrell.css +30 -16
- package/dist/tyrell-brand.css +176 -78
- package/dist/tyrell.css +30 -16
- package/dist/tyrell.js +1 -1
- package/lib/styles/button.d.ts +5 -2
- package/lib/styles/button.d.ts.map +1 -1
- package/lib/styles/button.js +35 -71
- package/lib/styles/button.js.map +1 -1
- package/lib/styles/tag.d.ts +1 -1
- package/lib/styles/tag.d.ts.map +1 -1
- package/lib/styles/tag.js +5 -5
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
package/css/tyrell-brand.css
CHANGED
|
@@ -54,15 +54,19 @@
|
|
|
54
54
|
* FILE LAYOUT
|
|
55
55
|
* =====================================================================
|
|
56
56
|
*
|
|
57
|
-
* SECTION 1 — KNOBS
|
|
58
|
-
* The variables you might want to override.
|
|
59
|
-
* rebrand (Tier 1) to surgical per-flavor tweak (Tier 5)
|
|
57
|
+
* SECTION 1 — KNOBS
|
|
58
|
+
* The variables you might want to override. Six tiers from drop-in
|
|
59
|
+
* rebrand (Tier 1) to surgical per-flavor tweak (Tier 5) plus solid
|
|
60
|
+
* buttons (Tier 6).
|
|
60
61
|
*
|
|
61
62
|
* SECTION 2 — IMPLEMENTATION
|
|
62
63
|
* The oklch() expressions that wire the knobs through to the actual
|
|
63
64
|
* color tokens. Rarely needs editing — Section 1 is the contract.
|
|
64
65
|
*
|
|
65
|
-
* Browser support:
|
|
66
|
+
* Browser support: oklch() is in every evergreen browser since mid-2023.
|
|
67
|
+
* Tier 6 (solid) additionally uses OKLCH relative color — oklch(from …) —
|
|
68
|
+
* which lands later: Chrome 119, Safari 16.4, Firefox 128 (mid-2024).
|
|
69
|
+
* Solid fills have no fallback below those versions.
|
|
66
70
|
*
|
|
67
71
|
* ===================================================================== */
|
|
68
72
|
|
|
@@ -81,6 +85,8 @@
|
|
|
81
85
|
* Tier 5 — PER-FLAVOR L-FACTOR per-flavor lightness multiplier — push
|
|
82
86
|
* one flavor up or down without touching
|
|
83
87
|
* the others. Default 1.
|
|
88
|
+
* Tier 6 — SOLID FILLS solid-button system: hover/active/tone
|
|
89
|
+
* L offsets + per-theme dim/desaturate.
|
|
84
90
|
* ===================================================================== */
|
|
85
91
|
|
|
86
92
|
:root {
|
|
@@ -91,7 +97,7 @@
|
|
|
91
97
|
* --------------------------------------------------------------*/
|
|
92
98
|
|
|
93
99
|
--ty-brand-hue: 230;
|
|
94
|
-
--ty-brand-chroma: 0.
|
|
100
|
+
--ty-brand-chroma: 0.2;
|
|
95
101
|
|
|
96
102
|
/* Secondary rotates from brand by an exposed offset. Default +60°
|
|
97
103
|
* (sibling accent). Try 30° for a close sibling, 120° for triadic,
|
|
@@ -180,6 +186,33 @@
|
|
|
180
186
|
--ty-warning-l-factor: 1.15;
|
|
181
187
|
--ty-danger-l-factor: 1;
|
|
182
188
|
--ty-neutral-l-factor: 1;
|
|
189
|
+
|
|
190
|
+
/* ----------------------------------------------------------------
|
|
191
|
+
* Tier 6 — SOLID FILLS
|
|
192
|
+
* Solid buttons are their OWN system, not the emphasis ramp. Each
|
|
193
|
+
* flavor's fill defaults to --ty-color-{flavor}; the knobs below
|
|
194
|
+
* derive its hover / active / tone+ / tone- and per-theme adjust.
|
|
195
|
+
* Math lives in SECTION 2 (search "Tier 6 — SOLID"); these are the
|
|
196
|
+
* dials.
|
|
197
|
+
*
|
|
198
|
+
* Axis A — interaction & tone, OKLCH L offsets on the fill.
|
|
199
|
+
* Axis B — per-theme adjust applied to the base fill (dim/desaturate).
|
|
200
|
+
*
|
|
201
|
+
* NOTE: like Tier 5, the emphasis curve flips for dark, so these L
|
|
202
|
+
* offsets are sign-flipped in `html.dark` below (darken in light =
|
|
203
|
+
* lighten in dark). Keep the two blocks in sync.
|
|
204
|
+
* --------------------------------------------------------------*/
|
|
205
|
+
|
|
206
|
+
/* Axis A — interaction (light: darken on press, so offsets are negative) */
|
|
207
|
+
--ty-solid-hover-l: -0.04; /* :hover */
|
|
208
|
+
--ty-solid-active-l: -0.08; /* :active */
|
|
209
|
+
--ty-solid-strong-l: -0.06; /* tone+ */
|
|
210
|
+
--ty-solid-soft-l: 0.1; /* tone- */
|
|
211
|
+
|
|
212
|
+
/* Axis B — per-theme adjust (light reads fine → identity) */
|
|
213
|
+
--ty-solid-l: 0; /* lightness offset — negative dims */
|
|
214
|
+
--ty-solid-c: 1; /* chroma multiplier — <1 desaturates */
|
|
215
|
+
--ty-solid-h: 0; /* hue offset (deg) */
|
|
183
216
|
}
|
|
184
217
|
|
|
185
218
|
/* Dark mode overrides for the L-curve and saturation curve. Tier 1 + 2
|
|
@@ -188,8 +221,8 @@ html.dark,
|
|
|
188
221
|
html[data-theme="dark"] {
|
|
189
222
|
/* Tier 3 dark — inverted curve. Higher L = lighter text = more
|
|
190
223
|
* emphasis on a dark background. */
|
|
191
|
-
--ty-l-strong: 0.
|
|
192
|
-
--ty-l-bold: 0.
|
|
224
|
+
--ty-l-strong: 0.72;
|
|
225
|
+
--ty-l-bold: 0.66;
|
|
193
226
|
--ty-l-base: 0.62;
|
|
194
227
|
--ty-l-soft: 0.46;
|
|
195
228
|
--ty-l-faint: 0.3;
|
|
@@ -209,6 +242,18 @@ html[data-theme="dark"] {
|
|
|
209
242
|
--ty-c-bg-base-mult: 0.38;
|
|
210
243
|
--ty-c-bg-bold-mult: 0.54;
|
|
211
244
|
--ty-c-bg-soft-mult: 0.23;
|
|
245
|
+
|
|
246
|
+
/* Tier 6 dark — interaction offsets flip sign (press LIGHTENS on dark),
|
|
247
|
+
* and the per-theme adjust dims + desaturates the fills against the
|
|
248
|
+
* dark canvas. (Computed solid tokens live in SECTION 2 DARK.) */
|
|
249
|
+
--ty-solid-hover-l: 0.04; /* :hover */
|
|
250
|
+
--ty-solid-active-l: 0.08; /* :active */
|
|
251
|
+
--ty-solid-strong-l: 0.06; /* tone+ */
|
|
252
|
+
--ty-solid-soft-l: -0.1; /* tone- */
|
|
253
|
+
|
|
254
|
+
--ty-solid-l: -0.25; /* dim against dark canvas */
|
|
255
|
+
--ty-solid-c: 0.65; /* desaturate against dark canvas */
|
|
256
|
+
--ty-solid-h: 0; /* hue offset */
|
|
212
257
|
}
|
|
213
258
|
|
|
214
259
|
/* =====================================================================
|
|
@@ -529,48 +574,137 @@ html[data-theme="dark"] {
|
|
|
529
574
|
var(--ty-color-primary) 5%,
|
|
530
575
|
transparent
|
|
531
576
|
);
|
|
577
|
+
}
|
|
532
578
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
579
|
+
/* ----------------------------------------------------------------
|
|
580
|
+
* Tier 6 — SOLID (implementation)
|
|
581
|
+
* Solid is its OWN system, NOT the text/emphasis ramp. The dials
|
|
582
|
+
* (--ty-solid-hover-l / -active-l / -strong-l / -soft-l and
|
|
583
|
+
* --ty-solid-l / -c / -h) live in SECTION 1, Tier 6. Below is the
|
|
584
|
+
* derivation only: base fill bakes in the per-theme adjust (Axis B);
|
|
585
|
+
* hover/active/strong/soft offset the base by Axis A. Override any
|
|
586
|
+
* single --ty-solid-{flavor}-{state} to recolor just that segment.
|
|
587
|
+
*
|
|
588
|
+
* Declared at `html:root` (specificity 0,1,1) — NOT plain `:root` (0,1,0) —
|
|
589
|
+
* on purpose: it must out-rank tyrell.css's hardcoded dark solids at
|
|
590
|
+
* `html.dark` (0,1,1). It wins light by specificity over base's `html{}`,
|
|
591
|
+
* and wins dark by source order over base's `html.dark` (brand loads after).
|
|
592
|
+
* That's what lets dark solids re-tint with --ty-brand-hue. Declared ONCE —
|
|
593
|
+
* the oklch(from var(--ty-color-*)) formulas resolve per-mode automatically,
|
|
594
|
+
* so no dark duplicate is needed.
|
|
595
|
+
* --------------------------------------------------------------*/
|
|
596
|
+
html:root {
|
|
597
|
+
/* base fill per flavor (= flavor color, theme-adjusted by Axis B) */
|
|
598
|
+
--ty-solid-primary: oklch(
|
|
599
|
+
from var(--ty-color-primary) calc(l + var(--ty-solid-l))
|
|
600
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
601
|
+
);
|
|
602
|
+
--ty-solid-secondary: oklch(
|
|
603
|
+
from var(--ty-color-secondary) calc(l + var(--ty-solid-l))
|
|
604
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
605
|
+
);
|
|
606
|
+
--ty-solid-success: oklch(
|
|
607
|
+
from var(--ty-color-success) calc(l + var(--ty-solid-l))
|
|
608
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
609
|
+
);
|
|
610
|
+
--ty-solid-danger: oklch(
|
|
611
|
+
from var(--ty-color-danger) calc(l + var(--ty-solid-l))
|
|
612
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
613
|
+
);
|
|
614
|
+
--ty-solid-warning: oklch(
|
|
615
|
+
from var(--ty-color-warning) calc(l + var(--ty-solid-l))
|
|
616
|
+
calc(c * var(--ty-solid-c)) calc(h + var(--ty-solid-h))
|
|
617
|
+
);
|
|
618
|
+
/* neutral is a deliberate dark grey fill, not the neutral text color */
|
|
619
|
+
--ty-solid-neutral: oklch(
|
|
620
|
+
0.4 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
|
|
621
|
+
var(--ty-neutral-hue)
|
|
622
|
+
);
|
|
540
623
|
|
|
541
|
-
--ty-solid-
|
|
542
|
-
--ty-solid-secondary-strong: var(--ty-color-secondary-bold);
|
|
543
|
-
--ty-solid-secondary-soft: var(--ty-color-secondary-soft);
|
|
624
|
+
--ty-solid-primary-fg: white;
|
|
544
625
|
--ty-solid-secondary-fg: white;
|
|
545
|
-
|
|
546
|
-
--ty-solid-success: var(--ty-color-success);
|
|
547
|
-
--ty-solid-success-strong: var(--ty-color-success-bold);
|
|
548
|
-
--ty-solid-success-soft: var(--ty-color-success-soft);
|
|
549
626
|
--ty-solid-success-fg: white;
|
|
550
|
-
|
|
551
|
-
--ty-solid-danger: var(--ty-color-danger);
|
|
552
|
-
--ty-solid-danger-strong: var(--ty-color-danger-bold);
|
|
553
|
-
--ty-solid-danger-soft: var(--ty-color-danger-soft);
|
|
554
627
|
--ty-solid-danger-fg: white;
|
|
555
|
-
|
|
556
|
-
--ty-solid-warning: var(--ty-color-warning);
|
|
557
|
-
--ty-solid-warning-strong: var(--ty-color-warning-bold);
|
|
558
|
-
--ty-solid-warning-soft: var(--ty-color-warning-soft);
|
|
559
628
|
--ty-solid-warning-fg: white;
|
|
629
|
+
--ty-solid-neutral-fg: white;
|
|
560
630
|
|
|
561
|
-
/*
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
0.6 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
|
|
565
|
-
var(--ty-neutral-hue)
|
|
631
|
+
/* derived states — axis 2 offsets on each base fill */
|
|
632
|
+
--ty-solid-primary-hover: oklch(
|
|
633
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-hover-l)) c h
|
|
566
634
|
);
|
|
567
|
-
--ty-solid-
|
|
568
|
-
|
|
569
|
-
|
|
635
|
+
--ty-solid-primary-active: oklch(
|
|
636
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-active-l)) c h
|
|
637
|
+
);
|
|
638
|
+
--ty-solid-primary-strong: oklch(
|
|
639
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-strong-l)) c h
|
|
640
|
+
);
|
|
641
|
+
--ty-solid-primary-soft: oklch(
|
|
642
|
+
from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
--ty-solid-secondary-hover: oklch(
|
|
646
|
+
from var(--ty-solid-secondary) calc(l + var(--ty-solid-hover-l)) c h
|
|
647
|
+
);
|
|
648
|
+
--ty-solid-secondary-active: oklch(
|
|
649
|
+
from var(--ty-solid-secondary) calc(l + var(--ty-solid-active-l)) c h
|
|
650
|
+
);
|
|
651
|
+
--ty-solid-secondary-strong: oklch(
|
|
652
|
+
from var(--ty-solid-secondary) calc(l + var(--ty-solid-strong-l)) c h
|
|
653
|
+
);
|
|
654
|
+
--ty-solid-secondary-soft: oklch(
|
|
655
|
+
from var(--ty-solid-secondary) calc(l + var(--ty-solid-soft-l)) c h
|
|
656
|
+
);
|
|
657
|
+
|
|
658
|
+
--ty-solid-success-hover: oklch(
|
|
659
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h
|
|
660
|
+
);
|
|
661
|
+
--ty-solid-success-active: oklch(
|
|
662
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-active-l)) c h
|
|
663
|
+
);
|
|
664
|
+
--ty-solid-success-strong: oklch(
|
|
665
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-strong-l)) c h
|
|
666
|
+
);
|
|
667
|
+
--ty-solid-success-soft: oklch(
|
|
668
|
+
from var(--ty-solid-success) calc(l + var(--ty-solid-soft-l)) c h
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
--ty-solid-danger-hover: oklch(
|
|
672
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-hover-l)) c h
|
|
673
|
+
);
|
|
674
|
+
--ty-solid-danger-active: oklch(
|
|
675
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-active-l)) c h
|
|
676
|
+
);
|
|
677
|
+
--ty-solid-danger-strong: oklch(
|
|
678
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-strong-l)) c h
|
|
679
|
+
);
|
|
680
|
+
--ty-solid-danger-soft: oklch(
|
|
681
|
+
from var(--ty-solid-danger) calc(l + var(--ty-solid-soft-l)) c h
|
|
682
|
+
);
|
|
683
|
+
|
|
684
|
+
--ty-solid-warning-hover: oklch(
|
|
685
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-hover-l)) c h
|
|
686
|
+
);
|
|
687
|
+
--ty-solid-warning-active: oklch(
|
|
688
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-active-l)) c h
|
|
689
|
+
);
|
|
690
|
+
--ty-solid-warning-strong: oklch(
|
|
691
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-strong-l)) c h
|
|
692
|
+
);
|
|
693
|
+
--ty-solid-warning-soft: oklch(
|
|
694
|
+
from var(--ty-solid-warning) calc(l + var(--ty-solid-soft-l)) c h
|
|
695
|
+
);
|
|
696
|
+
|
|
697
|
+
--ty-solid-neutral-hover: oklch(
|
|
698
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-hover-l)) c h
|
|
699
|
+
);
|
|
700
|
+
--ty-solid-neutral-active: oklch(
|
|
701
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h
|
|
570
702
|
);
|
|
571
703
|
--ty-solid-neutral-strong: oklch(
|
|
572
|
-
|
|
573
|
-
|
|
704
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-strong-l)) c h
|
|
705
|
+
);
|
|
706
|
+
--ty-solid-neutral-soft: oklch(
|
|
707
|
+
from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h
|
|
574
708
|
);
|
|
575
709
|
}
|
|
576
710
|
|
|
@@ -856,7 +990,7 @@ html[data-theme="dark"] {
|
|
|
856
990
|
--ty-input-bg: var(--ty-surface-input);
|
|
857
991
|
--ty-input-color: var(--ty-color-neutral-strong);
|
|
858
992
|
--ty-input-border: var(--ty-color-neutral-faint);
|
|
859
|
-
--ty-input-border-hover: var(--ty-color-neutral-
|
|
993
|
+
--ty-input-border-hover: var(--ty-color-neutral-soft);
|
|
860
994
|
--ty-input-border-focus: var(--ty-color-primary);
|
|
861
995
|
--ty-input-placeholder: var(--ty-color-neutral-soft);
|
|
862
996
|
--ty-input-disabled-bg: var(--ty-color-neutral-faint);
|
|
@@ -868,46 +1002,10 @@ html[data-theme="dark"] {
|
|
|
868
1002
|
transparent
|
|
869
1003
|
);
|
|
870
1004
|
|
|
871
|
-
/*
|
|
872
|
-
|
|
873
|
-
--ty-solid-primary-strong: var(--ty-color-primary-bold);
|
|
874
|
-
--ty-solid-primary-soft: var(--ty-color-primary-soft);
|
|
875
|
-
--ty-solid-primary-fg: white;
|
|
876
|
-
|
|
877
|
-
--ty-solid-secondary: var(--ty-color-secondary);
|
|
878
|
-
--ty-solid-secondary-strong: var(--ty-color-secondary-bold);
|
|
879
|
-
--ty-solid-secondary-soft: var(--ty-color-secondary-soft);
|
|
880
|
-
--ty-solid-secondary-fg: white;
|
|
881
|
-
|
|
882
|
-
--ty-solid-success: var(--ty-color-success);
|
|
883
|
-
--ty-solid-success-strong: var(--ty-color-success-bold);
|
|
884
|
-
--ty-solid-success-soft: var(--ty-color-success-soft);
|
|
885
|
-
--ty-solid-success-fg: white;
|
|
886
|
-
|
|
887
|
-
--ty-solid-danger: var(--ty-color-danger);
|
|
888
|
-
--ty-solid-danger-strong: var(--ty-color-danger-bold);
|
|
889
|
-
--ty-solid-danger-soft: var(--ty-color-danger-soft);
|
|
890
|
-
--ty-solid-danger-fg: white;
|
|
891
|
-
|
|
892
|
-
--ty-solid-warning: var(--ty-color-warning);
|
|
893
|
-
--ty-solid-warning-strong: var(--ty-color-warning-bold);
|
|
894
|
-
--ty-solid-warning-soft: var(--ty-color-warning-soft);
|
|
895
|
-
--ty-solid-warning-fg: white;
|
|
896
|
-
|
|
897
|
-
/* Solid neutral — in dark mode, "dark grey" lives at the other end
|
|
898
|
-
* of the ramp. Both modes get a shade darker than the page surface
|
|
899
|
-
* for a punchy default action. */
|
|
900
|
-
--ty-solid-neutral-soft: oklch(
|
|
901
|
-
0.2 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
|
|
902
|
-
var(--ty-neutral-hue)
|
|
903
|
-
);
|
|
1005
|
+
/* Tier 6 dark — solid dials live in SECTION 1's html.dark block.
|
|
1006
|
+
* neutral is hand-pinned (it ignores Axis B); dim it per theme here. */
|
|
904
1007
|
--ty-solid-neutral: oklch(
|
|
905
1008
|
0.3 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
|
|
906
1009
|
var(--ty-neutral-hue)
|
|
907
1010
|
);
|
|
908
|
-
--ty-solid-neutral-strong: oklch(
|
|
909
|
-
0.4 calc(var(--ty-neutral-chroma) * var(--ty-c-strong-mult))
|
|
910
|
-
var(--ty-neutral-hue)
|
|
911
|
-
);
|
|
912
|
-
--ty-solid-neutral-fg: white;
|
|
913
1011
|
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/* =====================================================================
|
|
2
|
+
* tyrell-simple.css — the lightweight color-mix theme engine for Tyrell
|
|
3
|
+
* =====================================================================
|
|
4
|
+
*
|
|
5
|
+
* EXPERIMENTAL, opt-in. The SIMPLE counterpart to tyrell-brand.css (the
|
|
6
|
+
* complex OKLCH engine). Same job — fill the color-token contract — with
|
|
7
|
+
* far fewer moving parts. Load it INSTEAD of tyrell-brand.css:
|
|
8
|
+
*
|
|
9
|
+
* <link rel="stylesheet" href=".../tyrell.css"> <!-- structure + default colors -->
|
|
10
|
+
* <link rel="stylesheet" href=".../tyrell-simple.css"> <!-- overrides colors -->
|
|
11
|
+
*
|
|
12
|
+
* THE WHOLE MODEL
|
|
13
|
+
* ---------------
|
|
14
|
+
* Every color is one expression:
|
|
15
|
+
* color-mix(in oklch, <ink>, var(--ty-bg) STOP%)
|
|
16
|
+
* - --ty-bg the page/background pole
|
|
17
|
+
* - --ty-ink-{role} the saturated emphasis pole for each role
|
|
18
|
+
* - STOP how far toward the background (shared, see below)
|
|
19
|
+
*
|
|
20
|
+
* Inputs are ~7 anchors per theme (page bg + 6 inks). Everything else is
|
|
21
|
+
* derived ONCE in :root. Dark mode only re-points those anchors — the
|
|
22
|
+
* whole palette falls out. No second curve, no sign-flips, no duplication.
|
|
23
|
+
*
|
|
24
|
+
* Rebrand: change the 6 inks. Retune contrast: change the STOP percentages.
|
|
25
|
+
*
|
|
26
|
+
* Needs oklch() + color-mix() + relative color (oklch(from …)) for solids:
|
|
27
|
+
* Chrome 119 / Safari 16.4 / Firefox 128 (mid-2024).
|
|
28
|
+
* ===================================================================== */
|
|
29
|
+
|
|
30
|
+
:root {
|
|
31
|
+
/* ---- shared emphasis stops (% toward --ty-bg). One curve, both themes. ---- */
|
|
32
|
+
--ty-s-strong: 0%;
|
|
33
|
+
--ty-s-bold: 16%;
|
|
34
|
+
--ty-s-base: 32%;
|
|
35
|
+
--ty-s-soft: 56%;
|
|
36
|
+
--ty-s-faint: 78%;
|
|
37
|
+
/* background tints: mostly bg, a breath of ink */
|
|
38
|
+
--ty-bgs-bold: 82%;
|
|
39
|
+
--ty-bgs-base: 88%;
|
|
40
|
+
--ty-bgs-soft: 94%;
|
|
41
|
+
|
|
42
|
+
/* ====================== ANCHORS (light) ====================== */
|
|
43
|
+
--ty-bg: oklch(0.99 0.003 250); /* page pole */
|
|
44
|
+
--ty-ink-primary: oklch(0.55 0.15 250);
|
|
45
|
+
--ty-ink-secondary: oklch(0.55 0.16 300);
|
|
46
|
+
--ty-ink-success: oklch(0.55 0.13 150);
|
|
47
|
+
--ty-ink-danger: oklch(0.55 0.17 25);
|
|
48
|
+
--ty-ink-warning: oklch(0.68 0.15 75);
|
|
49
|
+
--ty-ink-neutral: oklch(0.30 0.012 250);
|
|
50
|
+
|
|
51
|
+
/* ====================== DERIVED — everything below references anchors ===== */
|
|
52
|
+
|
|
53
|
+
/* ---- flavor color ramps ---- */
|
|
54
|
+
--ty-color-primary-strong: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-s-strong));
|
|
55
|
+
--ty-color-primary-bold: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-s-bold));
|
|
56
|
+
--ty-color-primary: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-s-base));
|
|
57
|
+
--ty-color-primary-soft: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-s-soft));
|
|
58
|
+
--ty-color-primary-faint: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-s-faint));
|
|
59
|
+
|
|
60
|
+
--ty-color-secondary-strong: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-s-strong));
|
|
61
|
+
--ty-color-secondary-bold: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-s-bold));
|
|
62
|
+
--ty-color-secondary: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-s-base));
|
|
63
|
+
--ty-color-secondary-soft: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-s-soft));
|
|
64
|
+
--ty-color-secondary-faint: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-s-faint));
|
|
65
|
+
|
|
66
|
+
--ty-color-success-strong: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-s-strong));
|
|
67
|
+
--ty-color-success-bold: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-s-bold));
|
|
68
|
+
--ty-color-success: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-s-base));
|
|
69
|
+
--ty-color-success-soft: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-s-soft));
|
|
70
|
+
--ty-color-success-faint: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-s-faint));
|
|
71
|
+
|
|
72
|
+
--ty-color-danger-strong: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-s-strong));
|
|
73
|
+
--ty-color-danger-bold: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-s-bold));
|
|
74
|
+
--ty-color-danger: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-s-base));
|
|
75
|
+
--ty-color-danger-soft: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-s-soft));
|
|
76
|
+
--ty-color-danger-faint: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-s-faint));
|
|
77
|
+
|
|
78
|
+
--ty-color-warning-strong: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-s-strong));
|
|
79
|
+
--ty-color-warning-bold: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-s-bold));
|
|
80
|
+
--ty-color-warning: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-s-base));
|
|
81
|
+
--ty-color-warning-soft: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-s-soft));
|
|
82
|
+
--ty-color-warning-faint: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-s-faint));
|
|
83
|
+
|
|
84
|
+
--ty-color-neutral-strong: var(--ty-ink-neutral);
|
|
85
|
+
--ty-color-neutral-bold: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 8%);
|
|
86
|
+
--ty-color-neutral: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 18%);
|
|
87
|
+
--ty-color-neutral-soft: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 45%);
|
|
88
|
+
--ty-color-neutral-faint: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 70%);
|
|
89
|
+
|
|
90
|
+
/* ---- text hierarchy (neutral ink → bg) ---- */
|
|
91
|
+
--ty-text-strong: var(--ty-ink-neutral);
|
|
92
|
+
--ty-text-bold: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 8%);
|
|
93
|
+
--ty-text: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 16%);
|
|
94
|
+
--ty-text-soft: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 40%);
|
|
95
|
+
--ty-text-faint: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) 60%);
|
|
96
|
+
|
|
97
|
+
/* ---- soft background tints per flavor ---- */
|
|
98
|
+
--ty-bg-primary-bold: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-bgs-bold));
|
|
99
|
+
--ty-bg-primary: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-bgs-base));
|
|
100
|
+
--ty-bg-primary-soft: color-mix(in oklch, var(--ty-ink-primary), var(--ty-bg) var(--ty-bgs-soft));
|
|
101
|
+
|
|
102
|
+
--ty-bg-secondary-bold: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-bgs-bold));
|
|
103
|
+
--ty-bg-secondary: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-bgs-base));
|
|
104
|
+
--ty-bg-secondary-soft: color-mix(in oklch, var(--ty-ink-secondary), var(--ty-bg) var(--ty-bgs-soft));
|
|
105
|
+
|
|
106
|
+
--ty-bg-success-bold: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-bgs-bold));
|
|
107
|
+
--ty-bg-success: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-bgs-base));
|
|
108
|
+
--ty-bg-success-soft: color-mix(in oklch, var(--ty-ink-success), var(--ty-bg) var(--ty-bgs-soft));
|
|
109
|
+
|
|
110
|
+
--ty-bg-danger-bold: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-bgs-bold));
|
|
111
|
+
--ty-bg-danger: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-bgs-base));
|
|
112
|
+
--ty-bg-danger-soft: color-mix(in oklch, var(--ty-ink-danger), var(--ty-bg) var(--ty-bgs-soft));
|
|
113
|
+
|
|
114
|
+
--ty-bg-warning-bold: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-bgs-bold));
|
|
115
|
+
--ty-bg-warning: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-bgs-base));
|
|
116
|
+
--ty-bg-warning-soft: color-mix(in oklch, var(--ty-ink-warning), var(--ty-bg) var(--ty-bgs-soft));
|
|
117
|
+
|
|
118
|
+
--ty-bg-neutral-bold: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) var(--ty-bgs-bold));
|
|
119
|
+
--ty-bg-neutral: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) var(--ty-bgs-base));
|
|
120
|
+
--ty-bg-neutral-soft: color-mix(in oklch, var(--ty-ink-neutral), var(--ty-bg) var(--ty-bgs-soft));
|
|
121
|
+
|
|
122
|
+
/* ---- generic bg / elevation ---- */
|
|
123
|
+
--ty-bg-faint: var(--ty-bg);
|
|
124
|
+
--ty-bg-soft: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 4%);
|
|
125
|
+
--ty-bg-bold: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 8%);
|
|
126
|
+
--ty-bg-strong: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 16%);
|
|
127
|
+
--ty-focus-ring-gap: var(--ty-bg);
|
|
128
|
+
|
|
129
|
+
/* ---- surfaces (elevate toward white in both themes) ---- */
|
|
130
|
+
--ty-surface-canvas: var(--ty-bg);
|
|
131
|
+
--ty-surface-content: color-mix(in oklab, var(--ty-bg), white 25%);
|
|
132
|
+
--ty-surface-elevated: color-mix(in oklab, var(--ty-bg), white 45%);
|
|
133
|
+
--ty-surface-floating: color-mix(in oklab, var(--ty-bg), white 60%);
|
|
134
|
+
--ty-surface-input: color-mix(in oklab, var(--ty-bg), white 30%);
|
|
135
|
+
|
|
136
|
+
/* ---- borders ---- */
|
|
137
|
+
--ty-border-strong: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 40%);
|
|
138
|
+
--ty-border-bold: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 22%);
|
|
139
|
+
--ty-border: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 14%);
|
|
140
|
+
--ty-border-soft: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 8%);
|
|
141
|
+
--ty-border-faint: color-mix(in oklch, var(--ty-bg), var(--ty-ink-neutral) 4%);
|
|
142
|
+
|
|
143
|
+
--ty-border-primary: var(--ty-color-primary-soft);
|
|
144
|
+
--ty-border-secondary: var(--ty-color-secondary-soft);
|
|
145
|
+
--ty-border-success: var(--ty-color-success-soft);
|
|
146
|
+
--ty-border-danger: var(--ty-color-danger-soft);
|
|
147
|
+
--ty-border-warning: var(--ty-color-warning-soft);
|
|
148
|
+
--ty-border-neutral: var(--ty-color-neutral);
|
|
149
|
+
|
|
150
|
+
--ty-elevated-border: var(--ty-border);
|
|
151
|
+
--ty-floating-border: var(--ty-border);
|
|
152
|
+
--ty-content-border: var(--ty-border);
|
|
153
|
+
--ty-canvas-border: transparent;
|
|
154
|
+
|
|
155
|
+
/* ---- scrollbar (neutral ink → transparent; auto-flips) ---- */
|
|
156
|
+
--ty-scrollbar-thumb: color-mix(in srgb, var(--ty-ink-neutral) 35%, transparent);
|
|
157
|
+
--ty-scrollbar-thumb-hover: color-mix(in srgb, var(--ty-ink-neutral) 50%, transparent);
|
|
158
|
+
--ty-scrollbar-thumb-active: color-mix(in srgb, var(--ty-ink-neutral) 60%, transparent);
|
|
159
|
+
--ty-scrollbar-track: transparent;
|
|
160
|
+
--ty-scrollbar-track-hover: color-mix(in srgb, var(--ty-ink-neutral) 8%, transparent);
|
|
161
|
+
|
|
162
|
+
/* ---- modal ---- */
|
|
163
|
+
--ty-modal-bg: var(--ty-surface-floating);
|
|
164
|
+
--ty-modal-color: var(--ty-text);
|
|
165
|
+
--ty-modal-border: var(--ty-border);
|
|
166
|
+
--ty-modal-backdrop: color-mix(in oklab, black 50%, transparent);
|
|
167
|
+
--ty-modal-shadow: var(--ty-shadow-xl);
|
|
168
|
+
|
|
169
|
+
/* ---- inputs ---- */
|
|
170
|
+
--ty-input-bg: var(--ty-surface-input);
|
|
171
|
+
--ty-input-color: var(--ty-text);
|
|
172
|
+
--ty-input-border: var(--ty-border-bold);
|
|
173
|
+
--ty-input-border-hover: var(--ty-border-strong);
|
|
174
|
+
--ty-input-border-focus: var(--ty-color-primary);
|
|
175
|
+
--ty-input-shadow-focus: color-mix(in srgb, var(--ty-color-primary) 12%, transparent);
|
|
176
|
+
--ty-input-placeholder: var(--ty-text-faint);
|
|
177
|
+
--ty-input-disabled-bg: var(--ty-bg-soft);
|
|
178
|
+
--ty-input-disabled-border: var(--ty-border);
|
|
179
|
+
--ty-input-disabled-color: var(--ty-text-faint);
|
|
180
|
+
--ty-label-color: var(--ty-text-soft);
|
|
181
|
+
--ty-input-success-border: var(--ty-color-success);
|
|
182
|
+
--ty-input-danger-border: var(--ty-color-danger);
|
|
183
|
+
--ty-input-warning-border: var(--ty-color-warning);
|
|
184
|
+
|
|
185
|
+
/* ====================== SOLID ====================== */
|
|
186
|
+
/* base fill = flavor ink; states via OKLCH L offsets (same axes as the
|
|
187
|
+
other engines). theme dim/desaturate via the dark block re-points ink. */
|
|
188
|
+
--ty-solid-hover-l: -0.04;
|
|
189
|
+
--ty-solid-active-l: -0.08;
|
|
190
|
+
--ty-solid-strong-l: -0.06;
|
|
191
|
+
--ty-solid-soft-l: 0.1;
|
|
192
|
+
/* solid fill lightness — PINNED, not the text ink (which flips light on dark).
|
|
193
|
+
Keeps fills a saturated mid so white fg stays legible in both themes. */
|
|
194
|
+
--ty-solid-base-l: 0.55;
|
|
195
|
+
|
|
196
|
+
--ty-solid-primary: oklch(from var(--ty-ink-primary) var(--ty-solid-base-l) c h);
|
|
197
|
+
--ty-solid-secondary: oklch(from var(--ty-ink-secondary) var(--ty-solid-base-l) c h);
|
|
198
|
+
--ty-solid-success: oklch(from var(--ty-ink-success) var(--ty-solid-base-l) c h);
|
|
199
|
+
--ty-solid-danger: oklch(from var(--ty-ink-danger) var(--ty-solid-base-l) c h);
|
|
200
|
+
--ty-solid-warning: oklch(from var(--ty-ink-warning) var(--ty-solid-base-l) c h);
|
|
201
|
+
--ty-solid-neutral: oklch(from var(--ty-ink-neutral) 0.4 c h);
|
|
202
|
+
|
|
203
|
+
--ty-solid-primary-fg: white;
|
|
204
|
+
--ty-solid-secondary-fg: white;
|
|
205
|
+
--ty-solid-success-fg: white;
|
|
206
|
+
--ty-solid-danger-fg: white;
|
|
207
|
+
--ty-solid-warning-fg: white;
|
|
208
|
+
--ty-solid-neutral-fg: white;
|
|
209
|
+
|
|
210
|
+
--ty-solid-primary-hover: oklch(from var(--ty-solid-primary) calc(l + var(--ty-solid-hover-l)) c h);
|
|
211
|
+
--ty-solid-primary-active: oklch(from var(--ty-solid-primary) calc(l + var(--ty-solid-active-l)) c h);
|
|
212
|
+
--ty-solid-primary-strong: oklch(from var(--ty-solid-primary) calc(l + var(--ty-solid-strong-l)) c h);
|
|
213
|
+
--ty-solid-primary-soft: oklch(from var(--ty-solid-primary) calc(l + var(--ty-solid-soft-l)) c h);
|
|
214
|
+
|
|
215
|
+
--ty-solid-secondary-hover: oklch(from var(--ty-solid-secondary) calc(l + var(--ty-solid-hover-l)) c h);
|
|
216
|
+
--ty-solid-secondary-active: oklch(from var(--ty-solid-secondary) calc(l + var(--ty-solid-active-l)) c h);
|
|
217
|
+
--ty-solid-secondary-strong: oklch(from var(--ty-solid-secondary) calc(l + var(--ty-solid-strong-l)) c h);
|
|
218
|
+
--ty-solid-secondary-soft: oklch(from var(--ty-solid-secondary) calc(l + var(--ty-solid-soft-l)) c h);
|
|
219
|
+
|
|
220
|
+
--ty-solid-success-hover: oklch(from var(--ty-solid-success) calc(l + var(--ty-solid-hover-l)) c h);
|
|
221
|
+
--ty-solid-success-active: oklch(from var(--ty-solid-success) calc(l + var(--ty-solid-active-l)) c h);
|
|
222
|
+
--ty-solid-success-strong: oklch(from var(--ty-solid-success) calc(l + var(--ty-solid-strong-l)) c h);
|
|
223
|
+
--ty-solid-success-soft: oklch(from var(--ty-solid-success) calc(l + var(--ty-solid-soft-l)) c h);
|
|
224
|
+
|
|
225
|
+
--ty-solid-danger-hover: oklch(from var(--ty-solid-danger) calc(l + var(--ty-solid-hover-l)) c h);
|
|
226
|
+
--ty-solid-danger-active: oklch(from var(--ty-solid-danger) calc(l + var(--ty-solid-active-l)) c h);
|
|
227
|
+
--ty-solid-danger-strong: oklch(from var(--ty-solid-danger) calc(l + var(--ty-solid-strong-l)) c h);
|
|
228
|
+
--ty-solid-danger-soft: oklch(from var(--ty-solid-danger) calc(l + var(--ty-solid-soft-l)) c h);
|
|
229
|
+
|
|
230
|
+
--ty-solid-warning-hover: oklch(from var(--ty-solid-warning) calc(l + var(--ty-solid-hover-l)) c h);
|
|
231
|
+
--ty-solid-warning-active: oklch(from var(--ty-solid-warning) calc(l + var(--ty-solid-active-l)) c h);
|
|
232
|
+
--ty-solid-warning-strong: oklch(from var(--ty-solid-warning) calc(l + var(--ty-solid-strong-l)) c h);
|
|
233
|
+
--ty-solid-warning-soft: oklch(from var(--ty-solid-warning) calc(l + var(--ty-solid-soft-l)) c h);
|
|
234
|
+
|
|
235
|
+
--ty-solid-neutral-hover: oklch(from var(--ty-solid-neutral) calc(l + var(--ty-solid-hover-l)) c h);
|
|
236
|
+
--ty-solid-neutral-active: oklch(from var(--ty-solid-neutral) calc(l + var(--ty-solid-active-l)) c h);
|
|
237
|
+
--ty-solid-neutral-strong: oklch(from var(--ty-solid-neutral) calc(l + var(--ty-solid-strong-l)) c h);
|
|
238
|
+
--ty-solid-neutral-soft: oklch(from var(--ty-solid-neutral) calc(l + var(--ty-solid-soft-l)) c h);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* =====================================================================
|
|
242
|
+
* DARK — re-point the anchors ONLY. The whole palette above re-derives.
|
|
243
|
+
* Inks go lighter (emphasis inverts); page goes dark.
|
|
244
|
+
* ===================================================================== */
|
|
245
|
+
html.dark,
|
|
246
|
+
html[data-theme="dark"] {
|
|
247
|
+
--ty-bg: oklch(0.16 0.012 250);
|
|
248
|
+
--ty-ink-primary: oklch(0.80 0.12 250);
|
|
249
|
+
--ty-ink-secondary: oklch(0.80 0.13 300);
|
|
250
|
+
--ty-ink-success: oklch(0.80 0.11 150);
|
|
251
|
+
--ty-ink-danger: oklch(0.78 0.14 25);
|
|
252
|
+
--ty-ink-warning: oklch(0.84 0.13 75);
|
|
253
|
+
--ty-ink-neutral: oklch(0.88 0.008 250);
|
|
254
|
+
|
|
255
|
+
/* solids: dim the pinned fill slightly against the dark canvas */
|
|
256
|
+
--ty-solid-base-l: 0.50;
|
|
257
|
+
}
|