@jdcpuwiz/homelab-ui 0.10.1 → 0.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +39 -13
- package/dist/index.d.ts +39 -13
- package/dist/index.js.map +1 -1
- package/fonts/LICENSE-jetbrains-mono.txt +93 -0
- package/fonts/LICENSE-orbitron.txt +93 -0
- package/fonts/LICENSE-poppins.txt +93 -0
- package/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
- package/fonts/jetbrains-mono-latin-500-normal.woff2 +0 -0
- package/fonts/jetbrains-mono-latin-600-normal.woff2 +0 -0
- package/fonts/jetbrains-mono-latin-700-normal.woff2 +0 -0
- package/fonts/orbitron-latin-400-normal.woff2 +0 -0
- package/fonts/orbitron-latin-500-normal.woff2 +0 -0
- package/fonts/orbitron-latin-600-normal.woff2 +0 -0
- package/fonts/orbitron-latin-700-normal.woff2 +0 -0
- package/fonts/orbitron-latin-800-normal.woff2 +0 -0
- package/fonts/orbitron-latin-900-normal.woff2 +0 -0
- package/fonts/poppins-latin-300-normal.woff2 +0 -0
- package/fonts/poppins-latin-400-normal.woff2 +0 -0
- package/fonts/poppins-latin-500-normal.woff2 +0 -0
- package/fonts/poppins-latin-600-normal.woff2 +0 -0
- package/fonts/poppins-latin-700-normal.woff2 +0 -0
- package/fonts/poppins-latin-800-normal.woff2 +0 -0
- package/fonts.css +148 -0
- package/package.json +11 -7
- package/starter/next-layout.tsx +40 -34
package/fonts.css
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* homelab-ui — the sanctioned faces, self-hosted (C525).
|
|
3
|
+
*
|
|
4
|
+
* WHY THIS EXISTS. Every consuming dashboard used to load these through
|
|
5
|
+
* `next/font/google`, which makes `next build` fetch from fonts.gstatic.com.
|
|
6
|
+
* That put the NETWORK on the critical path of every deploy: zoovault's
|
|
7
|
+
* 2026-08-15 deploy died when a floating `next` release's font requests 404'd,
|
|
8
|
+
* on a commit that had built clean locally. Pinning the toolchain removes the
|
|
9
|
+
* trigger; this file removes the dependency.
|
|
10
|
+
*
|
|
11
|
+
* WHY PLAIN CSS AND NOT A RE-EXPORTED LOADER. `src/lib/fonts.ts` is right that
|
|
12
|
+
* this package cannot own `next/font` loading — Next's SWC plugin scans the
|
|
13
|
+
* app's own source for a literal `const X = Font({...})`, and bundling rewrites
|
|
14
|
+
* `const` to `var`, so a re-exported loader cannot work. That constraint is
|
|
15
|
+
* specific to `next/font`. It does not apply to `@font-face`.
|
|
16
|
+
*
|
|
17
|
+
* WHY IT NEEDS NO CSS-VAR WIRING. globals.css asks for
|
|
18
|
+
* `var(--font-poppins, "Poppins")` — the app's variable first, then the LITERAL
|
|
19
|
+
* family name. Registering a "Poppins" @font-face therefore satisfies the
|
|
20
|
+
* package on its own, and an app can keep its existing `.variable` classes on
|
|
21
|
+
* <html> harmlessly (an undefined var just falls through to the literal).
|
|
22
|
+
*
|
|
23
|
+
* USAGE — replaces the whole three-loader block in a consumer:
|
|
24
|
+
* import "@jdcpuwiz/homelab-ui/fonts.css"
|
|
25
|
+
*
|
|
26
|
+
* Latin subset only, sourced from @fontsource. OFL licences ship alongside in
|
|
27
|
+
* fonts/. `font-display: swap` matches what next/font/google emitted, so text
|
|
28
|
+
* paints immediately in the fallback rather than blocking on the face.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
/* ── Poppins ── */
|
|
33
|
+
@font-face {
|
|
34
|
+
font-family: "Poppins";
|
|
35
|
+
font-style: normal;
|
|
36
|
+
font-weight: 300;
|
|
37
|
+
font-display: swap;
|
|
38
|
+
src: url("./fonts/poppins-latin-300-normal.woff2") format("woff2");
|
|
39
|
+
}
|
|
40
|
+
@font-face {
|
|
41
|
+
font-family: "Poppins";
|
|
42
|
+
font-style: normal;
|
|
43
|
+
font-weight: 400;
|
|
44
|
+
font-display: swap;
|
|
45
|
+
src: url("./fonts/poppins-latin-400-normal.woff2") format("woff2");
|
|
46
|
+
}
|
|
47
|
+
@font-face {
|
|
48
|
+
font-family: "Poppins";
|
|
49
|
+
font-style: normal;
|
|
50
|
+
font-weight: 500;
|
|
51
|
+
font-display: swap;
|
|
52
|
+
src: url("./fonts/poppins-latin-500-normal.woff2") format("woff2");
|
|
53
|
+
}
|
|
54
|
+
@font-face {
|
|
55
|
+
font-family: "Poppins";
|
|
56
|
+
font-style: normal;
|
|
57
|
+
font-weight: 600;
|
|
58
|
+
font-display: swap;
|
|
59
|
+
src: url("./fonts/poppins-latin-600-normal.woff2") format("woff2");
|
|
60
|
+
}
|
|
61
|
+
@font-face {
|
|
62
|
+
font-family: "Poppins";
|
|
63
|
+
font-style: normal;
|
|
64
|
+
font-weight: 700;
|
|
65
|
+
font-display: swap;
|
|
66
|
+
src: url("./fonts/poppins-latin-700-normal.woff2") format("woff2");
|
|
67
|
+
}
|
|
68
|
+
@font-face {
|
|
69
|
+
font-family: "Poppins";
|
|
70
|
+
font-style: normal;
|
|
71
|
+
font-weight: 800;
|
|
72
|
+
font-display: swap;
|
|
73
|
+
src: url("./fonts/poppins-latin-800-normal.woff2") format("woff2");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ── Orbitron ── */
|
|
77
|
+
@font-face {
|
|
78
|
+
font-family: "Orbitron";
|
|
79
|
+
font-style: normal;
|
|
80
|
+
font-weight: 400;
|
|
81
|
+
font-display: swap;
|
|
82
|
+
src: url("./fonts/orbitron-latin-400-normal.woff2") format("woff2");
|
|
83
|
+
}
|
|
84
|
+
@font-face {
|
|
85
|
+
font-family: "Orbitron";
|
|
86
|
+
font-style: normal;
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
font-display: swap;
|
|
89
|
+
src: url("./fonts/orbitron-latin-500-normal.woff2") format("woff2");
|
|
90
|
+
}
|
|
91
|
+
@font-face {
|
|
92
|
+
font-family: "Orbitron";
|
|
93
|
+
font-style: normal;
|
|
94
|
+
font-weight: 600;
|
|
95
|
+
font-display: swap;
|
|
96
|
+
src: url("./fonts/orbitron-latin-600-normal.woff2") format("woff2");
|
|
97
|
+
}
|
|
98
|
+
@font-face {
|
|
99
|
+
font-family: "Orbitron";
|
|
100
|
+
font-style: normal;
|
|
101
|
+
font-weight: 700;
|
|
102
|
+
font-display: swap;
|
|
103
|
+
src: url("./fonts/orbitron-latin-700-normal.woff2") format("woff2");
|
|
104
|
+
}
|
|
105
|
+
@font-face {
|
|
106
|
+
font-family: "Orbitron";
|
|
107
|
+
font-style: normal;
|
|
108
|
+
font-weight: 800;
|
|
109
|
+
font-display: swap;
|
|
110
|
+
src: url("./fonts/orbitron-latin-800-normal.woff2") format("woff2");
|
|
111
|
+
}
|
|
112
|
+
@font-face {
|
|
113
|
+
font-family: "Orbitron";
|
|
114
|
+
font-style: normal;
|
|
115
|
+
font-weight: 900;
|
|
116
|
+
font-display: swap;
|
|
117
|
+
src: url("./fonts/orbitron-latin-900-normal.woff2") format("woff2");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* ── JetBrains Mono ── */
|
|
121
|
+
@font-face {
|
|
122
|
+
font-family: "JetBrains Mono";
|
|
123
|
+
font-style: normal;
|
|
124
|
+
font-weight: 400;
|
|
125
|
+
font-display: swap;
|
|
126
|
+
src: url("./fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
|
|
127
|
+
}
|
|
128
|
+
@font-face {
|
|
129
|
+
font-family: "JetBrains Mono";
|
|
130
|
+
font-style: normal;
|
|
131
|
+
font-weight: 500;
|
|
132
|
+
font-display: swap;
|
|
133
|
+
src: url("./fonts/jetbrains-mono-latin-500-normal.woff2") format("woff2");
|
|
134
|
+
}
|
|
135
|
+
@font-face {
|
|
136
|
+
font-family: "JetBrains Mono";
|
|
137
|
+
font-style: normal;
|
|
138
|
+
font-weight: 600;
|
|
139
|
+
font-display: swap;
|
|
140
|
+
src: url("./fonts/jetbrains-mono-latin-600-normal.woff2") format("woff2");
|
|
141
|
+
}
|
|
142
|
+
@font-face {
|
|
143
|
+
font-family: "JetBrains Mono";
|
|
144
|
+
font-style: normal;
|
|
145
|
+
font-weight: 700;
|
|
146
|
+
font-display: swap;
|
|
147
|
+
src: url("./fonts/jetbrains-mono-latin-700-normal.woff2") format("woff2");
|
|
148
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jdcpuwiz/homelab-ui",
|
|
3
|
-
"version": "0.10.
|
|
4
|
-
"description": "Shared dark-theme UI primitives for the JdCpuWiz homelab
|
|
3
|
+
"version": "0.10.3",
|
|
4
|
+
"description": "Shared dark-theme UI primitives for the JdCpuWiz homelab — Sidebar, Button, Modal, PageHeader, TagChips, plus the canonical Tailwind preset, CSS vars, and the sanctioned three-face typography (Poppins / Orbitron / JetBrains Mono) on one flat #f0f1f4 text color.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Wiz <shad@deckerzoo.com>",
|
|
7
7
|
"repository": {
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
"import": "./tailwind-preset.cjs",
|
|
28
28
|
"default": "./tailwind-preset.cjs"
|
|
29
29
|
},
|
|
30
|
-
"./globals.css": "./globals.css"
|
|
30
|
+
"./globals.css": "./globals.css",
|
|
31
|
+
"./fonts.css": "./fonts.css"
|
|
31
32
|
},
|
|
32
33
|
"files": [
|
|
33
34
|
"dist",
|
|
@@ -35,7 +36,9 @@
|
|
|
35
36
|
"globals.css",
|
|
36
37
|
"starter",
|
|
37
38
|
"README.md",
|
|
38
|
-
"LICENSE"
|
|
39
|
+
"LICENSE",
|
|
40
|
+
"fonts.css",
|
|
41
|
+
"fonts"
|
|
39
42
|
],
|
|
40
43
|
"sideEffects": [
|
|
41
44
|
"*.css"
|
|
@@ -46,8 +49,9 @@
|
|
|
46
49
|
"ladle": "ladle serve",
|
|
47
50
|
"ladle:build": "ladle build",
|
|
48
51
|
"typecheck": "tsc --noEmit",
|
|
49
|
-
"prepublishOnly": "npm run build",
|
|
50
|
-
"prepare": "npm run build"
|
|
52
|
+
"prepublishOnly": "npm run build && npm run check:publish",
|
|
53
|
+
"prepare": "npm run build",
|
|
54
|
+
"check:publish": "node scripts/check-publish-clean.mjs"
|
|
51
55
|
},
|
|
52
56
|
"peerDependencies": {
|
|
53
57
|
"next": ">=15",
|
|
@@ -85,4 +89,4 @@
|
|
|
85
89
|
"react",
|
|
86
90
|
"design-system"
|
|
87
91
|
]
|
|
88
|
-
}
|
|
92
|
+
}
|
package/starter/next-layout.tsx
CHANGED
|
@@ -1,56 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* STARTER — Next.js root layout wiring the three sanctioned faces
|
|
3
3
|
* (BuildPlan #57). Copy into your app's `app/layout.tsx` and adjust the
|
|
4
|
-
* metadata / body content.
|
|
5
|
-
*
|
|
6
|
-
* literal `const Foo = Font({...})` call), so the loaders must live in YOUR
|
|
7
|
-
* app source. This file is a template, shipped for copy-paste only.
|
|
4
|
+
* metadata / body content. This file is a template, shipped for copy-paste
|
|
5
|
+
* only — do not import it from the package.
|
|
8
6
|
*
|
|
9
7
|
* SANS Poppins — body / UI / headings / labels
|
|
10
8
|
* DISPLAY Orbitron — big numbers only (≥ ~1.5rem): stat heroes, clock
|
|
11
9
|
* MONO JetBrains Mono — small values, version stamps, code (< ~1.5rem)
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* There is no per-app font config to get right any more: the single
|
|
12
|
+
* `fonts.css` import registers every face, and `globals.css` picks them up.
|
|
13
|
+
*
|
|
14
|
+
* ## The faces are SELF-HOSTED — no network at build time (C525)
|
|
15
|
+
*
|
|
16
|
+
* `import "@jdcpuwiz/homelab-ui/fonts.css"` registers all three faces from
|
|
17
|
+
* woff2 files shipped inside the package. `next build` never reaches
|
|
18
|
+
* fonts.gstatic.com, so your DEPLOY has no font-related network dependency.
|
|
19
|
+
*
|
|
20
|
+
* This template used to use `next/font/google`, and that broke a real deploy:
|
|
21
|
+
* on 2026-08-15 zoovault's image floated `next` to a release whose
|
|
22
|
+
* next/font/google requests started 404ing, and the deploy died on a commit
|
|
23
|
+
* that had built clean locally. Nothing warned — a build that can reach
|
|
24
|
+
* Google looks identical to one that never needed to.
|
|
25
|
+
*
|
|
26
|
+
* ## ⚠ DO NOT reference --font-poppins / --font-orbitron / --font-jetbrains-mono
|
|
27
|
+
*
|
|
28
|
+
* Those variables existed only because `next/font` defined them. They do not
|
|
29
|
+
* exist here. Referencing one is worse than a no-op: `var(--x)` with no
|
|
30
|
+
* fallback ARGUMENT is invalid at computed-value time, so the entire
|
|
31
|
+
* font-family declaration is DISCARDED and the element inherits its parent's
|
|
32
|
+
* face — your authored fallbacks after the comma never engage. The text still
|
|
33
|
+
* renders, in a plausible font, with nothing in the console. Tailwind's
|
|
34
|
+
* `font-[family-name:var(--x)]` form fails identically.
|
|
35
|
+
*
|
|
36
|
+
* Use the package tokens instead, which resolve to the self-hosted faces:
|
|
37
|
+
* var(--hl-font-sans) Poppins
|
|
38
|
+
* var(--hl-font-display) Orbitron
|
|
39
|
+
* var(--hl-font-mono) JetBrains Mono
|
|
40
|
+
* or the `font-display` / `font-mono` utility classes.
|
|
41
|
+
*
|
|
42
|
+
* ## Still mandatory, separately
|
|
43
|
+
*
|
|
44
|
+
* PIN your dependencies from a committed lockfile inside the image (`npm ci`,
|
|
45
|
+
* not a bare `npm install`). Self-hosting the fonts removes one network
|
|
46
|
+
* dependency; it does not make a floating install safe.
|
|
17
47
|
*/
|
|
18
48
|
import type { Metadata } from "next";
|
|
19
|
-
import
|
|
49
|
+
import "@jdcpuwiz/homelab-ui/fonts.css"; // the three faces, self-hosted
|
|
20
50
|
import "@jdcpuwiz/homelab-ui/globals.css";
|
|
21
51
|
import "./globals.css"; // optional: your own overrides, AFTER the package
|
|
22
52
|
|
|
23
|
-
const poppins = Poppins({
|
|
24
|
-
subsets: ["latin"],
|
|
25
|
-
weight: ["300", "400", "500", "600", "700", "800"],
|
|
26
|
-
display: "swap",
|
|
27
|
-
variable: "--font-poppins",
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const orbitron = Orbitron({
|
|
31
|
-
subsets: ["latin"],
|
|
32
|
-
weight: ["400", "500", "600", "700", "800", "900"],
|
|
33
|
-
display: "swap",
|
|
34
|
-
variable: "--font-orbitron",
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const jetbrainsMono = JetBrains_Mono({
|
|
38
|
-
subsets: ["latin"],
|
|
39
|
-
weight: ["400", "500", "600", "700"],
|
|
40
|
-
display: "swap",
|
|
41
|
-
variable: "--font-jetbrains-mono",
|
|
42
|
-
});
|
|
43
|
-
|
|
44
53
|
export const metadata: Metadata = { title: "My App" };
|
|
45
54
|
|
|
46
55
|
export default function RootLayout({
|
|
47
56
|
children,
|
|
48
57
|
}: Readonly<{ children: React.ReactNode }>) {
|
|
49
58
|
return (
|
|
50
|
-
<html
|
|
51
|
-
lang="en"
|
|
52
|
-
className={`dark ${poppins.variable} ${orbitron.variable} ${jetbrainsMono.variable}`}
|
|
53
|
-
>
|
|
59
|
+
<html lang="en" className="dark">
|
|
54
60
|
{/* Body font is Poppins with no extra style — the package sets
|
|
55
61
|
`font-family: var(--hl-font-sans)` on `body`. Reach for the other
|
|
56
62
|
faces by job with the `font-display` / `font-mono` classes. */}
|