@frontpanel/css 0.0.0-stage → 0.2.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dulan Katukurundage
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,101 @@
1
- # Temporary Holding Version
1
+ # @frontpanel/css
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An early-2000s hardware skin in plain CSS, for building device front panels in the browser:
4
+ liquid-chrome bezels, gel buttons, molded caps, LCD glass and LEDs. Two skins, Chrome Silver and
5
+ Gunmetal Night, follow the system setting. Tokens are `--fp-*` and classes `.fp-*`, with an
6
+ optional Tailwind 4 entry.
7
+
8
+ The UI kit behind [WhatsTheNextChord](https://whatsthenextchord.com).
9
+
10
+ **[Documentation](https://dulandev.github.io/frontpanel/)**: guides, live demos, and every
11
+ component, class and token.
12
+
13
+ > `0.x`: the class and token names may still change between minor versions. Pin the version.
14
+
15
+ ## Install
16
+
17
+ ```bash
18
+ npm install @frontpanel/css
19
+ ```
20
+
21
+ ## Use it
22
+
23
+ Plain CSS, everything in `@layer frontpanel`, so your own unlayered styles win:
24
+
25
+ ```css
26
+ @import "@frontpanel/css/index.css"; /* tokens and .fp-* classes */
27
+ @import "@frontpanel/css/fonts.css"; /* optional: the bundled display and LCD fonts */
28
+ @import "@frontpanel/css/page.css"; /* optional: website pieces around a device */
29
+ @import "@frontpanel/css/base.css"; /* optional: page defaults */
30
+ ```
31
+
32
+ Tailwind 4, where the tokens join the theme (`bg-fp-shell`, `text-fp-ink`, `font-fp-lcd`) and the
33
+ classes become utilities, so variants such as `lg:fp-module` work:
34
+
35
+ ```css
36
+ @import "tailwindcss";
37
+ @import "@frontpanel/css/tailwind.css";
38
+ @import "@frontpanel/css/fonts.css"; /* optional */
39
+ @import "@frontpanel/css/tailwind-page.css"; /* optional */
40
+ @import "@frontpanel/css/tailwind-base.css"; /* optional, and with no layer() */
41
+ ```
42
+
43
+ `tailwind-base.css` puts the page defaults in Tailwind's `base` layer itself. Importing `base.css`
44
+ with `layer(base)` would nest them in a layer of their own, where preflight beats them.
45
+
46
+ From TypeScript, import the file (`import '@frontpanel/css/index.css'`) rather than the bare
47
+ package name, which a type checker reads as a module without types.
48
+
49
+ ## Entries
50
+
51
+ | File | Holds | Global side effects |
52
+ | --- | --- | --- |
53
+ | `index.css` | `tokens.css` and `components.css` | None |
54
+ | `tokens.css` | The `--fp-*` colour and font tokens for both skins | None |
55
+ | `components.css` | The `.fp-*` classes | None |
56
+ | `fonts.css` | `@font-face` for Michroma and VT323 (latin, woff2) | None until used |
57
+ | `page.css` | Website pieces: `fp-field`, the phone bottom sheet (`fp-sheet-panel`, `fp-sheet-*`) | None |
58
+ | `base.css` | Page defaults: skin colours and UI font on the root, focus ring, selection | Yes, opt-in |
59
+ | `tailwind.css`, `tailwind-page.css`, `tailwind-base.css` | The same, for Tailwind 4 | As above |
60
+
61
+ ## Skins
62
+
63
+ Chrome Silver is the default and Gunmetal Night follows a dark system setting. Force either on
64
+ any element, including the root, with `data-fp-skin="silver"` or `data-fp-skin="gunmetal"`. Every
65
+ text pairing passes WCAG AA in both.
66
+
67
+ ## Layout and input
68
+
69
+ A device can scale as a whole or reflow its modules at your breakpoints: the classes carry no
70
+ viewport breakpoints. Controls are 44 px by default and 36 px under a precise pointer
71
+ (`pointer: fine`). Each interactive class has its own focus ring.
72
+
73
+ ## Motion
74
+
75
+ Nothing resets motion globally. Each class that moves (the LCD redraw, the LED's double blink,
76
+ the press of a button) handles `prefers-reduced-motion` itself. Under reduced motion the phone
77
+ sheet (`fp-sheet-*`) doesn't slide and its transition lasts 1 ms rather than 0, so a
78
+ `transitionend` listener still hears it finish.
79
+
80
+ ## Fonts
81
+
82
+ `fonts.css` loads Michroma (silkscreen labels and titles) and VT323 (LCD text) from its own
83
+ `fonts/` folder, and your bundler serves them from wherever it puts them. Without it, the tokens
84
+ fall back to Arial Black and Courier New. Tahoma is the UI face, from the system.
85
+
86
+ To preload the fonts, they need URLs that don't change between builds. Copy `fonts/` into your
87
+ public folder at build time and write the two `@font-face` rules yourself, pointing at those
88
+ URLs, in place of `fonts.css`. The file names (`michroma-latin-400.woff2`,
89
+ `vt323-latin-400.woff2`) stay the same across releases; a rename would be a breaking change.
90
+
91
+ ## Browser support
92
+
93
+ The plain CSS uses native CSS nesting, so it needs Chrome and Edge 112, Firefox 117 or Safari
94
+ 16.5 (Baseline 2023) or later. Everything else it uses is older: cascade layers, `:where()`,
95
+ `color-mix()`, `dvh` and the `translate` property. The Tailwind entry follows Tailwind 4's own
96
+ support, since Tailwind compiles the nesting away.
97
+
98
+ ## Licence
99
+
100
+ MIT. The bundled Michroma and VT323 fonts are under the SIL Open Font License; their licence texts
101
+ ship in `fonts/`.
package/base.css ADDED
@@ -0,0 +1,41 @@
1
+ /* Generated by scripts/build.ts from src/. Do not edit; edit the source and run `pnpm build`. */
2
+ @layer frontpanel {
3
+ /*
4
+ * Page defaults, part of the opt-in page extra: for a page that is mostly a device, or a website
5
+ * around one. They style elements outside .fp-* classes, so nothing else in the package does this.
6
+ *
7
+ * Generated into two entries:
8
+ * - base.css, in @layer frontpanel: `@import "@frontpanel/css/base.css";` after index.css.
9
+ * - tailwind-base.css, straight in Tailwind's base layer so they follow preflight and its
10
+ * utilities still win: `@import "@frontpanel/css/tailwind-base.css";` after tailwindcss,
11
+ * with no layer().
12
+ */
13
+ /* The page wears the skin. Native controls and scrollbars follow it, forced or not. */
14
+ :root {
15
+ color-scheme: var(--fp-scheme);
16
+ background-color: var(--fp-color-backdrop);
17
+ color: var(--fp-color-ink);
18
+ font-family: var(--fp-font-ui);
19
+ -webkit-text-size-adjust: 100%;
20
+ }
21
+
22
+ body {
23
+ margin: 0;
24
+ min-height: 100dvh;
25
+ }
26
+
27
+ /*
28
+ * Everything else that takes focus gets the controls' ring: solid, with a glow outside it, since
29
+ * the glow alone fails non-text contrast on light chrome.
30
+ */
31
+ :focus-visible {
32
+ outline: 2px solid var(--fp-color-focus-ring);
33
+ outline-offset: 2px;
34
+ filter: drop-shadow(0 0 3px var(--fp-color-focus));
35
+ }
36
+
37
+ ::selection {
38
+ background: var(--fp-color-gel);
39
+ color: var(--fp-color-gel-ink);
40
+ }
41
+ }