/* ===========================================================================
   bestes-wetter.de — global styles
   ---------------------------------------------------------------------------
   Lives at wwwroot/css/site.css, loaded once from App.razor.
   Component-scoped styles live next to their .razor file as .razor.css
   (Blazor's scoped-CSS pipeline rewrites class selectors with a unique
   attribute so they can't leak). Only truly global rules belong here:
   typography reset, brand custom-props, .container, link defaults.
   =========================================================================== */

/* ---- Fonts (loaded from Google Fonts in App.razor for simplicity;
        swap for self-hosted .woff2 once the site is live for an extra
        ~50ms LCP win) ----------------------------------------------------- */

/* ---- CSS custom properties (brand tokens) ------------------------------ */
:root {
    /* Brand palette: forest-green / earth-brown / sand. Soft, outdoor, no
       SaaS-startup vibes. */
    --bw-brand:        #2d5a3d;    /* fir green */
    --bw-brand-dark:   #1f4029;
    --bw-brand-soft:   #e6efe8;    /* tinted backgrounds, accent banners */
    --bw-earth:        #8b6f47;    /* secondary accent (price boxes etc.) */
    --bw-earth-soft:   #f1ead9;

    /* Surfaces */
    --bw-bg:           #fbf8f3;    /* page background — warm sand */
    --bw-bg-muted:     #f3eee5;    /* card / footer / muted blocks */
    --bw-surface:      #ffffff;    /* article cards, drawers */

    /* Text */
    --bw-fg:           #1d1f1c;    /* near-black, slight warmth */
    --bw-fg-soft:      #4a4f48;
    --bw-fg-muted:     #6f7468;

    /* Lines */
    --bw-border:       #d8d2c4;
    --bw-radius:       4px;
    --bw-radius-lg:    8px;

    /* Typography */
    --bw-font-sans:    'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --bw-font-serif:   'Source Serif 4', 'Source Serif Pro', Georgia, 'Times New Roman', serif;
    --bw-font-mono:    ui-monospace, SFMono-Regular, 'Cascadia Mono', Consolas, monospace;

    /* Layout */
    --bw-container:    1180px;
}

/* ---- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    font-family: var(--bw-font-sans);
    font-size: 17px;
    line-height: 1.5;
    color: var(--bw-fg);
    background: var(--bw-bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--bw-font-serif);
    color: var(--bw-fg);
    line-height: 1.2;
    letter-spacing: -.005em;
}

p { margin: 0 0 1em; }

a {
    color: var(--bw-brand-dark);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}
a:hover { color: var(--bw-brand); }

img { max-width: 100%; height: auto; display: block; }

blockquote {
    margin: 1.5em 0;
    padding: .8em 1.2em;
    border-left: 3px solid var(--bw-brand);
    background: var(--bw-brand-soft);
    color: var(--bw-fg-soft);
    font-style: italic;
}

code, pre, kbd, samp {
    font-family: var(--bw-font-mono);
    font-size: .92em;
}
pre {
    background: var(--bw-bg-muted);
    border: 1px solid var(--bw-border);
    border-radius: var(--bw-radius);
    padding: .9em 1.1em;
    overflow-x: auto;
}

hr {
    border: 0;
    border-top: 1px solid var(--bw-border);
    margin: 2em 0;
}

/* ---- Layout helpers ----------------------------------------------------- */

.container {
    max-width: var(--bw-container);
    margin: 0 auto;
    padding: 0 1.25rem;
}

/* ---- Focus styles ------------------------------------------------------- */

:focus-visible {
    outline: 2px solid var(--bw-brand);
    outline-offset: 2px;
    border-radius: 2px;
}

/* Programmatically-focused, non-interactive targets — the <h1> that
   FocusOnNavigate focuses after every navigation, skip-link anchors, etc.
   carry tabindex="-1". The focus is purely for screen-reader / keyboard
   landing; a visible ring on a huge hero headline just looks like a stray
   border. Interactive controls (links, buttons, inputs) have no tabindex
   or a non-negative one, so they keep their :focus-visible ring. */
[tabindex="-1"]:focus { outline: none; }

/* ---- Gallery + lightbox -------------------------------------------------
   The :::gallery shortcode renders into an article body via MarkupString,
   so its markup is NOT under the scoped-CSS pipeline — these rules have to
   be global. Same for the lightbox overlay, which lightbox.js appends
   straight to <body>. ----------------------------------------------------- */

.bw-gallery__btn {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    cursor: zoom-in;
}
.bw-gallery__btn img {
    width: 100%;
    height: auto;
    /* Drop the 4/3 cover crop — Pixel/iPhone shots come in landscape AND
       portrait, and forcing 4/3 chopped portraits' top+bottom off (~33%
       loss). Now: keep the photo's native aspect ratio, just constrain
       max-height so portraits don't tower over neighbouring landscapes
       in the grid. Grid rows will have varying heights — better than
       cropped pictures. */
    max-height: 320px;
    object-fit: contain;
    border-radius: var(--bw-radius);
    transition: transform .15s ease-out;
    background: var(--bw-bg-muted);
}
.bw-gallery__btn:hover img { transform: scale(1.02); }
.bw-gallery__item { margin: 0; }
.bw-gallery__item figcaption {
    margin-top: .3rem;
    font-size: .78rem;
    color: var(--bw-fg-muted);
    font-family: var(--bw-font-mono);
    line-height: 1.4;
    /* Caption ist als Block so breit wie die längste Zeile (max-content),
       per margin:auto im Container zentriert, der Text selbst läuft links.
       Damit beginnen Folgezeilen bei mehrzeiligen Captions linksbündig
       unter der ersten Zeile — sieht ruhiger aus als reine Zentrierung,
       die jede Zeile separat mittig setzt. */
    width: max-content;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    text-align: left;
}

.bw-lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    background: rgba(15, 18, 14, .92);
}
.bw-lightbox[hidden] { display: none; }
.bw-lightbox__figure {
    margin: 0;
    max-width: 95vw;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .6rem;
}
.bw-lightbox__img {
    max-width: 100%;
    max-height: 80vh;
    object-fit: contain;
    border-radius: var(--bw-radius);
}
.bw-lightbox__cap {
    color: #e8e2d2;
    font-family: var(--bw-font-mono);
    font-size: .85rem;
    text-align: center;
}
.bw-lightbox__close {
    position: absolute;
    top: 1rem;
    right: 1.2rem;
    width: 2.4rem;
    height: 2.4rem;
    font-size: 1.8rem;
    line-height: 1;
    color: #fff;
    background: rgba(255,255,255,.12);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
}
.bw-lightbox__close:hover { background: rgba(255,255,255,.25); }

/* Prev/Next-Pfeile innerhalb der Lightbox. Bei Single-Image-Lightboxes
   blendet das JS sie per [hidden] aus; am Anfang/Ende werden sie via
   [disabled] visuell abgesenkt. Größere Touch-Targets via padding +
   transparenter Border, damit man auch auf Mobile gut trifft, ohne
   dass die sichtbare Fläche aufdringlich wird. */
.bw-lightbox__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 3rem;
    height: 3rem;
    font-size: 2.2rem;
    line-height: 1;
    color: #fff;
    background: rgba(255, 255, 255, .12);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    /* Slight inset so the buttons don't sit on the very edge — easier to
       hit on touch and visually clearer that they're inside the dialog. */
}
.bw-lightbox__nav--prev { left: 1rem; }
.bw-lightbox__nav--next { right: 1rem; }
.bw-lightbox__nav:hover { background: rgba(255, 255, 255, .25); }
.bw-lightbox__nav[disabled] {
    opacity: .25;
    cursor: default;
}
.bw-lightbox__nav[hidden] { display: none; }

/* Auf schmalen Bildschirmen Pfeile etwas kompakter, damit sie nicht den
   Bildinhalt überdecken. */
@media (max-width: 480px) {
    .bw-lightbox__nav {
        width: 2.4rem;
        height: 2.4rem;
        font-size: 1.6rem;
    }
    .bw-lightbox__nav--prev { left: .4rem; }
    .bw-lightbox__nav--next { right: .4rem; }
}

/* ---- Cookie-Consent (Foundation-Komponente) -------------------------------
   Die Komponente wird in App.razor außerhalb von <Routes> gerendert und
   liegt damit ausserhalb der scoped-CSS-Welt. Daher hier global. Klassen-
   namen sind die der Foundation-Komponente — bitte beim Update auf neue
   Foundation-Versionen prüfen. ---------------------------------------------- */

.cookie-consent {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    background: var(--bw-fg);
    color: #f4f1e8;
    z-index: 80;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, .18);
}
.cookie-consent__inner {
    display: flex;
    gap: 1.5rem;
    align-items: center;
    padding: 1rem 0;
    flex-wrap: wrap;
}
.cookie-consent__copy { flex: 1; min-width: 280px; }
.cookie-consent__heading {
    font-family: var(--bw-font-serif);
    font-size: 1.1rem;
    margin: 0 0 .3rem;
    color: #fff;
}
.cookie-consent__body { margin: 0; font-size: .9rem; line-height: 1.45; }
.cookie-consent__body a { color: #d0e7d6; }
.cookie-consent__body a:hover { color: #fff; }

.cookie-consent__actions {
    display: flex;
    gap: .6rem;
    flex-shrink: 0;
}
.cookie-consent__btn {
    font: inherit;
    padding: .55rem 1.1rem;
    border-radius: var(--bw-radius);
    cursor: pointer;
    border: 1px solid transparent;
}
.cookie-consent__btn--accept {
    background: var(--bw-brand);
    color: #fff;
}
.cookie-consent__btn--accept:hover { background: var(--bw-brand-dark); }
.cookie-consent__btn--reject {
    background: transparent;
    color: #f4f1e8;
    border-color: rgba(255, 255, 255, .4);
}
.cookie-consent__btn--reject:hover { border-color: #fff; }

/* ---- Tour map (Leaflet canvas) ---------------------------------------------
   Shared between the single-tour <TourMap> and the multi-day <TourOverview>:
   both render canvases with .tour-map__canvas, so scoped CSS in one of the
   .razor.css files would only style one of them. The legend below the map
   is injected at runtime by tour-map.js, also without a scope attribute.
   --------------------------------------------------------------------------- */

/* `isolation: isolate` creates a new stacking context, scoping Leaflet's
   own z-indices (200–1000 across its panes and controls) to inside the
   map. Without it, the tile-pane and overlay-pane would punch through the
   sticky SiteHeader (z-index 50) on scroll. */
.tour-map {
    margin: 1.5rem 0;
    position: relative;
    isolation: isolate;
}

.tour-map__canvas {
    width: 100%;
    height: 360px;
    border-radius: var(--bw-radius-lg);
    overflow: hidden;
    background: var(--bw-bg-muted);
    border: 1px solid var(--bw-border);
    position: relative;
}

/* Smaller variant used inside the :::leg block, so the per-day map doesn't
   dominate the per-day card. Still tall enough to read on mobile (where it
   becomes effectively full-width). */
.tour-map__canvas--small { height: 240px; }

/* Auto-loading variant: empty canvas before tour-map.js takes over. A subtle
   pulsing gradient acts as a loading hint without needing a spinner. Leaflet
   replaces the background with tile imagery within a few hundred ms — on
   fast networks the pulse barely shows; on slow ones it stops looking like
   a broken empty box. */
.tour-map__canvas--auto {
    background:
        linear-gradient(135deg, var(--bw-bg-muted) 0%, #ece6d8 50%, var(--bw-bg-muted) 100%);
    background-size: 200% 200%;
    animation: tour-map-pulse 2.4s ease-in-out infinite;
}
.tour-map__canvas--auto[data-map-ready="1"] {
    animation: none;
    background: transparent;
}

@keyframes tour-map-pulse {
    0%, 100% { background-position: 0%   50%; }
    50%      { background-position: 100% 50%; }
}

/* Reset-Button (top-right Leaflet-Control). Sitzt im äußeren <div
   class="leaflet-bar leaflet-control"> wie Leaflets eigener Zoom-Control,
   bekommt also weißen Hintergrund + Border + Hover-Style aus leaflet.css.
   Wir tunen hier nur das Crosshair-Glyph: leicht größer als die ±-Zoom-
   Buttons, damit es lesbar bleibt, und farblich abgesenkt, damit es im
   Ruhezustand nicht aufdringt. `a.tour-map__reset` schlägt die Default-
   Link-Farbe (rgb(0,120,168) auf <a>). Explizite 30×30: Leaflet stylt
   .leaflet-bar a nur per Selektoren auf .leaflet-touch — auf Desktop
   bleibt das <a> sonst auf text-width zusammen (12 px Crosshair-Glyph). */
.leaflet-bar a.tour-map__reset {
    width: 30px;
    height: 30px;
    font-size: 18px;
    line-height: 30px;
    text-align: center;
    color: var(--bw-fg-soft);
}
.leaflet-bar a.tour-map__reset:hover {
    color: var(--bw-fg);
}

/* ---- Multi-leg tour blocks -------------------------------------------------
   :::leg shortcodes render straight into the article body via MarkupString
   and the tour-map.js legend is appended at runtime — both are outside the
   scoped-CSS world, so the styles live here. ------------------------------ */

.bw-leg {
    margin: .8rem 0 1.8rem;
    padding: .8rem 1rem 1rem;
    background: var(--bw-bg-muted);
    border-left: 3px solid var(--bw-brand);
    border-radius: var(--bw-radius);
    /* Fragment-Links aus der Tour-Uebersicht springen auf diesen Block.
       Direkt davor steht im Markdown-Body eine <h3> mit dem Etappen-
       Namen ("### Tag 5 — ..."); die id sitzt aber technisch auf dem
       Block selbst, nicht auf der Heading. Ohne grosszuegigen Scroll-
       Margin wuerde die <h3> beim Sprung oberhalb des Viewports
       landen und der Nutzer haette nur noch den Body ohne Titel.
       160px deckt sticky SiteHeader (~70px) + h3 mit Default-Margin
       (~90px) ab. */
    scroll-margin-top: 160px;
}
.bw-leg__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem 1.4rem;
}
.bw-leg__stats {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem 1rem;
    font-family: var(--bw-font-mono);
    font-size: .95rem;
    color: var(--bw-fg);
    flex: 1 1 auto;
}
.bw-leg__stat { white-space: nowrap; }
.bw-leg__map { margin: .9rem 0 0; }

/* Per-etappe lead photo — the one with lead="1" for this leg, hoisted out
   of the gallery and shown big at the top of the :::leg block. Clicks open
   in the same lightbox as the gallery items. */
.bw-leg__lead {
    margin: 0 -1rem 1rem;   /* pull to the edge of the .bw-leg padding */
}
.bw-leg__lead .bw-gallery__btn { cursor: zoom-in; }
.bw-leg__lead img {
    /* `object-fit: contain` so portrait shots aren't chopped — landscapes
       still get the full edge-to-edge look, portraits are centred with
       letterboxing on either side. */
    width: 100%;
    height: auto;
    max-height: 480px;
    object-fit: contain;
    border-radius: 0;
    display: block;
    background: var(--bw-bg-muted);
}
.bw-leg__lead figcaption {
    padding: .4rem 1rem 0;
    font-family: var(--bw-font-mono);
    font-size: .82rem;
    color: var(--bw-fg-muted);
    line-height: 1.4;
    /* Siehe Kommentar bei .bw-gallery__item figcaption — gleiches Schema:
       zentriert als Box, linksbündig im Text. */
    width: max-content;
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    text-align: left;
}

/* Per-leg photo gallery — same .bw-gallery markup as the :::gallery
   shortcode, just slightly tighter spacing and a smaller grid so the
   photos look like a per-day strip, not a hero block. */
.bw-leg__gallery {
    margin-top: .9rem;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: .5rem;
}
.bw-leg__gallery .bw-gallery__item { margin: 0; }
/* Don't constrain height further than the global .bw-gallery__btn img rule
   (320px) — the earlier 220-px cap stuffed a 2:3 portrait into a strip-
   thin letterbox. Portraits now stand a little taller than their landscape
   neighbours in the grid, but they're actually readable. */

.bw-leg__download {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .35rem .75rem;
    background: var(--bw-surface);
    border: 1px solid var(--bw-border);
    border-radius: var(--bw-radius);
    color: var(--bw-brand-dark);
    text-decoration: none;
    font-size: .9rem;
    transition: background .12s ease-out;
}
.bw-leg__download:hover {
    background: var(--bw-brand-soft);
    color: var(--bw-brand-dark);
}
.bw-leg__download-icon { font-size: 1.1rem; line-height: 1; }
.bw-leg__download-hint {
    color: var(--bw-fg-muted);
    font-size: .78rem;
}

/* Legende + Jump-Liste der Etappen in einem — sitzt direkt unter der
   Übersichtskarte. Früher war hier zusätzlich eine reine Map-Legende per
   tour-map.js gerendert; entfernt, weil dieselben Titel ein Pixel weiter
   unten in dieser <ol> nochmal vorkamen — jetzt ein einziger Block, Farbe
   matcht den Polyline-Farben aus tour-map.js, der Titel ist klickbar als
   Sprungmarke zur entsprechenden :::leg-Sektion im Body.

   Grid mit auto-fit/minmax: bei 17 Etappen + breiter Spalte (Body max
   740 px) ergibt das zwei bis drei Spalten je nach Viewport, schmale
   Bildschirme bekommen automatisch eine — dadurch deutlich weniger
   vertikaler Platz als die alte flex-wrap-Liste mit je einer Zeile pro
   langem Titel. */
.tour-overview__legs {
    list-style: none;
    margin: .6rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: .2rem .8rem;
    font-size: .78rem;
    color: var(--bw-fg-soft);
}
.tour-overview__leg {
    display: flex;
    align-items: baseline;
    gap: .4rem;
    margin: 0;
    line-height: 1.4;
}
.tour-overview__leg-swatch {
    display: inline-block;
    width: .9rem;
    height: .9rem;
    border-radius: 2px;
    border: 1px solid rgba(0, 0, 0, .15);
    flex: 0 0 auto;
}
.tour-overview__leg-link {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px dotted transparent;
    transition: border-color .15s ease, color .15s ease;
}
.tour-overview__leg-link:hover,
.tour-overview__leg-link:focus-visible {
    color: var(--bw-fg);
    border-bottom-color: currentColor;
    outline: none;
}

/* === Form fields (global) ===========================================
 * Genutzt vom Foundation-<ContactForm>. Vorher in
 * Components/Shared/ContactForm.razor.css scoped; mit dem Umzug auf
 * Foundation muessen die Input/Label/Button-Regeln site-weit verfuegbar
 * sein (Foundation-Komponente restyled keine Inputs).
 * ==================================================================== */

.form-field {
    display:        flex;
    flex-direction: column;
    gap:            0.3rem;
    margin-bottom:  0;
}
.form-field > span {
    font-size:   0.85rem;
    color:       var(--bw-fg-soft);
    font-weight: 600;
}
.form-field.is-required > span::after {
    content:     '*';
    color:       var(--bw-earth);
    margin-left: 0.2em;
}
.form-field input,
.form-field textarea {
    font:          inherit;
    padding:       0.55rem 0.7rem;
    border:        1px solid var(--bw-border);
    border-radius: var(--bw-radius);
    background:    #fff;
    color:         var(--bw-fg);
    transition:    border-color 0.15s ease, box-shadow 0.15s ease;
}
.form-field input:focus,
.form-field textarea:focus {
    outline:      none;
    border-color: var(--bw-brand);
    box-shadow:   0 0 0 3px rgba(31, 64, 41, .12);
}
.form-field textarea {
    resize:     vertical;
    min-height: 8rem;
    line-height:1.5;
}
/* Invalid-Marker (Blazor setzt .invalid auf den InputText/InputTextArea). */
.form-field .invalid    { border-color: #b53e3e; }
.form-field__error      { color: #b53e3e; font-size: 0.8rem; }

/* === Buttons (global, vom Foundation-<ContactForm> referenziert) ===== */

.btn-primary,
.btn-secondary {
    padding:       0.55rem 1.2rem;
    border:        1px solid var(--bw-brand);
    border-radius: var(--bw-radius);
    font:          inherit;
    cursor:        pointer;
    transition:    background 0.15s ease, color 0.15s ease;
}
.btn-primary           { background: var(--bw-brand); color: #fff; }
.btn-primary:hover:not([disabled]) { background: var(--bw-brand-dark, #163223); }
.btn-secondary         { background: transparent; color: var(--bw-fg-soft); border-color: var(--bw-border); }
.btn-secondary:hover:not([disabled]) { background: var(--bw-bg-muted); }
.btn-primary[disabled],
.btn-secondary[disabled] { opacity: 0.5; cursor: not-allowed; }

/* === Foundation-<ContactForm> Theming-Overrides =====================
 * bestes-wetter ist schlank: nur eine Spalte (kein Phone-Feld), und der
 * "Sent"-Streifen soll in der Brand-Tarnfarbe sitzen. *@
 * ==================================================================== */
:root {
    --contact-form-grid-columns: 1fr;          /* eine Spalte; Foundation default ist 1fr 1fr */
    --contact-form-radius:       var(--bw-radius);
    --contact-form-sent-bg:      #ecf5ee;
    --contact-form-sent-border:  #2d5a3d;
    --contact-form-sent-color:   #2d5a3d;
    --contact-form-error-bg:     #f6ebeb;
    --contact-form-error-color:  #b53e3e;
    --contact-form-footnote-color: var(--bw-fg-muted);
}

/* === Owner Preview Mode Banner =====================================
 * Sticht hervor (warmer Bernstein-Ton), damit der Owner nie aus Versehen
 * vergisst, dass er gerade den ComingSoon-Gate uebergeht. Schmaler
 * Streifen, sitzt oben ueber dem ganzen Layout. Cookie-Setting via
 * /_preview?token=<…> in Program.cs.
 * =================================================================== */

.preview-banner {
    display:         flex;
    flex-wrap:       wrap;
    justify-content: center;
    align-items:     center;
    gap:             0.5rem 1.25rem;
    padding:         0.4rem 1rem;
    background:      #fef3c7;            /* amber-100 */
    color:           #7c2d12;            /* amber-900 */
    border-bottom:   1px solid #fbbf24;  /* amber-400 */
    font-size:       0.85rem;
    text-align:      center;
}
.preview-banner a {
    color:           inherit;
    text-decoration: underline;
    font-weight:     600;
}
.preview-banner a:hover,
.preview-banner a:focus-visible {
    text-decoration: none;
}
