@import "tailwindcss"; @import "tw-animate-css"; @custom-variant dark (&:is(.dark *)); @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); --font-sans: Arial, Helvetica, sans-serif; --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace; --color-sidebar-ring: var(--sidebar-ring); --color-sidebar-border: var(--sidebar-border); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar: var(--sidebar); --color-chart-5: var(--chart-5); --color-chart-4: var(--chart-4); --color-chart-3: var(--chart-3); --color-chart-2: var(--chart-2); --color-chart-1: var(--chart-1); --color-ring: var(--ring); --color-input: var(--input); --color-border: var(--border); --color-destructive: var(--destructive); --color-accent-foreground: var(--accent-foreground); --color-accent: var(--accent); --color-muted-foreground: var(--muted-foreground); --color-muted: var(--muted); --color-secondary-foreground: var(--secondary-foreground); --color-secondary: var(--secondary); --color-primary-foreground: var(--primary-foreground); --color-primary: var(--primary); --color-popover-foreground: var(--popover-foreground); --color-popover: var(--popover); --color-card-foreground: var(--card-foreground); --color-card: var(--card); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); --color-emerald: #10b981; --color-teal: #14b8a6; --color-amber: #f59e0b; } :root { --radius: 0.75rem; /* Brand CSS custom properties — applied dynamically via JS */ --brand-primary: #10b981; --brand-secondary: #14b8a6; --brand-accent: #059669; --brand-font: "Inter", sans-serif; --background: oklch(0.99 0.002 155); --foreground: oklch(0.17 0.01 260); --card: oklch(1 0 0); --card-foreground: oklch(0.17 0.01 260); --popover: oklch(1 0 0); --popover-foreground: oklch(0.17 0.01 260); --primary: oklch(0.55 0.17 155); --primary-foreground: oklch(0.98 0.005 155); --secondary: oklch(0.96 0.01 155); --secondary-foreground: oklch(0.25 0.02 260); --muted: oklch(0.96 0.005 155); --muted-foreground: oklch(0.55 0.02 260); --accent: oklch(0.96 0.01 155); --accent-foreground: oklch(0.25 0.02 260); --destructive: oklch(0.577 0.245 27.325); --border: oklch(0.93 0.005 155); --input: oklch(0.93 0.005 155); --ring: oklch(0.55 0.17 155); --chart-1: oklch(0.55 0.17 155); --chart-2: oklch(0.53 0.14 175); --chart-3: oklch(0.72 0.19 85); --chart-4: oklch(0.60 0.18 50); --chart-5: oklch(0.65 0.22 330); --sidebar: oklch(0.97 0.01 155); --sidebar-foreground: oklch(0.17 0.01 260); --sidebar-primary: oklch(0.55 0.17 155); --sidebar-primary-foreground: oklch(0.98 0.005 155); --sidebar-accent: oklch(0.94 0.02 155); --sidebar-accent-foreground: oklch(0.25 0.02 260); --sidebar-border: oklch(0.93 0.005 155); --sidebar-ring: oklch(0.55 0.17 155); } .dark { --background: oklch(0.13 0.01 260); --foreground: oklch(0.98 0.005 155); --card: oklch(0.18 0.015 260); --card-foreground: oklch(0.98 0.005 155); --popover: oklch(0.18 0.015 260); --popover-foreground: oklch(0.98 0.005 155); --primary: oklch(0.65 0.17 155); --primary-foreground: oklch(0.15 0.01 260); --secondary: oklch(0.24 0.02 260); --secondary-foreground: oklch(0.98 0.005 155); --muted: oklch(0.24 0.02 260); --muted-foreground: oklch(0.65 0.02 260); --accent: oklch(0.24 0.02 260); --accent-foreground: oklch(0.98 0.005 155); --destructive: oklch(0.704 0.191 22.216); --border: oklch(1 0 0 / 10%); --input: oklch(1 0 0 / 15%); --ring: oklch(0.65 0.17 155); --chart-1: oklch(0.65 0.17 155); --chart-2: oklch(0.63 0.14 175); --chart-3: oklch(0.77 0.19 85); --chart-4: oklch(0.72 0.22 50); --chart-5: oklch(0.70 0.22 330); --sidebar: oklch(0.18 0.015 260); --sidebar-foreground: oklch(0.98 0.005 155); --sidebar-primary: oklch(0.65 0.17 155); --sidebar-primary-foreground: oklch(0.15 0.01 260); --sidebar-accent: oklch(0.24 0.02 260); --sidebar-accent-foreground: oklch(0.98 0.005 155); --sidebar-border: oklch(1 0 0 / 10%); --sidebar-ring: oklch(0.65 0.17 155); } @layer base { * { @apply border-border outline-ring/50; } body { @apply bg-background text-foreground; } } /* Custom scrollbar styling */ @layer utilities { .scrollbar-education::-webkit-scrollbar { width: 6px; } .scrollbar-education::-webkit-scrollbar-track { background: transparent; } .scrollbar-education::-webkit-scrollbar-thumb { background: oklch(0.80 0.02 155); border-radius: 3px; } .scrollbar-education::-webkit-scrollbar-thumb:hover { background: oklch(0.65 0.17 155); } .dark .scrollbar-education::-webkit-scrollbar-thumb { background: oklch(0.35 0.02 260); } .dark .scrollbar-education::-webkit-scrollbar-thumb:hover { background: oklch(0.65 0.17 155); } /* Global scrollbar override */ *::-webkit-scrollbar { width: 8px; height: 8px; } *::-webkit-scrollbar-track { background: transparent; } *::-webkit-scrollbar-thumb { background: oklch(0.85 0.01 155); border-radius: 4px; border: 2px solid transparent; background-clip: padding-box; } *::-webkit-scrollbar-thumb:hover { background: oklch(0.65 0.17 155); border: 2px solid transparent; background-clip: padding-box; } .dark *::-webkit-scrollbar-thumb { background: oklch(0.30 0.015 260); border: 2px solid transparent; background-clip: padding-box; } .dark *::-webkit-scrollbar-thumb:hover { background: oklch(0.50 0.10 155); border: 2px solid transparent; background-clip: padding-box; } /* Dot grid background pattern */ .bg-dots { background-image: radial-gradient(circle, oklch(0.80 0.02 155) 1px, transparent 1px); background-size: 24px 24px; } .dark .bg-dots { background-image: radial-gradient(circle, oklch(0.25 0.015 260) 1px, transparent 1px); background-size: 24px 24px; } /* Announcement banner styling */ .announcement-banner { transition: all 0.3s ease; } .announcement-banner:hover { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } /* Homework card styling */ .homework-card { transition: all 0.2s ease; } .homework-card:hover { transform: translateY(-1px); } /* Priority color classes */ .priority-urgent { border-color: oklch(0.577 0.245 27.325); background-color: oklch(0.95 0.05 27); } .priority-high { border-color: oklch(0.72 0.19 85); background-color: oklch(0.95 0.05 85); } .priority-normal { border-color: oklch(0.55 0.17 155); background-color: oklch(0.95 0.05 155); } .priority-low { border-color: oklch(0.53 0.14 175); background-color: oklch(0.95 0.05 175); } .dark .priority-urgent { border-color: oklch(0.577 0.245 27.325); background-color: oklch(0.18 0.05 27); } .dark .priority-high { border-color: oklch(0.72 0.19 85); background-color: oklch(0.18 0.05 85); } .dark .priority-normal { border-color: oklch(0.55 0.17 155); background-color: oklch(0.18 0.05 155); } .dark .priority-low { border-color: oklch(0.53 0.14 175); background-color: oklch(0.18 0.05 175); } /* Due date color classes */ .due-overdue { border-color: oklch(0.577 0.245 27.325); } .due-today { border-color: oklch(0.72 0.19 85); } .due-upcoming { border-color: oklch(0.55 0.17 155); } .dark .due-overdue { border-color: oklch(0.577 0.245 27.325); } .dark .due-today { border-color: oklch(0.72 0.19 85); } .dark .due-upcoming { border-color: oklch(0.55 0.17 155); } /* Smooth transitions for all interactive elements */ .interactive-transition { transition: all 0.2s ease-out; } /* Animated gradient background */ .animated-gradient-bg { background: linear-gradient(135deg, oklch(0.97 0.01 155) 0%, oklch(0.99 0.002 155) 50%, oklch(0.97 0.01 175) 100%); background-size: 200% 200%; animation: gradient-shift 8s ease infinite; } .dark .animated-gradient-bg { background: linear-gradient(135deg, oklch(0.15 0.01 260) 0%, oklch(0.13 0.01 260) 50%, oklch(0.15 0.01 155) 100%); background-size: 200% 200%; animation: gradient-shift 8s ease infinite; } @keyframes gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } /* Pulse animation */ @keyframes pulse-soft { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.05); opacity: 0.85; } } .animate-pulse-soft { animation: pulse-soft 2s ease-in-out infinite; } /* Shimmer animation for progress bars */ @keyframes shimmer-bar { 0% { transform: translateX(-100%); } 100% { transform: translateX(200%); } } .animate-shimmer { animation: shimmer-bar 2.5s ease-in-out infinite; } /* Float animation for geometric shapes */ @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 33% { transform: translateY(-15px) rotate(5deg); } 66% { transform: translateY(10px) rotate(-3deg); } } @keyframes float-reverse { 0%, 100% { transform: translateY(0) rotate(0deg); } 33% { transform: translateY(12px) rotate(-4deg); } 66% { transform: translateY(-10px) rotate(6deg); } } @keyframes float-slow { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20px) rotate(8deg); } } .animate-float { animation: float 6s ease-in-out infinite; } .animate-float-reverse { animation: float-reverse 7s ease-in-out infinite; } .animate-float-slow { animation: float-slow 10s ease-in-out infinite; } /* Progress bar animation */ @keyframes progress-fill { from { width: 0; } } .animate-progress-fill { animation: progress-fill 1s ease-out; } /* Print styles — full print stylesheet lives at end of file */ /* ─── Slide animations ──────────────────────────────────────────── */ @keyframes slide-in { from { transform: translateX(30px); opacity: 0; } to { transform: translateX(0); opacity: 1; } } .animate-slide-in { animation: slide-in 0.3s ease-out; } @keyframes slide-out { from { transform: translateX(0); opacity: 1; } to { transform: translateX(-30px); opacity: 0; } } .animate-slide-out { animation: slide-out 0.3s ease-in; } /* ─── Pulse dot for version timeline ────────────────────────────── */ @keyframes pulse-dot { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.3); opacity: 0.7; } } .animate-pulse-dot { animation: pulse-dot 2s ease-in-out infinite; } /* ─── Canvas toolbar ────────────────────────────────────────────── */ .canvas-toolbar { transition: transform 0.2s ease-out, width 0.2s ease-out, height 0.2s ease-out; } /* ─── Version timeline ──────────────────────────────────────────── */ .version-timeline { position: relative; } .version-timeline > div { padding-bottom: 0.5rem; } } /* Focus ring for accessibility */ @layer base { *:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; border-radius: 4px; } *:focus:not(:focus-visible) { outline: none; } /* Make keyboard focus more visible on interactive controls */ button:focus-visible, a:focus-visible, [role="button"]:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; box-shadow: 0 0 0 4px oklch(0.55 0.17 155 / 0.18); transition: box-shadow 0.15s ease-out; } .dark button:focus-visible, .dark a:focus-visible, .dark [role="button"]:focus-visible, .dark input:focus-visible, .dark select:focus-visible, .dark textarea:focus-visible, .dark [tabindex]:focus-visible { outline: 2px solid oklch(0.65 0.17 155); box-shadow: 0 0 0 4px oklch(0.65 0.17 155 / 0.25); } html { scroll-behavior: smooth; } } /* ─── Styling polish utilities ─────────────────────────────────────────── */ @layer utilities { /* Subtle paper texture for main backgrounds */ .bg-paper { background-color: oklch(0.99 0.002 155); background-image: radial-gradient(circle at 20% 10%, oklch(0.96 0.015 155 / 0.6) 0%, transparent 40%), radial-gradient(circle at 80% 80%, oklch(0.96 0.012 175 / 0.5) 0%, transparent 45%), url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.1 0 0 0 0 0.45 0 0 0 0 0.3 0 0 0 0.025 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); } .dark .bg-paper { background-color: oklch(0.13 0.01 260); background-image: radial-gradient(circle at 20% 10%, oklch(0.18 0.02 155 / 0.35) 0%, transparent 40%), radial-gradient(circle at 80% 80%, oklch(0.18 0.02 175 / 0.3) 0%, transparent 45%), url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0.55 0 0 0 0 0.85 0 0 0 0 0.7 0 0 0 0.04 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); } /* Mesh gradient for hero / stats areas */ .bg-mesh { background-color: oklch(0.99 0.002 155); background-image: radial-gradient(at 12% 18%, oklch(0.94 0.04 155 / 0.55) 0px, transparent 50%), radial-gradient(at 88% 22%, oklch(0.94 0.05 175 / 0.45) 0px, transparent 50%), radial-gradient(at 22% 88%, oklch(0.95 0.05 85 / 0.4) 0px, transparent 50%), radial-gradient(at 78% 78%, oklch(0.95 0.05 330 / 0.3) 0px, transparent 50%); } .dark .bg-mesh { background-color: oklch(0.13 0.01 260); background-image: radial-gradient(at 12% 18%, oklch(0.20 0.06 155 / 0.35) 0px, transparent 50%), radial-gradient(at 88% 22%, oklch(0.20 0.06 175 / 0.3) 0px, transparent 50%), radial-gradient(at 22% 88%, oklch(0.20 0.07 85 / 0.25) 0px, transparent 50%), radial-gradient(at 78% 78%, oklch(0.20 0.08 330 / 0.2) 0px, transparent 50%); } /* Shimmer skeleton loader */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } .shimmer { background: linear-gradient( 90deg, oklch(0.92 0.005 155 / 0.4) 0%, oklch(0.88 0.01 155 / 0.7) 50%, oklch(0.92 0.005 155 / 0.4) 100% ); background-size: 200% 100%; animation: shimmer 1.6s linear infinite; } .dark .shimmer { background: linear-gradient( 90deg, oklch(0.22 0.015 260 / 0.5) 0%, oklch(0.28 0.02 260 / 0.8) 50%, oklch(0.22 0.015 260 / 0.5) 100% ); background-size: 200% 100%; animation: shimmer 1.6s linear infinite; } /* Subtle inner ring for premium cards */ .ring-inset-soft { box-shadow: inset 0 0 0 1px oklch(1 0 0 / 0.05), 0 1px 2px oklch(0 0 0 / 0.04); } .dark .ring-inset-soft { box-shadow: inset 0 0 0 1px oklch(1 0 0 / 0.04), 0 1px 2px oklch(0 0 0 / 0.2); } /* Document / paper preview look for reports */ .paper-preview { background: white; background-image: linear-gradient(oklch(0.96 0.005 155 / 0.6) 1px, transparent 1px); background-size: 100% 28px; box-shadow: 0 1px 0 oklch(0.85 0.005 155), 0 4px 12px oklch(0 0 0 / 0.08), 0 24px 60px oklch(0 0 0 / 0.06); } .dark .paper-preview { background: oklch(0.18 0.015 260); background-image: linear-gradient(oklch(0.22 0.015 260 / 0.6) 1px, transparent 1px); background-size: 100% 28px; box-shadow: 0 1px 0 oklch(0 0 0 / 0.4), 0 4px 12px oklch(0 0 0 / 0.4), 0 24px 60px oklch(0 0 0 / 0.3); } /* Sticky header helper for tables */ .sticky-header th { position: sticky; top: 0; z-index: 5; background: oklch(0.96 0.005 155); } .dark .sticky-header th { background: oklch(0.20 0.015 260); } /* Sparkline path */ .sparkline-path { stroke-linecap: round; stroke-linejoin: round; fill: none; } /* Lift on hover for cards */ .lift-on-hover { transition: transform 0.18s ease, box-shadow 0.18s ease; } .lift-on-hover:hover { transform: translateY(-2px); box-shadow: 0 12px 28px -10px oklch(0.55 0.17 155 / 0.18); } /* Gradient text for highlights */ .text-gradient-emerald { background: linear-gradient(90deg, oklch(0.55 0.17 155), oklch(0.55 0.14 175)); -webkit-background-clip: text; background-clip: text; color: transparent; } .text-gradient-amber { background: linear-gradient(90deg, oklch(0.72 0.19 85), oklch(0.60 0.18 50)); -webkit-background-clip: text; background-clip: text; color: transparent; } .text-gradient-violet { background: linear-gradient(90deg, oklch(0.60 0.20 320), oklch(0.65 0.22 280)); -webkit-background-clip: text; background-clip: text; color: transparent; } .text-gradient-rose { background: linear-gradient(90deg, oklch(0.65 0.22 15), oklch(0.62 0.20 350)); -webkit-background-clip: text; background-clip: text; color: transparent; } .text-gradient-teal { background: linear-gradient(90deg, oklch(0.55 0.14 175), oklch(0.60 0.16 195)); -webkit-background-clip: text; background-clip: text; color: transparent; } /* Generic gradient text — direction aware */ .gradient-text { background: linear-gradient(135deg, oklch(0.55 0.17 155) 0%, oklch(0.55 0.14 175) 50%, oklch(0.65 0.22 330) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; } .dark .gradient-text { background: linear-gradient(135deg, oklch(0.70 0.17 155) 0%, oklch(0.70 0.14 175) 50%, oklch(0.78 0.22 330) 100%); -webkit-background-clip: text; background-clip: text; color: transparent; } /* Frosted glass card — backdrop blur + translucent surface */ .glass-card { background: oklch(1 0 0 / 0.7); backdrop-filter: blur(12px) saturate(180%); -webkit-backdrop-filter: blur(12px) saturate(180%); border: 1px solid oklch(1 0 0 / 0.4); box-shadow: 0 4px 16px -4px oklch(0 0 0 / 0.08), inset 0 0 0 1px oklch(1 0 0 / 0.3); } .dark .glass-card { background: oklch(0.18 0.015 260 / 0.65); backdrop-filter: blur(12px) saturate(140%); -webkit-backdrop-filter: blur(12px) saturate(140%); border: 1px solid oklch(1 0 0 / 0.08); box-shadow: 0 4px 16px -4px oklch(0 0 0 / 0.4), inset 0 0 0 1px oklch(1 0 0 / 0.05); } .glass-card-strong { background: oklch(1 0 0 / 0.85); backdrop-filter: blur(20px) saturate(200%); -webkit-backdrop-filter: blur(20px) saturate(200%); border: 1px solid oklch(1 0 0 / 0.5); } .dark .glass-card-strong { background: oklch(0.18 0.015 260 / 0.8); backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%); border: 1px solid oklch(1 0 0 / 0.1); } /* Animated count-up number */ @keyframes count-up { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } } .animate-count-up { animation: count-up 0.5s ease-out; } /* Decorative dotted/grid background pattern for headers */ .bg-pattern-dots { background-image: radial-gradient(circle, oklch(0.55 0.17 155 / 0.18) 1px, transparent 1px); background-size: 16px 16px; } .dark .bg-pattern-dots { background-image: radial-gradient(circle, oklch(0.65 0.17 155 / 0.18) 1px, transparent 1px); background-size: 16px 16px; } .bg-pattern-grid { background-image: linear-gradient(oklch(0.55 0.17 155 / 0.06) 1px, transparent 1px), linear-gradient(90deg, oklch(0.55 0.17 155 / 0.06) 1px, transparent 1px); background-size: 24px 24px; } .dark .bg-pattern-grid { background-image: linear-gradient(oklch(0.65 0.17 155 / 0.08) 1px, transparent 1px), linear-gradient(90deg, oklch(0.65 0.17 155 / 0.08) 1px, transparent 1px); background-size: 24px 24px; } /* Soft glow utility for highlighted elements */ .glow-emerald { box-shadow: 0 0 0 1px oklch(0.55 0.17 155 / 0.15), 0 8px 24px -6px oklch(0.55 0.17 155 / 0.35); } .dark .glow-emerald { box-shadow: 0 0 0 1px oklch(0.65 0.17 155 / 0.25), 0 8px 24px -6px oklch(0.65 0.17 155 / 0.45); } /* Subtle top-border accent for chart cards */ .accent-top-emerald { border-top: 3px solid oklch(0.55 0.17 155); } .accent-top-teal { border-top: 3px solid oklch(0.55 0.14 175); } .accent-top-amber { border-top: 3px solid oklch(0.72 0.19 85); } .accent-top-violet { border-top: 3px solid oklch(0.60 0.20 320); } .accent-top-rose { border-top: 3px solid oklch(0.65 0.22 15); } /* Subtle entrance animation for staggered items */ @keyframes enter-fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } } .animate-enter-fade { animation: enter-fade 0.35s ease-out backwards; } /* ─── Styling polish additions ──────────────────────────────────── */ /* Smooth page transition animation (fadeIn for view changes) */ @keyframes view-fade-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } } .animate-view-fade-in { animation: view-fade-in 0.3s ease-out; } /* Hover lift effect for cards */ .card-hover-lift { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; } .card-hover-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 24px -6px oklch(0.55 0.17 155 / 0.15); } .dark .card-hover-lift:hover { box-shadow: 0 8px 24px -6px oklch(0.65 0.17 155 / 0.25); } /* Focus-within ring animation for inputs */ .input-focus-ring { transition: box-shadow 0.2s ease-out; } .input-focus-ring:focus-within { box-shadow: 0 0 0 3px oklch(0.55 0.17 155 / 0.2); } .dark .input-focus-ring:focus-within { box-shadow: 0 0 0 3px oklch(0.65 0.17 155 / 0.3); } /* Tooltip animation (scale from 0.95 to 1) */ @keyframes tooltip-enter { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } .animate-tooltip-enter { animation: tooltip-enter 0.15s ease-out; } /* ─── Smooth Dark Mode Scrollbar ───────────────────────────────────── */ .dark ::-webkit-scrollbar { width: 8px; height: 8px; } .dark ::-webkit-scrollbar-track { background: oklch(0.15 0.01 260); } .dark ::-webkit-scrollbar-thumb { background: oklch(0.35 0.015 260 / 0.6); border-radius: 4px; border: 2px solid transparent; background-clip: padding-box; } .dark ::-webkit-scrollbar-thumb:hover { background: oklch(0.50 0.10 155 / 0.7); border: 2px solid transparent; background-clip: padding-box; } /* Firefox scrollbar for dark mode */ .dark * { scrollbar-width: thin; scrollbar-color: oklch(0.35 0.015 260 / 0.6) oklch(0.15 0.01 260); } /* ─── Better Focus-Visible Styles ──────────────────────────────────── */ @media (prefers-reduced-motion: reduce) { *:focus-visible { transition: none; } } /* Enhanced focus ring for card-based interactive elements */ [role="button"]:focus-visible, button:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; box-shadow: 0 0 0 4px oklch(0.55 0.17 155 / 0.15); border-radius: 8px; transition: box-shadow 0.15s ease-out; } .dark [role="button"]:focus-visible, .dark button:focus-visible { outline: 2px solid oklch(0.65 0.17 155); box-shadow: 0 0 0 4px oklch(0.65 0.17 155 / 0.2); } /* ─── Subtle Card Hover Effects ────────────────────────────────────── */ .card-hover-glow { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; } .card-hover-glow:hover { transform: translateY(-2px); box-shadow: 0 8px 24px -6px oklch(0.55 0.17 155 / 0.12), 0 0 0 1px oklch(0.55 0.17 155 / 0.08); } .dark .card-hover-glow:hover { box-shadow: 0 8px 24px -6px oklch(0.65 0.17 155 / 0.2), 0 0 0 1px oklch(0.65 0.17 155 / 0.12); } /* ─── Staggered Entry Animation ────────────────────────────────────── */ @keyframes stagger-fade-in { from { opacity: 0; transform: translateY(8px) scale(0.98); } to { opacity: 1; transform: translateY(0) scale(1); } } .animate-stagger-in { animation: stagger-fade-in 0.35s ease-out backwards; } /* ─── Chart Shimmer on Load ────────────────────────────────────────── */ @keyframes chart-shimmer { 0% { opacity: 0.5; transform: translateX(-100%); } 50% { opacity: 0.3; } 100% { opacity: 0; transform: translateX(100%); } } .animate-chart-shimmer { animation: chart-shimmer 1.5s ease-out forwards; } /* ─── Button Press Effect ────────────────────────────────────────── */ .btn-press { transition: transform 0.1s ease-out, box-shadow 0.1s ease-out; } .btn-press:active { transform: scale(0.97); } .btn-press:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; box-shadow: 0 0 0 4px oklch(0.55 0.17 155 / 0.15); } .dark .btn-press:focus-visible { outline: 2px solid oklch(0.65 0.17 155); box-shadow: 0 0 0 4px oklch(0.65 0.17 155 / 0.2); } /* ─── Smooth Theme Switching ─────────────────────────────────────── */ html { transition: background-color 0.3s ease, color 0.3s ease; } html *, html *::before, html *::after { transition-property: background-color, border-color, color, fill, stroke, box-shadow; transition-duration: 0.2s; transition-timing-function: ease-out; } @media (prefers-reduced-motion: reduce) { html *, html *::before, html *::after { transition-duration: 0ms !important; } } /* ─── Skeleton Loading Shimmer ───────────────────────────────────── */ .skeleton-shimmer { position: relative; overflow: hidden; background: oklch(0.92 0.01 155 / 0.5); } .dark .skeleton-shimmer { background: oklch(0.25 0.01 260 / 0.5); } .skeleton-shimmer::after { content: ''; position: absolute; inset: 0; background: linear-gradient( 90deg, transparent 0%, oklch(0.97 0.01 155 / 0.4) 50%, transparent 100% ); animation: skeleton-slide 1.5s ease-in-out infinite; } .dark .skeleton-shimmer::after { background: linear-gradient( 90deg, transparent 0%, oklch(0.35 0.01 260 / 0.3) 50%, transparent 100% ); } @keyframes skeleton-slide { from { transform: translateX(-100%); } to { transform: translateX(100%); } } /* ─── Interactive Card Hover Micro-Effect ─────────────────────────── */ .card-interactive { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; } .card-interactive:hover { transform: translateY(-2px); box-shadow: 0 8px 24px -6px oklch(0.55 0.17 155 / 0.12); } .dark .card-interactive:hover { box-shadow: 0 8px 24px -6px oklch(0.35 0.17 155 / 0.2); } .card-interactive:active { transform: translateY(0px) scale(0.99); } /* ─── New Utility Classes (Round 24) ──────────────────────────────── */ /* .animate-pulse-slow — Slower pulse animation */ @keyframes pulse-slow { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(1.05); } } .animate-pulse-slow { animation: pulse-slow 3s ease-in-out infinite; } /* .hover-lift — Hover lift effect */ .hover-lift { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; } .hover-lift:hover { transform: translateY(-3px); box-shadow: 0 12px 28px -8px oklch(0.55 0.17 155 / 0.2); } .dark .hover-lift:hover { box-shadow: 0 12px 28px -8px oklch(0.65 0.17 155 / 0.3); } /* .gradient-border — Border with gradient */ .gradient-border { position: relative; border: none; background-clip: padding-box; } .gradient-border::before { content: ''; position: absolute; inset: 0; z-index: -1; margin: -1.5px; border-radius: inherit; background: linear-gradient(135deg, oklch(0.55 0.17 155), oklch(0.55 0.14 175), oklch(0.65 0.22 330)); } .dark .gradient-border::before { background: linear-gradient(135deg, oklch(0.65 0.17 155), oklch(0.65 0.14 175), oklch(0.75 0.22 330)); } /* .pattern-dots — Dot pattern background */ .pattern-dots { background-image: radial-gradient(circle, oklch(0.55 0.17 155 / 0.12) 1px, transparent 1px); background-size: 20px 20px; } .dark .pattern-dots { background-image: radial-gradient(circle, oklch(0.65 0.17 155 / 0.15) 1px, transparent 1px); background-size: 20px 20px; } /* .pattern-grid — Grid pattern background */ .pattern-grid { background-image: linear-gradient(oklch(0.55 0.17 155 / 0.05) 1px, transparent 1px), linear-gradient(90deg, oklch(0.55 0.17 155 / 0.05) 1px, transparent 1px); background-size: 32px 32px; } .dark .pattern-grid { background-image: linear-gradient(oklch(0.65 0.17 155 / 0.06) 1px, transparent 1px), linear-gradient(90deg, oklch(0.65 0.17 155 / 0.06) 1px, transparent 1px); background-size: 32px 32px; } /* @keyframes slideInUp — Slide in from bottom */ @keyframes slideInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .animate-slide-in-up { animation: slideInUp 0.4s ease-out; } /* @keyframes scaleIn — Scale in from center */ @keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } .animate-scale-in { animation: scaleIn 0.3s ease-out; } /* @keyframes fadeInScale — Fade + scale combined */ @keyframes fadeInScale { from { opacity: 0; transform: scale(0.95) translateY(8px); } to { opacity: 1; transform: scale(1) translateY(0); } } .animate-fade-in-scale { animation: fadeInScale 0.4s ease-out; } /* Notification badge pulse */ @keyframes badge-pulse { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.55 0.17 155 / 0.4); } 50% { box-shadow: 0 0 0 6px oklch(0.55 0.17 155 / 0); } } .animate-badge-pulse { animation: badge-pulse 2s ease-in-out infinite; } .dark .animate-badge-pulse { animation-name: badge-pulse-dark; } @keyframes badge-pulse-dark { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.65 0.17 155 / 0.5); } 50% { box-shadow: 0 0 0 6px oklch(0.65 0.17 155 / 0); } } /* Animated gradient header banner */ @keyframes header-gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .animate-header-gradient { background-size: 200% 200%; animation: header-gradient-shift 6s ease infinite; } /* Timeline connector line for activity entries */ .timeline-connector { position: relative; } .timeline-connector::before { content: ''; position: absolute; left: 15px; top: 36px; bottom: -8px; width: 2px; background: oklch(0.90 0.01 155); } .dark .timeline-connector::before { background: oklch(0.25 0.015 260); } .timeline-connector:last-child::before { display: none; } /* Input validation states */ .input-valid { border-color: oklch(0.55 0.17 155) !important; box-shadow: 0 0 0 3px oklch(0.55 0.17 155 / 0.12); } .input-invalid { border-color: oklch(0.577 0.245 27.325) !important; box-shadow: 0 0 0 3px oklch(0.577 0.245 27.325 / 0.12); } /* Social login button hover */ .social-btn { transition: all 0.2s ease-out; } .social-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px oklch(0 0 0 / 0.1); } .social-btn:active { transform: translateY(0) scale(0.98); } /* ─── Danger Zone Styling ────────────────────────────────────────── */ .danger-zone { border: 2px dashed oklch(0.55 0.22 25 / 0.4); border-radius: 12px; padding: 1.5rem; background: oklch(0.55 0.22 25 / 0.03); } .dark .danger-zone { border-color: oklch(0.55 0.22 25 / 0.3); background: oklch(0.55 0.22 25 / 0.05); } .danger-zone:hover { border-color: oklch(0.55 0.22 25 / 0.6); background: oklch(0.55 0.22 25 / 0.06); } /* ─── File Drop Zone ─────────────────────────────────────────────── */ .file-drop-zone { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 120px; padding: 24px; border: 2px dashed oklch(0.75 0.05 155); border-radius: 12px; background: oklch(0.97 0.01 155 / 0.3); cursor: pointer; transition: all 0.2s ease; } .dark .file-drop-zone { border-color: oklch(0.4 0.05 155); background: oklch(0.2 0.02 155 / 0.3); } .file-drop-zone.drag-over { border-color: oklch(0.55 0.17 155); background: oklch(0.55 0.17 155 / 0.1); transform: scale(1.01); } .dark .file-drop-zone.drag-over { border-color: oklch(0.65 0.17 155); background: oklch(0.65 0.17 155 / 0.1); } .file-drop-zone:hover { border-color: oklch(0.55 0.17 155); background: oklch(0.55 0.17 155 / 0.05); } /* ─── Import Progress Bar ────────────────────────────────────────── */ .import-progress { animation: import-fade-in 0.3s ease-out; } @keyframes import-fade-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } /* ─── Report Preview Page ────────────────────────────────────────── */ .report-preview { position: relative; max-width: 800px; margin: 0 auto; padding: 40px 32px; background: white; box-shadow: 0 1px 3px rgba(0,0,0,0.1); border-radius: 8px; } .dark .report-preview { background: oklch(0.15 0.01 260); box-shadow: 0 1px 3px rgba(0,0,0,0.3); } /* ─── Environmental Watermark ────────────────────────────────────── */ .watermark-eco { position: fixed; bottom: 50%; right: -60px; transform: rotate(-45deg); font-size: 72px; font-weight: 900; color: oklch(0.55 0.17 155 / 0.04); pointer-events: none; z-index: -1; user-select: none; } /* ─── Badge Type ─────────────────────────────────────────────────── */ .badge-type { display: inline-block; padding: 2px 10px; border-radius: 12px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; } /* ─── Status Indicator Dot Pulse ─────────────────────────────────── */ @keyframes status-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.5; transform: scale(1.3); } } .status-dot-pulse { animation: status-pulse 2s ease-in-out infinite; } /* ─── Count-Up Animation for Numbers ─────────────────────────────── */ .animate-count-up { animation: count-up 0.8s ease-out; } @keyframes count-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } /* ─── Round 25 Utility Classes ──────────────────────────────────── */ /* .gradient-border-left — Left border with gradient accent */ .gradient-border-left { position: relative; border-left: none; } .gradient-border-left::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; border-radius: 0 3px 3px 0; background: linear-gradient(180deg, oklch(0.55 0.17 155), oklch(0.55 0.14 175), oklch(0.72 0.19 85)); } .dark .gradient-border-left::before { background: linear-gradient(180deg, oklch(0.65 0.17 155), oklch(0.65 0.14 175), oklch(0.77 0.19 85)); } /* @keyframes slideInLeft — Slide in from left */ @keyframes slideInLeft { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: translateX(0); } } .animate-slide-in-left { animation: slideInLeft 0.4s ease-out; } /* @keyframes fadeUp — Fade and move up */ @keyframes fadeUp { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } .animate-fade-up { animation: fadeUp 0.45s ease-out; } /* .status-dot — Small status indicator dot */ .status-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: oklch(0.55 0.17 155); box-shadow: 0 0 0 2px oklch(0.55 0.17 155 / 0.2); } .dark .status-dot { background: oklch(0.65 0.17 155); box-shadow: 0 0 0 2px oklch(0.65 0.17 155 / 0.3); } .status-dot-amber { background: oklch(0.72 0.19 85); box-shadow: 0 0 0 2px oklch(0.72 0.19 85 / 0.2); } .status-dot-rose { background: oklch(0.65 0.22 15); box-shadow: 0 0 0 2px oklch(0.65 0.22 15 / 0.2); } .status-dot-violet { background: oklch(0.60 0.20 320); box-shadow: 0 0 0 2px oklch(0.60 0.20 320 / 0.2); } /* .progress-animated — Progress bar with fill animation */ @keyframes progressFill { from { width: 0%; } } .progress-animated { animation: progressFill 1s ease-out; transition: width 0.6s ease-out; } /* @keyframes pulseGlow — Pulsing glow effect */ @keyframes pulseGlow { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.55 0.17 155 / 0.4); } 50% { box-shadow: 0 0 12px 4px oklch(0.55 0.17 155 / 0.15); } } .animate-pulse-glow { animation: pulseGlow 2.5s ease-in-out infinite; } .dark .animate-pulse-glow { animation-name: pulseGlowDark; } @keyframes pulseGlowDark { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.65 0.17 155 / 0.5); } 50% { box-shadow: 0 0 12px 4px oklch(0.65 0.17 155 / 0.2); } } /* .glassmorphism-card — Frosted glass card with blur */ .glassmorphism-card { background: oklch(1 0 0 / 0.6); backdrop-filter: blur(16px) saturate(180%); -webkit-backdrop-filter: blur(16px) saturate(180%); border: 1px solid oklch(1 0 0 / 0.35); box-shadow: 0 8px 32px -8px oklch(0 0 0 / 0.08), inset 0 0 0 1px oklch(1 0 0 / 0.2); } .dark .glassmorphism-card { background: oklch(0.18 0.015 260 / 0.55); backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%); border: 1px solid oklch(1 0 0 / 0.08); box-shadow: 0 8px 32px -8px oklch(0 0 0 / 0.4), inset 0 0 0 1px oklch(1 0 0 / 0.04); } /* .gradient-border-card — Card with gradient border on all sides */ .gradient-border-card { position: relative; border: none; background-clip: padding-box; border-radius: 12px; } .gradient-border-card::before { content: ''; position: absolute; inset: 0; z-index: -1; margin: -1.5px; border-radius: inherit; background: linear-gradient(135deg, oklch(0.55 0.17 155), oklch(0.55 0.14 175), oklch(0.72 0.19 85)); } .dark .gradient-border-card::before { background: linear-gradient(135deg, oklch(0.65 0.17 155), oklch(0.65 0.14 175), oklch(0.77 0.19 85)); } } /* Print-specific styling — expands to all reports when printing */ @media print { .no-print { display: none !important; } .print-only { display: block !important; } body { background: white !important; color: black !important; } /* Hide sidebar, header, navigation */ [data-sidebar], header, nav, .no-print { display: none !important; } /* Make main content full width */ main, .print-area { width: 100% !important; margin: 0 !important; padding: 1rem !important; } /* Ensure cards have borders for print */ .card, [class*="Card"] { border: 1px solid #e5e7eb !important; break-inside: avoid; } /* Ensure text is readable */ body { color: #000 !important; background: #fff !important; } /* Page breaks */ .page-break { page-break-before: always; } .print-break-before { page-break-before: always; } .print-avoid-break { page-break-inside: avoid; } .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl { box-shadow: none !important; } .paper-preview { box-shadow: none !important; } @page { margin: 18mm 16mm; } /* Better margins for print */ .card-hover-lift:hover { transform: none !important; box-shadow: none !important; } /* Hide interactive elements */ button, .no-print, [role="button"], nav, aside, footer, header, .sidebar, .sidebar-trigger, .breadcrumb { display: none !important; } /* Ensure readable text */ .dark { background: white !important; color: black !important; } .dark * { color: inherit !important; background: transparent !important; } /* Prevent overflow */ .overflow-y-auto, .max-h-96, .max-h-80, .max-h-72 { max-height: none !important; overflow: visible !important; } } /* ─── Tablet & Stylus Optimization ────────────────────────────────────── */ /* Minimum touch target size (44px as per Apple HIG and WCAG guidelines) */ @layer utilities { .min-touch { min-width: 44px; min-height: 44px; } } /* Touch-friendly media queries for tablets (768px-1024px) */ @media (pointer: coarse) { /* Increase touch targets for all interactive elements */ button, [role="button"], a, input[type="checkbox"], input[type="radio"], select, .tabs-trigger, [data-state] { min-height: 44px; } /* Stylus-friendly: larger focus rings to prevent accidental taps */ *:focus-visible { outline-width: 3px; outline-offset: 4px; } /* More generous spacing between interactive elements */ .sidebar-menu-item { margin-bottom: 2px; } /* Prevent text selection while using stylus on interactive elements */ button, a, [role="button"] { -webkit-user-select: none; user-select: none; } /* Slightly larger fonts for touch readability */ input, select, textarea { font-size: 16px; /* Prevents iOS zoom on input focus */ } } /* Tablet-specific viewport styles (768px-1024px) */ @media (min-width: 768px) and (max-width: 1024px) { /* Adjust grid layouts for tablet */ .lg\:grid-cols-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } /* More compact spacing for tablet */ .space-y-7 > * + * { margin-top: 1.25rem; } /* Ensure sidebar doesn't collapse too much */ [data-sidebar] { min-width: 220px; } } /* Stylus-specific improvements */ @media (pointer: fine) and (hover: none) { /* Stylus devices often lack hover — replace hover effects with active */ *:hover { /* Remove hover-only styles that don't make sense without hover capability */ } /* Larger active/focus states for stylus precision */ *:active { transform: scale(0.98); transition: transform 0.1s ease; } } /* ─── Smooth Scrollbar Styling (touch-friendly) ─────────────────────── */ @layer utilities { .scrollbar-touch::-webkit-scrollbar { width: 10px; height: 10px; } .scrollbar-touch::-webkit-scrollbar-track { background: transparent; margin: 4px; } .scrollbar-touch::-webkit-scrollbar-thumb { background: oklch(0.80 0.02 155 / 0.5); border-radius: 5px; border: 3px solid transparent; background-clip: padding-box; } .scrollbar-touch::-webkit-scrollbar-thumb:hover { background: oklch(0.65 0.17 155 / 0.7); border: 3px solid transparent; background-clip: padding-box; } .dark .scrollbar-touch::-webkit-scrollbar-thumb { background: oklch(0.35 0.015 260 / 0.5); border: 3px solid transparent; background-clip: padding-box; } /* Stylus-friendly input styles — larger focus rings for precision tapping */ .stylus-input:focus-visible { outline: 3px solid oklch(0.55 0.17 155); outline-offset: 4px; box-shadow: 0 0 0 6px oklch(0.55 0.17 155 / 0.15); border-radius: 8px; transition: box-shadow 0.2s ease-out, outline-offset 0.2s ease-out; } .dark .stylus-input:focus-visible { outline: 3px solid oklch(0.65 0.17 155); box-shadow: 0 0 0 6px oklch(0.65 0.17 155 / 0.2); } } /* ─── Better Print Styles ──────────────────────────────────────────────── */ @media print { /* Ensure emerald accent colors print as dark gray for readability */ .text-emerald-600, .text-emerald-700, .text-teal-600, .text-teal-700 { color: #333 !important; } .bg-emerald-50, .bg-emerald-100, .bg-teal-50, .bg-teal-100, .bg-gradient-to-r, [class*="from-emerald"], [class*="from-teal"] { background: #f5f5f5 !important; } /* Remove animations for print */ .animate-float, .animate-float-reverse, .animate-float-slow, .animate-pulse-soft, .animate-shimmer, .animate-progress-fill, .animate-view-fade-in, .animate-enter-fade, .animate-count-up, .animate-stagger-in, .animate-chart-shimmer { animation: none !important; } /* Force all cards to have visible borders */ [class*="border-0"], [class*="border-l-3"] { border: 1px solid #ddd !important; } /* Remove shadows */ .shadow-sm, .shadow-md, .shadow-lg, .shadow-xl, [class*="shadow-"] { box-shadow: none !important; } /* Notebook export specific styles */ .no-print { display: none !important; } .notebook-export { padding: 2cm; font-size: 12pt; } .notebook-export .page-break { page-break-after: always; } .notebook-export .page-content { min-height: 24cm; } /* Lined background for print */ .notebook-export .page-lined { background-image: repeating-linear-gradient( transparent, transparent 31px, #e5e7eb 31px, #e5e7eb 32px ); } } /* ─── Mobile Responsiveness Utilities ─────────────────────────────────── */ @layer utilities { /* Safe area insets for iOS notch/bottom bar */ .safe-top { padding-top: env(safe-area-inset-top, 0px); } .safe-bottom { padding-bottom: env(safe-area-inset-bottom, 0px); } .safe-left { padding-left: env(safe-area-inset-left, 0px); } .safe-right { padding-right: env(safe-area-inset-right, 0px); } .safe-all { padding-top: env(safe-area-inset-top, 0px); padding-bottom: env(safe-area-inset-bottom, 0px); padding-left: env(safe-area-inset-left, 0px); padding-right: env(safe-area-inset-right, 0px); } /* Prevent pinch-zoom on canvas elements */ .canvas-no-zoom { touch-action: none; -ms-touch-action: none; } /* Prevent text selection on drawing canvas */ .canvas-no-select { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; } /* Mobile-friendly horizontal scroll container for tables */ .mobile-scroll-x { -webkit-overflow-scrolling: touch; overflow-x: auto; scrollbar-width: thin; } /* Mobile stack helper */ .mobile-stack { @media (max-width: 639px) { flex-direction: column; gap: 0.75rem; } } /* Mobile full-width inputs */ .mobile-full-width { @media (max-width: 639px) { width: 100%; } } } /* Mobile-specific viewport adjustments */ @media (max-width: 639px) { /* Ensure dialogs don't overflow on small screens */ [role="dialog"] { max-width: calc(100vw - 2rem) !important; max-height: calc(100vh - 2rem) !important; margin: 1rem auto; } /* Ensure popovers are properly sized */ [data-radix-popper-content-wrapper] { max-width: calc(100vw - 2rem) !important; } /* Make card grids stack on mobile */ .grid { gap: 0.75rem; } /* Fix horizontal overflow */ body { overflow-x: hidden; } /* Prevent overflow in flex containers */ .flex { min-width: 0; } /* Make tabs scrollable on mobile */ [role="tablist"] { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; } [role="tablist"]::-webkit-scrollbar { display: none; } /* Stack stat cards vertically on mobile */ .mobile-card-stack { grid-template-columns: 1fr !important; } /* Notebook grid: 1 column on mobile */ .mobile-notebook-grid { grid-template-columns: 1fr !important; } /* Table horizontal scroll on mobile */ .mobile-table-scroll { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; } /* Full-width inputs on mobile */ input, select, textarea { max-width: 100%; } } /* Tablet-specific adjustments (640px-768px) */ @media (min-width: 640px) and (max-width: 767px) { /* Notebook grid: 2 columns on tablet */ .mobile-notebook-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; } } /* ─── Micro-interaction Animations ─────────────────────────────────────── */ @layer utilities { /* Fade in + slide up */ @keyframes fade-in-up { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } } .animate-fade-in-up { animation: fade-in-up 0.35s ease-out; } /* Scale in from 0.95 to 1 */ @keyframes scale-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } .animate-scale-in { animation: scale-in 0.2s ease-out; } /* Error shake animation */ @keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-4px); } 20%, 40%, 60%, 80% { transform: translateX(4px); } } .animate-shake { animation: shake 0.5s ease-in-out; } /* Success checkmark animation */ @keyframes success-check { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.2); } 100% { transform: scale(1); opacity: 1; } } .animate-success-check { animation: success-check 0.4s ease-out; } /* Subtle lift on hover (translateY -1px) */ .hover-lift { transition: transform 0.15s ease-out, box-shadow 0.15s ease-out; } .hover-lift:hover { transform: translateY(-1px); box-shadow: 0 4px 12px -2px oklch(0 0 0 / 0.08); } .dark .hover-lift:hover { box-shadow: 0 4px 12px -2px oklch(0 0 0 / 0.3); } /* Animated focus ring */ .focus-ring { transition: box-shadow 0.2s ease-out, outline 0.2s ease-out; } .focus-ring:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; box-shadow: 0 0 0 4px oklch(0.55 0.17 155 / 0.15); } .dark .focus-ring:focus-visible { outline: 2px solid oklch(0.65 0.17 155); box-shadow: 0 0 0 4px oklch(0.65 0.17 155 / 0.2); } } /* ─── Enhanced Print Styles ────────────────────────────────────────────── */ @media print { /* Better print layout for reports */ @page { margin: 15mm 12mm; size: A4; } body { font-size: 11pt; line-height: 1.4; color: #000 !important; background: #fff !important; } /* Print-specific font sizes */ h1 { font-size: 18pt !important; } h2 { font-size: 14pt !important; } h3 { font-size: 12pt !important; } p, li, td, th { font-size: 10pt !important; } /* Hide interactive elements */ button, nav, aside, footer, header, [role="button"], [role="tablist"], [role="tab"], .no-print, [data-sidebar], .sidebar-trigger, .breadcrumb, .toast-container, [data-radix-popper-content-wrapper] { display: none !important; } /* Ensure cards have visible borders */ [class*="card"], [class*="Card"] { border: 1px solid #ddd !important; break-inside: avoid; box-shadow: none !important; } /* Page break controls */ .page-break-before { page-break-before: always; } .page-break-after { page-break-after: always; } .page-break-avoid { page-break-inside: avoid; } /* Remove shadows */ [class*="shadow"] { box-shadow: none !important; } /* Ensure dark mode prints as white */ .dark { background: white !important; color: black !important; } .dark * { color: inherit !important; background: transparent !important; } /* Remove animations */ * { animation: none !important; transition: none !important; } /* Ensure overflow is visible */ .overflow-y-auto, .max-h-96, .max-h-80, .max-h-72 { max-height: none !important; overflow: visible !important; } /* Print links with URL */ a[href]:after { content: " (" attr(href) ")"; font-size: 9pt; color: #666; } a[href^="#"]:after { content: ""; } /* Table styling for print */ table { border-collapse: collapse; } th, td { border: 1px solid #ccc; padding: 4px 8px; } th { background: #f0f0f0 !important; } } /* ─── Dark Mode Polish ─────────────────────────────────────────────────── */ @layer utilities { /* Better dark mode borders */ .dark-border { border-color: oklch(1 0 0 / 8%); } .dark .dark-border { border-color: oklch(1 0 0 / 12%); } /* Dark mode card shadows */ .dark-shadow { box-shadow: 0 1px 3px oklch(0 0 0 / 0.06); } .dark .dark-shadow { box-shadow: 0 1px 3px oklch(0 0 0 / 0.3), 0 0 0 1px oklch(1 0 0 / 6%); } /* Smooth transitions between light/dark */ .theme-transition { transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease; } /* Dark mode specific borders for cards */ .dark .card-dark-border { border-color: oklch(1 0 0 / 8%); } /* Dark mode specific shadows for elevated elements */ .dark .elevated-dark { box-shadow: 0 4px 16px oklch(0 0 0 / 0.4), 0 0 0 1px oklch(1 0 0 / 6%); } /* Better contrast ratios for dark mode text */ .dark .text-muted-foreground { color: oklch(0.70 0.02 260); } } /* ─── Accessibility Improvements ───────────────────────────────────────── */ @layer utilities { /* Skip to content link */ .skip-to-content { position: absolute; top: -100%; left: 0; z-index: 9999; padding: 1rem 1.5rem; background: oklch(0.55 0.17 155); color: white; font-weight: 600; border-radius: 0 0 8px 0; transition: top 0.2s ease; } .skip-to-content:focus { top: 0; } /* Screen reader only utility */ .sr-only-focusable:focus { position: static; width: auto; height: auto; padding: inherit; margin: inherit; overflow: visible; clip: auto; white-space: inherit; } /* Focus management for modals */ .modal-focus-wrapper { outline: none; } .modal-focus-wrapper:focus-visible { outline: 2px solid oklch(0.55 0.17 155); outline-offset: 2px; } /* Live region for screen reader announcements */ .sr-live-region { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* High contrast mode support */ @media (forced-colors: active) { .button-primary { border: 2px solid ButtonText; } .card-outline { border: 1px solid CanvasText; } } /* Reduced motion support */ @media (prefers-reduced-motion: reduce) { .animate-fade-in-up, .animate-scale-in, .animate-shake, .animate-success-check, .animate-float, .animate-float-reverse, .animate-float-slow, .animate-pulse-soft, .animate-shimmer, .animate-progress-fill, .animate-view-fade-in, .animate-enter-fade, .animate-count-up, .animate-stagger-in, .animate-chart-shimmer, .animate-pulse-dot, .animate-slide-in, .animate-slide-out, .hover-lift:hover { animation: none !important; transition: none !important; transform: none !important; } } } /* ─── Canvas Drawing Performance ───────────────────────────────────────── */ @layer utilities { /* GPU-accelerated canvas rendering */ .canvas-gpu { will-change: transform; transform: translateZ(0); backface-visibility: hidden; } /* Canvas layer caching */ .canvas-layer-bg { position: absolute; inset: 0; pointer-events: none; } .canvas-layer-draw { position: absolute; inset: 0; } /* Performance monitor */ .fps-counter { position: fixed; top: 4px; right: 4px; z-index: 9999; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-family: monospace; background: oklch(0 0 0 / 0.7); color: oklch(0.55 0.17 155); pointer-events: none; } } /* ─── Report Scheduling Styles (Task 13) ────────────────────────────────── */ @layer utilities { /* Schedule timeline visualization */ .schedule-timeline { position: relative; padding-left: 1.5rem; } .schedule-timeline::before { content: ''; position: absolute; left: 0.5rem; top: 0; bottom: 0; width: 2px; background: linear-gradient(to bottom, oklch(0.55 0.17 155), oklch(0.65 0.12 175)); border-radius: 1px; } .schedule-timeline-item { position: relative; padding-bottom: 1.5rem; } .schedule-timeline-item::before { content: ''; position: absolute; left: -1.1rem; top: 0.35rem; width: 0.75rem; height: 0.75rem; border-radius: 50%; background: oklch(0.55 0.17 155); border: 2px solid white; box-shadow: 0 0 0 2px oklch(0.55 0.17 155 / 0.3); } .schedule-timeline-item.inactive::before { background: oklch(0.7 0 0); box-shadow: 0 0 0 2px oklch(0.7 0 0 / 0.3); } .schedule-timeline-item:last-child { padding-bottom: 0; } /* District card styling */ .district-card { position: relative; overflow: hidden; border-radius: 1rem; transition: transform 0.2s ease, box-shadow 0.2s ease; } .district-card:hover { transform: translateY(-2px); box-shadow: 0 8px 25px -5px oklch(0 0 0 / 0.1), 0 0 0 1px oklch(0.55 0.17 155 / 0.1); } .district-card::after { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(to right, oklch(0.55 0.17 155), oklch(0.65 0.12 175), oklch(0.55 0.17 155)); } .dark .district-card::after { background: linear-gradient(to right, oklch(0.65 0.17 155), oklch(0.75 0.12 175), oklch(0.65 0.17 155)); } /* Cross-school comparison styling */ .cross-school-comparison { display: grid; gap: 1rem; } .cross-school-comparison .comparison-bar { height: 0.5rem; border-radius: 9999px; overflow: hidden; background: oklch(0.95 0.02 155); } .dark .cross-school-comparison .comparison-bar { background: oklch(0.25 0.02 155); } .cross-school-comparison .comparison-bar-fill { height: 100%; border-radius: 9999px; transition: width 0.5s ease; } /* Report generation progress bar */ .report-progress { position: relative; height: 0.5rem; border-radius: 9999px; overflow: hidden; background: oklch(0.93 0.02 155); } .dark .report-progress { background: oklch(0.25 0.02 155); } .report-progress-fill { height: 100%; border-radius: 9999px; background: linear-gradient(to right, oklch(0.55 0.17 155), oklch(0.65 0.12 175)); transition: width 0.5s ease; position: relative; } .report-progress-fill::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.3), transparent); animation: shimmer-progress 2s ease-in-out infinite; } @keyframes shimmer-progress { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* Section divider with gradient line */ .section-divider { position: relative; height: 1px; background: linear-gradient(to right, transparent, oklch(0.55 0.17 155 / 0.3), transparent); margin: 1.5rem 0; } .dark .section-divider { background: linear-gradient(to right, transparent, oklch(0.65 0.17 155 / 0.3), transparent); } /* ─── Advanced Analytics Styles ──────────────────────────────────── */ /* Chart container with rounded corners and shadow */ .chart-container { background: oklch(1 0 0); border-radius: 1rem; box-shadow: 0 1px 3px oklch(0 0 0 / 0.06), 0 1px 2px oklch(0 0 0 / 0.04); border: 1px solid oklch(0.93 0.005 155); overflow: hidden; } .dark .chart-container { background: oklch(0.18 0.015 260); box-shadow: 0 1px 3px oklch(0 0 0 / 0.3), 0 0 0 1px oklch(1 0 0 / 6%); border-color: oklch(1 0 0 / 8%); } /* Stat card with gradient */ .stat-card { position: relative; border-radius: 1rem; padding: 1.25rem; overflow: hidden; transition: transform 0.2s ease-out, box-shadow 0.2s ease-out; } .stat-card::before { content: ''; position: absolute; inset: 0; opacity: 0.06; background: linear-gradient(135deg, oklch(0.55 0.17 155), oklch(0.55 0.14 175)); pointer-events: none; } .stat-card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px -6px oklch(0.55 0.17 155 / 0.15); } .dark .stat-card:hover { box-shadow: 0 8px 24px -6px oklch(0.65 0.17 155 / 0.25); } /* Heatmap cell styling */ .heatmap-cell { border-radius: 3px; transition: all 0.15s ease; min-width: 14px; min-height: 14px; } .heatmap-cell:hover { transform: scale(1.3); box-shadow: 0 0 0 2px oklch(0.55 0.17 155 / 0.3); z-index: 1; } /* Analytics dashboard grid layout */ .analytics-dashboard { display: grid; gap: 1.5rem; grid-template-columns: 1fr; } @media (min-width: 768px) { .analytics-dashboard { grid-template-columns: repeat(2, 1fr); } } .analytics-dashboard-full { grid-column: 1 / -1; } /* Chart loading skeleton */ .loading-skeleton-chart { position: relative; overflow: hidden; border-radius: 1rem; background: oklch(0.94 0.005 155 / 0.5); min-height: 200px; } .dark .loading-skeleton-chart { background: oklch(0.22 0.015 260 / 0.5); } .loading-skeleton-chart::after { content: ''; position: absolute; inset: 0; background: linear-gradient( 90deg, transparent 0%, oklch(0.97 0.01 155 / 0.4) 50%, transparent 100% ); animation: skeleton-slide 1.5s ease-in-out infinite; } .dark .loading-skeleton-chart::after { background: linear-gradient( 90deg, transparent 0%, oklch(0.30 0.01 260 / 0.3) 50%, transparent 100% ); } /* Predictive badge — risk / excelling */ .predictive-badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.75rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; letter-spacing: 0.02em; line-height: 1.25rem; } .predictive-badge-risk { background: oklch(0.55 0.22 25 / 0.1); color: oklch(0.55 0.22 25); border: 1px solid oklch(0.55 0.22 25 / 0.2); } .dark .predictive-badge-risk { background: oklch(0.55 0.22 25 / 0.15); color: oklch(0.70 0.19 22); border-color: oklch(0.55 0.22 25 / 0.3); } .predictive-badge-excel { background: oklch(0.55 0.17 155 / 0.1); color: oklch(0.55 0.17 155); border: 1px solid oklch(0.55 0.17 155 / 0.2); } .dark .predictive-badge-excel { background: oklch(0.55 0.17 155 / 0.15); color: oklch(0.70 0.17 155); border-color: oklch(0.65 0.17 155 / 0.3); } .predictive-badge-attention { background: oklch(0.72 0.19 85 / 0.1); color: oklch(0.60 0.18 50); border: 1px solid oklch(0.72 0.19 85 / 0.2); } .dark .predictive-badge-attention { background: oklch(0.72 0.19 85 / 0.15); color: oklch(0.77 0.19 85); border-color: oklch(0.72 0.19 85 / 0.3); } /* Analytics section tab navigation */ .analytics-tab { padding: 0.5rem 1rem; border-radius: 0.5rem; font-size: 0.8125rem; font-weight: 500; color: oklch(0.55 0.02 260); transition: all 0.2s ease; cursor: pointer; min-height: 44px; display: flex; align-items: center; gap: 0.375rem; border: 1px solid transparent; } .analytics-tab:hover { background: oklch(0.55 0.17 155 / 0.06); color: oklch(0.55 0.17 155); } .analytics-tab.active { background: oklch(0.55 0.17 155 / 0.1); color: oklch(0.55 0.17 155); border-color: oklch(0.55 0.17 155 / 0.2); font-weight: 600; } .dark .analytics-tab:hover { background: oklch(0.55 0.17 155 / 0.1); color: oklch(0.65 0.17 155); } .dark .analytics-tab.active { background: oklch(0.55 0.17 155 / 0.15); color: oklch(0.65 0.17 155); border-color: oklch(0.65 0.17 155 / 0.3); } /* Export button group */ .export-btn-group { display: flex; gap: 0.5rem; flex-wrap: wrap; } .export-btn { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.5rem 1rem; border-radius: 0.5rem; font-size: 0.8125rem; font-weight: 500; min-height: 44px; border: 1px solid oklch(0.93 0.005 155); background: oklch(1 0 0); color: oklch(0.35 0.02 260); transition: all 0.2s ease; cursor: pointer; } .export-btn:hover { background: oklch(0.55 0.17 155 / 0.06); border-color: oklch(0.55 0.17 155 / 0.2); color: oklch(0.55 0.17 155); } .dark .export-btn { background: oklch(0.18 0.015 260); border-color: oklch(1 0 0 / 8%); color: oklch(0.70 0.02 260); } .dark .export-btn:hover { background: oklch(0.55 0.17 155 / 0.1); border-color: oklch(0.65 0.17 155 / 0.3); color: oklch(0.65 0.17 155); } /* Chart description for screen readers */ .chart-sr-desc { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* ─── Offline / PWA Styles ──────────────────────────────────────── */ /* Offline indicator bar */ .offline-indicator-bar { z-index: 100; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; } /* PWA install prompt */ .pwa-install-prompt { animation: slide-up-fade 0.3s ease-out; } @keyframes slide-up-fade { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } /* Offline badge pulse */ .offline-badge-pulse { animation: offline-pulse 2s ease-in-out infinite; } @keyframes offline-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* Offline sync spinner */ .offline-sync-spinner { animation: offline-sync-spin 1s linear infinite; } @keyframes offline-sync-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Cached notebook indicator */ .cached-notebook-indicator { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; } /* Rate limit status card */ .rate-limit-card { border: 1px solid oklch(0.55 0.17 155 / 0.2); border-radius: 0.75rem; padding: 1rem; background: oklch(0.98 0.01 155 / 0.5); } .dark .rate-limit-card { border-color: oklch(0.55 0.17 155 / 0.15); background: oklch(0.2 0.02 155 / 0.3); } /* Rate limit bar */ .rate-limit-bar { height: 4px; border-radius: 2px; background: oklch(0.92 0.01 155); overflow: hidden; } .dark .rate-limit-bar { background: oklch(0.25 0.01 155); } .rate-limit-bar-fill { height: 100%; border-radius: 2px; transition: width 0.3s ease; } /* PWA standalone mode adjustments */ @media (display-mode: standalone) { body { padding-top: env(safe-area-inset-top); padding-bottom: env(safe-area-inset-bottom); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); } } /* Offline mode visual feedback */ .offline-mode-active { filter: none; } .offline-mode-active .offline-dimmed { opacity: 0.7; pointer-events: none; } /* Toast rate limit countdown */ .rate-limit-countdown { display: inline-flex; align-items: center; gap: 0.25rem; font-variant-numeric: tabular-nums; font-weight: 600; color: oklch(0.55 0.17 25); } /* ─── Performance & Styling Polish Animations ────────── */ /* Card hover lift effect */ .card-hover-lift { transition: transform 0.2s ease, box-shadow 0.2s ease; } .card-hover-lift:hover { transform: translateY(-2px); box-shadow: 0 8px 25px -5px oklch(0.55 0.17 155 / 0.15), 0 4px 10px -4px oklch(0.55 0.17 155 / 0.1); } .dark .card-hover-lift:hover { box-shadow: 0 8px 25px -5px oklch(0.3 0.05 155 / 0.3), 0 4px 10px -4px oklch(0.3 0.05 155 / 0.2); } /* Gradient line separator */ .gradient-separator { height: 1px; background: linear-gradient(to right, transparent, oklch(0.55 0.17 155 / 0.3), oklch(0.55 0.17 155 / 0.5), oklch(0.55 0.17 155 / 0.3), transparent); } .dark .gradient-separator { background: linear-gradient(to right, transparent, oklch(0.55 0.17 155 / 0.2), oklch(0.55 0.17 155 / 0.4), oklch(0.55 0.17 155 / 0.2), transparent); } /* Badge glow animations */ @keyframes badge-glow-emerald { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.55 0.17 155 / 0.3); } 50% { box-shadow: 0 0 8px 2px oklch(0.55 0.17 155 / 0.2); } } @keyframes badge-glow-amber { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.75 0.15 85 / 0.3); } 50% { box-shadow: 0 0 8px 2px oklch(0.75 0.15 85 / 0.2); } } @keyframes badge-glow-rose { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.55 0.2 15 / 0.3); } 50% { box-shadow: 0 0 8px 2px oklch(0.55 0.2 15 / 0.2); } } .badge-glow-emerald { animation: badge-glow-emerald 2s ease-in-out infinite; } .badge-glow-amber { animation: badge-glow-amber 2s ease-in-out infinite; } .badge-glow-rose { animation: badge-glow-rose 2s ease-in-out infinite; } /* Staggered entrance animation */ @keyframes stagger-entrance { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); } } .stagger-entrance { animation: stagger-entrance 0.4s ease-out forwards; opacity: 0; } .stagger-entrance:nth-child(1) { animation-delay: 0ms; } .stagger-entrance:nth-child(2) { animation-delay: 60ms; } .stagger-entrance:nth-child(3) { animation-delay: 120ms; } .stagger-entrance:nth-child(4) { animation-delay: 180ms; } .stagger-entrance:nth-child(5) { animation-delay: 240ms; } .stagger-entrance:nth-child(6) { animation-delay: 300ms; } .stagger-entrance:nth-child(7) { animation-delay: 360ms; } .stagger-entrance:nth-child(8) { animation-delay: 420ms; } /* Celebration confetti burst */ @keyframes confetti-burst { 0% { transform: scale(0); opacity: 1; } 50% { transform: scale(1.2); opacity: 0.8; } 100% { transform: scale(0); opacity: 0; } } /* Success animation for save actions */ @keyframes success-bounce { 0% { transform: scale(0.8); opacity: 0; } 50% { transform: scale(1.1); } 100% { transform: scale(1); opacity: 1; } } .success-bounce { animation: success-bounce 0.4s ease-out; } /* Animated pill filter */ @keyframes pill-highlight { from { background-position: left center; } to { background-position: right center; } } /* Onboarding tour animated highlight */ @keyframes tour-highlight-ring { 0% { transform: scale(0.95); opacity: 0.8; } 50% { transform: scale(1.05); opacity: 1; } 100% { transform: scale(0.95); opacity: 0.8; } } .tour-highlight-ring { animation: tour-highlight-ring 1.5s ease-in-out infinite; } /* Smooth theme transition */ .theme-transition * { transition: background-color 0.3s ease, color 0.15s ease, border-color 0.3s ease; } /* Custom scrollbar styling for lists */ .custom-scrollbar::-webkit-scrollbar { width: 6px; height: 6px; } .custom-scrollbar::-webkit-scrollbar-track { background: transparent; } .custom-scrollbar::-webkit-scrollbar-thumb { background: oklch(0.55 0.17 155 / 0.2); border-radius: 3px; } .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: oklch(0.55 0.17 155 / 0.4); } .dark .custom-scrollbar::-webkit-scrollbar-thumb { background: oklch(0.55 0.17 155 / 0.15); } .dark .custom-scrollbar::-webkit-scrollbar-thumb:hover { background: oklch(0.55 0.17 155 / 0.3); } /* Attendance grid colored cells */ .attendance-present { background: linear-gradient(135deg, oklch(0.6 0.17 155 / 0.15), oklch(0.6 0.17 155 / 0.08)); border-left: 3px solid oklch(0.55 0.17 155); } .dark .attendance-present { background: linear-gradient(135deg, oklch(0.55 0.17 155 / 0.2), oklch(0.55 0.17 155 / 0.08)); } .attendance-absent { background: linear-gradient(135deg, oklch(0.55 0.2 15 / 0.15), oklch(0.55 0.2 15 / 0.08)); border-left: 3px solid oklch(0.55 0.2 15); } .dark .attendance-absent { background: linear-gradient(135deg, oklch(0.55 0.2 15 / 0.2), oklch(0.55 0.2 15 / 0.08)); } .attendance-excused { background: linear-gradient(135deg, oklch(0.75 0.15 85 / 0.15), oklch(0.75 0.15 85 / 0.08)); border-left: 3px solid oklch(0.75 0.15 85); } .dark .attendance-excused { background: linear-gradient(135deg, oklch(0.75 0.15 85 / 0.2), oklch(0.75 0.15 85 / 0.08)); } .attendance-late { background: linear-gradient(135deg, oklch(0.55 0.1 185 / 0.15), oklch(0.55 0.1 185 / 0.08)); border-left: 3px solid oklch(0.55 0.1 185); } .dark .attendance-late { background: linear-gradient(135deg, oklch(0.55 0.1 185 / 0.2), oklch(0.55 0.1 185 / 0.08)); } /* Grade color coding */ .grade-excellent { background: linear-gradient(135deg, oklch(0.6 0.17 155 / 0.9), oklch(0.5 0.15 165 / 0.9)); color: white; } .grade-good { background: linear-gradient(135deg, oklch(0.65 0.13 155 / 0.85), oklch(0.55 0.12 165 / 0.85)); color: white; } .grade-satisfactory { background: linear-gradient(135deg, oklch(0.75 0.15 85 / 0.8), oklch(0.65 0.13 75 / 0.8)); color: white; } .grade-sufficient { background: linear-gradient(135deg, oklch(0.75 0.12 55 / 0.8), oklch(0.65 0.1 45 / 0.8)); color: white; } .grade-poor { background: linear-gradient(135deg, oklch(0.6 0.18 25 / 0.85), oklch(0.55 0.16 15 / 0.85)); color: white; } .grade-failing { background: linear-gradient(135deg, oklch(0.55 0.2 15 / 0.9), oklch(0.5 0.18 25 / 0.9)); color: white; } /* Glass effect for cards */ .glass-card { background: rgba(255, 255, 255, 0.6); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.2); } .dark .glass-card { background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.05); } /* Min touch target size (44px) */ .min-touch { min-height: 44px; min-width: 44px; } /* ─── Badge Circle Styling ─────────────────────────────────────── */ .badge-circle { width: 56px; height: 56px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: transform 0.2s ease, box-shadow 0.2s ease; position: relative; cursor: pointer; } .badge-circle:hover { transform: scale(1.12); } .badge-earned { background: linear-gradient(135deg, oklch(0.65 0.17 155), oklch(0.55 0.14 170)); box-shadow: 0 2px 12px oklch(0.55 0.17 155 / 0.3); } .badge-earned:hover { box-shadow: 0 4px 20px oklch(0.55 0.17 155 / 0.5); } .badge-unearned { background: oklch(0.92 0 0); border: 2px dashed oklch(0.7 0 0); opacity: 0.5; } .dark .badge-unearned { background: oklch(0.25 0 0); border-color: oklch(0.45 0 0); } .badge-progress { position: absolute; bottom: -2px; left: 50%; transform: translateX(-50%); width: 36px; height: 4px; border-radius: 2px; background: oklch(0.85 0 0); overflow: hidden; } .dark .badge-progress { background: oklch(0.35 0 0); } .badge-progress-fill { height: 100%; border-radius: 2px; background: linear-gradient(90deg, oklch(0.55 0.17 155), oklch(0.65 0.12 175)); transition: width 0.5s ease; } /* ─── Celebration Animation ────────────────────────────────────── */ @keyframes celebration-sparkle { 0% { opacity: 0; transform: scale(0.5) rotate(0deg); } 50% { opacity: 1; transform: scale(1.2) rotate(180deg); } 100% { opacity: 0; transform: scale(0.5) rotate(360deg); } } @keyframes celebration-bounce { 0%, 100% { transform: translateY(0); } 30% { transform: translateY(-12px); } 50% { transform: translateY(-6px); } 70% { transform: translateY(-8px); } } .celebration-sparkle { animation: celebration-sparkle 0.8s ease-in-out; } .celebration-bounce { animation: celebration-bounce 0.6s ease-in-out; } .celebration-ring { position: absolute; inset: -6px; border-radius: 50%; border: 2px solid oklch(0.65 0.17 155 / 0.6); animation: celebration-ring-pulse 1s ease-out; } @keyframes celebration-ring-pulse { 0% { transform: scale(0.8); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } } /* ─── QR Code Card Styling ─────────────────────────────────────── */ .qr-card { border-radius: 1rem; padding: 1.5rem; text-align: center; background: white; box-shadow: 0 4px 16px oklch(0 0 0 / 0.08); position: relative; overflow: hidden; } .dark .qr-card { background: oklch(0.2 0 0); box-shadow: 0 4px 16px oklch(0 0 0 / 0.3); } .qr-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 4px; background: linear-gradient(90deg, oklch(0.55 0.17 155), oklch(0.65 0.12 175), oklch(0.55 0.17 155)); } .qr-card img { border-radius: 0.5rem; max-width: 100%; } /* ─── Attendance QR Display ────────────────────────────────────── */ .attendance-qr-display { display: flex; flex-direction: column; align-items: center; gap: 1rem; padding: 2rem; background: linear-gradient(135deg, oklch(0.97 0.02 155), oklch(0.95 0.02 175)); border-radius: 1rem; border: 2px solid oklch(0.55 0.17 155 / 0.2); } .dark .attendance-qr-display { background: linear-gradient(135deg, oklch(0.2 0.01 155), oklch(0.18 0.01 175)); border-color: oklch(0.55 0.17 155 / 0.3); } .attendance-qr-display .qr-timer { display: flex; align-items: center; gap: 0.5rem; font-size: 0.875rem; color: oklch(0.5 0 0); } .dark .attendance-qr-display .qr-timer { color: oklch(0.65 0 0); } .attendance-qr-display .qr-timer-bar { width: 100%; height: 4px; border-radius: 2px; background: oklch(0.9 0 0); overflow: hidden; } .dark .attendance-qr-display .qr-timer-bar { background: oklch(0.3 0 0); } .attendance-qr-display .qr-timer-bar-fill { height: 100%; background: linear-gradient(90deg, oklch(0.55 0.17 155), oklch(0.65 0.12 175)); transition: width 1s linear; } /* ─── Student Detail Quick Stats ───────────────────────────────── */ .quick-stats-bar { display: flex; gap: 0.75rem; flex-wrap: wrap; padding: 0.75rem; border-radius: 0.75rem; background: oklch(0.97 0.02 155); border: 1px solid oklch(0.55 0.17 155 / 0.1); } .dark .quick-stats-bar { background: oklch(0.2 0.01 155); border-color: oklch(0.55 0.17 155 / 0.2); } .quick-stat-item { display: flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; border-radius: 0.5rem; background: white; border: 1px solid oklch(0.9 0 0); font-size: 0.8125rem; white-space: nowrap; } .dark .quick-stat-item { background: oklch(0.25 0 0); border-color: oklch(0.35 0 0); } /* ─── Section Header with Icon ─────────────────────────────────── */ .section-header-icon { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0; cursor: pointer; user-select: none; } .section-header-icon:hover { opacity: 0.8; } /* ─── Gradient Card Background ─────────────────────────────────── */ .gradient-card-bg { background: linear-gradient(135deg, oklch(0.97 0.02 155) 0%, oklch(0.98 0.01 175) 100%); border: 1px solid oklch(0.90 0.02 155); transition: all 0.3s ease; } .gradient-card-bg:hover { box-shadow: 0 4px 12px oklch(0.55 0.17 155 / 0.1); } .dark .gradient-card-bg { background: linear-gradient(135deg, oklch(0.18 0.02 260) 0%, oklch(0.16 0.01 155) 100%); border-color: oklch(0.30 0.02 260); } /* ─── Sparkline Mini Chart ─────────────────────────────────────── */ .sparkline-mini { display: inline-flex; align-items: flex-end; gap: 1px; height: 16px; } .sparkline-mini span { display: block; width: 2px; border-radius: 1px; background: oklch(0.55 0.17 155); transition: height 0.3s ease; } .dark .sparkline-mini span { background: oklch(0.65 0.17 155); } /* ─── Grade Color Badges (German 1-6 System) ──────────────────── */ .grade-badge-1 { background: linear-gradient(135deg, #10b981, #059669); color: white; border: 1px solid #059669; } .grade-badge-2 { background: linear-gradient(135deg, #14b8a6, #0d9488); color: white; border: 1px solid #0d9488; } .grade-badge-3 { background: linear-gradient(135deg, #f59e0b, #d97706); color: white; border: 1px solid #d97706; } .grade-badge-4 { background: linear-gradient(135deg, #f97316, #ea580c); color: white; border: 1px solid #ea580c; } .grade-badge-5 { background: linear-gradient(135deg, #f43f5e, #e11d48); color: white; border: 1px solid #e11d48; } .grade-badge-6 { background: linear-gradient(135deg, #dc2626, #b91c1c); color: white; border: 1px solid #b91c1c; } /* ─── Mastery Level Badges ─────────────────────────────────────── */ .mastery-badge-low { background: linear-gradient(135deg, #fda4af, #fb7185); color: #9f1239; border: 1px solid #fda4af; } .dark .mastery-badge-low { color: #fda4af; background: linear-gradient(135deg, rgba(253,164,175,0.15), rgba(251,113,133,0.15)); border-color: rgba(251,113,133,0.3); } .mastery-badge-medium { background: linear-gradient(135deg, #fde68a, #fbbf24); color: #92400e; border: 1px solid #fde68a; } .dark .mastery-badge-medium { color: #fde68a; background: linear-gradient(135deg, rgba(253,230,138,0.15), rgba(251,191,36,0.15)); border-color: rgba(251,191,36,0.3); } .mastery-badge-high { background: linear-gradient(135deg, #6ee7b7, #34d399); color: #065f46; border: 1px solid #6ee7b7; } .dark .mastery-badge-high { color: #6ee7b7; background: linear-gradient(135deg, rgba(110,231,183,0.15), rgba(52,211,153,0.15)); border-color: rgba(52,211,153,0.3); } /* ─── Newsletter Category Badge ────────────────────────────────── */ .category-badge { display: inline-flex; align-items: center; gap: 0.25rem; padding: 0.125rem 0.5rem; border-radius: 9999px; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; transition: all 0.2s ease; } .category-badge-general { background: oklch(0.95 0.01 260); color: oklch(0.35 0.02 260); } .dark .category-badge-general { background: oklch(0.22 0.02 260); color: oklch(0.75 0.02 260); } .category-badge-academic { background: #dbeafe; color: #1e40af; } .dark .category-badge-academic { background: rgba(59,130,246,0.15); color: #93c5fd; } .category-badge-sports { background: #dcfce7; color: #166534; } .dark .category-badge-sports { background: rgba(34,197,94,0.15); color: #86efac; } .category-badge-arts { background: #fae8ff; color: #86198f; } .dark .category-badge-arts { background: rgba(168,85,247,0.15); color: #d8b4fe; } .category-badge-events { background: #fef3c7; color: #92400e; } .dark .category-badge-events { background: rgba(245,158,11,0.15); color: #fcd34d; } .category-badge-community { background: #ffe4e6; color: #9f1239; } .dark .category-badge-community { background: rgba(244,63,94,0.15); color: #fda4af; } /* ─── Newsletter Preview Card ──────────────────────────────────── */ .newsletter-card { border-radius: 0.75rem; overflow: hidden; transition: all 0.3s ease; border: 1px solid oklch(0.90 0.01 155); background: white; } .newsletter-card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px oklch(0.55 0.17 155 / 0.1); } .dark .newsletter-card { background: oklch(0.18 0.015 260); border-color: oklch(0.30 0.015 260); } /* ─── Student Avatar Circle ────────────────────────────────────── */ .avatar-circle { display: inline-flex; align-items: center; justify-content: center; border-radius: 9999px; font-weight: 600; font-size: 0.75rem; line-height: 1; transition: all 0.2s ease; user-select: none; flex-shrink: 0; } .avatar-circle:hover { transform: scale(1.08); } /* ─── Student Photo Circle ─────────────────────────────────────── */ .avatar-photo { display: inline-flex; align-items: center; justify-content: center; border-radius: 9999px; overflow: hidden; transition: all 0.2s ease; flex-shrink: 0; } .avatar-photo img { width: 100%; height: 100%; object-fit: cover; } .avatar-photo:hover { transform: scale(1.08); box-shadow: 0 0 0 2px oklch(0.55 0.17 155); } /* ─── Animated Section Underline ───────────────────────────────── */ .animated-underline { position: relative; display: inline-block; } .animated-underline::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 0; height: 2px; background: linear-gradient(90deg, #10b981, #14b8a6); border-radius: 1px; transition: width 0.4s ease; } .animated-underline:hover::after { width: 100%; } /* ─── Count-up Animation ───────────────────────────────────────── */ @keyframes count-up-fade { 0% { opacity: 0; transform: translateY(8px); } 100% { opacity: 1; transform: translateY(0); } } .animate-count-up { animation: count-up-fade 0.6s ease-out forwards; } /* ─── Leaf Animation ───────────────────────────────────────────── */ @keyframes leaf-sway { 0%, 100% { transform: rotate(0deg); } 25% { transform: rotate(5deg); } 75% { transform: rotate(-5deg); } } .animate-leaf-sway { animation: leaf-sway 3s ease-in-out infinite; } /* ─── Staggered Card Entrance ──────────────────────────────────── */ @keyframes card-entrance { 0% { opacity: 0; transform: translateY(12px) scale(0.97); } 100% { opacity: 1; transform: translateY(0) scale(1); } } .animate-card-entrance { animation: card-entrance 0.4s ease-out forwards; } /* ─── Gradient Border for Class Cards ──────────────────────────── */ .gradient-border-card { position: relative; border-radius: 0.75rem; overflow: hidden; } .gradient-border-card::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, #10b981, #14b8a6); border-radius: 0.75rem 0.75rem 0 0; } /* ─── Task 9: Deep Styling Polish ──────────────────────────────────── */ /* Activity Timeline with animated dots */ .activity-timeline { position: relative; padding-left: 1.75rem; } .activity-timeline::before { content: ''; position: absolute; left: 0.55rem; top: 0.25rem; bottom: 0.25rem; width: 2px; background: linear-gradient(to bottom, oklch(0.55 0.17 155 / 0.3), oklch(0.55 0.17 155 / 0.08)); border-radius: 1px; } .activity-timeline-item { position: relative; padding-bottom: 1rem; } .activity-timeline-item::before { content: ''; position: absolute; left: -1.35rem; top: 0.4rem; width: 0.5rem; height: 0.5rem; border-radius: 50%; background: oklch(0.55 0.17 155); box-shadow: 0 0 0 3px oklch(0.55 0.17 155 / 0.15); transition: transform 0.2s ease, box-shadow 0.2s ease; } .activity-timeline-item:hover::before { transform: scale(1.4); box-shadow: 0 0 0 5px oklch(0.55 0.17 155 / 0.2); } .activity-timeline-item:last-child { padding-bottom: 0; } .dark .activity-timeline::before { background: linear-gradient(to bottom, oklch(0.65 0.17 155 / 0.3), oklch(0.65 0.17 155 / 0.08)); } .dark .activity-timeline-item::before { background: oklch(0.65 0.17 155); box-shadow: 0 0 0 3px oklch(0.65 0.17 155 / 0.2); } /* Gradient Card Header */ .card-header-gradient { position: relative; overflow: hidden; border-radius: 0.75rem 0.75rem 0 0; } .card-header-gradient::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, oklch(0.55 0.17 155 / 0.08) 0%, oklch(0.55 0.14 175 / 0.05) 100%); pointer-events: none; } .dark .card-header-gradient::before { background: linear-gradient(135deg, oklch(0.65 0.17 155 / 0.1) 0%, oklch(0.65 0.14 175 / 0.06) 100%); } /* Progress Ring (SVG-based) */ .progress-ring-circle { transition: stroke-dashoffset 0.6s ease-out; transform: rotate(-90deg); transform-origin: 50% 50%; } /* Glassmorphism Toolbar (for notebooks, editors) */ .glass-toolbar { background: oklch(1 0 0 / 0.75); backdrop-filter: blur(16px) saturate(180%); -webkit-backdrop-filter: blur(16px) saturate(180%); border: 1px solid oklch(1 0 0 / 0.35); box-shadow: 0 4px 16px -4px oklch(0 0 0 / 0.1), inset 0 0 0 1px oklch(1 0 0 / 0.2); border-radius: 0.75rem; } .dark .glass-toolbar { background: oklch(0.18 0.015 260 / 0.7); border-color: oklch(1 0 0 / 0.08); box-shadow: 0 4px 16px -4px oklch(0 0 0 / 0.4), inset 0 0 0 1px oklch(1 0 0 / 0.05); } /* Floating Action Button */ .fab { position: fixed; bottom: 5rem; right: 1.5rem; z-index: 30; display: flex; align-items: center; justify-content: center; width: 3.5rem; height: 3.5rem; border-radius: 9999px; background: linear-gradient(135deg, #10b981, #14b8a6); color: white; box-shadow: 0 6px 20px -4px oklch(0.55 0.17 155 / 0.45), 0 0 0 1px oklch(0.55 0.17 155 / 0.2); transition: transform 0.2s ease, box-shadow 0.2s ease; cursor: pointer; } .fab:hover { transform: translateY(-2px) scale(1.05); box-shadow: 0 10px 30px -6px oklch(0.55 0.17 155 / 0.5), 0 0 0 1px oklch(0.55 0.17 155 / 0.3); } .fab:active { transform: scale(0.95); } .dark .fab { box-shadow: 0 6px 20px -4px oklch(0 0 0 / 0.5), 0 0 0 1px oklch(0.65 0.17 155 / 0.3); background: linear-gradient(135deg, #10b981, #14b8a6); } .dark .fab:hover { box-shadow: 0 10px 30px -6px oklch(0 0 0 / 0.6), 0 0 0 1px oklch(0.65 0.17 155 / 0.4); } /* Notebook Cover Gradient Effects */ .notebook-cover { position: relative; overflow: hidden; border-radius: 0.75rem; } .notebook-cover::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 40%; background: linear-gradient(180deg, oklch(0.55 0.17 155 / 0.12) 0%, transparent 100%); pointer-events: none; transition: height 0.3s ease; } .notebook-cover:hover::before { height: 55%; } .dark .notebook-cover::before { background: linear-gradient(180deg, oklch(0.65 0.17 155 / 0.15) 0%, transparent 100%); } /* Grade Badge Color Coding */ .grade-badge-excellent { background: linear-gradient(135deg, oklch(0.55 0.17 155 / 0.15), oklch(0.55 0.14 175 / 0.1)); color: oklch(0.45 0.17 155); border: 1px solid oklch(0.55 0.17 155 / 0.25); } .dark .grade-badge-excellent { background: linear-gradient(135deg, oklch(0.65 0.17 155 / 0.2), oklch(0.65 0.14 175 / 0.15)); color: oklch(0.75 0.17 155); border-color: oklch(0.65 0.17 155 / 0.3); } .grade-badge-good { background: linear-gradient(135deg, oklch(0.55 0.14 175 / 0.15), oklch(0.60 0.16 195 / 0.1)); color: oklch(0.45 0.14 175); border: 1px solid oklch(0.55 0.14 175 / 0.25); } .dark .grade-badge-good { background: linear-gradient(135deg, oklch(0.65 0.14 175 / 0.2), oklch(0.70 0.16 195 / 0.15)); color: oklch(0.75 0.14 175); border-color: oklch(0.65 0.14 175 / 0.3); } .grade-badge-average { background: linear-gradient(135deg, oklch(0.72 0.19 85 / 0.15), oklch(0.72 0.19 85 / 0.1)); color: oklch(0.55 0.19 85); border: 1px solid oklch(0.72 0.19 85 / 0.25); } .dark .grade-badge-average { background: linear-gradient(135deg, oklch(0.72 0.19 85 / 0.2), oklch(0.72 0.19 85 / 0.15)); color: oklch(0.82 0.19 85); border-color: oklch(0.72 0.19 85 / 0.3); } .grade-badge-below { background: linear-gradient(135deg, oklch(0.65 0.22 15 / 0.15), oklch(0.65 0.22 15 / 0.1)); color: oklch(0.55 0.22 15); border: 1px solid oklch(0.65 0.22 15 / 0.25); } .dark .grade-badge-below { background: linear-gradient(135deg, oklch(0.65 0.22 15 / 0.2), oklch(0.65 0.22 15 / 0.15)); color: oklch(0.75 0.22 15); border-color: oklch(0.65 0.22 15 / 0.3); } /* Competence Flower Petal Animation */ @keyframes petal-bloom { 0% { transform: scale(0.3); opacity: 0; } 60% { transform: scale(1.05); opacity: 0.9; } 100% { transform: scale(1); opacity: 1; } } .animate-petal-bloom { animation: petal-bloom 0.6s ease-out backwards; } /* Radar Chart Gradient Fill */ .radar-gradient-fill { fill: oklch(0.55 0.17 155 / 0.2); stroke: oklch(0.55 0.17 155); stroke-width: 2; } .dark .radar-gradient-fill { fill: oklch(0.65 0.17 155 / 0.25); stroke: oklch(0.65 0.17 155); } /* Mastery Level Indicator */ .mastery-indicator { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.625rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; transition: transform 0.2s ease, box-shadow 0.2s ease; } .mastery-indicator:hover { transform: scale(1.05); } .mastery-indicator-1 { background: oklch(0.55 0.22 25 / 0.1); color: oklch(0.55 0.22 25); border: 1px solid oklch(0.55 0.22 25 / 0.2); } .mastery-indicator-2 { background: oklch(0.72 0.19 85 / 0.1); color: oklch(0.60 0.18 50); border: 1px solid oklch(0.72 0.19 85 / 0.2); } .mastery-indicator-3 { background: oklch(0.55 0.17 155 / 0.1); color: oklch(0.45 0.17 155); border: 1px solid oklch(0.55 0.17 155 / 0.2); } .mastery-indicator-4 { background: oklch(0.55 0.14 175 / 0.1); color: oklch(0.45 0.14 175); border: 1px solid oklch(0.55 0.14 175 / 0.2); } .dark .mastery-indicator-1 { background: oklch(0.55 0.22 25 / 0.15); color: oklch(0.75 0.19 22); border-color: oklch(0.55 0.22 25 / 0.3); } .dark .mastery-indicator-2 { background: oklch(0.72 0.19 85 / 0.15); color: oklch(0.82 0.19 85); border-color: oklch(0.72 0.19 85 / 0.3); } .dark .mastery-indicator-3 { background: oklch(0.65 0.17 155 / 0.15); color: oklch(0.75 0.17 155); border-color: oklch(0.65 0.17 155 / 0.3); } .dark .mastery-indicator-4 { background: oklch(0.65 0.14 175 / 0.15); color: oklch(0.75 0.14 175); border-color: oklch(0.65 0.14 175 / 0.3); } /* Animated Progress Bar with Gradient */ .progress-bar-animated { position: relative; height: 0.5rem; border-radius: 9999px; overflow: hidden; background: oklch(0.93 0.005 155); } .dark .progress-bar-animated { background: oklch(0.25 0.02 155); } .progress-bar-animated-fill { height: 100%; border-radius: 9999px; background: linear-gradient(90deg, #10b981, #14b8a6); transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1); position: relative; } .progress-bar-animated-fill::after { content: ''; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.3), transparent); animation: shimmer-progress 2s ease-in-out infinite; } /* Gradient Header Bar */ .header-gradient { background: linear-gradient(135deg, oklch(0.99 0.002 155) 0%, oklch(0.97 0.01 155) 50%, oklch(0.99 0.002 175) 100%); border-bottom: 1px solid oklch(0.93 0.005 155); } .dark .header-gradient { background: linear-gradient(135deg, oklch(0.15 0.01 260) 0%, oklch(0.13 0.01 260) 50%, oklch(0.15 0.015 155) 100%); border-bottom-color: oklch(1 0 0 / 8%); } /* Sidebar Active Indicator with Animated Underline */ .sidebar-active-indicator { position: relative; } .sidebar-active-indicator::after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 0; height: 2px; background: linear-gradient(90deg, #10b981, #14b8a6); border-radius: 1px; transition: width 0.3s ease; } .sidebar-active-indicator.active::after { width: 60%; } /* Notification Bell Pulse */ @keyframes bell-ring { 0% { transform: rotate(0deg); } 10% { transform: rotate(14deg); } 20% { transform: rotate(-12deg); } 30% { transform: rotate(10deg); } 40% { transform: rotate(-8deg); } 50% { transform: rotate(4deg); } 60% { transform: rotate(0deg); } 100% { transform: rotate(0deg); } } .animate-bell-ring { animation: bell-ring 0.8s ease-in-out; } /* Notification Badge Pulse */ @keyframes badge-pulse { 0%, 100% { box-shadow: 0 0 0 0 oklch(0.55 0.17 155 / 0.4); } 50% { box-shadow: 0 0 0 6px oklch(0.55 0.17 155 / 0); } } .animate-badge-pulse { animation: badge-pulse 2s ease-in-out infinite; } /* Card Shadow Transition on Hover */ .card-shadow-transition { transition: transform 0.2s ease-out, box-shadow 0.2s ease-out, border-color 0.2s ease-out; } .card-shadow-transition:hover { transform: translateY(-2px); box-shadow: 0 8px 24px -6px oklch(0.55 0.17 155 / 0.12), 0 0 0 1px oklch(0.55 0.17 155 / 0.06); border-color: oklch(0.55 0.17 155 / 0.2); } .dark .card-shadow-transition:hover { box-shadow: 0 8px 24px -6px oklch(0 0 0 / 0.4), 0 0 0 1px oklch(0.65 0.17 155 / 0.12); border-color: oklch(0.65 0.17 155 / 0.2); } /* Chart Gradient Fill */ .chart-gradient-fill { fill: url(#emeraldGradient); } /* Breadcrumb Current View Indicator */ .breadcrumb-active-view { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.75rem; border-radius: 0.5rem; background: linear-gradient(135deg, oklch(0.55 0.17 155 / 0.08), oklch(0.55 0.14 175 / 0.05)); color: oklch(0.45 0.17 155); font-weight: 600; font-size: 0.875rem; border: 1px solid oklch(0.55 0.17 155 / 0.12); } .dark .breadcrumb-active-view { background: linear-gradient(135deg, oklch(0.65 0.17 155 / 0.12), oklch(0.65 0.14 175 / 0.08)); color: oklch(0.75 0.17 155); border-color: oklch(0.65 0.17 155 / 0.2); } /* Student Grid Animation */ @keyframes student-appear { from { opacity: 0; transform: scale(0.9) translateY(4px); } to { opacity: 1; transform: scale(1) translateY(0); } } .animate-student-appear { animation: student-appear 0.3s ease-out backwards; } /* Enhanced Tooltip/Popover Styling */ .popover-enhanced { box-shadow: 0 8px 30px -6px oklch(0 0 0 / 0.12), 0 0 0 1px oklch(0.55 0.17 155 / 0.08); border-radius: 0.75rem; } .dark .popover-enhanced { box-shadow: 0 8px 30px -6px oklch(0 0 0 / 0.5), 0 0 0 1px oklch(0.65 0.17 155 / 0.12); } /* Gradient border for active class cards */ .class-card-active { position: relative; border: 2px solid transparent; background-clip: padding-box; } .class-card-active::before { content: ''; position: absolute; inset: -2px; border-radius: calc(0.75rem + 2px); background: linear-gradient(135deg, #10b981, #14b8a6, #10b981); z-index: -1; opacity: 0.6; transition: opacity 0.3s ease; } .class-card-active:hover::before { opacity: 1; } /* Report Card View - Badge shimmer animation */ @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } /* Report Card View - Print styles */ @media print { .report-card-print { box-shadow: none !important; border: 1px solid #e5e7eb !important; } .report-card-print * { color-adjust: exact; -webkit-print-color-adjust: exact; print-color-adjust: exact; } .no-print { display: none !important; } } /* Seating Chart - Desk hover glow */ @keyframes desk-glow { 0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); } 50% { box-shadow: 0 0 8px 2px rgba(16, 185, 129, 0.3); } } /* Seating Chart - Empty desk dashed border animation */ @keyframes dash-march { to { stroke-dashoffset: -12; } } /* Library - Book card hover lift */ .book-card-hover { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } .book-card-hover:hover { transform: translateY(-4px) scale(1.01); box-shadow: 0 12px 24px -8px rgba(16, 185, 129, 0.15), 0 4px 8px -2px rgba(0, 0, 0, 0.06); } /* Library - Availability pulse */ @keyframes availability-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } .availability-pulse { animation: availability-pulse 2s ease-in-out infinite; } /* Library - Overdue gradient border */ .overdue-gradient-border { position: relative; } .overdue-gradient-border::before { content: ''; position: absolute; inset: 0; border-radius: 0.5rem; padding: 2px; background: linear-gradient(135deg, #ef4444, #f97316, #ef4444); mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); mask-composite: exclude; -webkit-mask-composite: xor; pointer-events: none; } /* Parent Portal - Circular progress gradient */ @keyframes progress-fill-animate { from { stroke-dashoffset: var(--circumference); } to { stroke-dashoffset: var(--offset); } } /* Parent Portal - Tab transition */ .tab-content-enter { animation: tab-enter 0.3s ease-out; } @keyframes tab-enter { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } /* Glassmorphism card style */ .glass-card { background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.3); } .dark .glass-card { background: rgba(24, 24, 27, 0.7); border: 1px solid rgba(255, 255, 255, 0.06); } /* ─── Round 26: Attendance & Classes Enhancement Utilities ─── */ /* Attendance Gauge - Circular SVG gauge */ .attendance-gauge { position: relative; display: inline-flex; align-items: center; justify-content: center; } .attendance-gauge svg { transform: rotate(-90deg); } .attendance-gauge-track { fill: none; stroke: oklch(0.93 0.005 155); stroke-width: 6; } .dark .attendance-gauge-track { stroke: oklch(0.24 0.02 260); } .attendance-gauge-fill { fill: none; stroke-width: 6; stroke-linecap: round; animation: drawCircle 1.2s ease-out forwards; transition: stroke-dashoffset 0.6s ease-out; } .attendance-gauge-fill.rate-high { stroke: oklch(0.55 0.17 155); } .attendance-gauge-fill.rate-medium { stroke: oklch(0.72 0.19 85); } .attendance-gauge-fill.rate-low { stroke: oklch(0.577 0.245 27.325); } .attendance-gauge-label { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; transform: rotate(0deg); } /* Grade Indicator - Color-coded grade badge (1-6 German scale) */ .grade-indicator { display: inline-flex; align-items: center; justify-content: center; min-width: 1.75rem; height: 1.75rem; padding: 0 0.375rem; border-radius: 0.5rem; font-size: 0.75rem; font-weight: 700; line-height: 1; transition: transform 0.2s ease, box-shadow 0.2s ease; } .grade-indicator:hover { transform: scale(1.08); } .grade-indicator.grade-1 { background: oklch(0.55 0.17 155 / 0.15); color: oklch(0.45 0.17 155); border: 1px solid oklch(0.55 0.17 155 / 0.2); } .dark .grade-indicator.grade-1 { background: oklch(0.65 0.17 155 / 0.15); color: oklch(0.75 0.17 155); border-color: oklch(0.65 0.17 155 / 0.25); } .grade-indicator.grade-2 { background: oklch(0.53 0.14 175 / 0.15); color: oklch(0.43 0.14 175); border: 1px solid oklch(0.53 0.14 175 / 0.2); } .dark .grade-indicator.grade-2 { background: oklch(0.63 0.14 175 / 0.15); color: oklch(0.73 0.14 175); border-color: oklch(0.63 0.14 175 / 0.25); } .grade-indicator.grade-3 { background: oklch(0.72 0.19 85 / 0.15); color: oklch(0.62 0.19 85); border: 1px solid oklch(0.72 0.19 85 / 0.2); } .dark .grade-indicator.grade-3 { background: oklch(0.82 0.19 85 / 0.15); color: oklch(0.82 0.15 85); border-color: oklch(0.82 0.19 85 / 0.25); } .grade-indicator.grade-4 { background: oklch(0.75 0.15 60 / 0.15); color: oklch(0.65 0.15 60); border: 1px solid oklch(0.75 0.15 60 / 0.2); } .dark .grade-indicator.grade-4 { background: oklch(0.85 0.15 60 / 0.15); color: oklch(0.85 0.12 60); border-color: oklch(0.85 0.15 60 / 0.25); } .grade-indicator.grade-5 { background: oklch(0.65 0.2 40 / 0.15); color: oklch(0.55 0.2 40); border: 1px solid oklch(0.65 0.2 40 / 0.2); } .dark .grade-indicator.grade-5 { background: oklch(0.75 0.2 40 / 0.15); color: oklch(0.75 0.17 40); border-color: oklch(0.75 0.2 40 / 0.25); } .grade-indicator.grade-6 { background: oklch(0.577 0.245 27.325 / 0.15); color: oklch(0.477 0.245 27.325); border: 1px solid oklch(0.577 0.245 27.325 / 0.2); } .dark .grade-indicator.grade-6 { background: oklch(0.677 0.245 27.325 / 0.15); color: oklch(0.777 0.2 27.325); border-color: oklch(0.677 0.245 27.325 / 0.25); } /* Card Grid Auto - Auto-filling responsive grid for card layouts */ .card-grid-auto { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1rem; } @media (max-width: 640px) { .card-grid-auto { grid-template-columns: 1fr; } } /* Animate Count Up - Number counting animation */ .animate-count-up { animation: countUp 0.8s ease-out forwards; } /* Status Badge - Status indicator badge with variants */ .status-badge { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.25rem 0.625rem; border-radius: 9999px; font-size: 0.75rem; font-weight: 600; line-height: 1; border: 1px solid transparent; transition: transform 0.15s ease, box-shadow 0.15s ease; } .status-badge:hover { transform: scale(1.05); } .status-badge-present { background: oklch(0.55 0.17 155 / 0.12); color: oklch(0.45 0.17 155); border-color: oklch(0.55 0.17 155 / 0.2); } .dark .status-badge-present { background: oklch(0.65 0.17 155 / 0.15); color: oklch(0.75 0.17 155); border-color: oklch(0.65 0.17 155 / 0.25); } .status-badge-late { background: oklch(0.72 0.19 85 / 0.12); color: oklch(0.62 0.19 85); border-color: oklch(0.72 0.19 85 / 0.2); } .dark .status-badge-late { background: oklch(0.82 0.19 85 / 0.15); color: oklch(0.82 0.15 85); border-color: oklch(0.82 0.19 85 / 0.25); } .status-badge-absent { background: oklch(0.577 0.245 27.325 / 0.12); color: oklch(0.477 0.245 27.325); border-color: oklch(0.577 0.245 27.325 / 0.2); } .dark .status-badge-absent { background: oklch(0.677 0.245 27.325 / 0.15); color: oklch(0.777 0.2 27.325); border-color: oklch(0.677 0.245 27.325 / 0.25); } .status-badge-excused { background: oklch(0.72 0.15 85 / 0.12); color: oklch(0.62 0.15 85); border-color: oklch(0.72 0.15 85 / 0.2); } .dark .status-badge-excused { background: oklch(0.82 0.15 85 / 0.15); color: oklch(0.82 0.12 85); border-color: oklch(0.82 0.15 85 / 0.25); } /* Keyframe: countUp - Number counting up */ @keyframes countUp { 0% { opacity: 0; transform: translateY(8px); } 60% { opacity: 1; } 100% { opacity: 1; transform: translateY(0); } } /* Keyframe: drawCircle - SVG circle stroke animation */ @keyframes drawCircle { from { stroke-dashoffset: var(--circumference, 251); } to { stroke-dashoffset: var(--offset, 0); } } /* Keyframe: fadeInScale - Fade in with scale */ @keyframes fadeInScale { from { opacity: 0; transform: scale(0.92); } to { opacity: 1; transform: scale(1); } } /* Glassmorphism enhanced card */ .glass-card-enhanced { background: rgba(255, 255, 255, 0.6); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.4); box-shadow: 0 4px 24px -4px rgba(16, 185, 129, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04); transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease; } .glass-card-enhanced:hover { transform: translateY(-3px); box-shadow: 0 12px 32px -8px rgba(16, 185, 129, 0.15), 0 2px 4px rgba(0, 0, 0, 0.06); border-color: rgba(16, 185, 129, 0.3); } .dark .glass-card-enhanced { background: rgba(24, 24, 27, 0.6); border: 1px solid rgba(255, 255, 255, 0.06); box-shadow: 0 4px 24px -4px rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.2); } .dark .glass-card-enhanced:hover { transform: translateY(-3px); box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(16, 185, 129, 0.12); border-color: rgba(16, 185, 129, 0.15); } /* Gradient header banner */ .gradient-header-banner { background: linear-gradient(135deg, oklch(0.55 0.17 155 / 0.08) 0%, oklch(0.53 0.14 175 / 0.06) 50%, oklch(0.55 0.17 155 / 0.03) 100%); border-bottom: 1px solid oklch(0.55 0.17 155 / 0.1); } .dark .gradient-header-banner { background: linear-gradient(135deg, oklch(0.65 0.17 155 / 0.12) 0%, oklch(0.63 0.14 175 / 0.08) 50%, oklch(0.65 0.17 155 / 0.04) 100%); border-bottom-color: oklch(0.65 0.17 155 / 0.15); } /* Mini calendar date picker */ .mini-calendar-day { width: 2rem; height: 2rem; display: flex; align-items: center; justify-content: center; border-radius: 0.5rem; font-size: 0.75rem; font-weight: 500; cursor: pointer; transition: all 0.15s ease; } .mini-calendar-day:hover { background: oklch(0.55 0.17 155 / 0.1); color: oklch(0.35 0.17 155); } .dark .mini-calendar-day:hover { background: oklch(0.65 0.17 155 / 0.15); color: oklch(0.85 0.17 155); } .mini-calendar-day.selected { background: oklch(0.55 0.17 155); color: white; box-shadow: 0 2px 8px -2px oklch(0.55 0.17 155 / 0.4); } .dark .mini-calendar-day.selected { background: oklch(0.65 0.17 155); } .mini-calendar-day.today { border: 1.5px solid oklch(0.55 0.17 155); font-weight: 700; } .dark .mini-calendar-day.today { border-color: oklch(0.65 0.17 155); } .mini-calendar-day.has-session { position: relative; } .mini-calendar-day.has-session::after { content: ''; position: absolute; bottom: 2px; width: 4px; height: 4px; border-radius: 50%; background: oklch(0.55 0.17 155); } .dark .mini-calendar-day.has-session::after { background: oklch(0.65 0.17 155); } /* Attendance timeline dot */ .timeline-dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); transition: transform 0.2s ease; } .timeline-dot:hover { transform: scale(1.3); } .dark .timeline-dot { border-color: rgba(24, 24, 27, 0.8); box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.1); } /* Quick action button */ .quick-action-btn { display: inline-flex; align-items: center; gap: 0.375rem; padding: 0.375rem 0.75rem; border-radius: 0.5rem; font-size: 0.75rem; font-weight: 600; border: 1px solid oklch(0.93 0.005 155); background: oklch(0.99 0.002 155); color: oklch(0.35 0.01 260); transition: all 0.2s ease; cursor: pointer; } .quick-action-btn:hover { background: oklch(0.55 0.17 155 / 0.08); border-color: oklch(0.55 0.17 155 / 0.2); color: oklch(0.45 0.17 155); transform: translateY(-1px); box-shadow: 0 2px 8px -2px oklch(0.55 0.17 155 / 0.2); } .dark .quick-action-btn { border-color: oklch(0.24 0.02 260); background: oklch(0.18 0.015 260); color: oklch(0.75 0.005 260); } .dark .quick-action-btn:hover { background: oklch(0.65 0.17 155 / 0.12); border-color: oklch(0.65 0.17 155 / 0.25); color: oklch(0.85 0.17 155); box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.3); } }