feat(web): adopt cyberspace terminal aesthetic + dithered images
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
ci / web (push) Has been cancelled
Desktop App / Build Linux (amd64) (push) Has been cancelled
Desktop App / Attach to Release (push) Has been cancelled

Rebrand light/dark themes to the cyberspace.online look: warm cream-on-black
palette (light/dark are exact inverses), self-hosted JetBrains Mono + VT323,
square corners, border-driven surfaces with no soft shadows. Adds a terminal
design-system CSS layer (DOS double-border modals with hatched corner, fg focus,
inversion-on-hover), a theme-aware <RasterImage> (Atkinson-dithered canvas with
img fallback), and unifies desktop icons, taskbar, window controls, pills and
links under one idiom. Pins window titlebars to a fixed height and switches chat
auto-scroll off scrollIntoView to avoid titlebar reflow.

VERSION 0.15.1 -> 0.16.0
This commit is contained in:
2026-08-03 22:03:24 +02:00
parent b27e1bf3ec
commit 757ef2f34b
18 changed files with 554 additions and 139 deletions

View File

@@ -53,10 +53,10 @@
}
</script>
<div class="flex h-11 shrink-0 items-center gap-1.5 border-t bg-muted/30 px-2">
<div class="flex h-11 shrink-0 items-center gap-1.5 border-t border-border bg-background px-2">
<button
type="button"
class="flex shrink-0 items-center justify-center rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
class="flex shrink-0 items-center justify-center border border-border p-1.5 text-muted-foreground transition-colors hover:border-foreground hover:bg-foreground hover:text-background"
onclick={toggleShowDesktop}
title="Show desktop"
>
@@ -65,7 +65,7 @@
<div class="h-6 w-px shrink-0 bg-border"></div>
<div class="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto">
<div class="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto py-1.5">
{#each buttons as win (win.id)}
{@const Icon = iconFor(win.id)}
{@const badge = badgeFor(win.id)}
@@ -73,12 +73,12 @@
<button
type="button"
data-taskbar-btn={win.id}
class="flex h-8 max-w-56 items-center gap-1.5 rounded-md border px-2 font-mono text-xs transition-colors {$wmState.focusedId ===
class="flex h-8 max-w-56 items-center gap-1.5 border px-2 font-mono text-xs transition-colors {$wmState.focusedId ===
win.id && win.stage !== 'minimized'
? 'border-primary/50 bg-primary/10 text-foreground'
: 'border-transparent bg-card/60 text-muted-foreground hover:bg-muted'} {win.stage ===
? 'border-foreground bg-foreground text-background'
: 'border-border bg-background text-muted-foreground hover:border-foreground hover:bg-foreground hover:text-background'} {win.stage ===
'minimized'
? 'opacity-60'
? 'opacity-50'
: ''}"
onclick={() => toggle(win.id, win)}
title={win.title}
@@ -87,7 +87,7 @@
<span class="min-w-0 truncate">{truncateMiddle(win.title, 26)}</span>
{#if badge > 0}
<span
class="flex h-3.5 min-w-3.5 shrink-0 items-center justify-center rounded-full bg-destructive px-1 text-[9px] font-semibold text-destructive-foreground"
class="flex h-3.5 min-w-3.5 shrink-0 items-center justify-center border border-background bg-destructive px-1 text-[9px] font-semibold text-destructive-foreground"
>
{badge > 99 ? '99+' : badge}
</span>
@@ -95,7 +95,7 @@
</button>
<button
type="button"
class="absolute -top-1.5 -right-1.5 hidden size-4 items-center justify-center rounded-full bg-muted-foreground/80 text-background hover:bg-destructive group-hover/tb:flex"
class="win-ctrl absolute -top-1.5 -right-1.5 hidden size-4 group-hover/tb:flex"
onclick={(e) => {
e.stopPropagation()
wm.close(win.id)
@@ -113,7 +113,7 @@
<div class="flex shrink-0 items-center gap-0.5">
<button
type="button"
class="flex items-center justify-center rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
class="flex items-center justify-center border border-border p-1.5 text-muted-foreground transition-colors hover:border-foreground hover:bg-foreground hover:text-background"
onclick={() => toggleTheme()}
title="Cycle theme ({THEME_LABELS[getTheme()]})"
aria-label="Cycle theme, currently {THEME_LABELS[getTheme()]}"
@@ -122,12 +122,12 @@
</button>
<button
type="button"
class="flex items-center justify-center rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
class="flex items-center justify-center border border-border p-1.5 text-muted-foreground transition-colors hover:border-foreground hover:bg-foreground hover:text-background"
onclick={() => openAppWindow('settings')}
title="Settings"
>
<SettingsIcon class="size-4" />
</button>
<span class="px-1.5 text-[11px] text-muted-foreground select-none">{VERSION}</span>
<span class="px-1.5 font-mono text-[11px] text-muted-foreground select-none">{VERSION}</span>
</div>
</div>