@jdcpuwiz/homelab-ui 0.6.0 → 0.7.1

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.
@@ -0,0 +1,132 @@
1
+ # homelab-ui starter — the three-face font wiring (BuildPlan #57)
2
+
3
+ Copy-paste templates for loading the fleet's sanctioned faces and binding them
4
+ to `@jdcpuwiz/homelab-ui`'s CSS vars. **Loading is per-app** — a `next/font`
5
+ loader can't be re-exported from the package (Next's SWC plugin scans your own
6
+ source for literal `const Foo = Font({...})` calls), so each app self-hosts its
7
+ faces. The package only owns the `--hl-font-*` wiring.
8
+
9
+ ## The standard (settled, Wiz 2026-07-24)
10
+
11
+ | Role | Face | Where |
12
+ |---|---|---|
13
+ | Body / UI / headings / labels | **Poppins** (`--hl-font-sans`) | everything you read |
14
+ | Big display numbers (**≥ ~1.5rem**) | **Orbitron** (`--hl-font-display`) | stat-card heroes, clock, large KPIs |
15
+ | Small values + code/logs (**< 1.5rem**) | **JetBrains Mono** (`--hl-font-mono`) | table figures, inline values, version stamps, code |
16
+
17
+ The ~1.5rem line is the hard boundary — Orbitron is a display face and must
18
+ NEVER land in a dense small cell. If a number is small, it's JetBrains Mono.
19
+
20
+ Text is two colors only: flat **`#f0f1f4`** for everything you read (no opacity
21
+ ramp — hierarchy is size/weight), **`#ff9900`** for numeric values. Status pills
22
+ keep their solid semantic bg + white text.
23
+
24
+ The app-side variable names are a convention (`FONT_APP_VARIABLES` in the
25
+ package): `--font-poppins`, `--font-orbitron`, `--font-jetbrains-mono`. The
26
+ package's `globals.css` reads exactly these, so following the naming means zero
27
+ extra config.
28
+
29
+ ---
30
+
31
+ ## Next apps (`next/font/google`)
32
+
33
+ See [`next-layout.tsx`](./next-layout.tsx). The shape:
34
+
35
+ ```tsx
36
+ import { Poppins, Orbitron, JetBrains_Mono } from "next/font/google";
37
+ import "@jdcpuwiz/homelab-ui/globals.css";
38
+ import "./globals.css"; // your own overrides, AFTER the package
39
+
40
+ const poppins = Poppins({
41
+ subsets: ["latin"],
42
+ weight: ["300", "400", "500", "600", "700", "800"],
43
+ display: "swap",
44
+ variable: "--font-poppins",
45
+ });
46
+ const orbitron = Orbitron({
47
+ subsets: ["latin"],
48
+ weight: ["400", "500", "600", "700", "800", "900"],
49
+ display: "swap",
50
+ variable: "--font-orbitron",
51
+ });
52
+ const jetbrainsMono = JetBrains_Mono({
53
+ subsets: ["latin"],
54
+ weight: ["400", "500", "600", "700"],
55
+ display: "swap",
56
+ variable: "--font-jetbrains-mono",
57
+ });
58
+
59
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
60
+ return (
61
+ <html
62
+ lang="en"
63
+ className={`dark ${poppins.variable} ${orbitron.variable} ${jetbrainsMono.variable}`}
64
+ >
65
+ <body className="antialiased">{children}</body>
66
+ </html>
67
+ );
68
+ }
69
+ ```
70
+
71
+ That's it. The three `.variable` classes put `--font-poppins` /
72
+ `--font-orbitron` / `--font-jetbrains-mono` on the tree; `globals.css` already
73
+ references them, so `font-sans` / `font-display` / `font-mono` resolve to the
74
+ real faces. Body text is Poppins with no extra style — the package sets
75
+ `font-family: var(--hl-font-sans)` on `body`.
76
+
77
+ **Use the faces by job:**
78
+
79
+ ```tsx
80
+ <h1 className="text-xl font-semibold text-[#f0f1f4]">Dashboard</h1> {/* Poppins */}
81
+ <span className="font-display text-4xl tabular-nums" style={{ color: "#ff9900" }}>42</span> {/* Orbitron */}
82
+ <span className="font-mono text-xs tabular-nums" style={{ color: "#ff9900" }}>v0.7.0</span> {/* JetBrains Mono */}
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Vite apps (`@fontsource`)
88
+
89
+ wiz3dtools and timesheet. See [`vite-fonts.ts`](./vite-fonts.ts):
90
+
91
+ ```bash
92
+ npm install @fontsource/poppins @fontsource/orbitron @fontsource/jetbrains-mono
93
+ ```
94
+
95
+ ```ts
96
+ // src/main.tsx — import once, before your app
97
+ import "@fontsource/poppins/300.css";
98
+ import "@fontsource/poppins/400.css";
99
+ import "@fontsource/poppins/500.css";
100
+ import "@fontsource/poppins/600.css";
101
+ import "@fontsource/poppins/700.css";
102
+ import "@fontsource/poppins/800.css";
103
+ import "@fontsource/orbitron/400.css";
104
+ import "@fontsource/orbitron/500.css";
105
+ import "@fontsource/orbitron/600.css";
106
+ import "@fontsource/orbitron/700.css";
107
+ import "@fontsource/jetbrains-mono/400.css";
108
+ import "@fontsource/jetbrains-mono/500.css";
109
+ import "@fontsource/jetbrains-mono/600.css";
110
+ import "@jdcpuwiz/homelab-ui/globals.css";
111
+ ```
112
+
113
+ `@fontsource` registers the plain family names (`Poppins`, `Orbitron`,
114
+ `JetBrains Mono`). The package's `--hl-font-*` vars fall back to those literal
115
+ names after the (unset) next/font vars, so no CSS variable wiring is needed —
116
+ importing the CSS is the whole setup.
117
+
118
+ **Kill the runtime `<link href="fonts.googleapis.com">`** if the app has one —
119
+ self-hosted only.
120
+
121
+ ---
122
+
123
+ ## Verify after deploy
124
+
125
+ Open DevTools on the running app:
126
+
127
+ ```js
128
+ getComputedStyle(document.body).fontFamily // → should name "Poppins"
129
+ ```
130
+
131
+ If it names Geist, system-ui, or nothing, the app is off-standard — the loader
132
+ didn't land or the CSS import is missing.
@@ -0,0 +1,60 @@
1
+ /**
2
+ * STARTER — Next.js root layout wiring the three sanctioned faces
3
+ * (BuildPlan #57). Copy into your app's `app/layout.tsx` and adjust the
4
+ * metadata / body content. Do NOT import this file from the package — a
5
+ * next/font loader can't be re-exported (Next scans your own source for the
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.
8
+ *
9
+ * SANS Poppins — body / UI / headings / labels
10
+ * DISPLAY Orbitron — big numbers only (≥ ~1.5rem): stat heroes, clock
11
+ * MONO JetBrains Mono — small values, version stamps, code (< ~1.5rem)
12
+ *
13
+ * The `variable` names below MUST match the package convention
14
+ * (`FONT_APP_VARIABLES`): --font-poppins / --font-orbitron /
15
+ * --font-jetbrains-mono. `@jdcpuwiz/homelab-ui/globals.css` reads exactly
16
+ * these, so following the naming means zero extra config.
17
+ */
18
+ import type { Metadata } from "next";
19
+ import { Poppins, Orbitron, JetBrains_Mono } from "next/font/google";
20
+ import "@jdcpuwiz/homelab-ui/globals.css";
21
+ import "./globals.css"; // optional: your own overrides, AFTER the package
22
+
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
+ export const metadata: Metadata = { title: "My App" };
45
+
46
+ export default function RootLayout({
47
+ children,
48
+ }: Readonly<{ children: React.ReactNode }>) {
49
+ return (
50
+ <html
51
+ lang="en"
52
+ className={`dark ${poppins.variable} ${orbitron.variable} ${jetbrainsMono.variable}`}
53
+ >
54
+ {/* Body font is Poppins with no extra style — the package sets
55
+ `font-family: var(--hl-font-sans)` on `body`. Reach for the other
56
+ faces by job with the `font-display` / `font-mono` classes. */}
57
+ <body className="antialiased">{children}</body>
58
+ </html>
59
+ );
60
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * STARTER — Vite app font wiring (BuildPlan #57). For the two Vite apps in
3
+ * the fleet (wiz3dtools, timesheet). Copy these imports into your app entry
4
+ * (`src/main.tsx` / `src/main.ts`), BEFORE your app mounts.
5
+ *
6
+ * First install the faces:
7
+ * npm install @fontsource/poppins @fontsource/orbitron @fontsource/jetbrains-mono
8
+ *
9
+ * @fontsource registers the plain family names (Poppins, Orbitron, JetBrains
10
+ * Mono). The package's `--hl-font-*` vars fall back to those literal names, so
11
+ * NO CSS-variable wiring is needed — importing these stylesheets + the
12
+ * package's globals.css is the whole setup.
13
+ *
14
+ * Then DELETE any runtime `<link href="https://fonts.googleapis.com/...">`
15
+ * from index.html — self-hosted only, no runtime Google Fonts.
16
+ */
17
+
18
+ // Poppins — body / UI / headings / labels (weights 300–800)
19
+ import "@fontsource/poppins/300.css";
20
+ import "@fontsource/poppins/400.css";
21
+ import "@fontsource/poppins/500.css";
22
+ import "@fontsource/poppins/600.css";
23
+ import "@fontsource/poppins/700.css";
24
+ import "@fontsource/poppins/800.css";
25
+
26
+ // Orbitron — big display numbers only (≥ ~1.5rem)
27
+ import "@fontsource/orbitron/400.css";
28
+ import "@fontsource/orbitron/500.css";
29
+ import "@fontsource/orbitron/600.css";
30
+ import "@fontsource/orbitron/700.css";
31
+
32
+ // JetBrains Mono — small values, version stamps, code (< ~1.5rem)
33
+ import "@fontsource/jetbrains-mono/400.css";
34
+ import "@fontsource/jetbrains-mono/500.css";
35
+ import "@fontsource/jetbrains-mono/600.css";
36
+ import "@fontsource/jetbrains-mono/700.css";
37
+
38
+ // The package's token stylesheet — brings in --hl-font-* + the flat #f0f1f4
39
+ // foreground. Import AFTER the faces so the family names are already
40
+ // registered.
41
+ import "@jdcpuwiz/homelab-ui/globals.css";
@@ -82,21 +82,32 @@ module.exports = {
82
82
  DEFAULT: "rgba(0,0,0,0.9)",
83
83
  chip: "rgba(0,0,0,0.6)",
84
84
  },
85
+ // Reading text is ONE flat shade (BP #57). The old /60·/40·/30
86
+ // opacity ramp is dead — hierarchy comes from size/weight, not a
87
+ // dimmer grey. `primary`/`secondary`/`tertiary` are kept as
88
+ // back-compat aliases but now ALL resolve to the one flat
89
+ // foreground, so a consumer still on `text-ink-secondary` renders
90
+ // the standard automatically. `disabled` stays a genuine dim — it
91
+ // marks a disabled affordance, not reading text.
85
92
  ink: {
86
- primary: "#ffffff",
87
- secondary: "rgba(255,255,255,0.60)",
88
- tertiary: "rgba(255,255,255,0.40)",
93
+ primary: "var(--hl-foreground)",
94
+ secondary: "var(--hl-foreground)",
95
+ tertiary: "var(--hl-foreground)",
89
96
  disabled: "rgba(255,255,255,0.30)",
90
97
  },
91
98
  },
92
- // Typography — the sanctioned system stack (Wiz ruling 2026-07-23,
93
- // Change #345). No webfont. The `--hl-font-*` vars come from
94
- // `@jdcpuwiz/homelab-ui/globals.css`; the literal fallbacks after them
95
- // keep these classes correct even if a consumer skips that stylesheet.
99
+ // Typography — three self-hosted faces by job (Wiz ruling 2026-07-24,
100
+ // BuildPlan #57): Poppins (sans), Orbitron (display / big numbers),
101
+ // JetBrains Mono (mono / small values + code). The `--hl-font-*` vars
102
+ // come from `@jdcpuwiz/homelab-ui/globals.css` and reference each app's
103
+ // own next/font loader; the literal face names after them keep these
104
+ // classes correct even if a consumer skips that stylesheet or loads via
105
+ // @fontsource. Each app self-hosts its faces — see the package README
106
+ // and starter/.
96
107
  fontFamily: {
97
- sans: ["var(--hl-font-sans)", "system-ui", "sans-serif"],
98
- mono: ["var(--hl-font-mono)", "ui-monospace", "monospace"],
99
- display: ["var(--hl-font-display)", "var(--hl-font-sans)", "system-ui", "sans-serif"],
108
+ sans: ["var(--hl-font-sans)", "Poppins", "system-ui", "sans-serif"],
109
+ mono: ["var(--hl-font-mono)", "JetBrains Mono", "ui-monospace", "monospace"],
110
+ display: ["var(--hl-font-display)", "Orbitron", "var(--hl-font-sans)", "system-ui", "sans-serif"],
100
111
  },
101
112
  fontSize: {
102
113
  "2xs": ["10px", { lineHeight: "14px" }],