Orbital Visualization Hero
A two-column hero that sells a network. Left: a typewriter headline + CTA. Right: concentric rings slowly rotating, avatars pinned around them, a count-up number at the center. A logo ticker scrolls along the bottom.
Before building
Read /mnt/skills/public/frontend-design/SKILL.md. Collect: BRAND/logo,
NAV_LINKS, the HEADLINE (split into a dark part + a light part), the
CTA label, the center stat ("20k+" + label), a set of AVATARS, and
partner LOGOS for the ticker. Palette: an accent (#A068FF purple works),
dark #060218, black text on light areas, white on dark. Optional full-bleed
background image. Fonts: Inter (body) + Urbanist (display/numbers).
Stack
React + Vite (useState/useEffect/useRef). Tailwind or plain CSS both fine —
the effects below are pure CSS + a little JS, no animation library needed.
Left column
- Typewriter headline (
Urbanist,64px,35ms/char, after a 400ms delay). Color the first N characters dark and the rest white; show a blinking accent cursor while typing.line-height:64px,letter-spacing:-1.5px): type char-by-char ( - CTA pill with a rotating conic-gradient border (see below), appearing after typing finishes.
Right column — the orbits
Four concentric rings, each a ring div with a gradient-masked 1px border and its own slow spin:
.orbit { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); border-radius:9999px;
padding:1px; -webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite:xor; mask-composite:exclude;
background:linear-gradient(180deg, rgba(217,161,255,0) 0%, rgba(217,161,255,1) 43%, rgba(217,161,255,0) 100%); }
@keyframes spinL { to { transform:translate(-50%,-50%) rotate(-360deg); } }
@keyframes spinR { to { transform:translate(-50%,-50%) rotate(360deg); } }
Sizes/speeds: 353px spin-left 30s · 501px spin-right 40s · 649px spin-right 50s
· 797px spin-left 60s. Place each avatar on a ring with
transform: translate(-50%,-50%) rotate(<deg>) translate(<radius>) rotate(-<deg>)
and counter-rotate the whole avatar to stay upright. Center ring shows a
useCountUp number (0→target over ~2s, easeOutCubic) that counter-rotates so it
reads straight. Avatars fly in staggered (scale .3 + rotate -180 + blur → normal, delays 0.6s–2.3s) with colored glows.
Signature: rotating conic-gradient button border
@property --border-angle { syntax:'<angle>'; initial-value:0deg; inherits:false; }
.btn-border-wrap::before { content:''; position:absolute; inset:-3px; padding:3px; border-radius:inherit;
background:conic-gradient(from var(--border-angle), #A068FF,#070319,#A068FF,#070319,#A068FF);
-webkit-mask:linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite:xor; mask-composite:exclude; animation:spin-border 3s linear infinite; }
@keyframes spin-border { to { --border-angle:360deg; } }
Buttons are black pills; on hover an accent fill slides in via ::after
(translateX(-100%)→0, cubic-bezier(0.22,1,0.36,1)).
Bottom logo ticker
Horizontal strip, gap:64px, translating infinitely over ~20s; duplicate the
logo set 3–4× for a seamless loop; fade the left/right edges with a
linear-gradient mask. Each logo 137×40, object-fit:contain.
Entrance & responsive
Header fade-down, left column fade-up (1s), orbits scale-in (1.2s, delay 0.3s),
ticker fade-up — all cubic-bezier(0.22,1,0.36,1). Breakpoints: 1280 (orbits
scale 0.85) · 1024 (stack to column, heading 48px, orbits 0.7) · 768 (hide nav,
heading 36px, orbits 0.5) · 480 (heading 28px, orbits 0.4).
Quality checklist
- Four rings rotate at different speeds/directions; borders are gradient-masked.
- Avatars sit on the rings and stay upright; center number counts up.
- Headline types out; CTA border rotates (conic gradient via
@property). - Logo ticker loops seamlessly with faded edges.
- Stacks cleanly at 1024/768/480; orbits scale down instead of overflowing.