🌟 🎉 Major Update:
This commit is contained in:
@@ -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
|
||||
|
||||
### MYP Control Center (Empfohlen)
|
||||
|
||||
Das zentrale Installationssystem für alle Komponenten:
|
||||
|
||||
### Backend-System (Hardware & APIs)
|
||||
```bash
|
||||
# Repository klonen
|
||||
git clone <repository-url>
|
||||
cd Projektarbeit-MYP
|
||||
# Backend-Server starten (Till Tomczaks System)
|
||||
cd backend
|
||||
sudo ./setup.sh # Automatische Installation
|
||||
python app.py # Oder für Development
|
||||
|
||||
# MYP Control Center starten
|
||||
./myp_installer.sh
|
||||
# Kiosk-Modus auf Raspberry Pi
|
||||
sudo systemctl start myp-https.service
|
||||
```
|
||||
|
||||
Das MYP Control Center bietet:
|
||||
- **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
|
||||
### Frontend-System (Web-Interface)
|
||||
```bash
|
||||
# Frontend-Server starten (Torben Haacks System)
|
||||
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
|
||||
# Backend starten
|
||||
cd backend/app && python app.py
|
||||
# Backend (API-Server)
|
||||
cd backend && python app.py --host 0.0.0.0 --port 5000 &
|
||||
|
||||
# Kiosk-Browser starten (separates Terminal)
|
||||
./backend/app/start_kiosk.sh
|
||||
# Frontend (Web-Interface)
|
||||
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/
|
||||
├── myp_installer.sh # 🎯 HAUPT-INSTALLER (Control Center)
|
||||
├── backend/
|
||||
│ ├── app/
|
||||
│ │ ├── certs/ # TLS-Zertifikate
|
||||
│ │ ├── database/ # SQLite-Datenbank
|
||||
│ │ ├── logs/ # Anwendungslogs
|
||||
│ │ └── app.py # Hauptanwendung
|
||||
│ ├── myp.service # systemd Service
|
||||
│ ├── requirements.txt # Python-Abhängigkeiten
|
||||
│ └── legacy_setup_raspberry_pi.sh # Legacy Skript
|
||||
├── frontend/
|
||||
│ ├── certs/ # TLS-Zertifikate
|
||||
│ ├── docker/
|
||||
│ │ ├── caddy/
|
||||
│ │ │ └── Caddyfile # Reverse Proxy Konfiguration
|
||||
│ │ └── legacy_deploy.sh # Legacy Skript
|
||||
│ ├── src/ # Next.js Anwendung
|
||||
│ └── docker-compose.yml
|
||||
├── scripts/
|
||||
│ └── legacy_generate_certs.sh # Legacy Skript
|
||||
├── archiv/
|
||||
│ └── myp_installer_legacy.sh # Archivierte Version
|
||||
└── docs/ # Dokumentation
|
||||
├── backend/ # 🏗️ KERN-INFRASTRUKTUR (Till Tomczak)
|
||||
│ ├── app.py # Flask REST-API Server
|
||||
│ ├── models.py # SQLite-Datenbank & Business Logic
|
||||
│ ├── utils/ # Smart-Plug Integration (TP-Link Tapo P110)
|
||||
│ ├── templates/ # Kiosk-Mode Web-Interface
|
||||
│ ├── static/ # PWA-Assets für Offline-Betrieb
|
||||
│ └── systemd/ # Raspberry Pi Service-Integration
|
||||
├──
|
||||
├── frontend/ # 📊 WEB-INTERFACE (Torben Haack)
|
||||
│ ├── src/app/ # Next.js Haupt-Anwendung
|
||||
│ ├── src/components/ # React UI-Komponenten
|
||||
│ ├── src/lib/api/ # Backend-REST-API-Integration
|
||||
│ └── src/lib/analytics/ # Statistik-Algorithmen
|
||||
├──
|
||||
├── docs/ # 📚 Gemeinsame Dokumentation
|
||||
└── README.md # Diese Datei
|
||||
```
|
||||
|
||||
### Script-Status
|
||||
## 🎯 Funktions-Aufgabenteilung
|
||||
|
||||
| Skript | Status | Verwendung |
|
||||
|--------|--------|------------|
|
||||
| `myp_installer.sh` | ✅ **AKTIV** | Haupt-Control-Center |
|
||||
| `*legacy_*.sh` | 📦 Legacy | Historische Versionen |
|
||||
| `archiv/myp_installer_legacy.sh` | 📦 Archiv | Alte Version 4.0 |
|
||||
### Backend-Verantwortlichkeiten (Till Tomczak)
|
||||
- ✅ **Smart-Plug-Steuerung**: TP-Link Tapo P110 WLAN-Steckdosen
|
||||
- ✅ **Automatische Drucker-Schaltung**: Zeitgesteuerte Ein-/Ausschaltung
|
||||
- ✅ **REST-API-Bereitstellung**: Vollständige API für alle Drucker-Operationen
|
||||
- ✅ **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)
|
||||
- Selbstsignierte TLS-Zertifikate
|
||||
- HTTP → HTTPS Redirect
|
||||
- Security Headers (HSTS, CSP, etc.)
|
||||
## 🔗 API-Integration & Kommunikation
|
||||
|
||||
## 📝 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
|
||||
# systemd Journal
|
||||
sudo journalctl -u myp.service -f
|
||||
# Backend-Server (z.B. Raspberry Pi oder Linux-Server)
|
||||
cd backend
|
||||
sudo systemctl start myp-https.service
|
||||
|
||||
# Anwendungslogs
|
||||
tail -f backend/app/logs/app/app.log
|
||||
# Frontend-Server (z.B. Node.js-Server oder Cloud-Deployment)
|
||||
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
|
||||
# Docker Logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Caddy Logs
|
||||
docker-compose logs caddy
|
||||
# Vollständige Kiosk-Installation
|
||||
cd backend && sudo ./setup.sh
|
||||
# Automatischer Start: Touch-Interface + Smart-Plug-Steuerung
|
||||
```
|
||||
|
||||
### 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
|
||||
# Backend Service
|
||||
sudo systemctl status myp.service
|
||||
|
||||
# Kiosk-Browser Service
|
||||
sudo systemctl status myp-kiosk-browser.service
|
||||
|
||||
# Kiosk-Browser Logs
|
||||
sudo journalctl -u myp-kiosk-browser.service -f
|
||||
cd backend
|
||||
python -m venv venv
|
||||
source venv/bin/activate # Linux/Mac
|
||||
pip install -r requirements.txt
|
||||
python app.py --debug
|
||||
```
|
||||
|
||||
## 🔧 Services
|
||||
|
||||
### Backend Services
|
||||
### Frontend-Entwicklung (Torben Haack)
|
||||
```bash
|
||||
# Backend starten/stoppen
|
||||
sudo systemctl start myp.service
|
||||
sudo systemctl stop myp.service
|
||||
sudo systemctl restart myp.service
|
||||
|
||||
# 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
|
||||
cd frontend
|
||||
pnpm install
|
||||
pnpm db:migrate
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## 🆘 Troubleshooting
|
||||
|
||||
### MYP Control Center verwenden
|
||||
### Integration testen
|
||||
```bash
|
||||
./myp_installer.sh
|
||||
# → Option 6: Systemvoraussetzungen prüfen
|
||||
# → Option 7: Anwendung starten
|
||||
# Backend-APIs testen
|
||||
curl http://localhost:5000/api/printers
|
||||
|
||||
# Frontend mit Backend-Integration
|
||||
# Frontend auf :3000 konsumiert Backend-APIs von :5000
|
||||
```
|
||||
|
||||
### Backend startet nicht
|
||||
```bash
|
||||
# Service Status prüfen
|
||||
sudo systemctl status myp.service
|
||||
## 📚 Dokumentation
|
||||
|
||||
# Logs prüfen
|
||||
sudo journalctl -u myp.service --no-pager
|
||||
### Backend-Dokumentation (Till Tomczak)
|
||||
- [`backend/README.md`](backend/README.md) - Hardware-Setup & API-Dokumentation
|
||||
- [`backend/docs/`](backend/docs/) - Raspberry Pi Konfiguration & Smart-Plug-Integration
|
||||
|
||||
# Zertifikate prüfen
|
||||
ls -la backend/app/certs/
|
||||
```
|
||||
### Frontend-Dokumentation (Torben Haack)
|
||||
- [`frontend/README.md`](frontend/README.md) - UI-Entwicklung & Analytics
|
||||
- [`frontend/docs/`](frontend/docs/) - Component-Library & PWA-Features
|
||||
|
||||
### Frontend nicht erreichbar
|
||||
```bash
|
||||
# Container Status prüfen
|
||||
docker-compose ps
|
||||
### Gemeinsame Dokumentation
|
||||
- [`docs/myp_documentation.md`](docs/myp_documentation.md) - Vollständige Projektdokumentation
|
||||
- [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) - Production-Deployment-Guide
|
||||
|
||||
# Netzwerk prüfen
|
||||
docker network ls
|
||||
## 🤝 Projektphilosophie
|
||||
|
||||
# Zertifikate prüfen
|
||||
ls -la frontend/certs/
|
||||
```
|
||||
### Cyber-Physische Vernetzung
|
||||
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
|
||||
```bash
|
||||
# DNS auflösen
|
||||
nslookup raspberrypi
|
||||
nslookup m040tbaraspi001.de040.corpintra.net
|
||||
### Komplementäre Expertisen
|
||||
- **Till Tomczak**: Spezialist für Hardware-Integration und cyber-physische Vernetzung
|
||||
- **Torben Haack**: Spezialist für Frontend-Entwicklung und Datenanalyse
|
||||
|
||||
# Ports prüfen
|
||||
netstat -tlnp | grep :443
|
||||
```
|
||||
### Gemeinsame Ziele
|
||||
- **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
|
||||
- **Control Center**: v4.0 mit v3.2 Integration
|
||||
- **Build**: Production
|
||||
- **Installer**: MYP Control Center
|
||||
### Till Tomczak - **Backend-Infrastruktur & Hardware-Integration**
|
||||
- **Cyber-Physische Systeme**: Smart-Plug-Integration und Hardware-Steuerung
|
||||
- **System-Architektur**: Flask-APIs und SQLite-Datenbank-Design
|
||||
- **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
|
||||
|
||||
| Server | Hostname | Komponenten | URL |
|
||||
|--------|----------|-------------|-----|
|
||||
| **Frontend-Server** | `m040tbaraspi001.de040.corpintra.net` | Next.js + Docker + Caddy | `https://m040tbaraspi001.de040.corpintra.net` |
|
||||
| **Backend-Server** | `raspberrypi` | Flask API + Web Interface + Kiosk | `https://raspberrypi` |
|
||||
|
||||
### 🚀 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
|
||||
```
|
||||
**Backend-System**: Till Tomczak (Cyber-Physische Vernetzung & Hardware-Integration)
|
||||
**Frontend-System**: Torben Haack (Progressive Web App & Analytics)
|
||||
**Architektur**: Microservices mit REST-API-Integration
|
||||
**Technologie**: Flask + SQLite (Backend) + Next.js + React (Frontend)
|
||||
**Hardware**: Raspberry Pi + TP-Link Tapo P110 Smart-Plugs
|
||||
**Entwickelt für**: Mercedes-Benz Werk 040 Berlin MYP
|
||||
|
||||
|
||||
Binary file not shown.
@@ -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
|
||||
@@ -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.
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -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:56 - [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 - 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 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: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 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 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 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 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 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: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 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: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 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 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 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: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: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: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 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: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 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 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 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:57 - [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: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 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-sichere Log-Rotation: Aktiviert
|
||||
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 - ✅ Globaler subprocess-Patch 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
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
|
||||
MYP Platform - Performance Optimization Report
|
||||
==============================================
|
||||
|
||||
CSS-Dateien (39):
|
||||
- all.css: 106,394 Bytes
|
||||
- all.min.css: 73,890 Bytes
|
||||
- app-bundle.min.css: 8,714 Bytes
|
||||
- brands.css: 19,852 Bytes
|
||||
- brands.min.css: 14,574 Bytes
|
||||
- caching-optimizations.css: 5,613 Bytes
|
||||
- caching-optimizations.min.css: 3,565 Bytes
|
||||
- components.css: 17,232 Bytes
|
||||
- components.min.css: 13,062 Bytes
|
||||
- critical-inline.css: 1,473 Bytes
|
||||
- critical-inline.min.css: 1,399 Bytes
|
||||
- fontawesome.css: 83,677 Bytes
|
||||
- fontawesome.min.css: 56,777 Bytes
|
||||
- glassmorphism.css: 6,211 Bytes
|
||||
- glassmorphism.min.css: 4,715 Bytes
|
||||
- input.css: 99,414 Bytes
|
||||
- input.min.css: 76,568 Bytes
|
||||
- main.min.css: 115 Bytes
|
||||
- optimization-animations.css: 2,675 Bytes
|
||||
- optimization-animations.min.css: 1,443 Bytes
|
||||
- output.css: 248,934 Bytes
|
||||
- output.min.css: 210,598 Bytes
|
||||
- printers.css: 3,952 Bytes
|
||||
- printers.min.css: 2,502 Bytes
|
||||
- professional-theme.css: 24,631 Bytes
|
||||
- professional-theme.min.css: 18,762 Bytes
|
||||
- regular.css: 633 Bytes
|
||||
- regular.min.css: 580 Bytes
|
||||
- solid.css: 625 Bytes
|
||||
- solid.min.css: 572 Bytes
|
||||
- svg-with-js.css: 12,554 Bytes
|
||||
- svg-with-js.min.css: 10,197 Bytes
|
||||
- tailwind.min.css: 221,943 Bytes
|
||||
- v4-font-face.css: 1,831 Bytes
|
||||
- v4-font-face.min.css: 1,736 Bytes
|
||||
- v4-shims.css: 38,514 Bytes
|
||||
- v4-shims.min.css: 21,211 Bytes
|
||||
- v5-font-face.css: 871 Bytes
|
||||
- v5-font-face.min.css: 794 Bytes
|
||||
|
||||
JavaScript-Dateien (84):
|
||||
- admin-guest-requests.js: 32,046 Bytes
|
||||
- admin-guest-requests.min.js: 23,162 Bytes
|
||||
- admin-panel.js: 42,961 Bytes
|
||||
- admin-panel.min.js: 27,749 Bytes
|
||||
- admin-unified.js: 56,717 Bytes
|
||||
- admin-unified.min.js: 35,087 Bytes
|
||||
- advanced-components.js: 29,859 Bytes
|
||||
- advanced-components.min.js: 16,393 Bytes
|
||||
- all.js: 1,627,440 Bytes
|
||||
- all.min.js: 1,530,755 Bytes
|
||||
- apexcharts.min.js: 524,387 Bytes
|
||||
- auto-logout.js: 4,661 Bytes
|
||||
- auto-logout.min.js: 3,099 Bytes
|
||||
- brands.js: 510,493 Bytes
|
||||
- brands.min.js: 499,125 Bytes
|
||||
- chart-adapter.js: 8,486 Bytes
|
||||
- chart-config.js: 9,767 Bytes
|
||||
- chart-renderer.js: 10,396 Bytes
|
||||
- chart.min.js: 181,743 Bytes
|
||||
- charts.js: 13,704 Bytes
|
||||
- charts.min.js: 7,671 Bytes
|
||||
- conflict-detection.js: 38,929 Bytes
|
||||
- conflict-detection.min.js: 15,853 Bytes
|
||||
- core.min.js: 181,411 Bytes
|
||||
- countdown-timer.js: 35,228 Bytes
|
||||
- countdown-timer.min.js: 19,014 Bytes
|
||||
- csp-violation-handler.js: 10,509 Bytes
|
||||
- csp-violation-handler.min.js: 6,622 Bytes
|
||||
- css-cache-manager.js: 3,454 Bytes
|
||||
- css-cache-manager.min.js: 2,471 Bytes
|
||||
- css-cache-service-worker.js: 10,648 Bytes
|
||||
- css-cache-service-worker.min.js: 6,895 Bytes
|
||||
- dark-mode-fix.js: 7,630 Bytes
|
||||
- dark-mode-fix.min.js: 4,183 Bytes
|
||||
- dark-mode.js: 11,717 Bytes
|
||||
- dark-mode.min.js: 7,659 Bytes
|
||||
- dashboard.js: 11,344 Bytes
|
||||
- dashboard.min.js: 8,164 Bytes
|
||||
- daygrid.min.js: 26,955 Bytes
|
||||
- debug-fix.js: 7,419 Bytes
|
||||
- debug-fix.min.js: 4,146 Bytes
|
||||
- event-handlers.js: 16,020 Bytes
|
||||
- event-handlers.min.js: 8,399 Bytes
|
||||
- fontawesome.js: 106,548 Bytes
|
||||
- fontawesome.min.js: 49,856 Bytes
|
||||
- glassmorphism-notifications.js: 62,643 Bytes
|
||||
- glassmorphism-notifications.min.js: 35,476 Bytes
|
||||
- global-refresh-functions.js: 26,547 Bytes
|
||||
- global-refresh-functions.min.js: 14,785 Bytes
|
||||
- interaction.min.js: 35,636 Bytes
|
||||
- job-manager.js: 31,172 Bytes
|
||||
- job-manager.min.js: 16,598 Bytes
|
||||
- jobs-safety-fix.js: 10,729 Bytes
|
||||
- jobs-safety-fix.min.js: 5,270 Bytes
|
||||
- list.min.js: 9,361 Bytes
|
||||
- notifications.js: 26,568 Bytes
|
||||
- notifications.min.js: 16,192 Bytes
|
||||
- offline-app.js: 20,435 Bytes
|
||||
- offline-app.min.js: 10,758 Bytes
|
||||
- optimization-features.js: 33,307 Bytes
|
||||
- optimization-features.min.js: 19,873 Bytes
|
||||
- performance-service-worker.js: 10,657 Bytes
|
||||
- performance-service-worker.min.js: 7,730 Bytes
|
||||
- printer_monitor.js: 15,887 Bytes
|
||||
- printer_monitor.min.js: 7,574 Bytes
|
||||
- regular.js: 126,991 Bytes
|
||||
- regular.min.js: 119,408 Bytes
|
||||
- service-worker.js: 2,205 Bytes
|
||||
- service-worker.min.js: 1,361 Bytes
|
||||
- session-manager.js: 19,582 Bytes
|
||||
- session-manager.min.js: 10,369 Bytes
|
||||
- solid.js: 884,065 Bytes
|
||||
- solid.min.js: 863,023 Bytes
|
||||
- sw.js: 12,735 Bytes
|
||||
- sw.min.js: 7,745 Bytes
|
||||
- timegrid.min.js: 31,540 Bytes
|
||||
- ui-components.js: 711 Bytes
|
||||
- ui-components.min.js: 305 Bytes
|
||||
- user-dropdown.js: 1 Bytes
|
||||
- user-dropdown.min.js: 0 Bytes
|
||||
- v4-shims.js: 35,459 Bytes
|
||||
- v4-shims.min.js: 28,077 Bytes
|
||||
- validation-fix.js: 9,064 Bytes
|
||||
- validation-fix.min.js: 5,182 Bytes
|
||||
|
||||
Bilder (0):
|
||||
|
||||
|
||||
Optimierungen durchgeführt:
|
||||
✅ CSS-Minifizierung
|
||||
✅ JavaScript-Minifizierung
|
||||
✅ Gzip-Komprimierung
|
||||
✅ WebP-Bildkonvertierung
|
||||
✅ Critical CSS
|
||||
✅ Service Worker
|
||||
✅ PWA-Manifest
|
||||
|
||||
Empfohlene nächste Schritte:
|
||||
1. Performance-optimiertes Template verwenden
|
||||
2. Service Worker aktivieren
|
||||
3. HTTP/2 Push für kritische Assets
|
||||
4. CDN für statische Assets konfigurieren
|
||||
Binary file not shown.
@@ -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}}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
/**
|
||||
* MYP Platform - CSS Caching-Optimierungen
|
||||
* Performance-optimierte Styles für besseres Caching und schnellere Ladezeiten
|
||||
*/
|
||||
|
||||
/* ===== KRITISCHE ABOVE-THE-FOLD STYLES ===== */
|
||||
/* Diese Styles sollten inline im HTML-Head geladen werden */
|
||||
.critical-header {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(8px);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.critical-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.critical-logo {
|
||||
font-weight: 700;
|
||||
font-size: 1.25rem;
|
||||
color: #0073ce;
|
||||
}
|
||||
|
||||
.critical-main {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(135deg, #fafbfc 0%, #f5f7f9 100%);
|
||||
}
|
||||
|
||||
/* ===== LAZY LOADING PLACEHOLDER ===== */
|
||||
.lazy-placeholder {
|
||||
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||
background-size: 200% 100%;
|
||||
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@keyframes skeleton-loading {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -200% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .lazy-placeholder {
|
||||
background: linear-gradient(90deg, #374151 25%, #4b5563 50%, #374151 75%);
|
||||
background-size: 200% 100%;
|
||||
}
|
||||
|
||||
/* ===== PRELOAD HINTS ===== */
|
||||
.preload-image {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: 300px 200px;
|
||||
}
|
||||
|
||||
.preload-component {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: 100px;
|
||||
}
|
||||
|
||||
/* ===== CACHE-OPTIMIERTE KOMPONENTEN ===== */
|
||||
.cache-card {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(229, 231, 235, 0.5);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
transition: transform 0.2s ease;
|
||||
contain: layout style paint;
|
||||
}
|
||||
|
||||
.cache-card:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.cache-button {
|
||||
background: #0073ce;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 0.5rem 1rem;
|
||||
font-weight: 600;
|
||||
transition: background-color 0.2s ease;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.cache-button:hover {
|
||||
background: #005a9f;
|
||||
}
|
||||
|
||||
.cache-input {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(229, 231, 235, 0.8);
|
||||
border-radius: 4px;
|
||||
padding: 0.5rem;
|
||||
transition: border-color 0.2s ease;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.cache-input:focus {
|
||||
outline: none;
|
||||
border-color: #0073ce;
|
||||
box-shadow: 0 0 0 2px rgba(0, 115, 206, 0.1);
|
||||
}
|
||||
|
||||
/* ===== LAYOUT SHIFT PREVENTION ===== */
|
||||
.prevent-cls {
|
||||
min-height: 200px; /* Prevent layout shift */
|
||||
contain: layout;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
aspect-ratio: 16/9;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
background: #f3f4f6;
|
||||
}
|
||||
|
||||
.image-container img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.image-container img[loading="lazy"] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.image-container img[loading="lazy"].loaded {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ===== OPTIMIERTE TYPOGRAPHY ===== */
|
||||
.text-heading {
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
color: #111827;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.text-body {
|
||||
line-height: 1.6;
|
||||
color: #374151;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #6b7280;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
/* ===== DARK MODE CACHE OPTIMIZATIONS ===== */
|
||||
.dark .cache-card {
|
||||
background: rgba(30, 41, 59, 0.9);
|
||||
border-color: rgba(100, 116, 139, 0.3);
|
||||
}
|
||||
|
||||
.dark .cache-input {
|
||||
background: rgba(30, 41, 59, 0.9);
|
||||
border-color: rgba(100, 116, 139, 0.5);
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.dark .text-heading {
|
||||
color: #f8fafc;
|
||||
}
|
||||
|
||||
.dark .text-body {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.dark .text-muted {
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
.dark .image-container {
|
||||
background: #374151;
|
||||
}
|
||||
|
||||
/* ===== RESPONSIVE OPTIMIZATIONS ===== */
|
||||
@media (max-width: 768px) {
|
||||
.critical-nav {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.cache-card {
|
||||
padding: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.cache-button {
|
||||
padding: 0.75rem 1.25rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== PRINT OPTIMIZATIONS ===== */
|
||||
@media print {
|
||||
.critical-header,
|
||||
.cache-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cache-card {
|
||||
box-shadow: none;
|
||||
border: 1px solid #000;
|
||||
break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== GPU ACCELERATION HINTS ===== */
|
||||
.gpu-accelerated {
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
/* ===== EFFICIENT ANIMATIONS ===== */
|
||||
.fade-in-optimized {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-in-optimized.visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ===== CONTAINER QUERIES SUPPORT ===== */
|
||||
@container (min-width: 300px) {
|
||||
.cache-card {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== CONTENT VISIBILITY OPTIMIZATIONS ===== */
|
||||
.auto-height {
|
||||
content-visibility: auto;
|
||||
contain-intrinsic-size: 0 200px;
|
||||
}
|
||||
|
||||
.hidden-content {
|
||||
content-visibility: hidden;
|
||||
}
|
||||
|
||||
/* ===== REDUCED MOTION PREFERENCES ===== */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.fade-in-optimized,
|
||||
.cache-card,
|
||||
.cache-button,
|
||||
.cache-input {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.lazy-placeholder {
|
||||
animation: none !important;
|
||||
background: #f0f0f0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== HIGH CONTRAST MODE ===== */
|
||||
@media (prefers-contrast: high) {
|
||||
.cache-card {
|
||||
border-width: 2px;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.cache-button {
|
||||
border: 2px solid #000;
|
||||
}
|
||||
|
||||
.cache-input {
|
||||
border-width: 2px;
|
||||
border-color: #000;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
.critical-header{background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);position:sticky;top:0;z-index:1000;box-shadow:0 2px 8px rgba(0,0,0,0.06)}.critical-nav{display:flex;align-items:center;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce}.critical-main{min-height:100vh;background:linear-gradient(135deg,#fafbfc 0,#f5f7f9 100%)}.lazy-placeholder{background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:skeleton-loading 1.5s infinite ease-in-out;border-radius:4px}@keyframes skeleton-loading{0%{background-position:200% 0}100%{background-position:-200% 0}}.dark .lazy-placeholder{background:linear-gradient(90deg,#374151 25%,#4b5563 50%,#374151 75%);background-size:200% 100%}.preload-image{content-visibility:auto;contain-intrinsic-size:300px 200px}.preload-component{content-visibility:auto;contain-intrinsic-size:100px}.cache-card{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.5);border-radius:8px;padding:1rem;margin-bottom:1rem;transition:transform .2s ease;contain:layout style paint}.cache-card:hover{transform:translateY(-1px)}.cache-button{background:#0073ce;color:white;border:0;border-radius:6px;padding:.5rem 1rem;font-weight:600;transition:background-color .2s ease;contain:layout style}.cache-button:hover{background:#005a9f}.cache-input{background:rgba(255,255,255,0.9);border:1px solid rgba(229,231,235,0.8);border-radius:4px;padding:.5rem;transition:border-color .2s ease;contain:layout style}.cache-input:focus{outline:0;border-color:#0073ce;box-shadow:0 0 0 2px rgba(0,115,206,0.1)}.prevent-cls{min-height:200px;contain:layout}.image-container{aspect-ratio:16/9;overflow:hidden;border-radius:8px;background:#f3f4f6}.image-container img{width:100%;height:100%;object-fit:cover;transition:opacity .3s ease}.image-container img[loading="lazy"]{opacity:0}.image-container img[loading="lazy"].loaded{opacity:1}.text-heading{font-weight:700;line-height:1.2;color:#111827;contain:layout style}.text-body{line-height:1.6;color:#374151;contain:layout style}.text-muted{color:#6b7280;contain:layout style}.dark .cache-card{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.3)}.dark .cache-input{background:rgba(30,41,59,0.9);border-color:rgba(100,116,139,0.5);color:#e2e8f0}.dark .text-heading{color:#f8fafc}.dark .text-body{color:#e2e8f0}.dark .text-muted{color:#94a3b8}.dark .image-container{background:#374151}@media(max-width:768px){.critical-nav{padding:.75rem}.cache-card{padding:.75rem;margin-bottom:.75rem}.cache-button{padding:.75rem 1.25rem;font-size:.875rem}}@media print{.critical-header,.cache-button{display:none}.cache-card{box-shadow:none;border:1px solid #000;break-inside:avoid}}.gpu-accelerated{transform:translateZ(0);will-change:transform}.fade-in-optimized{opacity:0;transform:translateY(10px);transition:opacity .3s ease,transform .3s ease}.fade-in-optimized.visible{opacity:1;transform:translateY(0)}@container(min-width:300px){.cache-card{display:grid;grid-template-columns:1fr auto;gap:1rem;align-items:center}}.auto-height{content-visibility:auto;contain-intrinsic-size:0 200px}.hidden-content{content-visibility:hidden}@media(prefers-reduced-motion:reduce){.fade-in-optimized,.cache-card,.cache-button,.cache-input{transition:none !important}.lazy-placeholder{animation:none !important;background:#f0f0f0 !important}}@media(prefers-contrast:high){.cache-card{border-width:2px;border-color:#000}.cache-button{border:2px solid #000}.cache-input{border-width:2px;border-color:#000}}
|
||||
Binary file not shown.
Binary file not shown.
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
/* CRITICAL INLINE CSS - Sollte im HTML <head> stehen */
|
||||
/* Nur die absolut notwendigen Styles für First Paint */
|
||||
|
||||
:root{--primary:#0073ce;--bg:#fafbfc;--surface:#fff;--text:#111827;--border:#e5e7eb;--shadow:0 2px 4px rgba(0,0,0,.05)}
|
||||
*{box-sizing:border-box;margin:0;padding:0;contain:layout style}
|
||||
body{font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);line-height:1.5;text-rendering:optimizeSpeed;-webkit-font-smoothing:antialiased}
|
||||
.header{background:var(--surface);border-bottom:1px solid var(--border);padding:1rem;position:sticky;top:0;z-index:1000}
|
||||
.nav{display:flex;gap:1rem}
|
||||
.nav-item{padding:.5rem 1rem;border-radius:6px;text-decoration:none;color:#6b7280;transition:background .1s}
|
||||
.nav-item:hover{background:var(--bg);color:var(--text)}
|
||||
.nav-item.active{background:var(--primary);color:#fff}
|
||||
.container{max-width:1200px;margin:0 auto;padding:0 1rem}
|
||||
.btn{background:var(--primary);color:#fff;border:none;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;transition:background .1s}
|
||||
.btn:hover{background:#005a9f}
|
||||
.card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:1rem;box-shadow:var(--shadow)}
|
||||
.flex{display:flex}
|
||||
.grid{display:grid;gap:1rem}
|
||||
.hidden{display:none}
|
||||
.w-full{width:100%}
|
||||
.text-center{text-align:center}
|
||||
.p-4{padding:1rem}
|
||||
.mb-4{margin-bottom:1rem}
|
||||
.status{display:inline-block;padding:.25rem .75rem;border-radius:999px;font-size:.75rem;font-weight:600;text-transform:uppercase}
|
||||
.status-online{background:#d1fae5;color:#065f46}
|
||||
.status-offline{background:#fee2e2;color:#991b1b}
|
||||
.status-printing{background:#dbeafe;color:#1e40af}
|
||||
.input{background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:.75rem;width:100%}
|
||||
.input:focus{outline:none;border-color:var(--primary)}
|
||||
@media (prefers-color-scheme:dark){:root{--bg:#1e293b;--surface:#334155;--text:#f8fafc;--border:#475569;--shadow:0 2px 4px rgba(0,0,0,.3)}}
|
||||
@media (max-width:768px){.nav{flex-direction:column;gap:.5rem}}
|
||||
@media (prefers-reduced-motion:reduce){*{transition:none!important}}
|
||||
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
*,*::before,*::after{box-sizing:border-box}body{margin:0;font-family:system-ui,-apple-system,sans-serif;line-height:1.6;color:#111827;background:#fafbfc}.critical-header{position:sticky;top:0;z-index:1000;background:rgba(255,255,255,0.95);backdrop-filter:blur(8px);border-bottom:1px solid #e5e7eb}.critical-nav{display:flex;align-items:center;justify-content:space-between;padding:1rem;max-width:1200px;margin:0 auto}.critical-logo{font-weight:700;font-size:1.25rem;color:#0073ce;text-decoration:none}.critical-main{min-height:100vh;padding:2rem 1rem}.critical-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1.5rem;max-width:1200px;margin:0 auto}.critical-card{background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:1.5rem;box-shadow:0 1px 3px rgba(0,0,0,0.1)}.btn-primary{background:#0073ce;color:#fff;border:0;border-radius:6px;padding:.75rem 1.5rem;font-weight:600;cursor:pointer;text-decoration:none;display:inline-block}.loading{opacity:.6;pointer-events:none}.hidden{display:none}@media(max-width:768px){.critical-nav{padding:.75rem}.critical-main{padding:1rem}.critical-grid{grid-template-columns:1fr}.critical-card{padding:1rem}}@media(prefers-color-scheme:dark){body{background:#0f172a;color:#f8fafc}.critical-header{background:rgba(15,23,42,0.95);border-bottom-color:#334155}.critical-card{background:#1e293b;border-color:#334155;color:#f8fafc}}
|
||||
Binary file not shown.
@@ -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 {
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.12),
|
||||
0 8px 16px rgba(0, 0, 0, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
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 0.2s ease;
|
||||
}
|
||||
|
||||
.glass-strong {
|
||||
backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
-webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
box-shadow:
|
||||
0 35px 70px rgba(0, 0, 0, 0.15),
|
||||
0 12px 24px rgba(0, 0, 0, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
||||
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 {
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
box-shadow:
|
||||
0 15px 35px rgba(0, 0, 0, 0.08),
|
||||
0 4px 8px rgba(0, 0, 0, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Light Mode Glass */
|
||||
.glass-light {
|
||||
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 {
|
||||
/* ===== DARK MODE GLASS ===== */
|
||||
.dark .glass-base {
|
||||
background: rgba(15, 23, 42, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow:
|
||||
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);
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.glass-dark-strong {
|
||||
.dark .glass-strong {
|
||||
background: rgba(30, 41, 59, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow:
|
||||
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);
|
||||
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* Interactive Glass Elements */
|
||||
.glass-interactive {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.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-interactive::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.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 KARTEN ===== */
|
||||
.glass-card {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.95) 0%,
|
||||
rgba(250, 251, 252, 0.9) 100%);
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
border: 1px solid rgba(229, 231, 235, 0.6);
|
||||
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);
|
||||
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: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
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%);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.glass-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
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);
|
||||
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-color: rgba(100, 116, 139, 0.4);
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
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 25px 50px rgba(0, 0, 0, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 12px 20px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.9) 0%,
|
||||
rgba(248, 250, 252, 0.8) 100%);
|
||||
backdrop-filter: blur(16px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(180%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
border-radius: 12px;
|
||||
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: 0.75rem 1.5rem;
|
||||
color: #0f172a;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
|
||||
box-shadow:
|
||||
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;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
transition: transform 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
|
||||
.glass-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.95) 0%,
|
||||
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);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.glass-btn-primary {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(0, 115, 206, 0.9) 0%,
|
||||
rgba(0, 90, 159, 0.85) 100%);
|
||||
background: rgba(0, 115, 206, 0.9);
|
||||
color: white;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
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);
|
||||
box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
|
||||
}
|
||||
|
||||
.glass-btn-primary:hover {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(0, 115, 206, 0.95) 0%,
|
||||
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);
|
||||
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-color: rgba(100, 116, 139, 0.6);
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(100, 116, 139, 0.5);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.98) 0%,
|
||||
rgba(248, 250, 252, 0.95) 50%,
|
||||
rgba(255, 255, 255, 0.98) 100%);
|
||||
backdrop-filter: blur(32px) saturate(220%) brightness(120%);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(220%) brightness(120%);
|
||||
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);
|
||||
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-color: rgba(51, 65, 85, 0.7);
|
||||
box-shadow:
|
||||
0 50px 100px rgba(0, 0, 0, 0.5),
|
||||
inset 0 2px 0 rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(51, 65, 85, 0.6);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
/* Glass Form Elements */
|
||||
/* ===== GLASS FORM ELEMENTE ===== */
|
||||
.glass-input {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(226, 232, 240, 0.5);
|
||||
border-radius: 6px;
|
||||
padding: 0.75rem 1rem;
|
||||
color: #0f172a;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.06),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.glass-input:focus {
|
||||
outline: none;
|
||||
border-color: rgba(0, 115, 206, 0.6);
|
||||
box-shadow:
|
||||
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);
|
||||
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-color: rgba(100, 116, 139, 0.6);
|
||||
border: 1px solid rgba(100, 116, 139, 0.5);
|
||||
color: #e2e8f0;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* 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 {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
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: 12px;
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.dark .glass-dropdown {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Animation for glass elements */
|
||||
@keyframes glassFloat {
|
||||
0%, 100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.glass-float {
|
||||
animation: glassFloat 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Glass overlay for backgrounds */
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.glass-overlay {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0.05) 100%);
|
||||
backdrop-filter: blur(40px) saturate(200%);
|
||||
-webkit-backdrop-filter: blur(40px) saturate(200%);
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.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) {
|
||||
.glass-card {
|
||||
padding: 1rem;
|
||||
border-radius: 12px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.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) {
|
||||
.glass-base,
|
||||
.glass-strong,
|
||||
.glass-card {
|
||||
border-width: 2px;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
backdrop-filter: blur(4px);
|
||||
-webkit-backdrop-filter: blur(4px);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reduced motion support */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.glass-interactive,
|
||||
.glass-btn,
|
||||
.glass-card {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.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));
|
||||
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
|
||||
.glass-base,
|
||||
.glass-strong,
|
||||
.glass-subtle,
|
||||
.glass-card,
|
||||
.glass-btn,
|
||||
.glass-modal {
|
||||
will-change: transform;
|
||||
}
|
||||
Binary file not shown.
+1
@@ -0,0 +1 @@
|
||||
.glass-base{background:rgba(255,255,255,0.85);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.3);box-shadow:0 8px 20px rgba(0,0,0,0.1);transition:all .2s ease}.glass-strong{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.4);box-shadow:0 12px 24px rgba(0,0,0,0.12)}.glass-subtle{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(255,255,255,0.2);box-shadow:0 4px 12px rgba(0,0,0,0.08)}.dark .glass-base{background:rgba(15,23,42,0.8);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.dark .glass-strong{background:rgba(30,41,59,0.85);border:1px solid rgba(255,255,255,0.15);box-shadow:0 12px 24px rgba(0,0,0,0.4)}.dark .glass-subtle{background:rgba(15,23,42,0.7);border:1px solid rgba(255,255,255,0.08);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-card{background:rgba(255,255,255,0.9);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border:1px solid rgba(229,231,235,0.5);border-radius:12px;box-shadow:0 8px 16px rgba(0,0,0,0.08);padding:1.5rem;transition:transform .2s ease,box-shadow .2s ease}.glass-card:hover{transform:translateY(-1px);box-shadow:0 12px 20px rgba(0,0,0,0.12)}.dark .glass-card{background:rgba(30,41,59,0.85);border:1px solid rgba(100,116,139,0.3);box-shadow:0 8px 16px rgba(0,0,0,0.25)}.dark .glass-card:hover{box-shadow:0 12px 20px rgba(0,0,0,0.35)}.glass-nav{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(226,232,240,0.4);border-bottom:1px solid rgba(203,213,225,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.06)}.dark .glass-nav{background:rgba(15,23,42,0.85);border:1px solid rgba(51,65,85,0.5);box-shadow:0 4px 12px rgba(0,0,0,0.2)}.glass-btn{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:8px;padding:.75rem 1.5rem;color:#0f172a;font-weight:600;box-shadow:0 2px 8px rgba(0,0,0,0.06);transition:transform .2s ease,background .2s ease}.glass-btn:hover{transform:translateY(-1px);background:rgba(255,255,255,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.1)}.glass-btn-primary{background:rgba(0,115,206,0.9);color:white;box-shadow:0 2px 8px rgba(0,115,206,0.2)}.glass-btn-primary:hover{background:rgba(0,115,206,0.95);box-shadow:0 4px 12px rgba(0,115,206,0.3)}.dark .glass-btn{background:rgba(30,41,59,0.8);color:#e2e8f0;border:1px solid rgba(100,116,139,0.5);box-shadow:0 2px 8px rgba(0,0,0,0.15)}.dark .glass-btn:hover{background:rgba(30,41,59,0.9);box-shadow:0 4px 12px rgba(0,0,0,0.25)}.glass-modal{background:rgba(255,255,255,0.95);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);border:1px solid rgba(226,232,240,0.6);border-radius:16px;box-shadow:0 20px 40px rgba(0,0,0,0.12)}.dark .glass-modal{background:rgba(15,23,42,0.95);border:1px solid rgba(51,65,85,0.6);box-shadow:0 20px 40px rgba(0,0,0,0.4)}.glass-input{background:rgba(255,255,255,0.8);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(226,232,240,0.5);border-radius:6px;padding:.75rem 1rem;color:#0f172a;box-shadow:0 2px 4px rgba(0,0,0,0.04);transition:border-color .2s ease,box-shadow .2s ease}.glass-input:focus{outline:0;border-color:rgba(0,115,206,0.5);box-shadow:0 2px 8px rgba(0,115,206,0.1)}.dark .glass-input{background:rgba(30,41,59,0.8);border:1px solid rgba(100,116,139,0.5);color:#e2e8f0;box-shadow:0 2px 4px rgba(0,0,0,0.15)}.dark .glass-input:focus{border-color:rgba(59,130,246,0.5);box-shadow:0 2px 8px rgba(59,130,246,0.15)}.glass-dropdown{background:rgba(255,255,255,0.9);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border:1px solid rgba(255,255,255,0.3);border-radius:8px;box-shadow:0 8px 20px rgba(0,0,0,0.15)}.dark .glass-dropdown{background:rgba(15,23,42,0.9);border:1px solid rgba(255,255,255,0.1);box-shadow:0 8px 20px rgba(0,0,0,0.3)}.glass-overlay{background:rgba(255,255,255,0.1);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}.dark .glass-overlay{background:rgba(0,0,0,0.2)}@media(max-width:768px){.glass-card{padding:1rem;border-radius:8px}.glass-modal{border-radius:12px}.glass-base,.glass-strong,.glass-subtle{backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}}@media(prefers-reduced-motion:reduce){.glass-card,.glass-btn,.glass-input{transition:none !important}}@media(prefers-contrast:high){.glass-base,.glass-strong,.glass-card{border-width:2px;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}}.glass-base,.glass-strong,.glass-subtle,.glass-card,.glass-btn,.glass-modal{will-change:transform}
|
||||
Binary file not shown.
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* Minimales Icon-Set für Kiosk-Modus
|
||||
* SVG-basierte Icons als CSS-Pseudo-Elemente für beste Performance
|
||||
* Ersetzt FontAwesome für deutlich kleinere Bundle-Größe
|
||||
*/
|
||||
|
||||
/* Icon-Basis-Klasse */
|
||||
.icon {
|
||||
display: inline-block;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.icon-lg { width: 1.5rem; height: 1.5rem; }
|
||||
.icon-xl { width: 2rem; height: 2rem; }
|
||||
|
||||
/* ===== DRUCKER ICONS ===== */
|
||||
.icon-printer {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-print {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== STATUS ICONS ===== */
|
||||
.icon-check {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-warning {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23f59e0b'%3E%3Cpath d='M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-error {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-offline {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%236b7280'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== NAVIGATION ICONS ===== */
|
||||
.icon-home {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-settings {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.8,11.69,4.8,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-users {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A3.012 3.012 0 0 0 16.43 6c-.68 0-1.3.27-1.77.72L12 8.5l-2.66-1.78C8.87 6.27 8.25 6 7.57 6c-1.31 0-2.42.83-2.83 2L2.5 16H5v6h2v-6h2v6h2zm-6.5-10.5c.83 0 1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5S12 9.17 12 10s.67 1.5 1.5 1.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-dashboard {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 13h8V3H3v10zm0 8h8v-6H3v6zm10 0h8V11h-8v10zm0-18v6h8V3h-8z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== ACTION ICONS ===== */
|
||||
.icon-plus {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-edit {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-delete {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ef4444'%3E%3Cpath d='M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-refresh {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== POWER/CONNECTION ICONS ===== */
|
||||
.icon-power {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M13 3h-2v10h2V3zm4.83 2.17l-1.42 1.42C17.99 7.86 19 9.81 19 12c0 3.87-3.13 7-7 7s-7-3.13-7-7c0-2.19 1.01-4.14 2.58-5.42L6.17 5.17C4.23 6.82 3 9.26 3 12c0 4.97 4.03 9 9 9s9-4.03 9-9c0-2.74-1.23-5.18-3.17-6.83z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-wifi {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%2310b981'%3E%3Cpath d='M1 9l2 2c4.97-4.97 13.03-4.97 18 0l2-2C16.93 2.93 7.07 2.93 1 9zm8 8l3 3 3-3c-1.65-1.66-4.34-1.66-6 0zm-4-4l2 2c2.76-2.76 7.24-2.76 10 0l2-2C15.14 9.14 8.87 9.14 5 13z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== DOKUMENT ICONS ===== */
|
||||
.icon-file {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M18,20H6V4H13V9H18V20Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-queue {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M4 6H2v14c0 1.1.9 2 2 2h14v-2H4V6zm16-4H8c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-1 9H9V9h10v2zm-4 4H9v-2h6v2zm4-8H9V5h10v2z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== INFO ICONS ===== */
|
||||
.icon-info {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%233b82f6'%3E%3Cpath d='M12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12C22,6.48 17.52,2 12,2M13,17H11V11H13M13,9H11V7H13'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-time {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M16.2,16.2L11,13V7H12.5V12.2L17,14.7L16.2,16.2Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== ARROW ICONS ===== */
|
||||
.icon-arrow-right {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M8.59 16.59L13.17 12 8.59 7.41 10 6l6 6-6 6-1.41-1.41z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.icon-arrow-down {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23374151'%3E%3Cpath d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
/* ===== HOVER-STATES ===== */
|
||||
.btn:hover .icon,
|
||||
.nav-item:hover .icon {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* ===== DARK MODE ===== */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.icon-printer,
|
||||
.icon-print,
|
||||
.icon-home,
|
||||
.icon-settings,
|
||||
.icon-users,
|
||||
.icon-dashboard,
|
||||
.icon-plus,
|
||||
.icon-edit,
|
||||
.icon-refresh,
|
||||
.icon-file,
|
||||
.icon-queue,
|
||||
.icon-time,
|
||||
.icon-arrow-right,
|
||||
.icon-arrow-down {
|
||||
filter: brightness(2);
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== RESPONSIVE ICON-SIZES ===== */
|
||||
@media (max-width: 768px) {
|
||||
.icon { width: 1.25rem; height: 1.25rem; }
|
||||
.icon-lg { width: 1.75rem; height: 1.75rem; }
|
||||
.icon-xl { width: 2.25rem; height: 2.25rem; }
|
||||
}
|
||||
Binary file not shown.
Vendored
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -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
|
||||
* Belohnende und motivierende Animationen für Auto-Optimierung
|
||||
* MYP Platform - Optimierte einfache Animationen
|
||||
* Reduzierte, performante Animationen für bessere User Experience
|
||||
*/
|
||||
|
||||
/* ===== MODAL FADE-IN ANIMATION ===== */
|
||||
/* ===== EINFACHE FADE-IN ANIMATION ===== */
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
backdrop-filter: blur(0px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fade-in {
|
||||
animation: fade-in 0.3s ease-out;
|
||||
animation: fade-in 0.2s ease-out;
|
||||
}
|
||||
|
||||
/* ===== BOUNCE-IN 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 ===== */
|
||||
/* ===== EINFACHE SLIDE-UP ANIMATION ===== */
|
||||
@keyframes slide-up {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
transform: translateY(15px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@@ -103,239 +30,105 @@
|
||||
}
|
||||
|
||||
.animate-slide-up {
|
||||
animation: slide-up 0.6s ease-out;
|
||||
animation: slide-up 0.3s ease-out;
|
||||
}
|
||||
|
||||
.animate-slide-up-delay {
|
||||
animation: slide-up 0.6s ease-out;
|
||||
animation-delay: 0.2s;
|
||||
animation: slide-up 0.3s ease-out;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate-slide-up-delay-2 {
|
||||
animation: slide-up 0.6s ease-out;
|
||||
animation-delay: 0.4s;
|
||||
animation: slide-up 0.3s ease-out;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.animate-slide-up-delay-3 {
|
||||
animation: slide-up 0.6s ease-out;
|
||||
animation-delay: 0.6s;
|
||||
animation-fill-mode: both;
|
||||
/* ===== EINFACHER HOVER-EFFEKT ===== */
|
||||
.animate-hover-lift {
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
/* ===== COUNT-UP ANIMATION ===== */
|
||||
@keyframes count-up {
|
||||
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-hover-lift:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.animate-count-up {
|
||||
animation: count-up 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
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 {
|
||||
/* ===== EINFACHE SUCCESS ANIMATION ===== */
|
||||
@keyframes simple-success {
|
||||
0% {
|
||||
transform: translateY(-100vh) rotate(0deg);
|
||||
opacity: 1;
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(120vh) rotate(720deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== ERFOLGS-BADGE SPEZIAL-ANIMATIONEN ===== */
|
||||
@keyframes star-twinkle {
|
||||
0%, 100% {
|
||||
opacity: 0.6;
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
}
|
||||
|
||||
.animate-success {
|
||||
animation: simple-success 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* ===== EINFACHER PULSE FÜR LOADING ===== */
|
||||
@keyframes simple-pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.badge-star {
|
||||
animation: star-twinkle 1.5s infinite ease-in-out;
|
||||
}
|
||||
|
||||
/* ===== LOADING SPINNER IMPROVEMENTS ===== */
|
||||
@keyframes spinner-glow {
|
||||
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));
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
#optimization-loader .animate-spin {
|
||||
animation: spin 1s linear infinite, spinner-glow 2s ease-in-out infinite;
|
||||
.animate-pulse-simple {
|
||||
animation: simple-pulse 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
/* ===== DARK MODE OPTIMIERUNGEN ===== */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.animate-glow {
|
||||
animation: glow-dark 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes glow-dark {
|
||||
0%, 100% {
|
||||
box-shadow: 0 0 5px rgba(96, 165, 250, 0.5),
|
||||
0 0 10px rgba(96, 165, 250, 0.3),
|
||||
0 0 15px rgba(96, 165, 250, 0.1);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 20px rgba(96, 165, 250, 0.8),
|
||||
0 0 30px rgba(96, 165, 250, 0.6),
|
||||
0 0 40px rgba(96, 165, 250, 0.4);
|
||||
}
|
||||
}
|
||||
/* ===== EINFACHER PROGRESS BAR ===== */
|
||||
.progress-fill {
|
||||
transition: width 1s ease-out;
|
||||
}
|
||||
|
||||
/* ===== PERFORMANCE OPTIMIERUNGEN ===== */
|
||||
.animate-bounce-in,
|
||||
.animate-fade-in,
|
||||
.animate-slide-up,
|
||||
.animate-slide-up-delay,
|
||||
.animate-slide-up-delay-2,
|
||||
.animate-slide-up-delay-3 {
|
||||
.animate-slide-up-delay-2 {
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
.animate-pulse-scale,
|
||||
.animate-float,
|
||||
.animate-float-delay {
|
||||
.animate-hover-lift {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.animate-glow {
|
||||
will-change: box-shadow;
|
||||
/* ===== UTILITY CLASSES ===== */
|
||||
.animate-smooth {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.animate-smooth-fast {
|
||||
transition: all 0.1s ease;
|
||||
}
|
||||
|
||||
/* ===== RESPONSIVE ANPASSUNGEN ===== */
|
||||
@media (max-width: 768px) {
|
||||
.confetti-piece {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
.animate-fade-in,
|
||||
.animate-slide-up,
|
||||
.animate-slide-up-delay,
|
||||
.animate-slide-up-delay-2 {
|
||||
animation-duration: 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== REDUZIERTE BEWEGUNG UNTERSTÜTZUNG ===== */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
|
||||
#optimization-reward-modal .text-8xl {
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
#optimization-reward-modal .max-w-md {
|
||||
max-width: 90vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== BUTTON HOVER VERBESSERUNGEN ===== */
|
||||
button:hover .badge-star {
|
||||
animation-duration: 0.8s;
|
||||
}
|
||||
|
||||
/* ===== ZUSÄTZLICHE UTILITY CLASSES ===== */
|
||||
.animate-shake {
|
||||
animation: shake 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes shake {
|
||||
0%, 100% { transform: translateX(0); }
|
||||
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
||||
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
||||
}
|
||||
|
||||
.animate-heartbeat {
|
||||
animation: heartbeat 1.5s infinite;
|
||||
}
|
||||
|
||||
@keyframes heartbeat {
|
||||
0%, 100% { transform: scale(1); }
|
||||
14% { transform: scale(1.1); }
|
||||
28% { transform: scale(1); }
|
||||
42% { transform: scale(1.1); }
|
||||
70% { transform: scale(1); }
|
||||
}
|
||||
|
||||
/* ===== PROGRESS BAR ANIMATION ===== */
|
||||
.progress-fill {
|
||||
animation: progress-grow 2s ease-out;
|
||||
}
|
||||
|
||||
@keyframes progress-grow {
|
||||
from {
|
||||
width: 0%;
|
||||
}
|
||||
to {
|
||||
width: var(--progress-width, 100%);
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 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;
|
||||
.animate-hover-lift:hover {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate-fade-in{animation:fade-in .2s ease-out}@keyframes slide-up{from{opacity:0;transform:translateY(15px)}to{opacity:1;transform:translateY(0)}}.animate-slide-up{animation:slide-up .3s ease-out}.animate-slide-up-delay{animation:slide-up .3s ease-out;animation-delay:.1s;animation-fill-mode:both}.animate-slide-up-delay-2{animation:slide-up .3s ease-out;animation-delay:.2s;animation-fill-mode:both}.animate-hover-lift{transition:transform .2s ease}.animate-hover-lift:hover{transform:translateY(-2px)}@keyframes simple-success{0%{opacity:0;transform:scale(0.9)}100%{opacity:1;transform:scale(1)}}.animate-success{animation:simple-success .3s ease-out}@keyframes simple-pulse{0%,100%{opacity:1}50%{opacity:.6}}.animate-pulse-simple{animation:simple-pulse 2s infinite ease-in-out}.progress-fill{transition:width 1s ease-out}.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{will-change:transform,opacity}.animate-hover-lift{will-change:transform}.animate-smooth{transition:all .2s ease}.animate-smooth-fast{transition:all .1s ease}@media(max-width:768px){.animate-fade-in,.animate-slide-up,.animate-slide-up-delay,.animate-slide-up-delay-2{animation-duration:.2s}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}.animate-hover-lift:hover{transform:none}}
|
||||
Binary file not shown.
Binary file not shown.
Vendored
+1
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Vendored
+1
@@ -0,0 +1 @@
|
||||
.filter-btn{transition:all .2s ease-in-out}.filter-btn.active{background-color:white;box-shadow:0 1px 3px 0 rgba(0,0,0,0.1),0 1px 2px 0 rgba(0,0,0,0.06);color:#374151}.dark .filter-btn.active{background-color:#475569;color:#f1f5f9}.printer-card-online{background:linear-gradient(135deg,#f0fdf4 0,#fff 100%);border-color:#bbf7d0;box-shadow:0 1px 3px 0 rgba(34,197,94,0.1),0 1px 2px 0 rgba(34,197,94,0.06)}.dark .printer-card-online{background:linear-gradient(135deg,rgba(34,197,94,0.1) 0,#1e293b 100%);border-color:#166534;box-shadow:0 1px 3px 0 rgba(34,197,94,0.2),0 1px 2px 0 rgba(34,197,94,0.1)}.printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.2),0 2px 4px -1px rgba(34,197,94,0.1)}.dark .printer-card-online:hover{box-shadow:0 4px 6px -1px rgba(34,197,94,0.3),0 2px 4px -1px rgba(34,197,94,0.2)}.online-indicator{animation:pulse-green 2s cubic-bezier(0.4,0,0.6,1) infinite}@keyframes pulse-green{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(34,197,94,0.7)}50%{opacity:.8;box-shadow:0 0 0 4px rgba(34,197,94,0)}}.status-count-change{animation:count-change .5s ease-in-out}@keyframes count-change{0%{transform:scale(1)}50%{transform:scale(1.1)}100%{transform:scale(1)}}.auto-refresh-active{background:linear-gradient(45deg,#10b981,#059669);animation:gradient-shift 3s ease-in-out infinite}@keyframes gradient-shift{0%,100%{background-position:0 50%}50%{background-position:100% 50%}}.printer-card{transition:all .3s cubic-bezier(0.4,0,0.2,1)}.printer-card:hover{transform:translateY(-2px)}.live-update-spinner{animation:spin 1s linear infinite}@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}@media(max-width:640px){.filter-btn{padding:.375rem .75rem;font-size:.75rem}.status-overview{flex-direction:column;gap:.5rem}.printer-card{padding:1rem}}.dark .printer-card{background-color:#1e293b;border-color:#334155}.dark .printer-card:hover{background-color:#334155}.filter-btn:focus{outline:2px solid #3b82f6;outline-offset:2px}.printer-card:focus-within{outline:2px solid #3b82f6;outline-offset:2px}@media print{.filter-btn,.auto-refresh-btn,.printer-detail-btn,.delete-printer-btn{display:none}.printer-card{break-inside:avoid;box-shadow:none;border:1px solid #000}}@media(prefers-contrast:high){.printer-card-online{border:2px solid #059669}.online-indicator{border:1px solid #000}}@media(prefers-reduced-motion:reduce){.online-indicator,.auto-refresh-active,.live-update-spinner{animation:none}.printer-card{transition:none}.printer-card:hover{transform:none}}
|
||||
Binary file not shown.
@@ -1,12 +1,11 @@
|
||||
/**
|
||||
* Mercedes-Benz MYP Platform - Erweiterte Professional Theme
|
||||
* Verbesserte Light/Dark Mode Implementierung mit optimierten Kontrasten
|
||||
* OPTIMIERT: Light Mode deutlich verbessert für bessere Lesbarkeit
|
||||
* Mercedes-Benz MYP Platform - Optimierte Professional Theme
|
||||
* Vereinfachte Light/Dark Mode Implementierung für bessere Performance
|
||||
*/
|
||||
|
||||
/* Globale CSS-Variablen für konsistente Theming */
|
||||
:root {
|
||||
/* Mercedes-Benz Markenfarben - Erweitert */
|
||||
/* Mercedes-Benz Markenfarben */
|
||||
--mb-primary: #0073ce;
|
||||
--mb-primary-dark: #005a9f;
|
||||
--mb-secondary: #64748b;
|
||||
@@ -14,32 +13,22 @@
|
||||
--mb-black: #000000;
|
||||
--mb-silver: #c0c0c0;
|
||||
|
||||
/* Light Mode Farbpalette - DEUTLICH VERBESSERT für optimale Lesbarkeit */
|
||||
/* Light Mode Farbpalette */
|
||||
--light-bg-primary: #ffffff;
|
||||
--light-bg-secondary: #fafbfc;
|
||||
--light-bg-tertiary: #f3f5f7;
|
||||
--light-bg-accent: #fbfcfd;
|
||||
--light-surface: #ffffff;
|
||||
--light-surface-hover: #fafbfc;
|
||||
--light-surface-active: #f3f5f7;
|
||||
--light-text-primary: #111827; /* Deutlich verstärkter Kontrast */
|
||||
--light-text-secondary: #374151; /* Erhöhter Kontrast für bessere Lesbarkeit */
|
||||
--light-text-muted: #6b7280; /* Optimierter Muted-Text, immer noch lesbar */
|
||||
--light-text-primary: #111827;
|
||||
--light-text-secondary: #374151;
|
||||
--light-text-muted: #6b7280;
|
||||
--light-text-accent: #0073ce;
|
||||
--light-border: #e5e7eb; /* Sichtbarere aber elegante Borders */
|
||||
--light-border: #e5e7eb;
|
||||
--light-border-strong: #d1d5db;
|
||||
--light-border-accent: #0073ce15; /* Subtilerer Accent-Border */
|
||||
--light-shadow: rgba(0, 0, 0, 0.04); /* Sanftere, natürlichere Schatten */
|
||||
--light-shadow: rgba(0, 0, 0, 0.04);
|
||||
--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 */
|
||||
--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 Mode Farbpalette */
|
||||
--dark-bg-primary: #0f172a;
|
||||
--dark-bg-secondary: #1e293b;
|
||||
--dark-bg-tertiary: #334155;
|
||||
@@ -54,118 +43,81 @@
|
||||
--dark-shadow-strong: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Professionelle Hero-Header Stile - VERBESSERT für Light Mode */
|
||||
/* Vereinfachte Hero-Header */
|
||||
.professional-hero {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 1.5rem;
|
||||
border-radius: 1rem;
|
||||
margin: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
background: var(--light-gradient-hero);
|
||||
background: var(--light-bg-secondary);
|
||||
border: 1px solid var(--light-border);
|
||||
box-shadow:
|
||||
0 8px 25px var(--light-shadow),
|
||||
0 4px 12px rgba(0, 115, 206, 0.03),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 12px var(--light-shadow);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.professional-hero:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow:
|
||||
0 12px 35px var(--light-shadow-strong),
|
||||
0 6px 16px var(--light-shadow-accent),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.95);
|
||||
box-shadow: 0 8px 20px var(--light-shadow-strong);
|
||||
}
|
||||
|
||||
.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);
|
||||
box-shadow: 0 20px 40px var(--dark-shadow-strong);
|
||||
box-shadow: 0 8px 20px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.professional-hero::before {
|
||||
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 */
|
||||
/* Vereinfachte Container */
|
||||
.professional-container {
|
||||
background: var(--light-surface);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 1rem;
|
||||
box-shadow: 0 4px 20px var(--light-shadow);
|
||||
backdrop-filter: blur(16px);
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 0.75rem;
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.dark .professional-container {
|
||||
background: var(--dark-surface);
|
||||
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 {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 30px var(--light-shadow-strong);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 16px var(--light-shadow-strong);
|
||||
}
|
||||
|
||||
.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 {
|
||||
background: rgba(255, 255, 255, 0.94);
|
||||
backdrop-filter: blur(16px) saturate(180%);
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(229, 231, 235, 0.4);
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||||
transition: transform 0.2s ease, background 0.2s ease;
|
||||
}
|
||||
|
||||
.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);
|
||||
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 {
|
||||
background: rgba(255, 255, 255, 0.97);
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.dark .mb-glass:hover {
|
||||
background: rgba(15, 23, 42, 0.95);
|
||||
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
|
||||
background: rgba(15, 23, 42, 0.9);
|
||||
}
|
||||
|
||||
/* Professional Buttons - VERBESSERT */
|
||||
/* Vereinfachte Buttons */
|
||||
.btn-professional {
|
||||
background: var(--light-gradient-accent);
|
||||
background: linear-gradient(135deg, var(--mb-primary) 0%, var(--mb-primary-dark) 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
@@ -174,73 +126,50 @@
|
||||
font-size: 0.875rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.025em;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow:
|
||||
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;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 115, 206, 0.2);
|
||||
}
|
||||
|
||||
.btn-professional:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(0, 115, 206, 0.25),
|
||||
0 2px 8px rgba(0, 115, 206, 0.15);
|
||||
}
|
||||
|
||||
.btn-professional:hover::before {
|
||||
left: 100%;
|
||||
box-shadow: 0 4px 12px rgba(0, 115, 206, 0.3);
|
||||
}
|
||||
|
||||
.btn-professional:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Secondary Button Style - VERBESSERT */
|
||||
/* Secondary Button */
|
||||
.btn-secondary-professional {
|
||||
background: var(--light-surface);
|
||||
color: var(--light-text-primary);
|
||||
border: 1px solid var(--light-border-strong);
|
||||
border-radius: 0.75rem;
|
||||
padding: 0.75rem 1.75rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 1px 4px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .btn-secondary-professional {
|
||||
background: var(--dark-surface);
|
||||
color: var(--dark-text-primary);
|
||||
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 {
|
||||
background: var(--light-surface-hover);
|
||||
border-color: var(--mb-primary);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 15px var(--light-shadow-strong);
|
||||
}
|
||||
|
||||
.dark .btn-secondary-professional:hover {
|
||||
background: var(--dark-surface-hover);
|
||||
box-shadow: 0 8px 25px var(--dark-shadow);
|
||||
}
|
||||
|
||||
/* Professional Input Fields - VERBESSERT */
|
||||
/* Vereinfachte Input Fields */
|
||||
.input-professional {
|
||||
background: var(--light-surface);
|
||||
border: 1px solid var(--light-border);
|
||||
@@ -248,20 +177,20 @@
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--light-text-primary);
|
||||
font-size: 0.875rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 1px 6px var(--light-shadow);
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
box-shadow: 0 1px 4px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .input-professional {
|
||||
background: var(--dark-surface);
|
||||
border-color: var(--dark-border);
|
||||
color: var(--dark-text-primary);
|
||||
box-shadow: 0 2px 8px var(--dark-shadow);
|
||||
box-shadow: 0 2px 4px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.input-professional:focus {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -273,77 +202,51 @@
|
||||
color: var(--dark-text-muted);
|
||||
}
|
||||
|
||||
/* Professional Cards - VERBESSERT */
|
||||
/* Vereinfachte Cards */
|
||||
.card-professional {
|
||||
background: var(--light-gradient-card);
|
||||
background: var(--light-surface);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow:
|
||||
0 2px 12px var(--light-shadow),
|
||||
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;
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.card-professional:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
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;
|
||||
box-shadow: 0 4px 16px var(--light-shadow-strong);
|
||||
}
|
||||
|
||||
.dark .card-professional {
|
||||
background: var(--dark-surface);
|
||||
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 {
|
||||
background: var(--light-surface);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 2px 12px var(--light-shadow);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .stat-card {
|
||||
background: var(--dark-surface);
|
||||
border-color: var(--dark-border);
|
||||
box-shadow: 0 4px 15px var(--dark-shadow);
|
||||
box-shadow: 0 4px 12px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-1px) scale(1.01);
|
||||
box-shadow: 0 6px 20px var(--light-shadow-strong);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 16px var(--light-shadow-strong);
|
||||
}
|
||||
|
||||
.dark .stat-card:hover {
|
||||
box-shadow: 0 8px 30px var(--dark-shadow-strong);
|
||||
box-shadow: 0 8px 20px var(--dark-shadow-strong);
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
@@ -370,7 +273,7 @@
|
||||
color: var(--dark-text-muted);
|
||||
}
|
||||
|
||||
/* Professional Status Badges */
|
||||
/* Vereinfachte Status Badges */
|
||||
.status-professional {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -381,121 +284,61 @@
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
transition: all 0.2s ease;
|
||||
transition: transform 0.2s ease;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.status-professional:hover {
|
||||
transform: scale(1.05);
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
/* Verbesserte Status Indicators */
|
||||
/* Status Indicators */
|
||||
.status-online {
|
||||
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
|
||||
background: #ecfdf5;
|
||||
color: #065f46;
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
|
||||
}
|
||||
|
||||
.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;
|
||||
border-color: rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);
|
||||
background: #fef2f2;
|
||||
color: #991b1b;
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
.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;
|
||||
border-color: rgba(239, 68, 68, 0.3);
|
||||
}
|
||||
|
||||
.status-printing {
|
||||
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
||||
background: #eff6ff;
|
||||
color: #1d4ed8;
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.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;
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.status-maintenance {
|
||||
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 */
|
||||
/* Vereinfachte Typography */
|
||||
.title-professional {
|
||||
background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-accent) 50%, var(--light-text-secondary) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
color: var(--light-text-primary);
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.025em;
|
||||
line-height: 1.1;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dark .title-professional {
|
||||
background: linear-gradient(135deg, var(--dark-text-primary) 0%, var(--dark-text-secondary) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
color: var(--dark-text-primary);
|
||||
}
|
||||
|
||||
.subtitle-professional {
|
||||
@@ -512,21 +355,17 @@
|
||||
|
||||
/* Professional Navigation */
|
||||
.nav-professional {
|
||||
background: var(--light-gradient-card);
|
||||
background: var(--light-bg-secondary);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 1rem;
|
||||
border-radius: 0.75rem;
|
||||
padding: 0.5rem;
|
||||
box-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);
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .nav-professional {
|
||||
background: var(--dark-surface);
|
||||
background: var(--dark-bg-secondary);
|
||||
border-color: var(--dark-border);
|
||||
box-shadow: 0 4px 15px var(--dark-shadow);
|
||||
box-shadow: 0 4px 12px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.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%);
|
||||
color: var(--mb-primary);
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--light-border-accent);
|
||||
box-shadow: 0 2px 8px var(--light-shadow-accent);
|
||||
border: 1px solid var(--light-border-strong);
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .nav-item-professional.active {
|
||||
@@ -575,23 +414,20 @@
|
||||
.table-professional {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--light-gradient-card);
|
||||
border-radius: 1rem;
|
||||
background: var(--light-bg-secondary);
|
||||
border-radius: 0.75rem;
|
||||
overflow: hidden;
|
||||
box-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);
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
border: 1px solid var(--light-border);
|
||||
}
|
||||
|
||||
.dark .table-professional {
|
||||
background: var(--dark-surface);
|
||||
box-shadow: 0 4px 20px var(--dark-shadow);
|
||||
background: var(--dark-bg-secondary);
|
||||
box-shadow: 0 4px 12px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.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);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
@@ -611,7 +447,7 @@
|
||||
}
|
||||
|
||||
.dark .table-professional th {
|
||||
background: var(--dark-bg-secondary);
|
||||
background: var(--dark-bg-tertiary);
|
||||
color: var(--dark-text-primary);
|
||||
border-bottom-color: var(--dark-border);
|
||||
}
|
||||
@@ -723,7 +559,7 @@
|
||||
|
||||
/* Background Gradients für verschiedene Seiten */
|
||||
.bg-professional {
|
||||
background: var(--light-gradient-primary);
|
||||
background: var(--light-bg-secondary);
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user