fox/resources/css/app.css

1570 lines
60 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

@import "tailwindcss";
@import url("https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;600;700&family=Inter:wght@300;400;500;600&display=swap");
@theme {
/* Türkis (abgeschwächt) als Hauptakzent auf schwarzer Basis. */
--color-primary: #22d3ee;
--color-primary-dark: #0891b2;
--color-primary-soft: rgba(34, 211, 238, 0.09);
--color-surface: #000000;
--color-surface-elevated: #0a0a0a;
--color-glass: rgba(255, 255, 255, 0.035);
--color-glass-strong: rgba(255, 255, 255, 0.06);
--color-fox-accent: #22d3ee;
--color-fox-glow: rgba(34, 211, 238, 0.20);
--font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, "Fira Code", monospace;
}
@layer base {
html, body {
@apply bg-surface text-white antialiased;
font-family: var(--font-sans);
}
body {
background:
radial-gradient(1200px 800px at 10% -10%, rgba(34,211,238,0.06), transparent 60%),
radial-gradient(900px 600px at 100% 110%, rgba(34,211,238,0.05), transparent 60%),
var(--color-surface);
min-height: 100vh;
}
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.16); }
}
@layer components {
.glass {
@apply bg-glass border border-white/10 backdrop-blur-xl rounded-2xl;
}
.glass-strong {
@apply bg-glass-strong border border-white/10 backdrop-blur-2xl rounded-2xl;
}
.btn {
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl font-medium transition;
}
.btn-primary {
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl font-medium transition
bg-primary hover:bg-primary-dark text-white shadow-lg shadow-primary/30;
}
.btn-ghost {
@apply inline-flex items-center justify-center gap-2 px-4 py-2 rounded-xl font-medium transition
bg-white/5 hover:bg-white/10 text-white border border-white/10;
}
.input {
@apply w-full bg-white/5 border border-white/10 rounded-xl px-4 py-3
text-white placeholder-white/40 outline-none transition
focus:border-primary;
}
.badge-proactive {
@apply inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full
text-xs font-medium bg-primary/20 text-primary border border-primary/30;
}
.typing-dot {
@apply inline-block w-1.5 h-1.5 rounded-full bg-primary;
animation: typingBounce 1.2s infinite ease-in-out;
}
.typing-dot:nth-child(2) { animation-delay: 0.15s; }
.typing-dot:nth-child(3) { animation-delay: 0.3s; }
.ptt-ring {
box-shadow: 0 0 0 0 var(--color-fox-glow);
animation: pttPulse 1.4s infinite;
}
}
@keyframes typingBounce {
0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
30% { transform: translateY(-4px); opacity: 1; }
}
@keyframes pttPulse {
0% { box-shadow: 0 0 0 0 var(--color-fox-glow); }
70% { box-shadow: 0 0 0 24px rgba(255,255,255, 0); }
100% { box-shadow: 0 0 0 0 rgba(255,255,255, 0); }
}
/* ─── Fox HUD Dashboard ───────────────────────────────────────── */
@layer base {
.hud-body {
@apply text-white antialiased min-h-screen;
background:
radial-gradient(1200px 700px at 50% -10%, rgba(255,255,255,0.04), transparent 60%),
radial-gradient(900px 600px at 100% 110%, rgba(34,211,238,0.04), transparent 60%),
#050507;
font-family: var(--font-sans);
}
}
@layer components {
.hud-shell {
@apply h-screen w-screen grid;
grid-template-rows: 64px 1fr;
grid-template-areas: "topbar" "main";
}
.hud-topbar {
grid-area: topbar;
@apply px-6 flex items-center justify-between border-b border-white/5
backdrop-blur-xl bg-black/20 z-10;
}
.hud-main {
grid-area: main;
@apply grid gap-4 px-4 py-4 overflow-hidden;
grid-template-columns: 280px 1fr 380px;
}
@media (max-width: 1100px) {
.hud-main {
grid-template-columns: 240px 1fr 340px;
}
}
@media (max-width: 900px) {
.hud-main {
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr;
overflow-y: auto;
}
}
.hud-col-left,
.hud-col-right {
@apply flex flex-col gap-4 overflow-y-auto min-h-0;
}
.hud-col-center {
@apply flex items-center justify-center min-h-0;
}
}
@keyframes foxPulseRing {
0% { transform: scale(0.92); opacity: 0.7; }
70% { transform: scale(1.12); opacity: 0; }
100% { transform: scale(1.12); opacity: 0; }
}
.fox-pulse-ring {
animation: foxPulseRing 3s infinite ease-out;
}
/* ═══════════════════════════════════════════════════════════════════
Fox HUD - alle styles für /hud Route
Aus livewire/fox-hud.blade.php extrahiert damit nicht inline.
═══════════════════════════════════════════════════════════════════ */
/* ─── Fox HUD Design (Reference) ────────────────────────────── */
body.hud-page {
background: #000;
color: #e2e8f0;
margin: 0;
font-family: 'Inter', system-ui, sans-serif;
overflow: hidden;
cursor: none;
height: 100vh;
width: 100vw;
}
.fox-hud-root {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.grid-layer {
position: fixed; inset: 0; z-index: 1;
background-color: #000;
background-image:
linear-gradient(rgba(34,211,238,0.018) 1px, transparent 1px),
linear-gradient(90deg, rgba(34,211,238,0.018) 1px, transparent 1px);
background-size: 52px 52px;
pointer-events: none;
}
.scanlines {
position: fixed; inset: 0; z-index: 2;
background-image: repeating-linear-gradient(0deg,
transparent 0, transparent 3px,
rgba(34,211,238,0.010) 3px, rgba(34,211,238,0.010) 4px);
pointer-events: none;
}
/* Karte */
.map-wrap {
position: fixed; inset: 0; z-index: 6;
opacity: 0;
transition: opacity .8s ease;
-webkit-mask-image: radial-gradient(ellipse 58% 54% at 50% 52%,
black 0%, black 28%,
rgba(0,0,0,0.96) 38%,
rgba(0,0,0,0.82) 48%,
rgba(0,0,0,0.55) 58%,
rgba(0,0,0,0.22) 68%,
rgba(0,0,0,0.05) 77%,
transparent 85%);
mask-image: radial-gradient(ellipse 58% 54% at 50% 52%,
black 0%, black 28%,
rgba(0,0,0,0.96) 38%,
rgba(0,0,0,0.82) 48%,
rgba(0,0,0,0.55) 58%,
rgba(0,0,0,0.22) 68%,
rgba(0,0,0,0.05) 77%,
transparent 85%);
pointer-events: none;
}
body.map-visible .map-wrap { opacity: 1; pointer-events: auto; }
/* fox-center bleibt sichtbar - Position + Scale handled in fox-center-Block weiter unten */
body.map-visible .fox-mini { display: none; } /* mini ist redundant, fox-center übernimmt */
body.map-visible .layer-panel { opacity: 1; transform: translateX(0); pointer-events: auto; }
/* KRITISCH - MapLibre braucht expliziten Block mit Höhe, nicht nur 100% */
#map {
position: absolute; inset: 0;
width: 100%; height: 100%;
background: #000;
}
.maplibregl-map { width: 100% !important; height: 100% !important; }
.grid-overlay {
position: fixed; inset: 0; z-index: 4;
background-image:
linear-gradient(rgba(255,255,255,0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.05) 1px, transparent 1px);
background-size: 52px 52px;
pointer-events: none;
}
/* Karte sichtbar: Grid bleibt aber tritt zurück - Map-Mask fadet außen weich aus */
body.map-visible .grid-overlay { opacity: 0.35; }
body.map-visible .grid-layer { opacity: 0.5; }
body.map-visible .scanlines { opacity: 0.4; }
.zoom-rings { position: fixed; inset: 0; z-index: 8; pointer-events: none; }
.zoom-rings .zring {
position: absolute; left: 50%; top: 50%;
border: 1px solid rgba(255,255,255,0.5);
border-radius: 50%;
transform: translate(-50%, -50%);
animation: zoomRing 1.6s ease-out forwards;
}
@keyframes zoomRing {
0% { width: 40px; height: 40px; opacity: 0.9; }
100% { width: 1200px; height: 1200px; opacity: 0; }
}
/* Topbar — kühl getöntes Grau auf schwarzem Fade, Türkis nur am Wordmark */
.topbar {
position: fixed; top: 0; left: 0; right: 0; z-index: 20;
height: 48px; padding: 0 24px;
display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
background: linear-gradient(180deg, rgba(0,0,0,0.94) 0%, rgba(0,0,0,0) 100%);
font-size: 10px; letter-spacing: 0.18em;
font-family: 'JetBrains Mono', monospace;
}
.topbar-left { display: flex; align-items: center; gap: 16px; }
.topbar-center { display: flex; justify-content: center; }
.topbar-right { display: flex; align-items: center; justify-content: flex-end; gap: 10px; }
.fox-wordmark {
font-family: 'Orbitron', sans-serif;
font-size: 13px; font-weight: 700; letter-spacing: 8px;
color: #22d3ee;
text-shadow: 0 0 16px rgba(34,211,238,0.35);
}
.topbar-status {
display: flex; align-items: center; gap: 6px;
color: rgba(16,185,129,0.95);
font-size: 10px; letter-spacing: 0.22em;
}
.clock-time {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 14px; color: rgba(255,255,255,0.98);
font-variant-numeric: tabular-nums;
letter-spacing: 0.18em;
}
.tb-stat { color: rgba(255,255,255,0.85); font-size: 10px; letter-spacing: 0.18em; }
.tb-stat-llm { color: #22d3ee; text-shadow: 0 0 8px rgba(34,211,238,0.5); }
.tb-sep { color: rgba(255,255,255,0.3); }
.dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; }
.dot-green { background: #10b981; box-shadow: 0 0 8px #10b981; }
.dot-red { background: #ef4444; box-shadow: 0 0 8px #ef4444; }
.dot-cyan { background: #22d3ee; box-shadow: 0 0 8px #22d3ee; }
.dot-indigo { background: rgba(255,255,255,0.6); box-shadow: 0 0 8px rgba(255,255,255,0.6); }
.dot-amber { background: rgba(255,255,255,0.6); box-shadow: 0 0 8px rgba(255,255,255,0.6); }
/* Edge glow */
/* Türkis-Glow umlaufend - aktiv wenn Fox spricht/blitzt */
.eg { position: fixed; pointer-events: none; z-index: 15; opacity: 0; transition: opacity .5s; }
.eg.on { opacity: 1; }
.eg-t { top: 0; left: 0; right: 0; height: 90px; background: linear-gradient(180deg, rgba(34,211,238,0.45), rgba(34,211,238,0.10) 40%, transparent); }
.eg-b { bottom: 0; left: 0; right: 0; height: 90px; background: linear-gradient(0deg, rgba(34,211,238,0.45), rgba(34,211,238,0.10) 40%, transparent); }
.eg-l { top: 0; bottom: 0; left: 0; width: 90px; background: linear-gradient(90deg, rgba(34,211,238,0.45), rgba(34,211,238,0.10) 40%, transparent); }
.eg-r { top: 0; bottom: 0; right: 0; width: 90px; background: linear-gradient(-90deg, rgba(34,211,238,0.45), rgba(34,211,238,0.10) 40%, transparent); }
/* Fox Center */
.fox-center {
position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%);
z-index: 20;
transition: top 0.7s cubic-bezier(0.4, 0, 0.2, 1),
left 0.7s cubic-bezier(0.4, 0, 0.2, 1),
transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Karte offen: Fox slidet nach links unten - deutlich sichtbar, nicht winzig */
body.map-visible .fox-center {
top: auto;
bottom: 130px;
left: 30px;
transform: scale(0.65);
transform-origin: bottom left;
cursor: pointer;
}
.fox-center.hide { opacity: 0; transform: translate(-50%, -50%) scale(0.7); pointer-events: none; }
/* JARVIS-Style Fox Avatar - kompakter als zuvor */
.fox-jarvis {
position: relative;
width: 340px;
height: 340px;
}
.fox-arcs {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
overflow: visible;
}
.fox-arc {
transform-origin: 220px 220px;
filter: drop-shadow(0 0 8px currentColor);
/* animation-duration smooth interpolieren - Bögen verlangsamen/beschleunigen
ohne Sprung, weil das gleiche Keyframe-Animation weiter läuft. */
transition: stroke 0.6s ease, stroke-width 0.6s ease, filter 0.6s ease, animation-duration 0.6s ease;
}
@keyframes foxArcSpin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Bögen laufen IMMER. Denken via CSS duration, Sprechen + Random via WAAPI playbackRate. */
.fox-arc-top { animation: foxArcSpin 6s linear infinite; }
.fox-arc-mid { animation: foxArcSpin 8s linear infinite; }
.fox-arc-bot { animation: foxArcSpin 11s linear infinite reverse; }
.fox-center.is-thinking .fox-arc-top { animation-duration: 2.5s; }
.fox-center.is-thinking .fox-arc-mid { animation-duration: 3s; }
.fox-center.is-thinking .fox-arc-bot { animation-duration: 4s; }
/* Outer-Ring: beide Kreise drehen gegenläufig.
Gruppe selbst hat KEINE Rotation nur scale-Transition für Sprechen.
Langsam zurück wenn Sprechen endet (1.3s ease-in-out auf Basis-State). */
.fox-outer-ring {
transform-origin: 220px 220px;
transition: transform 1.3s ease-in-out;
}
.fox-outer-ring circle:nth-child(1) {
transform-origin: 220px 220px;
animation: foxRingSpinCCW 120s linear infinite;
}
.fox-outer-ring circle:nth-child(2) {
transform-origin: 220px 220px;
animation: foxRingSpinCW 80s linear infinite;
}
@keyframes foxRingSpinCW {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes foxRingSpinCCW {
from { transform: rotate(0deg); }
to { transform: rotate(-360deg); }
}
/* Sprechen: Ring zieht sich zusammen (scale ↓), kehrt danach smooth zurück.
Rotationsgeschwindigkeit wird via WAAPI playbackRate in fox-hud.js gesteuert. */
.fox-jarvis.is-speaking .fox-outer-ring {
transform: scale(0.87);
transition: transform 0.5s ease-in-out;
}
.fox-halo {
transform-origin: 220px 220px;
/* Läuft IMMER - Sprechen ändert nur duration, kein Neustart/Abbruch */
animation: foxBreath 8s ease-in-out infinite;
}
@keyframes foxBreath {
0%, 100% { opacity: 0.55; transform: scale(1); }
50% { opacity: 0.95; transform: scale(1.04); }
}
.fox-jarvis.is-speaking .fox-halo {
animation-duration: 1.4s;
}
/* Zentraler Kern */
.fox-jarvis-core {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 168px;
height: 168px;
border-radius: 50%;
background:
radial-gradient(circle at 50% 35%, rgba(34,211,238,0.32) 0%, rgba(0,0,0,0.96) 65%),
#000;
border: 1px solid rgba(34,211,238,0.55);
box-shadow:
0 0 32px rgba(34,211,238,0.55),
inset 0 0 28px rgba(34,211,238,0.22),
inset 0 -10px 20px rgba(0,0,0,0.85);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 6px;
transition: box-shadow 0.3s, border-color 0.3s;
/* Läuft IMMER langsam - Sprechen ändert nur duration, kein Sprung beim Stop */
animation: foxSpeakPulse 5s ease-in-out infinite;
}
.fox-jarvis-name {
font-family: 'Orbitron', sans-serif;
font-size: 19px;
font-weight: 500;
letter-spacing: 3px;
color: #ecfeff;
text-shadow: 0 0 14px rgba(34,211,238,0.85), 0 0 4px rgba(255,255,255,0.6);
transition: text-shadow 0.3s, color 0.3s;
}
.fox-jarvis-state {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 9px;
letter-spacing: 0.35em;
color: rgba(34,211,238,0.65);
}
/* THINKING - Amber */
.fox-center.is-thinking .fox-jarvis-core {
border-color: rgba(34,211,238,0.7) !important;
animation-duration: 0.8s !important;
box-shadow:
0 0 36px rgba(34,211,238,0.7),
inset 0 0 26px rgba(34,211,238,0.3),
inset 0 -10px 20px rgba(0,0,0,0.8) !important;
}
.fox-center.is-thinking .fox-jarvis-name { text-shadow: 0 0 14px rgba(34,211,238,0.9) !important; }
.fox-center.is-thinking .fox-arc-top { stroke: rgba(34,211,238,0.6) !important; }
.fox-center.is-thinking .fox-arc-mid { stroke: rgba(34,211,238,0.75) !important; }
.fox-center.is-thinking .fox-arc-bot { stroke: rgba(34,211,238,0.9) !important; }
/* duration ist im neuen Block oben gesetzt - kein !important Override mehr */
/* SPEAKING - Cyan, schnellere Drehung, pulsierender Glow */
.fox-jarvis.is-speaking .fox-jarvis-core {
border-color: rgba(34,211,238,0.55);
/* Gleicher Keyframe wie Basis - nur duration ändert sich, kein Sprung */
animation-duration: 0.55s;
}
.fox-jarvis.is-speaking .fox-jarvis-name {
color: rgba(186,230,253,0.7);
text-shadow: 0 0 18px rgba(6,182,212,0.9), 0 0 6px rgba(255,255,255,0.5);
}
.fox-jarvis.is-speaking .fox-arc-top {
stroke: #22d3ee;
stroke-width: 5;
}
.fox-jarvis.is-speaking .fox-arc-mid {
stroke: rgba(34,211,238,0.75);
stroke-width: 4;
}
.fox-jarvis.is-speaking .fox-arc-bot {
stroke: rgba(34,211,238,0.85);
stroke-width: 4;
}
@keyframes foxSpeakPulse {
0%, 100% {
box-shadow:
0 0 28px rgba(34,211,238,0.45),
inset 0 0 22px rgba(34,211,238,0.16),
inset 0 -10px 20px rgba(0,0,0,0.8);
}
50% {
box-shadow:
0 0 56px rgba(34,211,238,0.65),
inset 0 0 36px rgba(34,211,238,0.28),
inset 0 -10px 20px rgba(0,0,0,0.8);
}
}
@keyframes spin { from { transform: translate(-50%, -50%) rotate(0); } to { transform: translate(-50%, -50%) rotate(360deg); } }
.fox-core {
position: absolute; left: 50%; top: 50%;
width: 158px; height: 158px;
transform: translate(-50%, -50%);
border-radius: 50%;
background: radial-gradient(circle at 38% 32%, rgba(255,255,255,0.18), rgba(0,0,0,0.92));
border: 0.5px solid rgba(255,255,255,0.45);
backdrop-filter: blur(20px);
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: 6px;
animation: coreglow 5s ease-in-out infinite;
}
@keyframes coreglow {
0%, 100% { box-shadow: 0 0 30px rgba(255,255,255,0.16), inset 0 0 16px rgba(255,255,255,0.08); }
50% { box-shadow: 0 0 50px rgba(255,255,255,0.28), inset 0 0 24px rgba(255,255,255,0.16); }
}
/* Denken-Modus: Core leuchtet stärker, Ringe pulsieren schneller */
.fox-center.is-thinking .fox-core {
animation: coreglowThinking 1.4s ease-in-out infinite;
border-color: rgba(255,255,255,0.6);
}
.fox-center.is-thinking .fox-name { color: rgba(255,255,255,0.9); }
.fox-center.is-thinking .fox-ring { animation-duration: 8s !important; }
@keyframes coreglowThinking {
0%, 100% { box-shadow: 0 0 35px rgba(255,255,255,0.3), inset 0 0 20px rgba(255,255,255,0.18); }
50% { box-shadow: 0 0 70px rgba(255,255,255,0.55), inset 0 0 32px rgba(255,255,255,0.32); }
}
/* Drei pulsierende Punkte unter "DENKT NACH" */
.fox-dots {
margin-top: 6px;
display: flex; align-items: center; justify-content: center; gap: 4px;
}
.fox-dots span {
width: 4px; height: 4px; border-radius: 50%;
background: rgba(255,255,255,0.85);
animation: foxDot 1.2s ease-in-out infinite;
}
.fox-dots span:nth-child(2) { animation-delay: 0.18s; }
.fox-dots span:nth-child(3) { animation-delay: 0.36s; }
@keyframes foxDot {
0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
30% { transform: translateY(-4px); opacity: 1; }
}
[x-cloak] { display: none !important; }
.fox-name {
font-family: 'Orbitron', sans-serif;
font-size: 15px; font-weight: 700; letter-spacing: 5px;
color: rgba(129,140,248,0.9);
}
.fox-state {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 9px; letter-spacing: 0.3em;
color: rgba(255,255,255,0.4);
}
/* Fox Mini */
.fox-mini {
position: fixed; right: 28px; bottom: 96px; z-index: 20;
width: 146px; height: 146px;
background: transparent; border: none; cursor: none; padding: 0;
opacity: 0; transform: translateY(40px); pointer-events: none;
transition: opacity .5s, transform .5s;
animation: float 4s ease-in-out infinite;
}
.fox-mini.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-8px); }
}
.mini-rings { position: relative; width: 146px; height: 146px; }
.mini-ring {
position: absolute; left: 50%; top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
border-style: solid;
border-width: 1px;
border-color: rgba(255,255,255,0.20);
}
.mr1 { width: 108px; height: 108px; border-color: rgba(255,255,255,0.35) !important; animation: spin 12s linear infinite; }
.mr2 { width: 132px; height: 132px; border-color: rgba(255,255,255,0.20) !important; animation: spin 18s linear infinite reverse; }
.mr3 { width: 146px; height: 146px; border-color: rgba(255,255,255,0.10) !important; animation: spin 24s linear infinite; }
.mini-core {
position: absolute; left: 50%; top: 50%;
width: 88px; height: 88px;
transform: translate(-50%, -50%);
border-radius: 50%;
background: radial-gradient(circle at 38% 32%, rgba(255,255,255,0.25), rgba(0,0,0,0.9));
border: 1px solid rgba(255,255,255,0.4);
display: flex; align-items: center; justify-content: center;
}
.mini-name {
font-family: 'Orbitron', sans-serif;
font-size: 11px; font-weight: 700; letter-spacing: 3px;
color: rgba(129,140,248,0.9);
}
/* Input */
.inp-wrap {
position: fixed; left: 50%; bottom: 48px; transform: translateX(-50%);
z-index: 25;
width: min(720px, calc(100vw - 48px));
display: flex; align-items: center; gap: 10px;
padding: 10px 12px;
background: rgba(3,3,13,0.85);
border: 0.5px solid rgba(255,255,255,0.4);
border-radius: 14px;
backdrop-filter: blur(18px);
box-shadow: 0 0 60px rgba(255,255,255,0.25);
}
.mic, .sbtn {
width: 36px; height: 36px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
cursor: none;
background: rgba(255,255,255,0.12);
border: 0.5px solid rgba(255,255,255,0.3);
color: #fff; font-size: 14px;
transition: background .2s, border-color .2s, transform .15s;
flex-shrink: 0;
}
.mic:hover, .sbtn:hover { background: rgba(255,255,255,0.28); border-color: rgba(255,255,255,0.55); }
.mic.active { background: rgba(239,68,68,0.3); border-color: rgba(239,68,68,0.6); }
.sbtn { color: rgba(255,255,255,0.6); font-size: 16px; padding: 0; }
.sbtn:disabled { opacity: 0.5; }
.cinput {
flex: 1; background: transparent; border: none; outline: none; resize: none;
color: #fff; font-size: 13px; font-family: 'Inter', sans-serif;
cursor: none; padding: 8px 4px; max-height: 120px; line-height: 1.5;
}
.cinput::placeholder { color: rgba(255,255,255,0.3); }
/* Bottom Bar — kühl getöntes Grau, monospace */
.bottombar {
position: fixed; left: 0; right: 0; bottom: 0; z-index: 19;
height: 32px; padding: 0 24px;
display: flex; align-items: center; justify-content: center; gap: 16px;
background: linear-gradient(0deg, rgba(0,0,0,0.94) 0%, rgba(0,0,0,0) 100%);
font-size: 10px; letter-spacing: 0.22em;
color: rgba(255,255,255,0.85);
font-family: 'JetBrains Mono', monospace;
}
.bb-cell { display: flex; align-items: center; gap: 6px; }
.bb-state { color: #22d3ee; margin-left: 4px; }
.bb-sep { color: rgba(255,255,255,0.3); }
/* Place-Info-Mappe - mittig, mit Foto-Header und Detail-Body */
/* City-Choice — mittig, kompakt für Mehrfach-Treffer-Auswahl */
.city-choice {
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
z-index: 46;
width: 380px; max-width: calc(100vw - 32px);
background: #04060a;
border: 1px solid rgba(34,211,238,0.35);
border-radius: 10px;
box-shadow: 0 24px 80px rgba(0,0,0,0.85), 0 0 24px rgba(34,211,238,0.12);
font-family: 'JetBrains Mono', monospace;
overflow: hidden;
animation: status-in .3s cubic-bezier(.2,.8,.3,1) both;
}
.city-choice-head {
padding: 12px 16px;
border-bottom: 1px solid rgba(34,211,238,0.2);
display: flex; align-items: center; gap: 10px;
}
.city-choice-title { flex: 1; color: #22d3ee; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; }
.city-choice-items { padding: 8px; max-height: 60vh; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; }
.city-choice-btn {
text-align: left; padding: 10px 14px;
background: rgba(186,230,253,0.02);
border: 1px solid rgba(186,230,253,0.06);
border-radius: 8px; cursor: none;
transition: background .15s, border-color .15s, color .15s;
}
.city-choice-btn:hover { background: rgba(34,211,238,0.07); border-color: rgba(34,211,238,0.5); }
.city-choice-name { font-size: 14px; color: rgba(255,255,255,0.92); font-weight: 500; }
.city-choice-meta { font-size: 10px; color: rgba(255,255,255,0.5); margin-top: 3px; }
/* System-Status Diagnose-Panel — links seitlich, volle Höhe */
.status-panel {
position: fixed; top: 64px; left: 24px;
z-index: 45;
width: 380px; max-width: calc(100vw - 32px);
max-height: calc(100vh - 160px);
background: #02050a;
border: 1px solid rgba(34,211,238,0.45);
border-radius: 8px;
box-shadow:
0 24px 80px rgba(0,0,0,0.85),
0 0 32px rgba(34,211,238,0.18),
inset 0 0 0 1px rgba(0,0,0,0.5);
font-family: 'JetBrains Mono', monospace;
overflow: hidden;
display: flex; flex-direction: column;
animation: status-in .3s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes status-in {
from { opacity: 0; transform: translateX(-16px); }
to { opacity: 1; transform: translateX(0); }
}
.status-head {
display: flex; align-items: center; gap: 12px;
padding: 12px 18px;
border-bottom: 1px solid rgba(34,211,238,0.22);
background: linear-gradient(90deg, rgba(34,211,238,0.06), transparent);
}
.status-title {
flex: 1;
font-size: 11px; letter-spacing: 0.32em;
color: #22d3ee;
text-shadow: 0 0 10px rgba(34,211,238,0.5);
}
.status-spinner {
font-size: 9px; letter-spacing: 0.3em;
color: rgba(34,211,238,0.85);
animation: status-blink 0.9s linear infinite;
}
@keyframes status-blink {
0%, 60% { opacity: 1; }
61%, 100% { opacity: 0.25; }
}
.status-close {
background: transparent; border: none; cursor: none;
color: rgba(255,255,255,0.4); font-size: 18px; line-height: 1;
padding: 0 4px;
transition: color .15s;
}
.status-close:hover { color: #22d3ee; }
.status-body {
padding: 14px 18px;
max-height: 65vh;
overflow-y: auto;
}
.status-line {
display: grid;
grid-template-columns: 14px 100px 1fr;
gap: 8px; align-items: center;
padding: 4px 0;
font-size: 11px;
opacity: 0;
animation: status-line-in .25s ease forwards;
animation-delay: calc(var(--idx) * 30ms);
}
@keyframes status-line-in {
from { opacity: 0; transform: translateX(-8px); }
to { opacity: 1; transform: translateX(0); }
}
.status-mark {
color: #22d3ee;
font-size: 10px;
text-shadow: 0 0 8px rgba(34,211,238,0.7);
}
.status-line.fail .status-mark {
color: #ef4444;
text-shadow: 0 0 8px rgba(239,68,68,0.7);
}
.status-label {
color: rgba(255,255,255,0.55);
letter-spacing: 0.18em;
font-size: 10px;
}
.status-value {
color: rgba(255,255,255,0.92);
letter-spacing: 0.05em;
}
.status-line.fail .status-value {
color: #fca5a5;
}
/* Scanline-Animation während scanning */
.status-scanline {
position: absolute; left: 0; right: 0; top: 0;
height: 2px;
background: linear-gradient(90deg, transparent, #22d3ee, transparent);
box-shadow: 0 0 12px rgba(34,211,238,0.7);
animation: status-scan 1.6s linear infinite;
pointer-events: none;
}
@keyframes status-scan {
0% { top: 48px; opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { top: 100%; opacity: 0; }
}
/* ─── PLACE CARDS — Karten erscheinen direkt im Raum ────────────── */
.cards-scene {
position: fixed; inset: 0; z-index: 60;
background: rgba(0, 3, 10, 0.9);
display: flex; flex-direction: column;
opacity: 0; pointer-events: none;
transition: opacity 0.55s ease;
}
body.desk-visible .cards-scene { opacity: 1; pointer-events: auto; }
.cards-infobar {
width: 100%; padding: 10px 20px; flex-shrink: 0;
display: flex; align-items: center; justify-content: space-between;
border-bottom: 1px solid rgba(34,211,238,0.12);
}
.cards-place-name {
font-family: 'Orbitron', sans-serif; font-size: 13px;
font-weight: 600; letter-spacing: 2px;
color: #ecfeff; text-shadow: 0 0 10px rgba(34,211,238,0.5);
}
.cards-actions { display: flex; gap: 8px; align-items: center; }
.cards-btn-map, .cards-close-btn {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 10px; letter-spacing: 0.12em;
background: none; border: 1px solid rgba(34,211,238,0.25);
color: rgba(34,211,238,0.7); cursor: pointer;
padding: 4px 10px; transition: all 0.2s;
}
.cards-btn-map:hover { background: rgba(34,211,238,0.1); color: #22d3ee; }
.cards-close-btn { font-size: 14px; padding: 2px 8px; border-color: rgba(255,255,255,0.12); color: rgba(255,255,255,0.4); }
.cards-close-btn:hover { color: #fff; border-color: rgba(255,255,255,0.4); }
/* ─── Scattered cards field ──────────────────────────────── */
.cards-field {
flex: 1; position: relative;
}
.cards-field.has-open .pcard { opacity: 0; pointer-events: none; transition: opacity 0.2s ease; }
/* Paper file card */
.pcard {
position: absolute;
left: var(--l, 10%); top: var(--t, 20%);
width: 100px;
cursor: pointer;
transform: rotate(var(--rot, 0deg));
transition: transform 0.3s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s ease;
animation: pcardIn 0.5s ease both;
animation-delay: calc(var(--i, 0) * 75ms + 150ms);
}
.pcard:hover { transform: rotate(var(--rot, 0deg)) translateY(-10px) scale(1.06); z-index: 2; }
@keyframes pcardIn {
from { opacity: 0; transform: rotate(var(--rot, 0deg)) translateY(24px) scale(0.92); }
to { opacity: 1; transform: rotate(var(--rot, 0deg)) translateY(0) scale(1); }
}
/* Stacked paper sheets */
.pcard-back2, .pcard-back1, .pcard-main {
position: absolute; left: 0; right: 0;
border-radius: 1px;
background: #e8eef5;
border: 1px solid rgba(150,170,195,0.5);
}
.pcard-back2 {
top: -6px; bottom: 6px;
background: #cbd5e2; transform: rotate(3.5deg);
box-shadow: 1px 2px 6px rgba(0,0,0,0.4);
}
.pcard-back1 {
top: -3px; bottom: 3px;
background: #d5dfeb; transform: rotate(-2deg);
box-shadow: 1px 2px 5px rgba(0,0,0,0.32);
}
.pcard-main {
position: relative;
padding: 11px 9px 9px;
display: flex; flex-direction: column; align-items: center; gap: 7px;
box-shadow: 1px 4px 12px rgba(0,0,0,0.5);
}
.pcard:hover .pcard-main {
box-shadow: 0 6px 24px rgba(34,211,238,0.2), 1px 4px 12px rgba(0,0,0,0.5);
border-color: rgba(34,211,238,0.4);
}
.pcard-icon { font-size: 20px; color: rgba(10,45,85,0.75); }
.pcard-name {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 7px; letter-spacing: 0.12em;
color: rgba(20,50,90,0.6); text-align: center; white-space: nowrap;
}
.pcard-lines { width: 100%; display: flex; flex-direction: column; gap: 3px; padding: 0 2px; }
.pl { height: 2px; border-radius: 1px; background: rgba(50,70,105,0.18); }
.pl:nth-child(1) { width: 80%; }
.pl:nth-child(2) { width: 100%; }
.pl:nth-child(3) { width: 88%; }
.pl:nth-child(4) { width: 65%; }
/* ─── Opened card: full readable view ───────────────────── */
.cards-open {
position: fixed; inset: 0; z-index: 70;
background: rgba(0, 5, 14, 0.97);
padding: 28px 36px; overflow-y: auto;
display: flex; flex-direction: column; gap: 14px;
animation: cardsOpenIn 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes cardsOpenIn {
from { opacity: 0; transform: translateY(18px); }
to { opacity: 1; transform: translateY(0); }
}
.cards-back-btn {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 10px; letter-spacing: 0.18em;
background: none; border: 1px solid rgba(34,211,238,0.22);
color: rgba(34,211,238,0.6); cursor: pointer;
padding: 5px 12px; align-self: flex-start;
transition: all 0.2s;
}
.cards-back-btn:hover { background: rgba(34,211,238,0.08); color: #22d3ee; }
.cards-label {
font-family: 'JetBrains Mono', ui-monospace, monospace;
font-size: 9px; letter-spacing: 0.2em;
color: rgba(34,211,238,0.45); margin-bottom: 8px;
}
.cards-body { font-size: 13px; line-height: 1.7; color: rgba(220,235,245,0.85); }
.cards-hours-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 4px; }
.cards-hours-list li {
font-size: 12px; color: rgba(200,220,235,0.8);
font-family: 'JetBrains Mono', ui-monospace, monospace;
padding: 3px 0; border-bottom: 1px solid rgba(34,211,238,0.06);
}
.cards-phone-number { font-family: 'Orbitron', sans-serif; font-size: 22px; color: #22d3ee; letter-spacing: 3px; text-shadow: 0 0 16px rgba(34,211,238,0.5); }
.cards-rating-big { font-family: 'Orbitron', sans-serif; font-size: 32px; color: #fbbf24; letter-spacing: 2px; text-shadow: 0 0 20px rgba(251,191,36,0.4); }
.cards-rating-count { font-size: 11px; color: rgba(200,200,200,0.5); font-family: 'JetBrains Mono', ui-monospace, monospace; margin-top: 4px; }
.cards-address { font-size: 14px; color: rgba(220,235,245,0.85); line-height: 1.6; }
.cards-website-link { font-size: 12px; color: rgba(34,211,238,0.75); word-break: break-all; text-decoration: none; font-family: 'JetBrains Mono', ui-monospace, monospace; }
.cards-website-link:hover { color: #22d3ee; text-decoration: underline; }
.cards-photos { display: flex; flex-wrap: wrap; gap: 10px; }
.cards-photo { max-width: 280px; max-height: 200px; object-fit: cover; border-radius: 2px; border: 1px solid rgba(34,211,238,0.18); }
/* Place-Info-Mappe — alles tief schwarz, kühl getönte Greys, Türkis als Linie + Akzent-Text */
.place-info {
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
z-index: 40;
width: 420px; max-width: calc(100vw - 32px);
max-height: 72vh;
background: #04060a;
border: 1px solid rgba(34, 211, 238, 0.22);
border-radius: 14px;
backdrop-filter: blur(20px);
box-shadow:
0 24px 80px rgba(0,0,0,0.85),
0 0 0 1px rgba(0,0,0,0.6) inset,
0 0 24px rgba(34,211,238,0.08);
overflow: hidden;
display: flex; flex-direction: column;
animation: place-info-in .35s cubic-bezier(.2,.8,.3,1) both;
font-family: var(--font-sans);
}
.place-info.expanded { width: 540px; max-height: 86vh; }
@keyframes place-info-in {
from { opacity: 0; transform: translate(-50%, -45%) scale(0.94); }
to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
.place-info-close {
position: absolute; top: 12px; right: 14px; z-index: 2;
width: 26px; height: 26px; border-radius: 50%;
background: rgba(0,0,0,0.7); border: 1px solid rgba(255,255,255,0.07);
color: rgba(220,245,255,0.65); font-size: 15px; line-height: 1;
cursor: none;
transition: color .15s, background .15s, border-color .15s;
}
.place-info-close:hover { color: #22d3ee; background: rgba(0,0,0,0.9); border-color: rgba(34,211,238,0.4); }
.place-info-photo {
width: 100%; height: 220px;
background-size: cover; background-position: center;
position: relative;
}
.place-info-photo::after {
content: ''; position: absolute; inset: 0;
background: linear-gradient(180deg, transparent 0%, transparent 40%, #04060a 95%);
}
.place-info-body {
padding: 18px 22px 22px;
overflow-y: auto;
color: rgba(255,255,255,0.07);
}
.place-info-name {
margin: 0 0 4px 0;
font-family: 'Orbitron', sans-serif;
font-size: 18px; font-weight: 500; color: rgba(186,230,253,0.7);
letter-spacing: 0.05em;
text-transform: uppercase;
}
.place-info-meta {
font-size: 11px; letter-spacing: 0.04em;
color: rgba(255,255,255,0.4);
margin-bottom: 14px;
font-family: 'JetBrains Mono', monospace;
}
.place-info-rating {
display: flex; align-items: center; gap: 10px;
padding: 8px 0;
border-top: 1px solid rgba(255,255,255,0.07);
border-bottom: 1px solid rgba(255,255,255,0.07);
margin-bottom: 14px;
}
.place-info-stars {
color: #22d3ee; font-size: 13px; font-weight: 600;
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0.05em;
}
.place-info-rating-count {
color: rgba(255,255,255,0.05); font-size: 10px;
font-family: 'JetBrains Mono', monospace;
}
.place-info-summary {
font-size: 13px; line-height: 1.65;
color: rgba(255,255,255,0.98);
margin: 0 0 16px 0;
}
.place-info-section {
margin-top: 14px; padding-top: 14px;
border-top: 1px solid rgba(255,255,255,0.07);
}
.place-info-section h4 {
margin: 0 0 10px 0;
font-size: 10px; letter-spacing: 0.25em; text-transform: uppercase;
color: #22d3ee; font-weight: 500;
font-family: 'JetBrains Mono', monospace;
}
.place-info-section ul {
list-style: none; padding: 0; margin: 0;
font-size: 11px; color: rgba(255,255,255,0.05);
font-family: 'JetBrains Mono', monospace;
letter-spacing: 0.02em;
}
.place-info-section li { padding: 3px 0; }
.place-info-link {
display: inline-block; margin-top: 10px;
font-size: 11px; color: #22d3ee;
text-decoration: none;
font-family: 'JetBrains Mono', monospace;
border-bottom: 1px solid rgba(34,211,238,0.3);
padding-bottom: 1px;
}
.place-info-link:hover { color: #67e8f9; border-color: #67e8f9; }
.place-info-actions {
display: flex; gap: 6px; margin-top: 18px;
}
.place-info-actions button {
flex: 1; padding: 10px 12px;
background: transparent;
border: 1px solid rgba(255,255,255,0.05);
border-radius: 6px;
color: rgba(255,255,255,0.07);
font-size: 10px; letter-spacing: 0.18em; font-weight: 500;
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
cursor: none;
transition: color .15s, background .15s, border-color .15s;
}
.place-info-actions button:hover {
background: rgba(34,211,238,0.07);
border-color: rgba(34,211,238,0.5);
color: #22d3ee;
}
.place-info-loading { padding: 20px; }
.place-info-skeleton-photo {
width: 100%; height: 220px; border-radius: 8px;
background: linear-gradient(90deg, rgba(186,230,253,0.025), rgba(255,255,255,0.07), rgba(186,230,253,0.025));
background-size: 200% 100%;
animation: skeleton-pulse 1.6s linear infinite;
margin-bottom: 14px;
}
.place-info-skeleton-line {
height: 12px; border-radius: 3px;
background: linear-gradient(90deg, rgba(186,230,253,0.025), rgba(255,255,255,0.07), rgba(186,230,253,0.025));
background-size: 200% 100%;
animation: skeleton-pulse 1.6s linear infinite;
margin: 8px 0;
}
@keyframes skeleton-pulse {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Route Info Panel - oben mittig wenn Route aktiv */
.route-info {
position: fixed; top: 64px; left: 50%; transform: translateX(-50%);
z-index: 30;
display: flex; align-items: center; gap: 14px;
padding: 9px 14px 9px 14px;
background: #04060a;
border: 1px solid rgba(34,211,238,0.30);
border-radius: 10px;
backdrop-filter: blur(14px);
color: rgba(255,255,255,0.98);
font-size: 11px; letter-spacing: 0.16em; font-weight: 500;
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
box-shadow: 0 8px 24px rgba(0,0,0,0.6), 0 0 16px rgba(34,211,238,0.10);
}
.route-info-icon { color: #22d3ee; font-size: 11px; }
.route-info-close {
margin-left: 4px;
background: transparent; border: none; color: rgba(255,255,255,0.4);
font-size: 16px; line-height: 1; cursor: none; padding: 0 4px;
transition: color .15s;
}
.route-info-close:hover { color: #22d3ee; }
/* Layer Panel */
.layer-panel {
position: fixed; left: 24px; bottom: 96px; z-index: 22;
display: flex; flex-direction: column; gap: 8px;
opacity: 0; transform: translateX(-20px); pointer-events: none;
transition: opacity .4s, transform .4s;
}
.layer-panel.show { opacity: 1; transform: translateX(0); pointer-events: auto; }
.lbtn {
display: flex; align-items: center; gap: 8px;
padding: 8px 14px;
background: rgba(3,3,13,0.85);
border: 0.5px solid rgba(255,255,255,0.3);
border-radius: 8px;
backdrop-filter: blur(12px);
color: rgba(255,255,255,0.7);
font-size: 10px; letter-spacing: 0.2em; font-weight: 500;
cursor: none;
transition: background .2s, border-color .2s, color .2s;
}
.lbtn:hover { color: #fff; border-color: rgba(255,255,255,0.6); }
.lbtn.on {
background: rgba(255,255,255,0.2);
border-color: rgba(255,255,255,0.7);
color: #fff;
}
.ld { width: 8px; height: 8px; border-radius: 50%; box-shadow: 0 0 8px currentColor; }
/* POI Panel — schwarz mit kühl-getönten Greys + Türkis-Linie */
.poi-panel {
position: fixed; right: 24px; top: 64px; bottom: 110px; z-index: 22;
width: 320px;
display: none;
flex-direction: column;
background: #04060a;
border: 1px solid rgba(34,211,238,0.18);
border-radius: 12px;
backdrop-filter: blur(18px);
overflow: hidden;
box-shadow: 0 16px 48px rgba(0,0,0,0.7);
}
body.poi-visible .poi-panel { display: flex; }
body.route-visible .poi-panel { display: none; }
/* Route Step Panel - rechts, ersetzt POI-Liste wenn Route aktiv */
.route-panel {
position: fixed; right: 24px; top: 64px; bottom: 110px; z-index: 23;
width: 340px;
display: flex; flex-direction: column;
background: #04060a;
border: 1px solid rgba(34,211,238,0.22);
border-radius: 12px;
backdrop-filter: blur(18px);
overflow: hidden;
box-shadow: 0 16px 48px rgba(0,0,0,0.75), 0 0 24px rgba(34,211,238,0.06);
}
.route-panel-head {
padding: 12px 16px;
border-bottom: 1px solid rgba(255,255,255,0.07);
display: flex; align-items: center; gap: 10px;
font-size: 10px; letter-spacing: 0.22em;
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
}
.route-panel-title { color: #22d3ee; font-weight: 500; flex: 1; }
.route-panel-count { color: rgba(255,255,255,0.4); font-size: 9px; }
.route-panel-items { flex: 1; overflow-y: auto; padding: 8px; }
.route-step {
padding: 11px 13px;
margin-bottom: 6px;
border-radius: 8px;
background: rgba(186,230,253,0.02);
border: 1px solid rgba(255,255,255,0.05);
animation: route-step-in .35s ease both;
animation-delay: calc(var(--idx) * 60ms);
}
@keyframes route-step-in {
from { opacity: 0; transform: translateX(12px); }
to { opacity: 1; transform: translateX(0); }
}
.route-step-line {
display: flex; align-items: center; gap: 10px;
margin-bottom: 6px;
}
.route-line-badge {
display: inline-block; min-width: 32px; height: 22px;
padding: 0 8px;
line-height: 22px; text-align: center;
font-size: 11px; font-weight: 700; letter-spacing: 0.05em;
border-radius: 4px;
font-family: 'JetBrains Mono', monospace;
}
.route-walk-icon { font-size: 14px; flex-shrink: 0; }
.route-step-instruction { font-size: 12px; color: rgba(255,255,255,0.98); line-height: 1.4; }
.route-step-headsign { font-size: 11px; color: rgba(255,255,255,0.05); }
.route-step-meta {
font-size: 10px; color: rgba(255,255,255,0.4);
font-family: 'JetBrains Mono', monospace; letter-spacing: 0.05em;
margin-left: 28px;
}
.route-step-stops { padding-left: 4px; }
.route-step-stop {
display: flex; align-items: center; gap: 8px;
font-size: 11px; color: rgba(255,255,255,0.05);
margin: 2px 0;
}
.route-step-stop .dot { width: 6px; height: 6px; flex-shrink: 0; }
.route-step-stop > span:nth-child(2) { flex: 1; }
.route-step-time {
font-size: 10px; color: rgba(255,255,255,0.4);
font-family: 'JetBrains Mono', monospace;
}
.poi-head {
padding: 12px 16px;
border-bottom: 1px solid rgba(255,255,255,0.07);
display: flex; align-items: center; gap: 10px;
font-size: 10px; letter-spacing: 0.22em;
text-transform: uppercase;
font-family: 'JetBrains Mono', monospace;
}
.poi-title { color: #22d3ee; font-weight: 500; flex: 1; }
.poi-count { color: rgba(255,255,255,0.4); font-size: 9px; }
.poi-close {
width: 22px; height: 22px; border-radius: 50%;
background: transparent; border: none; cursor: none;
color: rgba(255,255,255,0.4); font-size: 18px; line-height: 1;
padding: 0;
transition: color .15s;
}
.poi-close:hover { color: #22d3ee; }
.poi-items { flex: 1; overflow-y: auto; padding: 6px; }
.poi-item {
padding: 11px 13px;
margin-bottom: 4px;
border-radius: 8px;
background: rgba(186,230,253,0.02);
border: 1px solid rgba(255,255,255,0.05);
cursor: none;
transition: background .2s, border-color .2s, opacity .35s, transform .35s;
opacity: 0;
transform: translateX(16px);
animation: poiIn 0.4s ease forwards;
animation-delay: calc(var(--idx, 0) * 40ms);
}
.poi-item.fading-out { animation: poiOut 0.25s ease forwards; }
.poi-item:hover {
background: rgba(34,211,238,0.06);
border-color: rgba(34,211,238,0.4);
}
.poi-name { font-size: 13px; color: rgba(186,230,253,0.7); font-weight: 500; letter-spacing: 0.01em; }
.poi-meta { font-size: 10px; color: rgba(255,255,255,0.4); margin-top: 3px; font-family: 'JetBrains Mono', monospace; }
@keyframes poiIn { to { opacity: 1; transform: translateX(0); } }
@keyframes poiOut { to { opacity: 0; transform: translateX(-16px); } }
/* Loading-Skeleton in der Liste während Overpass lädt */
.poi-skeleton {
padding: 10px 12px; margin-bottom: 4px; border-radius: 8px;
background: rgba(255,255,255,0.05);
border: 1px solid rgba(255,255,255,0.15);
height: 38px;
position: relative;
overflow: hidden;
}
.poi-skeleton::after {
content: ''; position: absolute; inset: 0;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.18), transparent);
animation: shimmer 1.4s ease-in-out infinite;
}
@keyframes shimmer {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
/* Notifications */
/* Notifications: links unten, kollidieren nicht mit POI/Route-Panel rechts */
.notifications {
position: fixed; left: 24px; bottom: 110px; z-index: 30;
display: flex; flex-direction: column-reverse; gap: 8px;
max-width: 340px;
}
.notif {
background: #04060a;
border: 1px solid rgba(34,211,238,0.30);
padding: 9px 13px; border-radius: 6px;
font-size: 11px; letter-spacing: 0.05em;
color: rgba(255,255,255,0.92);
backdrop-filter: blur(16px);
font-family: 'JetBrains Mono', monospace;
animation: notifIn .35s ease-out;
transition: opacity .4s;
box-shadow: 0 4px 18px rgba(0,0,0,0.6);
}
@keyframes notifIn {
from { opacity: 0; transform: translateX(-16px); }
to { opacity: 1; transform: translateX(0); }
}
/* ── CODE TERMINAL PANEL ── */
.code-panel {
position: fixed;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
width: min(860px, calc(100vw - 32px));
max-height: 60vh;
z-index: 22;
background: #0d0d1a;
border: 0.5px solid rgba(79,70,229,0.35);
border-radius: 10px;
overflow: hidden;
box-shadow: 0 0 60px rgba(79,70,229,0.15), 0 24px 60px rgba(0,0,0,0.6);
display: flex;
flex-direction: column;
}
.code-panel-header {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 14px;
background: rgba(79,70,229,0.08);
border-bottom: 0.5px solid rgba(79,70,229,0.2);
flex-shrink: 0;
}
.code-panel-dots { display: flex; gap: 5px; }
.code-panel-dots span { width: 10px; height: 10px; border-radius: 50%; }
.dot-red { background: #ff5f57; }
.dot-yellow { background: #febc2e; }
.dot-green { background: #28c840; }
.code-panel-title {
flex: 1;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: rgba(255,255,255,0.4);
letter-spacing: 1px;
text-align: center;
}
.code-panel-actions { display: flex; gap: 6px; }
.cp-btn {
font-family: 'JetBrains Mono', monospace;
font-size: 9px;
padding: 3px 10px;
background: rgba(79,70,229,0.15);
border: 0.5px solid rgba(79,70,229,0.3);
border-radius: 4px;
color: var(--i2, #a5b4fc);
cursor: pointer;
letter-spacing: 1px;
transition: all 0.15s;
}
.cp-btn:hover { background: rgba(79,70,229,0.3); }
.cp-btn-close {
background: rgba(239,68,68,0.1);
border-color: rgba(239,68,68,0.3);
color: #ef4444;
}
.cp-btn-close:hover { background: rgba(239,68,68,0.25); }
.code-panel-desc {
padding: 8px 16px;
font-size: 10px;
color: rgba(255,255,255,0.5);
letter-spacing: 0.5px;
border-bottom: 0.5px solid rgba(255,255,255,0.04);
flex-shrink: 0;
}
.code-panel-body {
flex: 1;
overflow-y: auto;
overflow-x: auto;
scrollbar-width: thin;
scrollbar-color: rgba(79,70,229,0.3) transparent;
}
.code-pre {
margin: 0;
padding: 16px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
line-height: 1.7;
color: #e2e8f0;
white-space: pre;
min-height: 80px;
}
.code-panel-files {
display: flex;
gap: 2px;
padding: 4px 12px;
background: rgba(0,0,0,0.3);
border-top: 0.5px solid rgba(79,70,229,0.15);
overflow-x: auto;
flex-shrink: 0;
}
.cp-file-tab {
font-family: 'JetBrains Mono', monospace;
font-size: 9px;
padding: 3px 10px;
border-radius: 3px;
color: rgba(255,255,255,0.4);
background: transparent;
border: none;
cursor: pointer;
white-space: nowrap;
transition: all 0.15s;
}
.cp-file-tab:hover,
.cp-file-tab.active {
background: rgba(79,70,229,0.2);
color: var(--i2, #a5b4fc);
}
.code-typing {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
font-family: 'JetBrains Mono', monospace;
font-size: 10px;
color: var(--g, #22d3ee);
flex-shrink: 0;
}
.typing-cursor { animation: blink 0.7s step-end infinite; }
@keyframes blink { 50% { opacity: 0; } }
/* ── FOX BRAIN LAYER ── */
.brain-layer {
position: fixed; inset: 0; z-index: 18;
opacity: 0; pointer-events: none;
transition: opacity 0.9s ease;
background: rgba(4,4,6,0.97);
-webkit-mask-image: radial-gradient(ellipse 80% 72% at 50% 52%,
black 0%, black 35%,
rgba(0,0,0,0.95) 48%,
rgba(0,0,0,0.75) 58%,
rgba(0,0,0,0.35) 70%,
rgba(0,0,0,0.08) 80%,
transparent 90%);
mask-image: radial-gradient(ellipse 80% 72% at 50% 52%,
black 0%, black 35%,
rgba(0,0,0,0.95) 48%,
rgba(0,0,0,0.75) 58%,
rgba(0,0,0,0.35) 70%,
rgba(0,0,0,0.08) 80%,
transparent 90%);
}
body.brain-visible .brain-layer { opacity: 1; pointer-events: all; }
body.brain-visible .fox-mini { display: none; }
body.brain-visible .fox-center {
top: auto; bottom: 130px; left: 30px;
transform: scale(0.65); transform-origin: bottom left; cursor: pointer;
}
.brain-info {
position: absolute; top: 50%; left: 24px;
transform: translateY(-50%); z-index: 10;
background: rgba(8,10,24,0.96);
backdrop-filter: blur(18px);
border: 1px solid rgba(99,102,241,0.55);
border-radius: 10px; padding: 16px; width: 154px;
box-shadow: 0 0 24px rgba(99,102,241,0.15);
}
.bi-title {
font-size: 8px; letter-spacing: 3px;
color: rgba(165,180,252,1.0); margin-bottom: 12px;
}
.bi-stat {
display: flex; justify-content: space-between; align-items: center;
padding: 5px 0; border-bottom: 0.5px solid rgba(255,255,255,0.12);
}
.bi-label { font-size: 7px; color: rgba(255,255,255,0.6); letter-spacing: 1.5px; }
.bi-value { font-size: 13px; color: rgba(255,255,255,1.0); }
.bi-legend { margin-top: 12px; display: flex; flex-direction: column; gap: 5px; }
.bi-legend-item {
display: flex; align-items: center; gap: 7px;
font-size: 8px; color: rgba(255,255,255,0.75);
}
.bi-legend-item span { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.bi-close {
margin-top: 14px; width: 100%; font-size: 8px; letter-spacing: 2px;
padding: 5px; background: rgba(239,68,68,0.12);
border: 1px solid rgba(239,68,68,0.45); border-radius: 4px;
color: rgba(239,68,68,0.9); cursor: pointer; transition: all 0.15s;
}
.bi-close:hover { background: rgba(239,68,68,0.25); color: #ef4444; }
.brain-popup {
position: fixed; background: rgba(3,5,18,0.96);
backdrop-filter: blur(20px);
border: 0.5px solid rgba(79,70,229,0.32);
border-radius: 10px; padding: 14px 16px;
max-width: 260px; z-index: 20; pointer-events: all;
}
.bp-type { font-size: 7px; letter-spacing: 2px; color: rgba(165,180,252,0.7); margin-bottom: 4px; }
.bp-title { font-size: 12px; color: rgba(255,255,255,0.95); margin-bottom: 8px; font-weight: 600; }
.bp-content { font-size: 9px; color: rgba(255,255,255,0.5); line-height: 1.6; margin-bottom: 6px; }
.bp-meta { font-size: 8px; color: rgba(255,255,255,0.25); }
.bp-close {
position: absolute; top: 8px; right: 10px; font-size: 10px;
color: rgba(255,255,255,0.3); cursor: pointer; background: none; border: none;
}
.brain-scan {
position: absolute; left: 0; right: 0; height: 1px;
background: linear-gradient(90deg, transparent, rgba(99,102,241,0.18), transparent);
animation: mapscan 9s linear infinite; opacity: 0.3; z-index: 5; pointer-events: none;
}
.brain-hover-label {
position: fixed; z-index: 25; pointer-events: none;
background: rgba(3,5,18,0.88); backdrop-filter: blur(8px);
border: 0.5px solid rgba(34,211,238,0.3); border-radius: 6px;
padding: 4px 10px; font-size: 10px; letter-spacing: 1px;
color: rgba(34,211,238,0.9); opacity: 0;
transition: opacity 0.15s ease; white-space: nowrap;
}
/* Custom cursor */
.cur {
position: fixed; pointer-events: none; z-index: 9999;
width: 16px; height: 16px;
border: 0.5px solid rgba(255,255,255,0.6);
border-radius: 50%;
transform: translate(-50%, -50%);
}
.cur-dot {
position: fixed; pointer-events: none; z-index: 9999;
width: 3px; height: 3px;
background: rgba(255,255,255,0.6);
border-radius: 50%;
transform: translate(-50%, -50%);
}
/* MapLibre Hintergrund */
.maplibregl-canvas, .maplibregl-canvas-container { background: #000 !important; }
/* Popup im HUD-Stil - nicht das default-weisse */
.maplibregl-popup { z-index: 25; }
.maplibregl-popup-content {
background: rgba(3,3,13,0.95) !important;
color: #fff !important;
border: 0.5px solid rgba(255,255,255,0.55) !important;
border-radius: 10px !important;
padding: 10px 14px !important;
font-size: 12px !important;
font-family: 'Inter', system-ui, sans-serif !important;
backdrop-filter: blur(12px);
box-shadow: 0 0 24px rgba(255,255,255,0.35) !important;
line-height: 1.4;
}
.maplibregl-popup-content b {
color: #fff;
display: block;
margin-bottom: 4px;
font-size: 13px;
font-weight: 600;
}
/* Tip auf allen Seiten dunkel färben */
.maplibregl-popup-tip { display: none !important; }
.maplibregl-popup-anchor-top .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-top-right .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip,
.maplibregl-popup-anchor-left .maplibregl-popup-tip,
.maplibregl-popup-anchor-right .maplibregl-popup-tip {
border-color: transparent !important;
}
.maplibregl-popup-close-button {
color: rgba(255,255,255,0.5) !important;
font-size: 18px !important;
padding: 0 6px !important;
}
.maplibregl-popup-close-button:hover { color: #fff !important; background: transparent !important; }