mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 06:15:39 -04:00
Replace client-side session checks (useSession + router.replace) with a two-layer server-side approach: Next.js middleware performs a fast cookie presence check for all protected routes, and the (pages) layout does a full server-side session validation before rendering. Move login/register into a dedicated (auth) route group with its own minimal layout so they sit outside the authenticated shell. Lift the Toaster to the root layout so it remains available across all route groups.
216 lines
5.7 KiB
CSS
216 lines
5.7 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
@import "shadcn/tailwind.css";
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
|
|
@theme inline {
|
|
--color-background: var(--background);
|
|
--color-foreground: var(--foreground);
|
|
--font-sans: var(--font-dm-sans);
|
|
--font-mono: var(--font-geist-mono);
|
|
--font-display: var(--font-dm-serif);
|
|
--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);
|
|
--radius-2xl: calc(var(--radius) + 8px);
|
|
--radius-3xl: calc(var(--radius) + 12px);
|
|
--radius-4xl: calc(var(--radius) + 16px);
|
|
--color-status-watchlist: var(--status-watchlist);
|
|
--color-status-watching: var(--status-watching);
|
|
--color-status-completed: var(--status-completed);
|
|
}
|
|
|
|
/* Dark cinema — warm charcoal base, amber accent light */
|
|
:root {
|
|
--background: oklch(0.13 0.006 55);
|
|
--foreground: oklch(0.93 0.015 80);
|
|
--card: oklch(0.19 0.008 55);
|
|
--card-foreground: oklch(0.93 0.015 80);
|
|
--popover: oklch(0.21 0.008 55);
|
|
--popover-foreground: oklch(0.93 0.015 80);
|
|
--primary: oklch(0.8 0.14 65);
|
|
--primary-foreground: oklch(0.13 0.006 55);
|
|
--secondary: oklch(0.22 0.008 55);
|
|
--secondary-foreground: oklch(0.85 0.02 80);
|
|
--muted: oklch(0.22 0.008 55);
|
|
--muted-foreground: oklch(0.63 0.02 80);
|
|
--accent: oklch(0.25 0.01 55);
|
|
--accent-foreground: oklch(0.93 0.015 80);
|
|
--destructive: oklch(0.65 0.2 25);
|
|
--border: oklch(1 0.015 65 / 10%);
|
|
--input: oklch(1 0 0 / 12%);
|
|
--ring: oklch(0.8 0.14 65);
|
|
--chart-1: oklch(0.8 0.14 65);
|
|
--chart-2: oklch(0.65 0.15 30);
|
|
--chart-3: oklch(0.58 0.12 260);
|
|
--chart-4: oklch(0.72 0.1 160);
|
|
--chart-5: oklch(0.63 0.15 310);
|
|
--radius: 0.625rem;
|
|
--sidebar: oklch(0.11 0.006 55);
|
|
--sidebar-foreground: oklch(0.93 0.015 80);
|
|
--sidebar-primary: oklch(0.8 0.14 65);
|
|
--sidebar-primary-foreground: oklch(0.13 0.006 55);
|
|
--sidebar-accent: oklch(0.22 0.008 55);
|
|
--sidebar-accent-foreground: oklch(0.93 0.015 80);
|
|
--sidebar-border: oklch(1 0.015 65 / 10%);
|
|
--sidebar-ring: oklch(0.8 0.14 65);
|
|
--status-watchlist: oklch(0.72 0.12 220);
|
|
--status-watching: oklch(0.78 0.14 65);
|
|
--status-completed: oklch(0.75 0.14 155);
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border outline-ring/50;
|
|
}
|
|
body {
|
|
@apply bg-background text-foreground antialiased;
|
|
}
|
|
|
|
/* https://ui.shadcn.com/docs/components/radix/button#cursor */
|
|
button:not(:disabled),
|
|
[role="button"]:not(:disabled) {
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
/* Film grain texture overlay */
|
|
body::before {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
z-index: 9999;
|
|
pointer-events: none;
|
|
opacity: 0.015;
|
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
|
|
}
|
|
|
|
/* Custom keyframe animations */
|
|
@keyframes card-enter {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(12px) scale(0.98);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0) scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes check-pop {
|
|
0% {
|
|
transform: scale(0);
|
|
}
|
|
60% {
|
|
transform: scale(1.15);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes star-fill {
|
|
0% {
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
transform: scale(1.25);
|
|
}
|
|
100% {
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
|
|
@keyframes gentle-float {
|
|
0%,
|
|
100% {
|
|
transform: translateY(0);
|
|
}
|
|
50% {
|
|
transform: translateY(-6px);
|
|
}
|
|
}
|
|
|
|
/* Warm skeleton pulse override */
|
|
@keyframes warm-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 1;
|
|
}
|
|
50% {
|
|
opacity: 0.4;
|
|
}
|
|
}
|
|
|
|
[data-slot="skeleton"] {
|
|
animation: warm-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
|
|
background: oklch(0.25 0.01 55);
|
|
}
|
|
|
|
/* Scrollbar styling */
|
|
::-webkit-scrollbar {
|
|
width: 6px;
|
|
height: 6px;
|
|
}
|
|
::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
::-webkit-scrollbar-thumb {
|
|
background: oklch(1 0 0 / 15%);
|
|
border-radius: 3px;
|
|
}
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: oklch(1 0 0 / 25%);
|
|
}
|
|
|
|
/* Horizontal scroll row for feeds */
|
|
.feed-scroll {
|
|
scrollbar-width: none;
|
|
-ms-overflow-style: none;
|
|
}
|
|
.feed-scroll::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
/* Utility animations */
|
|
.animate-gentle-float {
|
|
animation: gentle-float 3s ease-in-out infinite;
|
|
}
|
|
.animate-check-pop {
|
|
animation: check-pop 0.3s ease-out;
|
|
}
|
|
.animate-star-fill {
|
|
animation: star-fill 0.3s ease-out;
|
|
}
|