Style Guide v1.0.0: Indigo-Palette + lokale Web-Fonts

Komplette visuelle Umstellung nach dem generierten Style-Guide
(3d-lehrstun-de-v1.0.0). 3D-Druck-AG bekommt eine eigene Marke,
getrennt vom Teal der arduino.lehrstun.de-Schwester.

Farben: Teal #00979D -> Indigo #5B6EAE, warmes Off-White Surface
  #F0EEE9 statt Kuehlweiss, Lavendel-Akzent #9B8EC4.
Fonts: Raleway (Headings), Lato (Body), Inconsolata (Mono) — lokal
  gehostet in static/fonts/ (DSGVO-konform, kein Google-CDN),
  via @font-face + unicode-range (latin + latin-ext).
Form: Radius/Schatten/Spacing als Tokens (--radius-*, --shadow-*).

Technik:
  - base.html :root: neue --color-*/--font-*/--radius-* Tokens,
    alte Variablennamen (--primary etc.) als Aliase -> alle 33
    Templates ziehen sofort mit, kein Template-Rewrite noetig.
  - Semantische Banner-Tokens (--info/warn/success/error-bg+text+border)
    loesen ~130 Hardcoded-Pastelle ab (per sed gemappt).
  - Komponenten (Card, Button, Badge, Flash, Table, Code) auf Tokens.

Alle 13 Hauptseiten gegengeprueft (HTTP 200, keine Render-Fehler).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 12:52:14 +02:00
parent ae68da996f
commit 8a55e175a2
33 changed files with 349 additions and 110 deletions

View File

@@ -0,0 +1,70 @@
# Style Guide: 3d.lehrstun.de
Du arbeitest an einem Projekt mit folgendem Style Guide. **Verwende ausschließlich die unten definierten Design Tokens** für alle neuen oder geänderten Komponenten. Keine eigenen Farben, Schriften oder Abstände einführen.
## Projektkontext
- **Projekt:** 3d.lehrstun.de
- **Typ:** website
- **Zielgruppe:** Schülerinnen und Schüler
- **Sprache:** de-DE
## Tonalität
- **Soll wirken:** jugendlich, technisch, freundlich, modern
- **Soll NICHT wirken:** altmodisch, beliebig
## Do's
- Verwende abgerundete Ecken (border-radius: sm) für Karten und Buttons, um eine einladende, moderne Wirkung zu erzeugen
- Setze subtile Schatten ein, um Tiefe und Hierarchie zu schaffen, ohne die helle Cloud-Dancer-Palette zu überladen
- Nutze großzügige, komfortable Abstände zwischen Elementen, damit Inhalte für Schüler leicht scanbar und lesbar bleiben
- Kombiniere technische Akzentfarben (z. B. leuchtendes Cyan oder Electric Blue) mit der hellen Basispalette, um 3D-Themen jugendlich und modern zu inszenieren
## Don'ts
- Verwende keine harten, eckigen Container oder scharfe Drop-Shadows das wirkt altmodisch und bricht die freundliche Formensprache
- Nutze keine generischen Stock-Illustrationen oder Clip-Art das wirkt beliebig und verfehlt die technisch-moderne Markenpersönlichkeit
- Überhäufe Seiten nicht mit zu vielen Schriftgrößen oder Farben auf einmal das erzeugt visuelle Unruhe und widerspricht der comfortable Dichte
## Design Tokens (CSS Custom Properties)
```css
:root {
--color-primary: #5B6EAE;
--color-primary-hover: #4A5B96;
--color-secondary: #2C3E50;
--color-accent: #9B8EC4;
--color-surface: #F0EEE9;
--color-surface-muted: #E8E5DF;
--color-border: #D5D1CC;
--color-text: #2C3E50;
--color-text-muted: #6B7C8D;
--color-error: #C0392B;
--color-success: #27AE60;
--color-warning: #E67E22;
--font-heading: 'Raleway', system-ui, sans-serif;
--font-body: 'Lato', Georgia, serif;
--font-mono: 'Inconsolata', 'Courier New', monospace;
--radius-sm: 2px;
--radius-md: 4px;
--radius-lg: 8px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 40px;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 2px 8px rgba(0,0,0,0.08);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.1);
}
```
## Komponentenregeln
- **Buttons:** Radius `4px`, Padding `8px 16px`, Schatten `0 1px 2px rgba(0,0,0,0.05)`
- **Cards:** Radius `8px`, Border via `--color-border`, Schatten `0 2px 8px rgba(0,0,0,0.08)`
- **Inputs:** Radius `2px`, Border via `--color-border`
- **Icons:** Stil `outline`, Strichstärke `1.75px`, Line-Cap `round`
## Regel für neuen Code
Wenn du eine Komponente oder ein Stylesheet änderst: nutze `var(--color-…)`, `var(--font-…)`, `var(--spacing-…)` etc. Greife nie zu Hardcoded-Werten. Wenn dir ein Token fehlt, frage nach, bevor du eines erfindest.

View File

@@ -0,0 +1,78 @@
# Style Guide: 3d.lehrstun.de
> Version 1.0.0 | Revision 1 | 2026-06-04T09:57:23.143Z
## Projektinfo
- **Typ:** website
- **Zielgruppe:** Schülerinnen und Schüler
- **Sprache:** de-DE
## Designprinzipien
### Tonalität
- jugendlich
- technisch
- freundlich
- modern
### Anti-Tonalität
- altmodisch
- beliebig
### Do's
✓ Verwende abgerundete Ecken (border-radius: sm) für Karten und Buttons, um eine einladende, moderne Wirkung zu erzeugen
✓ Setze subtile Schatten ein, um Tiefe und Hierarchie zu schaffen, ohne die helle Cloud-Dancer-Palette zu überladen
✓ Nutze großzügige, komfortable Abstände zwischen Elementen, damit Inhalte für Schüler leicht scanbar und lesbar bleiben
✓ Kombiniere technische Akzentfarben (z. B. leuchtendes Cyan oder Electric Blue) mit der hellen Basispalette, um 3D-Themen jugendlich und modern zu inszenieren
### Don'ts
✗ Verwende keine harten, eckigen Container oder scharfe Drop-Shadows das wirkt altmodisch und bricht die freundliche Formensprache
✗ Nutze keine generischen Stock-Illustrationen oder Clip-Art das wirkt beliebig und verfehlt die technisch-moderne Markenpersönlichkeit
✗ Überhäufe Seiten nicht mit zu vielen Schriftgrößen oder Farben auf einmal das erzeugt visuelle Unruhe und widerspricht der comfortable Dichte
## Farbpalette
| Token | Wert |
|-------|------|
| Primary | `#5B6EAE` |
| Primary Hover | `#4A5B96` |
| Secondary | `#2C3E50` |
| Accent | `#9B8EC4` |
| Surface | `#F0EEE9` |
| Surface Muted | `#E8E5DF` |
| Border | `#D5D1CC` |
| Text | `#2C3E50` |
| Text Muted | `#6B7C8D` |
| Error | `#C0392B` |
| Success | `#27AE60` |
| Warning | `#E67E22` |
## Typografie
- **Überschriften:** Raleway
- **Fließtext:** Lato
- **Monospace:** Inconsolata
## Formensprache
- **Radius:** 2px / 4px / 8px
- **Schatten:** 0 1px 2px rgba(0,0,0,0.05) / 0 2px 8px rgba(0,0,0,0.08)
- **Spacing:** 4px / 8px / 16px / 24px / 40px
## Komponenten
### Button
- Radius: 4px
- Padding: 8px 16px
### Card
- Radius: 8px
- Border: 1px solid #D5D1CC
### Input
- Radius: 2px
- Border: 1px solid #D5D1CC
## Assets
- Icon-Stil: outline
- Strichstärke: 1.75
---
*Generiert am 2026-06-04T09:57:23.143Z*

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.

View File

@@ -11,7 +11,7 @@
</div>
</div>
<div class="card" style="background:#FEF9E7; border-left: 4px solid var(--warning);">
<div class="card" style="background:var(--warn-bg); border-left: 4px solid var(--warning);">
<strong>Hinweis:</strong> Live-Status via Bambu-Cloud-API kommt mit Etappe 5 (siehe
<code>docs/offene-fragen.md</code> &mdash; Bambu-Account muss noch geklaert werden).
Bis dahin pflegst du den Status hier manuell.

View File

@@ -22,7 +22,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=p.id) }}" alt=""
style="width: 100%; height: 160px; object-fit: cover; border-radius: 6px;">
{% else %}
<div style="height: 160px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB); border-radius: 6px;
<div style="height: 160px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover)); border-radius: 6px;
display: flex; align-items: center; justify-content: center; font-size: 2.5rem; color: var(--text-light);">
🎯
</div>

View File

@@ -15,7 +15,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=p.id) }}" alt=""
style="width: 100%; max-height: 240px; object-fit: cover; border-radius: 6px;">
{% else %}
<div style="height: 200px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB); border-radius: 6px;
<div style="height: 200px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover)); border-radius: 6px;
display: flex; align-items: center; justify-content: center; font-size: 3rem; color: var(--text-light);">
🎯
</div>
@@ -46,7 +46,7 @@
<div class="card">
<h2>Selbstbewertung</h2>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.6rem; margin-bottom: 1rem;">
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Gesamt</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung == 'zufrieden' %}🟢
@@ -55,7 +55,7 @@
</div>
<div style="font-size: 0.85rem; margin-top: 0.2rem;">{{ p.selbsteinschaetzung or '—' }}</div>
</div>
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Planung</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung_planung == 'gut' %}🟢
@@ -65,7 +65,7 @@
</div>
<div style="font-size: 0.85rem; margin-top: 0.2rem;">{{ p.selbsteinschaetzung_planung or '—' }}</div>
</div>
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Ausfuehrung</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung_ausfuehrung == 'gut' %}🟢
@@ -96,7 +96,7 @@
<h2>Rueckfragen-Historie</h2>
{% for r in rueckfragen %}
<div style="border-left: 3px solid {% if r.status == 'offen' %}var(--warning){% else %}var(--success){% endif %};
padding: 0.5rem 0.8rem; margin-bottom: 0.5rem; background: #F4F6F7; border-radius: 4px;">
padding: 0.5rem 0.8rem; margin-bottom: 0.5rem; background: var(--surface-muted); border-radius: 4px;">
<div style="font-size: 0.85rem; color: var(--text-light); margin-bottom: 0.2rem;">
{{ r.erstellt_am[:16].replace('T', ' ') }}{% if r.status == 'erledigt' %} · ✓ erledigt{% endif %}
</div>

View File

@@ -38,7 +38,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=p.id) }}" alt=""
style="width: 100%; height: 140px; object-fit: cover; border-radius: 6px;">
{% else %}
<div style="height: 140px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB); border-radius: 6px;
<div style="height: 140px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover)); border-radius: 6px;
display: flex; align-items: center; justify-content: center; font-size: 2rem; color: var(--text-light);">
🎯
</div>

View File

@@ -8,12 +8,12 @@
</div>
{% if not profile %}
<div class="card" style="background:#FADBD8; border-left: 4px solid var(--danger);">
<div class="card" style="background:var(--error-bg); border-left: 4px solid var(--danger);">
<strong>Keine aktiven SuS-Profile.</strong>
<a href="{{ url_for('admin.profile_liste') }}">Erst ein Profil anlegen.</a>
</div>
{% elif not drucker_liste %}
<div class="card" style="background:#FADBD8; border-left: 4px solid var(--danger);">
<div class="card" style="background:var(--error-bg); border-left: 4px solid var(--danger);">
<strong>Keine Drucker eingerichtet.</strong>
</div>
{% else %}
@@ -81,7 +81,7 @@
style="padding: 0.6rem; width: 100%; border: 1px solid var(--border); border-radius: 4px; font-size: 0.95rem;">
</div>
<div style="background: #EBF5FB; padding: 0.6rem 0.8rem; border-radius: 4px; font-size: 0.85rem; color: var(--text);">
<div style="background: var(--info-bg); padding: 0.6rem 0.8rem; border-radius: 4px; font-size: 0.85rem; color: var(--text);">
<strong>Hinweis:</strong> Du kannst auch fuer SuS reservieren, die noch nicht freigeschaltet
sind, und auch fuer gesperrte Drucker (du bekommst dann eine Warnung).
</div>

View File

@@ -21,7 +21,7 @@
</p>
<div id="drop-zone" style="border: 3px dashed var(--border); border-radius: 12px; padding: 3rem;
text-align: center; cursor: pointer; transition: border-color 0.2s; background: #fafafa;">
text-align: center; cursor: pointer; transition: border-color 0.2s; background: var(--surface-soft);">
<p style="font-size: 1.2rem; color: var(--text-light);">Strg+V zum Einfuegen</p>
<p style="font-size: 0.85rem; color: var(--text-light);">oder klicken um Datei auszuwaehlen</p>
<input type="file" id="datei-input" accept="image/*" style="display: none;">
@@ -54,7 +54,7 @@
<div style="min-width: 200px; text-align: center;">
<h3>Vorschau</h3>
<canvas id="vorschau-canvas" width="200" height="200"
style="border: 1px solid var(--border); border-radius: 8px; background: #f0f0f0;"></canvas>
style="border: 1px solid var(--border); border-radius: 8px; background: var(--surface-muted);"></canvas>
</div>
</div>
@@ -149,16 +149,16 @@ dateiInput.addEventListener('change', function() {
dropZone.addEventListener('dragover', function(e) {
e.preventDefault();
this.style.borderColor = 'var(--primary)';
this.style.background = '#EBF5FB';
this.style.background = 'var(--info-bg)';
});
dropZone.addEventListener('dragleave', function() {
this.style.borderColor = 'var(--border)';
this.style.background = '#fafafa';
this.style.background = 'var(--surface-soft)';
});
dropZone.addEventListener('drop', function(e) {
e.preventDefault();
this.style.borderColor = 'var(--border)';
this.style.background = '#fafafa';
this.style.background = 'var(--surface-soft)';
if (e.dataTransfer.files[0] && e.dataTransfer.files[0].type.indexOf('image') >= 0) {
var reader = new FileReader();
reader.onload = function(ev) { bildLaden(ev.target.result); };

View File

@@ -20,7 +20,7 @@
<img src="{{ url_for('static', filename='img/software/' ~ karte.bild_pfad) }}"
style="max-width: 200px; max-height: 200px; border-radius: 8px; border: 1px solid var(--border); background: #fff;">
{% else %}
<div style="width:200px; height:200px; background:#ECF0F1; border-radius: 8px; display:flex; align-items:center; justify-content:center; font-size:3rem; color: var(--text-light);">
<div style="width:200px; height:200px; background:var(--surface-muted); border-radius: 8px; display:flex; align-items:center; justify-content:center; font-size:3rem; color: var(--text-light);">
{%- if karte.kategorie == 'app' -%}📱
{%- elif karte.kategorie == 'generator' -%}🧩
{%- else -%}🖥️
@@ -54,7 +54,7 @@
<div>
<label style="display:block; font-size: 0.85rem; color: var(--text-light);">Slug (unveraenderbar)</label>
<input type="text" value="{{ karte.slug }}" disabled
style="padding: 0.5rem; width: 100%; border: 1px solid var(--border); border-radius: 4px; background: #f5f5f5;">
style="padding: 0.5rem; width: 100%; border: 1px solid var(--border); border-radius: 4px; background: var(--surface-soft);">
</div>
<div>
<label style="display:block; font-size: 0.85rem; color: var(--text-light);">Titel *</label>

View File

@@ -5,30 +5,120 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}3D-Druck-AG{% endblock %}</title>
<style>
/* ===========================================================================
Web-Fonts (lokal gehostet, DSGVO-konform — kein Google-CDN).
Raleway = Headings, Lato = Body, Inconsolata = Mono.
Raleway ist ein Variable Font (deckt 400-700 ab).
=========================================================================== */
@font-face {
font-family: 'Raleway'; font-style: normal; font-weight: 400 700; font-display: swap;
src: url('/static/fonts/raleway-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Raleway'; font-style: normal; font-weight: 400 700; font-display: swap;
src: url('/static/fonts/raleway-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
font-family: 'Lato'; font-style: normal; font-weight: 400; font-display: swap;
src: url('/static/fonts/lato-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Lato'; font-style: normal; font-weight: 400; font-display: swap;
src: url('/static/fonts/lato-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
font-family: 'Lato'; font-style: normal; font-weight: 700; font-display: swap;
src: url('/static/fonts/lato-700-latin.woff2') format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Lato'; font-style: normal; font-weight: 700; font-display: swap;
src: url('/static/fonts/lato-700-latin-ext.woff2') format('woff2');
unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
font-family: 'Inconsolata'; font-style: normal; font-weight: 400; font-display: swap;
src: url('/static/fonts/inconsolata-400-latin.woff2') format('woff2');
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
font-family: 'Inconsolata'; font-style: normal; font-weight: 400; font-display: swap;
src: url('/static/fonts/inconsolata-400-latin-ext.woff2') format('woff2');
unicode-range: U+0100-024F,U+0259,U+1E00-1EFF,U+2020,U+20A0-20AB,U+20AD-20CF,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
:root {
--primary: #00979D; /* Teal — identisch zum Arduino-Kurs fuer einheitliches Wirken */
--primary-dark: #007A80;
--secondary: #E67E22;
--bg: #F8F9FA;
/* === Style Guide v1.0.0 (2026-06-04): Indigo-Palette "Cloud Dancer" === */
--color-primary: #5B6EAE;
--color-primary-hover: #4A5B96;
--color-secondary: #2C3E50;
--color-accent: #9B8EC4;
--color-surface: #F0EEE9;
--color-surface-muted: #E8E5DF;
--color-border: #D5D1CC;
--color-text: #2C3E50;
--color-text-muted: #6B7C8D;
--color-error: #C0392B;
--color-success: #27AE60;
--color-warning: #E67E22;
--font-heading: 'Raleway', system-ui, sans-serif;
--font-body: 'Lato', system-ui, sans-serif;
--font-mono: 'Inconsolata', 'Consolas', monospace;
--radius-sm: 2px;
--radius-md: 4px;
--radius-lg: 8px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 40px;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 2px 8px rgba(0,0,0,0.08);
--shadow-lg: 0 4px 16px rgba(0,0,0,0.1);
/* === Alte Variablennamen als Aliase — alle 33 Templates ziehen sofort mit === */
--primary: var(--color-primary);
--primary-dark: var(--color-primary-hover);
--secondary: var(--color-accent);
--bg: var(--color-surface);
--card-bg: #FFFFFF;
--text: #2C3E50;
--text-light: #7F8C8D;
--border: #DEE2E6;
--code-bg: #2D2D2D;
--success: #27AE60;
--warning: #F39C12;
--danger: #E74C3C;
--text: var(--color-text);
--text-light: var(--color-text-muted);
--border: var(--color-border);
--code-bg: #2C3E50;
--success: var(--color-success);
--warning: var(--color-warning);
--danger: var(--color-error);
/* === Semantische Banner-/Status-Toene (loesen Hardcoded-Pastelle ab) === */
--info-bg: #ECEEF7; --info-border: #C8CEE8; --info-text: #41508A;
--warn-bg: #FBF2E2; --warn-border: #F0DBBC; --warn-text: #8A5A12;
--success-bg: #E5F4EB; --success-border: #B6E0C4; --success-text: #1E8449;
--error-bg: #F8E5E2; --error-border: #EFC4BD; --error-text: #A5352A;
--surface-soft: #FAF9F6; /* sehr helles Off-White (war #fafafa) */
--surface-muted: var(--color-surface-muted);
--surface-hover: #DDD9D2;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-family: var(--font-body);
background: var(--bg);
color: var(--text);
line-height: 1.6;
}
h1, h2, h3, h4, nav .brand { font-family: var(--font-heading); }
/* Navigation */
nav {
background: var(--primary);
@@ -81,11 +171,11 @@
/* Karten */
.card {
background: var(--card-bg);
border-radius: 8px;
border-radius: var(--radius-lg);
padding: 1.5rem;
margin-bottom: 1rem;
border: 1px solid var(--border);
box-shadow: 0 1px 3px rgba(0,0,0,0.08);
box-shadow: var(--shadow-md);
}
.card h2, .card h3 {
@@ -109,55 +199,56 @@
font-weight: 600;
text-transform: uppercase;
}
.badge-pflicht { background: #FDEBD0; color: #BA4A00; }
.badge-frei { background: #D5F5E3; color: #1E8449; }
.badge-anfaenger { background: #D5F5E3; color: #1E8449; }
.badge-mittel { background: #FEF9E7; color: #B7950B; }
.badge-fortgeschritten { background: #FADBD8; color: #943126; }
.badge-pflicht { background: var(--warn-bg); color: var(--warn-text); }
.badge-frei { background: var(--success-bg); color: var(--success-text); }
.badge-anfaenger { background: var(--success-bg); color: var(--success-text); }
.badge-mittel { background: var(--warn-bg); color: var(--warn-text); }
.badge-fortgeschritten { background: var(--error-bg); color: var(--error-text); }
/* Buttons */
.btn {
display: inline-block;
padding: 0.5rem 1.2rem;
border-radius: 6px;
border-radius: var(--radius-md);
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
font-weight: 600;
border: none;
cursor: pointer;
transition: background 0.2s;
box-shadow: var(--shadow-sm);
}
.btn-primary { background: var(--primary); color: white; }
.btn-primary:hover { background: var(--primary-dark); }
.btn-secondary { background: #ECF0F1; color: var(--text); }
.btn-secondary:hover { background: #D5DBDB; }
.btn-secondary { background: var(--surface-muted); color: var(--text); }
.btn-secondary:hover { background: var(--surface-hover); }
/* Tabellen */
table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
th, td { padding: 0.6rem 0.8rem; text-align: left; border-bottom: 1px solid var(--border); }
th { background: #F2F3F4; font-weight: 600; font-size: 0.85rem; }
th { background: var(--surface-muted); font-weight: 600; font-size: 0.85rem; }
/* Code */
pre {
background: var(--code-bg);
color: #F8F8F2;
color: #F0EEE9;
padding: 1.2rem;
border-radius: 8px;
border-radius: var(--radius-lg);
overflow-x: auto;
font-size: 0.85rem;
line-height: 1.5;
margin: 0.5rem 0;
}
code { font-family: 'Fira Code', 'Consolas', 'Monaco', monospace; }
code { font-family: var(--font-mono); }
/* Flash Messages */
.flash {
padding: 0.8rem 1.2rem;
border-radius: 6px;
border-radius: var(--radius-md);
margin-bottom: 1rem;
}
.flash-success { background: #D5F5E3; color: #1E8449; border: 1px solid #A9DFBF; }
.flash-error { background: #FADBD8; color: #943126; border: 1px solid #F5B7B1; }
.flash-success { background: var(--success-bg); color: var(--success-text); border: 1px solid var(--success-border); }
.flash-error { background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-border); }
h1 { font-size: 1.6rem; margin-bottom: 1rem; }
h2 { font-size: 1.3rem; }

View File

@@ -13,8 +13,8 @@
{# ====== BANNER: Lehrer-Notizen (V5-Quick-Action) ====== #}
{% for n in status.notizen %}
<div class="card" style="background: #FEF9E7; border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: #B7950B;">
<div class="card" style="background: var(--warn-bg); border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: var(--warn-text);">
<strong>📌 Lehrer-Notiz:</strong> {{ n.text }}
</p>
<form method="post" action="{{ url_for('profil.notiz_gelesen', notiz_id=n.id) }}" style="margin-top: 0.5rem;">
@@ -25,8 +25,8 @@
{# ====== BANNER: Offene Rueckfragen zu eigenen Projekten (V6) ====== #}
{% for r in status.rueckfragen %}
<div class="card" style="background: #FEF9E7; border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: #B7950B;">
<div class="card" style="background: var(--warn-bg); border-left: 5px solid var(--warning); margin-bottom: 0.5rem;">
<p style="margin: 0; color: var(--warn-text);">
<strong>❓ Rueckfrage zu „{{ r.projekt_titel }}":</strong> {{ r.text }}
</p>
<p style="margin-top: 0.5rem; font-size: 0.85rem; color: var(--text-light);">
@@ -37,7 +37,7 @@
{# ====== BANNER: Eingegangene Paarungs-Anfragen ====== #}
{% for a in status.offene_anfragen %}
<div class="card" style="background: #EBF5FB; border-left: 5px solid var(--primary); margin-bottom: 0.5rem;">
<div class="card" style="background: var(--info-bg); border-left: 5px solid var(--primary); margin-bottom: 0.5rem;">
<p style="margin: 0;">
<strong>{{ tier_emoji(a.von_tier) }} {{ a.von_vorname }}</strong> moechte mit dir
zusammenarbeiten. Magst du?
@@ -117,7 +117,7 @@
</form>
</div>
{% else %}
<div class="card" style="background: #EAFBF1; border-left: 4px solid var(--success); display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;">
<div class="card" style="background: var(--success-bg); border-left: 4px solid var(--success); display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap;">
<p style="margin: 0; font-size: 0.9rem;">
<strong>Heute eingecheckt:</strong>
{% if status.check_in_heute.modus == 'weiter_wie_bisher' %}Arbeite weiter
@@ -151,7 +151,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=status.projekt.aktiv.id) }}" alt=""
style="width: 120px; height: 120px; object-fit: cover; border-radius: 8px;">
{% else %}
<div style="width: 120px; height: 120px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB);
<div style="width: 120px; height: 120px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover));
border-radius: 8px; display: flex; align-items: center; justify-content: center;
font-size: 2.5rem; color: var(--text-light);">🎯</div>
{% endif %}
@@ -173,7 +173,7 @@
</div>
{% elif status.projekt.letztes and status.projekt.letztes.freigabe_status == 'wartet_auf_freigabe' %}
<div style="background: #FEF9E7; padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--warning);">
<div style="background: var(--warn-bg); padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--warning);">
<strong>⏳ Wartet auf Freigabe:</strong>
<a href="{{ url_for('profil.projekt_detail', projekt_id=status.projekt.letztes.id) }}">{{ status.projekt.letztes.titel }}</a>
<div style="font-size: 0.85rem; margin-top: 0.3rem; color: var(--text-light);">
@@ -182,7 +182,7 @@
</div>
{% elif status.projekt.letztes and status.projekt.letztes.freigabe_status == 'rueckfrage' %}
<div style="background: #FADBD8; padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--danger);">
<div style="background: var(--error-bg); padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--danger);">
<strong>❓ Rueckfrage offen zu:</strong>
<a href="{{ url_for('profil.projekt_detail', projekt_id=status.projekt.letztes.id) }}">{{ status.projekt.letztes.titel }}</a>
<div style="font-size: 0.85rem; margin-top: 0.3rem;">
@@ -197,7 +197,7 @@
{% if status.projekt.darf_neues %}
<a href="{{ url_for('profil.projekt_neu') }}" class="btn btn-primary">+ Neues Projekt anfangen</a>
{% else %}
<div style="background: #FEF9E7; padding: 0.6rem 0.8rem; border-radius: 6px; font-size: 0.9rem;">
<div style="background: var(--warn-bg); padding: 0.6rem 0.8rem; border-radius: 6px; font-size: 0.9rem;">
{{ status.projekt.sperr_grund }}
</div>
{% endif %}
@@ -324,17 +324,17 @@
padding: 0.5rem 0.7rem; border-radius: 6px; cursor: pointer;
transition: background 0.15s;
}
.ci-option:hover { background: #F2F3F4; }
.ci-option:hover { background: var(--surface-muted); }
.ci-option input[type=radio] { margin: 0; }
.onboarding-liste { display: flex; flex-direction: column; gap: 0.5rem; }
.onb-zeile {
display: flex; gap: 0.7rem; align-items: center;
padding: 0.5rem 0.7rem; border-radius: 6px;
background: #F2F3F4;
background: var(--surface-muted);
}
.onb-zeile.onb-fertig { background: #EAFBF1; opacity: 0.8; }
.onb-zeile.onb-aktuell { background: #EBF5FB; border-left: 4px solid var(--primary); }
.onb-zeile.onb-fertig { background: var(--success-bg); opacity: 0.8; }
.onb-zeile.onb-aktuell { background: var(--info-bg); border-left: 4px solid var(--primary); }
.onb-icon { font-size: 1.2rem; }
.onb-titel { flex: 1; }
.onb-aktion { display: flex; gap: 0.3rem; }

View File

@@ -9,7 +9,7 @@
<a href="{{ url_for('profil.logout') }}" class="btn btn-secondary">Abmelden</a>
</div>
<div class="card" style="background: #FEF9E7; border-color: #F5C842;">
<div class="card" style="background: var(--warn-bg); border-color: #F5C842;">
<h3>Cockpit-Stub &mdash; Etappe 1</h3>
<p>Hier kommt in Etappe 2 das progressive Cockpit (V1):</p>
<ul style="margin-top: 0.5rem; padding-left: 1.5rem;">

View File

@@ -16,7 +16,7 @@
font-size: 0.85rem; color: var(--text-light); margin-top: 0.2rem;
}
.druckerkachel-gross .sperre-banner {
background: #FADBD8; color: #943126; border: 1px solid #F5B7B1;
background: var(--error-bg); color: var(--error-text); border: 1px solid var(--error-border);
border-radius: 6px; padding: 0.6rem 0.8rem; font-size: 0.9rem;
}
.druckerkachel-gross .api-hinweis {
@@ -39,7 +39,7 @@
</p>
{% if not darf_reservieren %}
<div class="card" style="background:#FEF9E7; border-left: 4px solid var(--warning);">
<div class="card" style="background:var(--warn-bg); border-left: 4px solid var(--warning);">
<strong>Reservierung noch nicht freigeschaltet.</strong>
Du kannst die Drucker bisher nur ansehen. Lass dich beim Lehrer freischalten,
dann kannst du selbst Slots reservieren.
@@ -48,7 +48,7 @@
{% set gesperrte = drucker_liste | selectattr('freigegeben', 'equalto', 0) | list %}
{% if gesperrte %}
<div class="card" style="background:#FADBD8; border-left: 4px solid var(--danger);">
<div class="card" style="background:var(--error-bg); border-left: 4px solid var(--danger);">
<strong>⚠ {{ gesperrte|length }} Drucker derzeit gesperrt:</strong>
{{ gesperrte | map(attribute='name') | join(', ') }}
— Details auf den jeweiligen Kacheln.
@@ -111,7 +111,7 @@
{% endif %}
{# Belegung: aktuell + naechste 3 Slots #}
<div style="background:#F4F6F7; border-radius: 6px; padding: 0.6rem 0.8rem; font-size: 0.85rem;">
<div style="background:var(--surface-muted); border-radius: 6px; padding: 0.6rem 0.8rem; font-size: 0.85rem;">
{% if d.belegung %}
<div><strong>🔖 Jetzt belegt:</strong>
{{ tier_emoji(d.belegung.tier or '') }} {{ d.belegung.vorname or '—' }}

View File

@@ -43,7 +43,7 @@
</div>
<div class="card" style="max-width: 800px; margin: 2rem auto 0; background: #FEF9E7; border-color: #F5C842;">
<div class="card" style="max-width: 800px; margin: 2rem auto 0; background: var(--warn-bg); border-color: #F5C842;">
<h3 style="margin-bottom: 0.5rem;">Hinweis</h3>
<p style="margin: 0;">
Diese Seite ist im Aufbau. Stand: 2026-05-23, Skelett. Inhalte werden in

View File

@@ -30,7 +30,7 @@
{# Wenn eingeloggt: Status-Buttons zum Selbst-Zertifizieren #}
{% if session.profil_id %}
<div class="card" style="background: #EBF5FB; border-left: 4px solid var(--primary);">
<div class="card" style="background: var(--info-bg); border-left: 4px solid var(--primary);">
<p style="margin: 0;"><strong>Status setzen</strong> (du entscheidest selbst, wann du fertig bist):</p>
<div style="display: flex; gap: 0.5rem; margin-top: 0.5rem; flex-wrap: wrap;">
{% for opt, label in [('offen', '⚪ noch nicht angefangen'), ('laeuft', '🟡 läuft'), ('fertig', '✅ fertig')] %}

View File

@@ -49,7 +49,7 @@
}
.profil-power {
border-color: var(--primary);
background: linear-gradient(180deg, #fff, #EBF5FB);
background: linear-gradient(180deg, #fff, var(--info-bg));
}
</style>
{% endblock %}

View File

@@ -8,7 +8,7 @@
</div>
{% if not drucker_liste %}
<div class="card" style="background:#FADBD8; border-left: 4px solid var(--danger);">
<div class="card" style="background:var(--error-bg); border-left: 4px solid var(--danger);">
<strong>Kein Drucker frei.</strong> Alle Drucker sind derzeit gesperrt (Wartung / Reparatur).
Frag den Lehrer, wann wieder reserviert werden kann.
</div>
@@ -62,7 +62,7 @@
style="padding: 0.6rem; width: 100%; border: 1px solid var(--border); border-radius: 4px; font-size: 0.95rem;">
</div>
<div style="background: #EBF5FB; padding: 0.6rem 0.8rem; border-radius: 4px; font-size: 0.85rem; color: var(--text);">
<div style="background: var(--info-bg); padding: 0.6rem 0.8rem; border-radius: 4px; font-size: 0.85rem; color: var(--text);">
<strong>Regeln:</strong> Mindest-Dauer 15 Minuten, Maximum 24 Stunden.
Achte darauf, dass dein Druck in deinem Slot fertig wird — sonst kann der naechste SuS nicht starten.
</div>

View File

@@ -13,7 +13,7 @@
</div>
{% if not darf_reservieren %}
<div class="card" style="background:#FEF9E7; border-left: 4px solid var(--warning);">
<div class="card" style="background:var(--warn-bg); border-left: 4px solid var(--warning);">
<strong>Reservierung noch nicht freigeschaltet.</strong>
Bitte den Lehrer kurz darum — er muss dich einmalig freischalten, danach kannst du selbst reservieren.
</div>

View File

@@ -9,13 +9,13 @@
.eval-optionen { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; }
.eval-option {
cursor: pointer; padding: 0.7rem 0.5rem; border-radius: 6px; text-align: center;
background: #F4F6F7; border: 2px solid transparent; transition: all 0.15s;
background: var(--surface-muted); border: 2px solid transparent; transition: all 0.15s;
}
.eval-option:hover { background: #ECF0F1; }
.eval-option:hover { background: var(--surface-muted); }
.eval-option input[type=radio] { display: none; }
.eval-option input[type=radio]:checked + span { font-weight: 600; }
.eval-option:has(input[type=radio]:checked) {
background: #EBF5FB; border-color: var(--primary);
background: var(--info-bg); border-color: var(--primary);
}
.eval-emoji { font-size: 1.4rem; display: block; margin-bottom: 0.2rem; }
</style>
@@ -25,7 +25,7 @@
<a href="{{ url_for('profil.projekt_detail', projekt_id=p.id) }}" class="btn btn-secondary">Abbrechen</a>
</div>
<div class="card" style="background:#EBF5FB; border-left: 4px solid var(--primary);">
<div class="card" style="background:var(--info-bg); border-left: 4px solid var(--primary);">
<strong>Ehrlich bleiben.</strong> Niemand wird benotet — die Bewertung ist fuer dich selbst,
damit du beim naechsten Projekt besser einschaetzen kannst, was du planen musst.
</div>

View File

@@ -21,7 +21,7 @@
</p>
<div id="drop-zone" style="border: 3px dashed var(--border); border-radius: 12px; padding: 3rem;
text-align: center; cursor: pointer; transition: border-color 0.2s; background: #fafafa;">
text-align: center; cursor: pointer; transition: border-color 0.2s; background: var(--surface-soft);">
<p style="font-size: 1.2rem; color: var(--text-light);">Strg+V zum Einfuegen</p>
<p style="font-size: 0.85rem; color: var(--text-light);">oder klicken um Datei auszuwaehlen</p>
<input type="file" id="datei-input" accept="image/*" style="display: none;">
@@ -52,7 +52,7 @@
<div style="min-width: 200px; text-align: center;">
<h3>Vorschau</h3>
<canvas id="vorschau-canvas" width="200" height="200"
style="border: 1px solid var(--border); border-radius: 8px; background: #f0f0f0;"></canvas>
style="border: 1px solid var(--border); border-radius: 8px; background: var(--surface-muted);"></canvas>
</div>
</div>
@@ -139,14 +139,14 @@ dateiInput.addEventListener('change', function() {
}
});
dropZone.addEventListener('dragover', function(e) {
e.preventDefault(); this.style.borderColor = 'var(--primary)'; this.style.background = '#EBF5FB';
e.preventDefault(); this.style.borderColor = 'var(--primary)'; this.style.background = 'var(--info-bg)';
});
dropZone.addEventListener('dragleave', function() {
this.style.borderColor = 'var(--border)'; this.style.background = '#fafafa';
this.style.borderColor = 'var(--border)'; this.style.background = 'var(--surface-soft)';
});
dropZone.addEventListener('drop', function(e) {
e.preventDefault();
this.style.borderColor = 'var(--border)'; this.style.background = '#fafafa';
this.style.borderColor = 'var(--border)'; this.style.background = 'var(--surface-soft)';
if (e.dataTransfer.files[0] && e.dataTransfer.files[0].type.indexOf('image') >= 0) {
var reader = new FileReader();
reader.onload = function(ev) { bildLaden(ev.target.result); };

View File

@@ -12,7 +12,7 @@
{# ============== Lineage-Banner: Vorlage + Wiederholungen ============== #}
{% if vorlage %}
<div class="card" style="background: #EBF5FB; border-left: 4px solid var(--primary); margin-bottom: 0.8rem;">
<div class="card" style="background: var(--info-bg); border-left: 4px solid var(--primary); margin-bottom: 0.8rem;">
<strong>🔗 Vorlage:</strong>
<a href="{{ url_for('profil.projekt_detail', projekt_id=vorlage.id) }}">{{ vorlage.titel }}</a>
von {{ tier_emoji(vorlage.tier or '') }} {{ vorlage.vorname or '—' }}
@@ -23,7 +23,7 @@
{% endif %}
{% if wiederholungen %}
<div class="card" style="background: #EAFBF1; border-left: 4px solid var(--success); margin-bottom: 0.8rem;">
<div class="card" style="background: var(--success-bg); border-left: 4px solid var(--success); margin-bottom: 0.8rem;">
<strong>🔁 Wurde wiederholt von:</strong>
{% for w in wiederholungen %}
{{ tier_emoji(w.tier or '') }}
@@ -57,7 +57,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=p.id) }}" alt=""
style="width: 100%; max-height: 240px; object-fit: cover; border-radius: 6px;">
{% else %}
<div style="height: 200px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB); border-radius: 6px;
<div style="height: 200px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover)); border-radius: 6px;
display: flex; align-items: center; justify-content: center; font-size: 3rem; color: var(--text-light);">
🎯
</div>
@@ -97,7 +97,7 @@
<div class="card">
<h2>Deine Bewertung</h2>
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.6rem; margin-bottom: 1rem;">
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Gesamt</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung == 'zufrieden' %}🟢
@@ -107,7 +107,7 @@
</div>
<div style="font-size: 0.85rem; margin-top: 0.2rem;">{{ p.selbsteinschaetzung or '—' }}</div>
</div>
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Planung</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung_planung == 'gut' %}🟢
@@ -117,7 +117,7 @@
</div>
<div style="font-size: 0.85rem; margin-top: 0.2rem;">{{ p.selbsteinschaetzung_planung or '—' }}</div>
</div>
<div style="text-align: center; padding: 0.6rem; background: #F4F6F7; border-radius: 6px;">
<div style="text-align: center; padding: 0.6rem; background: var(--surface-muted); border-radius: 6px;">
<div style="font-size: 0.75rem; color: var(--text-light);">Ausfuehrung</div>
<div style="font-size: 1.4rem; margin-top: 0.2rem;">
{% if p.selbsteinschaetzung_ausfuehrung == 'gut' %}🟢
@@ -251,7 +251,7 @@
{# Upload-Zone #}
<div id="upload-zone" style="margin-top: 1rem; border: 3px dashed var(--border); border-radius: 8px;
padding: 1.5rem; text-align: center; cursor: pointer; background: #fafafa;">
padding: 1.5rem; text-align: center; cursor: pointer; background: var(--surface-soft);">
<div style="font-size: 1.1rem; color: var(--text-light);">📁 Dateien hier ablegen</div>
<div style="font-size: 0.85rem; color: var(--text-light); margin-top: 0.3rem;">
oder klicken — STL, 3MF, JPG, PNG · max. 60 MB pro Datei
@@ -300,7 +300,7 @@
{% endif %}
</div>
{% if not darf_abschliessen %}
<div style="margin-top: 0.6rem; background: #FEF9E7; padding: 0.6rem 0.8rem; border-radius: 6px; font-size: 0.85rem;">
<div style="margin-top: 0.6rem; background: var(--warn-bg); padding: 0.6rem 0.8rem; border-radius: 6px; font-size: 0.85rem;">
<strong>Noch nicht abschliessbar:</strong>
<ul style="margin: 0.3rem 0 0 1.2rem; padding: 0;">
{% for f in abschluss_fehlende %}<li>{{ f }}</li>{% endfor %}
@@ -308,17 +308,17 @@
</div>
{% endif %}
{% elif p.freigabe_status == 'wartet_auf_freigabe' %}
<div style="background: #FEF9E7; padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--warning);">
<div style="background: var(--warn-bg); padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--warning);">
<strong>Wartet auf Freigabe vom Lehrer.</strong>
Sobald er drueber geschaut hat, kannst du ein neues Projekt anfangen.
</div>
{% elif p.freigabe_status == 'rueckfrage' %}
<div style="background: #FADBD8; padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--danger);">
<div style="background: var(--error-bg); padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--danger);">
<strong>Lehrer hat eine Rueckfrage.</strong>
Schau ins Cockpit fuer die Details und beantworte sie.
</div>
{% else %}
<div style="background: #EAFBF1; padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--success);">
<div style="background: var(--success-bg); padding: 0.8rem; border-radius: 6px; border-left: 4px solid var(--success);">
<strong>Freigegeben.</strong>
{% if p.freigegeben_am %}Am {{ p.freigegeben_am[:10] }}.{% endif %}
Du kannst jetzt ein neues Projekt anfangen.
@@ -349,16 +349,16 @@
zone.addEventListener('dragover', function(e) {
e.preventDefault();
zone.style.borderColor = 'var(--primary)';
zone.style.background = '#EBF5FB';
zone.style.background = 'var(--info-bg)';
});
zone.addEventListener('dragleave', function() {
zone.style.borderColor = 'var(--border)';
zone.style.background = '#fafafa';
zone.style.background = 'var(--surface-soft)';
});
zone.addEventListener('drop', function(e) {
e.preventDefault();
zone.style.borderColor = 'var(--border)';
zone.style.background = '#fafafa';
zone.style.background = 'var(--surface-soft)';
if (e.dataTransfer.files && e.dataTransfer.files.length) {
dateienHochladen(e.dataTransfer.files);
}

View File

@@ -13,7 +13,7 @@
</div>
{% if not darf_neues and sperr_grund %}
<div class="card" style="background:#FEF9E7; border-left: 4px solid var(--warning);">
<div class="card" style="background:var(--warn-bg); border-left: 4px solid var(--warning);">
{{ sperr_grund }}
</div>
{% endif %}
@@ -27,7 +27,7 @@
<img src="{{ url_for('api.projekt_cover', projekt_id=p.id) }}" alt=""
style="width: 100%; height: 160px; object-fit: cover; border-radius: 6px; background: #fff;">
{% else %}
<div style="height: 160px; background: linear-gradient(135deg, #ECF0F1, #D5DBDB); border-radius: 6px;
<div style="height: 160px; background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover)); border-radius: 6px;
display: flex; align-items: center; justify-content: center; font-size: 2.5rem; color: var(--text-light);">
🎯
</div>

View File

@@ -7,7 +7,7 @@
<a href="{{ url_for('profil.cockpit') }}" class="btn btn-secondary">Abbrechen</a>
</div>
<div class="card" style="background:#EBF5FB; border-left: 4px solid var(--primary);">
<div class="card" style="background:var(--info-bg); border-left: 4px solid var(--primary);">
<strong>Commitment.</strong> Mit dem Anlegen entscheidest du dich, dieses Projekt durchzuziehen.
Du kannst es spaeter abschliessen und selbst bewerten — und erst dann wieder ein neues anfangen.
</div>

View File

@@ -5,11 +5,11 @@
<style>
.kat-tabelle { width: 100%; border-collapse: collapse; }
.kat-tabelle th {
background: #F2F3F4; padding: 0.6rem 0.5rem;
background: var(--surface-muted); padding: 0.6rem 0.5rem;
text-align: left; font-size: 0.85rem; cursor: pointer;
user-select: none; white-space: nowrap;
}
.kat-tabelle th:hover { background: #E5E7E8; }
.kat-tabelle th:hover { background: var(--surface-hover); }
.kat-tabelle th .sort-pfeil {
display: inline-block; margin-left: 0.3rem; opacity: 0.3; font-size: 0.7rem;
}
@@ -19,16 +19,16 @@
vertical-align: middle; font-size: 0.9rem;
}
.kat-zeile { cursor: pointer; }
.kat-zeile:hover { background: #F8F9FA; }
.kat-zeile.offen { background: #EBF5FB; }
.kat-zeile:hover { background: var(--surface-soft); }
.kat-zeile.offen { background: var(--info-bg); }
.kat-thumb {
width: 40px; height: 40px; border-radius: 6px; object-fit: cover;
background: linear-gradient(135deg, #ECF0F1, #D5DBDB);
background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover));
display: flex; align-items: center; justify-content: center;
font-size: 1.2rem; color: var(--text-light);
}
.kat-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 6px; }
.kat-detail { display: none; background: #F8F9FA; }
.kat-detail { display: none; background: var(--surface-soft); }
.kat-detail.offen { display: table-row; }
.kat-detail-inner {
display: flex; gap: 1.5rem; padding: 1rem 0.5rem; flex-wrap: wrap;
@@ -39,7 +39,7 @@
}
.kat-detail-bild-platzhalter {
width: 260px; height: 200px; border-radius: 8px;
background: linear-gradient(135deg, #ECF0F1, #D5DBDB);
background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover));
display: flex; align-items: center; justify-content: center;
font-size: 3rem; color: var(--text-light);
}
@@ -54,7 +54,7 @@
padding: 0.2rem 0.6rem; background: #fff; border: 1px solid var(--border);
border-radius: 4px; text-decoration: none; font-size: 0.85rem; color: var(--text);
}
.kat-dateien a:hover { background: #ECF0F1; }
.kat-dateien a:hover { background: var(--surface-muted); }
</style>
<h1>Projekte</h1>

View File

@@ -15,7 +15,7 @@
}
.sw-karte .bild-platzhalter {
height: 110px;
background: linear-gradient(135deg, #ECF0F1, #D5DBDB);
background: linear-gradient(135deg, var(--surface-muted), var(--surface-hover));
border-radius: 6px;
display: flex;
align-items: center;
@@ -49,8 +49,8 @@
gap: 0.3rem;
font-size: 0.8rem;
padding: 0.35rem 0.7rem;
border-radius: 6px;
background: #2C3E50;
border-radius: var(--radius-md);
background: var(--color-secondary);
color: #fff;
text-decoration: none;
}