@frontpanel/css 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +100 -2
- package/base.css +49 -0
- package/components.css +547 -0
- package/fonts/OFL-michroma.txt +93 -0
- package/fonts/OFL-vt323.txt +93 -0
- package/fonts/michroma-latin-400.woff2 +0 -0
- package/fonts/vt323-latin-400.woff2 +0 -0
- package/fonts.css +24 -0
- package/index.css +3 -0
- package/package.json +59 -3
- package/page.css +101 -0
- package/tailwind-base.css +49 -0
- package/tailwind-page.css +101 -0
- package/tailwind.css +605 -0
- package/tokens.css +132 -0
package/components.css
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
/* Generated by scripts/build.ts from src/. Do not edit; edit the source and run `pnpm build`. */
|
|
2
|
+
@layer frontpanel {
|
|
3
|
+
/* An LCD line redrawing left to right; the fp-lcd-redraw class steps through it. */
|
|
4
|
+
@keyframes fp-lcd-redraw {
|
|
5
|
+
from {
|
|
6
|
+
clip-path: inset(0 100% 0 0);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
to {
|
|
10
|
+
clip-path: inset(0 0 0 0);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Two blinks 400 ms apart, then steady. Nothing on the device blinks for longer. */
|
|
15
|
+
@keyframes fp-blink-twice {
|
|
16
|
+
0%,
|
|
17
|
+
100% {
|
|
18
|
+
opacity: 1;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
12.5%,
|
|
22
|
+
37.5% {
|
|
23
|
+
opacity: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
25%,
|
|
27
|
+
50% {
|
|
28
|
+
opacity: 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Redraws an LCD line left to right in four steps, as when its value changes. */
|
|
33
|
+
.fp-lcd-redraw {
|
|
34
|
+
animation: fp-lcd-redraw 160ms steps(4, end);
|
|
35
|
+
|
|
36
|
+
@media (prefers-reduced-motion: reduce) {
|
|
37
|
+
animation: none;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Blinks twice, then holds: an LED confirming an action. */
|
|
42
|
+
.fp-blink-twice {
|
|
43
|
+
animation: fp-blink-twice 1.6s steps(1, end) 1;
|
|
44
|
+
|
|
45
|
+
@media (prefers-reduced-motion: reduce) {
|
|
46
|
+
animation: none;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** The page behind the device: quiet blue-grey with a faint Y2K grid. */
|
|
51
|
+
.fp-device-backdrop {
|
|
52
|
+
background-color: var(--fp-color-backdrop);
|
|
53
|
+
background-image:
|
|
54
|
+
linear-gradient(var(--fp-color-grid) 1px, transparent 1px),
|
|
55
|
+
linear-gradient(90deg, var(--fp-color-grid) 1px, transparent 1px),
|
|
56
|
+
radial-gradient(ellipse 80% 60% at 20% 0%, var(--fp-color-backdrop-hi), transparent 70%),
|
|
57
|
+
linear-gradient(180deg, var(--fp-color-backdrop-hi), var(--fp-color-backdrop));
|
|
58
|
+
background-size:
|
|
59
|
+
32px 32px,
|
|
60
|
+
32px 32px,
|
|
61
|
+
auto,
|
|
62
|
+
auto;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Liquid-chrome ring around the device body. Diagonal so the reflection band crosses the corners. */
|
|
66
|
+
.fp-device-rim {
|
|
67
|
+
border-radius: 36px;
|
|
68
|
+
padding: 10px;
|
|
69
|
+
background-image: linear-gradient(
|
|
70
|
+
160deg,
|
|
71
|
+
var(--fp-color-chrome-hi) 0%,
|
|
72
|
+
var(--fp-color-chrome-100) 14%,
|
|
73
|
+
var(--fp-color-chrome-tint) 38%,
|
|
74
|
+
var(--fp-color-chrome-500) 50%,
|
|
75
|
+
var(--fp-color-chrome-300) 70%,
|
|
76
|
+
var(--fp-color-chrome-100) 100%
|
|
77
|
+
);
|
|
78
|
+
box-shadow:
|
|
79
|
+
0 0 0 1px var(--fp-color-chrome-800),
|
|
80
|
+
inset 0 1px 0 var(--fp-color-chrome-hi),
|
|
81
|
+
0 4px 0 var(--fp-color-cast),
|
|
82
|
+
0 14px 18px -10px var(--fp-color-cast);
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* A body set in the rim follows its curve (the rim's radius less its padding) and clips to it.
|
|
86
|
+
* No specificity, so a rim sized another way can give its body a matching radius with a class.
|
|
87
|
+
*/
|
|
88
|
+
:where(& > .fp-device-body) {
|
|
89
|
+
overflow: clip;
|
|
90
|
+
border-radius: 26px;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Molded body plastic the modules sit on. */
|
|
95
|
+
.fp-device-body {
|
|
96
|
+
background-image: linear-gradient(180deg, var(--fp-color-shell-hi), var(--fp-color-shell) 240px);
|
|
97
|
+
box-shadow:
|
|
98
|
+
inset 1px 1px 0 var(--fp-color-bevel-hi),
|
|
99
|
+
inset -1px -1px 0 var(--fp-color-bevel-lo);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Liquid chrome with a hard horizon, for title bars and other frames. Never behind text. */
|
|
103
|
+
.fp-chrome {
|
|
104
|
+
background-image: linear-gradient(
|
|
105
|
+
180deg,
|
|
106
|
+
var(--fp-color-chrome-hi) 0%,
|
|
107
|
+
var(--fp-color-chrome-100) 18%,
|
|
108
|
+
var(--fp-color-chrome-tint) 45%,
|
|
109
|
+
var(--fp-color-chrome-500) 52%,
|
|
110
|
+
var(--fp-color-chrome-300) 75%,
|
|
111
|
+
var(--fp-color-chrome-100) 100%
|
|
112
|
+
);
|
|
113
|
+
box-shadow:
|
|
114
|
+
inset 0 1px 0 var(--fp-color-chrome-hi),
|
|
115
|
+
inset 0 -1px 0 var(--fp-color-edge);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Brushed chrome without the horizon, calm enough to print a label in the middle of it. */
|
|
119
|
+
.fp-chrome-soft {
|
|
120
|
+
background-image: linear-gradient(
|
|
121
|
+
180deg,
|
|
122
|
+
color-mix(in srgb, var(--fp-color-chrome-hi) 60%, var(--fp-color-chrome-100)) 0%,
|
|
123
|
+
var(--fp-color-chrome-100) 40%,
|
|
124
|
+
var(--fp-color-chrome-300) 100%
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** Small hardware push button in brushed chrome. 44 px tall, 36 px with a mouse, trackpad or pen. */
|
|
129
|
+
.fp-chrome-btn {
|
|
130
|
+
display: inline-flex;
|
|
131
|
+
align-items: center;
|
|
132
|
+
justify-content: center;
|
|
133
|
+
gap: 0.375rem;
|
|
134
|
+
min-height: 2.75rem;
|
|
135
|
+
min-width: 2.75rem;
|
|
136
|
+
padding-inline: 0.625rem;
|
|
137
|
+
border-radius: 6px;
|
|
138
|
+
color: var(--fp-color-ink);
|
|
139
|
+
font-size: 13px;
|
|
140
|
+
font-weight: 700;
|
|
141
|
+
background-image: linear-gradient(
|
|
142
|
+
180deg,
|
|
143
|
+
color-mix(in srgb, var(--fp-color-chrome-hi) 60%, var(--fp-color-chrome-100)) 0%,
|
|
144
|
+
var(--fp-color-chrome-100) 40%,
|
|
145
|
+
var(--fp-color-chrome-300) 100%
|
|
146
|
+
);
|
|
147
|
+
box-shadow:
|
|
148
|
+
0 0 0 1px var(--fp-color-edge),
|
|
149
|
+
inset 1px 1px 0 var(--fp-color-bevel-hi),
|
|
150
|
+
inset -1px -1px 0 var(--fp-color-bevel-lo),
|
|
151
|
+
1px 2px 0 var(--fp-color-cast);
|
|
152
|
+
transition-property: translate, box-shadow, filter;
|
|
153
|
+
transition-duration: 70ms;
|
|
154
|
+
transition-timing-function: linear;
|
|
155
|
+
|
|
156
|
+
@media (prefers-reduced-motion: reduce) {
|
|
157
|
+
transition-duration: 0ms;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@media (pointer: fine) {
|
|
161
|
+
min-height: 2.25rem;
|
|
162
|
+
min-width: 2.25rem;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
&:hover:not(:disabled) {
|
|
166
|
+
filter: brightness(1.05);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
&:active:not(:disabled),
|
|
170
|
+
&[aria-pressed="true"],
|
|
171
|
+
&[aria-expanded="true"],
|
|
172
|
+
&[aria-current="page"] {
|
|
173
|
+
translate: 0 1px;
|
|
174
|
+
box-shadow:
|
|
175
|
+
0 0 0 1px var(--fp-color-edge),
|
|
176
|
+
inset 1px 1px 3px var(--fp-color-bevel-lo),
|
|
177
|
+
inset -1px -1px 0 var(--fp-color-bevel-hi);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/* A solid ring with a glow outside it: the glow alone fails non-text contrast on light chrome. */
|
|
181
|
+
&:focus-visible {
|
|
182
|
+
outline: 2px solid var(--fp-color-focus-ring);
|
|
183
|
+
outline-offset: 2px;
|
|
184
|
+
filter: drop-shadow(0 0 3px var(--fp-color-focus));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* The hover filter outranks the focus rule, so a hovered control keeps its glow here. */
|
|
188
|
+
&:focus-visible:hover:not(:disabled) {
|
|
189
|
+
filter: brightness(1.05) drop-shadow(0 0 3px var(--fp-color-focus));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
&:disabled {
|
|
193
|
+
opacity: 0.45;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Glossy gel pill for primary actions. Its white label sits on the base colour at mid-height,
|
|
199
|
+
* where the highlight ellipse has already faded out (7:1).
|
|
200
|
+
*/
|
|
201
|
+
.fp-gel {
|
|
202
|
+
display: inline-flex;
|
|
203
|
+
align-items: center;
|
|
204
|
+
justify-content: center;
|
|
205
|
+
gap: 0.5rem;
|
|
206
|
+
min-height: 2.75rem;
|
|
207
|
+
padding-inline: 1rem;
|
|
208
|
+
border-radius: 9999px;
|
|
209
|
+
color: var(--fp-color-gel-ink);
|
|
210
|
+
font-size: 14px;
|
|
211
|
+
font-weight: 700;
|
|
212
|
+
text-shadow: 0 -1px 0 rgb(0 0 0 / 0.35);
|
|
213
|
+
background-image:
|
|
214
|
+
radial-gradient(ellipse 80% 45% at 50% 0%, rgb(255 255 255 / 0.7), rgb(255 255 255 / 0.08) 90%, transparent 100%),
|
|
215
|
+
linear-gradient(180deg, var(--fp-color-gel-hi) 0%, var(--fp-color-gel) 48%, var(--fp-color-gel-lo) 100%);
|
|
216
|
+
box-shadow:
|
|
217
|
+
0 0 0 1px var(--fp-color-gel-lo),
|
|
218
|
+
inset 0 -3px 5px rgb(140 200 255 / 0.4),
|
|
219
|
+
1px 2px 0 var(--fp-color-cast);
|
|
220
|
+
transition-property: translate, box-shadow, filter;
|
|
221
|
+
transition-duration: 70ms;
|
|
222
|
+
transition-timing-function: linear;
|
|
223
|
+
|
|
224
|
+
@media (prefers-reduced-motion: reduce) {
|
|
225
|
+
transition-duration: 0ms;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@media (pointer: fine) {
|
|
229
|
+
min-height: 2.5rem;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
&:hover:not(:disabled) {
|
|
233
|
+
filter: brightness(1.08);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
&:active:not(:disabled) {
|
|
237
|
+
translate: 0 1px;
|
|
238
|
+
box-shadow:
|
|
239
|
+
0 0 0 1px var(--fp-color-gel-lo),
|
|
240
|
+
inset 0 2px 4px rgb(0 0 0 / 0.35);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* A solid ring with a glow outside it: the glow alone fails non-text contrast on light chrome. */
|
|
244
|
+
&:focus-visible {
|
|
245
|
+
outline: 2px solid var(--fp-color-focus-ring);
|
|
246
|
+
outline-offset: 2px;
|
|
247
|
+
filter: drop-shadow(0 0 3px var(--fp-color-focus));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/* The hover filter outranks the focus rule, so a hovered control keeps its glow here. */
|
|
251
|
+
&:focus-visible:hover:not(:disabled) {
|
|
252
|
+
filter: brightness(1.08) drop-shadow(0 0 3px var(--fp-color-focus));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
&:disabled {
|
|
256
|
+
opacity: 0.45;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Molded-plastic cap. The cap colour and its label colour come from the fp-cap-* classes
|
|
262
|
+
* (`--fp-cap`, `--fp-cap-ink`); a bare `fp-cap` is white plastic with a dark label. Selected caps
|
|
263
|
+
* stay pressed in and get a ring, so selection never depends on colour.
|
|
264
|
+
*/
|
|
265
|
+
.fp-cap {
|
|
266
|
+
position: relative;
|
|
267
|
+
display: inline-flex;
|
|
268
|
+
align-items: center;
|
|
269
|
+
justify-content: center;
|
|
270
|
+
min-height: 2.75rem;
|
|
271
|
+
padding-inline: 0.5rem;
|
|
272
|
+
border-radius: 6px;
|
|
273
|
+
color: var(--fp-cap-ink, var(--fp-color-cap-ink));
|
|
274
|
+
font-weight: 700;
|
|
275
|
+
background-color: var(--fp-cap, var(--fp-color-cap));
|
|
276
|
+
background-image: radial-gradient(ellipse 110% 80% at 30% 10%, rgb(255 255 255 / 0.28), transparent 65%);
|
|
277
|
+
box-shadow:
|
|
278
|
+
0 0 0 1px var(--fp-color-edge),
|
|
279
|
+
inset 0 2px 0 rgb(255 255 255 / 0.45),
|
|
280
|
+
inset 0 -2px 0 rgb(0 0 0 / 0.25),
|
|
281
|
+
1px 2px 1px var(--fp-color-cast);
|
|
282
|
+
transition-property: translate, box-shadow, filter;
|
|
283
|
+
transition-duration: 70ms;
|
|
284
|
+
transition-timing-function: linear;
|
|
285
|
+
|
|
286
|
+
@media (prefers-reduced-motion: reduce) {
|
|
287
|
+
transition-duration: 0ms;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
@media (pointer: fine) {
|
|
291
|
+
min-height: 2.25rem;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
&:hover:not(:disabled) {
|
|
295
|
+
filter: brightness(1.05);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
&:active:not(:disabled) {
|
|
299
|
+
translate: 0 1px;
|
|
300
|
+
box-shadow:
|
|
301
|
+
0 0 0 1px var(--fp-color-edge),
|
|
302
|
+
inset 0 2px 3px rgb(0 0 0 / 0.35),
|
|
303
|
+
inset 0 -1px 0 rgb(255 255 255 / 0.3);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
&[aria-pressed="true"],
|
|
307
|
+
&[aria-checked="true"] {
|
|
308
|
+
translate: 0 1px;
|
|
309
|
+
box-shadow:
|
|
310
|
+
0 0 0 2px var(--fp-color-select),
|
|
311
|
+
inset 0 2px 3px rgb(0 0 0 / 0.35),
|
|
312
|
+
inset 0 -1px 0 rgb(255 255 255 / 0.3);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* A solid ring with a glow outside it: the glow alone fails non-text contrast on light chrome. */
|
|
316
|
+
&:focus-visible {
|
|
317
|
+
outline: 2px solid var(--fp-color-focus-ring);
|
|
318
|
+
outline-offset: 2px;
|
|
319
|
+
filter: drop-shadow(0 0 3px var(--fp-color-focus));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/* The hover filter outranks the focus rule, so a hovered control keeps its glow here. */
|
|
323
|
+
&:focus-visible:hover:not(:disabled) {
|
|
324
|
+
filter: brightness(1.05) drop-shadow(0 0 3px var(--fp-color-focus));
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
&:disabled {
|
|
328
|
+
opacity: 0.5;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/** Blue plastic for an fp-cap, with its own label colour. */
|
|
333
|
+
.fp-cap-blue {
|
|
334
|
+
--fp-cap: var(--fp-color-cap-blue);
|
|
335
|
+
--fp-cap-ink: var(--fp-color-cap-blue-ink);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Amber plastic for an fp-cap, with its own label colour. */
|
|
339
|
+
.fp-cap-amber {
|
|
340
|
+
--fp-cap: var(--fp-color-cap-amber);
|
|
341
|
+
--fp-cap-ink: var(--fp-color-cap-amber-ink);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/** Graphite plastic for an fp-cap, with its own label colour. */
|
|
345
|
+
.fp-cap-graphite {
|
|
346
|
+
--fp-cap: var(--fp-color-cap-graphite);
|
|
347
|
+
--fp-cap-ink: var(--fp-color-cap-graphite-ink);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/** Berry plastic for an fp-cap, with its own label colour. */
|
|
351
|
+
.fp-cap-berry {
|
|
352
|
+
--fp-cap: var(--fp-color-cap-berry);
|
|
353
|
+
--fp-cap-ink: var(--fp-color-cap-berry-ink);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Matte content panel. This is where reading happens: no gloss, a 1 px bevel and a short hard shadow. */
|
|
357
|
+
.fp-module {
|
|
358
|
+
border-radius: 10px;
|
|
359
|
+
background-color: var(--fp-color-shell-matte);
|
|
360
|
+
box-shadow:
|
|
361
|
+
0 0 0 1px var(--fp-color-edge),
|
|
362
|
+
inset 1px 1px 0 var(--fp-color-bevel-hi),
|
|
363
|
+
inset -1px -1px 0 var(--fp-color-bevel-lo),
|
|
364
|
+
2px 3px 0 var(--fp-color-cast);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** A module's own little title bar, in brushed chrome. */
|
|
368
|
+
.fp-module-title {
|
|
369
|
+
display: flex;
|
|
370
|
+
align-items: center;
|
|
371
|
+
gap: 0.5rem;
|
|
372
|
+
min-height: 1.875rem;
|
|
373
|
+
padding: 0.25rem 0.625rem;
|
|
374
|
+
border-radius: 10px 10px 0 0;
|
|
375
|
+
border-bottom: 1px solid var(--fp-color-edge);
|
|
376
|
+
background-image: linear-gradient(
|
|
377
|
+
180deg,
|
|
378
|
+
color-mix(in srgb, var(--fp-color-chrome-hi) 60%, var(--fp-color-chrome-100)) 0%,
|
|
379
|
+
var(--fp-color-chrome-100) 40%,
|
|
380
|
+
var(--fp-color-chrome-300) 100%
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* A window: a module (or, in the page extra, a sheet panel) whose fp-module-title stays in view
|
|
386
|
+
* while its body scrolls under it.
|
|
387
|
+
*/
|
|
388
|
+
.fp-window {
|
|
389
|
+
/* Its top corners follow the window's, which differ between a module and a sheet. */
|
|
390
|
+
& > .fp-module-title {
|
|
391
|
+
position: sticky;
|
|
392
|
+
top: 0;
|
|
393
|
+
z-index: 1;
|
|
394
|
+
border-start-start-radius: inherit;
|
|
395
|
+
border-start-end-radius: inherit;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/* Title-bar buttons stay small with a precise pointer; touch keeps the 44 px target. */
|
|
399
|
+
@media (pointer: fine) {
|
|
400
|
+
& > .fp-module-title .fp-chrome-btn {
|
|
401
|
+
min-height: 1.75rem;
|
|
402
|
+
min-width: 1.75rem;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** A window's name in its title bar. Pair it with fp-silk; it pushes the title-bar buttons to the far end. */
|
|
408
|
+
.fp-window-title {
|
|
409
|
+
margin: 0;
|
|
410
|
+
margin-inline-end: auto;
|
|
411
|
+
font-weight: 400;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/** The padded body under a window's title bar. */
|
|
415
|
+
.fp-window-body {
|
|
416
|
+
padding: 0.75rem;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** Recessed well inside a matte panel, for secondary content or an empty slot. */
|
|
420
|
+
.fp-well {
|
|
421
|
+
border-radius: 6px;
|
|
422
|
+
background-color: var(--fp-color-well);
|
|
423
|
+
box-shadow:
|
|
424
|
+
inset 1px 1px 2px var(--fp-color-bevel-lo),
|
|
425
|
+
inset -1px -1px 0 var(--fp-color-bevel-hi);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/** Silkscreened hardware label. */
|
|
429
|
+
.fp-silk {
|
|
430
|
+
font-family: var(--fp-font-display);
|
|
431
|
+
font-size: 11px;
|
|
432
|
+
line-height: 1.3;
|
|
433
|
+
letter-spacing: 0.08em;
|
|
434
|
+
text-transform: uppercase;
|
|
435
|
+
color: var(--fp-color-ink-soft);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** LCD glass, recessed into the chrome. Text on it uses `--fp-font-lcd`; drawings use `--fp-color-lcd-ink`. */
|
|
439
|
+
.fp-lcd {
|
|
440
|
+
border-radius: 8px;
|
|
441
|
+
color: var(--fp-color-lcd-ink);
|
|
442
|
+
background-color: var(--fp-color-lcd-bg);
|
|
443
|
+
background-image: repeating-linear-gradient(0deg, rgb(0 0 0 / 0.04) 0 1px, transparent 1px 3px);
|
|
444
|
+
box-shadow:
|
|
445
|
+
0 0 0 2px var(--fp-color-chrome-800),
|
|
446
|
+
inset 2px 2px 4px rgb(0 0 0 / 0.35),
|
|
447
|
+
inset -1px -1px 0 rgb(255 255 255 / 0.2);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/** One line of LCD text. Cells of fp-lcd-ghost stacked behind it show the unlit segments, as on real glass. */
|
|
451
|
+
.fp-lcd-line {
|
|
452
|
+
display: grid;
|
|
453
|
+
margin: 0;
|
|
454
|
+
font-family: var(--fp-font-lcd);
|
|
455
|
+
white-space: pre;
|
|
456
|
+
|
|
457
|
+
& > * {
|
|
458
|
+
grid-area: 1 / 1;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/** The unlit segments behind an LCD line. Decorative: give it aria-hidden="true". */
|
|
463
|
+
.fp-lcd-ghost {
|
|
464
|
+
color: var(--fp-color-lcd-ghost);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/** Dark housing that LEDs and small readouts sit in. */
|
|
468
|
+
.fp-housing {
|
|
469
|
+
display: inline-flex;
|
|
470
|
+
align-items: center;
|
|
471
|
+
gap: 0.375rem;
|
|
472
|
+
border-radius: 9999px;
|
|
473
|
+
padding: 0.125rem 0.5rem;
|
|
474
|
+
color: var(--fp-color-housing-ink);
|
|
475
|
+
font-size: 12px;
|
|
476
|
+
font-weight: 700;
|
|
477
|
+
background-color: var(--fp-color-housing);
|
|
478
|
+
box-shadow:
|
|
479
|
+
inset 1px 1px 2px rgb(0 0 0 / 0.5),
|
|
480
|
+
0 1px 0 var(--fp-color-bevel-hi);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** An LED with its own dark bezel ring, so a lit one reads on light chrome too. Unlit by default. */
|
|
484
|
+
.fp-led {
|
|
485
|
+
display: inline-block;
|
|
486
|
+
flex-shrink: 0;
|
|
487
|
+
width: 0.5rem;
|
|
488
|
+
height: 0.5rem;
|
|
489
|
+
border-radius: 9999px;
|
|
490
|
+
background-color: var(--fp-color-led-off);
|
|
491
|
+
box-shadow:
|
|
492
|
+
0 0 0 2px var(--fp-color-housing),
|
|
493
|
+
inset 0 -1px 1px rgb(0 0 0 / 0.45);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/** Green for an fp-led, the default. */
|
|
497
|
+
.fp-led-green {
|
|
498
|
+
--fp-led: var(--fp-color-led-on);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** Amber for an fp-led. */
|
|
502
|
+
.fp-led-amber {
|
|
503
|
+
--fp-led: var(--fp-color-led-amber);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/** Red for an fp-led. */
|
|
507
|
+
.fp-led-red {
|
|
508
|
+
--fp-led: var(--fp-color-led-red);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/** Lights an fp-led in its colour, with a glow. Say what it means in text nearby, never by colour alone. */
|
|
512
|
+
.fp-led-lit {
|
|
513
|
+
background-color: var(--fp-led, var(--fp-color-led-on));
|
|
514
|
+
box-shadow:
|
|
515
|
+
0 0 0 2px var(--fp-color-housing),
|
|
516
|
+
0 0 7px 2px color-mix(in srgb, var(--fp-led, var(--fp-color-led-on)) 65%, transparent),
|
|
517
|
+
inset 0 -1px 1px rgb(0 0 0 / 0.2);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** Decorative screw head. Give it aria-hidden="true". */
|
|
521
|
+
.fp-screw {
|
|
522
|
+
display: inline-block;
|
|
523
|
+
flex-shrink: 0;
|
|
524
|
+
width: 10px;
|
|
525
|
+
height: 10px;
|
|
526
|
+
border-radius: 9999px;
|
|
527
|
+
background-image:
|
|
528
|
+
linear-gradient(135deg, transparent 44%, var(--fp-color-chrome-800) 44% 56%, transparent 56%),
|
|
529
|
+
radial-gradient(circle at 35% 30%, var(--fp-color-chrome-hi), var(--fp-color-chrome-300) 60%, var(--fp-color-chrome-500));
|
|
530
|
+
box-shadow: 0 0 0 1px var(--fp-color-edge);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/** A scrolling panel, such as a list window, with a thin scrollbar that never pushes the layout. */
|
|
534
|
+
.fp-scroll-thin {
|
|
535
|
+
scrollbar-width: thin;
|
|
536
|
+
scrollbar-color: var(--fp-color-scroll-thumb) transparent;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** A 16 px pixel icon. Size it in whole multiples of 16 px so its pixels stay crisp. */
|
|
540
|
+
.fp-icon {
|
|
541
|
+
flex-shrink: 0;
|
|
542
|
+
width: 16px;
|
|
543
|
+
height: 16px;
|
|
544
|
+
fill: currentColor;
|
|
545
|
+
shape-rendering: crispEdges;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2011 The Michroma Project Authors (https://github.com/googlefonts/Michroma-font)
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|