MicProtocol / apps /web /src /styles /globals.css
Benaah's picture
Upload folder using huggingface_hub
fb12607 verified
Raw History Blame Contribute Delete
69.5 kB
/* ─── MicProtocol Design System β€” Studio Desk ─────────── */ /* Entry stylesheet. Design tokens live in ./tokens.css; Tailwind v4 utilities are bridged onto the same custom properties below via @theme inline, so legacy CSS and EasyUI/Tailwind components stay in sync from one source of truth. */ @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@100..900&family=DM+Sans:opsz,wght@9..40,100..900&display=swap"); @import "./tokens.css"; @import "./textures.css"; @import "./marketing.css"; /* Tailwind v4 β€” theme + utilities only (no preflight: the legacy reset below still owns the base layer during migration). */ @layer theme, base, components, utilities; @import "tailwindcss/theme.css" layer(theme); @import "tailwindcss/utilities.css" layer(utilities); /* Scan shared UI package sources (outside apps/web cwd). */ @source "../../../packages/ui/src"; /* dark: variant follows the app's data-theme attribute */ @custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *)); /* ─── Tailwind ↔ Token Bridge ───────────────────────── Utility names map onto the CSS custom properties in tokens.css so classes like bg-canvas / text-ink-2 resolve through the same vars the legacy CSS consumes β€” theme switching stays reactive for both systems. Names are deliberately distinct from the underlying var names to avoid circular var() references. */ @theme inline { /* Brand */ --color-brand: var(--color-primary); --color-brand-light: var(--color-primary-light); --color-brand-dark: var(--color-primary-dark); --color-brand-glow: var(--color-primary-glow); --color-accent: var(--color-accent); --color-mint: var(--color-accent); /* Semantic */ --color-positive: var(--color-success); --color-caution: var(--color-warning); --color-negative: var(--color-error); --color-note: var(--color-info); /* Guest pipeline status */ --color-prospect: var(--status-prospect); --color-contacted: var(--status-contacted); --color-scheduled: var(--status-scheduled); --color-recorded: var(--status-recorded); --color-published: var(--status-published); /* Surfaces */ --color-canvas: var(--bg-primary); --color-surface: var(--bg-secondary); --color-surface-raised: var(--bg-tertiary); --color-elevated: var(--bg-elevated); --color-line: var(--border-color); --color-line-subtle: var(--border-color-subtle); /* Ink */ --color-ink: var(--text-primary); --color-ink-2: var(--text-secondary); --color-ink-3: var(--text-tertiary); --color-ink-inverse: var(--text-inverse); /* Warm stone */ --color-stone: var(--stone); --color-stone-light: var(--stone-light); --color-stone-dark: var(--stone-dark); /* Fonts (distinct names to avoid circular var() refs) */ --font-brand: var(--font-sans); --font-brand-display: var(--font-display); --font-code: var(--font-mono); /* Radius β€” sharp "edge" geometry alongside Tailwind defaults */ --radius-edge-sm: var(--radius-sm); --radius-edge: var(--radius-md); --radius-edge-lg: var(--radius-lg); --radius-edge-xl: var(--radius-xl); /* Shadows β€” elevation scale + signal glow */ --shadow-e1: var(--shadow-sm); --shadow-e2: var(--shadow-md); --shadow-e3: var(--shadow-lg); --shadow-e4: var(--shadow-xl); --shadow-signal: var(--shadow-glow); --shadow-signal-strong: var(--shadow-glow-strong); } /* ─── Reset & Base ──────────────────────────────────── */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } html { font-family: var(--font-sans); font-size: 16px; color-scheme: dark; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; scroll-behavior: smooth; } body { background-color: var(--bg-primary); color: var(--text-primary); line-height: 1.55; min-height: 100vh; } [data-theme="light"] { color-scheme: light; } button, input, select, textarea { font: inherit; } h1, h2, h3, h4, h5, h6 { font-family: var(--font-display); letter-spacing: -0.03em; line-height: 1.1; } a { color: var(--color-primary); text-decoration: none; transition: color var(--transition-fast); } a:hover { color: var(--color-primary-light); } /* ─── Utility Classes ───────────────────────────────── */ .container { max-width: var(--content-max-width); margin: 0 auto; padding: 0 var(--space-6); } /* ─── Status Badges ─────────────────────────────────── */ .status-badge { display: inline-flex; align-items: center; gap: var(--space-1); padding: 2px var(--space-3); border-radius: var(--radius-md); font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.06em; border: 1px solid transparent; } .status-prospect { background: color-mix(in srgb, var(--status-prospect) 12%, transparent); color: var(--status-prospect); border-color: color-mix(in srgb, var(--status-prospect) 20%, transparent); } .status-contacted { background: color-mix(in srgb, var(--status-contacted) 12%, transparent); color: var(--status-contacted); border-color: color-mix(in srgb, var(--status-contacted) 20%, transparent); } .status-scheduled { background: color-mix(in srgb, var(--status-scheduled) 12%, transparent); color: var(--status-scheduled); border-color: color-mix(in srgb, var(--status-scheduled) 20%, transparent); } .status-recorded { background: color-mix(in srgb, var(--status-recorded) 10%, transparent); color: var(--status-recorded); border-color: color-mix(in srgb, var(--status-recorded) 20%, transparent); } .status-published { background: color-mix(in srgb, var(--status-published) 12%, transparent); color: var(--status-published); border-color: color-mix(in srgb, var(--status-published) 20%, transparent); } /* ─── Card Surface ──────────────────────────────────── */ .card { background: var(--bg-elevated); border: 1px solid var(--border-color-subtle); border-radius: var(--radius-lg); padding: var(--space-6); transition: border-color var(--transition-fast), box-shadow var(--transition-fast); position: relative; } .card:hover { border-color: var(--border-color); } /* ─── Buttons ───────────────────────────────────────── */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-2) var(--space-4); border: 1px solid transparent; border-radius: var(--radius-md); font-family: var(--font-sans); font-size: var(--text-sm); font-weight: 600; cursor: pointer; transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast), box-shadow var(--transition-fast); white-space: nowrap; text-decoration: none; } .btn:active { transform: scale(0.99); } .btn-primary { background: var(--color-primary); color: var(--text-inverse); border-color: var(--color-primary); box-shadow: var(--shadow-sm); } .btn-primary:hover { background: var(--color-primary-dark); border-color: var(--color-primary-dark); box-shadow: var(--shadow-sm); } .btn-secondary { background: var(--bg-tertiary); color: var(--text-primary); border: 1px solid var(--border-color-subtle); } .btn-secondary:hover { border-color: var(--color-primary); color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 6%, transparent); } .btn-ghost { background: transparent; color: var(--text-secondary); border: none; } .btn-ghost:hover { color: var(--text-primary); background: var(--bg-tertiary); } /* ─── Inputs ────────────────────────────────────────── */ .input { width: 100%; padding: var(--space-2) var(--space-3); border: 1px solid var(--border-color); border-radius: var(--radius-md); font-family: var(--font-sans); font-size: var(--text-sm); color: var(--text-primary); background: var(--bg-elevated); transition: border-color var(--transition-fast), box-shadow var(--transition-fast); outline: none; } .input:focus { border-color: var(--color-primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 20%, transparent); } .input::placeholder { color: var(--text-tertiary); } .micprotocol-search-input { transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast); } .micprotocol-search-input:focus-within { border-color: color-mix( in srgb, var(--color-primary) 60%, var(--border-color) ); box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 12%, transparent); } /* ─── Frosted Panel (replaces glassmorphism) ─────────── */ .frosted { background: var(--bg-elevated); border: 1px solid var(--border-color); position: relative; } .frosted::after { content: ""; position: absolute; inset: 0; opacity: 0.015; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E"); pointer-events: none; border-radius: inherit; } /* ─── Keyframe Animations ───────────────────────────── */ @keyframes fadeIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideInRight { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } } @keyframes revealUp { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: translateY(0); } } @keyframes revealScale { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } } @keyframes pulse-glow { 0%, 100% { box-shadow: 0 0 4px color-mix(in srgb, var(--color-primary) 30%, transparent); } 50% { box-shadow: 0 0 18px color-mix(in srgb, var(--color-primary) 60%, transparent); } } @keyframes pulse-dot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(1.4); } } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } @keyframes grain { 0%, 100% { transform: translate(0, 0); } 10% { transform: translate(-2%, -2%); } 30% { transform: translate(1%, -3%); } 50% { transform: translate(-3%, 1%); } 70% { transform: translate(3%, 2%); } 90% { transform: translate(-1%, 3%); } } @keyframes count-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } @keyframes hero-word { from { opacity: 0; transform: translateY(100%) rotateX(-40deg); } to { opacity: 1; transform: translateY(0) rotateX(0); } } @keyframes glow-line { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: 1; } } /* Animation classes */ .animate-fade-in { animation: fadeIn 0.4s var(--ease-out-expo) forwards; } .animate-slide-in { animation: slideInRight 0.4s var(--ease-out-expo) forwards; } .animate-reveal { opacity: 0; animation: revealUp 0.7s var(--ease-out-expo) forwards; } .animate-reveal-delay-1 { animation-delay: 0.1s; } .animate-reveal-delay-2 { animation-delay: 0.2s; } .animate-reveal-delay-3 { animation-delay: 0.3s; } .animate-reveal-delay-4 { animation-delay: 0.4s; } .animate-reveal-delay-5 { animation-delay: 0.5s; } .animate-pulse-dot { animation: pulse-dot 2s ease-in-out infinite; } /* ─── Scrollbar β€” Minimal ───────────────────────────── */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--border-color); border: 2px solid var(--bg-primary); border-radius: var(--radius-full); } ::-webkit-scrollbar-thumb:hover { background: var(--text-tertiary); } /* ─── Focus Visible ─────────────────────────────────── */ :focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; } .btn:focus-visible, .input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-primary) 15%, transparent); } /* ─── Responsive ────────────────────────────────────── */ @media (max-width: 1024px) { :root { --sidebar-width: 220px; } } @media (max-width: 768px) { :root { --sidebar-width: 0px; --header-height: 52px; } .sidebar-desktop { display: none !important; } .sidebar-mobile-overlay { display: flex !important; } .mobile-hamburger { display: flex !important; } .kanban-grid { grid-template-columns: 1fr !important; overflow-x: visible !important; } .responsive-grid-2 { grid-template-columns: 1fr !important; } .stats-grid { grid-template-columns: repeat(2, 1fr) !important; } .profile-stats-row { flex-direction: column !important; gap: var(--space-3) !important; } .profile-stats-row > div[style*="width: 1px"] { width: 100% !important; height: 1px !important; } .marketing-footer-grid { grid-template-columns: 1fr !important; } } @media (max-width: 480px) { .stats-grid { grid-template-columns: 1fr !important; } } /* ─── Responsive hide/show ──────────────────────────── */ .sidebar-mobile-overlay { display: none; } .mobile-hamburger { display: none; } /* ─── Skeleton Loading ──────────────────────────────── */ .skeleton { background: linear-gradient( 90deg, var(--bg-tertiary) 25%, var(--border-color) 50%, var(--bg-tertiary) 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: var(--radius-md); } /* ─── Drop Zone ─────────────────────────────────────── */ .drop-zone-active { background: color-mix( in srgb, var(--color-primary) 6%, transparent ) !important; border: 2px dashed var(--color-primary) !important; } .guest-card-dragging { opacity: 0.5; transform: rotate(1deg); } /* ─── Modal / Overlay ───────────────────────────────── */ .modal-overlay { position: fixed; inset: 0; background: color-mix(in srgb, var(--bg-primary) 70%, transparent); display: flex; align-items: center; justify-content: center; z-index: 100; animation: fadeIn 0.12s ease; } .slide-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 480px; max-width: 100vw; background: var(--bg-primary); border-left: 1px solid var(--border-color); box-shadow: var(--shadow-xl); z-index: 100; animation: slideInRight 0.25s var(--ease-out-expo); overflow-y: auto; } @media (max-width: 768px) { .slide-panel { width: 100vw; } } /* ─── Reduced Motion ────────────────────────────────── */ @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } html { scroll-behavior: auto; } } /* ─── Accent Utilities ──────────────────────────────── */ .accent-left { border-left: 3px solid var(--color-primary); } .text-gradient { background: linear-gradient( 135deg, var(--color-primary), var(--color-primary-light) ); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } .glow-line { height: 1px; background: linear-gradient( 90deg, transparent, var(--color-primary), transparent ); animation: glow-line 1s var(--ease-out-expo) forwards; transform-origin: left; } /* ─── Sidebar ───────────────────────────────────────── */ .sidebar { width: var(--sidebar-width); border-right: 1px solid var(--border-color); background: var(--bg-primary); display: flex; flex-direction: column; position: fixed; top: 0; left: 0; bottom: 0; z-index: 50; } .sidebar-brand { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-5); text-decoration: none; border-bottom: 1px solid var(--border-color); } .sidebar-brand-icon { width: 28px; height: 28px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .sidebar-brand-name { font-size: var(--text-lg); font-weight: 700; color: var(--text-primary); font-family: var(--font-display); letter-spacing: -0.03em; } .sidebar-nav { flex: 1; padding-top: var(--space-3); } .sidebar-bottom { border-top: 1px solid var(--border-color); padding: var(--space-3) 0; } /* ─── Nav Link ──────────────────────────────────────── */ .nav-link { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-2) var(--space-5); margin: 1px var(--space-2); border-radius: var(--radius-md); color: var(--text-secondary); background: transparent; font-weight: 400; font-size: var(--text-sm); transition: all var(--transition-fast); text-decoration: none; border-left: 3px solid transparent; } .nav-link:hover { color: var(--text-primary); background: color-mix(in srgb, var(--text-primary) 4%, transparent); } .nav-link[data-active="true"] { color: var(--color-primary); background: color-mix(in srgb, var(--color-primary) 8%, transparent); font-weight: 600; border-left-color: var(--color-primary); } /* ─── User Profile ──────────────────────────────────── */ .user-profile { padding: var(--space-4) var(--space-5); border-top: 1px solid var(--border-color); display: flex; align-items: center; gap: var(--space-3); cursor: pointer; transition: background var(--transition-fast); } .user-profile:hover { background: color-mix(in srgb, var(--text-primary) 3%, transparent); } .user-avatar { width: 32px; height: 32px; border-radius: var(--radius-md); background: var(--color-primary); display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: var(--text-xs); font-family: var(--font-display); flex-shrink: 0; } .user-info { flex: 1; min-width: 0; } .user-name { font-size: var(--text-sm); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .user-role { font-size: var(--text-xs); color: var(--text-tertiary); } /* ─── Topbar ────────────────────────────────────────── */ .topbar { height: var(--header-height); border-bottom: 1px solid var(--border-color); display: flex; align-items: center; justify-content: space-between; padding: 0 var(--space-6); background: var(--bg-primary); position: sticky; top: 0; z-index: 40; } .topbar-search { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2) var(--space-4); border: 1px solid var(--border-color); border-radius: var(--radius-md); font-size: var(--text-sm); max-width: 360px; flex: 1; cursor: text; transition: border-color var(--transition-fast); } .topbar-search:focus-within { border-color: var(--color-primary); } .topbar-search:focus-within kbd { opacity: 0; pointer-events: none; } .topbar-search input { background: transparent; border: none; outline: none; flex: 1; font-size: var(--text-sm); color: var(--text-primary); font-family: var(--font-sans); } .topbar-actions { display: flex; align-items: center; gap: var(--space-4); } /* ─── Main Content ──────────────────────────────────── */ .main-content { flex: 1; margin-left: var(--sidebar-width); display: flex; flex-direction: column; } .main-content > main { flex: 1; padding: var(--space-6) var(--space-8); } /* ─── Page Header ───────────────────────────────────── */ .page-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-8); } .page-title { font-size: var(--text-3xl); font-weight: 700; font-family: var(--font-display); letter-spacing: -0.03em; } .page-subtitle { color: var(--text-tertiary); font-size: var(--text-sm); margin-top: 4px; } /* ─── Section Header ────────────────────────────────── */ .section-title { letter-spacing: -0.02em; font-size: var(--text-lg); color: var(--text-primary); font-weight: 650; line-height: 1.3; margin-bottom: var(--space-2); } /* ─── Stat Card ─────────────────────────────────────── */ .stat-card { background: var(--bg-elevated); border: 1px solid var(--border-color-subtle); border-radius: var(--radius-lg); padding: var(--space-6); display: flex; align-items: center; gap: var(--space-4); transition: box-shadow var(--transition-fast), border-color var(--transition-fast); } .stat-card:hover { border-color: var(--border-color); box-shadow: var(--shadow-sm); } .stat-icon { width: 40px; height: 40px; border-radius: var(--radius-md); background: var(--bg-tertiary); display: flex; align-items: center; justify-content: center; border: 1px solid var(--border-color); flex-shrink: 0; } .stat-value { font-size: var(--text-2xl); font-weight: 700; font-family: var(--font-display); } .stat-label { font-size: var(--text-xs); color: var(--text-tertiary); letter-spacing: 0.02em; } /* ─── Pipeline Stage ────────────────────────────────── */ .pipeline-card { background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); overflow: hidden; } .pipeline-row { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4); transition: background var(--transition-fast); } .pipeline-row:not(:last-child) { border-bottom: 1px solid var(--border-color-subtle); } .pipeline-row:hover { background: var(--bg-tertiary); } .pipeline-label { flex: 1; font-size: var(--text-sm); } .pipeline-count { font-weight: 700; font-size: var(--text-sm); font-family: var(--font-display); } /* ─── Recording Card ────────────────────────────────── */ .recording-card { background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-4); position: relative; transition: box-shadow var(--transition-normal); } .recording-card:hover { box-shadow: var(--shadow-sm); } .recording-time { position: absolute; top: var(--space-3); right: var(--space-3); display: inline-flex; align-items: center; gap: 4px; color: var(--text-tertiary); font-size: var(--text-xs); } .recording-guest { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); } .recording-avatar { width: 32px; height: 32px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .recording-avatar--confirmed { background: var(--color-primary); border: none; } .recording-avatar--pending { background: var(--bg-tertiary); border: 1px solid var(--border-color); } /* ─── Quick Action Card ─────────────────────────────── */ .action-card { background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); padding: var(--space-5); cursor: pointer; text-decoration: none; color: inherit; display: block; transition: all var(--transition-normal); } .action-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--color-primary); } .action-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-2); } .action-card-title { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: 600; font-family: var(--font-display); } .action-card-desc { font-size: var(--text-xs); color: var(--text-tertiary); } /* ─── Empty State ───────────────────────────────────── */ .empty-state { background: var(--bg-elevated); border: 1px solid var(--border-color); border-radius: var(--radius-md); text-align: center; color: var(--text-tertiary); padding: var(--space-8); } .empty-state p { font-size: var(--text-sm); } /* ─── Loading Skeleton ──────────────────────────────── */ .skeleton-stat { height: 80px; background: linear-gradient( 90deg, var(--bg-tertiary) 25%, var(--border-color) 50%, var(--bg-tertiary) 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: var(--radius-md); border: 1px solid var(--border-color); } .skeleton-card { height: 120px; background: linear-gradient( 90deg, var(--bg-tertiary) 25%, var(--border-color) 50%, var(--bg-tertiary) 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: var(--radius-md); border: 1px solid var(--border-color); } /* ─── Feature Grid (hover via CSS) ──────────────────── */ .feature-cell { background: var(--bg-elevated); padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-3); transition: background var(--transition-normal); } .feature-cell:hover { background: var(--bg-tertiary); } /* ─── Marketing Nav Link ────────────────────────────── */ .marketing-nav-link { color: var(--text-secondary); font-weight: 500; font-size: var(--text-sm); text-decoration: none; transition: color var(--transition-fast); position: relative; padding: var(--space-1) 0; } .marketing-nav-link::after { content: ""; position: absolute; bottom: -2px; left: 50%; width: 0; height: 2px; background: var(--color-primary); transition: width 0.3s var(--spring), left 0.3s var(--spring); border-radius: var(--radius-full); } .marketing-nav-link:hover { color: var(--text-primary); } .marketing-nav-link:hover::after { width: 100%; left: 0; } .marketing-nav-link[data-active="true"] { color: var(--color-primary); font-weight: 600; } .marketing-nav-link[data-active="true"]::after { width: 100%; left: 0; } /* ─── Marketing Header ──────────────────────────────── */ .marketing-header { height: 64px; display: flex; align-items: center; justify-content: space-between; padding: 0 var(--space-8); background: transparent; position: sticky; top: 0; z-index: 100; transition: all 0.35s var(--ease-out-expo); } .marketing-header-scrolled { background: color-mix(in srgb, var(--bg-primary) 90%, transparent); backdrop-filter: blur(20px) saturate(1.3); -webkit-backdrop-filter: blur(20px) saturate(1.3); border-bottom: 1px solid var(--border-color); box-shadow: 0 4px 24px color-mix(in srgb, var(--bg-primary) 25%, transparent); } /* ─── Immersive Header β€” Gradient + Glow ══════════════════════════════ */ .marketing-header-immersive { background: linear-gradient( 180deg, transparent 0%, color-mix(in srgb, var(--bg-primary) 20%, transparent) 100% ); border-bottom: 1px solid color-mix(in srgb, var(--color-primary) 6%, transparent); } .marketing-header-immersive.marketing-header-scrolled { background: linear-gradient( 180deg, transparent 0%, color-mix(in srgb, var(--bg-primary) 92%, transparent) 100% ); border-bottom: 1px solid color-mix(in srgb, var(--color-primary) 12%, transparent); box-shadow: 0 4px 30px color-mix(in srgb, var(--bg-primary) 35%, transparent), 0 0 0 1px color-mix(in srgb, var(--color-primary) 8%, transparent); } .header-glow { position: absolute; inset: 0; z-index: -1; background: radial-gradient( ellipse at 20% 0%, color-mix(in srgb, var(--color-primary) 12%, transparent) 0%, transparent 40% ), radial-gradient( ellipse at 80% 0%, color-mix(in srgb, var(--color-primary) 6%, transparent) 0%, transparent 40% ), radial-gradient( ellipse at 50% 100%, color-mix(in srgb, var(--color-primary) 4%, transparent) 0%, transparent 30% ); pointer-events: none; transition: opacity 0.35s var(--ease-out-expo); opacity: 0.35; } @keyframes header-glow-pulse { 0%, 100% { opacity: 0.35; transform: scale(1); } 50% { opacity: 0.55; transform: scale(1.03); } } .marketing-header-immersive:not(.marketing-header-scrolled) .header-glow { animation: header-glow-pulse 8s ease-in-out infinite; } /* ─── Marketing Logo ────────────────────────────────── */ .marketing-logo { display: flex; align-items: center; gap: var(--space-2); text-decoration: none; border-bottom: none; padding: 0; transition: transform 0.3s var(--spring); } .marketing-logo:hover { transform: scale(1.03); } .marketing-logo:hover .marketing-logo-icon { transform: rotate(-8deg) scale(1.1); filter: drop-shadow( 0 0 10px color-mix(in srgb, var(--color-primary) 50%, transparent) ); } .marketing-logo-icon { transition: transform 0.4s var(--spring), filter 0.3s ease; } /* ─── CTA Button Glow ───────────────────────────────── */ .marketing-cta { position: relative; overflow: hidden; transition: all 0.3s var(--spring); } .marketing-cta::before { content: ""; position: absolute; inset: -2px; background: linear-gradient( 135deg, var(--color-primary), var(--color-primary-light), var(--color-primary) ); border-radius: inherit; opacity: 0; transition: opacity 0.3s ease; z-index: -1; } .marketing-cta:hover::before { opacity: 0.5; } .marketing-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 20px color-mix(in srgb, var(--color-primary) 35%, transparent); } .marketing-cta:active { transform: translateY(0) scale(0.98); } /* ─── Mobile Menu ───────────────────────────────────── */ @keyframes mobile-menu-enter { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } @keyframes mobile-menu-item-enter { from { opacity: 0; transform: translateX(-20px); } to { opacity: 1; transform: translateX(0); } } .marketing-mobile-menu { position: fixed; top: 64px; left: 0; right: 0; bottom: 0; background: var(--bg-primary); z-index: 99; padding: var(--space-6); display: flex; flex-direction: column; gap: var(--space-2); animation: mobile-menu-enter 0.3s var(--ease-out-expo) forwards; overflow-y: auto; } .marketing-mobile-menu-item { opacity: 0; animation: mobile-menu-item-enter 0.35s var(--ease-out-expo) forwards; } .marketing-mobile-menu-item:nth-child(1) { animation-delay: 0.05s; } .marketing-mobile-menu-item:nth-child(2) { animation-delay: 0.1s; } .marketing-mobile-menu-item:nth-child(3) { animation-delay: 0.15s; } .marketing-mobile-menu-item:nth-child(4) { animation-delay: 0.2s; } .marketing-mobile-menu-item:nth-child(5) { animation-delay: 0.25s; } /* ─── Hamburger Animation ───────────────────────────── */ .hamburger-line { transition: all 0.3s var(--spring); transform-origin: center; } .hamburger-open .hamburger-line:nth-child(1) { transform: translateY(6px) rotate(45deg); } .hamburger-open .hamburger-line:nth-child(2) { opacity: 0; transform: scaleX(0); } .hamburger-open .hamburger-line:nth-child(3) { transform: translateY(-6px) rotate(-45deg); } /* ─── Marketing Footer ──────────────────────────────── */ .marketing-footer-link { font-size: var(--text-sm); color: var(--text-secondary); text-decoration: none; transition: color var(--transition-fast), transform var(--transition-fast); display: inline-block; } .marketing-footer-link:hover { color: var(--color-primary); transform: translateX(3px); } /* ─── Footer Link ───────────────────────────────────── */ .footer-link { font-size: var(--text-sm); color: var(--text-secondary); text-decoration: none; transition: color var(--transition-fast); } .footer-link:hover { color: var(--color-primary); } .footer-heading { font-weight: 600; margin-bottom: var(--space-4); font-size: var(--text-xs); letter-spacing: 0.08em; color: var(--text-tertiary); } /* ─── Hero Section ──────────────────────────────────── */ .hero { width: 100%; text-align: center; padding: var(--space-28) var(--space-8) var(--space-24); position: relative; overflow: hidden; background-color: var(--bg-primary); } .hero-sub { padding: var(--space-16) var(--space-8) var(--space-12); } .hero-bg { position: absolute; inset: 0; z-index: 0; background-image: linear-gradient( to bottom, color-mix(in srgb, var(--bg-primary) 40%, transparent) 0%, color-mix(in srgb, var(--bg-primary) 70%, transparent) 60%, var(--bg-primary) 100% ); background-size: cover; background-position: center; background-repeat: no-repeat; opacity: 0.6; } .hero-content { position: relative; z-index: 1; max-width: 1100px; margin: 0 auto; } .hero-glow { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -60%); width: 600px; height: 400px; background: radial-gradient( ellipse, color-mix(in srgb, var(--color-primary) 12%, transparent), transparent 70% ); pointer-events: none; z-index: 0; } .hero-headline { font-size: var(--text-hero); font-weight: 700; font-family: var(--font-display); letter-spacing: -0.04em; line-height: 1.05; margin-bottom: var(--space-6); max-width: 900px; margin-left: auto; margin-right: auto; } .hero-desc { font-size: var(--text-lg); color: var(--text-secondary); line-height: 1.7; max-width: 540px; margin: 0 auto var(--space-10); } .hero-ctas { display: flex; gap: var(--space-4); justify-content: center; flex-wrap: wrap; margin-bottom: var(--space-16); } /* ─── How It Works ──────────────────────────────────── */ .steps-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-8); } @media (max-width: 768px) { .steps-grid { grid-template-columns: 1fr; } .hero-headline { font-size: var(--text-4xl); } .marketing-nav-desktop { display: none !important; } .marketing-hamburger { display: flex !important; } } .marketing-hamburger { display: none; } /* ─── Notification Dot ──────────────────────────────── */ .notification-dot { position: absolute; top: 4px; right: 4px; width: 7px; height: 7px; border-radius: var(--radius-full); background: var(--color-primary); border: 2px solid var(--bg-primary); } /* ─── SR Only ───────────────────────────────────────── */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* ─── Diary Workspace ──────────────────────────────── */ /* Full‑screen diary: the container in page.tsx uses inline styles; these classes cover the internal panels and hover states. */ .diary-flow-shell { border: 1px solid var(--border-color); border-radius: var(--radius-md); height: 100%; flex: 1; min-height: 0; overflow: hidden; background: radial-gradient( circle at 20% 20%, color-mix(in srgb, var(--color-primary) 8%, transparent), transparent 44% ), radial-gradient( circle at 85% 10%, color-mix(in srgb, var(--color-accent) 6%, transparent) 0%, transparent 38% ), var(--bg-secondary); } .diary-note-input { flex: 1; min-height: 0; resize: none; line-height: 1.6; background: var(--bg-primary); } .diary-body-textarea { flex: 1; min-height: 0; resize: none; line-height: 1.6; background: var(--bg-primary); } /* ---- Kanban board refinements ---- */ .kanban-card { transition: box-shadow var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast); } .kanban-card:hover { border-color: color-mix( in srgb, var(--color-primary) 35%, var(--border-color) ); box-shadow: var(--shadow-md); transform: translateY(-1px); } .kanban-action-btn { display: inline-flex; align-items: center; justify-content: center; padding: 4px; border-radius: var(--radius-sm); color: var(--text-tertiary); transition: color var(--transition-fast), background var(--transition-fast); } .kanban-action-btn:hover, .kanban-action-btn:focus-visible { color: var(--text-primary); background: var(--bg-tertiary); } .kanban-action-btn--danger:hover, .kanban-action-btn--danger:focus-visible { color: var(--color-error); background: color-mix(in srgb, var(--color-error) 12%, transparent); } .kanban-scroll-x { scrollbar-width: thin; scrollbar-color: var(--border-color) transparent; } .kanban-scroll-x::-webkit-scrollbar { height: 8px; } .kanban-scroll-x::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 999px; } .kanban-scroll-x::-webkit-scrollbar-track { background: transparent; } .react-flow__controls { border: 1px solid var(--border-color) !important; border-radius: var(--radius-md) !important; box-shadow: var(--shadow-sm) !important; overflow: hidden; } .react-flow__controls-button { background: var(--bg-primary) !important; border-bottom: 1px solid var(--border-color) !important; color: var(--text-primary) !important; } .react-flow__controls-button:last-child { border-bottom: none !important; } .react-flow__controls-button:hover { background: var(--bg-tertiary) !important; } .react-flow__panel { margin: var(--space-3) !important; } .react-flow__attribution { background: transparent !important; color: var(--text-tertiary) !important; } /* Responsive: narrower sidebars on smaller screens */ @media (max-width: 1280px) { .diary-flow-shell { min-height: 300px; } } @media (max-width: 1024px) { .diary-flow-shell { height: 400px; } } /* ═══════════════════════════════════════════════════════════ MICRO-INTERACTIONS β€” Engaging feedback loops ═══════════════════════════════════════════════════════════ */ /* ─── Button Ripple Effect ────────────────────────────── */ .btn { position: relative; overflow: hidden; } .btn::after { content: ""; position: absolute; inset: 0; background: radial-gradient( circle at var(--ripple-x, 50%) var(--ripple-y, 50%), color-mix(in srgb, var(--text-primary) 30%, transparent) 0%, transparent 70% ); opacity: 0; transform: scale(0); transition: opacity 0.4s ease, transform 0.5s ease; pointer-events: none; } .btn:active::after { opacity: 1; transform: scale(2.5); transition: opacity 0s, transform 0s; } /* ─── Card Interactions ───────────────────────────────── */ .card { transition: border-color var(--transition-fast), box-shadow var(--transition-fast); } .card-interactive { cursor: pointer; } .card-interactive:hover { border-color: color-mix(in srgb, var(--color-primary) 30%, transparent); box-shadow: var(--shadow-md); transform: translateY(-1px); } .card-interactive:active { transform: translateY(0) scale(0.995); } /* ─── Stat Counter Animation ──────────────────────────── */ .stat-value { display: inline-block; transition: transform 0.3s var(--spring), color 0.2s ease; } .stat-value:hover { transform: scale(1.05); color: var(--color-primary); } /* ─── Status Badge Pulse on Change ────────────────────── */ @keyframes status-change-pulse { 0% { transform: scale(1); } 30% { transform: scale(1.15); } 60% { transform: scale(0.95); } 100% { transform: scale(1); } } .status-badge-animate { animation: status-change-pulse 0.4s var(--spring); } /* ─── Success Toast Animation ─────────────────────────── */ @keyframes success-bounce { 0% { transform: translateX(100%); opacity: 0; } 50% { transform: translateX(-4%); } 70% { transform: translateX(2%); } 100% { transform: translateX(0); opacity: 1; } } .toast-success-animate { animation: success-bounce 0.5s var(--spring) forwards; } /* ─── Loading Skeleton Shimmer ────────────────────────── */ .skeleton { background: linear-gradient( 90deg, var(--bg-tertiary) 25%, var(--bg-secondary) 50%, var(--bg-tertiary) 75% ); background-size: 200% 100%; animation: shimmer 1.5s infinite; border-radius: var(--radius-md); } /* ─── Drag Feedback ───────────────────────────────────── */ @keyframes drag-lift { from { transform: scale(1); box-shadow: none; } to { transform: scale(1.03) rotate(1deg); box-shadow: var(--shadow-lg); } } .guest-card-dragging { animation: drag-lift 0.2s var(--spring) forwards; opacity: 0.9; z-index: 100; } .drop-zone-active { border-color: var(--color-primary) !important; background: color-mix( in srgb, var(--color-primary) 4%, transparent ) !important; } .drop-zone-active::after { content: ""; position: absolute; inset: 0; border: 2px dashed var(--color-primary); border-radius: inherit; pointer-events: none; opacity: 0.4; animation: pulse-glow 2s ease-in-out infinite; } /* ─── Recording Pulse ─────────────────────────────────── */ @keyframes recording-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-error) 40%, transparent); } 50% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--color-error) 0%, transparent); } } .recording-active { animation: recording-pulse 1.5s ease-in-out infinite; } /* ─── Timer Glow ──────────────────────────────────────── */ @keyframes timer-glow { 0%, 100% { text-shadow: 0 0 8px color-mix(in srgb, var(--color-error) 30%, transparent); } 50% { text-shadow: 0 0 20px color-mix(in srgb, var(--color-error) 60%, transparent); } } .timer-recording { animation: timer-glow 2s ease-in-out infinite; } /* ─── Nav Link Hover Indicator ────────────────────────── */ .nav-link { position: relative; } .nav-link::before { content: none; } /* ─── Focus Ring Animation ────────────────────────────── */ @keyframes focus-ring-expand { from { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary) 40%, transparent); } to { box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-primary) 0%, transparent); } } /* ─── Dashboard Shell ────────────────────────────────── */ .dashboard-sidebar { z-index: 30; transition: transform var(--transition-normal), box-shadow var(--transition-normal); } .dashboard-nav-link { margin: 2px var(--space-3); padding: 10px var(--space-3) !important; border: 0 !important; border-radius: var(--radius-md); color: var(--text-secondary); transition: background-color var(--transition-fast), color var(--transition-fast); } .dashboard-nav-link:hover { color: var(--text-primary) !important; background: color-mix( in srgb, var(--text-primary) 5%, transparent ) !important; } .dashboard-nav-link[data-active="true"] { color: var(--color-primary) !important; background: color-mix( in srgb, var(--color-primary) 10%, transparent ) !important; } .dashboard-profile-link { transition: background-color var(--transition-fast); } .dashboard-profile-link:hover, .dashboard-signout:hover { background: color-mix( in srgb, var(--text-primary) 4%, transparent ) !important; } .dashboard-main { min-width: 0; } .dashboard-content { min-width: 0; } .dashboard-search-form { min-width: 0; } .dashboard-search-input { min-width: 0; } .dashboard-overview { min-width: 0; } .dashboard-overview-header { align-items: center !important; } .dashboard-stats-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } .dashboard-overview-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .dashboard-mobile-menu, .dashboard-mobile-overlay { display: none; } @media (max-width: 768px) { .dashboard-sidebar { position: fixed !important; inset: 0 auto 0 0 !important; width: min(84vw, 288px) !important; height: 100dvh !important; transform: translateX(-105%); visibility: hidden; z-index: 70; transition: transform var(--transition-normal), box-shadow var(--transition-normal), visibility 0s linear var(--transition-normal); } .dashboard-sidebar.is-open { transform: translateX(0); visibility: visible; box-shadow: var(--shadow-xl); transition-delay: 0s; } .dashboard-mobile-overlay { display: block; position: fixed; inset: 0; z-index: 60; border: 0; background: rgba(10, 12, 14, 0.58); backdrop-filter: blur(2px); } .dashboard-mobile-menu { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; flex-shrink: 0; border: 1px solid var(--border-color-subtle); border-radius: var(--radius-md); background: var(--bg-elevated); color: var(--text-secondary); cursor: pointer; } .dashboard-mobile-menu:hover { color: var(--text-primary); border-color: var(--border-color); } .dashboard-header { position: sticky; top: 0; z-index: 40; height: 60px !important; padding: 0 var(--space-4) !important; gap: var(--space-2); } .dashboard-content { padding: var(--space-5) var(--space-4) !important; } .dashboard-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .dashboard-overview-grid { grid-template-columns: 1fr; } .dashboard-overview-header { align-items: flex-start !important; flex-wrap: wrap; } .dashboard-overview-header > div:last-child { flex-wrap: wrap; } } @media (max-width: 520px) { .dashboard-search-shortcut { display: none !important; } .dashboard-header { padding: 0 var(--space-3) !important; } .dashboard-header > div:last-child { gap: 4px !important; } .dashboard-content { padding: var(--space-4) var(--space-3) !important; } .dashboard-stats-grid { grid-template-columns: 1fr; } } .btn:focus-visible { animation: focus-ring-expand 0.3s ease-out; } /* ─── Number Count-Up ─────────────────────────────────── */ @keyframes number-pop { 0% { transform: translateY(0); } 40% { transform: translateY(-6px); } 100% { transform: translateY(0); } } .number-animate { animation: number-pop 0.35s var(--spring); } /* ─── Stagger Children (for lists) ────────────────────── */ .stagger-children > * { opacity: 0; animation: fadeIn 0.3s var(--ease-out-expo) forwards; } .stagger-children > *:nth-child(1) { animation-delay: 0.05s; } .stagger-children > *:nth-child(2) { animation-delay: 0.1s; } .stagger-children > *:nth-child(3) { animation-delay: 0.15s; } .stagger-children > *:nth-child(4) { animation-delay: 0.2s; } .stagger-children > *:nth-child(5) { animation-delay: 0.25s; } .stagger-children > *:nth-child(6) { animation-delay: 0.3s; } .stagger-children > *:nth-child(7) { animation-delay: 0.35s; } .stagger-children > *:nth-child(8) { animation-delay: 0.4s; } .stagger-children > *:nth-child(9) { animation-delay: 0.45s; } .stagger-children > *:nth-child(10) { animation-delay: 0.5s; } /* ─── Checkbox Toggle Animation ───────────────────────── */ @keyframes checkbox-check { 0% { transform: scale(0); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } .card-checkbox span { animation: checkbox-check 0.25s var(--spring); } /* ─── Page Transition ─────────────────────────────────── */ .page-enter { animation: fadeIn 0.35s var(--ease-out-expo) forwards; } /* ─── Hover Lift for List Items ───────────────────────── */ .list-item-hover { transition: background var(--transition-fast), transform var(--transition-fast), box-shadow var(--transition-fast); } .list-item-hover:hover { background: var(--bg-secondary); transform: translateX(2px); box-shadow: -2px 0 0 var(--color-primary); } /* ─── Keyboard Shortcut Badge ─────────────────────────── */ kbd { transition: transform 0.15s var(--spring), box-shadow 0.15s ease; } kbd:hover { transform: translateY(-1px); box-shadow: 0 2px 4px color-mix(in srgb, var(--bg-primary) 30%, transparent); } /* ─── Sidebar Brand Glow ──────────────────────────────── */ .sidebar-brand-icon { transition: transform 0.3s var(--spring), filter 0.3s ease; } .sidebar-brand:hover .sidebar-brand-icon { transform: scale(1.1) rotate(-5deg); filter: drop-shadow( 0 0 8px color-mix(in srgb, var(--color-primary) 50%, transparent) ); } /* ─── Progress Bar Fill ───────────────────────────────── */ @keyframes progress-fill { from { width: 0%; } } .progress-bar-fill { animation: progress-fill 0.8s var(--ease-out-expo) forwards; } /* ─── Tooltip Fade ────────────────────────────────────── */ @keyframes tooltip-in { from { opacity: 0; transform: translateY(4px) scale(0.96); } to { opacity: 1; transform: translateY(0) scale(1); } } .tooltip-animate { animation: tooltip-in 0.15s var(--ease-out-expo) forwards; } /* ─── Modal Overlay Fade ──────────────────────────────── */ .modal-overlay { position: fixed; inset: 0; background: color-mix(in srgb, var(--bg-primary) 60%, transparent); backdrop-filter: blur(4px); z-index: 1000; animation: fadeIn 0.2s ease forwards; } /* ─── Slide Panel ─────────────────────────────────────── */ .slide-panel { position: fixed; top: 0; right: 0; bottom: 0; width: 480px; max-width: 90vw; background: var(--bg-primary); border-left: 1px solid var(--border-color); z-index: 1001; overflow-y: auto; animation: slideInRight 0.3s var(--ease-out-expo) forwards; box-shadow: var(--shadow-xl); } /* ─── Success Checkmark ───────────────────────────────── */ @keyframes checkmark-draw { 0% { stroke-dashoffset: 24; } 100% { stroke-dashoffset: 0; } } .success-check { stroke-dasharray: 24; animation: checkmark-draw 0.4s ease forwards 0.1s; } /* ─── Ripple on Select ────────────────────────────────── */ @keyframes select-ripple { 0% { transform: scale(0); opacity: 0.5; } 100% { transform: scale(4); opacity: 0; } } .select-ripple { position: absolute; width: 20px; height: 20px; border-radius: 50%; background: var(--color-primary); pointer-events: none; animation: select-ripple 0.5s ease-out forwards; } /* ─── Notification Bell Shake ─────────────────────────── */ @keyframes bell-shake { 0%, 100% { transform: rotate(0); } 15% { transform: rotate(12deg); } 30% { transform: rotate(-10deg); } 45% { transform: rotate(8deg); } 60% { transform: rotate(-6deg); } 75% { transform: rotate(3deg); } } .bell-animate { animation: bell-shake 0.6s var(--spring); } /* ─── Kanban Column Drop Zone Glow ────────────────────── */ @keyframes column-glow { 0%, 100% { box-shadow: inset 0 0 0 2px transparent; } 50% { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--color-primary) 30%, transparent); } } .column-drop-ready { animation: column-glow 1s ease-in-out infinite; } /* ═══════════════════════════════════════════════════════════ ONBOARDING β€” Multi-step Wizard Animations ═══════════════════════════════════════════════════════════ */ /* ─── Step Transitions ────────────────────────────────── */ @keyframes step-enter-right { from { opacity: 0; transform: translateX(60px) scale(0.96); } to { opacity: 1; transform: translateX(0) scale(1); } } @keyframes step-enter-left { from { opacity: 0; transform: translateX(-60px) scale(0.96); } to { opacity: 1; transform: translateX(0) scale(1); } } @keyframes step-exit-left { from { opacity: 1; transform: translateX(0) scale(1); } to { opacity: 0; transform: translateX(-60px) scale(0.96); } } @keyframes step-exit-right { from { opacity: 1; transform: translateX(0) scale(1); } to { opacity: 0; transform: translateX(60px) scale(0.96); } } .step-enter-next { animation: step-enter-right 0.5s var(--ease-out-expo) forwards; } .step-enter-prev { animation: step-enter-left 0.5s var(--ease-out-expo) forwards; } /* ─── Progress Bar ────────────────────────────────────── */ @keyframes progress-pulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-primary) 40%, transparent); } 50% { box-shadow: 0 0 8px 2px color-mix(in srgb, var(--color-primary) 20%, transparent); } } .progress-active { animation: progress-pulse 2s ease-in-out infinite; } /* ─── Floating Orbs (background decoration) ───────────── */ @keyframes float-orb-1 { 0%, 100% { transform: translate(0, 0) scale(1); } 25% { transform: translate(30px, -20px) scale(1.05); } 50% { transform: translate(-10px, -40px) scale(0.95); } 75% { transform: translate(-30px, -10px) scale(1.02); } } @keyframes float-orb-2 { 0%, 100% { transform: translate(0, 0) scale(1); } 25% { transform: translate(-20px, 30px) scale(0.95); } 50% { transform: translate(20px, 10px) scale(1.05); } 75% { transform: translate(10px, -20px) scale(0.98); } } .onboarding-orb-1 { animation: float-orb-1 12s ease-in-out infinite; } .onboarding-orb-2 { animation: float-orb-2 15s ease-in-out infinite; } /* ─── Feature Card Reveal ─────────────────────────────── */ @keyframes feature-reveal { from { opacity: 0; transform: translateY(20px) scale(0.95); filter: blur(4px); } to { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); } } .feature-card-reveal { opacity: 0; animation: feature-reveal 0.5s var(--ease-out-expo) forwards; } .feature-card-reveal:nth-child(1) { animation-delay: 0.1s; } .feature-card-reveal:nth-child(2) { animation-delay: 0.2s; } .feature-card-reveal:nth-child(3) { animation-delay: 0.3s; } .feature-card-reveal:nth-child(4) { animation-delay: 0.4s; } /* ─── Icon Bounce In ──────────────────────────────────── */ @keyframes icon-bounce-in { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.2); } 70% { transform: scale(0.9); } 100% { transform: scale(1); opacity: 1; } } .icon-bounce { animation: icon-bounce-in 0.5s var(--spring) forwards; } /* ─── Confetti Particles ──────────────────────────────── */ @keyframes confetti-fall { 0% { transform: translateY(-100vh) rotate(0deg); opacity: 1; } 100% { transform: translateY(100vh) rotate(720deg); opacity: 0; } } @keyframes confetti-sway { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(15px); } 75% { transform: translateX(-15px); } } .confetti-piece { position: fixed; width: 10px; height: 10px; top: -10px; z-index: 10000; animation: confetti-fall var(--fall-duration, 3s) var(--fall-delay, 0s) ease-in forwards; } .confetti-piece::after { content: ""; display: block; width: 100%; height: 100%; background: var(--confetti-color, var(--color-primary)); border-radius: var(--confetti-shape, 2px); animation: confetti-sway 1.5s ease-in-out infinite; } /* ─── Celebration Text ────────────────────────────────── */ @keyframes celebration-pop { 0% { transform: scale(0) rotate(-10deg); opacity: 0; } 50% { transform: scale(1.15) rotate(3deg); } 70% { transform: scale(0.95) rotate(-1deg); } 100% { transform: scale(1) rotate(0deg); opacity: 1; } } .celebration-text { animation: celebration-pop 0.7s var(--spring) forwards; } /* ─── Checkmark Drawing ───────────────────────────────── */ @keyframes draw-check { 0% { stroke-dashoffset: 50; } 100% { stroke-dashoffset: 0; } } .draw-checkmark { stroke-dasharray: 50; stroke-dashoffset: 50; animation: draw-check 0.6s ease forwards 0.3s; } /* ─── Pulse Ring (for success states) ─────────────────── */ @keyframes pulse-ring { 0% { transform: scale(0.8); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } .pulse-ring { animation: pulse-ring 1s ease-out forwards; } /* ─── Input Focus Glow ────────────────────────────────── */ @keyframes input-glow-pulse { 0%, 100% { box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 20%, transparent); } 50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-primary) 15%, transparent); } } .input-onboarding:focus { animation: input-glow-pulse 2s ease-in-out infinite; border-color: var(--color-primary); } /* ─── Category Card Selection ─────────────────────────── */ @keyframes category-select { 0% { transform: scale(1); } 30% { transform: scale(0.95); } 60% { transform: scale(1.02); } 100% { transform: scale(1); } } .category-selected { animation: category-select 0.35s var(--spring); } /* ─── Platform Card Hover ─────────────────────────────── */ .platform-card { transition: all 0.25s var(--spring); cursor: pointer; } .platform-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); } .platform-card[data-selected="true"] { border-color: var(--color-primary) !important; box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 20%, transparent), var(--shadow-md); transform: translateY(-2px); } /* ─── Typing Effect ───────────────────────────────────── */ @keyframes blink-caret { from, to { border-color: transparent; } 50% { border-color: var(--color-primary); } } .typing-caret { border-right: 2px solid var(--color-primary); animation: blink-caret 0.8s step-end infinite; } /* ─── Success Particles ───────────────────────────────── */ @keyframes particle-burst { 0% { transform: scale(0); opacity: 1; } 50% { opacity: 1; } 100% { transform: scale(3); opacity: 0; } } .particle-burst { animation: particle-burst 0.8s ease-out forwards; } /* ─── Onboarding Background Grid ──────────────────────── */ .onboarding-bg { background-image: radial-gradient( circle at 20% 10%, color-mix(in srgb, var(--color-primary) 8%, transparent) 0%, transparent 34% ), radial-gradient( circle at 80% 0%, color-mix(in srgb, var(--color-primary) 6%, transparent) 0%, transparent 40% ), radial-gradient( circle at 50% 80%, color-mix(in srgb, var(--color-primary) 5%, transparent) 0%, transparent 30% ), linear-gradient(180deg, var(--bg-primary) 0%, var(--bg-secondary) 100%); } /* ─── Shimmer Button ──────────────────────────────────── */ @keyframes shimmer-btn { 0% { background-position: -200% center; } 100% { background-position: 200% center; } } .btn-shimmer { background-size: 200% auto; background-image: linear-gradient( 90deg, var(--color-primary) 0%, var(--color-primary-light) 50%, var(--color-primary) 100% ); } .btn-shimmer:hover { animation: shimmer-btn 2s linear infinite; } /* ─── EasyUI Inspired Error & Feedback Micro-Animations ──────────────── */ @keyframes easyui-shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-4px); } 40%, 80% { transform: translateX(4px); } } @keyframes easyui-glyph-bounce { 0%, 100% { transform: translateY(0px) rotate(0deg); } 50% { transform: translateY(-8px) rotate(-1.5deg); } } @keyframes easyui-pulse-danger { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-error) 40%, transparent); } 50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--color-error) 0%, transparent); } }
/* ─── MicProtocol Design System β€” Studio Desk ─────────── */
/* Entry stylesheet. Design tokens live in ./tokens.css; Tailwind v4
utilities are bridged onto the same custom properties below via
@theme inline, so legacy CSS and EasyUI/Tailwind components stay
in sync from one source of truth. */
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@100..900&family=DM+Sans:opsz,wght@9..40,100..900&display=swap");
@import "./tokens.css";
@import "./textures.css";
@import "./marketing.css";
/* Tailwind v4 β€” theme + utilities only (no preflight: the legacy
reset below still owns the base layer during migration). */
@layer theme, base, components, utilities;
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/utilities.css" layer(utilities);
/* Scan shared UI package sources (outside apps/web cwd). */
@source "../../../packages/ui/src";
/* dark: variant follows the app's data-theme attribute */
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
/* ─── Tailwind ↔ Token Bridge ─────────────────────────
Utility names map onto the CSS custom properties in
tokens.css so classes like bg-canvas / text-ink-2 resolve
through the same vars the legacy CSS consumes β€” theme
switching stays reactive for both systems. Names are
deliberately distinct from the underlying var names to
avoid circular var() references. */
@theme inline {
/* Brand */
--color-brand: var(--color-primary);
--color-brand-light: var(--color-primary-light);
--color-brand-dark: var(--color-primary-dark);
--color-brand-glow: var(--color-primary-glow);
--color-accent: var(--color-accent);
--color-mint: var(--color-accent);
/* Semantic */
--color-positive: var(--color-success);
--color-caution: var(--color-warning);
--color-negative: var(--color-error);
--color-note: var(--color-info);
/* Guest pipeline status */
--color-prospect: var(--status-prospect);
--color-contacted: var(--status-contacted);
--color-scheduled: var(--status-scheduled);
--color-recorded: var(--status-recorded);
--color-published: var(--status-published);
/* Surfaces */
--color-canvas: var(--bg-primary);
--color-surface: var(--bg-secondary);
--color-surface-raised: var(--bg-tertiary);
--color-elevated: var(--bg-elevated);
--color-line: var(--border-color);
--color-line-subtle: var(--border-color-subtle);
/* Ink */
--color-ink: var(--text-primary);
--color-ink-2: var(--text-secondary);
--color-ink-3: var(--text-tertiary);
--color-ink-inverse: var(--text-inverse);
/* Warm stone */
--color-stone: var(--stone);
--color-stone-light: var(--stone-light);
--color-stone-dark: var(--stone-dark);
/* Fonts (distinct names to avoid circular var() refs) */
--font-brand: var(--font-sans);
--font-brand-display: var(--font-display);
--font-code: var(--font-mono);
/* Radius β€” sharp "edge" geometry alongside Tailwind defaults */
--radius-edge-sm: var(--radius-sm);
--radius-edge: var(--radius-md);
--radius-edge-lg: var(--radius-lg);
--radius-edge-xl: var(--radius-xl);
/* Shadows β€” elevation scale + signal glow */
--shadow-e1: var(--shadow-sm);
--shadow-e2: var(--shadow-md);
--shadow-e3: var(--shadow-lg);
--shadow-e4: var(--shadow-xl);
--shadow-signal: var(--shadow-glow);
--shadow-signal-strong: var(--shadow-glow-strong);
}
/* ─── Reset & Base ──────────────────────────────────── */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {