← Hub Directory Live Demo
Premium UI Design System

Premium Web Design System

Clean typography pairings, OkLCH color coordinates, frosted glassmorphism overlays, and macOS-style tactile components.

Download markdown file
Phase 01. Inject Skill

Inject Agent Skill

Inject this premium web design system skill into your workspace agents using the terminal command below.

npx skills add Saunakghosh10/premium-web-design
02. Theme Setup

Global CSS configuration

This stylesheet sets up the Inter/EB Garamond font pairs, defines the OkLCH color values, and registers keyframe micro-animations for interactive transitions.

/* Font Pairings */
@theme {
    --font-sans: var(--font-inter);
    --font-serif: var(--font-eb-garamond);
}

/* Base Color System (OkLCH) */
:root {
  --background: oklch(0.985 0 0); /* Soft off-white */
  --foreground: oklch(0.145 0 0); /* Soft dark gray */
  --primary: oklch(0.205 0 0);
  --border: oklch(0.922 0 0);
  --accent: oklch(0.60 0.16 250); /* Azure accent approx */
}

.dark {
  --background: oklch(0.145 0 0); /* Deep charcoal black */
  --foreground: oklch(0.985 0 0); /* Crisp white */
  --primary: oklch(0.922 0 0);
  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
}

@layer base {
    * {
        @apply border-border outline-ring/50;
    }
}

/* Micro-Animations & Transitions */

/* 1. Staggered Sidebar Fade-In */
@keyframes sidebarFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.sidebar-fade-in {
    animation: sidebarFadeIn 0.3s ease-out forwards;
    animation-delay: 0.1s;
    opacity: 0;
}
.sidebar-fade-in-2 {
    animation: sidebarFadeIn 0.3s ease-out forwards;
    animation-delay: 0.2s;
    opacity: 0;
}

/* 2. Shimmer / Skeleton loading animation */
@keyframes shimmer {
    from { background-position: 0 0; }
    to { background-position: -200% 0; }
}

.animate-shimmer {
    animation: shimmer 8s linear infinite;
}

/* 3. Flash Edit State Animation */
@keyframes docxEditFlash {
    0%, 20% {
        background-color: rgba(59, 130, 246, 0.45);
        box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.45);
    }
    100% {
        background-color: rgba(59, 130, 246, 0);
        box-shadow: 0 0 0 2px rgba(59, 130, 246, 0);
    }
}

.docx-edit-flash {
    animation: docxEditFlash 2s ease-out;
    border-radius: 2px;
}
03. Component Templates

Tactile UI Component blueprints

Copyable React TSX blueprints crafted in compliance with premium layout depth and interaction rules.

CiteButton.tsx

Tactile quote citation copy-to-clipboard button with visual checkmark success states.

import React, { useState } from "react";
import { Check, Quote } from "lucide-react";

interface CiteButtonProps {
  quoteText: string;
  citationText: string;
}

export function CiteButton({ quoteText, citationText }: CiteButtonProps) {
    const [isCopied, setIsCopied] = useState(false);

    const handleClick = async (e: React.MouseEvent) => {
        e.stopPropagation();
        e.preventDefault();
        try {
            const compiledText = `"${quoteText.replace(/"/g, "'")}" ${citationText}`.trim();
            await navigator.clipboard.writeText(compiledText);
            setIsCopied(true);
            setTimeout(() => setIsCopied(false), 2000);
        } catch (err) {
            console.error("Failed to copy citation:", err);
        }
    };

    return (
        <button
            onClick={handleClick}
            className="transition-colors flex items-center gap-1.5 px-2.5 py-1.5 rounded-md text-xs font-medium bg-secondary text-secondary-foreground hover:bg-secondary/80 border border-border cursor-pointer"
        >
            {isCopied ? (
                <>
                    <Check className="h-3 w-3 text-green-600 animate-in fade-in zoom-in-75 duration-150" />
                    <span className="text-green-600">Copied</span>
                </>
            ) : (
                <>
                    <Quote className="h-3 w-3" />
                    <span>Cite</span>
                </>
            )}
        </button>
    );
}

DropdownToggle.tsx

Smooth macOS-style dropdown toggle with rotating chevrons.

import React, { useState } from "react";
import { ChevronDown } from "lucide-react";

interface DropdownToggleProps {
  label: string;
}

export function DropdownToggle({ label }: DropdownToggleProps) {
    const [isOpen, setIsOpen] = useState(false);

    return (
        <button
            type="button"
            onClick={() => setIsOpen(!isOpen)}
            className={`flex items-center gap-1.5 rounded-lg px-2 h-8 text-sm transition-colors cursor-pointer text-gray-400 hover:bg-gray-100 hover:text-gray-700 ${
                isOpen ? "bg-gray-100 text-gray-700" : ""
            }`}
        >
            <span>{label}</span>
            <ChevronDown
                className={`h-3 w-3 shrink-0 transition-transform duration-200 ${
                    isOpen ? "rotate-180" : ""
                }`}
            />
        </button>
    );
}

GlassCapsule.tsx

Premium glass pill utilizing backdrop blur, multi-layered inner shadows, and specular reflection highlights.

import React from "react";

interface GlassCapsuleProps {
    href: string;
    children: React.ReactNode;
}

export function GlassCapsule({ href, children }: GlassCapsuleProps) {
    return (
        <div className="relative">
            <a
                href={href}
                className="relative flex items-center rounded-full border pl-3 pr-4 h-13 transition-[background,border-color,box-shadow,backdrop-filter] duration-300 border-gray-300/40 backdrop-blur-lg backdrop-saturate-150 no-underline"
                style={{
                    background: "linear-gradient(135deg, rgba(228, 230, 234, 0.48) 0%, rgba(214, 216, 222, 0.36) 100%)",
                    boxShadow: "rgba(255, 255, 255, 0.5) 0px 1px 0px 0px inset, rgba(0, 0, 0, 0.03) 0px -1px 0px 0px inset, rgba(17, 24, 39, 0.04) 0px 1px 2px, rgba(17, 24, 39, 0.08) 0px 12px 32px -8px"
                }}
            >
                {/* Highlight Specular Reflection Overlay */}
                <div
                    aria-hidden="true"
                    className="pointer-events-none absolute inset-x-4 top-0 h-1/2 rounded-t-full"
                    style={{
                        background: "linear-gradient(rgba(211, 211, 211, 0.6) 0%, rgba(255, 255, 255, 0) 100%)",
                        mixBlendMode: "overlay"
                    }}
                />
                
                {children}
            </a>
        </div>
    );
}

GlassActionBar.tsx

Glassmorphic rounded Action Bar/Toolbar container commonly used for page header actions.

import React from "react";
import { PlusIcon, TrashIcon } from "lucide-react";

export function GlassActionBar() {
    return (
        <div className="flex shrink-0 items-center gap-1 rounded-full border border-white/70 bg-white px-1 py-1 shadow-[0_8px_24px_rgba(15,23,42,0.06)] backdrop-blur-2xl">
            {/* Icon-only action */}
            <button aria-label="Add item" className="flex h-7 w-7 items-center justify-center rounded-full text-gray-500 hover:bg-gray-100 hover:text-gray-900 transition-colors cursor-pointer border-0">
                <PlusIcon className="h-3.5 w-3.5" aria-hidden="true" />
            </button>
            
            {/* Text + icon action */}
            <button className="flex h-7 items-center gap-1.5 px-3 rounded-full text-sm text-gray-500 hover:bg-gray-100 hover:text-gray-900 transition-colors cursor-pointer border-0">
                New
            </button>
            
            {/* Danger action */}
            <button aria-label="Delete item" className="flex h-7 w-7 items-center justify-center rounded-full text-gray-500 hover:bg-gray-100 hover:text-red-600 transition-colors cursor-pointer border-0">
                <TrashIcon className="h-3.5 w-3.5" aria-hidden="true" />
            </button>
        </div>
    );
}

ConfirmPopup.tsx

Progressive state confirm dialog (fixed at the bottom) with active loader labels.

import React from "react";

interface ConfirmPopupProps {
  status: "idle" | "loading" | "complete";
  onConfirm: () => void;
  onCancel: () => void;
}

export function ConfirmPopup({ status, onConfirm, onCancel }: ConfirmPopupProps) {
    function progressiveLabel(label: string) {
        return label.toLowerCase().endsWith("e")
            ? `${label.slice(0,-1)}ing…`
            : `${label}ing…`;
    }

    function completedLabel(label: string) {
        return label.toLowerCase().endsWith("e") ? `${label}d` : `${label}ed`;
    }

    return (
        <div className="pointer-events-none fixed inset-x-0 bottom-5 z-[230] flex justify-center px-4">
            <div className="pointer-events-auto w-[min(92vw,520px)] rounded-2xl border border-white/70 bg-white px-4 py-3 text-sm shadow-[0_4px_14px_rgba(15,23,42,0.08),inset_0_1px_0_rgba(255,255,255,0.92)] backdrop-blur-2xl">
                <div className="text-sm font-medium text-gray-950 mb-1 text-left">Are you sure?</div>
                <div className="text-xs text-gray-700 text-left">This action cannot be undone.</div>
                <div className="mt-3 flex items-center justify-end gap-2">
                    <button className="px-3 py-1.5 text-xs font-medium text-gray-700 hover:text-gray-950 cursor-pointer border-0 bg-transparent" onClick={onCancel}>
                        Cancel
                    </button>
                    <button
                        disabled={status !== "idle"}
                        className="inline-flex h-7 items-center justify-center rounded-full px-3.5 text-xs font-medium text-white cursor-pointer
                            border border-red-700/35 bg-red-600/90
                            shadow-[0_3px_9px_rgba(127,29,29,0.16),inset_0_1px_0_rgba(255,255,255,0.22),inset_0_-4px_9px_rgba(127,29,29,0.18)]
                            hover:bg-red-600 active:scale-[0.98] disabled:opacity-40 transition-all"
                        onClick={onConfirm}
                    >
                        {status === "loading" ? progressiveLabel("Delete") : status === "complete" ? completedLabel("Delete") : "Delete"}
                    </button>
                </div>
            </div>
        </div>
    );
}

EmailPillInput.tsx

Interactive chip-based input field for validating and adding multiple emails.

import React, { useState } from "react";
import { X } from "lucide-react";

interface EmailPillInputProps {
  emails: string[];
  onChange: (emails: string[]) => void;
}

const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function EmailPillInput({ emails, onChange }: EmailPillInputProps) {
    const [input, setInput] = useState("");
    const [error, setError] = useState<string | null>(null);

    function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
        if (e.key === "Enter" || e.key === ",") { 
            e.preventDefault(); 
            commit(); 
        } else if (e.key === "Backspace" && !input && emails.length > 0) {
            onChange(emails.slice(0, -1));
        }
    }

    function commit() {
        const email = input.trim().toLowerCase();
        if (!email || emails.includes(email)) { 
            setInput(""); 
            return; 
        }
        if (!EMAIL_RE.test(email)) { 
            setError("Enter a valid email."); 
            return; 
        }
        onChange([...emails, email]);
        setInput(""); 
        setError(null);
    }

    return (
        <div>
            <div className={`flex flex-wrap gap-1.5 rounded-lg border bg-gray-50 px-3 py-2 min-h-[40px] ${error ? "border-red-300" : "border-gray-200 focus-within:border-gray-400"}`}>
                {emails.map(email => (
                    <span key={email} className="inline-flex items-center gap-1 rounded-full bg-gray-200 px-2.5 py-0.5 text-xs text-gray-700">
                        {email}
                        <button 
                            type="button"
                            aria-label={`Remove ${email}`}
                            className="border-0 bg-transparent p-0 cursor-pointer flex items-center justify-center text-gray-400 hover:text-gray-600" 
                            onClick={() => onChange(emails.filter(e => e !== email))}
                        >
                            <X className="h-3 w-3" aria-hidden="true" />
                        </button>
                    </span>
                ))}
                <input
                    type="email" 
                    aria-label="Add email address"
                    value={input}
                    onChange={e => { setInput(e.target.value); setError(null); }}
                    onKeyDown={handleKeyDown} 
                    onBlur={commit}
                    placeholder={emails.length === 0 ? "Add by email…" : ""}
                    className="flex-1 min-w-[160px] bg-transparent text-sm text-gray-700 placeholder:text-gray-400 outline-none border-0"
                />
            </div>
            {error && <p className="mt-1.5 text-xs text-red-500 text-left">{error}</p>}
        </div>
    );
}

Badge.tsx

Context-aware colored badges and semantic color calculators.

import React from "react";

// Sequential color palette for tag arrays
export const TAG_COLORS = [
    "bg-blue-100 text-blue-800 dark:bg-blue-950/60 dark:text-blue-200",   "bg-violet-100 text-violet-800 dark:bg-violet-950/60 dark:text-violet-200",
    "bg-pink-100 text-pink-800 dark:bg-pink-950/60 dark:text-pink-200",   "bg-orange-100 text-orange-800 dark:bg-orange-950/60 dark:text-orange-200",
    "bg-teal-100 text-teal-800 dark:bg-teal-950/60 dark:text-teal-200",   "bg-amber-100 text-amber-800 dark:bg-amber-950/60 dark:text-amber-200",
];

// Semantic yes/no
export function getBoolColor(val: string) {
    if (val.toLowerCase() === "yes") return "bg-emerald-100 text-emerald-800 dark:bg-emerald-950/60 dark:text-emerald-200";
    if (val.toLowerCase() === "no")  return "bg-red-100 text-red-800 dark:bg-red-950/60 dark:text-red-200";
    return "bg-gray-100 text-gray-800 dark:bg-zinc-800 dark:text-zinc-200";
}

interface BadgeProps {
  children: React.ReactNode;
  color: string;
}

// Badge component
export function Badge({ children, color }: BadgeProps) {
    return (
        <span className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium leading-none ${color}`}>
            {children}
        </span>
    );
}

GlassModal.tsx

Frosted glass-backed modal window with layered shadow elevations and variant controls.

import React from "react";
import { X } from "lucide-react";

interface GlassModalProps {
  title: string;
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
}

export function GlassModal({ title, isOpen, onClose, children }: GlassModalProps) {
    if (!isOpen) return null;

    return (
        <div
            className="fixed inset-0 z-[200] flex items-center justify-center px-4 bg-white/30 backdrop-blur-[2px]"
            onClick={onClose}
        >
            <div
                className="w-full max-w-xl h-[600px] rounded-2xl flex flex-col border border-white/70 bg-white/94 shadow-[0_12px_36px_rgba(15,23,42,0.1)] backdrop-blur-2xl"
                onClick={e => e.stopPropagation()}
            >
                {/* Header */}
                <div className="flex items-start justify-between gap-3 px-4 py-4">
                    <h2 className="text-base font-medium text-gray-900 m-0">{title}</h2>
                    <button onClick={onClose} className="text-gray-400 hover:text-gray-600 border-0 bg-transparent p-0 cursor-pointer">
                        <X className="h-4 w-4" />
                    </button>
                </div>
                {/* Scrollable Body */}
                <div className="flex min-h-0 flex-1 flex-col overflow-y-auto px-4">{children}</div>
                {/* Footer */}
                <div className="flex items-center justify-end gap-2 p-3 border-t border-white/60">
                    <button onClick={onClose} className="px-4 py-1.5 text-sm font-medium text-gray-600 hover:text-gray-950 border-0 bg-transparent cursor-pointer">
                        Cancel
                    </button>
                    <button
                        className="inline-flex items-center gap-1.5 px-4 py-1.5 text-sm font-medium text-white rounded-full cursor-pointer
                            border border-blue-500/35 bg-blue-600/90
                            shadow-[0_3px_9px_rgba(37,99,235,0.16),inset_0_1px_0_rgba(255,255,255,0.28),inset_0_-4px_9px_rgba(29,78,216,0.2)]
                            hover:bg-blue-600 active:scale-[0.98] transition-all"
                    >
                        Save
                    </button>
                </div>
            </div>
        </div>
    );
}

DocCard.tsx

Document status attachment card supporting file uploading states (ready, processing, upload error).

import React from "react";
import { Loader2, AlertCircle, FileText, File, X } from "lucide-react";

interface DocCardProps {
  filename: string;
  fileType: "pdf" | "doc" | string;
  sizeBytes: number;
  pages: number;
  status: "ready" | "processing" | "error";
  onRemove: () => void;
}

export function DocCard({ filename, fileType, sizeBytes, pages, status, onRemove }: DocCardProps) {
    const isError = status === "error";
    const isProcessing = status === "processing";

    function formatBytes(bytes: number) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const sizes = ['Bytes', 'KB', 'MB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    }

    return (
        <div className={`flex items-center gap-2.5 rounded-lg border px-3 py-2.5 text-sm transition-colors w-full
            ${isError ? "border-red-300 bg-red-50 text-red-950 dark:bg-red-950/40 dark:border-red-900" : "border-gray-200 bg-white hover:border-gray-300 text-gray-900 dark:bg-zinc-900 dark:border-zinc-800 dark:text-zinc-100"}`}
        >
            {isProcessing ? <Loader2 className="h-4 w-4 animate-spin text-gray-400 shrink-0" />
             : isError ? <AlertCircle className="h-4 w-4 text-red-600 shrink-0" />
             : fileType === "pdf" ? <FileText className="h-4 w-4 text-red-600 shrink-0" />
             : <File className="h-4 w-4 text-blue-600 shrink-0" />}

            <div className="min-w-0 flex-1 text-left">
                <p className={`truncate font-semibold m-0 ${isError ? "text-red-950 dark:text-red-100" : "text-gray-900 dark:text-gray-100"}`}>{filename}</p>
                <p className={`text-xs m-0 ${isError ? "text-red-900 dark:text-red-200 font-medium" : "text-gray-700 dark:text-gray-300"}`}>
                    {isProcessing ? "Processing…" : isError ? "Upload failed" : `${formatBytes(sizeBytes)} · ${pages}p`}
                </p>
            </div>

            {!isProcessing && (
                <button 
                    type="button"
                    aria-label={`Remove document ${filename}`}
                    className="shrink-0 rounded p-0.5 text-gray-400 hover:bg-gray-100 border-0 bg-transparent cursor-pointer flex items-center justify-center" 
                    onClick={onRemove}
                >
                    <X className="h-3.5 w-3.5" aria-hidden="true" />
                </button>
            )}
        </div>
    );
}
04. AI Scaffolding Prompt

Workspace Master Prompt

Feed this prompt to any developer agent or coding assistant at the start of a session to instruct it to configure and apply the Premium UI design specifications in a single pass.

# Premium Web Design System Prompt

You are tasked with building a premium, modern web user interface inspired by macOS-like tactile dynamics and clean typography. Configure the project to adhere to the following specifications:

## 1. Typography & Hierarchy
Configure the fonts with the following pairings:
- **Sans-Serif (UI Elements)**: `Inter`, system-default sans-serif. Use for buttons, inputs, labels, sidebars, headers, and dashboard widgets.
- **Serif (Content & Documents)**: `EB Garamond`, Georgia, system-default serif. Use for documents, legal sections, rich text views, and long-form articles.

## 2. Color System (OkLCH)
Avoid flat digital colors. Use natural light scaling and matching palettes:
- **Azure Accent**: `rgb(0, 136, 255)` (for link/highlight/accent actions)
- **Light Theme**:
  - `--background`: `oklch(0.985 0 0)` (Soft off-white canvas)
  - `--foreground`: `oklch(0.145 0 0)` (Soft dark charcoal text)
  - `--primary`: `oklch(0.205 0 0)`
  - `--border`: `oklch(0.922 0 0)`
- **Dark Theme**:
  - `--background`: `oklch(0.145 0 0)` (Deep charcoal background)
  - `--foreground`: `oklch(0.985 0 0)` (Crisp off-white text)
  - `--primary`: `oklch(0.922 0 0)`
  - `--border`: `oklch(1 0 0 / 10%)`
  - `--input`: `oklch(1 0 0 / 15%)`

## 3. macOS Glassmorphism
When building modals, popups, or floaters, utilize the glassmorphism pattern:
- Base style: `border-white/70 bg-white/94 backdrop-blur-2xl`
- Specular highlights: Add an absolute top overlay with a linear gradient (`linear-gradient(rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 100%)`, blend mode `overlay`)
- Stacked shadows: Combine thin inset shadows with deep, soft ambient drop shadows to emulate macOS window depth:
  `box-shadow: rgba(255, 255, 255, 0.5) 0px 1px 0px 0px inset, rgba(0, 0, 0, 0.03) 0px -1px 0px 0px inset, rgba(17, 24, 39, 0.04) 0px 1px 2px, rgba(17, 24, 39, 0.08) 0px 12px 32px -8px`

## 4. UI Tactile Dynamics
- **Confirmations**: When confirming actions, use progressive labeling (`Delete` -> `Deleting...` -> `Deleted`).
- **Citation buttons**: Include instant visual confirmation triggers with checkmarks for clipboard copies.
- **Chevrons**: Smoothly transition state rotations (e.g. `rotate-180` for active dropdown toggles).

## 5. Core Agent Skills & Real-Time Research (last30days & AXI Rules)
- Ensure the `AGENTS.md` ruleset (including the `last30days` search requirement and AXI principles) is copied/installed in the root of the workspace to configure instructions for the installed developer skills (Codebase Architecture, AXI / Browser automation, Language standards, and Motion & Design Engineering).
- Rely on the `last30days` search tool to gather the latest developer and community feedback on packages and frameworks instead of outdated public resources.
- Adhere to the 10 AXI (Agent eXperience Interface) design principles when building agent-facing CLI tools (Token-efficient TOON output, minimal default schemas, truncation, aggregates, clean idempotent errors, ambient context/skills, content-first no-args output, contextual disclosure suggestions, and concise `--help`).
- Install the AXI skill: `npx skills add kunchenguid/axi --skill axi`.
- Install the Emil Kowalski design engineering skill: `npx skills add emilkowalski/skill --all`.