Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/web/check_output.txt
Binary file not shown.
7 changes: 7 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@
"@sveltejs/adapter-auto": "^7.0.0",
"@sveltejs/kit": "^2.50.2",
"@sveltejs/vite-plugin-svelte": "^6.2.4",
"@tailwindcss/vite": "^4.3.0",
"autoprefixer": "^10.5.0",
"clsx": "^2.1.1",
"lucide-svelte": "^1.0.1",
"postcss": "^8.5.14",
"svelte": "^5.51.0",
"svelte-check": "^4.4.2",
"tailwind-merge": "^3.6.0",
"tailwindcss": "^4.3.0",
"typescript": "^5.9.3",
"vite": "^7.3.1"
}
Expand Down
314 changes: 137 additions & 177 deletions apps/web/src/app.css
Original file line number Diff line number Diff line change
@@ -1,184 +1,144 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Outfit:wght@500;600;700;800;900&display=swap');

:root {
/* Primary Palette */
--primary: #6366f1;
--primary-glow: rgba(99, 102, 241, 0.4);
--accent: #a855f7;
--accent-glow: rgba(168, 85, 247, 0.35);

/* Backgrounds */
--bg-primary: #ffffff;
--bg-secondary: #f8fafc;
--bg-page: #f5f8ff;
--bg-glass: rgba(255, 255, 255, 0.75);
--bg-card: #ffffff;

/* Text */
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #64748b;

/* Effects */
--border: rgba(226, 232, 240, 0.9);
--border-glass: rgba(255, 255, 255, 0.35);
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 6px 18px -8px rgb(0 0 0 / 0.12), 0 4px 14px -12px rgb(0 0 0 / 0.08);
--shadow-lg: 0 12px 24px -10px rgb(0 0 0 / 0.15), 0 6px 12px -14px rgb(0 0 0 / 0.08);

--radius: 14px;
--radius-lg: 26px;
--radius-xl: 34px;

--theme-transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

html.dark {
--bg-primary: #020617;
--bg-secondary: #0f172a;
--bg-page: #050b18;
--bg-glass: rgba(15, 23, 42, 0.72);
--bg-card: #0f172a;

--text-primary: #f8fafc;
--text-secondary: #cbd5e1;
--text-muted: #64748b;

--border: rgba(30, 41, 59, 0.85);
--border-glass: rgba(255, 255, 255, 0.12);
}

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: 'Inter', sans-serif;
background: radial-gradient(circle at top, rgba(99, 102, 241, 0.08), transparent 22%), var(--bg-page);
color: var(--text-primary);
transition: var(--theme-transition);
-webkit-font-smoothing: antialiased;
min-height: 100vh;
overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 {
font-family: 'Outfit', sans-serif;
font-weight: 700;
line-height: 1.15;
}

a {
color: inherit;
text-decoration: none;
transition: var(--theme-transition);
}

button,
.btn-primary,
.btn-secondary {
transition: transform 0.24s ease, box-shadow 0.24s ease, background-color 0.24s ease, border-color 0.24s ease, color 0.24s ease;
}

button {
font: inherit;
}

.glass {
background: var(--bg-glass);
backdrop-filter: blur(18px);
-webkit-backdrop-filter: blur(18px);
border: 1px solid var(--border-glass);
}

.gradient-text {
background: linear-gradient(135deg, var(--primary), var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}

.btn-primary {
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, var(--primary), var(--accent));
color: white;
padding: 0.95rem 1.85rem;
border-radius: calc(var(--radius) * 1.2);
font-weight: 700;
box-shadow: 0 18px 35px -18px rgba(99, 102, 241, 0.9);
border: none;
cursor: pointer;
}

.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 22px 40px -16px rgba(99, 102, 241, 0.9);
}

.btn-primary:focus-visible {
outline: 3px solid rgba(99, 102, 241, 0.35);
outline-offset: 3px;
}

.btn-secondary {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0.85rem 1.75rem;
border-radius: calc(var(--radius) * 1.2);
font-weight: 700;
border: 1px solid rgba(255, 255, 255, 0.14);
background: rgba(255, 255, 255, 0.08);
color: var(--text-primary);
cursor: pointer;
}

.btn-secondary:hover {
background: rgba(255, 255, 255, 0.14);
border-color: rgba(99, 102, 241, 0.45);
}

.btn-secondary:focus-visible {
outline: 3px solid rgba(99, 102, 241, 0.18);
outline-offset: 3px;
}

/* ---------- Custom themed scrollbar (issue #151) ---------- */

/* Firefox */
html {
scrollbar-width: thin;
scrollbar-color: var(--primary) var(--bg-secondary);
}

/* WebKit (Chromium, Safari, Edge) */
@import "tailwindcss";

@theme {
--color-primary: #7C3AED;
--color-secondary: #06B6D4;
--color-accent-pink: #EC4899;
--color-accent-blue: #3B82F6;
--color-dark-950: #030712;
--color-dark-900: #0B1020;

--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
--font-display: "Space Grotesk", sans-serif;

--radius-xl: 1.5rem;
--radius-2xl: 2rem;
--radius-3xl: 3rem;
}

@layer base {
:root {
--bg-main: #f8fafc;
--bg-secondary: #ffffff;
--text-main: #0f172a;
--text-muted: #64748b;
--border-main: #e2e8f0;
--glass-bg: rgba(255, 255, 255, 0.7);
--glass-border: rgba(255, 255, 255, 0.5);
--primary-glow: rgba(124, 58, 237, 0.2);
}

.dark {
--bg-main: #030712;
--bg-secondary: #0B1020;
--text-main: #f8fafc;
--text-muted: #94a3b8;
--border-main: #1f2937;
--glass-bg: rgba(3, 7, 18, 0.6);
--glass-border: rgba(255, 255, 255, 0.08);
--primary-glow: rgba(124, 58, 237, 0.3);
}

body {
@apply bg-(--bg-main) text-(--text-main) transition-colors duration-500 antialiased font-sans overflow-x-hidden;
}
}

@utility glass {
backdrop-filter: blur(20px) saturate(180%);
background-color: var(--glass-bg);
border: 1px solid var(--glass-border);
}

@utility glass-morphic {
@apply glass shadow-[0_8px_32px_0_rgba(31,38,135,0.07)];
}

@utility text-gradient {
@apply bg-clip-text text-transparent bg-linear-to-r from-primary via-secondary to-accent-pink;
}

@layer components {
.mesh-bg {
@apply absolute inset-0 -z-20 opacity-40;
background-image:
radial-gradient(at 0% 0%, rgba(124, 58, 237, 0.15) 0px, transparent 50%),
radial-gradient(at 100% 0%, rgba(6, 182, 212, 0.15) 0px, transparent 50%),
radial-gradient(at 100% 100%, rgba(236, 72, 153, 0.15) 0px, transparent 50%),
radial-gradient(at 0% 100%, rgba(59, 130, 246, 0.15) 0px, transparent 50%);
filter: blur(100px);
animation: mesh 20s ease infinite;
}

.card-cinematic {
@apply glass-morphic rounded-3xl p-8 transition-all duration-700 hover:-translate-y-2 hover:shadow-2xl hover:shadow-primary/20 relative overflow-hidden;
}

.btn-premium-primary {
@apply relative inline-flex items-center justify-center rounded-2xl font-black uppercase tracking-widest text-white transition-all duration-500 overflow-hidden;
background: linear-gradient(135deg, var(--color-primary), var(--color-accent-pink));
box-shadow: 0 4px 15px rgba(124, 58, 237, 0.4);
}
.btn-premium-primary:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 8px 25px rgba(124, 58, 237, 0.6);
}

.btn-premium-secondary {
@apply relative inline-flex items-center justify-center rounded-2xl font-black uppercase tracking-widest transition-all duration-500 overflow-hidden;
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(124, 58, 237, 0.3);
color: var(--color-primary);
backdrop-filter: blur(10px);
}
.btn-premium-secondary:hover {
transform: translateY(-2px) scale(1.02);
background: rgba(124, 58, 237, 0.1);
border-color: rgba(124, 58, 237, 0.6);
}
}

@layer utilities {
.animate-mesh {
animation: mesh 20s ease infinite;
}

.animate-float {
animation: float 6s ease-in-out infinite;
}

.animate-pulse-glow {
animation: pulse-glow 4s ease-in-out infinite;
}
}

@keyframes mesh {
0%, 100% { background-position: 0% 50%; transform: scale(1); }
50% { background-position: 100% 50%; transform: scale(1.1); }
}

@keyframes float {
0%, 100% { transform: translateY(0) rotate(0deg); }
50% { transform: translateY(-20px) rotate(2deg); }
}

@keyframes pulse-glow {
0%, 100% { box-shadow: 0 0 20px rgba(124, 58, 237, 0.2); }
50% { box-shadow: 0 0 40px rgba(124, 58, 237, 0.4); }
}

/* Custom Scrollbar */
::-webkit-scrollbar {
width: 10px;
height: 10px;
width: 6px;
}

::-webkit-scrollbar-track {
background: var(--bg-secondary);
border-radius: 999px;
@apply bg-transparent;
}

::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, var(--primary), var(--accent));
border-radius: 999px;
border: 2px solid var(--bg-secondary);
background-clip: padding-box;
transition: background 0.2s ease, box-shadow 0.2s ease;
@apply bg-primary/30 rounded-full hover:bg-primary/50 transition-colors;
}

::-webkit-scrollbar-thumb:hover {
background: linear-gradient(135deg, var(--accent), var(--primary));
box-shadow: 0 0 8px var(--primary-glow);
}

::-webkit-scrollbar-corner {
background: var(--bg-secondary);
}
/* Fluid Typography Helpers */
.text-fluid-h1 { font-size: clamp(2.5rem, 8vw, 6rem); }
.text-fluid-h2 { font-size: clamp(2rem, 5vw, 4rem); }
.text-fluid-p { font-size: clamp(1rem, 2vw, 1.25rem); }
7 changes: 6 additions & 1 deletion apps/web/src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@
declare global {
namespace App {
// interface Error {}
// interface Locals {}
interface Locals {
user?: {
id: string;
username: string;
}
}
// interface PageData {}
// interface PageState {}
// interface Platform {}
Expand Down
23 changes: 22 additions & 1 deletion apps/web/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,29 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
<!--
Blocking theme script — runs synchronously before first paint.
Reads localStorage preference, falls back to system preference,
and applies the .dark class to <html> immediately.
This eliminates the white flash on dark mode initial load.
-->
<script>
(function () {
try {
var saved = localStorage.getItem('devcard-theme');
if (saved === 'dark') {
document.documentElement.classList.add('dark');
} else if (!saved && window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark');
}
} catch (e) {
// localStorage may be unavailable (private browsing, security restrictions)
// Silently fall back to light mode
}
})();
</script>
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
</html>
Loading