Import source: src/app/globals
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,547 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
/* Porcelain light theme */
|
||||
--background: 220 20% 96%;
|
||||
--foreground: 224 18% 12%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 224 18% 12%;
|
||||
--primary: 224 88% 53%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 220 14% 92%;
|
||||
--secondary-foreground: 224 18% 14%;
|
||||
--muted: 220 14% 93%;
|
||||
--muted-foreground: 224 8% 44%;
|
||||
--accent: 30 100% 48%;
|
||||
--accent-foreground: 224 18% 12%;
|
||||
--destructive: 4 74% 49%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--success: 154 84% 30%;
|
||||
--warning: 31 95% 42%;
|
||||
--border: 220 12% 86%;
|
||||
--input: 220 12% 86%;
|
||||
--ring: 224 88% 53%;
|
||||
|
||||
/* Aurora companions (hue triplets) */
|
||||
--aurora-a: 224 88% 60%;
|
||||
--aurora-b: 200 80% 55%;
|
||||
--aurora-c: 0 0% 70%;
|
||||
--aurora-opacity: 0.18;
|
||||
|
||||
/* Liquid glass */
|
||||
--glass-alpha: 0.78;
|
||||
--glass-blur: 3px;
|
||||
--glass-saturate: 112%;
|
||||
--glass-edge-alpha: 0.7;
|
||||
|
||||
--radius: 12px;
|
||||
--sidebar-width: 256px;
|
||||
--header-height: 56px;
|
||||
}
|
||||
|
||||
/* Pitch-black dark theme — strictly neutral grays, zero hue cast.
|
||||
* Color enters only through the user-selected accent. */
|
||||
.dark {
|
||||
--background: 0 0% 0%;
|
||||
--foreground: 0 0% 96%;
|
||||
--card: 0 0% 10%;
|
||||
--card-foreground: 0 0% 95%;
|
||||
--primary: 222 95% 63%;
|
||||
--primary-foreground: 0 0% 100%;
|
||||
--secondary: 0 0% 14%;
|
||||
--secondary-foreground: 0 0% 95%;
|
||||
--muted: 0 0% 12%;
|
||||
--muted-foreground: 0 0% 64%;
|
||||
--accent: 31 100% 54%;
|
||||
--accent-foreground: 0 0% 0%;
|
||||
--destructive: 4 78% 56%;
|
||||
--destructive-foreground: 0 0% 100%;
|
||||
--success: 154 70% 44%;
|
||||
--warning: 36 95% 56%;
|
||||
--border: 0 0% 17%;
|
||||
--input: 0 0% 17%;
|
||||
--ring: 222 95% 63%;
|
||||
|
||||
--aurora-opacity: 0.16;
|
||||
--glass-alpha: 0.62;
|
||||
--glass-edge-alpha: 0.14;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Accent presets — applied as data-accent on <html>.
|
||||
* ------------------------------------------------------------------------- */
|
||||
[data-accent="violet"] {
|
||||
--primary: 261 78% 56%;
|
||||
--ring: 261 78% 56%;
|
||||
--aurora-a: 261 80% 62%;
|
||||
}
|
||||
.dark[data-accent="violet"] {
|
||||
--primary: 260 90% 67%;
|
||||
--ring: 260 90% 67%;
|
||||
}
|
||||
|
||||
[data-accent="emerald"] {
|
||||
--primary: 161 92% 30%;
|
||||
--ring: 161 92% 30%;
|
||||
--aurora-a: 160 80% 45%;
|
||||
}
|
||||
.dark[data-accent="emerald"] {
|
||||
--primary: 158 68% 44%;
|
||||
--ring: 158 68% 44%;
|
||||
}
|
||||
|
||||
[data-accent="sunset"] {
|
||||
--primary: 24 94% 50%;
|
||||
--primary-foreground: 24 90% 98%;
|
||||
--ring: 24 94% 50%;
|
||||
--aurora-a: 24 94% 55%;
|
||||
}
|
||||
.dark[data-accent="sunset"] {
|
||||
--primary: 26 96% 56%;
|
||||
--primary-foreground: 24 95% 7%;
|
||||
--ring: 26 96% 56%;
|
||||
}
|
||||
|
||||
[data-accent="rose"] {
|
||||
--primary: 345 82% 51%;
|
||||
--ring: 345 82% 51%;
|
||||
--aurora-a: 345 85% 60%;
|
||||
}
|
||||
.dark[data-accent="rose"] {
|
||||
--primary: 347 90% 64%;
|
||||
--ring: 347 90% 64%;
|
||||
}
|
||||
|
||||
[data-accent="cyan"] {
|
||||
--primary: 196 95% 38%;
|
||||
--ring: 196 95% 38%;
|
||||
--aurora-a: 196 95% 50%;
|
||||
}
|
||||
.dark[data-accent="cyan"] {
|
||||
--primary: 194 92% 52%;
|
||||
--primary-foreground: 200 95% 6%;
|
||||
--ring: 194 92% 52%;
|
||||
}
|
||||
|
||||
/* In dark mode the ambient companions are strictly monochrome — only the
|
||||
* primary blob carries the accent hue. Declared after the accent presets so
|
||||
* it wins regardless of the selected accent. */
|
||||
.dark {
|
||||
--aurora-b: 0 0% 55%;
|
||||
--aurora-c: 0 0% 35%;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Glass intensity — applied as data-glass on <html>.
|
||||
* ------------------------------------------------------------------------- */
|
||||
[data-glass="off"] {
|
||||
--glass-alpha: 1;
|
||||
--glass-blur: 0px;
|
||||
--glass-saturate: 100%;
|
||||
}
|
||||
[data-glass="subtle"] {
|
||||
--glass-alpha: 0.86;
|
||||
--glass-blur: 2px;
|
||||
--glass-saturate: 108%;
|
||||
}
|
||||
[data-glass="heavy"] {
|
||||
--glass-alpha: 0.54;
|
||||
--glass-blur: 10px;
|
||||
--glass-saturate: 135%;
|
||||
}
|
||||
.dark[data-glass="subtle"] {
|
||||
--glass-alpha: 0.76;
|
||||
}
|
||||
.dark[data-glass="heavy"] {
|
||||
--glass-alpha: 0.34;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Corner radius — applied as data-radius on <html>.
|
||||
* ------------------------------------------------------------------------- */
|
||||
[data-radius="sharp"] {
|
||||
--radius: 6px;
|
||||
}
|
||||
[data-radius="soft"] {
|
||||
--radius: 18px;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Base
|
||||
* ------------------------------------------------------------------------- */
|
||||
* {
|
||||
border-color: hsl(var(--border));
|
||||
}
|
||||
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: hsl(var(--border)) transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: hsl(var(--border));
|
||||
border: 3px solid transparent;
|
||||
border-radius: 999px;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: hsl(var(--muted-foreground) / 0.55);
|
||||
border: 3px solid transparent;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
html {
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100%;
|
||||
background: hsl(var(--background));
|
||||
color: hsl(var(--foreground));
|
||||
font-feature-settings:
|
||||
"rlig" 1,
|
||||
"calt" 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: hsl(var(--primary) / 0.22);
|
||||
}
|
||||
|
||||
kbd {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-bottom-width: 2px;
|
||||
border-radius: 6px;
|
||||
background: hsl(var(--muted) / 0.8);
|
||||
padding: 1px 6px;
|
||||
font-family: var(--font-mono), ui-monospace, monospace;
|
||||
font-size: 11px;
|
||||
color: hsl(var(--muted-foreground));
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
::before,
|
||||
::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
scroll-behavior: auto !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
|
||||
.focus-ring {
|
||||
@apply outline-none ring-offset-2 ring-offset-background focus-visible:ring-2 focus-visible:ring-ring;
|
||||
}
|
||||
|
||||
.density-compact {
|
||||
--header-height: 56px;
|
||||
}
|
||||
|
||||
.density-comfortable {
|
||||
--header-height: 64px;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Liquid glass surfaces — iOS-style: translucent fill, saturated backdrop
|
||||
* blur, and a refraction ring made of four inset specular edges (bright top,
|
||||
* faint sides and bottom).
|
||||
* ------------------------------------------------------------------------- */
|
||||
@layer components {
|
||||
.glass-panel {
|
||||
position: relative;
|
||||
background:
|
||||
linear-gradient(
|
||||
180deg,
|
||||
hsl(0 0% 100% / 0.09),
|
||||
hsl(0 0% 100% / 0.02) 38%,
|
||||
transparent 70%
|
||||
),
|
||||
hsl(var(--card) / var(--glass-alpha));
|
||||
-webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
|
||||
border: 1px solid hsl(var(--border) / 0.7);
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.3)),
|
||||
inset 1px 0 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.2)),
|
||||
inset -1px 0 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.2)),
|
||||
0 1px 2px rgb(0 0 0 / 0.06),
|
||||
0 16px 40px -24px rgb(0 0 0 / 0.3);
|
||||
}
|
||||
|
||||
.dark .glass-panel {
|
||||
border-color: hsl(0 0% 100% / 0.1);
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.3)),
|
||||
inset 1px 0 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.2)),
|
||||
inset -1px 0 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.2)),
|
||||
0 1px 2px rgb(0 0 0 / 0.5),
|
||||
0 20px 48px -28px rgb(0 0 0 / 0.85);
|
||||
}
|
||||
|
||||
/* Chrome surfaces: floating header + sidebar rails. */
|
||||
.glass-bar {
|
||||
background:
|
||||
linear-gradient(
|
||||
180deg,
|
||||
hsl(0 0% 100% / 0.08),
|
||||
hsl(0 0% 100% / 0.02) 45%,
|
||||
transparent 75%
|
||||
),
|
||||
hsl(var(--card) / min(calc(var(--glass-alpha) + 0.12), 0.96));
|
||||
-webkit-backdrop-filter: blur(calc(var(--glass-blur) + 1px)) saturate(var(--glass-saturate));
|
||||
backdrop-filter: blur(calc(var(--glass-blur) + 1px)) saturate(var(--glass-saturate));
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.25)),
|
||||
0 12px 32px -20px rgb(0 0 0 / 0.45);
|
||||
}
|
||||
|
||||
.dark .glass-bar {
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.25)),
|
||||
0 12px 36px -18px rgb(0 0 0 / 0.9);
|
||||
}
|
||||
|
||||
/* Floating surfaces: dialogs, popovers, menus. Most opaque. */
|
||||
.glass-modal {
|
||||
background:
|
||||
linear-gradient(180deg, hsl(0 0% 100% / 0.08), transparent 40%),
|
||||
hsl(var(--card) / min(calc(var(--glass-alpha) + 0.28), 1));
|
||||
-webkit-backdrop-filter: blur(calc(var(--glass-blur) + 2px)) saturate(var(--glass-saturate));
|
||||
backdrop-filter: blur(calc(var(--glass-blur) + 2px)) saturate(var(--glass-saturate));
|
||||
border: 1px solid hsl(var(--border) / 0.75);
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.3)),
|
||||
0 24px 64px -24px rgb(0 0 0 / 0.5);
|
||||
}
|
||||
|
||||
.dark .glass-modal {
|
||||
border-color: hsl(0 0% 100% / 0.12);
|
||||
box-shadow:
|
||||
inset 0 1px 0 0 hsl(0 0% 100% / var(--glass-edge-alpha)),
|
||||
inset 0 -1px 0 0 hsl(0 0% 100% / calc(var(--glass-edge-alpha) * 0.3)),
|
||||
0 24px 72px -20px rgb(0 0 0 / 0.95);
|
||||
}
|
||||
|
||||
.text-gradient {
|
||||
background: linear-gradient(100deg, hsl(var(--foreground)) 35%, hsl(var(--primary)) 140%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.skeleton {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: hsl(var(--muted) / 0.7);
|
||||
}
|
||||
|
||||
.skeleton::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform: translateX(-100%);
|
||||
background: linear-gradient(90deg, transparent, hsl(var(--foreground) / 0.07), transparent);
|
||||
animation: shimmer 1.6s infinite;
|
||||
}
|
||||
}
|
||||
|
||||
/* Legacy shadow helpers, softened to match the glass language. */
|
||||
.dark .shadow-panel {
|
||||
box-shadow: 0 1px 0 hsl(var(--border) / 0.7);
|
||||
}
|
||||
|
||||
.dark .shadow-raised {
|
||||
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.72);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Ambient background: aurora blobs + grid + grain.
|
||||
* Hidden entirely when data-ambiance="off".
|
||||
* ------------------------------------------------------------------------- */
|
||||
.aurora {
|
||||
position: absolute;
|
||||
border-radius: 9999px;
|
||||
filter: blur(52px);
|
||||
opacity: var(--aurora-opacity);
|
||||
}
|
||||
|
||||
.aurora-1 {
|
||||
top: -22vh;
|
||||
left: -12vw;
|
||||
height: 60vh;
|
||||
width: 46vw;
|
||||
min-width: 420px;
|
||||
min-height: 420px;
|
||||
background: radial-gradient(closest-side, hsl(var(--aurora-a) / 0.7), transparent 70%);
|
||||
animation: aurora-drift-1 48s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.aurora-2 {
|
||||
top: 4vh;
|
||||
right: -16vw;
|
||||
height: 56vh;
|
||||
width: 42vw;
|
||||
min-width: 380px;
|
||||
min-height: 380px;
|
||||
background: radial-gradient(closest-side, hsl(var(--aurora-b) / 0.4), transparent 70%);
|
||||
animation: aurora-drift-2 58s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.aurora-3 {
|
||||
bottom: -26vh;
|
||||
left: 24vw;
|
||||
height: 54vh;
|
||||
width: 44vw;
|
||||
min-width: 380px;
|
||||
min-height: 380px;
|
||||
background: radial-gradient(closest-side, hsl(var(--aurora-c) / 0.3), transparent 70%);
|
||||
animation: aurora-drift-3 64s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.ambient-grid {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(hsl(var(--foreground) / 0.04) 1px, transparent 1px),
|
||||
linear-gradient(90deg, hsl(var(--foreground) / 0.04) 1px, transparent 1px);
|
||||
background-size: 56px 56px;
|
||||
-webkit-mask-image: radial-gradient(ellipse 90% 64% at 50% 0%, black 30%, transparent 75%);
|
||||
mask-image: radial-gradient(ellipse 90% 64% at 50% 0%, black 30%, transparent 75%);
|
||||
}
|
||||
|
||||
.grain {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160' viewBox='0 0 160 160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
|
||||
background-size: 160px 160px;
|
||||
opacity: 0.028;
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
.dark .grain {
|
||||
opacity: 0.06;
|
||||
}
|
||||
|
||||
[data-ambiance="off"] .aurora,
|
||||
[data-ambiance="off"] .ambient-grid,
|
||||
[data-ambiance="off"] .grain {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes aurora-drift-1 {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0) scale(1);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(10vw, 8vh, 0) scale(1.15);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aurora-drift-2 {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0) scale(1.1) rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(-8vw, 12vh, 0) scale(0.95) rotate(20deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes aurora-drift-3 {
|
||||
from {
|
||||
transform: translate3d(0, 0, 0) scale(1);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(-10vw, -8vh, 0) scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------
|
||||
* Motion: entrance choreography
|
||||
* ------------------------------------------------------------------------- */
|
||||
@keyframes rise {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(6px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
|
||||
.anim-rise {
|
||||
animation: rise 0.16s cubic-bezier(0.22, 0.61, 0.36, 1) both;
|
||||
}
|
||||
|
||||
.stagger > * {
|
||||
animation: rise 0.16s cubic-bezier(0.22, 0.61, 0.36, 1) both;
|
||||
}
|
||||
|
||||
.stagger > *:nth-child(1) {
|
||||
animation-delay: 0.02s;
|
||||
}
|
||||
.stagger > *:nth-child(2) {
|
||||
animation-delay: 0.03s;
|
||||
}
|
||||
.stagger > *:nth-child(3) {
|
||||
animation-delay: 0.05s;
|
||||
}
|
||||
.stagger > *:nth-child(4) {
|
||||
animation-delay: 0.07s;
|
||||
}
|
||||
.stagger > *:nth-child(5) {
|
||||
animation-delay: 0.08s;
|
||||
}
|
||||
.stagger > *:nth-child(6) {
|
||||
animation-delay: 0.09s;
|
||||
}
|
||||
.stagger > *:nth-child(7) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.stagger > *:nth-child(8) {
|
||||
animation-delay: 0.11s;
|
||||
}
|
||||
.stagger > *:nth-child(9) {
|
||||
animation-delay: 0.12s;
|
||||
}
|
||||
.stagger > *:nth-child(10) {
|
||||
animation-delay: 0.13s;
|
||||
}
|
||||
.stagger > *:nth-child(n + 11) {
|
||||
animation-delay: 0.14s;
|
||||
}
|
||||
Reference in New Issue
Block a user