feat/lab-terminal-theme #3

Merged
hzhang merged 3 commits from feat/lab-terminal-theme into main 2026-05-17 13:16:40 +00:00
32 changed files with 325 additions and 65 deletions

View File

@@ -19,6 +19,7 @@ COPY package*.json ./
COPY --from=build-stage /app/dist /usr/share/nginx/html COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage /app/public/icons /usr/share/nginx/html/icons COPY --from=build-stage /app/public/icons /usr/share/nginx/html/icons
COPY --from=build-stage /app/public/fonts /usr/share/nginx/html/fonts
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY BuildConfig.sh /docker-entrypoint.d/10-build-config.sh COPY BuildConfig.sh /docker-entrypoint.d/10-build-config.sh
RUN chmod a+x /docker-entrypoint.d/10-build-config.sh RUN chmod a+x /docker-entrypoint.d/10-build-config.sh

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

207
public/fonts/fonts.css Normal file
View File

@@ -0,0 +1,207 @@
/* cyrillic-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(./-F6pfjptAgt5VM-kVkqdyU8n1ioa2Hdgv-s.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'IBM Plex Mono';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(./-F6pfjptAgt5VM-kVkqdyU8n1ioa0Xdgv-s.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'IBM Plex Mono';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(./-F6pfjptAgt5VM-kVkqdyU8n1ioa2ndgv-s.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(./-F6pfjptAgt5VM-kVkqdyU8n1ioa23dgv-s.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'IBM Plex Mono';
font-style: italic;
font-weight: 400;
font-display: swap;
src: url(./-F6pfjptAgt5VM-kVkqdyU8n1ioa1Xdg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./-F63fjptAgt5VM-kVkqdyU8n1iIq129k.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./-F63fjptAgt5VM-kVkqdyU8n1isq129k.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./-F63fjptAgt5VM-kVkqdyU8n1iAq129k.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./-F63fjptAgt5VM-kVkqdyU8n1iEq129k.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./-F63fjptAgt5VM-kVkqdyU8n1i8q1w.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3twJwl1FgtIU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3twJwlRFgtIU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3twJwl9FgtIU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3twJwl5FgtIU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3twJwlBFgg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* cyrillic-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3vAOwl1FgtIU.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3vAOwlRFgtIU.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* vietnamese */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3vAOwl9FgtIU.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3vAOwl5FgtIU.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(./-F6qfjptAgt5VM-kVkqdyU8n3vAOwlBFgg.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* vietnamese */
@font-face {
font-family: 'Major Mono Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./RWmVoLyb5fEqtsfBX9PDZIGr2tFubRh7AneREnc.woff2) format('woff2');
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Major Mono Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./RWmVoLyb5fEqtsfBX9PDZIGr2tFubRh7A3eREnc.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Major Mono Display';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(./RWmVoLyb5fEqtsfBX9PDZIGr2tFubRh7DXeR.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

View File

@@ -0,0 +1,44 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 733.000000 733.000000" role="img" aria-label="Hangman Lab">
<g transform="translate(0.000000,733.000000) scale(0.100000,-0.100000)"
fill="#d8ff3e" stroke="none">
<path d="M812 6860 c-66 -40 -73 -66 -70 -242 3 -141 5 -159 24 -185 43 -58
63 -63 262 -64 l182 -1 0 -2694 0 -2694 -290 0 c-314 0 -332 -3 -380 -54 -24
-27 -25 -32 -28 -199 -3 -195 4 -218 71 -250 32 -16 257 -17 3084 -17 2955 0
3049 1 3083 19 65 34 75 66 75 236 0 186 -16 224 -104 254 -25 8 -682 11
-2512 11 l-2479 0 0 1998 0 1997 698 697 697 697 670 -3 c369 -2 680 -4 693
-5 22 -1 22 -1 22 -269 l0 -268 84 -12 c47 -7 103 -19 125 -27 41 -14 41 -14
43 283 l3 297 631 1 c698 2 673 -1 714 67 18 28 20 51 20 187 0 173 -8 201
-72 240 -33 20 -56 20 -2623 20 -2567 0 -2590 0 -2623 -20z m1725 -500 c-1 -3
-183 -185 -404 -404 l-403 -399 0 405 0 406 405 -1 c223 -1 404 -4 402 -7z
M4283 5701 c-459 -125 -690 -624 -483 -1046 67 -138 196 -266 335 -335 281
-139 612 -93 837 118 235 219 297 575 152 870 -85 174 -235 306 -427 375 -111
40 -302 48 -414 18z m267 -211 c95 -15 201 -70 274 -144 273 -274 173 -723
-189 -851 -93 -33 -236 -35 -326 -5 -202 68 -340 249 -356 465 -18 242 153
471 394 529 71 18 119 19 203 6z M5945 4716 c-56 -25 -80 -61 -80 -122 0 -48
4 -57 36 -90 88 -88 219 -29 219 98 0 45 -34 96 -75 114 -42 17 -61 17 -100 0z
M5675 4466 c-60 -26 -73 -109 -26 -157 62 -61 161 -19 161 70 0 74 -68 118
-135 87z M3747 4397 c-10 -7 -226 -223 -479 -482 -307 -313 -467 -483 -479
-510 -35 -75 -17 -177 38 -227 39 -35 114 -61 160 -54 100 13 104 17 583 554
l145 162 3 -404 c3 -455 15 -342 -137 -1186 -76 -423 -101 -587 -101 -664 0
-190 182 -307 377 -242 62 21 136 95 152 152 6 22 29 188 52 369 57 466 109
839 118 848 4 4 52 6 106 5 l99 -3 67 -210 c38 -115 68 -220 69 -232 0 -12
-38 -152 -85 -311 -47 -159 -85 -302 -85 -317 0 -128 109 -225 255 -225 109 1
185 42 228 125 26 51 237 683 237 710 0 11 -54 182 -121 380 -121 360 -121
360 -134 605 -8 135 -14 292 -14 350 l0 105 152 -158 c84 -87 166 -167 182
-177 44 -29 98 -26 135 8 38 35 187 379 173 401 -5 8 -34 20 -64 26 -59 11
-38 -8 -393 362 -89 93 -100 97 -174 59 -59 -30 -161 -62 -229 -71 -52 -7 -53
-7 -53 -41 0 -44 -21 -84 -61 -118 -38 -32 -41 0 32 -455 l52 -325 -82 -78
c-45 -43 -85 -78 -89 -78 -4 0 -42 35 -84 78 l-77 77 34 215 c19 118 46 289
61 379 26 164 26 164 -5 188 -42 33 -54 58 -61 121 -5 54 -5 54 -92 87 -98 38
-184 89 -243 145 -76 70 -123 87 -168 57z M5504 4170 c-74 -30 -69 -170 6
-170 19 0 20 -7 20 -123 0 -122 0 -122 -54 -262 -30 -77 -97 -243 -150 -369
-106 -252 -113 -287 -73 -347 46 -70 38 -69 560 -69 327 0 475 3 490 11 69 35
107 109 88 172 -5 17 -62 142 -126 277 -225 470 -215 443 -215 586 0 114 2
124 18 124 57 0 72 101 23 151 -29 29 -29 29 -298 28 -147 0 -278 -4 -289 -9z
m376 -307 c1 -148 1 -148 81 -333 101 -231 98 -222 68 -216 -13 3 -116 22
-229 42 -112 19 -208 37 -212 40 -4 2 18 75 48 160 54 156 54 156 54 305 l0
149 95 0 95 0 0 -147z m-219 -593 c22 0 49 -42 49 -75 0 -46 -29 -75 -74 -75
-37 0 -76 36 -76 71 0 46 45 94 78 83 8 -2 18 -4 23 -4z m327 -126 c53 -59 -7
-144 -80 -113 -54 22 -65 83 -22 125 30 31 67 27 102 -12z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -5,20 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="color-scheme" content="dark"> <meta name="color-scheme" content="dark">
<title>Hangman Lab</title> <title>Hangman Lab</title>
<link rel="icon" type="image/png" href="./icons/logo.png"> <link rel="icon" type="image/svg+xml" href="./icons/hangman-lab-logo.svg?v=hl-20260517">
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="stylesheet" href="/fonts/fonts.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<link
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css"
rel="stylesheet"
/>
</body> </body>
</html> </html>

View File

@@ -12,7 +12,7 @@
} }
code { code {
font-family: ui-monospace, "JetBrains Mono", "Courier New", Courier, monospace; font-family: ui-monospace, "IBM Plex Mono", "Courier New", Courier, monospace;
background-color: hsl(var(--muted)); background-color: hsl(var(--muted));
color: hsl(var(--foreground)); color: hsl(var(--foreground));
padding: 2px 6px; padding: 2px 6px;

View File

@@ -34,7 +34,7 @@
.markdown-preview h4, .markdown-preview h4,
.markdown-preview h5, .markdown-preview h5,
.markdown-preview h6 { .markdown-preview h6 {
font-family: "JetBrains Mono", ui-monospace, monospace; font-family: "IBM Plex Mono", ui-monospace, monospace;
font-weight: 600; font-weight: 600;
color: hsl(var(--foreground)); color: hsl(var(--foreground));
line-height: 1.3; line-height: 1.3;
@@ -108,7 +108,7 @@
/* Inline code */ /* Inline code */
.markdown-preview :not(pre) > code { .markdown-preview :not(pre) > code {
font-family: "JetBrains Mono", ui-monospace, monospace; font-family: "IBM Plex Mono", ui-monospace, monospace;
font-size: 0.85em; font-size: 0.85em;
background-color: hsl(var(--muted)); background-color: hsl(var(--muted));
color: hsl(var(--primary)); color: hsl(var(--primary));
@@ -128,7 +128,7 @@
box-shadow: inset 0 0 40px -20px hsl(var(--primary) / 0.25); box-shadow: inset 0 0 40px -20px hsl(var(--primary) / 0.25);
} }
.markdown-preview pre code { .markdown-preview pre code {
font-family: "JetBrains Mono", ui-monospace, monospace; font-family: "IBM Plex Mono", ui-monospace, monospace;
font-size: 0.85rem; font-size: 0.85rem;
background: transparent; background: transparent;
border: none; border: none;
@@ -150,7 +150,7 @@
} }
.markdown-preview th { .markdown-preview th {
background-color: hsl(var(--muted)); background-color: hsl(var(--muted));
font-family: "JetBrains Mono", ui-monospace, monospace; font-family: "IBM Plex Mono", ui-monospace, monospace;
font-size: 0.8rem; font-size: 0.8rem;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.04em; letter-spacing: 0.04em;

View File

@@ -124,13 +124,13 @@ const MainNavigation = () => {
className="group flex items-center gap-2.5 pr-3" className="group flex items-center gap-2.5 pr-3"
> >
<img <img
src="/icons/logo.png" src="/icons/hangman-lab-logo.svg"
alt="Logo" alt="Hangman Lab"
className="h-7 w-7 rounded" className="h-7 w-7"
/> />
<span className="font-mono text-sm font-semibold tracking-tight"> <span className="font-display text-base leading-none tracking-tight">
<span className="text-foreground">HANGMAN</span> <span className="text-foreground">hangman</span>
<span className="neon-text">//LAB</span> <span className="neon-text"> lab</span>
</span> </span>
</Link> </Link>

View File

@@ -2,37 +2,40 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
/* Dark-tech design tokens (single dark theme). HSL triplets so Tailwind /* Lab-terminal theme — adapted from the Gitea STYLE.md for this React app.
color utilities and shadcn-style primitives resolve via hsl(var(--x)). */ Single acid accent (#d8ff3e), dark blueprint surfaces, monospace UI.
HSL triplets so Tailwind / shadcn-style primitives resolve hsl(var(--x)). */
:root, :root,
.dark { .dark {
--background: 222 32% 6%; --background: 216 24% 4%; /* #080a0d ink */
--foreground: 210 22% 92%; --foreground: 217 35% 86%; /* #cdd8e8 text */
--surface: 222 28% 8.5%; --surface: 214 29% 8%; /* #0f141b panel */
--card: 222 26% 9.5%; --card: 214 29% 8%;
--card-foreground: 210 22% 92%; --card-foreground: 217 38% 95%; /* #e9f0fa strong text */
--muted: 222 20% 14%; --muted: 214 27% 12%; /* hovered panel */
--muted-foreground: 215 16% 60%; --muted-foreground: 216 18% 48%; /* #647691 dim / eyebrow */
--accent: 222 24% 13%; --accent: 214 27% 11%; /* row/element hover wash base */
--accent-foreground: 210 22% 92%; --accent-foreground: 217 35% 86%;
--border: 220 18% 18%; --border: 213 28% 16%; /* #1d2733 lines / dividers */
--input: 220 18% 16%; --input: 213 28% 14%;
--ring: 186 92% 56%; --ring: 72 100% 62%; /* acid focus ring */
/* cyan primary, violet secondary — the neon accents */ /* THE accent — one acid, used for links/primary/active/focus. */
--primary: 186 92% 56%; --primary: 72 100% 62%; /* #d8ff3e */
--primary-foreground: 222 47% 6%; --primary-foreground: 96 24% 5%; /* #0c0f08 text on acid */
--secondary: 258 90% 68%; /* No second hue (STYLE: "one acid"). Secondary == acid so any
--secondary-foreground: 0 0% 100%; component using it stays on-brand. */
--secondary: 72 100% 62%;
--secondary-foreground: 96 24% 5%;
--destructive: 0 72% 56%; --destructive: 3 100% 66%; /* #ff5a52 errors only */
--destructive-foreground: 0 0% 100%; --destructive-foreground: 0 0% 100%;
--radius: 0.5rem; --radius: 0.75rem;
} }
* { * {
@@ -45,25 +48,37 @@ body,
height: 100%; height: 100%;
} }
html {
background-color: hsl(var(--background));
/* Larger base so all rem-based UI text scales up. */
font-size: 18px;
}
body { body {
margin: 0; margin: 0;
background-color: hsl(var(--background)); background-color: transparent;
color: hsl(var(--foreground)); color: hsl(var(--foreground));
font-family: Inter, ui-sans-serif, system-ui, sans-serif; font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
/* Ambient grid + glow backdrop for the app shell */ /* Site-wide blueprint grid backdrop (STYLE §11.2): fixed, behind content,
48px #1d2733 lines at low opacity, radial-masked, plus one acid sheen. */
body::before { body::before {
content: ""; content: "";
position: fixed; position: fixed;
inset: 0; inset: 0;
z-index: -1;
pointer-events: none; pointer-events: none;
z-index: 0; background-color: hsl(var(--background));
background: background-image:
radial-gradient(60rem 60rem at 110% -10%, hsl(258 90% 68% / 0.10), transparent 60%), radial-gradient(1000px 560px at 78% -8%, hsl(72 100% 62% / 0.10), transparent 60%),
radial-gradient(50rem 50rem at -10% 110%, hsl(186 92% 56% / 0.08), transparent 60%); linear-gradient(hsl(213 28% 16% / 0.16) 1px, transparent 1px),
linear-gradient(90deg, hsl(213 28% 16% / 0.16) 1px, transparent 1px);
background-size: 100% 100%, 48px 48px, 48px 48px;
-webkit-mask-image: radial-gradient(ellipse 90% 80% at 50% 30%, #000 55%, transparent 100%);
mask-image: radial-gradient(ellipse 90% 80% at 50% 30%, #000 55%, transparent 100%);
} }
::selection { ::selection {
@@ -71,7 +86,6 @@ body::before {
color: hsl(var(--foreground)); color: hsl(var(--foreground));
} }
/* Slim techy scrollbars */
* { * {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: hsl(var(--border)) transparent; scrollbar-color: hsl(var(--border)) transparent;
@@ -89,16 +103,24 @@ body::before {
} }
@layer utilities { @layer utilities {
/* Display lockup font — always lowercase per STYLE §3. */
.font-display {
font-family: "Major Mono Display", "IBM Plex Mono", monospace;
text-transform: lowercase;
}
.neon-text { .neon-text {
color: hsl(var(--primary)); color: hsl(var(--primary));
text-shadow: 0 0 12px hsl(var(--primary) / 0.55); text-shadow: 0 0 44px hsl(var(--primary) / 0.38);
} }
/* kept for compatibility with components that used the old violet
accent — now the same single acid. */
.neon-text-violet { .neon-text-violet {
color: hsl(var(--secondary)); color: hsl(var(--primary));
text-shadow: 0 0 12px hsl(var(--secondary) / 0.55); text-shadow: 0 0 44px hsl(var(--primary) / 0.38);
} }
.glass { .glass {
background: hsl(var(--surface) / 0.7); background: hsl(214 29% 8% / 0.55);
backdrop-filter: blur(10px); backdrop-filter: blur(16px) saturate(150%);
border: 1px solid hsl(var(--primary) / 0.16);
} }
} }

View File

@@ -42,15 +42,10 @@ module.exports = {
sm: "calc(var(--radius) - 4px)", sm: "calc(var(--radius) - 4px)",
}, },
fontFamily: { fontFamily: {
sans: ["Inter", "ui-sans-serif", "system-ui", "sans-serif"], // Lab-terminal: IBM Plex Mono is the body/UI/mono face.
mono: [ sans: ["IBM Plex Mono", "ui-monospace", "SFMono-Regular", "monospace"],
"JetBrains Mono", mono: ["IBM Plex Mono", "ui-monospace", "SFMono-Regular", "monospace"],
"Fira Code", display: ["Major Mono Display", "IBM Plex Mono", "monospace"],
"ui-monospace",
"SFMono-Regular",
"Menlo",
"monospace",
],
}, },
boxShadow: { boxShadow: {
glow: "0 0 0 1px hsl(var(--primary) / 0.25), 0 0 24px -6px hsl(var(--primary) / 0.45)", glow: "0 0 0 1px hsl(var(--primary) / 0.25), 0 0 24px -6px hsl(var(--primary) / 0.45)",