/* ==========================================================================
   Wine Tracker — Designsystem

   Eine Akzentfarbe (Weinrot), warme Neutraltöne, Karten mit Rahmen statt
   Schlagschatten. Flächen sind ruhig, Farbe bedeutet etwas: gefüllt = die
   Hauptaktion einer Seite, alles andere tritt zurück.

   Aufbau: 1 Tokens · 2 Grundlagen · 3 Layout · 4 Bausteine · 5 Seiten
   · 6 Hilfsklassen · 7 Schmale Bildschirme
   ========================================================================== */

/* ---------------------------------------------------------------- 1 Tokens */
:root {
    /* Farben: Weinrot als einziger Akzent, Gold nur noch für Sterne */
    --wine: #722f37;
    --wine-dark: #5a242a;
    --wine-ink: #4a1c28;          /* Überschriften */
    --wine-tint: #f7f1f3;         /* getönte Flächen */
    --wine-tint-strong: #f0e3e7;
    --gold: #d9a441;

    --ink: #2b2226;               /* Fließtext */
    --ink-muted: #6f6469;         /* Zweitrangiges */
    --ink-faint: #9a9095;         /* Beschriftungen, Hinweise */

    --surface: #ffffff;
    --surface-sunken: #faf8f9;    /* Seitenhintergrund */
    --surface-raised: #f4f0f1;    /* Chips, Bildbühne */

    --border: #e6dee1;
    --border-strong: #d5c7cc;

    --danger: #b3261e;
    --danger-tint: #fdf3f2;
    --success-bg: #eaf5ee;
    --success-ink: #1e5133;
    --error-bg: #fdf0ef;
    --error-ink: #8c221c;

    /* Abstände: 4er-Raster, überall dieselben Stufen */
    --s-1: 0.25rem;
    --s-2: 0.5rem;
    --s-3: 0.75rem;
    --s-4: 1rem;
    --s-5: 1.5rem;
    --s-6: 2rem;
    --s-7: 3rem;

    --r-sm: 6px;
    --r: 10px;
    --r-lg: 14px;
    --r-pill: 999px;

    /* Schatten sparsam: nur was über der Seite schwebt */
    --shadow-pop: 0 6px 24px rgba(43, 34, 38, 0.12);
    --shadow-nav: 0 1px 0 var(--border);

    --focus: 0 0 0 3px rgba(114, 47, 55, 0.28);

    --font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
            'Helvetica Neue', Arial, sans-serif;
    --content-width: 1140px;

    /* Rückwärtskompatible Namen (ältere Regeln, Templates) */
    --primary-color: var(--wine);
    --primary-dark: var(--wine-dark);
    --secondary-color: #c19a6b;
    --danger-color: var(--danger);
    --warning-color: var(--gold);
    --light-bg: var(--surface-raised);
    --text-dark: var(--ink);
    --text-light: var(--ink-muted);
    --text-muted: var(--ink-muted);
    --border-color: var(--border);
    --shadow: none;
}

/* ----------------------------------------------------------- 2 Grundlagen */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* hidden muss staerker sein als jedes display der Bausteine: .btn ist
   inline-flex und stuende sonst trotz hidden weiter da (der Filtern-Knopf,
   den wine-search-box.js ausblendet). */
[hidden] {
    display: none !important;
}

body {
    font-family: var(--font);
    font-size: 1rem;
    line-height: 1.55;
    color: var(--ink);
    background: var(--surface-sunken);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
    color: var(--wine-ink);
    line-height: 1.25;
    font-weight: 600;
}

h1 { font-size: 1.75rem; letter-spacing: -0.01em; }
h2 { font-size: 1.25rem; }
h3 { font-size: 1.05rem; }

a {
    color: var(--wine);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

img {
    max-width: 100%;
}

/* ein einheitlicher Fokusring — vorher hatte ihn fast nichts */
:focus-visible {
    outline: 2px solid var(--wine);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

/* Übergang zwischen zwei Seiten desselben Ursprungs. Genutzt wird er genau
   für eine Sache: Beim Antippen einer Kachel wächst das Flaschenbild an
   seinen Platz auf der Weinseite (Namen stehen im wine_card-Makro und in
   wines/view.html). Bewusst nur das Bild — sobald Titel, Preis und Sterne
   mitwandern, wird es zappelig. Browser ohne Unterstützung wechseln die
   Seite wie bisher; ein Rückfallweg ist nicht nötig. */
@view-transition {
    navigation: auto;
}

/* Der Seitenwechsel selbst blendet nur weich — die Flasche macht die
   eigentliche Bewegung */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 0.18s;
}

/* ------------------------------------------------------------- 3 Layout */
.navbar {
    background: var(--surface);
    box-shadow: var(--shadow-nav);
    position: sticky;
    top: 0;
    z-index: 100;
    /* Beim Seitenwechsel bleibt die Kopfzeile stehen, statt mit der ganzen
       Seite durchzublenden — sonst sieht es aus, als lade das Logo neu. */
    view-transition-name: kopfzeile;
}

.nav-container {
    max-width: var(--content-width);
    margin: 0 auto;
    padding: var(--s-3) var(--s-4);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4);
}

.nav-brand {
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--wine-ink);
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: var(--s-2);
    white-space: nowrap;
}

.nav-logo {
    height: 1.75rem;
    width: auto;
    display: block;
}

/* Zeigt man auf das Logo, trinkt das Eichhörnchen einen Schluck. */
.logo-buehne {
    position: relative;
    display: block;
}

.logo-buehne::after {
    content: "";
    position: absolute;
    inset: 0;
    background: center / contain no-repeat;
}

/* Die Adresse des GIFs steht NUR in dieser Regel. Ein Hintergrundbild wird
   erst geladen, wenn die Regel das erste Mal greift — wer nie auf das Logo
   zeigt, lädt die 200 KB also nie. Deshalb auch kein zweites <img>.
   Der Hintergrund des GIFs ist deckend weiß wie die Kopfzeile (--surface);
   auf einer getönten Fläche sähe man ein Kästchen darum. */
.nav-brand:hover .logo-buehne::after,
.nav-brand:focus-visible .logo-buehne::after {
    background-image: url("../img/logo-animiert.gif");
}

@media (prefers-reduced-motion: reduce) {
    .nav-brand:hover .logo-buehne::after,
    .nav-brand:focus-visible .logo-buehne::after {
        background-image: none;
    }
}

.nav-menu {
    display: flex;
    gap: var(--s-1);
    align-items: center;
}

.nav-link {
    color: var(--ink-muted);
    text-decoration: none;
    font-size: 0.94rem;
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-sm);
    transition: background 0.15s ease, color 0.15s ease;
}

.nav-link:hover {
    background: var(--wine-tint);
    color: var(--wine-ink);
}

/* aktuelle Seite: erkennbar, ohne zu schreien */
.nav-link[aria-current="page"] {
    color: var(--wine);
    background: var(--wine-tint);
    font-weight: 500;
}

.nav-toggle {
    display: none;
    flex-direction: column;
    gap: 4px;
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--s-2);
}

.nav-toggle span {
    width: 22px;
    height: 2px;
    background: var(--ink);
    border-radius: 2px;
}

.main-content {
    flex: 1;
    padding: var(--s-6) var(--s-4);
    width: 100%;
}

.container {
    max-width: var(--content-width);
    margin: 0 auto;
}

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-4);
    margin-bottom: var(--s-5);
}

/* ---------------------------------------------------------- 4 Bausteine */

/* --- Knöpfe -------------------------------------------------------------
   Vier Rollen, eine Form: primary = die eine Hauptaktion, secondary =
   gleichrangige Nebenaktion, ghost = beiläufig (Werkzeugleisten), danger =
   erst beim Darüberfahren rot. Kein `width: 100%` auf schmalen Bildschirmen:
   das hat vorher jede Zeile gesprengt, in der ein Knopf neben etwas stand. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: 0 var(--s-4);
    min-height: 40px;
    border-radius: var(--r-sm);
    border: 1px solid transparent;
    font-family: inherit;
    font-size: 0.94rem;
    font-weight: 500;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.btn:focus-visible {
    outline: none;
    box-shadow: var(--focus);
}

.btn-primary {
    background: var(--wine);
    color: #fff;
}

.btn-primary:hover {
    background: var(--wine-dark);
}

.btn-secondary {
    background: var(--surface);
    color: var(--wine-ink);
    border-color: var(--border-strong);
}

.btn-secondary:hover {
    background: var(--wine-tint);
    border-color: var(--wine);
}

.btn-ghost {
    background: transparent;
    color: var(--ink-muted);
    border-color: transparent;
    padding: 0 var(--s-3);
}

.btn-ghost:hover {
    background: var(--surface-raised);
    color: var(--wine-ink);
}

.btn-danger {
    background: transparent;
    color: var(--danger);
    border-color: #e8c9c6;
}

.btn-danger:hover {
    background: var(--danger);
    border-color: var(--danger);
    color: #fff;
}

.btn-sm {
    min-height: 32px;
    padding: 0 var(--s-3);
    font-size: 0.85rem;
}

.btn-block {
    width: 100%;
}

.btn:disabled {
    cursor: default;
}

/* als Text getarnter Knopf (Formular-Auslöser im Fließtext) */
.link-button {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--wine);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

/* --- Flächen ----------------------------------------------------------- */
.card,
.empty-state,
.wine-card,
.wine-detail,
.wine-form,
.prose {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
}

.empty-state {
    text-align: center;
    padding: var(--s-7) var(--s-4);
}

.empty-state h2 {
    color: var(--ink-muted);
    margin-bottom: var(--s-2);
}

.empty-state p {
    color: var(--ink-faint);
    margin-bottom: var(--s-4);
}

.prose {
    padding: var(--s-5);
    max-width: 70ch;
}

.prose h2 {
    margin: var(--s-5) 0 var(--s-2);
}

.prose ul,
.prose ol {
    margin: 0 0 var(--s-4) var(--s-5);
}

.prose li {
    margin-bottom: var(--s-1);
}

.prose p {
    margin-bottom: var(--s-3);
}

/* --- Werkzeug- und Filterleiste ---------------------------------------- */
.list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-1);
    margin-bottom: var(--s-3);
}

.toolbar-spacer {
    flex: 1;
}

.toolbar-label {
    font-size: 0.8rem;
    color: var(--ink-faint);
    letter-spacing: 0.02em;
}

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    align-items: center;
    margin-bottom: var(--s-5);
    padding: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
}

.filter-select,
.filter-input,
.form-control,
.search-input,
.share-url {
    font-family: inherit;
    color: var(--ink);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.filter-select,
.filter-input {
    padding: 0.4rem 0.6rem;
    font-size: 0.9rem;
    min-height: 36px;
}

.filter-input {
    width: 110px;
}

.filter-check {
    font-size: 0.9rem;
    display: inline-flex;
    gap: var(--s-1);
    align-items: center;
    color: var(--ink-muted);
}

.filter-select:focus,
.filter-input:focus,
.form-control:focus,
.search-input:focus {
    outline: none;
    border-color: var(--wine);
    box-shadow: var(--focus);
}

/* Suchfeld über die ganze Breite der Leiste, Vorschläge hängen darunter */
.search-row {
    display: flex;
    gap: var(--s-2);
    flex: 1 0 100%;
    position: relative;
}

.search-input {
    flex: 1;
    min-width: 0;
    padding: 0 var(--s-3);
    min-height: 40px;
    font-size: 1rem;
}

.suggestions {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    width: 100%;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    box-shadow: var(--shadow-pop);
    max-height: 300px;
    overflow-y: auto;
    z-index: 10;
    padding: var(--s-1);
}

.suggestion-item {
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-sm);
    cursor: pointer;
    font-size: 0.94rem;
}

.suggestion-item:hover {
    background: var(--wine-tint);
}

/* --- Weinkacheln -------------------------------------------------------- */
/* Beim Tippen und Filtern wird der Block ausgetauscht; solange die Antwort
   unterwegs ist, tritt er einen Schritt zurueck. Kein Ladebalken: die Liste
   ist meist vor dem naechsten Tastendruck wieder da. */
.wine-results[aria-busy="true"] {
    opacity: 0.55;
}

.wine-results {
    transition: opacity 0.12s ease;
}

.wine-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: var(--s-4);
    margin-bottom: var(--s-5);
}

.wine-card {
    overflow: hidden;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}

.wine-card:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-pop);
    transform: translateY(-2px);
}

.wine-card a {
    text-decoration: none;
    color: inherit;
    display: block;
}

.wine-image {
    height: 210px;
    /* weiß statt getönt: die freigestellten Flaschen haben weißen Hintergrund
       und gehen so nahtlos in die Kachel über */
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s-3);
    border-bottom: 1px solid var(--border);
}

.wine-image img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    /* contain statt cover: eine hochformatige Flasche wurde sonst oben und
       unten abgeschnitten — genau das, was das Freistellen vermeiden soll */
    object-fit: contain;
}

.wine-info {
    padding: var(--s-3) var(--s-4) var(--s-4);
}

.wine-info h3 {
    font-size: 1rem;
    margin-bottom: 0.15rem;
    color: var(--wine-ink);
}

.vineyard {
    color: var(--ink-muted);
    font-size: 0.9rem;
}

/* Favorit in der Kachel — derselbe Stern wie auf der Weinseite. Vorher stand
   hier ein ⭐-Emoji, das iOS bunt und in Systemfarbe mitten in die Überschrift
   rendert. */
.card-fav {
    color: var(--gold);
    font-size: 0.9em;
}

/* Jahrgang, Sterne, Preis in einer Zeile — auf dem Handy ist die Kachel dafür
   zu schmal. Deshalb umbrechen die drei als Ganzes in die nächste Zeile,
   statt dass "6,49 €" mitten im Betrag auseinanderfällt. */
.wine-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-1) var(--s-2);
    margin-top: var(--s-3);
}

.wine-meta .rating {
    white-space: nowrap;
}

/* schiebt den Preis ans rechte Ende, auch wenn er allein in Zeile zwei steht */
.wine-meta .price {
    margin-left: auto;
    white-space: nowrap;
    font-weight: 600;
    color: var(--wine-ink);
}

.year {
    background: var(--surface-raised);
    color: var(--ink-muted);
    padding: 0.1rem 0.5rem;
    border-radius: var(--r-pill);
    font-size: 0.8rem;
}

/* Fraktionale Sterne (volle + halbe): grauer Grund, goldene Füllung per
   Breite geclippt. Genutzt via stars()-Makro (_macros.html). */
.rating,
.rating-stars {
    color: var(--gold);
}

.stars {
    position: relative;
    display: inline-block;
    white-space: nowrap;
    line-height: 1;
    letter-spacing: 0.02em;
}

.stars-base {
    color: #ddd6d8;
}

.stars-fill {
    position: absolute;
    left: 0;
    top: 0;
    overflow: hidden;
    color: var(--gold);
}

.tag-chip {
    background: var(--wine-tint);
    color: var(--wine-ink);
    border-radius: var(--r-pill);
    padding: 0.15rem 0.7rem;
    font-size: 0.8rem;
}

.wine-tags {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-1);
    margin: var(--s-4) 0;
}

/* Nachladen auf der Startseite: der Knopf ist auch der Anker für den
   IntersectionObserver, deshalb steht er als eigener Block unter dem Raster */
.load-more {
    display: block;
    margin: 0 auto var(--s-6);
}

.pagination {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--s-3);
    margin-top: var(--s-5);
}

.page-info {
    color: var(--ink-muted);
    font-size: 0.9rem;
}

/* --- Formulare ---------------------------------------------------------- */
.wine-form {
    padding: var(--s-5);
    max-width: 640px;
    margin: 0 auto;
}

.form-group {
    margin-bottom: var(--s-4);
}

.form-label {
    display: block;
    margin-bottom: var(--s-1);
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--ink);
}

.form-control {
    width: 100%;
    padding: 0 var(--s-3);
    min-height: 40px;
    font-size: 1rem;
}

/* Pflichtfeld leer abgeschickt (siehe Pruefung in main.js). Stand bis
   2026-08-01 als zur Laufzeit eingefuegtes <style>-Element in main.js. */
.form-control.error {
    border-color: var(--danger);
}

.form-control.error:focus {
    border-color: var(--danger);
    box-shadow: 0 0 0 3px rgba(179, 38, 30, 0.2);
}

textarea.form-control {
    padding: var(--s-2) var(--s-3);
    line-height: 1.5;
}

.form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-4);
}

.form-help {
    display: block;
    margin-top: var(--s-1);
    font-size: 0.85rem;
    color: var(--ink-faint);
}

.form-section-title {
    margin: var(--s-6) 0 var(--s-1);
    padding-top: var(--s-5);
    border-top: 1px solid var(--border);
    font-size: 1.05rem;
}

.form-section-help {
    margin-bottom: var(--s-4);
}

.form-actions {
    display: flex;
    gap: var(--s-2);
    justify-content: flex-end;
    margin-top: var(--s-6);
    padding-top: var(--s-4);
    border-top: 1px solid var(--border);
}

/* Formular als Zeile (Benutzerverwaltung, Passwort setzen) */
.inline-form {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    align-items: center;
}

/* Bildauswahl */
.image-upload {
    position: relative;
}

.file-input {
    display: none;
}

.file-label {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: var(--s-5);
    border: 1px dashed var(--border-strong);
    border-radius: var(--r);
    background: var(--surface-sunken);
    color: var(--ink-muted);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
    min-height: 120px;
}

.file-label:hover {
    border-color: var(--wine);
    background: var(--wine-tint);
    color: var(--wine-ink);
}

/* Strich-Icon statt Emoji: ein 📷 rendert iOS bunt und in Systemfarbe,
   mitten in eine Flaeche, die sonst ganz in --ink-muted gehalten ist. */
.file-icon {
    width: 1.5rem;
    height: 1.5rem;
    flex: 0 0 auto;
}

.image-preview {
    margin-top: var(--s-3);
}

.image-preview img,
.current-image img {
    border-radius: var(--r);
    border: 1px solid var(--border);
}

.image-preview img {
    max-height: 300px;
}

.current-image {
    margin-bottom: var(--s-3);
}

.current-image img {
    max-width: 180px;
}

/* Interaktives Halbstern-Widget (add/edit, siehe wines/_rating_input.html) */
.star-input {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    flex-wrap: wrap;
}

.star-input-track {
    position: relative;
    display: inline-block;
    font-size: 1.8rem;
    line-height: 1;
    letter-spacing: 0.1em;
    cursor: pointer;
    user-select: none;
    touch-action: manipulation;
}

/* 10 unsichtbare Halb-Stern-Klickzonen liegen über den Sternen */
.star-input-track .star-seg {
    position: absolute;
    top: 0;
    height: 100%;
    width: 10%;
    padding: 0;
    margin: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    z-index: 2;
}

.star-input-track .star-seg:nth-child(3)  { left: 0%; }
.star-input-track .star-seg:nth-child(4)  { left: 10%; }
.star-input-track .star-seg:nth-child(5)  { left: 20%; }
.star-input-track .star-seg:nth-child(6)  { left: 30%; }
.star-input-track .star-seg:nth-child(7)  { left: 40%; }
.star-input-track .star-seg:nth-child(8)  { left: 50%; }
.star-input-track .star-seg:nth-child(9)  { left: 60%; }
.star-input-track .star-seg:nth-child(10) { left: 70%; }
.star-input-track .star-seg:nth-child(11) { left: 80%; }
.star-input-track .star-seg:nth-child(12) { left: 90%; }

.star-input-label {
    color: var(--ink-muted);
    font-size: 0.9rem;
    min-width: 6.5em;
}

.star-clear {
    background: none;
    border: none;
    color: var(--ink-faint);
    text-decoration: underline;
    cursor: pointer;
    font-size: 0.85rem;
    padding: 0;
}

/* --- Tabellen ----------------------------------------------------------- */
.users-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: var(--s-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    overflow: hidden;
}

.users-table th,
.users-table td {
    text-align: left;
    padding: var(--s-2) var(--s-3);
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.users-table tr:last-child td {
    border-bottom: none;
}

.users-table th {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ink-faint);
    font-weight: 600;
    background: var(--surface-sunken);
}

/* --- Meldungen ---------------------------------------------------------- */
.alerts {
    max-width: var(--content-width);
    margin: 0 auto var(--s-4);
}

.alert {
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r);
    margin-bottom: var(--s-2);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-3);
    font-size: 0.94rem;
    border: 1px solid transparent;
}

.alert-success {
    background: var(--success-bg);
    color: var(--success-ink);
    border-color: #c8e3d3;
}

/* Hinweis, kein Fehler: der Wein ist gespeichert, es gibt nur etwas zu wissen */
.alert-warning {
    background: #fdf6e8;
    color: #6b4b12;
    border-color: #efdcb4;
}

.alert-error {
    background: var(--error-bg);
    color: var(--error-ink);
    border-color: #f0cdc9;
}

.alert-close {
    background: none;
    border: none;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    color: inherit;
    opacity: 0.6;
    padding: var(--s-1);
}

.alert-close:hover {
    opacity: 1;
}

/* ------------------------------------------------------------- 5 Seiten */

/* --- Weinseite ---------------------------------------------------------- */
.wine-detail {
    overflow: hidden;
    display: grid;
    /* Text bekommt mehr Platz als das Bild — die Angaben sind der Inhalt */
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
}

.wine-detail-image {
    padding: var(--s-5);
    background: var(--surface-sunken);
    border-right: 1px solid var(--border);
}

/* aspect-ratio steht, bevor das Bild da ist — sonst rutscht beim Öffnen aus
   dem Feed der ganze Text nach unten, sobald das JPEG ankommt. Flaschenfotos
   sind hochkant; ein Querformat bekommt durch `contain` nur mehr Rand, es
   verliert nichts. */
.detail-image {
    width: 100%;
    aspect-ratio: 3 / 4;
    max-height: 560px;
    object-fit: contain;
    border-radius: var(--r-sm);
}

/* Umschalter freigestellte Flasche <-> Originalfoto */
.image-toggle {
    position: relative;
}

.image-toggle-btn {
    position: absolute;
    top: var(--s-2);
    right: var(--s-2);
    padding: 0.3rem 0.7rem;
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 500;
    color: #fff;
    background: rgba(43, 34, 38, 0.6);
    border: none;
    border-radius: var(--r-pill);
    cursor: pointer;
    backdrop-filter: blur(3px);
    transition: background 0.15s ease;
}

.image-toggle-btn:hover {
    background: rgba(43, 34, 38, 0.85);
}

/* Statusstreifen für alles, was im Hintergrund läuft: die Läufe auf der
   Weinseite (static/js/wine-status.js) und das Nachschlagen auf der
   Scan-Seite (static/js/scan.js). Ruhig und textlich — kein Spinner: die
   Aussage ist nicht "gleich fertig", sondern "es passiert etwas". */
.wine-status {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    margin-bottom: var(--s-4);
    padding: var(--s-3) var(--s-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--wine);
    border-radius: var(--r);
    font-size: 0.9rem;
    color: var(--ink-muted);
}

.wine-status-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--wine);
}

.wine-status.is-running .wine-status-dot {
    animation: puls 1.6s ease-in-out infinite;
}

.wine-status.is-done {
    border-left-color: var(--gold);
}

.wine-status.is-done .wine-status-dot {
    background: var(--gold);
}

.wine-status .btn {
    margin-left: auto;
}

@keyframes puls {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.25; }
}

/* Die einzige Bewegung der App — und sie ist abschaltbar. */
@media (prefers-reduced-motion: reduce) {
    .wine-status.is-running .wine-status-dot {
        animation: none;
    }

    /* Der Seitenwechsel passiert weiterhin, nur ohne Bewegung */
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }

    * {
        transition-duration: 0.01ms !important;
    }
}

/* Rücketikett zugeklappt — auf dem Handy schob es sonst alles Lesbare
   unter den Bildschirmrand */
.back-label {
    margin-top: var(--s-3);
}

.back-label > summary,
.purchase-header,
.shared-details summary {
    cursor: pointer;
    list-style: none;
}

.back-label > summary::-webkit-details-marker,
.purchase-header::-webkit-details-marker { display: none; }

.back-label > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--s-1);
    color: var(--wine);
    font-size: 0.9rem;
    padding: var(--s-1) 0;
}

.back-label .detail-image {
    margin-top: var(--s-2);
}

.cutout-form {
    margin-top: var(--s-3);
}

.wine-detail-info {
    padding: var(--s-5);
    min-width: 0;
}

/* Weinname mit Favoriten-Stern: das Formular ist nur Transportmittel */
.wine-title {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    flex-wrap: wrap;
    margin-bottom: 0.15rem;
}

.wine-title form {
    display: inline-flex;
}

.favorite-star {
    background: none;
    border: none;
    padding: 0;
    line-height: 1;
    font-size: 1.5rem;
    color: #cfc5c8;              /* leer: nur angedeutet */
    cursor: pointer;
    transition: color 0.15s ease, transform 0.15s ease;
}

.favorite-star:hover {
    color: var(--gold);
    transform: scale(1.08);
}

.favorite-star.is-favorite {
    color: var(--gold);
}

.wine-detail-info h2.vineyard {
    font-size: 1.05rem;
    font-weight: 400;
    margin-bottom: var(--s-5);
}

/* Weingut führt zur gefilterten Liste */
.vineyard a {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted var(--border-strong);
}

.vineyard a:hover {
    color: var(--wine);
    border-bottom-color: currentColor;
}

.wine-specs {
    margin-bottom: var(--s-5);
}

.spec-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-4);
    padding: var(--s-2) 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.94rem;
}

.spec-item:last-child {
    border-bottom: none;
}

.spec-label {
    color: var(--ink-muted);
    flex: 0 0 auto;
}

.spec-value {
    text-align: right;
    min-width: 0;
}

/* Bewerten in der Angabenliste. Die Zeile darf höher sein als die anderen:
   die Sterne sind hier nicht nur Anzeige, sondern die Eingabe. */
.spec-item-rate {
    align-items: center;
}

.rate-form {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: var(--s-3);
}

.rate-form .star-input {
    gap: var(--s-3);
}

/* Feste Breite, und zwar so breit wie der längste Text („noch nicht
   bewertet"). Beim Darüberfahren wechselt die Beschriftung auf „3,5 / 5" —
   ohne feste Breite schrumpft sie dabei, der Rest der Zeile rutscht nach und
   der Speichern-Knopf springt sogar in die nächste Zeile und zurück. */
.rate-form .star-input-label {
    min-width: 10.5em;
    text-align: right;
}

/* Bon-Link in den lpg-Tracker: der Hinweis erklärt, warum er unterwegs
   ins Leere läuft — lpg hat keine Domain, nur die LAN-IP. */
.lpg-hint {
    display: block;
    color: var(--ink-faint);
    font-size: 0.75rem;
}

.wine-notes {
    margin: var(--s-5) 0;
}

.wine-notes h3 {
    margin-bottom: var(--s-1);
}

.wine-notes p {
    color: var(--ink);
}

/* Der Wortlaut vom Etikett unter einer Übersetzung. Bewusst leise: Gelesen
   wird die deutsche Fassung darüber, das Original ist der Beleg zum
   Nachschlagen. */
.wine-notes .original {
    margin-top: var(--s-2);
}

.wine-notes .original > summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: var(--s-1);
    color: var(--wine);
    font-size: 0.85rem;
    padding: var(--s-1) 0;
}

.wine-notes .original > summary::-webkit-details-marker { display: none; }

.wine-notes .original > summary::before {
    content: "▸";
    font-size: 0.7em;
}

.wine-notes .original[open] > summary::before {
    content: "▾";
}

.wine-notes .original p {
    color: var(--ink-muted);
    font-size: 0.92rem;
    font-style: italic;
    border-left: 2px solid var(--border);
    padding-left: var(--s-3);
}

/* Kaufhistorie: Wine.price ist der letzte Preis, hier steht der Verlauf */
.wine-purchases {
    margin: var(--s-5) 0;
}

/* Überschrift links, Aufklapp-Knopf rechts. Das <summary> ist der Knopf. */
.purchase-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
}

/* Beschriftung wechselt beim Aufklappen — ohne eine Zeile JavaScript */
.purchase-add-btn .when-open,
.purchase-add[open] .purchase-add-btn .when-closed {
    display: none;
}

.purchase-add[open] .purchase-add-btn .when-open {
    display: inline;
}

.purchase-list {
    list-style: none;
    margin: var(--s-2) 0 0;
    padding: 0;
}

.purchase-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--s-2);
    padding: var(--s-2) 0;
    border-bottom: 1px solid var(--border);
    font-size: 0.94rem;
}

.purchase-list li:last-child {
    border-bottom: none;
}

.purchase-price {
    font-weight: 600;
    color: var(--wine-ink);
    min-width: 4.5rem;
}

.purchase-meta,
.purchase-empty {
    color: var(--ink-muted);
    font-size: 0.875rem;
}

.purchase-form {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-3);
    padding: var(--s-3);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--r);
}

.purchase-form .form-control {
    width: auto;
    flex: 1 1 8rem;
}

/* Bearbeiten / Löschen: gleich breit, aber nicht gleich laut */
.wine-actions {
    display: flex;
    gap: var(--s-2);
    flex-wrap: wrap;
    padding-top: var(--s-4);
    border-top: 1px solid var(--border);
}

.wine-actions > * {
    flex: 1 1 8rem;
    margin: 0;
}

.wine-actions .btn {
    width: 100%;
}

/* Teilen-Kasten */
.share-box {
    margin-top: var(--s-5);
    padding: var(--s-3);
    background: var(--surface-sunken);
    border: 1px solid var(--border);
    border-radius: var(--r);
}

.share-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}

.share-url {
    flex: 1 1 14rem;
    min-width: 0;
    padding: 0 var(--s-2);
    min-height: 32px;
    font-size: 0.82rem;
    background: var(--surface);
    color: var(--ink-muted);
}

.share-hint {
    margin: var(--s-2) 0 0;
    font-size: 0.8rem;
    color: var(--ink-faint);
}

/* --- Scan-Seite (/scannen) ----------------------------------------------
   Wird im Supermarkt mit einer Hand bedient, oft mit der Flasche in der
   anderen: eine schmale Spalte, große Tippflächen, und alles Wichtige
   (Urteil, Bewertung, Preis) ohne Scrollen im Blick. */
.scan-page {
    max-width: 460px;
}

.scan-titel {
    font-size: 1.35rem;
    margin-bottom: var(--s-4);
}

.scan-ergebnis {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--wine);
    border-radius: var(--r);
    padding: var(--s-4);
    margin-bottom: var(--s-5);
}

/* Noch nicht getrunken ist keine schlechte Nachricht, nur eine andere —
   deshalb dieselbe Karte, nur ohne die kräftige Kante. */
.scan-nein {
    border-left-color: var(--border-strong);
}

.scan-kicker {
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0 0 var(--s-2);
}

.scan-wein {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    color: inherit;
    text-decoration: none;
}

.scan-wein img {
    flex: 0 0 auto;
    width: 64px;
    height: 84px;
    object-fit: contain;
    background: var(--surface-raised);
    border-radius: var(--r-sm);
}

.scan-wein-text {
    min-width: 0;
}

.scan-name {
    display: block;
    font-weight: 600;
    color: var(--wine-ink);
    font-size: 1.05rem;
    line-height: 1.3;
}

.scan-meta {
    display: block;
    color: var(--ink-muted);
    font-size: 0.88rem;
    margin: var(--s-1) 0 0;
}

.scan-bewertung {
    margin: var(--s-3) 0 0;
    font-size: 1.3rem;
}

.scan-notiz {
    margin: var(--s-2) 0 0;
    color: var(--ink);
    font-size: 0.92rem;
}

.scan-preis {
    margin: var(--s-3) 0 0;
    color: var(--ink-muted);
}

.scan-preis-haupt {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--ink);
}

.scan-preis-datum {
    color: var(--ink-faint);
}

.scan-preis-hinweis {
    margin: var(--s-1) 0 0;
    font-size: 0.85rem;
    color: var(--ink-faint);
}

/* Anhaltspunkte zu einem Wein, den die Sammlung nicht kennt: abgesetzt durch
   eine Linie, nicht durch eine zweite Karte — es ist der Nachsatz zum Urteil
   darüber und keine eigene Auskunft. */
.scan-anhalt {
    margin-top: var(--s-4);
    padding-top: var(--s-3);
    border-top: 1px solid var(--border);
}

.scan-anhalt-titel {
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0 0 var(--s-2);
}

.scan-anhalt-zeile {
    margin: var(--s-2) 0 0;
    font-size: 0.9rem;
    color: var(--ink-muted);
}

.scan-anhalt-zeile strong {
    color: var(--ink);
}

.scan-anhalt-liste {
    list-style: none;
    margin: var(--s-2) 0 0;
    padding: 0;
}

.scan-anhalt-liste li {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--s-2);
    padding: var(--s-1) 0;
    font-size: 0.92rem;
}

/* Die Sterne stehen hier neben Text und nicht in einer Kachel — ohne die
   kleinere Schrift überragen sie die Zeile. */
.scan-anhalt-liste .stars {
    font-size: 0.8rem;
}

.scan-anhalt-preis {
    margin-left: auto;
    color: var(--ink-faint);
    font-size: 0.85rem;
}

.scan-aktionen {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-4);
}

.scan-zweifel {
    margin: var(--s-3) 0 0;
    font-size: 0.82rem;
    color: var(--ink-faint);
}

/* Die Kamera ist die Hauptaktion der Seite und darf entsprechend groß sein. */
.scan-form .file-label {
    min-height: 108px;
}

.scan-form .wine-status {
    margin: var(--s-3) 0 0;
}

.scan-hilfe {
    margin-top: var(--s-3);
    font-size: 0.82rem;
    color: var(--ink-faint);
    text-align: center;
}

/* --- Anmeldeseite (eigenes Layout, ohne Navigation) --------------------- */
.login-wrap {
    max-width: 360px;
    margin: 10vh auto;
    padding: var(--s-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
}

.login-logo {
    text-align: center;
    margin-bottom: var(--s-3);
}

.login-logo img {
    height: 96px;
    width: auto;
}

.login-wrap h1 {
    text-align: center;
    font-size: 1.35rem;
    margin-bottom: var(--s-5);
}

.login-or {
    text-align: center;
    margin: var(--s-4) 0;
    color: var(--ink-faint);
    font-size: 0.85rem;
}

/* --- Fehlerseiten ------------------------------------------------------
   Teilen sich den zentrierten Aufbau mit der Empfehlungsseite (.shared-page),
   sind aber schmaler und ruhiger: hier gibt es nichts anzusehen, nur etwas
   zu verstehen. */
.error-card {
    width: 100%;
    max-width: 420px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--s-6) var(--s-5);
    text-align: center;
}

.error-logo {
    height: 64px;
    width: auto;
    opacity: 0.35;
    margin-bottom: var(--s-4);
}

.error-card h1 {
    font-size: 1.3rem;
    margin-bottom: var(--s-2);
}

.error-text {
    color: var(--ink-muted);
}

.error-hint {
    margin-top: var(--s-2);
    font-size: 0.85rem;
    color: var(--ink-faint);
}

.error-card .btn {
    margin-top: var(--s-5);
}

/* --- Öffentliche Weinempfehlung (/s/<token>) ---------------------------- */
.shared-page {
    background: var(--surface-sunken);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s-5) var(--s-4);
}

.shared-card {
    width: 100%;
    max-width: 460px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    overflow: hidden;
    box-shadow: var(--shadow-pop);
}

.shared-image {
    background: #fff;
    padding: var(--s-5) var(--s-5) 0;
    text-align: center;
}

.shared-image img {
    width: 100%;
    aspect-ratio: 3 / 4;
    max-height: 330px;
    object-fit: contain;
}

.shared-body {
    padding: var(--s-5);
}

.shared-kicker {
    font-size: 0.72rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-faint);
    margin: 0 0 var(--s-1);
}

.shared-card h1 {
    font-size: 1.4rem;
    margin: 0 0 0.15rem;
}

.shared-vineyard {
    color: var(--ink-muted);
    margin: 0 0 var(--s-3);
}

.shared-rating {
    font-size: 1.1rem;
    color: var(--gold);
    margin: 0 0 var(--s-4);
    letter-spacing: 0.06em;
}

.shared-rating-num {
    font-size: 0.82rem;
    color: var(--ink-faint);
    margin-left: var(--s-1);
    letter-spacing: normal;
}

.shared-notes {
    margin: 0 0 var(--s-4);
    padding: var(--s-3);
    border-left: 3px solid var(--wine-tint-strong);
    background: var(--surface-sunken);
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    font-style: italic;
    color: var(--ink);
}

.shared-facts {
    margin: 0 0 var(--s-4);
}

.shared-fact {
    display: flex;
    gap: var(--s-3);
    padding: var(--s-2) 0;
    border-bottom: 1px solid var(--border);
}

.shared-fact:last-child {
    border-bottom: none;
}

.shared-fact dt {
    flex: 0 0 33%;
    color: var(--ink-muted);
    font-size: 0.86rem;
    margin: 0;
}

.shared-fact dd {
    margin: 0;
    font-size: 0.9rem;
}

.shared-details {
    margin-bottom: var(--s-4);
    font-size: 0.88rem;
    color: var(--ink);
}

.shared-details summary {
    color: var(--wine);
    font-weight: 500;
}

.shared-details p {
    margin: var(--s-2) 0 0;
}

.shared-nutrition {
    color: var(--ink-muted);
}

.shared-footer {
    margin: 0;
    font-size: 0.78rem;
    color: var(--ink-faint);
    text-align: center;
}

/* -------------------------------------------------------- 6 Hilfsklassen */

/* läuft gerade ab: gedimmt, aber mit unveränderter Beschriftung */
.is-loading {
    opacity: 0.6;
    cursor: progress;
}

/* nur für Screenreader — die Felder erklären sich über ihre Platzhalter */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.muted {
    color: var(--ink-muted);
}

.stack-top {
    margin-top: var(--s-6);
}

/* ------------------------------------------- 7 Schmale Bildschirme */
@media (max-width: 860px) {
    .wine-detail {
        grid-template-columns: 1fr;
    }

    .wine-detail-image {
        border-right: none;
        border-bottom: 1px solid var(--border);
    }
}

@media (max-width: 768px) {
    .nav-menu {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: var(--surface);
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: var(--s-2);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--shadow-pop);
    }

    .nav-menu.active {
        display: flex;
    }

    .nav-link {
        padding: var(--s-3);
    }

    .nav-toggle {
        display: flex;
    }

    .wine-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: var(--s-3);
    }

    .wine-image {
        height: 170px;
    }

    /* schmale Kachel: Sterne und Preis eine Spur kleiner, damit Jahrgang,
       Bewertung und Preis meist noch nebeneinander passen */
    .wine-meta {
        font-size: 0.9rem;
    }

    .form-row {
        grid-template-columns: 1fr;
    }

    .page-header {
        flex-wrap: wrap;
    }

    .filter-input {
        flex: 1 1 100px;
        width: auto;
    }
}

@media (max-width: 480px) {
    .main-content {
        padding: var(--s-4) var(--s-3);
    }

    h1 { font-size: 1.4rem; }

    .wine-form,
    .wine-detail-image,
    .wine-detail-info,
    .prose {
        padding: var(--s-4);
    }

    .form-actions {
        flex-direction: column-reverse;
    }

    .form-actions .btn {
        width: 100%;
    }
}
