
Arcan Glass
- 5 installs
- Updated May 14, 2026
- broomva/arcan-glass
arcan-glass is a skill that provides a drop-in glass/frosted-effect styling system with dark-first OKLCh theming for Next.js, Tailwind v4, and shadcn/ui.
About
A web styling system that adds glass/frosted UI effects and a dark-first brand theme to Next.js, Tailwind v4, and shadcn/ui projects. A frontend developer uses it to drop in a globals.css and apply glass component classes like glass-card and glass-nav. It provides an OKLCh color system, brand tokens, and composable animation presets.
- Drop-in globals.css with glass/frosted UI effects for Next.js + Tailwind v4 + shadcn/ui
- OKLCh color system with AI Blue and Web3 Green brand tokens
- Glass component patterns (card, nav, button, modal, sidebar) and animation presets
Arcan Glass by the numbers
- 5 all-time installs (skills.sh)
- Ranked #1,513 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
- Data as of Jul 8, 2026 (Skillselion catalog sync)
arcan-glass capabilities & compatibility
- Capabilities
- frontend · ui design
- Use cases
- frontend · ui design · web design
- IDEs
- vscode · cursor ide
What arcan-glass says it does
Copy** `arcan-glass/assets/globals.css` into your Next.js project as `app/globals.css`
Three intensity presets: `glass-subtle` (40% / 8px), `glass` (60% / 16px), `glass-heavy` (80% / 24px).
All shadcn/ui components automatically pick up the Arcan Glass theme.
npx skills add https://github.com/broomva/arcan-glass --skill arcan-glassAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 5 |
|---|---|
| Last updated | May 14, 2026 |
| Repository | broomva/arcan-glass ↗ |
What it does
Style Next.js + Tailwind v4 + shadcn/ui interfaces with glass effects, dark-first theming, and OKLCh tokens.
Who is it for?
Adding glass/frosted UI effects and dark-first branding to Next.js + Tailwind + shadcn/ui apps
Skip if: Backend styling or non-Tailwind/shadcn stacks
When should I use this skill?
You are styling a web interface with frosted glass effects or setting up a dark-first brand theme
What you get
A themed Next.js UI with glass components and brand-consistent OKLCh tokens
- globals.css with tokens, glass utilities, components, and animations
By the numbers
- 7 glass components
- 3 glass intensity presets (subtle, glass, heavy)
- 4 composable glass layers
Files
Arcan Glass
Arcan Glass is BroomVA's trademark web design language — ArcanBG's brand DNA (AI Blue #0066FF + Web3 Green #00CC66 + dark surfaces) fused with liquid glass web effects (backdrop-filter blur, layered highlights, adaptive tinting, morphing transitions). Dark-first, glass-elevated.
Light mode is Day Glass: a luminous 275° violet surface system, not a white inversion. It keeps hue continuity, uses low chroma to avoid glare, and preserves clear OKLCh lightness distance between surfaces, text, borders, and shadows.
Quick Start
1. Copy assets/globals.css into your Next.js project as app/globals.css 2. Import in your layout: import "./globals.css" 3. Use glass classes: <div class="glass-card">, <button class="glass-button glass-button-primary">
That's it. All shadcn/ui components will automatically pick up the Arcan Glass theme.
7 Design Principles
1. Dark-first, Day Glass second — The default is dark mode. Light mode keeps the same 275° hue DNA with higher lightness, low chroma, and grounded shadows. 2. Glass is earned — Only key surfaces (nav, sidebar, modal, featured cards) get backdrop-filter. Limit to 3-5 per viewport. 3. Brand through surface — Surface hue 275° (blue-purple) connects all surfaces to AI Blue without competing. 4. OKLCh primary — Perceptually uniform lightness enables clean depth scales and natural color mixing. 5. Additive on shadcn — Glass effects layer on top of shadcn/ui, never replacing base accessibility. 6. Motion with purpose — Every animation communicates state (glow = active, lift = interactive, reveal = entering). Reduced motion is always respected. 7. Token-prefixed — All custom properties use --ag- prefix to avoid collisions with shadcn (--) and Tailwind (--tw-).
Glass Effect System
Every glass component is built from 4 composable layers:
| Layer | Technique | Purpose |
|---|---|---|
| 1. Backdrop blur | backdrop-filter: blur() saturate() | Frosted glass foundation |
| 2. Highlight | ::before with top-edge gradient | Light reflection / depth cue |
| 3. Shadow | Multi-level box-shadow | Elevation / grounding |
| 4. Adaptive tint | color-mix(in oklab) | Contextual color pickup |
Three intensity presets: glass-subtle (40% / 8px), glass (60% / 16px), glass-heavy (80% / 24px).
See references/glass-components.md for full component patterns.
Color System
Brand colors in OKLCh with hex fallbacks:
| Token | Color | Usage |
|---|---|---|
--ag-ai-blue | oklch(0.55 0.25 260) / #0066FF | Primary, interactive, links |
--ag-web3-green | oklch(0.72 0.19 155) / #00CC66 | Accent, success, web3 |
5-step surface scale at hue 275°, 4-level text hierarchy, semantic colors, 3-level border scale.
Full palette: references/color-system.md
Tailwind Integration
All tokens wired via @theme inline:
<!-- Brand colors as utilities -->
<div class="bg-ai-blue text-white">Primary</div>
<span class="text-web3-green">Accent</span>
<!-- Glass utilities -->
<div class="glass p-6">Standard glass</div>
<nav class="glass-heavy sticky top-0">Heavy glass nav</nav>
<!-- Glow effects -->
<div class="glass-card glow-blue">Glowing card</div>shadcn/ui components work unchanged — bg-primary, bg-card, text-muted-foreground, etc. all resolve to Arcan Glass tokens.
Full mapping: references/tailwind-integration.md
Component Index
| Component | Class | Glass Level | Notes |
|---|---|---|---|
| Card | .glass-card | Medium | Highlight + hover lift |
| Nav | .glass-nav | Heavy | Sticky, bottom border |
| Button | .glass-button | Medium | + .glass-button-primary, .glass-button-accent |
| Input | .glass-input | Subtle | Focus ring with blue glow |
| Modal | .glass-modal | Heavy | + .glass-modal-overlay, reveal animation |
| Sidebar | .glass-sidebar | Heavy | Full height, right border |
| Badge | .glass-badge | Subtle | + .glass-badge-blue, .glass-badge-green |
Full patterns with raw CSS + Tailwind composition: references/glass-components.md
Animation Index
| Animation | Tailwind | Duration | Usage |
|---|---|---|---|
| Glow pulse | animate-glow-pulse | 2s loop | Active/loading states |
| Glass reveal | animate-glass-reveal | 0.5s once | Entry animations |
| Gradient flow | animate-gradient-flow | 8s loop | Hero backgrounds |
Plus hover lift, morph, focus ring, scroll reveal patterns.
Full patterns: references/animation-patterns.md
shadcn/ui Compatibility
Arcan Glass defines all required shadcn/ui CSS variables. To add glass variants to shadcn components, extend with cva:
// In your button.tsx variants
glass: "glass glass-highlight hover:-translate-y-px hover:shadow-lg",
"glass-primary": "glass-button glass-button-primary",See references/tailwind-integration.md for full cva examples.
Dark/Light Mode
Uses next-themes with class strategy (.dark / .light). All tokens auto-adapt via CSS custom properties — explicit dark: prefixes are rarely needed. Light mode should be authored as Day Glass: tinted surfaces around OKLCh L=0.91-0.985, primary text near L=0.19, and darker low-chroma borders with alpha instead of pale gray outlines.
<ThemeProvider attribute="class" defaultTheme="dark">
{children}
</ThemeProvider>Performance Notes
- Limit `backdrop-filter` to 3-5 elements per viewport — each creates a compositing layer
- Use `glass-subtle` for repeated items (list items, table rows)
- Reserve `glass-heavy` for landmark surfaces (nav, sidebar, modal)
- Test on lower-end devices —
backdrop-filterperf varies by GPU - P3 gamut enhancement is automatic via
@media (color-gamut: p3)— wider chroma on capable displays - Reduced motion is handled globally — all transforms and animations respect
prefers-reduced-motion
Resources
references/
color-system.md— Full OKLCh palette, hex fallbacks, surface scale, text hierarchydesign-tokens.md— Shadows, blur, radius, spacing, typography, transitionsglass-components.md— 4-layer glass system, component CSS patterns + Tailwind compositionanimation-patterns.md— Glow pulse, hover lift, morph, scroll reveal, gradient flowtailwind-integration.md— @theme inline wiring, @utility blocks, shadcn mapping, cva extensions
assets/
globals.css— Drop-in CSS file with all tokens, glass utilities, components, and animations
/* ============================================================================
Arcan Glass — BroomVA Trademark Web Styling
Drop-in CSS for Next.js + Tailwind v4 + shadcn/ui
============================================================================ */
@import "tailwindcss";
@import "tw-animate-css";
@custom-variant dark (&:is(.dark *));
@plugin "@tailwindcss/typography";
/* ============================================================================
1. CUSTOM PROPERTIES — Dark Mode (Default)
============================================================================ */
:root {
/* --- Brand --- */
--ag-ai-blue: oklch(0.55 0.25 260);
--ag-web3-green: oklch(0.72 0.19 155);
/* --- Surfaces (hue 275° blue-purple) --- */
--ag-bg-deep: oklch(0.12 0.02 275);
--ag-bg-dark: oklch(0.15 0.04 245);
--ag-bg-surface: oklch(0.17 0.03 275);
--ag-bg-elevated: oklch(0.22 0.03 275);
--ag-bg-hover: oklch(0.26 0.03 275);
/* --- Text hierarchy --- */
--ag-text-primary: oklch(0.98 0 0);
--ag-text-secondary: oklch(0.70 0.02 275);
--ag-text-muted: oklch(0.50 0.02 275);
--ag-text-disabled: oklch(0.38 0.02 275);
/* --- Semantic --- */
--ag-success: oklch(0.72 0.19 155);
--ag-warning: oklch(0.87 0.18 85);
--ag-error: oklch(0.58 0.24 27);
--ag-info: oklch(0.55 0.25 260);
/* --- Borders --- */
--ag-border-subtle: oklch(0.30 0.02 275 / 0.40);
--ag-border-default: oklch(0.40 0.02 275 / 0.50);
--ag-border-strong: oklch(0.50 0.02 275 / 0.60);
--ag-border-focus: oklch(0.55 0.25 260);
/* --- Glass opacity scale --- */
--ag-glass-light: 0.40;
--ag-glass-medium: 0.60;
--ag-glass-heavy: 0.80;
/* --- Glass backdrop --- */
--ag-blur-sm: 4px;
--ag-blur-md: 8px;
--ag-blur-lg: 16px;
--ag-blur-xl: 24px;
/* --- Shadows --- */
--ag-shadow-xs: 0 1px 2px oklch(0 0 0 / 0.30);
--ag-shadow-sm: 0 2px 4px oklch(0 0 0 / 0.35);
--ag-shadow-md: 0 4px 8px oklch(0 0 0 / 0.40);
--ag-shadow-lg: 0 8px 16px oklch(0 0 0 / 0.45);
--ag-shadow-xl: 0 16px 32px oklch(0 0 0 / 0.50);
--ag-shadow-2xl: 0 24px 48px oklch(0 0 0 / 0.55);
--ag-shadow-glow-blue: 0 0 20px oklch(0.55 0.25 260 / 0.25);
--ag-shadow-glow-green: 0 0 20px oklch(0.72 0.19 155 / 0.25);
/* --- Radius --- */
--ag-radius-sm: 4px;
--ag-radius-md: 8px;
--ag-radius-lg: 12px;
--ag-radius-xl: 16px;
--ag-radius-full: 9999px;
--ag-radius-glass: 12px;
/* --- Typography --- */
--ag-font-heading: "Poppins", system-ui, -apple-system, sans-serif;
--ag-font-body: -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
--ag-font-mono: "SF Mono", "Fira Code", "JetBrains Mono", "Menlo", monospace;
/* --- Spacing (4px base) --- */
--ag-space-1: 0.25rem;
--ag-space-2: 0.5rem;
--ag-space-3: 0.75rem;
--ag-space-4: 1rem;
--ag-space-5: 1.25rem;
--ag-space-6: 1.5rem;
--ag-space-8: 2rem;
--ag-space-10: 2.5rem;
--ag-space-12: 3rem;
--ag-space-16: 4rem;
/* --- Transitions --- */
--ag-transition-fast: 150ms ease;
--ag-transition-normal: 250ms ease;
--ag-transition-slow: 350ms ease;
--ag-transition-morph: 500ms cubic-bezier(0.4, 0, 0.2, 1);
--ag-transition-glow: 1500ms ease-in-out;
/* --- shadcn/ui compatibility mapping --- */
--background: var(--ag-bg-deep);
--foreground: var(--ag-text-primary);
--card: var(--ag-bg-surface);
--card-foreground: var(--ag-text-primary);
--popover: var(--ag-bg-elevated);
--popover-foreground: var(--ag-text-primary);
--primary: var(--ag-ai-blue);
--primary-foreground: oklch(0.98 0 0);
--secondary: var(--ag-bg-hover);
--secondary-foreground: var(--ag-text-primary);
--muted: var(--ag-bg-surface);
--muted-foreground: var(--ag-text-muted);
--accent: var(--ag-web3-green);
--accent-foreground: oklch(0.12 0.02 275);
--destructive: var(--ag-error);
--destructive-foreground: oklch(0.98 0 0);
--success: var(--ag-success);
--border: var(--ag-border-default);
--input: var(--ag-border-default);
--ring: var(--ag-ai-blue);
--radius: var(--ag-radius-glass);
/* --- Sidebar (shadcn/ui sidebar) --- */
--sidebar: var(--ag-bg-dark);
--sidebar-foreground: var(--ag-text-primary);
--sidebar-primary: var(--ag-ai-blue);
--sidebar-primary-foreground: oklch(0.98 0 0);
--sidebar-accent: var(--ag-bg-hover);
--sidebar-accent-foreground: var(--ag-text-primary);
--sidebar-border: var(--ag-border-subtle);
--sidebar-ring: var(--ag-ai-blue);
/* --- Charts --- */
--chart-1: var(--ag-ai-blue);
--chart-2: var(--ag-web3-green);
--chart-3: oklch(0.65 0.22 330);
--chart-4: var(--ag-warning);
--chart-5: oklch(0.60 0.20 30);
}
/* ============================================================================
2. LIGHT MODE OVERRIDES — Day Glass
============================================================================ */
.light {
--ag-bg-deep: oklch(0.965 0.014 275);
--ag-bg-dark: oklch(0.930 0.020 275);
--ag-bg-surface: oklch(0.985 0.008 275);
--ag-bg-elevated: oklch(0.955 0.016 275);
--ag-bg-hover: oklch(0.910 0.024 275);
--ag-text-primary: oklch(0.190 0.030 275);
--ag-text-secondary: oklch(0.390 0.026 275);
--ag-text-muted: oklch(0.530 0.022 275);
--ag-text-disabled: oklch(0.680 0.016 275);
--ag-border-subtle: oklch(0.650 0.030 275 / 0.22);
--ag-border-default: oklch(0.560 0.035 275 / 0.32);
--ag-border-strong: oklch(0.450 0.045 275 / 0.42);
--ag-shadow-xs: 0 1px 2px oklch(0.200 0.030 275 / 0.06);
--ag-shadow-sm: 0 2px 5px oklch(0.200 0.030 275 / 0.08), 0 1px 0 oklch(1 0 0 / 0.70) inset;
--ag-shadow-md: 0 8px 24px oklch(0.200 0.030 275 / 0.10), 0 1px 0 oklch(1 0 0 / 0.72) inset;
--ag-shadow-lg: 0 16px 40px oklch(0.200 0.030 275 / 0.14), 0 1px 0 oklch(1 0 0 / 0.76) inset;
--ag-shadow-xl: 0 24px 56px oklch(0.200 0.030 275 / 0.16), 0 1px 0 oklch(1 0 0 / 0.78) inset;
--ag-shadow-2xl: 0 36px 72px oklch(0.200 0.030 275 / 0.18), 0 1px 0 oklch(1 0 0 / 0.80) inset;
--ag-shadow-glow-blue: 0 0 20px oklch(0.55 0.25 260 / 0.16);
--ag-shadow-glow-green: 0 0 20px oklch(0.72 0.19 155 / 0.16);
--ag-glass-light: 0.66;
--ag-glass-medium: 0.78;
--ag-glass-heavy: 0.88;
/* shadcn/ui light overrides */
--primary-foreground: oklch(0.98 0 0);
--accent-foreground: oklch(0.12 0.02 275);
--destructive-foreground: oklch(0.98 0 0);
}
/* ============================================================================
3. HEX FALLBACKS for browsers without OKLCh support
============================================================================ */
@supports not (color: oklch(0 0 0)) {
:root {
--ag-ai-blue: #0066ff;
--ag-web3-green: #00cc66;
--ag-bg-deep: #12121a;
--ag-bg-dark: #001f3f;
--ag-bg-surface: #1a1a2e;
--ag-bg-elevated: #232340;
--ag-bg-hover: #2a2a4a;
--ag-text-primary: #ffffff;
--ag-text-secondary: #a0a0b8;
--ag-text-muted: #6b6b80;
--ag-text-disabled: #4a4a5c;
--ag-success: #00cc66;
--ag-warning: #ffd60a;
--ag-error: #ff3b30;
--ag-info: #0066ff;
--ag-border-subtle: rgba(255, 255, 255, 0.06);
--ag-border-default: rgba(255, 255, 255, 0.10);
--ag-border-strong: rgba(255, 255, 255, 0.16);
--ag-border-focus: #0066ff;
--ag-shadow-glow-blue: 0 0 20px rgba(0, 102, 255, 0.25);
--ag-shadow-glow-green: 0 0 20px rgba(0, 204, 102, 0.25);
--background: #12121a;
--foreground: #ffffff;
--card: #1a1a2e;
--card-foreground: #ffffff;
--popover: #232340;
--popover-foreground: #ffffff;
--primary: #0066ff;
--primary-foreground: #ffffff;
--secondary: #2a2a4a;
--secondary-foreground: #ffffff;
--muted: #1a1a2e;
--muted-foreground: #6b6b80;
--accent: #00cc66;
--accent-foreground: #12121a;
--destructive: #ff3b30;
--destructive-foreground: #ffffff;
--border: rgba(255, 255, 255, 0.10);
--input: rgba(255, 255, 255, 0.10);
--ring: #0066ff;
}
.light {
--ag-bg-deep: #f2eff8;
--ag-bg-dark: #e6e0ef;
--ag-bg-surface: #fbfaff;
--ag-bg-elevated: #eee9f5;
--ag-bg-hover: #dcd5e8;
--ag-text-primary: #211f2b;
--ag-text-secondary: #575063;
--ag-text-muted: #787181;
--ag-text-disabled: #aaa4b0;
--ag-border-subtle: rgba(80, 68, 100, 0.22);
--ag-border-default: rgba(74, 62, 94, 0.32);
--ag-border-strong: rgba(64, 52, 84, 0.42);
--ag-shadow-xs: 0 1px 2px rgba(36, 30, 50, 0.06);
--ag-shadow-sm: 0 2px 5px rgba(36, 30, 50, 0.08), 0 1px 0 rgba(255, 255, 255, 0.70) inset;
--ag-shadow-md: 0 8px 24px rgba(36, 30, 50, 0.10), 0 1px 0 rgba(255, 255, 255, 0.72) inset;
--ag-shadow-lg: 0 16px 40px rgba(36, 30, 50, 0.14), 0 1px 0 rgba(255, 255, 255, 0.76) inset;
--ag-shadow-xl: 0 24px 56px rgba(36, 30, 50, 0.16), 0 1px 0 rgba(255, 255, 255, 0.78) inset;
--ag-shadow-2xl: 0 36px 72px rgba(36, 30, 50, 0.18), 0 1px 0 rgba(255, 255, 255, 0.80) inset;
--background: #f2eff8;
--foreground: #211f2b;
--card: #fbfaff;
--card-foreground: #211f2b;
--popover: #eee9f5;
--popover-foreground: #211f2b;
--secondary: #dcd5e8;
--secondary-foreground: #211f2b;
--muted: #fbfaff;
--muted-foreground: #787181;
--accent-foreground: #12121a;
--border: rgba(74, 62, 94, 0.32);
--input: rgba(74, 62, 94, 0.32);
}
}
/* ============================================================================
4. TAILWIND v4 @theme inline — maps --ag-* to Tailwind utility namespace
============================================================================ */
@theme inline {
/* Colors */
--color-ai-blue: var(--ag-ai-blue);
--color-web3-green: var(--ag-web3-green);
--color-bg-deep: var(--ag-bg-deep);
--color-bg-dark: var(--ag-bg-dark);
--color-bg-surface: var(--ag-bg-surface);
--color-bg-elevated: var(--ag-bg-elevated);
--color-bg-hover: var(--ag-bg-hover);
--color-text-primary: var(--ag-text-primary);
--color-text-secondary: var(--ag-text-secondary);
--color-text-muted: var(--ag-text-muted);
--color-text-disabled: var(--ag-text-disabled);
--color-success: var(--success);
--color-warning: var(--ag-warning);
--color-error: var(--ag-error);
--color-info: var(--ag-info);
/* shadcn/ui semantic colors */
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
/* Sidebar */
--color-sidebar: var(--sidebar);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-ring: var(--sidebar-ring);
/* Charts */
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
/* Typography */
--font-heading: var(--ag-font-heading);
--font-body: var(--ag-font-body);
--font-mono: var(--ag-font-mono);
--font-sans: var(--ag-font-body);
/* Radius */
--radius-sm: var(--ag-radius-sm);
--radius-md: var(--ag-radius-md);
--radius-lg: var(--ag-radius-lg);
--radius-xl: var(--ag-radius-xl);
--radius-full: var(--ag-radius-full);
/* Shadows */
--shadow-xs: var(--ag-shadow-xs);
--shadow-sm: var(--ag-shadow-sm);
--shadow-md: var(--ag-shadow-md);
--shadow-lg: var(--ag-shadow-lg);
--shadow-xl: var(--ag-shadow-xl);
--shadow-2xl: var(--ag-shadow-2xl);
--shadow-glow-blue: var(--ag-shadow-glow-blue);
--shadow-glow-green: var(--ag-shadow-glow-green);
/* Animations */
--animate-glow-pulse: glow-pulse 2s ease-in-out infinite;
--animate-glass-reveal: glass-reveal 0.5s cubic-bezier(0.4, 0, 0.2, 1) forwards;
--animate-gradient-flow: gradient-flow 8s ease infinite;
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
@keyframes glow-pulse {
0%, 100% {
box-shadow: 0 0 16px oklch(0.55 0.25 260 / 0.20);
}
50% {
box-shadow: 0 0 28px oklch(0.55 0.25 260 / 0.40);
}
}
@keyframes glass-reveal {
from {
opacity: 0;
backdrop-filter: blur(0px);
transform: translateY(8px) scale(0.98);
}
to {
opacity: 1;
backdrop-filter: blur(var(--ag-blur-lg));
transform: translateY(0) scale(1);
}
}
@keyframes gradient-flow {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes accordion-down {
from { height: 0; }
to { height: var(--radix-accordion-content-height); }
}
@keyframes accordion-up {
from { height: var(--radix-accordion-content-height); }
to { height: 0; }
}
}
/* ============================================================================
5. GLASS UTILITIES — @utility blocks for Tailwind v4
============================================================================ */
@utility glass {
background: color-mix(in oklab, var(--ag-bg-surface) calc(var(--ag-glass-medium) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
-webkit-backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
border: 1px solid var(--ag-border-subtle);
border-radius: var(--ag-radius-glass);
}
@utility glass-subtle {
background: color-mix(in oklab, var(--ag-bg-surface) calc(var(--ag-glass-light) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-md)) saturate(1.1);
-webkit-backdrop-filter: blur(var(--ag-blur-md)) saturate(1.1);
border: 1px solid var(--ag-border-subtle);
border-radius: var(--ag-radius-glass);
}
@utility glass-heavy {
background: color-mix(in oklab, var(--ag-bg-surface) calc(var(--ag-glass-heavy) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
-webkit-backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
border: 1px solid var(--ag-border-default);
border-radius: var(--ag-radius-glass);
}
@utility glow-blue {
box-shadow: var(--ag-shadow-glow-blue);
}
@utility glow-green {
box-shadow: var(--ag-shadow-glow-green);
}
@utility glass-highlight {
position: relative;
&::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
180deg,
oklch(1 0 0 / 0.05) 0%,
oklch(1 0 0 / 0.02) 20%,
transparent 50%
);
pointer-events: none;
}
}
/* ============================================================================
6. BASE LAYER — Resets, body, scrollbar, focus, typography
============================================================================ */
@layer base {
*,
*::before,
*::after {
@apply border-border;
}
* {
@apply min-w-0;
}
::after,
::before,
::backdrop,
::file-selector-button {
@apply border-border;
}
html {
text-rendering: optimizelegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
@apply bg-background text-foreground min-h-dvh;
font-family: var(--ag-font-body);
line-height: 1.5;
}
/* Scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--ag-border-strong);
border-radius: var(--ag-radius-full);
}
::-webkit-scrollbar-thumb:hover {
background: var(--ag-text-muted);
}
/* Focus */
:focus-visible {
outline: 2px solid var(--ag-border-focus);
outline-offset: 2px;
border-radius: var(--ag-radius-sm);
}
/* Headings */
h1, h2, h3, h4, h5, h6 {
font-family: var(--ag-font-heading);
font-weight: 600;
line-height: 1.2;
color: var(--ag-text-primary);
}
/* Links */
a {
color: var(--ag-ai-blue);
text-decoration: none;
transition: color var(--ag-transition-fast);
}
a:hover {
text-decoration: underline;
}
/* Code */
code, pre {
font-family: var(--ag-font-mono);
}
/* Inputs */
input::placeholder,
textarea::placeholder {
@apply text-muted-foreground;
}
button:not(:disabled),
[role="button"]:not(:disabled) {
@apply cursor-pointer;
}
}
/* ============================================================================
7. COMPONENT LAYER — Glass components
============================================================================ */
@layer components {
/* --- Glass Card --- */
.glass-card {
position: relative;
background: color-mix(in oklab, var(--ag-bg-surface) calc(var(--ag-glass-medium) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
-webkit-backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
border: 1px solid var(--ag-border-subtle);
border-radius: var(--ag-radius-glass);
box-shadow: var(--ag-shadow-md);
padding: var(--ag-space-6);
transition: transform var(--ag-transition-normal), box-shadow var(--ag-transition-normal);
}
.glass-card::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
180deg,
oklch(1 0 0 / 0.05) 0%,
oklch(1 0 0 / 0.02) 20%,
transparent 50%
);
pointer-events: none;
}
.glass-card:hover {
transform: translateY(-2px);
box-shadow: var(--ag-shadow-lg);
}
/* --- Glass Nav --- */
.glass-nav {
position: relative;
background: color-mix(in oklab, var(--ag-bg-dark) calc(var(--ag-glass-heavy) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
-webkit-backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
border-bottom: 1px solid var(--ag-border-subtle);
box-shadow: var(--ag-shadow-sm);
}
.glass-nav::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
180deg,
oklch(1 0 0 / 0.04) 0%,
transparent 100%
);
pointer-events: none;
}
/* --- Glass Button (default) --- */
.glass-button {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--ag-space-2);
background: color-mix(in oklab, var(--ag-bg-elevated) calc(var(--ag-glass-medium) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-md)) saturate(1.1);
-webkit-backdrop-filter: blur(var(--ag-blur-md)) saturate(1.1);
border: 1px solid var(--ag-border-default);
border-radius: var(--ag-radius-md);
padding: var(--ag-space-2) var(--ag-space-4);
color: var(--ag-text-primary);
font-family: var(--ag-font-body);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
min-height: 2.5rem;
transition: background var(--ag-transition-fast), border-color var(--ag-transition-fast), color var(--ag-transition-fast), box-shadow var(--ag-transition-fast), transform var(--ag-transition-fast);
}
.glass-button:hover {
background: color-mix(in oklab, var(--ag-bg-hover) calc(var(--ag-glass-medium) * 100%), transparent);
border-color: var(--ag-border-strong);
transform: translateY(-1px);
box-shadow: var(--ag-shadow-sm);
}
.glass-button:active {
transform: scale(0.96);
}
/* --- Glass Button Primary --- */
.glass-button-primary {
background: color-mix(in oklab, var(--ag-ai-blue) 85%, transparent);
border-color: oklch(0.60 0.25 260 / 0.50);
color: oklch(0.98 0 0);
}
.glass-button-primary:hover {
background: color-mix(in oklab, var(--ag-ai-blue) 95%, transparent);
box-shadow: var(--ag-shadow-glow-blue);
}
/* --- Glass Button Accent --- */
.glass-button-accent {
background: color-mix(in oklab, var(--ag-web3-green) 85%, transparent);
border-color: oklch(0.75 0.19 155 / 0.50);
color: oklch(0.12 0.02 275);
}
.glass-button-accent:hover {
background: color-mix(in oklab, var(--ag-web3-green) 95%, transparent);
box-shadow: var(--ag-shadow-glow-green);
}
/* --- Glass Input --- */
.glass-input {
background: color-mix(in oklab, var(--ag-bg-surface) calc(var(--ag-glass-light) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-sm));
-webkit-backdrop-filter: blur(var(--ag-blur-sm));
border: 1px solid var(--ag-border-default);
border-radius: var(--ag-radius-md);
padding: var(--ag-space-2) var(--ag-space-3);
color: var(--ag-text-primary);
font-family: var(--ag-font-body);
font-size: 0.875rem;
transition: border-color var(--ag-transition-fast), box-shadow var(--ag-transition-fast);
}
.glass-input::placeholder {
color: var(--ag-text-muted);
}
.glass-input:focus {
outline: none;
border-color: var(--ag-border-focus);
box-shadow: 0 0 0 3px oklch(0.55 0.25 260 / 0.15);
}
/* --- Glass Modal --- */
.glass-modal {
position: relative;
background: color-mix(in oklab, var(--ag-bg-elevated) calc(var(--ag-glass-heavy) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
-webkit-backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.3);
border: 1px solid var(--ag-border-default);
border-radius: var(--ag-radius-xl);
box-shadow: var(--ag-shadow-2xl);
padding: var(--ag-space-8);
animation: glass-reveal 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}
.glass-modal::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
180deg,
oklch(1 0 0 / 0.06) 0%,
oklch(1 0 0 / 0.02) 15%,
transparent 40%
);
pointer-events: none;
}
/* --- Glass Modal Overlay --- */
.glass-modal-overlay {
position: fixed;
inset: 0;
background: oklch(0 0 0 / 0.60);
backdrop-filter: blur(var(--ag-blur-sm));
-webkit-backdrop-filter: blur(var(--ag-blur-sm));
}
/* --- Glass Sidebar --- */
.glass-sidebar {
position: relative;
background: color-mix(in oklab, var(--ag-bg-dark) calc(var(--ag-glass-heavy) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.2);
-webkit-backdrop-filter: blur(var(--ag-blur-xl)) saturate(1.2);
border-right: 1px solid var(--ag-border-subtle);
height: 100%;
}
.glass-sidebar::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
90deg,
oklch(1 0 0 / 0.03) 0%,
transparent 100%
);
pointer-events: none;
}
/* --- Glass Badge --- */
.glass-badge {
display: inline-flex;
align-items: center;
background: color-mix(in oklab, var(--ag-bg-elevated) calc(var(--ag-glass-light) * 100%), transparent);
backdrop-filter: blur(var(--ag-blur-sm));
-webkit-backdrop-filter: blur(var(--ag-blur-sm));
border: 1px solid var(--ag-border-subtle);
border-radius: var(--ag-radius-full);
padding: var(--ag-space-1) var(--ag-space-3);
font-size: 0.75rem;
font-weight: 500;
color: var(--ag-text-secondary);
}
.glass-badge-blue {
background: color-mix(in oklab, var(--ag-ai-blue) 20%, transparent);
color: oklch(0.70 0.20 260);
border-color: oklch(0.55 0.25 260 / 0.30);
}
.glass-badge-green {
background: color-mix(in oklab, var(--ag-web3-green) 20%, transparent);
color: oklch(0.80 0.15 155);
border-color: oklch(0.72 0.19 155 / 0.30);
}
}
/* ============================================================================
8. KEYFRAMES (outside @theme for broader compat)
============================================================================ */
@keyframes glow-pulse {
0%, 100% {
box-shadow: 0 0 16px oklch(0.55 0.25 260 / 0.20);
}
50% {
box-shadow: 0 0 28px oklch(0.55 0.25 260 / 0.40);
}
}
@keyframes glass-reveal {
from {
opacity: 0;
backdrop-filter: blur(0px);
transform: translateY(8px) scale(0.98);
}
to {
opacity: 1;
backdrop-filter: blur(var(--ag-blur-lg));
transform: translateY(0) scale(1);
}
}
@keyframes gradient-flow {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
@keyframes focus-ring-expand {
from {
box-shadow: 0 0 0 0 oklch(0.55 0.25 260 / 0.40);
}
to {
box-shadow: 0 0 0 4px oklch(0.55 0.25 260 / 0.15);
}
}
/* ============================================================================
9. REDUCED MOTION
============================================================================ */
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
.glass-card:hover {
transform: none;
}
.glass-button:hover {
transform: none;
}
.glass-modal {
animation: none;
opacity: 1;
}
}
/* ============================================================================
10. WIDE GAMUT ENHANCEMENTS (P3 displays)
============================================================================ */
@media (color-gamut: p3) {
:root {
--ag-ai-blue: oklch(0.55 0.28 260);
--ag-web3-green: oklch(0.72 0.22 155);
--ag-shadow-glow-blue: 0 0 20px oklch(0.55 0.28 260 / 0.30);
--ag-shadow-glow-green: 0 0 20px oklch(0.72 0.22 155 / 0.30);
}
}
/* ============================================================================
11. PROSE OVERRIDES — @tailwindcss/typography integration
============================================================================ */
@utility prose {
--tw-prose-body: var(--ag-text-primary);
--tw-prose-headings: var(--ag-text-primary);
--tw-prose-lead: var(--ag-text-secondary);
--tw-prose-links: var(--ag-ai-blue);
--tw-prose-bold: var(--ag-text-primary);
--tw-prose-counters: var(--ag-text-secondary);
--tw-prose-bullets: var(--ag-text-muted);
--tw-prose-hr: var(--ag-border-default);
--tw-prose-quotes: var(--ag-text-secondary);
--tw-prose-quote-borders: var(--ag-border-strong);
--tw-prose-captions: var(--ag-text-muted);
--tw-prose-code: var(--ag-text-primary);
--tw-prose-pre-code: var(--ag-text-primary);
--tw-prose-pre-bg: var(--ag-bg-surface);
--tw-prose-th-borders: var(--ag-border-default);
--tw-prose-td-borders: var(--ag-border-subtle);
--tw-prose-invert-body: var(--ag-text-primary);
--tw-prose-invert-headings: var(--ag-text-primary);
--tw-prose-invert-lead: var(--ag-text-secondary);
--tw-prose-invert-links: var(--ag-ai-blue);
--tw-prose-invert-bold: var(--ag-text-primary);
--tw-prose-invert-counters: var(--ag-text-secondary);
--tw-prose-invert-bullets: var(--ag-text-secondary);
--tw-prose-invert-hr: var(--ag-border-default);
--tw-prose-invert-quotes: var(--ag-text-secondary);
--tw-prose-invert-quote-borders: var(--ag-border-strong);
--tw-prose-invert-captions: var(--ag-text-muted);
--tw-prose-invert-code: var(--ag-text-primary);
--tw-prose-invert-pre-code: var(--ag-text-primary);
--tw-prose-invert-pre-bg: var(--ag-bg-surface);
--tw-prose-invert-th-borders: var(--ag-border-default);
--tw-prose-invert-td-borders: var(--ag-border-subtle);
}
Arcan Glass — Animation Patterns
All animations are wrapped in @media (prefers-reduced-motion: no-preference) guards. When reduced motion is preferred, all durations collapse to near-zero and transforms are disabled.
---
Glow Pulse
Blue glow oscillation for active/loading states. Uses AI Blue at varying opacity.
@keyframes glow-pulse {
0%, 100% {
box-shadow: 0 0 16px oklch(0.55 0.25 260 / 0.20);
}
50% {
box-shadow: 0 0 28px oklch(0.55 0.25 260 / 0.40);
}
}Tailwind: animate-glow-pulse
Usage:
<!-- Loading indicator -->
<div class="glass-card animate-glow-pulse">Processing...</div>
<!-- Active state -->
<button class="glass-button glass-button-primary animate-glow-pulse">Live</button>Green variant (custom): Replace hue 260 with 155 for web3-green glow.
---
Hover Lift
Subtle upward translation with shadow elevation and optional highlight brightening.
.hover-lift {
transition: transform var(--ag-transition-normal),
box-shadow var(--ag-transition-normal);
}
.hover-lift:hover {
transform: translateY(-2px);
box-shadow: var(--ag-shadow-lg);
}Tailwind composition:
<div class="transition-[box-shadow,transform] duration-250 ease-out hover:-translate-y-0.5 hover:shadow-lg">
Hover me
</div>Already built into .glass-card and .glass-button.
---
Glass Reveal
Entry animation for glass surfaces — opacity, blur, and position animate together.
@keyframes glass-reveal {
from {
opacity: 0;
backdrop-filter: blur(0px);
transform: translateY(8px) scale(0.98);
}
to {
opacity: 1;
backdrop-filter: blur(var(--ag-blur-lg));
transform: translateY(0) scale(1);
}
}Tailwind: animate-glass-reveal
Usage:
<!-- Modal entrance -->
<div class="glass-modal animate-glass-reveal">...</div>
<!-- Card stagger (combine with delay utilities) -->
<div class="glass-card animate-glass-reveal" style="animation-delay: 0ms">Card 1</div>
<div class="glass-card animate-glass-reveal" style="animation-delay: 100ms">Card 2</div>
<div class="glass-card animate-glass-reveal" style="animation-delay: 200ms">Card 3</div>---
Morph
Border-radius transition with smooth cubic-bezier for shape-shifting effects.
.morph {
transition: border-radius var(--ag-transition-morph);
}
.morph:hover {
border-radius: var(--ag-radius-xl);
}Tailwind composition:
<div class="rounded-lg transition-[border-radius] duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] hover:rounded-xl">
Morphing shape
</div>---
Focus Ring
Expanding ring with blue glow fade-in for accessible focus indication.
@keyframes focus-ring-expand {
from {
box-shadow: 0 0 0 0 oklch(0.55 0.25 260 / 0.40);
}
to {
box-shadow: 0 0 0 4px oklch(0.55 0.25 260 / 0.15);
}
}
.focus-ring:focus-visible {
animation: focus-ring-expand 200ms ease forwards;
}Usage:
<button class="glass-button focus-ring">Accessible button</button>The default :focus-visible style in globals.css provides a solid 2px outline. Use focus-ring class for the animated variant.
---
Gradient Flow
Slowly rotating brand gradient for hero sections and feature backgrounds.
@keyframes gradient-flow {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}Tailwind: animate-gradient-flow
Usage:
<section class="bg-gradient-to-r from-ai-blue via-web3-green to-ai-blue bg-[length:200%_200%] animate-gradient-flow">
<h1 class="text-4xl font-heading text-white">Hero Section</h1>
</section>---
Scroll Reveal
Uses animation-timeline: view() for scroll-triggered glass reveal. Falls back to Intersection Observer for unsupported browsers.
CSS (progressive enhancement):
@supports (animation-timeline: view()) {
.scroll-reveal {
animation: glass-reveal linear both;
animation-timeline: view();
animation-range: entry 0% entry 100%;
}
}JavaScript fallback:
if (!CSS.supports("animation-timeline", "view()")) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("animate-glass-reveal");
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
document.querySelectorAll(".scroll-reveal").forEach((el) => observer.observe(el));
}---
Transition Tokens
| Token | Duration | Easing | Use Case |
|---|---|---|---|
--ag-transition-fast | 150ms | ease | Hover, focus, micro |
--ag-transition-normal | 250ms | ease | Card, menu, panel |
--ag-transition-slow | 350ms | ease | Sidebar, page |
--ag-transition-morph | 500ms | cubic-bezier(0.4, 0, 0.2, 1) | Shape, radius |
--ag-transition-glow | 1500ms | ease-in-out | Glow cycles |
---
Reduced Motion
All animations respect prefers-reduced-motion:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}This is already included in globals.css. No additional action needed — just use the animation classes normally.
Arcan Glass — Color System
Color Space
Arcan Glass uses OKLCh as the primary color space for perceptually uniform lightness across the surface depth scale. Hex fallbacks are provided via @supports not (color: oklch(0 0 0)).
All surface colors share hue 275° (blue-purple), connecting them subtly to the AI Blue brand without competing with it.
---
Brand Colors
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-ai-blue | oklch(0.55 0.25 260) | #0066FF | Primary, interactive, focus, links |
--ag-web3-green | oklch(0.72 0.19 155) | #00CC66 | Accent, success, web3 branding |
On P3 displays, chroma is boosted: AI Blue → 0.28, Web3 Green → 0.22.
---
Surface Scale
Surfaces form a lightness ramp at hue 275° (blue-purple). Each step is ~0.03-0.05 L apart in OKLCh for perceptual consistency.
Dark Mode (Default)
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-bg-deep | oklch(0.12 0.02 275) | #12121A | Body background |
--ag-bg-dark | oklch(0.15 0.04 245) | #001F3F | Secondary bg, sidebar |
--ag-bg-surface | oklch(0.17 0.03 275) | #1A1A2E | Cards, panels |
--ag-bg-elevated | oklch(0.22 0.03 275) | #232340 | Popovers, dialogs |
--ag-bg-hover | oklch(0.26 0.03 275) | #2A2A4A | Hover states |
Light Mode — Day Glass
Light mode is not a white inversion of dark mode. It is a day glass scale: same 275° hue family, higher lightness, low chroma, and enough L distance for dark text to remain crisp on translucent panels.
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-bg-deep | oklch(0.965 0.014 275) | — | Body background |
--ag-bg-dark | oklch(0.930 0.020 275) | — | Secondary bg, rails |
--ag-bg-surface | oklch(0.985 0.008 275) | — | Cards, panels |
--ag-bg-elevated | oklch(0.955 0.016 275) | — | Popovers, dialogs |
--ag-bg-hover | oklch(0.910 0.024 275) | — | Hover states |
---
Text Hierarchy
Dark Mode
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-text-primary | oklch(0.98 0 0) | #FFFFFF | Headings, body |
--ag-text-secondary | oklch(0.70 0.02 275) | #A0A0B8 | Labels, descriptions |
--ag-text-muted | oklch(0.50 0.02 275) | #6B6B80 | Placeholders, captions |
--ag-text-disabled | oklch(0.38 0.02 275) | #4A4A5C | Disabled text |
Light Mode
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-text-primary | oklch(0.190 0.030 275) | — | Headings, body |
--ag-text-secondary | oklch(0.390 0.026 275) | — | Labels |
--ag-text-muted | oklch(0.530 0.022 275) | — | Placeholders |
--ag-text-disabled | oklch(0.680 0.016 275) | — | Disabled |
---
Semantic Colors
| Token | OKLCh | Hex | Usage |
|---|---|---|---|
--ag-success | oklch(0.72 0.19 155) | #00CC66 | Success, confirmed |
--ag-warning | oklch(0.87 0.18 85) | #FFD60A | Caution, pending |
--ag-error | oklch(0.58 0.24 27) | #FF3B30 | Error, destructive |
--ag-info | oklch(0.55 0.25 260) | #0066FF | Informational |
---
Border Scale
| Token | Value (Dark) | Usage |
|---|---|---|
--ag-border-subtle | oklch(0.30 0.02 275 / 0.40) | Glass edges, dividers |
--ag-border-default | oklch(0.40 0.02 275 / 0.50) | Input borders, cards |
--ag-border-strong | oklch(0.50 0.02 275 / 0.60) | Active borders |
--ag-border-focus | oklch(0.55 0.25 260) | Focus rings (= AI Blue) |
Light mode borders use darker low-chroma violet with lower alpha: subtle = oklch(0.650 0.030 275 / 0.22), default = oklch(0.560 0.035 275 / 0.32), strong = oklch(0.450 0.045 275 / 0.42).
---
Glass Opacity Scale
| Token | Dark | Light | Usage |
|---|---|---|---|
--ag-glass-light | 40% | 66% | Subtle backgrounds, inputs |
--ag-glass-medium | 60% | 78% | Cards, panels (default) |
--ag-glass-heavy | 80% | 88% | Nav bars, modals, sidebars |
These values control the color-mix() ratio in glass surfaces — higher opacity = less transparency, more grounding.
---
Chart Colors
| Token | Value | Usage |
|---|---|---|
--chart-1 | AI Blue | Primary series |
--chart-2 | Web3 Green | Secondary series |
--chart-3 | oklch(0.65 0.22 330) | Tertiary (pink-purple) |
--chart-4 | Warning yellow | Fourth series |
--chart-5 | oklch(0.60 0.20 30) | Fifth series (warm red) |
---
Usage in Tailwind
All color tokens are mapped to Tailwind via @theme inline:
<div class="bg-ai-blue text-text-primary">AI Blue</div>
<div class="bg-bg-surface border-border">Surface card</div>
<div class="text-web3-green">Accent text</div>shadcn/ui semantic classes work as expected:
<div class="bg-primary text-primary-foreground">Button</div>
<div class="bg-card text-card-foreground">Card</div>Arcan Glass — Design Tokens
Overview
All tokens use the --ag- prefix to avoid collision with shadcn/ui (--) and Tailwind (--tw-). shadcn/ui compatibility is maintained via aliased --background, --foreground, etc. variables that reference --ag-* tokens.
---
Shadows
Six depth levels plus brand glow effects.
| Token | Value (Dark) | Usage |
|---|---|---|
--ag-shadow-xs | 0 1px 2px oklch(0 0 0 / 0.30) | Subtle lift, badges |
--ag-shadow-sm | 0 2px 4px oklch(0 0 0 / 0.35) | Buttons, inputs |
--ag-shadow-md | 0 4px 8px oklch(0 0 0 / 0.40) | Cards, panels |
--ag-shadow-lg | 0 8px 16px oklch(0 0 0 / 0.45) | Hover elevation |
--ag-shadow-xl | 0 16px 32px oklch(0 0 0 / 0.50) | Dialogs, dropdowns |
--ag-shadow-2xl | 0 24px 48px oklch(0 0 0 / 0.55) | Modals, max depth |
Glow Shadows
| Token | Value | Usage |
|---|---|---|
--ag-shadow-glow-blue | 0 0 20px oklch(0.55 0.25 260 / 0.25) | Primary glow, focus |
--ag-shadow-glow-green | 0 0 20px oklch(0.72 0.19 155 / 0.25) | Accent glow, success |
Day Glass shadows use lower opacity (0.06-0.18), darker low-chroma violet, and a subtle inset highlight so light surfaces stay grounded without looking muddy.
---
Blur Levels
Used for backdrop-filter in glass effects. Limit to 3-5 elements per viewport for performance.
| Token | Value | Usage |
|---|---|---|
--ag-blur-sm | 4px | Subtle frost, inputs, overlays |
--ag-blur-md | 8px | Buttons, badges |
--ag-blur-lg | 16px | Cards, panels (default glass) |
--ag-blur-xl | 24px | Nav, modal, sidebar (heavy glass) |
---
Typography
Font Families
| Token | Value | Usage |
|---|---|---|
--ag-font-heading | "Poppins", system-ui, -apple-system, sans-serif | Headings h1–h6 |
--ag-font-body | -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif | Body text, UI |
--ag-font-mono | "SF Mono", "Fira Code", "JetBrains Mono", "Menlo", monospace | Code, data |
Font Sizes
| Name | Value | px |
|---|---|---|
| xs | 0.75rem | 12 |
| sm | 0.875rem | 14 |
| base | 1rem | 16 |
| lg | 1.125rem | 18 |
| xl | 1.25rem | 20 |
| 2xl | 1.5rem | 24 |
| 3xl | 2.25rem | 36 |
| 4xl | 3rem | 48 |
Font Weights
| Name | Value | Usage |
|---|---|---|
| normal | 400 | Body text |
| medium | 500 | UI labels, buttons |
| semibold | 600 | Headings, emphasis |
| bold | 700 | Strong emphasis |
Line Heights
| Name | Value | Usage |
|---|---|---|
| tight | 1.2 | Headings |
| snug | 1.3 | Subheadings |
| normal | 1.5 | Body (default) |
| relaxed | 1.6 | Long-form prose |
---
Spacing
4px base unit. Maps directly to Tailwind's default spacing scale.
| Token | Value | px |
|---|---|---|
--ag-space-1 | 0.25rem | 4 |
--ag-space-2 | 0.5rem | 8 |
--ag-space-3 | 0.75rem | 12 |
--ag-space-4 | 1rem | 16 |
--ag-space-5 | 1.25rem | 20 |
--ag-space-6 | 1.5rem | 24 |
--ag-space-8 | 2rem | 32 |
--ag-space-10 | 2.5rem | 40 |
--ag-space-12 | 3rem | 48 |
--ag-space-16 | 4rem | 64 |
---
Border Radius
| Token | Value | Usage |
|---|---|---|
--ag-radius-sm | 4px | Small buttons, badges |
--ag-radius-md | 8px | Inputs, buttons |
--ag-radius-lg | 12px | Cards, panels |
--ag-radius-xl | 16px | Modals, large surfaces |
--ag-radius-full | 9999px | Pills, avatars |
--ag-radius-glass | 12px | Default for all glass components |
---
Transitions
| Token | Value | Usage |
|---|---|---|
--ag-transition-fast | 150ms ease | Hovers, focus, micro-interactions |
--ag-transition-normal | 250ms ease | Cards, panels, menus |
--ag-transition-slow | 350ms ease | Page-level, sidebars |
--ag-transition-morph | 500ms cubic-bezier(0.4, 0, 0.2, 1) | Shape morphing, radius transitions |
--ag-transition-glow | 1500ms ease-in-out | Glow pulse cycles |
---
Tailwind Mapping
All tokens are available as Tailwind utilities via @theme inline:
<!-- Shadows -->
<div class="shadow-md shadow-glow-blue">Glowing card</div>
<!-- Radius -->
<div class="rounded-lg">12px radius</div>
<!-- Fonts -->
<h1 class="font-heading">Poppins heading</h1>
<code class="font-mono">Monospace</code>Arcan Glass — Glass Components
The 4-Layer Glass Effect System
Every glass component in Arcan Glass is built from four composable layers:
Layer 1: Backdrop Blur
The foundation — frosted glass effect via backdrop-filter.
backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
-webkit-backdrop-filter: blur(var(--ag-blur-lg)) saturate(1.2);
background: color-mix(in oklab, var(--ag-bg-surface) 60%, transparent);The color-mix(in oklab) tint provides natural blending regardless of what's behind the element. saturate(1.2) enriches the backdrop content visible through the blur.
Layer 2: Highlight
A ::before pseudo-element creating a subtle top-edge light reflection.
&::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background: linear-gradient(
180deg,
oklch(1 0 0 / 0.05) 0%,
oklch(1 0 0 / 0.02) 20%,
transparent 50%
);
pointer-events: none;
}In light mode, increase to 0.08–0.12 opacity for visible sheen. In dark mode, keep subtle at 0.03–0.06.
Layer 3: Shadow
Multi-level box-shadow providing depth. Glass components use --ag-shadow-md by default, elevating to --ag-shadow-lg on hover. Primary/accent variants add glow shadows.
Layer 4: Adaptive Tint
Using color-mix() to blend the surface color with brand colors for contextual tinting:
/* Blue-tinted glass */
background: color-mix(in oklab, var(--ag-ai-blue) 15%, var(--ag-bg-surface) 50%, transparent);
/* Green-tinted glass */
background: color-mix(in oklab, var(--ag-web3-green) 15%, var(--ag-bg-surface) 50%, transparent);---
Components
Glass Card
The primary container. Medium glass with highlight, shadow, and hover lift.
CSS class: .glass-card
Raw CSS:
.glass-card {
position: relative;
background: color-mix(in oklab, var(--ag-bg-surface) 60%, transparent);
backdrop-filter: blur(16px) saturate(1.2);
border: 1px solid var(--ag-border-subtle);
border-radius: 12px;
box-shadow: var(--ag-shadow-md);
padding: 1.5rem;
transition: transform 250ms ease, box-shadow 250ms ease;
}
.glass-card::before { /* highlight layer */ }
.glass-card:hover {
transform: translateY(-2px);
box-shadow: var(--ag-shadow-lg);
}Tailwind composition:
<div class="glass glass-highlight p-6 shadow-md transition-[box-shadow,transform] hover:-translate-y-0.5 hover:shadow-lg">
<h3 class="font-heading text-lg text-text-primary">Card Title</h3>
<p class="text-text-secondary mt-2">Card content</p>
</div>Or use the class directly:
<div class="glass-card">
<h3>Card Title</h3>
<p>Card content</p>
</div>---
Glass Nav
Fixed navigation bar with heavy glass and bottom border.
CSS class: .glass-nav
Tailwind composition:
<nav class="glass-heavy sticky top-0 z-50 border-b border-border px-6 py-3">
<div class="flex items-center justify-between">
<span class="font-heading text-lg text-ai-blue">BroomVA</span>
<div class="flex gap-4">
<a class="text-text-secondary hover:text-text-primary transition-colors" href="#">Home</a>
<a class="text-text-secondary hover:text-text-primary transition-colors" href="#">About</a>
</div>
</div>
</nav>Or use the class:
<nav class="glass-nav sticky top-0 z-50 px-6 py-3">
<!-- nav content -->
</nav>---
Glass Button
Three variants: default (ghost glass), primary (AI Blue fill), accent (Web3 Green fill).
CSS classes: .glass-button, .glass-button .glass-button-primary, .glass-button .glass-button-accent
Usage:
<!-- Default (ghost glass) -->
<button class="glass-button">Settings</button>
<!-- Primary (AI Blue) -->
<button class="glass-button glass-button-primary">Get Started</button>
<!-- Accent (Web3 Green) -->
<button class="glass-button glass-button-accent">Connected</button>Tailwind composition (primary example):
<button class="inline-flex items-center gap-2 bg-ai-blue/85 backdrop-blur-sm border border-ai-blue/50
rounded-md px-4 py-2 text-sm font-medium text-white
min-h-10 transition-[background-color,box-shadow,transform]
hover:bg-ai-blue/95 hover:shadow-glow-blue hover:-translate-y-px active:scale-[0.96]">
Get Started
</button>---
Glass Input
Subtle glass with focus ring expansion.
CSS class: .glass-input
Usage:
<input type="text" class="glass-input w-full" placeholder="Search...">Tailwind composition:
<input type="text"
class="glass-subtle px-3 py-2 rounded-md text-sm text-text-primary placeholder:text-text-muted
transition-[border-color,box-shadow]
focus:outline-none focus:border-ai-blue focus:ring-2 focus:ring-ai-blue/15"
placeholder="Search...">---
Glass Modal
Heavy glass with reveal animation and overlay backdrop.
CSS classes: .glass-modal, .glass-modal-overlay
Usage:
<!-- Overlay -->
<div class="glass-modal-overlay" aria-hidden="true"></div>
<!-- Modal -->
<div class="glass-modal max-w-lg mx-auto">
<h2 class="font-heading text-xl text-text-primary">Modal Title</h2>
<p class="text-text-secondary mt-3">Modal content here.</p>
<div class="flex gap-3 mt-6 justify-end">
<button class="glass-button">Cancel</button>
<button class="glass-button glass-button-primary">Confirm</button>
</div>
</div>---
Glass Sidebar
Full-height sidebar with heavy glass and right border.
CSS class: .glass-sidebar
Usage:
<aside class="glass-sidebar w-64 p-4">
<nav class="flex flex-col gap-1">
<a class="rounded-md px-3 py-2 text-sm text-text-secondary hover:bg-bg-hover hover:text-text-primary transition-colors" href="#">
Dashboard
</a>
<a class="rounded-md px-3 py-2 text-sm bg-bg-hover text-text-primary" href="#">
Projects
</a>
</nav>
</aside>---
Glass Badge
Pill-shaped badge with subtle glass. Optional brand color variants.
CSS classes: .glass-badge, .glass-badge .glass-badge-blue, .glass-badge .glass-badge-green
Usage:
<span class="glass-badge">Default</span>
<span class="glass-badge glass-badge-blue">AI</span>
<span class="glass-badge glass-badge-green">Web3</span>---
Performance Guidelines
1. Limit `backdrop-filter` to 3-5 elements per viewport — each blurred element forces a compositing layer 2. Use `will-change: backdrop-filter` sparingly — only on elements that will animate 3. Prefer `.glass-subtle` for repeated items (list items, table rows) — lower blur = less GPU cost 4. Use `.glass-heavy` only for landmark surfaces — nav, sidebar, modal 5. Test on low-end devices — backdrop-filter performance varies significantly across GPUs
Arcan Glass — Tailwind v4 Integration
@theme inline Block
All --ag-* tokens are mapped to Tailwind's utility namespace via @theme inline in globals.css. This means you can use them directly as Tailwind classes:
<div class="bg-ai-blue text-text-primary rounded-lg shadow-md">
Direct token usage
</div>Color Mapping
| Tailwind Class | Token |
|---|---|
bg-ai-blue / text-ai-blue | --ag-ai-blue |
bg-web3-green / text-web3-green | --ag-web3-green |
bg-bg-deep | --ag-bg-deep |
bg-bg-dark | --ag-bg-dark |
bg-bg-surface | --ag-bg-surface |
bg-bg-elevated | --ag-bg-elevated |
bg-bg-hover | --ag-bg-hover |
text-text-primary | --ag-text-primary |
text-text-secondary | --ag-text-secondary |
text-text-muted | --ag-text-muted |
text-text-disabled | --ag-text-disabled |
shadcn/ui Semantic Colors
| Tailwind Class | Maps To |
|---|---|
bg-background | --ag-bg-deep |
bg-foreground | --ag-text-primary |
bg-card | --ag-bg-surface |
bg-popover | --ag-bg-elevated |
bg-primary | --ag-ai-blue |
bg-secondary | --ag-bg-hover |
bg-muted | --ag-bg-surface |
bg-accent | --ag-web3-green |
bg-destructive | --ag-error |
bg-sidebar | --ag-bg-dark |
border-border | --ag-border-default |
ring-ring | --ag-ai-blue |
---
@utility Blocks
Custom compound utilities defined in globals.css:
| Utility | Effect |
|---|---|
glass | Medium glass: 60% surface tint + 16px blur + saturate(1.2) + subtle border + 12px radius |
glass-subtle | Light glass: 40% tint + 8px blur + saturate(1.1) |
glass-heavy | Heavy glass: 80% tint + 24px blur + saturate(1.3) |
glow-blue | AI Blue glow shadow |
glow-green | Web3 Green glow shadow |
glass-highlight | Adds ::before highlight pseudo-element |
Usage:
<!-- Basic glass surface -->
<div class="glass p-6">Content</div>
<!-- Glass with highlight and glow -->
<div class="glass glass-highlight glow-blue p-6">Featured</div>
<!-- Heavy glass nav -->
<nav class="glass-heavy px-6 py-3 sticky top-0 z-50">Nav</nav>---
Dark/Light Mode Strategy
Arcan Glass uses the .dark / .light class strategy (compatible with next-themes):
// layout.tsx
import { ThemeProvider } from "next-themes";
export default function Layout({ children }) {
return (
<ThemeProvider attribute="class" defaultTheme="dark">
{children}
</ThemeProvider>
);
}The @custom-variant dark directive in globals.css wires dark: utilities to .dark class:
@custom-variant dark (&:is(.dark *));Usage:
<div class="bg-bg-surface dark:bg-bg-surface">
<!-- Tokens auto-adapt via CSS custom properties, so dark: prefix is rarely needed -->
</div>Since all colors are defined as CSS custom properties that change with .light class, most elements don't need explicit dark: variants — the tokens handle it automatically.
---
shadcn/ui Component Mapping
Arcan Glass tokens are designed to drop into shadcn/ui without modifications. The globals.css defines all required shadcn/ui variables:
| shadcn Variable | Arcan Glass Source |
|---|---|
--background | --ag-bg-deep |
--foreground | --ag-text-primary |
--card | --ag-bg-surface |
--card-foreground | --ag-text-primary |
--popover | --ag-bg-elevated |
--popover-foreground | --ag-text-primary |
--primary | --ag-ai-blue |
--primary-foreground | white |
--secondary | --ag-bg-hover |
--secondary-foreground | --ag-text-primary |
--muted | --ag-bg-surface |
--muted-foreground | --ag-text-muted |
--accent | --ag-web3-green |
--accent-foreground | --ag-bg-deep |
--destructive | --ag-error |
--border | --ag-border-default |
--input | --ag-border-default |
--ring | --ag-ai-blue |
--radius | --ag-radius-glass (12px) |
---
cva Variant Extensions
To add glass variants to shadcn components using cva:
Button with Glass Variant
import { cva } from "class-variance-authority";
const buttonVariants = cva(
"inline-flex min-h-10 items-center justify-center gap-2 rounded-md text-sm font-medium transition-[background-color,border-color,color,box-shadow,transform] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring active:scale-[0.96] disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
// Arcan Glass variants
glass: "glass glass-highlight hover:-translate-y-px hover:shadow-lg",
"glass-primary": "glass-button glass-button-primary",
"glass-accent": "glass-button glass-button-accent",
},
size: {
default: "h-9 px-4 py-2",
sm: "h-8 px-3 text-xs",
lg: "h-10 px-8",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);Card with Glass Variant
const cardVariants = cva("rounded-lg border text-card-foreground", {
variants: {
variant: {
default: "bg-card shadow-sm",
glass: "glass-card",
},
},
defaultVariants: {
variant: "default",
},
});---
Import Order
In your project's main CSS file:
/* globals.css — just import the Arcan Glass file */
@import "tailwindcss";
@import "tw-animate-css";
/* Copy arcan-glass globals.css content here, or import from package */If using Arcan Glass as the complete globals.css (recommended), simply copy it as your project's globals.css — it already includes the Tailwind import and all necessary configuration.
MIT License
Copyright (c) 2026 Carlos Escobar (BroomVA)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
arcan-glass
BroomVA's trademark web styling system -- the Arcan Glass design language for Next.js + Tailwind v4 + shadcn/ui projects. Glass/frosted UI effects, dark-first themes, and AI Blue brand tokens delivered as a drop-in globals.css and composable component patterns.
This is a skills.sh agent skill -- it can be installed by any AI agent that supports the skills protocol.
Features
- Drop-in globals.css with all tokens, glass utilities, components, and animations
- Dark-first design with automatic light mode support via CSS custom properties
- Glass effect system built from 4 composable layers (backdrop blur, highlight, shadow, adaptive tint)
- OKLCh color system with P3 gamut enhancement on capable displays
- Full shadcn/ui compatibility -- all shadcn CSS variables resolve to Arcan Glass tokens
- Tailwind v4 integration via
@theme inlinewith brand color utilities - Reduced motion respected globally across all animations and transforms
Quick Start
1. Copy arcan-glass/assets/globals.css into your Next.js project as app/globals.css 2. Import in your layout: import "./globals.css" 3. Use glass classes:
<div class="glass-card">Standard glass card</div>
<button class="glass-button glass-button-primary">Primary action</button>
<nav class="glass-heavy sticky top-0">Navigation</nav>All shadcn/ui components automatically pick up the Arcan Glass theme.
Brand Colors
| Token | Color | Usage |
|---|---|---|
--ag-ai-blue | #0066FF | Primary, interactive, links |
--ag-web3-green | #00CC66 | Accent, success, web3 |
Glass Intensity Presets
| Preset | Opacity / Blur | Use for |
|---|---|---|
glass-subtle | 40% / 8px | Repeated items (list items, table rows) |
glass | 60% / 16px | Key surfaces (cards, buttons) |
glass-heavy | 80% / 24px | Landmark surfaces (nav, sidebar, modal) |
Component Index
| Component | Class | Glass Level |
|---|---|---|
| Card | .glass-card | Medium |
| Nav | .glass-nav | Heavy |
| Button | .glass-button | Medium |
| Input | .glass-input | Subtle |
| Modal | .glass-modal | Heavy |
| Sidebar | .glass-sidebar | Heavy |
| Badge | .glass-badge | Subtle |
Animation Index
| Animation | Tailwind Class | Duration |
|---|---|---|
| Glow pulse | animate-glow-pulse | 2s loop |
| Glass reveal | animate-glass-reveal | 0.5s once |
| Gradient flow | animate-gradient-flow | 8s loop |
Design Principles
1. Dark-first -- dark mode is the default; light mode is supported but secondary 2. Glass is earned -- limit backdrop-filter to 3-5 elements per viewport 3. Brand through surface -- surface hue 275 connects all surfaces to AI Blue 4. OKLCh primary -- perceptually uniform lightness for clean depth scales 5. Additive on shadcn -- glass layers on top of shadcn/ui, never replacing base accessibility 6. Motion with purpose -- every animation communicates state; reduced motion is respected 7. Token-prefixed -- all custom properties use --ag- to avoid collisions
References
arcan-glass/references/color-system.md-- Full OKLCh palette, hex fallbacks, surface scalearcan-glass/references/design-tokens.md-- Shadows, blur, radius, spacing, typographyarcan-glass/references/glass-components.md-- 4-layer glass system, component CSS patternsarcan-glass/references/animation-patterns.md-- Glow, hover, morph, scroll reveal patternsarcan-glass/references/tailwind-integration.md-- @theme wiring, shadcn mapping, cva extensions
License
MIT
Related skills
FAQ
What stack does Arcan Glass target?
Next.js with Tailwind v4 and shadcn/ui; shadcn components automatically pick up the theme.
How do you install it?
Copy assets/globals.css into your project as app/globals.css, import it in the layout, then use glass classes like glass-card and glass-button.