Bolder, more delightful frontend across all pages

- app.css: replace flat --shadow-sm token with real shadows; add
  --shadow-card and --shadow-dialog tokens; add @keyframes status-ping
  and .animate-status-ping utility (outward ring ripple, GPU-composited
  via will-change) for live running status dots
- login: headline 5rem → 6.5rem with tighter leading/tracking; expand
  container to 460px; add sage-green dot grid texture layer beneath the
  mouse-reactive glow for industrial depth
- capsules: upgrade all running dots (header chip + row indicators +
  status bar) from opacity-fade to ring ripple; apply --shadow-dialog
  to Launch and Snapshot dialogs
- keys: apply --shadow-dialog to all three dialogs
- audit: remove duplicate @keyframes fadeUp and iconFloat (redundant
  with app.css definitions, audit's fadeUp also subtly diverged)
- sidebar: active indicator bar taller and thicker (h-5 w-[3px] → h-6
  w-1); active bg more vivid (accent/12%); label font-medium →
  font-semibold; team dialog gets --shadow-dialog
This commit is contained in:
2026-03-25 12:55:23 +06:00
parent d4eb24be7e
commit 2349f585ae
6 changed files with 56 additions and 35 deletions

View File

@ -69,8 +69,10 @@
--radius-avatar: 5px;
--radius-logo: 6px;
/* Shadows — flat aesthetic */
--shadow-sm: 0 0 #0000;
/* Shadows */
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35), 0 1px 2px rgba(0, 0, 0, 0.2);
--shadow-card: 0 4px 12px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.25);
--shadow-dialog: 0 16px 48px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.35);
}
/* Base styles */
@ -131,6 +133,24 @@ body {
}
}
/* Outward ring ripple — for live/running status dots; more delightful than opacity-only */
@keyframes status-ping {
0% {
transform: scale(1);
opacity: 0.8;
}
80%,
100% {
transform: scale(2.8);
opacity: 0;
}
}
.animate-status-ping {
animation: status-ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
will-change: transform, opacity;
}
/* Fade-up entrance animation */
@keyframes fadeUp {
from {

View File

@ -342,19 +342,19 @@
{:else if isActive(item.href)}
<a
href={item.href}
class="group relative flex items-center rounded-[var(--radius-input)] bg-[var(--color-accent-glow-mid)] px-2.5 py-2.5 transition-colors duration-150 {collapsed
? 'justify-center px-2'
: 'gap-3'}"
class="group relative flex items-center rounded-[var(--radius-input)] px-2.5 py-2.5 transition-colors duration-150 {collapsed
? 'justify-center px-2 bg-[var(--color-accent-glow-mid)]'
: 'gap-3 bg-[var(--color-accent)]/[0.12]'}"
title={collapsed ? item.label : undefined}
>
{#if !collapsed}
<div
class="absolute left-0 top-1/2 h-5 w-[3px] -translate-y-1/2 rounded-r-full bg-[var(--color-accent)]"
class="absolute left-0 top-1/2 h-6 w-1 -translate-y-1/2 rounded-r-full bg-[var(--color-accent)]"
></div>
{/if}
<item.icon size={16} class="shrink-0 text-[var(--color-accent-bright)]" />
{#if !collapsed}
<span class="text-ui font-medium text-[var(--color-accent-bright)]">
<span class="text-ui font-semibold text-[var(--color-accent-bright)]">
{item.label}
</span>
{/if}
@ -396,7 +396,7 @@
<div
class="relative w-full max-w-[380px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6"
style="animation: fadeUp 0.2s ease both"
style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)"
>
<h2 class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]">
Create Team

View File

@ -556,15 +556,7 @@
</div>
<style>
@keyframes fadeUp {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes iconFloat {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
/* fadeUp and iconFloat are defined globally in app.css — no need to redeclare them here */
@keyframes stripePulse {
0%, 100% { opacity: 1; }

View File

@ -327,14 +327,13 @@
<div class="flex items-center gap-3">
<!-- Status chip -->
<div
class="flex items-center gap-2.5 rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] px-3.5 py-2"
class="flex items-center gap-2.5 rounded-[var(--radius-card)] border border-[var(--color-accent)]/20 bg-[var(--color-bg-2)] px-3.5 py-2"
>
<span class="relative flex h-[7px] w-[7px]">
<span class="relative flex h-[8px] w-[8px]">
<span
class="absolute inline-flex h-full w-full rounded-full bg-[var(--color-accent)]"
style="animation: wrenn-glow 2.5s ease-in-out infinite"
class="animate-status-ping absolute inline-flex h-full w-full rounded-full bg-[var(--color-accent)]"
></span>
<span class="relative inline-flex h-[7px] w-[7px] rounded-full bg-[var(--color-accent)]"></span>
<span class="relative inline-flex h-[8px] w-[8px] rounded-full bg-[var(--color-accent)]"></span>
</span>
<span class="font-mono text-body font-semibold text-[var(--color-accent-bright)]">{runningCount}</span>
<span class="text-ui text-[var(--color-text-secondary)]">running now</span>
@ -531,7 +530,7 @@
<div class="flex items-center gap-2.5 px-5 py-4">
{#if capsule.status === 'running'}
<span class="relative flex h-[6px] w-[6px] shrink-0">
<span class="absolute inline-flex h-full w-full rounded-full bg-[var(--color-accent)]" style="animation: wrenn-glow 2.5s ease-in-out infinite"></span>
<span class="animate-status-ping absolute inline-flex h-full w-full rounded-full bg-[var(--color-accent)]"></span>
<span class="relative inline-flex h-[6px] w-[6px] rounded-full bg-[var(--color-accent)]"></span>
</span>
{:else if capsule.status === 'paused'}
@ -621,7 +620,10 @@
class="flex h-7 shrink-0 items-center justify-end border-t border-[var(--color-border)] bg-[var(--color-bg-1)] px-7"
>
<div class="flex items-center gap-1.5">
<span class="inline-flex h-[5px] w-[5px] rounded-full bg-[var(--color-accent)]"></span>
<span class="relative flex h-[5px] w-[5px]">
<span class="animate-status-ping absolute inline-flex h-full w-full rounded-full bg-[var(--color-accent)]"></span>
<span class="relative inline-flex h-[5px] w-[5px] rounded-full bg-[var(--color-accent)]"></span>
</span>
<span class="font-mono text-label uppercase tracking-[0.04em] text-[var(--color-text-secondary)]">All systems operational</span>
</div>
</footer>
@ -703,7 +705,7 @@
onkeydown={(e) => { if (e.key === 'Escape' && !snapshotting) snapshotTarget = null; }}
></div>
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] overflow-hidden" style="animation: fadeUp 0.2s ease both">
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] overflow-hidden" style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)">
<!-- Header band -->
<div class="flex items-center gap-4 border-b border-[var(--color-border)] bg-[var(--color-bg-3)] px-6 py-5">
<div class="flex h-10 w-10 shrink-0 items-center justify-center rounded-[var(--radius-input)] bg-[var(--color-accent)]/15 text-[var(--color-accent)] shadow-[0_0_12px_var(--color-accent-glow)]">
@ -793,7 +795,7 @@
onkeydown={(e) => { if (e.key === 'Escape' && !creating) showCreateDialog = false; }}
></div>
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both">
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)">
<h2 class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]">Launch Capsule</h2>
<p class="mt-1 text-ui text-[var(--color-text-tertiary)]">Configure resources and launch. The VM will be ready in under a second.</p>

View File

@ -262,7 +262,7 @@
onkeydown={(e) => { if (e.key === 'Escape' && !creating) showCreate = false; }}
></div>
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both">
<div class="relative w-full max-w-[420px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)">
<h2 class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]">New API Key</h2>
<p class="mt-1 text-ui text-[var(--color-text-tertiary)]">Name it after its environment or purpose — production, staging, CI. You can't rename it later.</p>
@ -323,7 +323,7 @@
onkeydown={(e) => { if (e.key === 'Escape') dismissReveal(); }}
></div>
<div class="relative w-full max-w-[480px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both">
<div class="relative w-full max-w-[480px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)">
<!-- Success indicator -->
<div class="mb-4 flex items-center gap-2.5">
<span class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-[var(--color-accent-glow-mid)]" style="animation: circlePop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both">
@ -404,7 +404,7 @@
onkeydown={(e) => { if (e.key === 'Escape' && !revoking) revokeTarget = null; }}
></div>
<div class="relative w-full max-w-[380px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both">
<div class="relative w-full max-w-[380px] rounded-[var(--radius-card)] border border-[var(--color-border-mid)] bg-[var(--color-bg-2)] p-6" style="animation: fadeUp 0.2s ease both; box-shadow: var(--shadow-dialog)">
<h2 class="font-serif text-heading tracking-[-0.02em] text-[var(--color-text-bright)]">Revoke Key</h2>
<p class="mt-2 text-ui text-[var(--color-text-tertiary)]">
Permanently revoke <span class="font-medium text-[var(--color-text-secondary)]">{revokeTarget.name || revokeTarget.id}</span>.

View File

@ -117,10 +117,17 @@
class="relative hidden w-1/2 flex-col items-center justify-center overflow-hidden bg-[var(--color-bg-1)] lg:flex"
onmousemove={handleMouseMove}
>
<!-- Mouse-reactive radial glow -->
<!-- Dot grid texture — industrial depth layer -->
<div
class="pointer-events-none absolute inset-0 opacity-60"
style="background-image: radial-gradient(circle, rgba(94,140,88,0.09) 1px, transparent 1px); background-size: 24px 24px;"
aria-hidden="true"
></div>
<!-- Mouse-reactive radial glow — renders above dot grid -->
<div
class="pointer-events-none absolute inset-0"
style="background: radial-gradient(ellipse 55% 45% at {glowX}% {glowY}%, rgba(94, 140, 88, 0.14) 0%, transparent 70%)"
style="background: radial-gradient(ellipse 60% 50% at {glowX}% {glowY}%, rgba(94, 140, 88, 0.18) 0%, transparent 70%)"
aria-hidden="true"
></div>
@ -137,13 +144,13 @@
</span>
</div>
<!-- Tagline below logo -->
<!-- Tagline below logo — larger, more commanding -->
<div
class="relative z-10 mt-16 max-w-[360px] text-center"
class="relative z-10 mt-14 max-w-[460px] text-center"
style="animation: fadeUp 0.35s ease 0.1s both"
>
<h1
class="font-serif text-[5rem] leading-[1.1] tracking-[-0.04em] text-[var(--color-text-bright)]"
class="font-serif text-[6.5rem] leading-[0.95] tracking-[-0.06em] text-[var(--color-text-bright)]"
>
Scale Up.<br /><span class="text-[var(--color-accent-bright)]">Spin Out.</span>
</h1>
@ -151,7 +158,7 @@
<!-- Sub-tagline -->
<p
class="relative z-10 mt-12 font-mono text-ui uppercase tracking-[0.08em] text-[var(--color-text-tertiary)]"
class="relative z-10 mt-10 font-mono text-ui uppercase tracking-[0.1em] text-[var(--color-text-tertiary)]"
style="animation: fadeUp 0.35s ease 0.2s both"
>
Isolated VMs. Milliseconds to live.