feat: Flimmer-Branding mit Logo, Icons und Design-Tokens
Logo als SVG in drei Varianten (Icon, Icon+Wortmarke horizontal, monochrom); die Wortmarke ist als Pfad konstruiert und braucht daher keine installierte Schrift. Daraus generiert scripts/generate-icons.ts Favicon (SVG + ICO), PWA-Icons, Maskable-Icons, Apple-Touch-Icon und OG-Bild. Die Farbwelt liegt als CSS-Variablen in globals.css und wird ueber @theme inline an Tailwind durchgereicht — Dark/Light und spaetere Themes bauen darauf auf. Alle Kombinationen erfuellen WCAG AA.
This commit is contained in:
@@ -0,0 +1,328 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
/* ==========================================================================
|
||||
Flimmer — Design-Tokens
|
||||
--------------------------------------------------------------------------
|
||||
Alle Farben liegen als CSS-Variablen (--fl-*) vor und werden über
|
||||
`@theme inline` an Tailwind durchgereicht. Dadurch reagieren sämtliche
|
||||
Utilities (bg-surface, text-muted, …) automatisch auf Theme-Wechsel und
|
||||
spätere zusätzliche Themes brauchen nur einen neuen Selektor-Block.
|
||||
|
||||
Kontrast: jede hier definierte Vorder-/Hintergrund-Kombination erfüllt
|
||||
mindestens WCAG AA (4,5:1 für Fließtext, 3:1 für große Schrift und
|
||||
UI-Begrenzungen). Werte siehe docs/DESIGN.md.
|
||||
========================================================================== */
|
||||
|
||||
@custom-variant dark (&:where([data-theme="dark"], [data-theme="dark"] *));
|
||||
|
||||
:root,
|
||||
[data-theme="dark"] {
|
||||
color-scheme: dark;
|
||||
|
||||
/* Flächen — sehr dunkles Blauviolett/Anthrazit */
|
||||
--fl-bg: #0c0a14;
|
||||
--fl-bg-elevated: #12101d;
|
||||
--fl-surface: #17142499;
|
||||
--fl-surface-solid: #171424;
|
||||
--fl-surface-2: #201b33;
|
||||
--fl-border: #2e2745;
|
||||
--fl-border-strong: #453a63;
|
||||
|
||||
/* Text */
|
||||
--fl-text: #f4f1fa; /* 17,0:1 auf --fl-bg */
|
||||
--fl-muted: #aca5c2; /* 7,7:1 auf --fl-bg */
|
||||
--fl-faint: #7c7594; /* 4,6:1 auf --fl-bg */
|
||||
|
||||
/* Signatur: Glow-Gradient Bernstein → Magenta */
|
||||
--fl-amber: #ffb454;
|
||||
--fl-amber-soft: #ffc46b;
|
||||
--fl-magenta: #ff4d9d;
|
||||
--fl-magenta-soft: #ff6fb0;
|
||||
--fl-accent: var(--fl-amber); /* als Textfarbe nutzbar: 11,3:1 */
|
||||
--fl-accent-alt: var(--fl-magenta); /* als Textfarbe nutzbar: 6,0:1 */
|
||||
--fl-on-accent: #1a1024; /* Text auf dem Gradient: min. 5,5:1 */
|
||||
--fl-gradient: linear-gradient(115deg, var(--fl-amber-soft) 0%, var(--fl-amber) 38%, var(--fl-magenta) 100%);
|
||||
--fl-gradient-soft: linear-gradient(115deg, #ffb45426 0%, #ff4d9d26 100%);
|
||||
--fl-glow: 0 0 0 1px #ffb4541f, 0 8px 34px -10px #ff4d9d59, 0 2px 12px -4px #ffb45440;
|
||||
--fl-glow-strong: 0 0 0 1px #ffb4543d, 0 14px 48px -12px #ff4d9d80, 0 4px 18px -6px #ffb4546b;
|
||||
--fl-ring: #ff8a70;
|
||||
|
||||
/* Statusfarben (AA auf --fl-bg) */
|
||||
--fl-success: #4ade80;
|
||||
--fl-warning: #fbbf24;
|
||||
--fl-danger: #ff6b6b;
|
||||
--fl-info: #7dd3fc;
|
||||
|
||||
--fl-shadow: 0 10px 30px -12px #00000099;
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
color-scheme: light;
|
||||
|
||||
/* Flächen — heller, warmgrauer Grund */
|
||||
--fl-bg: #faf7f5;
|
||||
--fl-bg-elevated: #ffffff;
|
||||
--fl-surface: #ffffffcc;
|
||||
--fl-surface-solid: #ffffff;
|
||||
--fl-surface-2: #f2ece8;
|
||||
--fl-border: #e3dad4;
|
||||
--fl-border-strong: #cbbdb4;
|
||||
|
||||
--fl-text: #1b1524; /* 16,2:1 auf --fl-bg */
|
||||
--fl-muted: #5b5268; /* 6,7:1 auf --fl-bg */
|
||||
--fl-faint: #766c84; /* 4,6:1 auf --fl-bg */
|
||||
|
||||
/* Dieselben Signaturfarben, für Text jedoch in abgedunkelten Varianten */
|
||||
--fl-amber: #ffb454;
|
||||
--fl-amber-soft: #ffc46b;
|
||||
--fl-magenta: #ff4d9d;
|
||||
--fl-magenta-soft: #ff6fb0;
|
||||
--fl-accent: #8a4b00; /* als Textfarbe: 6,4:1 */
|
||||
--fl-accent-alt: #b01262; /* als Textfarbe: 6,4:1 */
|
||||
--fl-on-accent: #23122c; /* Text auf dem Gradient: min. 6,1:1 */
|
||||
--fl-gradient: linear-gradient(115deg, var(--fl-amber-soft) 0%, var(--fl-amber) 38%, var(--fl-magenta) 100%);
|
||||
--fl-gradient-soft: linear-gradient(115deg, #ffb4542e 0%, #ff4d9d2e 100%);
|
||||
--fl-glow: 0 0 0 1px #d8a15c33, 0 8px 26px -12px #ff4d9d4d, 0 2px 10px -4px #ffb4544d;
|
||||
--fl-glow-strong: 0 0 0 1px #d8a15c59, 0 14px 40px -14px #ff4d9d66, 0 4px 16px -6px #ffb45473;
|
||||
--fl-ring: #b01262;
|
||||
|
||||
--fl-success: #15803d;
|
||||
--fl-warning: #a16207;
|
||||
--fl-danger: #b91c1c;
|
||||
--fl-info: #0369a1;
|
||||
|
||||
--fl-shadow: 0 10px 30px -14px #2a1a3a26;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-bg: var(--fl-bg);
|
||||
--color-bg-elevated: var(--fl-bg-elevated);
|
||||
--color-surface: var(--fl-surface);
|
||||
--color-surface-solid: var(--fl-surface-solid);
|
||||
--color-surface-2: var(--fl-surface-2);
|
||||
--color-border-subtle: var(--fl-border);
|
||||
--color-border-strong: var(--fl-border-strong);
|
||||
|
||||
--color-fg: var(--fl-text);
|
||||
--color-muted: var(--fl-muted);
|
||||
--color-faint: var(--fl-faint);
|
||||
|
||||
--color-amber: var(--fl-amber);
|
||||
--color-amber-soft: var(--fl-amber-soft);
|
||||
--color-magenta: var(--fl-magenta);
|
||||
--color-magenta-soft: var(--fl-magenta-soft);
|
||||
--color-accent: var(--fl-accent);
|
||||
--color-accent-alt: var(--fl-accent-alt);
|
||||
--color-on-accent: var(--fl-on-accent);
|
||||
|
||||
--color-success: var(--fl-success);
|
||||
--color-warning: var(--fl-warning);
|
||||
--color-danger: var(--fl-danger);
|
||||
--color-info: var(--fl-info);
|
||||
|
||||
--radius-card: 1rem;
|
||||
--radius-poster: 0.875rem;
|
||||
|
||||
--font-sans: var(--font-outfit), Outfit, Inter, ui-sans-serif, system-ui, -apple-system,
|
||||
"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
|
||||
--shadow-glow: var(--fl-glow);
|
||||
--shadow-glow-strong: var(--fl-glow-strong);
|
||||
--shadow-card: var(--fl-shadow);
|
||||
|
||||
--ease-glow: cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Basis
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
border-color: var(--fl-border);
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--fl-bg);
|
||||
color: var(--fl-text);
|
||||
font-family: var(--font-sans);
|
||||
min-height: 100dvh;
|
||||
/* Ruhiges Kino-Ambiente: zwei sehr weiche Lichtkegel im Hintergrund. */
|
||||
background-image:
|
||||
radial-gradient(60rem 40rem at 12% -8%, color-mix(in oklab, var(--fl-amber) 12%, transparent), transparent 70%),
|
||||
radial-gradient(52rem 38rem at 92% 4%, color-mix(in oklab, var(--fl-magenta) 12%, transparent), transparent 68%);
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--fl-ring);
|
||||
outline-offset: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: color-mix(in oklab, var(--fl-magenta) 40%, transparent);
|
||||
color: var(--fl-text);
|
||||
}
|
||||
|
||||
/* Dezente Scrollbar im Kino-Look */
|
||||
* {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--fl-border-strong) transparent;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Wiederkehrende Bausteine
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
@utility fl-gradient-text {
|
||||
background-image: var(--fl-gradient);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
@utility fl-gradient-bg {
|
||||
background-image: var(--fl-gradient);
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.fl-card {
|
||||
background-color: var(--fl-surface);
|
||||
border: 1px solid var(--fl-border);
|
||||
border-radius: var(--radius-card, 1rem);
|
||||
box-shadow: var(--fl-shadow);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
|
||||
/* Posterkarte: sanftes Aufglimmen beim Hover, kein hartes Aufblitzen. */
|
||||
.fl-poster-card {
|
||||
position: relative;
|
||||
border-radius: var(--radius-poster, 0.875rem);
|
||||
transition:
|
||||
transform 320ms var(--ease-glow),
|
||||
box-shadow 320ms var(--ease-glow);
|
||||
}
|
||||
|
||||
.fl-poster-card:hover,
|
||||
.fl-poster-card:focus-within {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: var(--fl-glow-strong);
|
||||
}
|
||||
|
||||
.fl-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 0.75rem;
|
||||
padding: 0.55rem 1rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.2;
|
||||
transition:
|
||||
transform 200ms var(--ease-glow),
|
||||
box-shadow 240ms var(--ease-glow),
|
||||
background-color 200ms ease,
|
||||
border-color 200ms ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fl-btn:disabled {
|
||||
opacity: 0.55;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.fl-btn-primary {
|
||||
background-image: var(--fl-gradient);
|
||||
color: var(--fl-on-accent);
|
||||
box-shadow: var(--fl-glow);
|
||||
}
|
||||
|
||||
.fl-btn-primary:hover:not(:disabled) {
|
||||
box-shadow: var(--fl-glow-strong);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.fl-btn-ghost {
|
||||
background-color: var(--fl-surface-2);
|
||||
color: var(--fl-text);
|
||||
border: 1px solid var(--fl-border);
|
||||
}
|
||||
|
||||
.fl-btn-ghost:hover:not(:disabled) {
|
||||
border-color: var(--fl-border-strong);
|
||||
background-color: color-mix(in oklab, var(--fl-surface-2) 70%, var(--fl-amber) 8%);
|
||||
}
|
||||
|
||||
.fl-input {
|
||||
width: 100%;
|
||||
background-color: var(--fl-surface-2);
|
||||
border: 1px solid var(--fl-border);
|
||||
border-radius: 0.75rem;
|
||||
padding: 0.6rem 0.85rem;
|
||||
color: var(--fl-text);
|
||||
transition: border-color 200ms ease, box-shadow 200ms ease;
|
||||
}
|
||||
|
||||
.fl-input::placeholder {
|
||||
color: var(--fl-faint);
|
||||
}
|
||||
|
||||
.fl-input:focus {
|
||||
outline: none;
|
||||
border-color: color-mix(in oklab, var(--fl-magenta) 55%, var(--fl-border));
|
||||
box-shadow: 0 0 0 3px color-mix(in oklab, var(--fl-magenta) 22%, transparent);
|
||||
}
|
||||
|
||||
/* Fortschrittsbalken im Signatur-Gradient */
|
||||
.fl-progress {
|
||||
height: 0.375rem;
|
||||
border-radius: 999px;
|
||||
background-color: var(--fl-surface-2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fl-progress > span {
|
||||
display: block;
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background-image: var(--fl-gradient);
|
||||
transition: width 420ms var(--ease-glow);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mikro-Animation: weiches Aufglimmen, z. B. beim Abhaken einer Episode. */
|
||||
@keyframes fl-glimmer {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 color-mix(in oklab, var(--fl-amber) 55%, transparent);
|
||||
background-color: color-mix(in oklab, var(--fl-amber) 16%, transparent);
|
||||
}
|
||||
60% {
|
||||
box-shadow: 0 0 0 10px color-mix(in oklab, var(--fl-magenta) 0%, transparent);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.fl-glimmer {
|
||||
animation: fl-glimmer 900ms var(--ease-glow);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user