/* ═══════════════════════════════════════════════════════════════════════════ MATERIAL 3 EXPRESSIVE — REDESIGN v2 (Compatibility Enhanced) ═══════════════════════════════════════════════════════════════════════════ */ :root { /* ══════════ Shape System (Expanded) ══════════ */ --shape-corner-none: 0px; --shape-corner-xs: 4px; --shape-corner-sm: 8px; --shape-corner-md: 12px; --shape-corner-lg: 16px; --shape-corner-xl: 28px; --shape-corner-2xl: 32px; --shape-corner-3xl: 48px; --shape-corner-full: 9999px; /* ══════════ Motion System (Springs) ══════════ */ --motion-spring-fast: linear(0, 0.53 14.8%, 0.82 27%, 0.94 38.6%, 0.985 49.3%, 1.001 59.8%, 1); --motion-spring-normal: linear(0, 0.45 13%, 0.76 27%, 0.92 41%, 0.98 56%, 1); --motion-spring-slow: linear(0, 0.3 12%, 0.6 28%, 0.85 46%, 0.96 64%, 1); --transition-standard: all 300ms var(--motion-spring-normal); /* ══════════ Typography (Outfit) ══════════ */ --font-brand: 'Outfit', sans-serif; --font-plain: 'Outfit', system-ui, sans-serif; --type-display-large: 700 57px/64px var(--font-brand); --type-display-medium: 700 45px/52px var(--font-brand); --type-headline-large: 600 32px/40px var(--font-brand); --type-headline-medium: 600 28px/36px var(--font-brand); --type-title-large: 500 22px/28px var(--font-brand); --type-title-medium: 500 16px/24px var(--font-brand); --type-body-large: 400 16px/24px var(--font-plain); --type-body-medium: 400 14px/20px var(--font-plain); --type-label-large: 600 14px/20px var(--font-plain); /* ══════════ Layout ══════════ */ --layout-rail-width: 80px; } /* ══════════ Reset & Base ══════════ */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; } body { background-color: var(--md-sys-color-background); color: var(--md-sys-color-on-background); font-family: var(--font-plain); font-size: 16px; line-height: 1.5; min-height: 100vh; display: flex; overflow-x: hidden; transition: background-color 0.4s var(--motion-spring-normal); } /* ══════════ Backgrounds ══════════ */ #stars-container { position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0.4; } .glow-overlay { position: fixed; inset: 0; z-index: -1; pointer-events: none; background: radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--md-sys-color-primary) 15%, transparent), transparent 70%); } /* ══════════ App Structure ══════════ */ .app-shell { display: flex; width: 100%; max-width: 100vw; height: 100vh; overflow: hidden; } .nav-rail { width: var(--layout-rail-width); height: 100%; display: flex; flex-direction: column; align-items: center; padding: 32px 0; background: var(--md-sys-color-surface); border-right: 1px solid var(--md-sys-color-outline-variant); z-index: 20; flex-shrink: 0; } .nav-rail .logo-area { margin-bottom: 40px; color: var(--md-sys-color-primary); transition: transform 0.3s var(--motion-spring-normal); } .nav-rail .logo-area:hover { transform: scale(1.1) rotate(5deg); } .nav-rail .nav-destinations { display: flex; flex-direction: column; gap: 12px; width: 100%; align-items: center; } .rail-item { width: 56px; height: 56px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; border-radius: 16px; color: var(--md-sys-color-on-surface-variant); cursor: pointer; transition: var(--transition-standard); position: relative; border: none; background: transparent; } .rail-item::before { content: ''; position: absolute; inset: 0; background: var(--md-sys-color-secondary-container); border-radius: 16px; transform: scaleY(0); opacity: 0; transition: var(--transition-standard); z-index: -1; } .rail-item.active { color: var(--md-sys-color-on-secondary-container); } .rail-item.active::before { transform: scaleY(1); opacity: 1; } .rail-item:hover:not(.active) { background: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent); } .rail-item i { width: 24px; height: 24px; } .rail-item span { font-size: 10px; font-weight: 600; letter-spacing: 0.5px; } .rail-fab { margin-top: auto; width: 56px; height: 56px; border-radius: 16px; background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); border: none; transition: var(--transition-standard); } .rail-fab:hover { transform: rotate(90deg) scale(1.05); } /* Main Pane */ .main-pane { flex: 1; height: 100%; overflow-y: auto; background: var(--md-sys-color-surface-container); border-top-left-radius: var(--shape-corner-2xl); border-bottom-left-radius: var(--shape-corner-2xl); margin: 0; position: relative; display: flex; flex-direction: column; padding-bottom: 20px; } /* Mobile Header/Nav */ .mobile-header, .bottom-bar { display: none; } @media (max-width: 800px) { .nav-rail { display: none; } .main-pane { border-radius: 0; background: var(--md-sys-color-background); } .mobile-header { display: flex; height: 64px; min-height: 64px; max-height: 64px; align-items: center; justify-content: space-between; padding: 0 20px; position: sticky; top: 0; z-index: 50; background: color-mix(in srgb, var(--md-sys-color-background) 80%, transparent); backdrop-filter: blur(16px); border-bottom: 1px solid color-mix(in srgb, var(--md-sys-color-outline-variant) 50%, transparent); flex-shrink: 0; } .mobile-header #header-title { font-size: 18px; font-weight: 600; line-height: 1.2; white-space: nowrap; } .bottom-bar { display: flex; height: 80px; position: fixed; bottom: 0; left: 0; right: 0; background: var(--md-sys-color-surface-container-high); z-index: 50; justify-content: space-around; align-items: center; padding-bottom: 12px; border-top-left-radius: var(--shape-corner-xl); border-top-right-radius: var(--shape-corner-xl); box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.05); } .bar-item { flex: 1; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; color: var(--md-sys-color-on-surface-variant); background: none; border: none; transition: color 0.2s; cursor: pointer; } .bar-pill { padding: 4px 20px; border-radius: 16px; transition: var(--transition-standard); } .bar-item.active .bar-pill { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); } } /* ══════════ Content Layout ══════════ */ .view-content { padding: 24px 20px; width: 100%; max-width: 800px; margin: 0 auto; animation: slideUp 0.5s var(--motion-spring-normal); } @keyframes slideUp { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: translateY(0); } } .page-header-large { margin-bottom: 28px; padding-top: 16px; padding-bottom: 8px; min-height: 80px; } .page-header-large h1 { font: var(--type-headline-large); color: var(--md-sys-color-on-surface); margin: 0 0 8px 0; font-size: 32px; font-weight: 700; line-height: 1.2; } .subtitle { font: var(--type-body-medium); color: var(--md-sys-color-outline); margin: 0; font-size: 15px; } /* ══════════ COMPATIBILITY LAYER (app.js Support) ══════════ */ /* --- 1. Generic Utils --- */ .loading-spinner { border: 4px solid var(--md-sys-color-surface-container-highest); border-top: 4px solid var(--md-sys-color-primary); border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 40px auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* --- 2. Cards & Plans --- */ /* app.js: class="glass plan-card plan-item" */ .plan-card, .m3-card, .card { background: var(--md-sys-color-surface-container-high); border-radius: var(--shape-corner-xl); padding: 24px; margin-bottom: 16px; position: relative; overflow: hidden; transition: var(--transition-standard); border: 1px solid transparent; } .plan-card:hover { /* Hover unavailable on mobile touch */ transform: translateY(-2px); box-shadow: 0 8px 24px -6px rgba(0, 0, 0, 0.15); background: var(--md-sys-color-surface-container-highest); } .plan-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; min-height: 32px; } .plan-title { font: var(--type-headline-small); color: var(--md-sys-color-on-surface); } .plan-price { font: var(--type-title-large); color: var(--md-sys-color-primary); font-weight: 700; } .plan-specs { display: flex; gap: 12px; margin-bottom: 24px; flex-wrap: wrap; } .plan-specs span { display: flex; align-items: center; gap: 8px; padding: 10px 16px; background: var(--md-sys-color-surface-container); border-radius: 12px; font: var(--type-label-large); color: var(--md-sys-color-on-surface-variant); min-height: 44px; } .plan-specs span i, .plan-specs span svg { width: 18px; height: 18px; flex-shrink: 0; color: var(--md-sys-color-primary); } /* Plan card buttons */ .plan-card .btn-primary { height: 52px; font-size: 15px; font-weight: 600; margin-top: 8px; } /* --- 3. Lists (Admin, Download, Profile) --- */ /* app.js: class="list-item glass" */ .list-item, .shop-item { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; background: var(--md-sys-color-surface-container-low); border-radius: var(--shape-corner-lg); margin-bottom: 8px; color: var(--md-sys-color-on-surface); cursor: pointer; transition: background 0.2s; user-select: none; } .list-item:active { background: var(--md-sys-color-surface-container-highest); } /* Prevent text overflow in lists */ .list-item>div { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } /* Admin Specific */ .admin-list { display: flex; flex-direction: column; gap: 4px; } .search-box { display: flex; gap: 12px; margin-bottom: 16px; align-items: center; } .search-box .glass-input { flex: 1; height: 48px; border-radius: 24px; border: none; border-bottom: none; padding: 0 20px; } .search-box .btn-primary { height: 48px; width: auto; min-width: 100px; padding: 0 24px; border-radius: 24px; flex-shrink: 0; } /* --- 4. Inputs --- */ /* app.js: class="glass-input" */ .glass-input, textarea.glass-input { width: 100%; background: var(--md-sys-color-surface-container-highest); border: none; border-bottom: 2px solid var(--md-sys-color-outline); border-radius: 4px 4px 0 0; padding: 16px; font: var(--type-body-large); color: var(--md-sys-color-on-surface); transition: all 0.2s; outline: none; } .glass-input:focus { background: var(--md-sys-color-surface-container-high); border-bottom-color: var(--md-sys-color-primary); } textarea.glass-input { border-radius: 12px; border: 1px solid var(--md-sys-color-outline-variant); } textarea.glass-input:focus { border-color: var(--md-sys-color-primary); } /* --- 5. Buttons --- */ /* app.js: class="btn-primary", "btn-secondary" */ button { font-family: inherit; } .btn-primary, .btn-secondary, .btn-error { width: 100%; height: 48px; display: flex; align-items: center; justify-content: center; gap: 8px; border-radius: 24px; /* Full pill */ font: var(--type-label-large); letter-spacing: 0.5px; cursor: pointer; transition: all 0.2s var(--motion-spring-fast); position: relative; overflow: hidden; } .btn-primary { background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); border: none; } .btn-primary:active { transform: scale(0.98); box-shadow: 0 0 0 4px color-mix(in srgb, var(--md-sys-color-primary) 30%, transparent); } .btn-primary:disabled { opacity: 0.5; background: var(--md-sys-color-on-surface); cursor: not-allowed; } .btn-secondary { background: transparent; color: var(--md-sys-color-primary); border: 1px solid var(--md-sys-color-outline); } .btn-secondary:active { background: color-mix(in srgb, var(--md-sys-color-primary) 10%, transparent); } .btn-error { background: var(--md-sys-color-error-container); color: var(--md-sys-color-on-error-container); border: none; } /* --- 6. Stats & Rings (Dashboard) --- */ .status-overview { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 16px; margin-bottom: 24px; } .ring-card { display: flex; flex-direction: row; /* Force row */ align-items: center; justify-content: flex-start; gap: 24px; } .ring-container { width: 80px; height: 80px; position: relative; flex-shrink: 0; } .circular-chart { width: 100%; height: 100%; } .circle-bg { stroke: var(--md-sys-color-surface-container-highest); stroke-width: 6; fill: none; } .circle { stroke: var(--md-sys-color-primary); stroke-width: 6; stroke-linecap: round; fill: none; transition: stroke-dasharray 1s var(--motion-spring-slow); } /* Actions Grid (Dashboard) */ .actions-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 20px; } .action-btn-large { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; background: var(--md-sys-color-surface-container); color: var(--md-sys-color-on-surface); border: 1px solid transparent; border-radius: 20px; padding: 20px; cursor: pointer; } .action-btn-large:active { background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); } .action-btn-large i { width: 28px; height: 28px; } /* --- 7. Modals & Confirms --- */ .modal-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(8px); z-index: 200; display: flex; align-items: center; /* Center vertically */ justify-content: center; padding: 20px; animation: fadeOverlay 0.3s; } .modal-overlay.hidden { display: none; } @keyframes fadeOverlay { from { opacity: 0; } to { opacity: 1; } } .modal-dialog, .modal { /* .modal for legacy */ background: var(--md-sys-color-surface-container-high); border-radius: 28px; padding: 24px; width: 100%; max-width: 400px; box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.3); animation: zoomModal 0.4s var(--motion-spring-fast); } @keyframes zoomModal { from { transform: scale(0.8) translateY(20px); opacity: 0; } to { transform: scale(1) translateY(0); opacity: 1; } } .btn-tonal { /* Admin tabs */ background: var(--md-sys-color-secondary-container); color: var(--md-sys-color-on-secondary-container); padding: 8px 16px; border-radius: 12px; border: none; font-weight: 600; opacity: 0.6; cursor: pointer; } .btn-tonal.active { opacity: 1; background: var(--md-sys-color-primary); color: var(--md-sys-color-on-primary); } /* Subscription Buttons (Legacy) */ .sub-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 24px; } /* Toast */ .toast { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: var(--md-sys-color-inverse-surface); color: var(--md-sys-color-inverse-on-surface); padding: 14px 24px; border-radius: 12px; display: flex; align-items: center; gap: 12px; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); z-index: 300; min-width: 300px; animation: toastUp 0.4s var(--motion-spring-normal); } .toast i { width: 20px; height: 20px; } .toast.success i { color: #4ade80; } .toast.error i { color: #f87171; } @keyframes toastUp { from { opacity: 0; transform: translate(-50%, 20px); } to { opacity: 1; transform: translate(-50%, 0); } } /* ══════════ Utility Classes ══════════ */ .hidden { display: none !important; } /* ══════════ Accordion ══════════ */ .accordion { padding: 0; } .acc-item { border-bottom: 1px solid var(--md-sys-color-outline-variant); } .acc-item:last-child { border-bottom: none; } .acc-head { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; cursor: pointer; font: var(--type-label-large); color: var(--md-sys-color-on-surface); transition: background 0.2s; } .acc-head:hover { background: color-mix(in srgb, var(--md-sys-color-on-surface) 5%, transparent); } .acc-head i { width: 20px; height: 20px; transition: transform 0.3s var(--motion-spring-normal); } .acc-item.open .acc-head i { transform: rotate(180deg); } .acc-body { max-height: 0; overflow: hidden; transition: max-height 0.3s var(--motion-spring-normal), padding 0.3s; padding: 0 20px; } .acc-item.open .acc-body { max-height: 200px; padding: 0 20px 16px; } .acc-body p { font: var(--type-body-medium); color: var(--md-sys-color-outline); margin-bottom: 8px; } .acc-body p:last-child { margin-bottom: 0; } /* ══════════ Plan Item Badge ══════════ */ .plan-badge { position: absolute; top: -8px; right: 16px; background: var(--md-sys-color-tertiary); color: var(--md-sys-color-on-tertiary); padding: 4px 12px; border-radius: 12px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; } /* ══════════ Headline Type Fix ══════════ */ .page-header-large h1 { font: var(--type-headline-large); } /* ══════════ Type Additions (Missing) ══════════ */ :root { --type-display-small: 600 36px/44px var(--font-brand); --type-headline-small: 500 24px/32px var(--font-brand); } /* ══════════ Avatar Styles ══════════ */ .avatar-xs { width: 40px; height: 40px; min-width: 40px; min-height: 40px; max-width: 40px; max-height: 40px; flex-shrink: 0; border-radius: 50%; overflow: hidden; background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 16px; } .avatar-xs img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; } /* User chip avatar */ .user-chip .avatar-xs { width: 32px; height: 32px; min-width: 32px; min-height: 32px; max-width: 32px; max-height: 32px; font-size: 14px; } /* Profile page big avatar */ #profile-avatar { width: 80px !important; height: 80px !important; min-width: 80px !important; min-height: 80px !important; max-width: 80px !important; max-height: 80px !important; font-size: 32px !important; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } /* Admin user detail avatar */ #adm-user-avatar { width: 48px !important; height: 48px !important; min-width: 48px !important; min-height: 48px !important; max-width: 48px !important; max-height: 48px !important; font-size: 20px !important; } .big-avatar { width: 88px; height: 88px; min-width: 88px; min-height: 88px; flex-shrink: 0; border-radius: 50%; background: var(--md-sys-color-primary-container); color: var(--md-sys-color-on-primary-container); display: flex; align-items: center; justify-content: center; font-size: 36px; font-weight: 700; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .big-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; } /* ══════════════════════════════════════════════════════════════════════════ ENHANCED ANIMATIONS ══════════════════════════════════════════════════════════════════════════ */ /* --- Button Press Effects --- */ .btn-primary:active, .btn-secondary:active, .btn-error:active { transform: scale(0.95); transition: transform 100ms ease; } .btn-primary:hover, .btn-secondary:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); } /* --- Card Hover Effects --- */ .plan-card, .m3-card { transition: transform 0.3s var(--motion-spring-normal), box-shadow 0.3s var(--motion-spring-normal), background 0.2s ease; } .plan-card:hover, .m3-card:hover { transform: translateY(-4px); box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.2); } .plan-card:active, .m3-card:active { transform: translateY(-1px) scale(0.99); } /* --- Navigation Item Animations --- */ .bar-item { transition: transform 0.2s var(--motion-spring-fast), color 0.2s ease; } .bar-item:active { transform: scale(0.9); } .bar-pill { transition: transform 0.3s var(--motion-spring-normal), background 0.2s ease; } .bar-item:active .bar-pill { transform: scale(0.85); } .rail-item { transition: transform 0.2s var(--motion-spring-fast), background 0.2s ease, color 0.2s ease; } .rail-item:hover { transform: scale(1.05); } .rail-item:active { transform: scale(0.95); } /* --- List Item Animations --- */ .list-item { transition: transform 0.2s var(--motion-spring-fast), background 0.2s ease, box-shadow 0.2s ease; } .list-item:hover { transform: translateX(4px); background: var(--md-sys-color-surface-container); } .list-item:active { transform: translateX(2px) scale(0.98); } /* --- Action Button Large Animations --- */ .action-btn-large { transition: transform 0.3s var(--motion-spring-normal), background 0.2s ease, box-shadow 0.3s ease; } .action-btn-large:hover { transform: translateY(-6px); box-shadow: 0 12px 24px -8px rgba(0, 0, 0, 0.2); } .action-btn-large:active { transform: translateY(-2px) scale(0.97); } .action-btn-large i { transition: transform 0.3s var(--motion-spring-fast); } .action-btn-large:hover i { transform: scale(1.2); } /* --- Modal Animations --- */ .modal-overlay { animation: fadeIn 0.25s ease-out forwards; transition: opacity 0.25s ease; } .modal-overlay.closing { animation: fadeOut 0.25s ease-out forwards; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } } .modal-dialog { animation: slideInUp 0.35s var(--motion-spring-normal) forwards; } .modal-dialog.closing { animation: slideOutDown 0.25s ease-out forwards; } @keyframes slideInUp { from { opacity: 0; transform: translateY(40px) scale(0.9); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes slideOutDown { from { opacity: 1; transform: translateY(0) scale(1); } to { opacity: 0; transform: translateY(30px) scale(0.95); } } /* --- Tab Transition Animations --- */ .tab-exit { animation: tabFadeOut 0.15s ease-out forwards; } .tab-enter { animation: tabFadeIn 0.35s var(--motion-spring-normal) forwards; } @keyframes tabFadeOut { from { opacity: 1; transform: translateX(0); } to { opacity: 0; transform: translateX(-20px); } } @keyframes tabFadeIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } } /* --- Admin Content Smooth --- */ #admin-content { transition: opacity 0.2s ease; } /* --- Ring Pulse Animation --- */ .ring-container { animation: pulse 3s ease-in-out infinite; } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.02); } } /* --- Avatar Hover --- */ .avatar-xs, #profile-avatar { transition: transform 0.3s var(--motion-spring-fast), box-shadow 0.3s ease; } .user-chip:hover .avatar-xs, #profile-avatar:hover { transform: scale(1.1); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); } /* --- Status Badge Pulse --- */ .status-badge { animation: badgePulse 2s ease-in-out infinite; } @keyframes badgePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } } /* --- Toast Slide In --- */ .toast { animation: toastSlide 0.4s var(--motion-spring-normal); } @keyframes toastSlide { from { opacity: 0; transform: translateX(-50%) translateY(20px) scale(0.9); } to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } } .toast-exit { animation: toastExit 0.4s var(--motion-spring-normal) forwards; } @keyframes toastExit { from { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } to { opacity: 0; transform: translateX(-50%) translateY(20px) scale(0.9); } } /* --- Icon Bounce on Hover --- */ .rail-fab:hover i, .action-btn-large:hover i { animation: iconBounce 0.5s var(--motion-spring-fast); } @keyframes iconBounce { 0% { transform: scale(1); } 30% { transform: scale(1.3); } 50% { transform: scale(0.9); } 70% { transform: scale(1.1); } 100% { transform: scale(1); } } /* --- Page Transition --- */ .view-content { animation: pageEnter 0.45s var(--motion-spring-normal); } @keyframes pageEnter { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } } .page-exit { animation: pageExit 0.2s ease-in forwards; } @keyframes pageExit { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-20px); } } /* --- Stagger Animation for Plan Cards --- */ .plan-card { animation: cardFadeIn 0.4s var(--motion-spring-normal) backwards; } .plan-card:nth-child(1) { animation-delay: 0.05s; } .plan-card:nth-child(2) { animation-delay: 0.1s; } .plan-card:nth-child(3) { animation-delay: 0.15s; } .plan-card:nth-child(4) { animation-delay: 0.2s; } .plan-card:nth-child(5) { animation-delay: 0.25s; } @keyframes cardFadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } /* --- Loading Spinner Smooth --- */ .loading-spinner { animation: spin 0.8s linear infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* --- Accordion Smooth Open --- */ .acc-body { transition: max-height 0.35s var(--motion-spring-normal), padding 0.35s var(--motion-spring-normal), opacity 0.25s ease; opacity: 0; } .acc-item.open .acc-body { opacity: 1; } .acc-head i { transition: transform 0.35s var(--motion-spring-normal); } /* --- QR Code Container Glow --- */ #qrcode-container { transition: box-shadow 0.3s ease, transform 0.3s var(--motion-spring-normal); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); } #qrcode-container:hover { transform: scale(1.02); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); }