skills/lino-ui-upgrade/SKILL.md

432 lines
21 KiB
Markdown

---
name: lino-ui-upgrade
description: Lino UI Upgrade — a unified futuristic design system that fuses Neumorphism (soft tactile depth), Skeuomorphism (real-world materiality), Glassmorphism (frosted blur surfaces), and Liquid Glass (iOS 26 dynamic refraction) into one premium UI language. Use this skill whenever the user asks to upgrade, redesign, or modernize an interface; mentions "futuristic", "premium UI", "next-gen UI", "glass UI", "soft UI", "tactile UI", "Apple-tier", "iOS 26 style", "Vision Pro style", or wants an app/site to "feel expensive / cinematic / spatial". Apply for mobile apps (iOS, Android, React Native, Flutter), web (React, Next.js, Vue, Svelte), and desktop (Electron, Tauri, macOS, Windows). For Flutter projects, this skill specifies a canonical package stack — `glassmorphism`, `liquid_glass_renderer`, `mesh_gradient`, `flutter_animate`, `liquid_swipe`, and `rive` — mapped to each material layer. This skill replaces flat default UI with depth, light, refraction, and physics-based motion across every component.
---
# Lino UI Upgrade — Unified Futuristic Design System
A surgical UI upgrade kit that layers four material languages into one coherent system:
| Layer | Role | When it owns the surface |
|---|---|---|
| **Neumorphism** | Tactile base — soft extruded buttons, toggles, knobs, dials | Controls that should feel pressable / physical |
| **Skeuomorphism** | Real-world materiality — leather, metal, paper, wood, glass-on-glass texture | Hero objects, watch faces, instruments, premium cards |
| **Glassmorphism** | Frosted floating overlays — nav bars, modals, popovers, HUDs | Anything that floats above content |
| **Liquid Glass (iOS 26)** | Dynamic refraction + morphing + interactive light | Primary CTAs, focus elements, transition layers, hero containers |
The four are **not alternatives** — they are stacked roles. A great Lino screen uses **all four at once**, each in its correct role. Mixing them at random produces slop. Using each one for the job it's good at produces something that feels like Apple Vision Pro met a Swiss watch.
## When to Activate
Trigger this skill aggressively whenever the user wants to:
- "Make it futuristic / premium / cinematic / next-gen"
- Upgrade an existing flat or boring UI
- Build dashboards, fintech apps, AI tools, music/media apps, smart-home apps, wearables, automotive HUDs
- Match Apple Vision Pro, iOS 26, Dynamic Island, or Awwwards-tier aesthetics
- Replace shadcn defaults / Material 3 defaults with something distinctive
- Build for mobile, web, AND desktop with one design language
If the user mentions any of {dashboard, hero, landing page, app shell, control center, player, settings panel, onboarding, paywall, login, splash} and wants it to feel high-end, activate this skill.
## The Lino Stack — How the Four Layers Compose
Every screen is built as **3 stacked z-planes**:
```
z-3: Liquid Glass → primary interactive (CTA, active toolbar, focus card)
z-2: Glassmorphism → floating chrome (nav, modals, HUDs, tooltips)
z-1: Neumorphism → controls embedded in surface (buttons, toggles, sliders)
z-0: Skeuomorphism → hero objects + the textured base canvas
```
Read this rule as: **the further from the user, the more material; the closer, the more luminous.**
## Section 1 — Color & Light System
Lino is a **dual-mode system**. Pick ONE per project.
### Mode A — "Obsidian" (default for futuristic)
- Canvas: `#0A0B0D` (off-black with blue undertone)
- Surface: `#14161A` (raised neumorphic plane)
- Surface inset: `#0F1115`
- Hairline: `rgba(255,255,255,0.06)`
- Inner highlight: `rgba(255,255,255,0.08)`
- Inner shadow: `rgba(0,0,0,0.6)`
- Text primary: `#F5F6F8`
- Text secondary: `#9095A0`
- Accent (pick one only): Electric Cyan `#5EE2FF`, Plasma Violet `#8B7CFF`, Solar Amber `#FFB454`, or Mint Photon `#5EFFB6`
### Mode B — "Pearl" (default for tactile / wellness / premium consumer)
- Canvas: `#ECEEF1` (warm pearl)
- Surface raised: `#F4F6F8`
- Surface inset: `#E4E7EB`
- Hairline: `rgba(15,20,30,0.08)`
- Inner highlight: `rgba(255,255,255,0.9)`
- Inner shadow: `rgba(150,160,180,0.35)`
- Text primary: `#11151B`
- Text secondary: `#5A6473`
- Accent: same options as Obsidian, used sparingly
### Banned colors
Pure `#000`, pure `#FFF` for surfaces, AI purple/blue gradients, more than one accent per screen, neon outer glows, oversaturated default Tailwind palette.
## Section 2 — Neumorphism Layer (the tactile base)
Use for: buttons, toggles, sliders, knobs, segmented controls, search inputs, dial widgets, settings rows.
### The dual-shadow formula
Every neumorphic element gets **two shadows simultaneously** — one light from top-left, one dark from bottom-right.
```css
/* Obsidian mode — raised */
.neu-raised {
background: #14161A;
border-radius: 20px;
box-shadow:
-6px -6px 14px rgba(255,255,255,0.04),
6px 6px 14px rgba(0,0,0,0.55);
}
/* Obsidian mode — inset (pressed / active) */
.neu-inset {
background: #14161A;
border-radius: 20px;
box-shadow:
inset -4px -4px 10px rgba(255,255,255,0.04),
inset 4px 4px 10px rgba(0,0,0,0.55);
}
/* Pearl mode — raised */
.neu-raised-pearl {
background: #ECEEF1;
box-shadow:
-6px -6px 14px rgba(255,255,255,0.9),
6px 6px 14px rgba(150,160,180,0.35);
}
```
### Rules
- Light source is always **top-left at 315°**. Never rotate it across components — inconsistent lighting destroys the illusion.
- Background of the neumorphic element **must equal** the parent surface color. Different colors break the "extruded from the surface" effect.
- Press state = swap raised → inset. Animate over 120ms with `cubic-bezier(0.32, 0.72, 0, 1)`.
- Never put a neumorphic element on a glass / blurred background. It needs an opaque parent.
- Border-radius must be at least 16px — neumorphism collapses at sharp corners.
### Tailwind variant
```tsx
<button className="
bg-[#14161A] rounded-2xl px-6 py-4 text-white/90
shadow-[-6px_-6px_14px_rgba(255,255,255,0.04),6px_6px_14px_rgba(0,0,0,0.55)]
active:shadow-[inset_-4px_-4px_10px_rgba(255,255,255,0.04),inset_4px_4px_10px_rgba(0,0,0,0.55)]
transition-all duration-150 ease-[cubic-bezier(0.32,0.72,0,1)]
">
Press me
</button>
```
## Section 3 — Skeuomorphism Layer (the hero materials)
Use sparingly — **one skeuomorphic hero per screen, max**. Use for: watch faces, music players' vinyl, camera shutters, instrument dials, premium card mockups, the "physical" thing your app is replacing.
### The four real materials Lino supports
**Brushed metal** — subtle horizontal noise + soft gradient + 1px inner highlight at the top edge.
```css
background:
linear-gradient(180deg, #2A2D33 0%, #1B1D21 100%),
url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="2"><rect width="200" height="1" fill="rgba(255,255,255,0.04)"/></svg>');
background-blend-mode: overlay;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), 0 20px 40px rgba(0,0,0,0.4);
```
**Glass-over-glass** (skeuo crystal) — a real-world lens cap effect using `backdrop-filter: blur()` + a radial highlight on top.
```css
position: relative;
background: rgba(255,255,255,0.04);
backdrop-filter: blur(20px) saturate(140%);
border: 1px solid rgba(255,255,255,0.12);
border-radius: 28px;
&::before {
content: '';
position: absolute; inset: 0;
background: radial-gradient(120% 80% at 30% 0%, rgba(255,255,255,0.18), transparent 60%);
border-radius: inherit; pointer-events: none;
}
```
**Soft leather / paper** — fine grain noise + warm tone + inset shadow at edges. Use SVG noise, not images.
**Polished ceramic** — for wellness/health apps. Smooth radial gradient + diffuse soft shadow + zero hairlines.
### Rules
- Skeuomorphic objects **must cast a real shadow on the canvas below**. Always include a soft drop shadow (40-60px blur, 30% opacity, offset Y +20).
- Add a **single specular highlight** at the top — this is what makes it read as a physical object.
- Never apply skeuomorphism to chrome (nav, buttons in toolbars). It belongs on content.
- One material per screen. Brushed metal + leather + glass-over-glass on the same view = costume party.
## Section 4 — Glassmorphism Layer (the floating chrome)
Use for: top navs, side panels that overlay content, modals, popovers, tooltips, command palettes, floating action menus, HUDs over media.
### The four glass strengths
```tsx
// Whisper — barely visible, for ambient HUDs
<div className="bg-white/5 backdrop-blur-sm border border-white/8 rounded-2xl" />
// Standard — nav bars, toolbars
<div className="bg-white/8 backdrop-blur-md saturate-150 border border-white/12 rounded-2xl" />
// Strong — modals, command palettes
<div className="bg-black/35 backdrop-blur-xl saturate-150 border border-white/15 rounded-3xl" />
// Crystal — splash overlays, hero scrims
<div className="bg-white/12 backdrop-blur-2xl saturate-180 border border-white/20 rounded-[2rem]
shadow-[inset_0_1px_0_rgba(255,255,255,0.18),0_20px_60px_rgba(0,0,0,0.4)]" />
```
### Rules — these are the difference between premium glass and slop
- **Always pair** `backdrop-blur` with `saturate(140-180%)`. Without saturation boost, blurred content looks washed out and dead.
- **Always include the inner top highlight**: `inset 0 1px 0 rgba(255,255,255,0.15)`. This is the edge refraction. Skipping it makes the glass look flat.
- **Never** put glass on a flat solid background — it needs busy content behind it (image, gradient, scrolling list) or there's nothing to refract.
- **Never** apply backdrop-blur to scrolling containers — only to fixed/sticky elements. Causes catastrophic mobile FPS drop.
- Border must use `rgba(255,255,255, X)` — never solid gray. The whole point is light passing through the edge.
### Glass over hero image — the canonical Lino nav
```tsx
<nav className="fixed top-4 inset-x-4 z-50 mx-auto max-w-5xl
bg-white/8 backdrop-blur-xl saturate-150
border border-white/12 rounded-full
shadow-[inset_0_1px_0_rgba(255,255,255,0.18),0_8px_32px_rgba(0,0,0,0.3)]
px-6 py-3 flex items-center justify-between">
...
</nav>
```
## Section 5 — Liquid Glass Layer (the interactive light)
This is the **top-of-stack** material — primary CTAs, focus elements, the active tab in a tab bar, the morphing element during a transition. It's glassmorphism + reactive light + spring physics.
### What makes Liquid Glass different from Glassmorphism
| Glassmorphism | Liquid Glass |
|---|---|
| Static blur | Dynamic refraction that **reacts to cursor / touch** |
| Fixed shape | **Morphs** between shapes during state changes |
| Single layer | Has **inner gloss + edge refraction + ambient color pickup** |
| `backdrop-blur` | `backdrop-blur` + `displacement` + `radial highlight that follows pointer` |
### Native iOS 26 (use when available)
```swift
Button("Continue") { /* */ }
.buttonStyle(.glassProminent)
.glassEffect(.regular.tint(.cyan).interactive(), in: .capsule)
```
### Web / React equivalent
```tsx
function LiquidGlassButton({ children }: { children: React.ReactNode }) {
const ref = useRef<HTMLButtonElement>(null);
// pointer position drives a CSS variable for the radial highlight
const onMove = (e: React.PointerEvent) => {
const r = ref.current!.getBoundingClientRect();
ref.current!.style.setProperty('--mx', `${e.clientX - r.left}px`);
ref.current!.style.setProperty('--my', `${e.clientY - r.top}px`);
};
return (
<button
ref={ref}
onPointerMove={onMove}
className="
relative isolate overflow-hidden
px-7 py-3.5 rounded-full
bg-white/10 backdrop-blur-xl saturate-180
border border-white/20
text-white font-medium
shadow-[inset_0_1px_0_rgba(255,255,255,0.25),inset_0_-1px_0_rgba(0,0,0,0.3),0_8px_32px_rgba(0,0,0,0.3)]
transition-transform duration-300 ease-[cubic-bezier(0.32,0.72,0,1)]
active:scale-[0.97]
before:content-[''] before:absolute before:inset-0 before:rounded-full
before:bg-[radial-gradient(120px_circle_at_var(--mx)_var(--my),rgba(255,255,255,0.25),transparent_60%)]
before:pointer-events-none before:transition-opacity
"
>
<span className="relative z-10">{children}</span>
</button>
);
}
```
### Morphing — the signature move
When a Liquid Glass element changes role (button → expanded panel, tab → hero card), it must **morph**, not swap. Use Framer Motion's `layoutId` on web, `matchedGeometryEffect` on iOS.
```tsx
<motion.div layoutId="primary-cta" className="liquid-glass-pill">
{expanded ? <FullPanel /> : <CompactButton />}
</motion.div>
```
Spring physics only: `{ type: "spring", stiffness: 220, damping: 26 }`. Never linear.
## Section 6 — Composition Rules (How to actually build a screen)
A canonical Lino screen, top to bottom:
1. **Canvas** — Obsidian or Pearl. Optionally a slow-drifting radial gradient blob (`opacity: 0.04`, `animation: 30s drift infinite`) to give the glass something to refract.
2. **Hero zone** — one Skeuomorphic object (the watch face, the album art, the device mockup), casting a real shadow.
3. **Content cards** — Neumorphic raised surfaces, holding text and small controls.
4. **Floating chrome** — Glassmorphic nav (top), glass tab bar (bottom on mobile), glass side rail (desktop).
5. **Primary action** — Liquid Glass CTA, single per screen.
### Asymmetric Bento layout (default)
```
┌─────────────────────────────────────┐
│ [Skeuo Hero — col-span-2 row-2] │
│ │
├──────────────┬──────────────────────┤
│ [Neu Card] │ [Neu Card] │
│ │ │
└──────────────┴──────────────────────┘
[Liquid Glass CTA — fixed]
[Glass Nav — fixed top]
```
### Spacing
8px base. Section padding `py-24` minimum on desktop, `py-12` mobile. Card internal padding `p-8` desktop, `p-5` mobile.
### Typography
Display: `Geist`, `Satoshi`, or `SF Pro Display` (iOS). Tight tracking `-0.025em`, weights 500-700.
Body: same family, 400, line-height 1.6, max-width 65ch.
Mono (for numbers in dashboards): `Geist Mono` or `SF Mono`.
Banned: Inter, generic system serifs, Roboto.
## Section 7 — Motion Choreography
Every Lino interaction obeys spring physics. Linear easing is banned.
| Interaction | Spring config | Duration |
|---|---|---|
| Press feedback | `stiffness: 400, damping: 30` | 120ms |
| Hover lift | `stiffness: 250, damping: 25` | 200ms |
| Glass morph | `stiffness: 220, damping: 26` | 400ms |
| Page enter | `stiffness: 100, damping: 20` + 80ms stagger | 600ms |
| Modal in | `stiffness: 180, damping: 22` | 350ms |
**Hardware rule**: animate only `transform` and `opacity`. Never `width`, `height`, `top`, `left`. Backdrop-filter is GPU-expensive — apply only to fixed elements, never scroll-bound.
**Perpetual micro-loops** — every active dashboard tile gets one infinite subtle animation: pulse on a status dot, shimmer on a skeleton, slow drift on a background blob. Never on more than 3 elements per viewport.
## Section 8 — Platform Adaptation
### Mobile (iOS / Android / React Native / Flutter)
- Bottom tab bar: Glassmorphism strong, `safe-area-inset-bottom` padding.
- Primary CTA: Liquid Glass, full-width with 16px side margin, `min-h: 56px` for thumb.
- Cards: Neumorphism, `border-radius: 24px`.
- Hero: Skeuomorphism (album art, watch face).
- Touch targets: 44x44 min. Press state = neu inset transition.
- Use `min-height: 100dvh`, never `100vh` (iOS Safari jump).
### Web (React / Next / Vue / Svelte)
- Top nav: floating Glass pill, detached from edge with `mt-4 mx-auto`.
- Dashboard cards: Neumorphic Bento grid (asymmetric, never 3 equal columns).
- Modals: Glass strong with backdrop scrim `bg-black/40`.
- CTA: Liquid Glass with cursor-tracking highlight.
- Responsive: collapse all multi-col to single col under 768px. `w-full px-4`.
### Desktop (Electron / Tauri / macOS / Windows native)
- Window chrome: Glass standard with traffic lights / window controls.
- Sidebar: Neumorphism inset rail, 72px wide collapsed / 240px expanded.
- Content area: Skeuomorphic surface (paper, leather) for document apps; Obsidian canvas for tools.
- Command palette (Cmd-K): Glass crystal, centered, with Liquid Glass selected row.
- Use platform vibrancy APIs when available (`NSVisualEffectView` on macOS, `Mica` on Windows 11) instead of CSS backdrop-filter.
## Section 9 — Accessibility (non-negotiable)
- **Reduced motion**: respect `prefers-reduced-motion: reduce`. Disable morphing, perpetual loops, parallax. Keep press feedback.
- **Reduced transparency**: respect `prefers-reduced-transparency`. Replace glass surfaces with opaque equivalents using the surface token.
- **Contrast**: text on glass must hit 4.5:1. If the background is unpredictable (image), add a subtle `bg-black/40` scrim under the glass.
- **Focus rings**: visible 2px ring in accent color, 2px offset. Liquid Glass elements get a ring + subtle outer glow on focus-visible.
- **Hit area**: 44x44 mobile, 32x32 desktop minimum.
- Test with screen reader: glass / skeuo decorative effects must be `aria-hidden`.
## Section 10 — Anti-Patterns (auto-fail)
- ❌ Mixing 3+ materials at the same z-level (e.g. neumorphism + skeuomorphism on the same button)
- ❌ Glass on a flat solid background (nothing to refract)
- ❌ Backdrop-blur on scrolling containers (kills mobile FPS)
- ❌ Pure `#000` or `#FFF` surfaces
- ❌ More than one accent color per screen
- ❌ More than one Skeuomorphic hero per screen
- ❌ More than one Liquid Glass primary CTA per screen
- ❌ Linear easing
- ❌ Animating `width`/`height`/`top`/`left`
- ❌ Inconsistent neumorphic light direction (always top-left at 315°)
- ❌ Glass without `saturate()` companion
- ❌ Glass without inner top highlight
- ❌ Neumorphism on a glass parent
- ❌ Emojis as icons (use Phosphor Light, SF Symbols, or Radix Icons)
- ❌ Inter font in any premium context
- ❌ AI purple/blue gradients
- ❌ Generic shadcn defaults left untuned
## Section 11 — Pre-Flight Checklist
Before shipping any Lino screen:
- [ ] One canvas mode (Obsidian or Pearl), not both
- [ ] One accent color
- [ ] At most one Skeuomorphic hero
- [ ] At most one Liquid Glass primary CTA
- [ ] All glass surfaces include `saturate()` + inner top highlight
- [ ] Neumorphic elements share parent surface color, light from 315°
- [ ] All transitions use spring physics (not linear / ease-in-out)
- [ ] Backdrop-blur only on fixed/sticky elements
- [ ] Layout collapses to single column under 768px
- [ ] `min-h-[100dvh]` not `h-screen`
- [ ] `prefers-reduced-motion` and `prefers-reduced-transparency` honored
- [ ] Focus rings visible on all interactive elements
- [ ] Touch targets ≥ 44x44 on mobile
- [ ] No banned fonts, colors, or motion patterns
- [ ] Real device test on a mid-tier Android (glass FPS check)
## Section 12 — Quick-Start Recipes
### Recipe: Futuristic mobile app shell (React Native / Expo)
1. Canvas: Obsidian.
2. Top status bar: transparent, `safe-area-inset-top`.
3. Hero card: Skeuomorphic (brushed metal background) holding the day's primary content.
4. Two Bento Neumorphic cards below.
5. Bottom tab bar: Glass standard, fixed, blur-xl + saturate-150.
6. Active tab indicator: Liquid Glass pill that morphs between tabs via `layoutId`.
### Recipe: Premium SaaS dashboard (Next.js + Tailwind)
1. Canvas: Obsidian with one drifting radial blob in the accent color (`opacity-[0.05]`).
2. Top nav: floating Glass pill, full-width minus 32px margin, rounded-full.
3. Sidebar: Neumorphic inset rail.
4. Main grid: 5-card Bento (1 large + 4 small), each Neumorphic raised.
5. Primary CTA in header: Liquid Glass with cursor-tracking highlight.
6. Modals (Cmd-K): Glass crystal, Liquid Glass on selected row.
### Recipe: Music / media app (cross-platform)
1. Canvas: Obsidian.
2. Hero: Skeuomorphic vinyl / album art with real cast shadow, slowly rotating during playback.
3. Player controls: Neumorphic raised circular buttons (play/pause swaps raised ↔ inset).
4. Now-playing bar: Glass standard, fixed bottom.
5. Lyrics overlay: Glass crystal full-screen sheet.
6. Next-track button: Liquid Glass that morphs into expanded queue.
### Recipe: Smart-home / IoT control panel (desktop / tablet)
1. Canvas: Pearl (warmer, more residential).
2. Hero: Skeuomorphic thermostat dial (polished ceramic) with real shadow.
3. Room cards: Neumorphic raised, one per room.
4. Top bar: Glass whisper.
5. Scene activator: Liquid Glass capsule, morphs to show active scene.
---
## Final principle
Lino UI is **not maximalism**. It's **disciplined material stacking**. Every layer earns its place by doing one job the others can't. When in doubt, remove a layer rather than add one. A screen with only Neumorphism + Glass can still be a Lino screen. A screen with all four piled on top of each other is a costume.
The goal is the feeling of holding a piece of impossibly well-engineered hardware that happens to be made of light.