6.1 KiB
SoftLAN — Logo handoff
The SoftLAN mark is a pixelated “S” (5×5 grid) that, at rest, is a static icon — but periodically and on hover it comes alive: it dissolves into a single segment that slithers across the board like the game Snake, then re-lays itself back into the S. Two shorter “glitch” flickers add variety.
This folder is everything an engineer/agent needs to ship it.
logo_handoff/
├── pixel-live.jsx ← the live React component (the deliverable)
├── demo.html ← open in a browser to see it in motion + in context
├── INTEGRATION.md ← this file
└── assets/
├── softlan-mark.svg static S, fill="currentColor" (inline use)
├── softlan-mark-blue.svg static S, fixed #3b82f6 (img/favicon use)
├── softlan-tile.svg rounded app-icon tile, gradient + white S
└── favicon.svg = tile (drop-in favicon)
1. The live component — pixel-live.jsx
A single React component, LiveLogo. No build step assumed in the demo (it’s
loaded via Babel-in-browser), but the source is plain JSX — drop it into your
normal React/TS toolchain and it compiles as-is.
Props
| prop | type | default | notes |
|---|---|---|---|
accent |
string | #3b82f6 |
the S color (any CSS color). Wire this to your theme accent. |
size |
number | 140 |
rendered width/height in px (it’s a square SVG). |
idleAuto |
boolean | true |
when true, plays a random trick by itself every idleMin–idleMax ms. |
idleMin |
number | 5000 |
min ms between idle auto-plays. |
idleMax |
number | 11000 |
max ms between idle auto-plays. |
Behavior (built in)
- Rest: renders the static pixel S in
accent. - Hover: plays a random trick (snake-weighted).
- Click: plays the snake trick.
- Idle: if
idleAuto, fires a random trick on a 5–11s jitter — but only while the tab is visible (document.hiddenguard), so background tabs stay quiet. - It never overlaps plays (a
playingguard ignores triggers mid-animation).
Imperative API (ref)
const logo = useRef(null);
// ...
<LiveLogo ref={logo} accent="#3b82f6" size={32} />
// trigger a specific trick on demand:
logo.current.play('snake'); // 'snake' | 'rgb' | 'glitch'
logo.current.isPlaying(); // boolean
Tricks
snake(~2.6s) — the headline animation. S → slither across the 5×5 board → S.rgb(~1.35s) — chromatic-aberration split that settles back to clean.glitch(~1.1s) — rows tear/kick sideways, then snap back.
Edit the POOL array near the bottom of the file to change which tricks the
random picker uses (and their weighting), and TRICK_DUR to retune durations.
2. Wiring it into the launcher
The current brand mark in launcher.jsx is a placeholder div:
// BEFORE — both the 'single' and 'two' topbar variants:
<div className="brand-mark" style={{ background: accent }}>S</div>
Replace each with the live component:
// AFTER:
<LiveLogo accent={accent} size={28} />
- Pass the existing
accenttweak straight through — the mark recolors live. size={28}matches the current 28px brand-mark box; adjust to taste.- Drop the old
.brand-markbackground/letter CSS (the SVG is self-contained). - The component is small and animates only on hover/idle, so it’s fine to mount
one instance per topbar. If you want the whole header to react to a single
event, share one
refand call.play().
Import at the top of the file (or via your bundler):
import { LiveLogo } from './pixel-live'; // if you convert exports to ES modules
The file currently attaches LiveLogo to window for the no-build demo —
swap the final Object.assign(window, …) line for export { LiveLogo } in a
module build.
3. Static assets (assets/)
For places that must be static — favicons, OS app icons, store listings, loading splash, OG images, anywhere JS isn’t running:
softlan-tile.svg— the rounded app-icon tile (gradient + white S). Use this for the favicon, dock/taskbar icon, and installer art.favicon.svgis an identical copy for convenient<link rel="icon">.softlan-mark-blue.svg— just the S in brand blue, transparent bg. Use in<img>tags and anywhere you need a fixed color.softlan-mark.svg— the S withfill="currentColor". Only inherits color when inlined into the DOM (inline<svg>or an SVG-as-component); via<img src>it won’t pick upcurrentColor. Best for inline React/JSX use where you want it to follow text/theme color.
Geometry note: all static marks use the exact same grid as the live component
(viewBox 0 0 100 100, cell 17, offset 7.5, gap 2.4, radius 3), so the static
and animated S are pixel-identical — no jump when the live one mounts.
Generating raster PNGs (if your pipeline needs them)
# requires librsvg (rsvg-convert) or Inkscape
rsvg-convert -w 512 -h 512 assets/softlan-tile.svg > icon-512.png
rsvg-convert -w 256 -h 256 assets/softlan-tile.svg > icon-256.png
rsvg-convert -w 32 -h 32 assets/favicon.svg > favicon-32.png
4. Accessibility & motion
- The static SVGs carry
role="img"+aria-label="SoftLAN". Give the live component an accessible label in its host (e.g. wrap witharia-label), since it’s decorative motion over a brand mark. - The idle auto-play already pauses in hidden tabs. If you want to fully respect
prefers-reduced-motion, gate the triggers:At rest it’s a clean static S, so reduced-motion users simply get the icon.const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; <LiveLogo idleAuto={!reduce} /* and skip the hover/click play when reduce */ />
5. Quick check
Open demo.html in any browser: hover the big mark (or wait), use the trick
buttons, and try the accent swatches. The small mark in the mock top bar is the
same component at size={30} — that’s exactly how it looks in the launcher.