CI / Typecheck, lint, tests, e2e (push) Failing after 3m51s
- Title screen over a real-time voxel office rendered at low resolution and quantized to a rotating 32-colour palette with Bayer dithering; day part and season re-light the scene and every surface. - 16-bit UI kit: name-plate dialogs, menu cursor, inventory, XP bar, badges, NPC speech, GAME OVER with CONTINUE, hand-placed 12x12 icons, Fusion Pixel font (Latin subset preloaded). - Sections as a game: quest log (onboarding), character select (AI CEO / AI Co-Founder), inventory (features), party roster (providers), live download XP, save point (all v1.5.1 builds), FAQ as NPC dialog, credits. - Downloads and source point to the Gitea release; the download function only redirects to git.zacharyzhang.com. - Tailwind and the old components removed; unit tests for platform/downloads, rewritten e2e suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
185 lines
8.0 KiB
CSS
185 lines
8.0 KiB
CSS
/* Fusion Pixel 12px (OFL, see /fonts/fusion-pixel-licenses): a small Latin subset, and the full CJK file only when CJK text appears. */
|
||
@font-face {
|
||
font-family: "Fusion Pixel";
|
||
font-display: swap;
|
||
src: url("/fonts/FusionPixel-12px-zh_hans.woff2") format("woff2");
|
||
unicode-range: U+3000-303F, U+4E00-4E2C, U+4E2E-4F52, U+4F54-6586, U+6588-7B7F, U+7B81-9FFF, U+FF00-FFEF;
|
||
}
|
||
@font-face {
|
||
font-family: "Fusion Pixel";
|
||
font-display: swap;
|
||
src: url("/fonts/FusionPixel-12px-latin.woff2") format("woff2");
|
||
unicode-range: U+0020-007E, U+00A0-00FF, U+2010-2027, U+2030-203A, U+2122, U+2190-21FF, U+2500-26FF, U+4E2D, U+4F53, U+6587, U+7B80;
|
||
}
|
||
|
||
/* Palette inks are registered colours so a palette swap fades in four hard steps, like a 16-bit palette cycle. */
|
||
@property --ink-void { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-shadow { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-ink { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-ink-soft { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-stone { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-stone-light { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-paper { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-white { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sky-0 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sky-1 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sky-2 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sky-3 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sun { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-glow { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-cloud { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-star { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-wood { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-wood-dark { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-brick { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-rug { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-leaf-0 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-leaf-1 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-leaf-2 { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-bloom { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-accent { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-accent-dark { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-gold { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-mint { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-sea { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-berry { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-skin { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
@property --ink-screen { syntax: "<color>"; inherits: true; initial-value: #000; }
|
||
|
||
/* The day palette (lib/palette.ts) for first paint without script; PaletteClock overwrites these on <html>. */
|
||
:root {
|
||
--p0: #0b0a12; --p1: #1d1b2b; --p2: #2f2c40; --p3: #4a4660;
|
||
--p4: #6d6884; --p5: #9a95ad; --p6: #e9e2cf; --p7: #fbf7ec;
|
||
--p8: #3f7fd1; --p9: #68a2e6; --p10: #9cc6f2; --p11: #d4e8fa;
|
||
--p12: #ffe08a; --p13: #fff2c2; --p14: #f4f7fb; --p15: #ffffff;
|
||
--p16: #a8693c; --p17: #6e3f23; --p18: #b4533f; --p19: #5d6ea8;
|
||
--p20: #235c2e; --p21: #3f8f3f; --p22: #78c050; --p23: #ffd35c;
|
||
--p24: #e0663d; --p25: #9c3b22; --p26: #f2b632; --p27: #5fd3a8;
|
||
--p28: #2a8fa8; --p29: #c4466f; --p30: #f1c79a; --p31: #7ef0c2;
|
||
--ink-void: var(--p0); --ink-shadow: var(--p1); --ink-ink: var(--p2); --ink-ink-soft: var(--p3);
|
||
--ink-stone: var(--p4); --ink-stone-light: var(--p5); --ink-paper: var(--p6); --ink-white: var(--p7);
|
||
--ink-sky-0: var(--p8); --ink-sky-1: var(--p9); --ink-sky-2: var(--p10); --ink-sky-3: var(--p11);
|
||
--ink-sun: var(--p12); --ink-glow: var(--p13); --ink-cloud: var(--p14); --ink-star: var(--p15);
|
||
--ink-wood: var(--p16); --ink-wood-dark: var(--p17); --ink-brick: var(--p18); --ink-rug: var(--p19);
|
||
--ink-leaf-0: var(--p20); --ink-leaf-1: var(--p21); --ink-leaf-2: var(--p22); --ink-bloom: var(--p23);
|
||
--ink-accent: var(--p24); --ink-accent-dark: var(--p25); --ink-gold: var(--p26); --ink-mint: var(--p27);
|
||
--ink-sea: var(--p28); --ink-berry: var(--p29); --ink-skin: var(--p30); --ink-screen: var(--p31);
|
||
|
||
/* UI roles. Dawn, day and dusk are paper-and-ink; night (below) inverts to a lit-window look. */
|
||
--ui-ground: var(--ink-paper);
|
||
--ui-dither: var(--ink-white);
|
||
--ui-panel: var(--ink-white);
|
||
--ui-text: var(--ink-void);
|
||
--ui-muted: var(--ink-ink-soft);
|
||
--ui-line: var(--ink-void);
|
||
--ui-on-line: var(--ink-white);
|
||
--ui-hi: var(--ink-star);
|
||
--ui-lo: var(--ink-stone-light);
|
||
--ui-drop: var(--ink-stone-light);
|
||
--ui-focus: var(--ink-void);
|
||
--ui-danger: var(--ink-accent-dark);
|
||
--ui-select: var(--ink-accent-dark);
|
||
--ui-xp: var(--ink-mint);
|
||
--ui-xp-off: var(--ink-ink-soft);
|
||
|
||
/* --px snaps one font pixel to whole device pixels (set before paint by PaletteClock); --u is one 2× art pixel. */
|
||
--px: 1;
|
||
--u: calc(2px * var(--px));
|
||
--fs-1: calc(12px * var(--px));
|
||
--fs-2: calc(24px * var(--px));
|
||
--fs-3: calc(36px * var(--px));
|
||
--fs-4: calc(48px * var(--px));
|
||
|
||
color-scheme: light;
|
||
transition-property:
|
||
--ink-void, --ink-shadow, --ink-ink, --ink-ink-soft, --ink-stone, --ink-stone-light, --ink-paper, --ink-white,
|
||
--ink-sky-0, --ink-sky-1, --ink-sky-2, --ink-sky-3, --ink-sun, --ink-glow, --ink-cloud, --ink-star,
|
||
--ink-wood, --ink-wood-dark, --ink-brick, --ink-rug, --ink-leaf-0, --ink-leaf-1, --ink-leaf-2, --ink-bloom,
|
||
--ink-accent, --ink-accent-dark, --ink-gold, --ink-mint, --ink-sea, --ink-berry, --ink-skin, --ink-screen;
|
||
transition-duration: 600ms;
|
||
transition-timing-function: steps(4, jump-end);
|
||
}
|
||
|
||
:root[data-daypart="night"] {
|
||
--ui-ground: var(--ink-shadow);
|
||
--ui-dither: var(--ink-void);
|
||
--ui-panel: var(--ink-ink);
|
||
--ui-text: var(--ink-star);
|
||
--ui-muted: var(--ink-glow);
|
||
--ui-line: var(--ink-glow);
|
||
--ui-on-line: var(--ink-void);
|
||
--ui-hi: var(--ink-stone);
|
||
--ui-lo: var(--ink-void);
|
||
--ui-drop: var(--ink-void);
|
||
--ui-focus: var(--ink-gold);
|
||
--ui-danger: var(--ink-accent);
|
||
--ui-select: var(--ink-accent);
|
||
--ui-xp-off: var(--ink-stone);
|
||
color-scheme: dark;
|
||
}
|
||
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
min-height: 100vh;
|
||
color: var(--ui-text);
|
||
font-family: "Fusion Pixel", ui-monospace, monospace;
|
||
font-size: var(--fs-1);
|
||
line-height: 1.5;
|
||
font-synthesis: none;
|
||
-webkit-font-smoothing: none;
|
||
text-rendering: optimizeSpeed;
|
||
image-rendering: pixelated;
|
||
overflow-x: clip;
|
||
/* Ground: a sparse two-colour dither, one art pixel lit in every 4×4 block on alternating diagonals. */
|
||
background:
|
||
conic-gradient(from 270deg at var(--u) var(--u), var(--ui-dither) 25%, transparent 0) 0 0 / calc(4 * var(--u)) calc(4 * var(--u)),
|
||
conic-gradient(from 270deg at var(--u) var(--u), var(--ui-dither) 25%, transparent 0) calc(2 * var(--u)) calc(2 * var(--u)) / calc(4 * var(--u)) calc(4 * var(--u)),
|
||
var(--ui-ground);
|
||
}
|
||
|
||
h1, h2, h3, h4, h5, h6, b, strong, th {
|
||
font-weight: normal;
|
||
}
|
||
|
||
a {
|
||
color: inherit;
|
||
}
|
||
|
||
button, input, select, textarea {
|
||
font: inherit;
|
||
color: inherit;
|
||
}
|
||
|
||
img, svg, canvas, video {
|
||
image-rendering: pixelated;
|
||
}
|
||
|
||
::selection {
|
||
background: var(--ink-gold);
|
||
color: var(--ink-void);
|
||
}
|
||
|
||
:focus-visible {
|
||
outline: var(--u) solid var(--ui-focus);
|
||
outline-offset: var(--u);
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
:root {
|
||
transition: none;
|
||
}
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
animation: none !important;
|
||
transition: none !important;
|
||
scroll-behavior: auto !important;
|
||
}
|
||
}
|