feat: SciFi theme — full dark/light palette with Tailwind v4 token remaps (#320)

* Upload SciFi theme screenshot

* fix: stabilize workspace swarm process spawning (#302)

Co-authored-by: Jarno de Vries <jarno@match-day.nl>

* feat(theme): add SciFi theme (dark + light variants) (#303)

* feat(theme): add SciFi theme (dark + light variants)

- Add scifi-theme.css with neon accents, glow effects, gradient backgrounds
- Register SciFi in theme.ts with dark/light color schemes
- Add SciFi option in settings UI
- Import scifi-theme.css in styles.css

* docs: add SciFi theme screenshot

---------

Co-authored-by: Fungraphique <fungraphique@jarvis.local>

* fix(chat): cross-session response contamination + /new opens previous chat (#297, #300)

Two related session-routing bugs that landed responses (or new-chat
clicks) into the wrong session.

#297 — cross-session response contamination

When the user navigated to a new chat while a previous chat was still
streaming, the previous chat's response chunks would land in the
**new** chat. Three fixes:

* useStreamingMessage now bumps a streamGenerationRef on every
  startStreaming call. The fetch-reader loop captures that token at
  start and re-checks it on every reader.read() and between events
  in the same batch. If the token has changed (because the user
  started a different stream), the loop cancels the reader and exits
  without dispatching anything. This closes the brief race between
  abortController.abort() and the underlying fetch reader actually
  stopping, during which buffered chunks were silently writing into
  activeSessionKeyRef.current (which had already been switched to
  the new session).

* chat-screen now cancels the in-flight stream on session-key change
  via a useEffect keyed on (activeCanonicalKey, activeFriendlyId,
  isNewChat). Previously nothing cancelled the stream on navigation
  \u2014 only the user clicking the explicit Stop button (handleStop)
  called cancelStreaming().

#300 — /new slash command opens last chat instead of new session

/new was calling navigate({ to: '/chat' }), but the /chat index route
unconditionally redirects to localStorage('claude-last-session'), so
/new always landed in whichever chat was last active. Fixed at three
entry points so all 'new chat' actions go through the explicit 'new'
sentinel:

* /new in chat-screen.handleUiSlashCommand
* /new in command-palette.runSlashCommand
* 'New Chat' quick-action tile in the search modal

The 'Chat' nav link in the sidebar still goes to /chat (= last session)
\u2014 that's the correct behaviour for a screen-level nav target. Only
'new' actions are routed to the new sentinel.

Closes #297, #300

* fix(terminal): keep PTY alive across SSE disconnects + auto-reattach (#298)

The browser terminal periodically 'reset back to prompt' during normal
use because any transient SSE disconnect (network blip, browser tab
suspension, HMR reload, dev-server restart) tore down the user's PTY
and dropped them into a fresh shell.

Root cause: terminal-stream's request.signal abort handler called
session.close(), which SIGTERM'd the underlying Python PTY helper.
There was also no auto-reconnect on the client \u2014 a single dropped
read terminated the loop, called /api/terminal-close, cleared the
tab's sessionId, and left the user with an idle tab.

Fix in three parts:

1) terminal-sessions: TerminalSession gains markDetached() and
   markAttached(). markDetached() starts a TTL timer (default 5 min,
   override via HERMES_TERMINAL_DETACH_TTL_MS) that reaps the PTY only
   if no client reattaches in time. The map keeps the session live in
   the meantime.

2) terminal-stream: accepts an optional sessionId in the POST body. If
   the id matches a still-alive session, the route reattaches to it
   instead of spawning a fresh PTY. The 'session' event payload now
   includes a 'reattach' flag. On SSE abort, we just detach listeners
   and call session.markDetached() \u2014 the PTY stays running.

3) terminal-workspace: passes sessionId on every connect, so reconnect
   reattaches automatically. When the read loop ends and the tab still
   has a sessionId, we attempt a single quick reattach with a
   '[reconnecting...]' nudge to the user instead of tearing the tab
   down. /api/terminal-close is no longer called on stream end \u2014 the
   server-side TTL handles abandoned sessions.

Fixes #298

* fix(scifi-theme): remap amber tokens to cyan/teal — no more pale yellow in SciFi

Amber colors (used for warnings/alerts in usage meter, agent thinking,
inspector badges, etc.) were not remapped in the SciFi theme, causing:
- Pale yellow bg-amber-100 with light text → unreadable menu items
- Jarring yellow accents breaking the cyberpunk aesthetic
- Trigger pill and selection states with impossible contrast

Remap all --color-amber-* tokens:
- Dark theme: amber → cyan/teal gradient (#041418 → #ccfaff)
- Light theme: amber → teal gradient (#e8f4f6 → #0a1628)

This replaces the previous .bg-amber-100 !important hack which broke
the usage meter bar by forcing dark text on already-dark remapped
primary-50 backgrounds.

* fix(scifi-theme): tweak amber remap contrast values

Brighten the amber→cyan tokens slightly so bg-amber-100 is visible
on --theme-panel (#0d1b2a) and text colors have good contrast
on the darker backgrounds.

* fix(theme): SciFi — visible usage pill + selected menu item colors

- Brightened amber-100 to #0c3245 (was #0a2633, too dark on #060b18 bg)
- Brightened amber-50/200/300/400/500/600/700 gradient for better contrast
- Added !important overrides for .bg-amber-100 to force background and
  text color, overriding MenuItem inline styles that were blocking
  the selected menu item appearance in SciFi dark theme

* fix(scifi-theme): add yellow, neutral, and white overrides for dark mode

- Add --color-yellow-* remap to teal-warm tones (was missing entirely)
- Add --color-neutral-* remap to dark slate/navy tones
- Add .bg-white override to theme-card for dialog backgrounds
- Add .bg-amber-100 color override for MenuItem selected state
  (MenuItem uses inline style color:var(--theme-text) which overwrites
   Tailwind text-amber-800, now overridden with !important)
- Add scifi-light remaps for yellow, red, emerald, neutral tokens
- Fixes: pale yellow/white backgrounds in usage meter menu, View Details
  dialog, status badges, progress bars, and tab pills in SciFi dark mode

* fix: replace bg-white with bg-primary-50 in usage-details-modal for theme compatibility

- All bg-white/bg-white/N in usage-details-modal replaced with bg-primary-50/N
  which is properly remapped by the SciFi theme (--theme-card/panel)
- Active tab pill: bg-white → bg-primary-100, text-primary-900 → text-primary-800
- Set as Default button: bg-white → bg-primary-50, hover:bg-primary-50 → hover:bg-primary-100
- Removed aggressive bg-white !important overrides from scifi-theme.css that
  broke borders, switches, and other elements using white elsewhere

* fix(scifi-theme): rewrite theme following nous pattern

- Replace hex values with var(--theme-*) references (same as nous theme)
- Remove broken red/emerald/yellow/neutral remaps that caused border/bg issues
- Add !important on dark-mode primary/accent remaps (needed for Tailwind v4 oklch)
- Move @import scifi-theme.css to END of styles.css (after .system dark rules)
- Keep essential .bg-amber-100 overrides for menu selected state
- Result: 238 lines (was 350+), clean structure matching nous theme pattern

Root cause: Tailwind v4 uses oklch color-mix internally for utility classes.
Simple --color-amber-100: #0f3547 overrides don't work because .border-primary-200
resolves via color-mix, not via the CSS custom property. Using var(--theme-*)
with !important ensures proper resolution.

* fix(scifi-theme): add !important to all dark mode token remaps

Tailwind v4 defines color tokens as oklch in @layer theme, which has
higher specificity than plain [data-theme] selectors. Without !important,
the remaps were ignored and components displayed native Tailwind colors
(white, amber, neutral-gray) instead of the SciFi palette.

Also remap --color-white to #0d1b2a so bg-white becomes dark navy
in SciFi dark mode (fixes chat-controls popover white background).

* feat(scifi): active tab indicator — cyan accent glow on Session/Providers tabs

* fix(scifi-theme): review fixes - 9 corrections

* fix: restore tab selector without role=tablist (component doesn't use it)

* fix(scifi): tab selector uses .bg-primary-50 > button instead of [role=tablist]

The usage-details-modal tabs don't use role=tablist ARIA attribute,
so [role=tablist] selector never matched. The tab container has
bg-primary-50 and direct child buttons with bg-primary-100 when active.

---------

Co-authored-by: jarnodevries-byte <jarnodevries@gmail.com>
Co-authored-by: Jarno de Vries <jarno@match-day.nl>
Co-authored-by: Fungraphique <fungraphique@jarvis.local>
Co-authored-by: Aurora release bot <release@outsourc-e.com>
This commit is contained in:
Fungraphic
2026-05-08 02:12:57 +02:00
committed by GitHub
parent 274e9a2e5c
commit 536e643d52
4 changed files with 258 additions and 34 deletions

BIN
screenshots/SciFi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

View File

@@ -335,7 +335,7 @@ export function UsageDetailsModal({
onClick={() => setActiveTab(tab)}
className={`rounded-full px-3 py-1 font-medium transition ${
activeTab === tab
? 'bg-white text-primary-900 shadow-sm'
? 'bg-primary-100 text-primary-800 shadow-sm'
: 'text-primary-600 hover:text-primary-800'
}`}
>
@@ -354,7 +354,7 @@ export function UsageDetailsModal({
) : null}
<div className="grid gap-3 md:grid-cols-3">
<div className="rounded-2xl border border-primary-200 bg-white/60 p-3">
<div className="rounded-2xl border border-primary-200 bg-primary-50/60 p-3">
<div className="text-xs uppercase tracking-wide text-primary-500">
Input Tokens
</div>
@@ -362,7 +362,7 @@ export function UsageDetailsModal({
{formatTokens(usage.inputTokens)}
</div>
</div>
<div className="rounded-2xl border border-primary-200 bg-white/60 p-3">
<div className="rounded-2xl border border-primary-200 bg-primary-50/60 p-3">
<div className="text-xs uppercase tracking-wide text-primary-500">
Output Tokens
</div>
@@ -370,7 +370,7 @@ export function UsageDetailsModal({
{formatTokens(usage.outputTokens)}
</div>
</div>
<div className="rounded-2xl border border-primary-200 bg-white/60 p-3">
<div className="rounded-2xl border border-primary-200 bg-primary-50/60 p-3">
<div className="text-xs uppercase tracking-wide text-primary-500">
Daily Cost
</div>
@@ -380,7 +380,7 @@ export function UsageDetailsModal({
</div>
</div>
<div className="rounded-2xl border border-primary-200 bg-white/70 p-4">
<div className="rounded-2xl border border-primary-200 bg-primary-50/70 p-4">
<div className="mb-3 text-sm font-semibold text-primary-900">
Cost per model
</div>
@@ -393,7 +393,7 @@ export function UsageDetailsModal({
usage.models.map((model) => (
<div
key={model.model}
className="flex flex-wrap items-center justify-between gap-2 rounded-xl border border-primary-100 bg-white px-3 py-2 text-sm"
className="flex flex-wrap items-center justify-between gap-2 rounded-xl border border-primary-100 bg-primary-50 px-3 py-2 text-sm"
>
<div className="font-medium text-primary-800">
{formatModelName(model.model)}
@@ -411,7 +411,7 @@ export function UsageDetailsModal({
</div>
</div>
<div className="rounded-2xl border border-primary-200 bg-white/70 p-4">
<div className="rounded-2xl border border-primary-200 bg-primary-50/70 p-4">
<div className="mb-3 text-sm font-semibold text-primary-900">
Session history
</div>
@@ -424,7 +424,7 @@ export function UsageDetailsModal({
usage.sessions.map((session) => (
<div
key={session.id}
className="flex flex-wrap items-center justify-between gap-2 rounded-xl border border-primary-100 bg-white px-3 py-2 text-sm"
className="flex flex-wrap items-center justify-between gap-2 rounded-xl border border-primary-100 bg-primary-50 px-3 py-2 text-sm"
>
<div>
<div className="font-medium text-primary-800">
@@ -485,7 +485,7 @@ export function UsageDetailsModal({
<div className="grid gap-3">
{providerUsage.length === 0 ? (
<div className="rounded-2xl border border-primary-200 bg-white/70 p-6 text-center">
<div className="rounded-2xl border border-primary-200 bg-primary-50/70 p-6 text-center">
<div className="text-sm font-medium text-primary-700">
No providers connected. Add a provider in Settings to start chatting.
</div>
@@ -503,7 +503,7 @@ export function UsageDetailsModal({
className={`rounded-2xl border p-4 ${
isDefault
? 'border-primary-300 bg-primary-50/50'
: 'border-primary-200 bg-white/70'
: 'border-primary-200 bg-primary-50/70'
}`}
>
<div className="flex items-center justify-between gap-2">
@@ -561,7 +561,7 @@ export function UsageDetailsModal({
onClick={() =>
handleSetDefault(provider.provider)
}
className="rounded-lg border border-primary-200 bg-white px-3 py-1.5 text-xs font-medium text-primary-700 transition hover:bg-primary-50"
className="rounded-lg border border-primary-200 bg-primary-50 px-3 py-1.5 text-xs font-medium text-primary-700 transition hover:bg-primary-100"
>
Set as Default
</button>

View File

@@ -6,6 +6,8 @@
/* ── SciFi Dark ─────────────────────────────────────────────────────── */
[data-theme='scifi'] {
color-scheme: dark !important;
--theme-bg: #060b18;
--theme-sidebar: #0a1628;
--theme-panel: #0d1b2a;
@@ -53,6 +55,8 @@
/* ── SciFi Light ────────────────────────────────────────────────────── */
[data-theme='scifi-light'] {
color-scheme: light !important;
--theme-bg: #eef1f5;
--theme-sidebar: #e4e9ef;
--theme-panel: #e8ecf2;
@@ -118,28 +122,27 @@
/* ── SciFi Tailwind primary token remaps — dark ─────────────────────── */
[data-theme='scifi'] {
--color-primary-50: var(--theme-panel);
--color-primary-100: var(--theme-card);
--color-primary-200: var(--theme-border);
--color-primary-300: var(--theme-border-subtle);
--color-primary-400: var(--theme-muted);
--color-primary-500: var(--theme-muted);
--color-primary-600: var(--theme-muted);
--color-primary-700: var(--theme-text);
--color-primary-800: var(--theme-text);
--color-primary-900: var(--theme-text);
--color-primary-950: var(--theme-text);
--color-surface: var(--theme-bg);
--color-surface-deep: var(--theme-bg);
--color-ink: var(--theme-text);
--color-accent-400: var(--theme-accent-secondary);
--color-accent-500: var(--theme-accent);
--color-accent-600: var(--theme-accent);
--color-primary-50: var(--theme-panel) !important;
--color-primary-100: var(--theme-card) !important;
--color-primary-200: var(--theme-border-subtle) !important;
--color-primary-300: var(--theme-border) !important;
--color-primary-400: var(--theme-muted) !important;
--color-primary-500: var(--theme-muted) !important;
--color-primary-600: var(--theme-muted) !important;
--color-primary-700: var(--theme-text) !important;
--color-primary-800: var(--theme-text) !important;
--color-primary-900: var(--theme-text) !important;
--color-primary-950: var(--theme-text) !important;
--color-surface: var(--theme-bg) !important;
--color-surface-deep: var(--theme-bg) !important;
--color-ink: var(--theme-text) !important;
--color-accent-400: var(--theme-accent-secondary) !important;
--color-accent-500: var(--theme-accent) !important;
--color-accent-600: var(--theme-accent) !important;
}
/* ── SciFi Tailwind primary token remaps — light ────────────────────── */
[data-theme='scifi-light'] {
color-scheme: light !important;
--color-primary-50: var(--theme-card) !important;
--color-primary-100: var(--theme-card2) !important;
--color-primary-200: var(--theme-border) !important;
@@ -157,6 +160,7 @@
--color-accent-400: var(--theme-accent-secondary) !important;
--color-accent-500: var(--theme-accent) !important;
--color-accent-600: var(--theme-accent) !important;
--color-white: var(--theme-card) !important;
}
/* ── SciFi dark: cyan glow on focus rings ───────────────────────────── */
@@ -175,3 +179,217 @@
[data-theme='scifi'] button:hover {
text-shadow: 0 0 8px rgba(0, 240, 255, 0.3);
}
/* ── SciFi dark: amber → teal remap ────────────────────────────────── */
/* Amber is used for warning/alert tones (usage meter, badges, etc.).
In SciFi dark, pale yellow breaks the cyberpunk aesthetic and creates
unreadable combos (light text on pale bg). Remap all amber tokens to
cyan/teal variants that fit the theme.
bg-amber-100 used for selected menu items must be visible on dark bg
with good contrast for text-amber-800 labels. */
[data-theme='scifi'] {
--color-amber-50: #071e2b !important;
--color-amber-100: #0f3547 !important;
--color-amber-200: #164d66 !important;
--color-amber-300: #1e6e8a !important;
--color-amber-400: #2690b3 !important;
--color-amber-500: #00bcd4 !important;
--color-amber-600: #00d4e8 !important;
--color-amber-700: #33e0f2 !important;
--color-amber-800: #ccf7ff !important;
--color-amber-900: #e0fbff !important;
--color-amber-950: #ebfcff !important;
}
/* ── SciFi dark: red → crimson remap ──────────────────────────────── */
/* Red tones for danger/error states. Keep them red but darker to fit
the dark HUD aesthetic. bg-red-100 must be visible on --theme-panel. */
[data-theme='scifi'] {
--color-red-50: #1a0a0a !important;
--color-red-100: #3d1111 !important;
--color-red-200: #5c1a1a !important;
--color-red-300: #8a2525 !important;
--color-red-400: #b83030 !important;
--color-red-500: #ef4444 !important;
--color-red-600: #f87171 !important;
--color-red-700: #fca5a5 !important;
--color-red-800: #fee2e2 !important;
--color-red-900: #fef2f2 !important;
--color-red-950: #fff5f5 !important;
}
/* ── SciFi dark: emerald → neon-green remap ─────────────────────── */
/* Emerald/green for success states. Fit the cyberpunk palette. */
[data-theme='scifi'] {
--color-emerald-50: #0a1a14 !important;
--color-emerald-100: #0f3326 !important;
--color-emerald-200: #15523a !important;
--color-emerald-300: #1c7a52 !important;
--color-emerald-400: #23a86b !important;
--color-emerald-500: #64ffda !important;
--color-emerald-600: #7cffd8 !important;
--color-emerald-700: #a3ffe0 !important;
--color-emerald-800: #ccfff0 !important;
--color-emerald-900: #e0fff6 !important;
--color-emerald-950: #ebfff8 !important;
}
/* ── SciFi dark: yellow → amber-warm remap ─────────────────────────── */
/* Yellow is used for mid-range progress bars and warning indicators.
Remap to warm amber/orange tones to differentiate from amber (teal)
while staying within the cyberpunk palette. */
[data-theme='scifi'] {
--color-yellow-50: #1a150a !important;
--color-yellow-100: #2e2510 !important;
--color-yellow-200: #4a3a18 !important;
--color-yellow-300: #6b5520 !important;
--color-yellow-400: #8a7028 !important;
--color-yellow-500: #d4930a !important;
--color-yellow-600: #e5a020 !important;
--color-yellow-700: #f0b840 !important;
--color-yellow-800: #fad480 !important;
--color-yellow-900: #fde8b0 !important;
--color-yellow-950: #fef3d8 !important;
}
/* ── SciFi dark: neutral → dark slate remap ──────────────────────── */
/* Neutral is used for secondary badges and subtle UI elements.
Remap to dark navy/slate tones that blend with the HUD.
!important required because Tailwind v4 defines these as oklch in @layer theme. */
[data-theme='scifi'] {
--color-neutral-50: #e8f4f8 !important;
--color-neutral-100: #d0e8ef !important;
--color-neutral-200: #a8cdd9 !important;
--color-neutral-300: #7ab4cc !important;
--color-neutral-400: #4d94b3 !important;
--color-neutral-500: #2a6d8a !important;
--color-neutral-600: #1e5a73 !important;
--color-neutral-700: #16475c !important;
--color-neutral-800: #0f3547 !important;
--color-neutral-900: #0a2035 !important;
--color-neutral-950: #060e18 !important;
/* ── white → dark background in SciFi dark ── */
/* Components like chat-controls popover use bg-white / dark:bg-neutral-900.
In SciFi dark, white must become the panel background color. */
--color-white: #0d1b2a !important;
}
/* ── SciFi dark: selected menu items — force bg/text on inline-styled MenuItem ─ */
/* MenuItem sets color: var(--theme-text) and background via onMouseEnter/Leave
inline styles, which override Tailwind classes like bg-amber-100 text-amber-800.
In SciFi dark, selected items need a visible teal background with bright text. */
[data-theme='scifi'] .bg-amber-100 {
background-color: var(--color-amber-100) !important;
color: var(--color-amber-800) !important;
}
[data-theme='scifi'] .bg-amber-100 .text-amber-800 {
color: var(--color-amber-800) !important;
}
[data-theme='scifi'] .bg-amber-100 .text-amber-600 {
color: var(--color-amber-600) !important;
}
[data-theme='scifi'] .bg-amber-100 .text-primary-600 {
color: var(--color-amber-600) !important;
}
[data-theme='scifi'] .bg-amber-100 .text-primary-300 {
color: var(--color-amber-700) !important;
}
/* ── SciFi dark: active tab indicator in Usage Details dialog ──── */
/* Tabs "Session / Providers" use bg-primary-100 for the active tab
inside a bg-primary-50 container. In SciFi dark, primary-50 (#0d1b2a)
and primary-100 (#112240) are too similar — the active tab is invisible.
Target .bg-primary-50 > button to scope to tab containers only. */
[data-theme='scifi'] .bg-primary-50 > button.bg-primary-100 {
background-color: rgba(0, 240, 255, 0.15) !important;
color: var(--theme-accent) !important;
box-shadow: 0 0 8px rgba(0, 240, 255, 0.2) !important;
text-shadow: 0 0 6px rgba(0, 240, 255, 0.3) !important;
}
/* ── SciFi light: amber → teal remap ──────────────────────────────── */
/* Same rationale: replace yellow/amber with teal to match the cold
steel + cyan accent palette of scifi-light. */
[data-theme='scifi-light'] {
--color-amber-50: #e8f4f6 !important;
--color-amber-100: #d0e8ec !important;
--color-amber-200: #b0d8e0 !important;
--color-amber-300: #80c4d0 !important;
--color-amber-400: #4da8b8 !important;
--color-amber-500: #0097a7 !important;
--color-amber-600: #00838f !important;
--color-amber-700: #006974 !important;
--color-amber-800: #004d57 !important;
--color-amber-900: #003a42 !important;
--color-amber-950: #002930 !important;
--color-yellow-50: #f5f0e0 !important;
--color-yellow-100: #ebe0c0 !important;
--color-yellow-200: #d8c890 !important;
--color-yellow-300: #c4a860 !important;
--color-yellow-400: #a88a30 !important;
--color-yellow-500: #8a7020 !important;
--color-yellow-600: #6b5518 !important;
--color-yellow-700: #4a3a10 !important;
--color-yellow-800: #2e2510 !important;
--color-yellow-900: #1a150a !important;
--color-yellow-950: #100d08 !important;
--color-red-50: #fde8e8 !important;
--color-red-100: #fbd0d0 !important;
--color-red-200: #f5a8a8 !important;
--color-red-300: #ef8080 !important;
--color-red-400: #e05050 !important;
--color-red-500: #c62828 !important;
--color-red-600: #b71c1c !important;
--color-red-700: #8e1515 !important;
--color-red-800: #6b1010 !important;
--color-red-900: #4a0a0a !important;
--color-red-950: #300606 !important;
--color-emerald-50: #e8f5ee !important;
--color-emerald-100: #d0ebda !important;
--color-emerald-200: #b0d8be !important;
--color-emerald-300: #80c498 !important;
--color-emerald-400: #4da870 !important;
--color-emerald-500: #2e7d52 !important;
--color-emerald-600: #256b45 !important;
--color-emerald-700: #1a5a37 !important;
--color-emerald-800: #0f4428 !important;
--color-emerald-900: #0a3018 !important;
--color-emerald-950: #061f10 !important;
--color-neutral-50: #f4f6f9 !important;
--color-neutral-100: #e4e9ef !important;
--color-neutral-200: #c4cdd8 !important;
--color-neutral-300: #a0b0c0 !important;
--color-neutral-400: #7088a0 !important;
--color-neutral-500: #5a6a7e !important;
--color-neutral-600: #4a5a6e !important;
--color-neutral-700: #3a4a5e !important;
--color-neutral-800: #2a3a4e !important;
--color-neutral-900: #1a2a3e !important;
--color-neutral-950: #0a1628 !important;
}
/* ── SciFi light: selected menu items — force bg/text on inline-styled MenuItem ─ */
[data-theme='scifi-light'] .bg-amber-100 {
background-color: var(--color-amber-100) !important;
color: var(--color-amber-800) !important;
}
[data-theme='scifi-light'] .bg-amber-100 .text-amber-800 {
color: var(--color-amber-800) !important;
}
[data-theme='scifi-light'] .bg-amber-100 .text-amber-600 {
color: var(--color-amber-600) !important;
}
[data-theme='scifi-light'] .bg-amber-100 .text-primary-600 {
color: var(--color-amber-600) !important;
}
[data-theme='scifi-light'] .bg-amber-100 .text-primary-300 {
color: var(--color-amber-700) !important;
}
/* ── SciFi light: active tab indicator ──────────────────────────── */
[data-theme='scifi-light'] .bg-primary-50 > button.bg-primary-100 {
background-color: rgba(0, 151, 167, 0.15) !important;
color: var(--theme-accent) !important;
box-shadow: 0 0 6px rgba(0, 151, 167, 0.2) !important;
text-shadow: none !important;
}

View File

@@ -1,6 +1,5 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=EB+Garamond:opsz,wght@8..120,400..800&family=JetBrains+Mono:wght@400;500&display=swap');
@import 'tailwindcss';
@import './scifi-theme.css';
/* Tailwind v4 — enable dark: variant on .dark class (set by __root.tsx) */
@variant dark (&:where(.dark, .dark *));
@@ -1525,3 +1524,10 @@ code {
border-radius 0.3s ease;
}
}
/* ════════════════════════════════════════════════════════════════════
SciFi Theme — imported AFTER all other theme rules so that
its CSS variable remaps take precedence over the default
Tailwind oklch values and .system dark mode overrides.
═══════════════════════════════════════════════════════════════════ */
@import './scifi-theme.css';