/* ==========================================================================
   zs-base.css — Shared base styles for Zvjezdane Staze
   --------------------------------------------------------------------------
   Contains:
   - Palette (CSS custom properties in :root)
   - HTML / body resets and defaults
   - Paper background system (paper-base, sun-blob, paper-grain, paper-vignette)
   - Sun keyframe animations (sunDrift, sunDriftAlt, sunBreathe, sunPulse)
   - Navigation styles (nav, dropdown, mobile menu, lang switch)
   - Footer styles
   - Generic responsive defaults (768px breakpoint)

   Usage: linked from /includes/head-common.php on all pages.
   Per-page CSS (in <style> blocks) ADDS to / OVERRIDES this base.

   Last updated: 2026-05-03 (Phase II/A pilot)
   ========================================================================== */


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


/* ----- Palette (canonical for entire site) -----
   Source of truth: Brand Book §12 Specifications (LAST VERSIONS, 2026-05-04).
   Tokens approved 2026-05-05 in brand consolidation pass. */
:root {
    /* Paper layer */
    --bg: #faf9f6;             /* primary cream paper */
    --bg-warm: #fdfcf9;         /* slightly warmer wash for radial gradients */
    --paper-deep: #f4f1e8;      /* deeper paper shadow — BB canon (replaces legacy --bg-shadow) */

    /* Forest stack (greenkast tones) */
    --forest: #2d4a2d;
    --forest-deep: #1f3a1f;     /* BB canon (was #1a3a1a) */
    --moss: #5a7062;            /* mid forest tone for body / muted UI */

    /* Gold + accents */
    --gold: #c4a050;
    --gold-deep: #a8853c;       /* deeper gold for active/hover states */
    --magenta: #a04060;
    --teal: #3a6b6b;            /* BB canon (was #2a6a6a) */

    /* Greyscale (greenkast, not neutral — kohezija sa forest paletom) */
    --text: #1a1a1a;            /* accessory: strict-black for high-contrast UI / print preview only.
                                   Body default uses --forest-deep (BB §05). Use --text only when pure
                                   black is intentional (modal scrim text, deep contrast labels). */
    --muted: #3a4a3a;           /* zelenkast muted (BB canon, was #3a3a3a) */
    --light: #7a8a7a;           /* zelenkast light (BB canon, was #5a5a5a) */
    --lighter: var(--light);    /* aliased to --light for palette cohesion. Pure-gray #888 retired
                                   2026-05-05 — all neutrals are greenish per BB §04. */

    /* Atmospheric whisper — universal soft fill */
    --whisper: rgba(45, 74, 45, 0.08);

    /* Type stacks — 4 system fonts.
       Hybrid font (Jost + Noto Sans Glagolitic) is reserved for catalog/brand-book
       reference contexts. Programme card titles use --font-serif (Cormorant) per
       2026-05-05 decision; Cormorant covers Latin + Cyrillic in one face,
       Noto Sans Glagolitic supplies U+2C00–2C5F glyphs for hybrid names. */
    --font-serif:  'Cormorant Garamond', 'Noto Serif', Georgia, serif;
    --font-sans:   'Space Grotesk', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-hybrid: 'Jost', 'Noto Sans Glagolitic', sans-serif;
    --font-mono:   'JetBrains Mono', 'Courier New', monospace;

    /* ----- Sky Hour 1.0 (2026-05-10) -----
       Chrome reacts to astro time at Mijakovići via <html data-sky="..."> set
       by includes/head-common.php (server-side, sun_info_for() in lib/sky-hour.php).
       Brand canon is NEVER changed — Sky Hour only shifts these helper tokens:
         --sky-paper-tint        overlay color above .paper-base
         --sky-paper-tint-alpha  overlay opacity (0 = invisible)
         --sky-vignette-rgba     vignette edge color
         --sky-sun-opacity       sun-blob multiplier (subtle dim/bright)
       Defaults below = sky-noon equivalent (no shift).
       Each phase below overrides only what's needed.

       8 phases: deep · dawn · morning · noon · afternoon · golden · dusk · night
       URL preview: ?sky=dawn (any phase). */
    --sky-paper-tint:       transparent;
    --sky-paper-tint-alpha: 0;
    --sky-vignette-rgba:    rgba(45, 74, 45, 0.03);
    --sky-sun-opacity:      1;
    --sky-halo-glow:        0;   /* additional radial glow strength, 0–1 */
}

/* ===== Sky Hour phase overrides =====
   All phases shift atmospheric helper tokens; brand canon stays untouched.
   Element-level transitions (5s ease) live on .paper-base::after,
   .paper-vignette, .living-sun-container — not here. CSS custom properties
   don't transition without @property declarations, so phase changes are
   instant at the var level; smoothness happens where the vars are consumed. */

/* DEEP NIGHT (02:00 → civil twilight) — coldest, quietest, paper barely tinted blue */
[data-sky="deep"] {
    --sky-paper-tint:       rgba(28, 38, 58, 1);
    --sky-paper-tint-alpha: 0.12;
    --sky-vignette-rgba:    rgba(20, 30, 50, 0.10);
    --sky-sun-opacity:      0.35;
    --sky-halo-glow:        0;
}

/* DAWN (twilight begin → sunrise) — cold blue-grey lifting toward warm */
[data-sky="dawn"] {
    --sky-paper-tint:       rgba(120, 130, 150, 1);
    --sky-paper-tint-alpha: 0.07;
    --sky-vignette-rgba:    rgba(60, 70, 90, 0.06);
    --sky-sun-opacity:      0.55;
    --sky-halo-glow:        0.15;
}

/* MORNING (sunrise → +90 min) — paper waking, gold rising */
[data-sky="morning"] {
    --sky-paper-tint:       rgba(245, 215, 165, 1);
    --sky-paper-tint-alpha: 0.05;
    --sky-vignette-rgba:    rgba(45, 74, 45, 0.03);
    --sky-sun-opacity:      0.9;
    --sky-halo-glow:        0.25;
}

/* NOON (morning end → solar transit) — clearest, default canon */
[data-sky="noon"] {
    --sky-paper-tint:       transparent;
    --sky-paper-tint-alpha: 0;
    --sky-vignette-rgba:    rgba(45, 74, 45, 0.025);
    --sky-sun-opacity:      1;
    --sky-halo-glow:        0;
}

/* AFTERNOON (transit → -90 min sunset) — warm settle */
[data-sky="afternoon"] {
    --sky-paper-tint:       rgba(240, 205, 155, 1);
    --sky-paper-tint-alpha: 0.04;
    --sky-vignette-rgba:    rgba(80, 60, 40, 0.04);
    --sky-sun-opacity:      0.95;
    --sky-halo-glow:        0.15;
}

/* GOLDEN HOUR (-90 min → sunset) — gold + magenta amplified */
[data-sky="golden"] {
    --sky-paper-tint:       rgba(220, 140, 90, 1);
    --sky-paper-tint-alpha: 0.10;
    --sky-vignette-rgba:    rgba(160, 64, 96, 0.06);
    --sky-sun-opacity:      1;
    --sky-halo-glow:        0.45;
}

/* DUSK / BLUE HOUR (sunset → civil twilight end) — blue hush */
[data-sky="dusk"] {
    --sky-paper-tint:       rgba(80, 90, 130, 1);
    --sky-paper-tint-alpha: 0.10;
    --sky-vignette-rgba:    rgba(50, 60, 100, 0.08);
    --sky-sun-opacity:      0.55;
    --sky-halo-glow:        0.2;
}

/* NIGHT (civil twilight end → 02:00) — full dark, stars feel awake */
[data-sky="night"] {
    --sky-paper-tint:       rgba(35, 45, 70, 1);
    --sky-paper-tint-alpha: 0.10;
    --sky-vignette-rgba:    rgba(25, 35, 60, 0.10);
    --sky-sun-opacity:      0.4;
    --sky-halo-glow:        0.05;
}

/* ===== Sky Hour 1.1 · Lunar reactivity =====
   Moon illumination (0.0 new → 1.0 full) is emitted as inline --moon-illum on
   <html>. Constellation pages consume it to modulate star intensity:

     --star-glow      max at new moon, dimmer at full moon (1 - illum * 0.4)
     --star-halo      same direction (full moon washes out stars)
     --moon-paper     subtle paper warmth at full moon (extra glow on paper)

   Why: at new moon the sky is darkest and stars feel brightest. At full moon
   the moon's light competes — stars dim. This is geographic truth, not
   aesthetic invention. Mirror what you see standing in Mijakovići.

   These tokens are GLOBAL but only consumed by Cassiopeia rules
   (/programmes/, /join/, /de/programme/, /de/unterstuetzen/). */
:root {
    --moon-illum: 0.5;                          /* fallback if HTML attr missing */
    --star-glow: calc(1 - var(--moon-illum) * 0.4);    /* 1.0 → 0.6 */
    --star-halo: calc(1 - var(--moon-illum) * 0.5);    /* 1.0 → 0.5 */
    --moon-paper-glow: calc(var(--moon-illum) * 0.04); /* 0 → 0.04 alpha */
}

/* Subtle paper-warming at full moon — paper feels lit by moonlight at night.
   Only visible on night/deep/dusk phases (when moon is the dominant light). */
[data-sky="night"] .paper-base::after,
[data-sky="deep"] .paper-base::after,
[data-sky="dusk"] .paper-base::after {
    box-shadow: inset 0 0 200px rgba(255, 245, 220, var(--moon-paper-glow, 0));
}

/* Cassiopeia star reactivity — only on pages with constellation (.cas-star
   exists). Brightness varies with moon: brighter at new moon (no competing
   moonlight), dimmer at full moon. Geographic truth. */
.cas-star {
    filter: brightness(var(--star-glow, 1));
    transition: filter 1.2s ease;
}
.cas-star .cas-halo {
    /* Halo extra modulation: visible at new moon, washed at full moon */
    --halo-moon-mod: var(--star-halo, 1);
}

/* Mycelium canvas: opposite reactivity. At full moon the sky is brighter,
   the mycelium network (background) is MORE visible. At new moon the
   constellation dominates, mycelium retreats. */
.cas-mycelium {
    opacity: calc(0.65 + var(--moon-illum, 0.5) * 0.3);
    transition: opacity 1.5s ease;
}

/* Active star (clicked, panel open) — full brightness regardless of moon
   so user knows which star they tapped. */
body.night-mode .cas-star.is-active {
    filter: brightness(1.15) !important;
}

/* Cassiopeia rotation — circumpolar constellation rotates around Polaris through
   the sidereal day. Apply astronomical hour angle (from --cas-rotation CSS var
   set by head-common.php → cas_rotation_compute()) so the on-screen W matches
   what's actually above Bosnia right now. Smooth transition between page
   loads (15s ease) so the change reads as breathing, not flick.
   Desktop only — mobile already applies a 90deg rotation for vertical layout
   on /programmes/, /join/ etc., so astro rotation would conflict.
   Amplitude is capped at ±25° in cas_rotation_compute() so the constellation
   stays inside the landscape frame; plus overflow:hidden on the frame as a
   safety net for any future scale tweaks. */
.cassiopeia-frame { overflow: hidden; }

@media (min-width: 721px) {
    .cassiopeia-map {
        transform: rotate(var(--cas-rotation, 0deg));
        transform-origin: center center;
        transition: transform 15s ease;
    }
    @media (prefers-reduced-motion: reduce) {
        .cassiopeia-map { transition: none; }
    }
}

/* ===== "About the map" expandable explainer ===================================
   Small, opt-in disclosure below the Cassiopeia map. Hidden by default; opens
   to a three-sentence scientific note explaining why the map looks the way it
   does (circumpolar above central Bosnia, 44°N visual position, real-time
   rotation tracking actual sky orientation). Serif italic moss register —
   same family as cassiopeia-explainer; quieter than caption.

   Discoverable for curious visitors, invisible to those who just want to
   click stars. Pure HTML <details>/<summary> — no JS, no a11y workarounds. */
.cas-about {
    max-width: 56ch;
    margin: 1.5rem auto 0;
    padding: 0 1.25rem;
    text-align: center;
    font-family: 'Cormorant Garamond', 'Noto Serif', serif;
}
.cas-about summary {
    cursor: pointer;
    list-style: none;
    font-style: italic;
    font-size: 0.98rem;
    color: rgba(45, 74, 45, 0.78);   /* moss, no opacity stacking */
    transition: color 0.4s ease;
    user-select: none;
    display: inline-block;
    padding: 0.3rem 0.6rem;
}
.cas-about summary::-webkit-details-marker { display: none; }
.cas-about summary::marker { content: ''; }
.cas-about summary::before {
    content: '+ ';
    font-style: normal;
    font-weight: 500;
    color: var(--magenta);   /* brand action signal — survives Sky Hour shifts */
    margin-right: 0.2rem;
}
.cas-about[open] summary::before { content: '− '; }
.cas-about summary:hover { color: rgba(45, 74, 45, 0.98); }
.cas-about[open] summary { color: rgba(45, 74, 45, 0.92); }
.cas-about-body {
    margin-top: 0.85rem;
    padding: 0.9rem 0.5rem 0.25rem;
    border-top: 1px solid rgba(45, 74, 45, 0.12);
    font-size: 0.92rem;
    line-height: 1.65;
    opacity: 0.92;
    animation: cas-about-in 0.5s ease;
}
.cas-about-body .lat-num {
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.85em;
    letter-spacing: 0.02em;
}
@keyframes cas-about-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 0.92; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    .cas-about-body { animation: none; }
}
@media (max-width: 720px) {
    .cas-about { font-size: 0.9rem; padding: 0 1rem; }
    .cas-about-body { font-size: 0.88rem; padding: 0.75rem 0.25rem 0.25rem; }
}

/* ===== Black-and-White Day · winter solstice 24h grayscale ====================
   One day a year (winter solstice, Europe/Sarajevo), the site renders in
   grayscale. Brand canon (paper, gold, magenta, forest, moss) is untouched —
   it just passes through a filter. Sky Hour, lunar reactivity, audio reactivity
   all keep working. Tomorrow, color returns by itself.

   URL override: ?bw=1 (force on for preview), ?bw=0 (force off — opt-out).
   Server-side computed in lib/special-days.php; emitted as data-bw="1" on <html>.

   Slight contrast bump (1.05) prevents grayscale from becoming muddy.
   2s ease transition smooths the entry/exit when the page loads on/off the day. */
html[data-bw="1"] {
    filter: grayscale(1) contrast(1.05);
    transition: filter 2s ease;
}

@media (prefers-reduced-motion: reduce) {
    html[data-bw="1"] { transition: none; }
}

/* Solstice signal — quiet trace shown only on Black-and-White Day, below the
   ephemeris row. Never on a normal day. Whisper, not declaration. */
.bw-day-signal {
    text-align: center;
    margin: 0.4rem auto 0.8rem;
    padding: 0 1rem;
    font-family: var(--font-serif);
    font-size: 12px;
    color: var(--moss);
    opacity: 0.7;
    letter-spacing: 0.04em;
}
@media (max-width: 720px) {
    .bw-day-signal { font-size: 11px; }
}

/* Astro signal — shown only when within 14 days of equinox/solstice.
   Same register as bw-day-signal (italic serif, moss, low opacity). */
.astro-signal {
    text-align: center;
    margin: 0.4rem auto 0.8rem;
    padding: 0 1rem;
    font-family: var(--font-serif);
    font-size: 12px;
    color: var(--moss);
    opacity: 0.7;
    letter-spacing: 0.04em;
}
@media (max-width: 720px) {
    .astro-signal { font-size: 11px; }
}

/* Lunar age — small mono suffix to moon phase (e.g. "last quarter · 22.6d").
   Desktop-only; mobile keeps just the phase name. */
.ephemeris-moon-age {
    color: var(--light);
    font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) {
    .ephemeris-moon-age { display: none; }
}

/* prefers-reduced-motion: skip Sky Hour transitions; phase still applies but instantly. */
@media (prefers-reduced-motion: reduce) {
    .paper-base::after,
    .paper-vignette,
    .living-sun-container { transition: none; }
}


/* ----- HTML / body defaults ----- */
html { scroll-behavior: smooth; }

/* Anchor jump scroll-margin — fixed nav (~80px height) covers anchor target
   on hash navigation. scroll-margin-top adds gap between anchor and viewport
   top so target is visible below the nav. 6rem = nav height (~80px) + small
   buffer. Applies to any element with id=, including section anchors used
   for hash links like /apply#three-paths. (Mobile audit 2026-05-06.) */
[id] { scroll-margin-top: 6rem; }
body {
    font-family: var(--font-sans);
    background: var(--bg);
    /* Brand book §05: body color = --forest-deep, not pure black.
       Cohesive with cream-paper register. Use --text only where pure black is intentional. */
    color: var(--forest-deep);
    min-height: 100vh;
    line-height: 1.7;
    overflow-x: hidden;
}


/* ----- Skip link (a11y — first focusable, hidden until focused) ----- */
.zs-skip-link {
    position: absolute;
    top: -100px;
    left: 0;
    background: var(--forest);
    color: var(--bg);
    padding: 0.75rem 1.25rem;
    text-decoration: none;
    font-size: 12px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    z-index: 10000;
    transition: top 0.2s;
}
.zs-skip-link:focus { top: 0; }


/* ==========================================================================
   PAPER BACKGROUND SYSTEM
   ========================================================================== */

.paper-base {
    position: fixed;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    background: var(--bg);
    pointer-events: none;
    z-index: 0;
}

/* Sky Hour tint overlay — sits between paper-base and sun blobs (z-index 0.5
   conceptually; we use z-index 1 with mix-blend-mode: multiply so cream paper
   can warm/cool without clobbering it). Pure-color screen at low alpha.
   Driven by --sky-paper-tint + --sky-paper-tint-alpha, set per [data-sky="..."]. */
.paper-base::after {
    content: '';
    position: fixed;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    background: var(--sky-paper-tint);
    opacity: var(--sky-paper-tint-alpha);
    mix-blend-mode: multiply;
    pointer-events: none;
    transition: opacity 5s ease, background 5s ease;
    z-index: 0;
}

.living-sun-container {
    position: fixed;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 1;
    overflow: hidden;
    /* Sky Hour: container-level opacity multiplier so sunPulse keyframes inside
       still pulse normally; this dims the whole sun field at night/dusk and
       keeps it bright at noon. */
    opacity: var(--sky-sun-opacity);
    transition: opacity 5s ease;
}

.sun-blob {
    position: absolute;
    border-radius: 50%;
    background: radial-gradient(ellipse at center,
        rgba(240, 225, 190, 0.85) 0%,
        rgba(245, 235, 210, 0.6) 20%,
        rgba(248, 240, 220, 0.35) 40%,
        rgba(250, 245, 230, 0.15) 60%,
        transparent 80%);
    filter: blur(40px);
}

/* Sun blob animations use top/left keyframes — intentional aesthetic decision
   (Belma 2026-05-06). The brief experiment with translate/scale (Phase 2 mobile
   audit Top 5 fix #2) was reverted: layout recalc per frame is the documented cost,
   but the organic "lebdeći" motion register is core brand intent. Performance impact
   is mitigated by the slow 80s drift cycle (microscopic per-frame delta) and the
   prefers-reduced-motion fallback below (line 553+) which fully disables animation
   for accessibility-sensitive users. */
.sun-primary {
    width: 50vmax; height: 50vmax;
    animation:
        sunDrift 80s ease-in-out infinite,
        sunBreathe 10s ease-in-out infinite,
        sunPulse 7s ease-in-out infinite;
}

.sun-secondary {
    width: 35vmax; height: 35vmax;
    opacity: 0.7;
    animation:
        sunDriftAlt 65s ease-in-out infinite,
        sunBreathe 8s ease-in-out infinite 2s,
        sunPulse 5s ease-in-out infinite 1s;
}

@keyframes sunDrift {
    0%   { top: -15%; left: -5%; }
    25%  { top: -10%; left: 40%; }
    50%  { top: -5%;  left: 75%; }
    75%  { top: -12%; left: 35%; }
    100% { top: -15%; left: -5%; }
}
@keyframes sunDriftAlt {
    0%   { top: 55%; left: 85%; }
    33%  { top: 35%; left: 15%; }
    66%  { top: 65%; left: 45%; }
    100% { top: 55%; left: 85%; }
}
@keyframes sunBreathe {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.25); }
}
@keyframes sunPulse {
    0%, 100% { opacity: 0.6; filter: blur(40px); }
    50%      { opacity: 1;   filter: blur(60px); }
}

.paper-grain {
    position: fixed;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 3;
    opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23grain)'/%3E%3C/svg%3E");
}

.paper-vignette {
    position: fixed;
    top: 0; left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 5;
    /* Vignette edge color responds to Sky Hour — shifts cool at dawn/dusk/night,
       warm at golden hour. Center always stays transparent. */
    background: radial-gradient(ellipse at 50% 50%, transparent 40%, var(--sky-vignette-rgba) 100%);
    transition: background 5s ease;
}


/* ==========================================================================
   PATTERNS — BB §09 routing
   --------------------------------------------------------------------------
   Five canonical pattern SVGs in img/patterns/. Background overlay at
   2–4% opacity sits between paper-grain (z-index 3) and paper-vignette
   (z-index 5). Per-page body class triggers the matching pattern.

   Routing (BB §09):
     Constellation → index, programmes/index, journal/index, media/index,
                     news/index (landing & archive contexts)
     Mycelium      → about/* (community, partners, network contexts)
     Vez Dijamant  → print/stationery only (NOT wired to web pages)
     Vez Cross-Stitch → print/stationery only (NOT wired to web pages)
     Dijamantna mreža → festival hero / year-end editions only (single
                        occasion, full-saturation; NOT default rollout)
   ========================================================================== */
body.page-landing::after,
body.page-programmes-index::after,
body.page-journal::after,
body.page-media-index::after {
    content: '';
    position: fixed;
    top: 0; left: 0;
    width: 100%; height: 100%;
    pointer-events: none;
    z-index: 4;
    background-repeat: repeat;
    opacity: 0.03;
}

/* Constellation — landings + archives */
body.page-landing::after,
body.page-programmes-index::after,
body.page-journal::after,
body.page-media-index::after {
    background-image: url('/img/patterns/zs-pattern-constellation.svg');
    background-size: 240px 240px;
}

/* Mycelium pattern was wired to /about/* via body[class*="page-about-"] but
   rendered too prominently in practice (radiating stroke lines + central
   gold disc read as visible stars at 280px tile). Removed 2026-05-07 to
   match the cleaner DE about presentation. Mycelium remains in the asset
   library for stationery/print and for opt-in single pages. */


/* ==========================================================================
   NAVIGATION
   ========================================================================== */

/* Nav overlay (mobile drawer backdrop) */
.nav-overlay {
    display: none;
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    z-index: 999;
    opacity: 0;
    transition: opacity 0.3s ease;
}
.nav-overlay.active { display: block; opacity: 1; }

/* Nav bar */
nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 1000;
    padding: 1.5rem 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: rgba(250, 249, 246, 0.92);
    backdrop-filter: blur(10px);
    box-shadow: 0 1px 20px rgba(45, 74, 45, 0.04);
}

.logo {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12px;
    letter-spacing: 0.25em;
    text-transform: uppercase;
    font-weight: 500;
    color: var(--forest);
    text-decoration: none;
    transition: color 0.3s;
}
.logo:hover { color: var(--magenta); }

.nav-links {
    display: flex;
    gap: 1.8rem;
    list-style: none;
    align-items: center;
}
.nav-links > li { position: relative; }
.nav-links > li > a {
    font-size: 11px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--muted);
    font-weight: 500;
    padding: 0.5rem 0;
    position: relative;
    transition: color 0.3s;
    display: inline-block;
    white-space: nowrap;          /* prevent "ABOUT ▾" wrapping onto two lines */
}
.nav-links > li > a::before {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 2px;
    background: var(--gold);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.3s ease;
}
.nav-links > li > a:hover { color: var(--forest); }
.nav-links > li > a:hover::before { transform: scaleX(1); }
.nav-links > li > a.active { color: var(--forest); }
.nav-links > li > a.active::before { transform: scaleX(1); }
.nav-links > li > a.highlight { color: var(--magenta); font-weight: 600; }

/* Drawer close button — hidden by default; shown only inside the mobile drawer
   (override at @media (max-width: 1280px) below). The <button> element is in
   the DOM unconditionally for a11y / progressive enhancement, but on desktop
   the open inline nav doesn't need a close affordance. Without this rule the
   browser's default button styling rendered a visible [×] box at the start of
   the inline nav (bug found 2026-05-07). */
.nav-close { display: none; }
/* Nav link focus ring inherits from global :focus-visible (a11y section below) */

/* Dropdown */
.dropdown { position: relative; }
.dropdown > a::after {
    content: '▾';
    margin-left: 0.5rem;
    font-size: 12px;
    color: var(--light);
    transition: transform 0.3s ease;
    display: inline-block;
}
.dropdown-menu {
    position: absolute;
    top: 100%; left: -1rem;
    background: rgba(250, 249, 246, 0.98);
    backdrop-filter: blur(10px);
    min-width: 200px;
    padding: 1rem 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(10px);
    transition: all 0.3s;
    box-shadow: 0 10px 40px rgba(45, 74, 45, 0.08);
}
.dropdown:hover .dropdown-menu,
.dropdown:focus-within .dropdown-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}
.dropdown-menu a {
    display: block;
    padding: 0.6rem 1.5rem;
    font-size: 11px;
    text-decoration: none;
    color: var(--muted);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-weight: 500;
    transition: all 0.2s;
}
.dropdown-menu a:hover { background: rgba(196, 160, 80, 0.08); color: var(--forest); }
.dropdown-menu a:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.dropdown-divider { height: 1px; background: rgba(45, 74, 45, 0.05); margin: 0.5rem 1rem; }

/* Lang switch */
.lang-switch { display: flex; align-items: center; gap: 0.5rem; border-left: 1px solid rgba(45, 74, 45, 0.15); padding-left: 1.5rem; margin-left: 0.5rem; }
.lang-switch a { font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none; color: var(--muted); transition: color 0.3s; padding: 0.5rem 0.85rem; min-height: 44px; display: inline-flex; align-items: center; }
.lang-switch a.active { color: var(--forest); font-weight: 600; }
.lang-switch a:hover { color: var(--forest); }
.lang-switch .separator { color: var(--light); font-size: 11px; }

/* Menu toggle (mobile only) — WCAG 2.5.5 minimum 44×44px touch target. */
.menu-toggle {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.75rem;
    min-width: 44px;
    min-height: 44px;
    z-index: 1002;
}
.menu-toggle span {
    display: block;
    width: 26px;
    height: 1.5px;
    background: var(--forest);
    margin: 5px 0;
    transition: all 0.3s;
}


/* ==========================================================================
   FOOTER
   ========================================================================== */

footer {
    position: relative;
    z-index: 100;
    padding: 4rem 2rem 2rem;
    background: rgba(45, 74, 45, 0.03);
    border-top: 1px solid rgba(45, 74, 45, 0.05);
}
.footer-content { max-width: 1200px; margin: 0 auto; text-align: center; }
.footer-decoration { width: 60px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold), transparent); margin: 0 auto 2rem; }
.footer-brand { margin-bottom: 1.5rem; }
.footer-logo { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; font-size: 12px; font-weight: 500; letter-spacing: 0.25em; text-transform: uppercase; color: var(--forest); margin-bottom: 0.5rem; }
.footer-location { font-size: 11px; color: var(--light); letter-spacing: 0.1em; }
/* .footer-links removed 2026-05-10 (Belma feedback): nav already has all those
   pages, footer duplication only added bulk on mobile. Legal-only footer kept. */
.footer-social { display: flex; justify-content: center; gap: 1rem; margin-bottom: 2rem; }
.footer-social a { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 50%; border: 1px solid rgba(45, 74, 45, 0.1); color: var(--light); transition: all 0.3s; }
.footer-social a:hover { border-color: var(--forest); color: var(--teal); }
.footer-social svg { width: 14px; height: 14px; fill: currentColor; }
.footer-bottom {
    padding-top: 1.5rem;
    border-top: 1px solid rgba(45, 74, 45, 0.05);
    font-size: 11px;
    color: var(--light);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
}
.footer-bottom a { color: var(--light); text-decoration: none; transition: color 0.3s; }
.footer-bottom a:hover { color: var(--forest); }
.footer-legal {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.4rem 0.6rem;
}
.footer-legal .sep { color: var(--light); opacity: 0.4; }
.footer-copyright { color: var(--light); }


/* ==========================================================================
   SKY MARKER (nav clock + sun/moon glyph) — Sky Hour 1.0
   ==========================================================================
   Sits in nav between logo and menu-toggle. Always visible. Click → scroll
   to footer ephemeris. Glyph (sun or moon) chosen server-side by Sky Hour
   phase; lunar phase reflected in moon glyph variants.

   Mobile: still visible (compact form, just glyph + smaller clock).
   Hidden on screens <360px to preserve nav usability. */

.sky-marker {
    position: absolute;
    /* Center vertically inside nav (which has padding via min-height ~80px).
       Right side, before menu-toggle (which is far right on mobile). */
    top: 50%;
    right: 5rem;          /* leave room for menu-toggle on mobile */
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.75rem;
    border-radius: 100px;
    background: rgba(45, 74, 45, 0.04);
    color: var(--moss);
    text-decoration: none;
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.05em;
    transition: background 0.3s ease, color 0.3s ease;
    z-index: 50;
}
.sky-marker:hover {
    background: rgba(196, 160, 80, 0.12);
    color: var(--forest);
}
.sky-marker-clock {
    font-variant-numeric: tabular-nums;
    line-height: 1;
}
.sky-marker-glyph-wrap {
    display: inline-flex;
    align-items: center;
    width: 16px;
    height: 16px;
}
.sky-marker-glyph {
    width: 100%;
    height: 100%;
    color: var(--gold-deep);
    transition: color 0.3s ease;
}
.sky-marker:hover .sky-marker-glyph { color: var(--magenta); }

/* Sun glyph: rays + disc, halo intensity from Sky Hour CSS var. */
.sky-marker-glyph--sun .sky-marker-rays {
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linecap: round;
    /* Ray opacity follows --sky-halo-glow (0–1). Default 0.4 baseline so rays
       remain readable; Sky Hour can boost up to 1 at golden hour. */
    opacity: calc(0.4 + var(--sky-halo-glow, 0) * 0.6);
}
.sky-marker-glyph--sun .sky-marker-disc {
    fill: currentColor;
}

/* Moon glyph: disc (lit) + shadow path (unlit). */
.sky-marker-glyph--moon .sky-marker-disc {
    fill: currentColor;
    opacity: 0.95;
}
.sky-marker-glyph--moon .sky-marker-shadow {
    fill: var(--bg);
    opacity: 0.85;
}

/* DESKTOP fix: marker is no longer absolute (was overlapping nav-links).
   It becomes a normal flex item inside <nav>, pushed right with margin-left:auto
   so it clusters next to the nav-links group instead of free-floating in center. */
@media (min-width: 1281px) {
    nav { gap: 1.25rem; }
    .sky-marker {
        position: static;
        top: auto;
        right: auto;
        left: auto;
        transform: none;
        margin-left: auto;          /* eat the space between logo and marker */
    }
}

/* On mobile / hamburger breakpoint, sky-marker is hidden in nav.
   Footer ephemeris carries the full data (vrijeme, datum, mjesec, sunrise/sunset, geo)
   so nothing is lost. Reduces nav clutter, prevents flex/SVG-sizing issues on small screens. */
@media (max-width: 1280px) {
    .sky-marker { display: none; }
}


/* ==========================================================================
   SKY EPHEMERIS (footer row) — Sky Hour 1.0
   ==========================================================================
   Sits inside <footer> .footer-content, just above .footer-bottom.
   One horizontal row of typographic data: date · weekday · time ·
   sky-phase · moon-phase · sunrise · sunset · geo. Wraps gracefully on
   mobile to multiple lines. Mono font, small size, --moss color. */

.sky-ephemeris {
    margin: 1.5rem auto 1rem;
    padding: 1rem 1.5rem;
    max-width: 1100px;
    border-top: 1px solid rgba(45, 74, 45, 0.06);
    border-bottom: 1px solid rgba(45, 74, 45, 0.06);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem 0.85rem;
    font-family: var(--font-mono);
    font-size: 12px;
    color: var(--moss);
    line-height: 1.7;
    letter-spacing: 0.02em;
}
.ephemeris-item {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    white-space: nowrap;
}
.ephemeris-sep {
    color: var(--light);
    user-select: none;
}
.ephemeris-time { font-variant-numeric: tabular-nums; }
.ephemeris-phase {
    font-style: italic;
    color: var(--forest);
}
.ephemeris-moon { color: var(--gold-deep); }
.ephemeris-sun  { color: var(--gold); }
.ephemeris-arrow {
    color: var(--light);
    font-size: 0.9em;
}
.ephemeris-coord {
    color: var(--light);
    font-size: 0.92em;
}

@media (max-width: 720px) {
    .sky-ephemeris {
        font-size: 10.5px;
        padding: 0.7rem 0.75rem;
        gap: 0.3rem 0.5rem;
        margin: 1rem auto 0.7rem;
        line-height: 1.5;
    }
    /* Hide weekday + geo coordinates on mobile — they're nice-to-have, not core.
       Core stays: date · time · sky-phase · moon · sunrise · sunset · location name. */
    .ephemeris-weekday,
    .ephemeris-coord {
        display: none;
    }
    /* Drop most separators on mobile — let flex-wrap + gap do the spacing. */
    .ephemeris-sep { display: none; }
    /* Single visible separator between date and time, between phase and moon. */
    .ephemeris-date + .ephemeris-sep,
    .ephemeris-phase + .ephemeris-sep,
    .ephemeris-sunrise + .ephemeris-sep { display: inline; opacity: 0.5; }
}

@media (max-width: 480px) {
    .sky-ephemeris {
        font-size: 10px;
        padding: 0.6rem 0.5rem;
    }
    /* On smallest screens, also drop sunrise/sunset (it's already abundant info).
       Keep: date · time · sky-phase · moon · location. */
    .ephemeris-sunrise,
    .ephemeris-sunset {
        display: none;
    }
    .ephemeris-sep { display: none; }
}


/* ==========================================================================
   PROGRAMME-NAME (HYBRID LATIN + CYRILLIC + GLAGOLITIC)
   ==========================================================================
   Programme names mix latin + cyrillic (+ glagolitic in Sтⰰр Trekъ, Boraviшte).
   Cormorant Garamond covers Latin + Cyrillic in one face; Noto Sans Glagolitic
   fallback supplies the U+2C00–2C5F Glagolitic glyphs that Cormorant lacks.

   Decision 2026-05-05: Cormorant won over Jost after side-by-side comparison
   with Razgovorište, Dvonoćje and Boraviшte. Jost was canonical in BB §05 v0.1
   but vizuelno nije sjelo; Cormorant gives kohezivniji serif feel that matches
   page h1 + body type system. BB §05 to be updated with this decision. */
.programme-name {
    font-family: 'Cormorant Garamond', 'Noto Sans Glagolitic', 'Noto Serif', Georgia, serif;
}


/* ==========================================================================
   COMMON PAGE PATTERNS (often used across journal/about/programmes pages)
   ========================================================================== */

/* Section divider — gold horizontal line, common end-of-section marker */
.footer-divider,
.section-divider,
.content-divider {
    width: 60px;
    height: 1px;
    background: var(--gold);
    margin: 3rem 0;
}
.content-divider {
    background: linear-gradient(90deg, var(--gold), var(--magenta), transparent);
    max-width: 150px;
    opacity: 0.4;
}


/* ==========================================================================
   RESPONSIVE — DRAWER NAV (1280px and below)
   --------------------------------------------------------------------------
   Breakpoint set at 1280px (not 768px) because the canonical nav has
   10 top-level items + lang switch (EN/DE/BHS), which crowds the bar
   below ~1300px even on widescreen laptops. Hamburger feels cleaner
   and matches the site's "tih, koncentriran" concept.
   ========================================================================== */

@media (max-width: 1280px) {
    .menu-toggle { display: block; }

    /* When drawer is open, hide the hamburger so user only sees ONE close button
       (the × inside the drawer, top-left). Eliminates the "two X" UX confusion. */
    nav:has(.nav-links.active) .menu-toggle { display: none; }

    .nav-links {
        position: fixed;
        top: 0; right: -100%;
        width: 85%;
        max-width: 380px;
        height: 100dvh;
        background: var(--bg);
        flex-direction: column;
        padding: 4.5rem 1.5rem 2rem;
        gap: 0;
        overflow-y: auto;
        transition: right 0.3s ease;
        box-shadow: -5px 0 30px rgba(45, 74, 45, 0.1);
        z-index: 1001;
        align-items: stretch;
    }
    .nav-links.active { right: 0; }
    /* Drawer close button — semantic <button> (was ::before pseudo-element).
       Real button gives proper a11y: role, aria-label, keyboard focus,
       Tab-reachable, screen-reader announces "Close menu, button". */
    .nav-close {
        display: flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 0.7rem; left: 0.7rem;
        width: 44px; height: 44px;
        background: none;
        border: none;
        font-size: 1.4rem;
        line-height: 1;
        color: var(--light);
        cursor: pointer;
        padding: 0;
        z-index: 1;
        transition: color 0.3s;
    }
    .nav-close:hover { color: var(--forest); }
    .nav-close:focus-visible {
        outline: 2px solid var(--gold);
        outline-offset: 2px;
        border-radius: 2px;
    }
    .nav-links > li {
        width: 100%;
        border-bottom: 1px solid rgba(45, 74, 45, 0.05);
    }
    .nav-links > li > a {
        display: block;
        padding: 1rem 0;
        font-size: 13px;
    }

    .dropdown-menu {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        box-shadow: none;
        background: transparent;
        padding: 0;
        max-height: 0;
        overflow: hidden;
        transition: max-height 0.3s ease, padding 0.3s ease;
    }
    .dropdown.open .dropdown-menu {
        max-height: 500px;
        padding: 0.5rem 0 1rem 1rem;
    }
    .dropdown-menu a { padding: 0.6rem 0; font-size: 12px; }

    .lang-switch {
        border-left: none;
        border-top: 1px solid rgba(45, 74, 45, 0.1);
        padding: 1rem 0;
        margin-left: 0;
        margin-top: 1rem;
        padding-left: 0;
        justify-content: center;
    }
    .lang-switch a { font-size: 11px; padding: 0.75rem 1rem; min-width: 44px; min-height: 44px; justify-content: center; }
    .nav-links > li.lang-switch { border-bottom: none; }

}

/* === Mobile footer compactness ================================================
   Tightened padding + gaps. .footer-links removed entirely (was duplicate of
   nav). Legal links + copyright structured into 2 lines, never more. */
@media (max-width: 768px) {
    footer {
        padding: 2.25rem 1.25rem 1.25rem;   /* was 4rem 2rem 2rem */
    }
    .footer-decoration {
        margin: 0 auto 1.25rem;            /* was 0 auto 2rem */
    }
    .footer-brand   { margin-bottom: 0.85rem; }
    .footer-logo    { font-size: 11px; }
    .footer-location { font-size: 10.5px; }
    .footer-social {
        gap: 0.6rem;
        margin-bottom: 1rem;
    }
    .footer-social a { width: 28px; height: 28px; }
    .footer-social svg { width: 12px; height: 12px; }
    .footer-bottom {
        font-size: 10.5px;
        padding-top: 0.85rem;
        gap: 0.35rem;
    }
    .footer-legal a,
    .footer-copyright { white-space: nowrap; }
}


/* ==========================================================================
   ACCESSIBILITY — focus, contrast, motion
   --------------------------------------------------------------------------
   Three primary a11y guarantees, in order of importance:
     1. Keyboard users always see a focus ring (gold, 2px, 4px offset)
     2. Reduced-motion users get a static, no-drift composition
     3. WCAG 2.1 AA contrast targeted across all token combinations (BB §21)
   ========================================================================== */


/* ----- Global :focus-visible — every interactive element gets a ring -----
   Brand book §21 Accessibility. Color: --gold (high-contrast on cream paper),
   2px outline + 4px offset = visible without crowding. border-radius 2px to
   soften the corner — matches the brand's not-perfectly-square paper feel.

   Mouse / touch users do NOT see the ring (browser-managed via :focus-visible).
   Only keyboard nav (Tab, Shift+Tab, arrow keys in custom controls) triggers it.
*/
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:not([tabindex="-1"]):focus-visible,
[role="button"]:focus-visible,
[role="link"]:focus-visible,
[role="menuitem"]:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 4px;
    border-radius: 2px;
}

/* Form inputs use a softer ring (combines with form-field border for double-layer
   feedback). Defined more specifically in zs-forms.css; this is the base safety. */
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline-offset: 2px;
}

/* Suppress legacy :focus glow on browsers that DO support :focus-visible —
   keeps mouse/touch from seeing the ring. */
:focus:not(:focus-visible) {
    outline: none;
}


/* ----- prefers-reduced-motion -----
   When user has system-level reduced-motion preference, suspend the ambient
   animations: sun drift/breathe/pulse, dappled-light noise, hover lifts, all
   transitions over 0.4s. The page should still feel paper-and-forest, just
   without the kinetic atmosphere.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    /* Suspend ambient sun motion */
    .sun-primary,
    .sun-secondary { animation: none; }

    /* Static fallback positions — sun stays mid-frame, single layer feel */
    .sun-primary   { top: -10%; left: 30%; }
    .sun-secondary { top: 50%; left: 60%; opacity: 0.5; }

    /* Cap all transitions to a single tick — preserves hover affordance
       without animation drift. */
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
