case0 / web /src /styles /pixel.css
HusseinEid's picture
Case Zero - initial public release (fully local: Qwen2.5-1.5B via llama.cpp + Supertonic, custom pixel-noir SPA via gradio.Server)
414dc55
raw
history blame
9.93 kB
/* ============================================================
CASE ZERO — pixel-art noir design system
Palette: blue-black shadows · desaturated teal/slate mids ·
warm sodium-amber (single light source) · oxblood (danger) ·
bone-white (key text)
Fonts are self-hosted via @fontsource (imported in main.tsx) — no network at runtime.
============================================================ */
/* ---------- palette variants ---------- */
:root,
[data-palette="sodium"]{
--ink-0:#080b10; --ink-1:#0d1117; --ink-2:#11202a; --ink-3:#1b2d38;
--slate-1:#2d4a52; --slate-2:#3a6b6b; --slate-3:#5d8a8a;
--amber-1:#b9772f; --amber-2:#e0a44c; --amber-3:#f5d08a;
--ox-1:#5e1c1c; --ox-2:#8a2a2a; --ox-3:#c23b3b;
--bone-1:#9a937e; --bone-2:#e0d9c4; --bone-3:#f5f1e6;
--glow:#e0a44c;
}
[data-palette="harbor"]{
--ink-0:#060a0f; --ink-1:#0a0e14; --ink-2:#0f1d26; --ink-3:#16242e;
--slate-1:#2c5151; --slate-2:#3a6b6b; --slate-3:#62989a;
--amber-1:#c2842f; --amber-2:#f0b860; --amber-3:#ffd98f;
--ox-1:#661f1f; --ox-2:#a33636; --ox-3:#d24a4a;
--bone-1:#a39d88; --bone-2:#eae3cf; --bone-3:#f7f3e8;
--glow:#f0b860;
}
[data-palette="violet"]{
--ink-0:#08060e; --ink-1:#0e0c14; --ink-2:#171425; --ink-3:#221d33;
--slate-1:#33344e; --slate-2:#46506b; --slate-3:#6b7396;
--amber-1:#b4802f; --amber-2:#d99a3c; --amber-3:#f0c071;
--ox-1:#5e1d2a; --ox-2:#922d3a; --ox-3:#c4485a;
--bone-1:#9690a0; --bone-2:#e6e0d4; --bone-3:#f4f0ea;
--glow:#d99a3c;
}
/* ---------- light precinct mood (daytime / bright bullpen) ---------- */
[data-mood="day"]{
--ink-0:#cdc6b2; --ink-1:#d8d2bf; --ink-2:#c6c0ac; --ink-3:#b8b29c;
--slate-1:#8a9a96; --slate-2:#6f8a88; --slate-3:#577070;
--bone-1:#5a5544; --bone-2:#2a2820; --bone-3:#15140f;
--glow:#b9772f;
}
/* ---------- font pairing variants ---------- */
:root,
[data-fonts="crisp"]{
--f-display:'Silkscreen', monospace;
--f-mono:'VT323', monospace;
--f-body:'Pixelify Sans', monospace;
--mono-scale:1.25;
}
[data-fonts="terminal"]{
--f-display:'VT323', monospace;
--f-mono:'VT323', monospace;
--f-body:'VT323', monospace;
--mono-scale:1.35;
}
[data-fonts="stamp"]{
--f-display:'Silkscreen', monospace;
--f-mono:'Silkscreen', monospace;
--f-body:'Pixelify Sans', monospace;
--mono-scale:1.0;
}
/* ---------- reset ---------- */
*{ box-sizing:border-box; margin:0; padding:0; }
html,body{ height:100%; }
body{
background:var(--ink-0);
color:var(--bone-2);
font-family:var(--f-body);
-webkit-font-smoothing:none;
font-smooth:never;
overflow:hidden;
}
img,canvas{ image-rendering:pixelated; image-rendering:crisp-edges; }
button{ font-family:inherit; color:inherit; cursor:pointer; }
input,textarea{ font-family:var(--f-body); }
::selection{ background:var(--amber-2); color:var(--ink-0); }
/* ---------- type scale ---------- */
.t-display{ font-family:var(--f-display); letter-spacing:.04em; line-height:1.05; text-transform:uppercase; }
.t-mono{ font-family:var(--f-mono); letter-spacing:.02em; }
.t-mono-lg{ font-family:var(--f-mono); font-size:calc(1.5rem * var(--mono-scale)); letter-spacing:.04em; }
.t-label{ font-family:var(--f-display); font-size:10px; letter-spacing:.14em; text-transform:uppercase; color:var(--bone-1); }
.t-body{ font-family:var(--f-body); font-size:17px; line-height:1.5; }
.amber{ color:var(--amber-2); }
.ox{ color:var(--ox-3); }
.bone{ color:var(--bone-3); }
.dim{ color:var(--bone-1); }
/* ============================================================
9-SLICE PIXEL PANELS — beveled, no border-radius ever
============================================================ */
.panel{
position:relative;
background:var(--ink-2);
border:3px solid var(--ink-0);
box-shadow:
inset 0 0 0 3px var(--ink-3),
inset 3px 3px 0 3px rgba(93,138,138,.12),
inset -3px -3px 0 3px rgba(0,0,0,.45),
0 0 0 1px var(--ink-0);
padding:18px;
}
.panel--raised{ background:var(--ink-3); }
.panel--inset{
background:var(--ink-1);
box-shadow:
inset 0 0 0 3px var(--ink-0),
inset 3px 3px 0 3px rgba(0,0,0,.5),
inset -3px -3px 0 3px rgba(93,138,138,.06);
}
.panel--amber{ border-color:var(--amber-1);
box-shadow:inset 0 0 0 2px var(--amber-1), 0 0 24px -6px var(--glow); }
.panel--ox{ border-color:var(--ox-1);
box-shadow:inset 0 0 0 2px var(--ox-1), 0 0 22px -8px var(--ox-3); }
.panel__tab{
position:absolute; top:-11px; left:14px;
background:var(--amber-2); color:var(--ink-0);
font-family:var(--f-display); font-size:9px; letter-spacing:.12em;
padding:4px 8px; text-transform:uppercase;
box-shadow:2px 2px 0 var(--ink-0);
}
/* ---------- pixel buttons ---------- */
.pbtn{
font-family:var(--f-display); font-size:11px; letter-spacing:.08em;
text-transform:uppercase; white-space:nowrap;
color:var(--bone-3); background:var(--slate-1);
border:0; padding:13px 18px;
box-shadow:
inset -3px -3px 0 0 rgba(0,0,0,.45),
inset 3px 3px 0 0 rgba(255,255,255,.12),
0 0 0 3px var(--ink-0);
transition:transform .04s steps(1);
position:relative;
}
.pbtn:hover{ background:var(--slate-2); color:var(--ink-0); }
.pbtn:active{
transform:translate(2px,2px);
box-shadow:
inset 3px 3px 0 0 rgba(0,0,0,.4),
0 0 0 3px var(--ink-0);
}
.pbtn--amber{ background:var(--amber-2); color:var(--ink-0); }
.pbtn--amber:hover{ background:var(--amber-3); }
.pbtn--ox{ background:var(--ox-2); color:var(--bone-3); }
.pbtn--ox:hover{ background:var(--ox-3); }
.pbtn--ghost{ background:rgba(13,17,23,.66); color:var(--bone-1);
box-shadow:inset 0 0 0 2px var(--slate-1); }
.pbtn--ghost:hover{ color:var(--bone-3); background:rgba(13,17,23,.85); box-shadow:inset 0 0 0 2px var(--slate-3); }
.pbtn:disabled{ opacity:.4; cursor:not-allowed; }
.pbtn--sm{ font-size:9px; padding:8px 11px; }
/* ---------- chips / tags ---------- */
.chip{
display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
font-family:var(--f-mono); font-size:calc(15px * var(--mono-scale));
line-height:1; padding:4px 8px;
background:var(--ink-1); color:var(--bone-1);
box-shadow:inset 0 0 0 2px var(--slate-1);
}
.chip--amber{ color:var(--amber-2); box-shadow:inset 0 0 0 2px var(--amber-1); }
.chip--ox{ color:var(--ox-3); box-shadow:inset 0 0 0 2px var(--ox-1); }
/* ============================================================
SUSPICION / COMPOSURE BAR
============================================================ */
.bar{
height:16px; background:var(--ink-1);
box-shadow:inset 0 0 0 2px var(--ink-0), inset 2px 2px 0 2px rgba(0,0,0,.5);
position:relative; overflow:hidden;
}
.bar__fill{
height:100%;
background:
repeating-linear-gradient(90deg, transparent 0 6px, rgba(0,0,0,.18) 6px 8px),
linear-gradient(var(--ox-3), var(--ox-2));
transition:width .5s steps(12);
box-shadow:inset 0 2px 0 rgba(255,255,255,.18);
}
.bar__fill--calm{ background:
repeating-linear-gradient(90deg, transparent 0 6px, rgba(0,0,0,.18) 6px 8px),
linear-gradient(var(--slate-3), var(--slate-1)); }
/* ============================================================
ATMOSPHERE — scanlines, vignette, lamp glow, rain
============================================================ */
.fx-layer{ position:fixed; inset:0; pointer-events:none; z-index:60; }
.fx-scanlines{
background:repeating-linear-gradient(
to bottom, rgba(0,0,0,0) 0, rgba(0,0,0,0) 2px,
rgba(0,0,0,.16) 3px, rgba(0,0,0,.16) 3px);
mix-blend-mode:multiply;
opacity:var(--fx-scan, .6);
}
.fx-vignette{
background:radial-gradient(120% 90% at 50% 38%,
transparent 40%, rgba(0,0,0,.4) 78%, rgba(0,0,0,.72) 100%);
opacity:var(--fx-vig, 1);
}
.fx-flicker{ animation:flicker 6s steps(1) infinite; background:var(--glow); opacity:0; mix-blend-mode:overlay; }
@keyframes flicker{
0%,97%,100%{ opacity:0; } 97.5%{ opacity:.05; } 98%{ opacity:.02; } 98.5%{ opacity:.06; }
}
[data-fx="low"]{ --fx-scan:.25; --fx-vig:.6; }
[data-fx="med"]{ --fx-scan:.55; --fx-vig:1; }
[data-fx="high"]{ --fx-scan:.85; --fx-vig:1.25; }
[data-fx="low"] .fx-rain, [data-fx="low"] .fx-flicker{ display:none; }
.fx-rain{ opacity:var(--fx-rain,.5); }
@media (prefers-reduced-motion: reduce){
.fx-flicker{ animation:none; }
}
/* ---------- blinking cursor ---------- */
.cursor::after{
content:'▮'; color:var(--amber-2);
animation:blink 1s steps(1) infinite; margin-left:2px;
}
@keyframes blink{ 50%{ opacity:0; } }
/* ---------- scrollbars ---------- */
*::-webkit-scrollbar{ width:10px; height:10px; }
*::-webkit-scrollbar-track{ background:var(--ink-1); }
*::-webkit-scrollbar-thumb{ background:var(--slate-1); border:2px solid var(--ink-1); }
*::-webkit-scrollbar-thumb:hover{ background:var(--slate-2); }
/* ---------- pixel divider ---------- */
.hr-pixel{
height:3px; background:repeating-linear-gradient(90deg,
var(--slate-1) 0 4px, transparent 4px 8px);
border:0;
}
/* ---------- dithered fill helper ---------- */
.dither-amber{
background-image:
radial-gradient(rgba(224,164,76,.5) 1px, transparent 1px);
background-size:4px 4px;
}
/* ---------- stamp ---------- */
.stamp{
font-family:var(--f-display); text-transform:uppercase;
color:var(--ox-3);
border:4px solid var(--ox-3);
padding:8px 14px; letter-spacing:.06em;
box-shadow:0 0 0 2px var(--ink-0);
transform:rotate(-6deg);
mix-blend-mode:screen;
}
.stamp--slam{ animation:slam .45s cubic-bezier(.2,1.4,.3,1) both; }
@keyframes slam{
0%{ transform:rotate(-6deg) scale(3); opacity:0; }
60%{ transform:rotate(-6deg) scale(.92); opacity:1; }
100%{ transform:rotate(-6deg) scale(1); opacity:1; }
}
/* utility */
.row{ display:flex; gap:12px; }
.col{ display:flex; flex-direction:column; gap:12px; }
.center{ display:flex; align-items:center; justify-content:center; }
.between{ display:flex; align-items:center; justify-content:space-between; }
.wrap{ flex-wrap:wrap; }
.grow{ flex:1; }
.scroll-y{ overflow-y:auto; }
.nowrap{ white-space:nowrap; }