commit a1346c98b1cdd5a040470ab7d8b5aa84cc3d5ccd Author: FliesentischKing Date: Sat Oct 3 20:07:49 2026 +0200 Initial Commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..35d0044 --- /dev/null +++ b/.env.example @@ -0,0 +1 @@ +DATABASE_URL=mysql://nuxt:nuxt_password@localhost:3306/nuxt_app diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ca2910 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules +.nuxt +.output +.env +data/ +public/uploads/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..fb641b6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,17 @@ +# Nuxt shadcn Demo + +## Workflow + +- Keine Headless-Browser-Verifizierung nach UI-Änderungen — der User testet selbst. Nur bei wiederholten Fehlern nachfragen/debuggen. Syntax-/Build-Checks sind weiterhin okay. +- Dev-Server: `npm run dev` (Port 3000). Der User lässt ihn meist selbst laufen — nicht blind starten, erst prüfen ob bereits aktiv. +- DB: MariaDB via `docker-compose.yml` (Container `nuxt-shadcn-demo-db`), URL in `DATABASE_URL`. Migrationen: `npm run db:generate` (Schema → SQL), `npm run db:migrate` (anwenden; im Dev-Modus auch automatisch per Nitro-Plugin). + +## Conventions + +- Vue 3 ` + + diff --git a/app/assets/css/tailwind.css b/app/assets/css/tailwind.css new file mode 100644 index 0000000..174c456 --- /dev/null +++ b/app/assets/css/tailwind.css @@ -0,0 +1,814 @@ + +@import "tailwindcss"; +@import "tw-animate-css"; +@import "shadcn-vue/tailwind.css"; + +@custom-variant dark (&:is(.dark *)); + +@utility cn-font-heading { + font-family: var(--font-heading); +} + +@theme inline { + --font-sans: var(--font-sans); + --font-weight-normal: 500; + --font-weight-medium: 600; + --font-weight-semibold: 700; + --font-weight-bold: 700; + --font-heading: var(--font-heading); + --font-logo: var(--font-logo); + --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); + --color-foreground: var(--foreground); + --color-background: var(--background); + --radius-xs: calc(var(--radius) * 0.2); + --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) * 1.6); + --radius-3xl: calc(var(--radius) * 2.4); +} + +:root, [data-theme="standard"] { + --font-sans: 'Figtree', sans-serif; + --font-heading: 'Manrope', sans-serif; + --font-logo: 'Archivo Black', sans-serif; + --radius: 0.625rem; + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.459 0.187 3.815); + --primary-foreground: oklch(0.971 0.014 343.198); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.459 0.187 3.815); + --accent-foreground: oklch(0.971 0.014 343.198); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.823 0.12 346.018); + --chart-2: oklch(0.656 0.241 354.308); + --chart-3: oklch(0.592 0.249 0.584); + --chart-4: oklch(0.525 0.223 3.958); + --chart-5: oklch(0.459 0.187 3.815); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.656 0.241 354.308); + --sidebar-primary-foreground: oklch(0.971 0.014 343.198); + --sidebar-accent: oklch(0.459 0.187 3.815); + --sidebar-accent-foreground: oklch(0.971 0.014 343.198); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +/* Discord-Theme (tweakcn, Dark-Variante) */ +[data-theme="discord"] { + --font-sans: 'Noto Sans JP', ui-sans-serif, sans-serif, system-ui; + --font-heading: 'Noto Sans JP', ui-sans-serif, sans-serif, system-ui; + --radius: 0.625rem; + --background: oklch(0.3225 0.0107 278.2517); + --foreground: oklch(1 0 0); + --card: oklch(0.3502 0.0122 279.2835); + --card-foreground: oklch(1 0 0); + --popover: oklch(0.3502 0.0122 279.2835); + --popover-foreground: oklch(1 0 0); + --primary: oklch(0.5774 0.2091 273.8504); + --primary-foreground: oklch(1 0 0); + --secondary: oklch(0.3779 0.0118 285.8207); + --secondary-foreground: oklch(1 0 0); + --muted: oklch(0.3066 0.0108 278.2166); + --muted-foreground: oklch(0.723 0.0087 278.582); + --accent: oklch(0.4074 0.0134 280.1154); + --accent-foreground: oklch(1 0 0); + --destructive: oklch(0.8004 0.1141 23.185); + --border: oklch(0.369 0.0103 278.3345); + --input: oklch(0.3066 0.0108 278.2166); + --ring: oklch(0.5774 0.2091 273.8504); + --chart-1: oklch(0.8092 0.1122 345.1956); + --chart-2: oklch(0.8757 0.0979 83.6546); + --chart-3: oklch(0.9075 0.0946 165.054); + --chart-4: oklch(0.8406 0.0699 242.1914); + --chart-5: oklch(0.7865 0.1232 309.4396); + --sidebar: oklch(0.2981 0.0091 276.8201); + --sidebar-foreground: oklch(0.6876 0.0102 279.6082); + --sidebar-primary: oklch(0.3804 0.0102 278.3511); + --sidebar-primary-foreground: oklch(1 0 0); + --sidebar-accent: oklch(0.3309 0.0087 285.9137); + --sidebar-accent-foreground: oklch(1 0 0); + --sidebar-border: oklch(0.3494 0.0087 276.903); + --sidebar-ring: oklch(0.7151 0.1523 235.2888); +} + +/* Cyberpunk-Theme (tweakcn „赛博朋克", Dark-Variante): + Neon-Grün auf Schwarz, Magenta-Primary, eckig, Glow-Schatten */ +[data-theme="cyberpunk"] { + --font-sans: 'Orbitron', sans-serif; + --font-heading: 'Orbitron', sans-serif; + --radius: 0rem; + --background: oklch(0.1149 0 0); + --foreground: oklch(0.8803 0.2083 157.334); + --card: oklch(0.1591 0 0); + --card-foreground: oklch(1 0 0); + --popover: oklch(0.1149 0 0); + --popover-foreground: oklch(0.8803 0.2083 157.334); + --primary: oklch(0.6083 0.2973 312.1096); + --primary-foreground: oklch(1 0 0); + --secondary: oklch(0.7392 0.1576 235.3407); + --secondary-foreground: oklch(1 0 0); + --muted: oklch(0.2178 0 0); + --muted-foreground: oklch(0.5693 0 0); + --accent: oklch(0.6354 0.2541 15.4582); + --accent-foreground: oklch(1 0 0); + --destructive: oklch(0.6317 0.2544 21.7529); + --border: oklch(0.3211 0 0); + --input: oklch(0.1591 0 0); + --ring: oklch(0.6083 0.2973 312.1096); + --chart-1: oklch(0.6083 0.2973 312.1096); + --chart-2: oklch(0.8803 0.2083 157.334); + --chart-3: oklch(0.7392 0.1576 235.3407); + --chart-4: oklch(0.6354 0.2541 15.4582); + --chart-5: oklch(0.9616 0.213 112.0777); + --sidebar: oklch(0.0847 0 0); + --sidebar-foreground: oklch(0.6268 0 0); + --sidebar-primary: oklch(0.6083 0.2973 312.1096); + --sidebar-primary-foreground: oklch(1 0 0); + --sidebar-accent: oklch(0.2178 0 0); + --sidebar-accent-foreground: oklch(0.8803 0.2083 157.334); + --sidebar-border: oklch(0.252 0 0); + --sidebar-ring: oklch(0.7392 0.1576 235.3407); + --shadow-2xs: 0 0 20px 4px hsl(340 100% 50% / 0.4); + --shadow-xs: 0 0 20px 4px hsl(340 100% 50% / 0.4); + --shadow-sm: 0 0 20px 4px hsl(340 100% 50% / 0.8), 0 1px 2px 3px hsl(340 100% 50% / 0.8); + --shadow: 0 0 20px 4px hsl(340 100% 50% / 0.8), 0 1px 2px 3px hsl(340 100% 50% / 0.8); + --shadow-md: 0 0 20px 4px hsl(340 100% 50% / 0.8), 0 2px 4px 3px hsl(340 100% 50% / 0.8); + --shadow-lg: 0 0 20px 4px hsl(340 100% 50% / 0.8), 0 4px 6px 3px hsl(340 100% 50% / 0.8); + --shadow-xl: 0 0 20px 4px hsl(340 100% 50% / 0.8), 0 8px 10px 3px hsl(340 100% 50% / 0.8); + --shadow-2xl: 0 0 20px 4px hsl(340 100% 50%); +} + +[data-theme="cyberpunk"] body { + letter-spacing: 0.08em; +} + +/* Spring-Theme (tweakcn „CuteSpringTheme", Dark-Variante): + Mauve/Pflaume-Hintergrund, Pink-Primary, Mint-Secondary, sehr rund */ +[data-theme="spring"] { + --font-sans: 'Jua', sans-serif; + --font-heading: 'Jua', sans-serif; + --radius: 1.25rem; + --background: oklch(0.2482 0.0307 354.5794); + --foreground: oklch(0.9678 0.0166 3.6461); + --card: oklch(0.3001 0.0369 357.054); + --card-foreground: oklch(0.9678 0.0166 3.6461); + --popover: oklch(0.3001 0.0369 357.054); + --popover-foreground: oklch(0.9678 0.0166 3.6461); + --primary: oklch(0.7716 0.1387 9.6611); + --primary-foreground: oklch(0.2482 0.0307 354.5794); + --secondary: oklch(0.766 0.1179 145.295); + --secondary-foreground: oklch(0.2941 0.0509 145.0535); + --muted: oklch(0.3458 0.0388 356.0232); + --muted-foreground: oklch(0.8178 0.0293 355.5969); + --accent: oklch(0.8391 0.1615 84.3763); + --accent-foreground: oklch(0.2482 0.0307 354.5794); + --destructive: oklch(0.6875 0.142 21.4566); + --border: oklch(0.4074 0.043 356.7696); + --input: oklch(0.3001 0.0369 357.054); + --ring: oklch(0.7716 0.1387 9.6611); + --chart-1: oklch(0.7716 0.1387 9.6611); + --chart-2: oklch(0.766 0.1179 145.295); + --chart-3: oklch(0.8391 0.1615 84.3763); + --chart-4: oklch(0.6297 0.1321 299.3578); + --chart-5: oklch(0.7546 0.1512 38.2575); + --sidebar: oklch(0.2239 0.0279 355.4364); + --sidebar-foreground: oklch(0.9678 0.0166 3.6461); + --sidebar-primary: oklch(0.7716 0.1387 9.6611); + --sidebar-primary-foreground: oklch(0.2482 0.0307 354.5794); + --sidebar-accent: oklch(0.3001 0.0369 357.054); + --sidebar-accent-foreground: oklch(0.9678 0.0166 3.6461); + --sidebar-border: oklch(0.3458 0.0388 356.0232); + --sidebar-ring: oklch(0.7716 0.1387 9.6611); +} + +[data-theme="spring"] body { + letter-spacing: 0.02em; +} + +/* Terminal-Theme (tweakcn „iconic terminal", Dark-Variante): + Monospace, Teal-Phosphor auf Schwarz, eckig, keine Schatten */ +[data-theme="terminal"] { + --font-sans: 'JetBrains Mono', monospace; + --font-heading: 'JetBrains Mono', monospace; + --radius: 0rem; + --background: oklch(0.1234 0.0134 174.8007); + --foreground: oklch(0.7678 0.1655 162.189); + --card: oklch(0.1577 0.018 172.3648); + --card-foreground: oklch(0.7678 0.1655 162.189); + --popover: oklch(0.1414 0.0154 174.4925); + --popover-foreground: oklch(0.7678 0.1655 162.189); + --primary: oklch(0.7678 0.1655 162.189); + --primary-foreground: oklch(0.1234 0.0134 174.8007); + --secondary: oklch(0.2393 0.0298 170.0849); + --secondary-foreground: oklch(0.7678 0.1655 162.189); + --muted: oklch(0.2123 0.0248 170.4461); + --muted-foreground: oklch(0.4814 0.0721 168.7206); + --accent: oklch(0.304 0.0414 169.4923); + --accent-foreground: oklch(0.8309 0.1796 162.0706); + --destructive: oklch(0.4344 0.1466 25.7809); + --border: oklch(0.4274 0.0886 163.5258); + --input: oklch(0.3519 0.0714 164.2596); + --ring: oklch(0.7678 0.1655 162.189); + --chart-1: oklch(0.7678 0.1655 162.189); + --chart-2: oklch(0.8052 0.1423 171.7621); + --chart-3: oklch(0.7935 0.133 163.1545); + --chart-4: oklch(0.6201 0.0963 179.7192); + --chart-5: oklch(0.4814 0.0721 168.7206); + --sidebar: oklch(0.0979 0.0106 174.8007); + --sidebar-foreground: oklch(0.7678 0.1655 162.189); + --sidebar-primary: oklch(0.7678 0.1655 162.189); + --sidebar-primary-foreground: oklch(0.1234 0.0134 174.8007); + --sidebar-accent: oklch(0.2393 0.0298 170.0849); + --sidebar-accent-foreground: oklch(0.8309 0.1796 162.0706); + --sidebar-border: oklch(0.3519 0.0714 164.2596); + --sidebar-ring: oklch(0.7678 0.1655 162.189); + --shadow-2xs: 0 0 0 0 transparent; + --shadow-xs: 0 0 0 0 transparent; + --shadow-sm: 0 0 0 0 transparent; + --shadow: 0 0 0 0 transparent; + --shadow-md: 0 0 0 0 transparent; + --shadow-lg: 0 0 0 0 transparent; + --shadow-xl: 0 0 0 0 transparent; + --shadow-2xl: 0 0 0 0 transparent; +} + +[data-theme="terminal"] body { + letter-spacing: 0.05em; +} + +/* Infoseer-Theme (tweakcn, Dark-Variante): schlichtes Monochrome, + weiße Primary-Buttons mit dunkler Schrift */ +[data-theme="infoseer"] { + --font-sans: 'Fira Sans', ui-sans-serif, sans-serif, system-ui; + --font-heading: 'Fira Sans', ui-sans-serif, sans-serif, system-ui; + --radius: 0.625rem; + --background: oklch(0.2138 0.0019 286.2347); + --foreground: oklch(0.9851 0 0); + --card: oklch(0.2138 0.0019 286.2347); + --card-foreground: oklch(0.9851 0 0); + --popover: oklch(0.2686 0 0); + --popover-foreground: oklch(0.9851 0 0); + --primary: oklch(0.9219 0 0); + --primary-foreground: oklch(0.2138 0.0019 286.2347); + --secondary: oklch(0.2686 0 0); + --secondary-foreground: oklch(0.9851 0 0); + --muted: oklch(0.2686 0 0); + --muted-foreground: oklch(0.709 0 0); + --accent: oklch(0.3715 0 0); + --accent-foreground: oklch(0.9851 0 0); + --destructive: oklch(0.709 0.1879 11.8353); + --border: oklch(0.2768 0 0); + --input: oklch(0.325 0 0); + --ring: oklch(0.5555 0 0); + --chart-1: oklch(0.8497 0.0888 233.6561); + --chart-2: oklch(0.6874 0.157 248.1539); + --chart-3: oklch(0.619 0.181 254.6741); + --chart-4: oklch(0.5528 0.1826 257.4254); + --chart-5: oklch(0.4684 0.1508 259.5323); + --sidebar: oklch(0.2138 0.0019 286.2347); + --sidebar-foreground: oklch(0.9851 0 0); + --sidebar-primary: oklch(0.5526 0.2035 259.283); + --sidebar-primary-foreground: oklch(0.9851 0 0); + --sidebar-accent: oklch(0.2686 0 0); + --sidebar-accent-foreground: oklch(0.9851 0 0); + --sidebar-border: oklch(0.2768 0 0); + --sidebar-ring: oklch(0.4386 0 0); +} + +[data-theme="infoseer"] body { + letter-spacing: 0.025em; +} + +/* Homebrew-Theme (tweakcn, Dark-Variante): Matrix-Grün auf Schwarz, + eckig, grüner Neon-Glow */ +[data-theme="homebrew"] { + --font-sans: 'Inter', ui-sans-serif, sans-serif, system-ui; + --font-heading: 'JetBrains Mono', ui-monospace, monospace; + --radius: 0rem; + --background: oklch(0 0 0); + --foreground: oklch(0.8686 0.2776 144.4661); + --card: oklch(0.2295 0.0624 145.0466); + --card-foreground: oklch(0.8686 0.2776 144.4661); + --popover: oklch(0 0 0); + --popover-foreground: oklch(0.8686 0.2776 144.4661); + --primary: oklch(0.8686 0.2776 144.4661); + --primary-foreground: oklch(0 0 0); + --secondary: oklch(0.3053 0.1039 142.4953); + --secondary-foreground: oklch(0.8686 0.2776 144.4661); + --muted: oklch(0.1887 0.0642 142.4953); + --muted-foreground: oklch(0.7556 0.2021 146.5242); + --accent: oklch(0.3053 0.1039 142.4953); + --accent-foreground: oklch(0.8686 0.2776 144.4661); + --destructive: oklch(0.6786 0.2095 24.6583); + --border: oklch(0.5412 0.175 144.0774); + --input: oklch(0.1149 0 0); + --ring: oklch(0.8686 0.2776 144.4661); + --chart-1: oklch(0.8686 0.2776 144.4661); + --chart-2: oklch(0.5638 0.1872 143.245); + --chart-3: oklch(0.3053 0.1039 142.4953); + --chart-4: oklch(0.1179 0.0327 343.3438); + --chart-5: oklch(0.8686 0.2776 144.4661); + --sidebar: oklch(0.1149 0 0); + --sidebar-foreground: oklch(0.8686 0.2776 144.4661); + --sidebar-primary: oklch(0.8686 0.2776 144.4661); + --sidebar-primary-foreground: oklch(0 0 0); + --sidebar-accent: oklch(0.3053 0.1039 142.4953); + --sidebar-accent-foreground: oklch(0.8686 0.2776 144.4661); + --sidebar-border: oklch(0.5412 0.175 144.0774); + --sidebar-ring: oklch(0.8686 0.2776 144.4661); + --shadow-2xs: 0 0 15px 2px hsl(135 100% 50% / 0.2); + --shadow-xs: 0 0 15px 2px hsl(135 100% 50% / 0.2); + --shadow-sm: 0 0 15px 2px hsl(135 100% 50% / 0.4), 0 1px 2px 1px hsl(135 100% 50% / 0.4); + --shadow: 0 0 15px 2px hsl(135 100% 50% / 0.4), 0 1px 2px 1px hsl(135 100% 50% / 0.4); + --shadow-md: 0 0 15px 2px hsl(135 100% 50% / 0.4), 0 2px 4px 1px hsl(135 100% 50% / 0.4); + --shadow-lg: 0 0 15px 2px hsl(135 100% 50% / 0.4), 0 4px 6px 1px hsl(135 100% 50% / 0.4); + --shadow-xl: 0 0 15px 2px hsl(135 100% 50% / 0.4), 0 8px 10px 1px hsl(135 100% 50% / 0.4); + --shadow-2xl: 0 0 15px 2px hsl(135 100% 50%); +} + +[data-theme="homebrew"] body { + letter-spacing: 0.05em; +} + +/* Florense-Theme (tweakcn, Dark-Variante): reines Monochrome, + weiße Primary mit schwarzer Schrift, keine Schatten */ +[data-theme="florense"] { + --font-sans: 'Geist', ui-sans-serif, sans-serif, system-ui; + --font-heading: 'Lora', ui-serif, serif; + --radius: 1rem; + --background: oklch(0.0969 0 0); + --foreground: oklch(0.9851 0 0); + --card: oklch(0 0 0); + --card-foreground: oklch(0.9851 0 0); + --popover: oklch(0 0 0); + --popover-foreground: oklch(0.9851 0 0); + --primary: oklch(1 0 0); + --primary-foreground: oklch(0 0 0); + --secondary: oklch(0.2178 0 0); + --secondary-foreground: oklch(0.9851 0 0); + --muted: oklch(0.2178 0 0); + --muted-foreground: oklch(0.683 0 0); + --accent: oklch(0.2686 0 0); + --accent-foreground: oklch(1 0 0); + --destructive: oklch(1 0 0); + --border: oklch(0.1913 0 0); + --input: oklch(0.2686 0 0); + --ring: oklch(1 0 0); + --chart-1: oklch(1 0 0); + --chart-2: oklch(0.8452 0 0); + --chart-3: oklch(0.683 0 0); + --chart-4: oklch(0.5103 0 0); + --chart-5: oklch(0.3211 0 0); + --sidebar: oklch(0 0 0); + --sidebar-foreground: oklch(0.9851 0 0); + --sidebar-primary: oklch(1 0 0); + --sidebar-primary-foreground: oklch(0 0 0); + --sidebar-accent: oklch(0.2178 0 0); + --sidebar-accent-foreground: oklch(1 0 0); + --sidebar-border: oklch(0.2686 0 0); + --sidebar-ring: oklch(1 0 0); + --shadow-2xs: 0 0 0 0 transparent; + --shadow-xs: 0 0 0 0 transparent; + --shadow-sm: 0 0 0 0 transparent; + --shadow: 0 0 0 0 transparent; + --shadow-md: 0 0 0 0 transparent; + --shadow-lg: 0 0 0 0 transparent; + --shadow-xl: 0 0 0 0 transparent; + --shadow-2xl: 0 0 0 0 transparent; +} + +/* Kawi-Green-Theme (tweakcn „high tech kawi green", Dark-Variante): + Schwarz mit Neon-Grün-Borders, roter Secondary, weiße Offset-Schatten */ +[data-theme="kawi-green"] { + --font-sans: 'Inter', sans-serif; + --font-heading: 'JetBrains Mono', monospace; + --radius: 0rem; + --background: oklch(0 0 0); + --foreground: oklch(1 0 0); + --card: oklch(0 0 0); + --card-foreground: oklch(1 0 0); + --popover: oklch(0 0 0); + --popover-foreground: oklch(1 0 0); + --primary: oklch(0.8815 0.275 138.4872); + --primary-foreground: oklch(0 0 0); + --secondary: oklch(0.628 0.2577 29.2339); + --secondary-foreground: oklch(1 0 0); + --muted: oklch(0.1448 0 0); + --muted-foreground: oklch(1 0 0); + --accent: oklch(1 0 0); + --accent-foreground: oklch(0 0 0); + --destructive: oklch(0.628 0.2577 29.2339); + --border: oklch(0.8815 0.275 138.4872); + --input: oklch(0.8815 0.275 138.4872); + --ring: oklch(0.8815 0.275 138.4872); + --chart-1: oklch(0.8815 0.275 138.4872); + --chart-2: oklch(0.628 0.2577 29.2339); + --chart-3: oklch(1 0 0); + --chart-4: oklch(0.8003 0.1821 151.711); + --chart-5: oklch(0.645 0.2154 16.4393); + --sidebar: oklch(0 0 0); + --sidebar-foreground: oklch(1 0 0); + --sidebar-primary: oklch(0.8815 0.275 138.4872); + --sidebar-primary-foreground: oklch(0 0 0); + --sidebar-accent: oklch(0.1776 0 0); + --sidebar-accent-foreground: oklch(0.8815 0.275 138.4872); + --sidebar-border: oklch(0.8815 0.275 138.4872); + --sidebar-ring: oklch(0.8815 0.275 138.4872); + --shadow-2xs: -4px 4px 0 0 hsl(0 0% 100% / 0.5); + --shadow-xs: -4px 4px 0 0 hsl(0 0% 100% / 0.5); + --shadow-sm: -4px 4px 0 0 hsl(0 0% 100%), -4px 1px 2px -1px hsl(0 0% 100%); + --shadow: -4px 4px 0 0 hsl(0 0% 100%), -4px 1px 2px -1px hsl(0 0% 100%); + --shadow-md: -4px 4px 0 0 hsl(0 0% 100%), -4px 2px 4px -1px hsl(0 0% 100%); + --shadow-lg: -4px 4px 0 0 hsl(0 0% 100%), -4px 4px 6px -1px hsl(0 0% 100%); + --shadow-xl: -4px 4px 0 0 hsl(0 0% 100%), -4px 8px 10px -1px hsl(0 0% 100%); + --shadow-2xl: -4px 4px 0 0 hsl(0 0% 100%); +} + +[data-theme="kawi-green"] body { + letter-spacing: 0.05em; +} + +/* Clo.nz-Theme (tweakcn, Dark-Variante): Slate-Dunkelblau, + Off-White-Primary, orangener Focus-Ring */ +[data-theme="clonz"] { + --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --font-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --radius: 0.5rem; + --background: oklch(0.2184 0.0079 274.5602); + --foreground: oklch(0.9596 0.0131 82.4019); + --card: oklch(0.2614 0.0094 276.7359); + --card-foreground: oklch(0.9596 0.0131 82.4019); + --popover: oklch(0.2614 0.0094 276.7359); + --popover-foreground: oklch(0.9596 0.0131 82.4019); + --primary: oklch(0.9596 0.0131 82.4019); + --primary-foreground: oklch(0.2184 0.0079 274.5602); + --secondary: oklch(0.3225 0.0205 73.1712); + --secondary-foreground: oklch(0.9596 0.0131 82.4019); + --muted: oklch(0.3022 0.0091 276.8278); + --muted-foreground: oklch(0.7333 0.0115 280.4017); + --accent: oklch(0.3022 0.0091 276.8278); + --accent-foreground: oklch(0.9596 0.0131 82.4019); + --destructive: oklch(0.5231 0.1583 27.6707); + --border: oklch(0.3022 0.0091 276.8278); + --input: oklch(0.3022 0.0091 276.8278); + --ring: oklch(0.6711 0.1394 48.3137); + --chart-1: oklch(0.9596 0.0131 82.4019); + --chart-2: oklch(0.6711 0.1394 48.3137); + --chart-3: oklch(0.484 0.0665 184.1633); + --chart-4: oklch(0.5194 0.0174 277.5749); + --chart-5: oklch(0.7333 0.0115 280.4017); + --sidebar: oklch(0.2184 0.0079 274.5602); + --sidebar-foreground: oklch(0.9596 0.0131 82.4019); + --sidebar-primary: oklch(0.3022 0.0091 276.8278); + --sidebar-primary-foreground: oklch(0.9596 0.0131 82.4019); + --sidebar-accent: oklch(0.3022 0.0091 276.8278); + --sidebar-accent-foreground: oklch(0.9596 0.0131 82.4019); + --sidebar-border: oklch(0.3022 0.0091 276.8278); + --sidebar-ring: oklch(0.6711 0.1394 48.3137); +} + +/* Clawmorphism-Theme (tweakcn, Dark-Variante): neutrales Grau, + markante 6px-Offset-Schatten */ +[data-theme="clawmorphism"] { + --font-sans: 'Inter', sans-serif; + --font-heading: 'Inter', sans-serif; + --radius: 0.575rem; + --background: oklch(0.2972 0 0); + --foreground: oklch(0.7826 0 0); + --card: oklch(0.325 0 0); + --card-foreground: oklch(0.7826 0 0); + --popover: oklch(0.2603 0 0); + --popover-foreground: oklch(0.931 0 0); + --primary: oklch(0.8822 0 0); + --primary-foreground: oklch(0.2435 0 0); + --secondary: oklch(0.3092 0 0); + --secondary-foreground: oklch(0.937 0 0); + --muted: oklch(0.2435 0 0); + --muted-foreground: oklch(0.6993 0 0); + --accent: oklch(0.3329 0 0); + --accent-foreground: oklch(0.9672 0 0); + --destructive: oklch(0.6398 0.0838 195.2629); + --border: oklch(0.36 0 0); + --input: oklch(0.3753 0 0); + --ring: oklch(0.2603 0 0); + --chart-1: oklch(0.9249 0 0); + --chart-2: oklch(0.7921 0 0); + --chart-3: oklch(0.66 0 0); + --chart-4: oklch(0.5208 0 0); + --chart-5: oklch(0.4017 0 0); + --sidebar: oklch(0.2435 0 0); + --sidebar-foreground: oklch(0.931 0 0); + --sidebar-primary: oklch(0.8822 0 0); + --sidebar-primary-foreground: oklch(0.2435 0 0); + --sidebar-accent: oklch(0.2809 0 0); + --sidebar-accent-foreground: oklch(0.931 0 0); + --sidebar-border: oklch(0.3171 0 0); + --sidebar-ring: oklch(0.6401 0 0); + --shadow-2xs: 6px 6px 16px 0 hsl(0 0% 8% / 0.38); + --shadow-xs: 6px 6px 16px 0 hsl(0 0% 8% / 0.38); + --shadow-sm: 6px 6px 16px 0 hsl(0 0% 8% / 0.76), 6px 1px 2px -1px hsl(0 0% 8% / 0.76); + --shadow: 6px 6px 16px 0 hsl(0 0% 8% / 0.76), 6px 1px 2px -1px hsl(0 0% 8% / 0.76); + --shadow-md: 6px 6px 16px 0 hsl(0 0% 8% / 0.76), 6px 2px 4px -1px hsl(0 0% 8% / 0.76); + --shadow-lg: 6px 6px 16px 0 hsl(0 0% 8% / 0.76), 6px 4px 6px -1px hsl(0 0% 8% / 0.76); + --shadow-xl: 6px 6px 16px 0 hsl(0 0% 8% / 0.76), 6px 8px 10px -1px hsl(0 0% 8% / 0.76); + --shadow-2xl: 6px 6px 16px 0 hsl(0 0% 8%); +} + +/* Realmorphism-Theme (tweakcn, Dark-Variante): dunkles Teal/Forest, + harte dunkelgrüne Offset-Schatten */ +[data-theme="realmorphism"] { + --font-sans: 'Inter', sans-serif; + --font-heading: 'Inter', sans-serif; + --radius: 0.5rem; + --background: oklch(0.1276 0.0035 245.8087); + --foreground: oklch(0.9457 0.0091 161.3462); + --card: oklch(0.1712 0.0039 229.0605); + --card-foreground: oklch(0.9457 0.0091 161.3462); + --popover: oklch(0.1712 0.0039 229.0605); + --popover-foreground: oklch(0.9457 0.0091 161.3462); + --primary: oklch(0.4794 0.075 168.9054); + --primary-foreground: oklch(0.9457 0.0091 161.3462); + --secondary: oklch(0.2201 0.0095 159.2095); + --secondary-foreground: oklch(0.9457 0.0091 161.3462); + --muted: oklch(0.2201 0.0095 159.2095); + --muted-foreground: oklch(0.7341 0.0188 169.8711); + --accent: oklch(0.5955 0.0953 168.0699); + --accent-foreground: oklch(0.9457 0.0091 161.3462); + --destructive: oklch(0.4041 0.112 23.5585); + --border: oklch(0.317 0.0173 165.969); + --input: oklch(0.2201 0.0095 159.2095); + --ring: oklch(0.5955 0.0953 168.0699); + --chart-1: oklch(0.4794 0.075 168.9054); + --chart-2: oklch(0.5337 0.0845 74.0079); + --chart-3: oklch(0.9068 0.1567 156.0616); + --chart-4: oklch(0.7341 0.0188 169.8711); + --chart-5: oklch(0.879 0.1534 91.6054); + --sidebar: oklch(0.1276 0.0035 245.8087); + --sidebar-foreground: oklch(0.9457 0.0091 161.3462); + --sidebar-primary: oklch(0.4794 0.075 168.9054); + --sidebar-primary-foreground: oklch(0.9457 0.0091 161.3462); + --sidebar-accent: oklch(0.2201 0.0095 159.2095); + --sidebar-accent-foreground: oklch(0.9457 0.0091 161.3462); + --sidebar-border: oklch(0.317 0.0173 165.969); + --sidebar-ring: oklch(0.5955 0.0953 168.0699); + --shadow-2xs: 2px 2px 0 1px hsl(160.6 43.6% 29.2% / 0.5); + --shadow-xs: 2px 2px 0 1px hsl(160.6 43.6% 29.2% / 0.5); + --shadow-sm: 2px 2px 0 1px hsl(160.6 43.6% 29.2%), 2px 1px 2px 0 hsl(160.6 43.6% 29.2%); + --shadow: 2px 2px 0 1px hsl(160.6 43.6% 29.2%), 2px 1px 2px 0 hsl(160.6 43.6% 29.2%); + --shadow-md: 2px 2px 0 1px hsl(160.6 43.6% 29.2%), 2px 2px 4px 0 hsl(160.6 43.6% 29.2%); + --shadow-lg: 2px 2px 0 1px hsl(160.6 43.6% 29.2%), 2px 4px 6px 0 hsl(160.6 43.6% 29.2%); + --shadow-xl: 2px 2px 0 1px hsl(160.6 43.6% 29.2%), 2px 8px 10px 0 hsl(160.6 43.6% 29.2%); + --shadow-2xl: 2px 2px 0 1px hsl(160.6 43.6% 29.2%); +} + +/* Amber-Theme (tweakcn „my amber theme", Dark-Variante): + Amber-Phosphor auf Schwarz, eckig, Amber-Glow, Retro-Font Workbench */ +[data-theme="amber"] { + --font-sans: 'Workbench', ui-monospace, monospace; + --font-heading: 'Workbench', ui-monospace, monospace; + --radius: 0rem; + --background: oklch(0 0 0); + --foreground: oklch(0.8403 0.1724 84.0757); + --card: oklch(0.1149 0 0); + --card-foreground: oklch(0.8403 0.1724 84.0757); + --popover: oklch(0.1149 0 0); + --popover-foreground: oklch(0.8403 0.1724 84.0757); + --primary: oklch(0.8403 0.1724 84.0757); + --primary-foreground: oklch(0 0 0); + --secondary: oklch(0.266 0.055 80.8676); + --secondary-foreground: oklch(0.8403 0.1724 84.0757); + --muted: oklch(0.1845 0.0378 85.8185); + --muted-foreground: oklch(0.5155 0.107 79.2295); + --accent: oklch(0.8403 0.1724 84.0757); + --accent-foreground: oklch(0 0 0); + --destructive: oklch(0.2428 0.0996 29.2339); + --border: oklch(0.8403 0.1724 84.0757); + --input: oklch(0.8403 0.1724 84.0757); + --ring: oklch(0.8403 0.1724 84.0757); + --chart-1: oklch(0.8403 0.1724 84.0757); + --chart-2: oklch(0.7773 0.1595 84.1047); + --chart-3: oklch(0.7119 0.146 84.6103); + --chart-4: oklch(0.6462 0.1325 84.7159); + --chart-5: oklch(0.5775 0.1183 85.4662); + --sidebar: oklch(0 0 0); + --sidebar-foreground: oklch(0.8403 0.1724 84.0757); + --sidebar-primary: oklch(0.8403 0.1724 84.0757); + --sidebar-primary-foreground: oklch(0 0 0); + --sidebar-accent: oklch(0.266 0.055 80.8676); + --sidebar-accent-foreground: oklch(0.8403 0.1724 84.0757); + --sidebar-border: oklch(0.8403 0.1724 84.0757); + --sidebar-ring: oklch(0.8403 0.1724 84.0757); + --shadow-2xs: 0 0 4px 0 hsl(45 100% 50% / 0.1); + --shadow-xs: 0 0 4px 0 hsl(45 100% 50% / 0.1); + --shadow-sm: 0 0 4px 0 hsl(45 100% 50% / 0.2), 0 1px 2px -1px hsl(45 100% 50% / 0.2); + --shadow: 0 0 4px 0 hsl(45 100% 50% / 0.2), 0 1px 2px -1px hsl(45 100% 50% / 0.2); + --shadow-md: 0 0 4px 0 hsl(45 100% 50% / 0.2), 0 2px 4px -1px hsl(45 100% 50% / 0.2); + --shadow-lg: 0 0 4px 0 hsl(45 100% 50% / 0.2), 0 4px 6px -1px hsl(45 100% 50% / 0.2); + --shadow-xl: 0 0 4px 0 hsl(45 100% 50% / 0.2), 0 8px 10px -1px hsl(45 100% 50% / 0.2); + --shadow-2xl: 0 0 4px 0 hsl(45 100% 50% / 0.5); +} + +[data-theme="amber"] body { + letter-spacing: 0.05em; +} + +/* Neo-Brutalismus: helle Pastell-Flächen, schwarze 2px-Borders, + harte Offset-Schatten, keine Rundungen */ + +[data-theme="neo"] { + --font-sans: 'Space Grotesk', sans-serif; + --font-heading: 'Archivo Black', sans-serif; + --radius: 0rem; + --background: oklch(0.96 0.045 95); + --foreground: oklch(0.22 0.02 60); + --card: oklch(0.99 0.01 95); + --card-foreground: oklch(0.22 0.02 60); + --popover: oklch(0.99 0.01 95); + --popover-foreground: oklch(0.22 0.02 60); + --primary: oklch(0.86 0.17 95); + --primary-foreground: oklch(0.22 0.02 60); + --secondary: oklch(0.9 0.06 95); + --secondary-foreground: oklch(0.22 0.02 60); + --muted: oklch(0.92 0.04 95); + --muted-foreground: oklch(0.45 0.03 60); + --accent: oklch(0.75 0.19 350); + --accent-foreground: oklch(0.22 0.02 60); + --destructive: oklch(0.6 0.24 25); + --border: oklch(0.22 0.02 60); + --input: oklch(0.22 0.02 60); + --ring: oklch(0.22 0.02 60); + --sidebar: oklch(0.99 0.01 95); + --sidebar-foreground: oklch(0.22 0.02 60); + --sidebar-primary: oklch(0.86 0.17 95); + --sidebar-primary-foreground: oklch(0.22 0.02 60); + --sidebar-accent: oklch(0.9 0.06 95); + --sidebar-accent-foreground: oklch(0.22 0.02 60); + --sidebar-border: oklch(0.22 0.02 60); + --sidebar-ring: oklch(0.22 0.02 60); +} + +[data-theme="neo-pink"] { + --font-sans: 'Space Grotesk', sans-serif; + --font-heading: 'Archivo Black', sans-serif; + --radius: 0rem; + --background: oklch(0.93 0.07 355); + --foreground: oklch(0.25 0.05 340); + --card: oklch(0.97 0.04 355); + --card-foreground: oklch(0.25 0.05 340); + --popover: oklch(0.97 0.04 355); + --popover-foreground: oklch(0.25 0.05 340); + --primary: oklch(0.85 0.15 200); + --primary-foreground: oklch(0.25 0.05 340); + --secondary: oklch(0.88 0.08 350); + --secondary-foreground: oklch(0.25 0.05 340); + --muted: oklch(0.9 0.06 355); + --muted-foreground: oklch(0.48 0.07 340); + --accent: oklch(0.88 0.17 95); + --accent-foreground: oklch(0.25 0.05 340); + --destructive: oklch(0.58 0.24 25); + --border: oklch(0.25 0.05 340); + --input: oklch(0.25 0.05 340); + --ring: oklch(0.25 0.05 340); + --sidebar: oklch(0.97 0.04 355); + --sidebar-foreground: oklch(0.25 0.05 340); + --sidebar-primary: oklch(0.85 0.15 200); + --sidebar-primary-foreground: oklch(0.25 0.05 340); + --sidebar-accent: oklch(0.88 0.08 350); + --sidebar-accent-foreground: oklch(0.25 0.05 340); + --sidebar-border: oklch(0.25 0.05 340); + --sidebar-ring: oklch(0.25 0.05 340); +} + +[data-theme="neo-mint"] { + --font-sans: 'Space Grotesk', sans-serif; + --font-heading: 'Archivo Black', sans-serif; + --radius: 0rem; + --background: oklch(0.93 0.08 160); + --foreground: oklch(0.25 0.05 200); + --card: oklch(0.97 0.04 160); + --card-foreground: oklch(0.25 0.05 200); + --popover: oklch(0.97 0.04 160); + --popover-foreground: oklch(0.25 0.05 200); + --primary: oklch(0.68 0.2 305); + --primary-foreground: oklch(0.98 0.02 300); + --secondary: oklch(0.88 0.08 165); + --secondary-foreground: oklch(0.25 0.05 200); + --muted: oklch(0.89 0.07 160); + --muted-foreground: oklch(0.45 0.06 200); + --accent: oklch(0.8 0.18 60); + --accent-foreground: oklch(0.25 0.05 200); + --destructive: oklch(0.58 0.24 25); + --border: oklch(0.25 0.05 200); + --input: oklch(0.25 0.05 200); + --ring: oklch(0.25 0.05 200); + --sidebar: oklch(0.97 0.04 160); + --sidebar-foreground: oklch(0.25 0.05 200); + --sidebar-primary: oklch(0.68 0.2 305); + --sidebar-primary-foreground: oklch(0.98 0.02 300); + --sidebar-accent: oklch(0.88 0.08 165); + --sidebar-accent-foreground: oklch(0.25 0.05 200); + --sidebar-border: oklch(0.25 0.05 200); + --sidebar-ring: oklch(0.25 0.05 200); +} + +/* Brutalist-Regeln für alle neo-* Themes: + 2px schwarze Borders + harter 4px-Offset-Schatten auf Karten-Elementen, + Buttons mit „reingedrückt"-Effekt beim Klick */ +[data-theme^="neo"] .border, +[data-theme^="neo"] [data-slot="button"], +[data-theme^="neo"] .upload-tile-media { + border-width: 2px; + border-style: solid; + border-color: var(--border); + box-shadow: 4px 4px 0 0 var(--border); +} + +[data-theme^="neo"] [data-slot="button"] { + transition: translate 0.1s ease, box-shadow 0.1s ease; +} + +[data-theme^="neo"] [data-slot="button"]:hover { + translate: -1px -1px; + box-shadow: 5px 5px 0 0 var(--border); +} + +[data-theme^="neo"] [data-slot="button"]:active { + translate: 2px 2px; + box-shadow: 1px 1px 0 0 var(--border); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + @apply font-sans; + font-weight: 500; + letter-spacing: -0.01em; + } + h1, h2, h3, h4 { + letter-spacing: -0.02em; + } +} +/* View Transition für Upload-Media: + Das Bild morpht geschmeidig vom Thumbnail auf Thread-Größe. + Old/New nutzen den synchronen Standard-Crossfade (kein Blinken), + nur Dauer und Easing werden angeglichen. */ +::view-transition-group(upload-media) { + animation-duration: 380ms; + animation-timing-function: cubic-bezier(0.2, 0, 0, 1); +} +::view-transition-old(upload-media), +::view-transition-new(upload-media) { + animation-duration: 380ms; + animation-timing-function: cubic-bezier(0.2, 0, 0, 1); +} + +/* Phosphor-Glyphen haben mehr Innenrand im ViewBox als Lucide — + leicht hochskalieren, damit sie bei gleicher size-* gleich groß wirken. */ +svg.iconify--ph { + transform: scale(1.15); +} diff --git a/app/components/AudioPlayerDialog.vue b/app/components/AudioPlayerDialog.vue new file mode 100644 index 0000000..2eba4a5 --- /dev/null +++ b/app/components/AudioPlayerDialog.vue @@ -0,0 +1,130 @@ + + + diff --git a/app/components/CommandPalette.vue b/app/components/CommandPalette.vue new file mode 100644 index 0000000..d074936 --- /dev/null +++ b/app/components/CommandPalette.vue @@ -0,0 +1,78 @@ + + + diff --git a/app/components/CommandPaletteResults.vue b/app/components/CommandPaletteResults.vue new file mode 100644 index 0000000..2d17e49 --- /dev/null +++ b/app/components/CommandPaletteResults.vue @@ -0,0 +1,78 @@ + + + diff --git a/app/components/CommentAttachments.vue b/app/components/CommentAttachments.vue new file mode 100644 index 0000000..f8f8846 --- /dev/null +++ b/app/components/CommentAttachments.vue @@ -0,0 +1,126 @@ + + + diff --git a/app/components/CommentContent.vue b/app/components/CommentContent.vue new file mode 100644 index 0000000..0d66a00 --- /dev/null +++ b/app/components/CommentContent.vue @@ -0,0 +1,148 @@ + + +