🌟 🎉 Major Update:

This commit is contained in:
Till Tomczak 2025-06-01 23:41:02 +02:00
parent 62efe03887
commit 4042f07c00
228 changed files with 8598 additions and 1893 deletions

657
README.md
View File

@ -1,376 +1,395 @@
# MYP Reservation Platform # MYP Druckerverwaltungssystem
Mercedes-Benz Werk 040 Berlin - 3D-Drucker Reservierungsplattform **Manage Your Printer** - Mercedes-Benz Werk 040 Berlin
Vollständige 3D-Drucker Verwaltungsplattform mit Smart-Plug-Technologie
## 🎯 System-Übersicht
**MYP (Manage Your Printer)** ist ein System zur **zentralen Verwaltung und Steuerung von 3D-Druckern mittels Smart-Plug-Technologie**. Es digitalisiert den Reservierungsprozess für mehrere 3D-Drucker und ermögligt eine **automatisierte Schaltung der Drucker über WLAN-Steckdosen (TP-Link Tapo P110)**.
### 🔑 Kernfunktionen
#### **Benutzer- und Rechteverwaltung**
- **Registrierung, Login und Rollenkonzept** (Admin/Benutzer)
- **Administrierende** können Drucker und Nutzer verwalten
- **Standard-Benutzer** können Reservierungen anlegen und Druckjobs verwalten
#### **Drucker- und Auftragsmanagement**
- **Zentrales Reservierungssystem** für Zeitfenster-Buchungen
- **Automatische Drucker-Schaltung**: Einschalten zum Reservierungsstart, Ausschalten nach Ende
- **Herstellerunabhängig**: Keine direkte Kommunikation mit 3D-Druckern - ausschließlich Stromsteuerung über Smart-Plug-Steckdosen
- **Einfache Integration**: Keine Eingriffe in die Druckerhardware erforderlich
#### **Statistikerfassung**
- **Protokollierung** von Nutzungszeiten und abgeschlossenen Druckaufträgen
- **Auswertungen** (z.B. Gesamtdruckzeit pro Zeitraum)
- **Analytics-Dashboard** für Effizienzanalysen
#### **Offline-Fähigkeit & Kiosk-Modus**
- **Autonomer Betrieb** ohne Internetzugang nach Installation
- **Raspberry Pi Kiosk-Modus**: Vollbild-Dashboard vor Ort
- **Touch-Interface** für aktuelle Druckerbelegungen und Systemstatus
## 📋 Projektarchitektur
Dieses Repository enthält **zwei sich ergänzende Projektarbeiten** für die IHK-Abschlussprüfung:
### 🏗️ **Backend-System** (Till Tomczak) - **KERN-INFRASTRUKTUR**
- **Entwickler**: Till Tomczak
- **Fachrichtung**: Fachinformatiker für digitale Vernetzung
- **Technologie**: **Flask-basiertes Backend in Python** mit **SQLite-Datenbank**
- **Verantwortung**: Hardware-Integration, REST-APIs und cyber-physische Vernetzung
### 📊 **Frontend-System** (Torben Haack) - **BENUTZEROBERFLÄCHE & ANALYTICS**
- **Entwickler**: Torben Haack
- **Fachrichtung**: Fachinformatiker für Daten- und Prozessanalyse
- **Technologie**: **Next.js-basierte Webanwendung** mit erweiterten Analytics
- **Verantwortung**: Moderne Web-UI, Datenvisualisierung und Benutzerfreundlichkeit
## 🏗️ Technische Architektur
### Cyber-Physische Lösung
```
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Frontend-Server │◄──►│ Backend-Server │◄──►│ Raspberry Pi │
│ (Port 3000) │ │ (Port 443/5000) │ │ (Smart-Plugs) │
│ Torben Haack │ │ Till Tomczak │ │ Till Tomczak │
│ │ │ │ │ │
│ • Next.js App │ │ • Flask REST-API │ │ • TP-Link Tapo P110 │
│ • Analytics UI │ │ • SQLite Database │ │ • Hardware Control │
│ • PWA-Features │ │ • Smart-Plug API │ │ • Kiosk Interface │
│ • HTTPS Client │ │ • HTTPS Server │ │ • Offline Operation │
│ • Export Functions │ │ • Session Management│ │ • Touch Interface │
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
```
### Kommunikations-Architektur
- **RESTful API**: Backend kommuniziert mit Frontend und externen Diensten
- **HTTPS-Verschlüsselung**: Selbstsignierte Zertifikate für sichere Übertragung
- **Progressive Web App (PWA)**: Offline-Funktionalität im Browser
- **Smart-Plug-Integration**: Lokale WLAN-Steuerung ohne Cloud-Abhängigkeit
## 🚀 Schnellstart ## 🚀 Schnellstart
### MYP Control Center (Empfohlen) ### Backend-System (Hardware & APIs)
Das zentrale Installationssystem für alle Komponenten:
```bash ```bash
# Repository klonen # Backend-Server starten (Till Tomczaks System)
git clone <repository-url> cd backend
cd Projektarbeit-MYP sudo ./setup.sh # Automatische Installation
python app.py # Oder für Development
# MYP Control Center starten # Kiosk-Modus auf Raspberry Pi
./myp_installer.sh sudo systemctl start myp-https.service
``` ```
Das MYP Control Center bietet: ### Frontend-System (Web-Interface)
- **Schnellstart-Installationen** (Vollständig, Backend-Only, Entwicklung)
- **Produktions-Installer** (Integration der v3.2 install.sh Funktionalität)
- **Granulare Installation** (Einzelne Komponenten)
- **System & Wartung** (Tests, Status, Informationen)
### Direkter Produktions-Installer
Für schnelle Produktions-Deployments direkt im MYP Control Center → Option 4:
```bash
./myp_installer.sh
# → Wähle Option 4: Produktions-Installer
# → Backend installieren (Raspberry Pi)
# → Frontend installieren (Docker)
```
### Voraussetzungen
- **Backend (Raspberry Pi)**: Python 3.11, systemd
- **Frontend (m040tbaraspi001)**: Docker, Docker Compose
## 🌐 Zugriff
- **Frontend**: https://m040tbaraspi001.de040.corpintra.net
- **Backend API**: https://raspberrypi/api
## 🔧 Konfiguration
### Netzwerk
| Komponente | Hostname | IP | Port |
|------------|----------|----|----- |
| Frontend | m040tbaraspi001.de040.corpintra.net | 192.168.0.109 | 443 |
| Backend | raspberrypi | 192.168.0.105 | 443 |
### TLS-Zertifikate
Selbstsignierte Zertifikate werden automatisch generiert:
- Backend: `backend/app/certs/`
- Frontend: `frontend/certs/`
## 📊 Health Checks
```bash
# Backend
curl -k https://raspberrypi/api/test
# Frontend
curl -k https://m040tbaraspi001.de040.corpintra.net/health
```
## 🛠️ Entwicklung
### MYP Control Center (Entwicklungs-Setup)
```bash
./myp_installer.sh
# → Option 3: Entwicklungs-Setup
```
### MYP Kiosk-Modus (Produktions-bereit)
Das Backend bietet parallel zur API auch ein **vollständiges Web-Interface** für Kiosk-Betrieb:
```bash
./myp_installer.sh
# → Option 2: Backend-Only Installation (mit Kiosk Web Interface)
# oder
# → Option 5: Granulare Installation → Kiosk-Modus installieren
```
**Kiosk-Features:**
- ✅ **Web-Interface parallel zur API** - Kein separates Frontend nötig
- ✅ **Touch-optimierte Bedienung** - Ideal für Raspberry Pi Touchscreens
- ✅ **Automatischer Browser-Start** - Vollbild-Modus beim Boot
- ✅ **systemd Integration** - Service-basierte Kiosk-Verwaltung
- ✅ **Produktions-bereit** - SSL, Logging, Monitoring
**Kiosk URLs:**
- Hauptinterface: `https://raspberrypi/`
- Dashboard: `https://raspberrypi/dashboard`
- Drucker-Verwaltung: `https://raspberrypi/printers`
- Job-Verwaltung: `https://raspberrypi/jobs`
- Admin-Panel: `https://raspberrypi/admin`
### Manuelle Installation
#### Backend Debug-Modus
```bash
cd backend/app
python3.11 app.py --debug
```
#### Frontend Development
```bash ```bash
# Frontend-Server starten (Torben Haacks System)
cd frontend cd frontend
npm run dev pnpm install
pnpm db # Datenbank einrichten
pnpm dev # Development-Server
# Produktions-Deployment
pnpm build && pnpm start
``` ```
#### Kiosk-Modus manuell starten ### Vollständiges System
```bash ```bash
# Backend starten # Backend (API-Server)
cd backend/app && python app.py cd backend && python app.py --host 0.0.0.0 --port 5000 &
# Kiosk-Browser starten (separates Terminal) # Frontend (Web-Interface)
./backend/app/start_kiosk.sh cd frontend && pnpm build && pnpm start &
``` ```
## 📁 Projektstruktur ## 🌐 Systemzugriff
### Produktions-URLs
- **Web-Interface**: `http://localhost:3000` (Torben Haacks Frontend)
- **API-Backend**: `https://192.168.0.105:443/api` (Till Tomczaks APIs auf separatem Server)
- **Kiosk-Modus**: `https://192.168.0.105:443` (Lokales Touch-Interface)
### Standard-Anmeldedaten
- **Benutzername**: `admin`
- **Passwort**: `admin123`
### Netzwerk-Konfiguration
- **Backend-Server**: `192.168.0.105:443` (HTTPS)
- **Frontend-Server**: `localhost:3000` (HTTP Development)
- **SSL-Zertifikate**: Selbstsigniert (automatisch akzeptiert)
## 📁 Projektstruktur & Integration
``` ```
Projektarbeit-MYP/ Projektarbeit-MYP/
├── myp_installer.sh # 🎯 HAUPT-INSTALLER (Control Center) ├── backend/ # 🏗️ KERN-INFRASTRUKTUR (Till Tomczak)
├── backend/ │ ├── app.py # Flask REST-API Server
│ ├── app/ │ ├── models.py # SQLite-Datenbank & Business Logic
│ │ ├── certs/ # TLS-Zertifikate │ ├── utils/ # Smart-Plug Integration (TP-Link Tapo P110)
│ │ ├── database/ # SQLite-Datenbank │ ├── templates/ # Kiosk-Mode Web-Interface
│ │ ├── logs/ # Anwendungslogs │ ├── static/ # PWA-Assets für Offline-Betrieb
│ │ └── app.py # Hauptanwendung │ └── systemd/ # Raspberry Pi Service-Integration
│ ├── myp.service # systemd Service ├──
│ ├── requirements.txt # Python-Abhängigkeiten ├── frontend/ # 📊 WEB-INTERFACE (Torben Haack)
│ └── legacy_setup_raspberry_pi.sh # Legacy Skript │ ├── src/app/ # Next.js Haupt-Anwendung
├── frontend/ │ ├── src/components/ # React UI-Komponenten
│ ├── certs/ # TLS-Zertifikate │ ├── src/lib/api/ # Backend-REST-API-Integration
│ ├── docker/ │ └── src/lib/analytics/ # Statistik-Algorithmen
│ │ ├── caddy/ ├──
│ │ │ └── Caddyfile # Reverse Proxy Konfiguration ├── docs/ # 📚 Gemeinsame Dokumentation
│ │ └── legacy_deploy.sh # Legacy Skript └── README.md # Diese Datei
│ ├── src/ # Next.js Anwendung
│ └── docker-compose.yml
├── scripts/
│ └── legacy_generate_certs.sh # Legacy Skript
├── archiv/
│ └── myp_installer_legacy.sh # Archivierte Version
└── docs/ # Dokumentation
``` ```
### Script-Status ## 🎯 Funktions-Aufgabenteilung
| Skript | Status | Verwendung | ### Backend-Verantwortlichkeiten (Till Tomczak)
|--------|--------|------------| - ✅ **Smart-Plug-Steuerung**: TP-Link Tapo P110 WLAN-Steckdosen
| `myp_installer.sh` | ✅ **AKTIV** | Haupt-Control-Center | - ✅ **Automatische Drucker-Schaltung**: Zeitgesteuerte Ein-/Ausschaltung
| `*legacy_*.sh` | 📦 Legacy | Historische Versionen | - ✅ **REST-API-Bereitstellung**: Vollständige API für alle Drucker-Operationen
| `archiv/myp_installer_legacy.sh` | 📦 Archiv | Alte Version 4.0 | - ✅ **Cyber-physische Vernetzung**: IT-System ↔ Hardware-Integration
- ✅ **SQLite-Datenbank**: Benutzer, Drucker, Jobs, Statistiken
- ✅ **HTTPS-Server**: Selbstsignierte Zertifikate und Session-Management
- ✅ **Raspberry Pi Integration**: Systemd-Services und Kiosk-Modus
- ✅ **Offline-Fähigkeit**: Autonomer Betrieb ohne Internet
## 🔒 Sicherheit ### Frontend-Verantwortlichkeiten (Torben Haack)
- ✅ **Moderne Web-UI**: React-basierte Benutzeroberfläche
- ✅ **Progressive Web App**: Offline-Funktionalität im Browser
- ✅ **Advanced Analytics**: Interaktive Charts und Datenvisualisierung
- ✅ **Reporting-System**: PDF/Excel-Export und automatisierte Berichte
- ✅ **Responsive Design**: Optimiert für Desktop, Tablet und Mobile
- ✅ **Backend-API-Integration**: Nahtlose REST-API-Anbindung
- ✅ **Statistik-Auswertungen**: Nutzungsanalysen und Trend-Analysen
- ✅ **Benutzerfreundlichkeit**: Intuitive Workflows für alle Stakeholder
- HTTPS-only (Port 443) ## 🔗 API-Integration & Kommunikation
- Selbstsignierte TLS-Zertifikate
- HTTP → HTTPS Redirect
- Security Headers (HSTS, CSP, etc.)
## 📝 Logs ### Backend-REST-Endpunkte (Till Tomczak)
```typescript
// Drucker-Management
GET /api/printers // Alle Drucker abrufen
POST /api/printers // Neuen Drucker hinzufügen
PUT /api/printers/{id} // Drucker aktualisieren
DELETE /api/printers/{id} // Drucker löschen
### Backend // Reservierungs-Management
GET /api/jobs // Alle Reservierungen abrufen
POST /api/jobs // Neue Reservierung erstellen
PUT /api/jobs/{id}/finish // Reservierung beenden
DELETE /api/jobs/{id} // Reservierung abbrechen
// Smart-Plug-Steuerung (TP-Link Tapo P110)
POST /api/plugs/{id}/on // Drucker einschalten
POST /api/plugs/{id}/off // Drucker ausschalten
GET /api/plugs/{id}/status // Plug-Status abfragen
// Statistiken & Analytics
GET /api/stats // Nutzungsstatistiken
GET /api/reports // Report-Daten für Analytics
```
### Frontend-Integration (Torben Haack)
```typescript
// Backend-API Client - Konfiguriert für separaten Server
export class MYPApiClient {
constructor(baseURL: string = 'https://192.168.0.105:443/api') {
this.baseURL = baseURL;
}
async getPrinters() {
return fetch(`${this.baseURL}/printers`).then(r => r.json());
}
async getJobs() {
return fetch(`${this.baseURL}/jobs`).then(r => r.json());
}
async getStats() {
return fetch(`${this.baseURL}/stats`).then(r => r.json());
}
}
// API-Konfiguration mit Fallback-URLs
export const API_BASE_URL = {
primary: 'https://192.168.0.105:443',
fallbacks: [
'https://192.168.0.105',
'https://raspberrypi'
]
};
```
## 🖥️ Deployment-Szenarien
### Szenario 1: Separate Server (Empfohlen)
```bash ```bash
# systemd Journal # Backend-Server (z.B. Raspberry Pi oder Linux-Server)
sudo journalctl -u myp.service -f cd backend
sudo systemctl start myp-https.service
# Anwendungslogs # Frontend-Server (z.B. Node.js-Server oder Cloud-Deployment)
tail -f backend/app/logs/app/app.log cd frontend
npm run build && npm start
``` ```
### Frontend ### Szenario 2: Docker-Deployment
```yaml
# docker-compose.yml
services:
backend:
build: ./backend
ports: ["5000:5000", "443:443"]
frontend:
build: ./frontend
ports: ["3000:3000"]
environment:
- NEXT_PUBLIC_API_URL=http://backend:5000/api
```
### Szenario 3: Raspberry Pi Kiosk (Lokal)
```bash ```bash
# Docker Logs # Vollständige Kiosk-Installation
docker-compose logs -f cd backend && sudo ./setup.sh
# Automatischer Start: Touch-Interface + Smart-Plug-Steuerung
# Caddy Logs
docker-compose logs caddy
``` ```
### Kiosk-Modus ## 🔧 Konfiguration & Environment
### Backend-Konfiguration (.env)
```env
# Flask-Server Einstellungen
FLASK_HOST=0.0.0.0
FLASK_PORT=5000
SSL_ENABLED=true
DATABASE_URL=sqlite:///myp.db
# Smart-Plug Konfiguration (TP-Link Tapo P110)
TAPO_USERNAME=your-tapo-email
TAPO_PASSWORD=your-tapo-password
# Kiosk-Modus
KIOSK_MODE=true
OFFLINE_MODE=true
```
### Frontend-Konfiguration (.env.local)
```env
# Frontend-Server Einstellungen - Separater Backend-Server
NEXT_PUBLIC_API_URL=https://192.168.0.105:443
DATABASE_URL=file:./db/frontend.db
# SSL-Zertifikat Handling für selbstsignierte Zertifikate
NODE_TLS_REJECT_UNAUTHORIZED=0
# Analytics-Features
ENABLE_ADVANCED_ANALYTICS=true
CHART_REFRESH_INTERVAL=30000
```
## 📊 Features im Überblick
### Backend-Features (Till Tomczak) - Cyber-Physische Integration
- **TP-Link Tapo P110 Integration**: Lokale WLAN-Steckdosen-Steuerung
- **Automatische Zeitsteuerung**: Drucker Ein-/Ausschaltung nach Reservierung
- **Herstellerunabhängigkeit**: Keine direkten Drucker-Eingriffe erforderlich
- **Flask REST-APIs**: Vollständige CRUD-Operationen
- **SQLite-Datenbank**: Lokale Datenpersistenz ohne externe Abhängigkeiten
- **HTTPS-Verschlüsselung**: Selbstsignierte Zertifikate
- **Offline-Betrieb**: Vollständig autonomer Betrieb ohne Internet
- **Raspberry Pi Kiosk**: Touch-optimiertes Dashboard vor Ort
### Frontend-Features (Torben Haack) - Moderne Web-Oberfläche
- **Progressive Web App**: Offline-Funktionalität im Browser
- **React 18 + Next.js 14**: Moderne, performante Web-Technologien
- **Analytics-Dashboard**: Recharts-Visualisierungen für Nutzungsstatistiken
- **Responsive Design**: Optimiert für alle Endgeräte (Desktop/Tablet/Mobile)
- **Real-time Updates**: Live-Synchronisation mit Backend-APIs
- **Export-Funktionen**: PDF/Excel-Reports für Management-Analysen
- **Benutzerfreundlich**: Intuitive Workflows für alle Stakeholder
## 🛠️ Entwicklung
### Backend-Entwicklung (Till Tomczak)
```bash ```bash
# Backend Service cd backend
sudo systemctl status myp.service python -m venv venv
source venv/bin/activate # Linux/Mac
# Kiosk-Browser Service pip install -r requirements.txt
sudo systemctl status myp-kiosk-browser.service python app.py --debug
# Kiosk-Browser Logs
sudo journalctl -u myp-kiosk-browser.service -f
``` ```
## 🔧 Services ### Frontend-Entwicklung (Torben Haack)
### Backend Services
```bash ```bash
# Backend starten/stoppen cd frontend
sudo systemctl start myp.service pnpm install
sudo systemctl stop myp.service pnpm db:migrate
sudo systemctl restart myp.service pnpm dev
# Kiosk-Browser starten/stoppen (falls installiert)
sudo systemctl start myp-kiosk-browser.service
sudo systemctl stop myp-kiosk-browser.service
# Automatischen Start aktivieren/deaktivieren
sudo systemctl enable myp.service
sudo systemctl enable myp-kiosk-browser.service
``` ```
## 🆘 Troubleshooting ### Integration testen
### MYP Control Center verwenden
```bash ```bash
./myp_installer.sh # Backend-APIs testen
# → Option 6: Systemvoraussetzungen prüfen curl http://localhost:5000/api/printers
# → Option 7: Anwendung starten
# Frontend mit Backend-Integration
# Frontend auf :3000 konsumiert Backend-APIs von :5000
``` ```
### Backend startet nicht ## 📚 Dokumentation
```bash
# Service Status prüfen
sudo systemctl status myp.service
# Logs prüfen ### Backend-Dokumentation (Till Tomczak)
sudo journalctl -u myp.service --no-pager - [`backend/README.md`](backend/README.md) - Hardware-Setup & API-Dokumentation
- [`backend/docs/`](backend/docs/) - Raspberry Pi Konfiguration & Smart-Plug-Integration
# Zertifikate prüfen ### Frontend-Dokumentation (Torben Haack)
ls -la backend/app/certs/ - [`frontend/README.md`](frontend/README.md) - UI-Entwicklung & Analytics
``` - [`frontend/docs/`](frontend/docs/) - Component-Library & PWA-Features
### Frontend nicht erreichbar ### Gemeinsame Dokumentation
```bash - [`docs/myp_documentation.md`](docs/myp_documentation.md) - Vollständige Projektdokumentation
# Container Status prüfen - [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) - Production-Deployment-Guide
docker-compose ps
# Netzwerk prüfen ## 🤝 Projektphilosophie
docker network ls
# Zertifikate prüfen ### Cyber-Physische Vernetzung
ls -la frontend/certs/ MYP stellt eine **cyber-physische Lösung** dar, die **IT-System (Reservierungsplattform) und Hardware (Smart-Plugs und Drucker) eng vernetzt**. Das System überbrückt die digitale und physische Welt durch intelligente Automatisierung.
```
### Verbindungsprobleme ### Komplementäre Expertisen
```bash - **Till Tomczak**: Spezialist für Hardware-Integration und cyber-physische Vernetzung
# DNS auflösen - **Torben Haack**: Spezialist für Frontend-Entwicklung und Datenanalyse
nslookup raspberrypi
nslookup m040tbaraspi001.de040.corpintra.net
# Ports prüfen ### Gemeinsame Ziele
netstat -tlnp | grep :443 - **Digitalisierung**: Modernisierung des Reservierungsprozesses
``` - **Automatisierung**: Zeitgesteuerte Hardware-Steuerung ohne manuelle Eingriffe
- **Benutzerfreundlichkeit**: Intuitive Bedienung für alle Stakeholder
- **Effizienz**: Optimierte Ressourcennutzung und Energieeinsparung
## 📋 Version ## 👥 Entwicklerteam
- **Version**: 3.2-final ### Till Tomczak - **Backend-Infrastruktur & Hardware-Integration**
- **Control Center**: v4.0 mit v3.2 Integration - **Cyber-Physische Systeme**: Smart-Plug-Integration und Hardware-Steuerung
- **Build**: Production - **System-Architektur**: Flask-APIs und SQLite-Datenbank-Design
- **Installer**: MYP Control Center - **DevOps**: Raspberry Pi Services und Produktions-Deployment
- **Offline-Systeme**: Autonomer Betrieb ohne Internet-Abhängigkeiten
## 👥 Support ### Torben Haack - **Frontend-Entwicklung & Analytics**
- **Progressive Web Apps**: Moderne Browser-Technologien und Offline-Features
- **User Interface**: React-Komponenten und responsive Design
- **Datenvisualisierung**: Charts, Dashboards und Analytics
- **API-Integration**: Nahtlose Backend-Anbindung und Real-time Updates
Bei Problemen verwenden Sie das MYP Control Center oder wenden Sie sich an das IT-Team des Mercedes-Benz Werk 040 Berlin. ## 📄 Lizenz
## 🖥️ Zwei-Server-Setup (Produktions-Architektur) Dieses Projekt wurde für den internen Gebrauch bei Mercedes-Benz entwickelt.
Das MYP-System ist für eine **Zwei-Server-Architektur** optimiert: ---
### Server-Architektur **Backend-System**: Till Tomczak (Cyber-Physische Vernetzung & Hardware-Integration)
**Frontend-System**: Torben Haack (Progressive Web App & Analytics)
| Server | Hostname | Komponenten | URL | **Architektur**: Microservices mit REST-API-Integration
|--------|----------|-------------|-----| **Technologie**: Flask + SQLite (Backend) + Next.js + React (Frontend)
| **Frontend-Server** | `m040tbaraspi001.de040.corpintra.net` | Next.js + Docker + Caddy | `https://m040tbaraspi001.de040.corpintra.net` | **Hardware**: Raspberry Pi + TP-Link Tapo P110 Smart-Plugs
| **Backend-Server** | `raspberrypi` | Flask API + Web Interface + Kiosk | `https://raspberrypi` | **Entwickelt für**: Mercedes-Benz Werk 040 Berlin MYP
### 🚀 Server-spezifische Installation (Empfohlen)
Der `myp_installer.sh` erkennt automatisch den Server-Typ und bietet passende Installationsoptionen:
```bash
./myp_installer.sh
# Wählen Sie: "1. Server-spezifische Installation (Empfohlen)"
```
#### Frontend-Server (m040tbaraspi001)
```bash
# Automatische Erkennung: m040tbaraspi001.de040.corpintra.net
# Verfügbare Optionen:
# 1. Frontend installieren (Next.js + Docker)
# 2. Frontend Produktions-Deployment (Port 443 mit SSL)
# 3. Nur Docker & Dependencies installieren
```
#### Backend-Server (Raspberry Pi)
```bash
# Automatische Erkennung: raspberrypi
# Verfügbare Optionen:
# 1. Backend installieren (Flask API + Web Interface)
# 2. Kiosk-Modus installieren (Touch-Interface)
# 3. Produktions-Setup (Backend + Kiosk + Services)
# 4. Nur Python & Dependencies installieren
```
### 🔧 Manuelle Installation
#### Frontend-Server Setup
```bash
# Auf m040tbaraspi001.de040.corpintra.net
cd frontend/
npm install
docker-compose up -d
```
#### Backend-Server Setup
```bash
# Auf raspberrypi
cd backend/app/
python3.11 -m pip install -r requirements.txt
sudo systemctl start myp.service
sudo systemctl start myp-kiosk-browser.service # Optional: Kiosk-Modus
```
### 🌐 URLs & Zugriff
#### Frontend (m040tbaraspi001)
- **Haupt-URL**: `https://m040tbaraspi001.de040.corpintra.net`
- **Entwicklung**: `http://localhost:3000` (npm run dev)
- **Produktion**: `https://localhost:443` (Docker)
#### Backend (Raspberry Pi)
- **API**: `https://raspberrypi/api`
- **Web Interface**: `https://raspberrypi`
- **Kiosk-Modus**: `https://raspberrypi` (Vollbild-Touch-Interface)
### 🔗 Server-Kommunikation
Die Server kommunizieren über HTTPS:
- **Frontend → Backend**: `https://raspberrypi/api`
- **OAuth Callbacks**: `https://m040tbaraspi001.de040.corpintra.net/auth/login/callback`
- **Cross-Origin**: Automatisch konfiguriert für beide Domains
### 🛠️ Konfiguration
#### Frontend (.env.local)
```bash
# Backend-Verbindung
NEXT_PUBLIC_API_URL=https://raspberrypi
NEXT_PUBLIC_BACKEND_HOST=raspberrypi
# Frontend-URLs
NEXT_PUBLIC_FRONTEND_URL=https://m040tbaraspi001.de040.corpintra.net
NEXTAUTH_URL=https://m040tbaraspi001.de040.corpintra.net
```
#### Backend (config/settings.py)
```python
# Frontend-Verbindung
FRONTEND_URL = "https://m040tbaraspi001.de040.corpintra.net"
CORS_ORIGINS = ["https://m040tbaraspi001.de040.corpintra.net"]
# Kiosk-Konfiguration
KIOSK_MODE = True
KIOSK_AUTO_LOGIN = True
```

151
backend/build-kiosk-css.ps1 Normal file
View File

@ -0,0 +1,151 @@
# MYP Platform - Kiosk CSS Build Script (PowerShell)
# Optimiert und minifiziert CSS für maximale Performance im Offline-Kiosk-Modus
Write-Host "Starte Kiosk CSS Build..." -ForegroundColor Green
# Erstelle Build-Verzeichnis
if (!(Test-Path "static\css\build")) {
New-Item -ItemType Directory -Path "static\css\build" -Force | Out-Null
}
# Prüfe ob Quelldateien existieren
if (!(Test-Path "static\css\kiosk-optimized.css")) {
Write-Host "FEHLER: static\css\kiosk-optimized.css nicht gefunden!" -ForegroundColor Red
exit 1
}
if (!(Test-Path "static\css\icons-minimal.css")) {
Write-Host "FEHLER: static\css\icons-minimal.css nicht gefunden!" -ForegroundColor Red
exit 1
}
if (!(Test-Path "static\css\critical-inline.css")) {
Write-Host "FEHLER: static\css\critical-inline.css nicht gefunden!" -ForegroundColor Red
exit 1
}
# Erstelle eine kombinierte CSS-Datei in korrekter Reihenfolge
Write-Host "Kombiniere CSS-Dateien..." -ForegroundColor Yellow
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$header = @"
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: $timestamp */
"@
# CSS-Dateien in optimaler Reihenfolge kombinieren
Write-Host "Lade kiosk-optimized.css..." -ForegroundColor Gray
$kioskCSS = Get-Content "static\css\kiosk-optimized.css" -Raw -Encoding UTF8
Write-Host "Lade icons-minimal.css..." -ForegroundColor Gray
$iconsCSS = Get-Content "static\css\icons-minimal.css" -Raw -Encoding UTF8
# Kombiniere CSS-Inhalte
$combinedCSS = $header + $kioskCSS + "`r`n`r`n" + $iconsCSS
# TailwindCSS mit aggressivem Purging bauen
Write-Host "Purge TailwindCSS..." -ForegroundColor Yellow
try {
$process = Start-Process "npx" -ArgumentList "tailwindcss", "-i", "static\css\input.css", "-o", "static\css\build\tailwind-purged.css", "--minify" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -eq 0) {
Write-Host "TailwindCSS erfolgreich gebaut" -ForegroundColor Green
$tailwindCSS = Get-Content "static\css\build\tailwind-purged.css" -Raw -Encoding UTF8
$combinedCSS += "`r`n`r`n" + $tailwindCSS
} else {
Write-Host "TailwindCSS Build fehlgeschlagen, verwende ohne Tailwind" -ForegroundColor Yellow
}
} catch {
Write-Host "TailwindCSS Build fehlgeschlagen: $($_.Exception.Message)" -ForegroundColor Yellow
}
# Kombinierte CSS speichern
Write-Host "Speichere kombinierte CSS..." -ForegroundColor Gray
$combinedCSS | Out-File -FilePath "static\css\build\kiosk-combined.css" -Encoding UTF8
# CSS minifizieren (falls cssnano verfügbar)
Write-Host "Minifiziere CSS..." -ForegroundColor Yellow
try {
$process = Start-Process "npx" -ArgumentList "cssnano", "static\css\build\kiosk-combined.css", "static\css\build\kiosk-production.css", "--no-map" -Wait -PassThru -NoNewWindow
if ($process.ExitCode -eq 0) {
Write-Host "CSS erfolgreich minifiziert" -ForegroundColor Green
} else {
Write-Host "cssnano fehlgeschlagen, verwende unminifizierte Version" -ForegroundColor Yellow
Copy-Item "static\css\build\kiosk-combined.css" "static\css\build\kiosk-production.css"
}
} catch {
Write-Host "cssnano nicht verfügbar, verwende unminifizierte Version" -ForegroundColor Yellow
Copy-Item "static\css\build\kiosk-combined.css" "static\css\build\kiosk-production.css"
}
# Erstelle kritisches CSS für Inline-Verwendung
Write-Host "Erstelle kritisches CSS..." -ForegroundColor Yellow
Copy-Item "static\css\critical-inline.css" "static\css\build\critical.css"
# Erstelle eine Version ohne FontAwesome
Write-Host "Entferne FontAwesome-Abhängigkeiten..." -ForegroundColor Yellow
if (Test-Path "static\css\build\kiosk-production.css") {
$content = Get-Content "static\css\build\kiosk-production.css" | Where-Object { $_ -notmatch "fontawesome" }
$content | Out-File -FilePath "static\css\build\kiosk-no-fa.css" -Encoding UTF8
}
# Dateigröße-Analyse
Write-Host ""
Write-Host "Dateigröße-Analyse:" -ForegroundColor Cyan
if (Test-Path "static\css\build\critical.css") {
$criticalSize = (Get-Item "static\css\build\critical.css").Length
Write-Host "Critical CSS (inline): $criticalSize bytes"
}
if (Test-Path "static\css\build\kiosk-production.css") {
$kioskSize = (Get-Item "static\css\build\kiosk-production.css").Length
Write-Host "Kiosk Production CSS: $kioskSize bytes"
}
if (Test-Path "static\css\build\kiosk-no-fa.css") {
$noFaSize = (Get-Item "static\css\build\kiosk-no-fa.css").Length
Write-Host "Ohne FontAwesome: $noFaSize bytes"
}
# Vergleich mit Original-Dateien
if ((Test-Path "static\css\tailwind.min.css") -and (Test-Path "static\css\build\kiosk-production.css")) {
$originalSize = (Get-Item "static\css\tailwind.min.css").Length
$optimizedSize = (Get-Item "static\css\build\kiosk-production.css").Length
if ($originalSize -gt 0) {
$reduction = [math]::Round((1 - ($optimizedSize / $originalSize)) * 100, 1)
Write-Host "TailwindCSS Original: $originalSize bytes"
Write-Host "Größenreduktion: $reduction%" -ForegroundColor Green
}
}
# Cache-Busting Hash generieren
if (Test-Path "static\css\build\kiosk-production.css") {
$hash = (Get-FileHash "static\css\build\kiosk-production.css" -Algorithm SHA256).Hash.Substring(0, 8).ToLower()
Copy-Item "static\css\build\kiosk-production.css" "static\css\build\kiosk-$hash.css"
Write-Host ""
Write-Host "Build abgeschlossen!" -ForegroundColor Green
Write-Host ""
Write-Host "Generierte Dateien:" -ForegroundColor Cyan
Write-Host " • static\css\build\critical.css (inline verwenden)"
Write-Host " • static\css\build\kiosk-production.css (Haupt-CSS)"
Write-Host " • static\css\build\kiosk-$hash.css (mit Cache-Busting)"
Write-Host ""
Write-Host "HTML-Integration:" -ForegroundColor Cyan
Write-Host ' <style>/* Inhalt von critical.css hier einfügen */</style>'
Write-Host ' <link rel="stylesheet" href="/static/css/build/kiosk-production.css">'
Write-Host ""
Write-Host "Für maximale Performance: Service Worker entfernen und nur statische CSS verwenden" -ForegroundColor Blue
}
# Cleanup temporärer Dateien
if (Test-Path "static\css\build\kiosk-combined.css") {
Remove-Item "static\css\build\kiosk-combined.css"
}
if (Test-Path "static\css\build\tailwind-purged.css") {
Remove-Item "static\css\build\tailwind-purged.css"
}
Write-Host "Cleanup abgeschlossen" -ForegroundColor Green

View File

@ -0,0 +1,88 @@
#!/bin/bash
# MYP Platform - Kiosk CSS Build Script
# Optimiert und minifiziert CSS für maximale Performance im Offline-Kiosk-Modus
echo "🚀 Starte Kiosk CSS Build..."
# Erstelle Build-Verzeichnis
mkdir -p static/css/build
# Erstelle eine kombinierte CSS-Datei in korrekter Reihenfolge
echo "📦 Kombiniere CSS-Dateien..."
cat > static/css/build/kiosk-combined.css << 'EOF'
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: $(date) */
EOF
# CSS-Dateien in optimaler Reihenfolge kombinieren
cat static/css/kiosk-optimized.css >> static/css/build/kiosk-combined.css
echo "" >> static/css/build/kiosk-combined.css
cat static/css/icons-minimal.css >> static/css/build/kiosk-combined.css
# TailwindCSS mit aggressivem Purging bauen
echo "🎯 Purge TailwindCSS..."
npx tailwindcss -i static/css/input.css -o static/css/build/tailwind-purged.css --minify
# Kombiniere mit Tailwind
echo "" >> static/css/build/kiosk-combined.css
cat static/css/build/tailwind-purged.css >> static/css/build/kiosk-combined.css
# CSS minifizieren (falls cssnano verfügbar)
if command -v npx &> /dev/null; then
echo "🗜️ Minifiziere CSS..."
npx cssnano static/css/build/kiosk-combined.css static/css/build/kiosk-production.css --no-map
else
echo "⚠️ cssnano nicht verfügbar, verwende unminifizierte Version"
cp static/css/build/kiosk-combined.css static/css/build/kiosk-production.css
fi
# Erstelle kritisches CSS für Inline-Verwendung
echo "⚡ Erstelle kritisches CSS..."
cp static/css/critical-inline.css static/css/build/critical.css
# Erstelle eine Version ohne FontAwesome
echo "🚫 Entferne FontAwesome-Abhängigkeiten..."
grep -v "fontawesome" static/css/build/kiosk-production.css > static/css/build/kiosk-no-fa.css
# Dateigröße-Analyse
echo ""
echo "📊 Dateigröße-Analyse:"
echo "Critical CSS (inline): $(wc -c < static/css/build/critical.css) bytes"
echo "Kiosk Production CSS: $(wc -c < static/css/build/kiosk-production.css) bytes"
echo "Ohne FontAwesome: $(wc -c < static/css/build/kiosk-no-fa.css) bytes"
# Vergleich mit Original-Dateien
if [ -f "static/css/tailwind.min.css" ]; then
original_size=$(wc -c < static/css/tailwind.min.css)
optimized_size=$(wc -c < static/css/build/kiosk-production.css)
reduction=$((100 - (optimized_size * 100 / original_size)))
echo "TailwindCSS Original: $original_size bytes"
echo "Größenreduktion: $reduction%"
fi
# Cache-Busting Hash generieren
hash=$(sha256sum static/css/build/kiosk-production.css | cut -d' ' -f1 | cut -c1-8)
cp static/css/build/kiosk-production.css static/css/build/kiosk-$hash.css
echo ""
echo "✅ Build abgeschlossen!"
echo ""
echo "📁 Generierte Dateien:"
echo " • static/css/build/critical.css (inline verwenden)"
echo " • static/css/build/kiosk-production.css (Haupt-CSS)"
echo " • static/css/build/kiosk-$hash.css (mit Cache-Busting)"
echo ""
echo "🔧 HTML-Integration:"
echo ' <style>/* Inhalt von critical.css hier einfügen */</style>'
echo ' <link rel="stylesheet" href="/static/css/build/kiosk-production.css">'
echo ""
echo "💡 Für maximale Performance: Service Worker entfernen und nur statische CSS verwenden"
# Cleanup temporärer Dateien
rm -f static/css/build/kiosk-combined.css
rm -f static/css/build/tailwind-purged.css
echo "🧹 Cleanup abgeschlossen"

Binary file not shown.

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@

View File

@ -87,3 +87,7 @@
2025-06-01 22:39:54 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert 2025-06-01 22:39:54 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 22:39:56 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert 2025-06-01 22:39:56 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 22:40:09 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert 2025-06-01 22:40:09 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:08:24 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:10:01 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:16:55 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
2025-06-01 23:32:06 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert

View File

@ -2099,3 +2099,123 @@ WHERE jobs.status = ?) AS anon_1]
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Job-Scheduler gestartet 2025-06-01 22:40:14 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP) 2025-06-01 22:40:14 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 22:40:14 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert 2025-06-01 22:40:14 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:08:24 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:08:25 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:08:25 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:08:25 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:08:25 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:08:25 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:08:25 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:08:29 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:08:29 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:08:29 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:08:29 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:10:01 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:10:02 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:10:02 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:10:02 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:10:02 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:10:03 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:10:03 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:10:03 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:10:07 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:10:07 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:10:07 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:10:07 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:10:11 - [app] app - [INFO] INFO - Admin-Check für Funktion admin_page: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:10:11 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:16:55 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:16:56 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:16:56 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:16:56 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:16:56 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:16:56 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:16:56 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:17:00 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:17:00 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:17:00 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:17:00 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:17:28 - [app] app - [INFO] INFO - Admin-Check für Funktion admin_page: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:17:29 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:18:51 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:19:46 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:19:46 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:19:47 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:19:47 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:20:34 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:18 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:21:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:22:39 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:32:05 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
2025-06-01 23:32:07 - [app] app - [INFO] INFO - SQLite für Raspberry Pi optimiert (reduzierte Cache-Größe, SD-Karten I/O)
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ Timeout Force-Quit Manager geladen
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
2025-06-01 23:32:07 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
2025-06-01 23:32:07 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
2025-06-01 23:32:07 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
2025-06-01 23:32:08 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
2025-06-01 23:32:08 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
2025-06-01 23:32:08 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
2025-06-01 23:32:12 - [app] app - [INFO] INFO - ✅ Steckdosen-Initialisierung: 0/2 Drucker erfolgreich
2025-06-01 23:32:12 - [app] app - [WARNING] WARNING - ⚠️ 2 Drucker konnten nicht initialisiert werden
2025-06-01 23:32:12 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Job-Scheduler gestartet
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
2025-06-01 23:32:12 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:33:27 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:10 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:34:57 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:34:57 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:35:55 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:36:45 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:37:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
2025-06-01 23:38:06 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 2, 'total_jobs': 16, 'pending_jobs': 0, 'success_rate': 0.0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 2}

View File

@ -91,3 +91,7 @@
2025-06-01 22:39:54 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) 2025-06-01 22:39:54 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 22:39:56 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) 2025-06-01 22:39:56 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 22:40:09 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation) 2025-06-01 22:40:09 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:08:24 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:10:01 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:16:55 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
2025-06-01 23:32:06 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)

View File

@ -37,3 +37,4 @@
2025-06-01 19:09:10 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 2025-06-01 19:09:10 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 21:14:20 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 2025-06-01 21:14:20 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 21:14:43 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00 2025-06-01 21:14:43 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
2025-06-01 23:32:26 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 16 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00

View File

@ -349,3 +349,19 @@
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet 2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback) 2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading) 2025-06-01 22:40:10 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:08:25 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:10:02 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:16:56 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
2025-06-01 23:32:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)

View File

@ -87,3 +87,7 @@
2025-06-01 22:39:54 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet 2025-06-01 22:39:54 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 22:39:56 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet 2025-06-01 22:39:56 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 22:40:09 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet 2025-06-01 22:40:09 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:08:24 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:10:01 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:16:55 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
2025-06-01 23:32:06 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet

View File

@ -84,3 +84,7 @@
2025-06-01 22:39:54 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) 2025-06-01 22:39:54 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 22:39:57 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) 2025-06-01 22:39:57 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 22:40:10 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand) 2025-06-01 22:40:10 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:08:25 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:10:02 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:16:56 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
2025-06-01 23:32:07 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)

View File

@ -124,3 +124,6 @@ WHERE printers.id = ?]
2025-06-01 19:04:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1) 2025-06-01 19:04:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 21:14:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1) 2025-06-01 21:14:21 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 21:14:25 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1) 2025-06-01 21:14:25 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:10:14 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:17:20 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)
2025-06-01 23:32:17 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 16 von 16 (Seite 1)

View File

@ -172,3 +172,11 @@
2025-06-01 22:39:57 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet 2025-06-01 22:39:57 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet 2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet 2025-06-01 22:40:10 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:08:25 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:08:25 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:10:02 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:10:02 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:16:56 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:16:56 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:32:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
2025-06-01 23:32:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet

View File

@ -172,3 +172,11 @@
2025-06-01 22:39:57 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt 2025-06-01 22:39:57 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt 2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt 2025-06-01 22:40:10 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:08:25 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:08:25 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:10:02 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:10:02 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:16:56 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:16:56 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:32:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
2025-06-01 23:32:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt

View File

@ -86,3 +86,7 @@
2025-06-01 22:39:55 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert 2025-06-01 22:39:55 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 22:39:57 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert 2025-06-01 22:39:57 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 22:40:10 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert 2025-06-01 22:40:10 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:08:25 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:10:02 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:16:56 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
2025-06-01 23:32:07 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert

View File

@ -2536,3 +2536,120 @@
2025-06-01 22:40:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100 2025-06-01 22:40:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 22:40:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105 2025-06-01 22:40:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 22:40:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101 2025-06-01 22:40:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:08:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:08:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:08:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:08:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:08:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:08:29 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:08:29 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:08:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:08:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:08:44 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:08:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:08:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:09:02 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.2s
2025-06-01 23:10:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:10:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:10:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:10:05 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:10:07 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:10:07 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:10:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:10:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:11 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:10:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:10:18 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:20 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:24 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:26 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:10:27 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:10:28 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:10:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:10:40 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:16:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:16:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:16:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:16:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:16:58 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:17:00 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:17:00 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:17:03 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:17:09 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:17:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:17:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:17:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:17:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:17:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:30 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:17:32 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:17:33 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:22:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:22:40 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:22:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:22:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:22:49 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
2025-06-01 23:32:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
2025-06-01 23:32:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
2025-06-01 23:32:10 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.103): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:32:12 - [printer_monitor] printer_monitor - [WARNING] WARNING - ❌ Tapo P110 (192.168.0.104): Steckdose konnte nicht ausgeschaltet werden
2025-06-01 23:32:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🎯 Steckdosen-Initialisierung abgeschlossen: 0/2 erfolgreich
2025-06-01 23:32:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:32:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:32:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
2025-06-01 23:32:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:32:16 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:32:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:22 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:32:25 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:32:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
2025-06-01 23:32:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
2025-06-01 23:32:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
2025-06-01 23:32:44 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.1s
2025-06-01 23:37:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:37:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Prüfe Status von 2 aktiven Druckern...
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:34 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.104): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [WARNING] WARNING - 🔌 Tapo P110 (192.168.0.103): UNREACHABLE (Ping fehlgeschlagen)
2025-06-01 23:37:43 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Status-Update abgeschlossen für 2 Drucker

View File

@ -5056,3 +5056,131 @@
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1) 2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker 2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.41ms 2025-06-01 21:14:47 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.41ms
2025-06-01 23:10:11 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:14 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:10:15 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:10:15 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:18 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:10:20 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:20 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9029.96ms
2025-06-01 23:10:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:24 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9041.46ms
2025-06-01 23:10:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9022.98ms
2025-06-01 23:10:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:10:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9032.41ms
2025-06-01 23:17:20 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:17:21 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:17:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:23 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:30 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:30 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9031.02ms
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9018.02ms
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:32 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.24ms
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:17:33 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.33ms
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:18:21 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:18:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.45ms
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:08 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.37ms
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:15 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:19:47 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:04 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.41ms
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:35 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.32ms
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:20:48 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:21:18 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.29ms
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:21:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.49ms
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:22:09 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.44ms
2025-06-01 23:22:40 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:47 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:22:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:22:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9004.42ms
2025-06-01 23:32:13 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:16 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:16 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:17 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:22 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:22 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9030.61ms
2025-06-01 23:32:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9035.13ms
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:31 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.35ms
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:33 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.66ms
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:35 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 2.22ms
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:32:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.29ms
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:33:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.34ms
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:33:40 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.38ms
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.34ms
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.27ms
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:34:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.33ms
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:35:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.48ms
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:35:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.51ms
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:05 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.39ms
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:45 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.25ms
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:36:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.31ms
2025-06-01 23:37:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:37:34 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9033.19ms
2025-06-01 23:37:43 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:37:43 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9021.61ms
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:38:06 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.30ms
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 2 Drucker
2025-06-01 23:38:20 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 0.26ms

File diff suppressed because it is too large Load Diff

View File

@ -86,3 +86,7 @@
2025-06-01 22:39:55 - [security] security - [INFO] INFO - 🔒 Security System initialisiert 2025-06-01 22:39:55 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 22:39:57 - [security] security - [INFO] INFO - 🔒 Security System initialisiert 2025-06-01 22:39:57 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 22:40:10 - [security] security - [INFO] INFO - 🔒 Security System initialisiert 2025-06-01 22:40:10 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:08:25 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:10:02 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:16:56 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
2025-06-01 23:32:07 - [security] security - [INFO] INFO - 🔒 Security System initialisiert

View File

@ -172,3 +172,7 @@
2025-06-01 22:39:55 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet... 2025-06-01 22:39:55 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🏁 System wird beendet...
2025-06-01 22:39:57 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert 2025-06-01 22:39:57 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 22:40:10 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert 2025-06-01 22:40:10 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:08:25 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:10:02 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:16:56 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
2025-06-01 23:32:07 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert

View File

@ -782,3 +782,39 @@
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert 2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert 2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - ================================================== 2025-06-01 22:40:10 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:08:25.318047
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:08:25 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:10:02.765896
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:10:02 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:16:56.191249
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:16:56 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ==================================================
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T23:32:07.643798
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
2025-06-01 23:32:07 - [startup] startup - [INFO] INFO - ==================================================

View File

@ -375,3 +375,19 @@
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen) 2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet 2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet 2025-06-01 22:40:09 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:08:24 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:10:01 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:16:55 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
2025-06-01 23:32:05 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet

View File

@ -0,0 +1,148 @@
MYP Platform - Performance Optimization Report
==============================================
CSS-Dateien (39):
- all.css: 106,394 Bytes
- all.min.css: 73,890 Bytes
- app-bundle.min.css: 8,714 Bytes
- brands.css: 19,852 Bytes
- brands.min.css: 14,574 Bytes
- caching-optimizations.css: 5,613 Bytes
- caching-optimizations.min.css: 3,565 Bytes
- components.css: 17,232 Bytes
- components.min.css: 13,062 Bytes
- critical-inline.css: 1,473 Bytes
- critical-inline.min.css: 1,399 Bytes
- fontawesome.css: 83,677 Bytes
- fontawesome.min.css: 56,777 Bytes
- glassmorphism.css: 6,211 Bytes
- glassmorphism.min.css: 4,715 Bytes
- input.css: 99,414 Bytes
- input.min.css: 76,568 Bytes
- main.min.css: 115 Bytes
- optimization-animations.css: 2,675 Bytes
- optimization-animations.min.css: 1,443 Bytes
- output.css: 248,934 Bytes
- output.min.css: 210,598 Bytes
- printers.css: 3,952 Bytes
- printers.min.css: 2,502 Bytes
- professional-theme.css: 24,631 Bytes
- professional-theme.min.css: 18,762 Bytes
- regular.css: 633 Bytes
- regular.min.css: 580 Bytes
- solid.css: 625 Bytes
- solid.min.css: 572 Bytes
- svg-with-js.css: 12,554 Bytes
- svg-with-js.min.css: 10,197 Bytes
- tailwind.min.css: 221,943 Bytes
- v4-font-face.css: 1,831 Bytes
- v4-font-face.min.css: 1,736 Bytes
- v4-shims.css: 38,514 Bytes
- v4-shims.min.css: 21,211 Bytes
- v5-font-face.css: 871 Bytes
- v5-font-face.min.css: 794 Bytes
JavaScript-Dateien (84):
- admin-guest-requests.js: 32,046 Bytes
- admin-guest-requests.min.js: 23,162 Bytes
- admin-panel.js: 42,961 Bytes
- admin-panel.min.js: 27,749 Bytes
- admin-unified.js: 56,717 Bytes
- admin-unified.min.js: 35,087 Bytes
- advanced-components.js: 29,859 Bytes
- advanced-components.min.js: 16,393 Bytes
- all.js: 1,627,440 Bytes
- all.min.js: 1,530,755 Bytes
- apexcharts.min.js: 524,387 Bytes
- auto-logout.js: 4,661 Bytes
- auto-logout.min.js: 3,099 Bytes
- brands.js: 510,493 Bytes
- brands.min.js: 499,125 Bytes
- chart-adapter.js: 8,486 Bytes
- chart-config.js: 9,767 Bytes
- chart-renderer.js: 10,396 Bytes
- chart.min.js: 181,743 Bytes
- charts.js: 13,704 Bytes
- charts.min.js: 7,671 Bytes
- conflict-detection.js: 38,929 Bytes
- conflict-detection.min.js: 15,853 Bytes
- core.min.js: 181,411 Bytes
- countdown-timer.js: 35,228 Bytes
- countdown-timer.min.js: 19,014 Bytes
- csp-violation-handler.js: 10,509 Bytes
- csp-violation-handler.min.js: 6,622 Bytes
- css-cache-manager.js: 3,454 Bytes
- css-cache-manager.min.js: 2,471 Bytes
- css-cache-service-worker.js: 10,648 Bytes
- css-cache-service-worker.min.js: 6,895 Bytes
- dark-mode-fix.js: 7,630 Bytes
- dark-mode-fix.min.js: 4,183 Bytes
- dark-mode.js: 11,717 Bytes
- dark-mode.min.js: 7,659 Bytes
- dashboard.js: 11,344 Bytes
- dashboard.min.js: 8,164 Bytes
- daygrid.min.js: 26,955 Bytes
- debug-fix.js: 7,419 Bytes
- debug-fix.min.js: 4,146 Bytes
- event-handlers.js: 16,020 Bytes
- event-handlers.min.js: 8,399 Bytes
- fontawesome.js: 106,548 Bytes
- fontawesome.min.js: 49,856 Bytes
- glassmorphism-notifications.js: 62,643 Bytes
- glassmorphism-notifications.min.js: 35,476 Bytes
- global-refresh-functions.js: 26,547 Bytes
- global-refresh-functions.min.js: 14,785 Bytes
- interaction.min.js: 35,636 Bytes
- job-manager.js: 31,172 Bytes
- job-manager.min.js: 16,598 Bytes
- jobs-safety-fix.js: 10,729 Bytes
- jobs-safety-fix.min.js: 5,270 Bytes
- list.min.js: 9,361 Bytes
- notifications.js: 26,568 Bytes
- notifications.min.js: 16,192 Bytes
- offline-app.js: 20,435 Bytes
- offline-app.min.js: 10,758 Bytes
- optimization-features.js: 33,307 Bytes
- optimization-features.min.js: 19,873 Bytes
- performance-service-worker.js: 10,657 Bytes
- performance-service-worker.min.js: 7,730 Bytes
- printer_monitor.js: 15,887 Bytes
- printer_monitor.min.js: 7,574 Bytes
- regular.js: 126,991 Bytes
- regular.min.js: 119,408 Bytes
- service-worker.js: 2,205 Bytes
- service-worker.min.js: 1,361 Bytes
- session-manager.js: 19,582 Bytes
- session-manager.min.js: 10,369 Bytes
- solid.js: 884,065 Bytes
- solid.min.js: 863,023 Bytes
- sw.js: 12,735 Bytes
- sw.min.js: 7,745 Bytes
- timegrid.min.js: 31,540 Bytes
- ui-components.js: 711 Bytes
- ui-components.min.js: 305 Bytes
- user-dropdown.js: 1 Bytes
- user-dropdown.min.js: 0 Bytes
- v4-shims.js: 35,459 Bytes
- v4-shims.min.js: 28,077 Bytes
- validation-fix.js: 9,064 Bytes
- validation-fix.min.js: 5,182 Bytes
Bilder (0):
Optimierungen durchgeführt:
✅ CSS-Minifizierung
✅ JavaScript-Minifizierung
✅ Gzip-Komprimierung
✅ WebP-Bildkonvertierung
✅ Critical CSS
✅ Service Worker
✅ PWA-Manifest
Empfohlene nächste Schritte:
1. Performance-optimiertes Template verwenden
2. Service Worker aktivieren
3. HTTP/2 Push für kritische Assets
4. CDN für statische Assets konfigurieren

Binary file not shown.

View File

@ -0,0 +1,31 @@
/* CRITICAL INLINE CSS - Sollte im HTML <head> stehen */
/* Nur die absolut notwendigen Styles für First Paint */
:root{--primary:#0073ce;--bg:#fafbfc;--surface:#fff;--text:#111827;--border:#e5e7eb;--shadow:0 2px 4px rgba(0,0,0,.05)}
*{box-sizing:border-box;margin:0;padding:0;contain:layout style}
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;text-rendering:optimizeSpeed;-webkit-font-smoothing:antialiased}
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:1rem;position:sticky;top:0;z-index:1000}
.nav{display:flex;gap:1rem}
.nav-item{padding:.5rem 1rem;border-radius:6px;text-decoration:none;color:#6b7280;transition:background .1s}
.nav-item:hover{background:var(--bg);color:var(--text)}
.nav-item.active{background:var(--primary);color:#fff}
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
.btn{background:var(--primary);color:#fff;border:none;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;transition:background .1s}
.btn:hover{background:#005a9f}
.card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1rem;box-shadow:var(--shadow)}
.flex{display:flex}
.grid{display:grid;gap:1rem}
.hidden{display:none}
.w-full{width:100%}
.text-center{text-align:center}
.p-4{padding:1rem}
.mb-4{margin-bottom:1rem}
.status{display:inline-block;padding:.25rem .75rem;border-radius:999px;font-size:.75rem;font-weight:600;text-transform:uppercase}
.status-online{background:#d1fae5;color:#065f46}
.status-offline{background:#fee2e2;color:#991b1b}
.status-printing{background:#dbeafe;color:#1e40af}
.input{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem;width:100%}
.input:focus{outline:none;border-color:var(--primary)}
@media (prefers-color-scheme:dark){:root{--bg:#1e293b;--surface:#334155;--text:#f8fafc;--border:#475569;--shadow:0 2px 4px rgba(0,0,0,.3)}}
@media (max-width:768px){.nav{flex-direction:column;gap:.5rem}}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

View File

@ -0,0 +1,498 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,497 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,498 @@
/* MYP Platform - Kiosk Optimierte CSS Bundle */
/* Generiert am: 2025-06-01 23:40:46 */
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

View File

@ -0,0 +1,288 @@
/**
* MYP Platform - CSS Caching-Optimierungen
* Performance-optimierte Styles für besseres Caching und schnellere Ladezeiten
*/
/* ===== KRITISCHE ABOVE-THE-FOLD STYLES ===== */
/* Diese Styles sollten inline im HTML-Head geladen werden */
.critical-header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(8px);
position: sticky;
top: 0;
z-index: 1000;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
.critical-nav {
display: flex;
align-items: center;
padding: 1rem;
max-width: 1200px;
margin: 0 auto;
}
.critical-logo {
font-weight: 700;
font-size: 1.25rem;
color: #0073ce;
}
.critical-main {
min-height: 100vh;
background: linear-gradient(135deg, #fafbfc 0%, #f5f7f9 100%);
}
/* ===== LAZY LOADING PLACEHOLDER ===== */
.lazy-placeholder {
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite ease-in-out;
border-radius: 4px;
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
.dark .lazy-placeholder {
background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
background-size: 200% 100%;
}
/* ===== PRELOAD HINTS ===== */
.preload-image {
content-visibility: auto;
contain-intrinsic-size: 300px 200px;
}
.preload-component {
content-visibility: auto;
contain-intrinsic-size: 100px;
}
/* ===== CACHE-OPTIMIERTE KOMPONENTEN ===== */
.cache-card {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(229, 231, 235, 0.5);
border-radius: 8px;
padding: 1rem;
margin-bottom: 1rem;
transition: transform 0.2s ease;
contain: layout style paint;
}
.cache-card:hover {
transform: translateY(-1px);
}
.cache-button {
background: #0073ce;
color: white;
border: none;
border-radius: 6px;
padding: 0.5rem 1rem;
font-weight: 600;
transition: background-color 0.2s ease;
contain: layout style;
}
.cache-button:hover {
background: #005a9f;
}
.cache-input {
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(229, 231, 235, 0.8);
border-radius: 4px;
padding: 0.5rem;
transition: border-color 0.2s ease;
contain: layout style;
}
.cache-input:focus {
outline: none;
border-color: #0073ce;
box-shadow: 0 0 0 2px rgba(0, 115, 206, 0.1);
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
.prevent-cls {
min-height: 200px; /* Prevent layout shift */
contain: layout;
}
.image-container {
aspect-ratio: 16/9;
overflow: hidden;
border-radius: 8px;
background: #f3f4f6;
}
.image-container img {
width: 100%;
height: 100%;
object-fit: cover;
transition: opacity 0.3s ease;
}
.image-container img[loading="lazy"] {
opacity: 0;
}
.image-container img[loading="lazy"].loaded {
opacity: 1;
}
/* ===== OPTIMIERTE TYPOGRAPHY ===== */
.text-heading {
font-weight: 700;
line-height: 1.2;
color: #111827;
contain: layout style;
}
.text-body {
line-height: 1.6;
color: #374151;
contain: layout style;
}
.text-muted {
color: #6b7280;
contain: layout style;
}
/* ===== DARK MODE CACHE OPTIMIZATIONS ===== */
.dark .cache-card {
background: rgba(30, 41, 59, 0.9);
border-color: rgba(100, 116, 139, 0.3);
}
.dark .cache-input {
background: rgba(30, 41, 59, 0.9);
border-color: rgba(100, 116, 139, 0.5);
color: #e2e8f0;
}
.dark .text-heading {
color: #f8fafc;
}
.dark .text-body {
color: #e2e8f0;
}
.dark .text-muted {
color: #94a3b8;
}
.dark .image-container {
background: #374151;
}
/* ===== RESPONSIVE OPTIMIZATIONS ===== */
@media (max-width: 768px) {
.critical-nav {
padding: 0.75rem;
}
.cache-card {
padding: 0.75rem;
margin-bottom: 0.75rem;
}
.cache-button {
padding: 0.75rem 1.25rem;
font-size: 0.875rem;
}
}
/* ===== PRINT OPTIMIZATIONS ===== */
@media print {
.critical-header,
.cache-button {
display: none;
}
.cache-card {
box-shadow: none;
border: 1px solid #000;
break-inside: avoid;
}
}
/* ===== GPU ACCELERATION HINTS ===== */
.gpu-accelerated {
transform: translateZ(0);
will-change: transform;
}
/* ===== EFFICIENT ANIMATIONS ===== */
.fade-in-optimized {
opacity: 0;
transform: translateY(10px);
transition: opacity 0.3s ease, transform 0.3s ease;
}
.fade-in-optimized.visible {
opacity: 1;
transform: translateY(0);
}
/* ===== CONTAINER QUERIES SUPPORT ===== */
@container (min-width: 300px) {
.cache-card {
display: grid;
grid-template-columns: 1fr auto;
gap: 1rem;
align-items: center;
}
}
/* ===== CONTENT VISIBILITY OPTIMIZATIONS ===== */
.auto-height {
content-visibility: auto;
contain-intrinsic-size: 0 200px;
}
.hidden-content {
content-visibility: hidden;
}
/* ===== REDUCED MOTION PREFERENCES ===== */
@media (prefers-reduced-motion: reduce) {
.fade-in-optimized,
.cache-card,
.cache-button,
.cache-input {
transition: none !important;
}
.lazy-placeholder {
animation: none !important;
background: #f0f0f0 !important;
}
}
/* ===== HIGH CONTRAST MODE ===== */
@media (prefers-contrast: high) {
.cache-card {
border-width: 2px;
border-color: #000;
}
.cache-button {
border: 2px solid #000;
}
.cache-input {
border-width: 2px;
border-color: #000;
}
}

Binary file not shown.

View File

@ -0,0 +1 @@
.critical-header{background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);position:sticky;top:0;z-index:1000;box-shadow:0 2px 8px rgba(0,0,0,0.06)}.critical-nav{display:flex;align-items:center;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce}.critical-main{min-height:100vh;background:linear-gradient(135deg,#fafbfc 0,#f5f7f9 100%)}.lazy-placeholder{background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite ease-in-out;border-radius:4px}@keyframes skeleton-loading{0%{background-position:200% 0}100%{background-position:-200% 0}}.dark .lazy-placeholder{background:linear-gradient(90deg,#374151 25%,#4b5563 50%,#374151 75%);background-size:200% 100%}.preload-image{content-visibility:auto;contain-intrinsic-size:300px 200px}.preload-component{content-visibility:auto;contain-intrinsic-size:100px}.cache-card{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.5);border-radius:8px;padding:1rem;margin-bottom:1rem;transition:transform .2s ease;contain:layout style paint}.cache-card:hover{transform:translateY(-1px)}.cache-button{background:#0073ce;color:white;border:0;border-radius:6px;padding:.5rem 1rem;font-weight:600;transition:background-color .2s ease;contain:layout style}.cache-button:hover{background:#005a9f}.cache-input{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.8);border-radius:4px;padding:.5rem;transition:border-color .2s ease;contain:layout style}.cache-input:focus{outline:0;border-color:#0073ce;box-shadow:0 0 0 2px rgba(0,115,206,0.1)}.prevent-cls{min-height:200px;contain:layout}.image-container{aspect-ratio:16/9;overflow:hidden;border-radius:8px;background:#f3f4f6}.image-container img{width:100%;height:100%;object-fit:cover;transition:opacity .3s ease}.image-container img[loading="lazy"]{opacity:0}.image-container img[loading="lazy"].loaded{opacity:1}.text-heading{font-weight:700;line-height:1.2;color:#111827;contain:layout style}.text-body{line-height:1.6;color:#374151;contain:layout style}.text-muted{color:#6b7280;contain:layout style}.dark .cache-card{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.3)}.dark .cache-input{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.5);color:#e2e8f0}.dark .text-heading{color:#f8fafc}.dark .text-body{color:#e2e8f0}.dark .text-muted{color:#94a3b8}.dark .image-container{background:#374151}@media(max-width:768px){.critical-nav{padding:.75rem}.cache-card{padding:.75rem;margin-bottom:.75rem}.cache-button{padding:.75rem 1.25rem;font-size:.875rem}}@media print{.critical-header,.cache-button{display:none}.cache-card{box-shadow:none;border:1px solid #000;break-inside:avoid}}.gpu-accelerated{transform:translateZ(0);will-change:transform}.fade-in-optimized{opacity:0;transform:translateY(10px);transition:opacity .3s ease,transform .3s ease}.fade-in-optimized.visible{opacity:1;transform:translateY(0)}@container(min-width:300px){.cache-card{display:grid;grid-template-columns:1fr auto;gap:1rem;align-items:center}}.auto-height{content-visibility:auto;contain-intrinsic-size:0 200px}.hidden-content{content-visibility:hidden}@media(prefers-reduced-motion:reduce){.fade-in-optimized,.cache-card,.cache-button,.cache-input{transition:none !important}.lazy-placeholder{animation:none !important;background:#f0f0f0 !important}}@media(prefers-contrast:high){.cache-card{border-width:2px;border-color:#000}.cache-button{border:2px solid #000}.cache-input{border-width:2px;border-color:#000}}

Binary file not shown.

Binary file not shown.

1
backend/static/css/components.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,31 @@
/* CRITICAL INLINE CSS - Sollte im HTML <head> stehen */
/* Nur die absolut notwendigen Styles für First Paint */
:root{--primary:#0073ce;--bg:#fafbfc;--surface:#fff;--text:#111827;--border:#e5e7eb;--shadow:0 2px 4px rgba(0,0,0,.05)}
*{box-sizing:border-box;margin:0;padding:0;contain:layout style}
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;text-rendering:optimizeSpeed;-webkit-font-smoothing:antialiased}
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:1rem;position:sticky;top:0;z-index:1000}
.nav{display:flex;gap:1rem}
.nav-item{padding:.5rem 1rem;border-radius:6px;text-decoration:none;color:#6b7280;transition:background .1s}
.nav-item:hover{background:var(--bg);color:var(--text)}
.nav-item.active{background:var(--primary);color:#fff}
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
.btn{background:var(--primary);color:#fff;border:none;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;transition:background .1s}
.btn:hover{background:#005a9f}
.card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1rem;box-shadow:var(--shadow)}
.flex{display:flex}
.grid{display:grid;gap:1rem}
.hidden{display:none}
.w-full{width:100%}
.text-center{text-align:center}
.p-4{padding:1rem}
.mb-4{margin-bottom:1rem}
.status{display:inline-block;padding:.25rem .75rem;border-radius:999px;font-size:.75rem;font-weight:600;text-transform:uppercase}
.status-online{background:#d1fae5;color:#065f46}
.status-offline{background:#fee2e2;color:#991b1b}
.status-printing{background:#dbeafe;color:#1e40af}
.input{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem;width:100%}
.input:focus{outline:none;border-color:var(--primary)}
@media (prefers-color-scheme:dark){:root{--bg:#1e293b;--surface:#334155;--text:#f8fafc;--border:#475569;--shadow:0 2px 4px rgba(0,0,0,.3)}}
@media (max-width:768px){.nav{flex-direction:column;gap:.5rem}}
@media (prefers-reduced-motion:reduce){*{transition:none!important}}

Binary file not shown.

View File

@ -0,0 +1 @@
*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;line-height:1.6;color:#111827;background:#fafbfc}.critical-header{position:sticky;top:0;z-index:1000;background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);border-bottom:1px solid #e5e7eb}.critical-nav{display:flex;align-items:center;justify-content:space-between;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce;text-decoration:none}.critical-main{min-height:100vh;padding:2rem 1rem}.critical-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.5rem;max-width:1200px;margin:0 auto}.critical-card{background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,0.1)}.btn-primary{background:#0073ce;color:#fff;border:0;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;text-decoration:none;display:inline-block}.loading{opacity:.6;pointer-events:none}.hidden{display:none}@media(max-width:768px){.critical-nav{padding:.75rem}.critical-main{padding:1rem}.critical-grid{grid-template-columns:1fr}.critical-card{padding:1rem}}@media(prefers-color-scheme:dark){body{background:#0f172a;color:#f8fafc}.critical-header{background:rgba(15,23,42,0.95);border-bottom-color:#334155}.critical-card{background:#1e293b;border-color:#334155;color:#f8fafc}}

Binary file not shown.

View File

@ -1,485 +1,255 @@
/* Enhanced Glassmorphism Effects for MYP Application */ /* Vereinfachte Glassmorphism-Effekte für MYP Application */
/* Base Glass Effects */ /* ===== BASIS GLASS EFFEKTE ===== */
.glass-base { .glass-base {
backdrop-filter: blur(24px) saturate(200%) brightness(115%); background: rgba(255, 255, 255, 0.85);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%); backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.25); -webkit-backdrop-filter: blur(10px);
box-shadow: border: 1px solid rgba(255, 255, 255, 0.3);
0 25px 50px rgba(0, 0, 0, 0.12), box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
0 8px 16px rgba(0, 0, 0, 0.08), transition: all 0.2s ease;
inset 0 1px 0 rgba(255, 255, 255, 0.3);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
} }
.glass-strong { .glass-strong {
backdrop-filter: blur(28px) saturate(220%) brightness(125%); background: rgba(255, 255, 255, 0.9);
-webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%); backdrop-filter: blur(12px);
box-shadow: -webkit-backdrop-filter: blur(12px);
0 35px 70px rgba(0, 0, 0, 0.15), border: 1px solid rgba(255, 255, 255, 0.4);
0 12px 24px rgba(0, 0, 0, 0.1), box-shadow: 0 12px 24px rgba(0, 0, 0, 0.12);
inset 0 1px 0 rgba(255, 255, 255, 0.4);
} }
.glass-subtle { .glass-subtle {
backdrop-filter: blur(20px) saturate(180%) brightness(110%); background: rgba(255, 255, 255, 0.8);
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); backdrop-filter: blur(8px);
box-shadow: -webkit-backdrop-filter: blur(8px);
0 15px 35px rgba(0, 0, 0, 0.08), border: 1px solid rgba(255, 255, 255, 0.2);
0 4px 8px rgba(0, 0, 0, 0.05), box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
inset 0 1px 0 rgba(255, 255, 255, 0.2);
} }
/* Light Mode Glass */ /* ===== DARK MODE GLASS ===== */
.glass-light { .dark .glass-base {
background: rgba(255, 255, 255, 0.85);
border: 1px solid rgba(255, 255, 255, 0.4);
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.1),
0 8px 16px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.glass-light-strong {
background: rgba(255, 255, 255, 0.75);
border: 1px solid rgba(255, 255, 255, 0.5);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.12),
0 10px 20px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
/* Light Mode Glass Premium */
.glass-light-premium {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.8) 50%,
rgba(255, 255, 255, 0.85) 100%);
border: 1px solid rgba(226, 232, 240, 0.6);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.08),
0 10px 20px rgba(0, 115, 206, 0.06),
inset 0 2px 0 rgba(255, 255, 255, 0.8),
inset 0 0 20px rgba(255, 255, 255, 0.3);
}
.glass-light-card {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.95) 0%,
rgba(250, 251, 252, 0.9) 100%);
border: 1px solid rgba(226, 232, 240, 0.4);
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.06),
0 8px 16px rgba(0, 115, 206, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
/* Dark Mode Glass */
.glass-dark {
background: rgba(15, 23, 42, 0.8); background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
0 25px 50px rgba(0, 0, 0, 0.4),
0 8px 16px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.05);
} }
.glass-dark-strong { .dark .glass-strong {
background: rgba(30, 41, 59, 0.85); background: rgba(30, 41, 59, 0.85);
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.15);
box-shadow: box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4);
0 35px 70px rgba(0, 0, 0, 0.5),
0 12px 24px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.08);
} }
/* Interactive Glass Elements */ .dark .glass-subtle {
.glass-interactive { background: rgba(15, 23, 42, 0.7);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); border: 1px solid rgba(255, 255, 255, 0.08);
cursor: pointer; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
position: relative;
overflow: hidden;
} }
.glass-interactive::before { /* ===== GLASS KARTEN ===== */
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.2),
transparent);
transition: left 0.6s ease;
z-index: 1;
}
.glass-interactive:hover {
transform: translateY(-3px) scale(1.01);
backdrop-filter: blur(32px) saturate(240%) brightness(130%);
-webkit-backdrop-filter: blur(32px) saturate(240%) brightness(130%);
box-shadow:
0 40px 80px rgba(0, 0, 0, 0.15),
0 16px 32px rgba(0, 115, 206, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.4);
}
.glass-interactive:hover::before {
left: 100%;
}
.glass-interactive:active {
transform: translateY(-1px) scale(0.99);
transition: transform 0.1s ease;
}
/* Glass Navigation */
.glass-nav {
background: linear-gradient(135deg,
rgba(255, 255, 255, 0.9) 0%,
rgba(248, 250, 252, 0.85) 50%,
rgba(255, 255, 255, 0.9) 100%);
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
border: 1px solid rgba(226, 232, 240, 0.5);
border-bottom: 1px solid rgba(203, 213, 225, 0.6);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.08),
0 4px 12px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
}
.dark .glass-nav {
background: rgba(15, 23, 42, 0.85);
border-color: rgba(51, 65, 85, 0.6);
border-bottom-color: rgba(71, 85, 105, 0.7);
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
/* Glass Cards */
.glass-card { .glass-card {
background: linear-gradient(135deg, background: rgba(255, 255, 255, 0.9);
rgba(255, 255, 255, 0.95) 0%, backdrop-filter: blur(10px);
rgba(250, 251, 252, 0.9) 100%); -webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(20px) saturate(180%) brightness(110%); border: 1px solid rgba(229, 231, 235, 0.5);
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%); border-radius: 12px;
border: 1px solid rgba(229, 231, 235, 0.6); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
border-radius: 16px;
box-shadow:
0 20px 40px rgba(0, 0, 0, 0.08),
0 8px 16px rgba(0, 115, 206, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
padding: 1.5rem; padding: 1.5rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: transform 0.2s ease, box-shadow 0.2s ease;
position: relative;
overflow: hidden;
}
.glass-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg,
transparent 0%,
rgba(226, 232, 240, 0.8) 50%,
transparent 100%);
} }
.glass-card:hover { .glass-card:hover {
transform: translateY(-2px); transform: translateY(-1px);
box-shadow: box-shadow: 0 12px 20px rgba(0, 0, 0, 0.12);
0 25px 50px rgba(0, 0, 0, 0.12),
0 12px 24px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.95);
} }
.dark .glass-card { .dark .glass-card {
background: rgba(30, 41, 59, 0.85); background: rgba(30, 41, 59, 0.85);
border-color: rgba(100, 116, 139, 0.4); border: 1px solid rgba(100, 116, 139, 0.3);
box-shadow: box-shadow: 0 8px 16px rgba(0, 0, 0, 0.25);
0 20px 40px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
} }
.dark .glass-card:hover { .dark .glass-card:hover {
box-shadow: box-shadow: 0 12px 20px rgba(0, 0, 0, 0.35);
0 25px 50px rgba(0, 0, 0, 0.4),
inset 0 1px 0 rgba(255, 255, 255, 0.15);
} }
/* Glass Buttons */ /* ===== GLASS NAVIGATION ===== */
.glass-nav {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(226, 232, 240, 0.4);
border-bottom: 1px solid rgba(203, 213, 225, 0.5);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}
.dark .glass-nav {
background: rgba(15, 23, 42, 0.85);
border: 1px solid rgba(51, 65, 85, 0.5);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* ===== GLASS BUTTONS ===== */
.glass-btn { .glass-btn {
background: linear-gradient(135deg, background: rgba(255, 255, 255, 0.8);
rgba(255, 255, 255, 0.9) 0%, backdrop-filter: blur(8px);
rgba(248, 250, 252, 0.8) 100%); -webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(16px) saturate(180%); border: 1px solid rgba(226, 232, 240, 0.5);
-webkit-backdrop-filter: blur(16px) saturate(180%); border-radius: 8px;
border: 1px solid rgba(226, 232, 240, 0.6);
border-radius: 12px;
padding: 0.75rem 1.5rem; padding: 0.75rem 1.5rem;
color: #0f172a; color: #0f172a;
font-weight: 600; font-weight: 600;
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
box-shadow: transition: transform 0.2s ease, background 0.2s ease;
0 4px 12px rgba(0, 0, 0, 0.08),
0 2px 4px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.2s ease;
} }
.glass-btn:hover { .glass-btn:hover {
transform: translateY(-1px); transform: translateY(-1px);
background: linear-gradient(135deg, background: rgba(255, 255, 255, 0.9);
rgba(255, 255, 255, 0.95) 0%, box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
rgba(248, 250, 252, 0.85) 100%);
box-shadow:
0 8px 20px rgba(0, 0, 0, 0.12),
0 4px 8px rgba(0, 115, 206, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.glass-btn:active {
transform: translateY(0);
box-shadow:
0 2px 8px rgba(0, 0, 0, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.7);
} }
.glass-btn-primary { .glass-btn-primary {
background: linear-gradient(135deg, background: rgba(0, 115, 206, 0.9);
rgba(0, 115, 206, 0.9) 0%,
rgba(0, 90, 159, 0.85) 100%);
color: white; color: white;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
box-shadow:
0 4px 12px rgba(0, 115, 206, 0.3),
0 2px 4px rgba(0, 115, 206, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.2);
} }
.glass-btn-primary:hover { .glass-btn-primary:hover {
background: linear-gradient(135deg, background: rgba(0, 115, 206, 0.95);
rgba(0, 115, 206, 0.95) 0%, box-shadow: 0 4px 12px rgba(0, 115, 206, 0.3);
rgba(0, 90, 159, 0.9) 100%);
box-shadow:
0 8px 20px rgba(0, 115, 206, 0.4),
0 4px 8px rgba(0, 115, 206, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
} }
.dark .glass-btn { .dark .glass-btn {
background: rgba(30, 41, 59, 0.8); background: rgba(30, 41, 59, 0.8);
color: #e2e8f0; color: #e2e8f0;
border-color: rgba(100, 116, 139, 0.6); border: 1px solid rgba(100, 116, 139, 0.5);
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
box-shadow:
0 4px 12px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
} }
/* Glass Modals */ .dark .glass-btn:hover {
background: rgba(30, 41, 59, 0.9);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}
/* ===== GLASS MODALS ===== */
.glass-modal { .glass-modal {
background: linear-gradient(135deg, background: rgba(255, 255, 255, 0.95);
rgba(255, 255, 255, 0.98) 0%, backdrop-filter: blur(16px);
rgba(248, 250, 252, 0.95) 50%, -webkit-backdrop-filter: blur(16px);
rgba(255, 255, 255, 0.98) 100%); border: 1px solid rgba(226, 232, 240, 0.6);
backdrop-filter: blur(32px) saturate(220%) brightness(120%); border-radius: 16px;
-webkit-backdrop-filter: blur(32px) saturate(220%) brightness(120%); box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
border: 1px solid rgba(226, 232, 240, 0.7);
border-radius: 20px;
box-shadow:
0 50px 100px rgba(0, 0, 0, 0.15),
0 20px 40px rgba(0, 115, 206, 0.08),
inset 0 2px 0 rgba(255, 255, 255, 0.9),
inset 0 0 40px rgba(255, 255, 255, 0.2);
} }
.dark .glass-modal { .dark .glass-modal {
background: rgba(15, 23, 42, 0.95); background: rgba(15, 23, 42, 0.95);
border-color: rgba(51, 65, 85, 0.7); border: 1px solid rgba(51, 65, 85, 0.6);
box-shadow: box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
0 50px 100px rgba(0, 0, 0, 0.5),
inset 0 2px 0 rgba(255, 255, 255, 0.1);
} }
/* Glass Form Elements */ /* ===== GLASS FORM ELEMENTE ===== */
.glass-input { .glass-input {
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(16px); backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(8px);
border: 1px solid rgba(226, 232, 240, 0.6); border: 1px solid rgba(226, 232, 240, 0.5);
border-radius: 8px; border-radius: 6px;
padding: 0.75rem 1rem; padding: 0.75rem 1rem;
color: #0f172a; color: #0f172a;
box-shadow: box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
0 2px 8px rgba(0, 0, 0, 0.06), transition: border-color 0.2s ease, box-shadow 0.2s ease;
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.2s ease;
} }
.glass-input:focus { .glass-input:focus {
outline: none; outline: none;
border-color: rgba(0, 115, 206, 0.6); border-color: rgba(0, 115, 206, 0.5);
box-shadow: box-shadow: 0 2px 8px rgba(0, 115, 206, 0.1);
0 4px 12px rgba(0, 115, 206, 0.15),
0 0 0 3px rgba(0, 115, 206, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
} }
.dark .glass-input { .dark .glass-input {
background: rgba(30, 41, 59, 0.8); background: rgba(30, 41, 59, 0.8);
border-color: rgba(100, 116, 139, 0.6); border: 1px solid rgba(100, 116, 139, 0.5);
color: #e2e8f0; color: #e2e8f0;
box-shadow: box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
0 2px 8px rgba(0, 0, 0, 0.2),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
} }
/* Glass Dropdown */ .dark .glass-input:focus {
border-color: rgba(59, 130, 246, 0.5);
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.15);
}
/* ===== GLASS DROPDOWN ===== */
.glass-dropdown { .glass-dropdown {
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(24px) saturate(200%) brightness(120%); backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%); -webkit-backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.3); border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 12px; border-radius: 8px;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.1); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
} }
.dark .glass-dropdown { .dark .glass-dropdown {
background: rgba(0, 0, 0, 0.8); background: rgba(15, 23, 42, 0.9);
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
} }
/* Animation for glass elements */ /* ===== UTILITY CLASSES ===== */
@keyframes glassFloat {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-2px);
}
}
.glass-float {
animation: glassFloat 3s ease-in-out infinite;
}
/* Glass overlay for backgrounds */
.glass-overlay { .glass-overlay {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%); background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(40px) saturate(200%); backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(40px) saturate(200%); -webkit-backdrop-filter: blur(20px);
} }
.dark .glass-overlay { .dark .glass-overlay {
background: linear-gradient(135deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.1) 100%); background: rgba(0, 0, 0, 0.2);
} }
/* Responsive glass effects */ /* ===== RESPONSIVE ANPASSUNGEN ===== */
@media (max-width: 768px) { @media (max-width: 768px) {
.glass-card { .glass-card {
padding: 1rem; padding: 1rem;
border-radius: 12px; border-radius: 8px;
} }
.glass-modal { .glass-modal {
border-radius: 16px; border-radius: 12px;
}
.glass-base,
.glass-strong,
.glass-subtle {
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
} }
} }
/* High contrast mode adjustments */ /* ===== REDUZIERTE BEWEGUNG ===== */
@media (prefers-reduced-motion: reduce) {
.glass-card,
.glass-btn,
.glass-input {
transition: none !important;
}
}
/* ===== HOHER KONTRAST MODUS ===== */
@media (prefers-contrast: high) { @media (prefers-contrast: high) {
.glass-base, .glass-base,
.glass-strong, .glass-strong,
.glass-card { .glass-card {
border-width: 2px; border-width: 2px;
backdrop-filter: blur(12px); backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(4px);
} }
} }
/* Reduced motion support */ /* ===== PERFORMANCE OPTIMIERUNGEN ===== */
@media (prefers-reduced-motion: reduce) { .glass-base,
.glass-interactive, .glass-strong,
.glass-btn, .glass-subtle,
.glass-card { .glass-card,
transition: none !important; .glass-btn,
} .glass-modal {
will-change: transform;
.glass-interactive::before {
display: none;
}
}
/* Glass Loading States */
.glass-loading {
position: relative;
overflow: hidden;
}
.glass-loading::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent);
animation: glass-shimmer 2s infinite;
}
.dark .glass-loading::after {
background: linear-gradient(90deg,
transparent,
rgba(255, 255, 255, 0.1),
transparent);
}
@keyframes glass-shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
/* Premium Glow Effects for Light Mode */
.glass-glow {
position: relative;
}
.glass-glow::after {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg,
rgba(0, 115, 206, 0.1),
rgba(0, 90, 159, 0.05),
rgba(0, 115, 206, 0.1));
border-radius: inherit;
z-index: -1;
opacity: 0;
transition: opacity 0.3s ease;
}
.glass-glow:hover::after {
opacity: 1;
}
.dark .glass-glow::after {
background: linear-gradient(45deg,
rgba(59, 130, 246, 0.2),
rgba(29, 78, 216, 0.1),
rgba(59, 130, 246, 0.2));
} }

Binary file not shown.

View File

@ -0,0 +1 @@
.glass-base{background:rgba(255,255,255,0.85);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.3);box-shadow:0 8px 20px rgba(0,0,0,0.1);transition:all .2s ease}.glass-strong{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.4);box-shadow:0 12px 24px rgba(0,0,0,0.12)}.glass-subtle{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.2);box-shadow:0 4px 12px rgba(0,0,0,0.08)}.dark .glass-base{background:rgba(15,23,42,0.8);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.dark .glass-strong{background:rgba(30,41,59,0.85);border:1px solid rgba(255,255,255,0.15);box-shadow:0 12px 24px rgba(0,0,0,0.4)}.dark .glass-subtle{background:rgba(15,23,42,0.7);border:1px solid rgba(255,255,255,0.08);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-card{background:rgba(255,255,255,0.9);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(229,231,235,0.5);border-radius:12px;box-shadow:0 8px 16px rgba(0,0,0,0.08);padding:1.5rem;transition:transform .2s ease,box-shadow .2s ease}.glass-card:hover{transform:translateY(-1px);box-shadow:0 12px 20px rgba(0,0,0,0.12)}.dark .glass-card{background:rgba(30,41,59,0.85);border:1px solid rgba(100,116,139,0.3);box-shadow:0 8px 16px rgba(0,0,0,0.25)}.dark .glass-card:hover{box-shadow:0 12px 20px rgba(0,0,0,0.35)}.glass-nav{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(226,232,240,0.4);border-bottom:1px solid rgba(203,213,225,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.06)}.dark .glass-nav{background:rgba(15,23,42,0.85);border:1px solid rgba(51,65,85,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-btn{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:8px;padding:.75rem 1.5rem;color:#0f172a;font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,0.06);transition:transform .2s ease,background .2s ease}.glass-btn:hover{transform:translateY(-1px);background:rgba(255,255,255,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.1)}.glass-btn-primary{background:rgba(0,115,206,0.9);color:white;box-shadow:0 2px 8px rgba(0,115,206,0.2)}.glass-btn-primary:hover{background:rgba(0,115,206,0.95);box-shadow:0 4px 12px rgba(0,115,206,0.3)}.dark .glass-btn{background:rgba(30,41,59,0.8);color:#e2e8f0;border:1px solid rgba(100,116,139,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.15)}.dark .glass-btn:hover{background:rgba(30,41,59,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.25)}.glass-modal{background:rgba(255,255,255,0.95);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(226,232,240,0.6);border-radius:16px;box-shadow:0 20px 40px rgba(0,0,0,0.12)}.dark .glass-modal{background:rgba(15,23,42,0.95);border:1px solid rgba(51,65,85,0.6);box-shadow:0 20px 40px rgba(0,0,0,0.4)}.glass-input{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:6px;padding:.75rem 1rem;color:#0f172a;box-shadow:0 2px 4px rgba(0,0,0,0.04);transition:border-color .2s ease,box-shadow .2s ease}.glass-input:focus{outline:0;border-color:rgba(0,115,206,0.5);box-shadow:0 2px 8px rgba(0,115,206,0.1)}.dark .glass-input{background:rgba(30,41,59,0.8);border:1px solid rgba(100,116,139,0.5);color:#e2e8f0;box-shadow:0 2px 4px rgba(0,0,0,0.15)}.dark .glass-input:focus{border-color:rgba(59,130,246,0.5);box-shadow:0 2px 8px rgba(59,130,246,0.15)}.glass-dropdown{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.3);border-radius:8px;box-shadow:0 8px 20px rgba(0,0,0,0.15)}.dark .glass-dropdown{background:rgba(15,23,42,0.9);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.glass-overlay{background:rgba(255,255,255,0.1);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.dark .glass-overlay{background:rgba(0,0,0,0.2)}@media(max-width:768px){.glass-card{padding:1rem;border-radius:8px}.glass-modal{border-radius:12px}.glass-base,.glass-strong,.glass-subtle{backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}}@media(prefers-reduced-motion:reduce){.glass-card,.glass-btn,.glass-input{transition:none !important}}@media(prefers-contrast:high){.glass-base,.glass-strong,.glass-card{border-width:2px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}}.glass-base,.glass-strong,.glass-subtle,.glass-card,.glass-btn,.glass-modal{will-change:transform}

Binary file not shown.

View File

@ -0,0 +1,148 @@
/**
* Minimales Icon-Set für Kiosk-Modus
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
*/
/* Icon-Basis-Klasse */
.icon {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: middle;
}
.icon-lg { width: 1.5rem; height: 1.5rem; }
.icon-xl { width: 2rem; height: 2rem; }
/* ===== DRUCKER ICONS ===== */
.icon-printer {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
.icon-print {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
}
/* ===== STATUS ICONS ===== */
.icon-check {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-warning {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
}
.icon-error {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
.icon-offline {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
}
/* ===== NAVIGATION ICONS ===== */
.icon-home {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
}
.icon-settings {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
}
.icon-users {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
}
.icon-dashboard {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
}
/* ===== ACTION ICONS ===== */
.icon-plus {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
}
.icon-edit {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
}
.icon-delete {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
}
.icon-refresh {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
}
/* ===== POWER/CONNECTION ICONS ===== */
.icon-power {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
}
.icon-wifi {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
}
/* ===== DOKUMENT ICONS ===== */
.icon-file {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
}
.icon-queue {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
}
/* ===== INFO ICONS ===== */
.icon-info {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
}
.icon-time {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
}
/* ===== ARROW ICONS ===== */
.icon-arrow-right {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
}
.icon-arrow-down {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
}
/* ===== HOVER-STATES ===== */
.btn:hover .icon,
.nav-item:hover .icon {
opacity: 0.8;
}
/* ===== DARK MODE ===== */
@media (prefers-color-scheme: dark) {
.icon-printer,
.icon-print,
.icon-home,
.icon-settings,
.icon-users,
.icon-dashboard,
.icon-plus,
.icon-edit,
.icon-refresh,
.icon-file,
.icon-queue,
.icon-time,
.icon-arrow-right,
.icon-arrow-down {
filter: brightness(2);
}
}
/* ===== RESPONSIVE ICON-SIZES ===== */
@media (max-width: 768px) {
.icon { width: 1.25rem; height: 1.25rem; }
.icon-lg { width: 1.75rem; height: 1.75rem; }
.icon-xl { width: 2.25rem; height: 2.25rem; }
}

Binary file not shown.

1
backend/static/css/input.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -0,0 +1,346 @@
/**
* MYP Platform - Kiosk-Optimierte CSS
* Maximale Performance für Offline-Kiosk-Umgebung
* Keine Touch-Events, minimale Animationen, optimierte Rendering-Performance
*/
/* ===== CRITICAL INLINE STYLES (sollten im HTML-Head stehen) ===== */
:root {
/* Reduzierte Farbvariablen für bessere Performance */
--primary: #0073ce;
--primary-dark: #005a9f;
--bg: #fafbfc;
--surface: #ffffff;
--text: #111827;
--text-muted: #6b7280;
--border: #e5e7eb;
--shadow: 0 2px 4px rgba(0,0,0,0.05);
}
/* CSS Containment für bessere Performance */
* {
contain: layout style;
}
/* Basis-Reset ohne aufwendige Normalisierung */
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.5;
contain: layout style paint;
/* Optimiert für Kiosk-Rendering */
text-rendering: optimizeSpeed;
-webkit-font-smoothing: antialiased;
}
/* ===== LAYOUT OPTIMIERUNGEN ===== */
.header {
background: var(--surface);
border-bottom: 1px solid var(--border);
padding: 1rem;
contain: layout style;
}
.nav {
display: flex;
gap: 1rem;
contain: layout;
}
.nav-item {
padding: 0.5rem 1rem;
border-radius: 6px;
text-decoration: none;
color: var(--text-muted);
transition: background-color 0.1s ease; /* Minimale Transition */
}
.nav-item:hover {
background: var(--bg);
color: var(--text);
}
.nav-item.active {
background: var(--primary);
color: white;
}
/* ===== OPTIMIERTE KARTEN ===== */
.card {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 1rem;
box-shadow: var(--shadow);
contain: layout style paint;
}
.card:hover {
transform: translateY(-1px); /* Minimaler Hover-Effekt */
}
/* ===== BUTTONS OHNE KOMPLEXE ANIMATIONEN ===== */
.btn {
background: var(--primary);
color: white;
border: none;
border-radius: 6px;
padding: 0.75rem 1.5rem;
font-weight: 600;
cursor: pointer;
transition: background-color 0.1s ease;
contain: layout style;
}
.btn:hover {
background: var(--primary-dark);
}
.btn-secondary {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.btn-secondary:hover {
background: var(--bg);
}
/* ===== INPUTS OPTIMIERT ===== */
.input {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 0.75rem;
width: 100%;
transition: border-color 0.1s ease;
contain: layout style;
}
.input:focus {
outline: none;
border-color: var(--primary);
}
/* ===== TABELLEN OHNE KOMPLEXE EFFEKTE ===== */
.table {
width: 100%;
border-collapse: collapse;
background: var(--surface);
border-radius: 8px;
overflow: hidden;
contain: layout;
}
.table th {
background: var(--bg);
padding: 1rem;
text-align: left;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.table td {
padding: 1rem;
border-bottom: 1px solid var(--border);
}
.table tr:hover {
background: var(--bg);
}
/* ===== STATUS BADGES VEREINFACHT ===== */
.status {
display: inline-block;
padding: 0.25rem 0.75rem;
border-radius: 999px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.status-online { background: #d1fae5; color: #065f46; }
.status-offline { background: #fee2e2; color: #991b1b; }
.status-printing { background: #dbeafe; color: #1e40af; }
/* ===== GRID LAYOUTS OPTIMIERT ===== */
.grid {
display: grid;
gap: 1rem;
contain: layout;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
/* ===== UTILITIES MINIMAL ===== */
.flex { display: flex; contain: layout; }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: 0.5rem; }
.gap-4 { gap: 1rem; }
.p-1 { padding: 0.25rem; }
.p-2 { padding: 0.5rem; }
.p-4 { padding: 1rem; }
.p-6 { padding: 1.5rem; }
.m-1 { margin: 0.25rem; }
.m-2 { margin: 0.5rem; }
.m-4 { margin: 1rem; }
.mb-2 { margin-bottom: 0.5rem; }
.mb-4 { margin-bottom: 1rem; }
.mb-6 { margin-bottom: 1.5rem; }
.text-sm { font-size: 0.875rem; }
.text-lg { font-size: 1.125rem; }
.text-xl { font-size: 1.25rem; }
.text-2xl { font-size: 1.5rem; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }
.text-center { text-align: center; }
.text-right { text-align: right; }
.w-full { width: 100%; }
.h-full { height: 100%; }
.rounded { border-radius: 6px; }
.rounded-lg { border-radius: 8px; }
.border { border: 1px solid var(--border); }
.border-t { border-top: 1px solid var(--border); }
.border-b { border-bottom: 1px solid var(--border); }
.bg-white { background: var(--surface); }
.bg-gray-50 { background: var(--bg); }
.text-gray-600 { color: var(--text-muted); }
.text-blue-600 { color: var(--primary); }
/* ===== DARK MODE MINIMAL ===== */
@media (prefers-color-scheme: dark) {
:root {
--bg: #1e293b;
--surface: #334155;
--text: #f8fafc;
--text-muted: #94a3b8;
--border: #475569;
--shadow: 0 2px 4px rgba(0,0,0,0.3);
}
}
/* ===== RESPONSIVE FÜR KIOSK-DISPLAYS ===== */
@media (max-width: 1024px) {
.grid-4 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.grid-4,
.grid-3,
.grid-2 { grid-template-columns: 1fr; }
.nav {
flex-direction: column;
gap: 0.5rem;
}
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
/* Deaktivierung nicht benötigter Features für Kiosk */
* {
/* Keine Touch-Events */
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
}
/* Nur notwendige Elemente selektierbar */
input,
textarea {
-webkit-user-select: text;
user-select: text;
touch-action: manipulation;
}
/* Optimierte Scrolling-Performance */
* {
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
}
/* GPU-Acceleration nur wo nötig */
.card:hover,
.btn:hover {
will-change: transform;
}
/* Minimale Animationen für bessere Performance */
@media (prefers-reduced-motion: reduce) {
* {
transition: none !important;
animation: none !important;
}
}
/* Print-Optimierung (falls Kiosk drucken kann) */
@media print {
.nav,
.btn {
display: none;
}
.card {
box-shadow: none;
border: 1px solid #000;
}
}
/* ===== LAYOUT SHIFT PREVENTION ===== */
img {
height: auto;
max-width: 100%;
vertical-align: middle;
}
/* Container für stabile Layouts */
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
contain: layout;
}
/* ===== KIOSK-SPEZIFISCHE OPTIMIERUNGEN ===== */
/* Vollbildmodus-Unterstützung */
html,
body {
height: 100%;
overflow-x: hidden;
}
/* Fokus-Management für Keyboard-Navigation */
:focus {
outline: 2px solid var(--primary);
outline-offset: 2px;
}
/* Kein Selection-Highlighting */
::selection {
background: transparent;
}
/* Optimierte Font-Loading */
@font-face {
font-family: 'system-ui';
font-display: swap;
}

View File

@ -1,100 +1,27 @@
/** /**
* MYP Platform - Optimierungs-Animationen * MYP Platform - Optimierte einfache Animationen
* Belohnende und motivierende Animationen für Auto-Optimierung * Reduzierte, performante Animationen für bessere User Experience
*/ */
/* ===== MODAL FADE-IN ANIMATION ===== */ /* ===== EINFACHE FADE-IN ANIMATION ===== */
@keyframes fade-in { @keyframes fade-in {
from { from {
opacity: 0; opacity: 0;
backdrop-filter: blur(0px);
} }
to { to {
opacity: 1; opacity: 1;
backdrop-filter: blur(8px);
} }
} }
.animate-fade-in { .animate-fade-in {
animation: fade-in 0.3s ease-out; animation: fade-in 0.2s ease-out;
} }
/* ===== BOUNCE-IN ANIMATION ===== */ /* ===== EINFACHE SLIDE-UP ANIMATION ===== */
@keyframes bounce-in {
0% {
opacity: 0;
transform: scale(0.3) translateY(-50px);
}
50% {
opacity: 1;
transform: scale(1.05) translateY(0);
}
70% {
transform: scale(0.95);
}
100% {
opacity: 1;
transform: scale(1);
}
}
.animate-bounce-in {
animation: bounce-in 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
/* ===== PULSE-SCALE ANIMATION ===== */
@keyframes pulse-scale {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
.animate-pulse-scale {
animation: pulse-scale 3s infinite ease-in-out;
}
/* ===== FLOATING ANIMATIONS ===== */
@keyframes float {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
33% {
transform: translateY(-15px) rotate(5deg);
}
66% {
transform: translateY(-5px) rotate(-3deg);
}
}
@keyframes float-delay {
0%, 100% {
transform: translateY(0px) rotate(0deg);
}
33% {
transform: translateY(-10px) rotate(-5deg);
}
66% {
transform: translateY(-8px) rotate(3deg);
}
}
.animate-float {
animation: float 4s infinite ease-in-out;
}
.animate-float-delay {
animation: float-delay 4s infinite ease-in-out;
animation-delay: 1.5s;
}
/* ===== SLIDE-UP ANIMATIONS ===== */
@keyframes slide-up { @keyframes slide-up {
from { from {
opacity: 0; opacity: 0;
transform: translateY(30px); transform: translateY(15px);
} }
to { to {
opacity: 1; opacity: 1;
@ -103,239 +30,105 @@
} }
.animate-slide-up { .animate-slide-up {
animation: slide-up 0.6s ease-out; animation: slide-up 0.3s ease-out;
} }
.animate-slide-up-delay { .animate-slide-up-delay {
animation: slide-up 0.6s ease-out; animation: slide-up 0.3s ease-out;
animation-delay: 0.2s; animation-delay: 0.1s;
animation-fill-mode: both; animation-fill-mode: both;
} }
.animate-slide-up-delay-2 { .animate-slide-up-delay-2 {
animation: slide-up 0.6s ease-out; animation: slide-up 0.3s ease-out;
animation-delay: 0.4s; animation-delay: 0.2s;
animation-fill-mode: both; animation-fill-mode: both;
} }
.animate-slide-up-delay-3 { /* ===== EINFACHER HOVER-EFFEKT ===== */
animation: slide-up 0.6s ease-out; .animate-hover-lift {
animation-delay: 0.6s; transition: transform 0.2s ease;
animation-fill-mode: both;
} }
/* ===== COUNT-UP ANIMATION ===== */ .animate-hover-lift:hover {
@keyframes count-up { transform: translateY(-2px);
from {
opacity: 0;
transform: scale(0.5) rotate(-10deg);
}
50% {
opacity: 1;
transform: scale(1.2) rotate(5deg);
}
to {
opacity: 1;
transform: scale(1) rotate(0deg);
}
} }
.animate-count-up { /* ===== EINFACHE SUCCESS ANIMATION ===== */
animation: count-up 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); @keyframes simple-success {
animation-delay: 0.3s;
animation-fill-mode: both;
}
/* ===== GLOW ANIMATION ===== */
@keyframes glow {
0%, 100% {
box-shadow: 0 0 5px rgba(59, 130, 246, 0.5),
0 0 10px rgba(59, 130, 246, 0.3),
0 0 15px rgba(59, 130, 246, 0.1);
}
50% {
box-shadow: 0 0 20px rgba(59, 130, 246, 0.8),
0 0 30px rgba(59, 130, 246, 0.6),
0 0 40px rgba(59, 130, 246, 0.4);
}
}
.animate-glow {
animation: glow 3s infinite ease-in-out;
}
/* ===== KONFETTI ANIMATION ===== */
.confetti-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
pointer-events: none;
}
.confetti-piece {
position: absolute;
width: 8px;
height: 8px;
top: -10px;
border-radius: 2px;
animation: confetti-fall linear infinite;
}
@keyframes confetti-fall {
0% { 0% {
transform: translateY(-100vh) rotate(0deg); opacity: 0;
opacity: 1; transform: scale(0.9);
} }
100% { 100% {
transform: translateY(120vh) rotate(720deg); opacity: 1;
opacity: 0;
}
}
/* ===== ERFOLGS-BADGE SPEZIAL-ANIMATIONEN ===== */
@keyframes star-twinkle {
0%, 100% {
opacity: 0.6;
transform: scale(1); transform: scale(1);
} }
50% {
opacity: 1;
transform: scale(1.2);
}
} }
.badge-star { .animate-success {
animation: star-twinkle 1.5s infinite ease-in-out; animation: simple-success 0.3s ease-out;
} }
/* ===== LOADING SPINNER IMPROVEMENTS ===== */ /* ===== EINFACHER PULSE FÜR LOADING ===== */
@keyframes spinner-glow { @keyframes simple-pulse {
0% {
filter: drop-shadow(0 0 5px rgba(59, 130, 246, 0.5));
}
50% {
filter: drop-shadow(0 0 15px rgba(59, 130, 246, 0.8));
}
100% {
filter: drop-shadow(0 0 5px rgba(59, 130, 246, 0.5));
}
}
#optimization-loader .animate-spin {
animation: spin 1s linear infinite, spinner-glow 2s ease-in-out infinite;
}
/* ===== DARK MODE OPTIMIERUNGEN ===== */
@media (prefers-color-scheme: dark) {
.animate-glow {
animation: glow-dark 2s infinite ease-in-out;
}
@keyframes glow-dark {
0%, 100% { 0%, 100% {
box-shadow: 0 0 5px rgba(96, 165, 250, 0.5), opacity: 1;
0 0 10px rgba(96, 165, 250, 0.3),
0 0 15px rgba(96, 165, 250, 0.1);
} }
50% { 50% {
box-shadow: 0 0 20px rgba(96, 165, 250, 0.8), opacity: 0.6;
0 0 30px rgba(96, 165, 250, 0.6),
0 0 40px rgba(96, 165, 250, 0.4);
}
} }
} }
.animate-pulse-simple {
animation: simple-pulse 2s infinite ease-in-out;
}
/* ===== EINFACHER PROGRESS BAR ===== */
.progress-fill {
transition: width 1s ease-out;
}
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */ /* ===== PERFORMANCE OPTIMIERUNGEN ===== */
.animate-bounce-in,
.animate-fade-in, .animate-fade-in,
.animate-slide-up, .animate-slide-up,
.animate-slide-up-delay, .animate-slide-up-delay,
.animate-slide-up-delay-2, .animate-slide-up-delay-2 {
.animate-slide-up-delay-3 {
will-change: transform, opacity; will-change: transform, opacity;
} }
.animate-pulse-scale, .animate-hover-lift {
.animate-float,
.animate-float-delay {
will-change: transform; will-change: transform;
} }
.animate-glow { /* ===== UTILITY CLASSES ===== */
will-change: box-shadow; .animate-smooth {
transition: all 0.2s ease;
}
.animate-smooth-fast {
transition: all 0.1s ease;
} }
/* ===== RESPONSIVE ANPASSUNGEN ===== */ /* ===== RESPONSIVE ANPASSUNGEN ===== */
@media (max-width: 768px) { @media (max-width: 768px) {
.confetti-piece { .animate-fade-in,
width: 6px; .animate-slide-up,
height: 6px; .animate-slide-up-delay,
} .animate-slide-up-delay-2 {
animation-duration: 0.2s;
#optimization-reward-modal .text-8xl {
font-size: 4rem;
}
#optimization-reward-modal .max-w-md {
max-width: 90vw;
} }
} }
/* ===== BUTTON HOVER VERBESSERUNGEN ===== */ /* ===== REDUZIERTE BEWEGUNG UNTERSTÜTZUNG ===== */
button:hover .badge-star { @media (prefers-reduced-motion: reduce) {
animation-duration: 0.8s; * {
} animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
/* ===== ZUSÄTZLICHE UTILITY CLASSES ===== */ transition-duration: 0.01ms !important;
.animate-shake {
animation: shake 0.5s ease-in-out;
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
}
.animate-heartbeat {
animation: heartbeat 1.5s infinite;
}
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
14% { transform: scale(1.1); }
28% { transform: scale(1); }
42% { transform: scale(1.1); }
70% { transform: scale(1); }
}
/* ===== PROGRESS BAR ANIMATION ===== */
.progress-fill {
animation: progress-grow 2s ease-out;
}
@keyframes progress-grow {
from {
width: 0%;
} }
to {
width: var(--progress-width, 100%); .animate-hover-lift:hover {
} transform: none;
}
/* ===== SUCCESS CHECKMARK ANIMATION ===== */
.success-checkmark {
animation: checkmark-draw 0.8s ease-out;
}
@keyframes checkmark-draw {
0% {
stroke-dasharray: 0 100;
}
100% {
stroke-dasharray: 100 0;
} }
} }

Binary file not shown.

View File

@ -0,0 +1 @@
@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate-fade-in{animation:fade-in .2s ease-out}@keyframes slide-up{from{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}.animate-slide-up{animation:slide-up .3s ease-out}.animate-slide-up-delay{animation:slide-up .3s ease-out;animation-delay:.1s;animation-fill-mode:both}.animate-slide-up-delay-2{animation:slide-up .3s ease-out;animation-delay:.2s;animation-fill-mode:both}.animate-hover-lift{transition:transform .2s ease}.animate-hover-lift:hover{transform:translateY(-2px)}@keyframes simple-success{0%{opacity:0;transform:scale(0.9)}100%{opacity:1;transform:scale(1)}}.animate-success{animation:simple-success .3s ease-out}@keyframes simple-pulse{0%,100%{opacity:1}50%{opacity:.6}}.animate-pulse-simple{animation:simple-pulse 2s infinite ease-in-out}.progress-fill{transition:width 1s ease-out}.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{will-change:transform,opacity}.animate-hover-lift{will-change:transform}.animate-smooth{transition:all .2s ease}.animate-smooth-fast{transition:all .1s ease}@media(max-width:768px){.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{animation-duration:.2s}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}.animate-hover-lift:hover{transform:none}}

Binary file not shown.

Binary file not shown.

1
backend/static/css/output.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

1
backend/static/css/printers.min.css vendored Normal file
View File

@ -0,0 +1 @@
.filter-btn{transition:all .2s ease-in-out}.filter-btn.active{background-color:white;box-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06);color:#374151}.dark .filter-btn.active{background-color:#475569;color:#f1f5f9}.printer-card-online{background:linear-gradient(135deg,#f0fdf4 0,#fff 100%);border-color:#bbf7d0;box-shadow:0 1px 3px 0 rgba(34,197,94,0.1),0 1px 2px 0 rgba(34,197,94,0.06)}.dark .printer-card-online{background:linear-gradient(135deg,rgba(34,197,94,0.1) 0,#1e293b 100%);border-color:#166534;box-shadow:0 1px 3px 0 rgba(34,197,94,0.2),0 1px 2px 0 rgba(34,197,94,0.1)}.printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.2),0 2px 4px -1px rgba(34,197,94,0.1)}.dark .printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.3),0 2px 4px -1px rgba(34,197,94,0.2)}.online-indicator{animation:pulse-green 2s cubic-bezier(0.4,0,0.6,1) infinite}@keyframes pulse-green{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(34,197,94,0.7)}50%{opacity:.8;box-shadow:0 0 0 4px rgba(34,197,94,0)}}.status-count-change{animation:count-change .5s ease-in-out}@keyframes count-change{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.auto-refresh-active{background:linear-gradient(45deg,#10b981,#059669);animation:gradient-shift 3s ease-in-out infinite}@keyframes gradient-shift{0%,100%{background-position:0 50%}50%{background-position:100% 50%}}.printer-card{transition:all .3s cubic-bezier(0.4,0,0.2,1)}.printer-card:hover{transform:translateY(-2px)}.live-update-spinner{animation:spin 1s linear infinite}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:640px){.filter-btn{padding:.375rem .75rem;font-size:.75rem}.status-overview{flex-direction:column;gap:.5rem}.printer-card{padding:1rem}}.dark .printer-card{background-color:#1e293b;border-color:#334155}.dark .printer-card:hover{background-color:#334155}.filter-btn:focus{outline:2px solid #3b82f6;outline-offset:2px}.printer-card:focus-within{outline:2px solid #3b82f6;outline-offset:2px}@media print{.filter-btn,.auto-refresh-btn,.printer-detail-btn,.delete-printer-btn{display:none}.printer-card{break-inside:avoid;box-shadow:none;border:1px solid #000}}@media(prefers-contrast:high){.printer-card-online{border:2px solid #059669}.online-indicator{border:1px solid #000}}@media(prefers-reduced-motion:reduce){.online-indicator,.auto-refresh-active,.live-update-spinner{animation:none}.printer-card{transition:none}.printer-card:hover{transform:none}}

Binary file not shown.

View File

@ -1,12 +1,11 @@
/** /**
* Mercedes-Benz MYP Platform - Erweiterte Professional Theme * Mercedes-Benz MYP Platform - Optimierte Professional Theme
* Verbesserte Light/Dark Mode Implementierung mit optimierten Kontrasten * Vereinfachte Light/Dark Mode Implementierung für bessere Performance
* OPTIMIERT: Light Mode deutlich verbessert für bessere Lesbarkeit
*/ */
/* Globale CSS-Variablen für konsistente Theming */ /* Globale CSS-Variablen für konsistente Theming */
:root { :root {
/* Mercedes-Benz Markenfarben - Erweitert */ /* Mercedes-Benz Markenfarben */
--mb-primary: #0073ce; --mb-primary: #0073ce;
--mb-primary-dark: #005a9f; --mb-primary-dark: #005a9f;
--mb-secondary: #64748b; --mb-secondary: #64748b;
@ -14,32 +13,22 @@
--mb-black: #000000; --mb-black: #000000;
--mb-silver: #c0c0c0; --mb-silver: #c0c0c0;
/* Light Mode Farbpalette - DEUTLICH VERBESSERT für optimale Lesbarkeit */ /* Light Mode Farbpalette */
--light-bg-primary: #ffffff; --light-bg-primary: #ffffff;
--light-bg-secondary: #fafbfc; --light-bg-secondary: #fafbfc;
--light-bg-tertiary: #f3f5f7; --light-bg-tertiary: #f3f5f7;
--light-bg-accent: #fbfcfd;
--light-surface: #ffffff; --light-surface: #ffffff;
--light-surface-hover: #fafbfc; --light-surface-hover: #fafbfc;
--light-surface-active: #f3f5f7; --light-text-primary: #111827;
--light-text-primary: #111827; /* Deutlich verstärkter Kontrast */ --light-text-secondary: #374151;
--light-text-secondary: #374151; /* Erhöhter Kontrast für bessere Lesbarkeit */ --light-text-muted: #6b7280;
--light-text-muted: #6b7280; /* Optimierter Muted-Text, immer noch lesbar */
--light-text-accent: #0073ce; --light-text-accent: #0073ce;
--light-border: #e5e7eb; /* Sichtbarere aber elegante Borders */ --light-border: #e5e7eb;
--light-border-strong: #d1d5db; --light-border-strong: #d1d5db;
--light-border-accent: #0073ce15; /* Subtilerer Accent-Border */ --light-shadow: rgba(0, 0, 0, 0.04);
--light-shadow: rgba(0, 0, 0, 0.04); /* Sanftere, natürlichere Schatten */
--light-shadow-strong: rgba(0, 0, 0, 0.08); --light-shadow-strong: rgba(0, 0, 0, 0.08);
--light-shadow-accent: rgba(0, 115, 206, 0.08);
/* Neue Light Mode Gradients - VERBESSERT für sanftere, harmonischere Optik */ /* Dark Mode Farbpalette */
--light-gradient-primary: linear-gradient(135deg, #ffffff 0%, #fafbfc 25%, #f8fafc 75%, #f3f5f7 100%);
--light-gradient-card: linear-gradient(135deg, #ffffff 0%, #fdfdfe 50%, #fafbfc 100%);
--light-gradient-hero: linear-gradient(135deg, #fafbfc 0%, #f5f7f9 30%, #f0f3f6 70%, #f8fafc 100%);
--light-gradient-accent: linear-gradient(135deg, #0073ce 0%, #005a9f 100%);
/* Dark Mode Farbpalette - UNVERÄNDERT (bereits perfekt) */
--dark-bg-primary: #0f172a; --dark-bg-primary: #0f172a;
--dark-bg-secondary: #1e293b; --dark-bg-secondary: #1e293b;
--dark-bg-tertiary: #334155; --dark-bg-tertiary: #334155;
@ -54,118 +43,81 @@
--dark-shadow-strong: rgba(0, 0, 0, 0.5); --dark-shadow-strong: rgba(0, 0, 0, 0.5);
} }
/* Professionelle Hero-Header Stile - VERBESSERT für Light Mode */ /* Vereinfachte Hero-Header */
.professional-hero { .professional-hero {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-radius: 1.5rem; border-radius: 1rem;
margin: 1.5rem; margin: 1.5rem;
margin-bottom: 2rem; margin-bottom: 2rem;
background: var(--light-gradient-hero); background: var(--light-bg-secondary);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
box-shadow: box-shadow: 0 4px 12px var(--light-shadow);
0 8px 25px var(--light-shadow), transition: transform 0.2s ease, box-shadow 0.2s ease;
0 4px 12px rgba(0, 115, 206, 0.03),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
transition: all 0.3s ease;
} }
.professional-hero:hover { .professional-hero:hover {
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: box-shadow: 0 8px 20px var(--light-shadow-strong);
0 12px 35px var(--light-shadow-strong),
0 6px 16px var(--light-shadow-accent),
inset 0 1px 0 rgba(255, 255, 255, 0.95);
} }
.dark .professional-hero { .dark .professional-hero {
background: linear-gradient(135deg, var(--dark-bg-primary) 0%, var(--dark-bg-secondary) 100%); background: var(--dark-bg-secondary);
border: 1px solid var(--dark-border); border: 1px solid var(--dark-border);
box-shadow: 0 20px 40px var(--dark-shadow-strong); box-shadow: 0 8px 20px var(--dark-shadow);
} }
.professional-hero::before { /* Vereinfachte Container */
content: '';
position: absolute;
inset: 0;
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.06) 50%, transparent 70%);
opacity: 0.6;
}
.dark .professional-hero::before {
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.05) 50%, transparent 70%);
opacity: 0.3;
}
/* Hero Pattern Overlay - OPTIMIERT */
.hero-pattern {
background-image:
radial-gradient(circle at 20% 20%, var(--light-border) 0.8px, transparent 0.8px),
radial-gradient(circle at 80% 80%, var(--light-border) 0.8px, transparent 0.8px);
background-size: 48px 48px;
background-position: 0 0, 24px 24px;
}
.dark .hero-pattern {
background-image:
radial-gradient(circle at 20% 20%, var(--dark-border) 1px, transparent 1px),
radial-gradient(circle at 80% 80%, var(--dark-border) 1px, transparent 1px);
}
/* Professionelle Container - VERBESSERT */
.professional-container { .professional-container {
background: var(--light-surface); background: var(--light-surface);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
border-radius: 1rem; border-radius: 0.75rem;
box-shadow: 0 4px 20px var(--light-shadow); box-shadow: 0 2px 8px var(--light-shadow);
backdrop-filter: blur(16px); transition: transform 0.2s ease, box-shadow 0.2s ease;
transition: all 0.3s ease;
} }
.dark .professional-container { .dark .professional-container {
background: var(--dark-surface); background: var(--dark-surface);
border: 1px solid var(--dark-border); border: 1px solid var(--dark-border);
box-shadow: 0 10px 30px var(--dark-shadow); box-shadow: 0 4px 12px var(--dark-shadow);
} }
.professional-container:hover { .professional-container:hover {
transform: translateY(-2px); transform: translateY(-1px);
box-shadow: 0 8px 30px var(--light-shadow-strong); box-shadow: 0 4px 16px var(--light-shadow-strong);
} }
.dark .professional-container:hover { .dark .professional-container:hover {
box-shadow: 0 20px 40px var(--dark-shadow-strong); box-shadow: 0 8px 20px var(--dark-shadow-strong);
} }
/* Mercedes-Benz Glassmorphism Effekt - OPTIMIERT für Light Mode */ /* Vereinfachte Glassmorphism-Effekte */
.mb-glass { .mb-glass {
background: rgba(255, 255, 255, 0.94); background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(8px);
border: 1px solid rgba(229, 231, 235, 0.4); border: 1px solid rgba(229, 231, 235, 0.4);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
transition: all 0.3s ease; transition: transform 0.2s ease, background 0.2s ease;
} }
.dark .mb-glass { .dark .mb-glass {
background: rgba(15, 23, 42, 0.9); background: rgba(15, 23, 42, 0.85);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
} }
.mb-glass:hover { .mb-glass:hover {
background: rgba(255, 255, 255, 0.97); background: rgba(255, 255, 255, 0.95);
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.06);
} }
.dark .mb-glass:hover { .dark .mb-glass:hover {
background: rgba(15, 23, 42, 0.95); background: rgba(15, 23, 42, 0.9);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
} }
/* Professional Buttons - VERBESSERT */ /* Vereinfachte Buttons */
.btn-professional { .btn-professional {
background: var(--light-gradient-accent); background: linear-gradient(135deg, var(--mb-primary) 0%, var(--mb-primary-dark) 100%);
color: white; color: white;
border: none; border: none;
border-radius: 0.5rem; border-radius: 0.5rem;
@ -174,73 +126,50 @@
font-size: 0.875rem; font-size: 0.875rem;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.025em; letter-spacing: 0.025em;
transition: all 0.2s ease; transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
0 2px 8px rgba(0, 115, 206, 0.2),
0 1px 3px rgba(0, 115, 206, 0.08);
position: relative;
overflow: hidden;
}
.btn-professional::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: left 0.5s ease;
} }
.btn-professional:hover { .btn-professional:hover {
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: box-shadow: 0 4px 12px rgba(0, 115, 206, 0.3);
0 4px 15px rgba(0, 115, 206, 0.25),
0 2px 8px rgba(0, 115, 206, 0.15);
}
.btn-professional:hover::before {
left: 100%;
} }
.btn-professional:active { .btn-professional:active {
transform: translateY(0); transform: translateY(0);
} }
/* Secondary Button Style - VERBESSERT */ /* Secondary Button */
.btn-secondary-professional { .btn-secondary-professional {
background: var(--light-surface); background: var(--light-surface);
color: var(--light-text-primary); color: var(--light-text-primary);
border: 1px solid var(--light-border-strong); border: 1px solid var(--light-border-strong);
border-radius: 0.75rem; border-radius: 0.5rem;
padding: 0.75rem 1.75rem; padding: 0.75rem 1.5rem;
font-weight: 600; font-weight: 600;
font-size: 0.875rem; font-size: 0.875rem;
transition: all 0.3s ease; transition: all 0.2s ease;
box-shadow: 0 2px 8px var(--light-shadow); box-shadow: 0 1px 4px var(--light-shadow);
} }
.dark .btn-secondary-professional { .dark .btn-secondary-professional {
background: var(--dark-surface); background: var(--dark-surface);
color: var(--dark-text-primary); color: var(--dark-text-primary);
border-color: var(--dark-border-strong); border-color: var(--dark-border-strong);
box-shadow: 0 4px 15px var(--dark-shadow); box-shadow: 0 2px 8px var(--dark-shadow);
} }
.btn-secondary-professional:hover { .btn-secondary-professional:hover {
background: var(--light-surface-hover); background: var(--light-surface-hover);
border-color: var(--mb-primary); border-color: var(--mb-primary);
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: 0 4px 15px var(--light-shadow-strong);
} }
.dark .btn-secondary-professional:hover { .dark .btn-secondary-professional:hover {
background: var(--dark-surface-hover); background: var(--dark-surface-hover);
box-shadow: 0 8px 25px var(--dark-shadow);
} }
/* Professional Input Fields - VERBESSERT */ /* Vereinfachte Input Fields */
.input-professional { .input-professional {
background: var(--light-surface); background: var(--light-surface);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
@ -248,20 +177,20 @@
padding: 0.75rem 1rem; padding: 0.75rem 1rem;
color: var(--light-text-primary); color: var(--light-text-primary);
font-size: 0.875rem; font-size: 0.875rem;
transition: all 0.3s ease; transition: border-color 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 1px 6px var(--light-shadow); box-shadow: 0 1px 4px var(--light-shadow);
} }
.dark .input-professional { .dark .input-professional {
background: var(--dark-surface); background: var(--dark-surface);
border-color: var(--dark-border); border-color: var(--dark-border);
color: var(--dark-text-primary); color: var(--dark-text-primary);
box-shadow: 0 2px 8px var(--dark-shadow); box-shadow: 0 2px 4px var(--dark-shadow);
} }
.input-professional:focus { .input-professional:focus {
border-color: var(--mb-primary); border-color: var(--mb-primary);
box-shadow: 0 0 0 3px rgba(0, 115, 206, 0.06); box-shadow: 0 0 0 3px rgba(0, 115, 206, 0.1);
transform: translateY(-1px); transform: translateY(-1px);
} }
@ -273,77 +202,51 @@
color: var(--dark-text-muted); color: var(--dark-text-muted);
} }
/* Professional Cards - VERBESSERT */ /* Vereinfachte Cards */
.card-professional { .card-professional {
background: var(--light-gradient-card); background: var(--light-surface);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
border-radius: 0.75rem; border-radius: 0.75rem;
padding: 1.5rem; padding: 1.5rem;
box-shadow: box-shadow: 0 2px 8px var(--light-shadow);
0 2px 12px var(--light-shadow), transition: transform 0.2s ease, box-shadow 0.2s ease;
0 1px 4px rgba(0, 115, 206, 0.02),
inset 0 1px 0 rgba(255, 255, 255, 0.8);
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.card-professional::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: var(--light-gradient-accent);
opacity: 0;
transition: opacity 0.3s ease;
} }
.card-professional:hover { .card-professional:hover {
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: box-shadow: 0 4px 16px var(--light-shadow-strong);
0 8px 25px var(--light-shadow-strong),
0 4px 12px var(--light-shadow-accent),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
}
.card-professional:hover::before {
opacity: 1;
} }
.dark .card-professional { .dark .card-professional {
background: var(--dark-surface); background: var(--dark-surface);
border-color: var(--dark-border); border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow); box-shadow: 0 4px 12px var(--dark-shadow);
} }
/* Professional Statistics Cards - VERBESSERT */ /* Vereinfachte Statistics Cards */
.stat-card { .stat-card {
background: var(--light-surface); background: var(--light-surface);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
border-radius: 0.75rem; border-radius: 0.75rem;
padding: 1.5rem; padding: 1.5rem;
text-align: center; text-align: center;
transition: all 0.3s ease; transition: transform 0.2s ease, box-shadow 0.2s ease;
box-shadow: 0 2px 12px var(--light-shadow); box-shadow: 0 2px 8px var(--light-shadow);
position: relative;
overflow: hidden;
} }
.dark .stat-card { .dark .stat-card {
background: var(--dark-surface); background: var(--dark-surface);
border-color: var(--dark-border); border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow); box-shadow: 0 4px 12px var(--dark-shadow);
} }
.stat-card:hover { .stat-card:hover {
transform: translateY(-1px) scale(1.01); transform: translateY(-1px);
box-shadow: 0 6px 20px var(--light-shadow-strong); box-shadow: 0 4px 16px var(--light-shadow-strong);
} }
.dark .stat-card:hover { .dark .stat-card:hover {
box-shadow: 0 8px 30px var(--dark-shadow-strong); box-shadow: 0 8px 20px var(--dark-shadow-strong);
} }
.stat-number { .stat-number {
@ -370,7 +273,7 @@
color: var(--dark-text-muted); color: var(--dark-text-muted);
} }
/* Professional Status Badges */ /* Vereinfachte Status Badges */
.status-professional { .status-professional {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@ -381,121 +284,61 @@
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.05em; letter-spacing: 0.05em;
transition: all 0.2s ease; transition: transform 0.2s ease;
border: 1px solid transparent; border: 1px solid transparent;
} }
.status-professional:hover { .status-professional:hover {
transform: scale(1.05); transform: scale(1.02);
} }
/* Verbesserte Status Indicators */ /* Status Indicators */
.status-online { .status-online {
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%); background: #ecfdf5;
color: #065f46; color: #065f46;
border: 1px solid rgba(16, 185, 129, 0.2); border: 1px solid rgba(16, 185, 129, 0.2);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
} }
.dark .status-online { .dark .status-online {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(16, 185, 129, 0.05) 100%); background: rgba(16, 185, 129, 0.15);
color: #10b981; color: #10b981;
border-color: rgba(16, 185, 129, 0.3); border-color: rgba(16, 185, 129, 0.3);
} }
.status-offline { .status-offline {
background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%); background: #fef2f2;
color: #991b1b; color: #991b1b;
border: 1px solid rgba(239, 68, 68, 0.2); border: 1px solid rgba(239, 68, 68, 0.2);
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
} }
.dark .status-offline { .dark .status-offline {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(239, 68, 68, 0.05) 100%); background: rgba(239, 68, 68, 0.15);
color: #ef4444; color: #ef4444;
border-color: rgba(239, 68, 68, 0.3); border-color: rgba(239, 68, 68, 0.3);
} }
.status-printing { .status-printing {
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%); background: #eff6ff;
color: #1d4ed8; color: #1d4ed8;
border: 1px solid rgba(59, 130, 246, 0.2); border: 1px solid rgba(59, 130, 246, 0.2);
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
} }
.dark .status-printing { .dark .status-printing {
background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(59, 130, 246, 0.05) 100%); background: rgba(59, 130, 246, 0.15);
color: #3b82f6; color: #3b82f6;
border-color: rgba(59, 130, 246, 0.3); border-color: rgba(59, 130, 246, 0.3);
} }
.status-maintenance { /* Vereinfachte Typography */
background: linear-gradient(135deg, #faf5ff 0%, #ede9fe 100%);
color: #6b21a8;
border: 1px solid rgba(139, 92, 246, 0.2);
box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1);
}
.dark .status-maintenance {
background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%);
color: #8b5cf6;
border-color: rgba(139, 92, 246, 0.3);
}
.status-pending {
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
color: #92400e;
border: 1px solid rgba(251, 191, 36, 0.2);
box-shadow: 0 2px 8px rgba(251, 191, 36, 0.1);
}
.dark .status-pending {
background: linear-gradient(135deg, rgba(251, 191, 36, 0.15) 0%, rgba(251, 191, 36, 0.05) 100%);
color: #fbbf24;
border-color: rgba(251, 191, 36, 0.3);
}
.status-approved {
background: linear-gradient(135deg, #ecfdf5 0%, #a7f3d0 100%);
color: #065f46;
border: 1px solid rgba(16, 185, 129, 0.3);
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15);
}
.dark .status-approved {
background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.1) 100%);
color: #10b981;
}
.status-denied {
background: linear-gradient(135deg, #fef2f2 0%, #fca5a5 100%);
color: #991b1b;
border: 1px solid rgba(239, 68, 68, 0.3);
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.15);
}
.dark .status-denied {
background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(239, 68, 68, 0.1) 100%);
color: #ef4444;
}
/* Professional Typography */
.title-professional { .title-professional {
background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-accent) 50%, var(--light-text-secondary) 100%); color: var(--light-text-primary);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: 700; font-weight: 700;
letter-spacing: -0.025em; letter-spacing: -0.025em;
line-height: 1.1; line-height: 1.1;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
} }
.dark .title-professional { .dark .title-professional {
background: linear-gradient(135deg, var(--dark-text-primary) 0%, var(--dark-text-secondary) 100%); color: var(--dark-text-primary);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
} }
.subtitle-professional { .subtitle-professional {
@ -512,21 +355,17 @@
/* Professional Navigation */ /* Professional Navigation */
.nav-professional { .nav-professional {
background: var(--light-gradient-card); background: var(--light-bg-secondary);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
border-radius: 1rem; border-radius: 0.75rem;
padding: 0.5rem; padding: 0.5rem;
box-shadow: box-shadow: 0 2px 8px var(--light-shadow);
0 4px 15px var(--light-shadow),
0 2px 8px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
backdrop-filter: blur(20px);
} }
.dark .nav-professional { .dark .nav-professional {
background: var(--dark-surface); background: var(--dark-bg-secondary);
border-color: var(--dark-border); border-color: var(--dark-border);
box-shadow: 0 4px 15px var(--dark-shadow); box-shadow: 0 4px 12px var(--dark-shadow);
} }
.nav-item-professional { .nav-item-professional {
@ -563,8 +402,8 @@
background: linear-gradient(135deg, rgba(0, 115, 206, 0.1) 0%, rgba(0, 115, 206, 0.05) 100%); background: linear-gradient(135deg, rgba(0, 115, 206, 0.1) 0%, rgba(0, 115, 206, 0.05) 100%);
color: var(--mb-primary); color: var(--mb-primary);
font-weight: 600; font-weight: 600;
border: 1px solid var(--light-border-accent); border: 1px solid var(--light-border-strong);
box-shadow: 0 2px 8px var(--light-shadow-accent); box-shadow: 0 2px 8px var(--light-shadow);
} }
.dark .nav-item-professional.active { .dark .nav-item-professional.active {
@ -575,23 +414,20 @@
.table-professional { .table-professional {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
background: var(--light-gradient-card); background: var(--light-bg-secondary);
border-radius: 1rem; border-radius: 0.75rem;
overflow: hidden; overflow: hidden;
box-shadow: box-shadow: 0 2px 8px var(--light-shadow);
0 4px 20px var(--light-shadow),
0 2px 8px rgba(0, 115, 206, 0.05),
inset 0 1px 0 rgba(255, 255, 255, 0.6);
border: 1px solid var(--light-border); border: 1px solid var(--light-border);
} }
.dark .table-professional { .dark .table-professional {
background: var(--dark-surface); background: var(--dark-bg-secondary);
box-shadow: 0 4px 20px var(--dark-shadow); box-shadow: 0 4px 12px var(--dark-shadow);
} }
.table-professional th { .table-professional th {
background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%); background: linear-gradient(135deg, var(--light-bg-tertiary) 0%, var(--light-bg-secondary) 100%);
color: var(--light-text-primary); color: var(--light-text-primary);
font-weight: 600; font-weight: 600;
text-align: left; text-align: left;
@ -611,7 +447,7 @@
} }
.dark .table-professional th { .dark .table-professional th {
background: var(--dark-bg-secondary); background: var(--dark-bg-tertiary);
color: var(--dark-text-primary); color: var(--dark-text-primary);
border-bottom-color: var(--dark-border); border-bottom-color: var(--dark-border);
} }
@ -723,7 +559,7 @@
/* Background Gradients für verschiedene Seiten */ /* Background Gradients für verschiedene Seiten */
.bg-professional { .bg-professional {
background: var(--light-gradient-primary); background: var(--light-bg-secondary);
min-height: 100vh; min-height: 100vh;
position: relative; position: relative;
} }

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More