🌟 🎉 Major Update:
This commit is contained in:
parent
62efe03887
commit
4042f07c00
657
README.md
657
README.md
@ -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
|
|
||||||
```
|
|
||||||
|
|
||||||
|
Binary file not shown.
151
backend/build-kiosk-css.ps1
Normal file
151
backend/build-kiosk-css.ps1
Normal 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
|
88
backend/build-kiosk-css.sh
Normal file
88
backend/build-kiosk-css.sh
Normal 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.
1
backend/docs/CSS_OPTIMIERUNGEN.md
Normal file
1
backend/docs/CSS_OPTIMIERUNGEN.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
1
backend/docs/KIOSK_OPTIMIERUNG.md
Normal file
1
backend/docs/KIOSK_OPTIMIERUNG.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
1
backend/docs/OPTIMIERUNG_ZUSAMMENFASSUNG.md
Normal file
1
backend/docs/OPTIMIERUNG_ZUSAMMENFASSUNG.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
1
backend/docs/ROADMAP_UPDATE_KIOSK.md
Normal file
1
backend/docs/ROADMAP_UPDATE_KIOSK.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
@ -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
|
||||||
|
@ -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}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 - ==================================================
|
||||||
|
@ -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
|
||||||
|
148
backend/performance-report.txt
Normal file
148
backend/performance-report.txt
Normal 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
|
BIN
backend/static/css/app-bundle.min.css.gz
Normal file
BIN
backend/static/css/app-bundle.min.css.gz
Normal file
Binary file not shown.
31
backend/static/css/build/critical.css
Normal file
31
backend/static/css/build/critical.css
Normal 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}}
|
498
backend/static/css/build/kiosk-1656af86.css
Normal file
498
backend/static/css/build/kiosk-1656af86.css
Normal 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; }
|
||||||
|
}
|
497
backend/static/css/build/kiosk-no-fa.css
Normal file
497
backend/static/css/build/kiosk-no-fa.css
Normal 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; }
|
||||||
|
}
|
498
backend/static/css/build/kiosk-production.css
Normal file
498
backend/static/css/build/kiosk-production.css
Normal 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; }
|
||||||
|
}
|
288
backend/static/css/caching-optimizations.css
Normal file
288
backend/static/css/caching-optimizations.css
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
BIN
backend/static/css/caching-optimizations.css.gz
Normal file
BIN
backend/static/css/caching-optimizations.css.gz
Normal file
Binary file not shown.
1
backend/static/css/caching-optimizations.min.css
vendored
Normal file
1
backend/static/css/caching-optimizations.min.css
vendored
Normal 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}}
|
BIN
backend/static/css/caching-optimizations.min.css.gz
Normal file
BIN
backend/static/css/caching-optimizations.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/css/components.css.gz
Normal file
BIN
backend/static/css/components.css.gz
Normal file
Binary file not shown.
1
backend/static/css/components.min.css
vendored
Normal file
1
backend/static/css/components.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/static/css/components.min.css.gz
Normal file
BIN
backend/static/css/components.min.css.gz
Normal file
Binary file not shown.
31
backend/static/css/critical-inline.css
Normal file
31
backend/static/css/critical-inline.css
Normal 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}}
|
BIN
backend/static/css/critical-inline.css.gz
Normal file
BIN
backend/static/css/critical-inline.css.gz
Normal file
Binary file not shown.
1
backend/static/css/critical-inline.min.css
vendored
Normal file
1
backend/static/css/critical-inline.min.css
vendored
Normal 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}}
|
BIN
backend/static/css/critical-inline.min.css.gz
Normal file
BIN
backend/static/css/critical-inline.min.css.gz
Normal file
Binary file not shown.
@ -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-subtle,
|
||||||
|
.glass-card,
|
||||||
.glass-btn,
|
.glass-btn,
|
||||||
.glass-card {
|
.glass-modal {
|
||||||
transition: none !important;
|
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));
|
|
||||||
}
|
}
|
BIN
backend/static/css/glassmorphism.css.gz
Normal file
BIN
backend/static/css/glassmorphism.css.gz
Normal file
Binary file not shown.
1
backend/static/css/glassmorphism.min.css
vendored
Normal file
1
backend/static/css/glassmorphism.min.css
vendored
Normal 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}
|
BIN
backend/static/css/glassmorphism.min.css.gz
Normal file
BIN
backend/static/css/glassmorphism.min.css.gz
Normal file
Binary file not shown.
148
backend/static/css/icons-minimal.css
Normal file
148
backend/static/css/icons-minimal.css
Normal 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; }
|
||||||
|
}
|
BIN
backend/static/css/input.css.gz
Normal file
BIN
backend/static/css/input.css.gz
Normal file
Binary file not shown.
1
backend/static/css/input.min.css
vendored
Normal file
1
backend/static/css/input.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/static/css/input.min.css.gz
Normal file
BIN
backend/static/css/input.min.css.gz
Normal file
Binary file not shown.
346
backend/static/css/kiosk-optimized.css
Normal file
346
backend/static/css/kiosk-optimized.css
Normal 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;
|
||||||
|
}
|
@ -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;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== ZUSÄTZLICHE UTILITY CLASSES ===== */
|
.animate-hover-lift:hover {
|
||||||
.animate-shake {
|
transform: none;
|
||||||
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%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ===== 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
BIN
backend/static/css/optimization-animations.css.gz
Normal file
BIN
backend/static/css/optimization-animations.css.gz
Normal file
Binary file not shown.
1
backend/static/css/optimization-animations.min.css
vendored
Normal file
1
backend/static/css/optimization-animations.min.css
vendored
Normal 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}}
|
BIN
backend/static/css/optimization-animations.min.css.gz
Normal file
BIN
backend/static/css/optimization-animations.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/css/output.css.gz
Normal file
BIN
backend/static/css/output.css.gz
Normal file
Binary file not shown.
1
backend/static/css/output.min.css
vendored
Normal file
1
backend/static/css/output.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/static/css/output.min.css.gz
Normal file
BIN
backend/static/css/output.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/css/printers.css.gz
Normal file
BIN
backend/static/css/printers.css.gz
Normal file
Binary file not shown.
1
backend/static/css/printers.min.css
vendored
Normal file
1
backend/static/css/printers.min.css
vendored
Normal 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}}
|
BIN
backend/static/css/printers.min.css.gz
Normal file
BIN
backend/static/css/printers.min.css.gz
Normal file
Binary file not shown.
@ -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;
|
||||||
}
|
}
|
||||||
|
BIN
backend/static/css/professional-theme.css.gz
Normal file
BIN
backend/static/css/professional-theme.css.gz
Normal file
Binary file not shown.
1
backend/static/css/professional-theme.min.css
vendored
Normal file
1
backend/static/css/professional-theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
backend/static/css/professional-theme.min.css.gz
Normal file
BIN
backend/static/css/professional-theme.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/css/tailwind.min.css.gz
Normal file
BIN
backend/static/css/tailwind.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/all.css.gz
Normal file
BIN
backend/static/fontawesome/css/all.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/all.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/all.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/brands.css.gz
Normal file
BIN
backend/static/fontawesome/css/brands.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/brands.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/brands.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/fontawesome.css.gz
Normal file
BIN
backend/static/fontawesome/css/fontawesome.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/fontawesome.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/fontawesome.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/regular.css.gz
Normal file
BIN
backend/static/fontawesome/css/regular.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/regular.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/regular.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/solid.css.gz
Normal file
BIN
backend/static/fontawesome/css/solid.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/solid.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/solid.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/svg-with-js.css.gz
Normal file
BIN
backend/static/fontawesome/css/svg-with-js.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/svg-with-js.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/svg-with-js.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v4-font-face.css.gz
Normal file
BIN
backend/static/fontawesome/css/v4-font-face.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v4-font-face.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/v4-font-face.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v4-shims.css.gz
Normal file
BIN
backend/static/fontawesome/css/v4-shims.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v4-shims.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/v4-shims.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v5-font-face.css.gz
Normal file
BIN
backend/static/fontawesome/css/v5-font-face.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/css/v5-font-face.min.css.gz
Normal file
BIN
backend/static/fontawesome/css/v5-font-face.min.css.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/all.js.gz
Normal file
BIN
backend/static/fontawesome/js/all.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/all.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/all.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/brands.js.gz
Normal file
BIN
backend/static/fontawesome/js/brands.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/brands.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/brands.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/conflict-detection.js.gz
Normal file
BIN
backend/static/fontawesome/js/conflict-detection.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/conflict-detection.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/conflict-detection.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/fontawesome.js.gz
Normal file
BIN
backend/static/fontawesome/js/fontawesome.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/fontawesome.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/fontawesome.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/regular.js.gz
Normal file
BIN
backend/static/fontawesome/js/regular.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/regular.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/regular.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/solid.js.gz
Normal file
BIN
backend/static/fontawesome/js/solid.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/solid.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/solid.min.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/v4-shims.js.gz
Normal file
BIN
backend/static/fontawesome/js/v4-shims.js.gz
Normal file
Binary file not shown.
BIN
backend/static/fontawesome/js/v4-shims.min.js.gz
Normal file
BIN
backend/static/fontawesome/js/v4-shims.min.js.gz
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user