@motir/design-system 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/theme/AppearancePickers.js +10 -4
- package/dist/components/theme/AppearancePickers.js.map +1 -1
- package/dist/components/theme/StyleVignette.d.ts +23 -10
- package/dist/components/theme/StyleVignette.js.map +1 -1
- package/dist/specimen/TokensSpecimen.js.map +1 -1
- package/package.json +1 -1
- package/theme.css +732 -583
package/theme.css
CHANGED
|
@@ -554,74 +554,88 @@
|
|
|
554
554
|
overrides `--el-*`, never `--color-*`, so reading `--el-*` here is what keeps
|
|
555
555
|
the glass orthogonal to the palette. The gradient is what the frosted panels
|
|
556
556
|
blur — without it, the blur is invisible. */
|
|
557
|
-
[data-style='glassmorphism']
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
557
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
558
|
+
body {
|
|
559
|
+
background-image:
|
|
560
|
+
radial-gradient(
|
|
561
|
+
85% 80% at 6% -12%,
|
|
562
|
+
color-mix(in srgb, var(--el-accent) var(--glass-wash), transparent),
|
|
563
|
+
transparent 62%
|
|
564
|
+
),
|
|
565
|
+
radial-gradient(
|
|
566
|
+
80% 75% at 110% 4%,
|
|
567
|
+
color-mix(in srgb, var(--el-highlight) var(--glass-wash), transparent),
|
|
568
|
+
transparent 60%
|
|
569
|
+
),
|
|
570
|
+
radial-gradient(
|
|
571
|
+
95% 90% at 50% 120%,
|
|
572
|
+
color-mix(in srgb, var(--el-link) var(--glass-wash), transparent),
|
|
573
|
+
transparent 62%
|
|
574
|
+
),
|
|
575
|
+
radial-gradient(
|
|
576
|
+
60% 60% at 85% 95%,
|
|
577
|
+
color-mix(in srgb, var(--el-accent) var(--glass-wash), transparent),
|
|
578
|
+
transparent 60%
|
|
579
|
+
);
|
|
580
|
+
background-attachment: fixed;
|
|
581
|
+
}
|
|
580
582
|
}
|
|
581
583
|
|
|
582
584
|
/* Frosted container surfaces — cards & popovers float as translucent sheets. */
|
|
583
|
-
[data-style='glassmorphism'] [data-
|
|
584
|
-
[data-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
585
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
586
|
+
[data-surface='card'],
|
|
587
|
+
[data-surface='popover'] {
|
|
588
|
+
/* The translucent fill lets the vibrant canvas through; the linear sheen is
|
|
589
|
+
the light raking across the glass (top-left → fading), the inset RIM is the
|
|
590
|
+
lit glass edge, and the soft drop makes the sheet FLOAT. White light is
|
|
591
|
+
palette-agnostic; the colour still comes only from the palette-derived
|
|
592
|
+
fill/border, so the axes stay disjoint. */
|
|
593
|
+
background-color: color-mix(in srgb, var(--el-page-bg) var(--glass-surface-alpha), transparent);
|
|
594
|
+
background-image: linear-gradient(150deg, var(--glass-sheen), transparent 55%);
|
|
595
|
+
border-color: color-mix(in srgb, var(--el-border) var(--glass-border-alpha), transparent);
|
|
596
|
+
box-shadow:
|
|
597
|
+
inset 0 1px 0 0 var(--glass-rim),
|
|
598
|
+
inset 0 0 0 1px rgba(255, 255, 255, 0.06),
|
|
599
|
+
0 8px 32px -8px rgba(15, 15, 15, 0.18);
|
|
600
|
+
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
601
|
+
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
602
|
+
}
|
|
599
603
|
}
|
|
600
604
|
|
|
601
605
|
/* Modal panel — a touch more opaque + a stronger blur (body-text AA + lift). */
|
|
602
|
-
[data-style='glassmorphism'] [data-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
606
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
607
|
+
[data-surface='modal'] {
|
|
608
|
+
background-color: color-mix(in srgb, var(--el-page-bg) var(--glass-modal-alpha), transparent);
|
|
609
|
+
background-image: linear-gradient(150deg, var(--glass-sheen), transparent 55%);
|
|
610
|
+
border-color: color-mix(in srgb, var(--el-border) var(--glass-border-alpha), transparent);
|
|
611
|
+
box-shadow:
|
|
612
|
+
inset 0 1px 0 0 var(--glass-rim),
|
|
613
|
+
0 28px 70px -16px rgba(15, 15, 15, 0.34);
|
|
614
|
+
-webkit-backdrop-filter: blur(var(--glass-blur-strong)) saturate(var(--glass-saturate));
|
|
615
|
+
backdrop-filter: blur(var(--glass-blur-strong)) saturate(var(--glass-saturate));
|
|
616
|
+
}
|
|
611
617
|
}
|
|
612
618
|
|
|
613
619
|
/* The sidebar rail — frosted chrome over the canvas. */
|
|
614
|
-
[data-style='glassmorphism'] [data-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
620
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
621
|
+
[data-surface='sidebar'] {
|
|
622
|
+
background-color: color-mix(
|
|
623
|
+
in srgb,
|
|
624
|
+
var(--el-sidebar-bg) var(--glass-chrome-alpha),
|
|
625
|
+
transparent
|
|
626
|
+
);
|
|
627
|
+
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
628
|
+
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
629
|
+
}
|
|
618
630
|
}
|
|
619
631
|
|
|
620
632
|
/* Form controls — a translucent fill so inputs read as glass too. */
|
|
621
|
-
[data-style='glassmorphism'] [data-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
633
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
634
|
+
[data-surface='input'] {
|
|
635
|
+
background-color: color-mix(in srgb, var(--el-page-bg) var(--glass-input-alpha), transparent);
|
|
636
|
+
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
637
|
+
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
|
638
|
+
}
|
|
625
639
|
}
|
|
626
640
|
|
|
627
641
|
/* The MODAL / command-palette BACKDROP — the most important glass surface, since
|
|
@@ -629,10 +643,12 @@
|
|
|
629
643
|
light, palette-derived veil + a page BLUR, so the whole page behind frosts and
|
|
630
644
|
the (also-frosted) modal panel refracts it — the proper glass-modal look.
|
|
631
645
|
Overrides the primitives' `bg-black/40` utility. Palette-derived (no hue). */
|
|
632
|
-
[data-style='glassmorphism'] [data-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
646
|
+
@scope ([data-style='glassmorphism']) to ([data-style]) {
|
|
647
|
+
[data-surface='overlay'] {
|
|
648
|
+
background-color: color-mix(in srgb, var(--el-page-bg) 24%, transparent);
|
|
649
|
+
-webkit-backdrop-filter: blur(8px) saturate(var(--glass-saturate));
|
|
650
|
+
backdrop-filter: blur(8px) saturate(var(--glass-saturate));
|
|
651
|
+
}
|
|
636
652
|
}
|
|
637
653
|
|
|
638
654
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -711,8 +727,10 @@
|
|
|
711
727
|
descendant rule, not a bare token block, so the disjoint-axis test (which
|
|
712
728
|
inspects token blocks) does not treat it as one — and it sets no colour
|
|
713
729
|
anyway, so the two axes stay disjoint regardless. */
|
|
714
|
-
[data-style='neo-brutalism']
|
|
715
|
-
border
|
|
730
|
+
@scope ([data-style='neo-brutalism']) to ([data-style]) {
|
|
731
|
+
.border {
|
|
732
|
+
border-width: 2px;
|
|
733
|
+
}
|
|
716
734
|
}
|
|
717
735
|
|
|
718
736
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -795,12 +813,14 @@
|
|
|
795
813
|
so it adapts to the active palette and sits BEHIND content (text never
|
|
796
814
|
renders on it), keeping AA intact. Dark-first — on the dark theme this reads
|
|
797
815
|
as a Tron grid over the near-black canvas. */
|
|
798
|
-
[data-style='cybercore-y2k']
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
816
|
+
@scope ([data-style='cybercore-y2k']) to ([data-style]) {
|
|
817
|
+
body {
|
|
818
|
+
background-image:
|
|
819
|
+
linear-gradient(color-mix(in srgb, currentColor 6%, transparent) 1px, transparent 1px),
|
|
820
|
+
linear-gradient(90deg, color-mix(in srgb, currentColor 6%, transparent) 1px, transparent 1px);
|
|
821
|
+
background-size: 32px 32px;
|
|
822
|
+
background-position: center top;
|
|
823
|
+
}
|
|
804
824
|
}
|
|
805
825
|
|
|
806
826
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -897,31 +917,33 @@
|
|
|
897
917
|
`--el-*`, never `--color-*`, which is what keeps the aurora orthogonal to the
|
|
898
918
|
palette. background-size > 100% gives the gradient room to drift; the whole
|
|
899
919
|
field eases back and forth over `--aurora-drift-duration`. */
|
|
900
|
-
[data-style='aurora']
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
920
|
+
@scope ([data-style='aurora']) to ([data-style]) {
|
|
921
|
+
body {
|
|
922
|
+
background-image:
|
|
923
|
+
radial-gradient(
|
|
924
|
+
58% 75% at 12% 0%,
|
|
925
|
+
color-mix(in srgb, var(--el-accent) var(--aurora-wash), transparent),
|
|
926
|
+
transparent 60%
|
|
927
|
+
),
|
|
928
|
+
radial-gradient(
|
|
929
|
+
54% 70% at 92% 8%,
|
|
930
|
+
color-mix(in srgb, var(--el-highlight) var(--aurora-wash), transparent),
|
|
931
|
+
transparent 58%
|
|
932
|
+
),
|
|
933
|
+
radial-gradient(
|
|
934
|
+
68% 82% at 62% 104%,
|
|
935
|
+
color-mix(in srgb, var(--el-link) var(--aurora-wash), transparent),
|
|
936
|
+
transparent 62%
|
|
937
|
+
),
|
|
938
|
+
radial-gradient(
|
|
939
|
+
48% 64% at 34% 58%,
|
|
940
|
+
color-mix(in srgb, var(--el-info) var(--aurora-wash-soft), transparent),
|
|
941
|
+
transparent 55%
|
|
942
|
+
);
|
|
943
|
+
background-size: 180% 180%;
|
|
944
|
+
background-attachment: fixed;
|
|
945
|
+
animation: aurora-drift var(--aurora-drift-duration) ease-in-out infinite alternate;
|
|
946
|
+
}
|
|
925
947
|
}
|
|
926
948
|
|
|
927
949
|
@keyframes aurora-drift {
|
|
@@ -944,8 +966,10 @@
|
|
|
944
966
|
/* Respect a reduced-motion preference — the aurora settles to a still gradient
|
|
945
967
|
(the identity holds; only the drift stops). */
|
|
946
968
|
@media (prefers-reduced-motion: reduce) {
|
|
947
|
-
[data-style='aurora']
|
|
948
|
-
|
|
969
|
+
@scope ([data-style='aurora']) to ([data-style]) {
|
|
970
|
+
body {
|
|
971
|
+
animation: none;
|
|
972
|
+
}
|
|
949
973
|
}
|
|
950
974
|
}
|
|
951
975
|
|
|
@@ -955,43 +979,49 @@
|
|
|
955
979
|
rather than lifted by a hard shadow. The sheen sits on background-image over
|
|
956
980
|
the opaque background-color, so it never pulls the surface far enough from its
|
|
957
981
|
base tone to threaten contrast. */
|
|
958
|
-
[data-style='aurora'] [data-
|
|
959
|
-
[data-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
982
|
+
@scope ([data-style='aurora']) to ([data-style]) {
|
|
983
|
+
[data-surface='card'],
|
|
984
|
+
[data-surface='popover'] {
|
|
985
|
+
background-color: var(--el-surface);
|
|
986
|
+
background-image: linear-gradient(
|
|
987
|
+
180deg,
|
|
988
|
+
color-mix(in srgb, var(--el-highlight) var(--aurora-sheen), transparent),
|
|
989
|
+
transparent 42%
|
|
990
|
+
);
|
|
991
|
+
box-shadow:
|
|
992
|
+
var(--shadow-card),
|
|
993
|
+
0 0 26px -8px color-mix(in srgb, var(--el-accent) var(--aurora-glow), transparent),
|
|
994
|
+
0 0 40px -14px color-mix(in srgb, var(--el-link) var(--aurora-glow), transparent);
|
|
995
|
+
}
|
|
970
996
|
}
|
|
971
997
|
|
|
972
998
|
/* Modal panel — opaque, with a deeper glow so the dialog separates cleanly from
|
|
973
999
|
the drifting canvas behind it (and body text stays on the solid surface). */
|
|
974
|
-
[data-style='aurora'] [data-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1000
|
+
@scope ([data-style='aurora']) to ([data-style]) {
|
|
1001
|
+
[data-surface='modal'] {
|
|
1002
|
+
background-color: var(--el-surface);
|
|
1003
|
+
background-image: linear-gradient(
|
|
1004
|
+
180deg,
|
|
1005
|
+
color-mix(in srgb, var(--el-highlight) var(--aurora-sheen), transparent),
|
|
1006
|
+
transparent 38%
|
|
1007
|
+
);
|
|
1008
|
+
box-shadow:
|
|
1009
|
+
var(--shadow-modal),
|
|
1010
|
+
0 0 60px -16px color-mix(in srgb, var(--el-accent) var(--aurora-glow-strong), transparent);
|
|
1011
|
+
}
|
|
984
1012
|
}
|
|
985
1013
|
|
|
986
1014
|
/* The sidebar rail — opaque chrome carrying the faint aurora sheen so it reads as
|
|
987
1015
|
part of the lit surface family, not a flat slab. */
|
|
988
|
-
[data-style='aurora'] [data-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
1016
|
+
@scope ([data-style='aurora']) to ([data-style]) {
|
|
1017
|
+
[data-surface='sidebar'] {
|
|
1018
|
+
background-color: var(--el-sidebar-bg);
|
|
1019
|
+
background-image: linear-gradient(
|
|
1020
|
+
180deg,
|
|
1021
|
+
color-mix(in srgb, var(--el-accent) var(--aurora-sheen), transparent),
|
|
1022
|
+
transparent 30%
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
995
1025
|
}
|
|
996
1026
|
|
|
997
1027
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -1086,24 +1116,26 @@
|
|
|
1086
1116
|
rule test passes: a palette swap re-tints the atmosphere, a style swap leaves
|
|
1087
1117
|
hues alone. This is what makes the table/list/board pages (no card surfaces of
|
|
1088
1118
|
their own) read as immersive too. */
|
|
1089
|
-
[data-style='3d-immersive']
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1119
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1120
|
+
body {
|
|
1121
|
+
background-image:
|
|
1122
|
+
radial-gradient(
|
|
1123
|
+
130% 85% at 50% -15%,
|
|
1124
|
+
color-mix(in srgb, var(--el-accent) 9%, transparent),
|
|
1125
|
+
transparent 60%
|
|
1126
|
+
),
|
|
1127
|
+
radial-gradient(
|
|
1128
|
+
95% 75% at 108% 112%,
|
|
1129
|
+
color-mix(in srgb, var(--el-link) 8%, transparent),
|
|
1130
|
+
transparent 55%
|
|
1131
|
+
),
|
|
1132
|
+
radial-gradient(
|
|
1133
|
+
150% 130% at 50% 42%,
|
|
1134
|
+
transparent 52%,
|
|
1135
|
+
color-mix(in srgb, var(--el-text) 8%, transparent)
|
|
1136
|
+
);
|
|
1137
|
+
background-attachment: fixed;
|
|
1138
|
+
}
|
|
1107
1139
|
}
|
|
1108
1140
|
|
|
1109
1141
|
/* EVERY PANEL FLOATS — systematic depth across the WHOLE app, not just the
|
|
@@ -1118,11 +1150,15 @@
|
|
|
1118
1150
|
Per-surface exceptions (the board column's clip-safe shadow, modals) override
|
|
1119
1151
|
below by source order. Modals carry their own deeper shadow via the modal
|
|
1120
1152
|
radius (next rule). */
|
|
1121
|
-
[data-style='3d-immersive']
|
|
1122
|
-
|
|
1153
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1154
|
+
.rounded-\(--radius-card\) {
|
|
1155
|
+
box-shadow: var(--shadow-card);
|
|
1156
|
+
}
|
|
1123
1157
|
}
|
|
1124
|
-
[data-style='3d-immersive']
|
|
1125
|
-
|
|
1158
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1159
|
+
.rounded-\(--radius-modal\) {
|
|
1160
|
+
box-shadow: var(--shadow-modal);
|
|
1161
|
+
}
|
|
1126
1162
|
}
|
|
1127
1163
|
|
|
1128
1164
|
/* 3D / Immersive — the POINTER-PARALLAX TILT (the standard "3D card" effect,
|
|
@@ -1147,10 +1183,12 @@
|
|
|
1147
1183
|
never establishes a transform stacking context that could reposition a
|
|
1148
1184
|
non-portaled fixed/absolute descendant. On leave the engine drops the
|
|
1149
1185
|
attribute and the transform eases back to none over 400ms. */
|
|
1150
|
-
[data-style='3d-immersive'] [data-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1186
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1187
|
+
[data-tilt] {
|
|
1188
|
+
transition:
|
|
1189
|
+
transform 400ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
1190
|
+
box-shadow 260ms ease-out;
|
|
1191
|
+
}
|
|
1154
1192
|
}
|
|
1155
1193
|
/* While the pointer is over the tile the engine sets data-tilt-active='1':
|
|
1156
1194
|
tip it toward the cursor (the per-tile --tilt-rx/ry the engine writes),
|
|
@@ -1159,14 +1197,16 @@
|
|
|
1159
1197
|
establish a 3D context (`preserve-3d`) so the card's slots can sit on
|
|
1160
1198
|
separate translateZ planes and PARALLAX (a flat-plane tilt without this is
|
|
1161
1199
|
the "halfway / flat-3D mix" tell). `position: relative` anchors the glare. */
|
|
1162
|
-
[data-style='3d-immersive'] [data-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1200
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1201
|
+
[data-tilt][data-tilt-active='1'] {
|
|
1202
|
+
transform: perspective(var(--tilt-perspective, 900px)) rotateX(var(--tilt-rx, 0deg))
|
|
1203
|
+
rotateY(var(--tilt-ry, 0deg));
|
|
1204
|
+
transform-style: preserve-3d;
|
|
1205
|
+
transition:
|
|
1206
|
+
transform 80ms linear,
|
|
1207
|
+
box-shadow 260ms ease-out;
|
|
1208
|
+
box-shadow: var(--shadow-elevated);
|
|
1209
|
+
}
|
|
1170
1210
|
}
|
|
1171
1211
|
|
|
1172
1212
|
/* DEPTH PLANES — the card's slots lift onto different translateZ planes so
|
|
@@ -1175,13 +1215,17 @@
|
|
|
1175
1215
|
content never renders skewed). Only while actively tilting, so a resting
|
|
1176
1216
|
card is perfectly flat. This is the standard layered-parallax technique
|
|
1177
1217
|
(vanilla-tilt / Atropos): perspective + preserve-3d + per-layer translateZ. */
|
|
1178
|
-
[data-style='3d-immersive']
|
|
1179
|
-
|
|
1180
|
-
|
|
1218
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1219
|
+
[data-tilt][data-tilt-active='1'] [data-tilt-layer='front'] {
|
|
1220
|
+
transform: translateZ(42px);
|
|
1221
|
+
transition: transform 80ms linear;
|
|
1222
|
+
}
|
|
1181
1223
|
}
|
|
1182
|
-
[data-style='3d-immersive']
|
|
1183
|
-
|
|
1184
|
-
|
|
1224
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1225
|
+
[data-tilt][data-tilt-active='1'] [data-tilt-layer='back'] {
|
|
1226
|
+
transform: translateZ(14px);
|
|
1227
|
+
transition: transform 80ms linear;
|
|
1228
|
+
}
|
|
1185
1229
|
}
|
|
1186
1230
|
|
|
1187
1231
|
/* GLARE — a cursor-tracked specular sweep across the face (the light catching
|
|
@@ -1189,33 +1233,39 @@
|
|
|
1189
1233
|
hue → passes the material-rule test; a palette swap re-tints the sheen). It
|
|
1190
1234
|
rides a high translateZ so it reads as light on the front glass, fades in
|
|
1191
1235
|
only while active, and never eats pointer events. */
|
|
1192
|
-
[data-style='3d-immersive'] [data-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1236
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1237
|
+
[data-tilt]::after {
|
|
1238
|
+
content: '';
|
|
1239
|
+
position: absolute;
|
|
1240
|
+
inset: 0;
|
|
1241
|
+
border-radius: inherit;
|
|
1242
|
+
background: radial-gradient(
|
|
1243
|
+
circle at var(--tilt-glare-x, 50%) var(--tilt-glare-y, 50%),
|
|
1244
|
+
color-mix(in srgb, var(--el-page-bg) 65%, transparent),
|
|
1245
|
+
transparent 55%
|
|
1246
|
+
);
|
|
1247
|
+
opacity: 0;
|
|
1248
|
+
transition: opacity 200ms ease-out;
|
|
1249
|
+
pointer-events: none;
|
|
1250
|
+
}
|
|
1205
1251
|
}
|
|
1206
|
-
[data-style='3d-immersive'] [data-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1252
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1253
|
+
[data-tilt][data-tilt-active='1']::after {
|
|
1254
|
+
opacity: 0.45;
|
|
1255
|
+
/* Just above the card FACE but BELOW the popped header/footer planes, so it
|
|
1256
|
+
lights the surface without washing the floating title. */
|
|
1257
|
+
transform: translateZ(2px);
|
|
1258
|
+
}
|
|
1211
1259
|
}
|
|
1212
1260
|
}
|
|
1213
1261
|
|
|
1214
1262
|
/* `position: relative` anchors the glare ::after to each tile. Static (outside
|
|
1215
1263
|
the motion gate) so the anchor is stable; the glare itself only shows while
|
|
1216
1264
|
tilting (above). */
|
|
1217
|
-
[data-style='3d-immersive'] [data-
|
|
1218
|
-
|
|
1265
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1266
|
+
[data-tilt] {
|
|
1267
|
+
position: relative;
|
|
1268
|
+
}
|
|
1219
1269
|
}
|
|
1220
1270
|
|
|
1221
1271
|
/* ── 3D / Immersive — BOARD COLUMNS ─────────────────────────────────────────
|
|
@@ -1226,33 +1276,37 @@
|
|
|
1226
1276
|
clip/occlusion-safe float shadow (small horizontal bleed, modest drop), and
|
|
1227
1277
|
the scroll row widens its gap + adds bottom room so the shadow shows. Result:
|
|
1228
1278
|
each column floats as its own distinct card. */
|
|
1229
|
-
[data-style='3d-immersive'] [data-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1279
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1280
|
+
[data-board-col-panel] {
|
|
1281
|
+
box-shadow:
|
|
1282
|
+
inset 0 1px 0 0 rgba(255, 255, 255, 0.55),
|
|
1283
|
+
0 1px 3px rgba(15, 15, 15, 0.08),
|
|
1284
|
+
0 8px 18px -8px rgba(15, 15, 15, 0.22);
|
|
1285
|
+
/* The column is `h-[calc(100dvh - 10.5rem - var(--shell-bottom-clearance))]` —
|
|
1286
|
+
sized to fill the board area. In the `overflow-x-auto` row that
|
|
1287
|
+
exactly-filling height means the column's rounded BOTTOM corner + its drop
|
|
1288
|
+
shadow sit at the overflow-clip boundary and get sheared flat (the reported
|
|
1289
|
+
"sharp bottom corner"). Trim the height by a further 2.5rem so the rounded
|
|
1290
|
+
corner + shadow clear the clip and the column reads as a fully-rounded
|
|
1291
|
+
floating card. Also clip the column's OWN children to its radius so a flush
|
|
1292
|
+
inner surface can't square a corner — the board cards pop on hover but the
|
|
1293
|
+
DragOverlay clone is portaled, so nothing 3D is lost.
|
|
1294
|
+
|
|
1295
|
+
⚠️ This tracks BoardColumn's height and must keep spending the same
|
|
1296
|
+
`--shell-bottom-clearance` the shell sets (MOTIR-2763), not a flat number:
|
|
1297
|
+
a stylesheet cannot read the `showPlanWithAi` prop, so the custom property
|
|
1298
|
+
is the only way this stays conditional on the orb actually mounting. The
|
|
1299
|
+
13rem below is 10.5rem of chrome + this style's own 2.5rem trim. */
|
|
1300
|
+
height: calc(100dvh - 13rem - var(--shell-bottom-clearance, 1.5rem));
|
|
1301
|
+
overflow: hidden;
|
|
1302
|
+
}
|
|
1251
1303
|
}
|
|
1252
|
-
[data-style='3d-immersive'] [data-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1304
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1305
|
+
[data-board-scroll] {
|
|
1306
|
+
gap: 1.5rem;
|
|
1307
|
+
padding-bottom: 2.25rem;
|
|
1308
|
+
padding-top: 0.25rem;
|
|
1309
|
+
}
|
|
1256
1310
|
}
|
|
1257
1311
|
|
|
1258
1312
|
/* ── 3D / Immersive — CONTROL DEPTH: every control sits on a named plane ────
|
|
@@ -1317,7 +1371,7 @@
|
|
|
1317
1371
|
The `.justify-center` limb is the square icon-button shape: a centred control
|
|
1318
1372
|
on the control radius is a key (the 3-dots trigger, the fullscreen toggle,
|
|
1319
1373
|
every close ×). A row is never centred — it is `w-full` and `text-left`. */
|
|
1320
|
-
[data-style='3d-immersive']
|
|
1374
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1321
1375
|
:where(
|
|
1322
1376
|
.rounded-\(--radius-btn\),
|
|
1323
1377
|
button.rounded-\(--radius-input\),
|
|
@@ -1333,27 +1387,34 @@
|
|
|
1333
1387
|
[data-depth='flat']
|
|
1334
1388
|
)
|
|
1335
1389
|
) {
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1390
|
+
box-shadow:
|
|
1391
|
+
0 3px 0 0 var(--el-border-strong),
|
|
1392
|
+
0 5px 10px -3px rgba(15, 15, 15, 0.18);
|
|
1393
|
+
transition:
|
|
1394
|
+
transform 90ms ease-out,
|
|
1395
|
+
box-shadow 90ms ease-out,
|
|
1396
|
+
background-color var(--transition-duration);
|
|
1397
|
+
}
|
|
1343
1398
|
}
|
|
1344
|
-
[data-style='3d-immersive'] [data-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1399
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1400
|
+
[data-variant='primary'] {
|
|
1401
|
+
box-shadow:
|
|
1402
|
+
0 4px 0 0 var(--el-accent-pressed),
|
|
1403
|
+
0 7px 12px -3px rgba(15, 15, 15, 0.32);
|
|
1404
|
+
}
|
|
1348
1405
|
}
|
|
1349
|
-
[data-style='3d-immersive'] [data-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1406
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1407
|
+
[data-variant='danger'] {
|
|
1408
|
+
box-shadow:
|
|
1409
|
+
0 4px 0 0 color-mix(in srgb, var(--el-danger), black 32%),
|
|
1410
|
+
0 7px 12px -3px rgba(15, 15, 15, 0.32);
|
|
1411
|
+
}
|
|
1353
1412
|
}
|
|
1354
1413
|
/* Ghost — the deliberately-flat quiet button; no thickness. */
|
|
1355
|
-
[data-style='3d-immersive'] [data-
|
|
1356
|
-
|
|
1414
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1415
|
+
[data-variant='ghost'] {
|
|
1416
|
+
box-shadow: none;
|
|
1417
|
+
}
|
|
1357
1418
|
}
|
|
1358
1419
|
|
|
1359
1420
|
/* THE FLAT SET — rows, chips and switches, which §4 keeps on their parent's
|
|
@@ -1361,7 +1422,7 @@
|
|
|
1361
1422
|
(0,1,0) wherever the two overlap (a centred control inside an open menu, a
|
|
1362
1423
|
`data-depth='flat'` icon button). A menu row raised inside an already-floating
|
|
1363
1424
|
popover reads as debris, not depth — the overlay is the thing that floats. */
|
|
1364
|
-
[data-style='3d-immersive']
|
|
1425
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1365
1426
|
:is(
|
|
1366
1427
|
[role='menuitem'],
|
|
1367
1428
|
[role='option'],
|
|
@@ -1370,50 +1431,57 @@
|
|
|
1370
1431
|
[role='switch'],
|
|
1371
1432
|
[data-depth='flat']
|
|
1372
1433
|
),
|
|
1373
|
-
[data-
|
|
1374
|
-
:is(
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
box-shadow: none;
|
|
1434
|
+
:is([data-surface='popover'], [data-menu-surface]) :is(button, a).rounded-\(--radius-control\),
|
|
1435
|
+
:is(button, a).w-full.rounded-\(--radius-control\) {
|
|
1436
|
+
box-shadow: none;
|
|
1437
|
+
}
|
|
1378
1438
|
}
|
|
1379
1439
|
|
|
1380
1440
|
/* THE PRESS — the raised set drops by its thickness and the base edge
|
|
1381
1441
|
compresses, like a real key. Overrides the base `active:scale`. */
|
|
1382
|
-
[data-style='3d-immersive']
|
|
1442
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1383
1443
|
:where(
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1444
|
+
.rounded-\(--radius-btn\),
|
|
1445
|
+
button.rounded-\(--radius-input\),
|
|
1446
|
+
:is(button, a).rounded-\(--radius-control\).justify-center,
|
|
1447
|
+
[data-depth='key']
|
|
1448
|
+
):active:not(:disabled) {
|
|
1449
|
+
transform: translateY(3px);
|
|
1450
|
+
box-shadow:
|
|
1451
|
+
0 1px 0 0 var(--el-border-strong),
|
|
1452
|
+
0 2px 4px rgba(15, 15, 15, 0.14);
|
|
1453
|
+
}
|
|
1393
1454
|
}
|
|
1394
|
-
[data-style='3d-immersive'] [data-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1455
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1456
|
+
[data-variant='primary']:active:not(:disabled) {
|
|
1457
|
+
box-shadow:
|
|
1458
|
+
0 1px 0 0 var(--el-accent-pressed),
|
|
1459
|
+
0 2px 5px rgba(15, 15, 15, 0.22);
|
|
1460
|
+
}
|
|
1398
1461
|
}
|
|
1399
|
-
[data-style='3d-immersive'] [data-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1462
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1463
|
+
[data-variant='danger']:active:not(:disabled) {
|
|
1464
|
+
box-shadow:
|
|
1465
|
+
0 1px 0 0 color-mix(in srgb, var(--el-danger), black 32%),
|
|
1466
|
+
0 2px 5px rgba(15, 15, 15, 0.22);
|
|
1467
|
+
}
|
|
1403
1468
|
}
|
|
1404
|
-
[data-style='3d-immersive'] [data-
|
|
1405
|
-
|
|
1469
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1470
|
+
[data-variant='ghost']:active:not(:disabled) {
|
|
1471
|
+
box-shadow: none;
|
|
1472
|
+
}
|
|
1406
1473
|
}
|
|
1407
1474
|
|
|
1408
1475
|
/* THE QUIET PRESS — a control with no resting thickness still has to answer the
|
|
1409
1476
|
pointer, or the style reads as flat wherever it is not a key: menu rows, list
|
|
1410
1477
|
rows, nav links, inline affordances, the ghost button. One pixel of travel is
|
|
1411
1478
|
the whole treatment; it is what separates "quiet" from "inert". */
|
|
1412
|
-
[data-style='3d-immersive']
|
|
1479
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1413
1480
|
:where(:is(button, a).rounded-\(--radius-control\), [data-variant='ghost']):active:not(
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1481
|
+
:disabled
|
|
1482
|
+
) {
|
|
1483
|
+
transform: translateY(1px);
|
|
1484
|
+
}
|
|
1417
1485
|
}
|
|
1418
1486
|
|
|
1419
1487
|
/* THE RECESSED SET — text fields are pressed INTO the surface, not raised off
|
|
@@ -1424,16 +1492,17 @@
|
|
|
1424
1492
|
not a copy of it. `[data-surface='input']` is the Input primitive's shell;
|
|
1425
1493
|
the bare element selectors catch the hand-rolled fields. Checkbox and radio
|
|
1426
1494
|
are excluded: they are chips, not wells. */
|
|
1427
|
-
[data-style='3d-immersive']
|
|
1495
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1428
1496
|
:where(
|
|
1429
1497
|
[data-surface='input'],
|
|
1430
1498
|
input:not([type='checkbox'], [type='radio'], [type='range'], [type='color']),
|
|
1431
1499
|
textarea,
|
|
1432
1500
|
select
|
|
1433
1501
|
) {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1502
|
+
box-shadow:
|
|
1503
|
+
inset 0 2px 6px -2px rgba(15, 15, 15, 0.26),
|
|
1504
|
+
inset 0 1px 2px 0 rgba(15, 15, 15, 0.05);
|
|
1505
|
+
}
|
|
1437
1506
|
}
|
|
1438
1507
|
|
|
1439
1508
|
/* Hero controls paint their own shadow in an INLINE style, which beats every
|
|
@@ -1452,18 +1521,20 @@
|
|
|
1452
1521
|
override every shape role. A descendant rule is neither, which is where the
|
|
1453
1522
|
immersive background (which reads `--el-*` for the same reason) already
|
|
1454
1523
|
lives. Custom properties inherit, so every control below `body` sees these. */
|
|
1455
|
-
[data-style='3d-immersive']
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1524
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1525
|
+
body {
|
|
1526
|
+
--plan-hero-shadow:
|
|
1527
|
+
0 4px 0 0 var(--el-accent-pressed),
|
|
1528
|
+
inset 0 1px 0 color-mix(in srgb, var(--el-accent-text) 38%, transparent),
|
|
1529
|
+
inset 0 0 0 1px color-mix(in srgb, var(--el-accent-text) 18%, transparent),
|
|
1530
|
+
0 9px 18px -5px color-mix(in srgb, var(--el-accent) 75%, transparent),
|
|
1531
|
+
0 0 22px -3px color-mix(in srgb, var(--el-highlight) 50%, transparent);
|
|
1532
|
+
--plan-orb-shadow:
|
|
1533
|
+
0 5px 0 0 var(--el-accent-pressed),
|
|
1534
|
+
inset 0 1px 0 color-mix(in srgb, var(--el-accent-text) 40%, transparent),
|
|
1535
|
+
0 12px 24px -6px color-mix(in srgb, var(--el-accent) 80%, transparent),
|
|
1536
|
+
0 0 28px -2px color-mix(in srgb, var(--el-highlight) 55%, transparent);
|
|
1537
|
+
}
|
|
1467
1538
|
}
|
|
1468
1539
|
|
|
1469
1540
|
/* ── 3D / Immersive — DROPDOWNS / POPOVERS / MENUS unfold in 3D ──────────────
|
|
@@ -1489,22 +1560,28 @@
|
|
|
1489
1560
|
rule above would otherwise flatten any `shadow-(--shadow-elevated)` surface to
|
|
1490
1561
|
--shadow-card). Global + static so menus, tooltips, drag-overlays all keep the
|
|
1491
1562
|
right depth. */
|
|
1492
|
-
[data-style='3d-immersive']
|
|
1493
|
-
|
|
1563
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1564
|
+
.shadow-\(--shadow-elevated\) {
|
|
1565
|
+
box-shadow: var(--shadow-elevated);
|
|
1566
|
+
}
|
|
1494
1567
|
}
|
|
1495
1568
|
@media (prefers-reduced-motion: no-preference) {
|
|
1496
1569
|
/* The 3D UNFOLD is scoped to actual MENU surfaces (the Popover primitive +
|
|
1497
1570
|
the `data-menu-surface` hook on Combobox / MultiSelect / BoardSwitcher
|
|
1498
1571
|
menus) — NOT every elevated surface, so a drag-overlay or toast doesn't
|
|
1499
1572
|
unexpectedly fold open. */
|
|
1500
|
-
[data-style='3d-immersive'] [data-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1573
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1574
|
+
[data-surface='popover'],
|
|
1575
|
+
[data-menu-surface] {
|
|
1576
|
+
transform-origin: top center;
|
|
1577
|
+
animation: immersive-menu-open 200ms cubic-bezier(0.22, 1, 0.36, 1);
|
|
1578
|
+
}
|
|
1504
1579
|
}
|
|
1505
1580
|
/* A Radix popover that flips ABOVE its trigger folds from the bottom edge. */
|
|
1506
|
-
[data-style='3d-immersive'] [data-
|
|
1507
|
-
|
|
1581
|
+
@scope ([data-style='3d-immersive']) to ([data-style]) {
|
|
1582
|
+
[data-surface='popover'][data-side='top'] {
|
|
1583
|
+
transform-origin: bottom center;
|
|
1584
|
+
}
|
|
1508
1585
|
}
|
|
1509
1586
|
}
|
|
1510
1587
|
|
|
@@ -1591,52 +1668,62 @@
|
|
|
1591
1668
|
dividers `.border-b` / `.border-t` (table rows, section rules) — the latter
|
|
1592
1669
|
scoped INSIDE `[data-surface]` panels to bound the count to real surfaces (and
|
|
1593
1670
|
their rows are virtualised, so only ~viewport-many overlays ever render). */
|
|
1594
|
-
[data-style='hand-drawn-indie']
|
|
1595
|
-
border
|
|
1671
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1672
|
+
.border {
|
|
1673
|
+
border-width: 2px;
|
|
1674
|
+
}
|
|
1596
1675
|
}
|
|
1597
|
-
[data-style='hand-drawn-indie']
|
|
1598
|
-
|
|
1676
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1677
|
+
.border:not(.fixed):not(.absolute):not(.sticky) {
|
|
1678
|
+
position: relative;
|
|
1679
|
+
}
|
|
1599
1680
|
}
|
|
1600
|
-
[data-style='hand-drawn-indie']
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1681
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1682
|
+
.border::after {
|
|
1683
|
+
content: '';
|
|
1684
|
+
position: absolute;
|
|
1685
|
+
inset: -1px;
|
|
1686
|
+
pointer-events: none;
|
|
1687
|
+
border: 2px solid var(--el-border-strong);
|
|
1688
|
+
border-radius: inherit;
|
|
1689
|
+
filter: url(#hd-rough);
|
|
1690
|
+
}
|
|
1608
1691
|
}
|
|
1609
1692
|
|
|
1610
1693
|
/* Internal grid dividers — make the inner rules as rough as the frame. Scoped
|
|
1611
1694
|
inside framed surfaces; `:not(.border)` so a full-box element isn't handled
|
|
1612
1695
|
twice; `:not(:last-child)` mirrors the common `last:border-b-0` strip so the
|
|
1613
1696
|
final row gets no phantom line. */
|
|
1614
|
-
[data-style='hand-drawn-indie']
|
|
1615
|
-
[data-surface]
|
|
1616
|
-
|
|
1617
|
-
|
|
1697
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1698
|
+
[data-surface] :is(.border-b, .border-t):not(.border):not(.fixed):not(.absolute):not(.sticky) {
|
|
1699
|
+
position: relative;
|
|
1700
|
+
}
|
|
1618
1701
|
}
|
|
1619
|
-
[data-style='hand-drawn-indie'] [data-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1702
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1703
|
+
[data-surface] .border-b:not(.border)::after {
|
|
1704
|
+
content: '';
|
|
1705
|
+
position: absolute;
|
|
1706
|
+
left: 0;
|
|
1707
|
+
right: 0;
|
|
1708
|
+
bottom: -1px;
|
|
1709
|
+
height: 0;
|
|
1710
|
+
pointer-events: none;
|
|
1711
|
+
border-bottom: 2px solid var(--el-border-strong);
|
|
1712
|
+
filter: url(#hd-rough);
|
|
1713
|
+
}
|
|
1629
1714
|
}
|
|
1630
|
-
[data-style='hand-drawn-indie'] [data-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1715
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1716
|
+
[data-surface] .border-t:not(.border)::after {
|
|
1717
|
+
content: '';
|
|
1718
|
+
position: absolute;
|
|
1719
|
+
left: 0;
|
|
1720
|
+
right: 0;
|
|
1721
|
+
top: -1px;
|
|
1722
|
+
height: 0;
|
|
1723
|
+
pointer-events: none;
|
|
1724
|
+
border-top: 2px solid var(--el-border-strong);
|
|
1725
|
+
filter: url(#hd-rough);
|
|
1726
|
+
}
|
|
1640
1727
|
}
|
|
1641
1728
|
/* Suppress the overlay only where the REAL divider is removed: the last row of a
|
|
1642
1729
|
fully-rendered list strips its border via `last:border-b-0`. (We can't use
|
|
@@ -1644,8 +1731,10 @@
|
|
|
1644
1731
|
own `role="rowgroup"`, so it is itself a `:last-child` and would be wrongly
|
|
1645
1732
|
skipped, which left the work-item table header's divider straight.) Same
|
|
1646
1733
|
specificity as the draw rule, placed after, so it wins on the real last row. */
|
|
1647
|
-
[data-style='hand-drawn-indie'] [data-
|
|
1648
|
-
|
|
1734
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1735
|
+
[data-surface] .last\:border-b-0:last-child::after {
|
|
1736
|
+
content: none;
|
|
1737
|
+
}
|
|
1649
1738
|
}
|
|
1650
1739
|
|
|
1651
1740
|
/* The APP SHELL FRAME — the sidebar rail's right edge + the top bar's bottom edge
|
|
@@ -1659,31 +1748,36 @@
|
|
|
1659
1748
|
ONLY to a STATIC host (the rail) — never the STICKY header, which is already a
|
|
1660
1749
|
containing block (overriding it would break the sticky), mirroring the `.border`
|
|
1661
1750
|
rule's guard. */
|
|
1662
|
-
[data-style='hand-drawn-indie']
|
|
1751
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1663
1752
|
:is([data-surface='sidebar'], [data-surface='header']):not(.fixed):not(.absolute):not(.sticky) {
|
|
1664
|
-
|
|
1753
|
+
position: relative;
|
|
1754
|
+
}
|
|
1665
1755
|
}
|
|
1666
|
-
[data-style='hand-drawn-indie'] [data-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1756
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1757
|
+
[data-surface='sidebar']::after {
|
|
1758
|
+
content: '';
|
|
1759
|
+
position: absolute;
|
|
1760
|
+
top: 0;
|
|
1761
|
+
bottom: 0;
|
|
1762
|
+
right: -1px;
|
|
1763
|
+
width: 0;
|
|
1764
|
+
pointer-events: none;
|
|
1765
|
+
border-right: 2px solid var(--el-border-strong);
|
|
1766
|
+
filter: url(#hd-rough);
|
|
1767
|
+
}
|
|
1676
1768
|
}
|
|
1677
|
-
[data-style='hand-drawn-indie'] [data-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1769
|
+
@scope ([data-style='hand-drawn-indie']) to ([data-style]) {
|
|
1770
|
+
[data-surface='header']::after {
|
|
1771
|
+
content: '';
|
|
1772
|
+
position: absolute;
|
|
1773
|
+
left: 0;
|
|
1774
|
+
right: 0;
|
|
1775
|
+
bottom: -1px;
|
|
1776
|
+
height: 0;
|
|
1777
|
+
pointer-events: none;
|
|
1778
|
+
border-bottom: 2px solid var(--el-border-strong);
|
|
1779
|
+
filter: url(#hd-rough);
|
|
1780
|
+
}
|
|
1687
1781
|
}
|
|
1688
1782
|
|
|
1689
1783
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -1795,8 +1889,10 @@
|
|
|
1795
1889
|
panels look MOULDED OUT OF the same material rather than placed on top. Both
|
|
1796
1890
|
the canvas and the surfaces below share `var(--el-surface)`, which is the whole
|
|
1797
1891
|
neumorphic illusion. Palette-derived (no hue of its own). */
|
|
1798
|
-
[data-style='neumorphism']
|
|
1799
|
-
|
|
1892
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1893
|
+
body {
|
|
1894
|
+
background-color: var(--el-surface);
|
|
1895
|
+
}
|
|
1800
1896
|
}
|
|
1801
1897
|
|
|
1802
1898
|
/* Raised container surfaces — cards & popovers swell OUT of the field on a paired
|
|
@@ -1806,45 +1902,53 @@
|
|
|
1806
1902
|
from hue. The faint hairline is kept as the accessibility fallback so structure
|
|
1807
1903
|
doesn't depend on the shadow alone. Opaque `--el-surface` keeps text on the
|
|
1808
1904
|
palette's AA-tuned surface. */
|
|
1809
|
-
[data-style='neumorphism'] [data-
|
|
1810
|
-
[data-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1905
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1906
|
+
[data-surface='card'],
|
|
1907
|
+
[data-surface='popover'] {
|
|
1908
|
+
background-color: var(--el-surface);
|
|
1909
|
+
border-color: color-mix(in srgb, var(--el-border) 45%, transparent);
|
|
1910
|
+
box-shadow:
|
|
1911
|
+
var(--neu-distance) var(--neu-distance) var(--neu-blur) var(--neu-shadow),
|
|
1912
|
+
calc(-1 * var(--neu-distance)) calc(-1 * var(--neu-distance)) var(--neu-blur) var(--neu-light);
|
|
1913
|
+
}
|
|
1816
1914
|
}
|
|
1817
1915
|
|
|
1818
1916
|
/* Modal panel — the same raised mould, a touch deeper so the dialog separates
|
|
1819
1917
|
from the field behind it (body text stays on the opaque surface). */
|
|
1820
|
-
[data-style='neumorphism'] [data-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
var(--neu-
|
|
1826
|
-
|
|
1827
|
-
var(--neu-
|
|
1918
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1919
|
+
[data-surface='modal'] {
|
|
1920
|
+
background-color: var(--el-surface);
|
|
1921
|
+
border-color: color-mix(in srgb, var(--el-border) 45%, transparent);
|
|
1922
|
+
box-shadow:
|
|
1923
|
+
calc(var(--neu-distance) + 2px) calc(var(--neu-distance) + 2px) calc(var(--neu-blur) + 8px)
|
|
1924
|
+
var(--neu-shadow),
|
|
1925
|
+
calc(-1 * var(--neu-distance)) calc(-1 * var(--neu-distance)) calc(var(--neu-blur) + 4px)
|
|
1926
|
+
var(--neu-light);
|
|
1927
|
+
}
|
|
1828
1928
|
}
|
|
1829
1929
|
|
|
1830
1930
|
/* The sidebar rail — moulded from the same field as the chrome, gently raised so
|
|
1831
1931
|
it reads as part of the one continuous surface. */
|
|
1832
|
-
[data-style='neumorphism'] [data-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1932
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1933
|
+
[data-surface='sidebar'] {
|
|
1934
|
+
background-color: var(--el-surface);
|
|
1935
|
+
box-shadow:
|
|
1936
|
+
var(--neu-distance) 0 var(--neu-blur) var(--neu-shadow),
|
|
1937
|
+
calc(-1 * var(--neu-distance)) 0 var(--neu-blur) var(--neu-light);
|
|
1938
|
+
}
|
|
1837
1939
|
}
|
|
1838
1940
|
|
|
1839
1941
|
/* Form controls — the inverse mould: a CONCAVE INSET well pressed INTO the field
|
|
1840
1942
|
(the soft-UI input look), the paired shadow flipped to `inset`. */
|
|
1841
|
-
[data-style='neumorphism'] [data-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
var(--neu-
|
|
1943
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1944
|
+
[data-surface='input'] {
|
|
1945
|
+
background-color: var(--el-surface);
|
|
1946
|
+
border-color: color-mix(in srgb, var(--el-border) 45%, transparent);
|
|
1947
|
+
box-shadow:
|
|
1948
|
+
inset var(--neu-distance-sm) var(--neu-distance-sm) var(--neu-blur-sm) var(--neu-shadow),
|
|
1949
|
+
inset calc(-1 * var(--neu-distance-sm)) calc(-1 * var(--neu-distance-sm)) var(--neu-blur-sm)
|
|
1950
|
+
var(--neu-light);
|
|
1951
|
+
}
|
|
1848
1952
|
}
|
|
1849
1953
|
|
|
1850
1954
|
/* Accessibility fallback — when a user asks for more contrast (or forced colours),
|
|
@@ -1852,23 +1956,27 @@
|
|
|
1852
1956
|
moulded surface and flatten the paired shadow to a single readable lift.
|
|
1853
1957
|
Palette-derived (var(--el-border)); no hue. */
|
|
1854
1958
|
@media (prefers-contrast: more) {
|
|
1855
|
-
[data-style='neumorphism'] [data-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1959
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1960
|
+
[data-surface='card'],
|
|
1961
|
+
[data-surface='popover'],
|
|
1962
|
+
[data-surface='modal'],
|
|
1963
|
+
[data-surface='input'],
|
|
1964
|
+
[data-surface='sidebar'] {
|
|
1965
|
+
border-color: var(--el-border-strong);
|
|
1966
|
+
box-shadow: var(--shadow-card);
|
|
1967
|
+
}
|
|
1862
1968
|
}
|
|
1863
1969
|
}
|
|
1864
1970
|
@media (forced-colors: active) {
|
|
1865
|
-
[data-style='neumorphism'] [data-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1971
|
+
@scope ([data-style='neumorphism']) to ([data-style]) {
|
|
1972
|
+
[data-surface='card'],
|
|
1973
|
+
[data-surface='popover'],
|
|
1974
|
+
[data-surface='modal'],
|
|
1975
|
+
[data-surface='input'],
|
|
1976
|
+
[data-surface='sidebar'] {
|
|
1977
|
+
border-color: var(--el-border-strong);
|
|
1978
|
+
box-shadow: none;
|
|
1979
|
+
}
|
|
1872
1980
|
}
|
|
1873
1981
|
}
|
|
1874
1982
|
|
|
@@ -1972,27 +2080,29 @@
|
|
|
1972
2080
|
axis overrides `--el-*`, never `--color-*`, which keeps the horizon orthogonal
|
|
1973
2081
|
to the palette. Painted as the body's own background (always behind content),
|
|
1974
2082
|
the proven 3D/Immersive atmosphere approach. */
|
|
1975
|
-
[data-style='retrofuturism']
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
2083
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2084
|
+
body {
|
|
2085
|
+
background-image:
|
|
2086
|
+
linear-gradient(
|
|
2087
|
+
180deg,
|
|
2088
|
+
transparent 54%,
|
|
2089
|
+
color-mix(in srgb, var(--el-highlight) var(--retro-horizon), transparent) 60.5%,
|
|
2090
|
+
color-mix(in srgb, var(--el-accent) var(--retro-horizon), transparent) 62.5%,
|
|
2091
|
+
transparent 69%
|
|
2092
|
+
),
|
|
2093
|
+
linear-gradient(
|
|
2094
|
+
180deg,
|
|
2095
|
+
color-mix(in srgb, var(--el-link) var(--retro-sky), transparent),
|
|
2096
|
+
transparent 46%
|
|
2097
|
+
),
|
|
2098
|
+
linear-gradient(
|
|
2099
|
+
0deg,
|
|
2100
|
+
color-mix(in srgb, var(--el-accent) var(--retro-ground), transparent),
|
|
2101
|
+
transparent 42%
|
|
2102
|
+
);
|
|
2103
|
+
background-size: 100% 100%;
|
|
2104
|
+
background-attachment: fixed;
|
|
2105
|
+
}
|
|
1996
2106
|
}
|
|
1997
2107
|
|
|
1998
2108
|
/* The Outrun GRID FLOOR — a receding neon grid below the horizon. A separate
|
|
@@ -2003,31 +2113,33 @@
|
|
|
2003
2113
|
their own); the mask uses the achromatic `black` keyword (no hex). The grid is
|
|
2004
2114
|
STATIC depth — like 3D/Immersive's atmosphere it carries the identity, so it is
|
|
2005
2115
|
not motion-gated (there is no animation to suppress). */
|
|
2006
|
-
[data-style='retrofuturism']
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2116
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2117
|
+
body::after {
|
|
2118
|
+
content: '';
|
|
2119
|
+
position: fixed;
|
|
2120
|
+
left: -30%;
|
|
2121
|
+
right: -30%;
|
|
2122
|
+
bottom: 0;
|
|
2123
|
+
height: 42vh;
|
|
2124
|
+
background-image:
|
|
2125
|
+
repeating-linear-gradient(
|
|
2126
|
+
0deg,
|
|
2127
|
+
color-mix(in srgb, var(--el-highlight) var(--retro-grid), transparent) 0 2px,
|
|
2128
|
+
transparent 2px var(--retro-grid-size)
|
|
2129
|
+
),
|
|
2130
|
+
repeating-linear-gradient(
|
|
2131
|
+
90deg,
|
|
2132
|
+
color-mix(in srgb, var(--el-accent) var(--retro-grid), transparent) 0 2px,
|
|
2133
|
+
transparent 2px var(--retro-grid-size)
|
|
2134
|
+
);
|
|
2135
|
+
background-size: var(--retro-grid-size) var(--retro-grid-size);
|
|
2136
|
+
transform: perspective(300px) rotateX(75deg);
|
|
2137
|
+
transform-origin: bottom center;
|
|
2138
|
+
-webkit-mask-image: linear-gradient(to top, black 2%, transparent 80%);
|
|
2139
|
+
mask-image: linear-gradient(to top, black 2%, transparent 80%);
|
|
2140
|
+
pointer-events: none;
|
|
2141
|
+
z-index: -1;
|
|
2142
|
+
}
|
|
2031
2143
|
}
|
|
2032
2144
|
|
|
2033
2145
|
/* Chrome container surfaces — OPAQUE (text AA is preserved against the base
|
|
@@ -2039,73 +2151,79 @@
|
|
|
2039
2151
|
so they never pull a surface far from its base tone; the inset top/bottom lines
|
|
2040
2152
|
are the lit chrome rim. Applied to EVERY panel via the global card-radius
|
|
2041
2153
|
utility (the 3D/Immersive coverage approach), not just the <Card> primitive. */
|
|
2042
|
-
[data-style='retrofuturism'] [data-
|
|
2043
|
-
[data-
|
|
2044
|
-
[data-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2154
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2155
|
+
[data-surface='card'],
|
|
2156
|
+
[data-surface='popover'],
|
|
2157
|
+
.rounded-\(--radius-card\) {
|
|
2158
|
+
background-color: var(--el-surface);
|
|
2159
|
+
background-image:
|
|
2160
|
+
linear-gradient(
|
|
2161
|
+
158deg,
|
|
2162
|
+
transparent 36%,
|
|
2163
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 49%,
|
|
2164
|
+
transparent 62%
|
|
2165
|
+
),
|
|
2166
|
+
linear-gradient(
|
|
2167
|
+
180deg,
|
|
2168
|
+
color-mix(in srgb, white var(--retro-bevel-light), transparent) 0%,
|
|
2169
|
+
transparent 16%,
|
|
2170
|
+
transparent 78%,
|
|
2171
|
+
color-mix(in srgb, black var(--retro-bevel-shade), transparent) 100%
|
|
2172
|
+
);
|
|
2173
|
+
box-shadow:
|
|
2174
|
+
var(--shadow-card),
|
|
2175
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2176
|
+
inset 0 -1px 0 color-mix(in srgb, black 24%, transparent),
|
|
2177
|
+
0 0 28px -8px color-mix(in srgb, var(--el-accent) var(--retro-glow), transparent);
|
|
2178
|
+
}
|
|
2065
2179
|
}
|
|
2066
2180
|
|
|
2067
2181
|
/* Modal panel — the same chrome, with a deeper palette glow so the dialog
|
|
2068
2182
|
separates cleanly from the grid behind it (and body text stays on the solid
|
|
2069
2183
|
surface). Overrides the card-radius rule above for the modal radius. */
|
|
2070
|
-
[data-style='retrofuturism'] [data-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2184
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2185
|
+
[data-surface='modal'] {
|
|
2186
|
+
background-color: var(--el-surface);
|
|
2187
|
+
background-image:
|
|
2188
|
+
linear-gradient(
|
|
2189
|
+
158deg,
|
|
2190
|
+
transparent 34%,
|
|
2191
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 49%,
|
|
2192
|
+
transparent 64%
|
|
2193
|
+
),
|
|
2194
|
+
linear-gradient(
|
|
2195
|
+
180deg,
|
|
2196
|
+
color-mix(in srgb, white var(--retro-bevel-light), transparent) 0%,
|
|
2197
|
+
transparent 14%,
|
|
2198
|
+
transparent 80%,
|
|
2199
|
+
color-mix(in srgb, black var(--retro-bevel-shade), transparent) 100%
|
|
2200
|
+
);
|
|
2201
|
+
box-shadow:
|
|
2202
|
+
var(--shadow-modal),
|
|
2203
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2204
|
+
0 0 56px -14px color-mix(in srgb, var(--el-highlight) var(--retro-glow-strong), transparent);
|
|
2205
|
+
}
|
|
2090
2206
|
}
|
|
2091
2207
|
|
|
2092
2208
|
/* The sidebar rail — opaque chrome with a quieter specular + bevel so it reads as
|
|
2093
2209
|
part of the polished-metal family, not a flat slab. */
|
|
2094
|
-
[data-style='retrofuturism'] [data-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2210
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2211
|
+
[data-surface='sidebar'] {
|
|
2212
|
+
background-color: var(--el-sidebar-bg);
|
|
2213
|
+
background-image:
|
|
2214
|
+
linear-gradient(
|
|
2215
|
+
158deg,
|
|
2216
|
+
transparent 40%,
|
|
2217
|
+
color-mix(in srgb, white var(--retro-sheen), transparent) 50%,
|
|
2218
|
+
transparent 60%
|
|
2219
|
+
),
|
|
2220
|
+
linear-gradient(
|
|
2221
|
+
180deg,
|
|
2222
|
+
color-mix(in srgb, white var(--retro-sheen), transparent),
|
|
2223
|
+
transparent 24%,
|
|
2224
|
+
color-mix(in srgb, black var(--retro-bevel-shade), transparent) 100%
|
|
2225
|
+
);
|
|
2226
|
+
}
|
|
2109
2227
|
}
|
|
2110
2228
|
|
|
2111
2229
|
/* Text inputs (a TYPING field) — a RECESSED chrome well: the bevel inverts (a
|
|
@@ -2113,14 +2231,16 @@
|
|
|
2113
2231
|
metal. Clickable controls (dropdown / select / picker triggers + buttons) get
|
|
2114
2232
|
the RAISED chrome below instead — matching the CTA — so a typing field stays
|
|
2115
2233
|
recessed while everything you click reads as a raised chrome control. */
|
|
2116
|
-
[data-style='retrofuturism'] [data-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2234
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2235
|
+
[data-surface='input'] {
|
|
2236
|
+
background-color: var(--el-page-bg);
|
|
2237
|
+
background-image: linear-gradient(
|
|
2238
|
+
180deg,
|
|
2239
|
+
color-mix(in srgb, black var(--retro-sheen), transparent) 0%,
|
|
2240
|
+
transparent 34%
|
|
2241
|
+
);
|
|
2242
|
+
box-shadow: inset 0 1px 3px color-mix(in srgb, black var(--retro-glow), transparent);
|
|
2243
|
+
}
|
|
2124
2244
|
}
|
|
2125
2245
|
|
|
2126
2246
|
/* ── EVERY clickable control reads as RETRO CHROME (7.3.40) ──────────────────
|
|
@@ -2151,46 +2271,50 @@
|
|
|
2151
2271
|
/* FILLED CTAs — accent (primary) keeps its hue under a diagonal specular glint +
|
|
2152
2272
|
a vertical metallic sweep + a palette glow. Keyed on the fill class so it
|
|
2153
2273
|
covers the `Button` primitive AND `buttonVariants()` anchors alike. */
|
|
2154
|
-
[data-style='retrofuturism']
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2274
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2275
|
+
.rounded-\(--radius-btn\).bg-\(--el-accent\) {
|
|
2276
|
+
background-image:
|
|
2277
|
+
linear-gradient(
|
|
2278
|
+
158deg,
|
|
2279
|
+
transparent 38%,
|
|
2280
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 50%,
|
|
2281
|
+
transparent 62%
|
|
2282
|
+
),
|
|
2283
|
+
linear-gradient(
|
|
2284
|
+
180deg,
|
|
2285
|
+
color-mix(in srgb, white var(--retro-spec), var(--el-accent)) 0%,
|
|
2286
|
+
var(--el-accent) 46%,
|
|
2287
|
+
color-mix(in srgb, black var(--retro-bevel-shade), var(--el-accent)) 100%
|
|
2288
|
+
);
|
|
2289
|
+
box-shadow:
|
|
2290
|
+
var(--shadow-subtle),
|
|
2291
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2292
|
+
0 0 22px -6px color-mix(in srgb, var(--el-accent) var(--retro-glow-strong), transparent);
|
|
2293
|
+
}
|
|
2172
2294
|
}
|
|
2173
2295
|
|
|
2174
2296
|
/* Danger CTAs — the same machined sweep, in the danger hue (so a destructive
|
|
2175
2297
|
button reads as red chrome, not a flat red, matching the accent CTA). */
|
|
2176
|
-
[data-style='retrofuturism']
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2298
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2299
|
+
.rounded-\(--radius-btn\).bg-\(--el-danger\) {
|
|
2300
|
+
background-image:
|
|
2301
|
+
linear-gradient(
|
|
2302
|
+
158deg,
|
|
2303
|
+
transparent 38%,
|
|
2304
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 50%,
|
|
2305
|
+
transparent 62%
|
|
2306
|
+
),
|
|
2307
|
+
linear-gradient(
|
|
2308
|
+
180deg,
|
|
2309
|
+
color-mix(in srgb, white var(--retro-spec), var(--el-danger)) 0%,
|
|
2310
|
+
var(--el-danger) 46%,
|
|
2311
|
+
color-mix(in srgb, black var(--retro-bevel-shade), var(--el-danger)) 100%
|
|
2312
|
+
);
|
|
2313
|
+
box-shadow:
|
|
2314
|
+
var(--shadow-subtle),
|
|
2315
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2316
|
+
0 0 22px -6px color-mix(in srgb, var(--el-danger) var(--retro-glow-strong), transparent);
|
|
2317
|
+
}
|
|
2194
2318
|
}
|
|
2195
2319
|
|
|
2196
2320
|
/* NEUTRAL STEEL chrome — every OTHER clickable control: bordered buttons + links
|
|
@@ -2199,67 +2323,74 @@
|
|
|
2199
2323
|
`:not([role='group'])` excludes the segmented TRACK (its own rule below); the
|
|
2200
2324
|
FILLED CTAs are excluded automatically (they carry a fill class, not `.border`).
|
|
2201
2325
|
The gunmetal base is set here because secondary controls ship `bg-transparent`. */
|
|
2202
|
-
[data-style='retrofuturism']
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2326
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2327
|
+
.rounded-\(--radius-btn\).border:not([role='group']),
|
|
2328
|
+
button.rounded-\(--radius-input\) {
|
|
2329
|
+
background-color: color-mix(in srgb, black 24%, var(--el-surface));
|
|
2330
|
+
background-image:
|
|
2331
|
+
linear-gradient(
|
|
2332
|
+
158deg,
|
|
2333
|
+
transparent 36%,
|
|
2334
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 50%,
|
|
2335
|
+
transparent 64%
|
|
2336
|
+
),
|
|
2337
|
+
linear-gradient(
|
|
2338
|
+
180deg,
|
|
2339
|
+
color-mix(in srgb, white var(--retro-bevel-light), transparent) 0%,
|
|
2340
|
+
transparent 42%,
|
|
2341
|
+
transparent 60%,
|
|
2342
|
+
color-mix(in srgb, black var(--retro-bevel-shade), transparent) 100%
|
|
2343
|
+
);
|
|
2344
|
+
box-shadow:
|
|
2345
|
+
var(--shadow-subtle),
|
|
2346
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2347
|
+
inset 0 -1px 0 color-mix(in srgb, black 24%, transparent),
|
|
2348
|
+
0 0 18px -8px color-mix(in srgb, var(--el-accent) var(--retro-glow), transparent);
|
|
2349
|
+
}
|
|
2224
2350
|
}
|
|
2225
2351
|
|
|
2226
2352
|
/* SEGMENTED control (the board "Group by" switch + every other `Segmented` use):
|
|
2227
2353
|
the classic metal segmented control — a RECESSED gunmetal TRACK (the
|
|
2228
2354
|
`[role='group']` wrapper) with the ACTIVE segment (`aria-pressed='true'`) raised
|
|
2229
2355
|
out of it as a chrome chip. Inactive segments stay transparent on the track. */
|
|
2230
|
-
[data-style='retrofuturism'] [
|
|
2231
|
-
|
|
2232
|
-
|
|
2356
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2357
|
+
[role='group'].rounded-\(--radius-btn\) {
|
|
2358
|
+
background-color: color-mix(in srgb, black 15%, var(--el-surface));
|
|
2359
|
+
box-shadow: inset 0 1px 3px color-mix(in srgb, black var(--retro-glow), transparent);
|
|
2360
|
+
}
|
|
2233
2361
|
}
|
|
2234
|
-
[data-style='retrofuturism']
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2362
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2363
|
+
[role='group'] [aria-pressed='true'] {
|
|
2364
|
+
background-color: color-mix(in srgb, black 24%, var(--el-surface));
|
|
2365
|
+
background-image:
|
|
2366
|
+
linear-gradient(
|
|
2367
|
+
158deg,
|
|
2368
|
+
transparent 36%,
|
|
2369
|
+
color-mix(in srgb, white var(--retro-spec), transparent) 50%,
|
|
2370
|
+
transparent 64%
|
|
2371
|
+
),
|
|
2372
|
+
linear-gradient(
|
|
2373
|
+
180deg,
|
|
2374
|
+
color-mix(in srgb, white var(--retro-bevel-light), transparent) 0%,
|
|
2375
|
+
transparent 42%,
|
|
2376
|
+
transparent 60%,
|
|
2377
|
+
color-mix(in srgb, black var(--retro-bevel-shade), transparent) 100%
|
|
2378
|
+
);
|
|
2379
|
+
box-shadow:
|
|
2380
|
+
var(--shadow-subtle),
|
|
2381
|
+
inset 0 1px 0 color-mix(in srgb, white 60%, transparent),
|
|
2382
|
+
inset 0 -1px 0 color-mix(in srgb, black 24%, transparent);
|
|
2383
|
+
}
|
|
2254
2384
|
}
|
|
2255
2385
|
|
|
2256
2386
|
/* Hover — brighten the steel a touch (the controls' own `hover:bg-*` utilities
|
|
2257
2387
|
are out-specified by the rules above, so restore a clear hover signal). */
|
|
2258
|
-
[data-style='retrofuturism']
|
|
2388
|
+
@scope ([data-style='retrofuturism']) to ([data-style]) {
|
|
2259
2389
|
.rounded-\(--radius-btn\).border:not([role='group']):hover:not(:disabled),
|
|
2260
|
-
|
|
2261
|
-
[
|
|
2262
|
-
|
|
2390
|
+
button.rounded-\(--radius-input\):hover:not(:disabled),
|
|
2391
|
+
[role='group'] [aria-pressed='false']:hover:not(:disabled) {
|
|
2392
|
+
background-color: color-mix(in srgb, black 14%, var(--el-surface));
|
|
2393
|
+
}
|
|
2263
2394
|
}
|
|
2264
2395
|
|
|
2265
2396
|
/* ─────────────────────────────────────────────────────────────────────────
|
|
@@ -2533,7 +2664,25 @@
|
|
|
2533
2664
|
nobody renders — the base layer IS how the browser reaches these values. */
|
|
2534
2665
|
--el-status-implemented: color-mix(in srgb, var(--color-accent) 75%, var(--color-charcoal));
|
|
2535
2666
|
--el-status-in-review: var(--color-primary); /* brand — differentiate from in-progress */
|
|
2536
|
-
|
|
2667
|
+
/* green — RESOLVED (MOTIR-3991). The bare --color-success (#1aae39) was
|
|
2668
|
+
2.93:1 on --el-card and 2.69:1 on --el-surface in the BASE palette's LIGHT
|
|
2669
|
+
theme — under 1.4.11's 3:1 for a graphical object, and the one palette x
|
|
2670
|
+
theme in which this token missed the bar. --color-success is NOT free to
|
|
2671
|
+
move: the same Tier-0 hue paints --el-success-surface's companion ink, the
|
|
2672
|
+
success toast/notice family and the chart-success step, each held to its
|
|
2673
|
+
own AA bar that pulls opposite to a dot's 3:1 — so the ramp takes one step
|
|
2674
|
+
of the palette's own emphasis ink instead of re-tuning the source. 85% of
|
|
2675
|
+
--color-success toward --color-charcoal gives #1e9c38, 3.58 / 3.29 / 3.58
|
|
2676
|
+
on card / surface / page-bg. --color-charcoal flips with the theme
|
|
2677
|
+
(#37352f light, #e5e5e5 dark), so the same expression DARKENS on white and
|
|
2678
|
+
LIGHTENS on near-black — dark goes 7.29 / 6.62 / 7.29:1. Both inputs stay
|
|
2679
|
+
palette-tuned, so the nine palettes that ride this base value re-skin it as
|
|
2680
|
+
before and each keeps its own --color-success; ΔE2000 to the nearest
|
|
2681
|
+
sibling stays >= 11.3 in all ten palettes x both themes. Why the base and
|
|
2682
|
+
not a [data-palette='motir'] block: same as --el-status-implemented above —
|
|
2683
|
+
<html> carries no data-appearance-scope, so the base layer IS how the
|
|
2684
|
+
browser reaches these values. */
|
|
2685
|
+
--el-status-done: color-mix(in srgb, var(--color-success) 85%, var(--color-charcoal));
|
|
2537
2686
|
--el-status-blocked: var(--color-warning); /* amber — can't proceed (gap fixed) */
|
|
2538
2687
|
--el-status-cancelled: var(--color-steel); /* terminal grey — not red (cancel ≠ error) */
|
|
2539
2688
|
|