*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Tipografia autoallotjada (contacte.html) ────────────────────
   Descarregada un cop del repositori oficial google/fonts (llicència
   OFL, lliure de redistribuir) i servida des del nostre propi domini
   — cap petició ix mai cap a fonts.googleapis.com/fonts.gstatic.com,
   per tant Google no rep l'adreça IP de qui visita la pàgina. */
@font-face {
  font-family: 'PT Sans Narrow';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/PT-Sans-Narrow-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Titillium Web';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/TitilliumWeb-Regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Titillium Web';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/TitilliumWeb-SemiBold.woff2') format('woff2');
}
@font-face {
  font-family: 'Sacramento';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/Sacramento-Regular.woff2') format('woff2');
}

/* Variables de color */
:root {
  --colour-neon:        #ff3066;  /* gerd — color principal del traç (stroke) i l'emplenament (fill) */

  --colour-bg-page:     #0f0f0f;  /* fons de la pàgina */

  --colour-bg-svg:      var(--colour-bg-page);  /* fons de la caixa SVG (SVG box) */
  --colour-transparent: var(--colour-bg-svg);   /* color de màscara — coincideix amb el color del fons de l'SVG */
}

body {
  background: var(--colour-bg-page);
  color: #e8e8e8;
  font-family: monospace;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0;      /* 1rem */
  gap: 1rem;
}

/* Sol */
/* --- */

#sol_bg {
    position:fixed;
    inset:0;
    z-index:5;
    display: flex;
    justify-content: center;
    align-items: center;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s ease;
}

#sol_bg iframe { 
    width:100%;
    height:100%; /* 100% de #sol_bg = 100vh (inset:0).
                    viewBoxSolAnpassen() en sol.js calcula la viewBox dinàmicament
                    segons l'escala del logo — sense efecte de zoom, l'horitzó
                    es manté al 55%. */
    border: 0;
    flex-shrink: 0;
    background: transparent;    
}


/* Firma-Logo */
/* ---------- */

#stage {
  pointer-events: none;
  z-index:10;
  position:fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  align-items: center;
  display: flex;
  gap: 2rem;
  flex-wrap: wrap;
  justify-content: center;
  opacity: 1;
  transition: opacity 0.4s ease;  
}

.svg-wrap  { position: relative;   border: 0px solid blue; }
/* Recuperació (fallback) sense JS: grandària de referència a escala 1,0.
   El JS sobreescriu width/height mitjançant inline-style,
   segons la relació d'aspecte en comptes de punts de ruptura fixos (breakpoints).
   sol_geo_bridge.js (berechneSolLayout(), sol_layout.js) */
#wrap-logo  { width: 230px; height: 340px; }
#wrap-firma { width: 230px; height: 340px; }


/* Sota 530px (230+230px + 2rem de gap = 492px) no hi ha espai per als
   dos SVG en fila — s'amaga firma i només queda logo visible.
   Sense !important a propòsit: quan s'integra sol_geo_bridge.js,
   el seu inline style (major especificitat que qualsevol regla de
   fulla d'estil) el sobreescriu automàticament amb la seua pròpia
   lògica basada en la relació d'aspecte. */
@media (max-width: 530px) {
  #wrap-firma {
    display: none;
  }
}


.svg-canvas { width: 100%; height: 100%; display: block; }

/* traços oberts / open paths (strokes) */
.path-orig, .path-ext {
  fill: none;
  stroke: var(--colour-neon);
  stroke-width: 10;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

/* traços tancats (emplenament/fill) */
.path-fill {
  stroke: none;
  fill: var(--colour-neon);
  pointer-events: none;
}

/* Màscara transparent — traços (paths) que coincideixen amb el fons de l'SVG (p. ex. mussol_carta_linies, mussol_lletra).
   Segueix automàticament --colour-bg-svg si aquest canvia. */
.path-transparent {
  fill: var(--colour-transparent);
  stroke: none;
  pointer-events: none;
}


/* Zones */
/* ----- */

/* zones — invisibles per defecte, visibles en mode desenvolupament (dev mode) */
.zona { fill: transparent; stroke: none; cursor: pointer; }
body.show-zones .zona {
  fill: rgba(100, 200, 255, 0.07);
  stroke: rgba(100, 200, 255, 0.35);
  stroke-width: 4;
}


/* Etiqueta del Nom */
/* ------------------ */

.svg-wrap  { 
  pointer-events: auto; 
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.name-trigger {
  display: contents;
}

#name-label {
  position: absolute;
  top: calc(50% - min(25vh + 60px, 205px));
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: monospace;
  font-size: 0.85rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #e8e8e8;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  transition: opacity 0.3s ease;
  z-index: 11;
}

@media (max-height: 419px) {
  #name-label {
    display: none;
  }
}

.name-trigger:hover ~ #name-label,
.name-trigger:focus-within ~ #name-label,
#name-toggle:checked ~ #name-label {
  opacity: 1;
}


/* Etiquetes del Menú */
/* ------------------ */

.menu-label {
  position: absolute;
  font-family: monospace;
  font-size: 11px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #e8e8e8;
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  /* Degradació per defecte (fade out): roman visible un moment, cau ràpid, s'apaga lentament.
     cubic-bezier(0.0, 0.0, 0.2, 1.0) = inici lent → sensació de pausa i després caiguda */
  transition: opacity 0.7s cubic-bezier(0.0, 0.0, 0.2, 1.0);
}
.menu-label.visible {
  opacity: 1;
  /* Aparició ràpida (fast fade in) */
  transition: opacity 0.12s ease-out;
}
/* Visibilitat de les etiquetes controlada totalment pel JS (showLabels / hint timer). */


/* Coda */
/* ---- */

#coda {
  position: absolute;
  top: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  display: none;
}

/* Controls Firma-Logo */
/* ------------------- */

/* conrols de desenvolupament (dev controls) */
#controls {
  pointer-events: auto;
  z-index:10;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: center;
  font-size: 11px;
}
button {
  font-family: monospace;
  font-size: 11px;
  padding: 5px 12px;
  background: transparent;
  color: #aaa;
  border: 1px solid #333;
  border-radius: 3px;
  cursor: pointer;
}
button:hover { color: #fff; border-color: #888; }
button.active { color: #7df; border-color: #7df; }

label { display: flex; align-items: center; gap: 5px; color: #666; cursor: pointer; }
label input { accent-color: #7df; }


/* Controls Sol */
/* ------------ */

/* extern, al fitxer css/sol_panel.css */


/* Depuració (debugging) */
/* --------------------- */

#debug {
  width: 380px;
  font-size: 10px;
  line-height: 1.6;
  color: #aaa;
  white-space: pre-wrap;
  background: #161616;
  border: 1px solid #222;
  border-radius: 4px;
  padding: 10px;
  max-height: 200px;
  overflow-y: auto;
  user-select: text;
  -webkit-user-select: text;
  cursor: text;
}


/* Efecte Neó */
/* ---------- */

/* colors dels traços (paths) definits més amunt, en les regles base */

/* Capa neó: oculta per defecte, visible quan una zona està activa.
   L'ombra caiguda (drop-shadow) de CSS genera la resplendor. */
.neon-layer {
  pointer-events: none;
}

/* Animació de tremolor a la capa neó */
.neon-layer.neon-flickering {
  animation: neon-flicker 2s ease-in-out infinite alternate;
}

/* ── Tremolor neó estàndard (zones g, proj, sost) ── */
@keyframes neon-flicker {
  0% {
    filter: drop-shadow(0 0  2px #fff)
            drop-shadow(0 0  6px #fff)
            drop-shadow(0 0 12px var(--colour-neon))
            drop-shadow(0 0 25px var(--colour-neon))
            drop-shadow(0 0 50px var(--colour-neon));
  }
  30% {
    filter: drop-shadow(0 0  1px #fff)
            drop-shadow(0 0  4px #fff)
            drop-shadow(0 0  8px var(--colour-neon))
            drop-shadow(0 0 18px var(--colour-neon))
            drop-shadow(0 0 36px var(--colour-neon));
  }
  45% {
    filter: drop-shadow(0 0  2px #fff)
            drop-shadow(0 0  7px #fff)
            drop-shadow(0 0 14px var(--colour-neon))
            drop-shadow(0 0 28px var(--colour-neon))
            drop-shadow(0 0 55px var(--colour-neon));
  }
  100% {
    filter: drop-shadow(0 0  1px #fff)
            drop-shadow(0 0  3px #fff)
            drop-shadow(0 0  8px var(--colour-neon))
            drop-shadow(0 0 16px var(--colour-neon))
            drop-shadow(0 0 30px var(--colour-neon));
  }
}

/* ── Variants de neó per ocell (zona cont) ──────────────────────────────
   S'aplica mitjançant la classe neon-ocell-{name} a l'element neon-layer.
   Sobreescriu l'animació de tremolor neon-flickering amb un keyframe específic per ocell.
   corb, colibri: valors originals (formes complexes però clares)
   ratPenat:      blanc lleugerament més fort
   mussol, pitRoig, falco: blanc fort per mantenir llegibles les formes filigranades
   ─────────────────────────────────────────────────────────────────────── */

/* corb + colibri: valors estàndard */
.neon-layer.neon-flickering.neon-ocell-corb,
.neon-layer.neon-flickering.neon-ocell-colibri {
  animation-name: neon-flicker;
}

/* ratPenat: blanc lleugerament més fort */
.neon-layer.neon-flickering.neon-ocell-ratPenat {
  animation-name: neon-flicker-ocell-mid;
}
@keyframes neon-flicker-ocell-mid {
  0%   { filter: drop-shadow(0 0 10px #fff) drop-shadow(0 0 16px #fff) drop-shadow(0 0 12px var(--colour-neon)) drop-shadow(0 0 25px var(--colour-neon)) drop-shadow(0 0 50px var(--colour-neon)); }
  30%  { filter: drop-shadow(0 0  7px #fff) drop-shadow(0 0 11px #fff) drop-shadow(0 0  8px var(--colour-neon)) drop-shadow(0 0 18px var(--colour-neon)) drop-shadow(0 0 36px var(--colour-neon)); }
  45%  { filter: drop-shadow(0 0  9px #fff) drop-shadow(0 0 18px #fff) drop-shadow(0 0 14px var(--colour-neon)) drop-shadow(0 0 28px var(--colour-neon)) drop-shadow(0 0 55px var(--colour-neon)); }
  100% { filter: drop-shadow(0 0  6px #fff) drop-shadow(0 0  9px #fff) drop-shadow(0 0  8px var(--colour-neon)) drop-shadow(0 0 16px var(--colour-neon)) drop-shadow(0 0 30px var(--colour-neon)); }
}

/* mussol, pitRoig, falco: blanc fort per als traços filigranats */
.neon-layer.neon-flickering.neon-ocell-mussol,
.neon-layer.neon-flickering.neon-ocell-pitRoig,
.neon-layer.neon-flickering.neon-ocell-falco {
  animation-name: neon-flicker-ocell-strong;
}
@keyframes neon-flicker-ocell-strong {
  0%   { filter: drop-shadow(0 0 14px #fff) drop-shadow(0 0 22px #fff) drop-shadow(0 0 12px var(--colour-neon)) drop-shadow(0 0 25px var(--colour-neon)) drop-shadow(0 0 50px var(--colour-neon)); }
  30%  { filter: drop-shadow(0 0 10px #fff) drop-shadow(0 0 15px #fff) drop-shadow(0 0  8px var(--colour-neon)) drop-shadow(0 0 18px var(--colour-neon)) drop-shadow(0 0 36px var(--colour-neon)); }
  45%  { filter: drop-shadow(0 0 12px #fff) drop-shadow(0 0 24px #fff) drop-shadow(0 0 14px var(--colour-neon)) drop-shadow(0 0 28px var(--colour-neon)) drop-shadow(0 0 55px var(--colour-neon)); }
  100% { filter: drop-shadow(0 0  8px #fff) drop-shadow(0 0 12px #fff) drop-shadow(0 0  8px var(--colour-neon)) drop-shadow(0 0 16px var(--colour-neon)) drop-shadow(0 0 30px var(--colour-neon)); }
}

/* Quan una etiqueta està activa, enfosquix totes les altres dins del mateix svg-wrap */
.svg-wrap:has(.label-active) .menu-label:not(.label-active) {
  opacity: 0.25;
  transition: opacity 0.2s ease-out;
}
/* Pols suau: l'opacitat va de 0 → 0,25 → 0 de manera contínua, sense pausa al punt màxim */
@keyframes label-hint-pulse {
  0%, 100% { opacity: 0; }
  50%       { opacity: 0.25; }
}
.menu-label.hint-visible {
  animation: label-hint-pulse 3s ease-in-out forwards;
}
/* Degradació (fade out) de les etiquetes no actives quan la zona roman activa (1s) */
.menu-label.label-fading {
  opacity: 0 !important;
  transition: opacity 1s ease-in-out !important;
}

/* Etiqueta activa: opacitat 1 + resplendor de neó */
.menu-label.label-active {
  opacity: 1;
  color: #fff;
  animation: label-neon 2s ease-in-out infinite alternate;
}

@keyframes label-neon {
  0% {
    text-shadow:
      0 0  4px #fff,
      0 0 10px #fff,
      0 0 18px var(--colour-neon),
      0 0 40px var(--colour-neon),
      0 0 80px var(--colour-neon);
  }
  30% {
    text-shadow:
      0 0  2px #fff,
      0 0  6px #fff,
      0 0 10px var(--colour-neon),
      0 0 24px var(--colour-neon),
      0 0 50px var(--colour-neon);
  }
  45% {
    text-shadow:
      0 0  4px #fff,
      0 0 12px #fff,
      0 0 20px var(--colour-neon),
      0 0 45px var(--colour-neon),
      0 0 90px var(--colour-neon);
  }
  100% {
    text-shadow:
      0 0  2px #fff,
      0 0  6px #fff,
      0 0 12px var(--colour-neon),
      0 0 28px var(--colour-neon),
      0 0 55px var(--colour-neon);
  }
}


/* ═══════════════════════════════════════════════════════
   PANELL FLOTANT DEL SOL
   ═══════════════════════════════════════════════════ */

/* Zona invisible que segueix el sol */
#sol_hover_zona {
  position: fixed;
  left: 50%;
  top: 30%;           /* recuperació (fallback) fins que JS actualitza */
  width: 60px;        /* recuperació */
  height: 60px;       /* recuperació */
  border-radius: 50%;
  z-index: 50;
  pointer-events: all;
  transform: translate(-50%, -50%);
  cursor: default;
}

/* Zona invisible que segueix la lluna — mateix mecanisme, cercle blau */
#lluna_hover_zona {
  position: fixed;
  left: 50%;
  top: 30%;           /* recuperació fins que JS actualitza */
  width: 60px;        /* recuperació */
  height: 60px;       /* recuperació */
  border-radius: 50%;
  z-index: 50;
  pointer-events: all;
  transform: translate(-50%, -50%);
  cursor: default;
}

/* Panell fix al viewport: messlatte (vara de mesurar) + infobox */
#sol_info_panel {
  position: fixed;
  top: 0; bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 280px;
  z-index: 49;
  pointer-events: none;
}

/* Vara de mesurar (escala) */
#sol_messlatte {
  position: absolute;
  top: 0; bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 48px;
  opacity: 0;
  transition: opacity 0.3s ease;
}
#sol_info_panel.actiu #sol_messlatte {
  opacity: 1;
  transition-delay: 0.5s; /* apareix després de la infobox */
}

#sol_messlatte_linie {
  position: absolute;
  left: 50%;
  top: 5%; bottom: 45%;
  width: 1px;
  background: linear-gradient(to bottom, rgba(255,48,102,0.15) 0%, #ff3066 100%);
  box-shadow: 0 0 6px #ff3066;
}

.sol_ml_label {
  position: absolute;
  right: 2px;
  font-size: 9px;
  font-family: monospace;
  line-height: 1;
  transform: translateY(-50%);
  /* Opacitat graduada: 0°=fort, 90°=suau */
  color: rgba(255,48,102,0.6); /* base, sobreescrit per data-deg */
}
/* Valors negatius (-30°/-60°/-90°, només en mode Llunar) tenen un caràcter
   més que els seus equivalents positius — amb el text ancorat a la dreta,
   el signe menys "-" arribaria fins al marcador centrat. Desplaçat més cap
   a la dreta per compensar-ho. */
.sol_ml_label[data-deg^="-"] { right: -6px; }
.sol_ml_label[data-deg="0"]  { color: rgba(255,48,102,1.0); }
.sol_ml_label[data-deg="30"] { color: rgba(255,48,102,0.8); }
.sol_ml_label[data-deg="60"] { color: rgba(255,48,102,0.6); }
.sol_ml_label[data-deg="90"] { color: rgba(255,48,102,0.4); }

.sol_ml_marker {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 8px; height: 8px;
  border-radius: 50%;
  transition: top 0.3s ease;
}
.sol_ml_marker.sol_marquee   { background: #ff3066; box-shadow: 0 0 8px #ff3066; }
.sol_ml_marker.lluna_marquee { background: #7348FF; box-shadow: 0 0 8px #7348FF; }

/* Marcadors dels graus de l'escala de la vara */
.sol_ml_deg_marker {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 8px; height: 2px;
}
#sol_ml_grad_0  { background: rgba(255,48,102,1.0); }
#sol_ml_grad_30 { background: rgba(255,48,102,0.8); }
#sol_ml_grad_60 { background: rgba(255,48,102,0.6); }
#sol_ml_grad_90 { background: rgba(255,48,102,0.4); }

/* Marcador de l'alçada màxima del dia (culminació) — cercle. Només visible
   a partir de 0° (nit polar: fins i tot el punt més alt del dia queda
   per davall de l'horitzó). */
.sol_ml_zenit_marker {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #ff3066;
  box-shadow: 0 0 6px rgba(255,48,102,0.7);
  display: none;
}
body.sol_ml_zenit_sichtbar #sol_ml_zenit { display: block; }
.sol_ml_nadir_marker { display: none; }
body.sol_ml_nadir_sichtbar .sol_ml_nadir_marker { display: block; }

/* Culminació/Mínim de la Lluna — mateixa forma, blau com en el panell
   flotant (--colour Lluna, vegeu .shp_lluna / .sol_ml_marker.lluna_marquee). */
#sol_ml_mond_zenit, #sol_ml_mond_nadir {
  position: absolute;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #7348FF;
  box-shadow: 0 0 6px rgba(115,72,255,0.7);
  display: none;
}
body.sol_ml_mond_zenit_sichtbar #sol_ml_mond_zenit { display: block; }
body.sol_ml_mond_nadir_sichtbar #sol_ml_mond_nadir { display: block; }

/* Etiquetes a l'esquerra de la línia (Zenit, Culminació, Mínim) — ancorades
   a la dreta prop de la línia central en comptes de a l'esquerra de la vora: l'etiqueta es mou, amb textos més llargs (p. ex. "Culminació"), cap a
   l'ESQUERRA, en comptes de passar per damunt del marcador cap a la dreta —
   així el marcador mai no queda enmig de la paraula. */
.sol_ml_label_left {
  left: auto;
  right: 50%;
  margin-right: 6px;
  color: rgba(255,48,102,0.9) !important;
  font-style: italic;
}
/* El Zenit sempre és a 90° (fix) — per això l'opacitat és fixa en compte
   de calculada per JS, igual que el número "90°" (1,0-90/90×0,6=0,4). */
.sol_ml_label_left[data-deg="90"] { opacity: 0.4; }
/* Visibilitat individual de cada etiqueta mitjançant data-deg — el Sol
   i la Lluna són visibles/invisibles de manera independent, no estan
   lligats per una classe comuna. */
.sol_ml_label_left[data-deg="zenit_sol"]   { display: none; }
body.sol_ml_zenit_sichtbar .sol_ml_label_left[data-deg="zenit_sol"]   { display: block; }
.sol_ml_label_left[data-deg="nadir_sol"]   { display: none; }
body.sol_ml_nadir_sichtbar .sol_ml_label_left[data-deg="nadir_sol"]   { display: block; }
.sol_ml_label_left[data-deg="zenit_lluna"] { display: none; color: rgba(115,72,255,0.9) !important; }
body.sol_ml_mond_zenit_sichtbar .sol_ml_label_left[data-deg="zenit_lluna"] { display: block; }
.sol_ml_label_left[data-deg="nadir_lluna"] { display: none; color: rgba(115,72,255,0.9) !important; }
body.sol_ml_mond_nadir_sichtbar .sol_ml_label_left[data-deg="nadir_lluna"] { display: block; }

/* ── Vara de mesurar de la Lluna (canvi de mode a l'eixida/posta del sol, 
   vegeu sol_hover_panel.js: body.sol_ml_modus_mond) ───────────────────
   0°/90°/Zenit no canvien (arquitectura idèntica per Sol i Lluna).
   30°/60° es reutilitzen, i canvien en mode Llunar al color i posició
   de la Lluna. zenit_sol/nadir_sol enfront de zenit_lluna/nadir_lluna
   ara també s'exclouen mútuament, a més de la condició *_sichtbar (visible)
   existent (només una vara de mesurar visible alhora). -30°/-60°/Nadir(fix)
   només existeixen en mode Llunar. */
body.sol_ml_modus_mond #sol_ml_grad_0,
body.sol_ml_modus_mond #sol_ml_grad_30,
body.sol_ml_modus_mond #sol_ml_grad_60,
body.sol_ml_modus_mond #sol_ml_grad_90,
body.sol_ml_modus_mond #sol_ml_zenit { background: rgba(115,72,255,0.8); box-shadow: 0 0 4px rgba(115,72,255,0.5); }
body.sol_ml_modus_mond .sol_ml_label[data-deg="0"],
body.sol_ml_modus_mond .sol_ml_label[data-deg="30"],
body.sol_ml_modus_mond .sol_ml_label[data-deg="60"],
body.sol_ml_modus_mond .sol_ml_label[data-deg="90"] { color: rgba(115,72,255,0.8); }
body.sol_ml_modus_mond .sol_ml_label_left[data-deg="90"] { color: rgba(115,72,255,0.9) !important; }
body.sol_ml_modus_mond #sol_ml_zenit,
body.sol_ml_modus_mond #sol_ml_nadir { display: none !important; }
body:not(.sol_ml_modus_mond) #sol_ml_mond_zenit,
body:not(.sol_ml_modus_mond) #sol_ml_mond_nadir { display: none !important; }

body.sol_ml_modus_mond .sol_ml_label_left[data-deg="zenit_sol"],
body.sol_ml_modus_mond .sol_ml_label_left[data-deg="nadir_sol"] { display: none !important; }
body:not(.sol_ml_modus_mond) .sol_ml_label_left[data-deg="zenit_lluna"],
body:not(.sol_ml_modus_mond) .sol_ml_label_left[data-deg="nadir_lluna"] { display: none !important; }

/* Elements que només existeixen en mode Llunar (per davall de
   l'horitzó, la vara de mesurar del Sol no té equivalent). */
.sol_ml_mond_nur { display: none; }
body.sol_ml_modus_mond .sol_ml_mond_nur { display: block; }
.sol_ml_label.sol_ml_mond_nur { color: rgba(115,72,255,0.8); }
.sol_ml_label_left.sol_ml_mond_nur { color: rgba(115,72,255,0.9) !important; }
.sol_ml_deg_marker.sol_ml_mond_nur { background: rgba(115,72,255,0.8); }
/* A més de la visibilitat general del mode Llunar: mostrar -30°/-60°/Nadir
   només si la Lluna, eixe dia i durant la seua visibilitat, realment
   baixa per davall de 0° — si no, no hi hauria res a marcar ací. */
body.sol_ml_modus_mond:not(.sol_ml_mond_unten_sichtbar) .sol_ml_mond_nur { display: none; }
/* De manera simètrica: els elements SUPERIORS reutilitzats (30°/60°/90°/
   Zenit — mostren la posició de la Lluna en mode Llunar) només quan la
   Culminació de la Lluna realment supera 0°. El 0° en si roman visible,
   ja que és el límit comú de l'horitzó per a dalt i per a baix. */
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) #sol_ml_grad_30,
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) #sol_ml_grad_60,
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) #sol_ml_grad_90,
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) #sol_ml_zenit,
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) .sol_ml_label[data-deg="30"],
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) .sol_ml_label[data-deg="60"],
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) .sol_ml_label[data-deg="90"],
body.sol_ml_modus_mond:not(.sol_ml_mond_oben_sichtbar) .sol_ml_label_left[data-deg="90"] { display: none !important; }

/* Línia (vara): canvia de color i, en mode Llunar, arriba per davall de
   l'horitzó. sol_hover_panel.js estableix dinàmicament el valor bottom (fons),
   igual que top (cim)). */
body.sol_ml_modus_mond #sol_messlatte_linie {
  background: linear-gradient(to bottom, rgba(115,72,255,0.15) 0%, #7348FF 50%, rgba(115,72,255,0.15) 100%);
  box-shadow: 0 0 6px #7348FF;
}

/* Overlay (capa superposada): captura clics quan la infobox és fixada */
#sol_info_overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 48;
  cursor: default; /* no canvia punter fora de zones especials */
}
body.sol_info_fixat #sol_info_overlay,
body.sol_info_tancant #sol_info_overlay { display: block; }
body.sol_info_fixat #stage svg path { pointer-events: none; }
body.sol_info_tancant #stage svg path { pointer-events: none; }

/* Botó de tancar — posicionat a dalt a la dreta del panell d'informació */
#shp-close {
  position: absolute;
  top: 6px; right: 8px;
  font-size: 14px;
  color: rgba(255,48,102,0.4);
  cursor: pointer;
  line-height: 1;
  transition: color 0.2s;
}
#shp-close:hover { color: #ff3066; }

/* Panell d'informació */
#shp-info {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 50%;
  padding: 12px 14px;
  padding-top: 18px;
  min-width: 173px;
  font-family: monospace;
  font-size: 11px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.5s ease;
  backdrop-filter: blur(4px);
  border: 1px solid rgba(255,48,102,0.3);
  border-radius: 8px;
  white-space: nowrap;
  line-height: 2;
}
#sol_info_panel.actiu #shp-info { opacity: 1; pointer-events: all; }

#shp-info div { display: flex; justify-content: space-between; gap: 14px; }
#shp-info div > span:first-child { color: rgba(255,255,255,0.45); }
#shp-info div > span:last-child  { color: rgba(255,255,255,0.9); }
#shp-info hr  { border: none; border-top: 1px solid rgba(255,48,102,0.2); margin: 4px 0; }

.shp_sol   { color: #ff3066; text-shadow: 0 0 8px #ff3066; display: block; }
.shp_lluna { color: #7348FF; text-shadow: 0 0 8px #7348FF; display: block; }


/* ── Disseny responsiu: format vertical ────────────────────────────
   La visibilitat de #wrap-firma, la grandària de #wrap-logo/#wrap-firma
   i el desplaçament del Sol arriben ara per Inline-Style/postMessage
   des de sol_geo_bridge.js (berechneSolLayout(), sol_layout.js) — basat
   en la relació d'aspecte en compte d'una amplada fixa, perquè es
   tracten correctament tant pantalles estretes com planes alhora. Ací
   només queda el mode compacte (amaga infobox + messlatte - el panell d'informació i la vara de mesurar - per davall de 280×350px).
   ─────────────────────────────────────────────────────────────── */

body.sol_schmal #sol-panel {
  overflow: hidden;
  width: auto;
  min-width: 0;
}

/* Mode compacte (< 280×350px): no hi ha espai per a la infobox + messlatte. */
body.sol_kompakt #sol_hover_zona,
body.sol_kompakt #sol_info_panel {
  display: none;
}

/* Infobox en la vista vertical: la posició ve completament de
   sol_hover_panel.js (posicioInfoBox(), ajust de píxels calculat) —
   position:fixed no funcionaria ací, perquè #sol_info_panel (element
   pare) té ell mateix transform:translateX(-50%) i, per tant, crea el
   seu propi bloc contenidor per als fills fixed. */

/* Per davall de 500px (amplada o alçada, vegeu sol_geo_bridge.js). */
body.sol_panele_aus #controls > *:not(#btn-hover):not(#btn-click) { display: none; }
body.sol_panele_aus #debug { display: none; }

#legal-footer {
  position: absolute;
  top: calc(100vh + 2px); /* xicotet marge contra errors d'arredoniment de vh */
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4em;
  font-size: 0.7rem;
  padding: 1.5rem 1rem;
}
#legal-footer a {
  color: #888888;   /* ≈ 5,4:1 contra #0f0f0f — complix WCAG AA (4,5:1) amb marge */
  text-decoration: none;
}
#legal-footer a:hover {
  color: #e8e8e8;   /* color de text normal del body — molt més clar en passar el ratolí per damunt */
}

/* ── Pàgines legals (Avís Legal, Privacitat, Cookies, Sitemap,
   Accessibilitat) ────────────────────────────────────────────
   Tipografia llegible, independent del motor loader.js/morph.js —
   només reutilitza les variables de color i el fons del body. */
.legal-page {
  max-width: 640px;
  margin: 4rem auto;
  padding: 0 3rem 5rem 2.5rem;
  line-height: 1.7;
}
.legal-page h1 {
  font-size: 1.3rem;
  color: var(--colour-neon);
  margin-bottom: 1.75rem;
}
.legal-page h2 {
  font-size: 1rem;
  color: #e8e8e8;
  margin-top: 2rem;
  margin-bottom: 0.5rem;
}
.legal-page p,
.legal-page li {
  font-size: 0.85rem;
  color: #cfcfcf;
}
.legal-page ul {
  padding-left: 1.2rem;
}
.legal-page a {
  color: var(--colour-neon);
}
.back-link {
  display: inline-block;
  max-width: 560px;
  width: 100%;
  margin: 4rem 0 -2rem 1.5rem;
  font-size: 0.8rem;
  color: #888888;
  text-decoration: none;
}
.back-link:hover {
  color: #e8e8e8;
}

/* A les pàgines legals el footer va al flux normal, sota el
   contingut — no a top:100vh, que només té sentit a la portada
   amb #stage a pantalla completa. */
#legal-footer.static {
  position: static;
  margin-top: 3rem;
}


/* ────────────────────────────────────────────────────────────────
── PÀGINA DE CONTACTE ─────────────────────────────────────────────
───────────────────────────────────────────────────────────────────
   Estètica pròpia, distinta de .legal-page. El gerd (--colour-neon)
   ja no és el color principal ací — turquesa/menta per als enllaços
   (color real de contacte), gerd només per als títols "cta". */

:root {
  --colour-turquesa: #00AFC4;
  --colour-menta:    #18F58A;
  --colour-taronja:  #FF9F1C;
}

/* ── Capçalera: logo a dalt a la dreta, sobreeixint una mica ──── */
.contact-page {
  max-width: 560px;
  margin: 4rem auto;
  padding: 0 1.5rem 7rem;
  position: relative;
}

.contact-top-name {
  margin-bottom: 1.5rem;
}
.nom-link {
  display: inline-flex;
  align-items: center;
  color: var(--colour-turquesa);
  transition: color 0.4s ease;
  text-decoration: none;
  position: relative;
}
.nom-link:hover {
  color: var(--colour-menta);
}
/* Resplendor neó: constant en repòs, amb parpelleig quan es passa el
   ratolí per damunt. Ritme pres directament de @keyframes neon-flicker
   (definit més amunt per a la portada), amb currentColor en compte del
   gerd fix, perquè seguisca el color del moment (turquesa o menta).
   Tècnica de parpelleig inspirada en el treball de F. Rilling
   (https://codepen.io/RillingDev/pen/oNNLMb).
   NOMÉS per als navegadors "bons" (html.logo-mode-filtreComplet):
   aplicar-la també a Safari faria coincidir dos mecanismes de
   resplendor alhora sobre el mateix element (esta regla i les 4
   capes fetes expressament per a Safari), sense que cap dels dos es
   puga avaluar de veres per separat. */
html.logo-mode-filtreComplet .nom-link:hover {
  animation: nom-flicker 3.6s ease-in-out infinite alternate;
}
@keyframes nom-flicker {
  0% {
    filter: drop-shadow(0 0  1px #fff)
            drop-shadow(0 0  2px #fff)
            drop-shadow(0 0  4px currentColor)
            drop-shadow(0 0  8px currentColor);
  }
  30% {
    filter: drop-shadow(0 0 0.5px #fff)
            drop-shadow(0 0  1px #fff)
            drop-shadow(0 0  2.5px currentColor)
            drop-shadow(0 0  5px currentColor);
  }
  45% {
    filter: drop-shadow(0 0  1px #fff)
            drop-shadow(0 0  2px #fff)
            drop-shadow(0 0  4px currentColor)
            drop-shadow(0 0  7px currentColor);
  }
  100% {
    filter: drop-shadow(0 0 0.5px #fff)
            drop-shadow(0 0  1.5px #fff)
            drop-shadow(0 0  3px currentColor)
            drop-shadow(0 0  6px currentColor);
  }
}
/* Variant NOMÉS per a Safari/WebKit (html.logo-mode-domSafari):
   directament sobre .nom-link, com fa l'original, però amb només 2
   drop-shadow apilats (mai 4) -- Safari no interpola bé el radi de
   més de 2 drop-shadow animats alhora. Mateixos 4 punts (0/30/45/
   100%) que l'original nom-flicker, per a mantindre el mateix ritme
   de base que ja funciona bé als altres navegadors. */
html.logo-mode-domSafari .nom-link:hover {
  animation: nom-flicker-safari 3.6s ease-in-out infinite alternate;
}
@keyframes nom-flicker-safari {
  /* Un tercer drop-shadow AFEGIT, blanc i FIX -- el mateix valor a
     les 4 stops, per tant no s'interpola mai (a diferència dels dos
     de currentColor, que sí canvien). Açò afig la "nitidesa
     interior" blanca que porta l'original (2 blancs + 2 de color),
     sense tocar la part que ja funciona bé en Safari (2 valors
     animant-se alhora). */
  0%   { filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0   2px currentColor) drop-shadow(0 0 8px currentColor); }
  30%  { filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0   1px currentColor) drop-shadow(0 0 5px currentColor); }
  45%  { filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0   2px currentColor) drop-shadow(0 0 7px currentColor); }
  100% { filter: drop-shadow(0 0 1px #fff) drop-shadow(0 0 1.5px currentColor) drop-shadow(0 0 6px currentColor); }
}
.nom-svg {
  display: inline-block;
  width: 180px;
  max-width: 55vw;
}
.nom-svg svg {
  display: block;
  width: 100%;
  height: auto;
}
.nom-svg svg path {
  fill: currentColor !important; /* el SVG original porta fill/style inline, que guanya per especificitat sense !important */
}
/* Dos grups a l'SVG: .nom-normal (amb el filtre d'ombra d'Inkscape)
   i .nom-neon (net, amb efecte propi). Per defecte es veu NOMÉS el
   normal; en hover/focus canvia
   a NOMÉS el neó -- mai els dos alhora. */
.nom-svg svg .nom-neon {
  opacity: 0;
}
.nom-svg svg .nom-normal {
  opacity: 1;
}
.nom-link:hover .nom-svg svg .nom-neon,
.nom-link:focus .nom-svg svg .nom-neon {
  opacity: 1;
}
.nom-link:hover .nom-svg svg .nom-normal,
.nom-link:focus .nom-svg svg .nom-normal {
  opacity: 0;
}
/* En repòs: turquesa (sense canvis). En hover: el CORE (fill) es torna
   blanc, independent del "color" (que seguix canviant a menta i, per
   tant, seguix acolorint el resplendor via currentColor al filtre).
   Només afecta .nom-neon -- .nom-normal manté el seu propi color. */
.nom-link:hover .nom-svg svg .nom-neon path {
  fill: #fff !important;
}
/* Efecte neó (l'intent de "glanç interior" amb drop-shadow blanc
   s'ha tret: drop-shadow només pot fer halo EXTERIOR, mai interior —
   amb blanc per davant, tapava la forma en compte de ressaltar-la) */
.nom-link {
  filter:
    drop-shadow(0 0 1px #fff)
    drop-shadow(0 0 3.5px currentColor);
}
/* Text de reserva si el SVG no carrega — tipografia de signatura */
.nom-fallback {
  font-family: 'Sacramento', cursive;
  font-size: 1.8rem;
  color: var(--colour-turquesa);
}
/* Quan el JS carrega nom.svg amb èxit, amaga el text de reserva */
.nom-link.svg-carregat .nom-fallback {
  display: none;
}
.nom-link:not(.svg-carregat) .nom-svg {
  display: none;
}

.contact-title {
  font-size: 1.3rem;
  color: var(--colour-neon);
  margin: 0 0 1.5rem;
}

.contact-header {
  position: absolute;
  top: 0;
  right: -1rem; /* el logo sobreïx del marge dret */
  z-index: 5;
}
@media (max-width: 480px) {
  .contact-header {
    /* En pantalles molt estretes: un marge xicotet, no zero (que
       deixaria el logo arran del cantó de la pantalla). */
    right: 0.5rem;
  }
}
.home-mark {
  display: block;
  position: relative;
  width: 153px; /* proporcional al viewBox 1027×1195 */
  height: 178px;
  color: var(--colour-neon);
  /* El resplendor pulsant ja el fa el propi filtre SVG en hover
     (glowFinal, amb triplicat gerd/verd/blau) -- cap animació CSS
     extra ací, per no duplicar-lo. */
}
.home-mark-fallback {
  display: none; /* amagat per defecte: només es mostra si el JS confirma que logo.svg ha fallat */
  width: 100%;
  height: 100%;
}
.home-mark.error .home-mark-fallback {
  display: block;
}
.home-mark-svg {
  position: absolute;
  inset: 0;
  /* El color base es manté fix (gerd); el canvi en hover es fa amb
     hue-rotate (vegeu més avall), no interpolant el color en si —
     interpolar directament de gerd a menta passa per un gris apagat
     pel mig, que és exactament el que volíem evitar. */
}
.home-mark-svg svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* Formes amb farciment (fill). !important perquè el fill/style
   inline que porta el logo.svg original guanyaria per especificitat. */
.home-mark-svg svg #logo_corn_ext1,
.home-mark-svg svg #logo_corn_ext2,
.home-mark-svg svg #logo_pota_dre,
.home-mark-svg svg #logo_ulleres_dre,
.home-mark-svg svg #logo_ulleres_esq,
.home-mark-svg svg #logo_barba_anell,
.home-mark-svg svg #logo_llavi_superior,
.home-mark-svg svg #logo_llavi_inferior,
.home-mark-svg svg #logo_barba_triangle,
.home-mark-svg svg #logo_molto {
  fill: currentColor !important;
  stroke: none !important;
}
/* Traços oberts, només contorn (sense farciment) */
.home-mark-svg svg #logo_nas,
.home-mark-svg svg #logo_orella_interior_s,
.home-mark-svg svg #logo_galta_orella {
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 10;
}

/* ── Efecte en hover, per filtre SVG (glitch + aberració cromàtica +
   resplendor) ─────────────────────────────────────────────────────
   Inspirat en la tècnica "waving menu" de Dirk Weber per a Smashing
   Magazine (https://codepen.io/smashingmag/pen/OJgNWpj) — no la part
   de la bandera onejant, sinó l'efecte de glitch fragmentat +
   interferència de colors complementaris en hover sobre els cercles
   del menú, adaptat als nostres colors (turquesa/gerd/menta) i sense
   la distorsió ondulant (feDisplacementMap complet), substituïda
   per un simple canvi de filtre en :hover.
   AVÍS: els filtres SVG complexos no es comporten igual a tots els
   navegadors (vegeu detectaCapacitatLogo() a contacte.js). El filtre
   complet està definit dins de contacte.html (element <svg><defs><filter>). */
.home-mark-svg svg {
  transition: filter 0.15s ease;
}
/* ── Entrada esgraonada en hover (i eixida amb tremolor) ──────────
   En compte de commutar l'efecte sencer de colp, dues capes extra
   se superposen exactament al mateix lloc:
   1. .home-mark-glow-previ: només el resplendor gerd, apareix de
      seguida (sense retard).
   2. .home-mark-efecte-complet: el filtre sencer (resplendor +
      fragmentació + aberració cromàtica), apareix DESPRÉS -- un
      retard perceptible perquè no "caiga tot de colp" damunt de qui
      mira.
   En eixir (mouseleave), la capa 1 simplement s'esvaeix; la capa 2
   (la més intensa) fa uns quants "tremolors" abans d'apagar-se del
   tot (vegeu @keyframes logo-tremolor-eixida, activada per JS). */
/* ── Nivell 2 (domSafari): versió de substitució, aplicada al logo real.
   Colors: sense currentColor -- cada còpia de color porta el seu
   color fix directament (fill/stroke amb !important sobre cada
   traç), vegeu contacte.js. */
.home-mark-dom-safari {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.home-mark-dom-safari .home-mark-svg svg {
  width: 100%;
  height: 100%;
  display: block;
}
/* Els elements <svg> arrel retallen implícitament tot el que quede
   fora de l'àrea que marca el seu propi viewBox -- cal desactivar-ho
   allà on el contingut es desplaça més enllà (bandes i còpies de
   color), o el clip-path personalitzat (que sí té marge) no arriba
   mai a fer efecte. TAMBÉ cal a la base i a les còpies de color pel
   PROPI resplendor (drop-shadow): un radi de desenfocament de N px
   necessita ell mateix uns quants N més d'espai per a difuminar-se
   del tot -- si no, el desenfocament es talla abans d'acabar
   d'esvair-se, deixant una vora difusa (no un tall dur) exactament
   allà on el viewBox l'interromp. Càlcul aproximat (radi × 3, regla
   pràctica per al llindar visual d'un desenfocament gaussià): el
   resplendor de la base (radi màxim 10px) necessitaria per si sol
   uns 200 unitats de marge, molt més que les 120 que dona el viewBox
   ampliat de les còpies de color -- per això calia "overflow: visible"
   ací i no únicament un viewBox més ample. */
.home-mark-dom-banda svg,
.home-mark-dom-color svg,
.home-mark-dom-base svg {
  overflow: visible;
}
/* Còpies de color: mode "screen" perquè s'ADDICIONEN (mai enfosquen)
   -- alineades (0,0) queden cobertes per la base nítida; desplaçades,
   deixen veure una vora de color pur. */
.home-mark-dom-color {
  mix-blend-mode: screen;
  /* Tècnica contra un bug de repintat de WebKit: en combinar
     "filter: drop-shadow" animat amb un desplaçament SMIL discret
     (salts, no lliscament continu), Safari a vegades no invalida
     correctament els píxels antics del resplendor quan l'element
     salta a una altra posició -- deixa un resplendor "congelat" a
     l'extrem de l'últim desplaçament, que només un repintat complet
     (canviar de finestra) neteja. Forçar l'element a la seua pròpia
     capa composta (GPU) sol solucionar este tipus de bug concret,
     perquè llavors tota la capa es torna a dibuixar sencera en
     compte de confiar en un càlcul parcial de "zona bruta". */
  will-change: transform, filter;
  transform: translateZ(0);
}
.home-mark-dom-base {
  position: absolute;
  inset: 0;
  animation: dom-safari-glow-base 2.6s linear infinite;
  /* NO "will-change"/"translateZ(0)" ací (a diferència de
     .home-mark-dom-color): esta capa depén d'un "mask" animat amb
     forats -- i "mask" + promoció forçada a una capa composta GPU
     és una combinació coneguda per portar problemes en WebKit (deixa
     de fer forat, mostrant la base sencera per davall dels
     fragments). La tècnica de la capa GPU és per a un problema
     concret (resplendor congelat en saltar per SMIL amb un
     drop-shadow animat); el resplendor de la base ve d'una
     @keyframes CSS contínua, no de salts discrets, un mecanisme
     diferent que no necessita eixa tècnica. */
}
@keyframes dom-safari-glow-base {
  /* Flicker de veres: l'amplària cau fins a quasi zero en diversos
     instants irregulars (no una simple oscil·lació entre dos valors
     mitjans, que es llig com un "blur respirant" en compte de neó
     parpellejant). NOMÉS gerd -- sumar-hi verd/blau ací tornaria a
     acostar el conjunt al blanc il·legible (per això eixos dos colors
     tenen el seu propi resplendor, més avall, lligat NOMÉS als
     instants en què la seua pròpia còpia és visible). */
  0%   { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
  4%   { filter: drop-shadow(0 0 3.5px #ff3066) drop-shadow(0 0 10px #ff3066); }
  9%   { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
  11%  { filter: drop-shadow(0 0 3px #ff3066) drop-shadow(0 0 8px #ff3066); }
  16%  { filter: drop-shadow(0 0 0.2px #ff3066) drop-shadow(0 0 0.3px #ff3066); }
  27%  { filter: drop-shadow(0 0 4px #ff3066) drop-shadow(0 0 11px #ff3066); }
  32%  { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
  40%  { filter: drop-shadow(0 0 3.5px #ff3066) drop-shadow(0 0 9px #ff3066); }
  45%  { filter: drop-shadow(0 0 0.2px #ff3066) drop-shadow(0 0 0.3px #ff3066); }
  47%  { filter: drop-shadow(0 0 3px #ff3066) drop-shadow(0 0 8px #ff3066); }
  58%  { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
  66%  { filter: drop-shadow(0 0 4px #ff3066) drop-shadow(0 0 12px #ff3066); }
  71%  { filter: drop-shadow(0 0 0.2px #ff3066) drop-shadow(0 0 0.3px #ff3066); }
  80%  { filter: drop-shadow(0 0 3.5px #ff3066) drop-shadow(0 0 9px #ff3066); }
  85%  { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
  93%  { filter: drop-shadow(0 0 3px #ff3066) drop-shadow(0 0 8px #ff3066); }
  100% { filter: drop-shadow(0 0 0.3px #ff3066) drop-shadow(0 0 0.5px #ff3066); }
}
/* Resplendor de cada còpia de color, directament sobre l'element --
   ara és segur: la còpia ja NO depén d'"overflow: visible" (usa el
   seu propi viewBox més ample, vegeu contacte.js), així que "filter"
   no té cap contingut desbordat que li faça falta. La caixa pròpia
   és MÉS GRAN que la del logo (marge de 120 unitats del viewBox a
   cada costat, ~17,9px a esta escala) i desplaçada cap amunt/
   esquerra la mateixa quantitat, perquè el traç nítid del logo
   quede exactament alineat amb les altres capes malgrat la caixa
   més gran. */
.home-mark-dom-color {
  position: absolute;
  top: -17.9px;
  left: -17.9px;
  width: 188.75px;
  height: 213.75px;
}
#home-logo-dom-color-verd {
  filter: drop-shadow(0 0 3px #66ff30) drop-shadow(0 0 6px #66ff30);
}
#home-logo-dom-color-blau {
  filter: drop-shadow(0 0 3px #3066ff) drop-shadow(0 0 6px #3066ff);
}
.home-mark-dom-banda {
  position: absolute;
  inset: 0;
  /* Este element (i el seu <svg> intern) es queda QUIET -- porta el
     clip-path, que defineix la finestra fixa. El moviment és NOMÉS
     al <g> intern amb els traços (.dom-safari-contingut-mobil,
     mateix nom de classe reutilitzat per contacte.js). */
}
.dom-safari-contingut-mobil {
  /* NOMÉS la classe/etiqueta -- l'animació de veres és SMIL
     (<animateTransform>, afegit per JS), no CSS transform, que dins
     d'un viewBox escalat no és fiable. */
}
/* La substitució NOMÉS es fa visible en hover quan <html> porta la
   classe logo-mode-domSafari (vegeu detectaCapacitatLogo() a
   contacte.js) -- als altres dos nivells es queda a opacity:0. */
html.logo-mode-domSafari .home-mark:hover .home-mark-dom-safari {
  opacity: 1;
}
/* CRUCIAL: #home-logo-svg (la còpia nítida original, sempre visible)
   s'ha d'amagar mentre .home-mark-dom-safari està activa -- si no,
   quedaria per davall de tot este muntatge, i els "forats" de la
   base del nivell 2 no portarien de veres a res buit: només
   mostrarien la gràfica original intacta per davall. Els fragments
   (banda1/2/diagonal) quedarien per tant afegits COM UNA CAPA damunt
   d'un logo ja complet, en compte de substituir-lo. Al nivell 1
   (filtreComplet) açò no fa falta perquè el seu propi efecte és un
   filtre que RECOBREIX per complet, no un sistema de forats que
   necessite que no hi haja res sòlid per davall. */
html.logo-mode-domSafari .home-mark:hover #home-logo-svg {
  opacity: 0;
}
#home-logo-svg {
  transition: opacity 0.3s ease;
}

.home-mark-glow-previ,
.home-mark-efecte-complet {
  opacity: 0;
  pointer-events: none;
}
.home-mark-glow-previ svg {
  filter: url(#filtre-logo-glow-previ);
}
.home-mark-efecte-complet svg {
  filter: url(#filtre-logo-hover);
}
.home-mark-glow-previ {
  transition: opacity 0.3s ease;
}
.home-mark-efecte-complet {
  transition: opacity 0.35s ease;
}
/* Estes dues regles NOMÉS s'activen a "html.logo-mode-filtreComplet"
   -- als altres dos nivells (domSafari / estatic), el filtre SVG
   complet ni tan sols s'intenta en hover: en Safari/WebKit, provar-lo
   igualment és exactament el problema de renderitzat que volem
   evitar (vegeu detectaCapacitatLogo() a contacte.js). */
html.logo-mode-filtreComplet .home-mark:hover .home-mark-glow-previ {
  opacity: 1;
  transition: opacity 0.25s ease 0s;
}
html.logo-mode-filtreComplet .home-mark:hover .home-mark-efecte-complet {
  opacity: 1;
  transition: opacity 0.35s ease 0.22s; /* ve darrere del resplendor previ */
}
@keyframes logo-tremolor-eixida {
  0%   { opacity: 1; }
  4%   { opacity: 0.1;  }
  15%  { opacity: 0.65; } /* tremolor 1 */
  18%  { opacity: 0.05; }
  32%  { opacity: 0.42; } /* tremolor 2 */
  35%  { opacity: 0.04; }
  50%  { opacity: 0.2;  } /* tremolor 3 */
  64%  { opacity: 0.02; }
  69%  { opacity: 0.1;  } /* tremolor 4, molt tènue */
  71%  { opacity: 0.02; }
  92%  { opacity: 0.12; } /* tremolor 5 */
  96%  { opacity: 0.05; }
  100% { opacity: 0; }
}
.home-mark-efecte-complet.tremolor {
  animation: logo-tremolor-eixida 3.8s ease-out forwards;
}

/* ── Text de benvinguda ────────────────────────────────────────── */
.contact-intro p {
  font-family: 'PT Sans Narrow', 'Trebuchet MS', 'Segoe UI', Verdana, sans-serif;
  font-size: 1.165rem;
  letter-spacing: 0.015rem;
  line-height: 1.45;
  color: #cfcfcf;
  margin-bottom: 0.65rem;
}
.text-link {
  color: var(--colour-turquesa);
  cursor: pointer;
  transition: color 0.3s ease;
}
.text-link:hover {
  color: var(--colour-menta);
  text-decoration: underline;
}

/* ── ESCENA BOSC/ALIEN ────────────────────────────────────────── */
.scene {
  position: relative;
  width: 160px; /* limita la zona interactiva a l'àrea real del dibuix, no tota l'amplada */
  height: 50px;
  margin: 1rem 0 1.5rem;
  font-size: 2.4rem;
  line-height: 1;
  user-select: none;
  cursor: default; /* reacciona igual, però no simula un enllaç */
  transition: margin-bottom 2.2s ease;
}
/* Quan les opcions ja estan desplegades, el marge inferior gran de la
   escena del bosc ja no té sentit — l'espai fins a "Envia un correu:"
   ha de ser semblant al que hi ha entre les altres línies. */
#escena-bosc:has(~ .zona-clic.revelada) {
  margin-bottom: 0.3rem;
}

/* 1. Escena bosc */

/* 1a Estàtic */
.scene-tree {
  position: absolute;
  bottom: 0;
  z-index: 3;
  opacity: 0.95;
}
.scene-tree-1 { left: 41px; font-size: 2.3rem; top: 1.5px; z-index: 3; }
.scene-tree-2 { left: 10px; z-index: 5; }
.scene-tree-3 { left: 26px; font-size: 2.5rem; bottom: -2.5px; z-index: 6; }

.scene-fulles {
  left: 67px;
  top: 1.5px;
  font-size: 1rem;
  opacity: 0;
}

.scene-vent {
  display: inline-block;
}

/* 1b Animació */

.scene.revelada .scene-tree-1 {
  animation: tree-rustle 1.2s ease-in-out 0.05s;
}

@keyframes tree-rustle {
  0%, 100% {
    transform: translateX(0) rotate(0deg);
  }
  15% {
    transform: translateX(-1px) rotate(-1deg);
  }
  30% {
    transform: translateX(2px) rotate(1.5deg);
  }
  45% {
    transform: translateX(-2px) rotate(-1.5deg);
  }
  60% {
    transform: translateX(1px) rotate(1deg);
  }
  75% {
    transform: translateX(-0.5px) rotate(-0.5deg);
  }
}

.scene.revelada .scene-fulles {
  animation: fulles-caure 2.5s ease-in 0.2s forwards;
}

.scene.revelada .scene-vent {
  animation: ventar 2.5s ease-in-out 0.15s forwards;
}

@keyframes fulles-caure {
  0% {
    opacity: 0;
    transform: translateY(0);
  }

  8% {
    opacity: 1;
  }

  70% {
    opacity: 1;
  }

  90% {
    opacity: 0;
    transform: translateY(65%);
  }

  100% {
    opacity: 0;
    transform: translateY(80%);
  }
}

@keyframes ventar {
  0% {
    transform: translateX(0) rotate(0deg);
  }

  15% {
    transform: translateX(-35%) rotate(12deg);
  }

  30% {
    transform: translateX(30%) rotate(-10deg);
  }

  45% {
    transform: translateX(-25%) rotate(8deg);
  }

  60% {
    transform: translateX(20%) rotate(-7deg);
  }

  75% {
    transform: translateX(-12%) rotate(5deg);
  }

  90% {
    transform: translateX(5%) rotate(-2deg);
  }

  100% {
    transform: translateX(0) rotate(0deg);
  }
}

/* 2. Alienígena */

.scene-alien {
  position: absolute;
  left: 20px;
  bottom: 6px;
  z-index: 4;
  font-size: 2rem;
  opacity: 0;
  /* La posició torna ràpid; l'opacitat s'esvaeix DESPRÉS (delay), no
     a la vegada — si no, desapareixeria abans que es veja tornar. */
  transition: transform 0.9s ease, opacity 0.5s ease 0.6s;
}

.scene.revelada .scene-alien {
  animation: alien-emerge 3.8s ease-in-out 1.3s forwards;
}

@keyframes alien-emerge {

  /* ocult */
  0% {
    opacity: 0;
    transform: translateX(0);
  }
  /* emergeix el cap */
  12% {
    opacity: 1;
    transform: translateX(45%);
  }
  /* mira */
  30% {
    transform: translateX(45%);
  }
  /* surt */
  55% {
    transform: translateX(210%);
  }
  /* breu alegria */
  70% {
    transform: translateX(210%) translateY(-5px);
  }
  78% {
    transform: translateX(210%) translateY(2px);
  }
  86% {
    transform: translateX(210%) translateY(-3px);
  }
  100% {
    opacity: 1;
    transform: translateX(210%) translateY(0);
  }
}

/* 3. Salutació */

.scene-vulcanic {
  display: block;
  position: absolute;
  width: 100%; 
  height: 100%;
  transform: scaleX(-1);
  filter: hue-rotate(150deg) grayscale(90%);
}

.scene-hand {
  position: absolute;
  width: 256px;
  height: 25px;
  top: 25px;
  left: -5px;
  z-index: 5;

  opacity: 0;
  transform: translateY(4px);

  /* Sense delay: s'usa per amagar-se ràpid en un segon clic */
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.scene.revelada .scene-hand {
  animation: hand-appear 1s cubic-bezier(0.61, 1, 0.87, 1) 5.1s forwards;
}
@keyframes hand-appear {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(-75%); }
}

@media (prefers-reduced-motion: reduce) {
  .scene-alien, .scene-hand { transition: none; }
}


/* ── Opcions de contacte ──────────────────────────────────────── */

/* (amagades per JS fins a la interacció; visibles per defecte perquè funcione sense JS) */

.zona-clic {
  position: relative;
  cursor: pointer; /* zeigt, dass die Zone klickbar ist */
}
/* Standardmäßig direkt eingeklappt — kein Warten auf ein per JS
   gesetztes Attribut, sonst blitzt der Inhalt beim Laden kurz auf,
   bevor er wieder verschwindet. Ohne JS hebt <noscript> im <head>
   diese Beschränkung wieder auf. */
.zona-clic .contact-intro,
.zona-clic .scene-papallona {
  overflow: hidden;
  max-height: 220px;
  opacity: 1;
  transition: max-height 2.2s ease, opacity 1.6s ease, margin 2.2s ease;
}
.zona-clic.revelada .contact-intro,
.zona-clic.revelada .scene-papallona {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  margin-bottom: 0;
  pointer-events: none;
}

.opcions-contacte {
  margin-top: 0.2rem;
  overflow: hidden;
  max-height: 0;
  transition: max-height 2.2s ease, margin-top 2.2s ease;
}
.opcions-contacte.revelada {
  max-height: 3000px;
}
/* Estat final directament, sense pas per l'estat inicial: quan
   contacte_enviat.js (carregat síncronament al <head>, abans de pintar
   res del <body>) detecta "?enviat=1" i afig esta classe a <html>,
   estes regles ja mostren l'aspecte final -- el "!important" les fa
   guanyar encara que contacte.js no haja arribat a afegir ".revelada"
   (que arriba més tard, en carregar-se al final del <body>). Així
   mai es pinta ni per un instant el text de benvinguda desplegat. */
html.ja-enviat .zona-clic .contact-intro,
html.ja-enviat .zona-clic .scene-papallona {
  max-height: 0 !important;
  opacity: 0 !important;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
  pointer-events: none !important;
}
html.ja-enviat .opcions-contacte {
  max-height: 3000px !important;
}
html.ja-enviat #papallona {
  display: none !important;
}

.contact-cta-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1.6rem 0 0.6rem;
}
.contact-cta {
  display: inline;
  font-family: 'Titillium Web', sans-serif;
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--colour-neon);
  font-weight: 600;
}
.contact-value {
  color: var(--colour-turquesa);
  text-decoration: none;
  font-size: 0.95rem;
  transition: color 0.2s ease;
}
.contact-value:hover {
  color: var(--colour-menta);
}

.instagram-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--colour-turquesa);
  text-decoration: none;
  font-size: 0.95rem;
  letter-spacing: 0.03em;
  line-height: 1;
  transition: color 0.2s ease;
}
.instagram-link svg {
  display: block;
}
.instagram-link:hover {
  color: var(--colour-menta);
}
.segueix-me {
  font-family: 'PT Sans Narrow', 'Trebuchet MS', 'Segoe UI', Verdana, sans-serif;
  font-size: 1.165rem;
  letter-spacing: 0.015rem;
  color: #cfcfcf;
  line-height: 1;
  display: inline-flex;
  align-items: center;
}

#missatge-e {
  display: inline-block;
}

/* ── Formulari ────────────────────────────────────────────────── */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  background: transparent;
  font-size: 0.9rem;
  padding: 1.2rem;
  border-radius: 6px;
  position: relative;
}
.field {
  background: #222;
  padding: 0.5rem 0.7rem;
  border-radius: 4px;
}
.field-row {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
}
.field-row .field {
  flex: 1 1 200px;
}
.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid #444;
  color: #e8e8e8;
  font-family: monospace;
  font-size: 0.9rem;
  padding: 0.5rem 0.1rem;
  resize: vertical;
}
.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: #777;
}
.contact-form input:focus,
.contact-form textarea:focus {
  outline: none;
  border-bottom-color: var(--colour-turquesa);
}
.contact-form .camp-error {
  color: #ff6b6b;
  font-size: 0.75rem;
  margin-top: 0.3rem; /* nom/correu: separació respecte a l'etiqueta anterior */
}
.contact-form textarea + .camp-error {
  margin-top: -0.7rem; /* missatge: més amunt, enganxat a la vora inferior del quadre */
}

/* Camp parany contra bots — amagat visualment però present al DOM */
.hp-field {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.consent {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.8rem;
  color: #aaa;
  cursor: pointer;
}
.consent input {
  margin-top: 0.2rem;
  accent-color: var(--colour-turquesa);
}
.consent input:checked {
  accent-color: var(--colour-menta);
}
.consent a {
  color: #666;
  font-weight: 600;
  text-decoration: underline;
}
.consent.avis {
  color: var(--colour-neon);
}
.consent.avis input {
  accent-color: var(--colour-neon);
  outline: 2px solid var(--colour-neon);
  outline-offset: 2px;
  border-radius: 2px;
}

.contact-form button {
  align-self: flex-start;
  margin-top: 0.25rem;
  font-family: 'Titillium Web', sans-serif;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.5rem 1.3rem;
  background: transparent;
  color: var(--colour-turquesa);
  border: 1px solid var(--colour-turquesa);
  border-radius: 3px;
  cursor: pointer;
  transition: border-color 1.8s ease, color 1.8s ease;
  position: relative;
  z-index: 2;
}
/* Consentiment marcat: menta */
.contact-form button.consent-ok {
  color: var(--colour-menta);
  border-color: var(--colour-menta);
}
/* Consentiment marcat + hover/clic sobre "Porta": gerd */
.contact-form button.consent-final {
  color: var(--colour-neon);
  border-color: var(--colour-neon);
}

.contact-confirmacio {
  color: var(--colour-menta);
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

/* ── Papallona: sempre position:absolute respecte a .contact-page
   (mai position:fixed) — així es desplaça amb el contingut en fer
   scroll, i les transicions top/left tenen sempre un punt de partida
   real per a "volar" en compte d'aparèixer de colp a la nova posició. */
#papallona {
  position: absolute;
  font-size: 2.4rem; /* una miqueta més gran */
  cursor: default; /* reacciona igual, sense simular un enllaç */
  z-index: 60;
  /* left/top ja NO es transicionen per CSS — els mou contacte.js
     fotograma a fotograma per a dibuixar una trajectòria corbada amb
     serpenteig, no un simple lliscament en línia recta.
     "transform" tampoc: tant comencaExcitacio() com
     volaA() ja interpolen l'escala/rotació ells mateixos, fotograma
     a fotograma -- tindre-hi a més una transition de 1,5s feia que
     cada nou valor (cada ~16ms) llançara una transició nova que mai
     arribava a completar-se abans de ser substituïda per la
     següent, donant la falsa impressió de "congelat" (quasi sense
     moviment visible) durant tota l'excitació. */
  transition: opacity 1.4s ease-in-out, filter 1.8s ease;
  filter: hue-rotate(0deg); /* colors naturals de l'emoji (blau/cian) */
}
#papallona.inerta {
  pointer-events: none;
}
#papallona.girada {
  transform: rotate(45deg) scale(1); /* posició 2: gir + tornada a la mida normal, TOTS DOS durant el vol */
}
#papallona.girada-esq {
  transform: rotate(-55deg); /* posició 3: sentit antihorari */
}
/* Consentiment marcat: verdós, a joc amb el botó en menta */
#papallona.consent-ok {
  filter: hue-rotate(-53deg);
}
/* Consentiment marcat + hover/clic sobre "Porta": gerd, a joc amb el
   botó — la rotació continua en el mateix sentit (mai passa pel blau),
   perquè el trajecte siga sempre progressiu, no un salt. */
#papallona.consent-final {
  filter: hue-rotate(-222deg);
}
/* Ix volant (fotograma a fotograma, per JS) i, en eixir, s'agranda
   una mica — com si s'apropara cap a qui mira en compte de només
   allunyar-se cap a l'esquerra. */
#papallona.fora {
  /* "transform" ja no es declara ací -- ara el porta volaA() fotograma
     a fotograma (escalaOrigen:1, escalaDesti:2.6, girDesti:-55), i
     una transition pròpia de "transform" ací reproduiria exactament
     el mateix bug de "congelat" que la base #papallona (una nova
     transició de 1,4s cada ~16ms, que mai arriba a completar-se). */
  opacity: 0;
  transition: opacity 1.4s ease-in 0.5s;
}

/* Zona de la flor: amplada limitada (com la escena del bosc), perquè
   el hover/clic només reaccione a prop del dibuix real. */
.scene-papallona {
  width: 130px;
}
.scene-flower {
  position: absolute;
  right: 10%;
  bottom: 4px;
  font-size: 1.8rem;
}

@keyframes voleteja {
  0%   { transform: translate(0, 0) rotate(0deg); }
  20%  { transform: translate(-13px, -16px) rotate(-10deg); }
  40%  { transform: translate(4px, -22px) rotate(6deg); }
  60%  { transform: translate(9px, -8px) rotate(10deg); }
  80%  { transform: translate(-11px, -13px) rotate(-9deg); }
  100% { transform: translate(0, 0) rotate(0deg); }
}
/* Reacció d'ensurt (posició 1 a 2) i excitació posterior: controlades
   DIRECTAMENT per JS (comencaExcitacio a contacte.js), fotograma a
   fotograma -- no per @keyframes CSS: fer-ho amb @keyframes exigiria
   llegir getComputedStyle().transform per a saber "quina escala té
   en eixe instant" abans de volar, i el parsing (una matriu, sovint
   en format matrix3d) pot fallar en silenci en alguns navegadors,
   deixant la papallona a mida normal en compte d'encongir-se de veres
   durant el vol. */
body:not(.papallona-volant) #papallona {
  animation: voleteja 4.5s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  #papallona { animation: none !important; }
}

/* ── Mapa visible (no com a fons) ─────────────────────────────── */
#mapa-visible {
  margin: 2rem 0 0;
  /* sense border/radius propis — el SVG del mapa ja porta el seu marc */
}
#mapa-visible.clicable {
  cursor: pointer;
}
#mapa-visible svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ── Modal genèric (Política de Privacitat, galetes.html, mapa) ── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
.modal-overlay[hidden] {
  display: none;
}
.modal-caixa {
  position: relative;
  background: #161616;
  border: 1px solid #333;
  border-radius: 8px;
  max-width: 640px;
  max-height: 85vh;
  overflow-y: auto;
  padding: 0 1.75rem 2rem;
}
/* Capçalera enganxosa: el botó de tancar sempre visible, encara
   que es faça scroll pel contingut llarg de la política. */
.modal-capçalera {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  justify-content: flex-end;
  padding: 0.75rem 0 0.5rem;
  background: #161616;
}
.modal-tancar {
  background: transparent;
  border: none;
  color: var(--colour-neon);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.4rem;
}
.modal-tancar:hover {
  color: var(--colour-menta);
}
.modal-contingut .legal-page {
  max-width: none;
  margin: 0;
  padding: 0 0.25rem 1rem;
}
.modal-contingut svg {
  width: 100%;
  height: auto;
  display: block;
}

/* Variant per al mapa ampliat: caixa molt més gran, sense el
   text llegible propi de .legal-page. */
.modal-mapa .modal-caixa {
  max-width: 95vw;
  max-height: 95vh;
  width: 95vw;
  padding: 0 0.75rem 0.75rem;
}
.modal-mapa .modal-capçalera {
  background: transparent;
}
