@quilltap/theme-storybook 1.0.61 → 1.0.63
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/CHANGELOG.md +15 -0
- package/dist/{chunk-XSNC4J5T.mjs → chunk-TESCTXU3.mjs} +52 -0
- package/dist/index.css +261 -0
- package/dist/index.js +52 -0
- package/dist/index.mjs +1 -1
- package/dist/stories/index.js +52 -0
- package/dist/stories/index.mjs +1 -1
- package/package.json +2 -2
- package/src/css/qt-components.css +367 -0
- package/src/stories/components/Surfaces.tsx +52 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@quilltap/theme-storybook` will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.0.63] - 2026-08-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- The rest of the `qt-*` utility families the app actually ships, so a theme can be previewed against what it will really meet: the missing opacity steps for `qt-bg-muted` (20–80), `qt-bg-card` (50–90), `qt-bg-primary`, `qt-bg-destructive`, `qt-bg-success`, `qt-bg-warning`, `qt-bg-info` and `qt-bg-secondary`; `qt-border-default`, `qt-border-primary`, `qt-border-destructive`, `qt-border-warning` and `qt-border-success` at their used opacities; `qt-text-secondary/50–80` and the status colours at `/80`; and the surface colours `qt-bg-default`, `qt-bg-input`, `qt-bg-secondary`, `qt-border-accent`, `qt-border-primary-foreground`.
|
|
9
|
+
- 34 state forms of those utilities — `hover:`, `focus:`, `disabled:`, `placeholder:`, `file:` and one named `group-hover/thumb:`. In the app every one of these is hand-written and escaped, because Tailwind generates no variants for a class declared inside `@layer utilities`; they are mirrored here so a theme author previewing hover states sees what the app actually ships rather than a resting state that never moves.
|
|
10
|
+
|
|
11
|
+
### Notes
|
|
12
|
+
- The typography-sizing classes (`qt-text-small`, `qt-text-xs`, `qt-text-label`, `qt-text-label-xs`, `qt-text-large`, `qt-text-lead`, `qt-text-section`) live in the app's `@layer components` sheet and have never been mirrored here. Still outstanding; the color-carrying `qt-text-*` utilities are complete.
|
|
13
|
+
|
|
14
|
+
## [1.0.62] - 2026-08-25
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- `qt-text-on-primary`, `qt-text-on-success`, and `qt-text-on-destructive`: the rest of the on-a-filled-surface foreground family that `qt-text-on-accent` started, each mapping to the theme's matching `*Foreground` token. Plus the hand-written hover partners `hover:qt-text-on-accent/-primary/-success/-destructive`, for controls that sit quiet at rest and take a filled background on hover. Mirrors the app-side definitions.
|
|
18
|
+
- `Surfaces` story: a "Foregrounds on filled surfaces" section previewing all four fills with their foregrounds, and a hover row for the hover partners. It also spells out the naming trap — the classes are `-on-<fill>`, never `-<fill>-foreground`, which is the Tailwind spelling and no `qt-` class at all.
|
|
19
|
+
|
|
5
20
|
## [1.0.44] - 2026-06-14
|
|
6
21
|
|
|
7
22
|
### Added
|
|
@@ -1043,6 +1043,11 @@ var note = {
|
|
|
1043
1043
|
};
|
|
1044
1044
|
var Surfaces = () => {
|
|
1045
1045
|
return /* @__PURE__ */ jsxs9("div", { style: { padding: "1.5rem" }, children: [
|
|
1046
|
+
/* @__PURE__ */ jsx9("style", { children: `
|
|
1047
|
+
.surfaces-demo-fill-primary:hover { background-color: var(--color-primary); }
|
|
1048
|
+
.surfaces-demo-fill-success:hover { background-color: var(--color-success); }
|
|
1049
|
+
.surfaces-demo-fill-destructive:hover { background-color: var(--color-destructive); }
|
|
1050
|
+
` }),
|
|
1046
1051
|
/* @__PURE__ */ jsx9("h2", { style: { fontSize: "1.5rem", fontWeight: 700, marginBottom: "0.5rem" }, children: "Surfaces" }),
|
|
1047
1052
|
/* @__PURE__ */ jsxs9("p", { style: { ...note, maxWidth: "44rem" }, children: [
|
|
1048
1053
|
"How accent-coloured surfaces stay legible no matter how bold a theme makes its ",
|
|
@@ -1079,6 +1084,53 @@ var Surfaces = () => {
|
|
|
1079
1084
|
/* @__PURE__ */ jsx9("kbd", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.125rem 0.375rem", borderRadius: "0.25rem", fontSize: "0.75rem" }, children: "\u21B5" })
|
|
1080
1085
|
] })
|
|
1081
1086
|
] }),
|
|
1087
|
+
/* @__PURE__ */ jsxs9("section", { style: { marginBottom: "2rem" }, children: [
|
|
1088
|
+
/* @__PURE__ */ jsxs9("h3", { style: sectionHeading2, children: [
|
|
1089
|
+
"Foregrounds on filled surfaces \u2014 the ",
|
|
1090
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-text-on-*" }),
|
|
1091
|
+
" family"
|
|
1092
|
+
] }),
|
|
1093
|
+
/* @__PURE__ */ jsxs9("p", { style: note, children: [
|
|
1094
|
+
"The same contract, extended to every filled surface the app paints:",
|
|
1095
|
+
" ",
|
|
1096
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-text-on-accent" }),
|
|
1097
|
+
", ",
|
|
1098
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-text-on-primary" }),
|
|
1099
|
+
",",
|
|
1100
|
+
" ",
|
|
1101
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-text-on-success" }),
|
|
1102
|
+
", and ",
|
|
1103
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-text-on-destructive" }),
|
|
1104
|
+
", each mapping to the theme's matching ",
|
|
1105
|
+
/* @__PURE__ */ jsx9("code", { children: "*Foreground" }),
|
|
1106
|
+
" token. Note the naming \u2014 ",
|
|
1107
|
+
/* @__PURE__ */ jsxs9("code", { children: [
|
|
1108
|
+
"-on-",
|
|
1109
|
+
/* @__PURE__ */ jsx9("em", { children: "fill" })
|
|
1110
|
+
] }),
|
|
1111
|
+
", never ",
|
|
1112
|
+
/* @__PURE__ */ jsxs9("code", { children: [
|
|
1113
|
+
"-",
|
|
1114
|
+
/* @__PURE__ */ jsx9("em", { children: "fill" }),
|
|
1115
|
+
"-foreground"
|
|
1116
|
+
] }),
|
|
1117
|
+
", which is the Tailwind spelling and is not a ",
|
|
1118
|
+
/* @__PURE__ */ jsx9("code", { children: "qt-" }),
|
|
1119
|
+
" class at all."
|
|
1120
|
+
] }),
|
|
1121
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1122
|
+
/* @__PURE__ */ jsx9("span", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on accent" }),
|
|
1123
|
+
/* @__PURE__ */ jsx9("span", { className: "qt-bg-primary qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on primary" }),
|
|
1124
|
+
/* @__PURE__ */ jsx9("span", { className: "qt-bg-success qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on success" }),
|
|
1125
|
+
/* @__PURE__ */ jsx9("span", { className: "qt-bg-destructive qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on destructive" })
|
|
1126
|
+
] }),
|
|
1127
|
+
/* @__PURE__ */ jsx9("p", { style: { ...note, marginTop: "1rem" }, children: "Each has a hover partner for controls that stay quiet at rest and take the fill on hover. Tailwind generates no variants for these classes, so the hover forms are written out by hand \u2014 reach for one that was never written and it is simply inert. Hover the buttons below." }),
|
|
1128
|
+
/* @__PURE__ */ jsxs9("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1129
|
+
/* @__PURE__ */ jsx9("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-primary hover:qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-primary" }),
|
|
1130
|
+
/* @__PURE__ */ jsx9("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-success hover:qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-success" }),
|
|
1131
|
+
/* @__PURE__ */ jsx9("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-destructive hover:qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-destructive" })
|
|
1132
|
+
] })
|
|
1133
|
+
] }),
|
|
1082
1134
|
/* @__PURE__ */ jsxs9("section", { style: { marginBottom: "2rem" }, children: [
|
|
1083
1135
|
/* @__PURE__ */ jsxs9("h3", { style: sectionHeading2, children: [
|
|
1084
1136
|
"Hover-highlight rows \u2014 ",
|
package/dist/index.css
CHANGED
|
@@ -1948,6 +1948,150 @@ body {
|
|
|
1948
1948
|
.qt-text-on-accent {
|
|
1949
1949
|
color: var(--color-accent-foreground);
|
|
1950
1950
|
}
|
|
1951
|
+
.qt-text-on-primary {
|
|
1952
|
+
color: var(--color-primary-foreground);
|
|
1953
|
+
}
|
|
1954
|
+
.qt-text-on-success {
|
|
1955
|
+
color: var(--color-success-foreground);
|
|
1956
|
+
}
|
|
1957
|
+
.qt-text-on-destructive {
|
|
1958
|
+
color: var(--color-destructive-foreground);
|
|
1959
|
+
}
|
|
1960
|
+
.qt-bg-card\/50 {
|
|
1961
|
+
background-color: color-mix(in srgb, var(--color-card) 50%, transparent);
|
|
1962
|
+
}
|
|
1963
|
+
.qt-bg-card\/60 {
|
|
1964
|
+
background-color: color-mix(in srgb, var(--color-card) 60%, transparent);
|
|
1965
|
+
}
|
|
1966
|
+
.qt-bg-card\/80 {
|
|
1967
|
+
background-color: color-mix(in srgb, var(--color-card) 80%, transparent);
|
|
1968
|
+
}
|
|
1969
|
+
.qt-bg-card\/90 {
|
|
1970
|
+
background-color: color-mix(in srgb, var(--color-card) 90%, transparent);
|
|
1971
|
+
}
|
|
1972
|
+
.qt-bg-default {
|
|
1973
|
+
background-color: var(--color-background);
|
|
1974
|
+
}
|
|
1975
|
+
.qt-bg-destructive\/15 {
|
|
1976
|
+
background-color: color-mix(in srgb, var(--color-destructive) 15%, transparent);
|
|
1977
|
+
}
|
|
1978
|
+
.qt-bg-destructive\/80 {
|
|
1979
|
+
background-color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
1980
|
+
}
|
|
1981
|
+
.qt-bg-info\/15 {
|
|
1982
|
+
background-color: color-mix(in srgb, var(--color-info) 15%, transparent);
|
|
1983
|
+
}
|
|
1984
|
+
.qt-bg-input {
|
|
1985
|
+
background-color: var(--color-input);
|
|
1986
|
+
}
|
|
1987
|
+
.qt-bg-muted-foreground\/20 {
|
|
1988
|
+
background-color: color-mix(in srgb, var(--color-muted-foreground) 20%, transparent);
|
|
1989
|
+
}
|
|
1990
|
+
.qt-bg-muted\/20 {
|
|
1991
|
+
background-color: color-mix(in srgb, var(--color-muted) 20%, transparent);
|
|
1992
|
+
}
|
|
1993
|
+
.qt-bg-muted\/30 {
|
|
1994
|
+
background-color: color-mix(in srgb, var(--color-muted) 30%, transparent);
|
|
1995
|
+
}
|
|
1996
|
+
.qt-bg-muted\/40 {
|
|
1997
|
+
background-color: color-mix(in srgb, var(--color-muted) 40%, transparent);
|
|
1998
|
+
}
|
|
1999
|
+
.qt-bg-muted\/50 {
|
|
2000
|
+
background-color: color-mix(in srgb, var(--color-muted) 50%, transparent);
|
|
2001
|
+
}
|
|
2002
|
+
.qt-bg-muted\/60 {
|
|
2003
|
+
background-color: color-mix(in srgb, var(--color-muted) 60%, transparent);
|
|
2004
|
+
}
|
|
2005
|
+
.qt-bg-muted\/70 {
|
|
2006
|
+
background-color: color-mix(in srgb, var(--color-muted) 70%, transparent);
|
|
2007
|
+
}
|
|
2008
|
+
.qt-bg-muted\/80 {
|
|
2009
|
+
background-color: color-mix(in srgb, var(--color-muted) 80%, transparent);
|
|
2010
|
+
}
|
|
2011
|
+
.qt-bg-primary\/15 {
|
|
2012
|
+
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
|
2013
|
+
}
|
|
2014
|
+
.qt-bg-primary\/30 {
|
|
2015
|
+
background-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2016
|
+
}
|
|
2017
|
+
.qt-bg-secondary\/50 {
|
|
2018
|
+
background-color: color-mix(in srgb, var(--color-secondary) 50%, transparent);
|
|
2019
|
+
}
|
|
2020
|
+
.qt-bg-success\/15 {
|
|
2021
|
+
background-color: color-mix(in srgb, var(--color-success) 15%, transparent);
|
|
2022
|
+
}
|
|
2023
|
+
.qt-bg-warning\/15 {
|
|
2024
|
+
background-color: color-mix(in srgb, var(--color-warning) 15%, transparent);
|
|
2025
|
+
}
|
|
2026
|
+
.qt-border-accent {
|
|
2027
|
+
border-color: var(--color-accent);
|
|
2028
|
+
}
|
|
2029
|
+
.qt-border-default\/50 {
|
|
2030
|
+
border-color: color-mix(in srgb, var(--color-border) 50%, transparent);
|
|
2031
|
+
}
|
|
2032
|
+
.qt-border-default\/60 {
|
|
2033
|
+
border-color: color-mix(in srgb, var(--color-border) 60%, transparent);
|
|
2034
|
+
}
|
|
2035
|
+
.qt-border-default\/70 {
|
|
2036
|
+
border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
2037
|
+
}
|
|
2038
|
+
.qt-border-destructive\/20 {
|
|
2039
|
+
border-color: color-mix(in srgb, var(--color-destructive) 20%, transparent);
|
|
2040
|
+
}
|
|
2041
|
+
.qt-border-destructive\/40 {
|
|
2042
|
+
border-color: color-mix(in srgb, var(--color-destructive) 40%, transparent);
|
|
2043
|
+
}
|
|
2044
|
+
.qt-border-destructive\/50 {
|
|
2045
|
+
border-color: color-mix(in srgb, var(--color-destructive) 50%, transparent);
|
|
2046
|
+
}
|
|
2047
|
+
.qt-border-primary-foreground {
|
|
2048
|
+
border-color: var(--color-primary-foreground);
|
|
2049
|
+
}
|
|
2050
|
+
.qt-border-primary\/20 {
|
|
2051
|
+
border-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2052
|
+
}
|
|
2053
|
+
.qt-border-primary\/30 {
|
|
2054
|
+
border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2055
|
+
}
|
|
2056
|
+
.qt-border-primary\/40 {
|
|
2057
|
+
border-color: color-mix(in srgb, var(--color-primary) 40%, transparent);
|
|
2058
|
+
}
|
|
2059
|
+
.qt-border-primary\/50 {
|
|
2060
|
+
border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
|
|
2061
|
+
}
|
|
2062
|
+
.qt-border-primary\/60 {
|
|
2063
|
+
border-color: color-mix(in srgb, var(--color-primary) 60%, transparent);
|
|
2064
|
+
}
|
|
2065
|
+
.qt-border-success\/50 {
|
|
2066
|
+
border-color: color-mix(in srgb, var(--color-success) 50%, transparent);
|
|
2067
|
+
}
|
|
2068
|
+
.qt-border-warning\/50 {
|
|
2069
|
+
border-color: color-mix(in srgb, var(--color-warning) 50%, transparent);
|
|
2070
|
+
}
|
|
2071
|
+
.qt-text-destructive\/80 {
|
|
2072
|
+
color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
2073
|
+
}
|
|
2074
|
+
.qt-text-info\/80 {
|
|
2075
|
+
color: color-mix(in srgb, var(--color-info) 80%, transparent);
|
|
2076
|
+
}
|
|
2077
|
+
.qt-text-secondary\/50 {
|
|
2078
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 50%, transparent);
|
|
2079
|
+
}
|
|
2080
|
+
.qt-text-secondary\/60 {
|
|
2081
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 60%, transparent);
|
|
2082
|
+
}
|
|
2083
|
+
.qt-text-secondary\/70 {
|
|
2084
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 70%, transparent);
|
|
2085
|
+
}
|
|
2086
|
+
.qt-text-secondary\/80 {
|
|
2087
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 80%, transparent);
|
|
2088
|
+
}
|
|
2089
|
+
.qt-text-success\/80 {
|
|
2090
|
+
color: color-mix(in srgb, var(--color-success) 80%, transparent);
|
|
2091
|
+
}
|
|
2092
|
+
.qt-text-warning\/80 {
|
|
2093
|
+
color: color-mix(in srgb, var(--color-warning) 80%, transparent);
|
|
2094
|
+
}
|
|
1951
2095
|
.qt-hover-accent {
|
|
1952
2096
|
transition: background-color 0.15s ease, color 0.15s ease;
|
|
1953
2097
|
}
|
|
@@ -2078,6 +2222,123 @@ body {
|
|
|
2078
2222
|
.hover\:qt-bg-primary\/10:hover {
|
|
2079
2223
|
background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
|
|
2080
2224
|
}
|
|
2225
|
+
.hover\:qt-text-on-accent:hover {
|
|
2226
|
+
color: var(--color-accent-foreground);
|
|
2227
|
+
}
|
|
2228
|
+
.hover\:qt-text-on-primary:hover {
|
|
2229
|
+
color: var(--color-primary-foreground);
|
|
2230
|
+
}
|
|
2231
|
+
.hover\:qt-text-on-success:hover {
|
|
2232
|
+
color: var(--color-success-foreground);
|
|
2233
|
+
}
|
|
2234
|
+
.hover\:qt-text-on-destructive:hover {
|
|
2235
|
+
color: var(--color-destructive-foreground);
|
|
2236
|
+
}
|
|
2237
|
+
.hover\:qt-bg-surface-hover:hover {
|
|
2238
|
+
background-color: var(--color-muted);
|
|
2239
|
+
}
|
|
2240
|
+
.hover\:qt-bg-muted:hover {
|
|
2241
|
+
background-color: var(--color-muted);
|
|
2242
|
+
}
|
|
2243
|
+
.hover\:qt-bg-muted\/30:hover {
|
|
2244
|
+
background-color: color-mix(in srgb, var(--color-muted) 30%, transparent);
|
|
2245
|
+
}
|
|
2246
|
+
.hover\:qt-bg-muted\/40:hover {
|
|
2247
|
+
background-color: color-mix(in srgb, var(--color-muted) 40%, transparent);
|
|
2248
|
+
}
|
|
2249
|
+
.hover\:qt-bg-muted\/50:hover {
|
|
2250
|
+
background-color: color-mix(in srgb, var(--color-muted) 50%, transparent);
|
|
2251
|
+
}
|
|
2252
|
+
.hover\:qt-bg-muted\/80:hover {
|
|
2253
|
+
background-color: color-mix(in srgb, var(--color-muted) 80%, transparent);
|
|
2254
|
+
}
|
|
2255
|
+
.hover\:qt-bg-primary\/5:hover {
|
|
2256
|
+
background-color: color-mix(in srgb, var(--color-primary) 5%, transparent);
|
|
2257
|
+
}
|
|
2258
|
+
.hover\:qt-bg-primary\/15:hover {
|
|
2259
|
+
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
|
2260
|
+
}
|
|
2261
|
+
.hover\:qt-bg-primary\/20:hover {
|
|
2262
|
+
background-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2263
|
+
}
|
|
2264
|
+
.hover\:qt-bg-primary\/90:hover {
|
|
2265
|
+
background-color: color-mix(in srgb, var(--color-primary) 90%, transparent);
|
|
2266
|
+
}
|
|
2267
|
+
.hover\:qt-bg-destructive:hover {
|
|
2268
|
+
background-color: var(--color-destructive);
|
|
2269
|
+
}
|
|
2270
|
+
.hover\:qt-bg-destructive\/20:hover {
|
|
2271
|
+
background-color: color-mix(in srgb, var(--color-destructive) 20%, transparent);
|
|
2272
|
+
}
|
|
2273
|
+
.hover\:qt-bg-destructive\/90:hover {
|
|
2274
|
+
background-color: color-mix(in srgb, var(--color-destructive) 90%, transparent);
|
|
2275
|
+
}
|
|
2276
|
+
.hover\:qt-bg-success\/20:hover {
|
|
2277
|
+
background-color: color-mix(in srgb, var(--color-success) 20%, transparent);
|
|
2278
|
+
}
|
|
2279
|
+
.hover\:qt-bg-success\/90:hover {
|
|
2280
|
+
background-color: color-mix(in srgb, var(--color-success) 90%, transparent);
|
|
2281
|
+
}
|
|
2282
|
+
.hover\:qt-bg-warning\/20:hover {
|
|
2283
|
+
background-color: color-mix(in srgb, var(--color-warning) 20%, transparent);
|
|
2284
|
+
}
|
|
2285
|
+
.hover\:qt-bg-info\/20:hover {
|
|
2286
|
+
background-color: color-mix(in srgb, var(--color-info) 20%, transparent);
|
|
2287
|
+
}
|
|
2288
|
+
.hover\:qt-text-destructive:hover {
|
|
2289
|
+
color: var(--color-destructive);
|
|
2290
|
+
}
|
|
2291
|
+
.hover\:qt-text-destructive\/80:hover {
|
|
2292
|
+
color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
2293
|
+
}
|
|
2294
|
+
.hover\:qt-text-warning\/80:hover {
|
|
2295
|
+
color: color-mix(in srgb, var(--color-warning) 80%, transparent);
|
|
2296
|
+
}
|
|
2297
|
+
.hover\:qt-text-info\/80:hover {
|
|
2298
|
+
color: color-mix(in srgb, var(--color-info) 80%, transparent);
|
|
2299
|
+
}
|
|
2300
|
+
.hover\:qt-text-primary:hover {
|
|
2301
|
+
color: var(--qt-text-primary-fg, var(--color-foreground));
|
|
2302
|
+
}
|
|
2303
|
+
.hover\:qt-border-primary:hover {
|
|
2304
|
+
border-color: var(--color-primary);
|
|
2305
|
+
}
|
|
2306
|
+
.hover\:qt-border-primary\/50:hover {
|
|
2307
|
+
border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
|
|
2308
|
+
}
|
|
2309
|
+
.hover\:qt-border-primary\/60:hover {
|
|
2310
|
+
border-color: color-mix(in srgb, var(--color-primary) 60%, transparent);
|
|
2311
|
+
}
|
|
2312
|
+
.hover\:qt-border-accent:hover {
|
|
2313
|
+
border-color: var(--color-accent);
|
|
2314
|
+
}
|
|
2315
|
+
.focus\:qt-border-primary:focus {
|
|
2316
|
+
border-color: var(--color-primary);
|
|
2317
|
+
}
|
|
2318
|
+
.disabled\:qt-bg-muted:disabled {
|
|
2319
|
+
background-color: var(--color-muted);
|
|
2320
|
+
}
|
|
2321
|
+
.disabled\:qt-text-secondary:disabled {
|
|
2322
|
+
color: var(--color-muted-foreground);
|
|
2323
|
+
}
|
|
2324
|
+
.placeholder\:qt-text-secondary::-moz-placeholder {
|
|
2325
|
+
color: var(--color-muted-foreground);
|
|
2326
|
+
}
|
|
2327
|
+
.placeholder\:qt-text-secondary::placeholder {
|
|
2328
|
+
color: var(--color-muted-foreground);
|
|
2329
|
+
}
|
|
2330
|
+
.file\:qt-bg-primary\/20::file-selector-button {
|
|
2331
|
+
background-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2332
|
+
}
|
|
2333
|
+
.hover\:file\:qt-bg-primary\/30:hover::file-selector-button {
|
|
2334
|
+
background-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2335
|
+
}
|
|
2336
|
+
.hover\:qt-shadow-md:hover {
|
|
2337
|
+
box-shadow: var(--qt-card-shadow-hover, 0 4px 12px hsl(225 18% 10% / 0.1), 0 2px 4px hsl(225 18% 10% / 0.05));
|
|
2338
|
+
}
|
|
2339
|
+
.group\/thumb:hover .group-hover\/thumb\:qt-bg-overlay-light {
|
|
2340
|
+
background-color: var(--qt-overlay-light-bg, rgb(0 0 0 / 0.2));
|
|
2341
|
+
}
|
|
2081
2342
|
.qt-bg-overlay {
|
|
2082
2343
|
background-color: var(--qt-overlay-bg, rgb(0 0 0 / 0.85));
|
|
2083
2344
|
}
|
package/dist/index.js
CHANGED
|
@@ -1153,6 +1153,11 @@ var note = {
|
|
|
1153
1153
|
};
|
|
1154
1154
|
var Surfaces = () => {
|
|
1155
1155
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { padding: "1.5rem" }, children: [
|
|
1156
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: `
|
|
1157
|
+
.surfaces-demo-fill-primary:hover { background-color: var(--color-primary); }
|
|
1158
|
+
.surfaces-demo-fill-success:hover { background-color: var(--color-success); }
|
|
1159
|
+
.surfaces-demo-fill-destructive:hover { background-color: var(--color-destructive); }
|
|
1160
|
+
` }),
|
|
1156
1161
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { style: { fontSize: "1.5rem", fontWeight: 700, marginBottom: "0.5rem" }, children: "Surfaces" }),
|
|
1157
1162
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { style: { ...note, maxWidth: "44rem" }, children: [
|
|
1158
1163
|
"How accent-coloured surfaces stay legible no matter how bold a theme makes its ",
|
|
@@ -1189,6 +1194,53 @@ var Surfaces = () => {
|
|
|
1189
1194
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("kbd", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.125rem 0.375rem", borderRadius: "0.25rem", fontSize: "0.75rem" }, children: "\u21B5" })
|
|
1190
1195
|
] })
|
|
1191
1196
|
] }),
|
|
1197
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
1198
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h3", { style: sectionHeading2, children: [
|
|
1199
|
+
"Foregrounds on filled surfaces \u2014 the ",
|
|
1200
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-text-on-*" }),
|
|
1201
|
+
" family"
|
|
1202
|
+
] }),
|
|
1203
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { style: note, children: [
|
|
1204
|
+
"The same contract, extended to every filled surface the app paints:",
|
|
1205
|
+
" ",
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-text-on-accent" }),
|
|
1207
|
+
", ",
|
|
1208
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-text-on-primary" }),
|
|
1209
|
+
",",
|
|
1210
|
+
" ",
|
|
1211
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-text-on-success" }),
|
|
1212
|
+
", and ",
|
|
1213
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-text-on-destructive" }),
|
|
1214
|
+
", each mapping to the theme's matching ",
|
|
1215
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "*Foreground" }),
|
|
1216
|
+
" token. Note the naming \u2014 ",
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("code", { children: [
|
|
1218
|
+
"-on-",
|
|
1219
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("em", { children: "fill" })
|
|
1220
|
+
] }),
|
|
1221
|
+
", never ",
|
|
1222
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("code", { children: [
|
|
1223
|
+
"-",
|
|
1224
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("em", { children: "fill" }),
|
|
1225
|
+
"-foreground"
|
|
1226
|
+
] }),
|
|
1227
|
+
", which is the Tailwind spelling and is not a ",
|
|
1228
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("code", { children: "qt-" }),
|
|
1229
|
+
" class at all."
|
|
1230
|
+
] }),
|
|
1231
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1232
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on accent" }),
|
|
1233
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "qt-bg-primary qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on primary" }),
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "qt-bg-success qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on success" }),
|
|
1235
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "qt-bg-destructive qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on destructive" })
|
|
1236
|
+
] }),
|
|
1237
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { style: { ...note, marginTop: "1rem" }, children: "Each has a hover partner for controls that stay quiet at rest and take the fill on hover. Tailwind generates no variants for these classes, so the hover forms are written out by hand \u2014 reach for one that was never written and it is simply inert. Hover the buttons below." }),
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1239
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-primary hover:qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-primary" }),
|
|
1240
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-success hover:qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-success" }),
|
|
1241
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-destructive hover:qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-destructive" })
|
|
1242
|
+
] })
|
|
1243
|
+
] }),
|
|
1192
1244
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
1193
1245
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("h3", { style: sectionHeading2, children: [
|
|
1194
1246
|
"Hover-highlight rows \u2014 ",
|
package/dist/index.mjs
CHANGED
package/dist/stories/index.js
CHANGED
|
@@ -1090,6 +1090,11 @@ var note = {
|
|
|
1090
1090
|
};
|
|
1091
1091
|
var Surfaces = () => {
|
|
1092
1092
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { padding: "1.5rem" }, children: [
|
|
1093
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `
|
|
1094
|
+
.surfaces-demo-fill-primary:hover { background-color: var(--color-primary); }
|
|
1095
|
+
.surfaces-demo-fill-success:hover { background-color: var(--color-success); }
|
|
1096
|
+
.surfaces-demo-fill-destructive:hover { background-color: var(--color-destructive); }
|
|
1097
|
+
` }),
|
|
1093
1098
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h2", { style: { fontSize: "1.5rem", fontWeight: 700, marginBottom: "0.5rem" }, children: "Surfaces" }),
|
|
1094
1099
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { style: { ...note, maxWidth: "44rem" }, children: [
|
|
1095
1100
|
"How accent-coloured surfaces stay legible no matter how bold a theme makes its ",
|
|
@@ -1126,6 +1131,53 @@ var Surfaces = () => {
|
|
|
1126
1131
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("kbd", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.125rem 0.375rem", borderRadius: "0.25rem", fontSize: "0.75rem" }, children: "\u21B5" })
|
|
1127
1132
|
] })
|
|
1128
1133
|
] }),
|
|
1134
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
1135
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("h3", { style: sectionHeading2, children: [
|
|
1136
|
+
"Foregrounds on filled surfaces \u2014 the ",
|
|
1137
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-text-on-*" }),
|
|
1138
|
+
" family"
|
|
1139
|
+
] }),
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { style: note, children: [
|
|
1141
|
+
"The same contract, extended to every filled surface the app paints:",
|
|
1142
|
+
" ",
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-text-on-accent" }),
|
|
1144
|
+
", ",
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-text-on-primary" }),
|
|
1146
|
+
",",
|
|
1147
|
+
" ",
|
|
1148
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-text-on-success" }),
|
|
1149
|
+
", and ",
|
|
1150
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-text-on-destructive" }),
|
|
1151
|
+
", each mapping to the theme's matching ",
|
|
1152
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "*Foreground" }),
|
|
1153
|
+
" token. Note the naming \u2014 ",
|
|
1154
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("code", { children: [
|
|
1155
|
+
"-on-",
|
|
1156
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("em", { children: "fill" })
|
|
1157
|
+
] }),
|
|
1158
|
+
", never ",
|
|
1159
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("code", { children: [
|
|
1160
|
+
"-",
|
|
1161
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("em", { children: "fill" }),
|
|
1162
|
+
"-foreground"
|
|
1163
|
+
] }),
|
|
1164
|
+
", which is the Tailwind spelling and is not a ",
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { children: "qt-" }),
|
|
1166
|
+
" class at all."
|
|
1167
|
+
] }),
|
|
1168
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1169
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "qt-bg-accent qt-text-on-accent", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on accent" }),
|
|
1170
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "qt-bg-primary qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on primary" }),
|
|
1171
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "qt-bg-success qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on success" }),
|
|
1172
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "qt-bg-destructive qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600 }, children: "on destructive" })
|
|
1173
|
+
] }),
|
|
1174
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { style: { ...note, marginTop: "1rem" }, children: "Each has a hover partner for controls that stay quiet at rest and take the fill on hover. Tailwind generates no variants for these classes, so the hover forms are written out by hand \u2014 reach for one that was never written and it is simply inert. Hover the buttons below." }),
|
|
1175
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: { display: "flex", flexWrap: "wrap", gap: "0.75rem", alignItems: "center" }, children: [
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-primary hover:qt-text-on-primary", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-primary" }),
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-success hover:qt-text-on-success", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-success" }),
|
|
1178
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { className: "qt-bg-card qt-text-secondary surfaces-demo-fill-destructive hover:qt-text-on-destructive", style: { padding: "0.25rem 0.625rem", borderRadius: "0.375rem", fontSize: "0.8125rem", fontWeight: 600, border: "1px solid var(--color-border)", cursor: "pointer" }, children: "hover:qt-text-on-destructive" })
|
|
1179
|
+
] })
|
|
1180
|
+
] }),
|
|
1129
1181
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("section", { style: { marginBottom: "2rem" }, children: [
|
|
1130
1182
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("h3", { style: sectionHeading2, children: [
|
|
1131
1183
|
"Hover-highlight rows \u2014 ",
|
package/dist/stories/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quilltap/theme-storybook",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.63",
|
|
4
4
|
"description": "Storybook preset and stories for developing Quilltap theme plugins",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"license": "MIT",
|
|
66
66
|
"repository": {
|
|
67
67
|
"type": "git",
|
|
68
|
-
"url": "https://github.com/foundry-9/quilltap-server.git",
|
|
68
|
+
"url": "git+https://github.com/foundry-9/quilltap-server.git",
|
|
69
69
|
"directory": "packages/theme-storybook"
|
|
70
70
|
},
|
|
71
71
|
"homepage": "https://github.com/foundry-9/quilltap-server/tree/main/packages/theme-storybook#readme",
|
|
@@ -2354,10 +2354,216 @@
|
|
|
2354
2354
|
background-color: var(--color-muted-foreground);
|
|
2355
2355
|
}
|
|
2356
2356
|
|
|
2357
|
+
/* Foregrounds intended for use ON a filled surface — the paired counterparts of
|
|
2358
|
+
the accent/primary/success/destructive fills. Each maps to the token a theme
|
|
2359
|
+
defines for text sitting on that fill, so a badge or a solid button keeps its
|
|
2360
|
+
contrast on every theme instead of inheriting whatever colour the surrounding
|
|
2361
|
+
page happens to be using.
|
|
2362
|
+
|
|
2363
|
+
<span class="qt-bg-accent qt-text-on-accent">…</span>
|
|
2364
|
+
<button class="qt-bg-destructive qt-text-on-destructive">…</button>
|
|
2365
|
+
|
|
2366
|
+
Mind the naming: these are `-on-<fill>`, never `-<fill>-foreground`. */
|
|
2357
2367
|
.qt-text-on-accent {
|
|
2358
2368
|
color: var(--color-accent-foreground);
|
|
2359
2369
|
}
|
|
2360
2370
|
|
|
2371
|
+
.qt-text-on-primary {
|
|
2372
|
+
color: var(--color-primary-foreground);
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
.qt-text-on-success {
|
|
2376
|
+
color: var(--color-success-foreground);
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
.qt-text-on-destructive {
|
|
2380
|
+
color: var(--color-destructive-foreground);
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
/* The remaining opacity steps and surface colours of the utility families. A
|
|
2384
|
+
theme that overrides --color-muted or --color-border gets all of these for
|
|
2385
|
+
free; they exist so that the app never has to reach for a raw Tailwind
|
|
2386
|
+
colour on a themed surface. */
|
|
2387
|
+
.qt-bg-card\/50 {
|
|
2388
|
+
background-color: color-mix(in srgb, var(--color-card) 50%, transparent);
|
|
2389
|
+
}
|
|
2390
|
+
|
|
2391
|
+
.qt-bg-card\/60 {
|
|
2392
|
+
background-color: color-mix(in srgb, var(--color-card) 60%, transparent);
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
.qt-bg-card\/80 {
|
|
2396
|
+
background-color: color-mix(in srgb, var(--color-card) 80%, transparent);
|
|
2397
|
+
}
|
|
2398
|
+
|
|
2399
|
+
.qt-bg-card\/90 {
|
|
2400
|
+
background-color: color-mix(in srgb, var(--color-card) 90%, transparent);
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
.qt-bg-default {
|
|
2404
|
+
background-color: var(--color-background);
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
.qt-bg-destructive\/15 {
|
|
2408
|
+
background-color: color-mix(in srgb, var(--color-destructive) 15%, transparent);
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
.qt-bg-destructive\/80 {
|
|
2412
|
+
background-color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
.qt-bg-info\/15 {
|
|
2416
|
+
background-color: color-mix(in srgb, var(--color-info) 15%, transparent);
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
.qt-bg-input {
|
|
2420
|
+
background-color: var(--color-input);
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
.qt-bg-muted-foreground\/20 {
|
|
2424
|
+
background-color: color-mix(in srgb, var(--color-muted-foreground) 20%, transparent);
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
.qt-bg-muted\/20 {
|
|
2428
|
+
background-color: color-mix(in srgb, var(--color-muted) 20%, transparent);
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
.qt-bg-muted\/30 {
|
|
2432
|
+
background-color: color-mix(in srgb, var(--color-muted) 30%, transparent);
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
.qt-bg-muted\/40 {
|
|
2436
|
+
background-color: color-mix(in srgb, var(--color-muted) 40%, transparent);
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
.qt-bg-muted\/50 {
|
|
2440
|
+
background-color: color-mix(in srgb, var(--color-muted) 50%, transparent);
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
.qt-bg-muted\/60 {
|
|
2444
|
+
background-color: color-mix(in srgb, var(--color-muted) 60%, transparent);
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
.qt-bg-muted\/70 {
|
|
2448
|
+
background-color: color-mix(in srgb, var(--color-muted) 70%, transparent);
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
.qt-bg-muted\/80 {
|
|
2452
|
+
background-color: color-mix(in srgb, var(--color-muted) 80%, transparent);
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
.qt-bg-primary\/15 {
|
|
2456
|
+
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
.qt-bg-primary\/30 {
|
|
2460
|
+
background-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
.qt-bg-secondary\/50 {
|
|
2464
|
+
background-color: color-mix(in srgb, var(--color-secondary) 50%, transparent);
|
|
2465
|
+
}
|
|
2466
|
+
|
|
2467
|
+
.qt-bg-success\/15 {
|
|
2468
|
+
background-color: color-mix(in srgb, var(--color-success) 15%, transparent);
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
.qt-bg-warning\/15 {
|
|
2472
|
+
background-color: color-mix(in srgb, var(--color-warning) 15%, transparent);
|
|
2473
|
+
}
|
|
2474
|
+
|
|
2475
|
+
.qt-border-accent {
|
|
2476
|
+
border-color: var(--color-accent);
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
.qt-border-default\/50 {
|
|
2480
|
+
border-color: color-mix(in srgb, var(--color-border) 50%, transparent);
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
.qt-border-default\/60 {
|
|
2484
|
+
border-color: color-mix(in srgb, var(--color-border) 60%, transparent);
|
|
2485
|
+
}
|
|
2486
|
+
|
|
2487
|
+
.qt-border-default\/70 {
|
|
2488
|
+
border-color: color-mix(in srgb, var(--color-border) 70%, transparent);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
.qt-border-destructive\/20 {
|
|
2492
|
+
border-color: color-mix(in srgb, var(--color-destructive) 20%, transparent);
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
.qt-border-destructive\/40 {
|
|
2496
|
+
border-color: color-mix(in srgb, var(--color-destructive) 40%, transparent);
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
.qt-border-destructive\/50 {
|
|
2500
|
+
border-color: color-mix(in srgb, var(--color-destructive) 50%, transparent);
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
.qt-border-primary-foreground {
|
|
2504
|
+
border-color: var(--color-primary-foreground);
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
.qt-border-primary\/20 {
|
|
2508
|
+
border-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
.qt-border-primary\/30 {
|
|
2512
|
+
border-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
.qt-border-primary\/40 {
|
|
2516
|
+
border-color: color-mix(in srgb, var(--color-primary) 40%, transparent);
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
.qt-border-primary\/50 {
|
|
2520
|
+
border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
.qt-border-primary\/60 {
|
|
2524
|
+
border-color: color-mix(in srgb, var(--color-primary) 60%, transparent);
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
.qt-border-success\/50 {
|
|
2528
|
+
border-color: color-mix(in srgb, var(--color-success) 50%, transparent);
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
.qt-border-warning\/50 {
|
|
2532
|
+
border-color: color-mix(in srgb, var(--color-warning) 50%, transparent);
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
.qt-text-destructive\/80 {
|
|
2536
|
+
color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
.qt-text-info\/80 {
|
|
2540
|
+
color: color-mix(in srgb, var(--color-info) 80%, transparent);
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
.qt-text-secondary\/50 {
|
|
2544
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 50%, transparent);
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
.qt-text-secondary\/60 {
|
|
2548
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 60%, transparent);
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
.qt-text-secondary\/70 {
|
|
2552
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 70%, transparent);
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
.qt-text-secondary\/80 {
|
|
2556
|
+
color: color-mix(in srgb, var(--color-muted-foreground) 80%, transparent);
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
.qt-text-success\/80 {
|
|
2560
|
+
color: color-mix(in srgb, var(--color-success) 80%, transparent);
|
|
2561
|
+
}
|
|
2562
|
+
|
|
2563
|
+
.qt-text-warning\/80 {
|
|
2564
|
+
color: color-mix(in srgb, var(--color-warning) 80%, transparent);
|
|
2565
|
+
}
|
|
2566
|
+
|
|
2361
2567
|
/* Hoverable accent surface — list rows, menu items, and option cards that
|
|
2362
2568
|
should highlight on hover. On hover it paints the accent background AND
|
|
2363
2569
|
forces the accent foreground onto the row and every descendant, so the whole
|
|
@@ -2549,6 +2755,167 @@
|
|
|
2549
2755
|
background-color: color-mix(in srgb, var(--color-primary) 10%, transparent);
|
|
2550
2756
|
}
|
|
2551
2757
|
|
|
2758
|
+
/* Hover foregrounds for filled surfaces — the hover partners of the
|
|
2759
|
+
qt-text-on-* family, for controls that sit quiet at rest and take a filled
|
|
2760
|
+
background on hover (`qt-text-secondary hover:qt-bg-success
|
|
2761
|
+
hover:qt-text-on-success`). */
|
|
2762
|
+
.hover\:qt-text-on-accent:hover {
|
|
2763
|
+
color: var(--color-accent-foreground);
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
.hover\:qt-text-on-primary:hover {
|
|
2767
|
+
color: var(--color-primary-foreground);
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
.hover\:qt-text-on-success:hover {
|
|
2771
|
+
color: var(--color-success-foreground);
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
.hover\:qt-text-on-destructive:hover {
|
|
2775
|
+
color: var(--color-destructive-foreground);
|
|
2776
|
+
}
|
|
2777
|
+
|
|
2778
|
+
/* State forms of the utilities above. Tailwind generates variants only for
|
|
2779
|
+
utilities it knows about, and a class declared in @layer utilities is
|
|
2780
|
+
invisible to it — so in the app every one of these is hand-written, escaped,
|
|
2781
|
+
with its own pseudo-selector, and an unwritten one is inert. Mirrored here so
|
|
2782
|
+
a theme author previewing hover states sees what the app actually ships. */
|
|
2783
|
+
.hover\:qt-bg-surface-hover:hover {
|
|
2784
|
+
background-color: var(--color-muted);
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
.hover\:qt-bg-muted:hover {
|
|
2788
|
+
background-color: var(--color-muted);
|
|
2789
|
+
}
|
|
2790
|
+
|
|
2791
|
+
.hover\:qt-bg-muted\/30:hover {
|
|
2792
|
+
background-color: color-mix(in srgb, var(--color-muted) 30%, transparent);
|
|
2793
|
+
}
|
|
2794
|
+
|
|
2795
|
+
.hover\:qt-bg-muted\/40:hover {
|
|
2796
|
+
background-color: color-mix(in srgb, var(--color-muted) 40%, transparent);
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2799
|
+
.hover\:qt-bg-muted\/50:hover {
|
|
2800
|
+
background-color: color-mix(in srgb, var(--color-muted) 50%, transparent);
|
|
2801
|
+
}
|
|
2802
|
+
|
|
2803
|
+
.hover\:qt-bg-muted\/80:hover {
|
|
2804
|
+
background-color: color-mix(in srgb, var(--color-muted) 80%, transparent);
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
.hover\:qt-bg-primary\/5:hover {
|
|
2808
|
+
background-color: color-mix(in srgb, var(--color-primary) 5%, transparent);
|
|
2809
|
+
}
|
|
2810
|
+
|
|
2811
|
+
.hover\:qt-bg-primary\/15:hover {
|
|
2812
|
+
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
.hover\:qt-bg-primary\/20:hover {
|
|
2816
|
+
background-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2817
|
+
}
|
|
2818
|
+
|
|
2819
|
+
.hover\:qt-bg-primary\/90:hover {
|
|
2820
|
+
background-color: color-mix(in srgb, var(--color-primary) 90%, transparent);
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
.hover\:qt-bg-destructive:hover {
|
|
2824
|
+
background-color: var(--color-destructive);
|
|
2825
|
+
}
|
|
2826
|
+
|
|
2827
|
+
.hover\:qt-bg-destructive\/20:hover {
|
|
2828
|
+
background-color: color-mix(in srgb, var(--color-destructive) 20%, transparent);
|
|
2829
|
+
}
|
|
2830
|
+
|
|
2831
|
+
.hover\:qt-bg-destructive\/90:hover {
|
|
2832
|
+
background-color: color-mix(in srgb, var(--color-destructive) 90%, transparent);
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
.hover\:qt-bg-success\/20:hover {
|
|
2836
|
+
background-color: color-mix(in srgb, var(--color-success) 20%, transparent);
|
|
2837
|
+
}
|
|
2838
|
+
|
|
2839
|
+
.hover\:qt-bg-success\/90:hover {
|
|
2840
|
+
background-color: color-mix(in srgb, var(--color-success) 90%, transparent);
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
.hover\:qt-bg-warning\/20:hover {
|
|
2844
|
+
background-color: color-mix(in srgb, var(--color-warning) 20%, transparent);
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
.hover\:qt-bg-info\/20:hover {
|
|
2848
|
+
background-color: color-mix(in srgb, var(--color-info) 20%, transparent);
|
|
2849
|
+
}
|
|
2850
|
+
|
|
2851
|
+
.hover\:qt-text-destructive:hover {
|
|
2852
|
+
color: var(--color-destructive);
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2855
|
+
.hover\:qt-text-destructive\/80:hover {
|
|
2856
|
+
color: color-mix(in srgb, var(--color-destructive) 80%, transparent);
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
.hover\:qt-text-warning\/80:hover {
|
|
2860
|
+
color: color-mix(in srgb, var(--color-warning) 80%, transparent);
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
.hover\:qt-text-info\/80:hover {
|
|
2864
|
+
color: color-mix(in srgb, var(--color-info) 80%, transparent);
|
|
2865
|
+
}
|
|
2866
|
+
|
|
2867
|
+
.hover\:qt-text-primary:hover {
|
|
2868
|
+
color: var(--qt-text-primary-fg, var(--color-foreground));
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
.hover\:qt-border-primary:hover {
|
|
2872
|
+
border-color: var(--color-primary);
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
.hover\:qt-border-primary\/50:hover {
|
|
2876
|
+
border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
.hover\:qt-border-primary\/60:hover {
|
|
2880
|
+
border-color: color-mix(in srgb, var(--color-primary) 60%, transparent);
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
.hover\:qt-border-accent:hover {
|
|
2884
|
+
border-color: var(--color-accent);
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
.focus\:qt-border-primary:focus {
|
|
2888
|
+
border-color: var(--color-primary);
|
|
2889
|
+
}
|
|
2890
|
+
|
|
2891
|
+
.disabled\:qt-bg-muted:disabled {
|
|
2892
|
+
background-color: var(--color-muted);
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
.disabled\:qt-text-secondary:disabled {
|
|
2896
|
+
color: var(--color-muted-foreground);
|
|
2897
|
+
}
|
|
2898
|
+
|
|
2899
|
+
.placeholder\:qt-text-secondary::placeholder {
|
|
2900
|
+
color: var(--color-muted-foreground);
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
.file\:qt-bg-primary\/20::file-selector-button {
|
|
2904
|
+
background-color: color-mix(in srgb, var(--color-primary) 20%, transparent);
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
.hover\:file\:qt-bg-primary\/30:hover::file-selector-button {
|
|
2908
|
+
background-color: color-mix(in srgb, var(--color-primary) 30%, transparent);
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
.hover\:qt-shadow-md:hover {
|
|
2912
|
+
box-shadow: var(--qt-card-shadow-hover, 0 4px 12px hsl(225 18% 10% / 0.1), 0 2px 4px hsl(225 18% 10% / 0.05));
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2915
|
+
.group\/thumb:hover .group-hover\/thumb\:qt-bg-overlay-light {
|
|
2916
|
+
background-color: var(--qt-overlay-light-bg, rgb(0 0 0 / 0.2));
|
|
2917
|
+
}
|
|
2918
|
+
|
|
2552
2919
|
/* ==========================================================================
|
|
2553
2920
|
OVERLAY UTILITIES
|
|
2554
2921
|
For image modals, lightboxes, and overlay UI elements.
|
|
@@ -27,6 +27,14 @@ const note: React.CSSProperties = {
|
|
|
27
27
|
export const Surfaces: React.FC = () => {
|
|
28
28
|
return (
|
|
29
29
|
<div style={{ padding: '1.5rem' }}>
|
|
30
|
+
{/* Story-local: the app pairs the hover foregrounds with Tailwind's
|
|
31
|
+
hover:bg-* fills, which don't exist here. Demo fills only — these are
|
|
32
|
+
not qt-* utilities and must not be copied into an app or a theme. */}
|
|
33
|
+
<style>{`
|
|
34
|
+
.surfaces-demo-fill-primary:hover { background-color: var(--color-primary); }
|
|
35
|
+
.surfaces-demo-fill-success:hover { background-color: var(--color-success); }
|
|
36
|
+
.surfaces-demo-fill-destructive:hover { background-color: var(--color-destructive); }
|
|
37
|
+
`}</style>
|
|
30
38
|
<h2 style={{ fontSize: '1.5rem', fontWeight: 700, marginBottom: '0.5rem' }}>Surfaces</h2>
|
|
31
39
|
<p style={{ ...note, maxWidth: '44rem' }}>
|
|
32
40
|
How accent-coloured surfaces stay legible no matter how bold a theme makes
|
|
@@ -57,6 +65,50 @@ export const Surfaces: React.FC = () => {
|
|
|
57
65
|
</div>
|
|
58
66
|
</section>
|
|
59
67
|
|
|
68
|
+
{/* Foregrounds on filled surfaces */}
|
|
69
|
+
<section style={{ marginBottom: '2rem' }}>
|
|
70
|
+
<h3 style={sectionHeading}>Foregrounds on filled surfaces — the <code>qt-text-on-*</code> family</h3>
|
|
71
|
+
<p style={note}>
|
|
72
|
+
The same contract, extended to every filled surface the app paints:{' '}
|
|
73
|
+
<code>qt-text-on-accent</code>, <code>qt-text-on-primary</code>,{' '}
|
|
74
|
+
<code>qt-text-on-success</code>, and <code>qt-text-on-destructive</code>, each
|
|
75
|
+
mapping to the theme's matching <code>*Foreground</code> token. Note the
|
|
76
|
+
naming — <code>-on-<em>fill</em></code>, never <code>-<em>fill</em>-foreground</code>,
|
|
77
|
+
which is the Tailwind spelling and is not a <code>qt-</code> class at all.
|
|
78
|
+
</p>
|
|
79
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem', alignItems: 'center' }}>
|
|
80
|
+
<span className="qt-bg-accent qt-text-on-accent" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600 }}>
|
|
81
|
+
on accent
|
|
82
|
+
</span>
|
|
83
|
+
<span className="qt-bg-primary qt-text-on-primary" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600 }}>
|
|
84
|
+
on primary
|
|
85
|
+
</span>
|
|
86
|
+
<span className="qt-bg-success qt-text-on-success" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600 }}>
|
|
87
|
+
on success
|
|
88
|
+
</span>
|
|
89
|
+
<span className="qt-bg-destructive qt-text-on-destructive" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600 }}>
|
|
90
|
+
on destructive
|
|
91
|
+
</span>
|
|
92
|
+
</div>
|
|
93
|
+
<p style={{ ...note, marginTop: '1rem' }}>
|
|
94
|
+
Each has a hover partner for controls that stay quiet at rest and take the fill
|
|
95
|
+
on hover. Tailwind generates no variants for these classes, so the hover forms
|
|
96
|
+
are written out by hand — reach for one that was never written and it is simply
|
|
97
|
+
inert. Hover the buttons below.
|
|
98
|
+
</p>
|
|
99
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.75rem', alignItems: 'center' }}>
|
|
100
|
+
<button className="qt-bg-card qt-text-secondary surfaces-demo-fill-primary hover:qt-text-on-primary" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600, border: '1px solid var(--color-border)', cursor: 'pointer' }}>
|
|
101
|
+
hover:qt-text-on-primary
|
|
102
|
+
</button>
|
|
103
|
+
<button className="qt-bg-card qt-text-secondary surfaces-demo-fill-success hover:qt-text-on-success" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600, border: '1px solid var(--color-border)', cursor: 'pointer' }}>
|
|
104
|
+
hover:qt-text-on-success
|
|
105
|
+
</button>
|
|
106
|
+
<button className="qt-bg-card qt-text-secondary surfaces-demo-fill-destructive hover:qt-text-on-destructive" style={{ padding: '0.25rem 0.625rem', borderRadius: '0.375rem', fontSize: '0.8125rem', fontWeight: 600, border: '1px solid var(--color-border)', cursor: 'pointer' }}>
|
|
107
|
+
hover:qt-text-on-destructive
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
</section>
|
|
111
|
+
|
|
60
112
|
{/* Hover-highlight rows */}
|
|
61
113
|
<section style={{ marginBottom: '2rem' }}>
|
|
62
114
|
<h3 style={sectionHeading}>Hover-highlight rows — <code>qt-hover-accent</code></h3>
|