@stealthscale/theme-ember 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # @stealthscale/theme-ember
2
+
3
+ A **library**: an app links it, and a Storybook draws it beside the other themes.
4
+
5
+ Draws a stealth product in a warm orange, packed and quick. It is the theme for an operations
6
+ console: rows matter more than whitespace, the shadows are half the base's so a screen full of
7
+ surfaces does not read as clutter, and everything moves a fifth faster because somebody working
8
+ a queue sees each animation hundreds of times a day.
9
+
10
+ ```ts
11
+ import { extendRecipe } from '@stealthscale/core-theme'
12
+ import { recipe as base } from '@stealthscale/theme-base'
13
+
14
+ export const recipe = extendRecipe(base, {
15
+ color: { primary: '#d9480f' },
16
+ effect: { depth: 0.5 },
17
+ font: {
18
+ display: { family: 'Bricolage Grotesque Variable', source: '…/bricolage-grotesque/wght.css' },
19
+ mono: { family: 'Fira Code Variable', source: '…/fira-code/wght.css' },
20
+ sans: { family: 'Jost Variable', source: '…/jost/wght.css' },
21
+ },
22
+ motion: { speed: 0.8 },
23
+ size: { density: { default: 'compact' } },
24
+ })
25
+ ```
26
+
27
+ It changes something in four of the five groups, which is what a house style of its own looks
28
+ like. `source` names the stylesheet that loads the face, resolved from this package, so the
29
+ theme brings its own font rather than naming one and hoping something else loaded it. Jost is
30
+ built on circles and sets a smaller x-height than the base's Inter, so a page reads rounder and
31
+ lighter at the same size.
32
+
33
+ `depth` and `speed` are one number each and reach every table under them: half the ink in every
34
+ box, inset, drop and text shadow, and four fifths of every duration, so the whole vocabulary
35
+ moves together rather than falling out of step.
36
+
37
+ ## Install
38
+
39
+ ```sh
40
+ bun add @stealthscale/theme-ember
41
+ ```
42
+
43
+ Link `@stealthscale/theme-ember/index.css` and nothing else.
package/dist/base.css ADDED
@@ -0,0 +1,59 @@
1
+ /* Generated by @stealthscale/core-theme. Do not edit. */
2
+ /* The mode is a class rather than an attribute, because that is what `dark:` keys off. */
3
+ @custom-variant dark (&:where(.dark, .dark *));
4
+
5
+ @layer base {
6
+ /*
7
+ * What a page is before a single component renders: the theme's surface, its text colour,
8
+ * its family. Without this the tokens exist and nothing reads them, which looks exactly
9
+ * like a theme that does not work.
10
+ */
11
+ html {
12
+ color-scheme: light dark;
13
+ }
14
+
15
+ body {
16
+ background-color: var(--background);
17
+ color: var(--foreground);
18
+ font-family: var(--font-sans);
19
+ -webkit-font-smoothing: antialiased;
20
+ }
21
+
22
+ /* A border with no colour is black, and every component assumes the token. */
23
+ *,
24
+ *::before,
25
+ *::after {
26
+ border-color: var(--border);
27
+ }
28
+
29
+ /*
30
+ * Focus is a system decision rather than a component one, and its geometry is the
31
+ * density's, so the browser's own ring and a component's agree.
32
+ */
33
+ :focus-visible {
34
+ outline: var(--focus-width) solid var(--ring);
35
+ outline-offset: var(--focus-offset);
36
+ }
37
+
38
+ /* Selected text is still text, so it takes the pair the contract guarantees. */
39
+ ::selection {
40
+ background-color: var(--selection);
41
+ color: var(--selection-foreground);
42
+ }
43
+
44
+ h1,
45
+ h2,
46
+ h3,
47
+ h4,
48
+ h5,
49
+ h6 {
50
+ font-family: var(--font-display);
51
+ }
52
+
53
+ code,
54
+ kbd,
55
+ pre,
56
+ samp {
57
+ font-family: var(--font-mono);
58
+ }
59
+ }
@@ -0,0 +1,33 @@
1
+ /* Generated by @stealthscale/core-theme. Do not edit. */
2
+ :root {
3
+ --focus-width: 2px;
4
+ --height-xs: 1.5rem;
5
+ --height-sm: 1.75rem;
6
+ --height-md: 2rem;
7
+ --height-lg: 2.25rem;
8
+ --focus-offset: 0px;
9
+ }
10
+
11
+ [data-density='comfortable'] {
12
+ --height-xs: 2rem;
13
+ --height-sm: 2.25rem;
14
+ --height-md: 2.5rem;
15
+ --height-lg: 2.75rem;
16
+ --focus-offset: 2px;
17
+ }
18
+
19
+ [data-density='compact'] {
20
+ --height-xs: 1.5rem;
21
+ --height-sm: 1.75rem;
22
+ --height-md: 2rem;
23
+ --height-lg: 2.25rem;
24
+ --focus-offset: 0px;
25
+ }
26
+
27
+ [data-density='touch'] {
28
+ --height-xs: 2.25rem;
29
+ --height-sm: 2.5rem;
30
+ --height-md: 2.75rem;
31
+ --height-lg: 3rem;
32
+ --focus-offset: 2px;
33
+ }
package/dist/fonts.css ADDED
@@ -0,0 +1,4 @@
1
+ /* Generated by @stealthscale/core-theme. Do not edit. */
2
+ @import '@fontsource-variable/jost/wght.css';
3
+ @import '@fontsource-variable/fira-code/wght.css';
4
+ @import '@fontsource-variable/bricolage-grotesque/wght.css';
package/dist/index.css ADDED
@@ -0,0 +1,7 @@
1
+ /* Generated by @stealthscale/core-theme. Do not edit. */
2
+ @import './fonts.css';
3
+ @import './tailwind.css';
4
+ @import './base.css';
5
+ @import './density.css';
6
+ @import './motion.css';
7
+ @import './tokens.css';
@@ -0,0 +1,12 @@
1
+ import { Recipe } from "@stealthscale/core-theme";
2
+ //#region src/recipe.d.ts
3
+ /**
4
+ * States a warm, dense, quick product: an operations console rather than a marketing page.
5
+ *
6
+ * It changes something in four of the five groups, which is what a theme with a house style
7
+ * of its own does: the colour, the family it reads in, how flat it draws and how fast it
8
+ * moves.
9
+ */
10
+ declare const recipe: Recipe;
11
+ //#endregion
12
+ export { recipe };
package/dist/index.mjs ADDED
@@ -0,0 +1,57 @@
1
+ import { extendRecipe } from "@stealthscale/core-theme";
2
+ import { recipe as recipe$1 } from "@stealthscale/theme-base";
3
+ //#region src/recipe.ts
4
+ /**
5
+ * @fileoverview States what makes Ember differ from the base theme, and nothing else. Every
6
+ * value it does not name is the base's, so a change to the base reaches this theme without an
7
+ * edit here.
8
+ */
9
+ /**
10
+ * States a warm, dense, quick product: an operations console rather than a marketing page.
11
+ *
12
+ * It changes something in four of the five groups, which is what a theme with a house style
13
+ * of its own does: the colour, the family it reads in, how flat it draws and how fast it
14
+ * moves.
15
+ */
16
+ const recipe = extendRecipe(recipe$1, {
17
+ color: {
18
+ dark: {
19
+ cardLift: 5,
20
+ page: 14,
21
+ popoverLift: 8
22
+ },
23
+ light: {
24
+ cardLift: 2,
25
+ page: 96,
26
+ popoverLift: 3
27
+ },
28
+ neutral: {
29
+ chroma: .014,
30
+ hue: 70
31
+ },
32
+ primary: "#d9480f",
33
+ surface: {
34
+ chroma: .02,
35
+ hue: 75
36
+ }
37
+ },
38
+ effect: { depth: .5 },
39
+ font: {
40
+ display: {
41
+ family: "Bricolage Grotesque Variable",
42
+ source: "@fontsource-variable/bricolage-grotesque/wght.css"
43
+ },
44
+ mono: {
45
+ family: "Fira Code Variable",
46
+ source: "@fontsource-variable/fira-code/wght.css"
47
+ },
48
+ sans: {
49
+ family: "Jost Variable",
50
+ source: "@fontsource-variable/jost/wght.css"
51
+ }
52
+ },
53
+ motion: { speed: .8 },
54
+ size: { density: { default: "compact" } }
55
+ });
56
+ //#endregion
57
+ export { recipe };
@@ -0,0 +1,198 @@
1
+ /* Generated by @stealthscale/core-theme. Do not edit. */
2
+
3
+ @keyframes collapse-down {
4
+ from {
5
+ height: 0;
6
+ opacity: 0;
7
+ }
8
+ to {
9
+ height: var(--collapsible-panel-height, auto);
10
+ opacity: 1;
11
+ }
12
+ }
13
+
14
+ @keyframes collapse-up {
15
+ from {
16
+ height: var(--collapsible-panel-height, auto);
17
+ opacity: 1;
18
+ }
19
+ to {
20
+ height: 0;
21
+ opacity: 0;
22
+ }
23
+ }
24
+
25
+ @keyframes fade-in {
26
+ from {
27
+ opacity: 0;
28
+ }
29
+ to {
30
+ opacity: 1;
31
+ }
32
+ }
33
+
34
+ @keyframes fade-out {
35
+ from {
36
+ opacity: 1;
37
+ }
38
+ to {
39
+ opacity: 0;
40
+ }
41
+ }
42
+
43
+ @keyframes ping {
44
+ 75%, 100% {
45
+ opacity: 0;
46
+ transform: scale(2);
47
+ }
48
+ }
49
+
50
+ @keyframes pulse {
51
+ 0%, 100% {
52
+ opacity: 1;
53
+ }
54
+ 50% {
55
+ opacity: 0.5;
56
+ }
57
+ }
58
+
59
+ @keyframes shimmer {
60
+ from {
61
+ background-position: -200% 0;
62
+ }
63
+ to {
64
+ background-position: 200% 0;
65
+ }
66
+ }
67
+
68
+ @keyframes slide-in-from-bottom {
69
+ from {
70
+ opacity: 0;
71
+ transform: translateY(8px);
72
+ }
73
+ to {
74
+ opacity: 1;
75
+ transform: translateY(0);
76
+ }
77
+ }
78
+
79
+ @keyframes slide-in-from-left {
80
+ from {
81
+ opacity: 0;
82
+ transform: translateX(-8px);
83
+ }
84
+ to {
85
+ opacity: 1;
86
+ transform: translateX(0);
87
+ }
88
+ }
89
+
90
+ @keyframes slide-in-from-right {
91
+ from {
92
+ opacity: 0;
93
+ transform: translateX(8px);
94
+ }
95
+ to {
96
+ opacity: 1;
97
+ transform: translateX(0);
98
+ }
99
+ }
100
+
101
+ @keyframes slide-in-from-top {
102
+ from {
103
+ opacity: 0;
104
+ transform: translateY(-8px);
105
+ }
106
+ to {
107
+ opacity: 1;
108
+ transform: translateY(0);
109
+ }
110
+ }
111
+
112
+ @keyframes slide-out-to-bottom {
113
+ from {
114
+ opacity: 1;
115
+ transform: translateY(0);
116
+ }
117
+ to {
118
+ opacity: 0;
119
+ transform: translateY(8px);
120
+ }
121
+ }
122
+
123
+ @keyframes slide-out-to-top {
124
+ from {
125
+ opacity: 1;
126
+ transform: translateY(0);
127
+ }
128
+ to {
129
+ opacity: 0;
130
+ transform: translateY(-8px);
131
+ }
132
+ }
133
+
134
+ @keyframes spin {
135
+ to {
136
+ transform: rotate(360deg);
137
+ }
138
+ }
139
+
140
+ @keyframes zoom-in {
141
+ from {
142
+ opacity: 0;
143
+ transform: scale(0.95);
144
+ }
145
+ to {
146
+ opacity: 1;
147
+ transform: scale(1);
148
+ }
149
+ }
150
+
151
+ @keyframes zoom-out {
152
+ from {
153
+ opacity: 1;
154
+ transform: scale(1);
155
+ }
156
+ to {
157
+ opacity: 0;
158
+ transform: scale(0.95);
159
+ }
160
+ }
161
+
162
+ @media (prefers-reduced-motion: reduce) {
163
+ :root {
164
+ --press-scale: 1 !important;
165
+ }
166
+
167
+ *,
168
+ *::before,
169
+ *::after {
170
+ animation-delay: 0s !important;
171
+ animation-duration: 0.01ms !important;
172
+ animation-iteration-count: 1 !important;
173
+ transition-delay: 0s !important;
174
+ transition-duration: 0.01ms !important;
175
+ }
176
+
177
+ [data-slot='spinner'] {
178
+ animation-duration: 2s !important;
179
+ animation-iteration-count: infinite !important;
180
+ }
181
+ }
182
+
183
+ [data-reduced-motion],
184
+ [data-reduced-motion] *,
185
+ [data-reduced-motion] *::before,
186
+ [data-reduced-motion] *::after {
187
+ --press-scale: 1 !important;
188
+ animation-delay: 0s !important;
189
+ animation-duration: 0.01ms !important;
190
+ animation-iteration-count: 1 !important;
191
+ transition-delay: 0s !important;
192
+ transition-duration: 0.01ms !important;
193
+ }
194
+
195
+ [data-reduced-motion] [data-slot='spinner'] {
196
+ animation-duration: 2s !important;
197
+ animation-iteration-count: infinite !important;
198
+ }