Creator Workspace: Anmeldeseite unter /workspace
Erstes sichtbares Stueck des Creator-Workspace-Konzepts. Reine statische Dateien in einem neuen Ordner workspace/ -- express.static liefert den Repo-Ordner aus, die Seite ist damit ohne Servercode-Aenderung und ohne Neustart unter /workspace/ erreichbar. Rein additiv: an bestehenden Dateien wurde nichts geaendert. Motiv: Dogfather und Hasi Dog stehen rechts im Bild, deshalb liegt die Code-Tafel links ueber der ruhigen Flaeche (bei VanVans Buchhaltung ist es gespiegelt, weil dort das Emblem links steht). Drei Layoutfaelle, damit die Figuren in keiner Fenstergroesse von der Tafel ueberdeckt werden. Bewusst nur WebP, kein AVIF: send 0.19.2 (Express 4) kennt AVIF nicht und liefert es als application/octet-stream aus -- wegen des nosniff-Headers verweigert der Browser das Bild dann komplett. Lokal gegen den echten Express-Server geprueft: 0 Konsolenfehler, 0 CSP-Verstoesse. Anmelden funktioniert noch nicht (kein Endpunkt); das Formular sagt das jetzt ehrlich statt "Code stimmt nicht".
This commit is contained in:
@@ -0,0 +1,336 @@
|
||||
/* ===================================================================
|
||||
Creator Workspace - Anmeldeseite
|
||||
-------------------------------------------------------------------
|
||||
Grundsatz: dunkel und ruhig. Die Farben stammen aus dem Motiv, sind
|
||||
aber bewusst entsättigt - Neon als Stimmung, nicht als Blendung.
|
||||
Kein reines Weiss auf Schwarz, keine harten Kanten, keine Blinker.
|
||||
=================================================================== */
|
||||
|
||||
:root {
|
||||
--tinte: #05070d;
|
||||
--glas: rgba(10, 14, 23, 0.74);
|
||||
--glas-tief: rgba(6, 9, 16, 0.86);
|
||||
--rand: rgba(150, 186, 220, 0.16);
|
||||
--rand-hell: rgba(150, 186, 220, 0.30);
|
||||
|
||||
--text: #dbe4ef; /* kein reines Weiss - schont die Augen */
|
||||
--text-leise: #94a5bb;
|
||||
--text-still: #6d7d92;
|
||||
|
||||
--akzent: #3fbdf5; /* aus dem Neon des Motivs, entsättigt */
|
||||
--akzent-tief: #1f7fb0;
|
||||
--violett: #8a76ff;
|
||||
--warn: #ff9aa2; /* weiches Rot statt Signalrot */
|
||||
|
||||
--radius: 18px;
|
||||
--radius-klein: 12px;
|
||||
--schatten: 0 24px 60px -20px rgba(0, 0, 0, 0.75);
|
||||
--tempo: .22s cubic-bezier(.4, 0, .2, 1);
|
||||
}
|
||||
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
|
||||
html { -webkit-text-size-adjust: 100%; }
|
||||
|
||||
body.gate {
|
||||
margin: 0;
|
||||
min-height: 100svh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: var(--tinte);
|
||||
color: var(--text);
|
||||
font-family: "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.55;
|
||||
letter-spacing: .01em;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* ---------- Bühne ---------------------------------------------------- */
|
||||
|
||||
.buehne { position: fixed; inset: 0; z-index: 0; }
|
||||
|
||||
.buehne__bild {
|
||||
width: 100%; height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
/* Minimal abgedunkelt und entsättigt, damit der Text darüber ruhig liegt. */
|
||||
filter: saturate(.92) brightness(.9);
|
||||
transform: scale(1.03); /* Reserve für die Parallaxe */
|
||||
transition: transform 1.4s cubic-bezier(.2, .7, .2, 1);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* Der Schleier macht die linke Seite lesbar, ohne das Motiv zu erschlagen.
|
||||
Rechts bleibt er fast durchsichtig - dort stehen Dogfather und Hasi Dog. */
|
||||
.buehne__schleier {
|
||||
position: absolute; inset: 0;
|
||||
/* Viele weiche Stufen statt weniger harter - sonst zeichnet sich die Kante
|
||||
des Verlaufs als sichtbare Diagonale quer durchs Bild. */
|
||||
background:
|
||||
linear-gradient(96deg,
|
||||
rgba(3, 5, 10, 0.93) 0%,
|
||||
rgba(3, 5, 10, 0.90) 18%,
|
||||
rgba(3, 5, 10, 0.82) 28%,
|
||||
rgba(4, 6, 12, 0.68) 36%,
|
||||
rgba(4, 6, 12, 0.50) 44%,
|
||||
rgba(4, 6, 12, 0.33) 52%,
|
||||
rgba(4, 6, 12, 0.19) 60%,
|
||||
rgba(4, 6, 12, 0.09) 68%,
|
||||
rgba(4, 6, 12, 0.03) 78%,
|
||||
rgba(4, 6, 12, 0.00) 88%),
|
||||
radial-gradient(120% 90% at 50% 120%, rgba(0, 0, 0, .42), transparent 62%);
|
||||
}
|
||||
|
||||
/* ---------- Tafel ---------------------------------------------------- */
|
||||
|
||||
.tafel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
margin-left: clamp(24px, 7vw, 104px);
|
||||
width: min(452px, 44vw);
|
||||
padding: clamp(28px, 3vw, 40px) clamp(24px, 2.6vw, 36px) clamp(24px, 2.6vw, 32px);
|
||||
background: var(--glas);
|
||||
backdrop-filter: blur(22px) saturate(115%);
|
||||
-webkit-backdrop-filter: blur(22px) saturate(115%);
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--schatten);
|
||||
animation: auftauchen .7s cubic-bezier(.2, .7, .2, 1) both;
|
||||
}
|
||||
|
||||
/* Feine Lichtkante links - nimmt das Neon des Motivs auf, ohne zu leuchten. */
|
||||
.tafel__kante {
|
||||
position: absolute; left: -1px; top: 16%; bottom: 16%;
|
||||
width: 2px; border-radius: 2px;
|
||||
background: linear-gradient(180deg,
|
||||
transparent, var(--akzent) 22%, var(--violett) 72%, transparent);
|
||||
opacity: .55;
|
||||
}
|
||||
|
||||
@keyframes auftauchen {
|
||||
from { opacity: 0; transform: translateY(14px); }
|
||||
to { opacity: 1; transform: none; }
|
||||
}
|
||||
|
||||
/* ---------- Kopf ----------------------------------------------------- */
|
||||
|
||||
.marke {
|
||||
margin: 0 0 6px;
|
||||
font-size: .74rem; font-weight: 700;
|
||||
letter-spacing: .18em; text-transform: uppercase;
|
||||
color: var(--akzent);
|
||||
}
|
||||
|
||||
.titel {
|
||||
margin: 0 0 8px;
|
||||
font-size: clamp(1.6rem, 2.5vw, 2rem);
|
||||
font-weight: 700; line-height: 1.15;
|
||||
letter-spacing: -.01em;
|
||||
}
|
||||
|
||||
.unterzeile { margin: 0 0 26px; color: var(--text-leise); font-size: .94rem; }
|
||||
|
||||
/* ---------- Rollen --------------------------------------------------- */
|
||||
|
||||
.feldschild {
|
||||
margin: 0 0 10px;
|
||||
font-size: .78rem; font-weight: 600;
|
||||
letter-spacing: .06em; text-transform: uppercase;
|
||||
color: var(--text-still);
|
||||
}
|
||||
|
||||
.rollen { margin-bottom: 22px; }
|
||||
|
||||
.rolle {
|
||||
display: flex; align-items: center; gap: 13px;
|
||||
width: 100%; margin-bottom: 8px; padding: 11px 14px;
|
||||
background: rgba(255, 255, 255, .035);
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein);
|
||||
color: var(--text);
|
||||
font: inherit; text-align: left; cursor: pointer;
|
||||
transition: border-color var(--tempo), background var(--tempo), transform var(--tempo);
|
||||
}
|
||||
.rolle:hover { background: rgba(255, 255, 255, .06); border-color: var(--rand-hell); }
|
||||
.rolle:active { transform: scale(.995); }
|
||||
|
||||
.rolle[aria-checked="true"] {
|
||||
background: linear-gradient(100deg, rgba(63, 189, 245, .14), rgba(138, 118, 255, .10));
|
||||
border-color: rgba(63, 189, 245, .55);
|
||||
}
|
||||
|
||||
.rolle__zeichen {
|
||||
flex: 0 0 auto; width: 21px; height: 21px;
|
||||
fill: none; stroke: var(--text-still);
|
||||
stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
|
||||
transition: stroke var(--tempo);
|
||||
}
|
||||
.rolle__zeichen .strich { fill: none; }
|
||||
.rolle[aria-checked="true"] .rolle__zeichen { stroke: var(--akzent); }
|
||||
|
||||
.rolle__text { display: flex; flex-direction: column; min-width: 0; }
|
||||
.rolle__name { font-weight: 600; font-size: .95rem; }
|
||||
.rolle__zusatz { font-size: .8rem; color: var(--text-still); }
|
||||
|
||||
/* ---------- Formular ------------------------------------------------- */
|
||||
|
||||
.fuer { color: var(--akzent); text-transform: none; letter-spacing: normal; }
|
||||
|
||||
.feld { position: relative; }
|
||||
|
||||
#code {
|
||||
width: 100%; padding: 13px 46px 13px 15px;
|
||||
background: rgba(255, 255, 255, .045);
|
||||
border: 1px solid var(--rand);
|
||||
border-radius: var(--radius-klein);
|
||||
color: var(--text);
|
||||
font: inherit; letter-spacing: .06em;
|
||||
transition: border-color var(--tempo), background var(--tempo), box-shadow var(--tempo);
|
||||
}
|
||||
#code::placeholder { color: var(--text-still); letter-spacing: normal; }
|
||||
#code:hover { border-color: var(--rand-hell); }
|
||||
#code:focus {
|
||||
outline: none;
|
||||
border-color: rgba(63, 189, 245, .7);
|
||||
background: rgba(255, 255, 255, .065);
|
||||
box-shadow: 0 0 0 3px rgba(63, 189, 245, .16);
|
||||
}
|
||||
|
||||
.feld__auge {
|
||||
position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
|
||||
width: 36px; height: 36px; padding: 8px;
|
||||
background: none; border: 0; border-radius: 9px;
|
||||
cursor: pointer; color: var(--text-still);
|
||||
transition: color var(--tempo), background var(--tempo);
|
||||
}
|
||||
.feld__auge:hover { color: var(--text-leise); background: rgba(255, 255, 255, .06); }
|
||||
.feld__auge svg { width: 100%; height: 100%; fill: none; stroke: currentColor;
|
||||
stroke-width: 1.7; stroke-linecap: round; }
|
||||
.feld__auge .durch { opacity: 0; transition: opacity var(--tempo); }
|
||||
.feld__auge[aria-pressed="true"] .durch { opacity: 1; }
|
||||
|
||||
.hinweis, .fehler {
|
||||
margin: 9px 2px 0; font-size: .84rem; min-height: 0;
|
||||
}
|
||||
.hinweis { color: var(--text-leise); }
|
||||
.fehler { color: var(--warn); }
|
||||
.fehler:empty { margin: 0; }
|
||||
|
||||
.knopf {
|
||||
position: relative;
|
||||
width: 100%; margin-top: 18px; padding: 13px 18px;
|
||||
background: linear-gradient(100deg, var(--akzent-tief), #2f6fa8 55%, var(--violett));
|
||||
border: 0; border-radius: var(--radius-klein);
|
||||
color: #f2f7fc; font: inherit; font-weight: 650; letter-spacing: .02em;
|
||||
cursor: pointer;
|
||||
transition: filter var(--tempo), transform var(--tempo);
|
||||
}
|
||||
.knopf:hover { filter: brightness(1.1); }
|
||||
.knopf:active { transform: scale(.99); }
|
||||
.knopf[disabled] { cursor: progress; filter: saturate(.6) brightness(.85); }
|
||||
|
||||
.knopf__laden {
|
||||
position: absolute; right: 16px; top: 50%; margin-top: -8px;
|
||||
width: 16px; height: 16px; border-radius: 50%;
|
||||
border: 2px solid rgba(255, 255, 255, .35);
|
||||
border-top-color: #fff;
|
||||
opacity: 0;
|
||||
animation: dreh .8s linear infinite;
|
||||
}
|
||||
.knopf[disabled] .knopf__laden { opacity: 1; }
|
||||
@keyframes dreh { to { transform: rotate(360deg); } }
|
||||
|
||||
.fuss {
|
||||
margin: 22px 0 0; padding-top: 16px;
|
||||
border-top: 1px solid var(--rand);
|
||||
font-size: .78rem; color: var(--text-still); text-align: center;
|
||||
}
|
||||
|
||||
/* ---------- Übergang beim erfolgreichen Anmelden ---------------------
|
||||
Die Tafel tritt zurück, das Motiv wird kurz frei - als würde sich das
|
||||
Tor öffnen. Bewusst kurz und ohne Aufblitzen. */
|
||||
|
||||
body.oeffnet .tafel {
|
||||
opacity: 0; transform: translateY(-8px) scale(.985);
|
||||
transition: opacity .26s ease, transform .26s ease;
|
||||
}
|
||||
body.oeffnet .buehne__schleier { opacity: .35; transition: opacity .26s ease; }
|
||||
body.oeffnet .buehne__bild { filter: saturate(1) brightness(1); transition: filter .26s ease; }
|
||||
|
||||
/* ---------- Tastatur-Bedienung --------------------------------------- */
|
||||
|
||||
:where(button, input):focus-visible {
|
||||
outline: 2px solid var(--akzent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* ---------- Schmale oder hohe Fenster --------------------------------
|
||||
Sobald das Fenster nicht mehr deutlich breiter als hoch ist, würde die
|
||||
Tafel den Figuren zu nahe kommen. Dann wechselt die Seite auf das
|
||||
Hochformat-Motiv und die Tafel rückt nach unten - die beiden bleiben
|
||||
oben im Bild sichtbar. */
|
||||
|
||||
/* Gemeinsam: Tafel wandert nach unten, Motiv bleibt darüber frei. */
|
||||
@media (max-width: 899px), (max-aspect-ratio: 7/5) {
|
||||
body.gate { align-items: flex-end; justify-content: center; }
|
||||
.tafel {
|
||||
margin: 0 0 max(18px, env(safe-area-inset-bottom));
|
||||
width: min(520px, calc(100vw - 32px));
|
||||
}
|
||||
.tafel__kante { display: none; }
|
||||
}
|
||||
|
||||
/* Schmale Geräte: Hochformat-Ausschnitt. Die Bildfläche endet oberhalb der
|
||||
Tafel - dadurch liegt ihr Seitenverhältnis nah am Ausschnitt und der
|
||||
Browser muss seitlich kaum etwas wegschneiden. Beide Figuren bleiben ganz
|
||||
im Bild, der Verlauf blendet nach unten ins Dunkle. */
|
||||
@media (max-width: 899px) {
|
||||
.buehne { bottom: auto; height: 66svh; }
|
||||
.buehne__bild { object-position: center top; }
|
||||
.buehne__schleier {
|
||||
background:
|
||||
linear-gradient(180deg,
|
||||
rgba(3, 5, 10, 0.30) 0%,
|
||||
rgba(3, 5, 10, 0.10) 20%,
|
||||
rgba(3, 5, 10, 0.22) 46%,
|
||||
rgba(3, 5, 10, 0.55) 66%,
|
||||
rgba(5, 7, 13, 0.88) 82%,
|
||||
/* Muss vor der Unterkante voll deckend sein und exakt der Seitenfarbe
|
||||
entsprechen - sonst zeichnet sich dort eine feine Kante ab. */
|
||||
rgba(5, 7, 13, 1.00) 94%);
|
||||
}
|
||||
}
|
||||
|
||||
/* Breite, aber hohe Fenster (z. B. 1100x980): Querformat bleibt und füllt die
|
||||
ganze Fläche - sonst entsteht unten eine tote dunkle Zone. Weil hier
|
||||
seitlich beschnitten wird, rückt das Motiv nach rechts, damit Dogfather und
|
||||
Hasi Dog vollständig im Bild bleiben. */
|
||||
@media (min-width: 900px) and (max-aspect-ratio: 7/5) {
|
||||
.buehne__bild { object-position: 82% center; }
|
||||
.buehne__schleier {
|
||||
background:
|
||||
linear-gradient(180deg,
|
||||
rgba(3, 5, 10, 0.12) 0%,
|
||||
rgba(3, 5, 10, 0.20) 34%,
|
||||
rgba(3, 5, 10, 0.48) 56%,
|
||||
rgba(3, 5, 10, 0.82) 74%,
|
||||
rgba(3, 5, 10, 0.95) 90%);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
.tafel { padding: 22px 18px 20px; border-radius: 16px; }
|
||||
.rolle__zusatz { display: none; }
|
||||
}
|
||||
|
||||
/* ---------- Weniger Bewegung ----------------------------------------- */
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: .001ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: .001ms !important;
|
||||
}
|
||||
.buehne__bild { transform: none; transition: none; }
|
||||
}
|
||||
Reference in New Issue
Block a user