From 5710fe41ee3456a11adcba48aef9fce85301cf00 Mon Sep 17 00:00:00 2001 From: Claude Code Date: Sat, 11 Apr 2026 19:02:11 +0000 Subject: [PATCH 1/3] feat(chromium-headful): replace kernel logo with OCM orange orb animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Neko loading screen and About dialog now render an animated orange orb instead of the static kernel.sh wordmark. Pure-CSS port of the OrbBackground component from the OpenClaw Machines frontend (frontend/src/components/hero/OrbBackground.tsx, commit 06c483a). Three layers: - Primary orb: blurred radial gradient, #fb923c → #f97316 → transparent - Secondary bloom: smaller counter-breathing layer, #fbbf24 → #f59e0b - SVG feTurbulence grain overlay at 6% opacity for texture Animations: - ocm-orb-popin: 0.9s cubic-bezier pop-in on mount (replaces the old scale-0.85/opacity-0.7 pulse) - ocm-orb-breathe-primary / -bloom: 3.6s infinite breathe with the two layers scaling inversely for depth No JS required — the React useOrbAnimation rAF driver is not needed for a fixed 140px loading slot. The breathe loop captures the essence of the organic drift motion without the positioning overhead. --- .../client/src/components/about.vue | 91 ++++++++++++++++-- .../client/src/components/connect.vue | 95 +++++++++++++++++-- 2 files changed, 166 insertions(+), 20 deletions(-) diff --git a/images/chromium-headful/client/src/components/about.vue b/images/chromium-headful/client/src/components/about.vue index 32a51610..440669b2 100644 --- a/images/chromium-headful/client/src/components/about.vue +++ b/images/chromium-headful/client/src/components/about.vue @@ -3,7 +3,16 @@
- +
@@ -72,19 +81,56 @@ } } + // OCM orange orb — see connect.vue for design notes. .loader { - width: 90px; - height: 90px; + width: 140px; + height: 140px; position: relative; margin: 0 auto 20px auto; display: flex; justify-content: center; align-items: center; + overflow: hidden; - .kernel-logo { + .ocm-orb { + position: relative; width: 100%; height: 100%; - animation: kernel-logo-pulse 1.5s ease-in-out infinite; + animation: ocm-orb-popin 0.9s cubic-bezier(0.34, 1.56, 0.64, 1) both; + } + + .ocm-orb__primary, + .ocm-orb__bloom { + position: absolute; + top: 50%; + left: 50%; + border-radius: 50%; + will-change: transform, opacity; + } + + .ocm-orb__primary { + width: 78%; + height: 78%; + filter: blur(16px); + background: radial-gradient(circle, #fb923c 0%, #f97316 40%, transparent 70%); + animation: ocm-orb-breathe-primary 3.6s ease-in-out infinite; + } + + .ocm-orb__bloom { + width: 56%; + height: 56%; + filter: blur(12px); + background: radial-gradient(circle, #fbbf24 0%, #f59e0b 50%, transparent 70%); + animation: ocm-orb-breathe-bloom 3.6s ease-in-out infinite; + } + + .ocm-orb__grain { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + opacity: 0.06; + pointer-events: none; } } } @@ -95,17 +141,42 @@ } } - @keyframes kernel-logo-pulse { - 0%, + @keyframes ocm-orb-popin { + 0% { + transform: scale(0.05); + opacity: 0; + } + 70% { + transform: scale(1.06); + opacity: 1; + } 100% { - transform: scale(0.85); - opacity: 0.7; + transform: scale(1); + opacity: 1; + } + } + + @keyframes ocm-orb-breathe-primary { + 0%, 100% { + transform: translate(-50%, -50%) scale(0.92); + opacity: 0.75; } 50% { - transform: scale(1); + transform: translate(-50%, -50%) scale(1.08); opacity: 1; } } + + @keyframes ocm-orb-breathe-bloom { + 0%, 100% { + transform: translate(-50%, -50%) scale(1.05); + opacity: 0.5; + } + 50% { + transform: translate(-50%, -50%) scale(0.9); + opacity: 0.7; + } + }